Microchip-Ethernet / EVB-KSZ9477

Repository for using Microchip EVB-KSZ9477 board. Product Supported: KSZ9477, KSZ9567, KSZ9897, KSZ9896, KSZ8567, KSZ8565, KSZ9893, KSZ9563, KSZ8563, LAN9646, Phys(KSZ9031/9131, LAN8770
76 stars 78 forks source link

KSZ8462/8441 packet receive hangup #72

Open aoleg94 opened 3 years ago

aoleg94 commented 3 years ago

Hello, I have experienced a problem with KSZ8462: packet receive stalls when there is a specific traffic pattern - periodic short packet burst. Packets are 90 bytes long (NTP), packet burst length is around 300-500 packets. RXFC register reports 0 new packets; though clearing hardware RX buffer allows KSZ chip to continue functioning properly.

sushinori commented 2 years ago

Hi. I think I am seeing a similar issue on ksz8462: if I do not limit the egress data rate on the CPU port 3 and I am sending bursts of data I first see CRC errors reported in ks_rcv(), which is either called by ks_irq() or rx_proc_task() of the reference linux driver. After all corrupt rx frames are cleared using RRXEF (bit 0) in RXQCR the ksz8462 stops sending interrupts (both rx and tx). I only can re-enable the interrupts by doing ifdown/ifup on the corresponding Linux network interface. It looks to me that packet bursts seem to corrupt the RX queue to the extend that it has to be reinitialised.

@aoleg94 can you describe in more detail how you cleared the hardware RX buffer?

aoleg94 commented 2 years ago

By flushing RX buffer: RXCR1.FRXQ Flush Receive Queue

static void ks_rx_reset(struct work_struct *work)
{
    struct dev_info *ks = container_of(work, struct dev_info, rx_reset);
    struct ksz_hw *hw = &ks->hw;

    dev_warn(&ks->pdev->dev, "rx timeout, flush rx buffer\n");

    mutex_lock(&ks->lock);

    ks_stop_rx(hw);

    ks_wrreg16(hw, KS_RXCR1, (hw->rc_rxcr1 | RXCR1_FRXQ));
    udelay(1);
    ks_wrreg16(hw, KS_RXCR1, hw->rc_rxcr1);

    if (hw->enabled)
        ks_start_rx(hw);

    ks->rx_flushed = 1;

    mutex_unlock(&ks->lock);
}