Index: sys/dev/altera/atse/a_api.h
===================================================================
--- sys/dev/altera/atse/a_api.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*-
- * Copyright (c) 2012 Bjoern A. Zeeb
- * All rights reserved.
- *
- * This software was developed by SRI International and the University of
- * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-11-C-0249)
- * ("MRC2"), as part of the DARPA MRC research programme.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-/*
- * Altera, Embedded Peripherals IP, User Guide, v. 11.0, June 2011.
- * UG-01085-11.0.
- */
-
-#ifndef _A_API_H
-#define _A_API_H
-
-/* Table 16-1. Memory Map. */
-#define A_ONCHIP_FIFO_MEM_CORE_DATA 0x00
-#define A_ONCHIP_FIFO_MEM_CORE_METADATA 0x04
-
-#define A_ONCHIP_FIFO_MEM_CORE_SOP (1<<0)
-#define A_ONCHIP_FIFO_MEM_CORE_EOP (1<<1)
-#define A_ONCHIP_FIFO_MEM_CORE_EMPTY_MASK 0x000000f7
-#define A_ONCHIP_FIFO_MEM_CORE_EMPTY_SHIFT 2
- /* Reserved (1<<7) */
-#define A_ONCHIP_FIFO_MEM_CORE_CHANNEL_MASK 0x0000ff00
-#define A_ONCHIP_FIFO_MEM_CORE_CHANNEL_SHIFT 8
-#define A_ONCHIP_FIFO_MEM_CORE_ERROR_MASK 0x00ff0000
-#define A_ONCHIP_FIFO_MEM_CORE_ERROR_SHIFT 16
- /* Reserved 0xff000000 */
-
-/* Table 16-3. FIFO Status Register Memory Map. */
-#define A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_FILL_LEVEL 0x00
-#define A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_I_STATUS 0x04
-#define A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_EVENT 0x08
-#define A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_INT_ENABLE 0x0c
-#define A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_ALMOSTFULL 0x10
-#define A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_ALMOSTEMPTY 0x14
-
-/* Table 16-5. Status Bit Field Descriptions. */
-#define A_ONCHIP_FIFO_MEM_CORE_STATUS_FULL (1<<0)
-#define A_ONCHIP_FIFO_MEM_CORE_STATUS_EMPTY (1<<1)
-#define A_ONCHIP_FIFO_MEM_CORE_STATUS_ALMOSTFULL (1<<2)
-#define A_ONCHIP_FIFO_MEM_CORE_STATUS_ALMOSTEMPTY (1<<3)
-#define A_ONCHIP_FIFO_MEM_CORE_STATUS_OVERFLOW (1<<4)
-#define A_ONCHIP_FIFO_MEM_CORE_STATUS_UNDERFLOW (1<<5)
-
-/* Table 16-6. Event Bit Field Descriptions. */
-/* XXX Datasheet has incorrect bit fields. Validate. */
-#define A_ONCHIP_FIFO_MEM_CORE_EVENT_FULL (1<<0)
-#define A_ONCHIP_FIFO_MEM_CORE_EVENT_EMPTY (1<<1)
-#define A_ONCHIP_FIFO_MEM_CORE_EVENT_ALMOSTFULL (1<<2)
-#define A_ONCHIP_FIFO_MEM_CORE_EVENT_ALMOSTEMPTY (1<<3)
-#define A_ONCHIP_FIFO_MEM_CORE_EVENT_OVERFLOW (1<<4)
-#define A_ONCHIP_FIFO_MEM_CORE_EVENT_UNDERFLOW (1<<5)
-
-/* Table 16-7. InterruptEnable Bit Field Descriptions. */
-/* XXX Datasheet has incorrect bit fields. Validate. */
-#define A_ONCHIP_FIFO_MEM_CORE_INTR_FULL (1<<0)
-#define A_ONCHIP_FIFO_MEM_CORE_INTR_EMPTY (1<<1)
-#define A_ONCHIP_FIFO_MEM_CORE_INTR_ALMOSTFULL (1<<2)
-#define A_ONCHIP_FIFO_MEM_CORE_INTR_ALMOSTEMPTY (1<<3)
-#define A_ONCHIP_FIFO_MEM_CORE_INTR_OVERFLOW (1<<4)
-#define A_ONCHIP_FIFO_MEM_CORE_INTR_UNDERFLOW (1<<5)
-#define A_ONCHIP_FIFO_MEM_CORE_INTR_ALL \
- (A_ONCHIP_FIFO_MEM_CORE_INTR_EMPTY| \
- A_ONCHIP_FIFO_MEM_CORE_INTR_FULL| \
- A_ONCHIP_FIFO_MEM_CORE_INTR_ALMOSTEMPTY| \
- A_ONCHIP_FIFO_MEM_CORE_INTR_ALMOSTFULL| \
- A_ONCHIP_FIFO_MEM_CORE_INTR_OVERFLOW| \
- A_ONCHIP_FIFO_MEM_CORE_INTR_UNDERFLOW)
-
-#endif /* _A_API_H */
-
-/* end */
Index: sys/dev/altera/atse/if_atse.c
===================================================================
--- sys/dev/altera/atse/if_atse.c
+++ sys/dev/altera/atse/if_atse.c
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 2012, 2013 Bjoern A. Zeeb
* Copyright (c) 2014 Robert N. M. Watson
+ * Copyright (c) 2016 Ruslan Bukin
* All rights reserved.
*
* This software was developed by SRI International and the University of
@@ -86,17 +87,14 @@
#include
#include
-#include
-
-MODULE_DEPEND(atse, ether, 1, 1, 1);
-MODULE_DEPEND(atse, miibus, 1, 1, 1);
+#include
+#define RX_QUEUE_SIZE 1024
+#define TX_QUEUE_SIZE 1024
+#define NUM_TX_DESC 256
+#define NUM_RX_DESC 256
-#define ATSE_WATCHDOG_TIME 5
-
-#ifdef DEVICE_POLLING
-static poll_handler_t atse_poll;
-#endif
+#include
/* XXX once we'd do parallel attach, we need a global lock for this. */
#define ATSE_ETHERNET_OPTION_BITS_UNDEF 0
@@ -104,11 +102,6 @@
static int atse_ethernet_option_bits_flag = ATSE_ETHERNET_OPTION_BITS_UNDEF;
static uint8_t atse_ethernet_option_bits[ALTERA_ETHERNET_OPTION_BITS_LEN];
-static int atse_intr_debug_enable = 0;
-SYSCTL_INT(_debug, OID_AUTO, atse_intr_debug_enable, CTLFLAG_RW,
- &atse_intr_debug_enable, 0,
- "Extra debugging output for atse interrupts");
-
/*
* Softc and critical resource locking.
*/
@@ -116,155 +109,12 @@
#define ATSE_UNLOCK(_sc) mtx_unlock(&(_sc)->atse_mtx)
#define ATSE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->atse_mtx, MA_OWNED)
-#define ATSE_TX_PENDING(sc) (sc->atse_tx_m != NULL || \
- !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
-
#ifdef DEBUG
#define DPRINTF(format, ...) printf(format, __VA_ARGS__)
#else
#define DPRINTF(format, ...)
#endif
-/* a_api.c functions; factor out? */
-static inline void
-a_onchip_fifo_mem_core_write(struct resource *res, uint32_t off,
- uint32_t val4, const char *desc, const char *f, const int l)
-{
-
- val4 = htole32(val4);
- DPRINTF("[%s:%d] FIFOW %s 0x%08x = 0x%08x\n", f, l, desc, off, val4);
- bus_write_4(res, off, val4);
-}
-
-static inline uint32_t
-a_onchip_fifo_mem_core_read(struct resource *res, uint32_t off,
- const char *desc, const char *f, const int l)
-{
- uint32_t val4;
-
- val4 = le32toh(bus_read_4(res, off));
- DPRINTF("[%s:%d] FIFOR %s 0x%08x = 0x%08x\n", f, l, desc, off, val4);
-
- return (val4);
-}
-
-/* The FIFO does an endian conversion, so we must not do it as well. */
-/* XXX-BZ in fact we should do a htobe32 so le would be fine as well? */
-#define ATSE_TX_DATA_WRITE(sc, val4) \
- bus_write_4((sc)->atse_tx_mem_res, A_ONCHIP_FIFO_MEM_CORE_DATA, val4)
-
-#define ATSE_TX_META_WRITE(sc, val4) \
- a_onchip_fifo_mem_core_write((sc)->atse_tx_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_METADATA, \
- (val4), "TXM", __func__, __LINE__)
-#define ATSE_TX_META_READ(sc) \
- a_onchip_fifo_mem_core_read((sc)->atse_tx_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_METADATA, \
- "TXM", __func__, __LINE__)
-
-#define ATSE_TX_READ_FILL_LEVEL(sc) \
- a_onchip_fifo_mem_core_read((sc)->atse_txc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_FILL_LEVEL, \
- "TX_FILL", __func__, __LINE__)
-#define ATSE_RX_READ_FILL_LEVEL(sc) \
- a_onchip_fifo_mem_core_read((sc)->atse_rxc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_FILL_LEVEL, \
- "RX_FILL", __func__, __LINE__)
-
-/* The FIFO does an endian conversion, so we must not do it as well. */
-/* XXX-BZ in fact we should do a htobe32 so le would be fine as well? */
-#define ATSE_RX_DATA_READ(sc) \
- bus_read_4((sc)->atse_rx_mem_res, A_ONCHIP_FIFO_MEM_CORE_DATA)
-#define ATSE_RX_META_READ(sc) \
- a_onchip_fifo_mem_core_read((sc)->atse_rx_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_METADATA, \
- "RXM", __func__, __LINE__)
-
-#define ATSE_RX_STATUS_READ(sc) \
- a_onchip_fifo_mem_core_read((sc)->atse_rxc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_I_STATUS, \
- "RX_EVENT", __func__, __LINE__)
-
-#define ATSE_TX_STATUS_READ(sc) \
- a_onchip_fifo_mem_core_read((sc)->atse_txc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_I_STATUS, \
- "TX_EVENT", __func__, __LINE__)
-
-#define ATSE_RX_EVENT_READ(sc) \
- a_onchip_fifo_mem_core_read((sc)->atse_rxc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_EVENT, \
- "RX_EVENT", __func__, __LINE__)
-
-#define ATSE_TX_EVENT_READ(sc) \
- a_onchip_fifo_mem_core_read((sc)->atse_txc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_EVENT, \
- "TX_EVENT", __func__, __LINE__)
-
-#define ATSE_RX_EVENT_CLEAR(sc) \
- do { \
- uint32_t val4; \
- \
- val4 = a_onchip_fifo_mem_core_read( \
- (sc)->atse_rxc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_EVENT, \
- "RX_EVENT", __func__, __LINE__); \
- if (val4 != 0x00) \
- a_onchip_fifo_mem_core_write( \
- (sc)->atse_rxc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_EVENT, \
- val4, "RX_EVENT", __func__, __LINE__); \
- } while(0)
-#define ATSE_TX_EVENT_CLEAR(sc) \
- do { \
- uint32_t val4; \
- \
- val4 = a_onchip_fifo_mem_core_read( \
- (sc)->atse_txc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_EVENT, \
- "TX_EVENT", __func__, __LINE__); \
- if (val4 != 0x00) \
- a_onchip_fifo_mem_core_write( \
- (sc)->atse_txc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_EVENT, \
- val4, "TX_EVENT", __func__, __LINE__); \
- } while(0)
-
-#define ATSE_RX_EVENTS (A_ONCHIP_FIFO_MEM_CORE_INTR_FULL | \
- A_ONCHIP_FIFO_MEM_CORE_INTR_OVERFLOW | \
- A_ONCHIP_FIFO_MEM_CORE_INTR_UNDERFLOW)
-#define ATSE_RX_INTR_ENABLE(sc) \
- a_onchip_fifo_mem_core_write((sc)->atse_rxc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_INT_ENABLE, \
- ATSE_RX_EVENTS, \
- "RX_INTR", __func__, __LINE__) /* XXX-BZ review later. */
-#define ATSE_RX_INTR_DISABLE(sc) \
- a_onchip_fifo_mem_core_write((sc)->atse_rxc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_INT_ENABLE, 0, \
- "RX_INTR", __func__, __LINE__)
-#define ATSE_RX_INTR_READ(sc) \
- a_onchip_fifo_mem_core_read((sc)->atse_rxc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_INT_ENABLE, \
- "RX_INTR", __func__, __LINE__)
-
-#define ATSE_TX_EVENTS (A_ONCHIP_FIFO_MEM_CORE_INTR_EMPTY | \
- A_ONCHIP_FIFO_MEM_CORE_INTR_OVERFLOW | \
- A_ONCHIP_FIFO_MEM_CORE_INTR_UNDERFLOW)
-#define ATSE_TX_INTR_ENABLE(sc) \
- a_onchip_fifo_mem_core_write((sc)->atse_txc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_INT_ENABLE, \
- ATSE_TX_EVENTS, \
- "TX_INTR", __func__, __LINE__) /* XXX-BZ review later. */
-#define ATSE_TX_INTR_DISABLE(sc) \
- a_onchip_fifo_mem_core_write((sc)->atse_txc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_INT_ENABLE, 0, \
- "TX_INTR", __func__, __LINE__)
-#define ATSE_TX_INTR_READ(sc) \
- a_onchip_fifo_mem_core_read((sc)->atse_txc_mem_res, \
- A_ONCHIP_FIFO_MEM_CORE_STATUS_REG_INT_ENABLE, \
- "TX_INTR", __func__, __LINE__)
-
-static int atse_rx_locked(struct atse_softc *sc);
-
/*
* Register space access macros.
*/
@@ -343,146 +193,152 @@
devclass_t atse_devclass;
static int
-atse_tx_locked(struct atse_softc *sc, int *sent)
+atse_rx_enqueue(struct atse_softc *sc, uint32_t n)
{
struct mbuf *m;
- uint32_t val4, fill_level;
- int leftm;
- int c;
-
- ATSE_LOCK_ASSERT(sc);
+ int i;
- m = sc->atse_tx_m;
- KASSERT(m != NULL, ("%s: m is null: sc=%p", __func__, sc));
- KASSERT(m->m_flags & M_PKTHDR, ("%s: not a pkthdr: m=%p", __func__, m));
+ for (i = 0; i < n; i++) {
+ m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+ if (m == NULL) {
+ device_printf(sc->dev,
+ "%s: Can't alloc rx mbuf\n", __func__);
+ return (-1);
+ }
- /*
- * Copy to buffer to minimize our pain as we can only store
- * double words which, after the first mbuf gets out of alignment
- * quite quickly.
- */
- if (sc->atse_tx_m_offset == 0) {
- m_copydata(m, 0, m->m_pkthdr.len, sc->atse_tx_buf);
- sc->atse_tx_buf_len = m->m_pkthdr.len;
+ m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
+ xdma_enqueue_mbuf(sc->xchan_rx, &m, 0, XDMA_DEV_TO_MEM);
}
- fill_level = ATSE_TX_READ_FILL_LEVEL(sc);
-#if 0 /* Returns 0xdeadc0de. */
- val4 = ATSE_TX_META_READ(sc);
-#endif
- if (sc->atse_tx_m_offset == 0) {
- /* Write start of packet. */
- val4 = A_ONCHIP_FIFO_MEM_CORE_SOP;
- val4 &= ~A_ONCHIP_FIFO_MEM_CORE_EOP;
- ATSE_TX_META_WRITE(sc, val4);
- }
+ return (0);
+}
+
+static int
+atse_xdma_tx_intr(void *arg, xdma_transfer_status_t *status)
+{
+ xdma_transfer_status_t st;
+ struct atse_softc *sc;
+ struct ifnet *ifp;
+ struct mbuf *m;
+ int err;
- /* TX FIFO is single clock mode, so we have the full FIFO. */
- c = 0;
- while ((sc->atse_tx_buf_len - sc->atse_tx_m_offset) > 4 &&
- fill_level < AVALON_FIFO_TX_BASIC_OPTS_DEPTH) {
+ sc = arg;
- bcopy(&sc->atse_tx_buf[sc->atse_tx_m_offset], &val4,
- sizeof(val4));
- ATSE_TX_DATA_WRITE(sc, val4);
- sc->atse_tx_m_offset += sizeof(val4);
- c += sizeof(val4);
+ ATSE_LOCK(sc);
- fill_level++;
- if (fill_level == AVALON_FIFO_TX_BASIC_OPTS_DEPTH)
- fill_level = ATSE_TX_READ_FILL_LEVEL(sc);
+ ifp = sc->atse_ifp;
+
+ for (;;) {
+ err = xdma_dequeue_mbuf(sc->xchan_tx, &m, &st);
+ if (err != 0) {
+ break;
+ }
+
+ if (st.error != 0) {
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ }
+
+ m_freem(m);
+ sc->txcount--;
}
- if (sent != NULL)
- *sent += c;
- /* Set EOP *before* writing the last symbol. */
- if (sc->atse_tx_m_offset >= (sc->atse_tx_buf_len - 4) &&
- fill_level < AVALON_FIFO_TX_BASIC_OPTS_DEPTH) {
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- /* Set EndOfPacket. */
- val4 = A_ONCHIP_FIFO_MEM_CORE_EOP;
+ ATSE_UNLOCK(sc);
- /* Set EMPTY. */
- leftm = sc->atse_tx_buf_len - sc->atse_tx_m_offset;
- val4 |= ((4 - leftm) << A_ONCHIP_FIFO_MEM_CORE_EMPTY_SHIFT);
- ATSE_TX_META_WRITE(sc, val4);
+ return (0);
+}
- /* Write last symbol. */
- val4 = 0;
- bcopy(sc->atse_tx_buf + sc->atse_tx_m_offset, &val4, leftm);
- ATSE_TX_DATA_WRITE(sc, val4);
+static int
+atse_xdma_rx_intr(void *arg, xdma_transfer_status_t *status)
+{
+ xdma_transfer_status_t st;
+ struct atse_softc *sc;
+ struct ifnet *ifp;
+ struct mbuf *m;
+ int err;
+ uint32_t cnt_processed;
- if (sent != NULL)
- *sent += leftm;
+ sc = arg;
- /* OK, the packet is gone. */
- sc->atse_tx_m = NULL;
- sc->atse_tx_m_offset = 0;
+ ATSE_LOCK(sc);
- /* If anyone is interested give them a copy. */
- BPF_MTAP(sc->atse_ifp, m);
+ ifp = sc->atse_ifp;
- m_freem(m);
- return (0);
+
+ cnt_processed = 0;
+ for (;;) {
+ err = xdma_dequeue_mbuf(sc->xchan_rx, &m, &st);
+ if (err != 0) {
+ break;
+ }
+ cnt_processed++;
+
+ if (st.error != 0) {
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ m_freem(m);
+ continue;
+ }
+
+ m->m_pkthdr.len = m->m_len = st.transferred;
+ m->m_pkthdr.rcvif = ifp;
+ m_adj(m, ETHER_ALIGN);
+ ATSE_UNLOCK(sc);
+ (*ifp->if_input)(ifp, m);
+ ATSE_LOCK(sc);
}
- return (EBUSY);
+ atse_rx_enqueue(sc, cnt_processed);
+
+ ATSE_UNLOCK(sc);
+
+ return (0);
}
-static void
-atse_start_locked(struct ifnet *ifp)
+static int
+atse_transmit_locked(struct ifnet *ifp, struct mbuf *m)
{
struct atse_softc *sc;
- int error, sent;
+ int ret;
sc = ifp->if_softc;
- ATSE_LOCK_ASSERT(sc);
- if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
- IFF_DRV_RUNNING || (sc->atse_flags & ATSE_FLAGS_LINK) == 0)
- return;
-
-#if 1
- /*
- * Disable the watchdog while sending, we are batching packets.
- * Though we should never reach 5 seconds, and are holding the lock,
- * but who knows.
- */
- sc->atse_watchdog_timer = 0;
-#endif
+ if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING) {
+ return (-1);
+ }
- if (sc->atse_tx_m != NULL) {
- error = atse_tx_locked(sc, &sent);
- if (error != 0)
- goto done;
+ if ((sc->atse_flags & ATSE_FLAGS_LINK) == 0) {
+ return (-1);
}
- /* We have more space to send so continue ... */
- for (; !IFQ_DRV_IS_EMPTY(&ifp->if_snd); ) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, sc->atse_tx_m);
- sc->atse_tx_m_offset = 0;
- if (sc->atse_tx_m == NULL)
- break;
- error = atse_tx_locked(sc, &sent);
- if (error != 0)
- goto done;
+ ret = xdma_enqueue_mbuf(sc->xchan_tx, &m, 0, XDMA_MEM_TO_DEV);
+ if (ret != 0) {
+ /* No space in request queue available yet. */
+ return (-1);
}
-done:
- /* If the IP core walks into Nekromanteion try to bail out. */
- if (sent > 0)
- sc->atse_watchdog_timer = ATSE_WATCHDOG_TIME;
+ /* If anyone is interested give them a copy. */
+ BPF_MTAP(sc->atse_ifp, m);
+
+ sc->txcount++;
+
+ xdma_queue_submit(sc->xchan_tx);
+
+ return (0);
}
-static void
-atse_start(struct ifnet *ifp)
+static int
+atse_transmit(struct ifnet *ifp, struct mbuf *m)
{
struct atse_softc *sc;
sc = ifp->if_softc;
+
ATSE_LOCK(sc);
- atse_start_locked(ifp);
+ atse_transmit_locked(ifp, m);
ATSE_UNLOCK(sc);
+
+ return (0);
}
static int
@@ -494,36 +350,33 @@
ATSE_LOCK_ASSERT(sc);
- sc->atse_watchdog_timer = 0;
callout_stop(&sc->atse_tick);
ifp = sc->atse_ifp;
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
- ATSE_RX_INTR_DISABLE(sc);
- ATSE_TX_INTR_DISABLE(sc);
- ATSE_RX_EVENT_CLEAR(sc);
- ATSE_TX_EVENT_CLEAR(sc);
/* Disable MAC transmit and receive datapath. */
mask = BASE_CFG_COMMAND_CONFIG_TX_ENA|BASE_CFG_COMMAND_CONFIG_RX_ENA;
val4 = CSR_READ_4(sc, BASE_CFG_COMMAND_CONFIG);
val4 &= ~mask;
CSR_WRITE_4(sc, BASE_CFG_COMMAND_CONFIG, val4);
+
/* Wait for bits to be cleared; i=100 is excessive. */
for (i = 0; i < 100; i++) {
val4 = CSR_READ_4(sc, BASE_CFG_COMMAND_CONFIG);
- if ((val4 & mask) == 0)
+ if ((val4 & mask) == 0) {
break;
+ }
DELAY(10);
}
- if ((val4 & mask) != 0)
+
+ if ((val4 & mask) != 0) {
device_printf(sc->atse_dev, "Disabling MAC TX/RX timed out.\n");
/* Punt. */
+ }
sc->atse_flags &= ~ATSE_FLAGS_LINK;
- /* XXX-BZ free the RX/TX rings. */
-
return (0);
}
@@ -559,10 +412,11 @@
val4 &= ~BASE_CFG_COMMAND_CONFIG_MHASH_SEL;
ifp = sc->atse_ifp;
- if (ifp->if_flags & IFF_PROMISC)
+ if (ifp->if_flags & IFF_PROMISC) {
val4 |= BASE_CFG_COMMAND_CONFIG_PROMIS_EN;
- else
+ } else {
val4 &= ~BASE_CFG_COMMAND_CONFIG_PROMIS_EN;
+ }
CSR_WRITE_4(sc, BASE_CFG_COMMAND_CONFIG, val4);
@@ -585,16 +439,18 @@
*/
if_maddr_rlock(ifp);
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
+ if (ifma->ifma_addr->sa_family != AF_LINK) {
continue;
+ }
h |= (1 << atse_mchash(sc,
LLADDR((struct sockaddr_dl *)ifma->ifma_addr)));
}
if_maddr_runlock(ifp);
- for (i = 0; i <= MHASH_LEN; i++)
+ for (i = 0; i <= MHASH_LEN; i++) {
CSR_WRITE_4(sc, MHASH_START + i,
(h & (1 << i)) ? 0x01 : 0x00);
+ }
}
return (0);
@@ -607,22 +463,26 @@
device_t fdev;
int i, rid;
- if (atse_ethernet_option_bits_flag & ATSE_ETHERNET_OPTION_BITS_READ)
+ if (atse_ethernet_option_bits_flag & ATSE_ETHERNET_OPTION_BITS_READ) {
return (0);
+ }
fdev = device_find_child(device_get_parent(dev), "cfi", 0);
- if (fdev == NULL)
+ if (fdev == NULL) {
return (ENOENT);
+ }
rid = 0;
res = bus_alloc_resource_any(fdev, SYS_RES_MEMORY, &rid,
RF_ACTIVE | RF_SHAREABLE);
- if (res == NULL)
+ if (res == NULL) {
return (ENXIO);
+ }
- for (i = 0; i < ALTERA_ETHERNET_OPTION_BITS_LEN; i++)
+ for (i = 0; i < ALTERA_ETHERNET_OPTION_BITS_LEN; i++) {
atse_ethernet_option_bits[i] = bus_read_1(res,
ALTERA_ETHERNET_OPTION_BITS_OFF + i);
+ }
bus_release_resource(fdev, SYS_RES_MEMORY, rid, res);
atse_ethernet_option_bits_flag |= ATSE_ETHERNET_OPTION_BITS_READ;
@@ -656,12 +516,14 @@
* possibly change our ethernet address, which is not good at all.
*/
if (sc->atse_eth_addr[0] != 0x00 || sc->atse_eth_addr[1] != 0x00 ||
- sc->atse_eth_addr[2] != 0x00)
+ sc->atse_eth_addr[2] != 0x00) {
return (0);
+ }
if ((atse_ethernet_option_bits_flag &
- ATSE_ETHERNET_OPTION_BITS_READ) == 0)
+ ATSE_ETHERNET_OPTION_BITS_READ) == 0) {
goto get_random;
+ }
val4 = atse_ethernet_option_bits[0] << 24;
val4 |= atse_ethernet_option_bits[1] << 16;
@@ -716,8 +578,9 @@
* Ethernet, go to random.
*/
unit = device_get_unit(sc->atse_dev);
- if (unit == 0x00)
+ if (unit == 0x00) {
return (0);
+ }
if (unit > 0x0f) {
device_printf(sc->atse_dev, "We do not support Ethernet "
@@ -829,8 +692,9 @@
/* Wait for reset bit to clear; i=100 is excessive. */
for (i = 0; i < 100; i++) {
val = PCS_READ_2(sc, PCS_CONTROL);
- if ((val & PCS_CONTROL_RESET) == 0)
+ if ((val & PCS_CONTROL_RESET) == 0) {
break;
+ }
DELAY(10);
}
@@ -849,8 +713,9 @@
/* Wait for bits to be cleared; i=100 is excessive. */
for (i = 0; i < 100; i++) {
val4 = CSR_READ_4(sc, BASE_CFG_COMMAND_CONFIG);
- if ((val4 & mask) == 0)
+ if ((val4 & mask) == 0) {
break;
+ }
DELAY(10);
}
if ((val4 & mask) != 0) {
@@ -924,8 +789,10 @@
val4 = CSR_READ_4(sc, TX_CMD_STAT);
val4 &= ~(TX_CMD_STAT_OMIT_CRC|TX_CMD_STAT_TX_SHIFT16);
CSR_WRITE_4(sc, TX_CMD_STAT, val4);
+
val4 = CSR_READ_4(sc, RX_CMD_STAT);
val4 &= ~RX_CMD_STAT_RX_SHIFT16;
+ val4 |= RX_CMD_STAT_RX_SHIFT16;
CSR_WRITE_4(sc, RX_CMD_STAT, val4);
/* e. Reset MAC. */
@@ -935,8 +802,9 @@
/* Wait for bits to be cleared; i=100 is excessive. */
for (i = 0; i < 100; i++) {
val4 = CSR_READ_4(sc, BASE_CFG_COMMAND_CONFIG);
- if ((val4 & BASE_CFG_COMMAND_CONFIG_SW_RESET) == 0)
+ if ((val4 & BASE_CFG_COMMAND_CONFIG_SW_RESET) == 0) {
break;
+ }
DELAY(10);
}
if ((val4 & BASE_CFG_COMMAND_CONFIG_SW_RESET) != 0) {
@@ -952,8 +820,9 @@
/* Wait for bits to be cleared; i=100 is excessive. */
for (i = 0; i < 100; i++) {
val4 = CSR_READ_4(sc, BASE_CFG_COMMAND_CONFIG);
- if ((val4 & mask) == mask)
+ if ((val4 & mask) == mask) {
break;
+ }
DELAY(10);
}
if ((val4 & mask) != mask) {
@@ -974,8 +843,9 @@
ATSE_LOCK_ASSERT(sc);
ifp = sc->atse_ifp;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
return;
+ }
/*
* Must update the ether address if changed. Given we do not handle
@@ -987,31 +857,14 @@
/* Make things frind to halt, cleanup, ... */
atse_stop_locked(sc);
- /* ... reset, ... */
+
atse_reset(sc);
/* ... and fire up the engine again. */
atse_rxfilter_locked(sc);
- /* Memory rings? DMA engine? */
-
- sc->atse_rx_buf_len = 0;
sc->atse_flags &= ATSE_FLAGS_LINK; /* Preserve. */
-#ifdef DEVICE_POLLING
- /* Only enable interrupts if we are not polling. */
- if (ifp->if_capenable & IFCAP_POLLING) {
- ATSE_RX_INTR_DISABLE(sc);
- ATSE_TX_INTR_DISABLE(sc);
- ATSE_RX_EVENT_CLEAR(sc);
- ATSE_TX_EVENT_CLEAR(sc);
- } else
-#endif
- {
- ATSE_RX_INTR_ENABLE(sc);
- ATSE_TX_INTR_ENABLE(sc);
- }
-
mii = device_get_softc(sc->atse_miibus);
sc->atse_flags &= ~ATSE_FLAGS_LINK;
@@ -1068,39 +921,6 @@
case SIOCSIFCAP:
ATSE_LOCK(sc);
mask = ifr->ifr_reqcap ^ ifp->if_capenable;
-#ifdef DEVICE_POLLING
- if ((mask & IFCAP_POLLING) != 0 &&
- (IFCAP_POLLING & ifp->if_capabilities) != 0) {
- ifp->if_capenable ^= IFCAP_POLLING;
- if ((IFCAP_POLLING & ifp->if_capenable) != 0) {
-
- error = ether_poll_register(atse_poll, ifp);
- if (error != 0) {
- ATSE_UNLOCK(sc);
- break;
- }
- /* Disable interrupts. */
- ATSE_RX_INTR_DISABLE(sc);
- ATSE_TX_INTR_DISABLE(sc);
- ATSE_RX_EVENT_CLEAR(sc);
- ATSE_TX_EVENT_CLEAR(sc);
-
- /*
- * Do not allow disabling of polling if we do
- * not have interrupts.
- */
- } else if (sc->atse_rx_irq_res != NULL ||
- sc->atse_tx_irq_res != NULL) {
- error = ether_poll_deregister(ifp);
- /* Enable interrupts. */
- ATSE_RX_INTR_ENABLE(sc);
- ATSE_TX_INTR_ENABLE(sc);
- } else {
- ifp->if_capenable ^= IFCAP_POLLING;
- error = EINVAL;
- }
- }
-#endif /* DEVICE_POLLING */
ATSE_UNLOCK(sc);
break;
case SIOCADDMULTI:
@@ -1129,55 +949,6 @@
}
static void
-atse_intr_debug(struct atse_softc *sc, const char *intrname)
-{
- uint32_t rxs, rxe, rxi, rxf, txs, txe, txi, txf;
-
- if (!atse_intr_debug_enable)
- return;
-
- rxs = ATSE_RX_STATUS_READ(sc);
- rxe = ATSE_RX_EVENT_READ(sc);
- rxi = ATSE_RX_INTR_READ(sc);
- rxf = ATSE_RX_READ_FILL_LEVEL(sc);
-
- txs = ATSE_TX_STATUS_READ(sc);
- txe = ATSE_TX_EVENT_READ(sc);
- txi = ATSE_TX_INTR_READ(sc);
- txf = ATSE_TX_READ_FILL_LEVEL(sc);
-
- printf(
- "%s - %s: "
- "rxs 0x%x rxe 0x%x rxi 0x%x rxf 0x%x "
- "txs 0x%x txe 0x%x txi 0x%x txf 0x%x\n",
- __func__, intrname,
- rxs, rxe, rxi, rxf,
- txs, txe, txi, txf);
-}
-
-static void
-atse_watchdog(struct atse_softc *sc)
-{
-
- ATSE_LOCK_ASSERT(sc);
-
- if (sc->atse_watchdog_timer == 0 || --sc->atse_watchdog_timer > 0)
- return;
-
- device_printf(sc->atse_dev, "watchdog timeout\n");
- if_inc_counter(sc->atse_ifp, IFCOUNTER_OERRORS, 1);
-
- atse_intr_debug(sc, "poll");
-
- sc->atse_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
- atse_init_locked(sc);
-
- atse_rx_locked(sc);
- if (!IFQ_DRV_IS_EMPTY(&sc->atse_ifp->if_snd))
- atse_start_locked(sc->atse_ifp);
-}
-
-static void
atse_tick(void *xsc)
{
struct atse_softc *sc;
@@ -1190,9 +961,10 @@
mii = device_get_softc(sc->atse_miibus);
mii_tick(mii);
- atse_watchdog(sc);
- if ((sc->atse_flags & ATSE_FLAGS_LINK) == 0)
+ if ((sc->atse_flags & ATSE_FLAGS_LINK) == 0) {
atse_miibus_statchg(sc->atse_dev);
+ }
+
callout_reset(&sc->atse_tick, hz, atse_tick, sc);
}
@@ -1211,171 +983,15 @@
ATSE_LOCK(sc);
mii = device_get_softc(sc->atse_miibus);
- LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
+ LIST_FOREACH(miisc, &mii->mii_phys, mii_list) {
PHY_RESET(miisc);
+ }
error = mii_mediachg(mii);
ATSE_UNLOCK(sc);
return (error);
}
-static void
-atse_update_rx_err(struct atse_softc *sc, uint32_t mask)
-{
- int i;
-
- /* RX error are 6 bits, we only know 4 of them. */
- for (i = 0; i < ATSE_RX_ERR_MAX; i++)
- if ((mask & (1 << i)) != 0)
- sc->atse_rx_err[i]++;
-}
-
-static int
-atse_rx_locked(struct atse_softc *sc)
-{
- uint32_t fill, i, j;
- uint32_t data, meta;
- struct ifnet *ifp;
- struct mbuf *m;
- int rx_npkts;
-
- ATSE_LOCK_ASSERT(sc);
-
- ifp = sc->atse_ifp;
- rx_npkts = 0;
- j = 0;
- meta = 0;
- do {
-outer:
- if (sc->atse_rx_m == NULL) {
- m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
- if (m == NULL)
- return (rx_npkts);
- m->m_len = m->m_pkthdr.len = MCLBYTES;
- /* Make sure upper layers will be aligned. */
- m_adj(m, ETHER_ALIGN);
- sc->atse_rx_m = m;
- }
-
- fill = ATSE_RX_READ_FILL_LEVEL(sc);
- for (i = 0; i < fill; i++) {
- /*
- * XXX-BZ for whatever reason the FIFO requires the
- * the data read before we can access the meta data.
- */
- data = ATSE_RX_DATA_READ(sc);
- meta = ATSE_RX_META_READ(sc);
- if (meta & A_ONCHIP_FIFO_MEM_CORE_ERROR_MASK) {
- /* XXX-BZ evaluate error. */
- atse_update_rx_err(sc, ((meta &
- A_ONCHIP_FIFO_MEM_CORE_ERROR_MASK) >>
- A_ONCHIP_FIFO_MEM_CORE_ERROR_SHIFT) & 0xff);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
- sc->atse_rx_buf_len = 0;
- /*
- * Should still read till EOP or next SOP.
- *
- * XXX-BZ might also depend on
- * BASE_CFG_COMMAND_CONFIG_RX_ERR_DISC
- */
- sc->atse_flags |= ATSE_FLAGS_ERROR;
- return (rx_npkts);
- }
- if ((meta & A_ONCHIP_FIFO_MEM_CORE_CHANNEL_MASK) != 0)
- device_printf(sc->atse_dev, "%s: unexpected "
- "channel %u\n", __func__, (meta &
- A_ONCHIP_FIFO_MEM_CORE_CHANNEL_MASK) >>
- A_ONCHIP_FIFO_MEM_CORE_CHANNEL_SHIFT);
-
- if (meta & A_ONCHIP_FIFO_MEM_CORE_SOP) {
- /*
- * There is no need to clear SOP between 1st
- * and subsequent packet data junks.
- */
- if (sc->atse_rx_buf_len != 0 &&
- (sc->atse_flags & ATSE_FLAGS_SOP_SEEN) == 0)
- {
- device_printf(sc->atse_dev, "%s: SOP "
- "without empty buffer: %u\n",
- __func__, sc->atse_rx_buf_len);
- /* XXX-BZ any better counter? */
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
- }
-
- if ((sc->atse_flags & ATSE_FLAGS_SOP_SEEN) == 0)
- {
- sc->atse_flags |= ATSE_FLAGS_SOP_SEEN;
- sc->atse_rx_buf_len = 0;
- }
- }
-#if 0 /* We had to read the data before we could access meta data. See above. */
- data = ATSE_RX_DATA_READ(sc);
-#endif
- /* Make sure to not overflow the mbuf data size. */
- if (sc->atse_rx_buf_len >= sc->atse_rx_m->m_len -
- sizeof(data)) {
- /*
- * XXX-BZ Error. We need more mbufs and are
- * not setup for this yet.
- */
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
- sc->atse_flags |= ATSE_FLAGS_ERROR;
- }
- if ((sc->atse_flags & ATSE_FLAGS_ERROR) == 0)
- /*
- * MUST keep this bcopy as m_data after m_adj
- * for IP header aligment is on half-word
- * and not word alignment.
- */
- bcopy(&data, (uint8_t *)(sc->atse_rx_m->m_data +
- sc->atse_rx_buf_len), sizeof(data));
- if (meta & A_ONCHIP_FIFO_MEM_CORE_EOP) {
- uint8_t empty;
-
- empty = (meta &
- A_ONCHIP_FIFO_MEM_CORE_EMPTY_MASK) >>
- A_ONCHIP_FIFO_MEM_CORE_EMPTY_SHIFT;
- sc->atse_rx_buf_len += (4 - empty);
-
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
- rx_npkts++;
-
- m = sc->atse_rx_m;
- m->m_pkthdr.len = m->m_len =
- sc->atse_rx_buf_len;
- sc->atse_rx_m = NULL;
-
- sc->atse_rx_buf_len = 0;
- sc->atse_flags &= ~ATSE_FLAGS_SOP_SEEN;
- if (sc->atse_flags & ATSE_FLAGS_ERROR) {
- sc->atse_flags &= ~ATSE_FLAGS_ERROR;
- m_freem(m);
- } else {
- m->m_pkthdr.rcvif = ifp;
- ATSE_UNLOCK(sc);
- (*ifp->if_input)(ifp, m);
- ATSE_LOCK(sc);
- }
-#ifdef DEVICE_POLLING
- if (ifp->if_capenable & IFCAP_POLLING) {
- if (sc->atse_rx_cycles <= 0)
- return (rx_npkts);
- sc->atse_rx_cycles--;
- }
-#endif
- goto outer; /* Need a new mbuf. */
- } else {
- sc->atse_rx_buf_len += sizeof(data);
- }
- } /* for */
-
- /* XXX-BZ could optimize in case of another packet waiting. */
- } while (fill > 0);
-
- return (rx_npkts);
-}
-
-
/*
* Report current media status.
*/
@@ -1395,168 +1011,6 @@
ATSE_UNLOCK(sc);
}
-static void
-atse_rx_intr(void *arg)
-{
- struct atse_softc *sc;
- struct ifnet *ifp;
- uint32_t rxe;
-
- sc = (struct atse_softc *)arg;
- ifp = sc->atse_ifp;
-
- ATSE_LOCK(sc);
-#ifdef DEVICE_POLLING
- if (ifp->if_capenable & IFCAP_POLLING) {
- ATSE_UNLOCK(sc);
- return;
- }
-#endif
-
- atse_intr_debug(sc, "rx");
- rxe = ATSE_RX_EVENT_READ(sc);
- if (rxe & (A_ONCHIP_FIFO_MEM_CORE_EVENT_OVERFLOW|
- A_ONCHIP_FIFO_MEM_CORE_EVENT_UNDERFLOW)) {
- /* XXX-BZ ERROR HANDLING. */
- atse_update_rx_err(sc, ((rxe &
- A_ONCHIP_FIFO_MEM_CORE_ERROR_MASK) >>
- A_ONCHIP_FIFO_MEM_CORE_ERROR_SHIFT) & 0xff);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
- }
-
- /*
- * There is considerable subtlety in the race-free handling of rx
- * interrupts: we must disable interrupts whenever we manipulate the
- * FIFO to prevent further interrupts from firing before we are done;
- * we must clear the event after processing to prevent the event from
- * being immediately reposted due to data remaining; we must clear the
- * event mask before reenabling interrupts or risk missing a positive
- * edge; and we must recheck everything after completing in case the
- * event posted between clearing events and reenabling interrupts. If
- * a race is experienced, we must restart the whole mechanism.
- */
- do {
- ATSE_RX_INTR_DISABLE(sc);
-#if 0
- sc->atse_rx_cycles = RX_CYCLES_IN_INTR;
-#endif
- atse_rx_locked(sc);
- ATSE_RX_EVENT_CLEAR(sc);
-
- /* Disable interrupts if interface is down. */
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ATSE_RX_INTR_ENABLE(sc);
- } while (!(ATSE_RX_STATUS_READ(sc) &
- A_ONCHIP_FIFO_MEM_CORE_STATUS_EMPTY));
- ATSE_UNLOCK(sc);
-
-}
-
-static void
-atse_tx_intr(void *arg)
-{
- struct atse_softc *sc;
- struct ifnet *ifp;
- uint32_t txe;
-
- sc = (struct atse_softc *)arg;
- ifp = sc->atse_ifp;
-
- ATSE_LOCK(sc);
-#ifdef DEVICE_POLLING
- if (ifp->if_capenable & IFCAP_POLLING) {
- ATSE_UNLOCK(sc);
- return;
- }
-#endif
-
- /* XXX-BZ build histogram. */
- atse_intr_debug(sc, "tx");
- txe = ATSE_TX_EVENT_READ(sc);
- if (txe & (A_ONCHIP_FIFO_MEM_CORE_EVENT_OVERFLOW|
- A_ONCHIP_FIFO_MEM_CORE_EVENT_UNDERFLOW)) {
- /* XXX-BZ ERROR HANDLING. */
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- }
-
- /*
- * There is also considerable subtlety in the race-free handling of
- * tx interrupts: all processing occurs with interrupts disabled to
- * prevent spurious refiring while transmit is in progress (which
- * could occur if the FIFO drains while sending -- quite likely); we
- * must not clear the event mask until after we've sent, also to
- * prevent spurious refiring; once we've cleared the event mask we can
- * reenable interrupts, but there is a possible race between clear and
- * enable, so we must recheck and potentially repeat the whole process
- * if it is detected.
- */
- do {
- ATSE_TX_INTR_DISABLE(sc);
- sc->atse_watchdog_timer = 0;
- atse_start_locked(ifp);
- ATSE_TX_EVENT_CLEAR(sc);
-
- /* Disable interrupts if interface is down. */
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ATSE_TX_INTR_ENABLE(sc);
- } while (ATSE_TX_PENDING(sc) &&
- !(ATSE_TX_STATUS_READ(sc) & A_ONCHIP_FIFO_MEM_CORE_STATUS_FULL));
- ATSE_UNLOCK(sc);
-}
-
-#ifdef DEVICE_POLLING
-static int
-atse_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
-{
- struct atse_softc *sc;
- int rx_npkts = 0;
-
- sc = ifp->if_softc;
- ATSE_LOCK(sc);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- ATSE_UNLOCK(sc);
- return (rx_npkts);
- }
-
- sc->atse_rx_cycles = count;
- rx_npkts = atse_rx_locked(sc);
- atse_start_locked(ifp);
-
- if (sc->atse_rx_cycles > 0 || cmd == POLL_AND_CHECK_STATUS) {
- uint32_t rx, tx;
-
- rx = ATSE_RX_EVENT_READ(sc);
- tx = ATSE_TX_EVENT_READ(sc);
-
- if (rx & (A_ONCHIP_FIFO_MEM_CORE_EVENT_OVERFLOW|
- A_ONCHIP_FIFO_MEM_CORE_EVENT_UNDERFLOW)) {
- /* XXX-BZ ERROR HANDLING. */
- atse_update_rx_err(sc, ((rx &
- A_ONCHIP_FIFO_MEM_CORE_ERROR_MASK) >>
- A_ONCHIP_FIFO_MEM_CORE_ERROR_SHIFT) & 0xff);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
- }
- if (tx & (A_ONCHIP_FIFO_MEM_CORE_EVENT_OVERFLOW|
- A_ONCHIP_FIFO_MEM_CORE_EVENT_UNDERFLOW)) {
- /* XXX-BZ ERROR HANDLING. */
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- }
- if (ATSE_TX_READ_FILL_LEVEL(sc) == 0)
- sc->atse_watchdog_timer = 0;
-
-#if 0
- if (/* Severe error; if only we could find out. */) {
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
- atse_init_locked(sc);
- }
-#endif
- }
-
- ATSE_UNLOCK(sc);
- return (rx_npkts);
-}
-#endif /* DEVICE_POLLING */
-
static struct atse_mac_stats_regs {
const char *name;
const char *descr; /* Mostly copied from Altera datasheet. */
@@ -1672,8 +1126,9 @@
s = CSR_READ_4(sc, offset);
error = sysctl_handle_int(oidp, &s, 0, req);
- if (error || !req->newptr)
+ if (error || !req->newptr) {
return (error);
+ }
return (0);
}
@@ -1715,8 +1170,9 @@
s = sc->atse_rx_err[offset];
error = sysctl_handle_int(oidp, &s, 0, req);
- if (error || !req->newptr)
+ if (error || !req->newptr) {
return (error);
+ }
return (0);
}
@@ -1736,8 +1192,9 @@
/* MAC statistics. */
for (i = 0; i < nitems(atse_mac_stats_regs); i++) {
if (atse_mac_stats_regs[i].name == NULL ||
- atse_mac_stats_regs[i].descr == NULL)
+ atse_mac_stats_regs[i].descr == NULL) {
continue;
+ }
SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
atse_mac_stats_regs[i].name, CTLTYPE_UINT|CTLFLAG_RD,
@@ -1748,8 +1205,9 @@
/* rx_err[]. */
for (i = 0; i < ATSE_RX_ERR_MAX; i++) {
if (atse_rx_err_stats_regs[i].name == NULL ||
- atse_rx_err_stats_regs[i].descr == NULL)
+ atse_rx_err_stats_regs[i].descr == NULL) {
continue;
+ }
SYSCTL_ADD_PROC(sctx, SYSCTL_CHILDREN(soid), OID_AUTO,
atse_rx_err_stats_regs[i].name, CTLTYPE_UINT|CTLFLAG_RD,
@@ -1769,6 +1227,55 @@
int error;
sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ /* Get xDMA controller */
+ sc->xdma_tx = xdma_ofw_get(sc->dev, "tx");
+ if (sc->xdma_tx == NULL) {
+ device_printf(dev, "Can't find DMA controller.\n");
+ return (ENXIO);
+ }
+
+ /* Alloc xDMA virtual channel. */
+ sc->xchan_tx = xdma_channel_alloc(sc->xdma_tx);
+ if (sc->xchan_tx == NULL) {
+ device_printf(dev, "Can't alloc virtual DMA channel.\n");
+ return (ENXIO);
+ }
+
+ /* Setup interrupt handler. */
+ error = xdma_setup_intr(sc->xchan_tx, atse_xdma_tx_intr, sc, &sc->ih_tx);
+ if (error) {
+ device_printf(sc->dev,
+ "Can't setup xDMA interrupt handler.\n");
+ return (ENXIO);
+ }
+
+ xdma_prep_sg(sc->xchan_tx, NUM_TX_DESC, TX_QUEUE_SIZE);
+
+ /* Get RX xDMA controller */
+ sc->xdma_rx = xdma_ofw_get(sc->dev, "rx");
+ if (sc->xdma_rx == NULL) {
+ device_printf(dev, "Can't find DMA controller.\n");
+ return (ENXIO);
+ }
+
+ /* Alloc xDMA virtual channel. */
+ sc->xchan_rx = xdma_channel_alloc(sc->xdma_rx);
+ if (sc->xchan_rx == NULL) {
+ device_printf(dev, "Can't alloc virtual DMA channel.\n");
+ return (ENXIO);
+ }
+
+ /* Setup interrupt handler. */
+ error = xdma_setup_intr(sc->xchan_rx, atse_xdma_rx_intr, sc, &sc->ih_rx);
+ if (error) {
+ device_printf(sc->dev,
+ "Can't setup xDMA interrupt handler.\n");
+ return (ENXIO);
+ }
+
+ xdma_prep_sg(sc->xchan_rx, NUM_RX_DESC, RX_QUEUE_SIZE);
atse_ethernet_option_bits_read(dev);
@@ -1777,8 +1284,6 @@
callout_init_mtx(&sc->atse_tick, &sc->atse_mtx, 0);
- sc->atse_tx_buf = malloc(ETHER_MAX_LEN_JUMBO, M_DEVBUF, M_WAITOK);
-
/*
* We are only doing single-PHY with this driver currently. The
* defaults would be right so that BASE_CFG_MDIO_ADDR0 points to the
@@ -1808,7 +1313,7 @@
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = atse_ioctl;
- ifp->if_start = atse_start;
+ ifp->if_transmit = atse_transmit;
ifp->if_init = atse_init;
IFQ_SET_MAXLEN(&ifp->if_snd, ATSE_TX_LIST_CNT - 1);
ifp->if_snd.ifq_drv_maxlen = ATSE_TX_LIST_CNT - 1;
@@ -1829,61 +1334,18 @@
ifp->if_hdrlen = sizeof(struct ether_vlan_header);
ifp->if_capabilities |= IFCAP_VLAN_MTU;
ifp->if_capenable = ifp->if_capabilities;
-#ifdef DEVICE_POLLING
- /* We will enable polling by default if no irqs available. See below. */
- ifp->if_capabilities |= IFCAP_POLLING;
-#endif
-
- /* Hook up interrupts. */
- if (sc->atse_rx_irq_res != NULL) {
- error = bus_setup_intr(dev, sc->atse_rx_irq_res, INTR_TYPE_NET |
- INTR_MPSAFE, NULL, atse_rx_intr, sc, &sc->atse_rx_intrhand);
- if (error != 0) {
- device_printf(dev, "enabling RX IRQ failed\n");
- ether_ifdetach(ifp);
- goto err;
- }
- }
-
- if (sc->atse_tx_irq_res != NULL) {
- error = bus_setup_intr(dev, sc->atse_tx_irq_res, INTR_TYPE_NET |
- INTR_MPSAFE, NULL, atse_tx_intr, sc, &sc->atse_tx_intrhand);
- if (error != 0) {
- bus_teardown_intr(dev, sc->atse_rx_irq_res,
- sc->atse_rx_intrhand);
- device_printf(dev, "enabling TX IRQ failed\n");
- ether_ifdetach(ifp);
- goto err;
- }
- }
-
- if ((ifp->if_capenable & IFCAP_POLLING) != 0 ||
- (sc->atse_rx_irq_res == NULL && sc->atse_tx_irq_res == NULL)) {
-#ifdef DEVICE_POLLING
- /* If not on and no IRQs force it on. */
- if (sc->atse_rx_irq_res == NULL && sc->atse_tx_irq_res == NULL){
- ifp->if_capenable |= IFCAP_POLLING;
- device_printf(dev, "forcing to polling due to no "
- "interrupts\n");
- }
- error = ether_poll_register(atse_poll, ifp);
- if (error != 0)
- goto err;
-#else
- device_printf(dev, "no DEVICE_POLLING in kernel and no IRQs\n");
- error = ENXIO;
-#endif
- } else {
- ATSE_RX_INTR_ENABLE(sc);
- ATSE_TX_INTR_ENABLE(sc);
- }
err:
- if (error != 0)
+ if (error != 0) {
atse_detach(dev);
+ }
- if (error == 0)
+ if (error == 0) {
atse_sysctl_stats_attach(dev);
+ }
+
+ atse_rx_enqueue(sc, (NUM_RX_DESC * 2));
+ xdma_queue_submit(sc->xchan_rx);
return (error);
}
@@ -1899,11 +1361,6 @@
device_get_nameunit(dev)));
ifp = sc->atse_ifp;
-#ifdef DEVICE_POLLING
- if (ifp->if_capenable & IFCAP_POLLING)
- ether_poll_deregister(ifp);
-#endif
-
/* Only cleanup if attach succeeded. */
if (device_is_attached(dev)) {
ATSE_LOCK(sc);
@@ -1912,21 +1369,13 @@
callout_drain(&sc->atse_tick);
ether_ifdetach(ifp);
}
- if (sc->atse_miibus != NULL)
+ if (sc->atse_miibus != NULL) {
device_delete_child(dev, sc->atse_miibus);
+ }
- if (sc->atse_tx_intrhand)
- bus_teardown_intr(dev, sc->atse_tx_irq_res,
- sc->atse_tx_intrhand);
- if (sc->atse_rx_intrhand)
- bus_teardown_intr(dev, sc->atse_rx_irq_res,
- sc->atse_rx_intrhand);
-
- if (ifp != NULL)
+ if (ifp != NULL) {
if_free(ifp);
-
- if (sc->atse_tx_buf != NULL)
- free(sc->atse_tx_buf, M_DEVBUF);
+ }
mtx_destroy(&sc->atse_mtx);
@@ -1941,36 +1390,6 @@
sc = device_get_softc(dev);
- if (sc->atse_txc_mem_res != NULL) {
- bus_release_resource(dev, SYS_RES_MEMORY, sc->atse_txc_mem_rid,
- sc->atse_txc_mem_res);
- sc->atse_txc_mem_res = NULL;
- }
- if (sc->atse_tx_mem_res != NULL) {
- bus_release_resource(dev, SYS_RES_MEMORY, sc->atse_tx_mem_rid,
- sc->atse_tx_mem_res);
- sc->atse_tx_mem_res = NULL;
- }
- if (sc->atse_tx_irq_res != NULL) {
- bus_release_resource(dev, SYS_RES_IRQ, sc->atse_tx_irq_rid,
- sc->atse_tx_irq_res);
- sc->atse_tx_irq_res = NULL;
- }
- if (sc->atse_rxc_mem_res != NULL) {
- bus_release_resource(dev, SYS_RES_MEMORY, sc->atse_rxc_mem_rid,
- sc->atse_rxc_mem_res);
- sc->atse_rxc_mem_res = NULL;
- }
- if (sc->atse_rx_mem_res != NULL) {
- bus_release_resource(dev, SYS_RES_MEMORY, sc->atse_rx_mem_rid,
- sc->atse_rx_mem_res);
- sc->atse_rx_mem_res = NULL;
- }
- if (sc->atse_rx_irq_res != NULL) {
- bus_release_resource(dev, SYS_RES_IRQ, sc->atse_rx_irq_rid,
- sc->atse_rx_irq_res);
- sc->atse_rx_irq_res = NULL;
- }
if (sc->atse_mem_res != NULL) {
bus_release_resource(dev, SYS_RES_MEMORY, sc->atse_mem_rid,
sc->atse_mem_res);
@@ -1999,6 +1418,7 @@
atse_miibus_readreg(device_t dev, int phy, int reg)
{
struct atse_softc *sc;
+ int val;
sc = device_get_softc(dev);
@@ -2006,10 +1426,13 @@
* We currently do not support re-mapping of MDIO space on-the-fly
* but de-facto hard-code the phy#.
*/
- if (phy != sc->atse_phy_addr)
+ if (phy != sc->atse_phy_addr) {
return (0);
+ }
- return (PHY_READ_2(sc, reg));
+ val = PHY_READ_2(sc, reg);
+
+ return (val);
}
int
@@ -2023,8 +1446,9 @@
* We currently do not support re-mapping of MDIO space on-the-fly
* but de-facto hard-code the phy#.
*/
- if (phy != sc->atse_phy_addr)
+ if (phy != sc->atse_phy_addr) {
return (0);
+ }
PHY_WRITE_2(sc, reg, data);
return (0);
@@ -2044,8 +1468,9 @@
mii = device_get_softc(sc->atse_miibus);
ifp = sc->atse_ifp;
if (mii == NULL || ifp == NULL ||
- (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
return;
+ }
val4 = CSR_READ_4(sc, BASE_CFG_COMMAND_CONFIG);
@@ -2077,15 +1502,17 @@
}
if ((sc->atse_flags & ATSE_FLAGS_LINK) == 0) {
- /* XXX-BZ need to stop the MAC? */
+ /* Need to stop the MAC? */
return;
}
- if (IFM_OPTIONS(mii->mii_media_active & IFM_FDX) != 0)
+ if (IFM_OPTIONS(mii->mii_media_active & IFM_FDX) != 0) {
val4 &= ~BASE_CFG_COMMAND_CONFIG_HD_ENA;
- else
+ } else {
val4 |= BASE_CFG_COMMAND_CONFIG_HD_ENA;
- /* XXX-BZ flow control? */
+ }
+
+ /* flow control? */
/* Make sure the MAC is activated. */
val4 |= BASE_CFG_COMMAND_CONFIG_TX_ENA;
@@ -2094,4 +1521,5 @@
CSR_WRITE_4(sc, BASE_CFG_COMMAND_CONFIG, val4);
}
-/* end */
+MODULE_DEPEND(atse, ether, 1, 1, 1);
+MODULE_DEPEND(atse, miibus, 1, 1, 1);
Index: sys/dev/altera/atse/if_atse_fdt.c
===================================================================
--- sys/dev/altera/atse/if_atse_fdt.c
+++ sys/dev/altera/atse/if_atse_fdt.c
@@ -50,7 +50,6 @@
#include
#include
-
#include
#include
#include
@@ -68,11 +67,13 @@
if (!ofw_bus_status_okay(dev))
return (ENXIO);
- if (ofw_bus_is_compatible(dev, "altera,atse")) {
- device_set_desc(dev, "Altera Triple-Speed Ethernet MegaCore");
- return (BUS_PROBE_DEFAULT);
+ if (!ofw_bus_is_compatible(dev, "altera,atse")) {
+ return (ENXIO);
}
- return (ENXIO);
+
+ device_set_desc(dev, "Altera Triple-Speed Ethernet MegaCore");
+
+ return (BUS_PROBE_DEFAULT);
}
static int
@@ -98,8 +99,10 @@
&sc->atse_mem_rid, RF_ACTIVE);
if (sc->atse_mem_res == NULL) {
device_printf(dev, "failed to map memory for ctrl region\n");
- error = ENXIO;
- goto err;
+ /* Cleanup. */
+ atse_detach_resources(dev);
+
+ return (ENXIO);
}
if (bootverbose)
device_printf(sc->atse_dev, "MAC ctrl region at mem %p-%p\n",
@@ -107,91 +110,15 @@
(void *)(rman_get_start(sc->atse_mem_res) +
rman_get_size(sc->atse_mem_res)));
- /*
- * RX and RXC FIFO memory regions.
- * 0x00: 2 * 32bit FIFO data,
- * 0x20: 8 * 32bit FIFO ctrl, Avalon-ST Sink to Avalon-MM R-Slave.
- */
- sc->atse_rx_mem_rid = 1;
- sc->atse_rx_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
- &sc->atse_rx_mem_rid, RF_ACTIVE);
- if (sc->atse_rx_mem_res == NULL) {
- device_printf(dev, "failed to map memory for RX FIFO\n");
- error = ENXIO;
- goto err;
- }
- if (bootverbose)
- device_printf(sc->atse_dev, "RX FIFO at mem %p-%p\n",
- (void *)rman_get_start(sc->atse_rx_mem_res),
- (void *)(rman_get_start(sc->atse_rx_mem_res) +
- rman_get_size(sc->atse_rx_mem_res)));
-
- sc->atse_rxc_mem_rid = 2;
- sc->atse_rxc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
- &sc->atse_rxc_mem_rid, RF_ACTIVE);
- if (sc->atse_rxc_mem_res == NULL) {
- device_printf(dev, "failed to map memory for RXC FIFO\n");
- error = ENXIO;
- goto err;
- }
- if (bootverbose)
- device_printf(sc->atse_dev, "RXC FIFO at mem %p-%p\n",
- (void *)rman_get_start(sc->atse_rxc_mem_res),
- (void *)(rman_get_start(sc->atse_rxc_mem_res) +
- rman_get_size(sc->atse_rxc_mem_res)));
+ error = atse_attach(dev);
+ if (error) {
+ /* Cleanup. */
+ atse_detach_resources(dev);
- /*
- * TX and TXC FIFO memory regions.
- * 0x00: 2 * 32bit FIFO data,
- * 0x20: 8 * 32bit FIFO ctrl, Avalon-MM W-Slave to Avalon-ST Source.
- */
- sc->atse_tx_mem_rid = 3;
- sc->atse_tx_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
- &sc->atse_tx_mem_rid, RF_ACTIVE);
- if (sc->atse_tx_mem_res == NULL) {
- device_printf(dev, "failed to map memory for TX FIFO\n");
- error = ENXIO;
- goto err;
+ return (error);
}
- if (bootverbose)
- device_printf(sc->atse_dev, "TX FIFO at mem %p-%p\n",
- (void *)rman_get_start(sc->atse_tx_mem_res),
- (void *)(rman_get_start(sc->atse_tx_mem_res) +
- rman_get_size(sc->atse_tx_mem_res)));
-
- sc->atse_txc_mem_rid = 4;
- sc->atse_txc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
- &sc->atse_txc_mem_rid, RF_ACTIVE);
- if (sc->atse_txc_mem_res == NULL) {
- device_printf(dev, "failed to map memory for TXC FIFO\n");
- error = ENXIO;
- goto err;
- }
- if (bootverbose)
- device_printf(sc->atse_dev, "TXC FIFO at mem %p-%p\n",
- (void *)rman_get_start(sc->atse_txc_mem_res),
- (void *)(rman_get_start(sc->atse_txc_mem_res) +
- rman_get_size(sc->atse_txc_mem_res)));
-
- /* (Optional) RX and TX IRQ. */
- sc->atse_rx_irq_rid = 0;
- sc->atse_rx_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
- &sc->atse_rx_irq_rid, RF_ACTIVE | RF_SHAREABLE);
- sc->atse_tx_irq_rid = 1;
- sc->atse_tx_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
- &sc->atse_tx_irq_rid, RF_ACTIVE | RF_SHAREABLE);
-
- error = atse_attach(dev);
- if (error)
- goto err;
return (0);
-
-err:
- /* Cleanup. */
- atse_detach_resources(dev);
-
- return (error);
}
static device_method_t atse_methods_fdt[] = {
@@ -216,5 +143,3 @@
DRIVER_MODULE(atse, simplebus, atse_driver_fdt, atse_devclass, 0, 0);
DRIVER_MODULE(miibus, atse, miibus_driver, miibus_devclass, 0, 0);
-
-/* end */
Index: sys/dev/altera/atse/if_atse_nexus.c
===================================================================
--- sys/dev/altera/atse/if_atse_nexus.c
+++ sys/dev/altera/atse/if_atse_nexus.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2012,2013 Bjoern A. Zeeb
+ * Copyright (c) 2012, 2013 Bjoern A. Zeeb
* All rights reserved.
*
* This software was developed by SRI International and the University of
@@ -64,7 +64,7 @@
* Device routines for interacting with nexus (probe, attach, detach) & helpers.
* XXX We should add suspend/resume later.
*/
-static int
+static int __unused
atse_resource_int(device_t dev, const char *resname, int *v)
{
int error;
@@ -80,7 +80,7 @@
return (0);
}
-static int
+static int __unused
atse_resource_long(device_t dev, const char *resname, long *v)
{
int error;
@@ -99,37 +99,9 @@
static int
atse_probe_nexus(device_t dev)
{
- struct resource *res;
- long l;
- int error, rid;
-
- /*
- * It is almost impossible to properly probe this device. We must
- * rely on hints being set correctly. So try to get hints and
- * one memory mapping. Must cleanup and do again in attach but
- * should not probe successfully if not able to attach later.
- */
- error = atse_resource_int(dev, "rx_irq", &rid);
- error += atse_resource_long(dev, "rx_maddr", &l);
- error += atse_resource_long(dev, "rx_msize", &l);
- error += atse_resource_long(dev, "rxc_maddr", &l);
- error += atse_resource_long(dev, "rxc_msize", &l);
- error += atse_resource_int(dev, "tx_irq", &rid);
- error += atse_resource_long(dev, "tx_maddr", &l);
- error += atse_resource_long(dev, "tx_msize", &l);
- error += atse_resource_long(dev, "txc_maddr", &l);
- error += atse_resource_long(dev, "txc_msize", &l);
- if (error != 0)
- return (ENXIO);
-
- rid = 0;
- res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (res == NULL)
- return (ENXIO);
- bus_release_resource(dev, SYS_RES_MEMORY, rid, res);
- /* Success. */
device_set_desc(dev, "Altera Triple-Speed Ethernet MegaCore");
+
return (BUS_PROBE_NOWILDCARD);
}
@@ -143,20 +115,6 @@
sc->atse_dev = dev;
sc->atse_unit = device_get_unit(dev);
- /* Get RX and TX IRQ and FIFO information from hints. */
- error = atse_resource_int(dev, "rx_irq", &sc->atse_rx_irq);
- error += atse_resource_long(dev, "rx_maddr", &sc->atse_rx_maddr);
- error += atse_resource_long(dev, "rx_msize", &sc->atse_rx_msize);
- error += atse_resource_long(dev, "rxc_maddr", &sc->atse_rxc_maddr);
- error += atse_resource_long(dev, "rxc_msize", &sc->atse_rxc_msize);
- error += atse_resource_int(dev, "tx_irq", &sc->atse_tx_irq);
- error += atse_resource_long(dev, "tx_maddr", &sc->atse_tx_maddr);
- error += atse_resource_long(dev, "tx_msize", &sc->atse_tx_msize);
- error += atse_resource_long(dev, "txc_maddr", &sc->atse_txc_maddr);
- error += atse_resource_long(dev, "txc_msize", &sc->atse_txc_msize);
- if (error != 0)
- return (error);
-
/* Avalon-MM, atse management register region. */
sc->atse_mem_rid = 0;
sc->atse_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
@@ -166,71 +124,14 @@
return (ENXIO);
}
- /*
- * (Optional) RX IRQ and memory mapped regions.
- * 0x00: 2 * 32bit FIFO data,
- * 0x20: 8 * 32bit FIFO ctrl, Avalon-ST Sink to Avalon-MM R-Slave.
- */
- sc->atse_rx_irq_rid = 0;
- sc->atse_rx_irq_res = bus_alloc_resource(dev, SYS_RES_IRQ,
- &sc->atse_rx_irq_rid, sc->atse_rx_irq, sc->atse_rx_irq, 1,
- RF_ACTIVE | RF_SHAREABLE);
-
- sc->atse_rx_mem_rid = 0;
- sc->atse_rx_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
- &sc->atse_rx_mem_rid, sc->atse_rx_maddr, sc->atse_rx_maddr +
- sc->atse_rx_msize, sc->atse_rx_msize, RF_ACTIVE);
- if (sc->atse_rx_mem_res == NULL) {
- device_printf(dev, "failed to map memory for RX\n");
- goto err;
- }
- sc->atse_rxc_mem_rid = 0;
- sc->atse_rxc_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
- &sc->atse_rxc_mem_rid, sc->atse_rxc_maddr, sc->atse_rxc_maddr +
- sc->atse_rxc_msize, sc->atse_rxc_msize, RF_ACTIVE);
- if (sc->atse_rxc_mem_res == NULL) {
- device_printf(dev, "failed to map memory for RX control\n");
- goto err;
- }
-
- /*
- * (Optional) TX IRQ and memory mapped regions.
- * 0x00: 2 * 32bit FIFO data,
- * 0x20: 8 * 32bit FIFO ctrl, Avalon-MM W-Slave to Avalon-ST Source.
- */
- sc->atse_tx_irq_rid = 0;
- sc->atse_tx_irq_res = bus_alloc_resource(dev, SYS_RES_IRQ,
- &sc->atse_tx_irq_rid, sc->atse_tx_irq, sc->atse_tx_irq, 1,
- RF_ACTIVE | RF_SHAREABLE);
-
- sc->atse_tx_mem_rid = 0;
- sc->atse_tx_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
- &sc->atse_tx_mem_rid, sc->atse_tx_maddr, sc->atse_tx_maddr +
- sc->atse_tx_msize, sc->atse_tx_msize, RF_ACTIVE);
- if (sc->atse_tx_mem_res == NULL) {
- device_printf(dev, "failed to map memory for TX\n");
- goto err;
- }
- sc->atse_txc_mem_rid = 0;
- sc->atse_txc_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
- &sc->atse_txc_mem_rid, sc->atse_txc_maddr, sc->atse_txc_maddr +
- sc->atse_txc_msize, sc->atse_txc_msize, RF_ACTIVE);
- if (sc->atse_txc_mem_res == NULL) {
- device_printf(dev, "failed to map memory for TX control\n");
- goto err;
- }
-
error = atse_attach(dev);
- if (error)
- goto err;
+ if (error) {
+ /* Cleanup. */
+ atse_detach_resources(dev);
+ return (error);
+ }
return (0);
-
-err:
- /* Cleanup. */
- atse_detach_resources(dev);
-
- return (error);
}
static device_method_t atse_methods_nexus[] = {
@@ -255,5 +156,3 @@
DRIVER_MODULE(atse, nexus, atse_driver_nexus, atse_devclass, 0, 0);
DRIVER_MODULE(miibus, atse, miibus_driver, miibus_devclass, 0, 0);
-
-/* end */
Index: sys/dev/altera/atse/if_atsereg.h
===================================================================
--- sys/dev/altera/atse/if_atsereg.h
+++ sys/dev/altera/atse/if_atsereg.h
@@ -33,6 +33,8 @@
#ifndef _DEV_IF_ATSEREG_H
#define _DEV_IF_ATSEREG_H
+#include
+
#define ATSE_VENDOR 0x6af7
#define ATSE_DEVICE 0x00bd
@@ -405,40 +407,13 @@
struct atse_softc {
struct ifnet *atse_ifp;
- struct mbuf *atse_rx_m;
- struct mbuf *atse_tx_m;
- uint8_t *atse_tx_buf;
struct resource *atse_mem_res;
- struct resource *atse_rx_irq_res;
- struct resource *atse_rx_mem_res;
- struct resource *atse_rxc_mem_res;
- struct resource *atse_tx_irq_res;
- struct resource *atse_tx_mem_res;
- struct resource *atse_txc_mem_res;
device_t atse_miibus;
device_t atse_dev;
int atse_unit;
int atse_mem_rid;
- int atse_rx_irq_rid;
- int atse_rx_mem_rid;
- int atse_rxc_mem_rid;
- int atse_tx_irq_rid;
- int atse_tx_mem_rid;
- int atse_txc_mem_rid;
int atse_phy_addr;
int atse_if_flags;
- int atse_rx_irq;
- int atse_tx_irq;
- u_long atse_rx_maddr;
- u_long atse_rx_msize;
- u_long atse_tx_maddr;
- u_long atse_tx_msize;
- u_long atse_rxc_maddr;
- u_long atse_rxc_msize;
- u_long atse_txc_maddr;
- u_long atse_txc_msize;
- void *atse_rx_intrhand;
- void *atse_tx_intrhand;
bus_addr_t atse_bmcr0;
bus_addr_t atse_bmcr1;
uint32_t atse_flags;
@@ -452,10 +427,6 @@
#define ATSE_ETH_ADDR_SUPP3 0x08
#define ATSE_ETH_ADDR_SUPP4 0x10
#define ATSE_ETH_ADDR_ALL 0x1f
- uint16_t atse_watchdog_timer;
- uint16_t atse_tx_m_offset;
- uint16_t atse_tx_buf_len;
- uint16_t atse_rx_buf_len;
int16_t atse_rx_cycles; /* POLLING */
#define RX_CYCLES_IN_INTR 5
uint32_t atse_rx_err[6];
@@ -468,6 +439,17 @@
#define ATSE_RX_ERR_MAX 6
struct callout atse_tick;
struct mtx atse_mtx;
+ device_t dev;
+
+ /* xDMA */
+ xdma_controller_t *xdma_tx;
+ xdma_channel_t *xchan_tx;
+ void *ih_tx;
+ int txcount;
+
+ xdma_controller_t *xdma_rx;
+ xdma_channel_t *xchan_rx;
+ void *ih_rx;
};
@@ -482,5 +464,3 @@
extern devclass_t atse_devclass;
#endif /* _DEV_IF_ATSEREG_H */
-
-/* end */