summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/smc
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-10-07 15:10:20 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-01-10 09:53:31 +0100
commitc40e45b75eb76d79a05c7fa85c1fa9b5c728a12f (patch)
treead4f2519067709f00ab98b3c591186c26dc3a21f /freebsd/sys/dev/smc
parentuserspace-header-gen.py: Simplify program ports (diff)
downloadrtems-libbsd-c40e45b75eb76d79a05c7fa85c1fa9b5c728a12f.tar.bz2
Update to FreeBSD head 2016-08-23
Git mirror commit 9fe7c416e6abb28b1398fd3e5687099846800cfd.
Diffstat (limited to 'freebsd/sys/dev/smc')
-rw-r--r--freebsd/sys/dev/smc/if_smc.c88
1 files changed, 52 insertions, 36 deletions
diff --git a/freebsd/sys/dev/smc/if_smc.c b/freebsd/sys/dev/smc/if_smc.c
index 8d3740cc..37f89a51 100644
--- a/freebsd/sys/dev/smc/if_smc.c
+++ b/freebsd/sys/dev/smc/if_smc.c
@@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
#include <net/ethernet.h>
#include <net/if.h>
+#include <net/if_var.h>
#include <net/if_arp.h>
#include <net/if_dl.h>
#include <net/if_types.h>
@@ -235,7 +236,7 @@ smc_probe(device_t dev)
if (sc->smc_usemem)
type = SYS_RES_MEMORY;
- reg = bus_alloc_resource(dev, type, &rid, 0, ~0, 16, RF_ACTIVE);
+ reg = bus_alloc_resource_anywhere(dev, type, &rid, 16, RF_ACTIVE);
if (reg == NULL) {
if (bootverbose)
device_printf(dev,
@@ -329,15 +330,15 @@ smc_attach(device_t dev)
type = SYS_RES_MEMORY;
sc->smc_reg_rid = 0;
- sc->smc_reg = bus_alloc_resource(dev, type, &sc->smc_reg_rid, 0, ~0,
+ sc->smc_reg = bus_alloc_resource_anywhere(dev, type, &sc->smc_reg_rid,
16, RF_ACTIVE);
if (sc->smc_reg == NULL) {
error = ENXIO;
goto done;
}
- sc->smc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->smc_irq_rid, 0,
- ~0, 1, RF_ACTIVE | RF_SHAREABLE);
+ sc->smc_irq = bus_alloc_resource_anywhere(dev, SYS_RES_IRQ,
+ &sc->smc_irq_rid, 1, RF_ACTIVE | RF_SHAREABLE);
if (sc->smc_irq == NULL) {
error = ENXIO;
goto done;
@@ -513,7 +514,7 @@ smc_start_locked(struct ifnet *ifp)
len += (len & 1);
if (len > ETHER_MAX_LEN - ETHER_CRC_LEN) {
if_printf(ifp, "large packet discarded\n");
- ++ifp->if_oerrors;
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
m_freem(m);
return; /* XXX readcheck? */
}
@@ -528,7 +529,7 @@ smc_start_locked(struct ifnet *ifp)
* Work out how many 256 byte "pages" we need. We have to include the
* control data for the packet in this calculation.
*/
- npages = (len * PKT_CTRL_DATA_LEN) >> 8;
+ npages = (len + PKT_CTRL_DATA_LEN) >> 8;
if (npages == 0)
npages = 1;
@@ -561,7 +562,7 @@ smc_start_locked(struct ifnet *ifp)
return;
}
- taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_tx);
+ taskqueue_enqueue(sc->smc_tq, &sc->smc_tx);
}
static void
@@ -599,7 +600,7 @@ smc_task_tx(void *context, int pending)
*/
if (packet & ARR_FAILED) {
IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ++ifp->if_oerrors;
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
smc_start_locked(ifp);
SMC_UNLOCK(sc);
@@ -656,7 +657,7 @@ smc_task_tx(void *context, int pending)
/*
* Finish up.
*/
- ifp->if_opackets++;
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
SMC_UNLOCK(sc);
BPF_MTAP(ifp, m0);
@@ -694,8 +695,7 @@ smc_task_rx(void *context, int pending)
if (m == NULL) {
break;
}
- MCLGET(m, M_NOWAIT);
- if ((m->m_flags & M_EXT) == 0) {
+ if (!(MCLGET(m, M_NOWAIT))) {
m_freem(m);
break;
}
@@ -722,7 +722,7 @@ smc_task_rx(void *context, int pending)
if (status & (RX_TOOSHORT | RX_TOOLNG | RX_BADCRC | RX_ALGNERR)) {
smc_mmu_wait(sc);
smc_write_2(sc, MMUCR, MMUCR_CMD_RELEASE);
- ifp->if_ierrors++;
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
m_freem(m);
break;
}
@@ -778,7 +778,7 @@ smc_task_rx(void *context, int pending)
m = mhead;
mhead = mhead->m_next;
m->m_next = NULL;
- ifp->if_ipackets++;
+ if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
(*ifp->if_input)(ifp, m);
}
}
@@ -799,7 +799,7 @@ smc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
SMC_UNLOCK(sc);
if (cmd == POLL_AND_CHECK_STATUS)
- taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_intr);
+ taskqueue_enqueue(sc->smc_tq, &sc->smc_intr);
}
#endif
@@ -807,15 +807,31 @@ static int
smc_intr(void *context)
{
struct smc_softc *sc;
-
+ uint32_t curbank;
+
sc = (struct smc_softc *)context;
#ifdef __rtems__
SMC_LOCK(sc);
+#endif /* __rtems__ */
+
+ /*
+ * Save current bank and restore later in this function
+ */
+ curbank = (smc_read_2(sc, BSR) & BSR_BANK_MASK);
+
+ /*
+ * Block interrupts in order to let smc_task_intr to kick in
+ */
smc_select_bank(sc, 2);
smc_write_1(sc, MSK, 0);
+
+ /* Restore bank */
+ smc_select_bank(sc, curbank);
+#ifdef __rtems__
SMC_UNLOCK(sc);
#endif /* __rtems__ */
- taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_intr);
+
+ taskqueue_enqueue(sc->smc_tq, &sc->smc_intr);
return (FILTER_HANDLED);
}
@@ -835,13 +851,6 @@ smc_task_intr(void *context, int pending)
smc_select_bank(sc, 2);
/*
- * Get the current mask, and then block all interrupts while we're
- * working.
- */
- if ((ifp->if_capenable & IFCAP_POLLING) == 0)
- smc_write_1(sc, MSK, 0);
-
- /*
* Find out what interrupts are flagged.
*/
status = smc_read_1(sc, IST) & sc->smc_mask;
@@ -855,13 +864,19 @@ smc_task_intr(void *context, int pending)
*/
packet = smc_read_1(sc, FIFO_TX);
if ((packet & FIFO_EMPTY) == 0) {
+ callout_stop(&sc->smc_watchdog);
+ smc_select_bank(sc, 2);
smc_write_1(sc, PNR, packet);
smc_write_2(sc, PTR, 0 | PTR_READ |
PTR_AUTO_INCR);
- tcr = smc_read_2(sc, DATA0);
+ smc_select_bank(sc, 0);
+ tcr = smc_read_2(sc, EPHSR);
+#if 0
if ((tcr & EPHSR_TX_SUC) == 0)
device_printf(sc->smc_dev,
"bad packet\n");
+#endif
+ smc_select_bank(sc, 2);
smc_mmu_wait(sc);
smc_write_2(sc, MMUCR, MMUCR_CMD_RELEASE_PKT);
@@ -870,7 +885,7 @@ smc_task_intr(void *context, int pending)
tcr |= TCR_TXENA | TCR_PAD_EN;
smc_write_2(sc, TCR, tcr);
smc_select_bank(sc, 2);
- taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_tx);
+ taskqueue_enqueue(sc->smc_tq, &sc->smc_tx);
}
/*
@@ -885,7 +900,7 @@ smc_task_intr(void *context, int pending)
if (status & RCV_INT) {
smc_write_1(sc, ACK, RCV_INT);
sc->smc_mask &= ~RCV_INT;
- taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_rx);
+ taskqueue_enqueue(sc->smc_tq, &sc->smc_rx);
}
/*
@@ -894,7 +909,7 @@ smc_task_intr(void *context, int pending)
if (status & ALLOC_INT) {
smc_write_1(sc, ACK, ALLOC_INT);
sc->smc_mask &= ~ALLOC_INT;
- taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_tx);
+ taskqueue_enqueue(sc->smc_tq, &sc->smc_tx);
}
/*
@@ -902,7 +917,7 @@ smc_task_intr(void *context, int pending)
*/
if (status & RX_OVRN_INT) {
smc_write_1(sc, ACK, RX_OVRN_INT);
- ifp->if_ierrors++;
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
}
/*
@@ -919,20 +934,20 @@ smc_task_intr(void *context, int pending)
smc_select_bank(sc, 0);
counter = smc_read_2(sc, ECR);
smc_select_bank(sc, 2);
- ifp->if_collisions +=
- (counter & ECR_SNGLCOL_MASK) >> ECR_SNGLCOL_SHIFT;
- ifp->if_collisions +=
- (counter & ECR_MULCOL_MASK) >> ECR_MULCOL_SHIFT;
+ if_inc_counter(ifp, IFCOUNTER_COLLISIONS,
+ ((counter & ECR_SNGLCOL_MASK) >> ECR_SNGLCOL_SHIFT) +
+ ((counter & ECR_MULCOL_MASK) >> ECR_MULCOL_SHIFT));
/*
* See if there are any packets to transmit.
*/
- taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_tx);
+ taskqueue_enqueue(sc->smc_tq, &sc->smc_tx);
}
/*
* Update the interrupt mask.
*/
+ smc_select_bank(sc, 2);
if ((ifp->if_capenable & IFCAP_POLLING) == 0)
smc_write_1(sc, MSK, sc->smc_mask);
@@ -1226,7 +1241,7 @@ smc_watchdog(void *arg)
sc = (struct smc_softc *)arg;
device_printf(sc->smc_dev, "watchdog timeout\n");
- taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_intr);
+ taskqueue_enqueue(sc->smc_tq, &sc->smc_intr);
}
static void
@@ -1245,9 +1260,10 @@ smc_init_locked(struct smc_softc *sc)
{
struct ifnet *ifp;
- ifp = sc->smc_ifp;
-
SMC_ASSERT_LOCKED(sc);
+ ifp = sc->smc_ifp;
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+ return;
smc_reset(sc);
smc_enable(sc);