Module Name: src Committed By: aymeric Date: Mon Sep 17 20:25:49 UTC 2018
Modified Files: src/sys/dev/ic: dwc_gmac.c dwc_gmac_reg.h dwc_gmac_var.h Log Message: Add support for the enhanced descriptors feature. This makes "recent" dwc gmac controllers, as found e.g. on the Cyclone V, work. The change was also tested working on an Allwinner A20 which doesn't have the feature. No negative reaction on port-arm. To generate a diff of this commit: cvs rdiff -u -r1.52 -r1.53 src/sys/dev/ic/dwc_gmac.c cvs rdiff -u -r1.16 -r1.17 src/sys/dev/ic/dwc_gmac_reg.h cvs rdiff -u -r1.9 -r1.10 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.52 src/sys/dev/ic/dwc_gmac.c:1.53 --- src/sys/dev/ic/dwc_gmac.c:1.52 Wed Jul 18 23:10:27 2018 +++ src/sys/dev/ic/dwc_gmac.c Mon Sep 17 20:25:49 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_gmac.c,v 1.52 2018/07/18 23:10:27 sevan Exp $ */ +/* $NetBSD: dwc_gmac.c,v 1.53 2018/09/17 20:25:49 aymeric 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.52 2018/07/18 23:10:27 sevan Exp $"); +__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.53 2018/09/17 20:25:49 aymeric 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 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)) @@ -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); @@ -194,6 +241,12 @@ dwc_gmac_attach(struct dwc_gmac_softc *s 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 +497,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 +525,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 +942,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 +993,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 +1016,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 +1055,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 +1138,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 +1158,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 +1198,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 +1209,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 +1288,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 +1446,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 +1591,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 +1610,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.16 src/sys/dev/ic/dwc_gmac_reg.h:1.17 --- src/sys/dev/ic/dwc_gmac_reg.h:1.16 Sat Jun 16 00:15:00 2018 +++ src/sys/dev/ic/dwc_gmac_reg.h Mon Sep 17 20:25:49 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_gmac_reg.h,v 1.16 2018/06/16 00:15:00 jmcneill Exp $ */ +/* $NetBSD: dwc_gmac_reg.h,v 1.17 2018/09/17 20:25:49 aymeric 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.9 src/sys/dev/ic/dwc_gmac_var.h:1.10 --- src/sys/dev/ic/dwc_gmac_var.h:1.9 Sat Jun 30 16:27:48 2018 +++ src/sys/dev/ic/dwc_gmac_var.h Mon Sep 17 20:25:49 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_gmac_var.h,v 1.9 2018/06/30 16:27:48 jmcneill Exp $ */ +/* $NetBSD: dwc_gmac_var.h,v 1.10 2018/09/17 20:25:49 aymeric 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); + 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;