1 /* $NetBSD: if_cs.c,v 1.2.4.3 2004/09/21 13:16:12 skrll Exp $ */
4 * Copyright (c) 2003 Naoto Shimazaki.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY NAOTO SHIMAZAKI AND CONTRIBUTORS ``AS IS''
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE NAOTO OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 * THE POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: if_cs.c,v 1.2.4.3 2004/09/21 13:16:12 skrll Exp $");
31 #include <sys/param.h>
32 #include <netinet/in.h>
34 #include <lib/libsa/stand.h>
35 #include <lib/libsa/netif.h>
37 #include <dev/ic/cs89x0reg.h>
41 static int cs_match(struct netif
*, void *);
42 static int cs_probe(struct netif
*, void *);
43 static void cs_init(struct iodesc
*, void *);
44 static int cs_get(struct iodesc
*, void *, size_t, time_t);
45 static int cs_put(struct iodesc
*, void *, size_t);
46 static void cs_end(struct netif
*);
48 static struct netif_stats cs_stats
;
50 static struct netif_dif cs_if
= {
53 .dif_stats
= &cs_stats
,
58 struct netif_driver cs_driver
= {
60 .netif_match
= cs_match
,
61 .netif_probe
= cs_probe
,
62 .netif_init
= cs_init
,
70 #define CS_IO_BASE 0x14010300U
72 #define CS_READ_1(off) REGREAD_1(CS_IO_BASE, (off))
73 #define CS_READ_2(off) REGREAD_2(CS_IO_BASE, (off))
74 #define CS_WRITE_1(off, val) REGWRITE_1(CS_IO_BASE, (off), (val))
75 #define CS_WRITE_2(off, val) REGWRITE_2(CS_IO_BASE, (off), (val))
76 #define CS_READ_PACKET_PAGE(off) \
77 (REGWRITE_2(CS_IO_BASE, PORT_PKTPG_PTR, (off)), \
78 REGREAD_2(CS_IO_BASE, PORT_PKTPG_DATA))
79 #define CS_WRITE_PACKET_PAGE(off, val) \
80 (REGWRITE_2(CS_IO_BASE, PORT_PKTPG_PTR, (off)), \
81 REGWRITE_2(CS_IO_BASE, PORT_PKTPG_DATA, (val)))
95 return REGREAD_4(VRETIMEL
, 0) >> 15;
99 cs_match(struct netif
*nif
, void *machdep_hint
)
105 cs_probe(struct netif
*nif
, void *machdep_hint
)
111 cs_get_eeprom(int offset
, u_int16_t
*result
)
115 for (timeo
= MAXLOOP
; timeo
> 0; timeo
--) {
116 if (!(CS_READ_PACKET_PAGE(PKTPG_SELF_ST
)
123 CS_WRITE_PACKET_PAGE(PKTPG_EEPROM_CMD
, offset
| EEPROM_CMD_READ
);
125 for (timeo
= MAXLOOP
; timeo
> 0; timeo
--) {
126 if (!(CS_READ_PACKET_PAGE(PKTPG_SELF_ST
)
133 *result
= CS_READ_PACKET_PAGE(PKTPG_EEPROM_DATA
);
138 panic("cannot read mac addr");
142 cs_init(struct iodesc
*desc
, void *machdep_hint
)
147 /* Issue a software reset command to the chip */
148 CS_WRITE_PACKET_PAGE(PKTPG_SELF_CTL
, SELF_CTL_RESET
);
150 /* We cannot touch the chip until calibration is done */
154 * Transition -SBHE H->L L->H is needed between reset and
155 * the first access to the chip's register.
157 CS_READ_1(PORT_PKTPG_PTR
+ 0);
158 CS_READ_1(PORT_PKTPG_PTR
+ 1);
159 CS_READ_1(PORT_PKTPG_PTR
+ 0);
160 CS_READ_1(PORT_PKTPG_PTR
+ 1);
162 /* wait for INIT_DONE */
163 for (i
= 10000; i
> 0; i
--) {
166 s
= CS_READ_PACKET_PAGE(PKTPG_SELF_ST
);
167 if ((s
& SELF_ST_INIT_DONE
) && !(s
& SELF_ST_SI_BUSY
))
171 panic("cannot reset netif");
173 myea
= (u_int16_t
*) desc
->myea
;
175 cs_get_eeprom(EEPROM_IND_ADDR_H
, &myea
[0]);
176 cs_get_eeprom(EEPROM_IND_ADDR_M
, &myea
[1]);
177 cs_get_eeprom(EEPROM_IND_ADDR_L
, &myea
[2]);
179 for (i
= 0; i
< 3; i
++)
180 CS_WRITE_PACKET_PAGE(PKTPG_IND_ADDR
+ (i
<< 1), myea
[i
]);
184 * RX_CTL_RX_OK_A: correct crc, and valid length
185 * RX_CTL_IND_A: dest addr maches individual address
186 * RX_CTL_BCAST_A: dest addr maches broadcast address
188 CS_WRITE_PACKET_PAGE(PKTPG_RX_CTL
,
189 RX_CTL_RX_OK_A
| RX_CTL_IND_A
| RX_CTL_BCAST_A
);
190 CS_WRITE_PACKET_PAGE(PKTPG_LINE_CTL
, LINE_CTL_RX_ON
| LINE_CTL_TX_ON
);
194 cs_get(struct iodesc
*desc
, void *pkt
, size_t len
, time_t timeout
)
203 while (getsecs() - t
< timeout
&& rlen
== 0) {
204 if (!(CS_READ_PACKET_PAGE(PKTPG_RX_EVENT
) & RX_EVENT_RX_OK
))
208 CS_READ_2(PORT_RXTX_DATA
);
210 /* get frame length */
211 rlen
= CS_READ_2(PORT_RXTX_DATA
);
214 CS_WRITE_PACKET_PAGE(PKTPG_RX_CFG
, RX_CFG_SKIP
);
220 for (i
= rlen
>> 1; i
> 0; i
--)
221 *p
++ = CS_READ_2(PORT_RXTX_DATA
);
223 *((u_int8_t
*) p
+ 1) = CS_READ_1(PORT_RXTX_DATA
);
225 /* exit while loop */
232 cs_put(struct iodesc
*desc
, void *pkt
, size_t len
)
238 CS_WRITE_2(PORT_TX_CMD
, TX_CMD_START_ALL
);
239 CS_WRITE_2(PORT_TX_LENGTH
, len
);
241 for (timeo
= 1000000; timeo
> 0; timeo
--) {
242 if (CS_READ_PACKET_PAGE(PKTPG_BUS_ST
) & BUS_ST_RDY4TXNOW
)
246 panic("cs: cannot send frame");
251 CS_WRITE_2(PORT_RXTX_DATA
, *p
++);
259 cs_end(struct netif
*nif
)
261 CS_WRITE_PACKET_PAGE(PKTPG_LINE_CTL
, 0);