if_xi.c revision 1.40 1 /* $NetBSD: if_xi.c,v 1.40 2004/08/08 05:56:50 mycroft Exp $ */
2 /* OpenBSD: if_xe.c,v 1.9 1999/09/16 11:28:42 niklas Exp */
3
4 /*
5 * Copyright (c) 2004 Charles M. Hannum. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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 Charles M. Hannum.
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.
20 */
21
22 /*
23 * Copyright (c) 1999 Niklas Hallqvist, Brandon Creighton, Job de Haas
24 * All rights reserved.
25 *
26 * Redistribution and use in source and binary forms, with or without
27 * modification, are permitted provided that the following conditions
28 * are met:
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 * 3. All advertising materials mentioning features or use of this software
35 * must display the following acknowledgement:
36 * This product includes software developed by Niklas Hallqvist,
37 * Brandon Creighton and Job de Haas.
38 * 4. The name of the author may not be used to endorse or promote products
39 * derived from this software without specific prior written permission
40 *
41 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
42 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
44 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
45 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
50 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 */
52
53 /*
54 * A driver for Xircom CreditCard PCMCIA Ethernet adapters.
55 */
56
57 /*
58 * Known Bugs:
59 *
60 * 1) Promiscuous mode doesn't work on at least the CE2.
61 * 2) Slow. ~450KB/s. Memory access would be better.
62 */
63
64 #include <sys/cdefs.h>
65 __KERNEL_RCSID(0, "$NetBSD: if_xi.c,v 1.40 2004/08/08 05:56:50 mycroft Exp $");
66
67 #include "opt_inet.h"
68 #include "opt_ipx.h"
69 #include "bpfilter.h"
70
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/device.h>
74 #include <sys/ioctl.h>
75 #include <sys/mbuf.h>
76 #include <sys/malloc.h>
77 #include <sys/socket.h>
78
79 #include <net/if.h>
80 #include <net/if_dl.h>
81 #include <net/if_media.h>
82 #include <net/if_types.h>
83 #include <net/if_ether.h>
84
85 #ifdef INET
86 #include <netinet/in.h>
87 #include <netinet/in_systm.h>
88 #include <netinet/in_var.h>
89 #include <netinet/ip.h>
90 #include <netinet/if_inarp.h>
91 #endif
92
93 #ifdef IPX
94 #include <netipx/ipx.h>
95 #include <netipx/ipx_if.h>
96 #endif
97
98 #ifdef NS
99 #include <netns/ns.h>
100 #include <netns/ns_if.h>
101 #endif
102
103 #if NBPFILTER > 0
104 #include <net/bpf.h>
105 #include <net/bpfdesc.h>
106 #endif
107
108 /*
109 * Maximum number of bytes to read per interrupt. Linux recommends
110 * somewhere between 2000-22000.
111 * XXX This is currently a hard maximum.
112 */
113 #define MAX_BYTES_INTR 12000
114
115 #include <dev/mii/mii.h>
116 #include <dev/mii/miivar.h>
117
118 #include <dev/pcmcia/pcmciareg.h>
119 #include <dev/pcmcia/pcmciavar.h>
120 #include <dev/pcmcia/pcmciadevs.h>
121
122 #include <dev/pcmcia/if_xireg.h>
123 #include <dev/pcmcia/if_xivar.h>
124
125 #ifdef __GNUC__
126 #define INLINE __inline
127 #else
128 #define INLINE
129 #endif /* __GNUC__ */
130
131 #define XIDEBUG
132 #define XIDEBUG_VALUE 0
133
134 #ifdef XIDEBUG
135 #define DPRINTF(cat, x) if (xidebug & (cat)) printf x
136
137 #define XID_CONFIG 0x01
138 #define XID_MII 0x02
139 #define XID_INTR 0x04
140 #define XID_FIFO 0x08
141 #define XID_MCAST 0x10
142
143 #ifdef XIDEBUG_VALUE
144 int xidebug = XIDEBUG_VALUE;
145 #else
146 int xidebug = 0;
147 #endif
148 #else
149 #define DPRINTF(cat, x) (void)0
150 #endif
151
152 #define STATIC
153
154 STATIC void xi_cycle_power __P((struct xi_softc *));
155 STATIC int xi_ether_ioctl __P((struct ifnet *, u_long cmd, caddr_t));
156 STATIC void xi_full_reset __P((struct xi_softc *));
157 STATIC void xi_init __P((struct xi_softc *));
158 STATIC int xi_ioctl __P((struct ifnet *, u_long, caddr_t));
159 STATIC int xi_mdi_read __P((struct device *, int, int));
160 STATIC void xi_mdi_write __P((struct device *, int, int, int));
161 STATIC int xi_mediachange __P((struct ifnet *));
162 STATIC void xi_mediastatus __P((struct ifnet *, struct ifmediareq *));
163 STATIC u_int16_t xi_get __P((struct xi_softc *));
164 STATIC void xi_reset __P((struct xi_softc *));
165 STATIC void xi_set_address __P((struct xi_softc *));
166 STATIC void xi_start __P((struct ifnet *));
167 STATIC void xi_statchg __P((struct device *));
168 STATIC void xi_stop __P((struct xi_softc *));
169 STATIC void xi_watchdog __P((struct ifnet *));
170
171 void
172 xi_attach(sc, myea)
173 struct xi_softc *sc;
174 u_int8_t *myea;
175 {
176 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
177
178 #if 0
179 /*
180 * Configuration as advised by DINGO documentation.
181 * Dingo has some extra configuration registers in the CCR space.
182 */
183 if (sc->sc_chipset >= XI_CHIPSET_DINGO) {
184 struct pcmcia_mem_handle pcmh;
185 int ccr_window;
186 bus_size_t ccr_offset;
187
188 /* get access to the DINGO CCR space */
189 if (pcmcia_mem_alloc(psc->sc_pf, PCMCIA_CCR_SIZE_DINGO,
190 &pcmh)) {
191 DPRINTF(XID_CONFIG, ("xi: bad mem alloc\n"));
192 goto fail;
193 }
194 if (pcmcia_mem_map(psc->sc_pf, PCMCIA_MEM_ATTR,
195 psc->sc_pf->ccr_base, PCMCIA_CCR_SIZE_DINGO,
196 &pcmh, &ccr_offset, &ccr_window)) {
197 DPRINTF(XID_CONFIG, ("xi: bad mem map\n"));
198 pcmcia_mem_free(psc->sc_pf, &pcmh);
199 goto fail;
200 }
201
202 /* enable the second function - usually modem */
203 bus_space_write_1(pcmh.memt, pcmh.memh,
204 ccr_offset + PCMCIA_CCR_DCOR0, PCMCIA_CCR_DCOR0_SFINT);
205 bus_space_write_1(pcmh.memt, pcmh.memh,
206 ccr_offset + PCMCIA_CCR_DCOR1,
207 PCMCIA_CCR_DCOR1_FORCE_LEVIREQ | PCMCIA_CCR_DCOR1_D6);
208 bus_space_write_1(pcmh.memt, pcmh.memh,
209 ccr_offset + PCMCIA_CCR_DCOR2, 0);
210 bus_space_write_1(pcmh.memt, pcmh.memh,
211 ccr_offset + PCMCIA_CCR_DCOR3, 0);
212 bus_space_write_1(pcmh.memt, pcmh.memh,
213 ccr_offset + PCMCIA_CCR_DCOR4, 0);
214
215 /* We don't need them anymore and can free them (I think). */
216 pcmcia_mem_unmap(psc->sc_pf, ccr_window);
217 pcmcia_mem_free(psc->sc_pf, &pcmh);
218 }
219 #endif
220
221 /* Reset and initialize the card. */
222 xi_full_reset(sc);
223
224 printf("%s: MAC address %s\n", sc->sc_dev.dv_xname, ether_sprintf(myea));
225
226 ifp = &sc->sc_ethercom.ec_if;
227 /* Initialize the ifnet structure. */
228 strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
229 ifp->if_softc = sc;
230 ifp->if_start = xi_start;
231 ifp->if_ioctl = xi_ioctl;
232 ifp->if_watchdog = xi_watchdog;
233 ifp->if_flags =
234 IFF_BROADCAST | IFF_NOTRAILERS | IFF_SIMPLEX | IFF_MULTICAST;
235 IFQ_SET_READY(&ifp->if_snd);
236
237 /* 802.1q capability */
238 sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
239
240 /* Attach the interface. */
241 if_attach(ifp);
242 ether_ifattach(ifp, myea);
243
244 /*
245 * Initialize our media structures and probe the MII.
246 */
247 sc->sc_mii.mii_ifp = ifp;
248 sc->sc_mii.mii_readreg = xi_mdi_read;
249 sc->sc_mii.mii_writereg = xi_mdi_write;
250 sc->sc_mii.mii_statchg = xi_statchg;
251 ifmedia_init(&sc->sc_mii.mii_media, 0, xi_mediachange,
252 xi_mediastatus);
253 DPRINTF(XID_MII | XID_CONFIG,
254 ("xi: bmsr %x\n", xi_mdi_read(&sc->sc_dev, 0, 1)));
255
256 mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
257 MII_OFFSET_ANY, 0);
258 if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL)
259 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO, 0,
260 NULL);
261 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO);
262
263 #if NRND > 0
264 rnd_attach_source(&sc->sc_rnd_source, sc->sc_dev.dv_xname, RND_TYPE_NET, 0);
265 #endif
266 }
267
268 int
269 xi_detach(self, flags)
270 struct device *self;
271 int flags;
272 {
273 struct xi_softc *sc = (void *)self;
274 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
275
276 DPRINTF(XID_CONFIG, ("xi_detach()\n"));
277
278 if (sc->sc_enabled)
279 (*sc->sc_disable)(sc);
280
281 #if NRND > 0
282 rnd_detach_source(&sc->sc_rnd_source);
283 #endif
284
285 mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
286 ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY);
287 ether_ifdetach(ifp);
288 if_detach(ifp);
289
290 return 0;
291 }
292
293 int
294 xi_activate(self, act)
295 struct device *self;
296 enum devact act;
297 {
298 struct xi_softc *sc = (void *)self;
299 int s, rv = 0;
300
301 DPRINTF(XID_CONFIG, ("xi_activate()\n"));
302
303 s = splnet();
304 switch (act) {
305 case DVACT_ACTIVATE:
306 rv = EOPNOTSUPP;
307 break;
308
309 case DVACT_DEACTIVATE:
310 if_deactivate(&sc->sc_ethercom.ec_if);
311 break;
312 }
313 splx(s);
314 return (rv);
315 }
316
317 int
318 xi_intr(arg)
319 void *arg;
320 {
321 struct xi_softc *sc = arg;
322 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
323 u_int8_t esr, rsr, isr, rx_status, savedpage;
324 u_int16_t tx_status, recvcount = 0, tempint;
325
326 DPRINTF(XID_CONFIG, ("xi_intr()\n"));
327
328 if (sc->sc_enabled == 0 ||
329 (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
330 return (0);
331
332 ifp->if_timer = 0; /* turn watchdog timer off */
333
334 if (sc->sc_chipset >= XI_CHIPSET_MOHAWK) {
335 /* Disable interrupt (Linux does it). */
336 bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + CR,
337 0);
338 }
339
340 savedpage =
341 bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + PR);
342
343 PAGE(sc, 0);
344 esr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + ESR);
345 isr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + ISR0);
346 rsr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + RSR);
347
348 /* Check to see if card has been ejected. */
349 if (isr == 0xff) {
350 #ifdef DIAGNOSTIC
351 printf("%s: interrupt for dead card\n", sc->sc_dev.dv_xname);
352 #endif
353 goto end;
354 }
355 DPRINTF(XID_INTR, ("xi: isr=%02x\n", isr));
356
357 PAGE(sc, 0x40);
358 rx_status =
359 bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + RXST0);
360 bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + RXST0,
361 ~rx_status & 0xff);
362 tx_status =
363 bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + TXST0);
364 tx_status |=
365 bus_space_read_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + TXST1) << 8;
366 bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + TXST0,0);
367 bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + TXST1,0);
368 DPRINTF(XID_INTR, ("xi: rx_status=%02x tx_status=%04x\n", rx_status,
369 tx_status));
370
371 PAGE(sc, 0);
372 while (esr & FULL_PKT_RCV) {
373 if (!(rsr & RSR_RX_OK))
374 break;
375
376 /* Compare bytes read this interrupt to hard maximum. */
377 if (recvcount > MAX_BYTES_INTR) {
378 DPRINTF(XID_INTR,
379 ("xi: too many bytes this interrupt\n"));
380 ifp->if_iqdrops++;
381 /* Drop packet. */
382 bus_space_write_2(sc->sc_bst, sc->sc_bsh,
383 sc->sc_offset + DO0, DO_SKIP_RX_PKT);
384 }
385 tempint = xi_get(sc); /* XXX doesn't check the error! */
386 recvcount += tempint;
387 ifp->if_ibytes += tempint;
388 esr = bus_space_read_1(sc->sc_bst, sc->sc_bsh,
389 sc->sc_offset + ESR);
390 rsr = bus_space_read_1(sc->sc_bst, sc->sc_bsh,
391 sc->sc_offset + RSR);
392 }
393
394 /* Packet too long? */
395 if (rsr & RSR_TOO_LONG) {
396 ifp->if_ierrors++;
397 DPRINTF(XID_INTR, ("xi: packet too long\n"));
398 }
399
400 /* CRC error? */
401 if (rsr & RSR_CRCERR) {
402 ifp->if_ierrors++;
403 DPRINTF(XID_INTR, ("xi: CRC error detected\n"));
404 }
405
406 /* Alignment error? */
407 if (rsr & RSR_ALIGNERR) {
408 ifp->if_ierrors++;
409 DPRINTF(XID_INTR, ("xi: alignment error detected\n"));
410 }
411
412 /* Check for rx overrun. */
413 if (rx_status & RX_OVERRUN) {
414 ifp->if_ierrors++;
415 bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + CR,
416 CLR_RX_OVERRUN);
417 DPRINTF(XID_INTR, ("xi: overrun cleared\n"));
418 }
419
420 /* Try to start more packets transmitting. */
421 if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
422 xi_start(ifp);
423
424 /* Detected excessive collisions? */
425 if ((tx_status & EXCESSIVE_COLL) && ifp->if_opackets > 0) {
426 DPRINTF(XID_INTR, ("xi: excessive collisions\n"));
427 bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + CR,
428 RESTART_TX);
429 ifp->if_oerrors++;
430 }
431
432 if ((tx_status & TX_ABORT) && ifp->if_opackets > 0)
433 ifp->if_oerrors++;
434
435 /* have handled the interrupt */
436 #if NRND > 0
437 rnd_add_uint32(&sc->sc_rnd_source, tx_status);
438 #endif
439
440 end:
441 /* Reenable interrupts. */
442 PAGE(sc, savedpage);
443 bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + CR,
444 ENABLE_INT);
445
446 return (1);
447 }
448
449 /*
450 * Pull a packet from the card into an mbuf chain.
451 */
452 STATIC u_int16_t
453 xi_get(sc)
454 struct xi_softc *sc;
455 {
456 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
457 struct mbuf *top, **mp, *m;
458 u_int16_t pktlen, len, recvcount = 0;
459 u_int8_t *data;
460
461 DPRINTF(XID_CONFIG, ("xi_get()\n"));
462
463 PAGE(sc, 0);
464 pktlen =
465 bus_space_read_2(sc->sc_bst, sc->sc_bsh, sc->sc_offset + RBC0) &
466 RBC_COUNT_MASK;
467
468 DPRINTF(XID_CONFIG, ("xi_get: pktlen=%d\n", pktlen));
469
470 if (pktlen == 0) {
471 /*
472 * XXX At least one CE2 sets RBC0 == 0 occasionally, and only
473 * when MPE is set. It is not known why.
474 */
475 return (0);
476 }
477
478 /* XXX should this be incremented now ? */
479 recvcount += pktlen;
480
481 MGETHDR(m, M_DONTWAIT, MT_DATA);
482 if (m == 0)
483 return (recvcount);
484 m->m_pkthdr.rcvif = ifp;
485 m->m_pkthdr.len = pktlen;
486 m->m_flags |= M_HASFCS;
487 len = MHLEN;
488 top = 0;
489 mp = ⊤
490
491 while (pktlen > 0) {
492 if (top) {
493 MGET(m, M_DONTWAIT, MT_DATA);
494 if (m == 0) {
495 m_freem(top);
496 return (recvcount);
497 }
498 len = MLEN;
499 }
500 if (pktlen >= MINCLSIZE) {
501 MCLGET(m, M_DONTWAIT);
502 if (!(m->m_flags & M_EXT)) {
503 m_freem(m);
504 m_freem(top);
505 return (recvcount);
506 }
507 len = MCLBYTES;
508 }
509 if (!top) {
510 caddr_t newdata = (caddr_t)ALIGN(m->m_data +
511 sizeof(struct ether_header)) -
512 sizeof(struct ether_header);
513 len -= newdata - m->m_data;
514 m->m_data = newdata;
515 }
516 len = min(pktlen, len);
517 data = mtod(m, u_int8_t *);
518 if (len > 1) {
519 len &= ~1;
520 bus_space_read_multi_2(sc->sc_bst, sc->sc_bsh,
521 sc->sc_offset + EDP, (u_int16_t *)data, len>>1);
522 } else
523 *data = bus_space_read_1(sc->sc_bst, sc->sc_bsh,
524 sc->sc_offset + EDP);
525 m->m_len = len;
526 pktlen -= len;
527 *mp = m;
528 mp = &m->m_next;
529 }
530
531 /* Skip Rx packet. */
532 bus_space_write_2(sc->sc_bst, sc->sc_bsh, sc->sc_offset + DO0,
533 DO_SKIP_RX_PKT);
534
535 ifp->if_ipackets++;
536
537 #if NBPFILTER > 0
538 if (ifp->if_bpf)
539 bpf_mtap(ifp->if_bpf, top);
540 #endif
541
542 (*ifp->if_input)(ifp, top);
543 return (recvcount);
544 }
545
546 /*
547 * Serial management for the MII.
548 * The DELAY's below stem from the fact that the maximum frequency
549 * acceptable on the MDC pin is 2.5 MHz and fast processors can easily
550 * go much faster than that.
551 */
552
553 /* Let the MII serial management be idle for one period. */
554 static INLINE void xi_mdi_idle __P((struct xi_softc *));
555 static INLINE void
556 xi_mdi_idle(sc)
557 struct xi_softc *sc;
558 {
559 bus_space_tag_t bst = sc->sc_bst;
560 bus_space_handle_t bsh = sc->sc_bsh;
561 bus_size_t offset = sc->sc_offset;
562
563 /* Drive MDC low... */
564 bus_space_write_1(bst, bsh, offset + GP2, MDC_LOW);
565 DELAY(1);
566
567 /* and high again. */
568 bus_space_write_1(bst, bsh, offset + GP2, MDC_HIGH);
569 DELAY(1);
570 }
571
572 /* Pulse out one bit of data. */
573 static INLINE void xi_mdi_pulse __P((struct xi_softc *, int));
574 static INLINE void
575 xi_mdi_pulse(sc, data)
576 struct xi_softc *sc;
577 int data;
578 {
579 bus_space_tag_t bst = sc->sc_bst;
580 bus_space_handle_t bsh = sc->sc_bsh;
581 bus_size_t offset = sc->sc_offset;
582 u_int8_t bit = data ? MDIO_HIGH : MDIO_LOW;
583
584 /* First latch the data bit MDIO with clock bit MDC low...*/
585 bus_space_write_1(bst, bsh, offset + GP2, bit | MDC_LOW);
586 DELAY(1);
587
588 /* then raise the clock again, preserving the data bit. */
589 bus_space_write_1(bst, bsh, offset + GP2, bit | MDC_HIGH);
590 DELAY(1);
591 }
592
593 /* Probe one bit of data. */
594 static INLINE int xi_mdi_probe __P((struct xi_softc *sc));
595 static INLINE int
596 xi_mdi_probe(sc)
597 struct xi_softc *sc;
598 {
599 bus_space_tag_t bst = sc->sc_bst;
600 bus_space_handle_t bsh = sc->sc_bsh;
601 bus_size_t offset = sc->sc_offset;
602 u_int8_t x;
603
604 /* Pull clock bit MDCK low... */
605 bus_space_write_1(bst, bsh, offset + GP2, MDC_LOW);
606 DELAY(1);
607
608 /* Read data and drive clock high again. */
609 x = bus_space_read_1(bst, bsh, offset + GP2);
610 bus_space_write_1(bst, bsh, offset + GP2, MDC_HIGH);
611 DELAY(1);
612
613 return (x & MDIO);
614 }
615
616 /* Pulse out a sequence of data bits. */
617 static INLINE void xi_mdi_pulse_bits __P((struct xi_softc *, u_int32_t, int));
618 static INLINE void
619 xi_mdi_pulse_bits(sc, data, len)
620 struct xi_softc *sc;
621 u_int32_t data;
622 int len;
623 {
624 u_int32_t mask;
625
626 for (mask = 1 << (len - 1); mask; mask >>= 1)
627 xi_mdi_pulse(sc, data & mask);
628 }
629
630 /* Read a PHY register. */
631 STATIC int
632 xi_mdi_read(self, phy, reg)
633 struct device *self;
634 int phy;
635 int reg;
636 {
637 struct xi_softc *sc = (struct xi_softc *)self;
638 int i;
639 u_int32_t mask;
640 u_int32_t data = 0;
641
642 PAGE(sc, 2);
643 for (i = 0; i < 32; i++) /* Synchronize. */
644 xi_mdi_pulse(sc, 1);
645 xi_mdi_pulse_bits(sc, 0x06, 4); /* Start + Read opcode */
646 xi_mdi_pulse_bits(sc, phy, 5); /* PHY address */
647 xi_mdi_pulse_bits(sc, reg, 5); /* PHY register */
648 xi_mdi_idle(sc); /* Turn around. */
649 xi_mdi_probe(sc); /* Drop initial zero bit. */
650
651 for (mask = 1 << 15; mask; mask >>= 1) {
652 if (xi_mdi_probe(sc))
653 data |= mask;
654 }
655 xi_mdi_idle(sc);
656
657 DPRINTF(XID_MII,
658 ("xi_mdi_read: phy %d reg %d -> %x\n", phy, reg, data));
659
660 return (data);
661 }
662
663 /* Write a PHY register. */
664 STATIC void
665 xi_mdi_write(self, phy, reg, value)
666 struct device *self;
667 int phy;
668 int reg;
669 int value;
670 {
671 struct xi_softc *sc = (struct xi_softc *)self;
672 int i;
673
674 PAGE(sc, 2);
675 for (i = 0; i < 32; i++) /* Synchronize. */
676 xi_mdi_pulse(sc, 1);
677 xi_mdi_pulse_bits(sc, 0x05, 4); /* Start + Write opcode */
678 xi_mdi_pulse_bits(sc, phy, 5); /* PHY address */
679 xi_mdi_pulse_bits(sc, reg, 5); /* PHY register */
680 xi_mdi_pulse_bits(sc, 0x02, 2); /* Turn around. */
681 xi_mdi_pulse_bits(sc, value, 16); /* Write the data */
682 xi_mdi_idle(sc); /* Idle away. */
683
684 DPRINTF(XID_MII,
685 ("xi_mdi_write: phy %d reg %d val %x\n", phy, reg, value));
686 }
687
688 STATIC void
689 xi_statchg(self)
690 struct device *self;
691 {
692 /* XXX Update ifp->if_baudrate */
693 }
694
695 /*
696 * Change media according to request.
697 */
698 STATIC int
699 xi_mediachange(ifp)
700 struct ifnet *ifp;
701 {
702 DPRINTF(XID_CONFIG, ("xi_mediachange()\n"));
703
704 if (ifp->if_flags & IFF_UP)
705 xi_init(ifp->if_softc);
706 return (0);
707 }
708
709 /*
710 * Notify the world which media we're using.
711 */
712 STATIC void
713 xi_mediastatus(ifp, ifmr)
714 struct ifnet *ifp;
715 struct ifmediareq *ifmr;
716 {
717 struct xi_softc *sc = ifp->if_softc;
718
719 DPRINTF(XID_CONFIG, ("xi_mediastatus()\n"));
720
721 mii_pollstat(&sc->sc_mii);
722 ifmr->ifm_status = sc->sc_mii.mii_media_status;
723 ifmr->ifm_active = sc->sc_mii.mii_media_active;
724 }
725
726 STATIC void
727 xi_reset(sc)
728 struct xi_softc *sc;
729 {
730 int s;
731
732 DPRINTF(XID_CONFIG, ("xi_reset()\n"));
733
734 s = splnet();
735 xi_stop(sc);
736 xi_init(sc);
737 splx(s);
738 }
739
740 STATIC void
741 xi_watchdog(ifp)
742 struct ifnet *ifp;
743 {
744 struct xi_softc *sc = ifp->if_softc;
745
746 printf("%s: device timeout\n", sc->sc_dev.dv_xname);
747 ++ifp->if_oerrors;
748
749 xi_reset(sc);
750 }
751
752 STATIC void
753 xi_stop(sc)
754 register struct xi_softc *sc;
755 {
756 bus_space_tag_t bst = sc->sc_bst;
757 bus_space_handle_t bsh = sc->sc_bsh;
758 bus_size_t offset = sc->sc_offset;
759
760 DPRINTF(XID_CONFIG, ("xi_stop()\n"));
761
762 /* Disable interrupts. */
763 PAGE(sc, 0);
764 bus_space_write_1(bst, bsh, offset + CR, 0);
765
766 PAGE(sc, 1);
767 bus_space_write_1(bst, bsh, offset + IMR0, 0);
768
769 /* Cancel watchdog timer. */
770 sc->sc_ethercom.ec_if.if_timer = 0;
771 }
772
773 STATIC void
774 xi_init(sc)
775 struct xi_softc *sc;
776 {
777 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
778 bus_space_tag_t bst = sc->sc_bst;
779 bus_space_handle_t bsh = sc->sc_bsh;
780 bus_size_t offset = sc->sc_offset;
781 int s;
782
783 DPRINTF(XID_CONFIG, ("xi_init()\n"));
784
785 if (!sc->sc_enabled) {
786 sc->sc_enabled = 1;
787 (*sc->sc_enable)(sc);
788 xi_full_reset(sc);
789 }
790
791 s = splnet();
792
793 xi_set_address(sc);
794
795 /* Setup the ethernet interrupt mask. */
796 PAGE(sc, 1);
797 bus_space_write_1(bst, bsh, offset + IMR0,
798 ISR_TX_OFLOW | ISR_PKT_TX | ISR_MAC_INT | /* ISR_RX_EARLY | */
799 ISR_RX_FULL | ISR_RX_PKT_REJ | ISR_FORCED_INT);
800 if (sc->sc_chipset < XI_CHIPSET_DINGO) {
801 /* XXX What is this? Not for Dingo at least. */
802 /* Unmask TX underrun detection */
803 bus_space_write_1(bst, bsh, offset + IMR1, 1);
804 }
805
806 /* Enable interrupts. */
807 PAGE(sc, 0);
808 bus_space_write_1(bst, bsh, offset + CR, ENABLE_INT);
809
810 /* Set current media. */
811 mii_mediachg(&sc->sc_mii);
812
813 ifp->if_flags |= IFF_RUNNING;
814 ifp->if_flags &= ~IFF_OACTIVE;
815
816 splx(s);
817 }
818
819 /*
820 * Start outputting on the interface.
821 * Always called as splnet().
822 */
823 STATIC void
824 xi_start(ifp)
825 struct ifnet *ifp;
826 {
827 struct xi_softc *sc = ifp->if_softc;
828 bus_space_tag_t bst = sc->sc_bst;
829 bus_space_handle_t bsh = sc->sc_bsh;
830 bus_size_t offset = sc->sc_offset;
831 unsigned int s, len, pad = 0;
832 struct mbuf *m0, *m;
833 u_int16_t space;
834
835 DPRINTF(XID_CONFIG, ("xi_start()\n"));
836
837 /* Don't transmit if interface is busy or not running. */
838 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) {
839 DPRINTF(XID_CONFIG, ("xi: interface busy or not running\n"));
840 return;
841 }
842
843 /* Peek at the next packet. */
844 IFQ_POLL(&ifp->if_snd, m0);
845 if (m0 == 0)
846 return;
847
848 /* We need to use m->m_pkthdr.len, so require the header. */
849 if (!(m0->m_flags & M_PKTHDR))
850 panic("xi_start: no header mbuf");
851
852 len = m0->m_pkthdr.len;
853
854 #if 1
855 /* Pad to ETHER_MIN_LEN - ETHER_CRC_LEN. */
856 if (len < ETHER_MIN_LEN - ETHER_CRC_LEN)
857 pad = ETHER_MIN_LEN - ETHER_CRC_LEN - len;
858 #else
859 pad = 0;
860 #endif
861
862 PAGE(sc, 0);
863
864 bus_space_write_2(bst, bsh, offset + TRS, (u_int16_t)len + pad + 2);
865 space = bus_space_read_2(bst, bsh, offset + TSO) & 0x7fff;
866 if (len + pad + 2 > space) {
867 DPRINTF(XID_FIFO,
868 ("xi: not enough space in output FIFO (%d > %d)\n",
869 len + pad + 2, space));
870 return;
871 }
872
873 IFQ_DEQUEUE(&ifp->if_snd, m0);
874
875 #if NBPFILTER > 0
876 if (ifp->if_bpf)
877 bpf_mtap(ifp->if_bpf, m0);
878 #endif
879
880 /*
881 * Do the output at splhigh() so that an interrupt from another device
882 * won't cause a FIFO underrun.
883 */
884 s = splhigh();
885
886 bus_space_write_2(bst, bsh, offset + EDP, (u_int16_t)len + pad);
887 for (m = m0; m; ) {
888 if (m->m_len > 1)
889 bus_space_write_multi_2(bst, bsh, offset + EDP,
890 mtod(m, u_int16_t *), m->m_len>>1);
891 if (m->m_len & 1) {
892 DPRINTF(XID_CONFIG, ("xi: XXX odd!\n"));
893 bus_space_write_1(bst, bsh, offset + EDP,
894 *(mtod(m, u_int8_t *) + m->m_len - 1));
895 }
896 MFREE(m, m0);
897 m = m0;
898 }
899 DPRINTF(XID_CONFIG, ("xi: len=%d pad=%d total=%d\n", len, pad, len+pad+4));
900 if (sc->sc_chipset >= XI_CHIPSET_MOHAWK)
901 bus_space_write_1(bst, bsh, offset + CR, TX_PKT | ENABLE_INT);
902 else {
903 for (; pad > 1; pad -= 2)
904 bus_space_write_2(bst, bsh, offset + EDP, 0);
905 if (pad == 1)
906 bus_space_write_1(bst, bsh, offset + EDP, 0);
907 }
908
909 splx(s);
910
911 ifp->if_timer = 5;
912 ++ifp->if_opackets;
913 }
914
915 STATIC int
916 xi_ether_ioctl(ifp, cmd, data)
917 struct ifnet *ifp;
918 u_long cmd;
919 caddr_t data;
920 {
921 struct ifaddr *ifa = (struct ifaddr *)data;
922 struct xi_softc *sc = ifp->if_softc;
923
924
925 DPRINTF(XID_CONFIG, ("xi_ether_ioctl()\n"));
926
927 switch (cmd) {
928 case SIOCSIFADDR:
929 ifp->if_flags |= IFF_UP;
930
931 switch (ifa->ifa_addr->sa_family) {
932 #ifdef INET
933 case AF_INET:
934 xi_init(sc);
935 arp_ifinit(ifp, ifa);
936 break;
937 #endif /* INET */
938
939 #ifdef NS
940 case AF_NS:
941 {
942 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
943
944 if (ns_nullhost(*ina))
945 ina->x_host = *(union ns_host *)
946 LLADDR(ifp->if_sadl);
947 else
948 memcpy(LLADDR(ifp->if_sadl), ina->x_host.c_host,
949 ifp->if_addrlen);
950 /* Set new address. */
951 xi_init(sc);
952 break;
953 }
954 #endif /* NS */
955
956 default:
957 xi_init(sc);
958 break;
959 }
960 break;
961
962 default:
963 return (EINVAL);
964 }
965
966 return (0);
967 }
968
969 STATIC int
970 xi_ioctl(ifp, cmd, data)
971 struct ifnet *ifp;
972 u_long cmd;
973 caddr_t data;
974 {
975 struct xi_softc *sc = ifp->if_softc;
976 struct ifreq *ifr = (struct ifreq *)data;
977 int s, error = 0;
978
979 DPRINTF(XID_CONFIG, ("xi_ioctl()\n"));
980
981 s = splnet();
982
983 switch (cmd) {
984 case SIOCSIFADDR:
985 error = xi_ether_ioctl(ifp, cmd, data);
986 break;
987
988 case SIOCSIFFLAGS:
989 if ((ifp->if_flags & IFF_UP) == 0 &&
990 (ifp->if_flags & IFF_RUNNING) != 0) {
991 /*
992 * If interface is marked down and it is running,
993 * stop it.
994 */
995 xi_stop(sc);
996 ifp->if_flags &= ~IFF_RUNNING;
997 (*sc->sc_disable)(sc);
998 sc->sc_enabled = 0;
999 } else if ((ifp->if_flags & IFF_UP) != 0 &&
1000 (ifp->if_flags & IFF_RUNNING) == 0) {
1001 /*
1002 * If interface is marked up and it is stopped,
1003 * start it.
1004 */
1005 xi_init(sc);
1006 } else if ((ifp->if_flags & IFF_UP) != 0) {
1007 /*
1008 * Reset the interface to pick up changes in any
1009 * other flags that affect hardware registers.
1010 */
1011 xi_reset(sc);
1012 }
1013 break;
1014
1015 case SIOCADDMULTI:
1016 case SIOCDELMULTI:
1017 if (sc->sc_enabled == 0) {
1018 error = EIO;
1019 break;
1020 }
1021
1022 error = (cmd == SIOCADDMULTI) ?
1023 ether_addmulti(ifr, &sc->sc_ethercom) :
1024 ether_delmulti(ifr, &sc->sc_ethercom);
1025 if (error == ENETRESET) {
1026 /*
1027 * Multicast list has changed; set the hardware
1028 * filter accordingly.
1029 */
1030 xi_set_address(sc);
1031 error = 0;
1032 }
1033 break;
1034
1035 case SIOCSIFMEDIA:
1036 case SIOCGIFMEDIA:
1037 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
1038 break;
1039
1040 default:
1041 error = EINVAL;
1042 break;
1043 }
1044
1045 splx(s);
1046 return (error);
1047 }
1048
1049 STATIC void
1050 xi_set_address(sc)
1051 struct xi_softc *sc;
1052 {
1053 bus_space_tag_t bst = sc->sc_bst;
1054 bus_space_handle_t bsh = sc->sc_bsh;
1055 bus_size_t offset = sc->sc_offset;
1056 struct ethercom *ether = &sc->sc_ethercom;
1057 struct ifnet *ifp = &sc->sc_ethercom.ec_if;
1058 struct ether_multistep step;
1059 struct ether_multi *enm;
1060 int page, num;
1061 int i;
1062 u_int8_t x;
1063 u_int8_t *enaddr;
1064 u_int8_t indaddr[64];
1065
1066 DPRINTF(XID_CONFIG, ("xi_set_address()\n"));
1067
1068 enaddr = (u_int8_t *)LLADDR(ifp->if_sadl);
1069 if (sc->sc_chipset >= XI_CHIPSET_MOHAWK)
1070 for (i = 0; i < 6; i++)
1071 indaddr[i] = enaddr[5 - i];
1072 else
1073 for (i = 0; i < 6; i++)
1074 indaddr[i] = enaddr[i];
1075 num = 1;
1076
1077 if (ether->ec_multicnt > 9) {
1078 ifp->if_flags |= IFF_ALLMULTI;
1079 goto done;
1080 }
1081
1082 ETHER_FIRST_MULTI(step, ether, enm);
1083 for (; enm; num++) {
1084 if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
1085 sizeof(enm->enm_addrlo)) != 0) {
1086 /*
1087 * The multicast address is really a range;
1088 * it's easier just to accept all multicasts.
1089 * XXX should we be setting IFF_ALLMULTI here?
1090 */
1091 ifp->if_flags |= IFF_ALLMULTI;
1092 goto done;
1093 }
1094 if (sc->sc_chipset >= XI_CHIPSET_MOHAWK)
1095 for (i = 0; i < 6; i++)
1096 indaddr[num * 6 + i] = enm->enm_addrlo[5 - i];
1097 else
1098 for (i = 0; i < 6; i++)
1099 indaddr[num * 6 + i] = enm->enm_addrlo[i];
1100 ETHER_NEXT_MULTI(step, enm);
1101 }
1102 ifp->if_flags &= ~IFF_ALLMULTI;
1103
1104 done:
1105 if (num < 10)
1106 memset(&indaddr[num * 6], 0xff, 6 * (10 - num));
1107
1108 for (page = 0; page < 8; page++) {
1109 #ifdef XIDEBUG
1110 if (xidebug & XID_MCAST) {
1111 printf("page %d:", page);
1112 for (i = 0; i < 8; i++)
1113 printf(" %02x", indaddr[page * 8 + i]);
1114 printf("\n");
1115 }
1116 #endif
1117
1118 PAGE(sc, 0x50 + page);
1119 bus_space_write_region_1(bst, bsh, offset + IA,
1120 &indaddr[page * 8], 8);
1121 }
1122
1123 PAGE(sc, 0x42);
1124 x = SWC1_IND_ADDR;
1125 if (ifp->if_flags & IFF_PROMISC)
1126 x |= SWC1_PROMISC;
1127 if (ifp->if_flags & IFF_ALLMULTI)
1128 x |= SWC1_MCAST_PROM;
1129 if (!LIST_FIRST(&sc->sc_mii.mii_phys))
1130 x |= SWC1_AUTO_MEDIA;
1131 bus_space_write_1(sc->sc_bst, sc->sc_bsh, sc->sc_offset + SWC1, x);
1132
1133 PAGE(sc, 0);
1134 }
1135
1136 STATIC void
1137 xi_cycle_power(sc)
1138 struct xi_softc *sc;
1139 {
1140 bus_space_tag_t bst = sc->sc_bst;
1141 bus_space_handle_t bsh = sc->sc_bsh;
1142 bus_size_t offset = sc->sc_offset;
1143
1144 DPRINTF(XID_CONFIG, ("xi_cycle_power()\n"));
1145
1146 PAGE(sc, 4);
1147 DELAY(1);
1148 bus_space_write_1(bst, bsh, offset + GP1, 0);
1149 DELAY(40000);
1150 if (sc->sc_chipset >= XI_CHIPSET_MOHAWK)
1151 bus_space_write_1(bst, bsh, offset + GP1, POWER_UP);
1152 else
1153 /* XXX What is bit 2 (aka AIC)? */
1154 bus_space_write_1(bst, bsh, offset + GP1, POWER_UP | 4);
1155 DELAY(20000);
1156 }
1157
1158 STATIC void
1159 xi_full_reset(sc)
1160 struct xi_softc *sc;
1161 {
1162 bus_space_tag_t bst = sc->sc_bst;
1163 bus_space_handle_t bsh = sc->sc_bsh;
1164 bus_size_t offset = sc->sc_offset;
1165 u_int8_t x;
1166
1167 DPRINTF(XID_CONFIG, ("xi_full_reset()\n"));
1168
1169 /* Do an as extensive reset as possible on all functions. */
1170 xi_cycle_power(sc);
1171 bus_space_write_1(bst, bsh, offset + CR, SOFT_RESET);
1172 DELAY(20000);
1173 bus_space_write_1(bst, bsh, offset + CR, 0);
1174 DELAY(20000);
1175 PAGE(sc, 4);
1176 if (sc->sc_chipset >= XI_CHIPSET_MOHAWK) {
1177 /*
1178 * Drive GP1 low to power up ML6692 and GP2 high to power up
1179 * the 10MHz chip. XXX What chip is that? The phy?
1180 */
1181 bus_space_write_1(bst, bsh, offset + GP0,
1182 GP1_OUT | GP2_OUT | GP2_WR);
1183 }
1184 DELAY(500000);
1185
1186 /* Get revision information. XXX Symbolic constants. */
1187 sc->sc_rev = bus_space_read_1(bst, bsh, offset + BV) &
1188 ((sc->sc_chipset >= XI_CHIPSET_MOHAWK) ? 0x70 : 0x30) >> 4;
1189 DPRINTF(XID_CONFIG, ("xi: rev=%02x\n", sc->sc_rev));
1190
1191 /* Media selection. XXX Maybe manual overriding too? */
1192 if (sc->sc_chipset < XI_CHIPSET_MOHAWK) {
1193 /*
1194 * XXX I have no idea what this really does, it is from the
1195 * Linux driver.
1196 */
1197 bus_space_write_1(bst, bsh, offset + GP0, GP1_OUT);
1198 }
1199 DELAY(40000);
1200
1201 /*
1202 * Disable source insertion.
1203 * XXX Dingo does not have this bit, but Linux does it unconditionally.
1204 */
1205 if (sc->sc_chipset < XI_CHIPSET_DINGO) {
1206 PAGE(sc, 0x42);
1207 bus_space_write_1(bst, bsh, offset + SWC0, 0x20);
1208 }
1209
1210 /* Set the local memory dividing line. */
1211 if (sc->sc_rev != 1) {
1212 PAGE(sc, 2);
1213 /* XXX Symbolic constant preferrable. */
1214 bus_space_write_2(bst, bsh, offset + RBS0, 0x2000);
1215 }
1216
1217 /*
1218 * Apparently the receive byte pointer can be bad after a reset, so
1219 * we hardwire it correctly.
1220 */
1221 PAGE(sc, 0);
1222 bus_space_write_2(bst, bsh, offset + DO0, DO_CHG_OFFSET);
1223
1224 /* Setup ethernet MAC registers. XXX Symbolic constants. */
1225 PAGE(sc, 0x40);
1226 bus_space_write_1(bst, bsh, offset + RX0MSK,
1227 PKT_TOO_LONG | CRC_ERR | RX_OVERRUN | RX_ABORT | RX_OK);
1228 bus_space_write_1(bst, bsh, offset + TX0MSK,
1229 CARRIER_LOST | EXCESSIVE_COLL | TX_UNDERRUN | LATE_COLLISION |
1230 SQE | TX_ABORT | TX_OK);
1231 if (sc->sc_chipset < XI_CHIPSET_DINGO)
1232 /* XXX From Linux, dunno what 0xb0 means. */
1233 bus_space_write_1(bst, bsh, offset + TX1MSK, 0xb0);
1234 bus_space_write_1(bst, bsh, offset + RXST0, 0);
1235 bus_space_write_1(bst, bsh, offset + TXST0, 0);
1236 bus_space_write_1(bst, bsh, offset + TXST1, 0);
1237
1238 PAGE(sc, 2);
1239
1240 /* Enable MII function if available. */
1241 x = 0;
1242 if (LIST_FIRST(&sc->sc_mii.mii_phys))
1243 x |= SELECT_MII;
1244 bus_space_write_1(bst, bsh, offset + MSR, x);
1245 DELAY(20000);
1246
1247 /* Configure the LED registers. */
1248 /* XXX This is not good for 10base2. */
1249 if (sc->sc_chipset >= XI_CHIPSET_DINGO) {
1250 bus_space_write_1(bst, bsh, offset + LED,
1251 (LED_TX_ACT << LED1_SHIFT) | (LED_10MB_LINK << LED0_SHIFT));
1252 bus_space_write_1(bst, bsh, offset + LED3,
1253 LED_100MB_LINK << LED3_SHIFT);
1254 } else {
1255 bus_space_write_1(bst, bsh, offset + LED,
1256 (LED_TX_ACT << LED1_SHIFT) | (LED_LINK << LED0_SHIFT));
1257 }
1258
1259 /* Enable receiver and go online. */
1260 PAGE(sc, 0x40);
1261 bus_space_write_1(bst, bsh, offset + CMD0, ENABLE_RX | ONLINE);
1262
1263 #if 0 /*XXXMYC*/
1264 /* XXX This is pure magic for me, found in the Linux driver. */
1265 if ((sc->sc_flags & (XIFLAGS_DINGO | XIFLAGS_MODEM)) == XIFLAGS_MODEM) {
1266 if ((bus_space_read_1(bst, bsh, offset + 0x10) & 0x01) == 0)
1267 /* Unmask the master interrupt bit. */
1268 bus_space_write_1(bst, bsh, offset + 0x10, 0x11);
1269 }
1270 #endif
1271
1272 /*
1273 * The Linux driver says this:
1274 * We should switch back to page 0 to avoid a bug in revision 0
1275 * where regs with offset below 8 can't be read after an access
1276 * to the MAC registers.
1277 */
1278 PAGE(sc, 0);
1279 }
1280