1139749Simp/*-
2150108Simp * Copyright (c) 2005, M. Warner Losh
352245Smdodd * Copyright (c) 1995, David Greenman
452245Smdodd * All rights reserved.
552245Smdodd *
652245Smdodd * Redistribution and use in source and binary forms, with or without
752245Smdodd * modification, are permitted provided that the following conditions
852245Smdodd * are met:
952245Smdodd * 1. Redistributions of source code must retain the above copyright
1052245Smdodd *    notice unmodified, this list of conditions, and the following
1152245Smdodd *    disclaimer.
1252245Smdodd * 2. Redistributions in binary form must reproduce the above copyright
1352245Smdodd *    notice, this list of conditions and the following disclaimer in the
1452245Smdodd *    documentation and/or other materials provided with the distribution.
1552245Smdodd *
1652245Smdodd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1752245Smdodd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1852245Smdodd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1952245Smdodd * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2052245Smdodd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2152245Smdodd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2252245Smdodd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2352245Smdodd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2452245Smdodd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2552245Smdodd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2652245Smdodd * SUCH DAMAGE.
2752245Smdodd *
2852245Smdodd * $FreeBSD$
2952245Smdodd */
3052245Smdodd
31150300Simp/*
32150300Simp * Notes for adding media support.  Each chipset is somewhat different
33150300Simp * from the others.  Linux has a table of OIDs that it uses to see what
34150300Simp * supports the misc register of the NS83903.  But a sampling of datasheets
35150300Simp * I could dig up on cards I own paints a different picture.
36150300Simp *
37150300Simp * Chipset specific details:
38150300Simp * NS 83903/902A paired
39150300Simp *    ccr base 0x1020
40150300Simp *    id register at 0x1000: 7-3 = 0, 2-0 = 1.
41150300Simp *	(maybe this test is too week)
42150300Simp *    misc register at 0x018:
43150300Simp *	6 WAIT_TOUTENABLE enable watchdog timeout
44150300Simp *	3 AUI/TPI 1 AUX, 0 TPI
45150300Simp *	2 loopback
46150300Simp *      1 gdlink (tpi mode only) 1 tp good, 0 tp bad
47150300Simp *	0 0-no mam, 1 mam connected
48190801Simp *
49150300Simp * NS83926 appears to be a NS pcmcia glue chip used on the IBM Ethernet II
50150300Simp * and the NEC PC9801N-J12 ccr base 0x2000!
51150300Simp *
52150300Simp * winbond 289c926
53150300Simp *    ccr base 0xfd0
54150300Simp *    cfb (am 0xff2):
55150300Simp *	0-1 PHY01	00 TPI, 01 10B2, 10 10B5, 11 TPI (reduced squ)
56150300Simp *	2 LNKEN		0 - enable link and auto switch, 1 disable
57150300Simp *	3 LNKSTS	TPI + LNKEN=0 + link good == 1, else 0
58150300Simp *    sr (am 0xff4)
59150300Simp *	88 00 88 00 88 00, etc
60150300Simp *
61150300Simp * TMI tc3299a (cr PHY01 == 0)
62150300Simp *    ccr base 0x3f8
63150300Simp *    cra (io 0xa)
64150300Simp *    crb (io 0xb)
65150300Simp *	0-1 PHY01	00 auto, 01 res, 10 10B5, 11 TPI
66150300Simp *	2 GDLINK	1 disable checking of link
67150300Simp *	6 LINK		0 bad link, 1 good link
68150300Simp *
69150300Simp * EN5017A, EN5020	no data, but very popular
70150300Simp * Other chips?
71150300Simp * NetBSD supports RTL8019, but none have surfaced that I can see
72150300Simp */
73150300Simp
7452245Smdodd#include <sys/param.h>
7552245Smdodd#include <sys/systm.h>
7652245Smdodd#include <sys/socket.h>
7752473Simp#include <sys/kernel.h>
7863775Stanimura#include <sys/conf.h>
7963775Stanimura#include <sys/uio.h>
8052245Smdodd
8152473Simp#include <sys/module.h>
8252473Simp#include <sys/bus.h>
8352473Simp#include <machine/bus.h>
8466332Stanimura#include <sys/rman.h>
8566332Stanimura#include <machine/resource.h>
8652473Simp
8752473Simp#include <net/ethernet.h>
8852473Simp#include <net/if.h>
8952473Simp#include <net/if_arp.h>
9052473Simp#include <net/if_mib.h>
9173374Simp#include <net/if_media.h>
9252473Simp
9363775Stanimura#include <dev/ed/if_edreg.h>
9452245Smdodd#include <dev/ed/if_edvar.h>
95150957Simp#include <dev/ed/ax88x90reg.h>
96150957Simp#include <dev/ed/dl100xxreg.h>
97150957Simp#include <dev/ed/tc5299jreg.h>
9856361Shosokawa#include <dev/pccard/pccardvar.h>
99150108Simp#include <dev/pccard/pccardreg.h>
100140522Simp#include <dev/pccard/pccard_cis.h>
10173374Simp#include <dev/mii/mii.h>
10273374Simp#include <dev/mii/miivar.h>
10369137Speter
10466332Stanimura#include "card_if.h"
10573374Simp/* "device miibus" required.  See GENERIC if you get errors here. */
10673374Simp#include "miibus_if.h"
107129764Simp#include "pccarddevs.h"
10852245Smdodd
10952245Smdodd/*
110150957Simp * NE-2000 based PC Cards have a number of ways to get the MAC address.
111150957Simp * Some cards encode this as a FUNCE.  Others have this in the ROMs the
112150957Simp * same way that ISA cards do.  Some have it encoded in the attribute
113150957Simp * memory somewhere that isn't in the CIS.  Some new chipsets have it
114150957Simp * in special registers in the ASIC part of the chip.
115149890Simp *
116190801Simp * For those cards that have the MAC adress stored in attribute memory
117190801Simp * outside of a FUNCE entry in the CIS, nearly all of them have it at
118190801Simp * a fixed offset (0xff0).  We use that offset as a source of last
119190801Simp * resource if other offsets have failed.  This is the address of the
120190801Simp * National Semiconductor DP83903A, which is the only chip's datasheet
121190801Simp * I've found.
122141744Simp */
123141744Simp#define ED_DEFAULT_MAC_OFFSET	0xff0
124141744Simp
12571324Simpstatic const struct ed_product {
12671324Simp	struct pccard_product	prod;
12771324Simp	int flags;
128142023Simp#define	NE2000DVF_DL100XX	0x0001		/* chip is D-Link DL10019/22 */
129142023Simp#define	NE2000DVF_AX88X90	0x0002		/* chip is ASIX AX88[17]90 */
130150957Simp#define NE2000DVF_TC5299J	0x0004		/* chip is Tamarack TC5299J */
131190483Simp#define NE2000DVF_TOSHIBA	0x0008		/* Toshiba DP83902A */
132150957Simp#define NE2000DVF_ENADDR	0x0100		/* Get MAC from attr mem */
133150957Simp#define NE2000DVF_ANYFUNC	0x0200		/* Allow any function type */
134150957Simp#define NE2000DVF_MODEM		0x0400		/* Has a modem/serial */
135141708Simp	int enoff;
13671324Simp} ed_pccard_products[] = {
137147580Simp	{ PCMCIA_CARD(ACCTON, EN2212), 0},
138147580Simp	{ PCMCIA_CARD(ACCTON, EN2216), 0},
139147580Simp	{ PCMCIA_CARD(ALLIEDTELESIS, LA_PCM), 0},
140191386Simp	{ PCMCIA_CARD(AMBICOM, AMB8002), 0},
141147580Simp	{ PCMCIA_CARD(AMBICOM, AMB8002T), 0},
142191386Simp	{ PCMCIA_CARD(AMBICOM, AMB8010), 0},
143191386Simp	{ PCMCIA_CARD(AMBICOM, AMB8010_ALT), 0},
144191386Simp	{ PCMCIA_CARD(AMBICOM, AMB8610), 0},
145151840Simp	{ PCMCIA_CARD(BILLIONTON, CFLT10N), 0},
146151840Simp	{ PCMCIA_CARD(BILLIONTON, LNA100B), NE2000DVF_AX88X90},
147191391Simp	{ PCMCIA_CARD(BILLIONTON, LNT10TB), 0},
148147580Simp	{ PCMCIA_CARD(BILLIONTON, LNT10TN), 0},
149190475Simp	{ PCMCIA_CARD(BROMAX, AXNET), NE2000DVF_AX88X90},
150147872Simp	{ PCMCIA_CARD(BROMAX, IPORT), 0},
151147872Simp	{ PCMCIA_CARD(BROMAX, IPORT2), 0},
152147872Simp	{ PCMCIA_CARD(BUFFALO, LPC2_CLT), 0},
153147580Simp	{ PCMCIA_CARD(BUFFALO, LPC3_CLT), 0},
154147580Simp	{ PCMCIA_CARD(BUFFALO, LPC3_CLX), NE2000DVF_AX88X90},
155147872Simp	{ PCMCIA_CARD(BUFFALO, LPC4_TX), NE2000DVF_AX88X90},
156151225Simp	{ PCMCIA_CARD(BUFFALO, LPC4_CLX), NE2000DVF_AX88X90},
157147580Simp	{ PCMCIA_CARD(BUFFALO, LPC_CF_CLT), 0},
158147580Simp	{ PCMCIA_CARD(CNET, NE2000), 0},
159147872Simp	{ PCMCIA_CARD(COMPEX, AX88190), NE2000DVF_AX88X90},
160147872Simp	{ PCMCIA_CARD(COMPEX, LANMODEM), 0},
161147580Simp	{ PCMCIA_CARD(COMPEX, LINKPORT_ENET_B), 0},
162147580Simp	{ PCMCIA_CARD(COREGA, ETHER_II_PCC_T), 0},
163147580Simp	{ PCMCIA_CARD(COREGA, ETHER_II_PCC_TD), 0},
164147580Simp	{ PCMCIA_CARD(COREGA, ETHER_PCC_T), 0},
165147580Simp	{ PCMCIA_CARD(COREGA, ETHER_PCC_TD), 0},
166150104Simp	{ PCMCIA_CARD(COREGA, FAST_ETHER_PCC_TX), NE2000DVF_DL100XX},
167150104Simp	{ PCMCIA_CARD(COREGA, FETHER_PCC_TXD), NE2000DVF_AX88X90},
168150104Simp	{ PCMCIA_CARD(COREGA, FETHER_PCC_TXF), NE2000DVF_DL100XX},
169180315Simp	{ PCMCIA_CARD(COREGA, FETHER_II_PCC_TXD), NE2000DVF_AX88X90},
170180315Simp	{ PCMCIA_CARD(COREGA, LAPCCTXD), 0},
171147580Simp	{ PCMCIA_CARD(DAYNA, COMMUNICARD_E_1), 0},
172147580Simp	{ PCMCIA_CARD(DAYNA, COMMUNICARD_E_2), 0},
173190899Simp	{ PCMCIA_CARD(DLINK, DE650), NE2000DVF_ANYFUNC },
174147580Simp	{ PCMCIA_CARD(DLINK, DE660), 0 },
175147580Simp	{ PCMCIA_CARD(DLINK, DE660PLUS), 0},
176147580Simp	{ PCMCIA_CARD(DYNALINK, L10C), 0},
177147580Simp	{ PCMCIA_CARD(EDIMAX, EP4000A), 0},
178190902Simp	{ PCMCIA_CARD(EPSON, EEN10B), 0},
179147580Simp	{ PCMCIA_CARD(EXP, THINLANCOMBO), 0},
180151840Simp	{ PCMCIA_CARD(GLOBALVILLAGE, LANMODEM), 0},
181147872Simp	{ PCMCIA_CARD(GREY_CELL, TDK3000), 0},
182148022Simp	{ PCMCIA_CARD(GREY_CELL, DMF650TX),
183149832Simp	    NE2000DVF_ANYFUNC | NE2000DVF_DL100XX | NE2000DVF_MODEM},
184191237Simp	{ PCMCIA_CARD(GVC, NIC_2000P), 0},
185147580Simp	{ PCMCIA_CARD(IBM, HOME_AND_AWAY), 0},
186190902Simp	{ PCMCIA_CARD(IBM, INFOMOVER), 0},
187147580Simp	{ PCMCIA_CARD(IODATA3, PCLAT), 0},
188147872Simp	{ PCMCIA_CARD(KINGSTON, CIO10T), 0},
189147580Simp	{ PCMCIA_CARD(KINGSTON, KNE2), 0},
190150104Simp	{ PCMCIA_CARD(LANTECH, FASTNETTX), NE2000DVF_AX88X90},
191190899Simp	/* Same ID for many different cards, including generic NE2000 */
192147580Simp	{ PCMCIA_CARD(LINKSYS, COMBO_ECARD),
193150104Simp	    NE2000DVF_DL100XX | NE2000DVF_AX88X90},
194147580Simp	{ PCMCIA_CARD(LINKSYS, ECARD_1), 0},
195147580Simp	{ PCMCIA_CARD(LINKSYS, ECARD_2), 0},
196150104Simp	{ PCMCIA_CARD(LINKSYS, ETHERFAST), NE2000DVF_DL100XX},
197147580Simp	{ PCMCIA_CARD(LINKSYS, TRUST_COMBO_ECARD), 0},
198147580Simp	{ PCMCIA_CARD(MACNICA, ME1_JEIDA), 0},
199147580Simp	{ PCMCIA_CARD(MAGICRAM, ETHER), 0},
200150104Simp	{ PCMCIA_CARD(MELCO, LPC3_CLX), NE2000DVF_AX88X90},
201150104Simp	{ PCMCIA_CARD(MELCO, LPC3_TX), NE2000DVF_AX88X90},
202191394Simp	{ PCMCIA_CARD(MELCO2, LPC2_T), 0},
203191394Simp	{ PCMCIA_CARD(MELCO2, LPC2_TX), 0},
204190475Simp	{ PCMCIA_CARD(MITSUBISHI, B8895), NE2000DVF_ANYFUNC}, /* NG */
205171352Simp	{ PCMCIA_CARD(MICRORESEARCH, MR10TPC), 0},
206147580Simp	{ PCMCIA_CARD(NDC, ND5100_E), 0},
207147580Simp	{ PCMCIA_CARD(NETGEAR, FA410TXC), NE2000DVF_DL100XX},
208149922Simp	/* Same ID as DLINK DFE-670TXD.  670 has DL10022, fa411 has ax88790 */
209149922Simp	{ PCMCIA_CARD(NETGEAR, FA411), NE2000DVF_AX88X90 | NE2000DVF_DL100XX},
210147580Simp	{ PCMCIA_CARD(NEXTCOM, NEXTHAWK), 0},
211191237Simp	{ PCMCIA_CARD(NEWMEDIA, LANSURFER), NE2000DVF_ANYFUNC},
212191237Simp	{ PCMCIA_CARD(NEWMEDIA, LIVEWIRE), 0},
213191469Simp	{ PCMCIA_CARD(OEM2, 100BASE), NE2000DVF_AX88X90},
214147580Simp	{ PCMCIA_CARD(OEM2, ETHERNET), 0},
215191469Simp	{ PCMCIA_CARD(OEM2, FAST_ETHERNET), NE2000DVF_AX88X90},
216149922Simp	{ PCMCIA_CARD(OEM2, NE2000), 0},
217147580Simp	{ PCMCIA_CARD(PLANET, SMARTCOM2000), 0 },
218147580Simp	{ PCMCIA_CARD(PREMAX, PE200), 0},
219150300Simp	{ PCMCIA_CARD(PSION, LANGLOBAL),
220150300Simp	    NE2000DVF_ANYFUNC | NE2000DVF_AX88X90 | NE2000DVF_MODEM},
221147580Simp	{ PCMCIA_CARD(RACORE, ETHERNET), 0},
222147580Simp	{ PCMCIA_CARD(RACORE, FASTENET), NE2000DVF_AX88X90},
223150957Simp	{ PCMCIA_CARD(RACORE, 8041TX), NE2000DVF_AX88X90 | NE2000DVF_TC5299J},
224147872Simp	{ PCMCIA_CARD(RELIA, COMBO), 0},
225190430Simp	{ PCMCIA_CARD(RIOS, PCCARD3), 0},
226147580Simp	{ PCMCIA_CARD(RPTI, EP400), 0},
227147580Simp	{ PCMCIA_CARD(RPTI, EP401), 0},
228147580Simp	{ PCMCIA_CARD(SMC, EZCARD), 0},
229147580Simp	{ PCMCIA_CARD(SOCKET, EA_ETHER), 0},
230147872Simp	{ PCMCIA_CARD(SOCKET, ES_1000), 0},
231147580Simp	{ PCMCIA_CARD(SOCKET, LP_ETHER), 0},
232147580Simp	{ PCMCIA_CARD(SOCKET, LP_ETHER_CF), 0},
233147580Simp	{ PCMCIA_CARD(SOCKET, LP_ETH_10_100_CF), NE2000DVF_DL100XX},
234147580Simp	{ PCMCIA_CARD(SVEC, COMBOCARD), 0},
235147580Simp	{ PCMCIA_CARD(SVEC, LANCARD), 0},
236147580Simp	{ PCMCIA_CARD(TAMARACK, ETHERNET), 0},
237149922Simp	{ PCMCIA_CARD(TDK, CFE_10), 0},
238147580Simp	{ PCMCIA_CARD(TDK, LAK_CD031), 0},
239147872Simp	{ PCMCIA_CARD(TDK, DFL5610WS), 0},
240147872Simp	{ PCMCIA_CARD(TELECOMDEVICE, LM5LT), 0 },
241150104Simp	{ PCMCIA_CARD(TELECOMDEVICE, TCD_HPC100), NE2000DVF_AX88X90},
242189726Simp	{ PCMCIA_CARD(TJ, PTJ_LAN_T), 0 },
243190483Simp	{ PCMCIA_CARD(TOSHIBA2, LANCT00A), NE2000DVF_ANYFUNC | NE2000DVF_TOSHIBA},
244147580Simp	{ PCMCIA_CARD(ZONET, ZEN), 0},
24586394Simp	{ { NULL } }
24669137Speter};
24769137Speter
248149841Simp/*
249149841Simp *      PC Card (PCMCIA) specific code.
250149841Simp */
251149841Simpstatic int	ed_pccard_probe(device_t);
252149841Simpstatic int	ed_pccard_attach(device_t);
253199380Sjhbstatic void	ed_pccard_tick(struct ed_softc *);
254149841Simp
255149841Simpstatic int	ed_pccard_dl100xx(device_t dev, const struct ed_product *);
256150108Simpstatic void	ed_pccard_dl100xx_mii_reset(struct ed_softc *sc);
257150108Simpstatic u_int	ed_pccard_dl100xx_mii_readbits(struct ed_softc *sc, int nbits);
258150108Simpstatic void	ed_pccard_dl100xx_mii_writebits(struct ed_softc *sc, u_int val,
259149841Simp    int nbits);
260150108Simp
261150957Simpstatic int	ed_pccard_ax88x90(device_t dev, const struct ed_product *);
262150108Simpstatic u_int	ed_pccard_ax88x90_mii_readbits(struct ed_softc *sc, int nbits);
263150108Simpstatic void	ed_pccard_ax88x90_mii_writebits(struct ed_softc *sc, u_int val,
264150108Simp    int nbits);
265150957Simp
266150108Simpstatic int	ed_miibus_readreg(device_t dev, int phy, int reg);
267150300Simpstatic int	ed_ifmedia_upd(struct ifnet *);
268150300Simpstatic void	ed_ifmedia_sts(struct ifnet *, struct ifmediareq *);
269149841Simp
270150957Simpstatic int	ed_pccard_tc5299j(device_t dev, const struct ed_product *);
271150957Simpstatic u_int	ed_pccard_tc5299j_mii_readbits(struct ed_softc *sc, int nbits);
272150957Simpstatic void	ed_pccard_tc5299j_mii_writebits(struct ed_softc *sc, u_int val,
273150957Simp    int nbits);
274149841Simp
275150581Simpstatic void
276150581Simped_pccard_print_entry(const struct ed_product *pp)
277150581Simp{
278150581Simp	int i;
279150581Simp
280150581Simp	printf("Product entry: ");
281150581Simp	if (pp->prod.pp_name)
282150581Simp		printf("name='%s',", pp->prod.pp_name);
283150581Simp	printf("vendor=%#x,product=%#x", pp->prod.pp_vendor,
284150581Simp	    pp->prod.pp_product);
285150581Simp	for (i = 0; i < 4; i++)
286150581Simp		if (pp->prod.pp_cis[i])
287150581Simp			printf(",CIS%d='%s'", i, pp->prod.pp_cis[i]);
288150581Simp	printf("\n");
289150581Simp}
290150581Simp
29169137Speterstatic int
292149558Simped_pccard_probe(device_t dev)
29369137Speter{
294150581Simp	const struct ed_product *pp, *pp2;
295150581Simp	int		error, first = 1;
296140522Simp	uint32_t	fcn = PCCARD_FUNCTION_UNSPEC;
29769137Speter
298140522Simp	/* Make sure we're a network function */
299140522Simp	error = pccard_get_function(dev, &fcn);
300140522Simp	if (error != 0)
301140522Simp		return (error);
302140522Simp
303100531Simp	if ((pp = (const struct ed_product *) pccard_product_lookup(dev,
30471324Simp	    (const struct pccard_product *) ed_pccard_products,
30569150Speter	    sizeof(ed_pccard_products[0]), NULL)) != NULL) {
306113317Simp		if (pp->prod.pp_name != NULL)
307113317Simp			device_set_desc(dev, pp->prod.pp_name);
308148022Simp		/*
309148022Simp		 * Some devices don't ID themselves as network, but
310148022Simp		 * that's OK if the flags say so.
311148022Simp		 */
312148022Simp		if (!(pp->flags & NE2000DVF_ANYFUNC) &&
313148022Simp		    fcn != PCCARD_FUNCTION_NETWORK)
314148022Simp			return (ENXIO);
315150581Simp		/*
316150581Simp		 * Some devices match multiple entries.  Report that
317150581Simp		 * as a warning to help cull the table
318150581Simp		 */
319150581Simp		pp2 = pp;
320150581Simp		while ((pp2 = (const struct ed_product *)pccard_product_lookup(
321150581Simp		    dev, (const struct pccard_product *)(pp2 + 1),
322150581Simp		    sizeof(ed_pccard_products[0]), NULL)) != NULL) {
323150581Simp			if (first) {
324150581Simp				device_printf(dev,
325150581Simp    "Warning: card matches multiple entries.  Report to imp@freebsd.org\n");
326150581Simp				ed_pccard_print_entry(pp);
327150581Simp				first = 0;
328150581Simp			}
329150581Simp			ed_pccard_print_entry(pp2);
330150581Simp		}
331150581Simp
332100531Simp		return (0);
33369137Speter	}
334132511Simp	return (ENXIO);
33569137Speter}
33669137Speter
33752245Smdoddstatic int
338141930Simped_pccard_rom_mac(device_t dev, uint8_t *enaddr)
339141930Simp{
340141930Simp	struct ed_softc *sc = device_get_softc(dev);
341191238Simp	uint8_t romdata[32], sum;
342141930Simp	int i;
343141930Simp
344141930Simp	/*
345150108Simp	 * Read in the rom data at location 0.  Since there are no
346150108Simp	 * NE-1000 based PC Card devices, we'll assume we're 16-bit.
347150108Simp	 *
348150108Simp	 * In researching what format this takes, I've found that the
349150108Simp	 * following appears to be true for multiple cards based on
350150108Simp	 * observation as well as datasheet digging.
351150108Simp	 *
352150108Simp	 * Data is stored in some ROM and is copied out 8 bits at a time
353150108Simp	 * into 16-bit wide locations.  This means that the odd locations
354150108Simp	 * of the ROM are not used (and can be either 0 or ff).
355150108Simp	 *
356150108Simp	 * The contents appears to be as follows:
357150108Simp	 * PROM   RAM
358150108Simp	 * Offset Offset	What
359150108Simp	 *  0      0	ENETADDR 0
360150108Simp	 *  1      2	ENETADDR 1
361150108Simp	 *  2      4	ENETADDR 2
362150108Simp	 *  3      6	ENETADDR 3
363150108Simp	 *  4      8	ENETADDR 4
364150108Simp	 *  5     10	ENETADDR 5
365150108Simp	 *  6-13  12-26 Reserved (varies by manufacturer)
366150108Simp	 * 14     28	0x57
367150108Simp	 * 15     30    0x57
368150108Simp	 *
369150108Simp	 * Some manufacturers have another image of enetaddr from
370150108Simp	 * PROM offset 0x10 to 0x15 with 0x42 in 0x1e and 0x1f, but
371150108Simp	 * this doesn't appear to be universally documented in the
372150108Simp	 * datasheets.  Some manufactuers have a card type, card config
373150108Simp	 * checksums, etc encoded into PROM offset 6-13, but deciphering it
374150108Simp	 * requires more knowledge about the exact underlying chipset than
375150108Simp	 * we possess (and maybe can possess).
376141930Simp	 */
377150108Simp	ed_pio_readmem(sc, 0, romdata, 32);
378150108Simp	if (bootverbose)
379190559Simp		device_printf(dev, "ROM DATA: %32D\n", romdata, " ");
380150108Simp	if (romdata[28] != 0x57 || romdata[30] != 0x57)
381150108Simp		return (0);
382191238Simp	for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++)
383191238Simp		sum |= romdata[i * 2];
384191238Simp	if (sum == 0)
385191238Simp		return (0);
386141930Simp	for (i = 0; i < ETHER_ADDR_LEN; i++)
387141930Simp		enaddr[i] = romdata[i * 2];
388150108Simp	return (1);
389141930Simp}
390141930Simp
391141930Simpstatic int
392149832Simped_pccard_add_modem(device_t dev)
393148022Simp{
394191299Simp	device_printf(dev, "Need to write this code\n");
395148022Simp	return 0;
396148022Simp}
397148022Simp
398148022Simpstatic int
399190643Simped_pccard_kick_phy(struct ed_softc *sc)
400190643Simp{
401190643Simp	struct mii_softc *miisc;
402190643Simp	struct mii_data *mii;
403190643Simp
404190643Simp	mii = device_get_softc(sc->miibus);
405221407Smarius	LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
406221407Smarius		PHY_RESET(miisc);
407190643Simp	return (mii_mediachg(mii));
408190643Simp}
409190643Simp
410190643Simpstatic int
411150300Simped_pccard_media_ioctl(struct ed_softc *sc, struct ifreq *ifr, u_long command)
412150300Simp{
413150300Simp	struct mii_data *mii;
414150300Simp
415150300Simp	if (sc->miibus == NULL)
416150300Simp		return (EINVAL);
417150300Simp	mii = device_get_softc(sc->miibus);
418150300Simp	return (ifmedia_ioctl(sc->ifp, ifr, &mii->mii_media, command));
419150300Simp}
420150300Simp
421150300Simp
422150300Simpstatic void
423150300Simped_pccard_mediachg(struct ed_softc *sc)
424150300Simp{
425150300Simp	struct mii_data *mii;
426150300Simp
427150300Simp	if (sc->miibus == NULL)
428150300Simp		return;
429150300Simp	mii = device_get_softc(sc->miibus);
430150300Simp	mii_mediachg(mii);
431150300Simp}
432150300Simp
433150300Simpstatic int
43452473Simped_pccard_attach(device_t dev)
43552245Smdodd{
43656361Shosokawa	u_char sum;
437141744Simp	u_char enaddr[ETHER_ADDR_LEN];
438141708Simp	const struct ed_product *pp;
439191299Simp	int	error, i, flags, port_rid, modem_rid;
440149558Simp	struct ed_softc *sc = device_get_softc(dev);
441149832Simp	u_long size;
442190483Simp	static uint16_t *intr_vals[] = {NULL, NULL};
443149558Simp
444190559Simp	sc->dev = dev;
445141708Simp	if ((pp = (const struct ed_product *) pccard_product_lookup(dev,
446141708Simp	    (const struct pccard_product *) ed_pccard_products,
447191299Simp		 sizeof(ed_pccard_products[0]), NULL)) == NULL) {
448191299Simp		printf("Can't find\n");
449141708Simp		return (ENXIO);
450191299Simp	}
451191299Simp	modem_rid = port_rid = -1;
452149832Simp	if (pp->flags & NE2000DVF_MODEM) {
453149832Simp		for (i = 0; i < 4; i++) {
454149832Simp			size = bus_get_resource_count(dev, SYS_RES_IOPORT, i);
455149832Simp			if (size == ED_NOVELL_IO_PORTS)
456191299Simp				port_rid = i;
457149832Simp			else if (size == 8)
458191299Simp				modem_rid = i;
459149832Simp		}
460191299Simp		if (port_rid == -1) {
461149832Simp			device_printf(dev, "Cannot locate my ports!\n");
462149832Simp			return (ENXIO);
463149832Simp		}
464149832Simp	} else {
465191299Simp		port_rid = 0;
466149832Simp	}
467149841Simp	/* Allocate the port resource during setup. */
468191299Simp	error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS);
469191299Simp	if (error) {
470191299Simp		printf("alloc_port failed\n");
471149558Simp		return (error);
472191299Simp	}
473191299Simp	if (rman_get_size(sc->port_res) == ED_NOVELL_IO_PORTS / 2) {
474191299Simp		port_rid++;
475191299Simp		sc->port_res2 = bus_alloc_resource(dev, SYS_RES_IOPORT,
476191299Simp		    &port_rid, 0ul, ~0ul, 1, RF_ACTIVE);
477191299Simp		if (sc->port_res2 == NULL ||
478191299Simp		    rman_get_size(sc->port_res2) != ED_NOVELL_IO_PORTS / 2) {
479191299Simp			error = ENXIO;
480191299Simp			goto bad;
481191299Simp		}
482191299Simp	}
483149558Simp	error = ed_alloc_irq(dev, 0, 0);
484149841Simp	if (error)
485149841Simp		goto bad;
486149558Simp
487149841Simp	/*
488190901Simp	 * Determine which chipset we are.  Almost all the PC Card chipsets
489190901Simp	 * have the Novel ASIC and NIC offsets.  There's 2 known cards that
490190901Simp	 * follow the WD80x3 conventions, which are handled as a special case.
491149841Simp	 */
492149841Simp	sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
493149841Simp	sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
494149841Simp	error = ENXIO;
495190483Simp	flags = device_get_flags(dev);
496149841Simp	if (error != 0)
497149841Simp		error = ed_pccard_dl100xx(dev, pp);
498150108Simp	if (error != 0)
499149841Simp		error = ed_pccard_ax88x90(dev, pp);
500149841Simp	if (error != 0)
501150957Simp		error = ed_pccard_tc5299j(dev, pp);
502191299Simp	if (error != 0) {
503190483Simp		error = ed_probe_Novell_generic(dev, flags);
504191299Simp		printf("Novell probe generic %d\n", error);
505191299Simp	}
506190559Simp	if (error != 0 && (pp->flags & NE2000DVF_TOSHIBA)) {
507190559Simp		flags |= ED_FLAGS_TOSH_ETHER;
508190483Simp		flags |= ED_FLAGS_PCCARD;
509190483Simp		sc->asic_offset = ED_WD_ASIC_OFFSET;
510190483Simp		sc->nic_offset  = ED_WD_NIC_OFFSET;
511190483Simp		error = ed_probe_WD80x3_generic(dev, flags, intr_vals);
512190483Simp	}
513149841Simp	if (error)
514149841Simp		goto bad;
515149841Simp
516141715Simp	/*
517190898Simp	 * There are several ways to get the MAC address for the card.
518190898Simp	 * Some of the above probe routines can fill in the enaddr.  If
519190898Simp	 * not, we run through a number of 'well known' locations:
520190898Simp	 *	(1) From the PC Card FUNCE
521190898Simp	 *	(2) From offset 0 in the shared memory
522190898Simp	 *	(3) From a hinted offset in attribute memory
523190898Simp	 *	(4) From 0xff0 in attribute memory
524190898Simp	 * If we can't get a non-zero MAC address from this list, we fail.
525141715Simp	 */
526190483Simp	for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++)
527190483Simp		sum |= sc->enaddr[i];
528190897Simp	if (sum == 0) {
529141744Simp		pccard_get_ether(dev, enaddr);
530141744Simp		if (bootverbose)
531141744Simp			device_printf(dev, "CIS MAC %6D\n", enaddr, ":");
53262236Sps		for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++)
533141744Simp			sum |= enaddr[i];
534141930Simp		if (sum == 0 && ed_pccard_rom_mac(dev, enaddr)) {
535141930Simp			if (bootverbose)
536141930Simp				device_printf(dev, "ROM mac %6D\n", enaddr,
537141930Simp				    ":");
538141930Simp			sum++;
539141930Simp		}
540141708Simp		if (sum == 0 && pp->flags & NE2000DVF_ENADDR) {
541141708Simp			for (i = 0; i < ETHER_ADDR_LEN; i++) {
542150108Simp				pccard_attr_read_1(dev, pp->enoff + i * 2,
543141744Simp				    enaddr + i);
544141744Simp				sum |= enaddr[i];
545141708Simp			}
546141744Simp			if (bootverbose)
547150108Simp				device_printf(dev, "Hint %x MAC %6D\n",
548150108Simp				    pp->enoff, enaddr, ":");
549141708Simp		}
550141744Simp		if (sum == 0) {
551141744Simp			for (i = 0; i < ETHER_ADDR_LEN; i++) {
552150108Simp				pccard_attr_read_1(dev, ED_DEFAULT_MAC_OFFSET +
553141744Simp				    i * 2, enaddr + i);
554141744Simp				sum |= enaddr[i];
555141744Simp			}
556141744Simp			if (bootverbose)
557141744Simp				device_printf(dev, "Fallback MAC %6D\n",
558141744Simp				    enaddr, ":");
559141744Simp		}
560141744Simp		if (sum == 0) {
561141744Simp			device_printf(dev, "Cannot extract MAC address.\n");
562141744Simp			ed_release_resources(dev);
563141744Simp			return (ENXIO);
564141744Simp		}
565147256Sbrooks		bcopy(enaddr, sc->enaddr, ETHER_ADDR_LEN);
56662236Sps	}
56756361Shosokawa
568121816Sbrooks	error = ed_attach(dev);
569149841Simp	if (error)
570149841Simp		goto bad;
571149558Simp 	if (sc->chip_type == ED_CHIP_TYPE_DL10019 ||
572149558Simp	    sc->chip_type == ED_CHIP_TYPE_DL10022) {
573213894Smarius		/* Try to attach an MII bus, but ignore errors. */
574150108Simp		ed_pccard_dl100xx_mii_reset(sc);
575213894Smarius		(void)mii_attach(dev, &sc->miibus, sc->ifp, ed_ifmedia_upd,
576213894Smarius		    ed_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY,
577221407Smarius		    MII_OFFSET_ANY, MIIF_FORCEANEG);
578190559Simp	} else if (sc->chip_type == ED_CHIP_TYPE_AX88190 ||
579213894Smarius	    sc->chip_type == ED_CHIP_TYPE_AX88790 ||
580213894Smarius	    sc->chip_type == ED_CHIP_TYPE_TC5299J) {
581213894Smarius		error = mii_attach(dev, &sc->miibus, sc->ifp, ed_ifmedia_upd,
582213894Smarius		    ed_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY,
583221407Smarius		    MII_OFFSET_ANY, MIIF_FORCEANEG);
584213894Smarius		if (error != 0) {
585213894Smarius			device_printf(dev, "attaching PHYs failed\n");
586150108Simp			goto bad;
587150108Simp		}
58880159Siedowse	}
589150300Simp	if (sc->miibus != NULL) {
590150300Simp		sc->sc_tick = ed_pccard_tick;
591150300Simp		sc->sc_mediachg = ed_pccard_mediachg;
592150300Simp		sc->sc_media_ioctl = ed_pccard_media_ioctl;
593190643Simp		ed_pccard_kick_phy(sc);
594190802Simp	} else {
595190802Simp		ed_gen_ifmedia_init(sc);
596150300Simp	}
597191299Simp	if (modem_rid != -1)
598149832Simp		ed_pccard_add_modem(dev);
599191234Simp
600191234Simp	error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
601191234Simp	    NULL, edintr, sc, &sc->irq_handle);
602191234Simp	if (error) {
603191234Simp		device_printf(dev, "setup intr failed %d \n", error);
604191234Simp		goto bad;
605191234Simp	}
606191234Simp
607149558Simp	return (0);
608149841Simpbad:
609181351Simp	ed_detach(dev);
610149841Simp	return (error);
61164777Snyan}
61263775Stanimura
61370154Stoshi/*
61470154Stoshi * Probe the Ethernet MAC addrees for PCMCIA Linksys EtherFast 10/100
61570154Stoshi * and compatible cards (DL10019C Ethernet controller).
61670154Stoshi */
61770154Stoshistatic int
618149841Simped_pccard_dl100xx(device_t dev, const struct ed_product *pp)
61970154Stoshi{
62070154Stoshi	struct ed_softc *sc = device_get_softc(dev);
62170154Stoshi	u_char sum;
622140844Simp	uint8_t id;
623190803Simp	u_int   memsize;
624149841Simp	int i, error;
62570154Stoshi
626150108Simp	if (!(pp->flags & NE2000DVF_DL100XX))
627149841Simp		return (ENXIO);
628150108Simp	if (bootverbose)
629150108Simp		device_printf(dev, "Trying DL100xx probing\n");
630149841Simp	error = ed_probe_Novell_generic(dev, device_get_flags(dev));
631150108Simp	if (bootverbose && error)
632150108Simp		device_printf(dev, "Novell generic probe failed: %d\n", error);
633149841Simp	if (error != 0)
634149841Simp		return (error);
635149841Simp
63670154Stoshi	/*
63770154Stoshi	 * Linksys registers(offset from ASIC base)
63870154Stoshi	 *
63970154Stoshi	 * 0x04-0x09 : Physical Address Register 0-5 (PAR0-PAR5)
64070154Stoshi	 * 0x0A      : Card ID Register (CIR)
64170154Stoshi	 * 0x0B      : Check Sum Register (SR)
64270154Stoshi	 */
64370154Stoshi	for (sum = 0, i = 0x04; i < 0x0c; i++)
64470154Stoshi		sum += ed_asic_inb(sc, i);
645150108Simp	if (sum != 0xff) {
646150108Simp		if (bootverbose)
647150108Simp			device_printf(dev, "Bad checksum %#x\n", sum);
648140844Simp		return (ENXIO);		/* invalid DL10019C */
649150108Simp	}
650150108Simp	if (bootverbose)
651150108Simp		device_printf(dev, "CIR is %d\n", ed_asic_inb(sc, 0xa));
652140844Simp	for (i = 0; i < ETHER_ADDR_LEN; i++)
653147256Sbrooks		sc->enaddr[i] = ed_asic_inb(sc, 0x04 + i);
65470154Stoshi	ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
655140844Simp	id = ed_asic_inb(sc, 0xf);
65670154Stoshi	sc->isa16bit = 1;
657190803Simp	/*
658190803Simp	 * Hard code values based on the datasheet.  We're NE-2000 compatible
659190803Simp	 * NIC with 24kb of packet memory starting at 24k offset.  These
660190803Simp	 * cards also work with 16k at 16k, but don't work with 24k at 16k
661190803Simp	 * or 32k at 16k.
662190803Simp	 */
663190803Simp	sc->type = ED_TYPE_NE2000;
664190803Simp	sc->mem_start = 24 * 1024;
665190803Simp	memsize = sc->mem_size = 24 * 1024;
666190803Simp	sc->mem_end = sc->mem_start + memsize;
667190803Simp	sc->tx_page_start = memsize / ED_PAGE_SIZE;
668190803Simp	sc->txb_cnt = 3;
669190803Simp	sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
670190803Simp	sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE;
671190803Simp
672190803Simp	sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
673190803Simp
674190803Simp	ed_nic_outb(sc, ED_P0_PSTART, sc->mem_start / ED_PAGE_SIZE);
675190803Simp	ed_nic_outb(sc, ED_P0_PSTOP, sc->mem_end / ED_PAGE_SIZE);
676141681Simp	sc->vendor = ED_VENDOR_NOVELL;
677141881Simp	sc->chip_type = (id & 0x90) == 0x90 ?
678141881Simp	    ED_CHIP_TYPE_DL10022 : ED_CHIP_TYPE_DL10019;
679140844Simp	sc->type_str = ((id & 0x90) == 0x90) ? "DL10022" : "DL10019";
680150108Simp	sc->mii_readbits = ed_pccard_dl100xx_mii_readbits;
681150108Simp	sc->mii_writebits = ed_pccard_dl100xx_mii_writebits;
682140844Simp	return (0);
68370154Stoshi}
68470355Simp
68573374Simp/* MII bit-twiddling routines for cards using Dlink chipset */
686150108Simp#define DL100XX_MIISET(sc, x) ed_asic_outb(sc, ED_DL100XX_MIIBUS, \
687150108Simp    ed_asic_inb(sc, ED_DL100XX_MIIBUS) | (x))
688150108Simp#define DL100XX_MIICLR(sc, x) ed_asic_outb(sc, ED_DL100XX_MIIBUS, \
689150108Simp    ed_asic_inb(sc, ED_DL100XX_MIIBUS) & ~(x))
69073374Simp
69173374Simpstatic void
692150108Simped_pccard_dl100xx_mii_reset(struct ed_softc *sc)
69373374Simp{
694141881Simp	if (sc->chip_type != ED_CHIP_TYPE_DL10022)
695141881Simp		return;
696141881Simp
697190650Simp	ed_asic_outb(sc, ED_DL100XX_MIIBUS, ED_DL10022_MII_RESET2);
69873374Simp	DELAY(10);
699150108Simp	ed_asic_outb(sc, ED_DL100XX_MIIBUS,
700190650Simp	    ED_DL10022_MII_RESET2 | ED_DL10022_MII_RESET1);
70173374Simp	DELAY(10);
702190650Simp	ed_asic_outb(sc, ED_DL100XX_MIIBUS, ED_DL10022_MII_RESET2);
70373374Simp	DELAY(10);
704150108Simp	ed_asic_outb(sc, ED_DL100XX_MIIBUS,
705190650Simp	    ED_DL10022_MII_RESET2 | ED_DL10022_MII_RESET1);
70673374Simp	DELAY(10);
707150108Simp	ed_asic_outb(sc, ED_DL100XX_MIIBUS, 0);
70873374Simp}
70973374Simp
71073374Simpstatic void
711150108Simped_pccard_dl100xx_mii_writebits(struct ed_softc *sc, u_int val, int nbits)
71273374Simp{
71373374Simp	int i;
71473374Simp
715190645Simp	DL100XX_MIISET(sc, ED_DL100XX_MII_DIROUT);
71673374Simp	for (i = nbits - 1; i >= 0; i--) {
71773374Simp		if ((val >> i) & 1)
718150108Simp			DL100XX_MIISET(sc, ED_DL100XX_MII_DATAOUT);
71973374Simp		else
720150108Simp			DL100XX_MIICLR(sc, ED_DL100XX_MII_DATAOUT);
721150108Simp		DL100XX_MIISET(sc, ED_DL100XX_MII_CLK);
722150108Simp		DL100XX_MIICLR(sc, ED_DL100XX_MII_CLK);
72373374Simp	}
72473374Simp}
72573374Simp
72673374Simpstatic u_int
727150108Simped_pccard_dl100xx_mii_readbits(struct ed_softc *sc, int nbits)
72873374Simp{
72973374Simp	int i;
73073374Simp	u_int val = 0;
73173374Simp
732190645Simp	DL100XX_MIICLR(sc, ED_DL100XX_MII_DIROUT);
73373374Simp	for (i = nbits - 1; i >= 0; i--) {
734150108Simp		DL100XX_MIISET(sc, ED_DL100XX_MII_CLK);
73573374Simp		val <<= 1;
736150957Simp		if (ed_asic_inb(sc, ED_DL100XX_MIIBUS) & ED_DL100XX_MII_DATAIN)
73773374Simp			val++;
738150108Simp		DL100XX_MIICLR(sc, ED_DL100XX_MII_CLK);
73973374Simp	}
74073374Simp	return val;
74173374Simp}
74273374Simp
743190559Simpstatic void
744190559Simped_pccard_ax88x90_reset(struct ed_softc *sc)
745190559Simp{
746190559Simp	int i;
747190559Simp
748190559Simp	/* Reset Card */
749190559Simp	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP | ED_CR_PAGE_0);
750190559Simp	ed_asic_outb(sc, ED_NOVELL_RESET, ed_asic_inb(sc, ED_NOVELL_RESET));
751190559Simp
752190596Simp	/* Wait for the RST bit to assert, but cap it at 10ms */
753190596Simp	for (i = 10000; !(ed_nic_inb(sc, ED_P0_ISR) & ED_ISR_RST) && i > 0;
754190596Simp	     i--)
755190596Simp		continue;
756190559Simp	ed_nic_outb(sc, ED_P0_ISR, ED_ISR_RST);	/* ACK INTR */
757190559Simp	if (i == 0)
758190559Simp		device_printf(sc->dev, "Reset didn't finish\n");
759190559Simp}
760190559Simp
761190559Simp/*
762190559Simp * Probe and vendor-specific initialization routine for ax88x90 boards
763190559Simp */
764150108Simpstatic int
765190559Simped_probe_ax88x90_generic(device_t dev, int flags)
766149841Simp{
767190559Simp	struct ed_softc *sc = device_get_softc(dev);
768190559Simp	u_int   memsize;
769190559Simp	static char test_pattern[32] = "THIS is A memory TEST pattern";
770190559Simp	char    test_buffer[32];
771190559Simp
772190559Simp	ed_pccard_ax88x90_reset(sc);
773190597Simp	DELAY(10*1000);
774190559Simp
775190559Simp	/* Make sure that we really have an 8390 based board */
776190559Simp	if (!ed_probe_generic8390(sc))
777190559Simp		return (ENXIO);
778190559Simp
779190559Simp	sc->vendor = ED_VENDOR_NOVELL;
780190559Simp	sc->mem_shared = 0;
781190559Simp	sc->cr_proto = ED_CR_RD2;
782190559Simp
783190559Simp	/*
784190559Simp	 * This prevents packets from being stored in the NIC memory when the
785190596Simp	 * readmem routine turns on the start bit in the CR.  We write some
786190596Simp	 * bytes in word mode and verify we can read them back.  If we can't
787190596Simp	 * then we don't have an AX88x90 chip here.
788190559Simp	 */
789190644Simp	sc->isa16bit = 1;
790190559Simp	ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON);
791190559Simp	ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
792190559Simp	ed_pio_writemem(sc, test_pattern, 16384, sizeof(test_pattern));
793190559Simp	ed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern));
794190559Simp	if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) != 0)
795190559Simp		return (ENXIO);
796190596Simp
797190596Simp	/*
798190596Simp	 * Hard code values based on the datasheet.  We're NE-2000 compatible
799190644Simp	 * NIC with 16kb of packet memory starting at 16k offset.
800190596Simp	 */
801190559Simp	sc->type = ED_TYPE_NE2000;
802190644Simp	memsize = sc->mem_size = 16*1024;
803190644Simp	sc->mem_start = 16 * 1024;
804190559Simp	if (ed_asic_inb(sc, ED_AX88X90_TEST) != 0)
805190559Simp		sc->chip_type = ED_CHIP_TYPE_AX88790;
806190644Simp	else {
807190559Simp		sc->chip_type = ED_CHIP_TYPE_AX88190;
808190644Simp		/*
809190644Simp		 * The AX88190 (not A) has external 64k SRAM.  Probe for this
810190644Simp		 * here.  Most of the cards I have either use the AX88190A
811190644Simp		 * part, or have only 32k SRAM for some reason, so I don't
812190644Simp		 * know if this works or not.
813190644Simp		 */
814190644Simp		ed_pio_writemem(sc, test_pattern, 32768, sizeof(test_pattern));
815190644Simp		ed_pio_readmem(sc, 32768, test_buffer, sizeof(test_pattern));
816190644Simp		if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) {
817190644Simp			sc->mem_start = 2*1024;
818190644Simp			memsize = sc->mem_size = 62 * 1024;
819190644Simp		}
820190644Simp	}
821190559Simp	sc->mem_end = sc->mem_start + memsize;
822190559Simp	sc->tx_page_start = memsize / ED_PAGE_SIZE;
823190644Simp	if (sc->mem_size > 16 * 1024)
824190644Simp		sc->txb_cnt = 3;
825190644Simp	else
826190644Simp		sc->txb_cnt = 2;
827190559Simp	sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
828190559Simp	sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE;
829190559Simp
830190559Simp	sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
831190644Simp
832190644Simp	ed_nic_outb(sc, ED_P0_PSTART, sc->mem_start / ED_PAGE_SIZE);
833190644Simp	ed_nic_outb(sc, ED_P0_PSTOP, sc->mem_end / ED_PAGE_SIZE);
834190644Simp
835190644Simp	/* Get the mac before we go -- It's just at 0x400 in "SRAM" */
836190644Simp	ed_pio_readmem(sc, 0x400, sc->enaddr, ETHER_ADDR_LEN);
837190644Simp
838190559Simp	/* clear any pending interrupts that might have occurred above */
839190559Simp	ed_nic_outb(sc, ED_P0_ISR, 0xff);
840190559Simp	sc->sc_write_mbufs = ed_pio_write_mbufs;
841190559Simp	return (0);
842190559Simp}
843190559Simp
844190559Simpstatic int
845190559Simped_pccard_ax88x90_check_mii(device_t dev, struct ed_softc *sc)
846190559Simp{
847190559Simp	int	i, id;
848190559Simp
849190559Simp	/*
850190559Simp	 * All AX88x90 devices have MII and a PHY, so we use this to weed out
851190559Simp	 * chips that would otherwise make it through the tests we have after
852190559Simp	 * this point.
853190559Simp	 */
854190559Simp	for (i = 0; i < 32; i++) {
855190559Simp		id = ed_miibus_readreg(dev, i, MII_BMSR);
856190559Simp		if (id != 0 && id != 0xffff)
857190559Simp			break;
858190559Simp	}
859190559Simp	/*
860190559Simp	 * Found one, we're good.
861190559Simp	 */
862190559Simp	if (i != 32)
863190559Simp		return (0);
864190559Simp	/*
865190559Simp	 * Didn't find anything, so try to power up and try again.  The PHY
866190559Simp	 * may be not responding because we're in power down mode.
867190559Simp	 */
868190559Simp	if (sc->chip_type == ED_CHIP_TYPE_AX88190)
869190559Simp		return (ENXIO);
870190559Simp	pccard_ccr_write_1(dev, PCCARD_CCR_STATUS, PCCARD_CCR_STATUS_PWRDWN);
871190559Simp	for (i = 0; i < 32; i++) {
872190559Simp		id = ed_miibus_readreg(dev, i, MII_BMSR);
873190559Simp		if (id != 0 && id != 0xffff)
874190559Simp			break;
875190559Simp	}
876190559Simp	/*
877190559Simp	 * Still no joy?  We're AFU, punt.
878190559Simp	 */
879190559Simp	if (i == 32)
880190559Simp		return (ENXIO);
881190559Simp	return (0);
882190559Simp
883190559Simp}
884190559Simp
885149841Simp/*
886149841Simp * Special setup for AX88[17]90
887149841Simp */
888149841Simpstatic int
889149841Simped_pccard_ax88x90(device_t dev, const struct ed_product *pp)
890149841Simp{
891190559Simp	int	error;
892190559Simp	int iobase;
893149841Simp	struct	ed_softc *sc = device_get_softc(dev);
894149841Simp
895150108Simp	if (!(pp->flags & NE2000DVF_AX88X90))
896149841Simp		return (ENXIO);
897149841Simp
898150108Simp	if (bootverbose)
899150108Simp		device_printf(dev, "Checking AX88x90\n");
900150108Simp
901150108Simp	/*
902150108Simp	 * Set the IOBASE Register.  The AX88x90 cards are potentially
903150108Simp	 * multifunction cards, and thus requires a slight workaround.
904190559Simp	 * We write the address the card is at, on the off chance that this
905190559Simp	 * card is not MFC.
906190559Simp	 * XXX I'm not sure that this is still needed...
907149841Simp	 */
908149841Simp	iobase = rman_get_start(sc->port_res);
909150108Simp	pccard_ccr_write_1(dev, PCCARD_CCR_IOBASE0, iobase & 0xff);
910150108Simp	pccard_ccr_write_1(dev, PCCARD_CCR_IOBASE1, (iobase >> 8) & 0xff);
911150108Simp
912150108Simp	sc->mii_readbits = ed_pccard_ax88x90_mii_readbits;
913150108Simp	sc->mii_writebits = ed_pccard_ax88x90_mii_writebits;
914190559Simp	error = ed_probe_ax88x90_generic(dev, device_get_flags(dev));
915190559Simp	if (error) {
916190559Simp		if (bootverbose)
917190559Simp			device_printf(dev, "probe ax88x90 failed %d\n",
918190559Simp			    error);
919190559Simp		goto fail;
920150108Simp	}
921190559Simp	error = ed_pccard_ax88x90_check_mii(dev, sc);
922190559Simp	if (error)
923190559Simp		goto fail;
924190559Simp	sc->vendor = ED_VENDOR_NOVELL;
925190559Simp	sc->type = ED_TYPE_NE2000;
926190559Simp	if (sc->chip_type == ED_CHIP_TYPE_AX88190)
927190559Simp		sc->type_str = "AX88190";
928190559Simp	else
929190559Simp		sc->type_str = "AX88790";
930190559Simp	return (0);
931190559Simpfail:;
932190559Simp	sc->mii_readbits = 0;
933190559Simp	sc->mii_writebits = 0;
934149841Simp	return (error);
935149841Simp}
936149841Simp
937150108Simpstatic void
938150108Simped_pccard_ax88x90_mii_writebits(struct ed_softc *sc, u_int val, int nbits)
939150108Simp{
940190559Simp	int i, data;
941150108Simp
942150108Simp	for (i = nbits - 1; i >= 0; i--) {
943190559Simp		data = (val >> i) & 1 ? ED_AX88X90_MII_DATAOUT : 0;
944190559Simp		ed_asic_outb(sc, ED_AX88X90_MIIBUS, data);
945190559Simp		ed_asic_outb(sc, ED_AX88X90_MIIBUS, data | ED_AX88X90_MII_CLK);
946150108Simp	}
947150108Simp}
948150108Simp
949150108Simpstatic u_int
950150108Simped_pccard_ax88x90_mii_readbits(struct ed_softc *sc, int nbits)
951150108Simp{
952150108Simp	int i;
953150108Simp	u_int val = 0;
954190559Simp	uint8_t mdio;
955150108Simp
956190559Simp	mdio = ED_AX88X90_MII_DIRIN;
957150108Simp	for (i = nbits - 1; i >= 0; i--) {
958190559Simp		ed_asic_outb(sc, ED_AX88X90_MIIBUS, mdio);
959150108Simp		val <<= 1;
960150957Simp		if (ed_asic_inb(sc, ED_AX88X90_MIIBUS) & ED_AX88X90_MII_DATAIN)
961150108Simp			val++;
962190559Simp		ed_asic_outb(sc, ED_AX88X90_MIIBUS, mdio | ED_AX88X90_MII_CLK);
963150108Simp	}
964150108Simp	return val;
965150108Simp}
966150108Simp
967150108Simp/*
968150957Simp * Special setup for TC5299J
969150957Simp */
970150957Simpstatic int
971150957Simped_pccard_tc5299j(device_t dev, const struct ed_product *pp)
972150957Simp{
973150957Simp	int	error, i, id;
974150957Simp	char *ts;
975150957Simp	struct	ed_softc *sc = device_get_softc(dev);
976150957Simp
977150957Simp	if (!(pp->flags & NE2000DVF_TC5299J))
978150957Simp		return (ENXIO);
979150957Simp
980150957Simp	if (bootverbose)
981150957Simp		device_printf(dev, "Checking Tc5299j\n");
982150957Simp
983191370Simp	error = ed_probe_Novell_generic(dev, device_get_flags(dev));
984191370Simp	if (bootverbose)
985191370Simp		device_printf(dev, "probe novel returns %d\n", error);
986191370Simp	if (error != 0)
987191370Simp		return (error);
988191370Simp
989150957Simp	/*
990191370Simp	 * Check to see if we have a MII PHY ID at any address.  All TC5299J
991191370Simp	 * devices have MII and a PHY, so we use this to weed out chips that
992191370Simp	 * would otherwise make it through the tests we have after this point.
993150957Simp	 */
994150957Simp	sc->mii_readbits = ed_pccard_tc5299j_mii_readbits;
995150957Simp	sc->mii_writebits = ed_pccard_tc5299j_mii_writebits;
996150957Simp	for (i = 0; i < 32; i++) {
997150957Simp		id = ed_miibus_readreg(dev, i, MII_PHYIDR1);
998150957Simp		if (id != 0 && id != 0xffff)
999150957Simp			break;
1000150957Simp	}
1001150957Simp	if (i == 32) {
1002150957Simp		sc->mii_readbits = 0;
1003150957Simp		sc->mii_writebits = 0;
1004150957Simp		return (ENXIO);
1005150957Simp	}
1006150957Simp	ts = "TC5299J";
1007150957Simp	if (ed_pccard_rom_mac(dev, sc->enaddr) == 0) {
1008150957Simp		sc->mii_readbits = 0;
1009150957Simp		sc->mii_writebits = 0;
1010150957Simp		return (ENXIO);
1011150957Simp	}
1012150957Simp	sc->vendor = ED_VENDOR_NOVELL;
1013150957Simp	sc->type = ED_TYPE_NE2000;
1014150957Simp	sc->chip_type = ED_CHIP_TYPE_TC5299J;
1015150957Simp	sc->type_str = ts;
1016150957Simp	return (0);
1017150957Simp}
1018150957Simp
1019150957Simpstatic void
1020150957Simped_pccard_tc5299j_mii_writebits(struct ed_softc *sc, u_int val, int nbits)
1021150957Simp{
1022150957Simp	int i;
1023190900Simp	uint8_t cr, data;
1024150957Simp
1025190900Simp	/* Select page 3 */
1026150957Simp	cr = ed_nic_inb(sc, ED_P0_CR);
1027150957Simp	ed_nic_outb(sc, ED_P0_CR, cr | ED_CR_PAGE_3);
1028150957Simp
1029150957Simp	for (i = nbits - 1; i >= 0; i--) {
1030190900Simp		data = (val >> i) & 1 ? ED_TC5299J_MII_DATAOUT : 0;
1031190900Simp		ed_nic_outb(sc, ED_TC5299J_MIIBUS, data);
1032190900Simp		ed_nic_outb(sc, ED_TC5299J_MIIBUS, data | ED_TC5299J_MII_CLK);
1033150957Simp	}
1034190900Simp	ed_nic_outb(sc, ED_TC5299J_MIIBUS, 0);
1035190900Simp
1036190900Simp	/* Restore prior page */
1037150957Simp	ed_nic_outb(sc, ED_P0_CR, cr);
1038150957Simp}
1039150957Simp
1040150957Simpstatic u_int
1041150957Simped_pccard_tc5299j_mii_readbits(struct ed_softc *sc, int nbits)
1042150957Simp{
1043150957Simp	int i;
1044150957Simp	u_int val = 0;
1045150957Simp	uint8_t cr;
1046150957Simp
1047190900Simp	/* Select page 3 */
1048150957Simp	cr = ed_nic_inb(sc, ED_P0_CR);
1049150957Simp	ed_nic_outb(sc, ED_P0_CR, cr | ED_CR_PAGE_3);
1050150957Simp
1051190900Simp	ed_asic_outb(sc, ED_TC5299J_MIIBUS, ED_TC5299J_MII_DIROUT);
1052150957Simp	for (i = nbits - 1; i >= 0; i--) {
1053190900Simp		ed_nic_outb(sc, ED_TC5299J_MIIBUS,
1054190900Simp		    ED_TC5299J_MII_CLK | ED_TC5299J_MII_DIROUT);
1055150957Simp		val <<= 1;
1056150957Simp		if (ed_nic_inb(sc, ED_TC5299J_MIIBUS) & ED_TC5299J_MII_DATAIN)
1057150957Simp			val++;
1058190900Simp		ed_nic_outb(sc, ED_TC5299J_MIIBUS, ED_TC5299J_MII_DIROUT);
1059150957Simp	}
1060190900Simp
1061190900Simp	/* Restore prior page */
1062150957Simp	ed_nic_outb(sc, ED_P0_CR, cr);
1063150957Simp	return val;
1064150957Simp}
1065150957Simp
1066150957Simp/*
1067150108Simp * MII bus support routines.
1068150108Simp */
1069150108Simpstatic int
1070150108Simped_miibus_readreg(device_t dev, int phy, int reg)
1071150108Simp{
1072150108Simp	struct ed_softc *sc;
1073150108Simp	int failed, val;
1074150108Simp
1075190559Simp	sc = device_get_softc(dev);
1076150108Simp	/*
1077190559Simp	 * The AX88790 has an interesting quirk.  It has an internal phy that
1078190559Simp	 * needs a special bit set to access, but can also have additional
1079190559Simp	 * external PHYs set for things like HomeNET media.  When accessing
1080190559Simp	 * the internal PHY, a bit has to be set, when accessing the external
1081190559Simp	 * PHYs, it must be clear.  See Errata 1, page 51, in the AX88790
1082190559Simp	 * datasheet for more details.
1083190586Simp	 *
1084190586Simp	 * Also, PHYs above 16 appear to be phantoms on some cards, but not
1085190586Simp	 * others.  Registers read for this are often the same as prior values
1086190586Simp	 * read.  Filter all register requests to 17-31.
1087190598Simp	 *
1088190598Simp	 * I can't explain it, since I don't have the DL100xx data sheets, but
1089190598Simp	 * the DL100xx chips do 13-bits before the 'ACK' but, but the AX88x90
1090190598Simp	 * chips have 14.  The linux pcnet and axnet drivers confirm this.
1091150108Simp	 */
1092190559Simp	if (sc->chip_type == ED_CHIP_TYPE_AX88790) {
1093190586Simp		if (phy > 0x10)
1094190586Simp			return (0);
1095190559Simp		if (phy == 0x10)
1096190559Simp			ed_asic_outb(sc, ED_AX88X90_GPIO,
1097190559Simp			    ED_AX88X90_GPIO_INT_PHY);
1098190559Simp		else
1099190559Simp			ed_asic_outb(sc, ED_AX88X90_GPIO, 0);
1100190559Simp	}
1101150108Simp
1102150108Simp	(*sc->mii_writebits)(sc, 0xffffffff, 32);
1103150108Simp	(*sc->mii_writebits)(sc, ED_MII_STARTDELIM, ED_MII_STARTDELIM_BITS);
1104150108Simp	(*sc->mii_writebits)(sc, ED_MII_READOP, ED_MII_OP_BITS);
1105150108Simp	(*sc->mii_writebits)(sc, phy, ED_MII_PHY_BITS);
1106150108Simp	(*sc->mii_writebits)(sc, reg, ED_MII_REG_BITS);
1107190583Simp	if (sc->chip_type == ED_CHIP_TYPE_AX88790 ||
1108190583Simp	    sc->chip_type == ED_CHIP_TYPE_AX88190)
1109190583Simp		(*sc->mii_readbits)(sc, ED_MII_ACK_BITS);
1110150108Simp	failed = (*sc->mii_readbits)(sc, ED_MII_ACK_BITS);
1111150108Simp	val = (*sc->mii_readbits)(sc, ED_MII_DATA_BITS);
1112150108Simp	(*sc->mii_writebits)(sc, ED_MII_IDLE, ED_MII_IDLE_BITS);
1113190651Simp/*	printf("Reading phy %d reg %#x returning %#x (valid %d)\n", phy, reg, val, !failed); */
1114150108Simp	return (failed ? 0 : val);
1115150108Simp}
1116150108Simp
1117189726Simpstatic int
1118150108Simped_miibus_writereg(device_t dev, int phy, int reg, int data)
1119150108Simp{
1120150108Simp	struct ed_softc *sc;
1121150108Simp
1122190651Simp/*	printf("Writing phy %d reg %#x data %#x\n", phy, reg, data); */
1123190559Simp	sc = device_get_softc(dev);
1124190586Simp	/* See ed_miibus_readreg for details */
1125190559Simp	if (sc->chip_type == ED_CHIP_TYPE_AX88790) {
1126190586Simp		if (phy > 0x10)
1127190586Simp			return (0);
1128190559Simp		if (phy == 0x10)
1129190559Simp			ed_asic_outb(sc, ED_AX88X90_GPIO,
1130190559Simp			    ED_AX88X90_GPIO_INT_PHY);
1131190559Simp		else
1132190559Simp			ed_asic_outb(sc, ED_AX88X90_GPIO, 0);
1133190559Simp	}
1134150108Simp	(*sc->mii_writebits)(sc, 0xffffffff, 32);
1135150108Simp	(*sc->mii_writebits)(sc, ED_MII_STARTDELIM, ED_MII_STARTDELIM_BITS);
1136150108Simp	(*sc->mii_writebits)(sc, ED_MII_WRITEOP, ED_MII_OP_BITS);
1137150108Simp	(*sc->mii_writebits)(sc, phy, ED_MII_PHY_BITS);
1138150108Simp	(*sc->mii_writebits)(sc, reg, ED_MII_REG_BITS);
1139150108Simp	(*sc->mii_writebits)(sc, ED_MII_TURNAROUND, ED_MII_TURNAROUND_BITS);
1140150108Simp	(*sc->mii_writebits)(sc, data, ED_MII_DATA_BITS);
1141150108Simp	(*sc->mii_writebits)(sc, ED_MII_IDLE, ED_MII_IDLE_BITS);
1142189726Simp	return (0);
1143150108Simp}
1144150108Simp
1145150300Simpstatic int
1146150300Simped_ifmedia_upd(struct ifnet *ifp)
1147150300Simp{
1148150300Simp	struct ed_softc *sc;
1149190643Simp	int error;
1150150300Simp
1151150300Simp	sc = ifp->if_softc;
1152150300Simp	if (sc->miibus == NULL)
1153150300Simp		return (ENXIO);
1154190643Simp	ED_LOCK(sc);
1155190643Simp	error = ed_pccard_kick_phy(sc);
1156190643Simp	ED_UNLOCK(sc);
1157190643Simp	return (error);
1158150300Simp}
1159150300Simp
1160150300Simpstatic void
1161150300Simped_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
1162150300Simp{
1163150300Simp	struct ed_softc *sc;
1164150300Simp	struct mii_data *mii;
1165150300Simp
1166150300Simp	sc = ifp->if_softc;
1167150300Simp	if (sc->miibus == NULL)
1168150300Simp		return;
1169150300Simp
1170150300Simp	mii = device_get_softc(sc->miibus);
1171150300Simp	mii_pollstat(mii);
1172150300Simp	ifmr->ifm_active = mii->mii_media_active;
1173150300Simp	ifmr->ifm_status = mii->mii_media_status;
1174150300Simp}
1175150300Simp
1176150300Simpstatic void
1177150300Simped_child_detached(device_t dev, device_t child)
1178150300Simp{
1179150300Simp	struct ed_softc *sc;
1180150300Simp
1181150300Simp	sc = device_get_softc(dev);
1182150300Simp	if (child == sc->miibus)
1183150300Simp		sc->miibus = NULL;
1184150300Simp}
1185150300Simp
1186190804Simpstatic void
1187199380Sjhbed_pccard_tick(struct ed_softc *sc)
1188190804Simp{
1189190804Simp	struct mii_data *mii;
1190190804Simp	int media = 0;
1191190804Simp
1192190804Simp	ED_ASSERT_LOCKED(sc);
1193190804Simp	if (sc->miibus != NULL) {
1194190804Simp		mii = device_get_softc(sc->miibus);
1195190804Simp		media = mii->mii_media_status;
1196190804Simp		mii_tick(mii);
1197190804Simp		if (mii->mii_media_status & IFM_ACTIVE &&
1198190804Simp		    media != mii->mii_media_status) {
1199190804Simp			if (sc->chip_type == ED_CHIP_TYPE_DL10022) {
1200190804Simp				ed_asic_outb(sc, ED_DL10022_DIAG,
1201190804Simp				    (mii->mii_media_active & IFM_FDX) ?
1202190804Simp				    ED_DL10022_COLLISON_DIS : 0);
1203190805Simp#ifdef notyet
1204190804Simp			} else if (sc->chip_type == ED_CHIP_TYPE_DL10019) {
1205190804Simp				write_asic(sc, ED_DL10019_MAGIC,
1206190804Simp				    (mii->mii_media_active & IFM_FDX) ?
1207190804Simp				    DL19FDUPLX : 0);
1208190805Simp#endif
1209190804Simp			}
1210190804Simp		}
1211190804Simp
1212190804Simp	}
1213190804Simp}
1214190804Simp
121570355Simpstatic device_method_t ed_pccard_methods[] = {
121670355Simp	/* Device interface */
1217149558Simp	DEVMETHOD(device_probe,		ed_pccard_probe),
1218149558Simp	DEVMETHOD(device_attach,	ed_pccard_attach),
1219141494Simp	DEVMETHOD(device_detach,	ed_detach),
122070355Simp
122173374Simp	/* Bus interface */
122273374Simp	DEVMETHOD(bus_child_detached,	ed_child_detached),
122373374Simp
122473374Simp	/* MII interface */
122573374Simp	DEVMETHOD(miibus_readreg,	ed_miibus_readreg),
122673374Simp	DEVMETHOD(miibus_writereg,	ed_miibus_writereg),
122773374Simp
122870355Simp	{ 0, 0 }
122970355Simp};
123070355Simp
123170355Simpstatic driver_t ed_pccard_driver = {
123270355Simp	"ed",
123370355Simp	ed_pccard_methods,
123470355Simp	sizeof(struct ed_softc)
123570355Simp};
123670355Simp
1237113506SmdoddDRIVER_MODULE(ed, pccard, ed_pccard_driver, ed_devclass, 0, 0);
123873374SimpDRIVER_MODULE(miibus, ed, miibus_driver, miibus_devclass, 0, 0);
1239150300SimpMODULE_DEPEND(ed, miibus, 1, 1, 1);
1240150300SimpMODULE_DEPEND(ed, ether, 1, 1, 1);
1241