diff options
Diffstat (limited to 'sys/arch/sparc/dev/if_ie.c')
-rw-r--r-- | sys/arch/sparc/dev/if_ie.c | 191 |
1 files changed, 114 insertions, 77 deletions
diff --git a/sys/arch/sparc/dev/if_ie.c b/sys/arch/sparc/dev/if_ie.c index 20aa5204d26..3bd3defb91a 100644 --- a/sys/arch/sparc/dev/if_ie.c +++ b/sys/arch/sparc/dev/if_ie.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_ie.c,v 1.15 1995/04/11 09:18:09 pk Exp $ */ +/* $NetBSD: if_ie.c,v 1.24 1996/05/07 01:28:28 thorpej Exp $ */ /*- * Copyright (c) 1993, 1994, 1995 Charles Hannum. @@ -57,7 +57,7 @@ * * Majorly cleaned up and 3C507 code merged by Charles Hannum. * - * Converted to SUN ie driver by Charles D. Cranor, + * Converted to SUN ie driver by Charles D. Cranor, * October 1994, January 1995. * This sun version based on i386 version 1.30. */ @@ -129,6 +129,11 @@ Mode of operation: #include <netinet/if_ether.h> #endif +#ifdef NS +#include <netns/ns.h> +#include <netns/ns_if.h> +#endif + #include <vm/vm.h> /* @@ -221,7 +226,6 @@ const char *ie_hardware_names[] = { struct ie_softc { struct device sc_dev; /* device structure */ struct intrhand sc_ih; /* interrupt info */ - struct evcnt sc_intrcnt; /* # of interrupts, per ie */ caddr_t sc_iobase; /* KVA of base of 24 bit addr space */ caddr_t sc_maddr; /* KVA of base of chip's RAM (16bit addr sp.)*/ @@ -230,15 +234,18 @@ struct ie_softc { struct arpcom sc_arpcom;/* system arpcom structure */ - void (*reset_586)(); /* card dependent reset function */ - void (*chan_attn)(); /* card dependent attn function */ - void (*run_586)(); /* card depenent "go on-line" function */ + void (*reset_586) __P((struct ie_softc *)); + /* card dependent reset function */ + void (*chan_attn) __P((struct ie_softc *)); + /* card dependent attn function */ + void (*run_586) __P((struct ie_softc *)); + /* card depenent "go on-line" function */ void (*memcopy) __P((const void *, void *, u_int)); /* card dependent memory copy function */ void (*memzero) __P((void *, u_int)); /* card dependent memory zero function */ - + enum ie_hardware hard_type; /* card type */ int want_mcsetup; /* mcsetup flag */ @@ -253,10 +260,10 @@ struct ie_softc { volatile struct ie_sys_ctl_block *scb; /* - * pointer and size of a block of KVA where the buffers + * pointer and size of a block of KVA where the buffers * are to be allocated from */ - + caddr_t buf_area; int buf_area_sz; @@ -294,7 +301,7 @@ static void ie_vmereset __P((struct ie_softc *)); static void ie_vmeattend __P((struct ie_softc *)); static void ie_vmerun __P((struct ie_softc *)); -void iewatchdog __P((/* short */)); +void iewatchdog __P((struct ifnet *)); int ieintr __P((void *)); int ieinit __P((struct ie_softc *)); int ieioctl __P((struct ifnet *, u_long, caddr_t)); @@ -302,6 +309,7 @@ void iestart __P((struct ifnet *)); void iereset __P((struct ie_softc *)); static void ie_readframe __P((struct ie_softc *, int)); static void ie_drop_packet_buffer __P((struct ie_softc *)); +int ie_setupram __P((struct ie_softc *)); static int command_and_wait __P((struct ie_softc *, int, void volatile *, int)); /*static*/ void ierint __P((struct ie_softc *)); @@ -311,6 +319,20 @@ static int ieget __P((struct ie_softc *, struct mbuf **, static void setup_bufs __P((struct ie_softc *)); static int mc_setup __P((struct ie_softc *, void *)); static void mc_reset __P((struct ie_softc *)); +static __inline int ether_equal __P((u_char *, u_char *)); +static __inline void ie_ack __P((struct ie_softc *, u_int)); +static __inline void ie_setup_config __P((volatile struct ie_config_cmd *, + int, int)); +static __inline int check_eh __P((struct ie_softc *, struct ether_header *, + int *)); +static __inline int ie_buflen __P((struct ie_softc *, int)); +static __inline int ie_packet_len __P((struct ie_softc *)); +static __inline void iexmit __P((struct ie_softc *)); +static __inline caddr_t Align __P((caddr_t)); + +static void chan_attn_timeout __P((void *)); +static void run_tdr __P((struct ie_softc *, struct ie_tdr_cmd *)); +static void iestop __P((struct ie_softc *)); #ifdef IEDEBUG void print_rbd __P((volatile struct ie_recv_buf_desc *)); @@ -319,11 +341,15 @@ int in_ierint = 0; int in_ietint = 0; #endif -int iematch(); -void ieattach(); +int iematch __P((struct device *, void *, void *)); +void ieattach __P((struct device *, struct device *, void *)); -struct cfdriver iecd = { - NULL, "ie", iematch, ieattach, DV_IFNET, sizeof(struct ie_softc) +struct cfattach ie_ca = { + sizeof(struct ie_softc), iematch, ieattach +}; + +struct cfdriver ie_cd = { + NULL, "ie", DV_IFNET }; /* @@ -344,7 +370,7 @@ struct cfdriver iecd = { * Here are a few useful functions. We could have done these as macros, but * since we have the inline facility, it makes sense to use that instead. */ -static inline void +static __inline void ie_setup_config(cmd, promiscuous, manchester) volatile struct ie_config_cmd *cmd; int promiscuous, manchester; @@ -364,7 +390,7 @@ ie_setup_config(cmd, promiscuous, manchester) cmd->ie_junk = 0xff; } -static inline void +static __inline void ie_ack(sc, mask) struct ie_softc *sc; u_int mask; @@ -375,12 +401,13 @@ ie_ack(sc, mask) } -int -iematch(parent, cf, aux) +int +iematch(parent, vcf, aux) struct device *parent; - struct cfdata *cf; + void *vcf; void *aux; { + struct cfdata *cf = vcf; struct confargs *ca = aux; struct romaux *ra = &ca->ca_ra; @@ -389,7 +416,7 @@ iematch(parent, cf, aux) if (ca->ca_bustype == BUS_SBUS) return (0); - if (cputyp == CPU_SUN4) { + if (CPU_ISSUN4) { /* * XXX need better probe here so we can figure out what we've got */ @@ -408,7 +435,7 @@ iematch(parent, cf, aux) /* * MULTIBUS/VME support */ -void +void ie_vmereset(sc) struct ie_softc *sc; { @@ -418,7 +445,7 @@ ie_vmereset(sc) iev->status = 0; } -void +void ie_vmeattend(sc) struct ie_softc *sc; { @@ -428,7 +455,7 @@ ie_vmeattend(sc) iev->status &= ~IEVME_ATTEN; /* down. */ } -void +void ie_vmerun(sc) struct ie_softc *sc; { @@ -473,7 +500,8 @@ ie_obrun(sc) */ void ieattach(parent, self, aux) - struct device *parent, *self; + struct device *parent; + struct device *self; void *aux; { struct ie_softc *sc = (void *) self; @@ -511,13 +539,13 @@ ieattach(parent, self, aux) * XXX */ - ie_map = vm_map_create(pmap_kernel(), (vm_offset_t)IEOB_ADBASE, + ie_map = vm_map_create(pmap_kernel(), (vm_offset_t)IEOB_ADBASE, (vm_offset_t)IEOB_ADBASE + sc->sc_msize, 1); if (ie_map == NULL) panic("ie_map"); sc->sc_maddr = (caddr_t) kmem_alloc(ie_map, sc->sc_msize); if (sc->sc_maddr == NULL) panic("ie kmem_alloc"); kvm_uncache(sc->sc_maddr, sc->sc_msize >> PGSHIFT); - if (((u_long)sc->sc_maddr & ~(NBPG-1)) != (u_long)sc->sc_maddr) + if (((u_long)sc->sc_maddr & ~(NBPG-1)) != (u_long)sc->sc_maddr) panic("unaligned dvmamalloc breaks"); sc->sc_iobase = (caddr_t)IEOB_ADBASE; /* 24 bit base addr */ (sc->memzero)(sc->sc_maddr, sc->sc_msize); @@ -539,7 +567,7 @@ ieattach(parent, self, aux) pa = pmap_extract(pmap_kernel(), (vm_offset_t)sc->sc_maddr); if (pa == 0) panic("ie pmap_extract"); pmap_enter(pmap_kernel(), trunc_page(IEOB_ADBASE+IE_SCP_ADDR), - (vm_offset_t)pa | PMAP_NC, + (vm_offset_t)pa | PMAP_NC /*| PMAP_IOC*/, VM_PROT_READ | VM_PROT_WRITE, 1); sc->scp = (volatile struct ie_sys_conf_ptr *) @@ -574,8 +602,8 @@ ieattach(parent, self, aux) /* 4 more */ rampaddr = rampaddr | ((iev->status & IEVME_HADDR) << 16); rampaddr -= (u_long)ca->ca_ra.ra_paddr; - sc->sc_maddr = mapiodev(ca->ca_ra.ra_reg, rampaddr, sc->sc_msize, - ca->ca_bustype); + sc->sc_maddr = mapiodev(ca->ca_ra.ra_reg, rampaddr, + sc->sc_msize, ca->ca_bustype); sc->sc_iobase = sc->sc_maddr; iev->pectrl = iev->pectrl | IEVME_PARACK; /* clear to start */ @@ -623,8 +651,8 @@ ieattach(parent, self, aux) /* XXX should reclaim resources? */ return; } - ifp->if_unit = sc->sc_dev.dv_unit; - ifp->if_name = iecd.cd_name; + bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); + ifp->if_softc = sc; ifp->if_start = iestart; ifp->if_ioctl = ieioctl; ifp->if_watchdog = iewatchdog; @@ -651,6 +679,7 @@ ieattach(parent, self, aux) intr_establish(pri, &sc->sc_ih); break; case BUS_VME16: + case BUS_VME32: sc->sc_ih.ih_fun = ieintr; sc->sc_ih.ih_arg = sc; vmeintr_establish(ca->ca_ra.ra_intr[0].int_vec, pri, @@ -659,12 +688,10 @@ ieattach(parent, self, aux) #endif /* SUN4 */ } - evcnt_attach(&sc->sc_dev, "intr", &sc->sc_intrcnt); - bp = ca->ca_ra.ra_bp; if (bp != NULL && strcmp(bp->name, "ie") == 0 && sc->sc_dev.dv_unit == bp->val[1]) - bootdv = &sc->sc_dev; + bp->dev = &sc->sc_dev; } @@ -674,10 +701,10 @@ ieattach(parent, self, aux) * an interrupt after a transmit has been started on it. */ void -iewatchdog(unit) - short unit; +iewatchdog(ifp) + struct ifnet *ifp; { - struct ie_softc *sc = iecd.cd_devs[unit]; + struct ie_softc *sc = ifp->if_softc; log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); ++sc->sc_arpcom.ac_if.if_oerrors; @@ -701,12 +728,12 @@ void *v; * check for parity error */ if (sc->hard_type == IE_VME) { - volatile struct ievme *iev = (volatile struct ievme *)sc->sc_reg; - + volatile struct ievme *iev = (volatile struct ievme *)sc->sc_reg +; if (iev->status & IEVME_PERR) { printf("%s: parity error (ctrl %x @ %02x%04x)\n", - iev->pectrl, iev->pectrl & IEVME_HADDR, - iev->peaddr); + sc->sc_dev.dv_xname, iev->pectrl, + iev->pectrl & IEVME_HADDR, iev->peaddr); iev->pectrl = iev->pectrl | IEVME_PARACK; } } @@ -754,7 +781,6 @@ loop: if ((status = sc->scb->ie_status) & IE_ST_WHENCE) goto loop; - sc->sc_intrcnt.ev_count++; return 1; } @@ -777,9 +803,9 @@ ierint(sc) sc->sc_arpcom.ac_if.if_ipackets++; if (!--timesthru) { sc->sc_arpcom.ac_if.if_ierrors += - SWAP(scb->ie_err_crc) + + SWAP(scb->ie_err_crc) + SWAP(scb->ie_err_align) + - SWAP(scb->ie_err_resource) + + SWAP(scb->ie_err_resource) + SWAP(scb->ie_err_overrun); scb->ie_err_crc = scb->ie_err_align = scb->ie_err_resource = scb->ie_err_overrun = @@ -792,7 +818,7 @@ ierint(sc) (scb->ie_status & IE_RU_READY) == 0) { sc->rframes[0]->ie_fd_buf_desc = MK_16(sc->sc_maddr, sc->rbuffs[0]); - scb->ie_recv_list = + scb->ie_recv_list = MK_16(sc->sc_maddr, sc->rframes[0]); command_and_wait(sc, IE_RU_START, 0, 0); } @@ -823,7 +849,7 @@ ietint(sc) if (status & IE_STAT_OK) { sc->sc_arpcom.ac_if.if_opackets++; - sc->sc_arpcom.ac_if.if_collisions += + sc->sc_arpcom.ac_if.if_collisions += SWAP(status & IE_XS_MAXCOLL); } else if (status & IE_STAT_ABORT) { printf("%s: send aborted\n", sc->sc_dev.dv_xname); @@ -865,7 +891,7 @@ ietint(sc) * Compare two Ether/802 addresses for equality, inlined and unrolled for * speed. I'd love to have an inline assembler version of this... */ -static inline int +static __inline int ether_equal(one, two) u_char *one, *two; { @@ -888,7 +914,7 @@ ether_equal(one, two) * only client which will fiddle with IFF_PROMISC is BPF. This is * probably a good assumption, but we do not make it here. (Yet.) */ -static inline int +static __inline int check_eh(sc, eh, to_bpf) struct ie_softc *sc; struct ether_header *eh; @@ -991,7 +1017,7 @@ check_eh(sc, eh, to_bpf) * IE_RBUF_SIZE is an even power of two. If somehow the act_len exceeds * the size of the buffer, then we are screwed anyway. */ -static inline int +static __inline int ie_buflen(sc, head) struct ie_softc *sc; int head; @@ -1001,7 +1027,7 @@ ie_buflen(sc, head) & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1))); } -static inline int +static __inline int ie_packet_len(sc) struct ie_softc *sc; { @@ -1034,7 +1060,7 @@ ie_packet_len(sc) * command to the chip to be executed. On the way, if we have a BPF listener * also give him a copy. */ -inline static void +static __inline void iexmit(sc) struct ie_softc *sc; { @@ -1063,7 +1089,7 @@ iexmit(sc) sc->xmit_cmds[sc->xctail]->ie_xmit_desc = MK_16(sc->sc_maddr, sc->xmit_buffs[sc->xctail]); - sc->scb->ie_command_list = + sc->scb->ie_command_list = MK_16(sc->sc_maddr, sc->xmit_cmds[sc->xctail]); command_and_wait(sc, IE_CU_START, 0, 0); @@ -1079,7 +1105,7 @@ iexmit(sc) * length of the data available. This enables us to allocate mbuf * clusters in many situations where before we would have had a long * chain of partially-full mbufs. This should help to speed up the - * operation considerably. (Provided that it works, of course.) + * operation considerably. (Provided that it works, of course.) */ static inline int ieget(sc, mp, ehp, to_bpf) @@ -1385,7 +1411,7 @@ void iestart(ifp) struct ifnet *ifp; { - struct ie_softc *sc = iecd.cd_devs[ifp->if_unit]; + struct ie_softc *sc = ifp->if_softc; struct mbuf *m0, *m; u_char *buffer; u_short len; @@ -1408,7 +1434,7 @@ iestart(ifp) len = 0; buffer = sc->xmit_cbuffs[sc->xchead]; - for (m0 = m; m && (len +m->m_len) < IE_TBUF_SIZE; + for (m0 = m; m && (len +m->m_len) < IE_TBUF_SIZE; m = m->m_next) { bcopy(mtod(m, caddr_t), buffer, m->m_len); buffer += m->m_len; @@ -1435,7 +1461,7 @@ iestart(ifp) /* * set up IE's ram space */ -int +int ie_setupram(sc) struct ie_softc *sc; { @@ -1517,7 +1543,7 @@ iereset(sc) */ static void chan_attn_timeout(rock) - caddr_t rock; + void *rock; { *(int *)rock = 1; @@ -1528,9 +1554,9 @@ chan_attn_timeout(rock) * or be accepted, depending on the command. If the command pointer * is null, then pretend that the command is not an action command. * If the command pointer is not null, and the command is an action - * command, wait for - * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK - * to become true. + * command, wait for + * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK + * to become true. */ static int command_and_wait(sc, cmd, pcmd, mask) @@ -1638,7 +1664,7 @@ run_tdr(sc, cmd) #define ALLOC(p, n) _ALLOC(p, ALIGN(n)) /* XXX convert to this? */ #endif -static inline caddr_t +static __inline caddr_t Align(ptr) caddr_t ptr; { @@ -1661,13 +1687,11 @@ Align(ptr) * note: this function was written to be easy to understand, rather than * highly efficient (it isn't in the critical path). */ -static void +static void setup_bufs(sc) struct ie_softc *sc; { caddr_t ptr = sc->buf_area; /* memory pool */ - volatile struct ie_recv_frame_desc *rfd = (void *) ptr; - volatile struct ie_recv_buf_desc *rbd; int n, r; /* @@ -1677,14 +1701,15 @@ setup_bufs(sc) (sc->memzero)(ptr, sc->buf_area_sz); ptr = Align(ptr); /* set alignment and stick with it */ - n = (int)Align(sizeof(struct ie_xmit_cmd)) + - (int)Align(sizeof(struct ie_xmit_buf)) + IE_TBUF_SIZE; + n = (int)Align((caddr_t) sizeof(struct ie_xmit_cmd)) + + (int)Align((caddr_t) sizeof(struct ie_xmit_buf)) + IE_TBUF_SIZE; n *= NTXBUF; /* n = total size of xmit area */ n = sc->buf_area_sz - n;/* n = free space for recv stuff */ - r = (int)Align(sizeof(struct ie_recv_frame_desc)) + - (((int)Align(sizeof(struct ie_recv_buf_desc)) + IE_RBUF_SIZE) * B_PER_F); + r = (int)Align((caddr_t) sizeof(struct ie_recv_frame_desc)) + + (((int)Align((caddr_t) sizeof(struct ie_recv_buf_desc)) + + IE_RBUF_SIZE) * B_PER_F); /* r = size of one R frame */ @@ -1804,7 +1829,7 @@ mc_setup(sc, ptr) (sc->memcopy)((caddr_t)sc->mcast_addrs, (caddr_t)cmd->ie_mcast_addrs, sc->mcast_count * sizeof *sc->mcast_addrs); - cmd->ie_mcast_bytes = + cmd->ie_mcast_bytes = SWAP(sc->mcast_count * ETHER_ADDR_LEN); /* grrr... */ sc->scb->ie_command_list = MK_16(sc->sc_maddr, cmd); @@ -1831,7 +1856,6 @@ ieinit(sc) { volatile struct ie_sys_ctl_block *scb = sc->scb; void *ptr; - int n; ptr = sc->buf_area; @@ -1867,7 +1891,7 @@ ieinit(sc) cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST; cmd->com.ie_cmd_link = SWAP(0xffff); - (sc->memcopy)(sc->sc_arpcom.ac_enaddr, + (sc->memcopy)(sc->sc_arpcom.ac_enaddr, (caddr_t)&cmd->ie_address, sizeof cmd->ie_address); if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) || @@ -1920,18 +1944,13 @@ ieioctl(ifp, cmd, data) u_long cmd; caddr_t data; { - struct ie_softc *sc = iecd.cd_devs[ifp->if_unit]; + struct ie_softc *sc = ifp->if_softc; struct ifaddr *ifa = (struct ifaddr *)data; struct ifreq *ifr = (struct ifreq *)data; int s, error = 0; s = splnet(); - if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) { - splx(s); - return error; - } - switch(cmd) { case SIOCSIFADDR: @@ -1944,6 +1963,24 @@ ieioctl(ifp, cmd, data) arp_ifinit(&sc->sc_arpcom, ifa); break; #endif +#ifdef NS + /* XXX - This code is probably wrong. */ + case AF_NS: + { + struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; + + if (ns_nullhost(*ina)) + ina->x_host = + *(union ns_host *)(sc->sc_arpcom.ac_enaddr); + else + bcopy(ina->x_host.c_host, + sc->sc_arpcom.ac_enaddr, + sizeof(sc->sc_arpcom.ac_enaddr)); + /* Set new address. */ + ieinit(sc); + break; + } +#endif /* NS */ default: ieinit(sc); break; |