if_cs.c revision 1.1 1 1.1 igy /* $NetBSD: if_cs.c,v 1.1 2003/08/09 08:01:48 igy Exp $ */
2 1.1 igy
3 1.1 igy /*
4 1.1 igy * Copyright (c) 2003 Naoto Shimazaki.
5 1.1 igy * All rights reserved.
6 1.1 igy *
7 1.1 igy * Redistribution and use in source and binary forms, with or without
8 1.1 igy * modification, are permitted provided that the following conditions
9 1.1 igy * are met:
10 1.1 igy * 1. Redistributions of source code must retain the above copyright
11 1.1 igy * notice, this list of conditions and the following disclaimer.
12 1.1 igy * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 igy * notice, this list of conditions and the following disclaimer in the
14 1.1 igy * documentation and/or other materials provided with the distribution.
15 1.1 igy *
16 1.1 igy * THIS SOFTWARE IS PROVIDED BY NAOTO SHIMAZAKI AND CONTRIBUTORS ``AS IS''
17 1.1 igy * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 1.1 igy * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.1 igy * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE NAOTO OR CONTRIBUTORS BE
20 1.1 igy * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1 igy * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1 igy * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1 igy * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1 igy * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1 igy * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 1.1 igy * THE POSSIBILITY OF SUCH DAMAGE.
27 1.1 igy */
28 1.1 igy #include <sys/cdefs.h>
29 1.1 igy __KERNEL_RCSID(0, "$NetBSD: if_cs.c,v 1.1 2003/08/09 08:01:48 igy Exp $");
30 1.1 igy
31 1.1 igy #include <sys/param.h>
32 1.1 igy #include <netinet/in.h>
33 1.1 igy
34 1.1 igy #include <lib/libsa/stand.h>
35 1.1 igy #include <lib/libsa/netif.h>
36 1.1 igy
37 1.1 igy #include <dev/ic/cs89x0reg.h>
38 1.1 igy
39 1.1 igy #include "extern.h"
40 1.1 igy
41 1.1 igy static int cs_match(struct netif *, void *);
42 1.1 igy static int cs_probe(struct netif *, void *);
43 1.1 igy static void cs_init(struct iodesc *, void *);
44 1.1 igy static int cs_get(struct iodesc *, void *, size_t, time_t);
45 1.1 igy static int cs_put(struct iodesc *, void *, size_t);
46 1.1 igy static void cs_end(struct netif *);
47 1.1 igy
48 1.1 igy static struct netif_stats cs_stats;
49 1.1 igy
50 1.1 igy static struct netif_dif cs_if = {
51 1.1 igy .dif_unit = 0,
52 1.1 igy .dif_nsel = 1,
53 1.1 igy .dif_stats = &cs_stats,
54 1.1 igy .dif_private = NULL,
55 1.1 igy .dif_used = 0,
56 1.1 igy };
57 1.1 igy
58 1.1 igy struct netif_driver cs_driver = {
59 1.1 igy .netif_bname = "cs",
60 1.1 igy .netif_match = cs_match,
61 1.1 igy .netif_probe = cs_probe,
62 1.1 igy .netif_init = cs_init,
63 1.1 igy .netif_get = cs_get,
64 1.1 igy .netif_put = cs_put,
65 1.1 igy .netif_end = cs_end,
66 1.1 igy .netif_ifs = &cs_if,
67 1.1 igy .netif_nifs = 1,
68 1.1 igy };
69 1.1 igy
70 1.1 igy #define CS_IO_BASE 0x14010300U
71 1.1 igy
72 1.1 igy #define CS_READ_1(off) REGREAD_1(CS_IO_BASE, (off))
73 1.1 igy #define CS_READ_2(off) REGREAD_2(CS_IO_BASE, (off))
74 1.1 igy #define CS_WRITE_1(off, val) REGWRITE_1(CS_IO_BASE, (off), (val))
75 1.1 igy #define CS_WRITE_2(off, val) REGWRITE_2(CS_IO_BASE, (off), (val))
76 1.1 igy #define CS_READ_PACKET_PAGE(off) \
77 1.1 igy (REGWRITE_2(CS_IO_BASE, PORT_PKTPG_PTR, (off)), \
78 1.1 igy REGREAD_2(CS_IO_BASE, PORT_PKTPG_DATA))
79 1.1 igy #define CS_WRITE_PACKET_PAGE(off, val) \
80 1.1 igy (REGWRITE_2(CS_IO_BASE, PORT_PKTPG_PTR, (off)), \
81 1.1 igy REGWRITE_2(CS_IO_BASE, PORT_PKTPG_DATA, (val)))
82 1.1 igy
83 1.1 igy static inline void
84 1.1 igy delay(int n)
85 1.1 igy {
86 1.1 igy int i = 33 * n;
87 1.1 igy
88 1.1 igy while (--i > 0)
89 1.1 igy ;
90 1.1 igy }
91 1.1 igy
92 1.1 igy time_t
93 1.1 igy getsecs(void)
94 1.1 igy {
95 1.1 igy return REGREAD_4(VRETIMEL, 0) >> 15;
96 1.1 igy }
97 1.1 igy
98 1.1 igy static int
99 1.1 igy cs_match(struct netif *nif, void *machdep_hint)
100 1.1 igy {
101 1.1 igy return 1;
102 1.1 igy }
103 1.1 igy
104 1.1 igy static int
105 1.1 igy cs_probe(struct netif *nif, void *machdep_hint)
106 1.1 igy {
107 1.1 igy return 0;
108 1.1 igy }
109 1.1 igy
110 1.1 igy static void
111 1.1 igy cs_init(struct iodesc *desc, void *machdep_hint)
112 1.1 igy {
113 1.1 igy int i;
114 1.1 igy
115 1.1 igy /* Issue a software reset command to the chip */
116 1.1 igy CS_WRITE_PACKET_PAGE(PKTPG_SELF_CTL, SELF_CTL_RESET);
117 1.1 igy
118 1.1 igy /* We cannot touch the chip until calibration is done */
119 1.1 igy delay(10000);
120 1.1 igy
121 1.1 igy /*
122 1.1 igy * Transition -SBHE H->L L->H is needed between reset and
123 1.1 igy * the first access to the chip's register.
124 1.1 igy */
125 1.1 igy CS_READ_1(PORT_PKTPG_PTR + 0);
126 1.1 igy CS_READ_1(PORT_PKTPG_PTR + 1);
127 1.1 igy CS_READ_1(PORT_PKTPG_PTR + 0);
128 1.1 igy CS_READ_1(PORT_PKTPG_PTR + 1);
129 1.1 igy
130 1.1 igy /* wait for INIT_DONE */
131 1.1 igy for (i = 10000; i > 0; i--) {
132 1.1 igy u_int16_t s;
133 1.1 igy
134 1.1 igy s = CS_READ_PACKET_PAGE(PKTPG_SELF_ST);
135 1.1 igy if ((s & SELF_ST_INIT_DONE) && !(s & SELF_ST_SI_BUSY))
136 1.1 igy break;
137 1.1 igy }
138 1.1 igy
139 1.1 igy if (i == 0)
140 1.1 igy panic("cannot reset netif");
141 1.1 igy
142 1.1 igy for (i = 0; i < 6; i += 2) {
143 1.1 igy u_int16_t ea;
144 1.1 igy
145 1.1 igy ea = CS_READ_PACKET_PAGE(PKTPG_IND_ADDR + i);
146 1.1 igy
147 1.1 igy /* assuming little endian */
148 1.1 igy desc->myea[i + 0] = (ea >> 0) & 0xff;
149 1.1 igy desc->myea[i + 1] = (ea >> 8) & 0xff;
150 1.1 igy }
151 1.1 igy
152 1.1 igy /*
153 1.1 igy * Accepting frames:
154 1.1 igy * RX_CTL_RX_OK_A: correct crc, and valid length
155 1.1 igy * RX_CTL_IND_A: dest addr maches individual address
156 1.1 igy * RX_CTL_BCAST_A: dest addr maches broadcast address
157 1.1 igy */
158 1.1 igy CS_WRITE_PACKET_PAGE(PKTPG_RX_CTL,
159 1.1 igy RX_CTL_RX_OK_A | RX_CTL_IND_A | RX_CTL_BCAST_A);
160 1.1 igy CS_WRITE_PACKET_PAGE(PKTPG_LINE_CTL, LINE_CTL_RX_ON | LINE_CTL_TX_ON);
161 1.1 igy }
162 1.1 igy
163 1.1 igy static int
164 1.1 igy cs_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout)
165 1.1 igy {
166 1.1 igy time_t t;
167 1.1 igy int rlen;
168 1.1 igy int i;
169 1.1 igy u_int16_t *p;
170 1.1 igy
171 1.1 igy t = getsecs();
172 1.1 igy rlen = 0;
173 1.1 igy while (getsecs() - t < timeout && rlen == 0) {
174 1.1 igy if (!(CS_READ_PACKET_PAGE(PKTPG_RX_EVENT) & RX_EVENT_RX_OK))
175 1.1 igy continue;
176 1.1 igy
177 1.1 igy /* drop status */
178 1.1 igy CS_READ_2(PORT_RXTX_DATA);
179 1.1 igy
180 1.1 igy /* get frame length */
181 1.1 igy rlen = CS_READ_2(PORT_RXTX_DATA);
182 1.1 igy
183 1.1 igy if (rlen > len) {
184 1.1 igy CS_WRITE_PACKET_PAGE(PKTPG_RX_CFG, RX_CFG_SKIP);
185 1.1 igy rlen = 0;
186 1.1 igy continue;
187 1.1 igy }
188 1.1 igy
189 1.1 igy p = pkt;
190 1.1 igy for (i = rlen >> 1; i > 0; i--)
191 1.1 igy *p++ = CS_READ_2(PORT_RXTX_DATA);
192 1.1 igy if (rlen & 1)
193 1.1 igy *((u_int8_t *) p + 1) = CS_READ_1(PORT_RXTX_DATA);
194 1.1 igy
195 1.1 igy /* exit while loop */
196 1.1 igy }
197 1.1 igy
198 1.1 igy return rlen;
199 1.1 igy }
200 1.1 igy
201 1.1 igy static int
202 1.1 igy cs_put(struct iodesc *desc, void *pkt, size_t len)
203 1.1 igy {
204 1.1 igy int timeo;
205 1.1 igy int i;
206 1.1 igy u_int16_t *p;
207 1.1 igy
208 1.1 igy CS_WRITE_2(PORT_TX_CMD, TX_CMD_START_ALL);
209 1.1 igy CS_WRITE_2(PORT_TX_LENGTH, len);
210 1.1 igy
211 1.1 igy for (timeo = 1000000; timeo > 0; timeo--) {
212 1.1 igy if (CS_READ_PACKET_PAGE(PKTPG_BUS_ST) & BUS_ST_RDY4TXNOW)
213 1.1 igy break;
214 1.1 igy }
215 1.1 igy if (timeo == 0)
216 1.1 igy panic("cs: cannot send frame");
217 1.1 igy
218 1.1 igy p = pkt;
219 1.1 igy i = (len + 1) >> 1;
220 1.1 igy while (i > 0) {
221 1.1 igy CS_WRITE_2(PORT_RXTX_DATA, *p++);
222 1.1 igy i--;
223 1.1 igy }
224 1.1 igy
225 1.1 igy return len;
226 1.1 igy }
227 1.1 igy
228 1.1 igy static void
229 1.1 igy cs_end(struct netif *nif)
230 1.1 igy {
231 1.1 igy CS_WRITE_PACKET_PAGE(PKTPG_LINE_CTL, 0);
232 1.1 igy }
233