Home | History | Annotate | Line # | Download | only in sociox
if_scx.c revision 1.43
      1  1.43  nisimura /*	$NetBSD: if_scx.c,v 1.43 2023/06/15 07:21:45 nisimura Exp $	*/
      2   1.1  nisimura 
      3   1.1  nisimura /*-
      4   1.1  nisimura  * Copyright (c) 2020 The NetBSD Foundation, Inc.
      5   1.1  nisimura  * All rights reserved.
      6   1.1  nisimura  *
      7   1.1  nisimura  * This code is derived from software contributed to The NetBSD Foundation
      8   1.1  nisimura  * by Tohru Nishimura.
      9   1.1  nisimura  *
     10   1.1  nisimura  * Redistribution and use in source and binary forms, with or without
     11   1.1  nisimura  * modification, are permitted provided that the following conditions
     12   1.1  nisimura  * are met:
     13   1.1  nisimura  * 1. Redistributions of source code must retain the above copyright
     14   1.1  nisimura  *    notice, this list of conditions and the following disclaimer.
     15   1.1  nisimura  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1  nisimura  *    notice, this list of conditions and the following disclaimer in the
     17   1.1  nisimura  *    documentation and/or other materials provided with the distribution.
     18   1.1  nisimura  *
     19   1.1  nisimura  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20   1.1  nisimura  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21   1.1  nisimura  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22   1.1  nisimura  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23   1.1  nisimura  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24   1.1  nisimura  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25   1.1  nisimura  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26   1.1  nisimura  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27   1.1  nisimura  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28   1.1  nisimura  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29   1.1  nisimura  * POSSIBILITY OF SUCH DAMAGE.
     30   1.1  nisimura  */
     31   1.1  nisimura 
     32  1.40  nisimura #define NOT_MP_SAFE	0
     33   1.1  nisimura 
     34   1.1  nisimura /*
     35   1.1  nisimura  * Socionext SC2A11 SynQuacer NetSec GbE driver
     36   1.1  nisimura  *
     37  1.23  nisimura  * Multiple Tx and Rx queues exist inside and dedicated descriptor
     38  1.23  nisimura  * fields specifies which queue is to use. Three internal micro-processors
     39  1.23  nisimura  * to handle incoming frames, outgoing frames and packet data crypto
     40  1.23  nisimura  * processing. uP programs are stored in an external flash memory and
     41  1.23  nisimura  * have to be loaded by device driver.
     42  1.25    andvar  * NetSec uses Synopsys DesignWare Core EMAC.  DWC implementation
     43  1.25    andvar  * register (0x20) is known to have 0x10.36 and feature register (0x1058)
     44  1.36  nisimura  * reports 0x11056f37.
     45  1.40  nisimura  *  <24> alternative/enhanced desc format
     46  1.36  nisimura  *  <18> receive IP type 2 checksum offload
     47  1.36  nisimura  *  <16> transmit checksum offload
     48  1.36  nisimura  *  <11> event counter (mac management counter, MMC)
     49   1.1  nisimura  */
     50   1.1  nisimura 
     51   1.1  nisimura #include <sys/cdefs.h>
     52  1.43  nisimura __KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1.43 2023/06/15 07:21:45 nisimura Exp $");
     53   1.1  nisimura 
     54   1.1  nisimura #include <sys/param.h>
     55   1.1  nisimura #include <sys/bus.h>
     56   1.1  nisimura #include <sys/intr.h>
     57   1.1  nisimura #include <sys/device.h>
     58   1.1  nisimura #include <sys/callout.h>
     59   1.1  nisimura #include <sys/mbuf.h>
     60   1.1  nisimura #include <sys/errno.h>
     61   1.1  nisimura #include <sys/rndsource.h>
     62   1.1  nisimura #include <sys/kernel.h>
     63   1.1  nisimura #include <sys/systm.h>
     64   1.1  nisimura 
     65   1.1  nisimura #include <net/if.h>
     66   1.1  nisimura #include <net/if_media.h>
     67   1.1  nisimura #include <net/if_dl.h>
     68   1.1  nisimura #include <net/if_ether.h>
     69   1.1  nisimura #include <dev/mii/mii.h>
     70   1.1  nisimura #include <dev/mii/miivar.h>
     71   1.1  nisimura #include <net/bpf.h>
     72   1.1  nisimura 
     73   1.1  nisimura #include <dev/fdt/fdtvar.h>
     74   1.1  nisimura #include <dev/acpi/acpireg.h>
     75   1.1  nisimura #include <dev/acpi/acpivar.h>
     76   1.1  nisimura #include <dev/acpi/acpi_intr.h>
     77   1.1  nisimura 
     78  1.41  nisimura /* SC2A11 GbE has 64-bit paddr descriptor */
     79  1.23  nisimura struct tdes {
     80  1.23  nisimura 	uint32_t t0, t1, t2, t3;
     81  1.23  nisimura };
     82  1.23  nisimura struct rdes {
     83  1.23  nisimura 	uint32_t r0, r1, r2, r3;
     84  1.23  nisimura };
     85  1.23  nisimura #define T0_OWN		(1U<<31)	/* desc is ready to Tx */
     86  1.40  nisimura #define T0_LD		(1U<<30)	/* last descriptor in array */
     87  1.26  nisimura #define T0_DRID		(24)		/* 29:24 desc ring id */
     88  1.26  nisimura #define T0_PT		(1U<<21)	/* 23:21 "pass-through" */
     89  1.26  nisimura #define T0_TDRID	(16)		/* 20:16 target desc ring id: GMAC=15 */
     90  1.40  nisimura #define T0_CC		(1U<<15)	/* ??? */
     91  1.23  nisimura #define T0_FS		(1U<<9)		/* first segment of frame */
     92  1.23  nisimura #define T0_LS		(1U<<8)		/* last segment of frame */
     93  1.23  nisimura #define T0_CSUM		(1U<<7)		/* enable check sum offload */
     94  1.26  nisimura #define T0_TSO		(1U<<6)		/* enable TCP segment offload */
     95  1.40  nisimura #define T0_TRS		(1U<<4)		/* 5:4 "TRS" ??? */
     96  1.26  nisimura /* T1 frame segment address 63:32 */
     97  1.26  nisimura /* T2 frame segment address 31:0 */
     98  1.26  nisimura /* T3 31:16 TCP segment length, 15:0 frame segment length to transmit */
     99  1.23  nisimura #define R0_OWN		(1U<<31)	/* desc is empty */
    100  1.40  nisimura #define R0_LD		(1U<<30)	/* last descriptor in array */
    101  1.26  nisimura #define R0_SDRID	(24)		/* 29:24 source desc ring id */
    102  1.26  nisimura #define R0_FR		(1U<<23)	/* found fragmented */
    103  1.23  nisimura #define R0_ER		(1U<<21)	/* Rx error indication */
    104  1.23  nisimura #define R0_ERR		(3U<<16)	/* 18:16 receive error code */
    105  1.26  nisimura #define R0_TDRID	(12)		/* 15:12 target desc ring id */
    106  1.23  nisimura #define R0_FS		(1U<<9)		/* first segment of frame */
    107  1.23  nisimura #define R0_LS		(1U<<8)		/* last segment of frame */
    108  1.41  nisimura #define R0_CSUM		(3U<<6)		/* 7:6 checksum status, 0: undone */
    109  1.41  nisimura #define R0_CERR		(2U<<6)		/* 2: found bad */
    110  1.41  nisimura #define R0_COK		(1U<<6)		/* 1: found ok */
    111  1.23  nisimura /* R1 frame address 63:32 */
    112  1.23  nisimura /* R2 frame address 31:0 */
    113  1.23  nisimura /* R3 31:16 received frame length, 15:0 buffer length to receive */
    114  1.23  nisimura 
    115  1.19  nisimura /*
    116  1.26  nisimura  * SC2A11 registers. 0x100 - 1204
    117  1.19  nisimura  */
    118   1.1  nisimura #define SWRESET		0x104
    119  1.26  nisimura #define  SRST_RUN	(1U<<31)	/* instruct start, 0 to stop */
    120   1.1  nisimura #define COMINIT		0x120
    121  1.26  nisimura #define  INIT_DB	(1U<<2)		/* ???; self clear when done */
    122  1.26  nisimura #define  INIT_CLS	(1U<<1)		/* ???; self clear when done */
    123  1.28  nisimura #define xINTSR		0x200		/* aggregated interrupt status */
    124  1.40  nisimura #define  IRQ_UCODE	(1U<<20)	/* ucode load completed; W1C */
    125  1.40  nisimura #define  IRQ_MAC	(1U<<19)	/* ??? */
    126  1.40  nisimura #define  IRQ_PKT	(1U<<18)	/* ??? */
    127  1.40  nisimura #define  IRQ_BOOTCODE	(1U<<5)		/* ??? */
    128  1.40  nisimura #define  IRQ_XDONE	(1U<<4)		/* ??? mode change completed */
    129  1.18  nisimura #define  IRQ_RX		(1U<<1)		/* top level Rx interrupt */
    130  1.40  nisimura #define  IRQ_TX		(1U<<0)		/* top level Tx interrupt */
    131  1.18  nisimura #define xINTAEN		0x204		/* INT_A enable */
    132  1.26  nisimura #define xINTAE_SET	0x234		/* bit to set */
    133  1.26  nisimura #define xINTAE_CLR	0x238		/* bit to clr */
    134  1.18  nisimura #define xINTBEN		0x23c		/* INT_B enable */
    135  1.26  nisimura #define xINTBE_SET	0x240		/* bit to set */
    136  1.26  nisimura #define xINTBE_CLR	0x244		/* bit to clr */
    137  1.31  nisimura #define TXISR		0x400		/* transmit status; W1C */
    138  1.26  nisimura #define TXIEN		0x404		/* tx interrupt enable */
    139  1.26  nisimura #define TXIE_SET	0x428		/* bit to set */
    140  1.26  nisimura #define TXIE_CLR	0x42c		/* bit to clr */
    141  1.31  nisimura #define  TXI_NTOWNR	(1U<<17)	/* ??? desc array got empty */
    142  1.43  nisimura #define  TXI_TR_ERR	(1U<<16)	/* xmit error detected */
    143  1.41  nisimura #define  TXI_TXDONE	(1U<<15)	/* xmit completed */
    144  1.41  nisimura #define  TXI_TMREXP	(1U<<14)	/* coalesce guard timer expired */
    145  1.31  nisimura #define RXISR		0x440		/* receive status; W1C */
    146  1.26  nisimura #define RXIEN		0x444		/* rx interrupt enable */
    147  1.26  nisimura #define RXIE_SET	0x468		/* bit to set */
    148  1.26  nisimura #define RXIE_CLR	0x46c		/* bit to clr */
    149  1.43  nisimura #define  RXI_RC_ERR	(1U<<16)	/* recv error detected */
    150  1.41  nisimura #define  RXI_PKTCNT	(1U<<15)	/* recv counter has new value */
    151  1.41  nisimura #define  RXI_TMREXP	(1U<<14)	/* coalesce guard timer expired */
    152  1.26  nisimura #define TDBA_LO		0x408		/* tdes array base addr 31:0 */
    153  1.26  nisimura #define TDBA_HI		0x434		/* tdes array base addr 63:32 */
    154  1.26  nisimura #define RDBA_LO		0x448		/* rdes array base addr 31:0 */
    155  1.26  nisimura #define RDBA_HI		0x474		/* rdes array base addr 63:32 */
    156  1.42  nisimura #define TXCONF		0x430		/* tdes config */
    157  1.42  nisimura #define RXCONF		0x470		/* rdes config */
    158  1.41  nisimura #define  DESCNF_UP	(1U<<31)	/* 'up-and-running' */
    159  1.26  nisimura #define  DESCNF_CHRST	(1U<<30)	/* channel reset */
    160  1.43  nisimura #define  DESCNF_TMR	(1U<<4)		/* coalesce timer unit select */
    161  1.26  nisimura #define  DESCNF_LE	(1)		/* little endian desc format */
    162  1.33  nisimura #define TXSUBMIT	0x410		/* submit frame(s) to transmit */
    163  1.41  nisimura #define TXCOALESC	0x418		/* tx intr coalesce upper bound */
    164  1.41  nisimura #define RXCOALESC	0x458		/* rx intr coalesce upper bound */
    165  1.43  nisimura #define TCLSCTIME	0x420		/* tintr guard time usec */
    166  1.43  nisimura #define RCLSCTIME	0x460		/* rintr guard time usec */
    167  1.32  nisimura #define TXDONECNT	0x414		/* tx completed count, auto-zero */
    168  1.41  nisimura #define RXAVAILCNT	0x454		/* rx available count, auto-zero */
    169  1.43  nisimura #define DMACTL_TMR	0x20c		/* DMA cycle tick value */
    170  1.43  nisimura #define PKTCTRL		0x140		/* pkt engine control */
    171  1.43  nisimura #define  MODENRM	(1U<<28)	/* set operational mode to 'normal' */
    172  1.43  nisimura #define  ENJUMBO	(1U<<27)	/* allow jumbo frame */
    173  1.43  nisimura #define  RPTCSUMERR	(1U<<3)		/* log Rx checksum error */
    174  1.43  nisimura #define  RPTHDCOMP	(1U<<2)		/* log header incomplete condition */
    175  1.43  nisimura #define  RPTHDERR	(1U<<1)		/* log header error */
    176  1.43  nisimura #define  DROPNOMATCH	(1U<<0)		/* drop no match frames */
    177  1.43  nisimura #define UCODE_PKT	0x0d0		/* packet engine ucode port */
    178  1.26  nisimura #define UCODE_H2M	0x210		/* host2media engine ucode port */
    179  1.26  nisimura #define UCODE_M2H	0x21c		/* media2host engine ucode port */
    180  1.26  nisimura #define CORESTAT	0x218		/* engine run state */
    181  1.41  nisimura #define  PKTSTOP	(1U<<2)		/* pkt engine stopped */
    182  1.41  nisimura #define  M2HSTOP	(1U<<1)		/* M2H engine stopped */
    183  1.41  nisimura #define  H2MSTOP	(1U<<0)		/* H2M engine stopped */
    184  1.26  nisimura #define DMACTL_H2M	0x214		/* host2media engine control */
    185  1.26  nisimura #define DMACTL_M2H	0x220		/* media2host engine control */
    186  1.26  nisimura #define  DMACTL_STOP	(1U<<0)		/* instruct stop; self-clear */
    187  1.41  nisimura #define  M2H_MODE_TRANS	(1U<<20)	/* initiate M2H mode change */
    188  1.43  nisimura #define MODE_TRANS	0x500		/* mode change completion status */
    189  1.43  nisimura #define  N2T_DONE	(1U<<20)	/* normal->taiki change completed */
    190  1.43  nisimura #define  T2N_DONE	(1U<<19)	/* taiki->normal change completed */
    191  1.18  nisimura #define CLKEN		0x100		/* clock distribution enable */
    192  1.41  nisimura #define  CLK_G		(1U<<5)		/* feed clk domain G */
    193  1.26  nisimura #define  CLK_C		(1U<<1)		/* feed clk domain C */
    194  1.26  nisimura #define  CLK_D		(1U<<0)		/* feed clk domain D */
    195  1.43  nisimura #define DESC_INIT	0x11fc		/* write 1 for desc init, SC */
    196  1.43  nisimura #define DESC_SRST	0x1204		/* write 1 for desc sw reset, SC */
    197  1.26  nisimura 
    198  1.26  nisimura /* GMAC register indirect access. thru MACCMD/MACDATA operation */
    199  1.26  nisimura #define MACDATA		0x11c0		/* gmac register rd/wr data */
    200  1.26  nisimura #define MACCMD		0x11c4		/* gmac register operation */
    201  1.26  nisimura #define  CMD_IOWR	(1U<<28)	/* write op */
    202  1.26  nisimura #define  CMD_BUSY	(1U<<31)	/* busy bit */
    203  1.42  nisimura #define MACSTAT		0x1024		/* mac interrupt status (unused) */
    204  1.42  nisimura #define MACINTE		0x1028		/* mac interrupt enable (unused) */
    205  1.26  nisimura 
    206  1.26  nisimura #define FLOWTHR		0x11cc		/* flow control threshold */
    207  1.26  nisimura /* 31:16 pause threshold, 15:0 resume threshold */
    208  1.41  nisimura #define INTF_SEL	0x11d4		/* phy interface type */
    209  1.41  nisimura #define  INTF_GMII	0
    210  1.41  nisimura #define  INTF_RGMII	1
    211  1.41  nisimura #define  INTF_RMII	4
    212  1.26  nisimura 
    213  1.17  nisimura #define MCVER		0x22c		/* micro controller version */
    214  1.17  nisimura #define HWVER		0x230		/* hardware version */
    215   1.1  nisimura 
    216  1.19  nisimura /*
    217  1.26  nisimura  * GMAC registers are mostly identical to Synopsys DesignWare Core
    218  1.26  nisimura  * Ethernet. These must be handled by indirect access.
    219  1.19  nisimura  */
    220   1.1  nisimura #define GMACMCR		0x0000		/* MAC configuration */
    221  1.41  nisimura #define  MCR_IBN	(1U<<30)	/* watch in-band-signal */
    222   1.1  nisimura #define  MCR_CST	(1U<<25)	/* strip CRC */
    223   1.1  nisimura #define  MCR_TC		(1U<<24)	/* keep RGMII PHY notified */
    224  1.28  nisimura #define  MCR_WD		(1U<<23)	/* allow long >2048 tx frame */
    225  1.28  nisimura #define  MCR_JE		(1U<<20)	/* allow ~9018 tx jumbo frame */
    226  1.19  nisimura #define  MCR_IFG	(7U<<17)	/* 19:17 IFG value 0~7 */
    227  1.40  nisimura #define  MCR_DCRS	(1U<<16)	/* ignore (G)MII HDX Tx error */
    228  1.40  nisimura #define  MCR_PS		(1U<<15)	/* 1: MII 10/100, 0: GMII 1000 */
    229  1.40  nisimura #define  MCR_FES	(1U<<14)	/* force speed 100 */
    230  1.28  nisimura #define  MCR_DO		(1U<<13)	/* don't receive my own HDX Tx frames */
    231  1.26  nisimura #define  MCR_LOOP	(1U<<12)	/* run loop back */
    232   1.1  nisimura #define  MCR_USEFDX	(1U<<11)	/* force full duplex */
    233  1.19  nisimura #define  MCR_IPCEN	(1U<<10)	/* handle checksum */
    234  1.28  nisimura #define  MCR_DR		(1U<<9)		/* attempt no tx retry, send once */
    235  1.28  nisimura #define  MCR_LUD	(1U<<8)		/* link condition report when RGMII */
    236  1.41  nisimura #define  MCR_ACS	(1U<<7)		/* auto pad auto strip CRC */
    237  1.40  nisimura #define  MCR_DC		(1U<<4)		/* report excessive tx deferral */
    238  1.19  nisimura #define  MCR_TE		(1U<<3)		/* run Tx MAC engine, 0 to stop */
    239  1.19  nisimura #define  MCR_RE		(1U<<2)		/* run Rx MAC engine, 0 to stop */
    240  1.19  nisimura #define  MCR_PREA	(3U)		/* 1:0 preamble len. 0~2 */
    241   1.1  nisimura #define GMACAFR		0x0004		/* frame DA/SA address filter */
    242  1.25    andvar #define  AFR_RA		(1U<<31)	/* accept all irrespective of filt. */
    243  1.18  nisimura #define  AFR_HPF	(1U<<10)	/* hash+perfect filter, or hash only */
    244   1.1  nisimura #define  AFR_SAF	(1U<<9)		/* source address filter */
    245   1.1  nisimura #define  AFR_SAIF	(1U<<8)		/* SA inverse filtering */
    246  1.42  nisimura #define  AFR_PCF	(2U<<6)		/* 7:6 accept pause frame 0~3 */
    247  1.18  nisimura #define  AFR_DBF	(1U<<5)		/* reject broadcast frame */
    248  1.18  nisimura #define  AFR_PM		(1U<<4)		/* accept all multicast frame */
    249   1.1  nisimura #define  AFR_DAIF	(1U<<3)		/* DA inverse filtering */
    250   1.1  nisimura #define  AFR_MHTE	(1U<<2)		/* use multicast hash table */
    251  1.19  nisimura #define  AFR_UHTE	(1U<<1)		/* use hash table for unicast */
    252  1.18  nisimura #define  AFR_PR		(1U<<0)		/* run promisc mode */
    253   1.1  nisimura #define GMACGAR		0x0010		/* MDIO operation */
    254  1.26  nisimura #define  GAR_PHY	(11)		/* 15:11 mii phy */
    255  1.26  nisimura #define  GAR_REG	(6)		/* 10:6 mii reg */
    256  1.26  nisimura #define  GAR_CLK	(2)		/* 5:2 mdio clock tick ratio */
    257   1.1  nisimura #define  GAR_IOWR	(1U<<1)		/* MDIO write op */
    258  1.26  nisimura #define  GAR_BUSY	(1U<<0)		/* busy bit */
    259  1.26  nisimura #define  GAR_MDIO_25_35MHZ	2
    260  1.26  nisimura #define  GAR_MDIO_35_60MHZ	3
    261  1.26  nisimura #define  GAR_MDIO_60_100MHZ	0
    262  1.26  nisimura #define  GAR_MDIO_100_150MHZ	1
    263  1.26  nisimura #define  GAR_MDIO_150_250MHZ	4
    264  1.26  nisimura #define  GAR_MDIO_250_300MHZ	5
    265   1.1  nisimura #define GMACGDR		0x0014		/* MDIO rd/wr data */
    266   1.1  nisimura #define GMACFCR		0x0018		/* 802.3x flowcontrol */
    267  1.26  nisimura /* 31:16 pause timer value, 5:4 pause timer threshold */
    268   1.1  nisimura #define  FCR_RFE	(1U<<2)		/* accept PAUSE to throttle Tx */
    269   1.1  nisimura #define  FCR_TFE	(1U<<1)		/* generate PAUSE to moderate Rx lvl */
    270  1.40  nisimura #define GMACIMPL	0x0020		/* implementation id */
    271  1.28  nisimura #define GMACISR		0x0038		/* interrupt status indication */
    272  1.28  nisimura #define GMACIMR		0x003c		/* interrupt mask to inhibit */
    273  1.19  nisimura #define  ISR_TS		(1U<<9)		/* time stamp operation detected */
    274  1.19  nisimura #define  ISR_CO		(1U<<7)		/* Rx checksum offload completed */
    275  1.19  nisimura #define  ISR_TX		(1U<<6)		/* Tx completed */
    276  1.19  nisimura #define  ISR_RX		(1U<<5)		/* Rx completed */
    277  1.19  nisimura #define  ISR_ANY	(1U<<4)		/* any of above 5-7 report */
    278  1.19  nisimura #define  ISR_LC		(1U<<0)		/* link status change detected */
    279  1.23  nisimura #define GMACMAH0	0x0040		/* my own MAC address 47:32 */
    280  1.23  nisimura #define GMACMAL0	0x0044		/* my own MAC address 31:0 */
    281  1.25    andvar #define GMACMAH(i) 	((i)*8+0x40)	/* supplemental MAC addr 1-15 */
    282  1.23  nisimura #define GMACMAL(i) 	((i)*8+0x44)	/* 31:0 MAC address low part */
    283  1.23  nisimura /* MAH bit-31: slot in use, 30: SA to match, 29:24 byte-wise don'care */
    284  1.25    andvar #define GMACAMAH(i)	((i)*8+0x800)	/* supplemental MAC addr 16-31 */
    285  1.23  nisimura #define GMACAMAL(i)	((i)*8+0x804)	/* 31: MAC address low part */
    286  1.28  nisimura /* supplimental MAH bit-31: slot in use, no other bit is effective */
    287  1.23  nisimura #define GMACMHTH	0x0008		/* 64bit multicast hash table 63:32 */
    288  1.23  nisimura #define GMACMHTL	0x000c		/* 64bit multicast hash table 31:0 */
    289  1.23  nisimura #define GMACMHT(i)	((i)*4+0x500)	/* 256-bit alternative mcast hash 0-7 */
    290  1.40  nisimura #define GMACVTAG	0x001c		/* VLAN tag control */
    291  1.28  nisimura #define  VTAG_HASH	(1U<<19)	/* use VLAN tag hash table */
    292  1.28  nisimura #define  VTAG_SVLAN	(1U<<18)	/* handle type 0x88A8 SVLAN frame */
    293  1.28  nisimura #define  VTAG_INV	(1U<<17)	/* run inverse match logic */
    294  1.28  nisimura #define  VTAG_ETV	(1U<<16)	/* use only 12bit VID field to match */
    295  1.28  nisimura /* 15:0 concat of PRIO+CFI+VID */
    296  1.23  nisimura #define GMACVHT		0x0588		/* 16-bit VLAN tag hash */
    297  1.40  nisimura #define GMACMIISR	0x00d8		/* resolved RGMII/SGMII link status */
    298  1.28  nisimura #define  MIISR_LUP	(1U<<3)		/* link up(1)/down(0) report */
    299  1.28  nisimura #define  MIISR_SPD	(3U<<1)		/* 2:1 speed 10(0)/100(1)/1000(2) */
    300  1.28  nisimura #define  MIISR_FDX	(1U<<0)		/* fdx detected */
    301  1.28  nisimura 
    302  1.28  nisimura #define GMACLPIS	0x0030		/* LPI control & status */
    303  1.28  nisimura #define  LPIS_TXA	(1U<<19)	/* complete Tx in progress and LPI */
    304  1.28  nisimura #define  LPIS_PLS	(1U<<17)
    305  1.28  nisimura #define  LPIS_EN	(1U<<16)	/* 1: enter LPI mode, 0: exit */
    306  1.28  nisimura #define  LPIS_TEN	(1U<<0)		/* Tx LPI report */
    307  1.28  nisimura #define GMACLPIC	0x0034		/* LPI timer control */
    308  1.28  nisimura #define  LPIC_LST	(5)		/* 16:5 ??? */
    309  1.28  nisimura #define  LPIC_TWT	(0)		/* 15:0 ??? */
    310  1.40  nisimura /* 0x700-764 Time Stamp control */
    311  1.18  nisimura 
    312  1.23  nisimura #define GMACBMR		0x1000		/* DMA bus mode control */
    313  1.40  nisimura /* 24    8xPBL multiply by 8 for RPBL & PBL values
    314  1.40  nisimura  * 23    USP 1 to use RPBL for Rx DMA burst, 0 to share PBL by Rx and Tx
    315  1.23  nisimura  * 22:17 RPBL
    316  1.40  nisimura  * 16    FB fixed burst
    317  1.23  nisimura  * 15:14 priority between Rx and Tx
    318  1.23  nisimura  *  3    rxtx ratio 41
    319  1.23  nisimura  *  2    rxtx ratio 31
    320  1.23  nisimura  *  1    rxtx ratio 21
    321  1.23  nisimura  *  0    rxtx ratio 11
    322  1.26  nisimura  * 13:8  PBL possible DMA burst length
    323  1.40  nisimura  *  7    ATDS select 32-byte descriptor format for advanced features
    324  1.40  nisimura  *  6:2	 DSL descriptor skip length, 0 for adjuscent, counted on bus width
    325  1.40  nisimura  *  0    MAC reset op. self-clear
    326  1.23  nisimura  */
    327  1.16  nisimura #define  BMR_RST	(1)		/* reset op. self clear when done */
    328  1.18  nisimura #define GMACTPD		0x1004		/* write any to resume tdes */
    329  1.18  nisimura #define GMACRPD		0x1008		/* write any to resume rdes */
    330  1.18  nisimura #define GMACRDLA	0x100c		/* rdes base address 32bit paddr */
    331  1.18  nisimura #define GMACTDLA	0x1010		/* tdes base address 32bit paddr */
    332  1.18  nisimura #define GMACDSR		0x1014		/* DMA status detail report; W1C */
    333  1.28  nisimura #define GMACDIE		0x101c		/* DMA interrupt enable */
    334  1.28  nisimura #define  DMAI_LPI	(1U<<30)	/* LPI interrupt */
    335  1.28  nisimura #define  DMAI_TTI	(1U<<29)	/* timestamp trigger interrupt */
    336  1.28  nisimura #define  DMAI_GMI	(1U<<27)	/* management counter interrupt */
    337  1.28  nisimura #define  DMAI_GLI	(1U<<26)	/* xMII link change detected */
    338  1.28  nisimura #define  DMAI_EB	(23)		/* 25:23 DMA bus error detected */
    339  1.28  nisimura #define  DMAI_TS	(20)		/* 22:20 Tx DMA state report */
    340  1.28  nisimura #define  DMAI_RS	(17)		/* 29:17 Rx DMA state report */
    341  1.28  nisimura #define  DMAI_NIS	(1U<<16)	/* normal interrupt summary; W1C */
    342  1.28  nisimura #define  DMAI_AIS	(1U<<15)	/* abnormal interrupt summary; W1C */
    343  1.28  nisimura #define  DMAI_ERI	(1U<<14)	/* the first Rx buffer is filled */
    344  1.28  nisimura #define  DMAI_FBI	(1U<<13)	/* DMA bus error detected */
    345  1.28  nisimura #define  DMAI_ETI	(1U<<10)	/* single frame Tx completed */
    346  1.28  nisimura #define  DMAI_RWT	(1U<<9)		/* longer than 2048 frame received */
    347  1.28  nisimura #define  DMAI_RPS	(1U<<8)		/* Rx process is now stopped */
    348  1.28  nisimura #define  DMAI_RU	(1U<<7)		/* Rx descriptor not available */
    349  1.28  nisimura #define  DMAI_RI	(1U<<6)		/* frame Rx completed by !R1_DIC */
    350  1.28  nisimura #define  DMAI_UNF	(1U<<5)		/* Tx underflow detected */
    351  1.28  nisimura #define  DMAI_OVF	(1U<<4)		/* receive buffer overflow detected */
    352  1.28  nisimura #define  DMAI_TJT	(1U<<3)		/* longer than 2048 frame sent */
    353  1.37    andvar #define  DMAI_TU	(1U<<2)		/* Tx descriptor not available */
    354  1.28  nisimura #define  DMAI_TPS	(1U<<1)		/* transmission is stopped */
    355  1.28  nisimura #define  DMAI_TI	(1U<<0)		/* frame Tx completed by T0_IC */
    356  1.26  nisimura #define GMACOMR		0x1018		/* DMA operation mode */
    357  1.43  nisimura #define  OMR_DT		(1U<<26)	/* don't drop error frames */
    358  1.37    andvar #define  OMR_RSF	(1U<<25)	/* 1: Rx store&forward, 0: immed. */
    359  1.43  nisimura #define  OMR_DFF	(1U<<24)	/* don't flush rx frames on shortage */
    360  1.28  nisimura #define  OMR_TSF	(1U<<21)	/* 1: Tx store&forward, 0: immed. */
    361  1.43  nisimura #define  OMR_FTF	(1U<<20)	/* initiate tx FIFO reset, SC */
    362  1.28  nisimura #define  OMR_TTC	(14)		/* 16:14 Tx threshold */
    363  1.18  nisimura #define  OMR_ST		(1U<<13)	/* run Tx DMA engine, 0 to stop */
    364  1.28  nisimura #define  OMR_RFD	(11)		/* 12:11 Rx FIFO fill level */
    365  1.18  nisimura #define  OMR_EFC	(1U<<8)		/* transmit PAUSE to throttle Rx lvl. */
    366  1.18  nisimura #define  OMR_FEF	(1U<<7)		/* allow to receive error frames */
    367  1.26  nisimura #define  OMR_SR		(1U<<1)		/* run Rx DMA engine, 0 to stop */
    368  1.18  nisimura #define GMACEVCS	0x1020		/* missed frame or ovf detected */
    369  1.28  nisimura #define GMACRWDT	0x1024		/* enable rx watchdog timer interrupt */
    370  1.18  nisimura #define GMACAXIB	0x1028		/* AXI bus mode control */
    371  1.18  nisimura #define GMACAXIS	0x102c		/* AXI status report */
    372  1.26  nisimura /* 0x1048 current tx desc address */
    373  1.26  nisimura /* 0x104c current rx desc address */
    374  1.26  nisimura /* 0x1050 current tx buffer address */
    375  1.26  nisimura /* 0x1054 current rx buffer address */
    376  1.26  nisimura #define HWFEA		0x1058		/* DWC feature report */
    377  1.40  nisimura #define  FEA_EXDESC	(1U<<24)	/* alternative/enhanced desc layout */
    378  1.28  nisimura #define  FEA_2COE	(1U<<18)	/* Rx type 2 IP checksum offload */
    379  1.28  nisimura #define  FEA_1COE	(1U<<17)	/* Rx type 1 IP checksum offload */
    380  1.28  nisimura #define  FEA_TXOE	(1U<<16)	/* Tx checksum offload */
    381  1.36  nisimura #define  FEA_MMC	(1U<<11)	/* RMON event counter */
    382   1.1  nisimura 
    383  1.23  nisimura #define GMACEVCTL	0x0100		/* event counter control */
    384  1.26  nisimura #define  EVC_FHP	(1U<<5)		/* full-half preset */
    385  1.36  nisimura #define  EVC_CP		(1U<<4)		/* counter preset */
    386  1.36  nisimura #define  EVC_MCF	(1U<<3)		/* counter freeze */
    387  1.26  nisimura #define  EVC_ROR	(1U<<2)		/* auto-zero on counter read */
    388  1.26  nisimura #define  EVC_CSR	(1U<<1)		/* counter stop rollover */
    389  1.26  nisimura #define  EVC_CR		(1U<<0)		/* reset counters */
    390  1.26  nisimura #define GMACEVCNT(i)	((i)*4+0x114)	/* 80 event counters 0x114 - 0x284 */
    391   1.1  nisimura 
    392  1.40  nisimura /* 0x400-4ac L3/L4 control */
    393  1.40  nisimura 
    394  1.23  nisimura /*
    395  1.23  nisimura  * flash memory layout
    396  1.23  nisimura  * 0x00 - 07	48-bit MAC station address. 4 byte wise in BE order.
    397  1.26  nisimura  * 0x08 - 0b	H->MAC xfer engine program start addr 63:32.
    398  1.26  nisimura  * 0x0c - 0f	H2M program addr 31:0 (these are absolute addr, not offset)
    399  1.23  nisimura  * 0x10 - 13	H2M program length in 4 byte count.
    400  1.26  nisimura  * 0x14 - 0b	M->HOST xfer engine program start addr 63:32.
    401  1.26  nisimura  * 0x18 - 0f	M2H program addr 31:0 (absolute addr, not relative)
    402  1.23  nisimura  * 0x1c - 13	M2H program length in 4 byte count.
    403  1.26  nisimura  * 0x20 - 23	packet engine program addr 31:0, (absolute addr, not offset)
    404  1.23  nisimura  * 0x24 - 27	packet program length in 4 byte count.
    405  1.23  nisimura  *
    406  1.23  nisimura  * above ucode are loaded via mapped reg 0x210, 0x21c and 0x0c0.
    407  1.23  nisimura  */
    408   1.1  nisimura 
    409  1.43  nisimura #define  _BMR		0x00412080	/* NetSec BMR value, magic spell */
    410  1.41  nisimura /* NetSec uses local RAM to handle GMAC desc arrays */
    411  1.40  nisimura #define  _RDLA		0x18000
    412  1.40  nisimura #define  _TDLA		0x1c000
    413  1.41  nisimura /* lower address region is used for intermediate frame data buffers */
    414  1.40  nisimura 
    415  1.19  nisimura /*
    416  1.41  nisimura  * all below are software construction.
    417  1.19  nisimura  */
    418  1.40  nisimura #define MD_NTXDESC		128
    419  1.40  nisimura #define MD_NRXDESC		64
    420  1.40  nisimura 
    421  1.40  nisimura #define MD_NTXSEGS		16
    422  1.40  nisimura #define MD_TXQUEUELEN		8
    423   1.6  nisimura #define MD_TXQUEUELEN_MASK	(MD_TXQUEUELEN - 1)
    424   1.6  nisimura #define MD_TXQUEUE_GC		(MD_TXQUEUELEN / 4)
    425   1.6  nisimura #define MD_NTXDESC_MASK	(MD_NTXDESC - 1)
    426   1.6  nisimura #define MD_NEXTTX(x)		(((x) + 1) & MD_NTXDESC_MASK)
    427   1.6  nisimura #define MD_NEXTTXS(x)		(((x) + 1) & MD_TXQUEUELEN_MASK)
    428   1.6  nisimura 
    429   1.6  nisimura #define MD_NRXDESC_MASK	(MD_NRXDESC - 1)
    430   1.6  nisimura #define MD_NEXTRX(x)		(((x) + 1) & MD_NRXDESC_MASK)
    431   1.1  nisimura 
    432   1.1  nisimura struct control_data {
    433   1.6  nisimura 	struct tdes cd_txdescs[MD_NTXDESC];
    434   1.6  nisimura 	struct rdes cd_rxdescs[MD_NRXDESC];
    435   1.1  nisimura };
    436   1.1  nisimura #define SCX_CDOFF(x)		offsetof(struct control_data, x)
    437   1.1  nisimura #define SCX_CDTXOFF(x)		SCX_CDOFF(cd_txdescs[(x)])
    438   1.1  nisimura #define SCX_CDRXOFF(x)		SCX_CDOFF(cd_rxdescs[(x)])
    439   1.1  nisimura 
    440   1.1  nisimura struct scx_txsoft {
    441   1.1  nisimura 	struct mbuf *txs_mbuf;		/* head of our mbuf chain */
    442   1.1  nisimura 	bus_dmamap_t txs_dmamap;	/* our DMA map */
    443   1.1  nisimura 	int txs_firstdesc;		/* first descriptor in packet */
    444   1.1  nisimura 	int txs_lastdesc;		/* last descriptor in packet */
    445   1.1  nisimura 	int txs_ndesc;			/* # of descriptors used */
    446   1.1  nisimura };
    447   1.1  nisimura 
    448   1.1  nisimura struct scx_rxsoft {
    449   1.1  nisimura 	struct mbuf *rxs_mbuf;		/* head of our mbuf chain */
    450   1.1  nisimura 	bus_dmamap_t rxs_dmamap;	/* our DMA map */
    451   1.1  nisimura };
    452   1.1  nisimura 
    453   1.1  nisimura struct scx_softc {
    454   1.1  nisimura 	device_t sc_dev;		/* generic device information */
    455   1.1  nisimura 	bus_space_tag_t sc_st;		/* bus space tag */
    456   1.1  nisimura 	bus_space_handle_t sc_sh;	/* bus space handle */
    457   1.1  nisimura 	bus_size_t sc_sz;		/* csr map size */
    458   1.1  nisimura 	bus_space_handle_t sc_eesh;	/* eeprom section handle */
    459   1.1  nisimura 	bus_size_t sc_eesz;		/* eeprom map size */
    460   1.1  nisimura 	bus_dma_tag_t sc_dmat;		/* bus DMA tag */
    461   1.1  nisimura 	struct ethercom sc_ethercom;	/* Ethernet common data */
    462   1.1  nisimura 	struct mii_data sc_mii;		/* MII */
    463  1.23  nisimura 	callout_t sc_callout;		/* PHY monitor callout */
    464   1.1  nisimura 	bus_dma_segment_t sc_seg;	/* descriptor store seg */
    465   1.1  nisimura 	int sc_nseg;			/* descriptor store nseg */
    466   1.3  nisimura 	void *sc_ih;			/* interrupt cookie */
    467   1.1  nisimura 	int sc_phy_id;			/* PHY address */
    468   1.3  nisimura 	int sc_flowflags;		/* 802.3x PAUSE flow control */
    469   1.7  nisimura 	uint32_t sc_mdclk;		/* GAR 5:2 clock selection */
    470  1.27  nisimura 	uint32_t sc_t0cotso;		/* T0_CSUM | T0_TSO to run */
    471  1.40  nisimura 	int sc_miigmii;			/* 1: MII/GMII, 0: RGMII */
    472   1.1  nisimura 	int sc_phandle;			/* fdt phandle */
    473  1.14  nisimura 	uint64_t sc_freq;
    474  1.40  nisimura 	uint32_t sc_maxsize;
    475   1.1  nisimura 
    476   1.1  nisimura 	bus_dmamap_t sc_cddmamap;	/* control data DMA map */
    477   1.1  nisimura #define sc_cddma	sc_cddmamap->dm_segs[0].ds_addr
    478   1.1  nisimura 
    479   1.1  nisimura 	struct control_data *sc_control_data;
    480   1.1  nisimura #define sc_txdescs	sc_control_data->cd_txdescs
    481   1.1  nisimura #define sc_rxdescs	sc_control_data->cd_rxdescs
    482   1.1  nisimura 
    483   1.6  nisimura 	struct scx_txsoft sc_txsoft[MD_TXQUEUELEN];
    484   1.6  nisimura 	struct scx_rxsoft sc_rxsoft[MD_NRXDESC];
    485   1.1  nisimura 	int sc_txfree;			/* number of free Tx descriptors */
    486   1.1  nisimura 	int sc_txnext;			/* next ready Tx descriptor */
    487   1.1  nisimura 	int sc_txsfree;			/* number of free Tx jobs */
    488   1.1  nisimura 	int sc_txsnext;			/* next ready Tx job */
    489   1.1  nisimura 	int sc_txsdirty;		/* dirty Tx jobs */
    490   1.1  nisimura 	int sc_rxptr;			/* next ready Rx descriptor/descsoft */
    491   1.1  nisimura 
    492   1.1  nisimura 	krndsource_t rnd_source;	/* random source */
    493  1.29  nisimura #ifdef GMAC_EVENT_COUNTERS
    494  1.29  nisimura 	/* 80 event counters exist */
    495  1.27  nisimura #endif
    496   1.1  nisimura };
    497   1.1  nisimura 
    498   1.1  nisimura #define SCX_CDTXADDR(sc, x)	((sc)->sc_cddma + SCX_CDTXOFF((x)))
    499   1.1  nisimura #define SCX_CDRXADDR(sc, x)	((sc)->sc_cddma + SCX_CDRXOFF((x)))
    500   1.1  nisimura 
    501   1.1  nisimura #define SCX_CDTXSYNC(sc, x, n, ops)					\
    502   1.1  nisimura do {									\
    503   1.1  nisimura 	int __x, __n;							\
    504   1.1  nisimura 									\
    505   1.1  nisimura 	__x = (x);							\
    506   1.1  nisimura 	__n = (n);							\
    507   1.1  nisimura 									\
    508   1.1  nisimura 	/* If it will wrap around, sync to the end of the ring. */	\
    509   1.6  nisimura 	if ((__x + __n) > MD_NTXDESC) {				\
    510   1.1  nisimura 		bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,	\
    511   1.1  nisimura 		    SCX_CDTXOFF(__x), sizeof(struct tdes) *		\
    512   1.6  nisimura 		    (MD_NTXDESC - __x), (ops));			\
    513   1.6  nisimura 		__n -= (MD_NTXDESC - __x);				\
    514   1.1  nisimura 		__x = 0;						\
    515   1.1  nisimura 	}								\
    516   1.1  nisimura 									\
    517   1.1  nisimura 	/* Now sync whatever is left. */				\
    518   1.1  nisimura 	bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,		\
    519   1.1  nisimura 	    SCX_CDTXOFF(__x), sizeof(struct tdes) * __n, (ops));	\
    520   1.1  nisimura } while (/*CONSTCOND*/0)
    521   1.1  nisimura 
    522   1.1  nisimura #define SCX_CDRXSYNC(sc, x, ops)					\
    523   1.1  nisimura do {									\
    524   1.1  nisimura 	bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_cddmamap,		\
    525   1.1  nisimura 	    SCX_CDRXOFF((x)), sizeof(struct rdes), (ops));		\
    526   1.1  nisimura } while (/*CONSTCOND*/0)
    527   1.1  nisimura 
    528  1.23  nisimura #define SCX_INIT_RXDESC(sc, x)						\
    529  1.23  nisimura do {									\
    530  1.23  nisimura 	struct scx_rxsoft *__rxs = &(sc)->sc_rxsoft[(x)];		\
    531  1.23  nisimura 	struct rdes *__rxd = &(sc)->sc_rxdescs[(x)];			\
    532  1.23  nisimura 	struct mbuf *__m = __rxs->rxs_mbuf;				\
    533  1.40  nisimura 	bus_addr_t __p = __rxs->rxs_dmamap->dm_segs[0].ds_addr;		\
    534  1.40  nisimura 	bus_size_t __z = __rxs->rxs_dmamap->dm_segs[0].ds_len;		\
    535  1.23  nisimura 	__m->m_data = __m->m_ext.ext_buf;				\
    536  1.41  nisimura 	__rxd->r3 = htole32(__z - 4);					\
    537  1.40  nisimura 	__rxd->r2 = htole32(BUS_ADDR_LO32(__p));			\
    538  1.40  nisimura 	__rxd->r1 = htole32(BUS_ADDR_HI32(__p));			\
    539  1.40  nisimura 	__rxd->r0 &= htole32(R0_LD);					\
    540  1.40  nisimura 	__rxd->r0 |= htole32(R0_OWN);					\
    541  1.23  nisimura } while (/*CONSTCOND*/0)
    542  1.23  nisimura 
    543  1.27  nisimura /* memory mapped CSR register access */
    544  1.27  nisimura #define CSR_READ(sc,off) \
    545  1.27  nisimura 	    bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (off))
    546  1.27  nisimura #define CSR_WRITE(sc,off,val) \
    547  1.27  nisimura 	    bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (off), (val))
    548  1.27  nisimura 
    549  1.27  nisimura /* flash memory access */
    550  1.27  nisimura #define EE_READ(sc,off) \
    551  1.27  nisimura 	    bus_space_read_4((sc)->sc_st, (sc)->sc_eesh, (off))
    552  1.27  nisimura 
    553   1.1  nisimura static int scx_fdt_match(device_t, cfdata_t, void *);
    554   1.1  nisimura static void scx_fdt_attach(device_t, device_t, void *);
    555   1.1  nisimura static int scx_acpi_match(device_t, cfdata_t, void *);
    556   1.1  nisimura static void scx_acpi_attach(device_t, device_t, void *);
    557   1.1  nisimura 
    558  1.35  nisimura CFATTACH_DECL_NEW(scx_fdt, sizeof(struct scx_softc),
    559   1.1  nisimura     scx_fdt_match, scx_fdt_attach, NULL, NULL);
    560   1.1  nisimura 
    561  1.35  nisimura CFATTACH_DECL_NEW(scx_acpi, sizeof(struct scx_softc),
    562   1.1  nisimura     scx_acpi_match, scx_acpi_attach, NULL, NULL);
    563   1.1  nisimura 
    564   1.1  nisimura static void scx_attach_i(struct scx_softc *);
    565   1.1  nisimura static void scx_reset(struct scx_softc *);
    566  1.41  nisimura static void scx_stop(struct ifnet *, int);
    567   1.1  nisimura static int scx_init(struct ifnet *);
    568   1.1  nisimura static int scx_ioctl(struct ifnet *, u_long, void *);
    569   1.1  nisimura static void scx_set_rcvfilt(struct scx_softc *);
    570  1.23  nisimura static void scx_start(struct ifnet *);
    571  1.23  nisimura static void scx_watchdog(struct ifnet *);
    572   1.1  nisimura static int scx_intr(void *);
    573   1.1  nisimura static void txreap(struct scx_softc *);
    574  1.41  nisimura static void rxfill(struct scx_softc *);
    575   1.1  nisimura static int add_rxbuf(struct scx_softc *, int);
    576  1.23  nisimura static void rxdrain(struct scx_softc *sc);
    577  1.23  nisimura static void mii_statchg(struct ifnet *);
    578  1.23  nisimura static void scx_ifmedia_sts(struct ifnet *, struct ifmediareq *);
    579  1.23  nisimura static int mii_readreg(device_t, int, int, uint16_t *);
    580  1.23  nisimura static int mii_writereg(device_t, int, int, uint16_t);
    581  1.23  nisimura static void phy_tick(void *);
    582  1.40  nisimura static void dump_hwfeature(struct scx_softc *);
    583  1.13  nisimura 
    584  1.41  nisimura static void resetuengine(struct scx_softc *);
    585   1.1  nisimura static void loaducode(struct scx_softc *);
    586   1.2  nisimura static void injectucode(struct scx_softc *, int, bus_addr_t, bus_size_t);
    587  1.42  nisimura static void forcephyloopback(struct scx_softc *);
    588  1.42  nisimura static void resetphytonormal(struct scx_softc *);
    589  1.23  nisimura 
    590  1.14  nisimura static int get_mdioclk(uint32_t);
    591   1.1  nisimura 
    592  1.41  nisimura #define WAIT_FOR_SET(sc, reg, set) \
    593  1.41  nisimura 	wait_for_bits(sc, reg, set, ~0, 0)
    594  1.41  nisimura #define WAIT_FOR_CLR(sc, reg, clr) \
    595  1.41  nisimura 	wait_for_bits(sc, reg, 0, clr, 0)
    596  1.23  nisimura 
    597  1.23  nisimura static int
    598  1.23  nisimura wait_for_bits(struct scx_softc *sc, int reg,
    599  1.23  nisimura     uint32_t set, uint32_t clr, uint32_t fail)
    600  1.23  nisimura {
    601  1.23  nisimura 	uint32_t val;
    602  1.23  nisimura 	int ntries;
    603  1.23  nisimura 
    604  1.23  nisimura 	for (ntries = 0; ntries < 1000; ntries++) {
    605  1.23  nisimura 		val = CSR_READ(sc, reg);
    606  1.23  nisimura 		if ((val & set) || !(val & clr))
    607  1.23  nisimura 			return 0;
    608  1.23  nisimura 		if (val & fail)
    609  1.23  nisimura 			return 1;
    610  1.23  nisimura 		DELAY(1);
    611  1.23  nisimura 	}
    612  1.23  nisimura 	return 1;
    613  1.23  nisimura }
    614  1.23  nisimura 
    615  1.23  nisimura /* GMAC register indirect access */
    616  1.23  nisimura static int
    617  1.23  nisimura mac_read(struct scx_softc *sc, int reg)
    618  1.23  nisimura {
    619  1.23  nisimura 
    620  1.31  nisimura 	CSR_WRITE(sc, MACCMD, reg | CMD_BUSY);
    621  1.41  nisimura 	(void)WAIT_FOR_CLR(sc, MACCMD, CMD_BUSY);
    622  1.23  nisimura 	return CSR_READ(sc, MACDATA);
    623  1.23  nisimura }
    624  1.23  nisimura 
    625  1.23  nisimura static void
    626  1.23  nisimura mac_write(struct scx_softc *sc, int reg, int val)
    627  1.23  nisimura {
    628  1.23  nisimura 
    629  1.23  nisimura 	CSR_WRITE(sc, MACDATA, val);
    630  1.31  nisimura 	CSR_WRITE(sc, MACCMD, reg | CMD_IOWR | CMD_BUSY);
    631  1.41  nisimura 	(void)WAIT_FOR_CLR(sc, MACCMD, CMD_BUSY);
    632  1.23  nisimura }
    633   1.1  nisimura 
    634  1.31  nisimura /* dig and decode "clock-frequency" value for a given clkname */
    635  1.30  nisimura static int
    636  1.30  nisimura get_clk_freq(int phandle, const char *clkname)
    637  1.30  nisimura {
    638  1.30  nisimura 	u_int index, n, cells;
    639  1.30  nisimura 	const u_int *p;
    640  1.30  nisimura 	int err, len, resid;
    641  1.30  nisimura 	unsigned int freq = 0;
    642  1.30  nisimura 
    643  1.30  nisimura 	err = fdtbus_get_index(phandle, "clock-names", clkname, &index);
    644  1.30  nisimura 	if (err == -1)
    645  1.30  nisimura 		return -1;
    646  1.30  nisimura 	p = fdtbus_get_prop(phandle, "clocks", &len);
    647  1.30  nisimura 	if (p == NULL)
    648  1.30  nisimura 		return -1;
    649  1.30  nisimura 	for (n = 0, resid = len; resid > 0; n++) {
    650  1.30  nisimura 		const int cc_phandle =
    651  1.30  nisimura 		    fdtbus_get_phandle_from_native(be32toh(p[0]));
    652  1.30  nisimura 		if (of_getprop_uint32(cc_phandle, "#clock-cells", &cells))
    653  1.30  nisimura 			return -1;
    654  1.30  nisimura 		if (n == index) {
    655  1.30  nisimura 			if (of_getprop_uint32(cc_phandle,
    656  1.30  nisimura 			    "clock-frequency", &freq))
    657  1.30  nisimura 				return -1;
    658  1.30  nisimura 			return freq;
    659  1.30  nisimura 		}
    660  1.30  nisimura 		resid -= (cells + 1) * 4;
    661  1.30  nisimura 		p += (cells + 1) * 4;
    662  1.30  nisimura 	}
    663  1.30  nisimura 	return -1;
    664  1.30  nisimura }
    665  1.30  nisimura 
    666  1.40  nisimura #define ATTACH_DEBUG 1
    667  1.40  nisimura 
    668  1.24   thorpej static const struct device_compatible_entry compat_data[] = {
    669  1.24   thorpej 	{ .compat = "socionext,synquacer-netsec" },
    670  1.24   thorpej 	DEVICE_COMPAT_EOL
    671  1.24   thorpej };
    672  1.27  nisimura static const struct device_compatible_entry compatible[] = {
    673  1.27  nisimura 	{ .compat = "SCX0001" },
    674  1.27  nisimura 	DEVICE_COMPAT_EOL
    675  1.27  nisimura };
    676  1.24   thorpej 
    677   1.1  nisimura static int
    678   1.1  nisimura scx_fdt_match(device_t parent, cfdata_t cf, void *aux)
    679   1.1  nisimura {
    680   1.1  nisimura 	struct fdt_attach_args * const faa = aux;
    681   1.1  nisimura 
    682  1.24   thorpej 	return of_compatible_match(faa->faa_phandle, compat_data);
    683   1.1  nisimura }
    684   1.1  nisimura 
    685   1.1  nisimura static void
    686   1.1  nisimura scx_fdt_attach(device_t parent, device_t self, void *aux)
    687   1.1  nisimura {
    688   1.1  nisimura 	struct scx_softc * const sc = device_private(self);
    689   1.1  nisimura 	struct fdt_attach_args * const faa = aux;
    690   1.1  nisimura 	const int phandle = faa->faa_phandle;
    691   1.1  nisimura 	bus_space_handle_t bsh;
    692   1.1  nisimura 	bus_space_handle_t eebsh;
    693   1.2  nisimura 	bus_addr_t addr[2];
    694   1.2  nisimura 	bus_size_t size[2];
    695  1.40  nisimura 	void *intrh;
    696   1.1  nisimura 	char intrstr[128];
    697  1.30  nisimura 	int phy_phandle;
    698  1.40  nisimura 	const char *phy_mode;
    699  1.30  nisimura 	bus_addr_t phy_id;
    700  1.30  nisimura 	long ref_clk;
    701  1.30  nisimura 
    702   1.2  nisimura 	if (fdtbus_get_reg(phandle, 0, addr+0, size+0) != 0
    703   1.2  nisimura 	    || bus_space_map(faa->faa_bst, addr[0], size[0], 0, &bsh) != 0) {
    704  1.40  nisimura 		aprint_error(": unable to map registers\n");
    705   1.1  nisimura 		return;
    706   1.1  nisimura 	}
    707  1.40  nisimura 	if (fdtbus_get_reg(phandle, 1, addr+1, size+1) != 0
    708  1.40  nisimura 	    || bus_space_map(faa->faa_bst, addr[1], size[1], 0, &eebsh) != 0) {
    709  1.40  nisimura 		aprint_error(": unable to map device eeprom\n");
    710  1.40  nisimura 		goto fail;
    711  1.40  nisimura 	}
    712   1.1  nisimura 	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
    713  1.40  nisimura 		aprint_error(": failed to decode interrupt\n");
    714   1.1  nisimura 		goto fail;
    715   1.1  nisimura 	}
    716  1.40  nisimura 
    717  1.40  nisimura 	phy_mode = fdtbus_get_string(phandle, "phy-mode");
    718  1.40  nisimura 	if (phy_mode == NULL)
    719  1.40  nisimura 		aprint_error(": missing 'phy-mode' property\n");
    720  1.40  nisimura 	phy_phandle = fdtbus_get_phandle(phandle, "phy-handle");
    721  1.40  nisimura 	if (phy_phandle == -1
    722  1.40  nisimura 	    || fdtbus_get_reg(phy_phandle, 0, &phy_id, NULL) != 0)
    723  1.40  nisimura 		phy_id = MII_PHY_ANY;
    724  1.40  nisimura 	ref_clk = get_clk_freq(phandle, "phy_ref_clk");
    725  1.40  nisimura 	if (ref_clk == -1)
    726  1.40  nisimura 		ref_clk = 250 * 1000 * 1000;
    727  1.40  nisimura 
    728  1.40  nisimura #if ATTACH_DEBUG == 1
    729  1.40  nisimura aprint_normal("\n");
    730  1.40  nisimura aprint_normal_dev(self,
    731  1.40  nisimura     "[FDT] phy mode %s, phy id %d, freq %ld\n",
    732  1.40  nisimura     phy_mode, (int)phy_id, ref_clk);
    733  1.40  nisimura aprint_normal("%s", device_xname(self));
    734  1.40  nisimura #endif
    735  1.40  nisimura 
    736  1.40  nisimura 	intrh = fdtbus_intr_establish(phandle, 0, IPL_NET,
    737   1.1  nisimura 		NOT_MP_SAFE, scx_intr, sc);
    738  1.40  nisimura 	if (intrh == NULL) {
    739  1.40  nisimura 		aprint_error(": couldn't establish interrupt\n");
    740   1.1  nisimura 		goto fail;
    741   1.1  nisimura 	}
    742  1.40  nisimura 	aprint_normal(" interrupt on %s", intrstr);
    743   1.1  nisimura 
    744   1.1  nisimura 	sc->sc_dev = self;
    745  1.31  nisimura 	sc->sc_st = faa->faa_bst;
    746   1.1  nisimura 	sc->sc_sh = bsh;
    747   1.2  nisimura 	sc->sc_sz = size[0];
    748   1.1  nisimura 	sc->sc_eesh = eebsh;
    749   1.2  nisimura 	sc->sc_eesz = size[1];
    750  1.40  nisimura 	sc->sc_ih = intrh;
    751   1.1  nisimura 	sc->sc_dmat = faa->faa_dmat;
    752   1.1  nisimura 	sc->sc_phandle = phandle;
    753  1.30  nisimura 	sc->sc_phy_id = phy_id;
    754  1.30  nisimura 	sc->sc_freq = ref_clk;
    755   1.1  nisimura 
    756   1.1  nisimura 	scx_attach_i(sc);
    757  1.40  nisimura 
    758   1.1  nisimura 	return;
    759   1.1  nisimura  fail:
    760   1.1  nisimura 	if (sc->sc_eesz)
    761   1.1  nisimura 		bus_space_unmap(sc->sc_st, sc->sc_eesh, sc->sc_eesz);
    762   1.1  nisimura 	if (sc->sc_sz)
    763   1.1  nisimura 		bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz);
    764   1.1  nisimura 	return;
    765   1.1  nisimura }
    766   1.1  nisimura 
    767   1.1  nisimura static int
    768   1.1  nisimura scx_acpi_match(device_t parent, cfdata_t cf, void *aux)
    769   1.1  nisimura {
    770   1.1  nisimura 	struct acpi_attach_args *aa = aux;
    771   1.1  nisimura 
    772  1.27  nisimura 	return acpi_compatible_match(aa, compatible);
    773   1.1  nisimura }
    774   1.1  nisimura 
    775  1.40  nisimura #define HWFEA_DEBUG 1
    776  1.40  nisimura 
    777   1.1  nisimura static void
    778   1.1  nisimura scx_acpi_attach(device_t parent, device_t self, void *aux)
    779   1.1  nisimura {
    780   1.1  nisimura 	struct scx_softc * const sc = device_private(self);
    781   1.1  nisimura 	struct acpi_attach_args * const aa = aux;
    782   1.1  nisimura 	ACPI_HANDLE handle = aa->aa_node->ad_handle;
    783   1.1  nisimura 	bus_space_handle_t bsh, eebsh;
    784   1.1  nisimura 	struct acpi_resources res;
    785  1.40  nisimura 	struct acpi_mem *mem, *mem1;
    786   1.1  nisimura 	struct acpi_irq *irq;
    787  1.40  nisimura 	ACPI_INTEGER max_spd, max_frame, phy_id, phy_freq;
    788   1.1  nisimura 	ACPI_STATUS rv;
    789  1.40  nisimura 	void *intrh;
    790   1.1  nisimura 
    791   1.1  nisimura 	rv = acpi_resource_parse(self, handle, "_CRS",
    792   1.1  nisimura 	    &res, &acpi_resource_parse_ops_default);
    793  1.35  nisimura 	if (ACPI_FAILURE(rv))
    794   1.1  nisimura 		return;
    795   1.1  nisimura 	mem = acpi_res_mem(&res, 0);
    796   1.1  nisimura 	irq = acpi_res_irq(&res, 0);
    797   1.1  nisimura 	if (mem == NULL || irq == NULL || mem->ar_length == 0) {
    798  1.40  nisimura 		aprint_error(": incomplete crs resources\n");
    799  1.40  nisimura 		goto done;
    800   1.1  nisimura 	}
    801  1.31  nisimura 	if (bus_space_map(aa->aa_memt, mem->ar_base, mem->ar_length, 0,
    802  1.31  nisimura 	    &bsh) != 0) {
    803  1.40  nisimura 		aprint_error(": unable to map registers\n");
    804  1.40  nisimura 		goto done;
    805   1.1  nisimura 	}
    806  1.40  nisimura 	mem1 = acpi_res_mem(&res, 1); /* EEPROM for MAC address and ucode */
    807  1.40  nisimura 	if (mem1 == NULL || mem1->ar_length == 0) {
    808  1.40  nisimura 		aprint_error(": incomplete eeprom resources\n");
    809  1.40  nisimura 		goto fail_0;
    810   1.1  nisimura 	}
    811  1.40  nisimura 	if (bus_space_map(aa->aa_memt, mem1->ar_base, mem1->ar_length, 0,
    812  1.31  nisimura 	    &eebsh)) {
    813  1.40  nisimura 		aprint_error(": unable to map device eeprom\n");
    814  1.40  nisimura 		goto fail_0;
    815  1.14  nisimura 	}
    816  1.40  nisimura 	rv = acpi_dsd_integer(handle, "max-speed", &max_spd);
    817  1.40  nisimura 	if (ACPI_FAILURE(rv))
    818  1.40  nisimura 		max_spd = 1000;
    819  1.40  nisimura 	rv = acpi_dsd_integer(handle, "max-frame-size", &max_frame);
    820  1.40  nisimura 	if (ACPI_FAILURE(rv))
    821  1.40  nisimura 		max_frame = 2048;
    822  1.30  nisimura 	rv = acpi_dsd_integer(handle, "phy-channel", &phy_id);
    823  1.14  nisimura 	if (ACPI_FAILURE(rv))
    824  1.35  nisimura 		phy_id = MII_PHY_ANY;
    825  1.14  nisimura 	rv = acpi_dsd_integer(handle, "socionext,phy-clock-frequency",
    826  1.40  nisimura 			&phy_freq);
    827  1.14  nisimura 	if (ACPI_FAILURE(rv))
    828  1.40  nisimura 		phy_freq = 250 * 1000 * 1000;
    829  1.40  nisimura 
    830  1.40  nisimura #if ATTACH_DEBUG == 1
    831  1.40  nisimura aprint_normal_dev(self,
    832  1.40  nisimura     "[ACPI] max-speed %d, phy id %d, freq %ld\n",
    833  1.40  nisimura     (int)max_spd, (int)phy_id, phy_freq);
    834  1.40  nisimura aprint_normal("%s", device_xname(self));
    835  1.40  nisimura #endif
    836  1.40  nisimura 
    837  1.40  nisimura 	intrh = acpi_intr_establish(self, (uint64_t)(uintptr_t)handle,
    838  1.40  nisimura 	    IPL_NET, NOT_MP_SAFE, scx_intr, sc, device_xname(self));
    839  1.40  nisimura 	if (intrh == NULL) {
    840  1.40  nisimura 		aprint_error(": couldn't establish interrupt\n");
    841  1.40  nisimura 		goto fail_1;
    842  1.40  nisimura 	}
    843   1.1  nisimura 
    844   1.1  nisimura 	sc->sc_dev = self;
    845  1.31  nisimura 	sc->sc_st = aa->aa_memt;
    846   1.1  nisimura 	sc->sc_sh = bsh;
    847  1.40  nisimura 	sc->sc_sz = mem->ar_length;
    848   1.1  nisimura 	sc->sc_eesh = eebsh;
    849  1.40  nisimura 	sc->sc_eesz = mem1->ar_length;
    850  1.40  nisimura 	sc->sc_ih = intrh;
    851  1.40  nisimura 	sc->sc_dmat =
    852  1.40  nisimura 	    BUS_DMA_TAG_VALID(aa->aa_dmat64) ? aa->aa_dmat64 : aa->aa_dmat;
    853  1.30  nisimura 	sc->sc_phy_id = (int)phy_id;
    854  1.40  nisimura 	sc->sc_freq = phy_freq;
    855  1.40  nisimura 	sc->sc_maxsize = max_frame;
    856  1.35  nisimura 
    857   1.1  nisimura 	scx_attach_i(sc);
    858  1.40  nisimura  done:
    859   1.1  nisimura 	acpi_resource_cleanup(&res);
    860   1.1  nisimura 	return;
    861  1.40  nisimura  fail_1:
    862  1.40  nisimura 	bus_space_unmap(sc->sc_st, sc->sc_eesh, sc->sc_eesz);
    863  1.40  nisimura  fail_0:
    864  1.40  nisimura 	bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz);
    865   1.1  nisimura 	acpi_resource_cleanup(&res);
    866   1.1  nisimura 	return;
    867   1.1  nisimura }
    868   1.1  nisimura 
    869   1.1  nisimura static void
    870   1.1  nisimura scx_attach_i(struct scx_softc *sc)
    871   1.1  nisimura {
    872   1.1  nisimura 	struct ifnet * const ifp = &sc->sc_ethercom.ec_if;
    873   1.1  nisimura 	struct mii_data * const mii = &sc->sc_mii;
    874   1.1  nisimura 	struct ifmedia * const ifm = &mii->mii_media;
    875  1.40  nisimura 	uint32_t which, dwimp, dwfea;
    876   1.1  nisimura 	uint8_t enaddr[ETHER_ADDR_LEN];
    877   1.1  nisimura 	bus_dma_segment_t seg;
    878  1.41  nisimura 	paddr_t p, q;
    879   1.1  nisimura 	uint32_t csr;
    880   1.1  nisimura 	int i, nseg, error = 0;
    881   1.1  nisimura 
    882  1.40  nisimura 	which = CSR_READ(sc, HWVER);	/* Socionext version 5.xx */
    883  1.40  nisimura 	dwimp = mac_read(sc, GMACIMPL);	/* DWC implementation XX.YY */
    884  1.40  nisimura 	dwfea = mac_read(sc, HWFEA);	/* DWC feature bits */
    885  1.40  nisimura 
    886  1.35  nisimura 	aprint_naive("\n");
    887  1.40  nisimura 	aprint_normal(": Socionext NetSec Gigabit Ethernet controller "
    888  1.40  nisimura 	    "%x.%x\n", which >> 16, which & 0xffff);
    889  1.35  nisimura 
    890  1.22  nisimura 	aprint_normal_dev(sc->sc_dev,
    891  1.40  nisimura 	    "DesignWare EMAC ver 0x%x (0x%x) hw feature %08x\n",
    892  1.40  nisimura 	    dwimp & 0xff, dwimp >> 8, dwfea);
    893  1.40  nisimura 	dump_hwfeature(sc);
    894  1.40  nisimura 
    895  1.40  nisimura 	/* detected PHY type */
    896  1.40  nisimura 	sc->sc_miigmii = ((dwfea & __BITS(30,28) >> 28) == 0);
    897  1.22  nisimura 
    898  1.35  nisimura 	/* fetch MAC address in flash 0:7, stored in big endian order */
    899  1.23  nisimura 	csr = EE_READ(sc, 0x00);
    900   1.1  nisimura 	enaddr[0] = csr >> 24;
    901   1.1  nisimura 	enaddr[1] = csr >> 16;
    902   1.1  nisimura 	enaddr[2] = csr >> 8;
    903   1.1  nisimura 	enaddr[3] = csr;
    904  1.23  nisimura 	csr = EE_READ(sc, 0x04);
    905   1.1  nisimura 	enaddr[4] = csr >> 24;
    906   1.1  nisimura 	enaddr[5] = csr >> 16;
    907   1.1  nisimura 	aprint_normal_dev(sc->sc_dev,
    908   1.1  nisimura 	    "Ethernet address %s\n", ether_sprintf(enaddr));
    909   1.1  nisimura 
    910  1.27  nisimura 	sc->sc_mdclk = get_mdioclk(sc->sc_freq) << GAR_CLK; /* 5:2 clk ratio */
    911   1.1  nisimura 
    912   1.1  nisimura 	mii->mii_ifp = ifp;
    913   1.1  nisimura 	mii->mii_readreg = mii_readreg;
    914   1.1  nisimura 	mii->mii_writereg = mii_writereg;
    915   1.1  nisimura 	mii->mii_statchg = mii_statchg;
    916   1.1  nisimura 
    917   1.1  nisimura 	sc->sc_ethercom.ec_mii = mii;
    918  1.21  nisimura 	ifmedia_init(ifm, 0, ether_mediachange, scx_ifmedia_sts);
    919  1.35  nisimura 	mii_attach(sc->sc_dev, mii, 0xffffffff, sc->sc_phy_id,
    920   1.1  nisimura 	    MII_OFFSET_ANY, MIIF_DOPAUSE);
    921   1.1  nisimura 	if (LIST_FIRST(&mii->mii_phys) == NULL) {
    922   1.1  nisimura 		ifmedia_add(ifm, IFM_ETHER | IFM_NONE, 0, NULL);
    923   1.1  nisimura 		ifmedia_set(ifm, IFM_ETHER | IFM_NONE);
    924   1.1  nisimura 	} else
    925   1.1  nisimura 		ifmedia_set(ifm, IFM_ETHER | IFM_AUTO);
    926   1.1  nisimura 	ifm->ifm_media = ifm->ifm_cur->ifm_media; /* as if user has requested */
    927   1.1  nisimura 
    928   1.1  nisimura 	/*
    929   1.1  nisimura 	 * Allocate the control data structures, and create and load the
    930   1.1  nisimura 	 * DMA map for it.
    931   1.1  nisimura 	 */
    932  1.30  nisimura 	error = bus_dmamem_alloc(sc->sc_dmat,
    933   1.1  nisimura 	    sizeof(struct control_data), PAGE_SIZE, 0, &seg, 1, &nseg, 0);
    934   1.1  nisimura 	if (error != 0) {
    935   1.1  nisimura 		aprint_error_dev(sc->sc_dev,
    936   1.1  nisimura 		    "unable to allocate control data, error = %d\n", error);
    937   1.1  nisimura 		goto fail_0;
    938   1.1  nisimura 	}
    939  1.30  nisimura 	error = bus_dmamem_map(sc->sc_dmat, &seg, nseg,
    940   1.1  nisimura 	    sizeof(struct control_data), (void **)&sc->sc_control_data,
    941   1.1  nisimura 	    BUS_DMA_COHERENT);
    942   1.1  nisimura 	if (error != 0) {
    943   1.1  nisimura 		aprint_error_dev(sc->sc_dev,
    944   1.1  nisimura 		    "unable to map control data, error = %d\n", error);
    945   1.1  nisimura 		goto fail_1;
    946   1.1  nisimura 	}
    947  1.30  nisimura 	error = bus_dmamap_create(sc->sc_dmat,
    948   1.1  nisimura 	    sizeof(struct control_data), 1,
    949   1.1  nisimura 	    sizeof(struct control_data), 0, 0, &sc->sc_cddmamap);
    950   1.1  nisimura 	if (error != 0) {
    951   1.1  nisimura 		aprint_error_dev(sc->sc_dev,
    952   1.1  nisimura 		    "unable to create control data DMA map, "
    953   1.1  nisimura 		    "error = %d\n", error);
    954   1.1  nisimura 		goto fail_2;
    955   1.1  nisimura 	}
    956  1.30  nisimura 	error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
    957   1.1  nisimura 	    sc->sc_control_data, sizeof(struct control_data), NULL, 0);
    958   1.1  nisimura 	if (error != 0) {
    959   1.1  nisimura 		aprint_error_dev(sc->sc_dev,
    960   1.1  nisimura 		    "unable to load control data DMA map, error = %d\n",
    961   1.1  nisimura 		    error);
    962   1.1  nisimura 		goto fail_3;
    963   1.1  nisimura 	}
    964   1.6  nisimura 	for (i = 0; i < MD_TXQUEUELEN; i++) {
    965  1.30  nisimura 		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
    966   1.6  nisimura 		    MD_NTXSEGS, MCLBYTES, 0, 0,
    967   1.1  nisimura 		    &sc->sc_txsoft[i].txs_dmamap)) != 0) {
    968   1.1  nisimura 			aprint_error_dev(sc->sc_dev,
    969   1.1  nisimura 			    "unable to create tx DMA map %d, error = %d\n",
    970   1.1  nisimura 			    i, error);
    971   1.1  nisimura 			goto fail_4;
    972   1.1  nisimura 		}
    973   1.1  nisimura 	}
    974   1.6  nisimura 	for (i = 0; i < MD_NRXDESC; i++) {
    975  1.30  nisimura 		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
    976   1.1  nisimura 		    1, MCLBYTES, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) {
    977   1.1  nisimura 			aprint_error_dev(sc->sc_dev,
    978   1.1  nisimura 			    "unable to create rx DMA map %d, error = %d\n",
    979   1.1  nisimura 			    i, error);
    980   1.1  nisimura 			goto fail_5;
    981   1.1  nisimura 		}
    982   1.1  nisimura 		sc->sc_rxsoft[i].rxs_mbuf = NULL;
    983   1.1  nisimura 	}
    984   1.1  nisimura 	sc->sc_seg = seg;
    985   1.1  nisimura 	sc->sc_nseg = nseg;
    986  1.35  nisimura #if 0
    987  1.14  nisimura aprint_normal_dev(sc->sc_dev, "descriptor ds_addr %lx, ds_len %lx, nseg %d\n", seg.ds_addr, seg.ds_len, nseg);
    988  1.35  nisimura #endif
    989  1.23  nisimura 	strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
    990  1.23  nisimura 	ifp->if_softc = sc;
    991  1.23  nisimura 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    992  1.23  nisimura 	ifp->if_ioctl = scx_ioctl;
    993  1.23  nisimura 	ifp->if_start = scx_start;
    994  1.23  nisimura 	ifp->if_watchdog = scx_watchdog;
    995  1.23  nisimura 	ifp->if_init = scx_init;
    996  1.23  nisimura 	ifp->if_stop = scx_stop;
    997  1.23  nisimura 	IFQ_SET_READY(&ifp->if_snd);
    998  1.23  nisimura 
    999  1.40  nisimura 	/* 802.1Q VLAN-sized frames, and 9000 jumbo frame are supported */
   1000  1.40  nisimura 	sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
   1001  1.42  nisimura 	/* sc->sc_ethercom.ec_capabilities |= ETHERCAP_JUMBO_MTU; not yet */
   1002  1.40  nisimura 
   1003  1.40  nisimura 	sc->sc_flowflags = 0; /* track PAUSE flow caps */
   1004  1.23  nisimura 
   1005  1.23  nisimura 	if_attach(ifp);
   1006  1.23  nisimura 	if_deferred_start_init(ifp, NULL);
   1007  1.23  nisimura 	ether_ifattach(ifp, enaddr);
   1008  1.23  nisimura 
   1009  1.23  nisimura 	callout_init(&sc->sc_callout, 0);
   1010  1.23  nisimura 	callout_setfunc(&sc->sc_callout, phy_tick, sc);
   1011   1.1  nisimura 
   1012   1.1  nisimura 	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
   1013   1.1  nisimura 	    RND_TYPE_NET, RND_FLAG_DEFAULT);
   1014   1.1  nisimura 
   1015  1.41  nisimura 	resetuengine(sc);
   1016  1.40  nisimura 	loaducode(sc);
   1017  1.40  nisimura 
   1018  1.40  nisimura 	/* feed NetSec descriptor array base addresses and timer value */
   1019  1.41  nisimura 	p = SCX_CDTXADDR(sc, 0);		/* tdes array (ring#0) */
   1020  1.41  nisimura 	q = SCX_CDRXADDR(sc, 0);		/* rdes array (ring#1) */
   1021  1.41  nisimura 	CSR_WRITE(sc, TDBA_LO, BUS_ADDR_LO32(p));
   1022  1.41  nisimura 	CSR_WRITE(sc, TDBA_HI, BUS_ADDR_HI32(p));
   1023  1.41  nisimura 	CSR_WRITE(sc, RDBA_LO, BUS_ADDR_LO32(q));
   1024  1.41  nisimura 	CSR_WRITE(sc, RDBA_HI, BUS_ADDR_HI32(q));
   1025  1.40  nisimura 	CSR_WRITE(sc, TXCONF, DESCNF_LE);	/* little endian */
   1026  1.40  nisimura 	CSR_WRITE(sc, RXCONF, DESCNF_LE);	/* little endian */
   1027  1.40  nisimura 	CSR_WRITE(sc, DMACTL_TMR, sc->sc_freq / 1000000 - 1);
   1028  1.40  nisimura 
   1029  1.42  nisimura 	forcephyloopback(sc);/* make PHY loopback mode for uengine init */
   1030  1.42  nisimura 
   1031  1.42  nisimura 	CSR_WRITE(sc, xINTSR, IRQ_UCODE); /* pre-cautional W1C */
   1032  1.42  nisimura 	CSR_WRITE(sc, CORESTAT, 0);	  /* start uengine to reprogram */
   1033  1.42  nisimura 	error = WAIT_FOR_SET(sc, xINTSR, IRQ_UCODE);
   1034  1.42  nisimura 	if (error) {
   1035  1.42  nisimura 		aprint_error_dev(sc->sc_dev, "uengine start failed\n");
   1036  1.42  nisimura 	}
   1037  1.42  nisimura 	CSR_WRITE(sc, xINTSR, IRQ_UCODE); /* W1C load complete report */
   1038  1.42  nisimura 
   1039  1.42  nisimura 	resetphytonormal(sc); /* take back PHY to normal mode */
   1040  1.42  nisimura 
   1041  1.41  nisimura 	CSR_WRITE(sc, DMACTL_M2H, M2H_MODE_TRANS);
   1042  1.42  nisimura 	CSR_WRITE(sc, PKTCTRL, MODENRM); /* change to use normal mode */
   1043  1.42  nisimura 	error = WAIT_FOR_SET(sc, MODE_TRANS, T2N_DONE);
   1044  1.42  nisimura 	if (error) {
   1045  1.42  nisimura 		aprint_error_dev(sc->sc_dev, "uengine mode change failed\n");
   1046  1.42  nisimura 	}
   1047  1.41  nisimura 
   1048  1.41  nisimura 	CSR_WRITE(sc, TXISR, ~0);	/* clear pending emtpry/error irq */
   1049  1.41  nisimura 	CSR_WRITE(sc, xINTAE_CLR, ~0);	/* disable tx / rx interrupts */
   1050  1.40  nisimura 
   1051   1.1  nisimura 	return;
   1052   1.1  nisimura 
   1053   1.1  nisimura   fail_5:
   1054   1.6  nisimura 	for (i = 0; i < MD_NRXDESC; i++) {
   1055   1.1  nisimura 		if (sc->sc_rxsoft[i].rxs_dmamap != NULL)
   1056   1.1  nisimura 			bus_dmamap_destroy(sc->sc_dmat,
   1057   1.1  nisimura 			    sc->sc_rxsoft[i].rxs_dmamap);
   1058   1.1  nisimura 	}
   1059   1.1  nisimura   fail_4:
   1060   1.6  nisimura 	for (i = 0; i < MD_TXQUEUELEN; i++) {
   1061   1.1  nisimura 		if (sc->sc_txsoft[i].txs_dmamap != NULL)
   1062   1.1  nisimura 			bus_dmamap_destroy(sc->sc_dmat,
   1063   1.1  nisimura 			    sc->sc_txsoft[i].txs_dmamap);
   1064   1.1  nisimura 	}
   1065   1.1  nisimura 	bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
   1066   1.1  nisimura   fail_3:
   1067   1.1  nisimura 	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
   1068   1.1  nisimura   fail_2:
   1069   1.1  nisimura 	bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data,
   1070   1.1  nisimura 	    sizeof(struct control_data));
   1071   1.1  nisimura   fail_1:
   1072   1.1  nisimura 	bus_dmamem_free(sc->sc_dmat, &seg, nseg);
   1073   1.1  nisimura   fail_0:
   1074   1.1  nisimura 	if (sc->sc_phandle)
   1075   1.1  nisimura 		fdtbus_intr_disestablish(sc->sc_phandle, sc->sc_ih);
   1076   1.1  nisimura 	else
   1077   1.1  nisimura 		acpi_intr_disestablish(sc->sc_ih);
   1078   1.1  nisimura 	bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_sz);
   1079   1.1  nisimura 	return;
   1080   1.1  nisimura }
   1081   1.1  nisimura 
   1082   1.1  nisimura static void
   1083   1.1  nisimura scx_reset(struct scx_softc *sc)
   1084   1.1  nisimura {
   1085  1.16  nisimura 	int loop = 0, busy;
   1086   1.1  nisimura 
   1087  1.18  nisimura 	mac_write(sc, GMACOMR, 0);
   1088  1.20  nisimura 	mac_write(sc, GMACBMR, BMR_RST);
   1089  1.16  nisimura 	do {
   1090  1.19  nisimura 		DELAY(1);
   1091  1.16  nisimura 		busy = mac_read(sc, GMACBMR) & BMR_RST;
   1092  1.16  nisimura 	} while (++loop < 3000 && busy);
   1093   1.1  nisimura 	mac_write(sc, GMACBMR, _BMR);
   1094  1.19  nisimura 	mac_write(sc, GMACAFR, 0);
   1095  1.41  nisimura }
   1096  1.41  nisimura 
   1097  1.41  nisimura static void
   1098  1.41  nisimura scx_stop(struct ifnet *ifp, int disable)
   1099  1.41  nisimura {
   1100  1.41  nisimura 	struct scx_softc *sc = ifp->if_softc;
   1101  1.41  nisimura 	uint32_t csr;
   1102  1.41  nisimura 
   1103  1.41  nisimura 	/* Stop the one second clock. */
   1104  1.41  nisimura 	callout_stop(&sc->sc_callout);
   1105  1.41  nisimura 
   1106  1.41  nisimura 	/* Down the MII. */
   1107  1.41  nisimura 	mii_down(&sc->sc_mii);
   1108  1.18  nisimura 
   1109  1.41  nisimura 	/* Mark the interface down and cancel the watchdog timer. */
   1110  1.41  nisimura 	ifp->if_flags &= ~IFF_RUNNING;
   1111  1.41  nisimura 	ifp->if_timer = 0;
   1112  1.19  nisimura 
   1113  1.41  nisimura 	CSR_WRITE(sc, RXIE_CLR, ~0);
   1114  1.41  nisimura 	CSR_WRITE(sc, TXIE_CLR, ~0);
   1115  1.41  nisimura 	CSR_WRITE(sc, xINTAE_CLR, ~0);
   1116  1.31  nisimura 	CSR_WRITE(sc, TXISR, ~0);
   1117  1.41  nisimura 	CSR_WRITE(sc, RXISR, ~0);
   1118  1.41  nisimura 
   1119  1.41  nisimura 	csr = mac_read(sc, GMACOMR);
   1120  1.41  nisimura 	mac_write(sc, GMACOMR, csr &~ (OMR_SR | OMR_ST));
   1121   1.1  nisimura }
   1122   1.1  nisimura 
   1123   1.1  nisimura static int
   1124   1.1  nisimura scx_init(struct ifnet *ifp)
   1125   1.1  nisimura {
   1126   1.1  nisimura 	struct scx_softc *sc = ifp->if_softc;
   1127   1.1  nisimura 	const uint8_t *ea = CLLADDR(ifp->if_sadl);
   1128   1.1  nisimura 	uint32_t csr;
   1129  1.23  nisimura 	int i, error;
   1130   1.1  nisimura 
   1131   1.1  nisimura 	/* Cancel pending I/O. */
   1132   1.1  nisimura 	scx_stop(ifp, 0);
   1133   1.1  nisimura 
   1134   1.1  nisimura 	/* Reset the chip to a known state. */
   1135   1.1  nisimura 	scx_reset(sc);
   1136   1.1  nisimura 
   1137  1.13  nisimura 	/* build sane Tx */
   1138  1.13  nisimura 	memset(sc->sc_txdescs, 0, sizeof(struct tdes) * MD_NTXDESC);
   1139  1.43  nisimura 	sc->sc_txdescs[MD_NTXDESC - 1].t0 = htole32(T0_LD); /* tie off */
   1140  1.13  nisimura 	SCX_CDTXSYNC(sc, 0, MD_NTXDESC,
   1141  1.13  nisimura 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1142  1.13  nisimura 	sc->sc_txfree = MD_NTXDESC;
   1143  1.13  nisimura 	sc->sc_txnext = 0;
   1144  1.13  nisimura 	for (i = 0; i < MD_TXQUEUELEN; i++)
   1145  1.13  nisimura 		sc->sc_txsoft[i].txs_mbuf = NULL;
   1146  1.13  nisimura 	sc->sc_txsfree = MD_TXQUEUELEN;
   1147  1.13  nisimura 	sc->sc_txsnext = 0;
   1148  1.13  nisimura 	sc->sc_txsdirty = 0;
   1149  1.13  nisimura 
   1150  1.13  nisimura 	/* load Rx descriptors with fresh mbuf */
   1151  1.23  nisimura 	for (i = 0; i < MD_NRXDESC; i++) {
   1152  1.23  nisimura 		if (sc->sc_rxsoft[i].rxs_mbuf == NULL) {
   1153  1.23  nisimura 			if ((error = add_rxbuf(sc, i)) != 0) {
   1154  1.23  nisimura 				aprint_error_dev(sc->sc_dev,
   1155  1.23  nisimura 				    "unable to allocate or map rx "
   1156  1.23  nisimura 				    "buffer %d, error = %d\n",
   1157  1.23  nisimura 				    i, error);
   1158  1.23  nisimura 				rxdrain(sc);
   1159  1.23  nisimura 				goto out;
   1160  1.23  nisimura 			}
   1161  1.23  nisimura 		}
   1162  1.23  nisimura 		else
   1163  1.23  nisimura 			SCX_INIT_RXDESC(sc, i);
   1164  1.23  nisimura 	}
   1165  1.43  nisimura 	sc->sc_rxdescs[MD_NRXDESC - 1].r0 = htole32(R0_LD); /* tie off */
   1166  1.13  nisimura 	sc->sc_rxptr = 0;
   1167  1.13  nisimura 
   1168  1.25    andvar 	/* set my address in perfect match slot 0. little endian order */
   1169  1.23  nisimura 	csr = (ea[3] << 24) | (ea[2] << 16) | (ea[1] << 8) |  ea[0];
   1170  1.23  nisimura 	mac_write(sc, GMACMAL0, csr);
   1171  1.23  nisimura 	csr = (ea[5] << 8) | ea[4];
   1172  1.23  nisimura 	mac_write(sc, GMACMAH0, csr);
   1173  1.23  nisimura 
   1174  1.23  nisimura 	/* accept multicast frame or run promisc mode */
   1175  1.23  nisimura 	scx_set_rcvfilt(sc);
   1176  1.23  nisimura 
   1177  1.23  nisimura 	/* set current media */
   1178  1.23  nisimura 	if ((error = ether_mediachange(ifp)) != 0)
   1179  1.23  nisimura 		goto out;
   1180  1.23  nisimura 
   1181  1.27  nisimura 	CSR_WRITE(sc, DESC_SRST, 01);
   1182  1.41  nisimura 	WAIT_FOR_CLR(sc, DESC_SRST, 01);
   1183  1.27  nisimura 
   1184  1.27  nisimura 	CSR_WRITE(sc, DESC_INIT, 01);
   1185  1.41  nisimura 	WAIT_FOR_CLR(sc, DESC_INIT, 01);
   1186  1.27  nisimura 
   1187  1.40  nisimura 	/* feed local memory descriptor array base addresses */
   1188  1.36  nisimura 	mac_write(sc, GMACRDLA, _RDLA);		/* GMAC rdes store */
   1189  1.36  nisimura 	mac_write(sc, GMACTDLA, _TDLA);		/* GMAC tdes store */
   1190  1.27  nisimura 
   1191  1.27  nisimura 	CSR_WRITE(sc, FLOWTHR, (48<<16) | 36);	/* pause|resume threshold */
   1192  1.27  nisimura 	mac_write(sc, GMACFCR, 256 << 16);	/* 31:16 pause value */
   1193  1.27  nisimura 
   1194  1.41  nisimura 	CSR_WRITE(sc, INTF_SEL, sc->sc_miigmii ? INTF_GMII : INTF_RGMII);
   1195  1.31  nisimura 
   1196  1.41  nisimura 	CSR_WRITE(sc, RXCOALESC, 8);		/* Rx coalesce bound */
   1197  1.41  nisimura 	CSR_WRITE(sc, TXCOALESC, 8);		/* Tx coalesce bound */
   1198  1.43  nisimura 	CSR_WRITE(sc, RCLSCTIME, 500);		/* Rx co. guard time usec */
   1199  1.43  nisimura 	CSR_WRITE(sc, TCLSCTIME, 500);		/* Tx co. guard time usec */
   1200  1.31  nisimura 
   1201  1.31  nisimura 	CSR_WRITE(sc, RXIE_SET, RXI_RC_ERR | RXI_PKTCNT | RXI_TMREXP);
   1202  1.31  nisimura 	CSR_WRITE(sc, TXIE_SET, TXI_TR_ERR | TXI_TXDONE | TXI_TMREXP);
   1203  1.31  nisimura 	CSR_WRITE(sc, xINTAE_SET, IRQ_RX | IRQ_TX);
   1204  1.40  nisimura #if 1
   1205  1.40  nisimura 	/* clear event counters, auto-zero after every read */
   1206  1.41  nisimura 	mac_write(sc, GMACEVCTL, EVC_CR | EVC_ROR);
   1207  1.40  nisimura #endif
   1208   1.1  nisimura 	/* kick to start GMAC engine */
   1209  1.13  nisimura 	csr = mac_read(sc, GMACOMR);
   1210  1.27  nisimura 	mac_write(sc, GMACOMR, csr | OMR_SR | OMR_ST);
   1211   1.1  nisimura 
   1212   1.1  nisimura 	ifp->if_flags |= IFF_RUNNING;
   1213   1.1  nisimura 
   1214   1.1  nisimura 	/* start one second timer */
   1215  1.23  nisimura 	callout_schedule(&sc->sc_callout, hz);
   1216  1.23  nisimura  out:
   1217  1.23  nisimura 	return error;
   1218   1.1  nisimura }
   1219   1.1  nisimura 
   1220  1.23  nisimura static int
   1221  1.23  nisimura scx_ioctl(struct ifnet *ifp, u_long cmd, void *data)
   1222   1.1  nisimura {
   1223   1.1  nisimura 	struct scx_softc *sc = ifp->if_softc;
   1224  1.23  nisimura 	struct ifreq *ifr = (struct ifreq *)data;
   1225  1.23  nisimura 	struct ifmedia *ifm = &sc->sc_mii.mii_media;
   1226  1.23  nisimura 	int s, error;
   1227   1.1  nisimura 
   1228  1.23  nisimura 	s = splnet();
   1229   1.1  nisimura 
   1230  1.23  nisimura 	switch (cmd) {
   1231  1.23  nisimura 	case SIOCSIFMEDIA:
   1232  1.23  nisimura 		/* Flow control requires full-duplex mode. */
   1233  1.23  nisimura 		if (IFM_SUBTYPE(ifr->ifr_media) == IFM_AUTO ||
   1234  1.23  nisimura 		    (ifr->ifr_media & IFM_FDX) == 0)
   1235  1.23  nisimura 			ifr->ifr_media &= ~IFM_ETH_FMASK;
   1236  1.23  nisimura 		if (IFM_SUBTYPE(ifr->ifr_media) != IFM_AUTO) {
   1237  1.23  nisimura 			if ((ifr->ifr_media & IFM_ETH_FMASK) == IFM_FLOW) {
   1238  1.23  nisimura 				/* We can do both TXPAUSE and RXPAUSE. */
   1239   1.1  nisimura 				ifr->ifr_media |=
   1240   1.1  nisimura 				    IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE;
   1241   1.1  nisimura 			}
   1242   1.1  nisimura 			sc->sc_flowflags = ifr->ifr_media & IFM_ETH_FMASK;
   1243   1.1  nisimura 		}
   1244   1.1  nisimura 		error = ifmedia_ioctl(ifp, ifr, ifm, cmd);
   1245   1.1  nisimura 		break;
   1246   1.1  nisimura 	default:
   1247  1.23  nisimura 		error = ether_ioctl(ifp, cmd, data);
   1248  1.23  nisimura 		if (error != ENETRESET)
   1249   1.1  nisimura 			break;
   1250   1.1  nisimura 		error = 0;
   1251   1.1  nisimura 		if (cmd == SIOCSIFCAP)
   1252  1.34  riastrad 			error = if_init(ifp);
   1253   1.1  nisimura 		if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI)
   1254   1.1  nisimura 			;
   1255   1.1  nisimura 		else if (ifp->if_flags & IFF_RUNNING) {
   1256   1.1  nisimura 			/*
   1257   1.1  nisimura 			 * Multicast list has changed; set the hardware filter
   1258   1.1  nisimura 			 * accordingly.
   1259   1.1  nisimura 			 */
   1260   1.1  nisimura 			scx_set_rcvfilt(sc);
   1261   1.1  nisimura 		}
   1262   1.1  nisimura 		break;
   1263   1.1  nisimura 	}
   1264   1.1  nisimura 
   1265   1.1  nisimura 	splx(s);
   1266   1.1  nisimura 	return error;
   1267   1.1  nisimura }
   1268   1.1  nisimura 
   1269  1.27  nisimura static uint32_t
   1270  1.27  nisimura bit_reverse_32(uint32_t x)
   1271  1.27  nisimura {
   1272  1.27  nisimura 	x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
   1273  1.27  nisimura 	x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
   1274  1.27  nisimura 	x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
   1275  1.27  nisimura 	x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
   1276  1.27  nisimura 	return (x >> 16) | (x << 16);
   1277  1.27  nisimura }
   1278  1.27  nisimura 
   1279  1.40  nisimura #define MCAST_DEBUG 0
   1280  1.40  nisimura 
   1281   1.1  nisimura static void
   1282   1.1  nisimura scx_set_rcvfilt(struct scx_softc *sc)
   1283   1.1  nisimura {
   1284   1.1  nisimura 	struct ethercom * const ec = &sc->sc_ethercom;
   1285   1.1  nisimura 	struct ifnet * const ifp = &ec->ec_if;
   1286   1.1  nisimura 	struct ether_multistep step;
   1287   1.1  nisimura 	struct ether_multi *enm;
   1288  1.17  nisimura 	uint32_t mchash[2]; 	/* 2x 32 = 64 bit */
   1289   1.1  nisimura 	uint32_t csr, crc;
   1290   1.1  nisimura 	int i;
   1291   1.1  nisimura 
   1292  1.13  nisimura 	csr = mac_read(sc, GMACAFR);
   1293  1.18  nisimura 	csr &= ~(AFR_PR | AFR_PM | AFR_MHTE | AFR_HPF);
   1294  1.13  nisimura 	mac_write(sc, GMACAFR, csr);
   1295   1.1  nisimura 
   1296  1.25    andvar 	/* clear 15 entry supplemental perfect match filter */
   1297  1.22  nisimura 	for (i = 1; i < 16; i++)
   1298  1.22  nisimura 		 mac_write(sc, GMACMAH(i), 0);
   1299  1.22  nisimura 	/* build 64 bit multicast hash filter */
   1300  1.22  nisimura 	crc = mchash[1] = mchash[0] = 0;
   1301  1.22  nisimura 
   1302   1.1  nisimura 	ETHER_LOCK(ec);
   1303   1.1  nisimura 	if (ifp->if_flags & IFF_PROMISC) {
   1304   1.1  nisimura 		ec->ec_flags |= ETHER_F_ALLMULTI;
   1305   1.1  nisimura 		ETHER_UNLOCK(ec);
   1306  1.22  nisimura 		/* run promisc. mode */
   1307  1.22  nisimura 		csr |= AFR_PR;
   1308   1.1  nisimura 		goto update;
   1309   1.1  nisimura 	}
   1310   1.1  nisimura 	ec->ec_flags &= ~ETHER_F_ALLMULTI;
   1311   1.1  nisimura 	ETHER_FIRST_MULTI(step, ec, enm);
   1312   1.1  nisimura 	i = 1; /* slot 0 is occupied */
   1313   1.1  nisimura 	while (enm != NULL) {
   1314   1.1  nisimura 		if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
   1315   1.1  nisimura 			/*
   1316   1.1  nisimura 			 * We must listen to a range of multicast addresses.
   1317   1.1  nisimura 			 * For now, just accept all multicasts, rather than
   1318   1.1  nisimura 			 * trying to set only those filter bits needed to match
   1319   1.1  nisimura 			 * the range.  (At this time, the only use of address
   1320   1.1  nisimura 			 * ranges is for IP multicast routing, for which the
   1321   1.1  nisimura 			 * range is big enough to require all bits set.)
   1322   1.1  nisimura 			 */
   1323   1.1  nisimura 			ec->ec_flags |= ETHER_F_ALLMULTI;
   1324   1.1  nisimura 			ETHER_UNLOCK(ec);
   1325  1.22  nisimura 			/* accept all multi */
   1326  1.22  nisimura 			csr |= AFR_PM;
   1327   1.1  nisimura 			goto update;
   1328   1.1  nisimura 		}
   1329  1.40  nisimura #if MCAST_DEBUG == 1
   1330  1.40  nisimura aprint_normal_dev(sc->sc_dev, "[%d] %s\n", i, ether_sprintf(enm->enm_addrlo));
   1331  1.40  nisimura #endif
   1332   1.1  nisimura 		if (i < 16) {
   1333   1.9  nisimura 			/* use 15 entry perfect match filter */
   1334   1.1  nisimura 			uint32_t addr;
   1335   1.1  nisimura 			uint8_t *ep = enm->enm_addrlo;
   1336   1.1  nisimura 			addr = (ep[3] << 24) | (ep[2] << 16)
   1337   1.1  nisimura 			     | (ep[1] <<  8) |  ep[0];
   1338  1.13  nisimura 			mac_write(sc, GMACMAL(i), addr);
   1339   1.1  nisimura 			addr = (ep[5] << 8) | ep[4];
   1340  1.13  nisimura 			mac_write(sc, GMACMAH(i), addr | 1U<<31);
   1341   1.1  nisimura 		} else {
   1342   1.1  nisimura 			/* use hash table when too many */
   1343   1.1  nisimura 			crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN);
   1344  1.27  nisimura 			crc = bit_reverse_32(~crc);
   1345  1.17  nisimura 			/* 1(31) 5(30:26) bit sampling */
   1346  1.17  nisimura 			mchash[crc >> 31] |= 1 << ((crc >> 26) & 0x1f);
   1347   1.1  nisimura 		}
   1348   1.1  nisimura 		ETHER_NEXT_MULTI(step, enm);
   1349   1.1  nisimura 		i++;
   1350   1.1  nisimura 	}
   1351   1.1  nisimura 	ETHER_UNLOCK(ec);
   1352   1.1  nisimura 	if (crc)
   1353  1.41  nisimura 		csr |= AFR_MHTE; /* use mchash[] */
   1354  1.41  nisimura 	csr |= AFR_HPF; /* use perfect match as well */
   1355  1.41  nisimura  update:
   1356  1.17  nisimura 	mac_write(sc, GMACMHTH, mchash[1]);
   1357  1.17  nisimura 	mac_write(sc, GMACMHTL, mchash[0]);
   1358  1.13  nisimura 	mac_write(sc, GMACAFR, csr);
   1359   1.1  nisimura 	return;
   1360   1.1  nisimura }
   1361   1.1  nisimura 
   1362   1.1  nisimura static void
   1363   1.1  nisimura scx_start(struct ifnet *ifp)
   1364   1.1  nisimura {
   1365   1.1  nisimura 	struct scx_softc *sc = ifp->if_softc;
   1366  1.27  nisimura 	struct mbuf *m0;
   1367   1.1  nisimura 	struct scx_txsoft *txs;
   1368   1.1  nisimura 	bus_dmamap_t dmamap;
   1369   1.1  nisimura 	int error, nexttx, lasttx, ofree, seg;
   1370   1.1  nisimura 	uint32_t tdes0;
   1371   1.1  nisimura 
   1372  1.38   thorpej 	if ((ifp->if_flags & IFF_RUNNING) == 0)
   1373   1.1  nisimura 		return;
   1374   1.1  nisimura 
   1375   1.1  nisimura 	/* Remember the previous number of free descriptors. */
   1376   1.1  nisimura 	ofree = sc->sc_txfree;
   1377   1.1  nisimura 	/*
   1378   1.1  nisimura 	 * Loop through the send queue, setting up transmit descriptors
   1379   1.1  nisimura 	 * until we drain the queue, or use up all available transmit
   1380   1.1  nisimura 	 * descriptors.
   1381   1.1  nisimura 	 */
   1382   1.1  nisimura 	for (;;) {
   1383   1.1  nisimura 		IFQ_POLL(&ifp->if_snd, m0);
   1384   1.1  nisimura 		if (m0 == NULL)
   1385   1.1  nisimura 			break;
   1386   1.6  nisimura 		if (sc->sc_txsfree < MD_TXQUEUE_GC) {
   1387   1.1  nisimura 			txreap(sc);
   1388   1.1  nisimura 			if (sc->sc_txsfree == 0)
   1389   1.1  nisimura 				break;
   1390   1.1  nisimura 		}
   1391   1.1  nisimura 		txs = &sc->sc_txsoft[sc->sc_txsnext];
   1392   1.1  nisimura 		dmamap = txs->txs_dmamap;
   1393   1.1  nisimura 		error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
   1394   1.1  nisimura 		    BUS_DMA_WRITE | BUS_DMA_NOWAIT);
   1395   1.1  nisimura 		if (error) {
   1396   1.1  nisimura 			if (error == EFBIG) {
   1397   1.1  nisimura 				aprint_error_dev(sc->sc_dev,
   1398   1.1  nisimura 				    "Tx packet consumes too many "
   1399   1.1  nisimura 				    "DMA segments, dropping...\n");
   1400  1.40  nisimura 				IFQ_DEQUEUE(&ifp->if_snd, m0);
   1401  1.40  nisimura 				m_freem(m0);
   1402  1.40  nisimura 				if_statinc_ref(ifp, if_oerrors);
   1403  1.40  nisimura 				continue;
   1404   1.1  nisimura 			}
   1405   1.1  nisimura 			/* Short on resources, just stop for now. */
   1406   1.1  nisimura 			break;
   1407   1.1  nisimura 		}
   1408   1.1  nisimura 		if (dmamap->dm_nsegs > sc->sc_txfree) {
   1409   1.1  nisimura 			/*
   1410   1.1  nisimura 			 * Not enough free descriptors to transmit this
   1411   1.1  nisimura 			 * packet.  We haven't committed anything yet,
   1412   1.1  nisimura 			 * so just unload the DMA map, put the packet
   1413  1.38   thorpej 			 * back on the queue, and punt.
   1414   1.1  nisimura 			 */
   1415   1.1  nisimura 			bus_dmamap_unload(sc->sc_dmat, dmamap);
   1416   1.1  nisimura 			break;
   1417   1.1  nisimura 		}
   1418   1.1  nisimura 
   1419   1.1  nisimura 		IFQ_DEQUEUE(&ifp->if_snd, m0);
   1420   1.1  nisimura 		/*
   1421   1.1  nisimura 		 * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET.
   1422   1.1  nisimura 		 */
   1423   1.1  nisimura 		bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize,
   1424   1.1  nisimura 		    BUS_DMASYNC_PREWRITE);
   1425   1.1  nisimura 
   1426   1.1  nisimura 		tdes0 = 0; /* to postpone 1st segment T0_OWN write */
   1427   1.1  nisimura 		lasttx = -1;
   1428   1.1  nisimura 		for (nexttx = sc->sc_txnext, seg = 0;
   1429   1.1  nisimura 		     seg < dmamap->dm_nsegs;
   1430   1.6  nisimura 		     seg++, nexttx = MD_NEXTTX(nexttx)) {
   1431   1.1  nisimura 			struct tdes *tdes = &sc->sc_txdescs[nexttx];
   1432  1.41  nisimura 			bus_addr_t p = dmamap->dm_segs[seg].ds_addr;
   1433  1.41  nisimura 			bus_size_t z = dmamap->dm_segs[seg].ds_len;
   1434   1.1  nisimura 			/*
   1435   1.1  nisimura 			 * If this is the first descriptor we're
   1436   1.1  nisimura 			 * enqueueing, don't set the OWN bit just
   1437   1.1  nisimura 			 * yet.	 That could cause a race condition.
   1438   1.1  nisimura 			 * We'll do it below.
   1439   1.1  nisimura 			 */
   1440  1.41  nisimura 			tdes->t3 = htole32(z);
   1441  1.41  nisimura 			tdes->t2 = htole32(BUS_ADDR_LO32(p));
   1442  1.41  nisimura 			tdes->t1 = htole32(BUS_ADDR_HI32(p));
   1443  1.41  nisimura 			tdes->t0 &= htole32(T0_LD);
   1444  1.41  nisimura 			tdes->t0 |= htole32(tdes0 |
   1445  1.27  nisimura 					(15 << T0_TDRID) | T0_PT |
   1446  1.29  nisimura 					sc->sc_t0cotso | T0_TRS);
   1447   1.1  nisimura 			tdes0 = T0_OWN; /* 2nd and other segments */
   1448  1.27  nisimura 			/* NB; t0 DRID field contains zero */
   1449   1.1  nisimura 			lasttx = nexttx;
   1450   1.1  nisimura 		}
   1451   1.1  nisimura 
   1452  1.41  nisimura 		/* HW lacks of per-frame xmit done interrupt control */
   1453  1.41  nisimura 
   1454   1.1  nisimura 		/* Write deferred 1st segment T0_OWN at the final stage */
   1455  1.29  nisimura 		sc->sc_txdescs[lasttx].t0 |= htole32(T0_LS);
   1456  1.29  nisimura 		sc->sc_txdescs[sc->sc_txnext].t0 |= htole32(T0_FS | T0_OWN);
   1457   1.1  nisimura 		SCX_CDTXSYNC(sc, sc->sc_txnext, dmamap->dm_nsegs,
   1458   1.1  nisimura 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
   1459   1.1  nisimura 
   1460  1.32  nisimura 		/* submit one frame to xmit */
   1461  1.32  nisimura 		CSR_WRITE(sc, TXSUBMIT, 1);
   1462   1.1  nisimura 
   1463   1.1  nisimura 		txs->txs_mbuf = m0;
   1464   1.1  nisimura 		txs->txs_firstdesc = sc->sc_txnext;
   1465   1.1  nisimura 		txs->txs_lastdesc = lasttx;
   1466   1.1  nisimura 		txs->txs_ndesc = dmamap->dm_nsegs;
   1467   1.1  nisimura 		sc->sc_txfree -= txs->txs_ndesc;
   1468   1.1  nisimura 		sc->sc_txnext = nexttx;
   1469   1.1  nisimura 		sc->sc_txsfree--;
   1470   1.6  nisimura 		sc->sc_txsnext = MD_NEXTTXS(sc->sc_txsnext);
   1471   1.1  nisimura 		/*
   1472   1.1  nisimura 		 * Pass the packet to any BPF listeners.
   1473   1.1  nisimura 		 */
   1474   1.1  nisimura 		bpf_mtap(ifp, m0, BPF_D_OUT);
   1475   1.1  nisimura 	}
   1476   1.1  nisimura 	if (sc->sc_txfree != ofree) {
   1477   1.1  nisimura 		/* Set a watchdog timer in case the chip flakes out. */
   1478   1.1  nisimura 		ifp->if_timer = 5;
   1479   1.1  nisimura 	}
   1480   1.1  nisimura }
   1481   1.1  nisimura 
   1482  1.40  nisimura #define EVENT_DEBUG 1
   1483  1.40  nisimura 
   1484  1.23  nisimura static void
   1485  1.23  nisimura scx_watchdog(struct ifnet *ifp)
   1486  1.23  nisimura {
   1487  1.23  nisimura 	struct scx_softc *sc = ifp->if_softc;
   1488  1.23  nisimura 
   1489  1.23  nisimura 	/*
   1490  1.23  nisimura 	 * Since we're not interrupting every packet, sweep
   1491  1.23  nisimura 	 * up before we report an error.
   1492  1.23  nisimura 	 */
   1493  1.23  nisimura 	txreap(sc);
   1494  1.23  nisimura 
   1495  1.23  nisimura 	if (sc->sc_txfree != MD_NTXDESC) {
   1496  1.23  nisimura 		aprint_error_dev(sc->sc_dev,
   1497  1.23  nisimura 		    "device timeout (txfree %d txsfree %d txnext %d)\n",
   1498  1.23  nisimura 		    sc->sc_txfree, sc->sc_txsfree, sc->sc_txnext);
   1499  1.23  nisimura 		if_statinc(ifp, if_oerrors);
   1500  1.40  nisimura #if EVENT_DEBUG == 1
   1501  1.40  nisimura aprint_error_dev(sc->sc_dev,
   1502  1.41  nisimura     "tx frames %d, octects %d, bcast %d, mcast %d\n",
   1503  1.41  nisimura     mac_read(sc, GMACEVCNT(1)),
   1504  1.41  nisimura     mac_read(sc, GMACEVCNT(0)),
   1505  1.41  nisimura     mac_read(sc, GMACEVCNT(2)),
   1506  1.41  nisimura     mac_read(sc, GMACEVCNT(3)));
   1507  1.41  nisimura aprint_error_dev(sc->sc_dev,
   1508  1.40  nisimura     "rx frames %d, octects %d, bcast %d, mcast %d\n",
   1509  1.40  nisimura     mac_read(sc, GMACEVCNT(27)),
   1510  1.40  nisimura     mac_read(sc, GMACEVCNT(28)),
   1511  1.40  nisimura     mac_read(sc, GMACEVCNT(30)),
   1512  1.40  nisimura     mac_read(sc, GMACEVCNT(31)));
   1513  1.40  nisimura aprint_error_dev(sc->sc_dev,
   1514  1.40  nisimura     "current tdes addr %x, buf addr %x\n",
   1515  1.40  nisimura     mac_read(sc, 0x1048), mac_read(sc, 0x1050));
   1516  1.40  nisimura aprint_error_dev(sc->sc_dev,
   1517  1.40  nisimura     "current rdes addr %x, buf addr %x\n",
   1518  1.40  nisimura     mac_read(sc, 0x104c), mac_read(sc, 0x1054));
   1519  1.40  nisimura #endif
   1520  1.23  nisimura 		/* Reset the interface. */
   1521  1.23  nisimura 		scx_init(ifp);
   1522  1.23  nisimura 	}
   1523  1.23  nisimura 
   1524  1.23  nisimura 	scx_start(ifp);
   1525  1.23  nisimura }
   1526  1.23  nisimura 
   1527   1.1  nisimura static int
   1528   1.1  nisimura scx_intr(void *arg)
   1529   1.1  nisimura {
   1530   1.1  nisimura 	struct scx_softc *sc = arg;
   1531  1.31  nisimura 	uint32_t enable, status;
   1532  1.31  nisimura 
   1533  1.31  nisimura 	status = CSR_READ(sc, xINTSR); /* not W1C */
   1534  1.31  nisimura 	enable = CSR_READ(sc, xINTAEN);
   1535  1.31  nisimura 	if ((status & enable) == 0)
   1536  1.31  nisimura 		return 0;
   1537  1.31  nisimura 	if (status & (IRQ_TX | IRQ_RX)) {
   1538  1.31  nisimura 		CSR_WRITE(sc, xINTAE_CLR, (IRQ_TX | IRQ_RX));
   1539  1.31  nisimura 
   1540  1.31  nisimura 		status = CSR_READ(sc, RXISR);
   1541  1.31  nisimura 		CSR_WRITE(sc, RXISR, status);
   1542  1.31  nisimura 		if (status & RXI_RC_ERR)
   1543  1.31  nisimura 			aprint_error_dev(sc->sc_dev, "Rx error\n");
   1544  1.31  nisimura 		if (status & (RXI_PKTCNT | RXI_TMREXP)) {
   1545  1.41  nisimura 			rxfill(sc);
   1546  1.43  nisimura 			(void)CSR_READ(sc, RXAVAILCNT); /* clear IRQ_RX ? */
   1547  1.31  nisimura 		}
   1548  1.31  nisimura 
   1549  1.31  nisimura 		status = CSR_READ(sc, TXISR);
   1550  1.31  nisimura 		CSR_WRITE(sc, TXISR, status);
   1551  1.31  nisimura 		if (status & TXI_TR_ERR)
   1552  1.31  nisimura 			aprint_error_dev(sc->sc_dev, "Tx error\n");
   1553  1.31  nisimura 		if (status & (TXI_TXDONE | TXI_TMREXP)) {
   1554  1.31  nisimura 			txreap(sc);
   1555  1.43  nisimura 			(void)CSR_READ(sc, TXDONECNT); /* clear IRQ_TX ? */
   1556  1.31  nisimura 		}
   1557   1.3  nisimura 
   1558  1.31  nisimura 		CSR_WRITE(sc, xINTAE_SET, (IRQ_TX | IRQ_RX));
   1559  1.31  nisimura 	}
   1560   1.1  nisimura 	return 1;
   1561   1.1  nisimura }
   1562   1.1  nisimura 
   1563   1.1  nisimura static void
   1564   1.1  nisimura txreap(struct scx_softc *sc)
   1565   1.1  nisimura {
   1566   1.1  nisimura 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
   1567   1.1  nisimura 	struct scx_txsoft *txs;
   1568   1.1  nisimura 	uint32_t txstat;
   1569   1.1  nisimura 	int i;
   1570   1.1  nisimura 
   1571   1.6  nisimura 	for (i = sc->sc_txsdirty; sc->sc_txsfree != MD_TXQUEUELEN;
   1572   1.6  nisimura 	     i = MD_NEXTTXS(i), sc->sc_txsfree++) {
   1573   1.1  nisimura 		txs = &sc->sc_txsoft[i];
   1574   1.1  nisimura 
   1575   1.1  nisimura 		SCX_CDTXSYNC(sc, txs->txs_firstdesc, txs->txs_ndesc,
   1576   1.1  nisimura 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   1577   1.1  nisimura 
   1578  1.31  nisimura 		txstat = le32toh(sc->sc_txdescs[txs->txs_lastdesc].t0);
   1579   1.1  nisimura 		if (txstat & T0_OWN) /* desc is still in use */
   1580   1.1  nisimura 			break;
   1581   1.1  nisimura 
   1582   1.1  nisimura 		/* There is no way to tell transmission status per frame */
   1583   1.1  nisimura 
   1584   1.1  nisimura 		if_statinc(ifp, if_opackets);
   1585   1.1  nisimura 
   1586   1.1  nisimura 		sc->sc_txfree += txs->txs_ndesc;
   1587   1.1  nisimura 		bus_dmamap_sync(sc->sc_dmat, txs->txs_dmamap,
   1588   1.1  nisimura 		    0, txs->txs_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
   1589   1.1  nisimura 		bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
   1590   1.1  nisimura 		m_freem(txs->txs_mbuf);
   1591   1.1  nisimura 		txs->txs_mbuf = NULL;
   1592   1.1  nisimura 	}
   1593   1.1  nisimura 	sc->sc_txsdirty = i;
   1594   1.6  nisimura 	if (sc->sc_txsfree == MD_TXQUEUELEN)
   1595   1.1  nisimura 		ifp->if_timer = 0;
   1596   1.1  nisimura }
   1597   1.1  nisimura 
   1598   1.1  nisimura static void
   1599  1.41  nisimura rxfill(struct scx_softc *sc)
   1600   1.1  nisimura {
   1601   1.1  nisimura 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
   1602   1.1  nisimura 	struct scx_rxsoft *rxs;
   1603   1.1  nisimura 	struct mbuf *m;
   1604  1.41  nisimura 	uint32_t rxstat, rlen;
   1605  1.41  nisimura 	int i;
   1606   1.1  nisimura 
   1607   1.6  nisimura 	for (i = sc->sc_rxptr; /*CONSTCOND*/ 1; i = MD_NEXTRX(i)) {
   1608   1.1  nisimura 		SCX_CDRXSYNC(sc, i,
   1609   1.1  nisimura 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
   1610   1.1  nisimura 
   1611  1.29  nisimura 		rxstat = le32toh(sc->sc_rxdescs[i].r0);
   1612   1.1  nisimura 		if (rxstat & R0_OWN) /* desc is left empty */
   1613   1.1  nisimura 			break;
   1614   1.1  nisimura 
   1615  1.41  nisimura 		/* received frame length in R3 31:16 */
   1616  1.41  nisimura 		rlen = le32toh(sc->sc_rxdescs[i].r3) >> 16;
   1617  1.41  nisimura 
   1618   1.1  nisimura 		/* R0_FS | R0_LS must have been marked for this desc */
   1619  1.41  nisimura 		rxs = &sc->sc_rxsoft[i];
   1620   1.1  nisimura 		bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
   1621   1.1  nisimura 		    rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
   1622   1.1  nisimura 
   1623  1.41  nisimura 		/* dispense new storage to receive frame */
   1624   1.1  nisimura 		m = rxs->rxs_mbuf;
   1625   1.1  nisimura 		if (add_rxbuf(sc, i) != 0) {
   1626  1.41  nisimura 			if_statinc(ifp, if_ierrors);	/* resource shortage */
   1627  1.41  nisimura 			SCX_INIT_RXDESC(sc, i);		/* then reuse */
   1628   1.1  nisimura 			bus_dmamap_sync(sc->sc_dmat,
   1629   1.1  nisimura 			    rxs->rxs_dmamap, 0,
   1630   1.1  nisimura 			    rxs->rxs_dmamap->dm_mapsize,
   1631   1.1  nisimura 			    BUS_DMASYNC_PREREAD);
   1632   1.1  nisimura 			continue;
   1633   1.1  nisimura 		}
   1634  1.41  nisimura 		/* complete mbuf */
   1635   1.1  nisimura 		m_set_rcvif(m, ifp);
   1636  1.41  nisimura 		m->m_pkthdr.len = m->m_len = rlen;
   1637  1.41  nisimura 		m->m_flags |= M_HASFCS;
   1638   1.1  nisimura 		if (rxstat & R0_CSUM) {
   1639   1.1  nisimura 			uint32_t csum = M_CSUM_IPv4;
   1640   1.1  nisimura 			if (rxstat & R0_CERR)
   1641   1.1  nisimura 				csum |= M_CSUM_IPv4_BAD;
   1642   1.1  nisimura 			m->m_pkthdr.csum_flags |= csum;
   1643   1.1  nisimura 		}
   1644  1.41  nisimura 		/* and pass to upper layer */
   1645   1.1  nisimura 		if_percpuq_enqueue(ifp->if_percpuq, m);
   1646   1.1  nisimura 	}
   1647   1.1  nisimura 	sc->sc_rxptr = i;
   1648   1.1  nisimura }
   1649   1.1  nisimura 
   1650   1.1  nisimura static int
   1651   1.1  nisimura add_rxbuf(struct scx_softc *sc, int i)
   1652   1.1  nisimura {
   1653   1.1  nisimura 	struct scx_rxsoft *rxs = &sc->sc_rxsoft[i];
   1654   1.1  nisimura 	struct mbuf *m;
   1655   1.1  nisimura 	int error;
   1656   1.1  nisimura 
   1657   1.1  nisimura 	MGETHDR(m, M_DONTWAIT, MT_DATA);
   1658   1.1  nisimura 	if (m == NULL)
   1659   1.1  nisimura 		return ENOBUFS;
   1660   1.1  nisimura 	MCLGET(m, M_DONTWAIT);
   1661   1.1  nisimura 	if ((m->m_flags & M_EXT) == 0) {
   1662   1.1  nisimura 		m_freem(m);
   1663   1.1  nisimura 		return ENOBUFS;
   1664   1.1  nisimura 	}
   1665   1.1  nisimura 	if (rxs->rxs_mbuf != NULL)
   1666   1.1  nisimura 		bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
   1667   1.1  nisimura 	rxs->rxs_mbuf = m;
   1668   1.1  nisimura 	error = bus_dmamap_load(sc->sc_dmat, rxs->rxs_dmamap,
   1669   1.1  nisimura 	    m->m_ext.ext_buf, m->m_ext.ext_size, NULL, BUS_DMA_NOWAIT);
   1670   1.1  nisimura 	if (error) {
   1671   1.1  nisimura 		aprint_error_dev(sc->sc_dev,
   1672   1.1  nisimura 		    "can't load rx DMA map %d, error = %d\n", i, error);
   1673   1.1  nisimura 		panic("add_rxbuf");
   1674   1.1  nisimura 	}
   1675   1.1  nisimura 	bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
   1676   1.1  nisimura 	    rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
   1677   1.1  nisimura 	SCX_INIT_RXDESC(sc, i);
   1678   1.1  nisimura 
   1679   1.1  nisimura 	return 0;
   1680   1.1  nisimura }
   1681   1.1  nisimura 
   1682  1.23  nisimura static void
   1683  1.23  nisimura rxdrain(struct scx_softc *sc)
   1684  1.23  nisimura {
   1685  1.23  nisimura 	struct scx_rxsoft *rxs;
   1686  1.23  nisimura 	int i;
   1687  1.23  nisimura 
   1688  1.23  nisimura 	for (i = 0; i < MD_NRXDESC; i++) {
   1689  1.23  nisimura 		rxs = &sc->sc_rxsoft[i];
   1690  1.23  nisimura 		if (rxs->rxs_mbuf != NULL) {
   1691  1.23  nisimura 			bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
   1692  1.23  nisimura 			m_freem(rxs->rxs_mbuf);
   1693  1.23  nisimura 			rxs->rxs_mbuf = NULL;
   1694  1.23  nisimura 		}
   1695  1.23  nisimura 	}
   1696  1.23  nisimura }
   1697  1.23  nisimura 
   1698  1.40  nisimura #define LINK_DEBUG 0
   1699  1.40  nisimura 
   1700  1.41  nisimura static void
   1701  1.23  nisimura mii_statchg(struct ifnet *ifp)
   1702  1.23  nisimura {
   1703  1.23  nisimura 	struct scx_softc *sc = ifp->if_softc;
   1704  1.23  nisimura 	struct mii_data *mii = &sc->sc_mii;
   1705  1.23  nisimura 	const int Mbps[4] = { 10, 100, 1000, 0 };
   1706  1.23  nisimura 	uint32_t miisr, mcr, fcr;
   1707  1.23  nisimura 	int spd;
   1708  1.23  nisimura 
   1709  1.23  nisimura 	/* decode MIISR register value */
   1710  1.23  nisimura 	miisr = mac_read(sc, GMACMIISR);
   1711  1.29  nisimura 	spd = Mbps[(miisr & MIISR_SPD) >> 1];
   1712  1.40  nisimura #if LINK_DEBUG == 1
   1713  1.29  nisimura 	static uint32_t oldmiisr = 0;
   1714  1.29  nisimura 	if (miisr != oldmiisr) {
   1715  1.29  nisimura 		printf("MII link status (0x%x) %s",
   1716  1.29  nisimura 		    miisr, (miisr & MIISR_LUP) ? "up" : "down");
   1717  1.29  nisimura 		if (miisr & MIISR_LUP) {
   1718  1.29  nisimura 			printf(" spd%d", spd);
   1719  1.29  nisimura 			if (miisr & MIISR_FDX)
   1720  1.29  nisimura 				printf(",full-duplex");
   1721  1.29  nisimura 		}
   1722  1.29  nisimura 		printf("\n");
   1723  1.23  nisimura 	}
   1724  1.23  nisimura #endif
   1725  1.23  nisimura 	/* Get flow control negotiation result. */
   1726  1.23  nisimura 	if (IFM_SUBTYPE(mii->mii_media.ifm_cur->ifm_media) == IFM_AUTO &&
   1727  1.23  nisimura 	    (mii->mii_media_active & IFM_ETH_FMASK) != sc->sc_flowflags)
   1728  1.23  nisimura 		sc->sc_flowflags = mii->mii_media_active & IFM_ETH_FMASK;
   1729  1.23  nisimura 
   1730  1.23  nisimura 	/* Adjust speed 1000/100/10. */
   1731  1.40  nisimura 	mcr = mac_read(sc, GMACMCR) &~ (MCR_PS | MCR_FES);
   1732  1.40  nisimura 	if (sc->sc_miigmii) {
   1733  1.40  nisimura 		if (spd != 1000)
   1734  1.40  nisimura 			mcr |= MCR_PS;
   1735  1.40  nisimura 	} else {
   1736  1.40  nisimura 		if (spd == 100)
   1737  1.40  nisimura 			mcr |= MCR_FES;
   1738  1.23  nisimura 	}
   1739  1.23  nisimura 	mcr |= MCR_CST | MCR_JE;
   1740  1.40  nisimura 	if (sc->sc_miigmii == 0)
   1741  1.23  nisimura 		mcr |= MCR_IBN;
   1742  1.23  nisimura 
   1743  1.23  nisimura 	/* Adjust duplexity and PAUSE flow control. */
   1744  1.23  nisimura 	mcr &= ~MCR_USEFDX;
   1745  1.23  nisimura 	fcr = mac_read(sc, GMACFCR) & ~(FCR_TFE | FCR_RFE);
   1746  1.29  nisimura 	if (miisr & MIISR_FDX) {
   1747  1.23  nisimura 		if (sc->sc_flowflags & IFM_ETH_TXPAUSE)
   1748  1.23  nisimura 			fcr |= FCR_TFE;
   1749  1.23  nisimura 		if (sc->sc_flowflags & IFM_ETH_RXPAUSE)
   1750  1.23  nisimura 			fcr |= FCR_RFE;
   1751  1.23  nisimura 		mcr |= MCR_USEFDX;
   1752  1.23  nisimura 	}
   1753  1.23  nisimura 	mac_write(sc, GMACMCR, mcr);
   1754  1.23  nisimura 	mac_write(sc, GMACFCR, fcr);
   1755  1.40  nisimura #if LINK_DEBUG == 1
   1756  1.29  nisimura 	if (miisr != oldmiisr) {
   1757  1.29  nisimura 		printf("%ctxfe, %crxfe\n",
   1758  1.29  nisimura 		    (fcr & FCR_TFE) ? '+' : '-',
   1759  1.29  nisimura 		    (fcr & FCR_RFE) ? '+' : '-');
   1760  1.29  nisimura 	}
   1761  1.29  nisimura 	oldmiisr = miisr;
   1762  1.29  nisimura #endif
   1763  1.23  nisimura }
   1764  1.23  nisimura 
   1765  1.23  nisimura static void
   1766  1.23  nisimura scx_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
   1767  1.23  nisimura {
   1768  1.23  nisimura 	struct scx_softc *sc = ifp->if_softc;
   1769  1.23  nisimura 	struct mii_data *mii = &sc->sc_mii;
   1770  1.23  nisimura 
   1771  1.23  nisimura 	mii_pollstat(mii);
   1772  1.23  nisimura 	ifmr->ifm_status = mii->mii_media_status;
   1773  1.23  nisimura 	ifmr->ifm_active = sc->sc_flowflags |
   1774  1.23  nisimura 	    (mii->mii_media_active & ~IFM_ETH_FMASK);
   1775  1.23  nisimura }
   1776  1.23  nisimura 
   1777   1.1  nisimura static int
   1778  1.23  nisimura mii_readreg(device_t self, int phy, int reg, uint16_t *val)
   1779   1.1  nisimura {
   1780  1.23  nisimura 	struct scx_softc *sc = device_private(self);
   1781  1.23  nisimura 	uint32_t miia;
   1782  1.23  nisimura 	int ntries;
   1783  1.23  nisimura 
   1784  1.27  nisimura 	miia = (phy << GAR_PHY) | (reg << GAR_REG) | sc->sc_mdclk;
   1785  1.23  nisimura 	mac_write(sc, GMACGAR, miia | GAR_BUSY);
   1786  1.23  nisimura 	for (ntries = 0; ntries < 1000; ntries++) {
   1787  1.23  nisimura 		if ((mac_read(sc, GMACGAR) & GAR_BUSY) == 0)
   1788  1.23  nisimura 			goto unbusy;
   1789  1.23  nisimura 		DELAY(1);
   1790  1.23  nisimura 	}
   1791  1.23  nisimura 	return ETIMEDOUT;
   1792  1.23  nisimura  unbusy:
   1793  1.23  nisimura 	*val = mac_read(sc, GMACGDR);
   1794  1.23  nisimura 	return 0;
   1795   1.1  nisimura }
   1796   1.1  nisimura 
   1797   1.1  nisimura static int
   1798  1.23  nisimura mii_writereg(device_t self, int phy, int reg, uint16_t val)
   1799   1.1  nisimura {
   1800  1.23  nisimura 	struct scx_softc *sc = device_private(self);
   1801  1.23  nisimura 	uint32_t miia;
   1802  1.23  nisimura 	uint16_t dummy;
   1803  1.23  nisimura 	int ntries;
   1804   1.1  nisimura 
   1805  1.23  nisimura 	miia = (phy << GAR_PHY) | (reg << GAR_REG) | sc->sc_mdclk;
   1806  1.23  nisimura 	mac_write(sc, GMACGDR, val);
   1807  1.23  nisimura 	mac_write(sc, GMACGAR, miia | GAR_IOWR | GAR_BUSY);
   1808  1.23  nisimura 	for (ntries = 0; ntries < 1000; ntries++) {
   1809  1.23  nisimura 		if ((mac_read(sc, GMACGAR) & GAR_BUSY) == 0)
   1810  1.23  nisimura 			goto unbusy;
   1811  1.23  nisimura 		DELAY(1);
   1812  1.23  nisimura 	}
   1813  1.23  nisimura 	return ETIMEDOUT;
   1814  1.23  nisimura   unbusy:
   1815  1.23  nisimura 	mii_readreg(self, phy, MII_PHYIDR1, &dummy); /* dummy read cycle */
   1816  1.23  nisimura 	return 0;
   1817   1.1  nisimura }
   1818   1.1  nisimura 
   1819   1.1  nisimura static void
   1820  1.23  nisimura phy_tick(void *arg)
   1821   1.1  nisimura {
   1822  1.23  nisimura 	struct scx_softc *sc = arg;
   1823  1.23  nisimura 	struct mii_data *mii = &sc->sc_mii;
   1824  1.23  nisimura 	int s;
   1825   1.1  nisimura 
   1826  1.23  nisimura 	s = splnet();
   1827  1.23  nisimura 	mii_tick(mii);
   1828  1.23  nisimura 	splx(s);
   1829  1.27  nisimura #ifdef GMAC_EVENT_COUNTERS
   1830  1.29  nisimura 	/* 80 event counters exist */
   1831  1.23  nisimura #endif
   1832  1.23  nisimura 	callout_schedule(&sc->sc_callout, hz);
   1833   1.1  nisimura }
   1834   1.1  nisimura 
   1835  1.31  nisimura static void
   1836  1.41  nisimura resetuengine(struct scx_softc *sc)
   1837  1.31  nisimura {
   1838  1.31  nisimura 
   1839  1.41  nisimura 	if (CSR_READ(sc, CORESTAT) == 0) {
   1840  1.41  nisimura 		/* make sure to stop */
   1841  1.31  nisimura 		CSR_WRITE(sc, DMACTL_H2M, DMACTL_STOP);
   1842  1.31  nisimura 		CSR_WRITE(sc, DMACTL_M2H, DMACTL_STOP);
   1843  1.41  nisimura 		WAIT_FOR_CLR(sc, DMACTL_H2M, DMACTL_STOP);
   1844  1.41  nisimura 		WAIT_FOR_CLR(sc, DMACTL_M2H, DMACTL_STOP);
   1845  1.31  nisimura 	}
   1846  1.31  nisimura 	CSR_WRITE(sc, SWRESET, 0);		/* reset operation */
   1847  1.31  nisimura 	CSR_WRITE(sc, SWRESET, SRST_RUN);	/* manifest run */
   1848  1.31  nisimura 	CSR_WRITE(sc, COMINIT, INIT_DB | INIT_CLS);
   1849  1.41  nisimura 	WAIT_FOR_CLR(sc, COMINIT, (INIT_DB | INIT_CLS));
   1850  1.31  nisimura }
   1851  1.31  nisimura 
   1852  1.41  nisimura #define UCODE_DEBUG 0
   1853  1.40  nisimura 
   1854  1.13  nisimura /*
   1855  1.23  nisimura  * 3 independent uengines exist to process host2media, media2host and
   1856  1.13  nisimura  * packet data flows.
   1857  1.13  nisimura  */
   1858   1.1  nisimura static void
   1859   1.1  nisimura loaducode(struct scx_softc *sc)
   1860   1.1  nisimura {
   1861   1.1  nisimura 	uint32_t up, lo, sz;
   1862   1.1  nisimura 	uint64_t addr;
   1863   1.3  nisimura 
   1864   1.1  nisimura 	up = EE_READ(sc, 0x08); /* H->M ucode addr high */
   1865   1.1  nisimura 	lo = EE_READ(sc, 0x0c); /* H->M ucode addr low */
   1866   1.1  nisimura 	sz = EE_READ(sc, 0x10); /* H->M ucode size */
   1867   1.2  nisimura 	sz *= 4;
   1868   1.1  nisimura 	addr = ((uint64_t)up << 32) | lo;
   1869  1.41  nisimura 	injectucode(sc, UCODE_H2M, (bus_addr_t)addr, (bus_size_t)sz);
   1870  1.41  nisimura #if UCODE_DEBUG == 1
   1871  1.14  nisimura aprint_normal_dev(sc->sc_dev, "0x%x H2M ucode %u\n", lo, sz);
   1872  1.41  nisimura #endif
   1873   1.1  nisimura 
   1874   1.1  nisimura 	up = EE_READ(sc, 0x14); /* M->H ucode addr high */
   1875   1.1  nisimura 	lo = EE_READ(sc, 0x18); /* M->H ucode addr low */
   1876   1.1  nisimura 	sz = EE_READ(sc, 0x1c); /* M->H ucode size */
   1877   1.2  nisimura 	sz *= 4;
   1878   1.1  nisimura 	addr = ((uint64_t)up << 32) | lo;
   1879  1.27  nisimura 	injectucode(sc, UCODE_M2H, (bus_addr_t)addr, (bus_size_t)sz);
   1880  1.41  nisimura #if UCODE_DEBUG == 1
   1881  1.14  nisimura aprint_normal_dev(sc->sc_dev, "0x%x M2H ucode %u\n", lo, sz);
   1882  1.41  nisimura #endif
   1883   1.1  nisimura 
   1884   1.1  nisimura 	lo = EE_READ(sc, 0x20); /* PKT ucode addr */
   1885   1.1  nisimura 	sz = EE_READ(sc, 0x24); /* PKT ucode size */
   1886   1.2  nisimura 	sz *= 4;
   1887  1.27  nisimura 	injectucode(sc, UCODE_PKT, (bus_addr_t)lo, (bus_size_t)sz);
   1888  1.41  nisimura #if UCODE_DEBUG == 1
   1889  1.14  nisimura aprint_normal_dev(sc->sc_dev, "0x%x PKT ucode %u\n", lo, sz);
   1890  1.41  nisimura #endif
   1891   1.1  nisimura }
   1892   1.1  nisimura 
   1893   1.1  nisimura static void
   1894   1.2  nisimura injectucode(struct scx_softc *sc, int port,
   1895   1.2  nisimura 	bus_addr_t addr, bus_size_t size)
   1896   1.1  nisimura {
   1897   1.2  nisimura 	bus_space_handle_t bsh;
   1898   1.2  nisimura 	bus_size_t off;
   1899   1.1  nisimura 	uint32_t ucode;
   1900   1.1  nisimura 
   1901  1.14  nisimura 	if (bus_space_map(sc->sc_st, addr, size, 0, &bsh) != 0) {
   1902   1.3  nisimura 		aprint_error_dev(sc->sc_dev,
   1903   1.3  nisimura 		    "eeprom map failure for ucode port 0x%x\n", port);
   1904   1.2  nisimura 		return;
   1905   1.2  nisimura 	}
   1906   1.5  nisimura 	for (off = 0; off < size; off += 4) {
   1907   1.2  nisimura 		ucode = bus_space_read_4(sc->sc_st, bsh, off);
   1908   1.1  nisimura 		CSR_WRITE(sc, port, ucode);
   1909   1.1  nisimura 	}
   1910   1.2  nisimura 	bus_space_unmap(sc->sc_st, bsh, size);
   1911   1.1  nisimura }
   1912  1.13  nisimura 
   1913  1.42  nisimura static void
   1914  1.42  nisimura forcephyloopback(struct scx_softc *sc)
   1915  1.42  nisimura {
   1916  1.42  nisimura 	struct device *d = sc->sc_dev;
   1917  1.42  nisimura 	uint16_t val;
   1918  1.42  nisimura 	int loop, err;
   1919  1.42  nisimura 
   1920  1.42  nisimura 	err = mii_readreg(d, sc->sc_phy_id, MII_BMCR, &val);
   1921  1.42  nisimura 	if (err) {
   1922  1.42  nisimura 		aprint_error_dev(d, "forcephyloopback() failed\n");
   1923  1.42  nisimura 		return;
   1924  1.42  nisimura 	}
   1925  1.42  nisimura 	if (val & BMCR_PDOWN)
   1926  1.42  nisimura 		val &=  ~BMCR_PDOWN;
   1927  1.42  nisimura 	val |= BMCR_ISO;
   1928  1.42  nisimura 	(void)mii_writereg(d, sc->sc_phy_id, MII_BMCR, val);
   1929  1.42  nisimura 	loop = 100;
   1930  1.42  nisimura 	do {
   1931  1.42  nisimura 		(void)mii_readreg(d, sc->sc_phy_id, MII_BMCR, &val);
   1932  1.42  nisimura 	} while (loop-- > 0 && (val & (BMCR_PDOWN | BMCR_ISO)) != 0);
   1933  1.42  nisimura 	(void)mii_writereg(d, sc->sc_phy_id, MII_BMCR, val | BMCR_LOOP);
   1934  1.42  nisimura 	loop = 100;
   1935  1.42  nisimura 	do {
   1936  1.42  nisimura 		(void)mii_readreg(d, sc->sc_phy_id, MII_BMSR, &val);
   1937  1.42  nisimura 	} while (loop-- > 0 && (val & BMSR_LINK) != 0);
   1938  1.42  nisimura }
   1939  1.42  nisimura 
   1940  1.42  nisimura static void
   1941  1.42  nisimura resetphytonormal(struct scx_softc *sc)
   1942  1.42  nisimura {
   1943  1.42  nisimura 	struct device *d = sc->sc_dev;
   1944  1.42  nisimura 	uint16_t val;
   1945  1.42  nisimura 	int loop, err;
   1946  1.42  nisimura 
   1947  1.42  nisimura 	err = mii_readreg(d, sc->sc_phy_id, MII_BMCR, &val);
   1948  1.42  nisimura 	if (err) {
   1949  1.42  nisimura 		aprint_error_dev(d, "resetphytonormal() failed\n");
   1950  1.42  nisimura 	}
   1951  1.42  nisimura 	val &= ~BMCR_LOOP;
   1952  1.42  nisimura 	(void)mii_writereg(d, sc->sc_phy_id, MII_BMCR, val);
   1953  1.42  nisimura 	loop = 100;
   1954  1.42  nisimura 	do {
   1955  1.42  nisimura 		(void)mii_readreg(d, sc->sc_phy_id, MII_BMCR, &val);
   1956  1.42  nisimura 	} while (loop-- > 0 && (val & BMCR_LOOP) != 0);
   1957  1.42  nisimura 	(void)mii_writereg(d, sc->sc_phy_id, MII_BMCR, val | BMCR_RESET);
   1958  1.42  nisimura 	loop = 100;
   1959  1.42  nisimura 	do {
   1960  1.42  nisimura 		(void)mii_readreg(d, sc->sc_phy_id, MII_BMCR, &val);
   1961  1.42  nisimura 	} while (loop-- > 0 && (val & BMCR_RESET) != 0);
   1962  1.42  nisimura }
   1963  1.42  nisimura 
   1964  1.27  nisimura /* GAR 5:2 MDIO frequency selection */
   1965  1.13  nisimura static int
   1966  1.13  nisimura get_mdioclk(uint32_t freq)
   1967  1.13  nisimura {
   1968  1.13  nisimura 
   1969  1.14  nisimura 	freq /= 1000 * 1000;
   1970  1.27  nisimura 	if (freq < 35)
   1971  1.27  nisimura 		return GAR_MDIO_25_35MHZ;
   1972  1.27  nisimura 	if (freq < 60)
   1973  1.27  nisimura 		return GAR_MDIO_35_60MHZ;
   1974  1.27  nisimura 	if (freq < 100)
   1975  1.27  nisimura 		return GAR_MDIO_60_100MHZ;
   1976  1.27  nisimura 	if (freq < 150)
   1977  1.27  nisimura 		return GAR_MDIO_100_150MHZ;
   1978  1.27  nisimura 	if (freq < 250)
   1979  1.27  nisimura 		return GAR_MDIO_150_250MHZ;
   1980  1.27  nisimura 	return GAR_MDIO_250_300MHZ;
   1981  1.13  nisimura }
   1982  1.40  nisimura 
   1983  1.40  nisimura #define HWFEA_DEBUG 1
   1984  1.40  nisimura 
   1985  1.41  nisimura static void
   1986  1.40  nisimura dump_hwfeature(struct scx_softc *sc)
   1987  1.40  nisimura {
   1988  1.40  nisimura #if HWFEA_DEBUG == 1
   1989  1.40  nisimura 	struct {
   1990  1.40  nisimura 		uint32_t bit;
   1991  1.40  nisimura 		const char *des;
   1992  1.40  nisimura 	} field[] = {
   1993  1.40  nisimura 		{ 27, "SA/VLAN insertion replacement enabled" },
   1994  1.40  nisimura 		{ 26, "flexible PPS enabled" },
   1995  1.40  nisimura 		{ 25, "time stamping with internal system enabled" },
   1996  1.40  nisimura 		{ 24, "alternate/enhanced descriptor enabled" },
   1997  1.40  nisimura 		{ 19, "rx FIFO >2048 enabled" },
   1998  1.40  nisimura 		{ 18, "type 2 IP checksum offload enabled" },
   1999  1.40  nisimura 		{ 17, "type 1 IP checksum offload enabled" },
   2000  1.40  nisimura 		{ 16, "Tx checksum offload enabled" },
   2001  1.40  nisimura 		{ 15, "AV feature enabled" },
   2002  1.40  nisimura 		{ 14, "EEE energy save feature enabled" },
   2003  1.40  nisimura 		{ 13, "1588-2008 version 2 advanced feature enabled" },
   2004  1.40  nisimura 		{ 12, "only 1588-2002 version 1 feature enabled" },
   2005  1.40  nisimura 		{ 11, "RMON event counter enabled" },
   2006  1.40  nisimura 		{ 10, "PMT magic packet enabled" },
   2007  1.40  nisimura 		{ 9,  "PMT remote wakeup enabled" },
   2008  1.40  nisimura 		{ 8,  "MDIO enabled", },
   2009  1.40  nisimura 		{ 7,  "L3/L4 filter enabled" },
   2010  1.40  nisimura 		{ 6,  "TBI/SGMII/RTBI support enabled" },
   2011  1.40  nisimura 		{ 5,  "supplimental MAC address enabled" },
   2012  1.40  nisimura 		{ 4,  "receive hash filter enabled" },
   2013  1.40  nisimura 		{ 3,  "hash size is expanded" },
   2014  1.40  nisimura 		{ 2,  "Half Duplex enabled" },
   2015  1.40  nisimura 		{ 1,  "1000 Mbps enabled" },
   2016  1.40  nisimura 		{ 0,  "10/100 Mbps enabled" },
   2017  1.40  nisimura 	};
   2018  1.40  nisimura 	const char *nameofmii[] = {
   2019  1.40  nisimura 		"GMII or MII",
   2020  1.40  nisimura 		"RGMII",
   2021  1.40  nisimura 		"SGMII",
   2022  1.40  nisimura 		"TBI",
   2023  1.40  nisimura 		"RMII",
   2024  1.40  nisimura 		"RTBI",
   2025  1.40  nisimura 		"SMII",
   2026  1.40  nisimura 		"RevMII"
   2027  1.40  nisimura 	};
   2028  1.40  nisimura 	uint32_t hwfea, mtype, txchan, rxchan;
   2029  1.40  nisimura 
   2030  1.40  nisimura 	hwfea = CSR_READ(sc, HWFEA);
   2031  1.40  nisimura 	mtype = (hwfea & __BITS(30,28)) >> 28;
   2032  1.40  nisimura 	aprint_normal("HWFEA 0x%08x\n", hwfea);
   2033  1.40  nisimura 	aprint_normal("%s <30:28>\n", nameofmii[mtype]);
   2034  1.40  nisimura 	for (unsigned i = 0; i < __arraycount(field); i++) {
   2035  1.40  nisimura 		if ((hwfea & (1U << field[i].bit)) == 0)
   2036  1.40  nisimura 			continue;
   2037  1.40  nisimura 		aprint_normal("%s <%d>\n", field[i].des, field[i].bit);
   2038  1.40  nisimura 	}
   2039  1.40  nisimura 	if ((txchan = (hwfea & __BITS(23,22)) >> 22) != 0)
   2040  1.40  nisimura 		aprint_normal("+%d tx channel available <23,22>\n", txchan);
   2041  1.40  nisimura 	if ((rxchan = (hwfea & __BITS(21,20)) >> 20) != 0)
   2042  1.40  nisimura 		aprint_normal("+%d rx channel available <21:20>\n", rxchan);
   2043  1.40  nisimura 	return;
   2044  1.40  nisimura #endif
   2045  1.40  nisimura }
   2046