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: