| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: if_scx.c,v 1.42 2023/06/14 00:07:22 nisimura Exp $ */ | | 1 | /* $NetBSD: if_scx.c,v 1.43 2023/06/15 07:21:45 nisimura Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2020 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2020 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Tohru Nishimura. | | 8 | * by Tohru Nishimura. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -39,27 +39,27 @@ | | | @@ -39,27 +39,27 @@ |
39 | * to handle incoming frames, outgoing frames and packet data crypto | | 39 | * to handle incoming frames, outgoing frames and packet data crypto |
40 | * processing. uP programs are stored in an external flash memory and | | 40 | * processing. uP programs are stored in an external flash memory and |
41 | * have to be loaded by device driver. | | 41 | * have to be loaded by device driver. |
42 | * NetSec uses Synopsys DesignWare Core EMAC. DWC implementation | | 42 | * NetSec uses Synopsys DesignWare Core EMAC. DWC implementation |
43 | * register (0x20) is known to have 0x10.36 and feature register (0x1058) | | 43 | * register (0x20) is known to have 0x10.36 and feature register (0x1058) |
44 | * reports 0x11056f37. | | 44 | * reports 0x11056f37. |
45 | * <24> alternative/enhanced desc format | | 45 | * <24> alternative/enhanced desc format |
46 | * <18> receive IP type 2 checksum offload | | 46 | * <18> receive IP type 2 checksum offload |
47 | * <16> transmit checksum offload | | 47 | * <16> transmit checksum offload |
48 | * <11> event counter (mac management counter, MMC) | | 48 | * <11> event counter (mac management counter, MMC) |
49 | */ | | 49 | */ |
50 | | | 50 | |
51 | #include <sys/cdefs.h> | | 51 | #include <sys/cdefs.h> |
52 | __KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1.42 2023/06/14 00:07:22 nisimura Exp $"); | | 52 | __KERNEL_RCSID(0, "$NetBSD: if_scx.c,v 1.43 2023/06/15 07:21:45 nisimura Exp $"); |
53 | | | 53 | |
54 | #include <sys/param.h> | | 54 | #include <sys/param.h> |
55 | #include <sys/bus.h> | | 55 | #include <sys/bus.h> |
56 | #include <sys/intr.h> | | 56 | #include <sys/intr.h> |
57 | #include <sys/device.h> | | 57 | #include <sys/device.h> |
58 | #include <sys/callout.h> | | 58 | #include <sys/callout.h> |
59 | #include <sys/mbuf.h> | | 59 | #include <sys/mbuf.h> |
60 | #include <sys/errno.h> | | 60 | #include <sys/errno.h> |
61 | #include <sys/rndsource.h> | | 61 | #include <sys/rndsource.h> |
62 | #include <sys/kernel.h> | | 62 | #include <sys/kernel.h> |
63 | #include <sys/systm.h> | | 63 | #include <sys/systm.h> |
64 | | | 64 | |
65 | #include <net/if.h> | | 65 | #include <net/if.h> |
| @@ -110,116 +110,116 @@ struct rdes { | | | @@ -110,116 +110,116 @@ struct rdes { |
110 | #define R0_COK (1U<<6) /* 1: found ok */ | | 110 | #define R0_COK (1U<<6) /* 1: found ok */ |
111 | /* R1 frame address 63:32 */ | | 111 | /* R1 frame address 63:32 */ |
112 | /* R2 frame address 31:0 */ | | 112 | /* R2 frame address 31:0 */ |
113 | /* R3 31:16 received frame length, 15:0 buffer length to receive */ | | 113 | /* R3 31:16 received frame length, 15:0 buffer length to receive */ |
114 | | | 114 | |
115 | /* | | 115 | /* |
116 | * SC2A11 registers. 0x100 - 1204 | | 116 | * SC2A11 registers. 0x100 - 1204 |
117 | */ | | 117 | */ |
118 | #define SWRESET 0x104 | | 118 | #define SWRESET 0x104 |
119 | #define SRST_RUN (1U<<31) /* instruct start, 0 to stop */ | | 119 | #define SRST_RUN (1U<<31) /* instruct start, 0 to stop */ |
120 | #define COMINIT 0x120 | | 120 | #define COMINIT 0x120 |
121 | #define INIT_DB (1U<<2) /* ???; self clear when done */ | | 121 | #define INIT_DB (1U<<2) /* ???; self clear when done */ |
122 | #define INIT_CLS (1U<<1) /* ???; self clear when done */ | | 122 | #define INIT_CLS (1U<<1) /* ???; self clear when done */ |
123 | #define PKTCTRL 0x140 /* pkt engine control */ | | | |
124 | #define MODENRM (1U<<28) /* set operational mode to 'normal' */ | | | |
125 | #define ENJUMBO (1U<<27) /* allow jumbo frame */ | | | |
126 | #define RPTCSUMERR (1U<<3) /* log Rx checksum error */ | | | |
127 | #define RPTHDCOMP (1U<<2) /* log header incomplete condition */ | | | |
128 | #define RPTHDERR (1U<<1) /* log header error */ | | | |
129 | #define DROPNOMATCH (1U<<0) /* drop no match frames */ | | | |
130 | #define xINTSR 0x200 /* aggregated interrupt status */ | | 123 | #define xINTSR 0x200 /* aggregated interrupt status */ |
131 | #define IRQ_UCODE (1U<<20) /* ucode load completed; W1C */ | | 124 | #define IRQ_UCODE (1U<<20) /* ucode load completed; W1C */ |
132 | #define IRQ_MAC (1U<<19) /* ??? */ | | 125 | #define IRQ_MAC (1U<<19) /* ??? */ |
133 | #define IRQ_PKT (1U<<18) /* ??? */ | | 126 | #define IRQ_PKT (1U<<18) /* ??? */ |
134 | #define IRQ_BOOTCODE (1U<<5) /* ??? */ | | 127 | #define IRQ_BOOTCODE (1U<<5) /* ??? */ |
135 | #define IRQ_XDONE (1U<<4) /* ??? mode change completed */ | | 128 | #define IRQ_XDONE (1U<<4) /* ??? mode change completed */ |
136 | #define IRQ_RX (1U<<1) /* top level Rx interrupt */ | | 129 | #define IRQ_RX (1U<<1) /* top level Rx interrupt */ |
137 | #define IRQ_TX (1U<<0) /* top level Tx interrupt */ | | 130 | #define IRQ_TX (1U<<0) /* top level Tx interrupt */ |
138 | #define xINTAEN 0x204 /* INT_A enable */ | | 131 | #define xINTAEN 0x204 /* INT_A enable */ |
139 | #define xINTAE_SET 0x234 /* bit to set */ | | 132 | #define xINTAE_SET 0x234 /* bit to set */ |
140 | #define xINTAE_CLR 0x238 /* bit to clr */ | | 133 | #define xINTAE_CLR 0x238 /* bit to clr */ |
141 | #define xINTBEN 0x23c /* INT_B enable */ | | 134 | #define xINTBEN 0x23c /* INT_B enable */ |
142 | #define xINTBE_SET 0x240 /* bit to set */ | | 135 | #define xINTBE_SET 0x240 /* bit to set */ |
143 | #define xINTBE_CLR 0x244 /* bit to clr */ | | 136 | #define xINTBE_CLR 0x244 /* bit to clr */ |
144 | #define TXISR 0x400 /* transmit status; W1C */ | | 137 | #define TXISR 0x400 /* transmit status; W1C */ |
145 | #define TXIEN 0x404 /* tx interrupt enable */ | | 138 | #define TXIEN 0x404 /* tx interrupt enable */ |
146 | #define TXIE_SET 0x428 /* bit to set */ | | 139 | #define TXIE_SET 0x428 /* bit to set */ |
147 | #define TXIE_CLR 0x42c /* bit to clr */ | | 140 | #define TXIE_CLR 0x42c /* bit to clr */ |
148 | #define TXI_NTOWNR (1U<<17) /* ??? desc array got empty */ | | 141 | #define TXI_NTOWNR (1U<<17) /* ??? desc array got empty */ |
149 | #define TXI_TR_ERR (1U<<16) /* xmit error */ | | 142 | #define TXI_TR_ERR (1U<<16) /* xmit error detected */ |
150 | #define TXI_TXDONE (1U<<15) /* xmit completed */ | | 143 | #define TXI_TXDONE (1U<<15) /* xmit completed */ |
151 | #define TXI_TMREXP (1U<<14) /* coalesce guard timer expired */ | | 144 | #define TXI_TMREXP (1U<<14) /* coalesce guard timer expired */ |
152 | #define RXISR 0x440 /* receive status; W1C */ | | 145 | #define RXISR 0x440 /* receive status; W1C */ |
153 | #define RXIEN 0x444 /* rx interrupt enable */ | | 146 | #define RXIEN 0x444 /* rx interrupt enable */ |
154 | #define RXIE_SET 0x468 /* bit to set */ | | 147 | #define RXIE_SET 0x468 /* bit to set */ |
155 | #define RXIE_CLR 0x46c /* bit to clr */ | | 148 | #define RXIE_CLR 0x46c /* bit to clr */ |
156 | #define RXI_RC_ERR (1U<<16) /* recv error */ | | 149 | #define RXI_RC_ERR (1U<<16) /* recv error detected */ |
157 | #define RXI_PKTCNT (1U<<15) /* recv counter has new value */ | | 150 | #define RXI_PKTCNT (1U<<15) /* recv counter has new value */ |
158 | #define RXI_TMREXP (1U<<14) /* coalesce guard timer expired */ | | 151 | #define RXI_TMREXP (1U<<14) /* coalesce guard timer expired */ |
159 | #define TDBA_LO 0x408 /* tdes array base addr 31:0 */ | | 152 | #define TDBA_LO 0x408 /* tdes array base addr 31:0 */ |
160 | #define TDBA_HI 0x434 /* tdes array base addr 63:32 */ | | 153 | #define TDBA_HI 0x434 /* tdes array base addr 63:32 */ |
161 | #define RDBA_LO 0x448 /* rdes array base addr 31:0 */ | | 154 | #define RDBA_LO 0x448 /* rdes array base addr 31:0 */ |
162 | #define RDBA_HI 0x474 /* rdes array base addr 63:32 */ | | 155 | #define RDBA_HI 0x474 /* rdes array base addr 63:32 */ |
163 | #define TXCONF 0x430 /* tdes config */ | | 156 | #define TXCONF 0x430 /* tdes config */ |
164 | #define RXCONF 0x470 /* rdes config */ | | 157 | #define RXCONF 0x470 /* rdes config */ |
165 | #define DESCNF_UP (1U<<31) /* 'up-and-running' */ | | 158 | #define DESCNF_UP (1U<<31) /* 'up-and-running' */ |
166 | #define DESCNF_CHRST (1U<<30) /* channel reset */ | | 159 | #define DESCNF_CHRST (1U<<30) /* channel reset */ |
167 | #define DESCNF_TMR (1U<<4) /* coalesce timer mode select */ | | 160 | #define DESCNF_TMR (1U<<4) /* coalesce timer unit select */ |
168 | #define DESCNF_LE (1) /* little endian desc format */ | | 161 | #define DESCNF_LE (1) /* little endian desc format */ |
169 | #define TXSUBMIT 0x410 /* submit frame(s) to transmit */ | | 162 | #define TXSUBMIT 0x410 /* submit frame(s) to transmit */ |
170 | #define TXCOALESC 0x418 /* tx intr coalesce upper bound */ | | 163 | #define TXCOALESC 0x418 /* tx intr coalesce upper bound */ |
171 | #define RXCOALESC 0x458 /* rx intr coalesce upper bound */ | | 164 | #define RXCOALESC 0x458 /* rx intr coalesce upper bound */ |
172 | #define TCLSCTIME 0x420 /* tintr guard time usec, MSB to on */ | | 165 | #define TCLSCTIME 0x420 /* tintr guard time usec */ |
173 | #define RCLSCTIME 0x460 /* rintr guard time usec, MSB to on */ | | 166 | #define RCLSCTIME 0x460 /* rintr guard time usec */ |
174 | #define TXDONECNT 0x414 /* tx completed count, auto-zero */ | | 167 | #define TXDONECNT 0x414 /* tx completed count, auto-zero */ |
175 | #define RXAVAILCNT 0x454 /* rx available count, auto-zero */ | | 168 | #define RXAVAILCNT 0x454 /* rx available count, auto-zero */ |
176 | #define DMACTL_TMR 0x20c /* engine DMA timer value */ | | 169 | #define DMACTL_TMR 0x20c /* DMA cycle tick value */ |
| | | 170 | #define PKTCTRL 0x140 /* pkt engine control */ |
| | | 171 | #define MODENRM (1U<<28) /* set operational mode to 'normal' */ |
| | | 172 | #define ENJUMBO (1U<<27) /* allow jumbo frame */ |
| | | 173 | #define RPTCSUMERR (1U<<3) /* log Rx checksum error */ |
| | | 174 | #define RPTHDCOMP (1U<<2) /* log header incomplete condition */ |
| | | 175 | #define RPTHDERR (1U<<1) /* log header error */ |
| | | 176 | #define DROPNOMATCH (1U<<0) /* drop no match frames */ |
| | | 177 | #define UCODE_PKT 0x0d0 /* packet engine ucode port */ |
177 | #define UCODE_H2M 0x210 /* host2media engine ucode port */ | | 178 | #define UCODE_H2M 0x210 /* host2media engine ucode port */ |
178 | #define UCODE_M2H 0x21c /* media2host engine ucode port */ | | 179 | #define UCODE_M2H 0x21c /* media2host engine ucode port */ |
179 | #define CORESTAT 0x218 /* engine run state */ | | 180 | #define CORESTAT 0x218 /* engine run state */ |
180 | #define PKTSTOP (1U<<2) /* pkt engine stopped */ | | 181 | #define PKTSTOP (1U<<2) /* pkt engine stopped */ |
181 | #define M2HSTOP (1U<<1) /* M2H engine stopped */ | | 182 | #define M2HSTOP (1U<<1) /* M2H engine stopped */ |
182 | #define H2MSTOP (1U<<0) /* H2M engine stopped */ | | 183 | #define H2MSTOP (1U<<0) /* H2M engine stopped */ |
183 | #define DMACTL_H2M 0x214 /* host2media engine control */ | | 184 | #define DMACTL_H2M 0x214 /* host2media engine control */ |
184 | #define DMACTL_M2H 0x220 /* media2host engine control */ | | 185 | #define DMACTL_M2H 0x220 /* media2host engine control */ |
185 | #define DMACTL_STOP (1U<<0) /* instruct stop; self-clear */ | | 186 | #define DMACTL_STOP (1U<<0) /* instruct stop; self-clear */ |
186 | #define M2H_MODE_TRANS (1U<<20) /* initiate M2H mode change */ | | 187 | #define M2H_MODE_TRANS (1U<<20) /* initiate M2H mode change */ |
187 | #define UCODE_PKT 0x0d0 /* packet engine ucode port */ | | 188 | #define MODE_TRANS 0x500 /* mode change completion status */ |
| | | 189 | #define N2T_DONE (1U<<20) /* normal->taiki change completed */ |
| | | 190 | #define T2N_DONE (1U<<19) /* taiki->normal change completed */ |
188 | #define CLKEN 0x100 /* clock distribution enable */ | | 191 | #define CLKEN 0x100 /* clock distribution enable */ |
189 | #define CLK_G (1U<<5) /* feed clk domain G */ | | 192 | #define CLK_G (1U<<5) /* feed clk domain G */ |
190 | #define CLK_C (1U<<1) /* feed clk domain C */ | | 193 | #define CLK_C (1U<<1) /* feed clk domain C */ |
191 | #define CLK_D (1U<<0) /* feed clk domain D */ | | 194 | #define CLK_D (1U<<0) /* feed clk domain D */ |
| | | 195 | #define DESC_INIT 0x11fc /* write 1 for desc init, SC */ |
| | | 196 | #define DESC_SRST 0x1204 /* write 1 for desc sw reset, SC */ |
192 | | | 197 | |
193 | /* GMAC register indirect access. thru MACCMD/MACDATA operation */ | | 198 | /* GMAC register indirect access. thru MACCMD/MACDATA operation */ |
194 | #define MACDATA 0x11c0 /* gmac register rd/wr data */ | | 199 | #define MACDATA 0x11c0 /* gmac register rd/wr data */ |
195 | #define MACCMD 0x11c4 /* gmac register operation */ | | 200 | #define MACCMD 0x11c4 /* gmac register operation */ |
196 | #define CMD_IOWR (1U<<28) /* write op */ | | 201 | #define CMD_IOWR (1U<<28) /* write op */ |
197 | #define CMD_BUSY (1U<<31) /* busy bit */ | | 202 | #define CMD_BUSY (1U<<31) /* busy bit */ |
198 | #define MACSTAT 0x1024 /* mac interrupt status (unused) */ | | 203 | #define MACSTAT 0x1024 /* mac interrupt status (unused) */ |
199 | #define MACINTE 0x1028 /* mac interrupt enable (unused) */ | | 204 | #define MACINTE 0x1028 /* mac interrupt enable (unused) */ |
200 | | | 205 | |
201 | #define FLOWTHR 0x11cc /* flow control threshold */ | | 206 | #define FLOWTHR 0x11cc /* flow control threshold */ |
202 | /* 31:16 pause threshold, 15:0 resume threshold */ | | 207 | /* 31:16 pause threshold, 15:0 resume threshold */ |
203 | #define INTF_SEL 0x11d4 /* phy interface type */ | | 208 | #define INTF_SEL 0x11d4 /* phy interface type */ |
204 | #define INTF_GMII 0 | | 209 | #define INTF_GMII 0 |
205 | #define INTF_RGMII 1 | | 210 | #define INTF_RGMII 1 |
206 | #define INTF_RMII 4 | | 211 | #define INTF_RMII 4 |
207 | | | 212 | |
208 | #define DESC_INIT 0x11fc /* write 1 for desc init, SC */ | | | |
209 | #define DESC_SRST 0x1204 /* write 1 for desc sw reset, SC */ | | | |
210 | #define MODE_TRANS 0x500 /* mode change completion status */ | | | |
211 | #define N2T_DONE (1U<<20) /* normal->taiki change completed */ | | | |
212 | #define T2N_DONE (1U<<19) /* taiki->normal change completed */ | | | |
213 | #define MCVER 0x22c /* micro controller version */ | | 213 | #define MCVER 0x22c /* micro controller version */ |
214 | #define HWVER 0x230 /* hardware version */ | | 214 | #define HWVER 0x230 /* hardware version */ |
215 | | | 215 | |
216 | /* | | 216 | /* |
217 | * GMAC registers are mostly identical to Synopsys DesignWare Core | | 217 | * GMAC registers are mostly identical to Synopsys DesignWare Core |
218 | * Ethernet. These must be handled by indirect access. | | 218 | * Ethernet. These must be handled by indirect access. |
219 | */ | | 219 | */ |
220 | #define GMACMCR 0x0000 /* MAC configuration */ | | 220 | #define GMACMCR 0x0000 /* MAC configuration */ |
221 | #define MCR_IBN (1U<<30) /* watch in-band-signal */ | | 221 | #define MCR_IBN (1U<<30) /* watch in-band-signal */ |
222 | #define MCR_CST (1U<<25) /* strip CRC */ | | 222 | #define MCR_CST (1U<<25) /* strip CRC */ |
223 | #define MCR_TC (1U<<24) /* keep RGMII PHY notified */ | | 223 | #define MCR_TC (1U<<24) /* keep RGMII PHY notified */ |
224 | #define MCR_WD (1U<<23) /* allow long >2048 tx frame */ | | 224 | #define MCR_WD (1U<<23) /* allow long >2048 tx frame */ |
225 | #define MCR_JE (1U<<20) /* allow ~9018 tx jumbo frame */ | | 225 | #define MCR_JE (1U<<20) /* allow ~9018 tx jumbo frame */ |
| @@ -344,28 +344,31 @@ struct rdes { | | | @@ -344,28 +344,31 @@ struct rdes { |
344 | #define DMAI_FBI (1U<<13) /* DMA bus error detected */ | | 344 | #define DMAI_FBI (1U<<13) /* DMA bus error detected */ |
345 | #define DMAI_ETI (1U<<10) /* single frame Tx completed */ | | 345 | #define DMAI_ETI (1U<<10) /* single frame Tx completed */ |
346 | #define DMAI_RWT (1U<<9) /* longer than 2048 frame received */ | | 346 | #define DMAI_RWT (1U<<9) /* longer than 2048 frame received */ |
347 | #define DMAI_RPS (1U<<8) /* Rx process is now stopped */ | | 347 | #define DMAI_RPS (1U<<8) /* Rx process is now stopped */ |
348 | #define DMAI_RU (1U<<7) /* Rx descriptor not available */ | | 348 | #define DMAI_RU (1U<<7) /* Rx descriptor not available */ |
349 | #define DMAI_RI (1U<<6) /* frame Rx completed by !R1_DIC */ | | 349 | #define DMAI_RI (1U<<6) /* frame Rx completed by !R1_DIC */ |
350 | #define DMAI_UNF (1U<<5) /* Tx underflow detected */ | | 350 | #define DMAI_UNF (1U<<5) /* Tx underflow detected */ |
351 | #define DMAI_OVF (1U<<4) /* receive buffer overflow detected */ | | 351 | #define DMAI_OVF (1U<<4) /* receive buffer overflow detected */ |
352 | #define DMAI_TJT (1U<<3) /* longer than 2048 frame sent */ | | 352 | #define DMAI_TJT (1U<<3) /* longer than 2048 frame sent */ |
353 | #define DMAI_TU (1U<<2) /* Tx descriptor not available */ | | 353 | #define DMAI_TU (1U<<2) /* Tx descriptor not available */ |
354 | #define DMAI_TPS (1U<<1) /* transmission is stopped */ | | 354 | #define DMAI_TPS (1U<<1) /* transmission is stopped */ |
355 | #define DMAI_TI (1U<<0) /* frame Tx completed by T0_IC */ | | 355 | #define DMAI_TI (1U<<0) /* frame Tx completed by T0_IC */ |
356 | #define GMACOMR 0x1018 /* DMA operation mode */ | | 356 | #define GMACOMR 0x1018 /* DMA operation mode */ |
| | | 357 | #define OMR_DT (1U<<26) /* don't drop error frames */ |
357 | #define OMR_RSF (1U<<25) /* 1: Rx store&forward, 0: immed. */ | | 358 | #define OMR_RSF (1U<<25) /* 1: Rx store&forward, 0: immed. */ |
| | | 359 | #define OMR_DFF (1U<<24) /* don't flush rx frames on shortage */ |
358 | #define OMR_TSF (1U<<21) /* 1: Tx store&forward, 0: immed. */ | | 360 | #define OMR_TSF (1U<<21) /* 1: Tx store&forward, 0: immed. */ |
| | | 361 | #define OMR_FTF (1U<<20) /* initiate tx FIFO reset, SC */ |
359 | #define OMR_TTC (14) /* 16:14 Tx threshold */ | | 362 | #define OMR_TTC (14) /* 16:14 Tx threshold */ |
360 | #define OMR_ST (1U<<13) /* run Tx DMA engine, 0 to stop */ | | 363 | #define OMR_ST (1U<<13) /* run Tx DMA engine, 0 to stop */ |
361 | #define OMR_RFD (11) /* 12:11 Rx FIFO fill level */ | | 364 | #define OMR_RFD (11) /* 12:11 Rx FIFO fill level */ |
362 | #define OMR_EFC (1U<<8) /* transmit PAUSE to throttle Rx lvl. */ | | 365 | #define OMR_EFC (1U<<8) /* transmit PAUSE to throttle Rx lvl. */ |
363 | #define OMR_FEF (1U<<7) /* allow to receive error frames */ | | 366 | #define OMR_FEF (1U<<7) /* allow to receive error frames */ |
364 | #define OMR_SR (1U<<1) /* run Rx DMA engine, 0 to stop */ | | 367 | #define OMR_SR (1U<<1) /* run Rx DMA engine, 0 to stop */ |
365 | #define GMACEVCS 0x1020 /* missed frame or ovf detected */ | | 368 | #define GMACEVCS 0x1020 /* missed frame or ovf detected */ |
366 | #define GMACRWDT 0x1024 /* enable rx watchdog timer interrupt */ | | 369 | #define GMACRWDT 0x1024 /* enable rx watchdog timer interrupt */ |
367 | #define GMACAXIB 0x1028 /* AXI bus mode control */ | | 370 | #define GMACAXIB 0x1028 /* AXI bus mode control */ |
368 | #define GMACAXIS 0x102c /* AXI status report */ | | 371 | #define GMACAXIS 0x102c /* AXI status report */ |
369 | /* 0x1048 current tx desc address */ | | 372 | /* 0x1048 current tx desc address */ |
370 | /* 0x104c current rx desc address */ | | 373 | /* 0x104c current rx desc address */ |
371 | /* 0x1050 current tx buffer address */ | | 374 | /* 0x1050 current tx buffer address */ |
| @@ -393,27 +396,27 @@ struct rdes { | | | @@ -393,27 +396,27 @@ struct rdes { |
393 | * 0x00 - 07 48-bit MAC station address. 4 byte wise in BE order. | | 396 | * 0x00 - 07 48-bit MAC station address. 4 byte wise in BE order. |
394 | * 0x08 - 0b H->MAC xfer engine program start addr 63:32. | | 397 | * 0x08 - 0b H->MAC xfer engine program start addr 63:32. |
395 | * 0x0c - 0f H2M program addr 31:0 (these are absolute addr, not offset) | | 398 | * 0x0c - 0f H2M program addr 31:0 (these are absolute addr, not offset) |
396 | * 0x10 - 13 H2M program length in 4 byte count. | | 399 | * 0x10 - 13 H2M program length in 4 byte count. |
397 | * 0x14 - 0b M->HOST xfer engine program start addr 63:32. | | 400 | * 0x14 - 0b M->HOST xfer engine program start addr 63:32. |
398 | * 0x18 - 0f M2H program addr 31:0 (absolute addr, not relative) | | 401 | * 0x18 - 0f M2H program addr 31:0 (absolute addr, not relative) |
399 | * 0x1c - 13 M2H program length in 4 byte count. | | 402 | * 0x1c - 13 M2H program length in 4 byte count. |
400 | * 0x20 - 23 packet engine program addr 31:0, (absolute addr, not offset) | | 403 | * 0x20 - 23 packet engine program addr 31:0, (absolute addr, not offset) |
401 | * 0x24 - 27 packet program length in 4 byte count. | | 404 | * 0x24 - 27 packet program length in 4 byte count. |
402 | * | | 405 | * |
403 | * above ucode are loaded via mapped reg 0x210, 0x21c and 0x0c0. | | 406 | * above ucode are loaded via mapped reg 0x210, 0x21c and 0x0c0. |
404 | */ | | 407 | */ |
405 | | | 408 | |
406 | #define _BMR 0x00412080 /* XXX TBD */ | | 409 | #define _BMR 0x00412080 /* NetSec BMR value, magic spell */ |
407 | /* NetSec uses local RAM to handle GMAC desc arrays */ | | 410 | /* NetSec uses local RAM to handle GMAC desc arrays */ |
408 | #define _RDLA 0x18000 | | 411 | #define _RDLA 0x18000 |
409 | #define _TDLA 0x1c000 | | 412 | #define _TDLA 0x1c000 |
410 | /* lower address region is used for intermediate frame data buffers */ | | 413 | /* lower address region is used for intermediate frame data buffers */ |
411 | | | 414 | |
412 | /* | | 415 | /* |
413 | * all below are software construction. | | 416 | * all below are software construction. |
414 | */ | | 417 | */ |
415 | #define MD_NTXDESC 128 | | 418 | #define MD_NTXDESC 128 |
416 | #define MD_NRXDESC 64 | | 419 | #define MD_NRXDESC 64 |
417 | | | 420 | |
418 | #define MD_NTXSEGS 16 | | 421 | #define MD_NTXSEGS 16 |
419 | #define MD_TXQUEUELEN 8 | | 422 | #define MD_TXQUEUELEN 8 |
| @@ -1123,53 +1126,53 @@ scx_init(struct ifnet *ifp) | | | @@ -1123,53 +1126,53 @@ scx_init(struct ifnet *ifp) |
1123 | struct scx_softc *sc = ifp->if_softc; | | 1126 | struct scx_softc *sc = ifp->if_softc; |
1124 | const uint8_t *ea = CLLADDR(ifp->if_sadl); | | 1127 | const uint8_t *ea = CLLADDR(ifp->if_sadl); |
1125 | uint32_t csr; | | 1128 | uint32_t csr; |
1126 | int i, error; | | 1129 | int i, error; |
1127 | | | 1130 | |
1128 | /* Cancel pending I/O. */ | | 1131 | /* Cancel pending I/O. */ |
1129 | scx_stop(ifp, 0); | | 1132 | scx_stop(ifp, 0); |
1130 | | | 1133 | |
1131 | /* Reset the chip to a known state. */ | | 1134 | /* Reset the chip to a known state. */ |
1132 | scx_reset(sc); | | 1135 | scx_reset(sc); |
1133 | | | 1136 | |
1134 | /* build sane Tx */ | | 1137 | /* build sane Tx */ |
1135 | memset(sc->sc_txdescs, 0, sizeof(struct tdes) * MD_NTXDESC); | | 1138 | memset(sc->sc_txdescs, 0, sizeof(struct tdes) * MD_NTXDESC); |
1136 | sc->sc_txdescs[MD_NTXDESC - 1].t0 = T0_LD; /* tie off the ring */ | | 1139 | sc->sc_txdescs[MD_NTXDESC - 1].t0 = htole32(T0_LD); /* tie off */ |
1137 | SCX_CDTXSYNC(sc, 0, MD_NTXDESC, | | 1140 | SCX_CDTXSYNC(sc, 0, MD_NTXDESC, |
1138 | BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); | | 1141 | BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); |
1139 | sc->sc_txfree = MD_NTXDESC; | | 1142 | sc->sc_txfree = MD_NTXDESC; |
1140 | sc->sc_txnext = 0; | | 1143 | sc->sc_txnext = 0; |
1141 | for (i = 0; i < MD_TXQUEUELEN; i++) | | 1144 | for (i = 0; i < MD_TXQUEUELEN; i++) |
1142 | sc->sc_txsoft[i].txs_mbuf = NULL; | | 1145 | sc->sc_txsoft[i].txs_mbuf = NULL; |
1143 | sc->sc_txsfree = MD_TXQUEUELEN; | | 1146 | sc->sc_txsfree = MD_TXQUEUELEN; |
1144 | sc->sc_txsnext = 0; | | 1147 | sc->sc_txsnext = 0; |
1145 | sc->sc_txsdirty = 0; | | 1148 | sc->sc_txsdirty = 0; |
1146 | | | 1149 | |
1147 | /* load Rx descriptors with fresh mbuf */ | | 1150 | /* load Rx descriptors with fresh mbuf */ |
1148 | for (i = 0; i < MD_NRXDESC; i++) { | | 1151 | for (i = 0; i < MD_NRXDESC; i++) { |
1149 | if (sc->sc_rxsoft[i].rxs_mbuf == NULL) { | | 1152 | if (sc->sc_rxsoft[i].rxs_mbuf == NULL) { |
1150 | if ((error = add_rxbuf(sc, i)) != 0) { | | 1153 | if ((error = add_rxbuf(sc, i)) != 0) { |
1151 | aprint_error_dev(sc->sc_dev, | | 1154 | aprint_error_dev(sc->sc_dev, |
1152 | "unable to allocate or map rx " | | 1155 | "unable to allocate or map rx " |
1153 | "buffer %d, error = %d\n", | | 1156 | "buffer %d, error = %d\n", |
1154 | i, error); | | 1157 | i, error); |
1155 | rxdrain(sc); | | 1158 | rxdrain(sc); |
1156 | goto out; | | 1159 | goto out; |
1157 | } | | 1160 | } |
1158 | } | | 1161 | } |
1159 | else | | 1162 | else |
1160 | SCX_INIT_RXDESC(sc, i); | | 1163 | SCX_INIT_RXDESC(sc, i); |
1161 | } | | 1164 | } |
1162 | sc->sc_rxdescs[MD_NRXDESC - 1].r0 = R0_LD; /* tie off the ring */ | | 1165 | sc->sc_rxdescs[MD_NRXDESC - 1].r0 = htole32(R0_LD); /* tie off */ |
1163 | sc->sc_rxptr = 0; | | 1166 | sc->sc_rxptr = 0; |
1164 | | | 1167 | |
1165 | /* set my address in perfect match slot 0. little endian order */ | | 1168 | /* set my address in perfect match slot 0. little endian order */ |
1166 | csr = (ea[3] << 24) | (ea[2] << 16) | (ea[1] << 8) | ea[0]; | | 1169 | csr = (ea[3] << 24) | (ea[2] << 16) | (ea[1] << 8) | ea[0]; |
1167 | mac_write(sc, GMACMAL0, csr); | | 1170 | mac_write(sc, GMACMAL0, csr); |
1168 | csr = (ea[5] << 8) | ea[4]; | | 1171 | csr = (ea[5] << 8) | ea[4]; |
1169 | mac_write(sc, GMACMAH0, csr); | | 1172 | mac_write(sc, GMACMAH0, csr); |
1170 | | | 1173 | |
1171 | /* accept multicast frame or run promisc mode */ | | 1174 | /* accept multicast frame or run promisc mode */ |
1172 | scx_set_rcvfilt(sc); | | 1175 | scx_set_rcvfilt(sc); |
1173 | | | 1176 | |
1174 | /* set current media */ | | 1177 | /* set current media */ |
1175 | if ((error = ether_mediachange(ifp)) != 0) | | 1178 | if ((error = ether_mediachange(ifp)) != 0) |
| @@ -1182,28 +1185,28 @@ scx_init(struct ifnet *ifp) | | | @@ -1182,28 +1185,28 @@ scx_init(struct ifnet *ifp) |
1182 | WAIT_FOR_CLR(sc, DESC_INIT, 01); | | 1185 | WAIT_FOR_CLR(sc, DESC_INIT, 01); |
1183 | | | 1186 | |
1184 | /* feed local memory descriptor array base addresses */ | | 1187 | /* feed local memory descriptor array base addresses */ |
1185 | mac_write(sc, GMACRDLA, _RDLA); /* GMAC rdes store */ | | 1188 | mac_write(sc, GMACRDLA, _RDLA); /* GMAC rdes store */ |
1186 | mac_write(sc, GMACTDLA, _TDLA); /* GMAC tdes store */ | | 1189 | mac_write(sc, GMACTDLA, _TDLA); /* GMAC tdes store */ |
1187 | | | 1190 | |
1188 | CSR_WRITE(sc, FLOWTHR, (48<<16) | 36); /* pause|resume threshold */ | | 1191 | CSR_WRITE(sc, FLOWTHR, (48<<16) | 36); /* pause|resume threshold */ |
1189 | mac_write(sc, GMACFCR, 256 << 16); /* 31:16 pause value */ | | 1192 | mac_write(sc, GMACFCR, 256 << 16); /* 31:16 pause value */ |
1190 | | | 1193 | |
1191 | CSR_WRITE(sc, INTF_SEL, sc->sc_miigmii ? INTF_GMII : INTF_RGMII); | | 1194 | CSR_WRITE(sc, INTF_SEL, sc->sc_miigmii ? INTF_GMII : INTF_RGMII); |
1192 | | | 1195 | |
1193 | CSR_WRITE(sc, RXCOALESC, 8); /* Rx coalesce bound */ | | 1196 | CSR_WRITE(sc, RXCOALESC, 8); /* Rx coalesce bound */ |
1194 | CSR_WRITE(sc, TXCOALESC, 8); /* Tx coalesce bound */ | | 1197 | CSR_WRITE(sc, TXCOALESC, 8); /* Tx coalesce bound */ |
1195 | CSR_WRITE(sc, RCLSCTIME, 500|(1U<<31)); /* Rx co. guard time usec */ | | 1198 | CSR_WRITE(sc, RCLSCTIME, 500); /* Rx co. guard time usec */ |
1196 | CSR_WRITE(sc, TCLSCTIME, 500|(1U<<31)); /* Tx co. guard time usec */ | | 1199 | CSR_WRITE(sc, TCLSCTIME, 500); /* Tx co. guard time usec */ |
1197 | | | 1200 | |
1198 | CSR_WRITE(sc, RXIE_SET, RXI_RC_ERR | RXI_PKTCNT | RXI_TMREXP); | | 1201 | CSR_WRITE(sc, RXIE_SET, RXI_RC_ERR | RXI_PKTCNT | RXI_TMREXP); |
1199 | CSR_WRITE(sc, TXIE_SET, TXI_TR_ERR | TXI_TXDONE | TXI_TMREXP); | | 1202 | CSR_WRITE(sc, TXIE_SET, TXI_TR_ERR | TXI_TXDONE | TXI_TMREXP); |
1200 | CSR_WRITE(sc, xINTAE_SET, IRQ_RX | IRQ_TX); | | 1203 | CSR_WRITE(sc, xINTAE_SET, IRQ_RX | IRQ_TX); |
1201 | #if 1 | | 1204 | #if 1 |
1202 | /* clear event counters, auto-zero after every read */ | | 1205 | /* clear event counters, auto-zero after every read */ |
1203 | mac_write(sc, GMACEVCTL, EVC_CR | EVC_ROR); | | 1206 | mac_write(sc, GMACEVCTL, EVC_CR | EVC_ROR); |
1204 | #endif | | 1207 | #endif |
1205 | /* kick to start GMAC engine */ | | 1208 | /* kick to start GMAC engine */ |
1206 | csr = mac_read(sc, GMACOMR); | | 1209 | csr = mac_read(sc, GMACOMR); |
1207 | mac_write(sc, GMACOMR, csr | OMR_SR | OMR_ST); | | 1210 | mac_write(sc, GMACOMR, csr | OMR_SR | OMR_ST); |
1208 | | | 1211 | |
1209 | ifp->if_flags |= IFF_RUNNING; | | 1212 | ifp->if_flags |= IFF_RUNNING; |
| @@ -1530,36 +1533,36 @@ scx_intr(void *arg) | | | @@ -1530,36 +1533,36 @@ scx_intr(void *arg) |
1530 | status = CSR_READ(sc, xINTSR); /* not W1C */ | | 1533 | status = CSR_READ(sc, xINTSR); /* not W1C */ |
1531 | enable = CSR_READ(sc, xINTAEN); | | 1534 | enable = CSR_READ(sc, xINTAEN); |
1532 | if ((status & enable) == 0) | | 1535 | if ((status & enable) == 0) |
1533 | return 0; | | 1536 | return 0; |
1534 | if (status & (IRQ_TX | IRQ_RX)) { | | 1537 | if (status & (IRQ_TX | IRQ_RX)) { |
1535 | CSR_WRITE(sc, xINTAE_CLR, (IRQ_TX | IRQ_RX)); | | 1538 | CSR_WRITE(sc, xINTAE_CLR, (IRQ_TX | IRQ_RX)); |
1536 | | | 1539 | |
1537 | status = CSR_READ(sc, RXISR); | | 1540 | status = CSR_READ(sc, RXISR); |
1538 | CSR_WRITE(sc, RXISR, status); | | 1541 | CSR_WRITE(sc, RXISR, status); |
1539 | if (status & RXI_RC_ERR) | | 1542 | if (status & RXI_RC_ERR) |
1540 | aprint_error_dev(sc->sc_dev, "Rx error\n"); | | 1543 | aprint_error_dev(sc->sc_dev, "Rx error\n"); |
1541 | if (status & (RXI_PKTCNT | RXI_TMREXP)) { | | 1544 | if (status & (RXI_PKTCNT | RXI_TMREXP)) { |
1542 | rxfill(sc); | | 1545 | rxfill(sc); |
1543 | (void)CSR_READ(sc, RXAVAILCNT); /* clear RXI_PKTCNT */ | | 1546 | (void)CSR_READ(sc, RXAVAILCNT); /* clear IRQ_RX ? */ |
1544 | } | | 1547 | } |
1545 | | | 1548 | |
1546 | status = CSR_READ(sc, TXISR); | | 1549 | status = CSR_READ(sc, TXISR); |
1547 | CSR_WRITE(sc, TXISR, status); | | 1550 | CSR_WRITE(sc, TXISR, status); |
1548 | if (status & TXI_TR_ERR) | | 1551 | if (status & TXI_TR_ERR) |
1549 | aprint_error_dev(sc->sc_dev, "Tx error\n"); | | 1552 | aprint_error_dev(sc->sc_dev, "Tx error\n"); |
1550 | if (status & (TXI_TXDONE | TXI_TMREXP)) { | | 1553 | if (status & (TXI_TXDONE | TXI_TMREXP)) { |
1551 | txreap(sc); | | 1554 | txreap(sc); |
1552 | (void)CSR_READ(sc, TXDONECNT); /* clear TXI_TXDONE */ | | 1555 | (void)CSR_READ(sc, TXDONECNT); /* clear IRQ_TX ? */ |
1553 | } | | 1556 | } |
1554 | | | 1557 | |
1555 | CSR_WRITE(sc, xINTAE_SET, (IRQ_TX | IRQ_RX)); | | 1558 | CSR_WRITE(sc, xINTAE_SET, (IRQ_TX | IRQ_RX)); |
1556 | } | | 1559 | } |
1557 | return 1; | | 1560 | return 1; |
1558 | } | | 1561 | } |
1559 | | | 1562 | |
1560 | static void | | 1563 | static void |
1561 | txreap(struct scx_softc *sc) | | 1564 | txreap(struct scx_softc *sc) |
1562 | { | | 1565 | { |
1563 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; | | 1566 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; |
1564 | struct scx_txsoft *txs; | | 1567 | struct scx_txsoft *txs; |
1565 | uint32_t txstat; | | 1568 | uint32_t txstat; |