]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ed/if_ed_pccard.c
When stopping the card, and returning to page 0, it is best if you do
[FreeBSD/FreeBSD.git] / sys / dev / ed / if_ed_pccard.c
1 /*-
2  * Copyright (c) 2005, M. Warner Losh
3  * Copyright (c) 1995, David Greenman
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice unmodified, this list of conditions, and the following
11  *    disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30
31 #include "opt_ed.h"
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/socket.h>
36 #include <sys/kernel.h>
37 #include <sys/conf.h>
38 #include <sys/uio.h>
39
40 #include <sys/module.h>
41 #include <sys/bus.h>
42 #include <machine/bus.h>
43 #include <sys/rman.h>
44 #include <machine/resource.h>
45
46 #include <net/ethernet.h>
47 #include <net/if.h>
48 #include <net/if_arp.h>
49 #include <net/if_mib.h>
50 #include <net/if_media.h>
51
52 #include <dev/ed/if_edreg.h>
53 #include <dev/ed/if_edvar.h>
54 #include <dev/pccard/pccardvar.h>
55 #include <dev/pccard/pccardreg.h>
56 #include <dev/pccard/pccard_cis.h>
57 #ifndef ED_NO_MIIBUS
58 #include <dev/mii/mii.h>
59 #include <dev/mii/miivar.h>
60 #endif
61
62 #include "card_if.h"
63 #ifndef ED_NO_MIIBUS
64 /* "device miibus" required.  See GENERIC if you get errors here. */
65 #include "miibus_if.h"
66 #endif
67 #include "pccarddevs.h"
68
69 #ifndef ED_NO_MIIBUS
70 MODULE_DEPEND(ed, miibus, 1, 1, 1);
71 #endif
72 MODULE_DEPEND(ed, ether, 1, 1, 1);
73
74 /*
75  * PC Cards should be using a network specific FUNCE in the CIS to
76  * communicate their MAC address to the driver.  However, there are a
77  * large number of NE-2000ish PC Cards that don't do this.  Nearly all
78  * of them store the MAC address at a fixed offset into attribute
79  * memory, without any reference at all appearing in the CIS.  And
80  * nearly all of those store it at the same location.
81  *
82  * This applies only to the older, NE-2000 compatbile cards.  The newer
83  * cards based on the AX88x90 or DL100XX chipsets have a specific place
84  * to look for MAC information.  And only to those NE-2000 compatible cards
85  * that don't the NE-2000 compatible thing of placing the PROM contents
86  * starting at location 0 of memory.
87  */
88 #define ED_DEFAULT_MAC_OFFSET   0xff0
89
90 static const struct ed_product {
91         struct pccard_product   prod;
92         int flags;
93 #define NE2000DVF_DL100XX       0x0001          /* chip is D-Link DL10019/22 */
94 #define NE2000DVF_AX88X90       0x0002          /* chip is ASIX AX88[17]90 */
95 #define NE2000DVF_ENADDR        0x0004          /* Get MAC from attr mem */
96 #define NE2000DVF_ANYFUNC       0x0008          /* Allow any function type */
97 #define NE2000DVF_MODEM         0x0010          /* Has a modem/serial */
98         int enoff;
99 } ed_pccard_products[] = {
100         { PCMCIA_CARD(ACCTON, EN2212), 0},
101         { PCMCIA_CARD(ACCTON, EN2216), 0},
102         { PCMCIA_CARD(ALLIEDTELESIS, LA_PCM), 0},
103         { PCMCIA_CARD(AMBICOM, AMB8002T), 0},
104         { PCMCIA_CARD(BILLIONTON, LNT10TN), 0},
105         { PCMCIA_CARD(BILLIONTON, CFLT10N), 0},
106         { PCMCIA_CARD(BROMAX, IPORT), 0},
107         { PCMCIA_CARD(BROMAX, IPORT2), 0},
108         { PCMCIA_CARD(BUFFALO, LPC2_CLT), 0},
109         { PCMCIA_CARD(BUFFALO, LPC3_CLT), 0},
110         { PCMCIA_CARD(BUFFALO, LPC3_CLX), NE2000DVF_AX88X90},
111         { PCMCIA_CARD(BUFFALO, LPC4_TX), NE2000DVF_AX88X90},
112         { PCMCIA_CARD(BUFFALO, LPC_CF_CLT), 0},
113         { PCMCIA_CARD(CNET, NE2000), 0},
114         { PCMCIA_CARD(COMPEX, AX88190), NE2000DVF_AX88X90},
115         { PCMCIA_CARD(COMPEX, LANMODEM), 0},
116         { PCMCIA_CARD(COMPEX, LINKPORT_ENET_B), 0},
117         { PCMCIA_CARD(COREGA, ETHER_II_PCC_T), 0},
118         { PCMCIA_CARD(COREGA, ETHER_II_PCC_TD), 0},
119         { PCMCIA_CARD(COREGA, ETHER_PCC_T), 0},
120         { PCMCIA_CARD(COREGA, ETHER_PCC_TD), 0},
121         { PCMCIA_CARD(COREGA, FAST_ETHER_PCC_TX), NE2000DVF_DL100XX},
122         { PCMCIA_CARD(COREGA, FETHER_PCC_TXD), NE2000DVF_AX88X90},
123         { PCMCIA_CARD(COREGA, FETHER_PCC_TXF), NE2000DVF_DL100XX},
124         { PCMCIA_CARD(DAYNA, COMMUNICARD_E_1), 0},
125         { PCMCIA_CARD(DAYNA, COMMUNICARD_E_2), 0},
126         { PCMCIA_CARD(DLINK, DE650), 0},
127         { PCMCIA_CARD(DLINK, DE660), 0 },
128         { PCMCIA_CARD(DLINK, DE660PLUS), 0},
129         { PCMCIA_CARD(DYNALINK, L10C), 0},
130         { PCMCIA_CARD(EDIMAX, EP4000A), 0},
131         { PCMCIA_CARD(EPSON, EEN10B), 0},
132         { PCMCIA_CARD(EXP, THINLANCOMBO), 0},
133         { PCMCIA_CARD(GREY_CELL, TDK3000), 0},
134         { PCMCIA_CARD(GREY_CELL, DMF650TX),
135             NE2000DVF_ANYFUNC | NE2000DVF_DL100XX | NE2000DVF_MODEM},
136         { PCMCIA_CARD(IBM, HOME_AND_AWAY), 0},
137         { PCMCIA_CARD(IBM, INFOMOVER), NE2000DVF_ENADDR, 0xff0},
138         { PCMCIA_CARD(IODATA3, PCLAT), 0},
139         { PCMCIA_CARD(KINGSTON, CIO10T), 0},
140         { PCMCIA_CARD(KINGSTON, KNE2), 0},
141         { PCMCIA_CARD(LANTECH, FASTNETTX), NE2000DVF_AX88X90},
142         { PCMCIA_CARD(LINKSYS, COMBO_ECARD),
143             NE2000DVF_DL100XX | NE2000DVF_AX88X90},
144         { PCMCIA_CARD(LINKSYS, ECARD_1), 0},
145         { PCMCIA_CARD(LINKSYS, ECARD_2), 0},
146         { PCMCIA_CARD(LINKSYS, ETHERFAST), NE2000DVF_DL100XX},
147         { PCMCIA_CARD(LINKSYS, TRUST_COMBO_ECARD), 0},
148         { PCMCIA_CARD(MACNICA, ME1_JEIDA), 0},
149         { PCMCIA_CARD(MAGICRAM, ETHER), 0},
150         { PCMCIA_CARD(MELCO, LPC3_CLX), NE2000DVF_AX88X90},
151         { PCMCIA_CARD(MELCO, LPC3_TX), NE2000DVF_AX88X90},
152         { PCMCIA_CARD(NDC, ND5100_E), 0},
153         { PCMCIA_CARD(NETGEAR, FA410TXC), NE2000DVF_DL100XX},
154         /* Same ID as DLINK DFE-670TXD.  670 has DL10022, fa411 has ax88790 */
155         { PCMCIA_CARD(NETGEAR, FA411), NE2000DVF_AX88X90 | NE2000DVF_DL100XX},
156         { PCMCIA_CARD(NEXTCOM, NEXTHAWK), 0},
157         { PCMCIA_CARD(NEWMEDIA, LANSURFER), 0},
158         { PCMCIA_CARD(OEM2, ETHERNET), 0},
159         { PCMCIA_CARD(OEM2, NE2000), 0},
160         { PCMCIA_CARD(PLANET, SMARTCOM2000), 0 },
161         { PCMCIA_CARD(PREMAX, PE200), 0},
162         { PCMCIA_CARD(PSION, LANGLOBAL), 0},
163         { PCMCIA_CARD(RACORE, ETHERNET), 0},
164         { PCMCIA_CARD(RACORE, FASTENET), NE2000DVF_AX88X90},
165         { PCMCIA_CARD(RACORE, 8041TX), NE2000DVF_AX88X90},
166         { PCMCIA_CARD(RELIA, COMBO), 0},
167         { PCMCIA_CARD(RPTI, EP400), 0},
168         { PCMCIA_CARD(RPTI, EP401), 0},
169         { PCMCIA_CARD(SMC, EZCARD), 0},
170         { PCMCIA_CARD(SOCKET, EA_ETHER), 0},
171         { PCMCIA_CARD(SOCKET, ES_1000), 0},
172         { PCMCIA_CARD(SOCKET, LP_ETHER), 0},
173         { PCMCIA_CARD(SOCKET, LP_ETHER_CF), 0},
174         { PCMCIA_CARD(SOCKET, LP_ETH_10_100_CF), NE2000DVF_DL100XX},
175         { PCMCIA_CARD(SVEC, COMBOCARD), 0},
176         { PCMCIA_CARD(SVEC, LANCARD), 0},
177         { PCMCIA_CARD(TAMARACK, ETHERNET), 0},
178         { PCMCIA_CARD(TDK, CFE_10), 0},
179         { PCMCIA_CARD(TDK, LAK_CD031), 0},
180         { PCMCIA_CARD(TDK, DFL5610WS), 0},
181         { PCMCIA_CARD(TELECOMDEVICE, LM5LT), 0 },
182         { PCMCIA_CARD(TELECOMDEVICE, TCD_HPC100), NE2000DVF_AX88X90},
183         { PCMCIA_CARD(ZONET, ZEN), 0},
184         { { NULL } }
185 };
186
187 /*
188  *      PC Card (PCMCIA) specific code.
189  */
190 static int      ed_pccard_probe(device_t);
191 static int      ed_pccard_attach(device_t);
192
193 static int      ed_pccard_dl100xx(device_t dev, const struct ed_product *);
194 #ifndef ED_NO_MIIBUS
195 static void     ed_pccard_dl100xx_mii_reset(struct ed_softc *sc);
196 static u_int    ed_pccard_dl100xx_mii_readbits(struct ed_softc *sc, int nbits);
197 static void     ed_pccard_dl100xx_mii_writebits(struct ed_softc *sc, u_int val,
198     int nbits);
199
200 static void     ed_pccard_ax88x90_mii_reset(struct ed_softc *sc);
201 static u_int    ed_pccard_ax88x90_mii_readbits(struct ed_softc *sc, int nbits);
202 static void     ed_pccard_ax88x90_mii_writebits(struct ed_softc *sc, u_int val,
203     int nbits);
204 static int      ed_miibus_readreg(device_t dev, int phy, int reg);
205 #endif
206
207 static int      ed_pccard_ax88x90(device_t dev, const struct ed_product *);
208
209 static int
210 ed_pccard_probe(device_t dev)
211 {
212         const struct ed_product *pp;
213         int             error;
214         uint32_t        fcn = PCCARD_FUNCTION_UNSPEC;
215
216         /* Make sure we're a network function */
217         error = pccard_get_function(dev, &fcn);
218         if (error != 0)
219                 return (error);
220
221         if ((pp = (const struct ed_product *) pccard_product_lookup(dev, 
222             (const struct pccard_product *) ed_pccard_products,
223             sizeof(ed_pccard_products[0]), NULL)) != NULL) {
224                 if (pp->prod.pp_name != NULL)
225                         device_set_desc(dev, pp->prod.pp_name);
226                 /*
227                  * Some devices don't ID themselves as network, but
228                  * that's OK if the flags say so.
229                  */
230                 if (!(pp->flags & NE2000DVF_ANYFUNC) &&
231                     fcn != PCCARD_FUNCTION_NETWORK)
232                         return (ENXIO);
233                 return (0);
234         }
235         return (ENXIO);
236 }
237
238 static int
239 ed_pccard_rom_mac(device_t dev, uint8_t *enaddr)
240 {
241         struct ed_softc *sc = device_get_softc(dev);
242         uint8_t romdata[32];
243         int i;
244
245         /*
246          * Read in the rom data at location 0.  Since there are no
247          * NE-1000 based PC Card devices, we'll assume we're 16-bit.
248          *
249          * In researching what format this takes, I've found that the
250          * following appears to be true for multiple cards based on
251          * observation as well as datasheet digging.
252          *
253          * Data is stored in some ROM and is copied out 8 bits at a time
254          * into 16-bit wide locations.  This means that the odd locations
255          * of the ROM are not used (and can be either 0 or ff).
256          *
257          * The contents appears to be as follows:
258          * PROM   RAM
259          * Offset Offset        What
260          *  0      0    ENETADDR 0
261          *  1      2    ENETADDR 1
262          *  2      4    ENETADDR 2
263          *  3      6    ENETADDR 3
264          *  4      8    ENETADDR 4
265          *  5     10    ENETADDR 5
266          *  6-13  12-26 Reserved (varies by manufacturer)
267          * 14     28    0x57
268          * 15     30    0x57
269          *
270          * Some manufacturers have another image of enetaddr from
271          * PROM offset 0x10 to 0x15 with 0x42 in 0x1e and 0x1f, but
272          * this doesn't appear to be universally documented in the
273          * datasheets.  Some manufactuers have a card type, card config
274          * checksums, etc encoded into PROM offset 6-13, but deciphering it
275          * requires more knowledge about the exact underlying chipset than
276          * we possess (and maybe can possess).
277          */
278         ed_pio_readmem(sc, 0, romdata, 32);
279         if (bootverbose)
280                 printf("ROM DATA: %32D\n", romdata, " ");
281         if (romdata[28] != 0x57 || romdata[30] != 0x57)
282                 return (0);
283         for (i = 0; i < ETHER_ADDR_LEN; i++)
284                 enaddr[i] = romdata[i * 2];
285         return (1);
286 }
287
288 static int
289 ed_pccard_add_modem(device_t dev)
290 {
291         struct ed_softc *sc = device_get_softc(dev);
292
293         device_printf(dev, "Need to write this code: modem rid is %d\n",
294             sc->modem_rid);
295         return 0;
296 }
297
298 static int
299 ed_pccard_attach(device_t dev)
300 {
301         u_char sum;
302         u_char enaddr[ETHER_ADDR_LEN];
303         const struct ed_product *pp;
304         int     error, i;
305         struct ed_softc *sc = device_get_softc(dev);
306         u_long size;
307
308         if ((pp = (const struct ed_product *) pccard_product_lookup(dev, 
309             (const struct pccard_product *) ed_pccard_products,
310             sizeof(ed_pccard_products[0]), NULL)) == NULL)
311                 return (ENXIO);
312         sc->modem_rid = -1;
313         if (pp->flags & NE2000DVF_MODEM) {
314                 sc->port_rid = -1;
315                 for (i = 0; i < 4; i++) {
316                         size = bus_get_resource_count(dev, SYS_RES_IOPORT, i);
317                         if (size == ED_NOVELL_IO_PORTS)
318                                 sc->port_rid = i;
319                         else if (size == 8)
320                                 sc->modem_rid = i;
321                 }
322                 if (sc->port_rid == -1) {
323                         device_printf(dev, "Cannot locate my ports!\n");
324                         return (ENXIO);
325                 }
326         } else {
327                 sc->port_rid = 0;
328         }
329         /* Allocate the port resource during setup. */
330         error = ed_alloc_port(dev, sc->port_rid, ED_NOVELL_IO_PORTS);
331         if (error)
332                 return (error);
333         error = ed_alloc_irq(dev, 0, 0);
334         if (error)
335                 goto bad;
336
337         /*
338          * Determine which chipset we are.  All the PC Card chipsets have the
339          * ASIC and NIC offsets in the same place.
340          */
341         sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
342         sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
343         error = ENXIO;
344         if (error != 0)
345                 error = ed_pccard_dl100xx(dev, pp);
346         if (error != 0)
347                 error = ed_pccard_ax88x90(dev, pp);
348         if (error != 0)
349                 error = ed_probe_Novell_generic(dev, device_get_flags(dev));
350         if (error)
351                 goto bad;
352
353         error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE,
354             edintr, sc, &sc->irq_handle);
355         if (error) {
356                 device_printf(dev, "setup intr failed %d \n", error);
357                 goto bad;
358         }             
359
360         /*
361          * For the older cards, we have to get the MAC address from
362          * the card in some way.  Let's try the standard PCMCIA way
363          * first.  If that fails, then check to see if we have valid
364          * data from the standard NE-2000 data roms.  If that fails,
365          * check to see if the card has a hint about where to look in
366          * its CIS.  If that fails, maybe we should look at some
367          * default value.  In all fails, we should fail the attach,
368          * but don't right now.
369          */
370         if (sc->chip_type == ED_CHIP_TYPE_DP8390) {
371                 pccard_get_ether(dev, enaddr);
372                 if (bootverbose)
373                         device_printf(dev, "CIS MAC %6D\n", enaddr, ":");
374                 for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++)
375                         sum |= enaddr[i];
376                 if (sum == 0 && ed_pccard_rom_mac(dev, enaddr)) {
377                         if (bootverbose)
378                                 device_printf(dev, "ROM mac %6D\n", enaddr,
379                                     ":");
380                         sum++;
381                 }
382                 if (sum == 0 && pp->flags & NE2000DVF_ENADDR) {
383                         for (i = 0; i < ETHER_ADDR_LEN; i++) {
384                                 pccard_attr_read_1(dev, pp->enoff + i * 2,
385                                     enaddr + i);
386                                 sum |= enaddr[i];
387                         }
388                         if (bootverbose)
389                                 device_printf(dev, "Hint %x MAC %6D\n",
390                                     pp->enoff, enaddr, ":");
391                 }
392                 if (sum == 0) {
393                         for (i = 0; i < ETHER_ADDR_LEN; i++) {
394                                 pccard_attr_read_1(dev, ED_DEFAULT_MAC_OFFSET +
395                                     i * 2, enaddr + i);
396                                 sum |= enaddr[i];
397                         }
398                         if (bootverbose)
399                                 device_printf(dev, "Fallback MAC %6D\n",
400                                     enaddr, ":");
401                 }
402                 if (sum == 0) {
403                         device_printf(dev, "Cannot extract MAC address.\n");
404                         ed_release_resources(dev);
405                         return (ENXIO);
406                 }
407                 bcopy(enaddr, sc->enaddr, ETHER_ADDR_LEN);
408         }
409
410         error = ed_attach(dev);
411         if (error)
412                 goto bad;
413 #ifndef ED_NO_MIIBUS
414         if (sc->chip_type == ED_CHIP_TYPE_DL10019 ||
415             sc->chip_type == ED_CHIP_TYPE_DL10022) {
416                 /* Probe for an MII bus, but ignore errors. */
417                 ed_pccard_dl100xx_mii_reset(sc);
418                 mii_phy_probe(dev, &sc->miibus, ed_ifmedia_upd,
419                     ed_ifmedia_sts);
420         } else if (sc->chip_type == ED_CHIP_TYPE_AX88190) {
421                 ed_pccard_ax88x90_mii_reset(sc);
422                 if ((error = mii_phy_probe(dev, &sc->miibus, ed_ifmedia_upd,
423                      ed_ifmedia_sts)) != 0) {
424                         device_printf(dev, "Missing mii!\n");
425                         goto bad;
426                 }
427                     
428         }
429 #endif
430         if (sc->modem_rid != -1)
431                 ed_pccard_add_modem(dev);
432         return (0);
433 bad:
434         ed_release_resources(dev);
435         return (error);
436 }
437
438 /*
439  * Probe the Ethernet MAC addrees for PCMCIA Linksys EtherFast 10/100 
440  * and compatible cards (DL10019C Ethernet controller).
441  *
442  * Note: The PAO patches try to use more memory for the card, but that
443  * seems to fail for my card.  A future optimization would add this back
444  * conditionally.
445  */
446 static int
447 ed_pccard_dl100xx(device_t dev, const struct ed_product *pp)
448 {
449         struct ed_softc *sc = device_get_softc(dev);
450         u_char sum;
451         uint8_t id;
452         int i, error;
453
454         if (!(pp->flags & NE2000DVF_DL100XX))
455                 return (ENXIO);
456         if (bootverbose)
457                 device_printf(dev, "Trying DL100xx probing\n");
458         error = ed_probe_Novell_generic(dev, device_get_flags(dev));
459         if (bootverbose && error)
460                 device_printf(dev, "Novell generic probe failed: %d\n", error);
461         if (error != 0)
462                 return (error);
463
464         /*
465          * Linksys registers(offset from ASIC base)
466          *
467          * 0x04-0x09 : Physical Address Register 0-5 (PAR0-PAR5)
468          * 0x0A      : Card ID Register (CIR)
469          * 0x0B      : Check Sum Register (SR)
470          */
471         for (sum = 0, i = 0x04; i < 0x0c; i++)
472                 sum += ed_asic_inb(sc, i);
473         if (sum != 0xff) {
474                 if (bootverbose)
475                         device_printf(dev, "Bad checksum %#x\n", sum);
476                 return (ENXIO);         /* invalid DL10019C */
477         }
478         if (bootverbose)
479                 device_printf(dev, "CIR is %d\n", ed_asic_inb(sc, 0xa));
480         for (i = 0; i < ETHER_ADDR_LEN; i++)
481                 sc->enaddr[i] = ed_asic_inb(sc, 0x04 + i);
482         ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
483         id = ed_asic_inb(sc, 0xf);
484         sc->isa16bit = 1;
485         sc->vendor = ED_VENDOR_NOVELL;
486         sc->type = ED_TYPE_NE2000;
487         sc->chip_type = (id & 0x90) == 0x90 ?
488             ED_CHIP_TYPE_DL10022 : ED_CHIP_TYPE_DL10019;
489         sc->type_str = ((id & 0x90) == 0x90) ? "DL10022" : "DL10019";
490         sc->mii_readbits = ed_pccard_dl100xx_mii_readbits;
491         sc->mii_writebits = ed_pccard_dl100xx_mii_writebits;
492         return (0);
493 }
494
495 #ifndef ED_NO_MIIBUS
496 /* MII bit-twiddling routines for cards using Dlink chipset */
497 #define DL100XX_MIISET(sc, x) ed_asic_outb(sc, ED_DL100XX_MIIBUS, \
498     ed_asic_inb(sc, ED_DL100XX_MIIBUS) | (x))
499 #define DL100XX_MIICLR(sc, x) ed_asic_outb(sc, ED_DL100XX_MIIBUS, \
500     ed_asic_inb(sc, ED_DL100XX_MIIBUS) & ~(x))
501
502 static void
503 ed_pccard_dl100xx_mii_reset(struct ed_softc *sc)
504 {
505         if (sc->chip_type != ED_CHIP_TYPE_DL10022)
506                 return;
507
508         ed_asic_outb(sc, ED_DL100XX_MIIBUS, ED_DL100XX_MII_RESET2);
509         DELAY(10);
510         ed_asic_outb(sc, ED_DL100XX_MIIBUS,
511             ED_DL100XX_MII_RESET2 | ED_DL100XX_MII_RESET1);
512         DELAY(10);
513         ed_asic_outb(sc, ED_DL100XX_MIIBUS, ED_DL100XX_MII_RESET2);
514         DELAY(10);
515         ed_asic_outb(sc, ED_DL100XX_MIIBUS,
516             ED_DL100XX_MII_RESET2 | ED_DL100XX_MII_RESET1);
517         DELAY(10);
518         ed_asic_outb(sc, ED_DL100XX_MIIBUS, 0);
519 }
520
521 static void
522 ed_pccard_dl100xx_mii_writebits(struct ed_softc *sc, u_int val, int nbits)
523 {
524         int i;
525
526         if (sc->chip_type == ED_CHIP_TYPE_DL10022)
527                 DL100XX_MIISET(sc, ED_DL100XX_MII_DIROUT_22);
528         else
529                 DL100XX_MIISET(sc, ED_DL100XX_MII_DIROUT_19);
530
531         for (i = nbits - 1; i >= 0; i--) {
532                 if ((val >> i) & 1)
533                         DL100XX_MIISET(sc, ED_DL100XX_MII_DATAOUT);
534                 else
535                         DL100XX_MIICLR(sc, ED_DL100XX_MII_DATAOUT);
536                 DELAY(10);
537                 DL100XX_MIISET(sc, ED_DL100XX_MII_CLK);
538                 DELAY(10);
539                 DL100XX_MIICLR(sc, ED_DL100XX_MII_CLK);
540                 DELAY(10);
541         }
542 }
543
544 static u_int
545 ed_pccard_dl100xx_mii_readbits(struct ed_softc *sc, int nbits)
546 {
547         int i;
548         u_int val = 0;
549
550         if (sc->chip_type == ED_CHIP_TYPE_DL10022)
551                 DL100XX_MIICLR(sc, ED_DL100XX_MII_DIROUT_22);
552         else
553                 DL100XX_MIICLR(sc, ED_DL100XX_MII_DIROUT_19);
554
555         for (i = nbits - 1; i >= 0; i--) {
556                 DL100XX_MIISET(sc, ED_DL100XX_MII_CLK);
557                 DELAY(10);
558                 val <<= 1;
559                 if (ed_asic_inb(sc, ED_DL100XX_MIIBUS) & ED_DL100XX_MII_DATATIN)
560                         val++;
561                 DL100XX_MIICLR(sc, ED_DL100XX_MII_CLK);
562                 DELAY(10);
563         }
564         return val;
565 }
566 #endif
567
568 static int
569 ed_pccard_ax88x90_geteprom(struct ed_softc *sc)
570 {
571         int prom[16],i;
572         u_char tmp;
573         struct {
574                 unsigned char offset, value;
575         } pg_seq[] = {
576                                                 /* Select Page0 */
577                 {ED_P0_CR, ED_CR_RD2 | ED_CR_STP | ED_CR_PAGE_0},
578                 {ED_P0_DCR, 0x01},
579                 {ED_P0_RBCR0, 0x00},            /* Clear the count regs. */
580                 {ED_P0_RBCR1, 0x00},
581                 {ED_P0_IMR, 0x00},              /* Mask completion irq. */
582                 {ED_P0_ISR, 0xff},
583                 {ED_P0_RCR, ED_RCR_MON | ED_RCR_INTT}, /* Set To Monitor */
584                 {ED_P0_TCR, ED_TCR_LB0},        /* loopback mode. */
585                 {ED_P0_RBCR0, 32},
586                 {ED_P0_RBCR1, 0x00},
587                 {ED_P0_RSAR0, 0x00},
588                 {ED_P0_RSAR1, 0x04},
589                 {ED_P0_CR, ED_CR_RD0 | ED_CR_STA | ED_CR_PAGE_0},
590         };
591
592         /* Reset Card */
593         tmp = ed_asic_inb(sc, ED_NOVELL_RESET);
594         ed_asic_outb(sc, ED_NOVELL_RESET, tmp);
595         DELAY(5000);
596         ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP | ED_CR_PAGE_0);
597         DELAY(5000);
598
599         /* Card Settings */
600         for (i = 0; i < sizeof(pg_seq) / sizeof(pg_seq[0]); i++)
601                 ed_nic_outb(sc, pg_seq[i].offset, pg_seq[i].value);
602
603         /* Get Data */
604         for (i = 0; i < ETHER_ADDR_LEN / 2; i++)
605                 prom[i] = ed_asic_inw(sc, 0);
606         for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
607                 sc->enaddr[i] = prom[i / 2] & 0xff;
608                 sc->enaddr[i + 1] = (prom[i / 2] >> 8) & 0xff;
609         }
610         return (0);
611 }
612
613 /*
614  * Special setup for AX88[17]90
615  */
616 static int
617 ed_pccard_ax88x90(device_t dev, const struct ed_product *pp)
618 {
619         int     error, iobase, i, id;
620         char *ts;
621         struct  ed_softc *sc = device_get_softc(dev);
622
623         if (!(pp->flags & NE2000DVF_AX88X90))
624                 return (ENXIO);
625
626         if (bootverbose)
627                 device_printf(dev, "Checking AX88x90\n");
628
629         /*
630          * Set the IOBASE Register.  The AX88x90 cards are potentially
631          * multifunction cards, and thus requires a slight workaround.
632          * We write the address the card is at.
633          */
634         iobase = rman_get_start(sc->port_res);
635         pccard_ccr_write_1(dev, PCCARD_CCR_IOBASE0, iobase & 0xff);
636         pccard_ccr_write_1(dev, PCCARD_CCR_IOBASE1, (iobase >> 8) & 0xff);
637
638 #ifdef ED_NO_MIIBUS
639         return (ENXIO);
640 #else
641         /*
642          * Check to see if we have a MII PHY ID at any of the first 17
643          * locations.  All AX88x90 devices have MII and a PHY, so we use
644          * this to weed out chips that would otherwise make it through
645          * the tests we have after this point.
646          */
647         sc->mii_readbits = ed_pccard_ax88x90_mii_readbits;
648         sc->mii_writebits = ed_pccard_ax88x90_mii_writebits;
649         for (i = 0; i < 17; i++) {
650                 id = ed_miibus_readreg(dev, i, MII_PHYIDR1);
651                 if (id != 0 && id != 0xffff)
652                         break;
653         }
654         if (i == 17) {
655                 sc->mii_readbits = 0;
656                 sc->mii_writebits = 0;
657                 return (ENXIO);
658         }
659         
660
661         ts = "AX88190";
662         if (ed_asic_inb(sc, ED_ASIX_TEST) != 0) {
663                 /*
664                  * AX88790 (and I think AX88190A) chips need to be
665                  * powered down.  There's an erratum that says we should
666                  * power down the PHY for 2.5s, but this seems to power
667                  * down the whole card.  I'm unsure why this was done, but
668                  * appears to be required for proper operation.
669                  */
670                 pccard_ccr_write_1(dev, PCCARD_CCR_STATUS,
671                     PCCARD_CCR_STATUS_PWRDWN);
672                 ts = "AX88790";
673         }
674         sc->chip_type = ED_CHIP_TYPE_AX88190;
675         error = ed_pccard_ax88x90_geteprom(sc);
676         if (error)
677                 return (error);
678         error = ed_probe_Novell_generic(dev, device_get_flags(dev));
679         if (bootverbose)
680                 device_printf(dev, "probe novel returns %d\n", error);
681         if (error == 0) {
682                 sc->vendor = ED_VENDOR_NOVELL;
683                 sc->type = ED_TYPE_NE2000;
684                 sc->chip_type = ED_CHIP_TYPE_AX88190;
685                 sc->type_str = ts;
686         }
687         return (error);
688 #endif
689 }
690
691 #ifndef ED_NO_MIIBUS
692 /* MII bit-twiddling routines for cards using Dlink chipset */
693 #define AX88X90_MIISET(sc, x) ed_asic_outb(sc, ED_AX88X90_MIIBUS, \
694     ed_asic_inb(sc, ED_AX88X90_MIIBUS) | (x))
695 #define AX88X90_MIICLR(sc, x) ed_asic_outb(sc, ED_AX88X90_MIIBUS, \
696     ed_asic_inb(sc, ED_AX88X90_MIIBUS) & ~(x))
697
698 static void
699 ed_pccard_ax88x90_mii_reset(struct ed_softc *sc)
700 {
701         /* Do nothing! */
702 }
703
704 static void
705 ed_pccard_ax88x90_mii_writebits(struct ed_softc *sc, u_int val, int nbits)
706 {
707         int i;
708
709         AX88X90_MIICLR(sc, ED_AX88X90_MII_DIROUT);
710         for (i = nbits - 1; i >= 0; i--) {
711                 if ((val >> i) & 1)
712                         AX88X90_MIISET(sc, ED_AX88X90_MII_DATAOUT);
713                 else
714                         AX88X90_MIICLR(sc, ED_AX88X90_MII_DATAOUT);
715                 DELAY(10);
716                 AX88X90_MIISET(sc, ED_AX88X90_MII_CLK);
717                 DELAY(10);
718                 AX88X90_MIICLR(sc, ED_AX88X90_MII_CLK);
719                 DELAY(10);
720         }
721 }
722
723 static u_int
724 ed_pccard_ax88x90_mii_readbits(struct ed_softc *sc, int nbits)
725 {
726         int i;
727         u_int val = 0;
728
729         AX88X90_MIISET(sc, ED_AX88X90_MII_DIROUT);
730         for (i = nbits - 1; i >= 0; i--) {
731                 AX88X90_MIISET(sc, ED_AX88X90_MII_CLK);
732                 DELAY(10);
733                 val <<= 1;
734                 if (ed_asic_inb(sc, ED_AX88X90_MIIBUS) & ED_AX88X90_MII_DATATIN)
735                         val++;
736                 AX88X90_MIICLR(sc, ED_AX88X90_MII_CLK);
737                 DELAY(10);
738         }
739         return val;
740 }
741 #endif
742
743 #ifndef ED_NO_MIIBUS
744 /*
745  * MII bus support routines.
746  */
747 static int
748 ed_miibus_readreg(device_t dev, int phy, int reg)
749 {
750         struct ed_softc *sc;
751         int failed, val;
752
753         /*
754          * The AX88790 seem to have phy 0..f external, and 0x10 internal.
755          * but they also seem to have a bogus one that shows up at phy
756          * 0x11 through 0x1f.
757          */
758         if (phy >= 0x11)
759                 return (0);
760
761         sc = device_get_softc(dev);
762         (*sc->mii_writebits)(sc, 0xffffffff, 32);
763         (*sc->mii_writebits)(sc, ED_MII_STARTDELIM, ED_MII_STARTDELIM_BITS);
764         (*sc->mii_writebits)(sc, ED_MII_READOP, ED_MII_OP_BITS);
765         (*sc->mii_writebits)(sc, phy, ED_MII_PHY_BITS);
766         (*sc->mii_writebits)(sc, reg, ED_MII_REG_BITS);
767         failed = (*sc->mii_readbits)(sc, ED_MII_ACK_BITS);
768         val = (*sc->mii_readbits)(sc, ED_MII_DATA_BITS);
769         (*sc->mii_writebits)(sc, ED_MII_IDLE, ED_MII_IDLE_BITS);
770         return (failed ? 0 : val);
771 }
772
773 static void
774 ed_miibus_writereg(device_t dev, int phy, int reg, int data)
775 {
776         struct ed_softc *sc;
777
778         /*
779          * The AX88790 seem to have phy 0..f external, and 0x10 internal.
780          * but they also seem to have a bogus one that shows up at phy
781          * 0x11 through 0x1f.
782          */
783         if (phy >= 0x11)
784                 return;
785
786         sc = device_get_softc(dev);
787         (*sc->mii_writebits)(sc, 0xffffffff, 32);
788         (*sc->mii_writebits)(sc, ED_MII_STARTDELIM, ED_MII_STARTDELIM_BITS);
789         (*sc->mii_writebits)(sc, ED_MII_WRITEOP, ED_MII_OP_BITS);
790         (*sc->mii_writebits)(sc, phy, ED_MII_PHY_BITS);
791         (*sc->mii_writebits)(sc, reg, ED_MII_REG_BITS);
792         (*sc->mii_writebits)(sc, ED_MII_TURNAROUND, ED_MII_TURNAROUND_BITS);
793         (*sc->mii_writebits)(sc, data, ED_MII_DATA_BITS);
794         (*sc->mii_writebits)(sc, ED_MII_IDLE, ED_MII_IDLE_BITS);
795 }
796 #endif
797
798 static device_method_t ed_pccard_methods[] = {
799         /* Device interface */
800         DEVMETHOD(device_probe,         ed_pccard_probe),
801         DEVMETHOD(device_attach,        ed_pccard_attach),
802         DEVMETHOD(device_detach,        ed_detach),
803
804 #ifndef ED_NO_MIIBUS
805         /* Bus interface */
806         DEVMETHOD(bus_child_detached,   ed_child_detached),
807
808         /* MII interface */
809         DEVMETHOD(miibus_readreg,       ed_miibus_readreg),
810         DEVMETHOD(miibus_writereg,      ed_miibus_writereg),
811 #endif
812
813         { 0, 0 }
814 };
815
816 static driver_t ed_pccard_driver = {
817         "ed",
818         ed_pccard_methods,
819         sizeof(struct ed_softc)
820 };
821
822 DRIVER_MODULE(ed, pccard, ed_pccard_driver, ed_devclass, 0, 0);
823 #ifndef ED_NO_MIIBUS
824 DRIVER_MODULE(miibus, ed, miibus_driver, miibus_devclass, 0, 0);
825 #endif