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> 7852473Simp#include <sys/module.h> 7952473Simp#include <sys/bus.h> 8052473Simp#include <machine/bus.h> 8166332Stanimura#include <sys/rman.h> 8266332Stanimura#include <machine/resource.h> 8352473Simp 8452473Simp#include <net/ethernet.h> 8552473Simp#include <net/if.h> 8652473Simp#include <net/if_arp.h> 8752473Simp#include <net/if_mib.h> 8873374Simp#include <net/if_media.h> 8952473Simp 9063775Stanimura#include <dev/ed/if_edreg.h> 9152245Smdodd#include <dev/ed/if_edvar.h> 92150957Simp#include <dev/ed/ax88x90reg.h> 93150957Simp#include <dev/ed/dl100xxreg.h> 94150957Simp#include <dev/ed/tc5299jreg.h> 9556361Shosokawa#include <dev/pccard/pccardvar.h> 96150108Simp#include <dev/pccard/pccardreg.h> 97140522Simp#include <dev/pccard/pccard_cis.h> 9873374Simp#include <dev/mii/mii.h> 9973374Simp#include <dev/mii/miivar.h> 10069137Speter 10166332Stanimura#include "card_if.h" 10273374Simp/* "device miibus" required. See GENERIC if you get errors here. */ 10373374Simp#include "miibus_if.h" 104129764Simp#include "pccarddevs.h" 10552245Smdodd 10652245Smdodd/* 107150957Simp * NE-2000 based PC Cards have a number of ways to get the MAC address. 108150957Simp * Some cards encode this as a FUNCE. Others have this in the ROMs the 109150957Simp * same way that ISA cards do. Some have it encoded in the attribute 110150957Simp * memory somewhere that isn't in the CIS. Some new chipsets have it 111150957Simp * in special registers in the ASIC part of the chip. 112149890Simp * 113190801Simp * For those cards that have the MAC adress stored in attribute memory 114190801Simp * outside of a FUNCE entry in the CIS, nearly all of them have it at 115190801Simp * a fixed offset (0xff0). We use that offset as a source of last 116190801Simp * resource if other offsets have failed. This is the address of the 117190801Simp * National Semiconductor DP83903A, which is the only chip's datasheet 118190801Simp * I've found. 119141744Simp */ 120141744Simp#define ED_DEFAULT_MAC_OFFSET 0xff0 121141744Simp 12271324Simpstatic const struct ed_product { 12371324Simp struct pccard_product prod; 12471324Simp int flags; 125142023Simp#define NE2000DVF_DL100XX 0x0001 /* chip is D-Link DL10019/22 */ 126142023Simp#define NE2000DVF_AX88X90 0x0002 /* chip is ASIX AX88[17]90 */ 127150957Simp#define NE2000DVF_TC5299J 0x0004 /* chip is Tamarack TC5299J */ 128190483Simp#define NE2000DVF_TOSHIBA 0x0008 /* Toshiba DP83902A */ 129150957Simp#define NE2000DVF_ENADDR 0x0100 /* Get MAC from attr mem */ 130150957Simp#define NE2000DVF_ANYFUNC 0x0200 /* Allow any function type */ 131150957Simp#define NE2000DVF_MODEM 0x0400 /* Has a modem/serial */ 132141708Simp int enoff; 13371324Simp} ed_pccard_products[] = { 134147580Simp { PCMCIA_CARD(ACCTON, EN2212), 0}, 135147580Simp { PCMCIA_CARD(ACCTON, EN2216), 0}, 136147580Simp { PCMCIA_CARD(ALLIEDTELESIS, LA_PCM), 0}, 137191386Simp { PCMCIA_CARD(AMBICOM, AMB8002), 0}, 138147580Simp { PCMCIA_CARD(AMBICOM, AMB8002T), 0}, 139191386Simp { PCMCIA_CARD(AMBICOM, AMB8010), 0}, 140191386Simp { PCMCIA_CARD(AMBICOM, AMB8010_ALT), 0}, 141191386Simp { PCMCIA_CARD(AMBICOM, AMB8610), 0}, 142151840Simp { PCMCIA_CARD(BILLIONTON, CFLT10N), 0}, 143151840Simp { PCMCIA_CARD(BILLIONTON, LNA100B), NE2000DVF_AX88X90}, 144191391Simp { PCMCIA_CARD(BILLIONTON, LNT10TB), 0}, 145147580Simp { PCMCIA_CARD(BILLIONTON, LNT10TN), 0}, 146190475Simp { PCMCIA_CARD(BROMAX, AXNET), NE2000DVF_AX88X90}, 147147872Simp { PCMCIA_CARD(BROMAX, IPORT), 0}, 148147872Simp { PCMCIA_CARD(BROMAX, IPORT2), 0}, 149147872Simp { PCMCIA_CARD(BUFFALO, LPC2_CLT), 0}, 150147580Simp { PCMCIA_CARD(BUFFALO, LPC3_CLT), 0}, 151147580Simp { PCMCIA_CARD(BUFFALO, LPC3_CLX), NE2000DVF_AX88X90}, 152147872Simp { PCMCIA_CARD(BUFFALO, LPC4_TX), NE2000DVF_AX88X90}, 153151225Simp { PCMCIA_CARD(BUFFALO, LPC4_CLX), NE2000DVF_AX88X90}, 154147580Simp { PCMCIA_CARD(BUFFALO, LPC_CF_CLT), 0}, 155147580Simp { PCMCIA_CARD(CNET, NE2000), 0}, 156147872Simp { PCMCIA_CARD(COMPEX, AX88190), NE2000DVF_AX88X90}, 157147872Simp { PCMCIA_CARD(COMPEX, LANMODEM), 0}, 158147580Simp { PCMCIA_CARD(COMPEX, LINKPORT_ENET_B), 0}, 159147580Simp { PCMCIA_CARD(COREGA, ETHER_II_PCC_T), 0}, 160147580Simp { PCMCIA_CARD(COREGA, ETHER_II_PCC_TD), 0}, 161147580Simp { PCMCIA_CARD(COREGA, ETHER_PCC_T), 0}, 162147580Simp { PCMCIA_CARD(COREGA, ETHER_PCC_TD), 0}, 163150104Simp { PCMCIA_CARD(COREGA, FAST_ETHER_PCC_TX), NE2000DVF_DL100XX}, 164150104Simp { PCMCIA_CARD(COREGA, FETHER_PCC_TXD), NE2000DVF_AX88X90}, 165150104Simp { PCMCIA_CARD(COREGA, FETHER_PCC_TXF), NE2000DVF_DL100XX}, 166180315Simp { PCMCIA_CARD(COREGA, FETHER_II_PCC_TXD), NE2000DVF_AX88X90}, 167180315Simp { PCMCIA_CARD(COREGA, LAPCCTXD), 0}, 168147580Simp { PCMCIA_CARD(DAYNA, COMMUNICARD_E_1), 0}, 169147580Simp { PCMCIA_CARD(DAYNA, COMMUNICARD_E_2), 0}, 170190899Simp { PCMCIA_CARD(DLINK, DE650), NE2000DVF_ANYFUNC }, 171147580Simp { PCMCIA_CARD(DLINK, DE660), 0 }, 172147580Simp { PCMCIA_CARD(DLINK, DE660PLUS), 0}, 173147580Simp { PCMCIA_CARD(DYNALINK, L10C), 0}, 174147580Simp { PCMCIA_CARD(EDIMAX, EP4000A), 0}, 175190902Simp { PCMCIA_CARD(EPSON, EEN10B), 0}, 176147580Simp { PCMCIA_CARD(EXP, THINLANCOMBO), 0}, 177151840Simp { PCMCIA_CARD(GLOBALVILLAGE, LANMODEM), 0}, 178147872Simp { PCMCIA_CARD(GREY_CELL, TDK3000), 0}, 179148022Simp { PCMCIA_CARD(GREY_CELL, DMF650TX), 180149832Simp NE2000DVF_ANYFUNC | NE2000DVF_DL100XX | NE2000DVF_MODEM}, 181191237Simp { PCMCIA_CARD(GVC, NIC_2000P), 0}, 182147580Simp { PCMCIA_CARD(IBM, HOME_AND_AWAY), 0}, 183190902Simp { PCMCIA_CARD(IBM, INFOMOVER), 0}, 184147580Simp { PCMCIA_CARD(IODATA3, PCLAT), 0}, 185147872Simp { PCMCIA_CARD(KINGSTON, CIO10T), 0}, 186147580Simp { PCMCIA_CARD(KINGSTON, KNE2), 0}, 187150104Simp { PCMCIA_CARD(LANTECH, FASTNETTX), NE2000DVF_AX88X90}, 188190899Simp /* Same ID for many different cards, including generic NE2000 */ 189147580Simp { PCMCIA_CARD(LINKSYS, COMBO_ECARD), 190150104Simp NE2000DVF_DL100XX | NE2000DVF_AX88X90}, 191147580Simp { PCMCIA_CARD(LINKSYS, ECARD_1), 0}, 192147580Simp { PCMCIA_CARD(LINKSYS, ECARD_2), 0}, 193150104Simp { PCMCIA_CARD(LINKSYS, ETHERFAST), NE2000DVF_DL100XX}, 194147580Simp { PCMCIA_CARD(LINKSYS, TRUST_COMBO_ECARD), 0}, 195147580Simp { PCMCIA_CARD(MACNICA, ME1_JEIDA), 0}, 196147580Simp { PCMCIA_CARD(MAGICRAM, ETHER), 0}, 197150104Simp { PCMCIA_CARD(MELCO, LPC3_CLX), NE2000DVF_AX88X90}, 198150104Simp { PCMCIA_CARD(MELCO, LPC3_TX), NE2000DVF_AX88X90}, 199191394Simp { PCMCIA_CARD(MELCO2, LPC2_T), 0}, 200191394Simp { PCMCIA_CARD(MELCO2, LPC2_TX), 0}, 201190475Simp { PCMCIA_CARD(MITSUBISHI, B8895), NE2000DVF_ANYFUNC}, /* NG */ 202171352Simp { PCMCIA_CARD(MICRORESEARCH, MR10TPC), 0}, 203147580Simp { PCMCIA_CARD(NDC, ND5100_E), 0}, 204147580Simp { PCMCIA_CARD(NETGEAR, FA410TXC), NE2000DVF_DL100XX}, 205149922Simp /* Same ID as DLINK DFE-670TXD. 670 has DL10022, fa411 has ax88790 */ 206149922Simp { PCMCIA_CARD(NETGEAR, FA411), NE2000DVF_AX88X90 | NE2000DVF_DL100XX}, 207147580Simp { PCMCIA_CARD(NEXTCOM, NEXTHAWK), 0}, 208191237Simp { PCMCIA_CARD(NEWMEDIA, LANSURFER), NE2000DVF_ANYFUNC}, 209191237Simp { PCMCIA_CARD(NEWMEDIA, LIVEWIRE), 0}, 210191469Simp { PCMCIA_CARD(OEM2, 100BASE), NE2000DVF_AX88X90}, 211147580Simp { PCMCIA_CARD(OEM2, ETHERNET), 0}, 212191469Simp { PCMCIA_CARD(OEM2, FAST_ETHERNET), NE2000DVF_AX88X90}, 213149922Simp { PCMCIA_CARD(OEM2, NE2000), 0}, 214147580Simp { PCMCIA_CARD(PLANET, SMARTCOM2000), 0 }, 215147580Simp { PCMCIA_CARD(PREMAX, PE200), 0}, 216150300Simp { PCMCIA_CARD(PSION, LANGLOBAL), 217150300Simp NE2000DVF_ANYFUNC | NE2000DVF_AX88X90 | NE2000DVF_MODEM}, 218147580Simp { PCMCIA_CARD(RACORE, ETHERNET), 0}, 219147580Simp { PCMCIA_CARD(RACORE, FASTENET), NE2000DVF_AX88X90}, 220150957Simp { PCMCIA_CARD(RACORE, 8041TX), NE2000DVF_AX88X90 | NE2000DVF_TC5299J}, 221147872Simp { PCMCIA_CARD(RELIA, COMBO), 0}, 222190430Simp { PCMCIA_CARD(RIOS, PCCARD3), 0}, 223147580Simp { PCMCIA_CARD(RPTI, EP400), 0}, 224147580Simp { PCMCIA_CARD(RPTI, EP401), 0}, 225147580Simp { PCMCIA_CARD(SMC, EZCARD), 0}, 226147580Simp { PCMCIA_CARD(SOCKET, EA_ETHER), 0}, 227147872Simp { PCMCIA_CARD(SOCKET, ES_1000), 0}, 228147580Simp { PCMCIA_CARD(SOCKET, LP_ETHER), 0}, 229147580Simp { PCMCIA_CARD(SOCKET, LP_ETHER_CF), 0}, 230147580Simp { PCMCIA_CARD(SOCKET, LP_ETH_10_100_CF), NE2000DVF_DL100XX}, 231147580Simp { PCMCIA_CARD(SVEC, COMBOCARD), 0}, 232147580Simp { PCMCIA_CARD(SVEC, LANCARD), 0}, 233147580Simp { PCMCIA_CARD(TAMARACK, ETHERNET), 0}, 234149922Simp { PCMCIA_CARD(TDK, CFE_10), 0}, 235147580Simp { PCMCIA_CARD(TDK, LAK_CD031), 0}, 236147872Simp { PCMCIA_CARD(TDK, DFL5610WS), 0}, 237147872Simp { PCMCIA_CARD(TELECOMDEVICE, LM5LT), 0 }, 238150104Simp { PCMCIA_CARD(TELECOMDEVICE, TCD_HPC100), NE2000DVF_AX88X90}, 239189726Simp { PCMCIA_CARD(TJ, PTJ_LAN_T), 0 }, 240190483Simp { PCMCIA_CARD(TOSHIBA2, LANCT00A), NE2000DVF_ANYFUNC | NE2000DVF_TOSHIBA}, 241147580Simp { PCMCIA_CARD(ZONET, ZEN), 0}, 24286394Simp { { NULL } } 24369137Speter}; 24469137Speter 245149841Simp/* 246264942Smarius * MII bit-bang glue 247264942Smarius */ 248264942Smariusstatic uint32_t ed_pccard_dl100xx_mii_bitbang_read(device_t dev); 249264942Smariusstatic void ed_pccard_dl100xx_mii_bitbang_write(device_t dev, uint32_t val); 250264942Smarius 251264942Smariusstatic const struct mii_bitbang_ops ed_pccard_dl100xx_mii_bitbang_ops = { 252264942Smarius ed_pccard_dl100xx_mii_bitbang_read, 253264942Smarius ed_pccard_dl100xx_mii_bitbang_write, 254264942Smarius { 255264942Smarius ED_DL100XX_MII_DATAOUT, /* MII_BIT_MDO */ 256264942Smarius ED_DL100XX_MII_DATAIN, /* MII_BIT_MDI */ 257264942Smarius ED_DL100XX_MII_CLK, /* MII_BIT_MDC */ 258264942Smarius ED_DL100XX_MII_DIROUT, /* MII_BIT_DIR_HOST_PHY */ 259264942Smarius 0 /* MII_BIT_DIR_PHY_HOST */ 260264942Smarius } 261264942Smarius}; 262264942Smarius 263264942Smariusstatic uint32_t ed_pccard_ax88x90_mii_bitbang_read(device_t dev); 264264942Smariusstatic void ed_pccard_ax88x90_mii_bitbang_write(device_t dev, uint32_t val); 265264942Smarius 266264942Smariusstatic const struct mii_bitbang_ops ed_pccard_ax88x90_mii_bitbang_ops = { 267264942Smarius ed_pccard_ax88x90_mii_bitbang_read, 268264942Smarius ed_pccard_ax88x90_mii_bitbang_write, 269264942Smarius { 270264942Smarius ED_AX88X90_MII_DATAOUT, /* MII_BIT_MDO */ 271264942Smarius ED_AX88X90_MII_DATAIN, /* MII_BIT_MDI */ 272264942Smarius ED_AX88X90_MII_CLK, /* MII_BIT_MDC */ 273264942Smarius 0, /* MII_BIT_DIR_HOST_PHY */ 274264942Smarius ED_AX88X90_MII_DIRIN /* MII_BIT_DIR_PHY_HOST */ 275264942Smarius } 276264942Smarius}; 277264942Smarius 278264942Smariusstatic uint32_t ed_pccard_tc5299j_mii_bitbang_read(device_t dev); 279264942Smariusstatic void ed_pccard_tc5299j_mii_bitbang_write(device_t dev, uint32_t val); 280264942Smarius 281264942Smariusstatic const struct mii_bitbang_ops ed_pccard_tc5299j_mii_bitbang_ops = { 282264942Smarius ed_pccard_tc5299j_mii_bitbang_read, 283264942Smarius ed_pccard_tc5299j_mii_bitbang_write, 284264942Smarius { 285264942Smarius ED_TC5299J_MII_DATAOUT, /* MII_BIT_MDO */ 286264942Smarius ED_TC5299J_MII_DATAIN, /* MII_BIT_MDI */ 287264942Smarius ED_TC5299J_MII_CLK, /* MII_BIT_MDC */ 288264942Smarius 0, /* MII_BIT_DIR_HOST_PHY */ 289264942Smarius ED_AX88X90_MII_DIRIN /* MII_BIT_DIR_PHY_HOST */ 290264942Smarius } 291264942Smarius}; 292264942Smarius 293264942Smarius/* 294149841Simp * PC Card (PCMCIA) specific code. 295149841Simp */ 296149841Simpstatic int ed_pccard_probe(device_t); 297149841Simpstatic int ed_pccard_attach(device_t); 298199380Sjhbstatic void ed_pccard_tick(struct ed_softc *); 299149841Simp 300149841Simpstatic int ed_pccard_dl100xx(device_t dev, const struct ed_product *); 301150108Simpstatic void ed_pccard_dl100xx_mii_reset(struct ed_softc *sc); 302150108Simp 303150957Simpstatic int ed_pccard_ax88x90(device_t dev, const struct ed_product *); 304150957Simp 305150108Simpstatic int ed_miibus_readreg(device_t dev, int phy, int reg); 306150300Simpstatic int ed_ifmedia_upd(struct ifnet *); 307150300Simpstatic void ed_ifmedia_sts(struct ifnet *, struct ifmediareq *); 308149841Simp 309150957Simpstatic int ed_pccard_tc5299j(device_t dev, const struct ed_product *); 310149841Simp 311150581Simpstatic void 312150581Simped_pccard_print_entry(const struct ed_product *pp) 313150581Simp{ 314150581Simp int i; 315150581Simp 316150581Simp printf("Product entry: "); 317150581Simp if (pp->prod.pp_name) 318150581Simp printf("name='%s',", pp->prod.pp_name); 319150581Simp printf("vendor=%#x,product=%#x", pp->prod.pp_vendor, 320150581Simp pp->prod.pp_product); 321150581Simp for (i = 0; i < 4; i++) 322150581Simp if (pp->prod.pp_cis[i]) 323150581Simp printf(",CIS%d='%s'", i, pp->prod.pp_cis[i]); 324150581Simp printf("\n"); 325150581Simp} 326150581Simp 32769137Speterstatic int 328149558Simped_pccard_probe(device_t dev) 32969137Speter{ 330150581Simp const struct ed_product *pp, *pp2; 331150581Simp int error, first = 1; 332140522Simp uint32_t fcn = PCCARD_FUNCTION_UNSPEC; 33369137Speter 334140522Simp /* Make sure we're a network function */ 335140522Simp error = pccard_get_function(dev, &fcn); 336140522Simp if (error != 0) 337140522Simp return (error); 338140522Simp 339100531Simp if ((pp = (const struct ed_product *) pccard_product_lookup(dev, 34071324Simp (const struct pccard_product *) ed_pccard_products, 34169150Speter sizeof(ed_pccard_products[0]), NULL)) != NULL) { 342113317Simp if (pp->prod.pp_name != NULL) 343113317Simp device_set_desc(dev, pp->prod.pp_name); 344148022Simp /* 345148022Simp * Some devices don't ID themselves as network, but 346148022Simp * that's OK if the flags say so. 347148022Simp */ 348148022Simp if (!(pp->flags & NE2000DVF_ANYFUNC) && 349148022Simp fcn != PCCARD_FUNCTION_NETWORK) 350148022Simp return (ENXIO); 351150581Simp /* 352150581Simp * Some devices match multiple entries. Report that 353150581Simp * as a warning to help cull the table 354150581Simp */ 355150581Simp pp2 = pp; 356150581Simp while ((pp2 = (const struct ed_product *)pccard_product_lookup( 357150581Simp dev, (const struct pccard_product *)(pp2 + 1), 358150581Simp sizeof(ed_pccard_products[0]), NULL)) != NULL) { 359150581Simp if (first) { 360150581Simp device_printf(dev, 361150581Simp "Warning: card matches multiple entries. Report to imp@freebsd.org\n"); 362150581Simp ed_pccard_print_entry(pp); 363150581Simp first = 0; 364150581Simp } 365150581Simp ed_pccard_print_entry(pp2); 366150581Simp } 367150581Simp 368100531Simp return (0); 36969137Speter } 370132511Simp return (ENXIO); 37169137Speter} 37269137Speter 37352245Smdoddstatic int 374141930Simped_pccard_rom_mac(device_t dev, uint8_t *enaddr) 375141930Simp{ 376141930Simp struct ed_softc *sc = device_get_softc(dev); 377191238Simp uint8_t romdata[32], sum; 378141930Simp int i; 379141930Simp 380141930Simp /* 381150108Simp * Read in the rom data at location 0. Since there are no 382150108Simp * NE-1000 based PC Card devices, we'll assume we're 16-bit. 383150108Simp * 384150108Simp * In researching what format this takes, I've found that the 385150108Simp * following appears to be true for multiple cards based on 386150108Simp * observation as well as datasheet digging. 387150108Simp * 388150108Simp * Data is stored in some ROM and is copied out 8 bits at a time 389150108Simp * into 16-bit wide locations. This means that the odd locations 390150108Simp * of the ROM are not used (and can be either 0 or ff). 391150108Simp * 392150108Simp * The contents appears to be as follows: 393150108Simp * PROM RAM 394150108Simp * Offset Offset What 395150108Simp * 0 0 ENETADDR 0 396150108Simp * 1 2 ENETADDR 1 397150108Simp * 2 4 ENETADDR 2 398150108Simp * 3 6 ENETADDR 3 399150108Simp * 4 8 ENETADDR 4 400150108Simp * 5 10 ENETADDR 5 401150108Simp * 6-13 12-26 Reserved (varies by manufacturer) 402150108Simp * 14 28 0x57 403150108Simp * 15 30 0x57 404150108Simp * 405150108Simp * Some manufacturers have another image of enetaddr from 406150108Simp * PROM offset 0x10 to 0x15 with 0x42 in 0x1e and 0x1f, but 407150108Simp * this doesn't appear to be universally documented in the 408150108Simp * datasheets. Some manufactuers have a card type, card config 409150108Simp * checksums, etc encoded into PROM offset 6-13, but deciphering it 410150108Simp * requires more knowledge about the exact underlying chipset than 411150108Simp * we possess (and maybe can possess). 412141930Simp */ 413150108Simp ed_pio_readmem(sc, 0, romdata, 32); 414150108Simp if (bootverbose) 415190559Simp device_printf(dev, "ROM DATA: %32D\n", romdata, " "); 416150108Simp if (romdata[28] != 0x57 || romdata[30] != 0x57) 417150108Simp return (0); 418191238Simp for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++) 419191238Simp sum |= romdata[i * 2]; 420191238Simp if (sum == 0) 421191238Simp return (0); 422141930Simp for (i = 0; i < ETHER_ADDR_LEN; i++) 423141930Simp enaddr[i] = romdata[i * 2]; 424150108Simp return (1); 425141930Simp} 426141930Simp 427141930Simpstatic int 428149832Simped_pccard_add_modem(device_t dev) 429148022Simp{ 430191299Simp device_printf(dev, "Need to write this code\n"); 431148022Simp return 0; 432148022Simp} 433148022Simp 434148022Simpstatic int 435190643Simped_pccard_kick_phy(struct ed_softc *sc) 436190643Simp{ 437190643Simp struct mii_softc *miisc; 438190643Simp struct mii_data *mii; 439190643Simp 440190643Simp mii = device_get_softc(sc->miibus); 441221407Smarius LIST_FOREACH(miisc, &mii->mii_phys, mii_list) 442221407Smarius PHY_RESET(miisc); 443190643Simp return (mii_mediachg(mii)); 444190643Simp} 445190643Simp 446190643Simpstatic int 447150300Simped_pccard_media_ioctl(struct ed_softc *sc, struct ifreq *ifr, u_long command) 448150300Simp{ 449150300Simp struct mii_data *mii; 450150300Simp 451150300Simp if (sc->miibus == NULL) 452150300Simp return (EINVAL); 453150300Simp mii = device_get_softc(sc->miibus); 454150300Simp return (ifmedia_ioctl(sc->ifp, ifr, &mii->mii_media, command)); 455150300Simp} 456150300Simp 457150300Simp 458150300Simpstatic void 459150300Simped_pccard_mediachg(struct ed_softc *sc) 460150300Simp{ 461150300Simp struct mii_data *mii; 462150300Simp 463150300Simp if (sc->miibus == NULL) 464150300Simp return; 465150300Simp mii = device_get_softc(sc->miibus); 466150300Simp mii_mediachg(mii); 467150300Simp} 468150300Simp 469150300Simpstatic int 47052473Simped_pccard_attach(device_t dev) 47152245Smdodd{ 47256361Shosokawa u_char sum; 473141744Simp u_char enaddr[ETHER_ADDR_LEN]; 474141708Simp const struct ed_product *pp; 475191299Simp int error, i, flags, port_rid, modem_rid; 476149558Simp struct ed_softc *sc = device_get_softc(dev); 477149832Simp u_long size; 478190483Simp static uint16_t *intr_vals[] = {NULL, NULL}; 479149558Simp 480190559Simp sc->dev = dev; 481141708Simp if ((pp = (const struct ed_product *) pccard_product_lookup(dev, 482141708Simp (const struct pccard_product *) ed_pccard_products, 483191299Simp sizeof(ed_pccard_products[0]), NULL)) == NULL) { 484191299Simp printf("Can't find\n"); 485141708Simp return (ENXIO); 486191299Simp } 487191299Simp modem_rid = port_rid = -1; 488149832Simp if (pp->flags & NE2000DVF_MODEM) { 489149832Simp for (i = 0; i < 4; i++) { 490149832Simp size = bus_get_resource_count(dev, SYS_RES_IOPORT, i); 491149832Simp if (size == ED_NOVELL_IO_PORTS) 492191299Simp port_rid = i; 493149832Simp else if (size == 8) 494191299Simp modem_rid = i; 495149832Simp } 496191299Simp if (port_rid == -1) { 497149832Simp device_printf(dev, "Cannot locate my ports!\n"); 498149832Simp return (ENXIO); 499149832Simp } 500149832Simp } else { 501191299Simp port_rid = 0; 502149832Simp } 503149841Simp /* Allocate the port resource during setup. */ 504191299Simp error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS); 505191299Simp if (error) { 506191299Simp printf("alloc_port failed\n"); 507149558Simp return (error); 508191299Simp } 509191299Simp if (rman_get_size(sc->port_res) == ED_NOVELL_IO_PORTS / 2) { 510191299Simp port_rid++; 511191299Simp sc->port_res2 = bus_alloc_resource(dev, SYS_RES_IOPORT, 512191299Simp &port_rid, 0ul, ~0ul, 1, RF_ACTIVE); 513191299Simp if (sc->port_res2 == NULL || 514191299Simp rman_get_size(sc->port_res2) != ED_NOVELL_IO_PORTS / 2) { 515191299Simp error = ENXIO; 516191299Simp goto bad; 517191299Simp } 518191299Simp } 519149558Simp error = ed_alloc_irq(dev, 0, 0); 520149841Simp if (error) 521149841Simp goto bad; 522149558Simp 523149841Simp /* 524190901Simp * Determine which chipset we are. Almost all the PC Card chipsets 525190901Simp * have the Novel ASIC and NIC offsets. There's 2 known cards that 526190901Simp * follow the WD80x3 conventions, which are handled as a special case. 527149841Simp */ 528149841Simp sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 529149841Simp sc->nic_offset = ED_NOVELL_NIC_OFFSET; 530149841Simp error = ENXIO; 531190483Simp flags = device_get_flags(dev); 532149841Simp if (error != 0) 533149841Simp error = ed_pccard_dl100xx(dev, pp); 534150108Simp if (error != 0) 535149841Simp error = ed_pccard_ax88x90(dev, pp); 536149841Simp if (error != 0) 537150957Simp error = ed_pccard_tc5299j(dev, pp); 538191299Simp if (error != 0) { 539190483Simp error = ed_probe_Novell_generic(dev, flags); 540264942Smarius printf("Novell generic probe failed: %d\n", error); 541191299Simp } 542190559Simp if (error != 0 && (pp->flags & NE2000DVF_TOSHIBA)) { 543190559Simp flags |= ED_FLAGS_TOSH_ETHER; 544190483Simp flags |= ED_FLAGS_PCCARD; 545190483Simp sc->asic_offset = ED_WD_ASIC_OFFSET; 546190483Simp sc->nic_offset = ED_WD_NIC_OFFSET; 547190483Simp error = ed_probe_WD80x3_generic(dev, flags, intr_vals); 548190483Simp } 549149841Simp if (error) 550149841Simp goto bad; 551149841Simp 552141715Simp /* 553190898Simp * There are several ways to get the MAC address for the card. 554190898Simp * Some of the above probe routines can fill in the enaddr. If 555190898Simp * not, we run through a number of 'well known' locations: 556190898Simp * (1) From the PC Card FUNCE 557190898Simp * (2) From offset 0 in the shared memory 558190898Simp * (3) From a hinted offset in attribute memory 559190898Simp * (4) From 0xff0 in attribute memory 560190898Simp * If we can't get a non-zero MAC address from this list, we fail. 561141715Simp */ 562190483Simp for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++) 563190483Simp sum |= sc->enaddr[i]; 564190897Simp if (sum == 0) { 565141744Simp pccard_get_ether(dev, enaddr); 566141744Simp if (bootverbose) 567141744Simp device_printf(dev, "CIS MAC %6D\n", enaddr, ":"); 56862236Sps for (i = 0, sum = 0; i < ETHER_ADDR_LEN; i++) 569141744Simp sum |= enaddr[i]; 570141930Simp if (sum == 0 && ed_pccard_rom_mac(dev, enaddr)) { 571141930Simp if (bootverbose) 572141930Simp device_printf(dev, "ROM mac %6D\n", enaddr, 573141930Simp ":"); 574141930Simp sum++; 575141930Simp } 576141708Simp if (sum == 0 && pp->flags & NE2000DVF_ENADDR) { 577141708Simp for (i = 0; i < ETHER_ADDR_LEN; i++) { 578150108Simp pccard_attr_read_1(dev, pp->enoff + i * 2, 579141744Simp enaddr + i); 580141744Simp sum |= enaddr[i]; 581141708Simp } 582141744Simp if (bootverbose) 583150108Simp device_printf(dev, "Hint %x MAC %6D\n", 584150108Simp pp->enoff, enaddr, ":"); 585141708Simp } 586141744Simp if (sum == 0) { 587141744Simp for (i = 0; i < ETHER_ADDR_LEN; i++) { 588150108Simp pccard_attr_read_1(dev, ED_DEFAULT_MAC_OFFSET + 589141744Simp i * 2, enaddr + i); 590141744Simp sum |= enaddr[i]; 591141744Simp } 592141744Simp if (bootverbose) 593141744Simp device_printf(dev, "Fallback MAC %6D\n", 594141744Simp enaddr, ":"); 595141744Simp } 596141744Simp if (sum == 0) { 597141744Simp device_printf(dev, "Cannot extract MAC address.\n"); 598141744Simp ed_release_resources(dev); 599141744Simp return (ENXIO); 600141744Simp } 601147256Sbrooks bcopy(enaddr, sc->enaddr, ETHER_ADDR_LEN); 60262236Sps } 60356361Shosokawa 604121816Sbrooks error = ed_attach(dev); 605149841Simp if (error) 606149841Simp goto bad; 607149558Simp if (sc->chip_type == ED_CHIP_TYPE_DL10019 || 608149558Simp sc->chip_type == ED_CHIP_TYPE_DL10022) { 609213894Smarius /* Try to attach an MII bus, but ignore errors. */ 610150108Simp ed_pccard_dl100xx_mii_reset(sc); 611213894Smarius (void)mii_attach(dev, &sc->miibus, sc->ifp, ed_ifmedia_upd, 612213894Smarius ed_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, 613221407Smarius MII_OFFSET_ANY, MIIF_FORCEANEG); 614190559Simp } else if (sc->chip_type == ED_CHIP_TYPE_AX88190 || 615213894Smarius sc->chip_type == ED_CHIP_TYPE_AX88790 || 616213894Smarius sc->chip_type == ED_CHIP_TYPE_TC5299J) { 617213894Smarius error = mii_attach(dev, &sc->miibus, sc->ifp, ed_ifmedia_upd, 618213894Smarius ed_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, 619221407Smarius MII_OFFSET_ANY, MIIF_FORCEANEG); 620213894Smarius if (error != 0) { 621213894Smarius device_printf(dev, "attaching PHYs failed\n"); 622150108Simp goto bad; 623150108Simp } 62480159Siedowse } 625150300Simp if (sc->miibus != NULL) { 626150300Simp sc->sc_tick = ed_pccard_tick; 627150300Simp sc->sc_mediachg = ed_pccard_mediachg; 628150300Simp sc->sc_media_ioctl = ed_pccard_media_ioctl; 629190643Simp ed_pccard_kick_phy(sc); 630190802Simp } else { 631190802Simp ed_gen_ifmedia_init(sc); 632150300Simp } 633191299Simp if (modem_rid != -1) 634149832Simp ed_pccard_add_modem(dev); 635191234Simp 636191234Simp error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, 637191234Simp NULL, edintr, sc, &sc->irq_handle); 638191234Simp if (error) { 639191234Simp device_printf(dev, "setup intr failed %d \n", error); 640191234Simp goto bad; 641191234Simp } 642191234Simp 643149558Simp return (0); 644149841Simpbad: 645181351Simp ed_detach(dev); 646149841Simp return (error); 64764777Snyan} 64863775Stanimura 64970154Stoshi/* 65070154Stoshi * Probe the Ethernet MAC addrees for PCMCIA Linksys EtherFast 10/100 65170154Stoshi * and compatible cards (DL10019C Ethernet controller). 65270154Stoshi */ 65370154Stoshistatic int 654149841Simped_pccard_dl100xx(device_t dev, const struct ed_product *pp) 65570154Stoshi{ 65670154Stoshi struct ed_softc *sc = device_get_softc(dev); 65770154Stoshi u_char sum; 658140844Simp uint8_t id; 659190803Simp u_int memsize; 660149841Simp int i, error; 66170154Stoshi 662150108Simp if (!(pp->flags & NE2000DVF_DL100XX)) 663149841Simp return (ENXIO); 664150108Simp if (bootverbose) 665264942Smarius device_printf(dev, "Trying DL100xx\n"); 666149841Simp error = ed_probe_Novell_generic(dev, device_get_flags(dev)); 667150108Simp if (bootverbose && error) 668150108Simp device_printf(dev, "Novell generic probe failed: %d\n", error); 669149841Simp if (error != 0) 670149841Simp return (error); 671149841Simp 67270154Stoshi /* 67370154Stoshi * Linksys registers(offset from ASIC base) 67470154Stoshi * 67570154Stoshi * 0x04-0x09 : Physical Address Register 0-5 (PAR0-PAR5) 67670154Stoshi * 0x0A : Card ID Register (CIR) 67770154Stoshi * 0x0B : Check Sum Register (SR) 67870154Stoshi */ 67970154Stoshi for (sum = 0, i = 0x04; i < 0x0c; i++) 68070154Stoshi sum += ed_asic_inb(sc, i); 681150108Simp if (sum != 0xff) { 682150108Simp if (bootverbose) 683150108Simp device_printf(dev, "Bad checksum %#x\n", sum); 684140844Simp return (ENXIO); /* invalid DL10019C */ 685150108Simp } 686150108Simp if (bootverbose) 687150108Simp device_printf(dev, "CIR is %d\n", ed_asic_inb(sc, 0xa)); 688140844Simp for (i = 0; i < ETHER_ADDR_LEN; i++) 689147256Sbrooks sc->enaddr[i] = ed_asic_inb(sc, 0x04 + i); 69070154Stoshi ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS); 691140844Simp id = ed_asic_inb(sc, 0xf); 69270154Stoshi sc->isa16bit = 1; 693190803Simp /* 694190803Simp * Hard code values based on the datasheet. We're NE-2000 compatible 695190803Simp * NIC with 24kb of packet memory starting at 24k offset. These 696190803Simp * cards also work with 16k at 16k, but don't work with 24k at 16k 697190803Simp * or 32k at 16k. 698190803Simp */ 699190803Simp sc->type = ED_TYPE_NE2000; 700190803Simp sc->mem_start = 24 * 1024; 701190803Simp memsize = sc->mem_size = 24 * 1024; 702190803Simp sc->mem_end = sc->mem_start + memsize; 703190803Simp sc->tx_page_start = memsize / ED_PAGE_SIZE; 704190803Simp sc->txb_cnt = 3; 705190803Simp sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE; 706190803Simp sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE; 707190803Simp 708190803Simp sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE; 709190803Simp 710190803Simp ed_nic_outb(sc, ED_P0_PSTART, sc->mem_start / ED_PAGE_SIZE); 711190803Simp ed_nic_outb(sc, ED_P0_PSTOP, sc->mem_end / ED_PAGE_SIZE); 712141681Simp sc->vendor = ED_VENDOR_NOVELL; 713141881Simp sc->chip_type = (id & 0x90) == 0x90 ? 714141881Simp ED_CHIP_TYPE_DL10022 : ED_CHIP_TYPE_DL10019; 715140844Simp sc->type_str = ((id & 0x90) == 0x90) ? "DL10022" : "DL10019"; 716264942Smarius sc->mii_bitbang_ops = &ed_pccard_dl100xx_mii_bitbang_ops; 717140844Simp return (0); 71870154Stoshi} 71970355Simp 72073374Simp/* MII bit-twiddling routines for cards using Dlink chipset */ 72173374Simp 72273374Simpstatic void 723150108Simped_pccard_dl100xx_mii_reset(struct ed_softc *sc) 72473374Simp{ 725141881Simp if (sc->chip_type != ED_CHIP_TYPE_DL10022) 726141881Simp return; 727141881Simp 728190650Simp ed_asic_outb(sc, ED_DL100XX_MIIBUS, ED_DL10022_MII_RESET2); 72973374Simp DELAY(10); 730150108Simp ed_asic_outb(sc, ED_DL100XX_MIIBUS, 731190650Simp ED_DL10022_MII_RESET2 | ED_DL10022_MII_RESET1); 73273374Simp DELAY(10); 733190650Simp ed_asic_outb(sc, ED_DL100XX_MIIBUS, ED_DL10022_MII_RESET2); 73473374Simp DELAY(10); 735150108Simp ed_asic_outb(sc, ED_DL100XX_MIIBUS, 736190650Simp ED_DL10022_MII_RESET2 | ED_DL10022_MII_RESET1); 73773374Simp DELAY(10); 738150108Simp ed_asic_outb(sc, ED_DL100XX_MIIBUS, 0); 73973374Simp} 74073374Simp 74173374Simpstatic void 742264942Smariused_pccard_dl100xx_mii_bitbang_write(device_t dev, uint32_t val) 74373374Simp{ 744264942Smarius struct ed_softc *sc; 74573374Simp 746264942Smarius sc = device_get_softc(dev); 747264942Smarius 748264942Smarius ed_asic_outb(sc, ED_DL100XX_MIIBUS, val); 749264942Smarius ed_asic_barrier(sc, ED_DL100XX_MIIBUS, 1, 750264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 75173374Simp} 75273374Simp 753264942Smariusstatic uint32_t 754264942Smariused_pccard_dl100xx_mii_bitbang_read(device_t dev) 75573374Simp{ 756264942Smarius struct ed_softc *sc; 757264942Smarius uint32_t val; 75873374Simp 759264942Smarius sc = device_get_softc(dev); 760264942Smarius 761264942Smarius val = ed_asic_inb(sc, ED_DL100XX_MIIBUS); 762264942Smarius ed_asic_barrier(sc, ED_DL100XX_MIIBUS, 1, 763264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 764264942Smarius return (val); 76573374Simp} 76673374Simp 767190559Simpstatic void 768190559Simped_pccard_ax88x90_reset(struct ed_softc *sc) 769190559Simp{ 770190559Simp int i; 771190559Simp 772190559Simp /* Reset Card */ 773264942Smarius ed_nic_barrier(sc, ED_P0_CR, 1, 774264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 775190559Simp ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP | ED_CR_PAGE_0); 776264942Smarius ed_nic_barrier(sc, ED_P0_CR, 1, 777264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 778190559Simp ed_asic_outb(sc, ED_NOVELL_RESET, ed_asic_inb(sc, ED_NOVELL_RESET)); 779190559Simp 780190596Simp /* Wait for the RST bit to assert, but cap it at 10ms */ 781190596Simp for (i = 10000; !(ed_nic_inb(sc, ED_P0_ISR) & ED_ISR_RST) && i > 0; 782190596Simp i--) 783190596Simp continue; 784190559Simp ed_nic_outb(sc, ED_P0_ISR, ED_ISR_RST); /* ACK INTR */ 785190559Simp if (i == 0) 786190559Simp device_printf(sc->dev, "Reset didn't finish\n"); 787190559Simp} 788190559Simp 789190559Simp/* 790190559Simp * Probe and vendor-specific initialization routine for ax88x90 boards 791190559Simp */ 792150108Simpstatic int 793190559Simped_probe_ax88x90_generic(device_t dev, int flags) 794149841Simp{ 795190559Simp struct ed_softc *sc = device_get_softc(dev); 796190559Simp u_int memsize; 797190559Simp static char test_pattern[32] = "THIS is A memory TEST pattern"; 798190559Simp char test_buffer[32]; 799190559Simp 800190559Simp ed_pccard_ax88x90_reset(sc); 801190597Simp DELAY(10*1000); 802190559Simp 803190559Simp /* Make sure that we really have an 8390 based board */ 804190559Simp if (!ed_probe_generic8390(sc)) 805190559Simp return (ENXIO); 806190559Simp 807190559Simp sc->vendor = ED_VENDOR_NOVELL; 808190559Simp sc->mem_shared = 0; 809190559Simp sc->cr_proto = ED_CR_RD2; 810190559Simp 811190559Simp /* 812190559Simp * This prevents packets from being stored in the NIC memory when the 813190596Simp * readmem routine turns on the start bit in the CR. We write some 814190596Simp * bytes in word mode and verify we can read them back. If we can't 815190596Simp * then we don't have an AX88x90 chip here. 816190559Simp */ 817190644Simp sc->isa16bit = 1; 818190559Simp ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON); 819190559Simp ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS); 820190559Simp ed_pio_writemem(sc, test_pattern, 16384, sizeof(test_pattern)); 821190559Simp ed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern)); 822190559Simp if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) != 0) 823190559Simp return (ENXIO); 824190596Simp 825190596Simp /* 826190596Simp * Hard code values based on the datasheet. We're NE-2000 compatible 827190644Simp * NIC with 16kb of packet memory starting at 16k offset. 828190596Simp */ 829190559Simp sc->type = ED_TYPE_NE2000; 830190644Simp memsize = sc->mem_size = 16*1024; 831190644Simp sc->mem_start = 16 * 1024; 832190559Simp if (ed_asic_inb(sc, ED_AX88X90_TEST) != 0) 833190559Simp sc->chip_type = ED_CHIP_TYPE_AX88790; 834190644Simp else { 835190559Simp sc->chip_type = ED_CHIP_TYPE_AX88190; 836190644Simp /* 837190644Simp * The AX88190 (not A) has external 64k SRAM. Probe for this 838190644Simp * here. Most of the cards I have either use the AX88190A 839190644Simp * part, or have only 32k SRAM for some reason, so I don't 840190644Simp * know if this works or not. 841190644Simp */ 842190644Simp ed_pio_writemem(sc, test_pattern, 32768, sizeof(test_pattern)); 843190644Simp ed_pio_readmem(sc, 32768, test_buffer, sizeof(test_pattern)); 844190644Simp if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) { 845190644Simp sc->mem_start = 2*1024; 846190644Simp memsize = sc->mem_size = 62 * 1024; 847190644Simp } 848190644Simp } 849190559Simp sc->mem_end = sc->mem_start + memsize; 850190559Simp sc->tx_page_start = memsize / ED_PAGE_SIZE; 851190644Simp if (sc->mem_size > 16 * 1024) 852190644Simp sc->txb_cnt = 3; 853190644Simp else 854190644Simp sc->txb_cnt = 2; 855190559Simp sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE; 856190559Simp sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE; 857190559Simp 858190559Simp sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE; 859190644Simp 860190644Simp ed_nic_outb(sc, ED_P0_PSTART, sc->mem_start / ED_PAGE_SIZE); 861190644Simp ed_nic_outb(sc, ED_P0_PSTOP, sc->mem_end / ED_PAGE_SIZE); 862190644Simp 863190644Simp /* Get the mac before we go -- It's just at 0x400 in "SRAM" */ 864190644Simp ed_pio_readmem(sc, 0x400, sc->enaddr, ETHER_ADDR_LEN); 865190644Simp 866190559Simp /* clear any pending interrupts that might have occurred above */ 867190559Simp ed_nic_outb(sc, ED_P0_ISR, 0xff); 868190559Simp sc->sc_write_mbufs = ed_pio_write_mbufs; 869190559Simp return (0); 870190559Simp} 871190559Simp 872190559Simpstatic int 873190559Simped_pccard_ax88x90_check_mii(device_t dev, struct ed_softc *sc) 874190559Simp{ 875190559Simp int i, id; 876190559Simp 877190559Simp /* 878190559Simp * All AX88x90 devices have MII and a PHY, so we use this to weed out 879190559Simp * chips that would otherwise make it through the tests we have after 880190559Simp * this point. 881190559Simp */ 882190559Simp for (i = 0; i < 32; i++) { 883190559Simp id = ed_miibus_readreg(dev, i, MII_BMSR); 884190559Simp if (id != 0 && id != 0xffff) 885190559Simp break; 886190559Simp } 887190559Simp /* 888190559Simp * Found one, we're good. 889190559Simp */ 890190559Simp if (i != 32) 891190559Simp return (0); 892190559Simp /* 893190559Simp * Didn't find anything, so try to power up and try again. The PHY 894190559Simp * may be not responding because we're in power down mode. 895190559Simp */ 896190559Simp if (sc->chip_type == ED_CHIP_TYPE_AX88190) 897190559Simp return (ENXIO); 898190559Simp pccard_ccr_write_1(dev, PCCARD_CCR_STATUS, PCCARD_CCR_STATUS_PWRDWN); 899190559Simp for (i = 0; i < 32; i++) { 900190559Simp id = ed_miibus_readreg(dev, i, MII_BMSR); 901190559Simp if (id != 0 && id != 0xffff) 902190559Simp break; 903190559Simp } 904190559Simp /* 905190559Simp * Still no joy? We're AFU, punt. 906190559Simp */ 907190559Simp if (i == 32) 908190559Simp return (ENXIO); 909190559Simp return (0); 910190559Simp} 911190559Simp 912149841Simp/* 913149841Simp * Special setup for AX88[17]90 914149841Simp */ 915149841Simpstatic int 916149841Simped_pccard_ax88x90(device_t dev, const struct ed_product *pp) 917149841Simp{ 918190559Simp int error; 919190559Simp int iobase; 920149841Simp struct ed_softc *sc = device_get_softc(dev); 921149841Simp 922150108Simp if (!(pp->flags & NE2000DVF_AX88X90)) 923149841Simp return (ENXIO); 924149841Simp 925150108Simp if (bootverbose) 926150108Simp device_printf(dev, "Checking AX88x90\n"); 927150108Simp 928150108Simp /* 929150108Simp * Set the IOBASE Register. The AX88x90 cards are potentially 930150108Simp * multifunction cards, and thus requires a slight workaround. 931190559Simp * We write the address the card is at, on the off chance that this 932190559Simp * card is not MFC. 933190559Simp * XXX I'm not sure that this is still needed... 934149841Simp */ 935149841Simp iobase = rman_get_start(sc->port_res); 936150108Simp pccard_ccr_write_1(dev, PCCARD_CCR_IOBASE0, iobase & 0xff); 937150108Simp pccard_ccr_write_1(dev, PCCARD_CCR_IOBASE1, (iobase >> 8) & 0xff); 938150108Simp 939190559Simp error = ed_probe_ax88x90_generic(dev, device_get_flags(dev)); 940190559Simp if (error) { 941190559Simp if (bootverbose) 942190559Simp device_printf(dev, "probe ax88x90 failed %d\n", 943190559Simp error); 944264942Smarius return (error); 945150108Simp } 946264942Smarius sc->mii_bitbang_ops = &ed_pccard_ax88x90_mii_bitbang_ops; 947190559Simp error = ed_pccard_ax88x90_check_mii(dev, sc); 948190559Simp if (error) 949264942Smarius return (error); 950190559Simp sc->vendor = ED_VENDOR_NOVELL; 951190559Simp sc->type = ED_TYPE_NE2000; 952190559Simp if (sc->chip_type == ED_CHIP_TYPE_AX88190) 953190559Simp sc->type_str = "AX88190"; 954190559Simp else 955190559Simp sc->type_str = "AX88790"; 956190559Simp return (0); 957149841Simp} 958149841Simp 959150108Simpstatic void 960264942Smariused_pccard_ax88x90_mii_bitbang_write(device_t dev, uint32_t val) 961150108Simp{ 962264942Smarius struct ed_softc *sc; 963150108Simp 964264942Smarius sc = device_get_softc(dev); 965264942Smarius 966264942Smarius ed_asic_outb(sc, ED_AX88X90_MIIBUS, val); 967264942Smarius ed_asic_barrier(sc, ED_AX88X90_MIIBUS, 1, 968264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 969150108Simp} 970150108Simp 971264942Smariusstatic uint32_t 972264942Smariused_pccard_ax88x90_mii_bitbang_read(device_t dev) 973150108Simp{ 974264942Smarius struct ed_softc *sc; 975264942Smarius uint32_t val; 976150108Simp 977264942Smarius sc = device_get_softc(dev); 978264942Smarius 979264942Smarius val = ed_asic_inb(sc, ED_AX88X90_MIIBUS); 980264942Smarius ed_asic_barrier(sc, ED_AX88X90_MIIBUS, 1, 981264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 982264942Smarius return (val); 983150108Simp} 984150108Simp 985150108Simp/* 986150957Simp * Special setup for TC5299J 987150957Simp */ 988150957Simpstatic int 989150957Simped_pccard_tc5299j(device_t dev, const struct ed_product *pp) 990150957Simp{ 991150957Simp int error, i, id; 992150957Simp char *ts; 993150957Simp struct ed_softc *sc = device_get_softc(dev); 994150957Simp 995150957Simp if (!(pp->flags & NE2000DVF_TC5299J)) 996150957Simp return (ENXIO); 997150957Simp 998150957Simp if (bootverbose) 999150957Simp device_printf(dev, "Checking Tc5299j\n"); 1000150957Simp 1001191370Simp error = ed_probe_Novell_generic(dev, device_get_flags(dev)); 1002191370Simp if (bootverbose) 1003264942Smarius device_printf(dev, "Novell generic probe failed: %d\n", error); 1004191370Simp if (error != 0) 1005191370Simp return (error); 1006191370Simp 1007150957Simp /* 1008191370Simp * Check to see if we have a MII PHY ID at any address. All TC5299J 1009191370Simp * devices have MII and a PHY, so we use this to weed out chips that 1010191370Simp * would otherwise make it through the tests we have after this point. 1011150957Simp */ 1012264942Smarius sc->mii_bitbang_ops = &ed_pccard_tc5299j_mii_bitbang_ops; 1013150957Simp for (i = 0; i < 32; i++) { 1014150957Simp id = ed_miibus_readreg(dev, i, MII_PHYIDR1); 1015150957Simp if (id != 0 && id != 0xffff) 1016150957Simp break; 1017150957Simp } 1018264942Smarius if (i == 32) 1019150957Simp return (ENXIO); 1020150957Simp ts = "TC5299J"; 1021264942Smarius if (ed_pccard_rom_mac(dev, sc->enaddr) == 0) 1022150957Simp return (ENXIO); 1023150957Simp sc->vendor = ED_VENDOR_NOVELL; 1024150957Simp sc->type = ED_TYPE_NE2000; 1025150957Simp sc->chip_type = ED_CHIP_TYPE_TC5299J; 1026150957Simp sc->type_str = ts; 1027150957Simp return (0); 1028150957Simp} 1029150957Simp 1030150957Simpstatic void 1031264942Smariused_pccard_tc5299j_mii_bitbang_write(device_t dev, uint32_t val) 1032150957Simp{ 1033264942Smarius struct ed_softc *sc; 1034150957Simp 1035264942Smarius sc = device_get_softc(dev); 1036150957Simp 1037264942Smarius /* We are already on page 3. */ 1038264942Smarius ed_nic_outb(sc, ED_TC5299J_MIIBUS, val); 1039264942Smarius ed_nic_barrier(sc, ED_TC5299J_MIIBUS, 1, 1040264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 1041150957Simp} 1042150957Simp 1043264942Smariusstatic uint32_t 1044264942Smariused_pccard_tc5299j_mii_bitbang_read(device_t dev) 1045150957Simp{ 1046264942Smarius struct ed_softc *sc; 1047264942Smarius uint32_t val; 1048150957Simp 1049264942Smarius sc = device_get_softc(dev); 1050150957Simp 1051264942Smarius /* We are already on page 3. */ 1052264942Smarius val = ed_asic_inb(sc, ED_TC5299J_MIIBUS); 1053264942Smarius ed_nic_barrier(sc, ED_TC5299J_MIIBUS, 1, 1054264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 1055264942Smarius return (val); 1056150957Simp} 1057150957Simp 1058150957Simp/* 1059150108Simp * MII bus support routines. 1060150108Simp */ 1061150108Simpstatic int 1062150108Simped_miibus_readreg(device_t dev, int phy, int reg) 1063150108Simp{ 1064150108Simp struct ed_softc *sc; 1065264942Smarius int val; 1066264942Smarius uint8_t cr = 0; 1067150108Simp 1068190559Simp sc = device_get_softc(dev); 1069150108Simp /* 1070190559Simp * The AX88790 has an interesting quirk. It has an internal phy that 1071190559Simp * needs a special bit set to access, but can also have additional 1072190559Simp * external PHYs set for things like HomeNET media. When accessing 1073190559Simp * the internal PHY, a bit has to be set, when accessing the external 1074190559Simp * PHYs, it must be clear. See Errata 1, page 51, in the AX88790 1075190559Simp * datasheet for more details. 1076190586Simp * 1077190586Simp * Also, PHYs above 16 appear to be phantoms on some cards, but not 1078190586Simp * others. Registers read for this are often the same as prior values 1079190586Simp * read. Filter all register requests to 17-31. 1080150108Simp */ 1081190559Simp if (sc->chip_type == ED_CHIP_TYPE_AX88790) { 1082190586Simp if (phy > 0x10) 1083190586Simp return (0); 1084190559Simp if (phy == 0x10) 1085190559Simp ed_asic_outb(sc, ED_AX88X90_GPIO, 1086190559Simp ED_AX88X90_GPIO_INT_PHY); 1087190559Simp else 1088190559Simp ed_asic_outb(sc, ED_AX88X90_GPIO, 0); 1089264942Smarius ed_asic_barrier(sc, ED_AX88X90_GPIO, 1, 1090264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 1091264942Smarius } else if (sc->chip_type == ED_CHIP_TYPE_TC5299J) { 1092264942Smarius /* Select page 3. */ 1093264942Smarius ed_nic_barrier(sc, ED_P0_CR, 1, 1094264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 1095264942Smarius cr = ed_nic_inb(sc, ED_P0_CR); 1096264942Smarius ed_nic_outb(sc, ED_P0_CR, cr | ED_CR_PAGE_3); 1097264942Smarius ed_nic_barrier(sc, ED_P0_CR, 1, 1098264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 1099190559Simp } 1100264942Smarius val = mii_bitbang_readreg(dev, sc->mii_bitbang_ops, phy, reg); 1101264942Smarius if (sc->chip_type == ED_CHIP_TYPE_TC5299J) { 1102264942Smarius /* Restore prior page. */ 1103264942Smarius ed_nic_outb(sc, ED_P0_CR, cr); 1104264942Smarius ed_nic_barrier(sc, ED_P0_CR, 1, 1105264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 1106264942Smarius } 1107264942Smarius return (val); 1108150108Simp} 1109150108Simp 1110189726Simpstatic int 1111150108Simped_miibus_writereg(device_t dev, int phy, int reg, int data) 1112150108Simp{ 1113150108Simp struct ed_softc *sc; 1114264942Smarius uint8_t cr = 0; 1115150108Simp 1116190559Simp sc = device_get_softc(dev); 1117190586Simp /* See ed_miibus_readreg for details */ 1118190559Simp if (sc->chip_type == ED_CHIP_TYPE_AX88790) { 1119190586Simp if (phy > 0x10) 1120190586Simp return (0); 1121190559Simp if (phy == 0x10) 1122190559Simp ed_asic_outb(sc, ED_AX88X90_GPIO, 1123190559Simp ED_AX88X90_GPIO_INT_PHY); 1124190559Simp else 1125190559Simp ed_asic_outb(sc, ED_AX88X90_GPIO, 0); 1126264942Smarius ed_asic_barrier(sc, ED_AX88X90_GPIO, 1, 1127264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 1128264942Smarius } else if (sc->chip_type == ED_CHIP_TYPE_TC5299J) { 1129264942Smarius /* Select page 3. */ 1130264942Smarius ed_nic_barrier(sc, ED_P0_CR, 1, 1131264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 1132264942Smarius cr = ed_nic_inb(sc, ED_P0_CR); 1133264942Smarius ed_nic_outb(sc, ED_P0_CR, cr | ED_CR_PAGE_3); 1134264942Smarius ed_nic_barrier(sc, ED_P0_CR, 1, 1135264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 1136190559Simp } 1137264942Smarius mii_bitbang_writereg(dev, sc->mii_bitbang_ops, phy, reg, data); 1138264942Smarius if (sc->chip_type == ED_CHIP_TYPE_TC5299J) { 1139264942Smarius /* Restore prior page. */ 1140264942Smarius ed_nic_outb(sc, ED_P0_CR, cr); 1141264942Smarius ed_nic_barrier(sc, ED_P0_CR, 1, 1142264942Smarius BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 1143264942Smarius } 1144189726Simp return (0); 1145150108Simp} 1146150108Simp 1147150300Simpstatic int 1148150300Simped_ifmedia_upd(struct ifnet *ifp) 1149150300Simp{ 1150150300Simp struct ed_softc *sc; 1151190643Simp int error; 1152150300Simp 1153150300Simp sc = ifp->if_softc; 1154264942Smarius ED_LOCK(sc); 1155264942Smarius if (sc->miibus == NULL) { 1156264942Smarius ED_UNLOCK(sc); 1157150300Simp return (ENXIO); 1158264942Smarius } 1159264942Smarius 1160190643Simp error = ed_pccard_kick_phy(sc); 1161190643Simp ED_UNLOCK(sc); 1162190643Simp return (error); 1163150300Simp} 1164150300Simp 1165150300Simpstatic void 1166150300Simped_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 1167150300Simp{ 1168150300Simp struct ed_softc *sc; 1169150300Simp struct mii_data *mii; 1170150300Simp 1171150300Simp sc = ifp->if_softc; 1172264942Smarius ED_LOCK(sc); 1173264942Smarius if (sc->miibus == NULL) { 1174150300Simp return; 1175264942Smarius ED_UNLOCK(sc); 1176264942Smarius } 1177150300Simp 1178150300Simp mii = device_get_softc(sc->miibus); 1179150300Simp mii_pollstat(mii); 1180150300Simp ifmr->ifm_active = mii->mii_media_active; 1181150300Simp ifmr->ifm_status = mii->mii_media_status; 1182264942Smarius ED_UNLOCK(sc); 1183150300Simp} 1184150300Simp 1185150300Simpstatic void 1186150300Simped_child_detached(device_t dev, device_t child) 1187150300Simp{ 1188150300Simp struct ed_softc *sc; 1189150300Simp 1190150300Simp sc = device_get_softc(dev); 1191150300Simp if (child == sc->miibus) 1192150300Simp sc->miibus = NULL; 1193150300Simp} 1194150300Simp 1195190804Simpstatic void 1196199380Sjhbed_pccard_tick(struct ed_softc *sc) 1197190804Simp{ 1198190804Simp struct mii_data *mii; 1199190804Simp int media = 0; 1200190804Simp 1201190804Simp ED_ASSERT_LOCKED(sc); 1202190804Simp if (sc->miibus != NULL) { 1203190804Simp mii = device_get_softc(sc->miibus); 1204190804Simp media = mii->mii_media_status; 1205190804Simp mii_tick(mii); 1206190804Simp if (mii->mii_media_status & IFM_ACTIVE && 1207190804Simp media != mii->mii_media_status) { 1208190804Simp if (sc->chip_type == ED_CHIP_TYPE_DL10022) { 1209190804Simp ed_asic_outb(sc, ED_DL10022_DIAG, 1210190804Simp (mii->mii_media_active & IFM_FDX) ? 1211190804Simp ED_DL10022_COLLISON_DIS : 0); 1212190805Simp#ifdef notyet 1213190804Simp } else if (sc->chip_type == ED_CHIP_TYPE_DL10019) { 1214190804Simp write_asic(sc, ED_DL10019_MAGIC, 1215190804Simp (mii->mii_media_active & IFM_FDX) ? 1216190804Simp DL19FDUPLX : 0); 1217190805Simp#endif 1218190804Simp } 1219190804Simp } 1220190804Simp 1221190804Simp } 1222190804Simp} 1223190804Simp 122470355Simpstatic device_method_t ed_pccard_methods[] = { 122570355Simp /* Device interface */ 1226149558Simp DEVMETHOD(device_probe, ed_pccard_probe), 1227149558Simp DEVMETHOD(device_attach, ed_pccard_attach), 1228141494Simp DEVMETHOD(device_detach, ed_detach), 122970355Simp 123073374Simp /* Bus interface */ 123173374Simp DEVMETHOD(bus_child_detached, ed_child_detached), 123273374Simp 123373374Simp /* MII interface */ 123473374Simp DEVMETHOD(miibus_readreg, ed_miibus_readreg), 123573374Simp DEVMETHOD(miibus_writereg, ed_miibus_writereg), 123673374Simp 1237264942Smarius DEVMETHOD_END 123870355Simp}; 123970355Simp 124070355Simpstatic driver_t ed_pccard_driver = { 124170355Simp "ed", 124270355Simp ed_pccard_methods, 124370355Simp sizeof(struct ed_softc) 124470355Simp}; 124570355Simp 1246264942SmariusDRIVER_MODULE(ed, pccard, ed_pccard_driver, ed_devclass, 0, NULL); 1247264942SmariusDRIVER_MODULE(miibus, ed, miibus_driver, miibus_devclass, 0, NULL); 1248150300SimpMODULE_DEPEND(ed, miibus, 1, 1, 1); 1249150300SimpMODULE_DEPEND(ed, ether, 1, 1, 1); 1250