1 /* $NetBSD: if_netdock_nubus.c,v 1.18 2008/04/04 09:49:33 hauke Exp $ */
4 * Copyright (C) 2000,2002 Daishi Kato <daishi@axlight.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Daishi Kato
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * Asante NetDock (for Duo series) driver
35 * the chip inside is not known
39 * The author would like to thank Takeo Kuwata <tkuwata@mac.com> for
40 * his help in stabilizing this driver.
43 /***********************/
45 #include <sys/cdefs.h>
46 __KERNEL_RCSID(0, "$NetBSD: if_netdock_nubus.c,v 1.18 2008/04/04 09:49:33 hauke Exp $");
48 #include <sys/param.h>
49 #include <sys/device.h>
50 #include <sys/socket.h>
51 #include <sys/systm.h>
53 #include <sys/ioctl.h>
56 #include <net/if_dl.h>
57 #include <net/if_ether.h>
61 #include <netinet/in.h>
62 #include <netinet/if_inarp.h>
70 #include <machine/bus.h>
71 #include <machine/viareg.h>
72 #include <mac68k/nubus/nubus.h>
74 /***********************/
78 #define NETDOCK_NUBUS_CATEGORY 0x0020
79 #define NETDOCK_NUBUS_TYPE 0x0003
80 #define NETDOCK_NUBUS_DRSW 0x0103
81 #define NETDOCK_NUBUS_DRHW 0x0100
83 #define ETHERMICRODOCK_NUBUS_CATEGORY 0x0020
84 #define ETHERMICRODOCK_NUBUS_TYPE 0x0003
85 #define ETHERMICRODOCK_NUBUS_DRSW 0x0102
86 #define ETHERMICRODOCK_NUBUS_DRHW 0x0100
88 #define REG_ISR 0x000c
89 #define REG_000E 0x000e
90 #define REG_0000 0x0000
91 #define REG_0002 0x0002
92 #define REG_0004 0x0004
93 #define REG_0006 0x0006
94 #define REG_DATA 0x0008
95 #define REG_EFD00 0xefd00
97 #define ISR_ALL 0x3300
100 #define ISR_READY 0x0800
101 #define ISR_BIT_0C 0x1000
102 #define ISR_BIT_0D 0x2000
103 #define ISR_MASK 0x0033
104 #define ISR_BIT_03 0x0008
106 #define REG_0002_BIT_04 0x0010
107 #define REG_0000_BIT_08 0x0100
108 #define REG_0004_BIT_0F 0x8000
109 #define REG_0004_BIT_07 0x0080
110 #define REG_DATA_BIT_02 0x0004
111 #define REG_DATA_BIT_03 0x0008
112 #define REG_DATA_BIT_04 0x0010
113 #define REG_DATA_BIT_05 0x0020
114 #define REG_DATA_BIT_08 0x0100
115 #define REG_DATA_BIT_07 0x0080
116 #define REG_DATA_BIT_0F 0x8000
118 /***********************/
120 typedef struct netdock_softc
{
122 struct ethercom sc_ethercom
;
123 #define sc_if sc_ethercom.ec_if
125 bus_space_tag_t sc_regt
;
126 bus_space_handle_t sc_regh
;
128 u_int8_t sc_enaddr
[ETHER_ADDR_LEN
];
132 /***********************/
134 static int netdock_nubus_match(struct device
*, struct cfdata
*, void *);
135 static void netdock_nubus_attach(struct device
*, struct device
*, void *);
136 static int netdock_nb_get_enaddr(bus_space_tag_t
, bus_space_handle_t
,
137 struct nubus_attach_args
*, u_int8_t
*);
138 #ifdef NETDOCK_DEBUG_DRIVER
139 static void netdock_print_driver(bus_space_tag_t
, bus_space_handle_t
,
140 struct nubus_attach_args
*);
143 int netdock_setup(struct netdock_softc
*, u_int8_t
*);
144 void netdock_intr(void *);
146 static void netdock_watchdog(struct ifnet
*);
147 static int netdock_init(struct netdock_softc
*);
148 static int netdock_stop(struct netdock_softc
*);
149 static int netdock_ioctl(struct ifnet
*, u_long
, void *);
150 static void netdock_start(struct ifnet
*);
151 static void netdock_reset(struct netdock_softc
*);
152 static void netdock_txint(struct netdock_softc
*);
153 static void netdock_rxint(struct netdock_softc
*);
155 static u_int
netdock_put(struct netdock_softc
*, struct mbuf
*);
156 static int netdock_read(struct netdock_softc
*, int);
157 static struct mbuf
*netdock_get(struct netdock_softc
*, int);
159 /***********************/
161 #define NIC_GET_1(sc, o) (bus_space_read_1((sc)->sc_regt, \
163 #define NIC_PUT_1(sc, o, val) (bus_space_write_1((sc)->sc_regt, \
164 (sc)->sc_regh, (o), (val)))
165 #define NIC_GET_2(sc, o) (bus_space_read_2((sc)->sc_regt, \
167 #define NIC_PUT_2(sc, o, val) (bus_space_write_2((sc)->sc_regt, \
168 (sc)->sc_regh, (o), (val)))
169 #define NIC_GET_4(sc, o) (bus_space_read_4((sc)->sc_regt, \
171 #define NIC_PUT_4(sc, o, val) (bus_space_write_4((sc)->sc_regt, \
172 (sc)->sc_regh, (o), (val)))
174 #define NIC_BSET(sc, o, b) \
175 __asm volatile("bset %0,%1" : : "di" ((u_short)(b)), \
176 "g" (*(u_int8_t *)((sc)->sc_regh.base + (o))))
177 #define NIC_BCLR(sc, o, b) \
178 __asm volatile("bclr %0,%1" : : "di" ((u_short)(b)), \
179 "g" (*(u_int8_t *)((sc)->sc_regh.base + (o))))
180 #define NIC_ANDW(sc, o, b) \
181 __asm volatile("andw %0,%1" : : "di" ((u_short)(b)), \
182 "g" (*(u_int8_t *)((sc)->sc_regh.base + (o))))
183 #define NIC_ORW(sc, o, b) \
184 __asm volatile("orw %0,%1" : : "di" ((u_short)(b)), \
185 "g" (*(u_int8_t *)((sc)->sc_regh.base + (o))))
188 /***********************/
190 CFATTACH_DECL(netdock_nubus
, sizeof(struct netdock_softc
),
191 netdock_nubus_match
, netdock_nubus_attach
, NULL
, NULL
);
193 /***********************/
196 netdock_nubus_match(struct device
*parent
, struct cfdata
*cf
, void *aux
)
198 struct nubus_attach_args
*na
= (struct nubus_attach_args
*)aux
;
199 bus_space_handle_t bsh
;
202 if (bus_space_map(na
->na_tag
, NUBUS_SLOT2PA(na
->slot
),
208 if (na
->category
== NETDOCK_NUBUS_CATEGORY
&&
209 na
->type
== NETDOCK_NUBUS_TYPE
&&
210 na
->drsw
== NETDOCK_NUBUS_DRSW
) {
211 /* assuming this IS Asante NetDock */
215 if (na
->category
== ETHERMICRODOCK_NUBUS_CATEGORY
&&
216 na
->type
== ETHERMICRODOCK_NUBUS_TYPE
&&
217 na
->drsw
== ETHERMICRODOCK_NUBUS_DRSW
) {
218 /* assuming this IS Newer EtherMicroDock */
222 bus_space_unmap(na
->na_tag
, bsh
, NBMEMSIZE
);
228 netdock_nubus_attach(struct device
*parent
, struct device
*self
, void *aux
)
230 struct netdock_softc
*sc
= (struct netdock_softc
*)self
;
231 struct nubus_attach_args
*na
= (struct nubus_attach_args
*)aux
;
233 bus_space_handle_t bsh
;
234 u_int8_t enaddr
[ETHER_ADDR_LEN
];
235 const char *cardtype
;
238 if (bus_space_map(bst
, NUBUS_SLOT2PA(na
->slot
), NBMEMSIZE
, 0, &bsh
)) {
239 printf(": failed to map memory space.\n");
244 cardtype
= nubus_get_card_name(bst
, bsh
, na
->fmt
);
246 #ifdef NETDOCK_DEBUG_DRIVER
247 netdock_print_driver(bst
, bsh
, na
);
250 if (netdock_nb_get_enaddr(bst
, bsh
, na
, enaddr
)) {
251 printf(": can't find MAC address.\n");
252 bus_space_unmap(bst
, bsh
, NBMEMSIZE
);
256 if (bus_space_subregion(bst
, bsh
, 0xe00300, 0xf0000, &sc
->sc_regh
)) {
257 printf(": failed to map register space.\n");
258 bus_space_unmap(bst
, bsh
, NBMEMSIZE
);
262 printf(": %s\n", cardtype
);
264 if (netdock_setup(sc
, enaddr
)) {
265 bus_space_unmap(bst
, bsh
, NBMEMSIZE
);
269 add_nubus_intr(na
->slot
, netdock_intr
, (void *)sc
);
275 netdock_nb_get_enaddr(bus_space_tag_t bst
, bus_space_handle_t bsh
,
276 struct nubus_attach_args
*na
, u_int8_t
*ep
)
282 * these hardwired resource IDs are only for NetDock
284 nubus_get_main_dir(na
->fmt
, &dir
);
285 if (nubus_find_rsrc(bst
, bsh
, na
->fmt
, &dir
, 0x81, &dirent
) <= 0)
287 nubus_get_dir_from_rsrc(na
->fmt
, &dirent
, &dir
);
288 if (nubus_find_rsrc(bst
, bsh
, na
->fmt
, &dir
, 0x80, &dirent
) <= 0)
290 if (nubus_get_ind_data(bst
, bsh
, na
->fmt
, &dirent
,
291 ep
, ETHER_ADDR_LEN
) <= 0)
297 #ifdef NETDOCK_DEBUG_DRIVER
299 netdock_print_driver(bus_space_tag_t bst
, bus_space_handle_t bsh
,
300 struct nubus_attach_args
*na
)
302 #define HEADSIZE (8+4)
303 #define CODESIZE (6759-4)
304 unsigned char mydata
[HEADSIZE
+ CODESIZE
];
309 nubus_get_main_dir(na
->fmt
, &dir
);
310 rv
= nubus_find_rsrc(bst
, bsh
, na
->fmt
, &dir
, 0x81, &dirent
);
312 printf(": can't find sResource.\n");
315 nubus_get_dir_from_rsrc(na
->fmt
, &dirent
, &dir
);
316 if (nubus_find_rsrc(bst
, bsh
, na
->fmt
, &dir
, NUBUS_RSRC_DRVRDIR
,
318 printf(": can't find sResource.\n");
321 if (nubus_get_ind_data(bst
, bsh
, na
->fmt
,
322 &dirent
, mydata
, HEADSIZE
+CODESIZE
) <= 0) {
323 printf(": can't find indirect data.\n");
326 printf("\n########## begin driver dir");
327 for (i
= 0; i
< HEADSIZE
; i
++) {
330 printf(" %02x", mydata
[i
]);
332 printf("\n########## begin driver code");
333 for (i
= 0; i
< CODESIZE
; i
++) {
336 printf(" %02x", mydata
[i
+ HEADSIZE
]);
339 printf("\n########## begin driver code (partial)\n");
341 #define OFFSET 0x1568
342 for (i
= OFFSET
; i
< OFFSET
+ PARTSIZE
; i
++) {
343 if ((i
- OFFSET
) % 16 == 0)
345 printf(" %02x", mydata
[i
+ HEADSIZE
]);
348 printf("\n########## end\n");
354 netdock_setup(struct netdock_softc
*sc
, u_int8_t
*lladdr
)
356 struct ifnet
*ifp
= &sc
->sc_if
;
358 memcpy(sc
->sc_enaddr
, lladdr
, ETHER_ADDR_LEN
);
359 printf("%s: Ethernet address %s\n",
360 sc
->sc_dev
->dv_xname
, ether_sprintf(lladdr
));
362 memcpy(ifp
->if_xname
, device_xname(sc
->sc_dev
), IFNAMSIZ
);
364 ifp
->if_ioctl
= netdock_ioctl
;
365 ifp
->if_start
= netdock_start
;
367 IFF_BROADCAST
| IFF_SIMPLEX
| IFF_NOTRAILERS
| IFF_MULTICAST
;
368 ifp
->if_watchdog
= netdock_watchdog
;
371 ether_ifattach(ifp
, lladdr
);
377 netdock_ioctl(struct ifnet
*ifp
, u_long cmd
, void *data
)
380 struct netdock_softc
*sc
= ifp
->if_softc
;
387 ifa
= (struct ifaddr
*)data
;
388 ifp
->if_flags
|= IFF_UP
;
389 (void)netdock_init(sc
);
390 switch (ifa
->ifa_addr
->sa_family
) {
393 arp_ifinit(ifp
, ifa
);
402 if ((err
= ifioctl_common(ifp
, cmd
, data
)) != 0)
404 /* XXX see the comment in ed_ioctl() about code re-use */
405 if ((ifp
->if_flags
& IFF_UP
) == 0 &&
406 (ifp
->if_flags
& IFF_RUNNING
) != 0) {
408 ifp
->if_flags
&= ~IFF_RUNNING
;
409 } else if ((ifp
->if_flags
& IFF_UP
) != 0 &&
410 (ifp
->if_flags
& IFF_RUNNING
) == 0) {
411 (void)netdock_init(sc
);
413 temp
= ifp
->if_flags
& IFF_UP
;
415 ifp
->if_flags
|= temp
;
422 if ((err
= ether_ioctl(ifp
, cmd
, data
)) == ENETRESET
) {
423 if (ifp
->if_flags
& IFF_RUNNING
) {
424 temp
= ifp
->if_flags
& IFF_UP
;
426 ifp
->if_flags
|= temp
;
432 err
= ether_ioctl(ifp
, cmd
, data
);
440 netdock_start(struct ifnet
*ifp
)
442 struct netdock_softc
*sc
= ifp
->if_softc
;
445 if ((ifp
->if_flags
& (IFF_RUNNING
| IFF_OACTIVE
)) != IFF_RUNNING
)
449 IF_DEQUEUE(&ifp
->if_snd
, m
);
453 if ((m
->m_flags
& M_PKTHDR
) == 0)
454 panic("%s: netdock_start: no header mbuf",
455 device_xname(sc
->sc_dev
));
459 bpf_mtap(ifp
->if_bpf
, m
);
462 if ((netdock_put(sc
, m
)) == 0) {
463 IF_PREPEND(&ifp
->if_snd
, m
);
473 netdock_reset(struct netdock_softc
*sc
)
481 netdock_init(struct netdock_softc
*sc
)
487 if (sc
->sc_if
.if_flags
& IFF_RUNNING
)
493 NIC_PUT_2(sc
, REG_000E
, 0x0200);
494 NIC_PUT_2(sc
, REG_ISR
, 0);
495 NIC_PUT_2(sc
, REG_000E
, 0);
497 NIC_PUT_2(sc
, REG_0000
, 0x8104);
498 NIC_PUT_2(sc
, REG_0004
, 0x0043);
499 NIC_PUT_2(sc
, REG_000E
, 0x0100);
500 NIC_PUT_2(sc
, REG_0002
, 0x6618);
501 NIC_PUT_2(sc
, REG_0000
, 0x8010);
503 NIC_PUT_1(sc
, REG_0004
+ 0, sc
->sc_enaddr
[0]);
504 NIC_PUT_1(sc
, REG_0004
+ 1, sc
->sc_enaddr
[1]);
505 NIC_PUT_1(sc
, REG_0004
+ 2, sc
->sc_enaddr
[2]);
506 NIC_PUT_1(sc
, REG_0004
+ 3, sc
->sc_enaddr
[3]);
507 NIC_PUT_1(sc
, REG_0004
+ 4, sc
->sc_enaddr
[4]);
508 NIC_PUT_1(sc
, REG_0004
+ 5, sc
->sc_enaddr
[5]);
510 NIC_PUT_2(sc
, REG_ISR
, 0x2008);
511 NIC_PUT_2(sc
, REG_000E
, 0x0200);
512 NIC_PUT_2(sc
, REG_0000
, 0x4000);
513 NIC_PUT_2(sc
, REG_ISR
, ISR_MASK
);
517 saveisr
= NIC_GET_2(sc
, REG_ISR
);
518 NIC_PUT_2(sc
, REG_ISR
, 0);
519 savetmp
= NIC_GET_2(sc
, REG_000E
);
520 NIC_PUT_2(sc
, REG_000E
, 0x0100);
521 NIC_ANDW(sc
, REG_ISR
, ~ISR_BIT_03
);
522 NIC_PUT_2(sc
, REG_000E
, savetmp
);
525 savetmp
= NIC_GET_2(sc
, REG_000E
);
526 NIC_PUT_2(sc
, REG_000E
, 0x0100);
527 NIC_ORW(sc
, REG_ISR
, ISR_BIT_03
);
528 NIC_PUT_2(sc
, REG_000E
, savetmp
);
529 NIC_PUT_2(sc
, REG_ISR
, saveisr
);
532 sc
->sc_if
.if_flags
|= IFF_RUNNING
;
533 sc
->sc_if
.if_flags
&= ~IFF_OACTIVE
;
540 netdock_stop(struct netdock_softc
*sc
)
544 sc
->sc_if
.if_timer
= 0;
545 sc
->sc_if
.if_flags
&= ~(IFF_RUNNING
| IFF_UP
);
552 netdock_watchdog(struct ifnet
*ifp
)
554 struct netdock_softc
*sc
= ifp
->if_softc
;
557 printf("netdock_watchdog: resetting chip\n");
558 tmp
= ifp
->if_flags
& IFF_UP
;
560 ifp
->if_flags
|= tmp
;
564 netdock_put(struct netdock_softc
*sc
, struct mbuf
*m0
)
574 for (m
= m0
; m
; m
= m
->m_next
)
577 if (totlen
>= ETHER_MAX_LEN
)
578 panic("%s: netdock_put: packet overflow",
579 device_xname(sc
->sc_dev
));
585 NIC_PUT_2(sc
, REG_0000
, tmplen
);
588 while ((((isr
= NIC_GET_2(sc
, REG_ISR
)) & ISR_READY
) == 0) &&
596 tmp
= NIC_GET_2(sc
, REG_0002
);
598 NIC_PUT_2(sc
, REG_0002
, tmp
);
599 NIC_PUT_2(sc
, REG_0006
, 0x240);
600 NIC_GET_2(sc
, REG_ISR
);
601 tmplen
= ((totlen
<< 8) & 0xfe00) | ((totlen
>> 8) & 0x00ff);
602 NIC_PUT_2(sc
, REG_DATA
, tmplen
);
604 for (m
= m0
; m
; m
= m
->m_next
) {
605 u_char
*data
= mtod(m
, u_char
*);
608 u_int32_t
*data4
= (u_int32_t
*)data
;
609 for (i
= 0; i
< len4
; i
++)
610 NIC_PUT_4(sc
, REG_DATA
, data4
[i
]);
611 for (i
= len4
<< 2; i
< len
; i
++)
612 NIC_PUT_1(sc
, REG_DATA
, data
[i
]);
616 NIC_PUT_2(sc
, REG_DATA
, 0x2020);
618 NIC_PUT_2(sc
, REG_DATA
, 0);
620 NIC_PUT_2(sc
, REG_0000
, 0xc000);
623 /* sc->sc_if.if_timer = 5; */
628 netdock_intr(void *arg
)
630 struct netdock_softc
*sc
= (struct netdock_softc
*)arg
;
634 NIC_PUT_2(sc
, REG_ISR
, 0);
635 while ((isr
= (NIC_GET_2(sc
, REG_ISR
) & ISR_ALL
)) != 0) {
642 if (isr
& (ISR_BIT_0C
| ISR_BIT_0D
)) {
643 if (isr
& ISR_BIT_0C
) {
644 NIC_PUT_2(sc
, REG_000E
, 0);
645 NIC_BSET(sc
, REG_0004
, 0x08);
646 NIC_PUT_2(sc
, REG_000E
, 0x0200);
648 if (isr
& ISR_BIT_0D
) {
649 NIC_PUT_2(sc
, REG_000E
, 0);
650 tmp
= NIC_GET_2(sc
, REG_0002
);
651 if (tmp
& REG_0002_BIT_04
)
652 NIC_GET_2(sc
, REG_0006
);
653 tmp
= NIC_GET_2(sc
, REG_0000
);
654 if (tmp
& REG_0000_BIT_08
)
655 NIC_BSET(sc
, REG_0000
, 0x08);
656 NIC_PUT_2(sc
, REG_000E
, 0x0200);
658 NIC_PUT_2(sc
, REG_ISR
, isr
);
661 NIC_PUT_2(sc
, REG_ISR
, ISR_MASK
);
665 netdock_txint(struct netdock_softc
*sc
)
667 struct ifnet
*ifp
= &sc
->sc_if
;
672 ifp
->if_flags
&= ~IFF_OACTIVE
;
675 savereg0002
= NIC_GET_2(sc
, REG_0002
);
677 while (((reg0004
= NIC_GET_2(sc
, REG_0004
)) & REG_0004_BIT_0F
) == 0) {
678 NIC_PUT_2(sc
, REG_0002
, reg0004
);
679 NIC_PUT_2(sc
, REG_0006
, 0x0060);
680 NIC_GET_2(sc
, REG_ISR
);
681 regdata
= NIC_GET_2(sc
, REG_DATA
);
682 if ((regdata
& REG_DATA_BIT_08
) == 0) {
683 /* ifp->if_collisions++; */
684 if (regdata
& REG_DATA_BIT_07
)
685 /* ifp->if_oerrors++; */
686 NIC_PUT_2(sc
, REG_000E
, 0);
687 NIC_ORW(sc
, REG_0000
, 0x0100);
688 NIC_PUT_2(sc
, REG_000E
, 0x0200);
690 NIC_GET_2(sc
,REG_DATA
);
692 if (regdata
& REG_DATA_BIT_0F
)
693 NIC_GET_4(sc
, REG_EFD00
);
694 NIC_PUT_2(sc
, REG_0000
, 0xa000);
695 NIC_PUT_2(sc
, REG_ISR
, ISR_TX
);
698 NIC_PUT_2(sc
, REG_0002
, savereg0002
);
699 NIC_PUT_2(sc
, REG_000E
, 0);
700 NIC_GET_2(sc
, REG_0006
);
701 NIC_PUT_2(sc
, REG_000E
, 0x0200);
702 NIC_PUT_2(sc
, REG_0006
, 0);
706 netdock_rxint(struct netdock_softc
*sc
)
708 struct ifnet
*ifp
= &sc
->sc_if
;
714 while ((NIC_GET_2(sc
, REG_0004
) & REG_0004_BIT_07
) == 0) {
715 NIC_GET_2(sc
, REG_ISR
);
716 NIC_PUT_2(sc
, REG_0006
, 0x00e0);
717 NIC_GET_2(sc
, REG_ISR
);
718 regdata1
= NIC_GET_2(sc
, REG_DATA
);
719 regdata2
= NIC_GET_2(sc
, REG_DATA
);
720 len
= ((regdata2
<< 8) & 0x0700) | ((regdata2
>> 8) & 0x00ff);
723 printf("netdock_rxint: r1=0x%04x, r2=0x%04x, len=%d\n",
724 regdata1
, regdata2
, len
);
727 if ((regdata1
& REG_DATA_BIT_04
) == 0)
730 /* CRC is included with the packet; trim it off. */
731 len
-= ETHER_CRC_LEN
;
733 if ((regdata1
& 0x00ac) == 0) {
734 if (netdock_read(sc
, len
))
741 if (regdata1
& REG_DATA_BIT_02
)
742 NIC_GET_4(sc
, REG_EFD00
);
743 if (regdata1
& REG_DATA_BIT_03
)
745 if (regdata1
& REG_DATA_BIT_05
)
746 NIC_GET_4(sc
, REG_EFD00
);
747 if (regdata1
& REG_DATA_BIT_07
)
752 while ((NIC_GET_2(sc
, REG_0000
) & REG_0000_BIT_08
) && timeout
--)
757 NIC_PUT_2(sc
, REG_0000
, 0x8000);
759 NIC_PUT_2(sc
, REG_0006
, 0);
763 netdock_read(struct netdock_softc
*sc
, int len
)
765 struct ifnet
*ifp
= &sc
->sc_if
;
768 m
= netdock_get(sc
, len
);
774 bpf_mtap(ifp
->if_bpf
, m
);
777 (*ifp
->if_input
)(ifp
, m
);
783 netdock_get(struct netdock_softc
*sc
, int datalen
)
785 struct mbuf
*m
, *top
, **mp
;
792 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
795 m
->m_pkthdr
.rcvif
= &sc
->sc_if
;
796 m
->m_pkthdr
.len
= datalen
;
801 while (datalen
> 0) {
803 MGET(m
, M_DONTWAIT
, MT_DATA
);
810 if (datalen
>= MINCLSIZE
) {
811 MCLGET(m
, M_DONTWAIT
);
812 if ((m
->m_flags
& M_EXT
) == 0) {
821 char *newdata
= (char *)
822 ALIGN(m
->m_data
+ sizeof(struct ether_header
)) -
823 sizeof(struct ether_header
);
824 len
-= newdata
- m
->m_data
;
828 m
->m_len
= len
= min(datalen
, len
);
830 data
= mtod(m
, u_char
*);
832 data4
= (u_int32_t
*)data
;
833 for (i
= 0; i
< len4
; i
++)
834 data4
[i
] = NIC_GET_4(sc
, REG_DATA
);
835 for (i
= len4
<< 2; i
< len
; i
++)
836 data
[i
] = NIC_GET_1(sc
, REG_DATA
);