ffec: Use RACC[SHIFT16]

This avoids the move of entire receive frames to meet the alignment
requirements of the IP header and so on.

Add FECFLAG_RACC feature flag for this similar to the Linux driver.

Update #3090.
This commit is contained in:
Sebastian Huber 2017-10-04 14:15:59 +02:00
parent 2fcf5aadd5
commit b8fdbe2fa9

View File

@ -108,6 +108,7 @@ enum {
#define FECTYPE_MASK 0x0000ffff #define FECTYPE_MASK 0x0000ffff
#define FECFLAG_GBE (1 << 16) #define FECFLAG_GBE (1 << 16)
#define FECFLAG_AVB (1 << 17) #define FECFLAG_AVB (1 << 17)
#define FECFLAG_RACC (1 << 18)
/* /*
* Table of supported FDT compat strings and their associated FECTYPE values. * Table of supported FDT compat strings and their associated FECTYPE values.
@ -115,10 +116,11 @@ enum {
static struct ofw_compat_data compat_data[] = { static struct ofw_compat_data compat_data[] = {
{"fsl,imx51-fec", FECTYPE_GENERIC}, {"fsl,imx51-fec", FECTYPE_GENERIC},
{"fsl,imx53-fec", FECTYPE_IMX53}, {"fsl,imx53-fec", FECTYPE_IMX53},
{"fsl,imx6q-fec", FECTYPE_IMX6 | FECFLAG_GBE}, {"fsl,imx6q-fec", FECTYPE_IMX6 | FECFLAG_GBE | FECFLAG_RACC},
{"fsl,mvf600-fec", FECTYPE_MVF}, {"fsl,mvf600-fec", FECTYPE_MVF | FECFLAG_RACC},
{"fsl,mvf-fec", FECTYPE_MVF}, {"fsl,mvf-fec", FECTYPE_MVF},
{"fsl,imx7d-fec", FECTYPE_IMX6 | FECFLAG_GBE | FECFLAG_AVB}, {"fsl,imx7d-fec", FECTYPE_IMX6 | FECFLAG_GBE | FECFLAG_AVB |
FECFLAG_RACC},
{NULL, FECTYPE_NONE}, {NULL, FECTYPE_NONE},
}; };
@ -753,14 +755,17 @@ ffec_setup_rxbuf(struct ffec_softc *sc, int idx, struct mbuf * m)
int error, nsegs; int error, nsegs;
struct bus_dma_segment seg; struct bus_dma_segment seg;
/* if ((sc->fectype & FECFLAG_RACC) == 0) {
* We need to leave at least ETHER_ALIGN bytes free at the beginning of /*
* the buffer to allow the data to be re-aligned after receiving it (by * The RACC[SHIFT16] feature is not used. So, we need to leave
* copying it backwards ETHER_ALIGN bytes in the same buffer). We also * at least ETHER_ALIGN bytes free at the beginning of the
* have to ensure that the beginning of the buffer is aligned to the * buffer to allow the data to be re-aligned after receiving it
* hardware's requirements. * (by copying it backwards ETHER_ALIGN bytes in the same
*/ * buffer). We also have to ensure that the beginning of the
m_adj(m, roundup(ETHER_ALIGN, sc->rxbuf_align)); * buffer is aligned to the hardware's requirements.
*/
m_adj(m, roundup(ETHER_ALIGN, sc->rxbuf_align));
}
error = bus_dmamap_load_mbuf_sg(sc->rxbuf_tag, sc->rxbuf_map[idx].map, error = bus_dmamap_load_mbuf_sg(sc->rxbuf_tag, sc->rxbuf_map[idx].map,
m, &seg, &nsegs, 0); m, &seg, &nsegs, 0);
@ -796,7 +801,6 @@ ffec_rxfinish_onebuf(struct ffec_softc *sc, int len)
{ {
struct mbuf *m, *newmbuf; struct mbuf *m, *newmbuf;
struct ffec_bufmap *bmap; struct ffec_bufmap *bmap;
uint8_t *dst, *src;
int error; int error;
/* /*
@ -840,10 +844,17 @@ ffec_rxfinish_onebuf(struct ffec_softc *sc, int len)
m->m_pkthdr.len = len; m->m_pkthdr.len = len;
m->m_pkthdr.rcvif = sc->ifp; m->m_pkthdr.rcvif = sc->ifp;
src = mtod(m, uint8_t*); if (sc->fectype & FECFLAG_RACC) {
dst = src - ETHER_ALIGN; /* We use the RACC[SHIFT16] feature */
bcopy(src, dst, len); m->m_data = mtod(m, uint8_t *) + 2;
m->m_data = dst; } else {
uint8_t *dst, *src;
src = mtod(m, uint8_t*);
dst = src - ETHER_ALIGN;
bcopy(src, dst, len);
m->m_data = dst;
}
sc->ifp->if_input(sc->ifp, m); sc->ifp->if_input(sc->ifp, m);
FFEC_LOCK(sc); FFEC_LOCK(sc);
@ -1217,6 +1228,14 @@ ffec_init_locked(struct ffec_softc *sc)
ffec_clear_stats(sc); ffec_clear_stats(sc);
WR4(sc, FEC_MIBC_REG, regval & ~FEC_MIBC_DIS); WR4(sc, FEC_MIBC_REG, regval & ~FEC_MIBC_DIS);
if (sc->fectype & FECFLAG_RACC) {
/*
* RACC - Receive Accelerator Function Configuration.
*/
regval = RD4(sc, FEC_RACC_REG);
WR4(sc, FEC_RACC_REG, regval | FEC_RACC_SHIFT16);
}
/* /*
* ECR - Ethernet control register. * ECR - Ethernet control register.
* *