Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/sociox Socionext "NetSec" GbE driver
details: https://anonhg.NetBSD.org/src/rev/c2c60c86e938
branches: trunk
changeset: 1008451:c2c60c86e938
user: nisimura <nisimura%NetBSD.org@localhost>
date: Mon Mar 23 03:25:06 2020 +0000
description:
Socionext "NetSec" GbE driver
diffstat:
sys/arch/arm/sociox/if_scx.c | 1444 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 1444 insertions(+), 0 deletions(-)
diffs (truncated from 1448 to 300 lines):
diff -r 0c17ffb1d9cd -r c2c60c86e938 sys/arch/arm/sociox/if_scx.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/sociox/if_scx.c Mon Mar 23 03:25:06 2020 +0000
@@ -0,0 +1,1444 @@
+/* $NetBSD: if_scx.c,v 1.1 2020/03/23 03:25:06 nisimura Exp $ */
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tohru Nishimura.
+ *
+ * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+#define NOT_MP_SAFE 0
+
+/*
+ * Socionext SC2A11 SynQuacer NetSec GbE driver
+ *
+ * (possibly incorrect notes to be removed eventually)
+ * - 32 byte descriptor for 64 bit paddr design.
+ * - multiple rings seems available. There are special descriptor fields
+ * to designify ring number from which to arrive or to which go.
+ * - memory mapped EEPROM to hold MAC address. The rest of the area is
+ * occupied by a set of ucode for two DMA engines and one packet engine.
+ * - The size of frame address filter is unknown. Might be 32
+ * - The first slot is my own station address. Always enabled to perform
+ * to identify oneself.
+ * - 1~31 are for supplimental MAC addresses. Independently enabled
+ * for use. Good to catch multicast. Byte-wise selective match available.
+ * Use to catch { 0x01, 0x00, 0x00 } and/or { 0x33, 0x33 }.
+ * - The size of multicast hash filter store is unknown. Might be 256 bit.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1.1 2020/03/23 03:25:06 nisimura Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/intr.h>
+#include <sys/device.h>
+#include <sys/callout.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/errno.h>
+#include <sys/rndsource.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+#include <net/if_dl.h>
+#include <net/if_ether.h>
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+#include <net/bpf.h>
+
+#include <dev/fdt/fdtvar.h>
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpi_intr.h>
+
+#define SWRESET 0x104
+#define COMINIT 0x120
+#define INTRST 0x200
+#define IRQ_RX (1U<<1)
+#define IRQ_TX (1U<<0)
+#define INTREN 0x204
+#define INTR_SET 0x234
+#define INTR_CLR 0x238
+#define TXINTST 0x400
+#define TXINTEN 0x404
+#define TXINT_SET 0x428
+#define TXINT_CLR 0x42c
+#define TXI_NTOWNR (1U<<17)
+#define TXI_TR_ERR (1U<<16)
+#define TXI_TXDONE (1U<<15)
+#define TXI_TMREXP (1U<<14)
+#define RXINTST 0x440
+#define RXINTEN 0x444
+#define RXINT_SET 0x468
+#define RXINT_CLR 0x46c
+#define RXI_RC_ERR (1U<<16)
+#define RXI_PKTCNT (1U<<15)
+#define RXI_TMREXP (1U<<14)
+#define TXTIMER 0x41c
+#define RXTIMER 0x45c
+#define TXCOUNT 0x410
+#define RXCOUNT 0x454
+#define DMACH2M 0x210 /* DMAC host2media ucode port */
+#define DMACM2H 0x21c /* DMAC media2host ucode port */
+#define PKTENG 0x0d0 /* packet engine ucode port */
+#define HWVER0 0x22c
+#define HWVER1 0x230
+
+#define MACSTAT 0x1024 /* gmac status */
+#define MACDATA 0x11c0 /* gmac rd/wr data */
+#define MACCMD 0x11c4 /* gmac operation */
+#define CMD_IOWR (1U<<28) /* write op */
+#define CMD_BUSY (1U<<31) /* busy bit */
+#define DESCENG_INIT 0x11fc
+#define DESCENG_SRST 0x1204
+
+#define GMACMCR 0x0000 /* MAC configuration */
+#define MCR_IBN (1U<<30) /* */
+#define MCR_CST (1U<<25) /* strip CRC */
+#define MCR_TC (1U<<24) /* keep RGMII PHY notified */
+#define MCR_JE (1U<<20) /* ignore oversized >9018 frame */
+#define MCR_USEMII (1U<<15) /* 1: RMII/MII, 0: RGMII */
+#define MCR_SPD100 (1U<<14) /* force speed 100 */
+#define MCR_USEFDX (1U<<11) /* force full duplex */
+#define MCR_IPCKEN (1U<<10) /* handle checksum */
+#define MCR_ACS (1U<<7) /* auto pad CRC strip */
+#define MCR_TXE (1U<<3) /* start Tx DMA engine */
+#define MCR_RXE (1U<<2) /* start Rx DMA engine */
+#define _MCR_FDX 0x0000280c /* XXX TBD */
+#define _MCR_HDX 0x0001a00c /* XXX TBD */
+#define GMACAFR 0x0004 /* frame DA/SA address filter */
+#define AFR_RA (1U<<31) /* receive all on */
+#define AFR_HPF (1U<<10) /* activate hash or perfect filter */
+#define AFR_SAF (1U<<9) /* source address filter */
+#define AFR_SAIF (1U<<8) /* SA inverse filtering */
+#define AFR_PCF (3U<<6) /* */
+#define AFR_RB (1U<<5) /* reject broadcast frame */
+#define AFR_AM (1U<<4) /* accept all multicast frame */
+#define AFR_DAIF (1U<<3) /* DA inverse filtering */
+#define AFR_MHTE (1U<<2) /* use multicast hash table */
+#define AFR_UHTE (1U<<1) /* use additional MAC addresses */
+#define AFR_PM (1U<<0) /* run promisc mode */
+#define _AFR 0x80000001 /* XXX TBD */
+#define GMACMHTH 0x0008 /* XXX multicast hash table 63:32 */
+#define GMACMHTL 0x000c /* XXX multicast hash table 31:0 */
+#define GMACGAR 0x0010 /* MDIO operation */
+#define GAR_PHY (11) /* mii phy 15:11 */
+#define GAR_REG (6) /* mii reg 10:6 */
+#define GAR_CTL (2) /* control 5:2 */
+#define GAR_IOWR (1U<<1) /* MDIO write op */
+#define GAR_BUSY (1U) /* busy bit */
+#define GMACGDR 0x0014 /* MDIO rd/wr data */
+#define GMACFCR 0x0018 /* 802.3x flowcontrol */
+#define FCR_RFE (1U<<2) /* accept PAUSE to throttle Tx */
+#define FCR_TFE (1U<<1) /* generate PAUSE to moderate Rx lvl */
+#define GMACIMPL 0x0020 /* (dig this number XXXX.YYYY) */
+#define GMACVTAG 0x001c /* VLAN tag control */
+#define GMACMAH0 0x0040 /* MAC address 0 47:32 */
+#define GMACMAL0 0x0044 /* MAC address 0 31:0 */
+#define GMACMAH(i) ((i)*8+0x40) /* 0 - 15 */
+#define GMACMAL(i) ((i)*8+0x44)
+#define GMACMHT0 0x0500 /* multcast hash table 0 - 8*/
+#define GMACBMR 0x1000 /* DMA bus mode
+ * 24 4PBL
+ * 22:17 RPBL
+ * 16 fix burst
+ * 15:14 priority between Rx and Tx
+ * 3 rxtx41
+ * 2 rxtx31
+ * 1 rxtx21
+ * 0 rxtx11
+ * 13:8 PBL possible DMA burst len
+ * 0 reset op. self clear
+ */
+#define _BMR 0x00412080 /* XXX TBD */
+#define _BMR0 0x00020181 /* XXX TBD */
+#define BMR_RST (1U<<0) /* reset op. self clear when done */
+#define GMACRDLAR 0x100c /* */
+#define _RDLAR 0x18000 /* XXX TBD */
+#define GMACTDLAR 0x1010 /* */
+#define _TDLAR 0x1c000 /* XXX TBD */
+#define GMACOMR 0x1018 /* DMA operation */
+#define OMR_TXE (1U<<13) /* start Tx DMA engine */
+#define OMR_RXE (1U<<1) /* start Rx DMA engine */
+
+const struct {
+ uint16_t freq, bit; /* GAR 5:2 MDIO frequency selection */
+} garclk[] = {
+ { 35, 2 }, /* 25-35 MHz */
+ { 60, 3 }, /* 35-60 MHz */
+ { 100, 0 }, /* 60-100 MHz */
+ { 150, 1 }, /* 100-150 MHz */
+ { 250, 4 }, /* 150-250 MHz */
+ { 300, 5 }, /* 250-300 MHz */
+ { 0 },
+};
+static int get_garclk(uint32_t);
+
+/* descriptor format definition */
+struct tdes {
+ uint32_t t0, t1, t2, t3;
+};
+
+struct rdes {
+ uint32_t r0, r1, r2, r3;
+};
+
+#define T0_OWN (1U<<31) /* desc is ready to Tx */
+#define T0_EOD (1U<<30) /* end of descriptor array */
+#define T0_DRID (24) /* 29:24 DRID */
+#define T0_PT (1U<<21) /* 23:21 PT */
+#define T0_TRID (16) /* 20:16 TRID */
+#define T0_FS (1U<<9) /* first segment of frame */
+#define T0_LS (1U<<8) /* last segment of frame */
+#define T0_CSUM (1U<<7) /* enable check sum offload */
+#define T0_SGOL (1U<<6) /* enable TCP segment offload */
+#define T0_TRS (1U<<4) /* 5:4 TRS */
+#define T0_IOC (0) /* XXX TBD interrupt when completed */
+/* T1 segment address 63:32 */
+/* T2 segment address 31:0 */
+/* T3 31:16 TCP segment length, 15:0 segment length to transmit */
+#define R0_OWN (1U<<31) /* desc is empty */
+#define R0_EOD (1U<<30) /* end of descriptor array */
+#define R0_SRID (24) /* 29:24 SRID */
+#define R0_FR (1U<<23) /* FR */
+#define R0_ER (1U<<21) /* Rx error indication */
+#define R0_ERR (3U<<16) /* 18:16 receive error code */
+#define R0_TDRID (14) /* 15:14 TDRID */
+#define R0_FS (1U<<9) /* first segment of frame */
+#define R0_LS (1U<<8) /* last segment of frame */
+#define R0_CSUM (3U<<6) /* 7:6 checksum status */
+#define R0_CERR (2U<<6) /* 0 (undone), 1 (found ok), 2 (bad) */
+/* R1 frame address 63:32 */
+/* R2 frame address 31:0 */
+/* R3 31:16 received frame length, 15:0 buffer length to receive */
+
+#define SCX_NTXSEGS 16
+#define SCX_TXQUEUELEN 16
+#define SCX_TXQUEUELEN_MASK (SCX_TXQUEUELEN - 1)
+#define SCX_TXQUEUE_GC (SCX_TXQUEUELEN / 4)
+#define SCX_NTXDESC (SCX_TXQUEUELEN * SCX_NTXSEGS)
+#define SCX_NTXDESC_MASK (SCX_NTXDESC - 1)
+#define SCX_NEXTTX(x) (((x) + 1) & SCX_NTXDESC_MASK)
+#define SCX_NEXTTXS(x) (((x) + 1) & SCX_TXQUEUELEN_MASK)
+
+#define SCX_NRXDESC 64
+#define SCX_NRXDESC_MASK (SCX_NRXDESC - 1)
+#define SCX_NEXTRX(x) (((x) + 1) & SCX_NRXDESC_MASK)
+
+#define SCX_INIT_RXDESC(sc, x) \
+do { \
+ struct scx_rxsoft *__rxs = &(sc)->sc_rxsoft[(x)]; \
+ struct rdes *__rxd = &(sc)->sc_rxdescs[(x)]; \
+ struct mbuf *__m = __rxs->rxs_mbuf; \
+ bus_addr_t __paddr =__rxs->rxs_dmamap->dm_segs[0].ds_addr; \
+ __m->m_data = __m->m_ext.ext_buf; \
+ __rxd->r3 = __rxs->rxs_dmamap->dm_segs[0].ds_len; \
+ __rxd->r2 = htole32(BUS_ADDR_LO32(__paddr)); \
+ __rxd->r1 = htole32(BUS_ADDR_HI32(__paddr)); \
+ __rxd->r0 = R0_OWN | R0_FS | R0_LS; \
+ if ((x) == SCX_NRXDESC - 1) __rxd->r0 |= R0_EOD; \
+} while (/*CONSTCOND*/0)
+
+struct control_data {
+ struct tdes cd_txdescs[SCX_NTXDESC];
+ struct rdes cd_rxdescs[SCX_NRXDESC];
+};
+#define SCX_CDOFF(x) offsetof(struct control_data, x)
+#define SCX_CDTXOFF(x) SCX_CDOFF(cd_txdescs[(x)])
+#define SCX_CDRXOFF(x) SCX_CDOFF(cd_rxdescs[(x)])
+
+struct scx_txsoft {
+ struct mbuf *txs_mbuf; /* head of our mbuf chain */
+ bus_dmamap_t txs_dmamap; /* our DMA map */
+ int txs_firstdesc; /* first descriptor in packet */
+ int txs_lastdesc; /* last descriptor in packet */
+ int txs_ndesc; /* # of descriptors used */
+};
+
+struct scx_rxsoft {
+ struct mbuf *rxs_mbuf; /* head of our mbuf chain */
+ bus_dmamap_t rxs_dmamap; /* our DMA map */
+};
+
+struct scx_softc {
+ device_t sc_dev; /* generic device information */
+ bus_space_tag_t sc_st; /* bus space tag */
+ bus_space_handle_t sc_sh; /* bus space handle */
+ bus_size_t sc_sz; /* csr map size */
+ bus_space_handle_t sc_eesh; /* eeprom section handle */
+ bus_size_t sc_eesz; /* eeprom map size */
+ bus_dma_tag_t sc_dmat; /* bus DMA tag */
Home |
Main Index |
Thread Index |
Old Index