Tüm eğitimler
TEKNİK REHBER GÖMÜLÜ LİNUX AĞ SÜRÜCÜSÜ 2026

DSA
Linux Distributed Switch Architecture

SoC entegre Ethernet switch'leri Linux çekirdeğine entegre etmek için DSA çerçevesini — Marvell 88E6xxx, MediaTek MT7530 ve Realtek RTL8370 örnekleriyle — adım adım öğrenin.

00 DSA neden var — SoC switch ve CPU port

Yönlendirici ve geçit (gateway) SoC'lerinin büyük çoğunluğu entegre bir Ethernet switch çekirdeği içerir. Linux'un bu switch'i nasıl yönettiğini anlamak, DSA'nın neden var olduğunu açıklar.

Klasik yaklaşımın sorunu

OpenWrt veya benzeri yönlendirici dağıtımlarının ilk kuşaklarında entegre switch'ler bir tek parça MAC olarak gösterilir, portlar arası yönetim ise vendor-specific kullanıcı alanı araçlarıyla (switch binary, swconfig) yapılırdı. Bu yaklaşım şu sorunları doğuruyordu:

Kernel görünürlüğü yokBireysel switch portları bağımsız ağ arayüzü olarak görünmüyordu; tc, iptables uygulanamıyordu
Standart dışı yönetimHer vendor farklı kullanıcı alanı araçları; taşınabilirlik sıfır
Bridge/VLAN entegrasyonuLinux yazılım bridge ile donanım switch koordinasyonu imkânsız
netfilter/tc hook yokTrafiği kernel ağ yığınından geçiremediğiniz için paket filtreleme yapılamaz

DSA çözümü

DSA (Distributed Switch Architecture, net/dsa/), her switch portunu bağımsız bir Linux ağ arayüzü (slave netdev) olarak sunar. Trafik hâlâ donanımda anahtarlanır; ancak CPU port üzerinden geçen paketler kernel yığınına girer, böylece tc/netfilter/bridge API'leri çalışır.

         Linux Kernel
    ┌──────────────────────────────┐
    │  eth0 (master/CPU netdev)    │
    │   lan1   lan2   lan3   wan   │  ← slave netdev'ler
    └────────────┬─────────────────┘
                 │ DSA tag (Ethertype / trailer)
    ┌────────────▼─────────────────┐
    │   Switch donanımı            │
    │  P0(CPU) P1  P2  P3  P4(WAN)│
    └──────────────────────────────┘

DSA etiket protokolleri

Etiket türüKonumKullanan chipset
DSA (Ethertype 0xDADA)Frame başıMarvell 88E6xxx (eski)
EDSA (Ethertype 0xDADB)Frame başıMarvell 88E6xxx (yeni)
MTKFrame başı (4 B)MediaTek MT7530/MT7621
RTL4 / RTL8_4Frame sonu (trailer)Realtek RTL8370/RTL838x
OCELOTIFH başlıkMicrochip Ocelot/Sparx
SJA1105Meta frameNXP SJA1105

Bu bölümde

  • DSA her switch portunu bağımsız netdev olarak sunar — standart Linux araçları çalışır
  • CPU port üzerinden geçen trafik DSA etiketiyle hangi porta ait olduğunu belirtir
  • Donanım anahtarlama hâlâ chip içinde yapılır — yazılım yolu sadece CPU'ya gelen trafik için

01 DSA mimarisi — master ve slave netdev

DSA'nın katmanlı mimarisini anlamak, sürücü yazarken hangi katmanın ne yaptığını bilmek açısından kritiktir.

Katman yapısı

Kullanıcı alanı: ip link / bridge / tc
         │
   Linux Ağ Çekirdeği (netdev API)
         │
   ┌─────┴──────────────────────────────┐
   │ DSA çerçevesi (net/dsa/dsa2.c)     │
   │  ┌─────────────────────────────┐   │
   │  │ slave netdev (lan1…lanN, wan)│   │
   │  │ dsa_slave_xmit()            │   │
   │  │ → DSA etiket ekle           │   │
   │  └──────────────┬──────────────┘   │
   │                 │                  │
   │  master netdev (eth0, CPU port)    │
   │  dsa_master_xmit() → MAC sürücüsü │
   └─────────────────┬──────────────────┘
                     │
             Switch chip sürücüsü
             (mv88e6xxx / mt7530 …)
                     │
              MDIO / SPI / I2C

dsa_switch yapısı

c
/* include/net/dsa.h'den sadeleştirilmiş */
struct dsa_switch {
    struct device        *dev;
    struct dsa_switch_tree *dst;         /* çok-chip topoloji ağacı */
    unsigned int          index;         /* bu switch'in numarası (cascaded) */
    const struct dsa_switch_ops *ops;    /* sürücü callback'leri */
    void                 *priv;          /* sürücüye özel veri */
    int                   num_ports;
    struct dsa_port       ports[DSA_MAX_PORTS];
    unsigned long         phys_mii_mask; /* dahili MDIO maskelemesi */
    struct mii_bus       *slave_mii_bus; /* slave MDIO bus (dahili PHY) */
    /* VLAN filtreleme modu */
    bool                  vlan_filtering_is_global;
    bool                  needs_standalone_vlan_filtering;
};

RX path — paket gelişi

c
/* Master netdev RX handler (dsa_switch_rcv) */
static rx_handler_result_t dsa_switch_rcv(struct sk_buff **pskb)
{
    struct sk_buff *skb = *pskb;
    struct dsa_port *cpu_dp = skb->dev->rx_handler_data;
    const struct dsa_device_ops *tag_ops = cpu_dp->dst->tag_ops;
    struct dsa_slave_priv *p;

    /* DSA etiketini çöz — hangi port gönderdi? */
    skb = tag_ops->rcv(skb, skb->dev);
    if (!skb)
        return RX_HANDLER_CONSUMED;

    /* sk_buff'ın dev'ini doğru slave netdev'e yönlendir */
    skb->dev->stats.rx_packets++;
    netif_receive_skb(skb);
    return RX_HANDLER_CONSUMED;
}

Bu bölümde

  • Master netdev = CPU portuna bağlı MAC arayüzü (eth0)
  • Slave netdev'ler = her switch portuna karşılık gelen sanal arayüzler (lan1, wan…)
  • RX: DSA etiketi çözülerek skb doğru slave arayüze yönlendirilir

02 dsa_switch_ops — temel callback'ler

dsa_switch_ops, switch chip sürücüsünün DSA çerçevesine sunduğu işlev tablosudur. Tüm alanları uygulamak zorunlu değildir; kritik olanlar aşağıda ele alınmıştır.

Zorunlu callback'ler

c
static const struct dsa_switch_ops myswitch_ops = {
    .get_tag_protocol  = myswitch_get_tag_protocol,
    .setup             = myswitch_setup,
    .port_enable       = myswitch_port_enable,
    .port_disable      = myswitch_port_disable,
    .phylink_get_caps  = myswitch_phylink_get_caps,
};

/* Hangi DSA etiket protokolünü kullanıyoruz */
static enum dsa_tag_protocol
myswitch_get_tag_protocol(struct dsa_switch *ds, int port,
                           enum dsa_tag_protocol mp)
{
    return DSA_TAG_PROTO_MTK;   /* veya _EDSA, _RTL8_4 … */
}

/* Switch ilk kurulum */
static int myswitch_setup(struct dsa_switch *ds)
{
    int port, ret;

    /* Global reset */
    ret = myswitch_global_reset(ds);
    if (ret)
        return ret;

    /* Her port için bağımsız VLAN, STP durumu başlangıç ayarı */
    for (port = 0; port < ds->num_ports; port++) {
        if (dsa_is_unused_port(ds, port))
            continue;
        myswitch_port_init(ds, port);
    }
    return 0;
}

Bridge entegrasyon callback'leri

c
/* Port bir Linux bridge'e eklendiğinde */
static int myswitch_port_bridge_join(struct dsa_switch *ds, int port,
                                      struct dsa_bridge bridge,
                                      bool *tx_fwd_offload,
                                      struct netlink_ext_ack *extack)
{
    /* Donanımda portlar arası anahtarlamayı etkinleştir */
    myswitch_set_port_bridge_member(ds, port, bridge.num);
    *tx_fwd_offload = true;   /* donanım TX yönlendirmesi yapılabilir */
    return 0;
}

/* Port bridge'den çıkarıldığında */
static void myswitch_port_bridge_leave(struct dsa_switch *ds, int port,
                                        struct dsa_bridge bridge)
{
    myswitch_clear_port_bridge_member(ds, port);
}

/* VLAN ekleme */
static int myswitch_port_vlan_add(struct dsa_switch *ds, int port,
                                   const struct switchdev_obj_port_vlan *vlan,
                                   struct netlink_ext_ack *extack)
{
    bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
    bool pvid     = vlan->flags & BRIDGE_VLAN_INFO_PVID;

    myswitch_hw_vlan_add(ds, port, vlan->vid, untagged, pvid);
    return 0;
}

/* VLAN silme */
static int myswitch_port_vlan_del(struct dsa_switch *ds, int port,
                                   const struct switchdev_obj_port_vlan *vlan)
{
    myswitch_hw_vlan_del(ds, port, vlan->vid);
    return 0;
}

FDB (Forwarding Database) callback'leri

c
/* Statik FDB girdisi ekle */
static int myswitch_port_fdb_add(struct dsa_switch *ds, int port,
                                  const unsigned char *addr, u16 vid,
                                  struct db_info *db)
{
    return myswitch_hw_fdb_insert(ds, port, addr, vid);
}

/* FDB gezinti — bridge fdb show için */
static int myswitch_port_fdb_dump(struct dsa_switch *ds, int port,
                                   dsa_fdb_dump_cb_t *cb, void *data)
{
    struct myswitch_fdb_entry entry;
    int bucket, i, ret;

    for (bucket = 0; bucket < MY_FDB_BUCKETS; bucket++) {
        ret = myswitch_read_fdb(ds, bucket, &entry);
        if (ret)
            continue;
        if (entry.port == port)
            cb(entry.addr, entry.vid, entry.is_static, data);
    }
    return 0;
}

Bu bölümde

  • get_tag_protocol ve setup zorunludur; diğerleri isteğe bağlı
  • port_bridge_join → donanım port gruplamasını etkinleştirir
  • port_vlan_add/port_vlan_del VLAN aware mod için gereklidir

03 Device Tree DSA binding

DSA switch'i tanımlamak için cihaz ağacında standart bir bağlama yapısı kullanılır. Bu yapı, CPU portunu, switch portlarını ve bağlı PHY'leri sisteme bildirir.

Temel DSA Device Tree yapısı

dts
/* MAC (CPU port) */
&gmac0 {
    status = "okay";
    phy-mode = "rgmii-id";
    fixed-link {
        speed = <1000>;
        full-duplex;
    };
};

/* Switch chip — MDIO üzerinden erişim */
&mdio {
    switch0: ethernet-switch@0 {
        compatible = "mediatek,mt7530";
        reg = <0>;               /* MDIO adres */
        reset-gpios = <&gpio 10 GPIO_ACTIVE_LOW>;

        ports {
            #address-cells = <1>;
            #size-cells = <0>;

            /* LAN portları */
            port@0 {
                reg = <0>;
                label = "lan1";
            };
            port@1 {
                reg = <1>;
                label = "lan2";
            };
            port@2 {
                reg = <2>;
                label = "lan3";
            };
            port@3 {
                reg = <3>;
                label = "lan4";
            };

            /* WAN portu — ayrı phy */
            port@4 {
                reg = <4>;
                label = "wan";
            };

            /* CPU port — master netdev'e bağlı */
            port@6 {
                reg = <6>;
                ethernet = <&gmac0>;  /* CPU netdev */
                phy-mode = "rgmii-id";
                fixed-link {
                    speed = <1000>;
                    full-duplex;
                };
            };
        };
    };
};

Dahili PHY'leri olan switch

MT7530 gibi chipset'lerde her porta entegre PHY vardır. Bu durumda cihaz ağacına PHY referansı eklenir:

dts
port@0 {
    reg = <0>;
    label = "lan1";
    phy-handle = <&switch0phy0>;   /* dahili PHY referansı */
};

/* Switch dahili MDIO bus */
mdio {
    #address-cells = <1>;
    #size-cells = <0>;

    switch0phy0: ethernet-phy@0 {
        reg = <0>;
    };
    switch0phy1: ethernet-phy@1 {
        reg = <1>;
    };
    /* ... */
};

Çok-chip (daisy-chain) topoloji

dts
/* Switch 0 — CPU'ya bağlı */
switch0: ethernet-switch@0 {
    /* ... */
    ports {
        port@5 {
            reg = <5>;
            label = "dsa";    /* cascade port, bir sonraki switch'e */
            link = <&switch1p0>;
        };
        /* CPU port @6 ... */
    };
};

/* Switch 1 — switch 0'a cascade */
switch1: ethernet-switch@1 {
    /* ... */
    ports {
        switch1p0: port@0 {
            reg = <0>;
            ethernet = <&switch0port5>;
        };
        port@1 { reg = <1>; label = "lan5"; };
        port@2 { reg = <2>; label = "lan6"; };
    };
};

Bu bölümde

  • CPU portu ethernet phandle ile MAC'e bağlanır
  • LAN/WAN portlarına label değeri, netdev ismine dönüşür
  • Dahili PHY'ler switch'in kendi mdio alt düğümünde tanımlanır

04 VLAN aware mod

DSA ile VLAN aware köprüleme, donanım switch içindeki VLAN tablosunu Linux bridge VLAN API'sine bağlar. Tagged/untagged üyelik, PVID ve VID atanması adım adım açıklanmaktadır.

VLAN aware bridge oluşturma

bash
# VLAN aware bridge oluştur
ip link add name br0 type bridge vlan_filtering 1
ip link set br0 up

# Switch portlarını bridge'e ekle
ip link set lan1 master br0
ip link set lan2 master br0
ip link set lan3 master br0
ip link set wan  master br0

# Portları etkinleştir
ip link set lan1 up
ip link set lan2 up
ip link set lan3 up
ip link set wan  up

VLAN üyeliği ayarlama

bash
# Mevcut VLAN yapılandırmasını sıfırla (default VID 1'i kaldır)
bridge vlan del dev lan1 vid 1
bridge vlan del dev lan2 vid 1
bridge vlan del dev lan3 vid 1

# LAN portlarını VLAN 10'a untagged + PVID olarak ekle
bridge vlan add dev lan1 vid 10 pvid untagged
bridge vlan add dev lan2 vid 10 pvid untagged
bridge vlan add dev lan3 vid 10 pvid untagged

# WAN portunu VLAN 20'ye tagged üye yap
bridge vlan add dev wan vid 20

# CPU portunu (br0) her iki VLAN'a ekle
bridge vlan add dev br0 vid 10 self
bridge vlan add dev br0 vid 20 self

# Yapılandırmayı doğrula
bridge vlan show

Donanım offload doğrulama

DSA VLAN offload gerçekleştiğinde bridge vlan show çıktısında offloaded bayrağı görünür:

bash
# Örnek çıktı
bridge vlan show
port    vlan ids
lan1     10 PVID Egress Untagged offloaded
lan2     10 PVID Egress Untagged offloaded
lan3     10 PVID Egress Untagged offloaded
wan      20 offloaded
br0      10
         20

VLAN ve FDB ilişkisi

PVID (Port VLAN ID)Etiketlenmemiş gelen pakete atanan VLAN kimliği; genellikle erişim (access) portu için
Egress UntaggedBu VLAN paketleri çıkarken etiket soyulur; erişim portlarında zorunlu
Tagged üyelikPaket VLAN etiketi ile iletilir; trunk portlarında kullanılır
VID 0VLAN-unaware mode'da kullanılan VID; donanımda özel anlam taşır

Bu bölümde

  • vlan_filtering 1 ile bridge oluşturulmalı — aksi hâlde VLAN göz ardı edilir
  • bridge vlan add dev PORT vid VID pvid untagged → erişim portu yapılandırması
  • Donanım offload gerçekleşmişse bridge vlan show çıktısında offloaded görünür

05 STP ve bridge entegrasyonu

DSA slave portları standart Linux bridge ile birlikte kullanıldığında, STP (Spanning Tree Protocol) ve RSTP protokolleri donanıma offload edilebilir.

STP durumları ve DSA

Linux bridge STP'yi etkinleştirdiğinde, her port BLOCKING → LISTENING → LEARNING → FORWARDING geçişini yapar. DSA sürücüsü bu durumları switch donanımına yansıtmak için port_stp_state_set callback'ini uygular.

c
static void myswitch_port_stp_state_set(struct dsa_switch *ds, int port,
                                          u8 state)
{
    u16 hw_state;

    switch (state) {
    case BR_STATE_DISABLED:
    case BR_STATE_BLOCKING:
        hw_state = MY_PORT_STATE_BLOCKING;
        break;
    case BR_STATE_LISTENING:
        hw_state = MY_PORT_STATE_LISTENING;
        break;
    case BR_STATE_LEARNING:
        hw_state = MY_PORT_STATE_LEARNING;
        break;
    case BR_STATE_FORWARDING:
    default:
        hw_state = MY_PORT_STATE_FORWARDING;
        break;
    }

    myswitch_write_port_state(ds, port, hw_state);
}

Kullanıcı alanında STP etkinleştirme

bash
# STP ile bridge oluştur
ip link add name br0 type bridge vlan_filtering 1 stp_state 1
ip link set br0 up

# STP öncelik ayarı (root bridge için düşük değer)
ip link set br0 type bridge priority 4096

# Port path cost
ip link set lan1 type bridge_slave cost 4

# STP durumunu görüntüle
ip -d link show br0
bridge link show

# Per-port STP durumu
bridge link show dev lan1

RSTP — 802.1w desteği

Daha hızlı yakınsama için RSTP, mstpd arka plan süreci ile kullanılır. mstpd, bridge'e doğrudan STP durumlarını NETLINK üzerinden yazar:

bash
# mstpd'yi kur ve başlat
apt-get install mstpd    # veya Yocto'da IMAGE_INSTALL += "mstpd"
mstpd

# Bridge'i RSTP moduna al
mstpctl setforcevers br0 rstp

# RSTP durumunu izle
mstpctl showbridge br0
mstpctl showport br0 lan1

Multicast — MDB offload

bash
# Multicast snooping etkinleştir
ip link set br0 type bridge mcast_snooping 1
ip link set br0 type bridge mcast_querier 1

# MDB (Multicast Database) izle
bridge mdb show dev br0

# Statik MDB girdisi ekle
bridge mdb add dev br0 port lan1 grp 239.255.0.1 permanent vid 10

Bu bölümde

  • port_stp_state_set callback STP durumlarını donanıma yansıtır
  • mstpd ile RSTP yakınsama süresi STP'ye göre çok daha kısadır
  • Multicast snooping MDB callback'leriyle donanıma offload edilebilir

06 Port mirroring ve trafik izleme

DSA çerçevesi, switch donanımının port mirroring özelliğini tc mirred eylemi ve port_mirror_add callback'i aracılığıyla kullanıcı alanına sunar.

Donanım port mirroring callback

c
/* Kaynak portu hedef porta yansıt */
static int myswitch_port_mirror_add(struct dsa_switch *ds, int port,
                                     struct dsa_mall_mirror_tc_entry *mirror,
                                     bool ingress,
                                     struct netlink_ext_ack *extack)
{
    int monitor_port = mirror->to_local_port;

    if (ingress)
        myswitch_set_ingress_mirror(ds, port, monitor_port);
    else
        myswitch_set_egress_mirror(ds, port, monitor_port);

    return 0;
}

static void myswitch_port_mirror_del(struct dsa_switch *ds, int port,
                                      struct dsa_mall_mirror_tc_entry *mirror)
{
    myswitch_clear_mirror(ds, port);
}

tc ile port mirroring kullanımı

bash
# lan1 ingress trafiğini lan3'e yansıt (analiz için)
tc qdisc add dev lan1 handle ffff: ingress

tc filter add dev lan1 parent ffff: \
    protocol all u32 match u32 0 0 \
    action mirred egress mirror dev lan3

# Egress mirroring
tc qdisc add dev lan1 handle 1: root prio
tc filter add dev lan1 parent 1: \
    protocol all u32 match u32 0 0 \
    action mirred egress mirror dev lan3

# Mirroring kaldır
tc qdisc del dev lan1 handle ffff: ingress

# Aktif tc filter'ları listele
tc filter show dev lan1 ingress

tcpdump ile analiz

bash
# Yansıma portunda trafik yakala
tcpdump -i lan3 -n -e -v

# Sadece belirli protokol
tcpdump -i lan3 arp or icmp

# Dosyaya kaydet, Wireshark ile analiz
tcpdump -i lan3 -w /tmp/capture.pcap

devlink health reporter

bash
# Switch devlink aygıtını bul
devlink dev show

# Port istatistikleri
devlink port show

# Health reporter listesi
devlink health show

Bu bölümde

  • port_mirror_add/port_mirror_del callback'leri donanım yansıtma yönetir
  • Kullanıcı alanında tc mirred egress mirror ile yapılandırılır
  • Yansıtma portuna bağlı tcpdump ile gerçek zamanlı analiz yapılabilir

07 mv88e6xxx ve MT7530 gerçek dünya yapılandırması

Marvell 88E6xxx serisi ve MediaTek MT7530, açık kaynak DSA sürücüleriyle en geniş destek bulan switch ailesidir. Bu bölümde gerçek ürün yapılandırma örnekleri verilmektedir.

Marvell 88E6xxx — OpenWrt tipik konfigürasyon

dts
/* Marvell 88E6176 — 7 portlu Gigabit switch */
&mdio {
    switch0: ethernet-switch@0 {
        compatible = "marvell,mv88e6085";
        reg = <0>;

        reset-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
        reset-assert-us = <10000>;
        reset-deassert-us = <10000>;

        dsa,member = <0 0>;    /* çok-chip: 0. ağaç, 0. switch */

        ports {
            #address-cells = <1>;
            #size-cells = <0>;

            port@0 { reg = <0>; label = "lan1"; };
            port@1 { reg = <1>; label = "lan2"; };
            port@2 { reg = <2>; label = "lan3"; };
            port@3 { reg = <3>; label = "lan4"; };
            port@4 { reg = <4>; label = "wan"; };
            port@5 {
                reg = <5>;
                label = "cpu";
                ethernet = <&gmac0>;
                phy-mode = "rgmii-id";
                fixed-link {
                    speed = <1000>;
                    full-duplex;
                };
            };
        };
    };
};

MediaTek MT7530 — çok yaygın kullanım

dts
/* MT7530 — bağımsız switch (MT7621 SoC entegre değil) */
&mdio0 {
    switch@1f {
        compatible = "mediatek,mt7530";
        reg = <0x1f>;     /* MT7530 MDIO adresi sabit 0x1f */

        reset-gpios = <&gpio 2 GPIO_ACTIVE_LOW>;

        ports {
            #address-cells = <1>;
            #size-cells = <0>;

            port@0 { reg = <0>; label = "lan1"; };
            port@1 { reg = <1>; label = "lan2"; };
            port@2 { reg = <2>; label = "lan3"; };
            port@3 { reg = <3>; label = "lan4"; };
            port@4 { reg = <4>; label = "wan"; };

            /* CPU port — RGMII, genellikle port 6 */
            port@6 {
                reg = <6>;
                ethernet = <&eth0>;
                phy-mode = "rgmii";
                fixed-link {
                    speed = <1000>;
                    full-duplex;
                    pause;
                };
            };
        };
    };
};

Realtek RTL8370 — SPI erişimli switch

dts
/* RTL8370 SPI ile bağlı */
&spi0 {
    switch@0 {
        compatible = "realtek,rtl8370b";
        reg = <0>;
        spi-max-frequency = <1000000>;

        ports {
            #address-cells = <1>;
            #size-cells = <0>;

            port@0 { reg = <0>; label = "lan1"; };
            port@1 { reg = <1>; label = "lan2"; };
            port@2 { reg = <2>; label = "lan3"; };
            port@3 { reg = <3>; label = "lan4"; };
            port@4 { reg = <4>; label = "wan"; };
            port@9 {
                reg = <9>;    /* RTL837x CPU port */
                ethernet = <&gmac0>;
                phy-mode = "rgmii";
                fixed-link { speed = <1000>; full-duplex; };
            };
        };
    };
};

Sürücü yapılandırma seçenekleri

Kconfig seçeneğiSürücüChipset
CONFIG_NET_DSA_MV88E6XXXmv88e6xxxMarvell 88E6xxx ailesi
CONFIG_NET_DSA_MT7530mt7530MediaTek MT7530, MT7531, MT7621 entegre
CONFIG_NET_DSA_REALTEKrealtek-smi/mdioRealtek RTL8366, RTL8370, RTL838x
CONFIG_NET_DSA_SJA1105sja1105NXP SJA1105 (automotive)
CONFIG_NET_DSA_MICROCHIP_KSZkszMicrochip KSZ8xxx, KSZ9xxx

Bu bölümde

  • mv88e6xxx: marvell,mv88e6085 compatible — tüm 88E6xxx ailesi için
  • MT7530 MDIO adresi 0x1f'ye sabitlenmiştir, reset GPIO zorunludur
  • RTL8370 SPI üzerinden erişilir; sürücü CONFIG_NET_DSA_REALTEK ile etkinleşir

08 Hata ayıklama

DSA sorunlarını teşhis etmek için devlink, ethtool, bridge araçları ve kernel debugfs birlikte kullanılır.

devlink ile switch bilgisi

bash
# Sistemdeki switch aygıtları
devlink dev show

# Switch portlarını listele
devlink port show

# Belirli port bilgisi
devlink port show pci/0000:00:00.0/1

# Switch bilgi (chip türü, firmware)
devlink dev info pci/0000:00:00.0

# Donanım istatistikleri
devlink port show -s pci/0000:00:00.0

ethtool ile PHY istatistikleri

bash
# Switch slave port istatistikleri
ethtool -S lan1

# Örnek çıktı:
#  rx_packets: 1234
#  tx_packets: 987
#  rx_errors: 0
#  tx_errors: 0
#  rx_crc_errors: 0

# PHY istatistikleri (dahili PHY'ler)
ethtool --phy-statistics lan1

# Link durumu
ethtool lan1

bridge araçları ile FDB ve VLAN denetimi

bash
# Forwarding Database — öğrenilmiş MAC adresleri
bridge fdb show dev lan1
bridge fdb show br br0

# Tüm arayüzlerdeki FDB
bridge fdb show

# VLAN üyeliği
bridge vlan show

# MDB (multicast database)
bridge mdb show dev br0

# Port bağlantı bilgisi
bridge link show

Kernel log ve dynamic debug

bash
# DSA ve switch sürücüsü log
dmesg | grep -iE "dsa|mv88e6|mt7530|rtl|switch"

# Verbose log etkinleştir
echo "module dsa_core +p" > /sys/kernel/debug/dynamic_debug/control
echo "module mv88e6xxx +p" > /sys/kernel/debug/dynamic_debug/control
echo "module mt7530 +p" > /sys/kernel/debug/dynamic_debug/control

# DSA notifier trace (gelişmiş)
echo 1 > /sys/kernel/debug/tracing/events/net/enable

Yaygın sorunlar

BelirtiOlası NedenÇözüm
Slave netdev'ler görünmüyorDSA sürücüsü yüklenmemiş veya DT binding hatasıdmesg'de DSA hatalarını kontrol et, CONFIG_NET_DSA etkin mi?
Portlar arası trafik yokBridge kurulmamış veya VLAN yapılandırma hatasıbridge fdb show, bridge vlan show çıktılarını kontrol et
offloaded bayrağı görünmüyorport_vlan_add callback uygulanmamışSürücü dsa_switch_ops'ta bu callback'i sağlamalı
CPU port üzerinden trafik geçmiyorDSA etiketi protokol uyumsuzluğuget_tag_protocol doğru protokolü döndürmeli
Reset sonrası switch kayboldureset-deassert-us çok kısaDT'de reset zamanlama değerlerini artır

Bu bölümde

  • devlink dev info switch yonga bilgisi ve firmware versiyonu verir
  • bridge fdb show öğrenilmiş MAC adreslerini; bridge vlan show VLAN üyeliğini gösterir
  • dynamic_debug ile dsa_core ve chip sürücülerinde ayrıntılı log alınabilir