Port-arm archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Support for enhanced descriptors in dwc_gmac
The following patch adds support for enhanced descriptors to the
dwc_gmac driver (awge). This support is not optional for recent chips:
the descriptors are either standard or enhanced, and there is no way to
choose.
The patch is not cleaned as far as debug messages are concerned but I
need some input first anyway:
. I use AWIN_GMAC_DMA_HWFEATURES to detect the use of enhanced
descriptors but in sys/dev/ic/dwc_gmac_reg.h the following question
is raised. Does anyone have a clue whether it's safe to use this
test?
#define AWIN_GMAC_DMA_HWFEATURES 0x1058 /* not always implemented? */
. I need to remove AWIN_GMAC_MAC_INT_RGSMII from AWIN_DEF_MAC_INTRMASK
for awge to work on the DE0 nanosoc. I think it does no harm to other
users of awge but again, if someone has a clue...
As a very partial answer to the two questions above, this patch works
correctly also on my Olinuxino Lime 2 A20.
Regards,
Aymeric
diff --git a/sys/dev/ic/dwc_gmac.c b/sys/dev/ic/dwc_gmac.c
index b8576929d8fd..b06034561771 100644
--- a/sys/dev/ic/dwc_gmac.c
+++ b/sys/dev/ic/dwc_gmac.c
@@ -43,7 +43,9 @@
__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.52 2018/07/18 23:10:27 sevan Exp $");
-/* #define DWC_GMAC_DEBUG 1 */
+#if 0
+#define DWC_GMAC_DEBUG 1
+#endif
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -100,6 +102,53 @@ static void dwc_gmac_rx_intr(struct dwc_gmac_softc *sc);
static void dwc_gmac_setmulti(struct dwc_gmac_softc *sc);
static int dwc_gmac_ifflags_cb(struct ethercom *);
static uint32_t bitrev32(uint32_t x);
+static void dwc_gmac_desc_set_owned_by_dev(struct dwc_gmac_dev_dmadesc *);
+static int dwc_gmac_desc_is_owned_by_dev(struct dwc_gmac_dev_dmadesc *);
+static void dwc_gmac_desc_std_set_len(struct dwc_gmac_dev_dmadesc *, int);
+static int dwc_gmac_desc_std_get_len(struct dwc_gmac_dev_dmadesc *);
+static void dwc_gmac_desc_std_tx_init_flags(struct dwc_gmac_dev_dmadesc *);
+static void dwc_gmac_desc_std_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *);
+static void dwc_gmac_desc_std_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *);
+static void dwc_gmac_desc_std_rx_init_flags(struct dwc_gmac_dev_dmadesc *);
+static int dwc_gmac_desc_std_rx_has_error(struct dwc_gmac_dev_dmadesc *);
+static void dwc_gmac_desc_enh_set_len(struct dwc_gmac_dev_dmadesc *, int);
+static int dwc_gmac_desc_enh_get_len(struct dwc_gmac_dev_dmadesc *);
+static void dwc_gmac_desc_enh_tx_init_flags(struct dwc_gmac_dev_dmadesc *);
+static void dwc_gmac_desc_enh_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *);
+static void dwc_gmac_desc_enh_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *);
+static void dwc_gmac_desc_enh_rx_init_flags(struct dwc_gmac_dev_dmadesc *);
+static int dwc_gmac_desc_enh_rx_has_error(struct dwc_gmac_dev_dmadesc *);
+
+static const struct dwc_gmac_desc_methods desc_methods_standard = {
+ .tx_init_flags = dwc_gmac_desc_std_tx_init_flags,
+ .tx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
+ .tx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
+ .tx_set_len = dwc_gmac_desc_std_set_len,
+ .tx_set_first_frag = dwc_gmac_desc_std_tx_set_first_frag,
+ .tx_set_last_frag = dwc_gmac_desc_std_tx_set_last_frag,
+ .rx_init_flags = dwc_gmac_desc_std_rx_init_flags,
+ .rx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
+ .rx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
+ .rx_set_len = dwc_gmac_desc_std_set_len,
+ .rx_get_len = dwc_gmac_desc_std_get_len,
+ .rx_has_error = dwc_gmac_desc_std_rx_has_error
+};
+
+static const struct dwc_gmac_desc_methods desc_methods_enhanced = {
+ .tx_init_flags = dwc_gmac_desc_enh_tx_init_flags,
+ .tx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
+ .tx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
+ .tx_set_len = dwc_gmac_desc_enh_set_len,
+ .tx_set_first_frag = dwc_gmac_desc_enh_tx_set_first_frag,
+ .tx_set_last_frag = dwc_gmac_desc_enh_tx_set_last_frag,
+ .rx_init_flags = dwc_gmac_desc_enh_rx_init_flags,
+ .rx_set_owned_by_dev = dwc_gmac_desc_set_owned_by_dev,
+ .rx_is_owned_by_dev = dwc_gmac_desc_is_owned_by_dev,
+ .rx_set_len = dwc_gmac_desc_enh_set_len,
+ .rx_get_len = dwc_gmac_desc_enh_get_len,
+ .rx_has_error = dwc_gmac_desc_enh_rx_has_error
+};
+
#define TX_DESC_OFFSET(N) ((AWGE_RX_RING_COUNT+(N)) \
*sizeof(struct dwc_gmac_dev_dmadesc))
@@ -120,9 +169,16 @@ static uint32_t bitrev32(uint32_t x);
GMAC_DMA_INT_UNE|GMAC_DMA_INT_OVE| \
GMAC_DMA_INT_TJE)
+#if 0
#define AWIN_DEF_MAC_INTRMASK \
(AWIN_GMAC_MAC_INT_TSI | AWIN_GMAC_MAC_INT_ANEG | \
AWIN_GMAC_MAC_INT_LINKCHG | AWIN_GMAC_MAC_INT_RGSMII)
+#else
+/* XXX we must not mask INT_RGSMII, but I don't know why */
+#define AWIN_DEF_MAC_INTRMASK \
+ (AWIN_GMAC_MAC_INT_TSI | AWIN_GMAC_MAC_INT_ANEG | \
+ AWIN_GMAC_MAC_INT_LINKCHG)
+#endif
#ifdef DWC_GMAC_DEBUG
static void dwc_gmac_dump_dma(struct dwc_gmac_softc *sc);
@@ -194,6 +250,12 @@ dwc_gmac_attach(struct dwc_gmac_softc *sc, uint32_t mii_clk)
aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n",
ether_sprintf(enaddr));
+ if (bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_HWFEATURES) &
+ GMAC_DMA_FEAT_ENHANCED_DESC)
+ sc->sc_descm = &desc_methods_enhanced;
+ else
+ sc->sc_descm = &desc_methods_standard;
+
/*
* Allocate Tx and Rx rings
*/
@@ -444,10 +506,9 @@ dwc_gmac_alloc_rx_ring(struct dwc_gmac_softc *sc,
next = RX_NEXT(i);
desc->ddesc_next = htole32(ring->r_physaddr
+ next * sizeof(*desc));
- desc->ddesc_cntl = htole32(
- __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) |
- DDESC_CNTL_RXCHAIN);
- desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV);
+ sc->sc_descm->rx_init_flags(desc);
+ sc->sc_descm->rx_set_len(desc, AWGE_MAX_PACKET);
+ sc->sc_descm->rx_set_owned_by_dev(desc);
}
bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0,
@@ -473,10 +534,9 @@ dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc,
mutex_enter(&ring->r_mtx);
for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
desc = &sc->sc_rxq.r_desc[i];
- desc->ddesc_cntl = htole32(
- __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) |
- DDESC_CNTL_RXCHAIN);
- desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV);
+ sc->sc_descm->rx_init_flags(desc);
+ sc->sc_descm->rx_set_len(desc, AWGE_MAX_PACKET);
+ sc->sc_descm->rx_set_owned_by_dev(desc);
}
bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0,
@@ -810,6 +870,9 @@ dwc_gmac_init_locked(struct ifnet *ifp)
} else {
ffilt |= AWIN_GMAC_MAC_FFILT_DBF;
}
+#if 0
+ ffilt |= AWIN_GMAC_MAC_FFILT_PR;
+#endif
bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt);
/*
@@ -891,11 +954,13 @@ dwc_gmac_start_locked(struct ifnet *ifp)
dwc_gmac_txdesc_sync(sc, start, sc->sc_txq.t_cur,
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
- bus_space_write_4(sc->sc_bst, sc->sc_bsh,
- AWIN_GMAC_DMA_TXPOLL, ~0U);
-#ifdef DWC_GMAC_DEBUG
+#if 0 && defined(DWC_GMAC_DEBUG)
dwc_dump_status(sc);
+ dwc_gmac_dump_dma(sc);
+ dwc_gmac_dump_rx_desc(sc);
#endif
+ bus_space_write_4(sc->sc_bst, sc->sc_bsh,
+ AWIN_GMAC_DMA_TXPOLL, ~0U);
}
}
@@ -942,7 +1007,6 @@ dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0)
struct dwc_gmac_dev_dmadesc *desc = NULL;
struct dwc_gmac_tx_data *data = NULL;
bus_dmamap_t map;
- uint32_t flags, len, status;
int error, i, first;
#ifdef DWC_GMAC_DEBUG
@@ -966,38 +1030,37 @@ dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0)
return ENOBUFS;
}
- flags = DDESC_CNTL_TXFIRST|DDESC_CNTL_TXCHAIN;
- status = 0;
for (i = 0; i < map->dm_nsegs; i++) {
data = &sc->sc_txq.t_data[sc->sc_txq.t_cur];
desc = &sc->sc_txq.t_desc[sc->sc_txq.t_cur];
desc->ddesc_data = htole32(map->dm_segs[i].ds_addr);
- len = __SHIFTIN(map->dm_segs[i].ds_len, DDESC_CNTL_SIZE1MASK);
#ifdef DWC_GMAC_DEBUG
aprint_normal_dev(sc->sc_dev, "enqueing desc #%d data %08lx "
- "len %lu (flags: %08x, len: %08x)\n", sc->sc_txq.t_cur,
+ "len %lu\n", sc->sc_txq.t_cur,
(unsigned long)map->dm_segs[i].ds_addr,
- (unsigned long)map->dm_segs[i].ds_len,
- flags, len);
+ (unsigned long)map->dm_segs[i].ds_len);
#endif
- desc->ddesc_cntl = htole32(len|flags);
- flags &= ~DDESC_CNTL_TXFIRST;
+ sc->sc_descm->tx_init_flags(desc);
+ sc->sc_descm->tx_set_len(desc, map->dm_segs[i].ds_len);
+
+ if (i == 0)
+ sc->sc_descm->tx_set_first_frag(desc);
/*
* Defer passing ownership of the first descriptor
* until we are done.
*/
- desc->ddesc_status = htole32(status);
- status |= DDESC_STATUS_OWNEDBYDEV;
+ if (i != 0)
+ sc->sc_descm->tx_set_owned_by_dev(desc);
sc->sc_txq.t_queued++;
sc->sc_txq.t_cur = TX_NEXT(sc->sc_txq.t_cur);
}
- desc->ddesc_cntl |= htole32(DDESC_CNTL_TXLAST|DDESC_CNTL_TXINT);
+ sc->sc_descm->tx_set_last_frag(desc);
data->td_m = m0;
data->td_active = map;
@@ -1006,8 +1069,10 @@ dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0)
BUS_DMASYNC_PREWRITE);
/* Pass first to device */
- sc->sc_txq.t_desc[first].ddesc_status =
- htole32(DDESC_STATUS_OWNEDBYDEV);
+ sc->sc_descm->tx_set_owned_by_dev(&sc->sc_txq.t_desc[first]);
+
+ bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
+ BUS_DMASYNC_PREWRITE);
return 0;
}
@@ -1087,7 +1152,6 @@ dwc_gmac_tx_intr(struct dwc_gmac_softc *sc)
struct ifnet *ifp = &sc->sc_ec.ec_if;
struct dwc_gmac_tx_data *data;
struct dwc_gmac_dev_dmadesc *desc;
- uint32_t status;
int i, nsegs;
mutex_enter(&sc->sc_txq.t_mtx);
@@ -1108,8 +1172,7 @@ dwc_gmac_tx_intr(struct dwc_gmac_softc *sc)
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
desc = &sc->sc_txq.t_desc[i];
- status = le32toh(desc->ddesc_status);
- if (status & DDESC_STATUS_OWNEDBYDEV)
+ if (sc->sc_descm->tx_is_owned_by_dev(desc))
break;
data = &sc->sc_txq.t_data[i];
@@ -1149,7 +1212,6 @@ dwc_gmac_rx_intr(struct dwc_gmac_softc *sc)
struct dwc_gmac_dev_dmadesc *desc;
struct dwc_gmac_rx_data *data;
bus_addr_t physaddr;
- uint32_t status;
struct mbuf *m, *mnew;
int i, len, error;
@@ -1161,21 +1223,20 @@ dwc_gmac_rx_intr(struct dwc_gmac_softc *sc)
desc = &sc->sc_rxq.r_desc[i];
data = &sc->sc_rxq.r_data[i];
- status = le32toh(desc->ddesc_status);
- if (status & DDESC_STATUS_OWNEDBYDEV)
+ if (sc->sc_descm->rx_is_owned_by_dev(desc))
break;
- if (status & (DDESC_STATUS_RXERROR|DDESC_STATUS_RXTRUNCATED)) {
+ if (sc->sc_descm->rx_has_error(desc)) {
#ifdef DWC_GMAC_DEBUG
aprint_normal_dev(sc->sc_dev,
"RX error: descriptor status %08x, skipping\n",
- status);
+ le32toh(desc->ddesc_status0));
#endif
ifp->if_ierrors++;
goto skip;
}
- len = __SHIFTOUT(status, DDESC_STATUS_FRMLENMSK);
+ len = sc->sc_descm->rx_get_len(desc);
#ifdef DWC_GMAC_DEBUG
aprint_normal_dev(sc->sc_dev,
@@ -1241,10 +1302,11 @@ dwc_gmac_rx_intr(struct dwc_gmac_softc *sc)
skip:
bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0,
data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD);
- desc->ddesc_cntl = htole32(
- __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) |
- DDESC_CNTL_RXCHAIN);
- desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV);
+
+ sc->sc_descm->rx_init_flags(desc);
+ sc->sc_descm->rx_set_len(desc, AWGE_MAX_PACKET);
+ sc->sc_descm->rx_set_owned_by_dev(desc);
+
bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
RX_DESC_OFFSET(i), sizeof(*desc),
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
@@ -1284,6 +1346,11 @@ dwc_gmac_setmulti(struct dwc_gmac_softc *sc)
ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT);
+#if 0
+ ffilt |= AWIN_GMAC_MAC_FFILT_PR;
+ goto special_filter;
+#endif
+
if (ifp->if_flags & IFF_PROMISC) {
ffilt |= AWIN_GMAC_MAC_FFILT_PR;
goto special_filter;
@@ -1398,6 +1465,107 @@ dwc_gmac_intr(struct dwc_gmac_softc *sc)
return rv;
}
+static void
+dwc_gmac_desc_set_owned_by_dev(struct dwc_gmac_dev_dmadesc *desc) {
+ desc->ddesc_status0 |= DDESC_STATUS_OWNEDBYDEV;
+}
+
+static int
+dwc_gmac_desc_is_owned_by_dev(struct dwc_gmac_dev_dmadesc *desc) {
+ return !!(desc->ddesc_status0 & DDESC_STATUS_OWNEDBYDEV);
+}
+
+static void
+dwc_gmac_desc_std_set_len(struct dwc_gmac_dev_dmadesc *desc, int len) {
+ uint32_t cntl = le32toh(desc->ddesc_cntl1);
+
+ desc->ddesc_cntl1 = htole32((cntl & ~DDESC_CNTL_SIZE1MASK) |
+ __SHIFTIN(len, DDESC_CNTL_SIZE1MASK));
+}
+
+static int
+dwc_gmac_desc_std_get_len(struct dwc_gmac_dev_dmadesc *desc) {
+ return __SHIFTOUT(le32toh(desc->ddesc_status0), DDESC_STATUS_FRMLENMSK);
+}
+
+static void
+dwc_gmac_desc_std_tx_init_flags(struct dwc_gmac_dev_dmadesc *desc) {
+ desc->ddesc_status0 = 0;
+ desc->ddesc_cntl1 = DDESC_CNTL_TXCHAIN;
+}
+
+static void
+dwc_gmac_desc_std_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *desc) {
+ uint32_t cntl = le32toh(desc->ddesc_cntl1);
+
+ desc->ddesc_cntl1 = htole32(cntl | DDESC_CNTL_TXFIRST);
+}
+
+static void
+dwc_gmac_desc_std_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *desc) {
+ uint32_t cntl = le32toh(desc->ddesc_cntl1);
+
+ desc->ddesc_cntl1 = htole32(cntl |
+ DDESC_CNTL_TXLAST | DDESC_CNTL_TXINT);
+}
+
+static void
+dwc_gmac_desc_std_rx_init_flags(struct dwc_gmac_dev_dmadesc *desc) {
+ desc->ddesc_status0 = 0;
+ desc->ddesc_cntl1 = DDESC_CNTL_TXCHAIN;
+}
+
+static int
+dwc_gmac_desc_std_rx_has_error(struct dwc_gmac_dev_dmadesc *desc) {
+ return !!(le32toh(desc->ddesc_status0) &
+ (DDESC_STATUS_RXERROR | DDESC_STATUS_RXTRUNCATED));
+}
+
+static void
+dwc_gmac_desc_enh_set_len(struct dwc_gmac_dev_dmadesc *desc, int len) {
+ uint32_t tdes1 = le32toh(desc->ddesc_cntl1);
+
+ desc->ddesc_cntl1 = htole32((tdes1 & ~DDESC_DES1_SIZE1MASK) |
+ __SHIFTIN(len, DDESC_DES1_SIZE1MASK));
+}
+
+static int
+dwc_gmac_desc_enh_get_len(struct dwc_gmac_dev_dmadesc *desc) {
+ return __SHIFTOUT(le32toh(desc->ddesc_status0), DDESC_RDES0_FL);
+}
+
+static void
+dwc_gmac_desc_enh_tx_init_flags(struct dwc_gmac_dev_dmadesc *desc) {
+ desc->ddesc_status0 = DDESC_TDES0_TCH;
+ desc->ddesc_cntl1 = 0;
+}
+
+static void
+dwc_gmac_desc_enh_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *desc) {
+ uint32_t tdes0 = le32toh(desc->ddesc_status0);
+
+ desc->ddesc_status0 = htole32(tdes0 | DDESC_TDES0_FS);
+}
+
+static void
+dwc_gmac_desc_enh_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *desc) {
+ uint32_t tdes0 = le32toh(desc->ddesc_status0);
+
+ desc->ddesc_status0 = htole32(tdes0 | DDESC_TDES0_LS | DDESC_TDES0_IC);
+}
+
+static void
+dwc_gmac_desc_enh_rx_init_flags(struct dwc_gmac_dev_dmadesc *desc) {
+ desc->ddesc_status0 = 0;
+ desc->ddesc_cntl1 = DDESC_RDES1_RCH;
+}
+
+static int
+dwc_gmac_desc_enh_rx_has_error(struct dwc_gmac_dev_dmadesc *desc) {
+ return !!(le32toh(desc->ddesc_status0) &
+ (DDESC_RDES0_ES | DDESC_RDES0_LE));
+}
+
#ifdef DWC_GMAC_DEBUG
static void
dwc_gmac_dump_dma(struct dwc_gmac_softc *sc)
@@ -1442,7 +1610,7 @@ dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *sc)
"data: %08x next: %08x\n",
i, sc->sc_txq.t_physaddr +
i*sizeof(struct dwc_gmac_dev_dmadesc),
- le32toh(desc->ddesc_status), le32toh(desc->ddesc_cntl),
+ le32toh(desc->ddesc_status0), le32toh(desc->ddesc_cntl1),
le32toh(desc->ddesc_data), le32toh(desc->ddesc_next));
}
}
@@ -1461,7 +1629,7 @@ dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *sc)
"data: %08x next: %08x\n",
i, sc->sc_rxq.r_physaddr +
i*sizeof(struct dwc_gmac_dev_dmadesc),
- le32toh(desc->ddesc_status), le32toh(desc->ddesc_cntl),
+ le32toh(desc->ddesc_status0), le32toh(desc->ddesc_cntl1),
le32toh(desc->ddesc_data), le32toh(desc->ddesc_next));
}
}
diff --git a/sys/dev/ic/dwc_gmac_reg.h b/sys/dev/ic/dwc_gmac_reg.h
index eb0c35671fcb..b7eb3cdda88e 100644
--- a/sys/dev/ic/dwc_gmac_reg.h
+++ b/sys/dev/ic/dwc_gmac_reg.h
@@ -164,8 +164,10 @@
#define GMAC_DMA_INT_MASK __BITS(0,16) /* all possible intr bits */
+#define GMAC_DMA_FEAT_ENHANCED_DESC __BIT(24)
+
struct dwc_gmac_dev_dmadesc {
- uint32_t ddesc_status;
+ uint32_t ddesc_status0; /* Status / TDES0 */
/* both: */
#define DDESC_STATUS_OWNEDBYDEV __BIT(31)
@@ -189,7 +191,7 @@ struct dwc_gmac_dev_dmadesc {
#define DDESC_STATUS_RXDRIBBLING __BIT(2)
#define DDESC_STATUS_RXCRC __BIT(1)
- uint32_t ddesc_cntl;
+ uint32_t ddesc_cntl1; /* Control / TDES1 */
/* for TX descriptors */
#define DDESC_CNTL_TXINT __BIT(31)
@@ -221,3 +223,25 @@ struct dwc_gmac_dev_dmadesc {
uint32_t ddesc_data; /* pointer to buffer data */
uint32_t ddesc_next; /* link to next descriptor */
};
+
+/* Common to enhanced descriptors */
+
+#define DDESC_DES0_OWN __BIT(31)
+
+#define DDESC_DES1_SIZE2MASK __BITS(28,16)
+#define DDESC_DES1_SIZE1MASK __BITS(12,0)
+
+/* For enhanced TX descriptors */
+
+#define DDESC_TDES0_IC __BIT(30)
+#define DDESC_TDES0_LS __BIT(29)
+#define DDESC_TDES0_FS __BIT(28)
+#define DDESC_TDES0_TCH __BIT(20)
+
+/* For enhanced RX descriptors */
+
+#define DDESC_RDES0_FL __BITS(29,16)
+#define DDESC_RDES0_ES __BIT(15)
+#define DDESC_RDES0_LE __BIT(12)
+
+#define DDESC_RDES1_RCH __BIT(14)
diff --git a/sys/dev/ic/dwc_gmac_var.h b/sys/dev/ic/dwc_gmac_var.h
index ca6562808431..7c6323d33cdd 100644
--- a/sys/dev/ic/dwc_gmac_var.h
+++ b/sys/dev/ic/dwc_gmac_var.h
@@ -46,7 +46,23 @@
#define AWGE_MAX_PACKET 0x7ff
+struct dwc_gmac_dev_dmadesc;
+struct dwc_gmac_desc_methods {
+ void (*tx_init_flags)(struct dwc_gmac_dev_dmadesc *);
+ void (*tx_set_owned_by_dev)(struct dwc_gmac_dev_dmadesc *);
+ int (*tx_is_owned_by_dev)(struct dwc_gmac_dev_dmadesc *);
+ void (*tx_set_len)(struct dwc_gmac_dev_dmadesc *, int);
+ void (*tx_set_first_frag)(struct dwc_gmac_dev_dmadesc *);
+ void (*tx_set_last_frag)(struct dwc_gmac_dev_dmadesc *);
+
+ void (*rx_init_flags)(struct dwc_gmac_dev_dmadesc *);
+ void (*rx_set_owned_by_dev)(struct dwc_gmac_dev_dmadesc *);
+ int (*rx_is_owned_by_dev)(struct dwc_gmac_dev_dmadesc *);
+ void (*rx_set_len)(struct dwc_gmac_dev_dmadesc *, int);
+ int (*rx_get_len)(struct dwc_gmac_dev_dmadesc *);
+ int (*rx_has_error)(struct dwc_gmac_dev_dmadesc *);
+};
struct dwc_gmac_rx_data {
bus_dmamap_t rd_map;
@@ -89,6 +105,7 @@ struct dwc_gmac_softc {
bus_dma_segment_t sc_dma_ring_seg; /* and TX ring */
struct dwc_gmac_rx_ring sc_rxq;
struct dwc_gmac_tx_ring sc_txq;
+ const struct dwc_gmac_desc_methods *sc_descm;
short sc_if_flags; /* shadow of ether flags */
uint16_t sc_mii_clk;
bool sc_stopping;
Home |
Main Index |
Thread Index |
Old Index