1 /* $NetBSD: tlp.c,v 1.7 2008/03/23 17:19:57 tsutsui Exp $ */
4 * Copyright (c) 2007 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/param.h>
33 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <netinet/in_systm.h>
38 #include <lib/libsa/stand.h>
39 #include <lib/libsa/net.h>
41 #include <mips/cpuregs.h>
43 #include <machine/cpu.h>
48 * - little endian access for CSR register.
49 * - assume KSEG0 on vtophys() translation.
50 * - PIPT writeback cache aware.
52 #define CSR_WRITE(l, r, v) \
54 *(volatile uint32_t *)((l)->csr + (r)) = (v); \
56 #define CSR_READ(l, r) (*(volatile uint32_t *)((l)->csr + (r)))
57 #define VTOPHYS(va) MIPS_KSEG0_TO_PHYS(va)
58 #define wb(adr, siz) pdcache_wb((uint32_t)(adr), (u_int)(siz))
59 #define wbinv(adr, siz) pdcache_wbinv((uint32_t)(adr), (u_int)(siz))
60 #define inv(adr, siz) pdcache_inv((uint32_t)(adr), (u_int)(siz))
61 #define DELAY(n) delay(n)
62 #define ALLOC(T, A) (T *)((uint32_t)alloc(sizeof(T) + (A)) & ~((A) - 1))
64 #define T0_OWN (1U<<31) /* desc is ready to tx */
65 #define T0_ES (1U<<15) /* Tx error summary */
66 #define T1_LS (1U<<30) /* last segment */
67 #define T1_FS (1U<<29) /* first segment */
68 #define T1_SET (1U<<27) /* "setup packet" */
69 #define T1_TER (1U<<25) /* end of ring mark */
70 #define T1_TCH (1U<<24) /* Second address chained */
71 #define T1_TBS_MASK 0x7ff /* segment size 10:0 */
72 #define R0_OWN (1U<<31) /* desc is empty */
73 #define R0_FS (1U<<30) /* first desc of frame */
74 #define R0_LS (1U<<8) /* last desc of frame */
75 #define R0_ES (1U<<15) /* Rx error summary */
76 #define R1_RCH (1U<<24) /* Second address chained */
77 #define R1_RER (1U<<25) /* end of ring mark */
78 #define R0_FL_MASK 0x3fff0000 /* frame length 29:16 */
79 #define R1_RBS_MASK 0x7ff /* segment size 10:0 */
83 volatile uint32_t xd0
, xd1
, xd2
, xd3
;
84 #if CACHELINESIZE > DESCSIZE
85 uint8_t pad
[CACHELINESIZE
- DESCSIZE
];
89 #define TLP_BMR 0x00 /* 0: bus mode */
90 #define BMR_RST (1U<< 0) /* software reset */
91 #define BMR_BAR (1U<< 1) /* bus arbitration */
92 #define BMR_PBL8 (1U<<11) /* burst length 8 longword */
93 #define BMR_CAL8 (1U<<13) /* cache alignment 8 longword */
94 #define TLP_TPD 0x08 /* 1: instruct Tx to start */
95 #define TPD_POLL (1U<< 0) /* transmit poll demand */
96 #define TLP_RPD 0x10 /* 2: instruct Rx to start */
97 #define RPD_POLL (1U<< 0) /* receive poll demand */
98 #define TLP_RRBA 0x18 /* 3: Rx descriptor base */
99 #define TLP_TRBA 0x20 /* 4: Tx descriptor base */
100 #define TLP_STS 0x28 /* 5: status */
101 #define STS_TS 0x00700000 /* Tx status */
102 #define STS_RS 0x000e0000 /* Rx status */
103 #define TLP_OMR 0x30 /* 6: operation mode */
104 #define OMR_SDP (1U<<25) /* always ON */
105 #define OMR_PS (1U<<18) /* port select */
106 #define OMR_PM (1U<< 6) /* promicuous */
107 #define OMR_TEN (1U<<13) /* instruct start/stop Tx */
108 #define OMR_REN (1U<< 1) /* instruct start/stop Rx */
109 #define OMR_FD (1U<< 9) /* FDX */
110 #define TLP_IEN 0x38 /* 7: interrupt enable mask */
111 #define TLP_APROM 0x48 /* 9: SEEPROM and MII management */
112 #define SROM_RD (1U <<14) /* read operation */
113 #define SROM_WR (1U <<13) /* write openration */
114 #define SROM_SR (1U <<11) /* SEEPROM select */
115 #define TLP_CSR12 0x60 /* SIA status */
117 #define TLP_CSR13 0x68 /* SIA connectivity register */
118 #define SIACONN_10BT 0x0000ef01 /* 10BASE-T for 21041 */
120 #define TLP_CSR14 0x70 /* SIA TX RX register */
121 #define SIATXRX_10BT 0x0000ffff /* 10BASE-T for 21041 pass 2 */
123 #define TLP_CSR15 0x78 /* SIA general register */
124 #define SIAGEN_MD0 (1U<<16)
125 #define SIAGEN_CWE (1U<<28)
126 #define SIAGEN_10BT 0x00000000 /* 10BASE-T for 21041 */
128 #define TLP_SETUP_NADDR 16
129 #define TLP_SETUPLEN 192 /* 16 * 3 * sizeof(uint32_t) */
131 #define FRAMESIZE 1536
134 #define NEXT_TXBUF(x) (((x) + 1) & (NTXBUF - 1))
136 #define NEXT_RXBUF(x) (((x) + 1) & (NRXBUF - 1))
139 struct desc txd
[NTXBUF
];
140 struct desc rxd
[NRXBUF
];
141 uint8_t txstore
[TLP_SETUPLEN
];
142 uint8_t rxstore
[NRXBUF
][BUFSIZE
];
148 uint32_t bmsr
, anlpar
;
151 #define COBALT_TLP0_BASE 0x10100000
152 #define SROM_MAC_OFFSET 0
154 static void size_srom(struct local
*);
155 static u_int
read_srom(struct local
*, int);
157 static u_int
tlp_mii_read(struct local
*, int, int);
158 static void tlp_mii_write(struct local
*, int, int, int);
159 static void mii_initphy(struct local
*);
163 tlp_init(void *cookie
)
167 struct desc
*txd
, *rxd
;
172 if (cobalt_id
== COBALT_ID_QUBE2700
)
177 l
= ALLOC(struct local
, CACHELINESIZE
);
178 memset(l
, 0, sizeof(struct local
));
180 DPRINTF(("tlp: l = %p, txd[0] = %p, txd[1] = %p\n",
181 l
, &l
->txd
[0], &l
->txd
[1]));
182 DPRINTF(("tlp: rxd[0] = %p, rxd[1] = %p\n",
183 &l
->rxd
[0], &l
->rxd
[1]));
184 DPRINTF(("tlp: txstore = %p, rxstore[0] = %p, rxstore[1] = %p\n",
185 l
->txstore
, l
->rxstore
[0], l
->rxstore
[1]));
188 /* XXX assume tlp0 at pci0 dev 7 function 0 */
189 tag
= (0 << 16) | ( 7 << 11) | (0 << 8);
190 /* memory map is not initialized by the firmware on cobalt */
191 l
->csr
= MIPS_PHYS_TO_KSEG1(pcicfgread(tag
, 0x10) & ~3U);
192 DPRINTF(("%s: CSR = 0x%x\n", __func__
, l
->csr
));
194 l
->csr
= MIPS_PHYS_TO_KSEG1(COBALT_TLP0_BASE
);
197 val
= CSR_READ(l
, TLP_BMR
);
198 CSR_WRITE(l
, TLP_BMR
, val
| BMR_RST
);
200 CSR_WRITE(l
, TLP_BMR
, val
);
202 (void)CSR_READ(l
, TLP_BMR
);
205 /* reset SIA for 10BASE-T */
206 CSR_WRITE(l
, TLP_CSR13
, 0);
208 CSR_WRITE(l
, TLP_CSR15
, SIAGEN_10BT
);
209 CSR_WRITE(l
, TLP_CSR14
, SIATXRX_10BT
);
210 CSR_WRITE(l
, TLP_CSR13
, SIACONN_10BT
);
212 /* reset PHY (cobalt quirk from if_tlp_pci.c) */
213 CSR_WRITE(l
, TLP_CSR15
, SIAGEN_CWE
| SIAGEN_MD0
);
215 CSR_WRITE(l
, TLP_CSR15
, SIAGEN_CWE
);
219 l
->omr
= OMR_PS
| OMR_SDP
;
220 CSR_WRITE(l
, TLP_OMR
, l
->omr
);
221 CSR_WRITE(l
, TLP_IEN
, 0);
222 CSR_WRITE(l
, TLP_STS
, ~0);
230 /* MAC address is stored at offset 0 in SROM on cobalt */
231 val
= read_srom(l
, SROM_MAC_OFFSET
/ 2 + 0);
234 val
= read_srom(l
, SROM_MAC_OFFSET
/ 2 + 1);
237 val
= read_srom(l
, SROM_MAC_OFFSET
/ 2 + 2);
241 DPRINTF(("tlp: MAC address %x:%x:%x:%x:%x:%x\n",
242 en
[0], en
[1], en
[2], en
[3], en
[4], en
[5]));
245 for (i
= 0; i
< NRXBUF
; i
++) {
246 rxd
[i
].xd3
= htole32(VTOPHYS(&rxd
[NEXT_RXBUF(i
)]));
247 rxd
[i
].xd2
= htole32(VTOPHYS(l
->rxstore
[i
]));
248 rxd
[i
].xd1
= htole32(R1_RCH
|FRAMESIZE
);
249 rxd
[i
].xd0
= htole32(R0_OWN
);
253 for (i
= 0; i
< NTXBUF
; i
++) {
254 txd
[i
].xd3
= htole32(VTOPHYS(&txd
[NEXT_TXBUF(i
)]));
255 txd
[i
].xd0
= htole32(0);
258 /* prepare setup packet */
260 memset(p
, 0, TLP_SETUPLEN
);
261 /* put broadcast first */
262 p
[0] = p
[1] = p
[4] = p
[5] = p
[8] = p
[9] = 0xff;
263 for (i
= 1; i
< TLP_SETUP_NADDR
; i
++) {
264 /* put own station address to the rest */
265 p
[i
* 12 + 0] = en
[0];
266 p
[i
* 12 + 1] = en
[1];
267 p
[i
* 12 + 4] = en
[2];
268 p
[i
* 12 + 5] = en
[3];
269 p
[i
* 12 + 8] = en
[4];
270 p
[i
* 12 + 9] = en
[5];
274 txd
->xd2
= htole32(VTOPHYS(l
->txstore
));
275 txd
->xd1
= htole32(T1_SET
| T1_TCH
| TLP_SETUPLEN
);
276 txd
->xd0
= htole32(T0_OWN
);
278 /* make sure the entire descriptors transfered to memory */
279 wbinv(l
, sizeof(struct local
));
281 CSR_WRITE(l
, TLP_RRBA
, VTOPHYS(rxd
));
282 CSR_WRITE(l
, TLP_TRBA
, VTOPHYS(txd
));
284 l
->tx
= NEXT_TXBUF(0);
286 l
->omr
|= OMR_TEN
| OMR_REN
;
291 CSR_WRITE(l
, TLP_OMR
, l
->omr
);
292 /* start TX and send setup packet */
293 CSR_WRITE(l
, TLP_TPD
, TPD_POLL
);
296 CSR_WRITE(l
, TLP_RPD
, RPD_POLL
);
302 tlp_send(void *dev
, char *buf
, u_int len
)
304 struct local
*l
= dev
;
309 txd
= &l
->txd
[l
->tx
];
310 txd
->xd2
= htole32(VTOPHYS(buf
));
311 txd
->xd1
= htole32(T1_FS
| T1_LS
| T1_TCH
| (len
& T1_TBS_MASK
));
312 txd
->xd0
= htole32(T0_OWN
);
313 wbinv(txd
, sizeof(struct desc
));
314 CSR_WRITE(l
, TLP_TPD
, TPD_POLL
);
315 l
->tx
= NEXT_TXBUF(l
->tx
);
318 if ((le32toh(txd
->xd0
) & T0_OWN
) == 0)
320 inv(txd
, sizeof(struct desc
));
322 } while (--loop
> 0);
323 printf("xmit failed\n");
330 tlp_recv(void *dev
, char *buf
, u_int maxlen
, u_int timo
)
332 struct local
*l
= dev
;
338 bound
= timo
* 1000000;
341 rxd
= &l
->rxd
[l
->rx
];
343 rxstat
= le32toh(rxd
->xd0
);
344 inv(rxd
, sizeof(struct desc
));
345 if ((rxstat
& R0_OWN
) == 0)
348 } while (--bound
> 0);
350 CSR_WRITE(l
, TLP_RPD
, RPD_POLL
);
353 if (rxstat
& R0_ES
) {
354 rxd
->xd0
= htole32(R0_OWN
);
355 wbinv(rxd
, sizeof(struct desc
));
356 l
->rx
= NEXT_RXBUF(l
->rx
);
357 CSR_WRITE(l
, TLP_RPD
, RPD_POLL
);
361 len
= ((rxstat
& R0_FL_MASK
) >> 16) - 4; /* HASFCS */
364 ptr
= l
->rxstore
[l
->rx
];
365 memcpy(buf
, ptr
, len
);
367 rxd
->xd0
= htole32(R0_OWN
);
368 wbinv(rxd
, sizeof(struct desc
));
369 l
->rx
= NEXT_RXBUF(l
->rx
);
370 CSR_WRITE(l
, TLP_OMR
, l
->omr
); /* necessary? */
375 size_srom(struct local
*l
)
377 /* determine 8/6 bit addressing SEEPROM */
379 l
->sromsft
= (read_srom(l
, 255) & 0x40000) ? 8 : 6;
383 * bare SEEPROM access with bitbang'ing
385 #define R110 6 /* SEEPROM read op */
386 #define CS (1U << 0) /* hold chip select */
387 #define CLK (1U << 1) /* clk bit */
388 #define D1 (1U << 2) /* bit existence */
389 #define D0 0 /* bit absence */
390 #define VV (1U << 3) /* taken 0/1 from SEEPROM */
393 read_srom(struct local
*l
, int off
)
396 uint32_t val
, x1
, x0
, bit
;
398 idx
= off
& 0xff; /* A7-A0 */
399 idx
|= R110
<< l
->sromsft
; /* 110 for READ */
401 val
= SROM_RD
| SROM_SR
;
402 CSR_WRITE(l
, TLP_APROM
, val
);
403 val
|= CS
; /* hold CS */
404 CSR_WRITE(l
, TLP_APROM
, val
);
406 x1
= val
| D1
; /* 1 */
407 x0
= val
| D0
; /* 0 */
408 /* instruct R110 op. at off in MSB first order */
409 for (cnt
= (1 << (l
->sromsft
+ 2)); cnt
> 0; cnt
>>= 1) {
410 bit
= (idx
& cnt
) ? x1
: x0
;
411 CSR_WRITE(l
, TLP_APROM
, bit
);
413 CSR_WRITE(l
, TLP_APROM
, bit
| CLK
);
416 /* read 16bit quantity in MSB first order */
418 for (cnt
= 16; cnt
> 0; cnt
--) {
419 CSR_WRITE(l
, TLP_APROM
, val
);
421 CSR_WRITE(l
, TLP_APROM
, val
| CLK
);
423 ret
= (ret
<< 1) | !!(CSR_READ(l
, TLP_APROM
) & VV
);
425 val
&= ~CS
; /* turn off chip select */
426 CSR_WRITE(l
, TLP_APROM
, val
);
434 tlp_mii_read(struct local
*l
, int phy
, int reg
)
441 tlp_mii_write(struct local
*l
, int phy
, int reg
, int val
)
446 #define MII_BMCR 0x00 /* Basic mode control register (rw) */
447 #define BMCR_RESET 0x8000 /* reset */
448 #define BMCR_AUTOEN 0x1000 /* autonegotiation enable */
449 #define BMCR_ISO 0x0400 /* isolate */
450 #define BMCR_STARTNEG 0x0200 /* restart autonegotiation */
451 #define MII_BMSR 0x01 /* Basic mode status register (ro) */
454 mii_initphy(struct local
*l
)
459 for (phy
= 0; phy
< 32; phy
++) {
460 ctl
= tlp_mii_read(l
, phy
, MII_BMCR
);
461 sts
= tlp_mii_read(l
, phy
, MII_BMSR
);
462 if (ctl
!= 0xffff && sts
!= 0xffff)
465 printf("MII: no PHY found\n");
468 ctl
= tlp_mii_read(l
, phy
, MII_BMCR
);
469 tlp_mii_write(l
, phy
, MII_BMCR
, ctl
| BMCR_RESET
);
473 ctl
= tlp_mii_read(l
, phy
, MII_BMCR
);
475 printf("MII: PHY %d has died after reset\n", phy
);
478 } while (bound
-- > 0 && (ctl
& BMCR_RESET
));
480 printf("PHY %d reset failed\n", phy
);
483 tlp_mii_write(l
, phy
, MII_BMCR
, ctl
);
484 sts
= tlp_mii_read(l
, phy
, MII_BMSR
) |
485 tlp_mii_read(l
, phy
, MII_BMSR
); /* read twice */
491 mii_dealan(struct local
*, u_int timo
)
496 anar
= ANAR_TX_FD
| ANAR_TX
| ANAR_10_FD
| ANAR_10
| ANAR_CSMA
;
497 tlp_mii_write(l
, l
->phy
, MII_ANAR
, anar
);
498 tlp_mii_write(l
, l
->phy
, MII_BMCR
, BMCR_AUTOEN
| BMCR_STARTNEG
);
500 bound
= getsecs() + timo
;
502 l
->bmsr
= tlp_mii_read(l
, l
->phy
, MII_BMSR
) |
503 tlp_mii_read(l
, l
->phy
, MII_BMSR
); /* read twice */
504 if ((l
->bmsr
& BMSR_LINK
) && (l
->bmsr
& BMSR_ACOMP
)) {
505 l
->anlpar
= tlp_mii_read(l
, l
->phy
, MII_ANLPAR
);
509 } while (getsecs() < bound
);