Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/marvell Add Marvell Gigabit Ethernet Controller on S...



details:   https://anonhg.NetBSD.org/src/rev/e303c3d39bc4
branches:  trunk
changeset: 755341:e303c3d39bc4
user:      kiyohara <kiyohara%NetBSD.org@localhost>
date:      Wed Jun 02 06:18:11 2010 +0000

description:
Add Marvell Gigabit Ethernet Controller on SC/SoC.
  Will support on ofppc soon.
  Tested on G4+PegasosII (kiyohara@)
            G3+PegasosII (phx@)

diffstat:

 sys/dev/marvell/files.discovery |    14 +-
 sys/dev/marvell/if_mvgbe.c      |  1832 +++++++++++++++++++++++++++++++++++++++
 sys/dev/marvell/mvgbereg.h      |   419 ++++++++
 3 files changed, 2258 insertions(+), 7 deletions(-)

diffs (truncated from 2287 to 300 lines):

diff -r fd8429e5086a -r e303c3d39bc4 sys/dev/marvell/files.discovery
--- a/sys/dev/marvell/files.discovery   Wed Jun 02 06:05:32 2010 +0000
+++ b/sys/dev/marvell/files.discovery   Wed Jun 02 06:18:11 2010 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.discovery,v 1.12 2010/05/07 17:06:32 kiyohara Exp $
+#      $NetBSD: files.discovery,v 1.13 2010/06/02 06:18:11 kiyohara Exp $
 #
 # Config file and device description for machine-independent support for
 # the Marvell (formerly Galileo Technology) Discovery system controllers.
@@ -62,12 +62,12 @@
 #file  dev/marvell/mvsata_mv.c         mvsata_gt | mvsata_mbus
 
 # Gigabit Ethernet Controller Interface
-#define        mvgbec { [port = -1], [irq = -1] }
-#device        mvgbec: mvgbec
-#attach        mvgbec at gt with mvgbec_gt
-#device        mvgbe: ether, ifnet, arp, mii
-#attach        mvgbe at mvgbec
-#file  dev/marvell/if_mvgbe.c          mvgbec | mvgbe
+define mvgbec { [port = -1], [irq = -1] }
+device mvgbec: mvgbec
+attach mvgbec at gt with mvgbec_gt
+device mvgbe: ether, ifnet, arp, mii
+attach mvgbe at mvgbec
+file   dev/marvell/if_mvgbe.c          mvgbec | mvgbe
 
 # USB 2.0 Interface
 #attach        ehci at gt with mvusb_gt
diff -r fd8429e5086a -r e303c3d39bc4 sys/dev/marvell/if_mvgbe.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/marvell/if_mvgbe.c        Wed Jun 02 06:18:11 2010 +0000
@@ -0,0 +1,1832 @@
+/*     $NetBSD: if_mvgbe.c,v 1.1 2010/06/02 06:18:11 kiyohara Exp $    */
+/*
+ * Copyright (c) 2007, 2008 KIYOHARA Takashi
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: if_mvgbe.c,v 1.1 2010/06/02 06:18:11 kiyohara Exp $");
+
+#include "rnd.h"
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/endian.h>
+#include <sys/errno.h>
+#include <sys/kmem.h>
+#include <sys/mutex.h>
+#include <sys/sockio.h>
+
+#include <dev/marvell/marvellreg.h>
+#include <dev/marvell/marvellvar.h>
+#include <dev/marvell/mvgbereg.h>
+
+#include <net/if.h>
+#include <net/if_ether.h>
+#include <net/if_media.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#include <net/bpf.h>
+#if NRND > 0
+#include <sys/rnd.h>
+#endif
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include "locators.h"
+
+/* #define MVGBE_DEBUG 3 */
+#ifdef MVGBE_DEBUG
+#define DPRINTF(x)     if (mvgbe_debug) printf x
+#define DPRINTFN(n,x)  if (mvgbe_debug >= (n)) printf x
+int mvgbe_debug = MVGBE_DEBUG;
+#else
+#define DPRINTF(x)
+#define DPRINTFN(n,x)
+#endif
+
+
+#define MVGBE_READ(sc, reg) \
+       bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))
+#define MVGBE_WRITE(sc, reg, val) \
+       bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
+#define MVGBE_READ_FILTER(sc, reg) \
+       bus_space_read_4((sc)->sc_iot, (sc)->sc_dafh, (reg))
+#define MVGBE_WRITE_FILTER(sc, reg, val, c) \
+       bus_space_set_region_4((sc)->sc_iot, (sc)->sc_dafh, (reg), (val), (c))
+
+#define MVGBE_TX_RING_CNT      256
+#define MVGBE_RX_RING_CNT      256
+
+#define MVGBE_JSLOTS           384     /* XXXX */
+#define MVGBE_JLEN             (MVGBE_MRU + MVGBE_BUF_ALIGN)
+#define MVGBE_NTXSEG           30
+#define MVGBE_JPAGESZ          PAGE_SIZE
+#define MVGBE_RESID \
+    (MVGBE_JPAGESZ - (MVGBE_JLEN * MVGBE_JSLOTS) % MVGBE_JPAGESZ)
+#define MVGBE_JMEM \
+    ((MVGBE_JLEN * MVGBE_JSLOTS) + MVGBE_RESID)
+
+#define MVGBE_TX_RING_ADDR(sc, i)              \
+    ((sc)->sc_ring_map->dm_segs[0].ds_addr +   \
+                       offsetof(struct mvgbe_ring_data, mvgbe_tx_ring[(i)]))
+
+#define MVGBE_RX_RING_ADDR(sc, i)              \
+    ((sc)->sc_ring_map->dm_segs[0].ds_addr +   \
+                       offsetof(struct mvgbe_ring_data, mvgbe_rx_ring[(i)]))
+
+#define MVGBE_CDOFF(x)         offsetof(struct mvgbe_ring_data, x)
+#define MVGBE_CDTXOFF(x)       MVGBE_CDOFF(mvgbe_tx_ring[(x)])
+#define MVGBE_CDRXOFF(x)       MVGBE_CDOFF(mvgbe_rx_ring[(x)])
+
+#define MVGBE_CDTXSYNC(sc, x, n, ops)                                  \
+do {                                                                   \
+       int __x, __n;                                                   \
+       const int __descsize = sizeof(struct mvgbe_tx_desc);            \
+                                                                       \
+       __x = (x);                                                      \
+       __n = (n);                                                      \
+                                                                       \
+       /* If it will wrap around, sync to the end of the ring. */      \
+       if ((__x + __n) > MVGBE_TX_RING_CNT) {                          \
+               bus_dmamap_sync((sc)->sc_dmat,                          \
+                   (sc)->sc_ring_map, MVGBE_CDTXOFF(__x),              \
+                   __descsize * (MVGBE_TX_RING_CNT - __x), (ops));     \
+               __n -= (MVGBE_TX_RING_CNT - __x);                       \
+               __x = 0;                                                \
+       }                                                               \
+                                                                       \
+       /* Now sync whatever is left. */                                \
+       bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_ring_map,               \
+           MVGBE_CDTXOFF((__x)), __descsize * __n, (ops));             \
+} while (0 /*CONSTCOND*/)
+
+#define MVGBE_CDRXSYNC(sc, x, ops)                                     \
+do {                                                                   \
+       bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_ring_map,               \
+           MVGBE_CDRXOFF((x)), sizeof(struct mvgbe_rx_desc), (ops));   \
+       } while (/*CONSTCOND*/0)
+
+
+struct mvgbe_jpool_entry {
+       int slot;
+       LIST_ENTRY(mvgbe_jpool_entry) jpool_entries;
+};
+
+struct mvgbe_chain {
+       void *mvgbe_desc;
+       struct mbuf *mvgbe_mbuf;
+       struct mvgbe_chain *mvgbe_next;
+};
+
+struct mvgbe_txmap_entry {
+       bus_dmamap_t dmamap;
+       SIMPLEQ_ENTRY(mvgbe_txmap_entry) link;
+};
+
+struct mvgbe_chain_data {
+       struct mvgbe_chain mvgbe_tx_chain[MVGBE_TX_RING_CNT];
+       struct mvgbe_txmap_entry *mvgbe_tx_map[MVGBE_TX_RING_CNT];
+       int mvgbe_tx_prod;
+       int mvgbe_tx_cons;
+       int mvgbe_tx_cnt;
+
+       struct mvgbe_chain mvgbe_rx_chain[MVGBE_RX_RING_CNT];
+       bus_dmamap_t mvgbe_rx_map[MVGBE_RX_RING_CNT];
+       bus_dmamap_t mvgbe_rx_jumbo_map;
+       int mvgbe_rx_prod;
+       int mvgbe_rx_cons;
+       int mvgbe_rx_cnt;
+
+       /* Stick the jumbo mem management stuff here too. */
+       void *mvgbe_jslots[MVGBE_JSLOTS];
+       void *mvgbe_jumbo_buf;
+};
+
+struct mvgbe_ring_data {
+       struct mvgbe_tx_desc mvgbe_tx_ring[MVGBE_TX_RING_CNT];
+       struct mvgbe_rx_desc mvgbe_rx_ring[MVGBE_RX_RING_CNT];
+};
+
+struct mvgbec_softc {
+       device_t sc_dev;
+
+       bus_space_tag_t sc_iot;
+       bus_space_handle_t sc_ioh;
+
+       kmutex_t sc_mtx;
+};
+
+struct mvgbe_softc {
+       device_t sc_dev;
+       int sc_port;                            /* port num (0 or 1) */
+
+       bus_space_tag_t sc_iot;
+       bus_space_handle_t sc_ioh;
+       bus_space_handle_t sc_dafh;             /* dest address filter handle */
+       bus_dma_tag_t sc_dmat;
+
+       struct ethercom sc_ethercom;
+       struct mii_data sc_mii;
+       u_int8_t sc_enaddr[ETHER_ADDR_LEN];     /* station addr */
+
+       struct mvgbe_chain_data sc_cdata;
+       struct mvgbe_ring_data *sc_rdata;
+       bus_dmamap_t sc_ring_map;
+       int sc_if_flags;
+
+       LIST_HEAD(__mvgbe_jfreehead, mvgbe_jpool_entry) sc_jfree_listhead;
+       LIST_HEAD(__mvgbe_jinusehead, mvgbe_jpool_entry) sc_jinuse_listhead;
+       SIMPLEQ_HEAD(__mvgbe_txmaphead, mvgbe_txmap_entry) sc_txmap_head;
+
+#if NRND > 0
+       rndsource_element_t sc_rnd_source;
+#endif
+};
+
+
+/* Gigabit Ethernet Unit Global part functions */
+
+static int mvgbec_match(device_t, struct cfdata *, void *);
+static void mvgbec_attach(device_t, device_t, void *);
+
+static int mvgbec_print(void *, const char *);
+static int mvgbec_search(device_t, cfdata_t, const int *, void *);
+
+/* MII funcstions */
+static int mvgbec_miibus_readreg(device_t, int, int);
+static void mvgbec_miibus_writereg(device_t, int, int, int);
+static void mvgbec_miibus_statchg(device_t);
+
+static void mvgbec_wininit(struct mvgbec_softc *);
+
+/* Gigabit Ethernet Port part functions */
+
+static int mvgbe_match(device_t, struct cfdata *, void *);
+static void mvgbe_attach(device_t, device_t, void *);
+
+static int mvgbe_intr(void *);
+
+static void mvgbe_start(struct ifnet *);
+static int mvgbe_ioctl(struct ifnet *, u_long, void *);
+static int mvgbe_init(struct ifnet *);
+static void mvgbe_stop(struct ifnet *, int);
+static void mvgbe_watchdog(struct ifnet *);
+
+/* MII funcstions */
+static int mvgbe_ifmedia_upd(struct ifnet *);
+static void mvgbe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
+
+static int mvgbe_init_rx_ring(struct mvgbe_softc *);
+static int mvgbe_init_tx_ring(struct mvgbe_softc *);
+static int mvgbe_newbuf(struct mvgbe_softc *, int, struct mbuf *, bus_dmamap_t);
+static int mvgbe_alloc_jumbo_mem(struct mvgbe_softc *);
+static void *mvgbe_jalloc(struct mvgbe_softc *);
+static void mvgbe_jfree(struct mbuf *, void *, size_t, void *);
+static int mvgbe_encap(struct mvgbe_softc *, struct mbuf *, uint32_t *);
+static void mvgbe_rxeof(struct mvgbe_softc *);
+static void mvgbe_txeof(struct mvgbe_softc *);
+static void mvgbe_setmulti(struct mvgbe_softc *);
+#ifdef MVGBE_DEBUG
+static void mvgbe_dump_txdesc(struct mvgbe_tx_desc *, int);
+#endif
+
+CFATTACH_DECL_NEW(mvgbec_gt, sizeof(struct mvgbec_softc),
+    mvgbec_match, mvgbec_attach, NULL, NULL);
+CFATTACH_DECL_NEW(mvgbec_mbus, sizeof(struct mvgbec_softc),
+    mvgbec_match, mvgbec_attach, NULL, NULL);
+
+CFATTACH_DECL_NEW(mvgbe, sizeof(struct mvgbe_softc),
+    mvgbe_match, mvgbe_attach, NULL, NULL);
+
+
+struct mvgbe_port {



Home | Main Index | Thread Index | Old Index