tlp.c revision 1.3.14.2 1 1.3.14.2 ad /* $NetBSD: tlp.c,v 1.3.14.2 2007/12/03 19:03:11 ad Exp $ */
2 1.3.14.2 ad
3 1.3.14.2 ad /*-
4 1.3.14.2 ad * Copyright (c) 2007 The NetBSD Foundation, Inc.
5 1.3.14.2 ad * All rights reserved.
6 1.3.14.2 ad *
7 1.3.14.2 ad * This code is derived from software contributed to The NetBSD Foundation
8 1.3.14.2 ad * by Tohru Nishimura.
9 1.3.14.2 ad *
10 1.3.14.2 ad * Redistribution and use in source and binary forms, with or without
11 1.3.14.2 ad * modification, are permitted provided that the following conditions
12 1.3.14.2 ad * are met:
13 1.3.14.2 ad * 1. Redistributions of source code must retain the above copyright
14 1.3.14.2 ad * notice, this list of conditions and the following disclaimer.
15 1.3.14.2 ad * 2. Redistributions in binary form must reproduce the above copyright
16 1.3.14.2 ad * notice, this list of conditions and the following disclaimer in the
17 1.3.14.2 ad * documentation and/or other materials provided with the distribution.
18 1.3.14.2 ad * 3. All advertising materials mentioning features or use of this software
19 1.3.14.2 ad * must display the following acknowledgement:
20 1.3.14.2 ad * This product includes software developed by the NetBSD
21 1.3.14.2 ad * Foundation, Inc. and its contributors.
22 1.3.14.2 ad * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.3.14.2 ad * contributors may be used to endorse or promote products derived
24 1.3.14.2 ad * from this software without specific prior written permission.
25 1.3.14.2 ad *
26 1.3.14.2 ad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.3.14.2 ad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.3.14.2 ad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.3.14.2 ad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.3.14.2 ad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.3.14.2 ad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.3.14.2 ad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.3.14.2 ad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.3.14.2 ad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.3.14.2 ad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.3.14.2 ad * POSSIBILITY OF SUCH DAMAGE.
37 1.3.14.2 ad */
38 1.3.14.2 ad
39 1.3.14.2 ad #include <sys/param.h>
40 1.3.14.2 ad #include <sys/socket.h>
41 1.3.14.2 ad
42 1.3.14.2 ad #include <netinet/in.h>
43 1.3.14.2 ad #include <netinet/in_systm.h>
44 1.3.14.2 ad
45 1.3.14.2 ad #include <lib/libsa/stand.h>
46 1.3.14.2 ad #include <lib/libsa/net.h>
47 1.3.14.2 ad
48 1.3.14.2 ad #include <mips/cpuregs.h>
49 1.3.14.2 ad
50 1.3.14.2 ad #include "boot.h"
51 1.3.14.2 ad
52 1.3.14.2 ad /*
53 1.3.14.2 ad * - little endian access for CSR register.
54 1.3.14.2 ad * - assume KSEG0 on vtophys() translation.
55 1.3.14.2 ad * - PIPT writeback cache aware.
56 1.3.14.2 ad */
57 1.3.14.2 ad #define CSR_WRITE(l, r, v) \
58 1.3.14.2 ad do { \
59 1.3.14.2 ad *(volatile uint32_t *)((l)->csr + (r)) = (v); \
60 1.3.14.2 ad } while (0)
61 1.3.14.2 ad #define CSR_READ(l, r) (*(volatile uint32_t *)((l)->csr + (r)))
62 1.3.14.2 ad #define VTOPHYS(va) MIPS_KSEG0_TO_PHYS(va)
63 1.3.14.2 ad #define wb(adr, siz) pdcache_wb((uint32_t)(adr), (u_int)(siz))
64 1.3.14.2 ad #define wbinv(adr, siz) pdcache_wbinv((uint32_t)(adr), (u_int)(siz))
65 1.3.14.2 ad #define inv(adr, siz) pdcache_inv((uint32_t)(adr), (u_int)(siz))
66 1.3.14.2 ad #define DELAY(n) delay(n)
67 1.3.14.2 ad #define ALLOC(T, A) (T *)((uint32_t)alloc(sizeof(T) + (A)) & ~((A) - 1))
68 1.3.14.2 ad
69 1.3.14.2 ad #define T0_OWN (1U<<31) /* desc is ready to tx */
70 1.3.14.2 ad #define T0_ES (1U<<15) /* Tx error summary */
71 1.3.14.2 ad #define T1_LS (1U<<30) /* last segment */
72 1.3.14.2 ad #define T1_FS (1U<<29) /* first segment */
73 1.3.14.2 ad #define T1_SET (1U<<27) /* "setup packet" */
74 1.3.14.2 ad #define T1_TER (1U<<25) /* end of ring mark */
75 1.3.14.2 ad #define T1_TBS_MASK 0x7ff /* segment size 10:0 */
76 1.3.14.2 ad #define R0_OWN (1U<<31) /* desc is empty */
77 1.3.14.2 ad #define R0_FS (1U<<30) /* first desc of frame */
78 1.3.14.2 ad #define R0_LS (1U<<8) /* last desc of frame */
79 1.3.14.2 ad #define R0_ES (1U<<15) /* Rx error summary */
80 1.3.14.2 ad #define R1_RCH (1U<<24) /* Second address chained */
81 1.3.14.2 ad #define R1_RER (1U<<25) /* end of ring mark */
82 1.3.14.2 ad #define R0_FL_MASK 0x3fff0000 /* frame length 29:16 */
83 1.3.14.2 ad #define R1_RBS_MASK 0x7ff /* segment size 10:0 */
84 1.3.14.2 ad
85 1.3.14.2 ad #define DESCSIZE 16
86 1.3.14.2 ad struct desc {
87 1.3.14.2 ad volatile uint32_t xd0, xd1, xd2, xd3;
88 1.3.14.2 ad #if CACHELINESIZE > DESCSIZE
89 1.3.14.2 ad uint8_t pad[CACHELINESIZE - DESCSIZE];
90 1.3.14.2 ad #endif
91 1.3.14.2 ad };
92 1.3.14.2 ad
93 1.3.14.2 ad #define TLP_BMR 0x000 /* 0: bus mode */
94 1.3.14.2 ad #define BMR_RST (1U<< 0) /* software reset */
95 1.3.14.2 ad #define TLP_TPD 0x008 /* 1: instruct Tx to start */
96 1.3.14.2 ad #define TPD_POLL (1U<< 0) /* transmit poll demand */
97 1.3.14.2 ad #define TLP_RPD 0x010 /* 2: instruct Rx to start */
98 1.3.14.2 ad #define RPD_POLL (1U<< 0) /* receive poll demand */
99 1.3.14.2 ad #define TLP_RRBA 0x018 /* 3: Rx descriptor base */
100 1.3.14.2 ad #define TLP_TRBA 0x020 /* 4: Tx descriptor base */
101 1.3.14.2 ad #define TLP_STS 0x028 /* 5: status */
102 1.3.14.2 ad #define STS_TS 0x00700000 /* Tx status */
103 1.3.14.2 ad #define STS_RS 0x000e0000 /* Rx status */
104 1.3.14.2 ad #define TLP_OMR 0x030 /* 6: operation mode */
105 1.3.14.2 ad #define OMR_SDP (1U<<25) /* always ON */
106 1.3.14.2 ad #define OMR_PS (1U<<18) /* port select */
107 1.3.14.2 ad #define OMR_PM (1U<< 6) /* promicuous */
108 1.3.14.2 ad #define OMR_TEN (1U<<13) /* instruct start/stop Tx */
109 1.3.14.2 ad #define OMR_REN (1U<< 1) /* instruct start/stop Rx */
110 1.3.14.2 ad #define OMR_FD (1U<< 9) /* FDX */
111 1.3.14.2 ad #define TLP_IEN 0x38 /* 7: interrupt enable mask */
112 1.3.14.2 ad #define TLP_APROM 0x048 /* 9: SEEPROM and MII management */
113 1.3.14.2 ad #define SROM_RD (1U <<14) /* read operation */
114 1.3.14.2 ad #define SROM_WR (1U <<13) /* write openration */
115 1.3.14.2 ad #define SROM_SR (1U <<11) /* SEEPROM select */
116 1.3.14.2 ad #define TLP_CSR12 0x60 /* SIA status */
117 1.3.14.2 ad
118 1.3.14.2 ad #define TLP_CSR15 0x78 /* SIA general register */
119 1.3.14.2 ad #define SIAGEN_MD0 (1U<<16)
120 1.3.14.2 ad #define SIAGEN_CWE (1U<<28)
121 1.3.14.2 ad
122 1.3.14.2 ad #define FRAMESIZE 1536
123 1.3.14.2 ad #define BUFSIZE 2048
124 1.3.14.2 ad #define NRXBUF 2
125 1.3.14.2 ad #define NEXT_RXBUF(x) (((x) + 1) & (NRXBUF - 1))
126 1.3.14.2 ad
127 1.3.14.2 ad struct local {
128 1.3.14.2 ad struct desc TxD;
129 1.3.14.2 ad struct desc RxD[NRXBUF];
130 1.3.14.2 ad uint8_t txstore[BUFSIZE];
131 1.3.14.2 ad uint8_t rxstore[NRXBUF][BUFSIZE];
132 1.3.14.2 ad uint32_t csr, omr;
133 1.3.14.2 ad u_int rx;
134 1.3.14.2 ad u_int sromsft;
135 1.3.14.2 ad u_int phy;
136 1.3.14.2 ad uint32_t bmsr, anlpar;
137 1.3.14.2 ad };
138 1.3.14.2 ad
139 1.3.14.2 ad #define COBALT_TLP0_BASE 0x10100000
140 1.3.14.2 ad #define SROM_MAC_OFFSET 0
141 1.3.14.2 ad
142 1.3.14.2 ad static void size_srom(struct local *);
143 1.3.14.2 ad static u_int read_srom(struct local *, int);
144 1.3.14.2 ad #if 0
145 1.3.14.2 ad static u_int tlp_mii_read(struct local *, int, int);
146 1.3.14.2 ad static void tlp_mii_write(struct local *, int, int, int);
147 1.3.14.2 ad static void mii_initphy(struct local *);
148 1.3.14.2 ad #endif
149 1.3.14.2 ad
150 1.3.14.2 ad void *
151 1.3.14.2 ad tlp_init(void *cookie)
152 1.3.14.2 ad {
153 1.3.14.2 ad uint32_t val;
154 1.3.14.2 ad struct local *l;
155 1.3.14.2 ad struct desc *TxD, *RxD;
156 1.3.14.2 ad uint8_t *en;
157 1.3.14.2 ad int i;
158 1.3.14.2 ad
159 1.3.14.2 ad l = ALLOC(struct local, CACHELINESIZE);
160 1.3.14.2 ad memset(l, 0, sizeof(struct local));
161 1.3.14.2 ad
162 1.3.14.2 ad DPRINTF(("tlp: l = %p, TxD = %p, RxD[0] = %p, RxD[1] = %p\n",
163 1.3.14.2 ad l, &l->TxD, &l->RxD[0], &l->RxD[1]));
164 1.3.14.2 ad DPRINTF(("tlp: txstore = %p, rxstore[0] = %p, rxstore[1] = %p\n",
165 1.3.14.2 ad l->txstore, l->rxstore[0], l->rxstore[1]));
166 1.3.14.2 ad
167 1.3.14.2 ad #if 0
168 1.3.14.2 ad /* XXX assume tlp0 at pci0 dev 7 function 0 */
169 1.3.14.2 ad tag = (0 << 16) | ( 7 << 11) | (0 << 8);
170 1.3.14.2 ad /* memory map is not initialized by the firmware on cobalt */
171 1.3.14.2 ad l->csr = MIPS_PHYS_TO_KSEG1(pcicfgread(tag, 0x10) & 0xfffffffc);
172 1.3.14.2 ad DPRINTF(("%s: CSR = 0x%x\n", __func__, l->csr));
173 1.3.14.2 ad #else
174 1.3.14.2 ad l->csr = MIPS_PHYS_TO_KSEG1(COBALT_TLP0_BASE);
175 1.3.14.2 ad #endif
176 1.3.14.2 ad
177 1.3.14.2 ad val = CSR_READ(l, TLP_BMR);
178 1.3.14.2 ad CSR_WRITE(l, TLP_BMR, val | BMR_RST);
179 1.3.14.2 ad DELAY(1000);
180 1.3.14.2 ad CSR_WRITE(l, TLP_BMR, val);
181 1.3.14.2 ad DELAY(1000);
182 1.3.14.2 ad (void)CSR_READ(l, TLP_BMR);
183 1.3.14.2 ad
184 1.3.14.2 ad l->omr = OMR_PS | OMR_SDP;
185 1.3.14.2 ad CSR_WRITE(l, TLP_OMR, l->omr);
186 1.3.14.2 ad CSR_WRITE(l, TLP_STS, ~0);
187 1.3.14.2 ad CSR_WRITE(l, TLP_IEN, 0);
188 1.3.14.2 ad
189 1.3.14.2 ad #if 0
190 1.3.14.2 ad mii_initphy(l);
191 1.3.14.2 ad #endif
192 1.3.14.2 ad size_srom(l);
193 1.3.14.2 ad
194 1.3.14.2 ad en = cookie;
195 1.3.14.2 ad /* MAC address is stored at offset 0 in SROM on cobalt */
196 1.3.14.2 ad val = read_srom(l, SROM_MAC_OFFSET / 2 + 0);
197 1.3.14.2 ad en[0] = val;
198 1.3.14.2 ad en[1] = val >> 8;
199 1.3.14.2 ad val = read_srom(l, SROM_MAC_OFFSET / 2 + 1);
200 1.3.14.2 ad en[2] = val;
201 1.3.14.2 ad en[3] = val >> 8;
202 1.3.14.2 ad val = read_srom(l, SROM_MAC_OFFSET / 2 + 2);
203 1.3.14.2 ad en[4] = val;
204 1.3.14.2 ad en[5] = val >> 8;
205 1.3.14.2 ad
206 1.3.14.2 ad DPRINTF(("tlp: MAC address %x:%x:%x:%x:%x:%x\n",
207 1.3.14.2 ad en[0], en[1], en[2], en[3], en[4], en[5]));
208 1.3.14.2 ad
209 1.3.14.2 ad RxD = &l->RxD[0];
210 1.3.14.2 ad for (i = 0; i < NRXBUF; i++) {
211 1.3.14.2 ad RxD[i].xd3 = htole32(VTOPHYS(&RxD[NEXT_RXBUF(i)]));
212 1.3.14.2 ad RxD[i].xd2 = htole32(VTOPHYS(l->rxstore[i]));
213 1.3.14.2 ad RxD[i].xd1 = htole32(R1_RCH|FRAMESIZE);
214 1.3.14.2 ad RxD[i].xd0 = htole32(R0_OWN);
215 1.3.14.2 ad }
216 1.3.14.2 ad CSR_WRITE(l, TLP_RRBA, VTOPHYS(RxD));
217 1.3.14.2 ad
218 1.3.14.2 ad /* "setup packet" to have own station address */
219 1.3.14.2 ad TxD = &l->TxD;
220 1.3.14.2 ad TxD->xd3 = htole32(VTOPHYS(TxD));
221 1.3.14.2 ad TxD->xd2 = htole32(VTOPHYS(l->txstore));
222 1.3.14.2 ad TxD->xd1 = htole32(T1_SET | T1_TER);
223 1.3.14.2 ad TxD->xd0 = htole32(0);
224 1.3.14.2 ad CSR_WRITE(l, TLP_TRBA, VTOPHYS(TxD));
225 1.3.14.2 ad
226 1.3.14.2 ad memset(l->txstore, 0, FRAMESIZE);
227 1.3.14.2 ad
228 1.3.14.2 ad /* make sure the entire descriptors transfered to memory */
229 1.3.14.2 ad wbinv(l, sizeof(struct local));
230 1.3.14.2 ad
231 1.3.14.2 ad l->rx = 0;
232 1.3.14.2 ad l->omr |= OMR_FD | OMR_TEN | OMR_REN;
233 1.3.14.2 ad
234 1.3.14.2 ad #if 1
235 1.3.14.2 ad /* reset PHY (cobalt quirk from if_tlp_pci.c) */
236 1.3.14.2 ad CSR_WRITE(l, TLP_CSR15, SIAGEN_CWE | SIAGEN_MD0);
237 1.3.14.2 ad DELAY(10);
238 1.3.14.2 ad CSR_WRITE(l, TLP_CSR15, SIAGEN_CWE);
239 1.3.14.2 ad DELAY(10);
240 1.3.14.2 ad #endif
241 1.3.14.2 ad
242 1.3.14.2 ad /* start Tx/Rx */
243 1.3.14.2 ad CSR_WRITE(l, TLP_OMR, l->omr);
244 1.3.14.2 ad #if 0
245 1.3.14.2 ad CSR_WRITE(l, TLP_TPD, TPD_POLL);
246 1.3.14.2 ad #endif
247 1.3.14.2 ad CSR_WRITE(l, TLP_RPD, RPD_POLL);
248 1.3.14.2 ad
249 1.3.14.2 ad return l;
250 1.3.14.2 ad }
251 1.3.14.2 ad
252 1.3.14.2 ad int
253 1.3.14.2 ad tlp_send(void *dev, char *buf, u_int len)
254 1.3.14.2 ad {
255 1.3.14.2 ad struct local *l = dev;
256 1.3.14.2 ad struct desc *TxD;
257 1.3.14.2 ad u_int loop;
258 1.3.14.2 ad
259 1.3.14.2 ad #if 1
260 1.3.14.2 ad wb(buf, len);
261 1.3.14.2 ad TxD = &l->TxD;
262 1.3.14.2 ad TxD->xd3 = htole32(VTOPHYS(TxD));
263 1.3.14.2 ad TxD->xd2 = htole32(VTOPHYS(buf));
264 1.3.14.2 ad TxD->xd1 = htole32(T1_FS | T1_LS | T1_TER | (len & T1_TBS_MASK));
265 1.3.14.2 ad #else
266 1.3.14.2 ad memcpy(l->txstore, buf, len);
267 1.3.14.2 ad wb(l->txstore, len);
268 1.3.14.2 ad TxD = &l->TxD;
269 1.3.14.2 ad TxD->xd3 = htole32(VTOPHYS(TxD));
270 1.3.14.2 ad TxD->xd2 = htole32(VTOPHYS(l->txstore));
271 1.3.14.2 ad TxD->xd1 = htole32(T1_FS | T1_LS | T1_TER | (len & T1_TBS_MASK));
272 1.3.14.2 ad #endif
273 1.3.14.2 ad TxD->xd0 = htole32(T0_OWN);
274 1.3.14.2 ad wbinv(TxD, sizeof(struct desc));
275 1.3.14.2 ad CSR_WRITE(l, TLP_TPD, TPD_POLL);
276 1.3.14.2 ad loop = 100;
277 1.3.14.2 ad do {
278 1.3.14.2 ad if ((le32toh(TxD->xd0) & T0_OWN) == 0)
279 1.3.14.2 ad goto done;
280 1.3.14.2 ad inv(TxD, sizeof(struct desc));
281 1.3.14.2 ad DELAY(10);
282 1.3.14.2 ad } while (--loop > 0);
283 1.3.14.2 ad printf("xmit failed\n");
284 1.3.14.2 ad return -1;
285 1.3.14.2 ad done:
286 1.3.14.2 ad return len;
287 1.3.14.2 ad }
288 1.3.14.2 ad
289 1.3.14.2 ad int
290 1.3.14.2 ad tlp_recv(void *dev, char *buf, u_int maxlen, u_int timo)
291 1.3.14.2 ad {
292 1.3.14.2 ad struct local *l = dev;
293 1.3.14.2 ad struct desc *RxD;
294 1.3.14.2 ad u_int bound, len;
295 1.3.14.2 ad uint32_t rxstat;
296 1.3.14.2 ad uint8_t *ptr;
297 1.3.14.2 ad
298 1.3.14.2 ad bound = 1000 * timo;
299 1.3.14.2 ad
300 1.3.14.2 ad again:
301 1.3.14.2 ad RxD = &l->RxD[l->rx];
302 1.3.14.2 ad do {
303 1.3.14.2 ad rxstat = le32toh(RxD->xd0);
304 1.3.14.2 ad inv(RxD, sizeof(struct desc));
305 1.3.14.2 ad if ((rxstat & R0_OWN) == 0)
306 1.3.14.2 ad goto gotone;
307 1.3.14.2 ad DELAY(1000); /* 1 milli second */
308 1.3.14.2 ad } while (--bound > 0);
309 1.3.14.2 ad errno = 0;
310 1.3.14.2 ad CSR_WRITE(l, TLP_RPD, RPD_POLL);
311 1.3.14.2 ad return -1;
312 1.3.14.2 ad gotone:
313 1.3.14.2 ad if (rxstat & R0_ES) {
314 1.3.14.2 ad RxD->xd0 = htole32(R0_OWN);
315 1.3.14.2 ad wbinv(RxD, sizeof(struct desc));
316 1.3.14.2 ad l->rx = NEXT_RXBUF(l->rx);
317 1.3.14.2 ad CSR_WRITE(l, TLP_RPD, RPD_POLL);
318 1.3.14.2 ad goto again;
319 1.3.14.2 ad }
320 1.3.14.2 ad /* good frame */
321 1.3.14.2 ad len = ((rxstat & R0_FL_MASK) >> 16) - 4; /* HASFCS */
322 1.3.14.2 ad if (len > maxlen)
323 1.3.14.2 ad len = maxlen;
324 1.3.14.2 ad ptr = l->rxstore[l->rx];
325 1.3.14.2 ad memcpy(buf, ptr, len);
326 1.3.14.2 ad inv(ptr, FRAMESIZE);
327 1.3.14.2 ad RxD->xd0 = htole32(R0_OWN);
328 1.3.14.2 ad wbinv(RxD, sizeof(struct desc));
329 1.3.14.2 ad l->rx = NEXT_RXBUF(l->rx);
330 1.3.14.2 ad CSR_WRITE(l, TLP_OMR, l->omr); /* necessary? */
331 1.3.14.2 ad return len;
332 1.3.14.2 ad }
333 1.3.14.2 ad
334 1.3.14.2 ad static void
335 1.3.14.2 ad size_srom(struct local *l)
336 1.3.14.2 ad {
337 1.3.14.2 ad /* determine 8/6 bit addressing SEEPROM */
338 1.3.14.2 ad l->sromsft = 8;
339 1.3.14.2 ad l->sromsft = (read_srom(l, 255) & 0x40000) ? 8 : 6;
340 1.3.14.2 ad }
341 1.3.14.2 ad
342 1.3.14.2 ad /*
343 1.3.14.2 ad * bare SEEPROM access with bitbang'ing
344 1.3.14.2 ad */
345 1.3.14.2 ad #define R110 6 /* SEEPROM read op */
346 1.3.14.2 ad #define CS (1U << 0) /* hold chip select */
347 1.3.14.2 ad #define CLK (1U << 1) /* clk bit */
348 1.3.14.2 ad #define D1 (1U << 2) /* bit existence */
349 1.3.14.2 ad #define D0 0 /* bit absence */
350 1.3.14.2 ad #define VV (1U << 3) /* taken 0/1 from SEEPROM */
351 1.3.14.2 ad
352 1.3.14.2 ad static u_int
353 1.3.14.2 ad read_srom(struct local *l, int off)
354 1.3.14.2 ad {
355 1.3.14.2 ad u_int idx, cnt, ret;
356 1.3.14.2 ad uint32_t val, x1, x0, bit;
357 1.3.14.2 ad
358 1.3.14.2 ad idx = off & 0xff; /* A7-A0 */
359 1.3.14.2 ad idx |= R110 << l->sromsft; /* 110 for READ */
360 1.3.14.2 ad
361 1.3.14.2 ad val = SROM_RD | SROM_SR;
362 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, val);
363 1.3.14.2 ad val |= CS; /* hold CS */
364 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, val);
365 1.3.14.2 ad
366 1.3.14.2 ad x1 = val | D1; /* 1 */
367 1.3.14.2 ad x0 = val | D0; /* 0 */
368 1.3.14.2 ad /* instruct R110 op. at off in MSB first order */
369 1.3.14.2 ad for (cnt = (1 << (l->sromsft + 2)); cnt > 0; cnt >>= 1) {
370 1.3.14.2 ad bit = (idx & cnt) ? x1 : x0;
371 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, bit);
372 1.3.14.2 ad DELAY(10);
373 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, bit | CLK);
374 1.3.14.2 ad DELAY(10);
375 1.3.14.2 ad }
376 1.3.14.2 ad /* read 16bit quantity in MSB first order */
377 1.3.14.2 ad ret = 0;
378 1.3.14.2 ad for (cnt = 16; cnt > 0; cnt--) {
379 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, val);
380 1.3.14.2 ad DELAY(10);
381 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, val | CLK);
382 1.3.14.2 ad DELAY(10);
383 1.3.14.2 ad ret = (ret << 1) | !!(CSR_READ(l, TLP_APROM) & VV);
384 1.3.14.2 ad }
385 1.3.14.2 ad val &= ~CS; /* turn off chip select */
386 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, val);
387 1.3.14.2 ad
388 1.3.14.2 ad return ret;
389 1.3.14.2 ad }
390 1.3.14.2 ad
391 1.3.14.2 ad #if 0
392 1.3.14.2 ad
393 1.3.14.2 ad static u_int
394 1.3.14.2 ad tlp_mii_read(struct local *l, int phy, int reg)
395 1.3.14.2 ad {
396 1.3.14.2 ad /* later ... */
397 1.3.14.2 ad return 0;
398 1.3.14.2 ad }
399 1.3.14.2 ad
400 1.3.14.2 ad static void
401 1.3.14.2 ad tlp_mii_write(struct local *l, int phy, int reg, int val)
402 1.3.14.2 ad {
403 1.3.14.2 ad /* later ... */
404 1.3.14.2 ad }
405 1.3.14.2 ad
406 1.3.14.2 ad #define MII_BMCR 0x00 /* Basic mode control register (rw) */
407 1.3.14.2 ad #define BMCR_RESET 0x8000 /* reset */
408 1.3.14.2 ad #define BMCR_AUTOEN 0x1000 /* autonegotiation enable */
409 1.3.14.2 ad #define BMCR_ISO 0x0400 /* isolate */
410 1.3.14.2 ad #define BMCR_STARTNEG 0x0200 /* restart autonegotiation */
411 1.3.14.2 ad #define MII_BMSR 0x01 /* Basic mode status register (ro) */
412 1.3.14.2 ad
413 1.3.14.2 ad static void
414 1.3.14.2 ad mii_initphy(struct local *l)
415 1.3.14.2 ad {
416 1.3.14.2 ad int phy, bound;
417 1.3.14.2 ad uint32_t ctl, sts;
418 1.3.14.2 ad
419 1.3.14.2 ad for (phy = 0; phy < 32; phy++) {
420 1.3.14.2 ad ctl = tlp_mii_read(l, phy, MII_BMCR);
421 1.3.14.2 ad sts = tlp_mii_read(l, phy, MII_BMSR);
422 1.3.14.2 ad if (ctl != 0xffff && sts != 0xffff)
423 1.3.14.2 ad goto found;
424 1.3.14.2 ad }
425 1.3.14.2 ad printf("MII: no PHY found\n");
426 1.3.14.2 ad return;
427 1.3.14.2 ad found:
428 1.3.14.2 ad ctl = tlp_mii_read(l, phy, MII_BMCR);
429 1.3.14.2 ad tlp_mii_write(l, phy, MII_BMCR, ctl | BMCR_RESET);
430 1.3.14.2 ad bound = 100;
431 1.3.14.2 ad do {
432 1.3.14.2 ad DELAY(10);
433 1.3.14.2 ad ctl = tlp_mii_read(l, phy, MII_BMCR);
434 1.3.14.2 ad if (ctl == 0xffff) {
435 1.3.14.2 ad printf("MII: PHY %d has died after reset\n", phy);
436 1.3.14.2 ad return;
437 1.3.14.2 ad }
438 1.3.14.2 ad } while (bound-- > 0 && (ctl & BMCR_RESET));
439 1.3.14.2 ad if (bound == 0) {
440 1.3.14.2 ad printf("PHY %d reset failed\n", phy);
441 1.3.14.2 ad }
442 1.3.14.2 ad ctl &= ~BMCR_ISO;
443 1.3.14.2 ad tlp_mii_write(l, phy, MII_BMCR, ctl);
444 1.3.14.2 ad sts = tlp_mii_read(l, phy, MII_BMSR) |
445 1.3.14.2 ad tlp_mii_read(l, phy, MII_BMSR); /* read twice */
446 1.3.14.2 ad l->phy = phy;
447 1.3.14.2 ad l->bmsr = sts;
448 1.3.14.2 ad }
449 1.3.14.2 ad
450 1.3.14.2 ad static void
451 1.3.14.2 ad mii_dealan(struct local *, u_int timo)
452 1.3.14.2 ad {
453 1.3.14.2 ad uint32_t anar;
454 1.3.14.2 ad u_int bound;
455 1.3.14.2 ad
456 1.3.14.2 ad anar = ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10 | ANAR_CSMA;
457 1.3.14.2 ad tlp_mii_write(l, l->phy, MII_ANAR, anar);
458 1.3.14.2 ad tlp_mii_write(l, l->phy, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG);
459 1.3.14.2 ad l->anlpar = 0;
460 1.3.14.2 ad bound = getsecs() + timo;
461 1.3.14.2 ad do {
462 1.3.14.2 ad l->bmsr = tlp_mii_read(l, l->phy, MII_BMSR) |
463 1.3.14.2 ad tlp_mii_read(l, l->phy, MII_BMSR); /* read twice */
464 1.3.14.2 ad if ((l->bmsr & BMSR_LINK) && (l->bmsr & BMSR_ACOMP)) {
465 1.3.14.2 ad l->anlpar = tlp_mii_read(l, l->phy, MII_ANLPAR);
466 1.3.14.2 ad break;
467 1.3.14.2 ad }
468 1.3.14.2 ad DELAY(10 * 1000);
469 1.3.14.2 ad } while (getsecs() < bound);
470 1.3.14.2 ad return;
471 1.3.14.2 ad }
472 1.3.14.2 ad #endif
473 1.3.14.2 ad /* $NetBSD: tlp.c,v 1.3.14.2 2007/12/03 19:03:11 ad Exp $ */
474 1.3.14.2 ad
475 1.3.14.2 ad /*-
476 1.3.14.2 ad * Copyright (c) 2007 The NetBSD Foundation, Inc.
477 1.3.14.2 ad * All rights reserved.
478 1.3.14.2 ad *
479 1.3.14.2 ad * This code is derived from software contributed to The NetBSD Foundation
480 1.3.14.2 ad * by Tohru Nishimura.
481 1.3.14.2 ad *
482 1.3.14.2 ad * Redistribution and use in source and binary forms, with or without
483 1.3.14.2 ad * modification, are permitted provided that the following conditions
484 1.3.14.2 ad * are met:
485 1.3.14.2 ad * 1. Redistributions of source code must retain the above copyright
486 1.3.14.2 ad * notice, this list of conditions and the following disclaimer.
487 1.3.14.2 ad * 2. Redistributions in binary form must reproduce the above copyright
488 1.3.14.2 ad * notice, this list of conditions and the following disclaimer in the
489 1.3.14.2 ad * documentation and/or other materials provided with the distribution.
490 1.3.14.2 ad * 3. All advertising materials mentioning features or use of this software
491 1.3.14.2 ad * must display the following acknowledgement:
492 1.3.14.2 ad * This product includes software developed by the NetBSD
493 1.3.14.2 ad * Foundation, Inc. and its contributors.
494 1.3.14.2 ad * 4. Neither the name of The NetBSD Foundation nor the names of its
495 1.3.14.2 ad * contributors may be used to endorse or promote products derived
496 1.3.14.2 ad * from this software without specific prior written permission.
497 1.3.14.2 ad *
498 1.3.14.2 ad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
499 1.3.14.2 ad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
500 1.3.14.2 ad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
501 1.3.14.2 ad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
502 1.3.14.2 ad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
503 1.3.14.2 ad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
504 1.3.14.2 ad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
505 1.3.14.2 ad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
506 1.3.14.2 ad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
507 1.3.14.2 ad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
508 1.3.14.2 ad * POSSIBILITY OF SUCH DAMAGE.
509 1.3.14.2 ad */
510 1.3.14.2 ad
511 1.3.14.2 ad #include <sys/param.h>
512 1.3.14.2 ad #include <sys/socket.h>
513 1.3.14.2 ad
514 1.3.14.2 ad #include <netinet/in.h>
515 1.3.14.2 ad #include <netinet/in_systm.h>
516 1.3.14.2 ad
517 1.3.14.2 ad #include <lib/libsa/stand.h>
518 1.3.14.2 ad #include <lib/libsa/net.h>
519 1.3.14.2 ad
520 1.3.14.2 ad #include <mips/cpuregs.h>
521 1.3.14.2 ad
522 1.3.14.2 ad #include "boot.h"
523 1.3.14.2 ad
524 1.3.14.2 ad /*
525 1.3.14.2 ad * - little endian access for CSR register.
526 1.3.14.2 ad * - assume KSEG0 on vtophys() translation.
527 1.3.14.2 ad * - PIPT writeback cache aware.
528 1.3.14.2 ad */
529 1.3.14.2 ad #define CSR_WRITE(l, r, v) \
530 1.3.14.2 ad do { \
531 1.3.14.2 ad *(volatile uint32_t *)((l)->csr + (r)) = (v); \
532 1.3.14.2 ad } while (0)
533 1.3.14.2 ad #define CSR_READ(l, r) (*(volatile uint32_t *)((l)->csr + (r)))
534 1.3.14.2 ad #define VTOPHYS(va) MIPS_KSEG0_TO_PHYS(va)
535 1.3.14.2 ad #define wb(adr, siz) pdcache_wb((uint32_t)(adr), (u_int)(siz))
536 1.3.14.2 ad #define wbinv(adr, siz) pdcache_wbinv((uint32_t)(adr), (u_int)(siz))
537 1.3.14.2 ad #define inv(adr, siz) pdcache_inv((uint32_t)(adr), (u_int)(siz))
538 1.3.14.2 ad #define DELAY(n) delay(n)
539 1.3.14.2 ad #define ALLOC(T, A) (T *)((uint32_t)alloc(sizeof(T) + (A)) & ~((A) - 1))
540 1.3.14.2 ad
541 1.3.14.2 ad #define T0_OWN (1U<<31) /* desc is ready to tx */
542 1.3.14.2 ad #define T0_ES (1U<<15) /* Tx error summary */
543 1.3.14.2 ad #define T1_LS (1U<<30) /* last segment */
544 1.3.14.2 ad #define T1_FS (1U<<29) /* first segment */
545 1.3.14.2 ad #define T1_SET (1U<<27) /* "setup packet" */
546 1.3.14.2 ad #define T1_TER (1U<<25) /* end of ring mark */
547 1.3.14.2 ad #define T1_TBS_MASK 0x7ff /* segment size 10:0 */
548 1.3.14.2 ad #define R0_OWN (1U<<31) /* desc is empty */
549 1.3.14.2 ad #define R0_FS (1U<<30) /* first desc of frame */
550 1.3.14.2 ad #define R0_LS (1U<<8) /* last desc of frame */
551 1.3.14.2 ad #define R0_ES (1U<<15) /* Rx error summary */
552 1.3.14.2 ad #define R1_RCH (1U<<24) /* Second address chained */
553 1.3.14.2 ad #define R1_RER (1U<<25) /* end of ring mark */
554 1.3.14.2 ad #define R0_FL_MASK 0x3fff0000 /* frame length 29:16 */
555 1.3.14.2 ad #define R1_RBS_MASK 0x7ff /* segment size 10:0 */
556 1.3.14.2 ad
557 1.3.14.2 ad #define DESCSIZE 16
558 1.3.14.2 ad struct desc {
559 1.3.14.2 ad volatile uint32_t xd0, xd1, xd2, xd3;
560 1.3.14.2 ad #if CACHELINESIZE > DESCSIZE
561 1.3.14.2 ad uint8_t pad[CACHELINESIZE - DESCSIZE];
562 1.3.14.2 ad #endif
563 1.3.14.2 ad };
564 1.3.14.2 ad
565 1.3.14.2 ad #define TLP_BMR 0x000 /* 0: bus mode */
566 1.3.14.2 ad #define BMR_RST (1U<< 0) /* software reset */
567 1.3.14.2 ad #define TLP_TPD 0x008 /* 1: instruct Tx to start */
568 1.3.14.2 ad #define TPD_POLL (1U<< 0) /* transmit poll demand */
569 1.3.14.2 ad #define TLP_RPD 0x010 /* 2: instruct Rx to start */
570 1.3.14.2 ad #define RPD_POLL (1U<< 0) /* receive poll demand */
571 1.3.14.2 ad #define TLP_RRBA 0x018 /* 3: Rx descriptor base */
572 1.3.14.2 ad #define TLP_TRBA 0x020 /* 4: Tx descriptor base */
573 1.3.14.2 ad #define TLP_STS 0x028 /* 5: status */
574 1.3.14.2 ad #define STS_TS 0x00700000 /* Tx status */
575 1.3.14.2 ad #define STS_RS 0x000e0000 /* Rx status */
576 1.3.14.2 ad #define TLP_OMR 0x030 /* 6: operation mode */
577 1.3.14.2 ad #define OMR_SDP (1U<<25) /* always ON */
578 1.3.14.2 ad #define OMR_PS (1U<<18) /* port select */
579 1.3.14.2 ad #define OMR_PM (1U<< 6) /* promicuous */
580 1.3.14.2 ad #define OMR_TEN (1U<<13) /* instruct start/stop Tx */
581 1.3.14.2 ad #define OMR_REN (1U<< 1) /* instruct start/stop Rx */
582 1.3.14.2 ad #define OMR_FD (1U<< 9) /* FDX */
583 1.3.14.2 ad #define TLP_IEN 0x38 /* 7: interrupt enable mask */
584 1.3.14.2 ad #define TLP_APROM 0x048 /* 9: SEEPROM and MII management */
585 1.3.14.2 ad #define SROM_RD (1U <<14) /* read operation */
586 1.3.14.2 ad #define SROM_WR (1U <<13) /* write openration */
587 1.3.14.2 ad #define SROM_SR (1U <<11) /* SEEPROM select */
588 1.3.14.2 ad #define TLP_CSR12 0x60 /* SIA status */
589 1.3.14.2 ad
590 1.3.14.2 ad #define TLP_CSR15 0x78 /* SIA general register */
591 1.3.14.2 ad #define SIAGEN_MD0 (1U<<16)
592 1.3.14.2 ad #define SIAGEN_CWE (1U<<28)
593 1.3.14.2 ad
594 1.3.14.2 ad #define FRAMESIZE 1536
595 1.3.14.2 ad #define BUFSIZE 2048
596 1.3.14.2 ad #define NRXBUF 2
597 1.3.14.2 ad #define NEXT_RXBUF(x) (((x) + 1) & (NRXBUF - 1))
598 1.3.14.2 ad
599 1.3.14.2 ad struct local {
600 1.3.14.2 ad struct desc TxD;
601 1.3.14.2 ad struct desc RxD[NRXBUF];
602 1.3.14.2 ad uint8_t txstore[BUFSIZE];
603 1.3.14.2 ad uint8_t rxstore[NRXBUF][BUFSIZE];
604 1.3.14.2 ad uint32_t csr, omr;
605 1.3.14.2 ad u_int rx;
606 1.3.14.2 ad u_int sromsft;
607 1.3.14.2 ad u_int phy;
608 1.3.14.2 ad uint32_t bmsr, anlpar;
609 1.3.14.2 ad };
610 1.3.14.2 ad
611 1.3.14.2 ad #define COBALT_TLP0_BASE 0x10100000
612 1.3.14.2 ad #define SROM_MAC_OFFSET 0
613 1.3.14.2 ad
614 1.3.14.2 ad static void size_srom(struct local *);
615 1.3.14.2 ad static u_int read_srom(struct local *, int);
616 1.3.14.2 ad #if 0
617 1.3.14.2 ad static u_int tlp_mii_read(struct local *, int, int);
618 1.3.14.2 ad static void tlp_mii_write(struct local *, int, int, int);
619 1.3.14.2 ad static void mii_initphy(struct local *);
620 1.3.14.2 ad #endif
621 1.3.14.2 ad
622 1.3.14.2 ad void *
623 1.3.14.2 ad tlp_init(void *cookie)
624 1.3.14.2 ad {
625 1.3.14.2 ad uint32_t val;
626 1.3.14.2 ad struct local *l;
627 1.3.14.2 ad struct desc *TxD, *RxD;
628 1.3.14.2 ad uint8_t *en;
629 1.3.14.2 ad int i;
630 1.3.14.2 ad
631 1.3.14.2 ad l = ALLOC(struct local, CACHELINESIZE);
632 1.3.14.2 ad memset(l, 0, sizeof(struct local));
633 1.3.14.2 ad
634 1.3.14.2 ad DPRINTF(("tlp: l = %p, TxD = %p, RxD[0] = %p, RxD[1] = %p\n",
635 1.3.14.2 ad l, &l->TxD, &l->RxD[0], &l->RxD[1]));
636 1.3.14.2 ad DPRINTF(("tlp: txstore = %p, rxstore[0] = %p, rxstore[1] = %p\n",
637 1.3.14.2 ad l->txstore, l->rxstore[0], l->rxstore[1]));
638 1.3.14.2 ad
639 1.3.14.2 ad #if 0
640 1.3.14.2 ad /* XXX assume tlp0 at pci0 dev 7 function 0 */
641 1.3.14.2 ad tag = (0 << 16) | ( 7 << 11) | (0 << 8);
642 1.3.14.2 ad /* memory map is not initialized by the firmware on cobalt */
643 1.3.14.2 ad l->csr = MIPS_PHYS_TO_KSEG1(pcicfgread(tag, 0x10) & 0xfffffffc);
644 1.3.14.2 ad DPRINTF(("%s: CSR = 0x%x\n", __func__, l->csr));
645 1.3.14.2 ad #else
646 1.3.14.2 ad l->csr = MIPS_PHYS_TO_KSEG1(COBALT_TLP0_BASE);
647 1.3.14.2 ad #endif
648 1.3.14.2 ad
649 1.3.14.2 ad val = CSR_READ(l, TLP_BMR);
650 1.3.14.2 ad CSR_WRITE(l, TLP_BMR, val | BMR_RST);
651 1.3.14.2 ad DELAY(1000);
652 1.3.14.2 ad CSR_WRITE(l, TLP_BMR, val);
653 1.3.14.2 ad DELAY(1000);
654 1.3.14.2 ad (void)CSR_READ(l, TLP_BMR);
655 1.3.14.2 ad
656 1.3.14.2 ad l->omr = OMR_PS | OMR_SDP;
657 1.3.14.2 ad CSR_WRITE(l, TLP_OMR, l->omr);
658 1.3.14.2 ad CSR_WRITE(l, TLP_STS, ~0);
659 1.3.14.2 ad CSR_WRITE(l, TLP_IEN, 0);
660 1.3.14.2 ad
661 1.3.14.2 ad #if 0
662 1.3.14.2 ad mii_initphy(l);
663 1.3.14.2 ad #endif
664 1.3.14.2 ad size_srom(l);
665 1.3.14.2 ad
666 1.3.14.2 ad en = cookie;
667 1.3.14.2 ad /* MAC address is stored at offset 0 in SROM on cobalt */
668 1.3.14.2 ad val = read_srom(l, SROM_MAC_OFFSET / 2 + 0);
669 1.3.14.2 ad en[0] = val;
670 1.3.14.2 ad en[1] = val >> 8;
671 1.3.14.2 ad val = read_srom(l, SROM_MAC_OFFSET / 2 + 1);
672 1.3.14.2 ad en[2] = val;
673 1.3.14.2 ad en[3] = val >> 8;
674 1.3.14.2 ad val = read_srom(l, SROM_MAC_OFFSET / 2 + 2);
675 1.3.14.2 ad en[4] = val;
676 1.3.14.2 ad en[5] = val >> 8;
677 1.3.14.2 ad
678 1.3.14.2 ad DPRINTF(("tlp: MAC address %x:%x:%x:%x:%x:%x\n",
679 1.3.14.2 ad en[0], en[1], en[2], en[3], en[4], en[5]));
680 1.3.14.2 ad
681 1.3.14.2 ad RxD = &l->RxD[0];
682 1.3.14.2 ad for (i = 0; i < NRXBUF; i++) {
683 1.3.14.2 ad RxD[i].xd3 = htole32(VTOPHYS(&RxD[NEXT_RXBUF(i)]));
684 1.3.14.2 ad RxD[i].xd2 = htole32(VTOPHYS(l->rxstore[i]));
685 1.3.14.2 ad RxD[i].xd1 = htole32(R1_RCH|FRAMESIZE);
686 1.3.14.2 ad RxD[i].xd0 = htole32(R0_OWN);
687 1.3.14.2 ad }
688 1.3.14.2 ad CSR_WRITE(l, TLP_RRBA, VTOPHYS(RxD));
689 1.3.14.2 ad
690 1.3.14.2 ad /* "setup packet" to have own station address */
691 1.3.14.2 ad TxD = &l->TxD;
692 1.3.14.2 ad TxD->xd3 = htole32(VTOPHYS(TxD));
693 1.3.14.2 ad TxD->xd2 = htole32(VTOPHYS(l->txstore));
694 1.3.14.2 ad TxD->xd1 = htole32(T1_SET | T1_TER);
695 1.3.14.2 ad TxD->xd0 = htole32(0);
696 1.3.14.2 ad CSR_WRITE(l, TLP_TRBA, VTOPHYS(TxD));
697 1.3.14.2 ad
698 1.3.14.2 ad memset(l->txstore, 0, FRAMESIZE);
699 1.3.14.2 ad
700 1.3.14.2 ad /* make sure the entire descriptors transfered to memory */
701 1.3.14.2 ad wbinv(l, sizeof(struct local));
702 1.3.14.2 ad
703 1.3.14.2 ad l->rx = 0;
704 1.3.14.2 ad l->omr |= OMR_FD | OMR_TEN | OMR_REN;
705 1.3.14.2 ad
706 1.3.14.2 ad #if 1
707 1.3.14.2 ad /* reset PHY (cobalt quirk from if_tlp_pci.c) */
708 1.3.14.2 ad CSR_WRITE(l, TLP_CSR15, SIAGEN_CWE | SIAGEN_MD0);
709 1.3.14.2 ad DELAY(10);
710 1.3.14.2 ad CSR_WRITE(l, TLP_CSR15, SIAGEN_CWE);
711 1.3.14.2 ad DELAY(10);
712 1.3.14.2 ad #endif
713 1.3.14.2 ad
714 1.3.14.2 ad /* start Tx/Rx */
715 1.3.14.2 ad CSR_WRITE(l, TLP_OMR, l->omr);
716 1.3.14.2 ad #if 0
717 1.3.14.2 ad CSR_WRITE(l, TLP_TPD, TPD_POLL);
718 1.3.14.2 ad #endif
719 1.3.14.2 ad CSR_WRITE(l, TLP_RPD, RPD_POLL);
720 1.3.14.2 ad
721 1.3.14.2 ad return l;
722 1.3.14.2 ad }
723 1.3.14.2 ad
724 1.3.14.2 ad int
725 1.3.14.2 ad tlp_send(void *dev, char *buf, u_int len)
726 1.3.14.2 ad {
727 1.3.14.2 ad struct local *l = dev;
728 1.3.14.2 ad struct desc *TxD;
729 1.3.14.2 ad u_int loop;
730 1.3.14.2 ad
731 1.3.14.2 ad #if 1
732 1.3.14.2 ad wb(buf, len);
733 1.3.14.2 ad TxD = &l->TxD;
734 1.3.14.2 ad TxD->xd3 = htole32(VTOPHYS(TxD));
735 1.3.14.2 ad TxD->xd2 = htole32(VTOPHYS(buf));
736 1.3.14.2 ad TxD->xd1 = htole32(T1_FS | T1_LS | T1_TER | (len & T1_TBS_MASK));
737 1.3.14.2 ad #else
738 1.3.14.2 ad memcpy(l->txstore, buf, len);
739 1.3.14.2 ad wb(l->txstore, len);
740 1.3.14.2 ad TxD = &l->TxD;
741 1.3.14.2 ad TxD->xd3 = htole32(VTOPHYS(TxD));
742 1.3.14.2 ad TxD->xd2 = htole32(VTOPHYS(l->txstore));
743 1.3.14.2 ad TxD->xd1 = htole32(T1_FS | T1_LS | T1_TER | (len & T1_TBS_MASK));
744 1.3.14.2 ad #endif
745 1.3.14.2 ad TxD->xd0 = htole32(T0_OWN);
746 1.3.14.2 ad wbinv(TxD, sizeof(struct desc));
747 1.3.14.2 ad CSR_WRITE(l, TLP_TPD, TPD_POLL);
748 1.3.14.2 ad loop = 100;
749 1.3.14.2 ad do {
750 1.3.14.2 ad if ((le32toh(TxD->xd0) & T0_OWN) == 0)
751 1.3.14.2 ad goto done;
752 1.3.14.2 ad inv(TxD, sizeof(struct desc));
753 1.3.14.2 ad DELAY(10);
754 1.3.14.2 ad } while (--loop > 0);
755 1.3.14.2 ad printf("xmit failed\n");
756 1.3.14.2 ad return -1;
757 1.3.14.2 ad done:
758 1.3.14.2 ad return len;
759 1.3.14.2 ad }
760 1.3.14.2 ad
761 1.3.14.2 ad int
762 1.3.14.2 ad tlp_recv(void *dev, char *buf, u_int maxlen, u_int timo)
763 1.3.14.2 ad {
764 1.3.14.2 ad struct local *l = dev;
765 1.3.14.2 ad struct desc *RxD;
766 1.3.14.2 ad u_int bound, len;
767 1.3.14.2 ad uint32_t rxstat;
768 1.3.14.2 ad uint8_t *ptr;
769 1.3.14.2 ad
770 1.3.14.2 ad bound = 1000 * timo;
771 1.3.14.2 ad
772 1.3.14.2 ad again:
773 1.3.14.2 ad RxD = &l->RxD[l->rx];
774 1.3.14.2 ad do {
775 1.3.14.2 ad rxstat = le32toh(RxD->xd0);
776 1.3.14.2 ad inv(RxD, sizeof(struct desc));
777 1.3.14.2 ad if ((rxstat & R0_OWN) == 0)
778 1.3.14.2 ad goto gotone;
779 1.3.14.2 ad DELAY(1000); /* 1 milli second */
780 1.3.14.2 ad } while (--bound > 0);
781 1.3.14.2 ad errno = 0;
782 1.3.14.2 ad CSR_WRITE(l, TLP_RPD, RPD_POLL);
783 1.3.14.2 ad return -1;
784 1.3.14.2 ad gotone:
785 1.3.14.2 ad if (rxstat & R0_ES) {
786 1.3.14.2 ad RxD->xd0 = htole32(R0_OWN);
787 1.3.14.2 ad wbinv(RxD, sizeof(struct desc));
788 1.3.14.2 ad l->rx = NEXT_RXBUF(l->rx);
789 1.3.14.2 ad CSR_WRITE(l, TLP_RPD, RPD_POLL);
790 1.3.14.2 ad goto again;
791 1.3.14.2 ad }
792 1.3.14.2 ad /* good frame */
793 1.3.14.2 ad len = ((rxstat & R0_FL_MASK) >> 16) - 4; /* HASFCS */
794 1.3.14.2 ad if (len > maxlen)
795 1.3.14.2 ad len = maxlen;
796 1.3.14.2 ad ptr = l->rxstore[l->rx];
797 1.3.14.2 ad memcpy(buf, ptr, len);
798 1.3.14.2 ad inv(ptr, FRAMESIZE);
799 1.3.14.2 ad RxD->xd0 = htole32(R0_OWN);
800 1.3.14.2 ad wbinv(RxD, sizeof(struct desc));
801 1.3.14.2 ad l->rx = NEXT_RXBUF(l->rx);
802 1.3.14.2 ad CSR_WRITE(l, TLP_OMR, l->omr); /* necessary? */
803 1.3.14.2 ad return len;
804 1.3.14.2 ad }
805 1.3.14.2 ad
806 1.3.14.2 ad static void
807 1.3.14.2 ad size_srom(struct local *l)
808 1.3.14.2 ad {
809 1.3.14.2 ad /* determine 8/6 bit addressing SEEPROM */
810 1.3.14.2 ad l->sromsft = 8;
811 1.3.14.2 ad l->sromsft = (read_srom(l, 255) & 0x40000) ? 8 : 6;
812 1.3.14.2 ad }
813 1.3.14.2 ad
814 1.3.14.2 ad /*
815 1.3.14.2 ad * bare SEEPROM access with bitbang'ing
816 1.3.14.2 ad */
817 1.3.14.2 ad #define R110 6 /* SEEPROM read op */
818 1.3.14.2 ad #define CS (1U << 0) /* hold chip select */
819 1.3.14.2 ad #define CLK (1U << 1) /* clk bit */
820 1.3.14.2 ad #define D1 (1U << 2) /* bit existence */
821 1.3.14.2 ad #define D0 0 /* bit absence */
822 1.3.14.2 ad #define VV (1U << 3) /* taken 0/1 from SEEPROM */
823 1.3.14.2 ad
824 1.3.14.2 ad static u_int
825 1.3.14.2 ad read_srom(struct local *l, int off)
826 1.3.14.2 ad {
827 1.3.14.2 ad u_int idx, cnt, ret;
828 1.3.14.2 ad uint32_t val, x1, x0, bit;
829 1.3.14.2 ad
830 1.3.14.2 ad idx = off & 0xff; /* A7-A0 */
831 1.3.14.2 ad idx |= R110 << l->sromsft; /* 110 for READ */
832 1.3.14.2 ad
833 1.3.14.2 ad val = SROM_RD | SROM_SR;
834 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, val);
835 1.3.14.2 ad val |= CS; /* hold CS */
836 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, val);
837 1.3.14.2 ad
838 1.3.14.2 ad x1 = val | D1; /* 1 */
839 1.3.14.2 ad x0 = val | D0; /* 0 */
840 1.3.14.2 ad /* instruct R110 op. at off in MSB first order */
841 1.3.14.2 ad for (cnt = (1 << (l->sromsft + 2)); cnt > 0; cnt >>= 1) {
842 1.3.14.2 ad bit = (idx & cnt) ? x1 : x0;
843 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, bit);
844 1.3.14.2 ad DELAY(10);
845 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, bit | CLK);
846 1.3.14.2 ad DELAY(10);
847 1.3.14.2 ad }
848 1.3.14.2 ad /* read 16bit quantity in MSB first order */
849 1.3.14.2 ad ret = 0;
850 1.3.14.2 ad for (cnt = 16; cnt > 0; cnt--) {
851 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, val);
852 1.3.14.2 ad DELAY(10);
853 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, val | CLK);
854 1.3.14.2 ad DELAY(10);
855 1.3.14.2 ad ret = (ret << 1) | !!(CSR_READ(l, TLP_APROM) & VV);
856 1.3.14.2 ad }
857 1.3.14.2 ad val &= ~CS; /* turn off chip select */
858 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, val);
859 1.3.14.2 ad
860 1.3.14.2 ad return ret;
861 1.3.14.2 ad }
862 1.3.14.2 ad
863 1.3.14.2 ad #if 0
864 1.3.14.2 ad
865 1.3.14.2 ad static u_int
866 1.3.14.2 ad tlp_mii_read(struct local *l, int phy, int reg)
867 1.3.14.2 ad {
868 1.3.14.2 ad /* later ... */
869 1.3.14.2 ad return 0;
870 1.3.14.2 ad }
871 1.3.14.2 ad
872 1.3.14.2 ad static void
873 1.3.14.2 ad tlp_mii_write(struct local *l, int phy, int reg, int val)
874 1.3.14.2 ad {
875 1.3.14.2 ad /* later ... */
876 1.3.14.2 ad }
877 1.3.14.2 ad
878 1.3.14.2 ad #define MII_BMCR 0x00 /* Basic mode control register (rw) */
879 1.3.14.2 ad #define BMCR_RESET 0x8000 /* reset */
880 1.3.14.2 ad #define BMCR_AUTOEN 0x1000 /* autonegotiation enable */
881 1.3.14.2 ad #define BMCR_ISO 0x0400 /* isolate */
882 1.3.14.2 ad #define BMCR_STARTNEG 0x0200 /* restart autonegotiation */
883 1.3.14.2 ad #define MII_BMSR 0x01 /* Basic mode status register (ro) */
884 1.3.14.2 ad
885 1.3.14.2 ad static void
886 1.3.14.2 ad mii_initphy(struct local *l)
887 1.3.14.2 ad {
888 1.3.14.2 ad int phy, bound;
889 1.3.14.2 ad uint32_t ctl, sts;
890 1.3.14.2 ad
891 1.3.14.2 ad for (phy = 0; phy < 32; phy++) {
892 1.3.14.2 ad ctl = tlp_mii_read(l, phy, MII_BMCR);
893 1.3.14.2 ad sts = tlp_mii_read(l, phy, MII_BMSR);
894 1.3.14.2 ad if (ctl != 0xffff && sts != 0xffff)
895 1.3.14.2 ad goto found;
896 1.3.14.2 ad }
897 1.3.14.2 ad printf("MII: no PHY found\n");
898 1.3.14.2 ad return;
899 1.3.14.2 ad found:
900 1.3.14.2 ad ctl = tlp_mii_read(l, phy, MII_BMCR);
901 1.3.14.2 ad tlp_mii_write(l, phy, MII_BMCR, ctl | BMCR_RESET);
902 1.3.14.2 ad bound = 100;
903 1.3.14.2 ad do {
904 1.3.14.2 ad DELAY(10);
905 1.3.14.2 ad ctl = tlp_mii_read(l, phy, MII_BMCR);
906 1.3.14.2 ad if (ctl == 0xffff) {
907 1.3.14.2 ad printf("MII: PHY %d has died after reset\n", phy);
908 1.3.14.2 ad return;
909 1.3.14.2 ad }
910 1.3.14.2 ad } while (bound-- > 0 && (ctl & BMCR_RESET));
911 1.3.14.2 ad if (bound == 0) {
912 1.3.14.2 ad printf("PHY %d reset failed\n", phy);
913 1.3.14.2 ad }
914 1.3.14.2 ad ctl &= ~BMCR_ISO;
915 1.3.14.2 ad tlp_mii_write(l, phy, MII_BMCR, ctl);
916 1.3.14.2 ad sts = tlp_mii_read(l, phy, MII_BMSR) |
917 1.3.14.2 ad tlp_mii_read(l, phy, MII_BMSR); /* read twice */
918 1.3.14.2 ad l->phy = phy;
919 1.3.14.2 ad l->bmsr = sts;
920 1.3.14.2 ad }
921 1.3.14.2 ad
922 1.3.14.2 ad static void
923 1.3.14.2 ad mii_dealan(struct local *, u_int timo)
924 1.3.14.2 ad {
925 1.3.14.2 ad uint32_t anar;
926 1.3.14.2 ad u_int bound;
927 1.3.14.2 ad
928 1.3.14.2 ad anar = ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10 | ANAR_CSMA;
929 1.3.14.2 ad tlp_mii_write(l, l->phy, MII_ANAR, anar);
930 1.3.14.2 ad tlp_mii_write(l, l->phy, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG);
931 1.3.14.2 ad l->anlpar = 0;
932 1.3.14.2 ad bound = getsecs() + timo;
933 1.3.14.2 ad do {
934 1.3.14.2 ad l->bmsr = tlp_mii_read(l, l->phy, MII_BMSR) |
935 1.3.14.2 ad tlp_mii_read(l, l->phy, MII_BMSR); /* read twice */
936 1.3.14.2 ad if ((l->bmsr & BMSR_LINK) && (l->bmsr & BMSR_ACOMP)) {
937 1.3.14.2 ad l->anlpar = tlp_mii_read(l, l->phy, MII_ANLPAR);
938 1.3.14.2 ad break;
939 1.3.14.2 ad }
940 1.3.14.2 ad DELAY(10 * 1000);
941 1.3.14.2 ad } while (getsecs() < bound);
942 1.3.14.2 ad return;
943 1.3.14.2 ad }
944 1.3.14.2 ad #endif
945 1.3.14.2 ad /* $NetBSD: tlp.c,v 1.3.14.2 2007/12/03 19:03:11 ad Exp $ */
946 1.3.14.2 ad
947 1.3.14.2 ad /*-
948 1.3.14.2 ad * Copyright (c) 2007 The NetBSD Foundation, Inc.
949 1.3.14.2 ad * All rights reserved.
950 1.3.14.2 ad *
951 1.3.14.2 ad * This code is derived from software contributed to The NetBSD Foundation
952 1.3.14.2 ad * by Tohru Nishimura.
953 1.3.14.2 ad *
954 1.3.14.2 ad * Redistribution and use in source and binary forms, with or without
955 1.3.14.2 ad * modification, are permitted provided that the following conditions
956 1.3.14.2 ad * are met:
957 1.3.14.2 ad * 1. Redistributions of source code must retain the above copyright
958 1.3.14.2 ad * notice, this list of conditions and the following disclaimer.
959 1.3.14.2 ad * 2. Redistributions in binary form must reproduce the above copyright
960 1.3.14.2 ad * notice, this list of conditions and the following disclaimer in the
961 1.3.14.2 ad * documentation and/or other materials provided with the distribution.
962 1.3.14.2 ad * 3. All advertising materials mentioning features or use of this software
963 1.3.14.2 ad * must display the following acknowledgement:
964 1.3.14.2 ad * This product includes software developed by the NetBSD
965 1.3.14.2 ad * Foundation, Inc. and its contributors.
966 1.3.14.2 ad * 4. Neither the name of The NetBSD Foundation nor the names of its
967 1.3.14.2 ad * contributors may be used to endorse or promote products derived
968 1.3.14.2 ad * from this software without specific prior written permission.
969 1.3.14.2 ad *
970 1.3.14.2 ad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
971 1.3.14.2 ad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
972 1.3.14.2 ad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
973 1.3.14.2 ad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
974 1.3.14.2 ad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
975 1.3.14.2 ad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
976 1.3.14.2 ad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
977 1.3.14.2 ad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
978 1.3.14.2 ad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
979 1.3.14.2 ad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
980 1.3.14.2 ad * POSSIBILITY OF SUCH DAMAGE.
981 1.3.14.2 ad */
982 1.3.14.2 ad
983 1.3.14.2 ad #include <sys/param.h>
984 1.3.14.2 ad #include <sys/socket.h>
985 1.3.14.2 ad
986 1.3.14.2 ad #include <netinet/in.h>
987 1.3.14.2 ad #include <netinet/in_systm.h>
988 1.3.14.2 ad
989 1.3.14.2 ad #include <lib/libsa/stand.h>
990 1.3.14.2 ad #include <lib/libsa/net.h>
991 1.3.14.2 ad
992 1.3.14.2 ad #include <mips/cpuregs.h>
993 1.3.14.2 ad
994 1.3.14.2 ad #include "boot.h"
995 1.3.14.2 ad
996 1.3.14.2 ad /*
997 1.3.14.2 ad * - little endian access for CSR register.
998 1.3.14.2 ad * - assume KSEG0 on vtophys() translation.
999 1.3.14.2 ad * - PIPT writeback cache aware.
1000 1.3.14.2 ad */
1001 1.3.14.2 ad #define CSR_WRITE(l, r, v) \
1002 1.3.14.2 ad do { \
1003 1.3.14.2 ad *(volatile uint32_t *)((l)->csr + (r)) = (v); \
1004 1.3.14.2 ad } while (0)
1005 1.3.14.2 ad #define CSR_READ(l, r) (*(volatile uint32_t *)((l)->csr + (r)))
1006 1.3.14.2 ad #define VTOPHYS(va) MIPS_KSEG0_TO_PHYS(va)
1007 1.3.14.2 ad #define wb(adr, siz) pdcache_wb((uint32_t)(adr), (u_int)(siz))
1008 1.3.14.2 ad #define wbinv(adr, siz) pdcache_wbinv((uint32_t)(adr), (u_int)(siz))
1009 1.3.14.2 ad #define inv(adr, siz) pdcache_inv((uint32_t)(adr), (u_int)(siz))
1010 1.3.14.2 ad #define DELAY(n) delay(n)
1011 1.3.14.2 ad #define ALLOC(T, A) (T *)((uint32_t)alloc(sizeof(T) + (A)) & ~((A) - 1))
1012 1.3.14.2 ad
1013 1.3.14.2 ad #define T0_OWN (1U<<31) /* desc is ready to tx */
1014 1.3.14.2 ad #define T0_ES (1U<<15) /* Tx error summary */
1015 1.3.14.2 ad #define T1_LS (1U<<30) /* last segment */
1016 1.3.14.2 ad #define T1_FS (1U<<29) /* first segment */
1017 1.3.14.2 ad #define T1_SET (1U<<27) /* "setup packet" */
1018 1.3.14.2 ad #define T1_TER (1U<<25) /* end of ring mark */
1019 1.3.14.2 ad #define T1_TBS_MASK 0x7ff /* segment size 10:0 */
1020 1.3.14.2 ad #define R0_OWN (1U<<31) /* desc is empty */
1021 1.3.14.2 ad #define R0_FS (1U<<30) /* first desc of frame */
1022 1.3.14.2 ad #define R0_LS (1U<<8) /* last desc of frame */
1023 1.3.14.2 ad #define R0_ES (1U<<15) /* Rx error summary */
1024 1.3.14.2 ad #define R1_RCH (1U<<24) /* Second address chained */
1025 1.3.14.2 ad #define R1_RER (1U<<25) /* end of ring mark */
1026 1.3.14.2 ad #define R0_FL_MASK 0x3fff0000 /* frame length 29:16 */
1027 1.3.14.2 ad #define R1_RBS_MASK 0x7ff /* segment size 10:0 */
1028 1.3.14.2 ad
1029 1.3.14.2 ad #define DESCSIZE 16
1030 1.3.14.2 ad struct desc {
1031 1.3.14.2 ad volatile uint32_t xd0, xd1, xd2, xd3;
1032 1.3.14.2 ad #if CACHELINESIZE > DESCSIZE
1033 1.3.14.2 ad uint8_t pad[CACHELINESIZE - DESCSIZE];
1034 1.3.14.2 ad #endif
1035 1.3.14.2 ad };
1036 1.3.14.2 ad
1037 1.3.14.2 ad #define TLP_BMR 0x000 /* 0: bus mode */
1038 1.3.14.2 ad #define BMR_RST (1U<< 0) /* software reset */
1039 1.3.14.2 ad #define TLP_TPD 0x008 /* 1: instruct Tx to start */
1040 1.3.14.2 ad #define TPD_POLL (1U<< 0) /* transmit poll demand */
1041 1.3.14.2 ad #define TLP_RPD 0x010 /* 2: instruct Rx to start */
1042 1.3.14.2 ad #define RPD_POLL (1U<< 0) /* receive poll demand */
1043 1.3.14.2 ad #define TLP_RRBA 0x018 /* 3: Rx descriptor base */
1044 1.3.14.2 ad #define TLP_TRBA 0x020 /* 4: Tx descriptor base */
1045 1.3.14.2 ad #define TLP_STS 0x028 /* 5: status */
1046 1.3.14.2 ad #define STS_TS 0x00700000 /* Tx status */
1047 1.3.14.2 ad #define STS_RS 0x000e0000 /* Rx status */
1048 1.3.14.2 ad #define TLP_OMR 0x030 /* 6: operation mode */
1049 1.3.14.2 ad #define OMR_SDP (1U<<25) /* always ON */
1050 1.3.14.2 ad #define OMR_PS (1U<<18) /* port select */
1051 1.3.14.2 ad #define OMR_PM (1U<< 6) /* promicuous */
1052 1.3.14.2 ad #define OMR_TEN (1U<<13) /* instruct start/stop Tx */
1053 1.3.14.2 ad #define OMR_REN (1U<< 1) /* instruct start/stop Rx */
1054 1.3.14.2 ad #define OMR_FD (1U<< 9) /* FDX */
1055 1.3.14.2 ad #define TLP_IEN 0x38 /* 7: interrupt enable mask */
1056 1.3.14.2 ad #define TLP_APROM 0x048 /* 9: SEEPROM and MII management */
1057 1.3.14.2 ad #define SROM_RD (1U <<14) /* read operation */
1058 1.3.14.2 ad #define SROM_WR (1U <<13) /* write openration */
1059 1.3.14.2 ad #define SROM_SR (1U <<11) /* SEEPROM select */
1060 1.3.14.2 ad #define TLP_CSR12 0x60 /* SIA status */
1061 1.3.14.2 ad
1062 1.3.14.2 ad #define TLP_CSR15 0x78 /* SIA general register */
1063 1.3.14.2 ad #define SIAGEN_MD0 (1U<<16)
1064 1.3.14.2 ad #define SIAGEN_CWE (1U<<28)
1065 1.3.14.2 ad
1066 1.3.14.2 ad #define FRAMESIZE 1536
1067 1.3.14.2 ad #define BUFSIZE 2048
1068 1.3.14.2 ad #define NRXBUF 2
1069 1.3.14.2 ad #define NEXT_RXBUF(x) (((x) + 1) & (NRXBUF - 1))
1070 1.3.14.2 ad
1071 1.3.14.2 ad struct local {
1072 1.3.14.2 ad struct desc TxD;
1073 1.3.14.2 ad struct desc RxD[NRXBUF];
1074 1.3.14.2 ad uint8_t txstore[BUFSIZE];
1075 1.3.14.2 ad uint8_t rxstore[NRXBUF][BUFSIZE];
1076 1.3.14.2 ad uint32_t csr, omr;
1077 1.3.14.2 ad u_int rx;
1078 1.3.14.2 ad u_int sromsft;
1079 1.3.14.2 ad u_int phy;
1080 1.3.14.2 ad uint32_t bmsr, anlpar;
1081 1.3.14.2 ad };
1082 1.3.14.2 ad
1083 1.3.14.2 ad #define COBALT_TLP0_BASE 0x10100000
1084 1.3.14.2 ad #define SROM_MAC_OFFSET 0
1085 1.3.14.2 ad
1086 1.3.14.2 ad static void size_srom(struct local *);
1087 1.3.14.2 ad static u_int read_srom(struct local *, int);
1088 1.3.14.2 ad #if 0
1089 1.3.14.2 ad static u_int tlp_mii_read(struct local *, int, int);
1090 1.3.14.2 ad static void tlp_mii_write(struct local *, int, int, int);
1091 1.3.14.2 ad static void mii_initphy(struct local *);
1092 1.3.14.2 ad #endif
1093 1.3.14.2 ad
1094 1.3.14.2 ad void *
1095 1.3.14.2 ad tlp_init(void *cookie)
1096 1.3.14.2 ad {
1097 1.3.14.2 ad uint32_t val;
1098 1.3.14.2 ad struct local *l;
1099 1.3.14.2 ad struct desc *TxD, *RxD;
1100 1.3.14.2 ad uint8_t *en;
1101 1.3.14.2 ad int i;
1102 1.3.14.2 ad
1103 1.3.14.2 ad l = ALLOC(struct local, CACHELINESIZE);
1104 1.3.14.2 ad memset(l, 0, sizeof(struct local));
1105 1.3.14.2 ad
1106 1.3.14.2 ad DPRINTF(("tlp: l = %p, TxD = %p, RxD[0] = %p, RxD[1] = %p\n",
1107 1.3.14.2 ad l, &l->TxD, &l->RxD[0], &l->RxD[1]));
1108 1.3.14.2 ad DPRINTF(("tlp: txstore = %p, rxstore[0] = %p, rxstore[1] = %p\n",
1109 1.3.14.2 ad l->txstore, l->rxstore[0], l->rxstore[1]));
1110 1.3.14.2 ad
1111 1.3.14.2 ad #if 0
1112 1.3.14.2 ad /* XXX assume tlp0 at pci0 dev 7 function 0 */
1113 1.3.14.2 ad tag = (0 << 16) | ( 7 << 11) | (0 << 8);
1114 1.3.14.2 ad /* memory map is not initialized by the firmware on cobalt */
1115 1.3.14.2 ad l->csr = MIPS_PHYS_TO_KSEG1(pcicfgread(tag, 0x10) & 0xfffffffc);
1116 1.3.14.2 ad DPRINTF(("%s: CSR = 0x%x\n", __func__, l->csr));
1117 1.3.14.2 ad #else
1118 1.3.14.2 ad l->csr = MIPS_PHYS_TO_KSEG1(COBALT_TLP0_BASE);
1119 1.3.14.2 ad #endif
1120 1.3.14.2 ad
1121 1.3.14.2 ad val = CSR_READ(l, TLP_BMR);
1122 1.3.14.2 ad CSR_WRITE(l, TLP_BMR, val | BMR_RST);
1123 1.3.14.2 ad DELAY(1000);
1124 1.3.14.2 ad CSR_WRITE(l, TLP_BMR, val);
1125 1.3.14.2 ad DELAY(1000);
1126 1.3.14.2 ad (void)CSR_READ(l, TLP_BMR);
1127 1.3.14.2 ad
1128 1.3.14.2 ad l->omr = OMR_PS | OMR_SDP;
1129 1.3.14.2 ad CSR_WRITE(l, TLP_OMR, l->omr);
1130 1.3.14.2 ad CSR_WRITE(l, TLP_STS, ~0);
1131 1.3.14.2 ad CSR_WRITE(l, TLP_IEN, 0);
1132 1.3.14.2 ad
1133 1.3.14.2 ad #if 0
1134 1.3.14.2 ad mii_initphy(l);
1135 1.3.14.2 ad #endif
1136 1.3.14.2 ad size_srom(l);
1137 1.3.14.2 ad
1138 1.3.14.2 ad en = cookie;
1139 1.3.14.2 ad /* MAC address is stored at offset 0 in SROM on cobalt */
1140 1.3.14.2 ad val = read_srom(l, SROM_MAC_OFFSET / 2 + 0);
1141 1.3.14.2 ad en[0] = val;
1142 1.3.14.2 ad en[1] = val >> 8;
1143 1.3.14.2 ad val = read_srom(l, SROM_MAC_OFFSET / 2 + 1);
1144 1.3.14.2 ad en[2] = val;
1145 1.3.14.2 ad en[3] = val >> 8;
1146 1.3.14.2 ad val = read_srom(l, SROM_MAC_OFFSET / 2 + 2);
1147 1.3.14.2 ad en[4] = val;
1148 1.3.14.2 ad en[5] = val >> 8;
1149 1.3.14.2 ad
1150 1.3.14.2 ad DPRINTF(("tlp: MAC address %x:%x:%x:%x:%x:%x\n",
1151 1.3.14.2 ad en[0], en[1], en[2], en[3], en[4], en[5]));
1152 1.3.14.2 ad
1153 1.3.14.2 ad RxD = &l->RxD[0];
1154 1.3.14.2 ad for (i = 0; i < NRXBUF; i++) {
1155 1.3.14.2 ad RxD[i].xd3 = htole32(VTOPHYS(&RxD[NEXT_RXBUF(i)]));
1156 1.3.14.2 ad RxD[i].xd2 = htole32(VTOPHYS(l->rxstore[i]));
1157 1.3.14.2 ad RxD[i].xd1 = htole32(R1_RCH|FRAMESIZE);
1158 1.3.14.2 ad RxD[i].xd0 = htole32(R0_OWN);
1159 1.3.14.2 ad }
1160 1.3.14.2 ad CSR_WRITE(l, TLP_RRBA, VTOPHYS(RxD));
1161 1.3.14.2 ad
1162 1.3.14.2 ad /* "setup packet" to have own station address */
1163 1.3.14.2 ad TxD = &l->TxD;
1164 1.3.14.2 ad TxD->xd3 = htole32(VTOPHYS(TxD));
1165 1.3.14.2 ad TxD->xd2 = htole32(VTOPHYS(l->txstore));
1166 1.3.14.2 ad TxD->xd1 = htole32(T1_SET | T1_TER);
1167 1.3.14.2 ad TxD->xd0 = htole32(0);
1168 1.3.14.2 ad CSR_WRITE(l, TLP_TRBA, VTOPHYS(TxD));
1169 1.3.14.2 ad
1170 1.3.14.2 ad memset(l->txstore, 0, FRAMESIZE);
1171 1.3.14.2 ad
1172 1.3.14.2 ad /* make sure the entire descriptors transfered to memory */
1173 1.3.14.2 ad wbinv(l, sizeof(struct local));
1174 1.3.14.2 ad
1175 1.3.14.2 ad l->rx = 0;
1176 1.3.14.2 ad l->omr |= OMR_FD | OMR_TEN | OMR_REN;
1177 1.3.14.2 ad
1178 1.3.14.2 ad #if 1
1179 1.3.14.2 ad /* reset PHY (cobalt quirk from if_tlp_pci.c) */
1180 1.3.14.2 ad CSR_WRITE(l, TLP_CSR15, SIAGEN_CWE | SIAGEN_MD0);
1181 1.3.14.2 ad DELAY(10);
1182 1.3.14.2 ad CSR_WRITE(l, TLP_CSR15, SIAGEN_CWE);
1183 1.3.14.2 ad DELAY(10);
1184 1.3.14.2 ad #endif
1185 1.3.14.2 ad
1186 1.3.14.2 ad /* start Tx/Rx */
1187 1.3.14.2 ad CSR_WRITE(l, TLP_OMR, l->omr);
1188 1.3.14.2 ad #if 0
1189 1.3.14.2 ad CSR_WRITE(l, TLP_TPD, TPD_POLL);
1190 1.3.14.2 ad #endif
1191 1.3.14.2 ad CSR_WRITE(l, TLP_RPD, RPD_POLL);
1192 1.3.14.2 ad
1193 1.3.14.2 ad return l;
1194 1.3.14.2 ad }
1195 1.3.14.2 ad
1196 1.3.14.2 ad int
1197 1.3.14.2 ad tlp_send(void *dev, char *buf, u_int len)
1198 1.3.14.2 ad {
1199 1.3.14.2 ad struct local *l = dev;
1200 1.3.14.2 ad struct desc *TxD;
1201 1.3.14.2 ad u_int loop;
1202 1.3.14.2 ad
1203 1.3.14.2 ad #if 1
1204 1.3.14.2 ad wb(buf, len);
1205 1.3.14.2 ad TxD = &l->TxD;
1206 1.3.14.2 ad TxD->xd3 = htole32(VTOPHYS(TxD));
1207 1.3.14.2 ad TxD->xd2 = htole32(VTOPHYS(buf));
1208 1.3.14.2 ad TxD->xd1 = htole32(T1_FS | T1_LS | T1_TER | (len & T1_TBS_MASK));
1209 1.3.14.2 ad #else
1210 1.3.14.2 ad memcpy(l->txstore, buf, len);
1211 1.3.14.2 ad wb(l->txstore, len);
1212 1.3.14.2 ad TxD = &l->TxD;
1213 1.3.14.2 ad TxD->xd3 = htole32(VTOPHYS(TxD));
1214 1.3.14.2 ad TxD->xd2 = htole32(VTOPHYS(l->txstore));
1215 1.3.14.2 ad TxD->xd1 = htole32(T1_FS | T1_LS | T1_TER | (len & T1_TBS_MASK));
1216 1.3.14.2 ad #endif
1217 1.3.14.2 ad TxD->xd0 = htole32(T0_OWN);
1218 1.3.14.2 ad wbinv(TxD, sizeof(struct desc));
1219 1.3.14.2 ad CSR_WRITE(l, TLP_TPD, TPD_POLL);
1220 1.3.14.2 ad loop = 100;
1221 1.3.14.2 ad do {
1222 1.3.14.2 ad if ((le32toh(TxD->xd0) & T0_OWN) == 0)
1223 1.3.14.2 ad goto done;
1224 1.3.14.2 ad inv(TxD, sizeof(struct desc));
1225 1.3.14.2 ad DELAY(10);
1226 1.3.14.2 ad } while (--loop > 0);
1227 1.3.14.2 ad printf("xmit failed\n");
1228 1.3.14.2 ad return -1;
1229 1.3.14.2 ad done:
1230 1.3.14.2 ad return len;
1231 1.3.14.2 ad }
1232 1.3.14.2 ad
1233 1.3.14.2 ad int
1234 1.3.14.2 ad tlp_recv(void *dev, char *buf, u_int maxlen, u_int timo)
1235 1.3.14.2 ad {
1236 1.3.14.2 ad struct local *l = dev;
1237 1.3.14.2 ad struct desc *RxD;
1238 1.3.14.2 ad u_int bound, len;
1239 1.3.14.2 ad uint32_t rxstat;
1240 1.3.14.2 ad uint8_t *ptr;
1241 1.3.14.2 ad
1242 1.3.14.2 ad bound = 1000 * timo;
1243 1.3.14.2 ad
1244 1.3.14.2 ad again:
1245 1.3.14.2 ad RxD = &l->RxD[l->rx];
1246 1.3.14.2 ad do {
1247 1.3.14.2 ad rxstat = le32toh(RxD->xd0);
1248 1.3.14.2 ad inv(RxD, sizeof(struct desc));
1249 1.3.14.2 ad if ((rxstat & R0_OWN) == 0)
1250 1.3.14.2 ad goto gotone;
1251 1.3.14.2 ad DELAY(1000); /* 1 milli second */
1252 1.3.14.2 ad } while (--bound > 0);
1253 1.3.14.2 ad errno = 0;
1254 1.3.14.2 ad CSR_WRITE(l, TLP_RPD, RPD_POLL);
1255 1.3.14.2 ad return -1;
1256 1.3.14.2 ad gotone:
1257 1.3.14.2 ad if (rxstat & R0_ES) {
1258 1.3.14.2 ad RxD->xd0 = htole32(R0_OWN);
1259 1.3.14.2 ad wbinv(RxD, sizeof(struct desc));
1260 1.3.14.2 ad l->rx = NEXT_RXBUF(l->rx);
1261 1.3.14.2 ad CSR_WRITE(l, TLP_RPD, RPD_POLL);
1262 1.3.14.2 ad goto again;
1263 1.3.14.2 ad }
1264 1.3.14.2 ad /* good frame */
1265 1.3.14.2 ad len = ((rxstat & R0_FL_MASK) >> 16) - 4; /* HASFCS */
1266 1.3.14.2 ad if (len > maxlen)
1267 1.3.14.2 ad len = maxlen;
1268 1.3.14.2 ad ptr = l->rxstore[l->rx];
1269 1.3.14.2 ad memcpy(buf, ptr, len);
1270 1.3.14.2 ad inv(ptr, FRAMESIZE);
1271 1.3.14.2 ad RxD->xd0 = htole32(R0_OWN);
1272 1.3.14.2 ad wbinv(RxD, sizeof(struct desc));
1273 1.3.14.2 ad l->rx = NEXT_RXBUF(l->rx);
1274 1.3.14.2 ad CSR_WRITE(l, TLP_OMR, l->omr); /* necessary? */
1275 1.3.14.2 ad return len;
1276 1.3.14.2 ad }
1277 1.3.14.2 ad
1278 1.3.14.2 ad static void
1279 1.3.14.2 ad size_srom(struct local *l)
1280 1.3.14.2 ad {
1281 1.3.14.2 ad /* determine 8/6 bit addressing SEEPROM */
1282 1.3.14.2 ad l->sromsft = 8;
1283 1.3.14.2 ad l->sromsft = (read_srom(l, 255) & 0x40000) ? 8 : 6;
1284 1.3.14.2 ad }
1285 1.3.14.2 ad
1286 1.3.14.2 ad /*
1287 1.3.14.2 ad * bare SEEPROM access with bitbang'ing
1288 1.3.14.2 ad */
1289 1.3.14.2 ad #define R110 6 /* SEEPROM read op */
1290 1.3.14.2 ad #define CS (1U << 0) /* hold chip select */
1291 1.3.14.2 ad #define CLK (1U << 1) /* clk bit */
1292 1.3.14.2 ad #define D1 (1U << 2) /* bit existence */
1293 1.3.14.2 ad #define D0 0 /* bit absence */
1294 1.3.14.2 ad #define VV (1U << 3) /* taken 0/1 from SEEPROM */
1295 1.3.14.2 ad
1296 1.3.14.2 ad static u_int
1297 1.3.14.2 ad read_srom(struct local *l, int off)
1298 1.3.14.2 ad {
1299 1.3.14.2 ad u_int idx, cnt, ret;
1300 1.3.14.2 ad uint32_t val, x1, x0, bit;
1301 1.3.14.2 ad
1302 1.3.14.2 ad idx = off & 0xff; /* A7-A0 */
1303 1.3.14.2 ad idx |= R110 << l->sromsft; /* 110 for READ */
1304 1.3.14.2 ad
1305 1.3.14.2 ad val = SROM_RD | SROM_SR;
1306 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, val);
1307 1.3.14.2 ad val |= CS; /* hold CS */
1308 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, val);
1309 1.3.14.2 ad
1310 1.3.14.2 ad x1 = val | D1; /* 1 */
1311 1.3.14.2 ad x0 = val | D0; /* 0 */
1312 1.3.14.2 ad /* instruct R110 op. at off in MSB first order */
1313 1.3.14.2 ad for (cnt = (1 << (l->sromsft + 2)); cnt > 0; cnt >>= 1) {
1314 1.3.14.2 ad bit = (idx & cnt) ? x1 : x0;
1315 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, bit);
1316 1.3.14.2 ad DELAY(10);
1317 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, bit | CLK);
1318 1.3.14.2 ad DELAY(10);
1319 1.3.14.2 ad }
1320 1.3.14.2 ad /* read 16bit quantity in MSB first order */
1321 1.3.14.2 ad ret = 0;
1322 1.3.14.2 ad for (cnt = 16; cnt > 0; cnt--) {
1323 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, val);
1324 1.3.14.2 ad DELAY(10);
1325 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, val | CLK);
1326 1.3.14.2 ad DELAY(10);
1327 1.3.14.2 ad ret = (ret << 1) | !!(CSR_READ(l, TLP_APROM) & VV);
1328 1.3.14.2 ad }
1329 1.3.14.2 ad val &= ~CS; /* turn off chip select */
1330 1.3.14.2 ad CSR_WRITE(l, TLP_APROM, val);
1331 1.3.14.2 ad
1332 1.3.14.2 ad return ret;
1333 1.3.14.2 ad }
1334 1.3.14.2 ad
1335 1.3.14.2 ad #if 0
1336 1.3.14.2 ad
1337 1.3.14.2 ad static u_int
1338 1.3.14.2 ad tlp_mii_read(struct local *l, int phy, int reg)
1339 1.3.14.2 ad {
1340 1.3.14.2 ad /* later ... */
1341 1.3.14.2 ad return 0;
1342 1.3.14.2 ad }
1343 1.3.14.2 ad
1344 1.3.14.2 ad static void
1345 1.3.14.2 ad tlp_mii_write(struct local *l, int phy, int reg, int val)
1346 1.3.14.2 ad {
1347 1.3.14.2 ad /* later ... */
1348 1.3.14.2 ad }
1349 1.3.14.2 ad
1350 1.3.14.2 ad #define MII_BMCR 0x00 /* Basic mode control register (rw) */
1351 1.3.14.2 ad #define BMCR_RESET 0x8000 /* reset */
1352 1.3.14.2 ad #define BMCR_AUTOEN 0x1000 /* autonegotiation enable */
1353 1.3.14.2 ad #define BMCR_ISO 0x0400 /* isolate */
1354 1.3.14.2 ad #define BMCR_STARTNEG 0x0200 /* restart autonegotiation */
1355 1.3.14.2 ad #define MII_BMSR 0x01 /* Basic mode status register (ro) */
1356 1.3.14.2 ad
1357 1.3.14.2 ad static void
1358 1.3.14.2 ad mii_initphy(struct local *l)
1359 1.3.14.2 ad {
1360 1.3.14.2 ad int phy, bound;
1361 1.3.14.2 ad uint32_t ctl, sts;
1362 1.3.14.2 ad
1363 1.3.14.2 ad for (phy = 0; phy < 32; phy++) {
1364 1.3.14.2 ad ctl = tlp_mii_read(l, phy, MII_BMCR);
1365 1.3.14.2 ad sts = tlp_mii_read(l, phy, MII_BMSR);
1366 1.3.14.2 ad if (ctl != 0xffff && sts != 0xffff)
1367 1.3.14.2 ad goto found;
1368 1.3.14.2 ad }
1369 1.3.14.2 ad printf("MII: no PHY found\n");
1370 1.3.14.2 ad return;
1371 1.3.14.2 ad found:
1372 1.3.14.2 ad ctl = tlp_mii_read(l, phy, MII_BMCR);
1373 1.3.14.2 ad tlp_mii_write(l, phy, MII_BMCR, ctl | BMCR_RESET);
1374 1.3.14.2 ad bound = 100;
1375 1.3.14.2 ad do {
1376 1.3.14.2 ad DELAY(10);
1377 1.3.14.2 ad ctl = tlp_mii_read(l, phy, MII_BMCR);
1378 1.3.14.2 ad if (ctl == 0xffff) {
1379 1.3.14.2 ad printf("MII: PHY %d has died after reset\n", phy);
1380 1.3.14.2 ad return;
1381 1.3.14.2 ad }
1382 1.3.14.2 ad } while (bound-- > 0 && (ctl & BMCR_RESET));
1383 1.3.14.2 ad if (bound == 0) {
1384 1.3.14.2 ad printf("PHY %d reset failed\n", phy);
1385 1.3.14.2 ad }
1386 1.3.14.2 ad ctl &= ~BMCR_ISO;
1387 1.3.14.2 ad tlp_mii_write(l, phy, MII_BMCR, ctl);
1388 1.3.14.2 ad sts = tlp_mii_read(l, phy, MII_BMSR) |
1389 1.3.14.2 ad tlp_mii_read(l, phy, MII_BMSR); /* read twice */
1390 1.3.14.2 ad l->phy = phy;
1391 1.3.14.2 ad l->bmsr = sts;
1392 1.3.14.2 ad }
1393 1.3.14.2 ad
1394 1.3.14.2 ad static void
1395 1.3.14.2 ad mii_dealan(struct local *, u_int timo)
1396 1.3.14.2 ad {
1397 1.3.14.2 ad uint32_t anar;
1398 1.3.14.2 ad u_int bound;
1399 1.3.14.2 ad
1400 1.3.14.2 ad anar = ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10 | ANAR_CSMA;
1401 1.3.14.2 ad tlp_mii_write(l, l->phy, MII_ANAR, anar);
1402 1.3.14.2 ad tlp_mii_write(l, l->phy, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG);
1403 1.3.14.2 ad l->anlpar = 0;
1404 1.3.14.2 ad bound = getsecs() + timo;
1405 1.3.14.2 ad do {
1406 1.3.14.2 ad l->bmsr = tlp_mii_read(l, l->phy, MII_BMSR) |
1407 1.3.14.2 ad tlp_mii_read(l, l->phy, MII_BMSR); /* read twice */
1408 1.3.14.2 ad if ((l->bmsr & BMSR_LINK) && (l->bmsr & BMSR_ACOMP)) {
1409 1.3.14.2 ad l->anlpar = tlp_mii_read(l, l->phy, MII_ANLPAR);
1410 1.3.14.2 ad break;
1411 1.3.14.2 ad }
1412 1.3.14.2 ad DELAY(10 * 1000);
1413 1.3.14.2 ad } while (getsecs() < bound);
1414 1.3.14.2 ad return;
1415 1.3.14.2 ad }
1416 1.3.14.2 ad #endif
1417