1 /* $NetBSD: if_ie_gsc.c,v 1.19 2009/05/24 06:53:35 skrll Exp $ */
3 /* $OpenBSD: if_ie_gsc.c,v 1.6 2001/01/12 22:57:04 mickey Exp $ */
6 * Copyright (c) 1998-2004 Michael Shalayeff
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
33 * 1. 82596DX and 82596SX High-Perfomance 32-bit Local Area Network Coprocessor
34 * Intel Corporation, November 1996, Order Number: 290219-006
36 * 2. 712 I/O Subsystem ERS Rev 1.0
37 * Hewlett-Packard, June 17 1992, Dwg No. A-A2263-66510-31
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: if_ie_gsc.c,v 1.19 2009/05/24 06:53:35 skrll Exp $");
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/device.h>
46 #include <sys/socket.h>
47 #include <sys/sockio.h>
49 #include <uvm/uvm_extern.h>
52 #include <net/if_dl.h>
53 #include <net/if_ether.h>
54 #include <net/if_types.h>
55 #include <net/if_media.h>
57 #include <netinet/in.h>
59 #include <machine/bus.h>
60 #include <machine/intr.h>
61 #include <machine/iomod.h>
62 #include <machine/autoconf.h>
64 #include <hp700/dev/cpudevs.h>
65 #include <hp700/gsc/gscbusvar.h>
66 #include <hp700/hp700/machdep.h>
68 #include <dev/ic/i82586reg.h>
69 #include <dev/ic/i82586var.h>
71 #define I82596_DEBUG I82586_DEBUG
74 * XXX fredette - I'm defining these on a hunch. When things
75 * appear to be working, remove these.
78 #define fdcache_small fdcache
79 #define pdcache_small pdcache
82 #ifdef __for_reference_only
90 #define IE_GSC_BANK_SZ (12)
91 #define IE_GSC_REG_RESET (0)
92 #define IE_GSC_REG_PORT (4)
93 #define IE_GSC_REG_ATTN (8)
95 #define IE_GSC_ALIGN(v) ((((u_int) (v)) + 0xf) & ~0xf)
97 #define IE_GSC_SYSBUS (IE_SYSBUS_596_RSVD_SET | \
98 IE_SYSBUS_596_82586 | \
99 IE_SYSBUS_596_INTLOW | \
100 IE_SYSBUS_596_TRGEXT | \
103 #define IE_SIZE 0x8000
105 struct ie_gsc_softc
{
108 /* tag and handle to hp700-specific adapter registers. */
110 bus_space_handle_t ioh
;
112 /* bus_dma_tag_t for the memory used by the adapter. */
115 /* interrupt handle. */
118 /* miscellaneous flags. */
120 #define IEGSC_GECKO (1 << 0)
123 int ie_gsc_probe(device_t
, cfdata_t
, void *);
124 void ie_gsc_attach(device_t
, device_t
, void *);
126 CFATTACH_DECL(ie_gsc
, sizeof(struct ie_gsc_softc
),
127 ie_gsc_probe
, ie_gsc_attach
, NULL
, NULL
);
129 static int ie_gsc_media
[] = {
130 IFM_ETHER
| IFM_10_2
,
132 #define IE_NMEDIA (sizeof(ie_gsc_media) / sizeof(ie_gsc_media[0]))
134 void ie_gsc_reset(struct ie_softc
*, int);
135 void ie_gsc_attend(struct ie_softc
*, int);
136 void ie_gsc_run(struct ie_softc
*);
137 void ie_gsc_port(struct ie_softc
*, u_int
);
138 uint16_t ie_gsc_read16(struct ie_softc
*, int);
139 void ie_gsc_write16(struct ie_softc
*, int, uint16_t);
140 void ie_gsc_write24(struct ie_softc
*, int, int);
141 void ie_gsc_memcopyin(struct ie_softc
*, void *, int, size_t);
142 void ie_gsc_memcopyout(struct ie_softc
*, const void *, int, size_t);
145 /* Reset the adapter. */
147 ie_gsc_reset(struct ie_softc
*sc
, int what
)
149 struct ie_gsc_softc
*gsc
= (struct ie_gsc_softc
*) sc
;
154 bus_space_write_4(gsc
->iot
, gsc
->ioh
, IE_GSC_REG_RESET
, 0);
158 bus_space_write_4(gsc
->iot
, gsc
->ioh
, IE_GSC_REG_RESET
, 0);
162 * delay for 10 system clocks + 5 transmit clocks,
163 * NB: works for system clocks over 10MHz
168 * after the hardware reset:
169 * inform i825[89]6 about new SCP address,
170 * which must be at least 16-byte aligned
172 ie_gsc_port(sc
, IE_PORT_ALT_SCP
);
173 ie_gsc_attend(sc
, what
);
175 for (i
= 9000; i
-- && ie_gsc_read16(sc
, IE_ISCP_BUSY(sc
->iscp
));
177 pdcache(0, (vaddr_t
)sc
->sc_maddr
+ sc
->iscp
, IE_ISCP_SZ
);
181 printf("timeout for PORT command (%x)%s\n",
182 ie_gsc_read16(sc
, IE_ISCP_BUSY(sc
->iscp
)),
183 (gsc
->flags
& IEGSC_GECKO
)? " on gecko":"");
191 /* Do a channel attention on the adapter. */
193 ie_gsc_attend(struct ie_softc
*sc
, int why
)
195 struct ie_gsc_softc
*gsc
= (struct ie_gsc_softc
*) sc
;
197 bus_space_write_4(gsc
->iot
, gsc
->ioh
, IE_GSC_REG_ATTN
, 0);
200 /* Enable the adapter. */
202 ie_gsc_run(struct ie_softc
*sc
)
206 /* Run an i82596 PORT command on the adapter. */
208 ie_gsc_port(struct ie_softc
*sc
, u_int cmd
)
210 struct ie_gsc_softc
*gsc
= (struct ie_gsc_softc
*) sc
;
216 case IE_PORT_SELF_TEST
:
217 cmd
|= (sc
->sc_dmamap
->dm_segs
[0].ds_addr
+ 0);
219 case IE_PORT_ALT_SCP
:
220 cmd
|= (sc
->sc_dmamap
->dm_segs
[0].ds_addr
+ sc
->scp
);
224 if (gsc
->flags
& IEGSC_GECKO
) {
225 bus_space_write_4(gsc
->iot
, gsc
->ioh
,
226 IE_GSC_REG_PORT
, (cmd
& 0xffff));
228 bus_space_write_4(gsc
->iot
, gsc
->ioh
,
229 IE_GSC_REG_PORT
, (cmd
>> 16));
232 bus_space_write_4(gsc
->iot
, gsc
->ioh
,
233 IE_GSC_REG_PORT
, (cmd
>> 16));
235 bus_space_write_4(gsc
->iot
, gsc
->ioh
,
236 IE_GSC_REG_PORT
, (cmd
& 0xffff));
242 ie_gsc_read16(struct ie_softc
*sc
, int offset
)
250 : "r" ((char *)sc
->sc_maddr
+ offset
));
255 ie_gsc_write16(struct ie_softc
*sc
, int offset
, uint16_t v
)
262 : "r" (v
), "r" ((char *)sc
->sc_maddr
+ offset
));
266 ie_gsc_write24(struct ie_softc
*sc
, int offset
, int addr
)
270 * i82586.c assumes that the chip address space starts at
271 * zero, so we have to add in the appropriate offset here.
273 addr
+= sc
->sc_dmamap
->dm_segs
[0].ds_addr
;
276 " extru %0, 15, 16, %%r22 \n"
278 " sth %%r22, 2(%1) \n"
282 : "r" (addr
), "r" ((char *)sc
->sc_maddr
+ offset
)
287 ie_gsc_memcopyin(struct ie_softc
*sc
, void *p
, int offset
, size_t size
)
289 struct ie_gsc_softc
*gsc
= (struct ie_gsc_softc
*) sc
;
294 memcpy(p
, (char *)sc
->sc_maddr
+ offset
, size
);
295 bus_dmamap_sync(gsc
->iemt
, sc
->sc_dmamap
, offset
, size
,
296 BUS_DMASYNC_PREREAD
);
297 hp700_led_blink(HP700_LED_NETRCV
);
301 ie_gsc_memcopyout(struct ie_softc
*sc
, const void *p
, int offset
, size_t size
)
303 struct ie_gsc_softc
*gsc
= (struct ie_gsc_softc
*) sc
;
308 memcpy((char *)sc
->sc_maddr
+ offset
, p
, size
);
309 bus_dmamap_sync(gsc
->iemt
, sc
->sc_dmamap
, offset
, size
,
310 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
311 hp700_led_blink(HP700_LED_NETSND
);
315 * i82596 probe routine
317 int i82596_probe(struct ie_softc
*);
319 i82596_probe(struct ie_softc
*sc
)
321 struct ie_gsc_softc
*gsc
= (struct ie_gsc_softc
*) sc
;
324 /* Set up the SCP. */
325 sc
->ie_bus_write16(sc
, IE_SCP_BUS_USE(sc
->scp
), IE_GSC_SYSBUS
);
326 sc
->ie_bus_write24(sc
, IE_SCP_ISCP(sc
->scp
), sc
->iscp
);
328 /* Set up the ISCP. */
329 sc
->ie_bus_write16(sc
, IE_ISCP_SCB(sc
->iscp
), sc
->scb
);
330 sc
->ie_bus_write24(sc
, IE_ISCP_BASE(sc
->iscp
), 0);
332 /* Set BUSY in the ISCP. */
333 sc
->ie_bus_write16(sc
, IE_ISCP_BUSY(sc
->iscp
), 1);
335 /* Reset the adapter. */
336 bus_dmamap_sync(gsc
->iemt
, sc
->sc_dmamap
, 0, sc
->sc_msize
,
337 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
338 sc
->hwreset(sc
, CARD_RESET
);
340 /* Make sure that BUSY got cleared. */
341 if (sc
->ie_bus_read16(sc
, IE_ISCP_BUSY(sc
->iscp
))) {
343 printf ("%s: ISCP set failed\n", sc
->sc_dev
.dv_xname
);
348 /* Run the chip self-test. */
349 sc
->ie_bus_write24(sc
, 0, -sc
->sc_dmamap
->dm_segs
[0].ds_addr
);
350 sc
->ie_bus_write24(sc
, 4, -(sc
->sc_dmamap
->dm_segs
[0].ds_addr
+ 1));
351 bus_dmamap_sync(gsc
->iemt
, sc
->sc_dmamap
, 0, sc
->sc_msize
,
352 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
353 ie_gsc_port(sc
, IE_PORT_SELF_TEST
);
354 for (i
= 9000; i
-- &&
355 sc
->ie_bus_read16(sc
, 4);
357 pdcache(0, (vaddr_t
)sc
->sc_maddr
, sc
->sc_msize
);
360 printf (": test %x:%x\n%s",
361 *((volatile int32_t *)((char *)sc
->sc_maddr
+ 0)),
362 *((volatile int32_t *)((char *)sc
->sc_maddr
+ 4)),
363 sc
->sc_dev
.dv_xname
);
369 ie_gsc_probe(device_t parent
, cfdata_t match
, void *aux
)
371 struct gsc_attach_args
*ga
= aux
;
373 if (ga
->ga_type
.iodc_type
!= HPPA_TYPE_FIO
||
374 (ga
->ga_type
.iodc_sv_model
!= HPPA_FIO_LAN
&&
375 ga
->ga_type
.iodc_sv_model
!= HPPA_FIO_GLAN
))
382 ie_gsc_attach(device_t parent
, device_t self
, void *aux
)
384 struct ie_gsc_softc
*gsc
= device_private(self
);
385 struct ie_softc
*sc
= &gsc
->ie
;
386 struct gsc_attach_args
*ga
= aux
;
387 bus_dma_segment_t seg
;
390 uint8_t myaddr
[ETHER_ADDR_LEN
];
392 extern int pmapdebug
;
393 int opmapdebug
= pmapdebug
;
397 if (ga
->ga_type
.iodc_sv_model
== HPPA_FIO_GLAN
)
398 gsc
->flags
|= IEGSC_GECKO
;
401 * Map the GSC registers.
403 if (bus_space_map(ga
->ga_iot
, ga
->ga_hpa
,
404 IE_GSC_BANK_SZ
, 0, &gsc
->ioh
)) {
405 printf(": can't map i/o space\n");
409 /* Set up some initial glue. */
410 gsc
->iot
= ga
->ga_iot
;
411 gsc
->iemt
= ga
->ga_dmatag
;
413 sc
->sc_msize
= IE_SIZE
;
416 * Allocate one contiguous segment of physical memory
417 * to be used with the i82596. Since we're running the
418 * chip in i82586 mode, we're restricted to 24-bit
419 * physical addresses.
421 if (bus_dmamem_alloc(gsc
->iemt
, sc
->sc_msize
, PAGE_SIZE
, 0,
422 &seg
, 1, &rseg
, BUS_DMA_NOWAIT
| BUS_DMA_24BIT
)) {
423 printf (": can't allocate %d bytes of DMA memory\n",
429 * Map that physical memory into kernel virtual space.
431 if (bus_dmamem_map(gsc
->iemt
, &seg
, rseg
, sc
->sc_msize
,
432 (void **)&sc
->sc_maddr
, BUS_DMA_NOWAIT
)) {
433 printf (": can't map DMA memory\n");
434 bus_dmamem_free(gsc
->iemt
, &seg
, rseg
);
439 * Create a DMA map for the memory.
441 if (bus_dmamap_create(gsc
->iemt
, sc
->sc_msize
, rseg
, sc
->sc_msize
,
442 0, BUS_DMA_NOWAIT
, &sc
->sc_dmamap
)) {
443 printf(": can't create DMA map\n");
444 bus_dmamem_unmap(gsc
->iemt
,
445 (void *)sc
->sc_maddr
, sc
->sc_msize
);
446 bus_dmamem_free(gsc
->iemt
, &seg
, rseg
);
451 * Load the mapped DMA memory into the DMA map.
453 if (bus_dmamap_load(gsc
->iemt
, sc
->sc_dmamap
,
454 sc
->sc_maddr
, sc
->sc_msize
,
455 NULL
, BUS_DMA_NOWAIT
)) {
456 printf(": can't load DMA map\n");
457 bus_dmamap_destroy(gsc
->iemt
, sc
->sc_dmamap
);
458 bus_dmamem_unmap(gsc
->iemt
,
459 (void *)sc
->sc_maddr
, sc
->sc_msize
);
460 bus_dmamem_free(gsc
->iemt
, &seg
, rseg
);
465 /* XXX - this should go away. */
466 sc
->bh
= (bus_space_handle_t
) sc
->sc_maddr
;
470 printf(" mem %x[%p]/%x\n%s",
471 (u_int
)sc
->sc_dmamap
->dm_segs
[0].ds_addr
,
474 sc
->sc_dev
.dv_xname
);
475 sc
->sc_debug
= IED_ALL
;
478 /* Initialize our bus glue. */
479 sc
->hwreset
= ie_gsc_reset
;
480 sc
->chan_attn
= ie_gsc_attend
;
481 sc
->hwinit
= ie_gsc_run
;
482 sc
->memcopyout
= ie_gsc_memcopyout
;
483 sc
->memcopyin
= ie_gsc_memcopyin
;
484 sc
->ie_bus_read16
= ie_gsc_read16
;
485 sc
->ie_bus_write16
= ie_gsc_write16
;
486 sc
->ie_bus_write24
= ie_gsc_write24
;
490 memset(sc
->sc_maddr
, 0, sc
->sc_msize
);
491 bus_dmamap_sync(gsc
->iemt
, sc
->sc_dmamap
, 0, sc
->sc_msize
,
492 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
495 * We use low memory to set up SCP, ICSP and SCB data
496 * structures. The remaining pages become the buffer area
497 * (managed in i82586.c).
501 * Since we have an i82596, we can control where where
502 * the chip looks for SCP. We plan to use the first
503 * two 32-bit words of memory for the self-test, so the
504 * SCP can go after that.
506 sc
->scp
= IE_GSC_ALIGN(8);
508 /* ISCP follows SCP */
509 sc
->iscp
= IE_GSC_ALIGN(sc
->scp
+ IE_SCP_SZ
);
511 /* SCB follows ISCP */
512 sc
->scb
= IE_GSC_ALIGN(sc
->iscp
+ IE_ISCP_SZ
);
514 /* The remainder of the memory is for buffers. */
515 sc
->buf_area
= IE_GSC_ALIGN(sc
->scb
+ IE_SCB_SZ
);
516 sc
->buf_area_sz
= sc
->sc_msize
- sc
->buf_area
;
518 /* Finally, we can probe the chip. */
519 rv
= i82596_probe(sc
);
521 bus_dmamap_destroy(gsc
->iemt
, sc
->sc_dmamap
);
522 bus_dmamem_unmap(gsc
->iemt
,
523 (void *)sc
->sc_maddr
, sc
->sc_msize
);
524 bus_dmamem_free(gsc
->iemt
, &seg
, rseg
);
528 pmapdebug
= opmapdebug
;
533 /* Get our Ethernet address. */
534 memcpy(myaddr
, ga
->ga_ether_address
, ETHER_ADDR_LEN
);
536 /* Set up the SCP. */
537 sc
->ie_bus_write16(sc
, IE_SCP_BUS_USE(sc
->scp
), IE_GSC_SYSBUS
);
538 sc
->ie_bus_write24(sc
, IE_SCP_ISCP(sc
->scp
), sc
->iscp
);
540 /* Set up the ISCP. */
541 sc
->ie_bus_write16(sc
, IE_ISCP_SCB(sc
->iscp
), sc
->scb
);
542 sc
->ie_bus_write24(sc
, IE_ISCP_BASE(sc
->iscp
), 0);
544 /* Set BUSY in the ISCP. */
545 sc
->ie_bus_write16(sc
, IE_ISCP_BUSY(sc
->iscp
), 1);
547 /* Reset the adapter. */
548 bus_dmamap_sync(gsc
->iemt
, sc
->sc_dmamap
, 0, sc
->sc_msize
,
549 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
550 sc
->hwreset(sc
, CARD_RESET
);
551 bus_dmamap_sync(gsc
->iemt
, sc
->sc_dmamap
, 0, sc
->sc_msize
,
552 BUS_DMASYNC_PREREAD
);
554 /* Now call the MI attachment. */
555 printf(": v%d.%d", ga
->ga_type
.iodc_model
, ga
->ga_type
.iodc_sv_rev
);
557 (gsc
->flags
& IEGSC_GECKO
) ?
560 myaddr
, ie_gsc_media
, IE_NMEDIA
, ie_gsc_media
[0]);
561 gsc
->sc_ih
= hp700_intr_establish(&sc
->sc_dev
, IPL_NET
,
563 ga
->ga_int_reg
, ga
->ga_irq
);