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