Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F135647110
D9618.id25420.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
55 KB
Referenced Files
None
Subscribers
None
D9618.id25420.diff
View Options
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 <br@bsdpad.com>
* All rights reserved.
*
* This software was developed by SRI International and the University of
@@ -86,17 +87,14 @@
#include <dev/mii/miivar.h>
#include <dev/altera/atse/if_atsereg.h>
-#include <dev/altera/atse/a_api.h>
-
-MODULE_DEPEND(atse, ether, 1, 1, 1);
-MODULE_DEPEND(atse, miibus, 1, 1, 1);
+#include <dev/xdma/xdma.h>
+#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 <machine/cache.h>
/* 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 <dev/mii/mii.h>
#include <dev/mii/miivar.h>
-
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
@@ -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 <dev/xdma/xdma.h>
+
#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 */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 12, 2:16 PM (19 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25214390
Default Alt Text
D9618.id25420.diff (55 KB)
Attached To
Mode
D9618: xDMA support for atse(4)
Attached
Detach File
Event Timeline
Log In to Comment