]>
git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/net/cs8900.c
2 * Cirrus Logic CS8900A Ethernet
4 * (C) 2009 Ben Warren , biggerbadderben@gmail.com
5 * Converted to use CONFIG_NET_MULTI API
7 * (C) 2003 Wolfgang Denk, wd@denx.de
8 * Extension to synchronize ethaddr environment variable
9 * against value in EEPROM
12 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
13 * Marius Groeger <mgroeger@sysgo.de>
15 * Copyright (C) 1999 Ben Williamson <benw@pobox.com>
17 * This program is loaded into SRAM in bootstrap mode, where it waits
18 * for commands on UART1 to read and write memory, jump to code etc.
19 * A design goal for this program is to be entirely independent of the
20 * target board. Anything with a CL-PS7111 or EP7211 should be able to run
21 * this code in bootstrap mode. All the board specifics can be handled on
24 * SPDX-License-Identifier: GPL-2.0+
36 /* packet page register access functions */
38 #ifdef CONFIG_CS8900_BUS32
40 #define REG_WRITE(v, a) writel((v),(a))
41 #define REG_READ(a) readl((a))
43 /* we don't need 16 bit initialisation on 32 bit bus */
44 #define get_reg_init_bus(r,d) get_reg((r),(d))
48 #define REG_WRITE(v, a) writew((v),(a))
49 #define REG_READ(a) readw((a))
51 static u16
get_reg_init_bus(struct eth_device
*dev
, int regno
)
53 /* force 16 bit busmode */
54 struct cs8900_priv
*priv
= (struct cs8900_priv
*)(dev
->priv
);
55 uint8_t volatile * const iob
= (uint8_t volatile * const)dev
->iobase
;
63 REG_WRITE(regno
, &priv
->regs
->pptr
);
64 return REG_READ(&priv
->regs
->pdata
);
68 static u16
get_reg(struct eth_device
*dev
, int regno
)
70 struct cs8900_priv
*priv
= (struct cs8900_priv
*)(dev
->priv
);
71 REG_WRITE(regno
, &priv
->regs
->pptr
);
72 return REG_READ(&priv
->regs
->pdata
);
76 static void put_reg(struct eth_device
*dev
, int regno
, u16 val
)
78 struct cs8900_priv
*priv
= (struct cs8900_priv
*)(dev
->priv
);
79 REG_WRITE(regno
, &priv
->regs
->pptr
);
80 REG_WRITE(val
, &priv
->regs
->pdata
);
83 static void cs8900_reset(struct eth_device
*dev
)
89 put_reg(dev
, PP_SelfCTL
, get_reg(dev
, PP_SelfCTL
) | PP_SelfCTL_Reset
);
93 /* Wait until the chip is reset */
95 tmo
= get_timer(0) + 1 * CONFIG_SYS_HZ
;
96 while ((((us
= get_reg_init_bus(dev
, PP_SelfSTAT
)) &
97 PP_SelfSTAT_InitD
) == 0) && tmo
< get_timer(0))
101 static void cs8900_reginit(struct eth_device
*dev
)
103 /* receive only error free packets addressed to this card */
104 put_reg(dev
, PP_RxCTL
,
105 PP_RxCTL_IA
| PP_RxCTL_Broadcast
| PP_RxCTL_RxOK
);
106 /* do not generate any interrupts on receive operations */
107 put_reg(dev
, PP_RxCFG
, 0);
108 /* do not generate any interrupts on transmit operations */
109 put_reg(dev
, PP_TxCFG
, 0);
110 /* do not generate any interrupts on buffer operations */
111 put_reg(dev
, PP_BufCFG
, 0);
112 /* enable transmitter/receiver mode */
113 put_reg(dev
, PP_LineCTL
, PP_LineCTL_Rx
| PP_LineCTL_Tx
);
116 void cs8900_get_enetaddr(struct eth_device
*dev
)
121 if (get_reg_init_bus(dev
, PP_ChipID
) != 0x630e)
124 if ((get_reg(dev
, PP_SelfSTAT
) &
125 (PP_SelfSTAT_EEPROM
| PP_SelfSTAT_EEPROM_OK
)) ==
126 (PP_SelfSTAT_EEPROM
| PP_SelfSTAT_EEPROM_OK
)) {
128 /* Load the MAC from EEPROM */
129 for (i
= 0; i
< 3; i
++) {
132 Addr
= get_reg(dev
, PP_IA
+ i
* 2);
133 dev
->enetaddr
[i
* 2] = Addr
& 0xFF;
134 dev
->enetaddr
[i
* 2 + 1] = Addr
>> 8;
139 void cs8900_halt(struct eth_device
*dev
)
141 /* disable transmitter/receiver mode */
142 put_reg(dev
, PP_LineCTL
, 0);
144 /* "shutdown" to show ChipID or kernel wouldn't find he cs8900 ... */
145 get_reg_init_bus(dev
, PP_ChipID
);
148 static int cs8900_init(struct eth_device
*dev
, bd_t
* bd
)
150 uchar
*enetaddr
= dev
->enetaddr
;
154 id
= get_reg_init_bus(dev
, PP_ChipID
);
156 printf ("CS8900 Ethernet chip not found: "
157 "ID=0x%04x instead 0x%04x\n", id
, 0x630e);
162 /* set the ethernet address */
163 put_reg(dev
, PP_IA
+ 0, enetaddr
[0] | (enetaddr
[1] << 8));
164 put_reg(dev
, PP_IA
+ 2, enetaddr
[2] | (enetaddr
[3] << 8));
165 put_reg(dev
, PP_IA
+ 4, enetaddr
[4] | (enetaddr
[5] << 8));
171 /* Get a data block via Ethernet */
172 static int cs8900_recv(struct eth_device
*dev
)
179 struct cs8900_priv
*priv
= (struct cs8900_priv
*)(dev
->priv
);
181 status
= get_reg(dev
, PP_RER
);
183 if ((status
& PP_RER_RxOK
) == 0)
186 status
= REG_READ(&priv
->regs
->rtdata
);
187 rxlen
= REG_READ(&priv
->regs
->rtdata
);
189 if (rxlen
> PKTSIZE_ALIGN
+ PKTALIGN
)
190 debug("packet too big!\n");
191 for (addr
= (u16
*) NetRxPackets
[0], i
= rxlen
>> 1; i
> 0;
193 *addr
++ = REG_READ(&priv
->regs
->rtdata
);
195 *addr
++ = REG_READ(&priv
->regs
->rtdata
);
197 /* Pass the packet up to the protocol layers. */
198 NetReceive (NetRxPackets
[0], rxlen
);
202 /* Send a data block via Ethernet. */
203 static int cs8900_send(struct eth_device
*dev
, void *packet
, int length
)
208 struct cs8900_priv
*priv
= (struct cs8900_priv
*)(dev
->priv
);
211 /* initiate a transmit sequence */
212 REG_WRITE(PP_TxCmd_TxStart_Full
, &priv
->regs
->txcmd
);
213 REG_WRITE(length
, &priv
->regs
->txlen
);
215 /* Test to see if the chip has allocated memory for the packet */
216 if ((get_reg(dev
, PP_BusSTAT
) & PP_BusSTAT_TxRDY
) == 0) {
217 /* Oops... this should not happen! */
218 debug("cs: unable to send packet; retrying...\n");
219 for (tmo
= get_timer(0) + 5 * CONFIG_SYS_HZ
;
227 /* Write the contents of the packet */
228 /* assume even number of bytes */
229 for (addr
= packet
; length
> 0; length
-= 2)
230 REG_WRITE(*addr
++, &priv
->regs
->rtdata
);
232 /* wait for transfer to succeed */
233 tmo
= get_timer(0) + 5 * CONFIG_SYS_HZ
;
234 while ((s
= get_reg(dev
, PP_TER
) & ~0x1F) == 0) {
235 if (get_timer(0) >= tmo
)
240 if((s
& (PP_TER_CRS
| PP_TER_TxOK
)) != PP_TER_TxOK
) {
241 debug("\ntransmission error %#x\n", s
);
247 static void cs8900_e2prom_ready(struct eth_device
*dev
)
249 while (get_reg(dev
, PP_SelfSTAT
) & SI_BUSY
)
253 /***********************************************************/
254 /* read a 16-bit word out of the EEPROM */
255 /***********************************************************/
257 int cs8900_e2prom_read(struct eth_device
*dev
,
260 cs8900_e2prom_ready(dev
);
261 put_reg(dev
, PP_EECMD
, EEPROM_READ_CMD
| addr
);
262 cs8900_e2prom_ready(dev
);
263 *value
= get_reg(dev
, PP_EEData
);
269 /***********************************************************/
270 /* write a 16-bit word into the EEPROM */
271 /***********************************************************/
273 int cs8900_e2prom_write(struct eth_device
*dev
, u8 addr
, u16 value
)
275 cs8900_e2prom_ready(dev
);
276 put_reg(dev
, PP_EECMD
, EEPROM_WRITE_EN
);
277 cs8900_e2prom_ready(dev
);
278 put_reg(dev
, PP_EEData
, value
);
279 put_reg(dev
, PP_EECMD
, EEPROM_WRITE_CMD
| addr
);
280 cs8900_e2prom_ready(dev
);
281 put_reg(dev
, PP_EECMD
, EEPROM_WRITE_DIS
);
282 cs8900_e2prom_ready(dev
);
287 int cs8900_initialize(u8 dev_num
, int base_addr
)
289 struct eth_device
*dev
;
290 struct cs8900_priv
*priv
;
292 dev
= malloc(sizeof(*dev
));
296 memset(dev
, 0, sizeof(*dev
));
298 priv
= malloc(sizeof(*priv
));
303 memset(priv
, 0, sizeof(*priv
));
304 priv
->regs
= (struct cs8900_regs
*)base_addr
;
306 dev
->iobase
= base_addr
;
308 dev
->init
= cs8900_init
;
309 dev
->halt
= cs8900_halt
;
310 dev
->send
= cs8900_send
;
311 dev
->recv
= cs8900_recv
;
313 /* Load MAC address from EEPROM */
314 cs8900_get_enetaddr(dev
);
316 sprintf(dev
->name
, "%s-%hu", CS8900_DRIVERNAME
, dev_num
);