Subject: port-arm32/8765: EtherN/EtherI card support + EtherH media Support
To: None <gnats-bugs@gnats.netbsd.org>
From: Mike Pumford <mpumford@black-star.demon.co.uk>
List: netbsd-bugs
Date: 11/08/1999 14:41:51
>Number: 8765
>Category: port-arm32
>Synopsis: EtherN/EtherI card support + EtherH media Support
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-arm32-maintainer (NetBSD/arm32 Portmaster)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Mon Nov 8 14:39:12 1999
>Last-Modified:
>Originator: Mike Pumford
>Organization:
>Release: 1.4
>Environment:
N/A
System: NetBSD black-star.demon.co.uk 1.4K NetBSD 1.4K (FOO2) #14: Tue Sep 21 21:41:06 BST 1999 mpumford@black-star.demon.co.uk:/usr/src/netbsd/sys/arch/arm32/compile/FOO2 arm32
>Description:
Patches to support Irlam instruments EtherI and Acorn EtherN cards
these cards are typically supplied in Acorn NC's. The attached patch
also adds support for media selection for Acorn/I-cubed Etherlan600
cards
>How-To-Repeat:
N/A
>Fix:
Index: if_ne_pbus.c
===================================================================
RCS file: /overflow/cvsrep/netbsd/sys/arch/arm32/podulebus/if_ne_pbus.c,v
retrieving revision 1.1.1.2
retrieving revision 1.8
diff -r1.1.1.2 -r1.8
1c1
< /* $NetBSD: if_ne_pbus.c,v 1.2 1998/10/28 00:13:53 thorpej Exp $ */
---
> /* $NetBSD: if_ne_pbus.c,v 1.1 1998/03/21 21:35:20 mark Exp $ */
10a11
> * EtherN/EtherI code Copyright (c) 1999 Mike Pumford
46c47,52
< * ICubed EtherH network slot cards
---
> * ICubed Etherlan 600 (EtherH) network slot cards
> * Irlam EtherN podules
> * Acorn EtherI podules (identical hardware to EtherN)
> *
> * Thanks go to Stephen Borrill for providing the EtherN card for testing
> * and for providing programming information for the EtherN/EtherI.
56,57c62
< * Needs to be converted to use media a'la if_ne_pci.c, not the home-grown
< * hack it currently uses.
---
> * EtherM - NetBSD style media support.
74d78
<
83a88,89
>
>
92,96c98
< void *sc_ih; /* Interrupt handler */
< int sc_mediatype; /* Media Info */
< #define NE_MEDIA_AUTO 0
< #define NE_MEDIA_10BASET 1
< #define NE_MEDIA_10BASE2 2
---
> irqhandler_t sc_ih; /* Interrupt handler */
115d116
< static void eh600_postattach __P((struct ne_pbus_softc *sc));
117a119,129
> int eh600_mediachange __P((struct dp8390_softc *));
> void eh600_mediastatus __P((struct dp8390_softc *, struct ifmediareq *));
> void eh600_init_card __P((struct dp8390_softc *));
> void eh600_init_media __P((struct dp8390_softc *, int **, int *, int *));
>
> int en_mediachange __P((struct dp8390_softc *));
> void en_mediastatus __P((struct dp8390_softc *, struct ifmediareq *));
> void en_init_card __P((struct dp8390_softc *));
> void en_init_media __P((struct dp8390_softc *, int **, int *, int *));
>
>
132,133c144,145
< unsigned char nicspace; /* fast or mod space ? */
< unsigned char asicspace; /* fast or mod space ? */
---
> unsigned char nicspace; /* easi,fast or mod space ? */
> unsigned char asicspace; /* easi,fast or mod space ? */
135a148
> #define NE_SPACE_EASI 2
144a158,165
> int (*mediachange) /* media change */
> __P((struct dp8390_softc *));
> void (*mediastatus) /* media status */
> __P((struct dp8390_softc *, struct ifmediareq *));
> void (*init_card) /* media init card */
> __P((struct dp8390_softc *));
> void (*init_media) /* media init */
> __P((struct dp8390_softc *, int **, int *, int *));
151c172,173
< "EtherM", em_ea, NULL, em_postattach
---
> "EtherM", em_ea, NULL, em_postattach,
> NULL,NULL,NULL,NULL
158c180,182
< "EtherLan 600", eh600_ea, eh600_preattach, eh600_postattach
---
> "EtherLan 600", eh600_ea, eh600_preattach, NULL,
> eh600_mediachange, eh600_mediastatus, eh600_init_card,
> eh600_init_media
165c189,209
< "EtherLan 600A", eh600_ea , eh600_preattach, eh600_postattach
---
> "EtherLan 600A", eh600_ea , eh600_preattach, NULL,
> eh600_mediachange, eh600_mediastatus, eh600_init_card,
> eh600_init_media
> },
> /* Irlam EtherN podule. (supplied with NC) */
> {
> MANUFACTURER_IRLAM ,PODULE_IRLAM_ETHERN ,EN_REGSHIFT,
> EN_NIC_OFFSET, EN_NIC_SIZE, EN_ASIC_OFFSET, EN_ASIC_SIZE,
> NE_SPACE_EASI, NE_SPACE_EASI, 0, 0,
> "EtherN", em_ea, NULL ,NULL,
> en_mediachange, en_mediastatus, en_init_card,
> en_init_media
> },
> /* Acorn EtherI podule. (supplied with NC) */
> {
> MANUFACTURER_ACORN ,PODULE_ACORN_ETHERI ,EN_REGSHIFT,
> EN_NIC_OFFSET, EN_NIC_SIZE, EN_ASIC_OFFSET, EN_ASIC_SIZE,
> NE_SPACE_EASI, NE_SPACE_EASI, 0, 0,
> "EtherI", em_ea, NULL ,NULL,
> en_mediachange, en_mediastatus, en_init_card,
> en_init_media
190a235
>
202a248,249
>
> int *media, nmedia, defmedia;
207a255,256
> media = NULL;
> nmedia = defmedia = 0;
234a284,286
> case NE_SPACE_EASI:
> ne->nicbase += npsc->sc_podule->easi_base;
> break;
243a296,298
> case NE_SPACE_EASI:
> ne->asicbase += npsc->sc_podule->easi_base;
> break;
252a308
>
287d342
< npsc->sc_mediatype = NE_MEDIA_AUTO; /* Default */
301a357,364
> /* if the interface has media support initialise it */
> if (ne->init_media) {
> dsc->sc_mediachange = ne->mediachange;
> dsc->sc_mediastatus = ne->mediastatus;
> dsc->init_card = ne->init_card;
> ne->init_media(dsc,&media,&nmedia,&defmedia);
> }
>
306c369
< ne2000_attach(nsc, myea, NULL, 0, 0);
---
> ne2000_attach(nsc, myea, media, nmedia, defmedia);
313,315c376,383
< npsc->sc_ih = intr_claim(npsc->sc_podule->interrupt, IPL_NET,
< "if_ne", dp8390_intr, dsc);
< if (npsc->sc_ih == NULL)
---
> npsc->sc_ih.ih_func = dp8390_intr;
> npsc->sc_ih.ih_arg = dsc;
> npsc->sc_ih.ih_level = IPL_NET;
> npsc->sc_ih.ih_name = "if_ne";
> npsc->sc_ih.ih_maskaddr = npsc->sc_podule->irq_addr;
> npsc->sc_ih.ih_maskbits = npsc->sc_podule->irq_mask;
>
> if (irq_claim(npsc->sc_podule->interrupt,&(npsc->sc_ih)) < 0) {
317a386
> }
383a453
>
387c457,458
< * Detect whether the BNC or UTP media attachment is being used.
---
> * pre-initialise the AT/Lantic chipset so that the card probes and
> * detects properly.
393,404c464,569
< u_int8_t tmp;
< bus_space_tag_t nict = sc->sc_ne2000.sc_dp8390.sc_regt;
< bus_space_handle_t nich = sc->sc_ne2000.sc_dp8390.sc_regh;
<
< /* now try and detect a UTP connection */
< tmp = bus_space_read_1(nict, nich, EH600_MCRB);
< tmp = (tmp & 0xf8) | EH600_10BTSEL;
< bus_space_write_1(nict, nich, EH600_MCRB, tmp);
< tmp = bus_space_read_1(nict, nich, EH600_MCRB);
< if ((tmp & 0x04) == 0x04)
< /* UTP link detected */
< sc->sc_mediatype = NE_MEDIA_10BASET;
---
> struct ne2000_softc *nsc = &sc->sc_ne2000;
> struct dp8390_softc *dsc = &nsc->sc_dp8390;
> bus_space_tag_t nict = dsc->sc_regt;
> bus_space_handle_t nich = dsc->sc_regh;
>
> /* initialise EH600 config register */
> bus_space_read_1(nict, nich, EH600_MCRA);
> bus_space_write_1(nict,nich,EH600_MCRA,0x18);
> /* XXX: we also need some more initialisation here so that the
> * card interrupts properly
> */
> }
>
> /*
> * EtherLan 600 media.
> */
> void eh600_init_media(sc, mediap,nmediap, defmediap)
> struct dp8390_softc *sc;
> int **mediap, *nmediap, *defmediap;
> {
> static int eh600_media[] = {
> IFM_ETHER|IFM_AUTO,
> IFM_ETHER|IFM_10_T,
> IFM_ETHER|IFM_10_2,
> };
> printf("%s: 10base2, 10baseT, auto, default auto\n",
> sc->sc_dev.dv_xname);
>
> *mediap = eh600_media;
> *nmediap = sizeof(eh600_media) / sizeof(eh600_media[0]);
> *defmediap = IFM_ETHER|IFM_AUTO;
> }
>
>
>
>
> void eh600_init_card(sc)
> struct dp8390_softc *sc;
> {
> struct ifmedia *ifm = &sc->sc_media;
> bus_space_tag_t nict = sc->sc_regt;
> bus_space_handle_t nich = sc->sc_regh;
> u_int8_t reg;
>
>
> /* Set basic media type. */
> switch (IFM_SUBTYPE(ifm->ifm_cur->ifm_media)) {
> case IFM_AUTO:
> /* software auto detect the media */
> reg = bus_space_read_1(nict, nich, EH600_MCRB);
> reg = (reg & 0xf8) | EH600_10BTSEL;
> bus_space_write_1(nict, nich, EH600_MCRB, reg);
> reg = bus_space_read_1(nict, nich, EH600_MCRB);
> if ((reg & 0x04) != 0x04) {
> /* No UTP use BNC */
> reg = (reg & 0xf8) | EH600_10B2SEL;
> bus_space_write_1(nict, nich, EH600_MCRB, reg);
> }
>
> break;
>
> case IFM_10_T:
> reg = bus_space_read_1(nict, nich, EH600_MCRB);
> reg = (reg & 0xf8) | EH600_10BTSEL;
> bus_space_write_1(nict, nich, EH600_MCRB, reg);
> /* seems that re-reading config B here is required to
> * prevent the interface hanging when manually selecting.
> */
> bus_space_read_1(nict, nich, EH600_MCRB);
> break;
>
> case IFM_10_2:
> reg = bus_space_read_1(nict, nich, EH600_MCRB);
> reg = (reg & 0xf8) | EH600_10B2SEL;
> bus_space_write_1(nict, nich, EH600_MCRB,reg);
> /* seems that re-reading config B here is required to
> * prevent the interface hanging when manually selecting.
> */
> bus_space_read_1(nict, nich, EH600_MCRB);
> break;
> }
> }
>
> int
> eh600_mediachange(dsc)
> struct dp8390_softc *dsc;
> {
> /* media is already set up. Interface reset will invoke new
> * new media setting. */
> dp8390_reset(dsc);
> return (0);
> }
>
>
> void
> eh600_mediastatus(sc, ifmr)
> struct dp8390_softc *sc;
> struct ifmediareq *ifmr;
> {
> bus_space_tag_t nict = sc->sc_regt;
> bus_space_handle_t nich = sc->sc_regh;
> u_int8_t reg;
> reg = bus_space_read_1(nict, nich, EH600_MCRB);
> if ((reg & 0x3) == 1) {
> ifmr->ifm_active = IFM_ETHER|IFM_10_2;
> }
406,409c571
< /* No UTP use BNC */
< tmp = (tmp & 0xf8) | EH600_10B2SEL;
< bus_space_write_1(nict, nich, EH600_MCRB, tmp);
< sc->sc_mediatype = NE_MEDIA_10BASE2;
---
> ifmr->ifm_active = IFM_ETHER|IFM_10_T;
412a575
>
414,416c577
< * eh600_postattach()
< *
< * Report the media connection detected in the preattach routine
---
> * EtherN media.
418,420c579,600
< static void
< eh600_postattach(sc)
< struct ne_pbus_softc *sc;
---
> void
> en_init_media(sc, mediap,nmediap, defmediap)
> struct dp8390_softc *sc;
> int **mediap, *nmediap, *defmediap;
> {
> static int en_media[] = {
> IFM_ETHER|IFM_10_T
> };
> printf("%s: 10baseT, default 10baseT\n",
> sc->sc_dev.dv_xname);
>
> *mediap = en_media;
> *nmediap = sizeof(en_media) / sizeof(en_media[0]);
> *defmediap = IFM_ETHER|IFM_10_T;
> }
>
>
>
>
> void
> en_init_card(sc)
> struct dp8390_softc *sc;
422,426d601
< printf("%s: using ", sc->sc_ne2000.sc_dp8390.sc_dev.dv_xname);
< if (sc->sc_mediatype == NE_MEDIA_10BASET)
< printf("10BaseT/UTP\n");
< else
< printf("10Base2/BNC\n");
427a603,620
>
> int
> en_mediachange(dsc)
> struct dp8390_softc *dsc;
> {
> /* media is static so any change is invalid. */
> return (EINVAL);
> }
>
>
> void
> en_mediastatus(sc, ifmr)
> struct dp8390_softc *sc;
> struct ifmediareq *ifmr;
> {
> ifmr->ifm_active = IFM_ETHER|IFM_10_T;
> }
>
Index: if_ne_pbusreg.h
===================================================================
RCS file: /overflow/cvsrep/netbsd/sys/arch/arm32/podulebus/if_ne_pbusreg.h,v
retrieving revision 1.1.1.1
retrieving revision 1.6
diff -r1.1.1.1 -r1.6
73a74,84
>
>
> /* Acorn EtherN registers */
> #define EN_REGSHIFT 3
> #define EN_NIC_OFFSET 0x400000 /* this seems very big */
> #define EN_NIC_SIZE (NE2000_NIC_NPORTS << EN_REGSHIFT)
> #define EN_ASIC_OFFSET (EN_NIC_OFFSET + (NE2000_ASIC_OFFSET \
> << EN_REGSHIFT))
> #define EN_ASIC_SIZE (NE2000_ASIC_NPORTS << EN_REGSHIFT)
>
>
Index: podules
===================================================================
RCS file: /overflow/cvsrep/netbsd/sys/arch/arm32/podulebus/podules,v
retrieving revision 1.1.1.3
retrieving revision 1.3
diff -r1.1.1.3 -r1.3
77a78
> podule ACORN ETHERI 0x0139 EtherI interface
98a100
> podule IRLAM ETHERN 0x5678 EtherN interface
>Audit-Trail:
>Unformatted: