1FILE_LICENCE ( GPL_ANY );
2
3#define NATSEMI_HW_TIMEOUT 400
4
5#define TX_RING_SIZE 4
6#define NUM_RX_DESC  4
7#define RX_BUF_SIZE 1536
8#define OWN       0x80000000
9#define DSIZE     0x00000FFF
10#define CRC_SIZE  4
11
12struct natsemi_tx {
13	uint32_t link;
14	uint32_t cmdsts;
15	uint32_t bufptr;
16};
17
18struct natsemi_rx {
19	uint32_t link;
20	uint32_t cmdsts;
21	uint32_t bufptr;
22};
23
24struct natsemi_private {
25	unsigned short ioaddr;
26	unsigned short tx_cur;
27	unsigned short tx_dirty;
28	unsigned short rx_cur;
29	struct natsemi_tx tx[TX_RING_SIZE];
30	struct natsemi_rx rx[NUM_RX_DESC];
31
32	/* need to add iobuf as we cannot free iobuf->data in close without this
33	 * alternatively substracting sizeof(head) and sizeof(list_head) can also
34	 * give the same.
35	 */
36	struct io_buffer *iobuf[NUM_RX_DESC];
37
38	/* netdev_tx_complete needs pointer to the iobuf of the data so as to free
39	 * it from the memory.
40	 */
41	struct io_buffer *tx_iobuf[TX_RING_SIZE];
42	struct spi_bit_basher spibit;
43	struct spi_device eeprom;
44	struct nvo_block nvo;
45};
46
47/*
48 * Support for fibre connections on Am79C874:
49 * This phy needs a special setup when connected to a fibre cable.
50 * http://www.amd.com/files/connectivitysolutions/networking/archivednetworking/22235.pdf
51 */
52#define PHYID_AM79C874	0x0022561b
53
54enum {
55	MII_MCTRL	= 0x15,		/* mode control register */
56	MII_FX_SEL	= 0x0001,	/* 100BASE-FX (fiber) */
57	MII_EN_SCRM	= 0x0004,	/* enable scrambler (tp) */
58};
59
60
61
62/* values we might find in the silicon revision register */
63#define SRR_DP83815_C	0x0302
64#define SRR_DP83815_D	0x0403
65#define SRR_DP83816_A4	0x0504
66#define SRR_DP83816_A5	0x0505
67
68/* NATSEMI: Offsets to the device registers.
69 * Unlike software-only systems, device drivers interact with complex hardware.
70 * It's not useful to define symbolic names for every register bit in the
71 * device.
72 */
73enum register_offsets {
74    ChipCmd      = 0x00,
75    ChipConfig   = 0x04,
76    EECtrl       = 0x08,
77    PCIBusCfg    = 0x0C,
78    IntrStatus   = 0x10,
79    IntrMask     = 0x14,
80    IntrEnable   = 0x18,
81    TxRingPtr    = 0x20,
82    TxConfig     = 0x24,
83    RxRingPtr    = 0x30,
84    RxConfig     = 0x34,
85    ClkRun       = 0x3C,
86    WOLCmd       = 0x40,
87    PauseCmd     = 0x44,
88    RxFilterAddr = 0x48,
89    RxFilterData = 0x4C,
90    BootRomAddr  = 0x50,
91    BootRomData  = 0x54,
92    SiliconRev   = 0x58,
93    StatsCtrl    = 0x5C,
94    StatsData    = 0x60,
95    RxPktErrs    = 0x60,
96    RxMissed     = 0x68,
97    RxCRCErrs    = 0x64,
98    PCIPM        = 0x44,
99    PhyStatus    = 0xC0,
100    MIntrCtrl    = 0xC4,
101    MIntrStatus  = 0xC8,
102
103    /* These are from the spec, around page 78... on a separate table.
104     */
105    PGSEL        = 0xCC,
106    PMDCSR       = 0xE4,
107    TSTDAT       = 0xFC,
108    DSPCFG       = 0xF4,
109    SDCFG        = 0x8C,
110    BasicControl = 0x80,
111    BasicStatus  = 0x84
112
113};
114
115/* the values for the 'magic' registers above (PGSEL=1) */
116#define PMDCSR_VAL	0x189c	/* enable preferred adaptation circuitry */
117#define TSTDAT_VAL	0x0
118#define DSPCFG_VAL	0x5040
119#define SDCFG_VAL	0x008c	/* set voltage thresholds for Signal Detect */
120#define DSPCFG_LOCK	0x20	/* coefficient lock bit in DSPCFG */
121#define DSPCFG_COEF	0x1000	/* see coefficient (in TSTDAT) bit in DSPCFG */
122#define TSTDAT_FIXED	0xe8	/* magic number for bad coefficients */
123
124/* Bit in ChipCmd.
125 */
126enum ChipCmdBits {
127    ChipReset = 0x100,
128    RxReset   = 0x20,
129    TxReset   = 0x10,
130    RxOff     = 0x08,
131    RxOn      = 0x04,
132    TxOff     = 0x02,
133    TxOn      = 0x01
134};
135
136enum ChipConfig_bits {
137	CfgPhyDis		= 0x200,
138	CfgPhyRst		= 0x400,
139	CfgExtPhy		= 0x1000,
140	CfgAnegEnable		= 0x2000,
141	CfgAneg100		= 0x4000,
142	CfgAnegFull		= 0x8000,
143	CfgAnegDone		= 0x8000000,
144	CfgFullDuplex		= 0x20000000,
145	CfgSpeed100		= 0x40000000,
146	CfgLink			= 0x80000000,
147};
148
149
150/* Bits in the RxMode register.
151 */
152enum rx_mode_bits {
153    AcceptErr          = 0x20,
154    AcceptRunt         = 0x10,
155    AcceptBroadcast    = 0xC0000000,
156    AcceptMulticast    = 0x00200000,
157    AcceptAllMulticast = 0x20000000,
158    AcceptAllPhys      = 0x10000000,
159    AcceptMyPhys       = 0x08000000,
160    RxFilterEnable     = 0x80000000
161};
162
163/* Bits in network_desc.status
164 */
165enum desc_status_bits {
166    DescOwn   = 0x80000000,
167    DescMore  = 0x40000000,
168    DescIntr  = 0x20000000,
169    DescNoCRC = 0x10000000,
170    DescPktOK = 0x08000000,
171    RxTooLong = 0x00400000
172};
173
174/*Bits in Interrupt Mask register
175 */
176enum Intr_mask_register_bits {
177    RxOk       = 0x001,
178    RxErr      = 0x004,
179    TxOk       = 0x040,
180    TxErr      = 0x100
181};
182
183enum MIntrCtrl_bits {
184  MICRIntEn               = 0x2,
185};
186
187/* CFG bits [13:16] [18:23] */
188#define CFG_RESET_SAVE 0xfde000
189/* WCSR bits [0:4] [9:10] */
190#define WCSR_RESET_SAVE 0x61f
191/* RFCR bits [20] [22] [27:31] */
192#define RFCR_RESET_SAVE 0xf8500000;
193
194/* Delay between EEPROM clock transitions.
195   No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
196   a delay. */
197#define eeprom_delay(ee_addr)   inl(ee_addr)
198
199enum EEPROM_Ctrl_Bits {
200	EE_ShiftClk   = 0x04,
201	EE_DataIn     = 0x01,
202	EE_ChipSelect = 0x08,
203	EE_DataOut    = 0x02
204};
205
206#define EE_Write0 (EE_ChipSelect)
207#define EE_Write1 (EE_ChipSelect | EE_DataIn)
208
209/* The EEPROM commands include the alway-set leading bit. */
210enum EEPROM_Cmds {
211  EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
212};
213
214/*  EEPROM access , values are devices specific
215 */
216#define EE_CS		0x08	/* EEPROM chip select */
217#define EE_SK		0x04	/* EEPROM shift clock */
218#define EE_DI		0x01	/* Data in */
219#define EE_DO		0x02	/* Data out */
220
221/* Offsets within EEPROM (these are word offsets)
222 */
223#define EE_MAC 7
224#define EE_REG  EECtrl
225
226static const uint8_t natsemi_ee_bits[] = {
227	[SPI_BIT_SCLK]	= EE_SK,
228	[SPI_BIT_MOSI]	= EE_DI,
229	[SPI_BIT_MISO]	= EE_DO,
230	[SPI_BIT_SS(0)]	= EE_CS,
231};
232
233