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