Thu Jun 15 07:21:45 2023 UTC ()
if_scx.c


(nisimura)
diff -r1.42 -r1.43 src/sys/arch/arm/sociox/if_scx.c

cvs diff -r1.42 -r1.43 src/sys/arch/arm/sociox/if_scx.c (expand / switch to unified diff)

--- src/sys/arch/arm/sociox/if_scx.c 2023/06/14 00:07:22 1.42
+++ src/sys/arch/arm/sociox/if_scx.c 2023/06/15 07:21:45 1.43
@@ -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
1560static void 1563static void
1561txreap(struct scx_softc *sc) 1564txreap(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;