PERFORCE change 169170 for review
Yohanes Nugroho
yohanes at FreeBSD.org
Sat Oct 3 02:35:59 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=169170
Change 169170 by yohanes at econa on 2009/10/03 02:35:46
not stopping DMA, using interrupt for cleanup
Affected files ...
.. //depot/projects/str91xx/src/sys/arm/conf/CNS11XXNAS#4 edit
.. //depot/projects/str91xx/src/sys/arm/econa/econa_machdep.c#4 edit
.. //depot/projects/str91xx/src/sys/arm/econa/if_ece.c#5 edit
.. //depot/projects/str91xx/src/sys/arm/econa/timer.c#4 edit
Differences ...
==== //depot/projects/str91xx/src/sys/arm/conf/CNS11XXNAS#4 (text+ko) ====
@@ -52,7 +52,8 @@
#options COMPAT_FREEBSD7
-options SCHED_ULE #ULE scheduler
+#options SCHED_ULE #ULE scheduler
+options SCHED_4BSD #4BSD scheduler
options GEOM_PART_GPT # GUID Partition Tables.
#options GEOM_PART_EBR
#options GEOM_PART_EBR_COMPAT
@@ -106,7 +107,7 @@
#options ARM_USE_SMALL_ALLOC
device usb
-options USB_DEBUG
+#options USB_DEBUG
device ohci
device ehci
device umass
==== //depot/projects/str91xx/src/sys/arm/econa/econa_machdep.c#4 (text+ko) ====
@@ -201,7 +201,7 @@
boot_arg1 = arg;
boot_arg2 = arg2;
boothowto = RB_VERBOSE;
- //boothowto |= RB_SINGLE;
+ boothowto |= RB_SINGLE;
set_cpufuncs();
lastaddr = fake_preload_metadata();
==== //depot/projects/str91xx/src/sys/arm/econa/if_ece.c#5 (text+ko) ====
@@ -79,6 +79,7 @@
struct mtx sc_mtx; /* global mutex */
struct mtx sc_mtx_tx; /* tx mutex */
struct mtx sc_mtx_rx; /* rx mutex */
+ struct mtx sc_mtx_cleanup; /* rx mutex */
bus_dma_tag_t sc_parent_tag; /* parent bus DMA tag */
@@ -86,11 +87,13 @@
device_t miibus; /* My child miibus */
void *intrhand; /* Interrupt handle */
void *intrhand_qf; /* Interrupt handle: queue full */
+ void *intrhand_tx; /* Interrupt handle: queue full */
void *intrhand_status; /* Interrupt handle */
- struct resource *irq_res_rec; /* IRQ resource */
- struct resource *irq_res_qf; /* IRQ resource */
- struct resource *irq_res_status; /* IRQ resource */
+ struct resource *irq_res_tx; /* transmit */
+ struct resource *irq_res_rec; /* receive */
+ struct resource *irq_res_qf; /* queue full */
+ struct resource *irq_res_status; /* status */
struct resource *mem_res; /* Memory resource */
@@ -131,6 +134,7 @@
struct taskqueue *sc_tq;
struct task sc_intr_task;
+ struct task sc_cleanup_task;
struct task sc_tx_task;
};
@@ -212,6 +216,14 @@
mtx_init(&_sc->sc_mtx_tx, device_get_nameunit(_sc->dev), \
"ECE TX Lock", MTX_DEF)
+
+#define ECE_CLEANUPLOCK(_sc) mtx_lock(&(_sc)->sc_mtx_cleanup)
+#define ECE_CLEANUPUNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx_cleanup)
+#define ECE_CLEANUPLOCK_INIT(_sc) \
+ mtx_init(&_sc->sc_mtx_cleanup, device_get_nameunit(_sc->dev), \
+ "ECE cleanup Lock", MTX_DEF)
+
+
#define ECE_RXLOCK(_sc) mtx_lock(&(_sc)->sc_mtx_rx)
#define ECE_RXUNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx_rx)
#define ECE_RXLOCK_INIT(_sc) \
@@ -221,6 +233,7 @@
#define ECE_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx);
#define ECE_TXLOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx_tx);
#define ECE_RXLOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx_rx);
+#define ECE_CLEANUPLOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx_cleanup);
#define ECE_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED);
#define ECE_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
@@ -271,9 +284,13 @@
static void ece_intr_task(void *arg, int pending __unused);
static void ece_tx_task(void *arg, int pending __unused);
+static void ece_cleanup_task(void *arg, int pending __unused);
static int ece_allocate_dma(struct ece_softc *sc);
+static void ece_intr_tx(void *xsc);
+
+
static inline int
phy_read(struct ece_softc *sc, int phy, int reg)
{
@@ -289,6 +306,7 @@
for (ii = 0; ii < 0x1000; ii++) {
status = RD4(sc, PHY_CONTROL);
+ DELAY(1);
if (status & (0x1 << 15)) {
/* clear the rw_ok status, and clear other bits value */
WR4(sc, PHY_CONTROL, (0x1 << 15));
@@ -393,6 +411,13 @@
if (sc->irq_res_rec == NULL)
goto out;
+ //
+ rid = 1; /*TSTC: Fm-Switch-Tx-Complete*/
+ sc->irq_res_tx = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+ RF_ACTIVE);
+ if (sc->irq_res_tx == NULL)
+ goto out;
+
rid = 0;
sc->irq_res_status = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
@@ -488,6 +513,7 @@
TASK_INIT(&sc->sc_intr_task, 0, ece_intr_task, sc);
TASK_INIT(&sc->sc_tx_task, 1, ece_tx_task, ifp);
+ TASK_INIT(&sc->sc_cleanup_task, 2, ece_cleanup_task, sc);
sc->sc_tq = taskqueue_create_fast("ece_taskq", M_WAITOK,
taskqueue_thread_enqueue, &sc->sc_tq);
if (sc->sc_tq == NULL) {
@@ -517,6 +543,7 @@
ECE_LOCK_DESTROY(sc);
goto out;
}
+
err = bus_setup_intr(dev, sc->irq_res_qf, INTR_TYPE_NET | INTR_MPSAFE,
NULL,ece_intr_qf, sc, &sc->intrhand_qf);
@@ -525,8 +552,21 @@
ECE_LOCK_DESTROY(sc);
goto out;
}
+
+
+ err = bus_setup_intr(dev, sc->irq_res_tx, INTR_TYPE_NET | INTR_MPSAFE,
+ NULL,ece_intr_tx, sc, &sc->intrhand_tx);
+
+ if (err) {
+ ether_ifdetach(ifp);
+ ECE_LOCK_DESTROY(sc);
+ goto out;
+ }
+
+
ECE_TXLOCK_INIT(sc);
ECE_RXLOCK_INIT(sc);
+ ECE_CLEANUPLOCK_INIT(sc);
DEBUG_TRACE;
@@ -1652,9 +1692,69 @@
taskqueue_enqueue(sc->sc_tq, &sc->sc_intr_task);
}
+static void
+ece_cleanup_locked(struct ece_softc *sc)
+{
+ //printf("cleaning up\n");
+ int desc_idx;
+ eth_tx_desc_t *desc;
+ int start = sc->curr_tx_mbuf - 1;
+ if (start<0) start = ECE_MAX_TX_BUFFERS-1;
+
+ desc_idx = sc->sent_position[start];
+ while (desc_idx!=-1) {
+ //bus_dmamap_sync(sc->dmatag_ring_tx, sc->dmap_tx[desc_idx], BUS_DMASYNC_PREREAD);
+ desc = (eth_tx_desc_t *)&(sc->desc_tx[desc_idx]);
+ if (desc->cown != 0) {
+ if (sc->buffer_tx[start]) {
+ //printf("freeing\n");
+ m_freem(sc->buffer_tx[start]);
+ sc->buffer_tx[start] = 0;
+ }
+ sc->sent_position[start] = -1;
+ start--;
+ if (start<0) start = ECE_MAX_TX_BUFFERS-1;
+ desc_idx = sc->sent_position[start];
+ } else {
+ break;
+ }
+ }
+
+}
+
+static void
+ece_cleanup_task(void *arg, int pending __unused)
+{
+// printf("ECE INTR TASK");
+ struct ece_softc *sc = arg;
+ //struct ifnet *ifp = sc->ifp;
+ //printf("cleanup task called\n");
+ ECE_CLEANUPLOCK(sc);
+ //printf("inside lock\n");
+ ece_cleanup_locked(sc);
+ ECE_CLEANUPUNLOCK(sc);
+}
+
static void
+ece_intr_tx(void *xsc)
+{
+ struct ece_softc *sc = xsc;
+ struct ifnet *ifp = sc->ifp;
+ //printf("data sent");
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ printf("should not happen, stopping dma");
+ /*this should not happen, stop DMA*/
+ WR4(sc, FS_DMA_CONTROL, 0);
+ return;
+ }
+ taskqueue_enqueue(sc->sc_tq, &sc->sc_cleanup_task);
+}
+
+
+
+static void
ece_intr_qf(void *xsc)
{
struct ece_softc *sc = xsc;
@@ -1706,7 +1806,7 @@
int seg;
int nsegs;
int desc_no;
- int desc_idx;
+ //int desc_idx;
int start;
eth_tx_desc_t *desc = 0;
@@ -1767,6 +1867,7 @@
desc->ico = 0;
desc->tco = 0;
desc->uco = 0;
+ desc->interrupt = 1;
#if 0
if (csum_flags) {
@@ -1783,7 +1884,7 @@
}
//desc->cown = 0;
- desc->interrupt = 0;
+ //sc->interrupt = 0;
desc++;
sc->desc_curr_tx = (sc->desc_curr_tx+1) % ECE_MAX_TX_BUFFERS;
@@ -1796,7 +1897,7 @@
for (seg = 0; seg < nsegs; seg++) {
desc->cown = 0;
desc++;
- bus_dmamap_sync(sc->dmatag_ring_tx, sc->dmap_tx[desc_no], BUS_DMASYNC_PREWRITE);
+ //bus_dmamap_sync(sc->dmatag_ring_tx, sc->dmap_tx[desc_no], BUS_DMASYNC_PREWRITE);
desc_no = (desc_no+1) % ECE_MAX_TX_BUFFERS;
if (desc_no==0) {
desc = (eth_tx_desc_t *)&(sc->desc_tx[0]);
@@ -1806,24 +1907,6 @@
bus_dmamap_sync(sc->dmatag_ring_tx, mapp, BUS_DMASYNC_PREWRITE);
- if (start<0) start = ECE_MAX_TX_BUFFERS-1;
-
- desc_idx = sc->sent_position[start];
- while (desc_idx!=-1) {
- //bus_dmamap_sync(sc->dmatag_ring_tx, sc->dmap_tx[desc_idx], BUS_DMASYNC_PREREAD);
- desc = (eth_tx_desc_t *)&(sc->desc_tx[desc_idx]);
- if (desc->cown != 0) {
- if (sc->buffer_tx[start]) {
- m_freem(sc->buffer_tx[start]);
- sc->buffer_tx[start] = 0;
-
- }
- sc->sent_position[start] = -1;
- start--;
- if (start<0) start = ECE_MAX_TX_BUFFERS-1;
- desc_idx = sc->sent_position[start];
- }
- }
return (0);
}
@@ -1845,7 +1928,7 @@
IFF_DRV_RUNNING)
return;
- WR4(sc, TS_DMA_CONTROL, 0);
+ //WR4(sc, TS_DMA_CONTROL, 0);
for (;;) {
/* Get packet from the queue */
IF_DEQUEUE(&ifp->if_snd, m0);
@@ -2032,7 +2115,7 @@
if (phy>0) return 0;
//printf("read reg %d phy %d\n", reg, phy);
sc = device_get_softc(dev);
-
+
return phy_read(sc, phy, reg);
}
==== //depot/projects/str91xx/src/sys/arm/econa/timer.c#4 (text+ko) ====
@@ -51,7 +51,7 @@
unsigned int AHB_clock;
unsigned int APB_clock;
-unsigned long gettimeoffset(void);
+
void timer_enable(void);
unsigned int str9100_timer_disable(void);
unsigned int read_timer_counter(void);
@@ -358,50 +358,6 @@
-unsigned long
-gettimeoffset(void)
-{
- unsigned int ticks1, ticks2;
- unsigned int interrupt_status;
- u_int savedints;
- savedints = disable_interrupts(I32_bit);
-
-
- /*
- * Get the current number of ticks. Note that there is a race
- * condition between us reading the timer and checking for
- * an interrupt. We get around this by ensuring that the
- * counter has not reloaded between our two reads.
- */
- ticks2 = read_timer_counter();
- do {
- ticks1 = ticks2;
- interrupt_status = read_timer_interrupt_status();
- ticks2 = read_timer_counter();
- } while (ticks2 > ticks1);
-
- /*
- * Number of ticks since last interrupt.
- */
- ticks1 = timer_counter - ticks2;
-
- /*
- * Interrupt pending? If so, we've reloaded once already.
- */
- if (interrupt_status &
- ((1 << TIMER1_MATCH1_INTR_BIT_INDEX) ||
- (1 << TIMER1_MATCH2_INTR_BIT_INDEX) ||
- (1 << TIMER1_OVERFLOW_INTR_BIT_INDEX))) {
- ticks1 += timer_counter;
- }
- restore_interrupts(savedints);
- /*
- * Convert the ticks to usecs
- */
- return TICKS2USECS(ticks1);
-}
-
-
static unsigned
ec_timer_get_timecount(struct timecounter *a)
@@ -427,9 +383,9 @@
{
sys_clock = 100000000;
- printf("System clock %08x", (*(unsigned int *)(0x77000008)));
+ printf("System clock %08x\n", (*(unsigned int *)(0x77000008)));
- printf("Reset conf %08x", (*(unsigned int *)(0x77000014)));
+ printf("Reset conf %08x\n", (*(unsigned int *)(0x77000014)));
switch (((*(unsigned int *)(0x77000014)) >> 6) & 0x3) {
More information about the p4-projects
mailing list