Module Name: src Committed By: martin Date: Mon Oct 8 17:09:31 UTC 2018
Modified Files: src/sys/dev/ic: dwc_gmac.c dwc_gmac_reg.h dwc_gmac_var.h Log Message: Bring back support for enhanced descriptor format in newer core versions. Fix a few endian bugs and check the main core version before trying to read the hardware feature mask. Only read the hardware feature register if core version reported is >= 3.5 (all my older hardware reports 0). With some hints and patches from jared, and ok from aymeric To generate a diff of this commit: cvs rdiff -u -r1.54 -r1.55 src/sys/dev/ic/dwc_gmac.c cvs rdiff -u -r1.18 -r1.19 src/sys/dev/ic/dwc_gmac_reg.h cvs rdiff -u -r1.11 -r1.12 src/sys/dev/ic/dwc_gmac_var.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ic/dwc_gmac.c diff -u src/sys/dev/ic/dwc_gmac.c:1.54 src/sys/dev/ic/dwc_gmac.c:1.55 --- src/sys/dev/ic/dwc_gmac.c:1.54 Fri Sep 28 21:51:42 2018 +++ src/sys/dev/ic/dwc_gmac.c Mon Oct 8 17:09:31 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_gmac.c,v 1.54 2018/09/28 21:51:42 aymeric Exp $ */ +/* $NetBSD: dwc_gmac.c,v 1.55 2018/10/08 17:09:31 martin Exp $ */ /*- * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. @@ -41,7 +41,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.54 2018/09/28 21:51:42 aymeric Exp $"); +__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.55 2018/10/08 17:09:31 martin Exp $"); /* #define DWC_GMAC_DEBUG 1 */ @@ -100,6 +100,53 @@ static void dwc_gmac_rx_intr(struct dwc_ 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 uint32_t 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 uint32_t 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)) @@ -122,7 +169,7 @@ static uint32_t bitrev32(uint32_t x); #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) + AWIN_GMAC_MAC_INT_LINKCHG) #ifdef DWC_GMAC_DEBUG static void dwc_gmac_dump_dma(struct dwc_gmac_softc *sc); @@ -141,7 +188,7 @@ int dwc_gmac_attach(struct dwc_gmac_softc *sc, uint32_t mii_clk) { uint8_t enaddr[ETHER_ADDR_LEN]; - uint32_t maclo, machi; + uint32_t maclo, machi, ver, hwft; struct mii_data * const mii = &sc->sc_mii; struct ifnet * const ifp = &sc->sc_ec.ec_if; prop_dictionary_t dict; @@ -185,6 +232,9 @@ dwc_gmac_attach(struct dwc_gmac_softc *s enaddr[5] = (machi >> 8) & 0x0ff; } + ver = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_VERSION); + aprint_normal_dev(sc->sc_dev, "Core version: %08x\n", ver); + /* * Init chip and do initial setup */ @@ -194,6 +244,21 @@ dwc_gmac_attach(struct dwc_gmac_softc *s aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n", ether_sprintf(enaddr)); + hwft = 0; + if (ver >= 0x35) { + hwft = bus_space_read_4(sc->sc_bst, sc->sc_bsh, + AWIN_GMAC_DMA_HWFEATURES); + aprint_normal_dev(sc->sc_dev, + "HW feature mask: %x\n", hwft); + } + if (hwft & GMAC_DMA_FEAT_ENHANCED_DESC) { + aprint_normal_dev(sc->sc_dev, + "Using enhanced descriptor format\n"); + sc->sc_descm = &desc_methods_enhanced; + } else { + sc->sc_descm = &desc_methods_standard; + } + /* * Allocate Tx and Rx rings */ @@ -444,10 +509,9 @@ dwc_gmac_alloc_rx_ring(struct dwc_gmac_s 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 +537,9 @@ dwc_gmac_reset_rx_ring(struct dwc_gmac_s 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, @@ -891,11 +954,11 @@ 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 dwc_dump_status(sc); #endif + bus_space_write_4(sc->sc_bst, sc->sc_bsh, + AWIN_GMAC_DMA_TXPOLL, ~0U); } } @@ -942,7 +1005,6 @@ dwc_gmac_queue(struct dwc_gmac_softc *sc 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 +1028,37 @@ dwc_gmac_queue(struct dwc_gmac_softc *sc 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 +1067,10 @@ dwc_gmac_queue(struct dwc_gmac_softc *sc 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 +1150,6 @@ dwc_gmac_tx_intr(struct dwc_gmac_softc * 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 +1170,7 @@ dwc_gmac_tx_intr(struct dwc_gmac_softc * 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 +1210,6 @@ dwc_gmac_rx_intr(struct dwc_gmac_softc * 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 +1221,20 @@ dwc_gmac_rx_intr(struct dwc_gmac_softc * 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 +1300,11 @@ dwc_gmac_rx_intr(struct dwc_gmac_softc * 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); @@ -1398,6 +1458,131 @@ 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 |= htole32(DDESC_STATUS_OWNEDBYDEV); +} + +static int +dwc_gmac_desc_is_owned_by_dev(struct dwc_gmac_dev_dmadesc *desc) +{ + + return !!(le32toh(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 uint32_t +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 = htole32(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 = htole32(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 uint32_t +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 = htole32(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 = htole32(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 +1627,7 @@ dwc_gmac_dump_tx_desc(struct dwc_gmac_so "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 +1646,7 @@ dwc_gmac_dump_rx_desc(struct dwc_gmac_so "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)); } } Index: src/sys/dev/ic/dwc_gmac_reg.h diff -u src/sys/dev/ic/dwc_gmac_reg.h:1.18 src/sys/dev/ic/dwc_gmac_reg.h:1.19 --- src/sys/dev/ic/dwc_gmac_reg.h:1.18 Fri Sep 28 21:51:42 2018 +++ src/sys/dev/ic/dwc_gmac_reg.h Mon Oct 8 17:09:31 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_gmac_reg.h,v 1.18 2018/09/28 21:51:42 aymeric Exp $ */ +/* $NetBSD: dwc_gmac_reg.h,v 1.19 2018/10/08 17:09:31 martin Exp $ */ /*- * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. @@ -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) Index: src/sys/dev/ic/dwc_gmac_var.h diff -u src/sys/dev/ic/dwc_gmac_var.h:1.11 src/sys/dev/ic/dwc_gmac_var.h:1.12 --- src/sys/dev/ic/dwc_gmac_var.h:1.11 Fri Sep 28 21:51:42 2018 +++ src/sys/dev/ic/dwc_gmac_var.h Mon Oct 8 17:09:31 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_gmac_var.h,v 1.11 2018/09/28 21:51:42 aymeric Exp $ */ +/* $NetBSD: dwc_gmac_var.h,v 1.12 2018/10/08 17:09:31 martin Exp $ */ /*- * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. @@ -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); + uint32_t (*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;