Page MenuHomeFreeBSD

D19798.id55739.diff
No OneTemporary

D19798.id55739.diff

Index: sys/dev/cadence/if_cgem.c
===================================================================
--- sys/dev/cadence/if_cgem.c
+++ sys/dev/cadence/if_cgem.c
@@ -98,6 +98,12 @@
#define CGEM_CKSUM_ASSIST (CSUM_IP | CSUM_TCP | CSUM_UDP | \
CSUM_TCP_IPV6 | CSUM_UDP_IPV6)
+static struct ofw_compat_data compat_data[] = {
+ { "cadence,gem", 1 },
+ { "cdns,macb", 1 },
+ { NULL, 0 },
+};
+
struct cgem_softc {
if_t ifp;
struct mtx sc_mtx;
@@ -112,6 +118,7 @@
uint32_t net_ctl_shadow;
int ref_clk_num;
u_char eaddr[6];
+ uint32_t istatus;
bus_dma_tag_t desc_dma_tag;
bus_dma_tag_t mbuf_dma_tag;
@@ -926,48 +933,58 @@
callout_reset(&sc->tick_ch, hz, cgem_tick, sc);
}
+static int
+cgem_filter_intr(void *arg)
+{
+ struct cgem_softc *sc;
+
+ sc = (struct cgem_softc *)arg;
+
+ /* Read interrupt status and immediately clear the bits. */
+ sc->istatus = RD4(sc, CGEM_INTR_STAT);
+ WR4(sc, CGEM_INTR_STAT, sc->istatus);
+
+ /* Disable interrupts. */
+ WR4(sc, CGEM_INTR_DIS, CGEM_INTR_ALL);
+
+ return (FILTER_SCHEDULE_THREAD);
+}
+
/* Interrupt handler. */
static void
cgem_intr(void *arg)
{
struct cgem_softc *sc = (struct cgem_softc *)arg;
if_t ifp = sc->ifp;
- uint32_t istatus;
CGEM_LOCK(sc);
- if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0) {
- CGEM_UNLOCK(sc);
- return;
- }
-
- /* Read interrupt status and immediately clear the bits. */
- istatus = RD4(sc, CGEM_INTR_STAT);
- WR4(sc, CGEM_INTR_STAT, istatus);
+ if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0)
+ goto finish;
/* Packets received. */
- if ((istatus & CGEM_INTR_RX_COMPLETE) != 0)
+ if ((sc->istatus & CGEM_INTR_RX_COMPLETE) != 0)
cgem_recv(sc);
/* Free up any completed transmit buffers. */
cgem_clean_tx(sc);
/* Hresp not ok. Something is very bad with DMA. Try to clear. */
- if ((istatus & CGEM_INTR_HRESP_NOT_OK) != 0) {
+ if ((sc->istatus & CGEM_INTR_HRESP_NOT_OK) != 0) {
device_printf(sc->dev, "cgem_intr: hresp not okay! "
"rx_status=0x%x\n", RD4(sc, CGEM_RX_STAT));
WR4(sc, CGEM_RX_STAT, CGEM_RX_STAT_HRESP_NOT_OK);
}
/* Receiver overrun. */
- if ((istatus & CGEM_INTR_RX_OVERRUN) != 0) {
+ if ((sc->istatus & CGEM_INTR_RX_OVERRUN) != 0) {
/* Clear status bit. */
WR4(sc, CGEM_RX_STAT, CGEM_RX_STAT_OVERRUN);
sc->rxoverruns++;
}
/* Receiver ran out of bufs. */
- if ((istatus & CGEM_INTR_RX_USED_READ) != 0) {
+ if ((sc->istatus & CGEM_INTR_RX_USED_READ) != 0) {
WR4(sc, CGEM_NET_CTRL, sc->net_ctl_shadow |
CGEM_NET_CTRL_FLUSH_DPRAM_PKT);
cgem_fill_rqueue(sc);
@@ -978,7 +995,14 @@
if (!if_sendq_empty(ifp))
cgem_start_locked(ifp);
+finish:
CGEM_UNLOCK(sc);
+
+ /* Restore interrupts. */
+ WR4(sc, CGEM_INTR_EN,
+ CGEM_INTR_RX_COMPLETE | CGEM_INTR_RX_OVERRUN |
+ CGEM_INTR_TX_USED_READ | CGEM_INTR_RX_USED_READ |
+ CGEM_INTR_HRESP_NOT_OK);
}
/* Reset hardware. */
@@ -1635,7 +1659,7 @@
if (!ofw_bus_status_okay(dev))
return (ENXIO);
- if (!ofw_bus_is_compatible(dev, "cadence,gem"))
+ if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
return (ENXIO);
device_set_desc(dev, "Cadence CGEM Gigabit Ethernet Interface");
@@ -1739,7 +1763,7 @@
ether_ifattach(ifp, eaddr);
err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE |
- INTR_EXCL, NULL, cgem_intr, sc, &sc->intrhand);
+ INTR_EXCL, cgem_filter_intr, cgem_intr, sc, &sc->intrhand);
if (err) {
device_printf(dev, "could not set interrupt handler.\n");
ether_ifdetach(ifp);

File Metadata

Mime Type
text/plain
Expires
Mon, Mar 9, 1:01 AM (20 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29426244
Default Alt Text
D19798.id55739.diff (3 KB)

Event Timeline