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