Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/rockchip various fixes from FUKAUMI Naoki <fun@...
details: https://anonhg.NetBSD.org/src/rev/a3fa42a9bce6
branches: trunk
changeset: 335399:a3fa42a9bce6
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Mon Jan 05 21:57:49 2015 +0000
description:
various fixes from FUKAUMI Naoki <fun%naobsd.org@localhost> and martin@
diffstat:
sys/arch/arm/rockchip/rockchip_emac.c | 56 ++++++++++++++++++++++++----------
1 files changed, 39 insertions(+), 17 deletions(-)
diffs (149 lines):
diff -r 95f415dbdcab -r a3fa42a9bce6 sys/arch/arm/rockchip/rockchip_emac.c
--- a/sys/arch/arm/rockchip/rockchip_emac.c Mon Jan 05 21:37:07 2015 +0000
+++ b/sys/arch/arm/rockchip/rockchip_emac.c Mon Jan 05 21:57:49 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rockchip_emac.c,v 1.2 2015/01/04 11:54:43 jmcneill Exp $ */
+/* $NetBSD: rockchip_emac.c,v 1.3 2015/01/05 21:57:49 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
#include "opt_rkemac.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rockchip_emac.c,v 1.2 2015/01/04 11:54:43 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rockchip_emac.c,v 1.3 2015/01/05 21:57:49 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -119,6 +119,7 @@
bus_dma_segment_t sc_ring_dmaseg;
struct rkemac_txring sc_txq;
struct rkemac_rxring sc_rxq;
+ bus_addr_t sc_pad_physaddr;
};
static int rkemac_match(device_t, cfdata_t, void *);
@@ -186,8 +187,8 @@
} else {
soc_con1_reg = 0x0154;
}
- bus_space_subregion(obio->obio_bst, obio->obio_bsh,
- ROCKCHIP_GRF_OFFSET + soc_con1_reg, 4, &sc->sc_soc_con1_bsh);
+ bus_space_subregion(obio->obio_bst, obio->obio_grf_bsh, soc_con1_reg,
+ 4, &sc->sc_soc_con1_bsh);
aprint_naive("\n");
aprint_normal(": Ethernet controller\n");
@@ -275,7 +276,8 @@
rkemac_dma_init(struct rkemac_softc *sc)
{
size_t descsize = RKEMAC_RX_RING_COUNT * sizeof(struct rkemac_rxdesc) +
- RKEMAC_TX_RING_COUNT * sizeof(struct rkemac_txdesc);
+ RKEMAC_TX_RING_COUNT * sizeof(struct rkemac_txdesc) +
+ ETHER_MIN_LEN;
bus_addr_t physaddr;
int error, nsegs;
void *descs;
@@ -310,6 +312,9 @@
sc->sc_txq.t_physaddr = sc->sc_rxq.r_physaddr +
RKEMAC_RX_RING_COUNT * sizeof(struct rkemac_rxdesc);
+ sc->sc_pad_physaddr = sc->sc_txq.t_physaddr +
+ RKEMAC_TX_RING_COUNT * sizeof(struct rkemac_txdesc);
+
/*
* Setup RX ring
*/
@@ -538,6 +543,8 @@
control |= EMAC_CONTROL_EN;
EMAC_WRITE(sc, EMAC_CONTROL_REG, control);
+ callout_schedule(&sc->sc_mii_tick, hz);
+
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
@@ -548,7 +555,8 @@
rkemac_start(struct ifnet *ifp)
{
struct rkemac_softc *sc = ifp->if_softc;
- int old = sc->sc_txq.t_queued;
+ const int old = sc->sc_txq.t_queued;
+ const int start = sc->sc_txq.t_cur;
struct mbuf *m0;
if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
@@ -567,10 +575,9 @@
}
if (sc->sc_txq.t_queued != old) {
- rkemac_txdesc_sync(sc, old, sc->sc_txq.t_cur,
+ rkemac_txdesc_sync(sc, start, sc->sc_txq.t_cur,
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
- EMAC_WRITE(sc, EMAC_STAT_REG,
- EMAC_READ(sc, EMAC_STAT_REG) | EMAC_STAT_TXPL);
+ EMAC_WRITE(sc, EMAC_STAT_REG, EMAC_STAT_TXPL);
}
}
@@ -694,8 +701,6 @@
map = sc->sc_txq.t_data[first].td_map;
info = 0;
- KASSERT(map->dm_nsegs > 0);
-
error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m0,
BUS_DMA_WRITE | BUS_DMA_NOWAIT);
if (error) {
@@ -703,7 +708,12 @@
return error;
}
- if (sc->sc_txq.t_queued + map->dm_nsegs >= RKEMAC_TX_RING_COUNT - 1) {
+ KASSERT(map->dm_nsegs > 0);
+
+ const u_int nbufs = map->dm_nsegs +
+ ((m0->m_pkthdr.len < ETHER_MIN_LEN) ? 1 : 0);
+
+ if (sc->sc_txq.t_queued + nbufs >= RKEMAC_TX_RING_COUNT - 1) {
bus_dmamap_unload(sc->sc_dmat, map);
return ENOBUFS;
}
@@ -715,11 +725,23 @@
tx->tx_ptr = htole32(map->dm_segs[i].ds_addr);
len = __SHIFTIN(map->dm_segs[i].ds_len, EMAC_TXDESC_TXLEN);
- if (i == map->dm_nsegs - 1)
- info |= EMAC_TXDESC_LAST;
tx->tx_info = htole32(info | len);
- if (i > 0)
- tx->tx_info |= EMAC_TXDESC_OWN;
+ info &= ~EMAC_TXDESC_FIRST;
+ info |= EMAC_TXDESC_OWN;
+ if (i == map->dm_nsegs - 1) {
+ if (m0->m_pkthdr.len < ETHER_MIN_LEN) {
+ sc->sc_txq.t_queued++;
+ sc->sc_txq.t_cur = (sc->sc_txq.t_cur + 1)
+ % RKEMAC_TX_RING_COUNT;
+ td = &sc->sc_txq.t_data[sc->sc_txq.t_cur];
+ tx = &sc->sc_txq.t_desc[sc->sc_txq.t_cur];
+ tx->tx_ptr = htole32(sc->sc_pad_physaddr);
+ len = __SHIFTIN(ETHER_MIN_LEN -
+ m0->m_pkthdr.len , EMAC_TXDESC_TXLEN);
+ tx->tx_info = htole32(info | len);
+ }
+ tx->tx_info |= htole32(EMAC_TXDESC_LAST);
+ }
sc->sc_txq.t_queued++;
sc->sc_txq.t_cur =
@@ -815,7 +837,7 @@
goto skip;
}
- const u_int len = __SHIFTOUT(info, EMAC_RXDESC_LAST);
+ const u_int len = __SHIFTOUT(info, EMAC_RXDESC_RXLEN);
MGETHDR(mnew, M_DONTWAIT, MT_DATA);
if (mnew == NULL) {
Home |
Main Index |
Thread Index |
Old Index