Home | History | Annotate | Line # | Download | only in ibus
if_le_ibus.c revision 1.1.2.1
      1 /*	$NetBSD: if_le_ibus.c,v 1.1.2.1 1998/10/15 02:41:16 nisimura Exp $	*/
      2 
      3 /*
      4  * Copyright 1996 The Board of Trustees of The Leland Stanford
      5  * Junior University. All Rights Reserved.
      6  *
      7  * Permission to use, copy, modify, and distribute this
      8  * software and its documentation for any purpose and without
      9  * fee is hereby granted, provided that the above copyright
     10  * notice appear in all copies.  Stanford University
     11  * makes no representations about the suitability of this
     12  * software for any purpose.  It is provided "as is" without
     13  * express or implied warranty.
     14  *
     15  * This driver was contributed by Jonathan Stone.
     16  */
     17 
     18 /*
     19  * LANCE on Decstation kn01/kn230 baseboard.
     20  */
     21 #include "opt_inet.h"
     22 
     23 #include <sys/param.h>
     24 #include <sys/systm.h>
     25 #include <sys/mbuf.h>
     26 #include <sys/syslog.h>
     27 #include <sys/socket.h>
     28 #include <sys/device.h>
     29 
     30 #include <net/if.h>
     31 #include <net/if_ether.h>
     32 #include <net/if_media.h>
     33 
     34 #ifdef INET
     35 #include <netinet/in.h>
     36 #include <netinet/if_inarp.h>
     37 #endif
     38 
     39 #include <dev/ic/lancereg.h>
     40 #include <dev/ic/lancevar.h>
     41 #include <dev/ic/am7990reg.h>
     42 #include <dev/ic/am7990var.h>
     43 
     44 #include <dev/tc/if_levar.h>
     45 #include <dev/tc/tcvar.h>
     46 #include <machine/autoconf.h>
     47 #include <pmax/ibus/ibusvar.h>
     48 #include <pmax/pmax/kn01.h>
     49 
     50 extern void le_dec_copytobuf_gap2 __P((struct lance_softc *, void *,
     51 	    int, int));
     52 extern void le_dec_copyfrombuf_gap2 __P((struct lance_softc *, void *,
     53 	    int, int));
     54 
     55 #if defined(_KERNEL) && !defined(_LKM)
     56 #include "opt_ddb.h"
     57 #endif
     58 
     59 #ifdef DDB
     60 #define	integrate
     61 #define hide
     62 #else
     63 #define	integrate	static __inline
     64 #define hide		static
     65 #endif
     66 
     67 hide void le_dec_zerobuf_gap2 __P((struct lance_softc *, int, int));
     68 
     69 
     70 int	le_pmax_match __P((struct device *, struct cfdata *, void *));
     71 void	le_pmax_attach __P((struct device *, struct device *, void *));
     72 
     73 struct cfattach le_pmax_ca = {
     74 	sizeof(struct le_softc), le_pmax_match, le_pmax_attach
     75 };
     76 
     77 int
     78 le_pmax_match(parent, match, aux)
     79 	struct device *parent;
     80 	struct cfdata *match;
     81 	void *aux;
     82 {
     83   	struct ibus_attach_args *d = aux;
     84 #define	CFNAME(cf) ((cf)->dv_cfdata->cf_driver->cd_name)
     85 
     86 	if (strcmp(CFNAME(parent), "ibus") != 0)
     87 		return (0);
     88 	if (strcmp("lance", d->ia_name) != 0)
     89 		return (0);
     90 	return (1);
     91 #undef CFNAME
     92 }
     93 
     94 void
     95 le_pmax_attach(parent, self, aux)
     96 	struct device *parent, *self;
     97 	void *aux;
     98 {
     99 	register struct le_softc *lesc = (void *)self;
    100 	register struct lance_softc *sc = &lesc->sc_am7990.lsc;
    101 	register u_char *cp;
    102 	register struct ibus_attach_args *ia = aux;
    103 
    104 	/*
    105 	 * It's on the baseboard, with a dedicated interrupt line.
    106 	 */
    107 	lesc->sc_r1 = (struct lereg1 *)(ia->ia_addr);
    108 /*XXX*/	sc->sc_mem = (void *)TC_PHYS_TO_UNCACHED(0x19000000);
    109 /*XXX*/	cp = (u_char *)(TC_PHYS_TO_UNCACHED(KN01_SYS_CLOCK) + 1);
    110 
    111 	sc->sc_copytodesc = le_dec_copytobuf_gap2;
    112 	sc->sc_copyfromdesc = le_dec_copyfrombuf_gap2;
    113 	sc->sc_copytobuf = le_dec_copytobuf_gap2;
    114 	sc->sc_copyfrombuf = le_dec_copyfrombuf_gap2;
    115 	sc->sc_zerobuf = le_dec_zerobuf_gap2;
    116 
    117 	dec_le_common_attach(&lesc->sc_am7990, cp);
    118 
    119 	ibus_intr_establish(parent, ia->ia_cookie, IPL_NET, am7990_intr, sc);
    120 }
    121 
    122 /*
    123  * gap2: two bytes of data followed by two bytes of pad.
    124  *
    125  * Buffers must be 4-byte aligned.  The code doesn't worry about
    126  * doing an extra byte.
    127  */
    128 
    129 void
    130 le_dec_copytobuf_gap2(sc, fromv, boff, len)
    131 	struct lance_softc *sc;
    132 	void *fromv;
    133 	int boff;
    134 	register int len;
    135 {
    136 	volatile caddr_t buf = sc->sc_mem;
    137 	register caddr_t from = fromv;
    138 	register volatile u_int16_t *bptr;
    139 
    140 	if (boff & 0x1) {
    141 		/* handle unaligned first byte */
    142 		bptr = ((volatile u_int16_t *)buf) + (boff - 1);
    143 		*bptr = (*from++ << 8) | (*bptr & 0xff);
    144 		bptr += 2;
    145 		len--;
    146 	} else
    147 		bptr = ((volatile u_int16_t *)buf) + boff;
    148 	while (len > 1) {
    149 		*bptr = (from[1] << 8) | (from[0] & 0xff);
    150 		bptr += 2;
    151 		from += 2;
    152 		len -= 2;
    153 	}
    154 	if (len == 1)
    155 		*bptr = (u_int16_t)*from;
    156 }
    157 
    158 void
    159 le_dec_copyfrombuf_gap2(sc, tov, boff, len)
    160 	struct lance_softc *sc;
    161 	void *tov;
    162 	int boff, len;
    163 {
    164 	volatile caddr_t buf = sc->sc_mem;
    165 	register caddr_t to = tov;
    166 	register volatile u_int16_t *bptr;
    167 	register u_int16_t tmp;
    168 
    169 	if (boff & 0x1) {
    170 		/* handle unaligned first byte */
    171 		bptr = ((volatile u_int16_t *)buf) + (boff - 1);
    172 		*to++ = (*bptr >> 8) & 0xff;
    173 		bptr += 2;
    174 		len--;
    175 	} else
    176 		bptr = ((volatile u_int16_t *)buf) + boff;
    177 	while (len > 1) {
    178 		tmp = *bptr;
    179 		*to++ = tmp & 0xff;
    180 		*to++ = (tmp >> 8) & 0xff;
    181 		bptr += 2;
    182 		len -= 2;
    183 	}
    184 	if (len == 1)
    185 		*to = *bptr & 0xff;
    186 }
    187 
    188 void
    189 le_dec_zerobuf_gap2(sc, boff, len)
    190 	struct lance_softc *sc;
    191 	int boff, len;
    192 {
    193 	volatile caddr_t buf = sc->sc_mem;
    194 	register volatile u_int16_t *bptr;
    195 
    196 	if ((unsigned)boff & 0x1) {
    197 		bptr = ((volatile u_int16_t *)buf) + (boff - 1);
    198 		*bptr &= 0xff;
    199 		bptr += 2;
    200 		len--;
    201 	} else
    202 		bptr = ((volatile u_int16_t *)buf) + boff;
    203 	while (len > 0) {
    204 		*bptr = 0;
    205 		bptr += 2;
    206 		len -= 2;
    207 	}
    208 }
    209