Page MenuHomeFreeBSD

D59295.id185525.diff
No OneTemporary

D59295.id185525.diff

diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c
--- a/sys/dev/alc/if_alc.c
+++ b/sys/dev/alc/if_alc.c
@@ -1573,6 +1573,10 @@
CSR_READ_4(sc, ALC_SRAM_TX_FIFO_LEN) * 8,
CSR_READ_4(sc, ALC_SRAM_RX_FIFO_LEN) * 8);
+ sc->alc_intrs = ALC_INTRS;
+ if ((sc->alc_flags & ALC_FLAG_MT) != 0)
+ sc->alc_intrs = ALC_MT_INTRS;
+
/* Initialize DMA parameters. */
sc->alc_dma_rd_burst = 0;
sc->alc_dma_wr_burst = 0;
@@ -3434,7 +3438,7 @@
}
status = CSR_READ_4(sc, ALC_INTR_STATUS);
- if ((status & ALC_INTRS) == 0)
+ if ((status & sc->alc_intrs) == 0)
return (FILTER_STRAY);
/* Disable interrupts. */
CSR_WRITE_4(sc, ALC_INTR_STATUS, INTR_DIS_INT);
@@ -3460,14 +3464,21 @@
sc->alc_morework = 0;
status |= INTR_RX_PKT;
}
- if ((status & ALC_INTRS) == 0)
+ if ((status & sc->alc_intrs) == 0)
goto done;
/* Acknowledge interrupts but still disable interrupts. */
- CSR_WRITE_4(sc, ALC_INTR_STATUS, status | INTR_DIS_INT);
+ CSR_WRITE_4(sc, ALC_INTR_STATUS,
+ (status & sc->alc_intrs) | INTR_DIS_INT);
more = 0;
if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) != 0) {
+ if ((sc->alc_flags & ALC_FLAG_MT) != 0 &&
+ (status & ALC_MT_LINK_INTRS) != 0 &&
+ alc_mt_link_check(sc) != 0) {
+ ALC_UNLOCK(sc);
+ return;
+ }
if ((status & INTR_RX_PKT) != 0) {
more = alc_rxintr(sc, sc->alc_process_limit);
if (more == EAGAIN)
@@ -3500,8 +3511,12 @@
alc_start_locked(ifp);
}
- if (more == EAGAIN ||
- (CSR_READ_4(sc, ALC_INTR_STATUS) & ALC_INTRS) != 0) {
+ /*
+ * On the Mikrotik card, if we kept the acknowledgement written above,
+ * we have not raised anything new, and rescheduling would never end.
+ */
+ if (more == EAGAIN || ((sc->alc_flags & ALC_FLAG_MT) == 0 &&
+ (CSR_READ_4(sc, ALC_INTR_STATUS) & sc->alc_intrs) != 0)) {
ALC_UNLOCK(sc);
taskqueue_enqueue(sc->alc_tq, &sc->alc_int_task);
return;
@@ -4391,7 +4406,7 @@
alc_rxvlan(sc);
/* Acknowledge all pending interrupts and clear it. */
- CSR_WRITE_4(sc, ALC_INTR_MASK, ALC_INTRS);
+ CSR_WRITE_4(sc, ALC_INTR_MASK, sc->alc_intrs);
CSR_WRITE_4(sc, ALC_INTR_STATUS, 0xFFFFFFFF);
CSR_WRITE_4(sc, ALC_INTR_STATUS, 0);
diff --git a/sys/dev/alc/if_alcreg.h b/sys/dev/alc/if_alcreg.h
--- a/sys/dev/alc/if_alcreg.h
+++ b/sys/dev/alc/if_alcreg.h
@@ -840,6 +840,13 @@
INTR_RX_FIFO_OFLOW | INTR_RD_UNDERRUN | \
INTR_TX_FIFO_UNDERRUN)
+/* The Mikrotik NIC reports link state changes with these. */
+#define ALC_MT_LINK_INTRS \
+ (INTR_GPHY | INTR_GPHY_LOW_PW | INTR_PHY_LINK_DOWN)
+
+#define ALC_MT_INTRS \
+ (ALC_INTRS | ALC_MT_LINK_INTRS)
+
#define ALC_INTR_RETRIG_TIMER 0x1608
#define INTR_RETRIG_TIMER_MASK 0x0000FFFF
#define INTR_RETRIG_TIMER_SHIFT 0
diff --git a/sys/dev/alc/if_alcvar.h b/sys/dev/alc/if_alcvar.h
--- a/sys/dev/alc/if_alcvar.h
+++ b/sys/dev/alc/if_alcvar.h
@@ -238,6 +238,7 @@
#define ALC_FLAG_LINK 0x10000
#define ALC_FLAG_MT 0x20000
+ uint32_t alc_intrs;
/* Media state of controllers that have no PHY. */
struct ifmedia alc_ifmedia;
uint32_t alc_mt_speed;

File Metadata

Mime Type
text/plain
Expires
Thu, Sep 10, 12:18 AM (8 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38469885
Default Alt Text
D59295.id185525.diff (2 KB)

Event Timeline