|
|
1.1 ! root 1: /*====================================================================== ! 2: ! 3: A PCMCIA ethernet driver for SMC91c92-based cards. ! 4: ! 5: This driver supports Megahertz PCMCIA ethernet cards; and ! 6: Megahertz, Motorola, Ositech, and Psion Dacom ethernet/modem ! 7: multifunction cards. ! 8: ! 9: Copyright (C) 1999 David A. Hinds -- [email protected] ! 10: ! 11: smc91c92_cs.c 1.123 2003/08/25 15:57:41 ! 12: ! 13: This driver contains code written by Donald Becker ! 14: ([email protected]), Rowan Hughes ([email protected]), ! 15: David Hinds ([email protected]), and Erik Stahlman ! 16: ([email protected]). Donald wrote the SMC 91c92 code using parts of ! 17: Erik's SMC 91c94 driver. Rowan wrote a similar driver, and I've ! 18: incorporated some parts of his driver here. I (Dave) wrote most ! 19: of the PCMCIA glue code, and the Ositech support code. Kelly ! 20: Stephens ([email protected]) added support for the Motorola ! 21: Mariner, with help from Allen Brost. ! 22: ! 23: This software may be used and distributed according to the terms of ! 24: the GNU General Public License, incorporated herein by reference. ! 25: ! 26: ======================================================================*/ ! 27: ! 28: #include <linux/module.h> ! 29: #include <linux/kernel.h> ! 30: #include <linux/init.h> ! 31: #include <linux/sched.h> ! 32: #include <linux/slab.h> ! 33: #include <linux/string.h> ! 34: #include <linux/timer.h> ! 35: #include <linux/interrupt.h> ! 36: #include <linux/delay.h> ! 37: #include <linux/crc32.h> ! 38: #include <asm/io.h> ! 39: #include <asm/system.h> ! 40: #include <asm/uaccess.h> ! 41: ! 42: #include <linux/netdevice.h> ! 43: #include <linux/etherdevice.h> ! 44: #include <linux/skbuff.h> ! 45: #include <linux/if_arp.h> ! 46: #include <linux/ioport.h> ! 47: ! 48: #include <pcmcia/version.h> ! 49: #include <pcmcia/cs_types.h> ! 50: #include <pcmcia/cs.h> ! 51: #include <pcmcia/cistpl.h> ! 52: #include <pcmcia/cisreg.h> ! 53: #include <pcmcia/ciscode.h> ! 54: #include <pcmcia/ds.h> ! 55: ! 56: /* Ositech Seven of Diamonds firmware */ ! 57: #include "ositech.h" ! 58: ! 59: /*====================================================================*/ ! 60: ! 61: static char *if_names[] = { "auto", "10baseT", "10base2"}; ! 62: ! 63: /* Module parameters */ ! 64: ! 65: MODULE_DESCRIPTION("SMC 91c92 series PCMCIA ethernet driver"); ! 66: MODULE_LICENSE("GPL"); ! 67: ! 68: #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") ! 69: ! 70: /* ! 71: Transceiver/media type. ! 72: 0 = auto ! 73: 1 = 10baseT (and autoselect if #define AUTOSELECT), ! 74: 2 = AUI/10base2, ! 75: */ ! 76: INT_MODULE_PARM(if_port, 0); ! 77: ! 78: /* Bit map of interrupts to choose from. */ ! 79: INT_MODULE_PARM(irq_mask, 0xdeb8); ! 80: static int irq_list[4] = { -1 }; ! 81: MODULE_PARM(irq_list, "1-4i"); ! 82: ! 83: #ifdef PCMCIA_DEBUG ! 84: INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG); ! 85: static const char *version = ! 86: "smc91c92_cs.c 0.09 1996/8/4 Donald Becker, [email protected].\n"; ! 87: #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) ! 88: #else ! 89: #define DEBUG(n, args...) ! 90: #endif ! 91: ! 92: /*====================================================================*/ ! 93: ! 94: /* Operational parameter that usually are not changed. */ ! 95: ! 96: /* Time in jiffies before concluding Tx hung */ ! 97: #define TX_TIMEOUT ((400*HZ)/1000) ! 98: ! 99: /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ ! 100: #define INTR_WORK 4 ! 101: ! 102: /* Times to check the check the chip before concluding that it doesn't ! 103: currently have room for another Tx packet. */ ! 104: #define MEMORY_WAIT_TIME 8 ! 105: ! 106: static dev_info_t dev_info = "smc91c92_cs"; ! 107: ! 108: static dev_link_t *dev_list; ! 109: ! 110: struct smc_private { ! 111: dev_link_t link; ! 112: struct net_device dev; ! 113: u_short manfid; ! 114: u_short cardid; ! 115: struct net_device_stats stats; ! 116: dev_node_t node; ! 117: struct sk_buff *saved_skb; ! 118: int packets_waiting; ! 119: caddr_t base; ! 120: u_short cfg; ! 121: struct timer_list media; ! 122: int watchdog, tx_err; ! 123: u_short media_status; ! 124: u_short fast_poll; ! 125: u_short link_status; ! 126: int phy_id; ! 127: int duplex; ! 128: int rx_ovrn; ! 129: }; ! 130: ! 131: /* Special definitions for Megahertz multifunction cards */ ! 132: #define MEGAHERTZ_ISR 0x0380 ! 133: ! 134: /* Special function registers for Motorola Mariner */ ! 135: #define MOT_LAN 0x0000 ! 136: #define MOT_UART 0x0020 ! 137: #define MOT_EEPROM 0x20 ! 138: ! 139: #define MOT_NORMAL \ ! 140: (COR_LEVEL_REQ | COR_FUNC_ENA | COR_ADDR_DECODE | COR_IREQ_ENA) ! 141: ! 142: /* Special function registers for Ositech cards */ ! 143: #define OSITECH_AUI_CTL 0x0c ! 144: #define OSITECH_PWRDOWN 0x0d ! 145: #define OSITECH_RESET 0x0e ! 146: #define OSITECH_ISR 0x0f ! 147: #define OSITECH_AUI_PWR 0x0c ! 148: #define OSITECH_RESET_ISR 0x0e ! 149: ! 150: #define OSI_AUI_PWR 0x40 ! 151: #define OSI_LAN_PWRDOWN 0x02 ! 152: #define OSI_MODEM_PWRDOWN 0x01 ! 153: #define OSI_LAN_RESET 0x02 ! 154: #define OSI_MODEM_RESET 0x01 ! 155: ! 156: /* Symbolic constants for the SMC91c9* series chips, from Erik Stahlman. */ ! 157: #define BANK_SELECT 14 /* Window select register. */ ! 158: #define SMC_SELECT_BANK(x) { outw(x, ioaddr + BANK_SELECT); } ! 159: ! 160: /* Bank 0 registers. */ ! 161: #define TCR 0 /* transmit control register */ ! 162: #define TCR_CLEAR 0 /* do NOTHING */ ! 163: #define TCR_ENABLE 0x0001 /* if this is 1, we can transmit */ ! 164: #define TCR_PAD_EN 0x0080 /* pads short packets to 64 bytes */ ! 165: #define TCR_MONCSN 0x0400 /* Monitor Carrier. */ ! 166: #define TCR_FDUPLX 0x0800 /* Full duplex mode. */ ! 167: #define TCR_NORMAL TCR_ENABLE | TCR_PAD_EN ! 168: ! 169: #define EPH 2 /* Ethernet Protocol Handler report. */ ! 170: #define EPH_TX_SUC 0x0001 ! 171: #define EPH_SNGLCOL 0x0002 ! 172: #define EPH_MULCOL 0x0004 ! 173: #define EPH_LTX_MULT 0x0008 ! 174: #define EPH_16COL 0x0010 ! 175: #define EPH_SQET 0x0020 ! 176: #define EPH_LTX_BRD 0x0040 ! 177: #define EPH_TX_DEFR 0x0080 ! 178: #define EPH_LAT_COL 0x0200 ! 179: #define EPH_LOST_CAR 0x0400 ! 180: #define EPH_EXC_DEF 0x0800 ! 181: #define EPH_CTR_ROL 0x1000 ! 182: #define EPH_RX_OVRN 0x2000 ! 183: #define EPH_LINK_OK 0x4000 ! 184: #define EPH_TX_UNRN 0x8000 ! 185: #define MEMINFO 8 /* Memory Information Register */ ! 186: #define MEMCFG 10 /* Memory Configuration Register */ ! 187: ! 188: /* Bank 1 registers. */ ! 189: #define CONFIG 0 ! 190: #define CFG_MII_SELECT 0x8000 /* 91C100 only */ ! 191: #define CFG_NO_WAIT 0x1000 ! 192: #define CFG_FULL_STEP 0x0400 ! 193: #define CFG_SET_SQLCH 0x0200 ! 194: #define CFG_AUI_SELECT 0x0100 ! 195: #define CFG_16BIT 0x0080 ! 196: #define CFG_DIS_LINK 0x0040 ! 197: #define CFG_STATIC 0x0030 ! 198: #define CFG_IRQ_SEL_1 0x0004 ! 199: #define CFG_IRQ_SEL_0 0x0002 ! 200: #define BASE_ADDR 2 ! 201: #define ADDR0 4 ! 202: #define GENERAL 10 ! 203: #define CONTROL 12 ! 204: #define CTL_STORE 0x0001 ! 205: #define CTL_RELOAD 0x0002 ! 206: #define CTL_EE_SELECT 0x0004 ! 207: #define CTL_TE_ENABLE 0x0020 ! 208: #define CTL_CR_ENABLE 0x0040 ! 209: #define CTL_LE_ENABLE 0x0080 ! 210: #define CTL_AUTO_RELEASE 0x0800 ! 211: #define CTL_POWERDOWN 0x2000 ! 212: ! 213: /* Bank 2 registers. */ ! 214: #define MMU_CMD 0 ! 215: #define MC_ALLOC 0x20 /* or with number of 256 byte packets */ ! 216: #define MC_RESET 0x40 ! 217: #define MC_RELEASE 0x80 /* remove and release the current rx packet */ ! 218: #define MC_FREEPKT 0xA0 /* Release packet in PNR register */ ! 219: #define MC_ENQUEUE 0xC0 /* Enqueue the packet for transmit */ ! 220: #define PNR_ARR 2 ! 221: #define FIFO_PORTS 4 ! 222: #define FP_RXEMPTY 0x8000 ! 223: #define POINTER 6 ! 224: #define PTR_AUTO_INC 0x0040 ! 225: #define PTR_READ 0x2000 ! 226: #define PTR_AUTOINC 0x4000 ! 227: #define PTR_RCV 0x8000 ! 228: #define DATA_1 8 ! 229: #define INTERRUPT 12 ! 230: #define IM_RCV_INT 0x1 ! 231: #define IM_TX_INT 0x2 ! 232: #define IM_TX_EMPTY_INT 0x4 ! 233: #define IM_ALLOC_INT 0x8 ! 234: #define IM_RX_OVRN_INT 0x10 ! 235: #define IM_EPH_INT 0x20 ! 236: ! 237: #define RCR 4 ! 238: enum RxCfg { RxAllMulti = 0x0004, RxPromisc = 0x0002, ! 239: RxEnable = 0x0100, RxStripCRC = 0x0200}; ! 240: #define RCR_SOFTRESET 0x8000 /* resets the chip */ ! 241: #define RCR_STRIP_CRC 0x200 /* strips CRC */ ! 242: #define RCR_ENABLE 0x100 /* IFF this is set, we can receive packets */ ! 243: #define RCR_ALMUL 0x4 /* receive all multicast packets */ ! 244: #define RCR_PROMISC 0x2 /* enable promiscuous mode */ ! 245: ! 246: /* the normal settings for the RCR register : */ ! 247: #define RCR_NORMAL (RCR_STRIP_CRC | RCR_ENABLE) ! 248: #define RCR_CLEAR 0x0 /* set it to a base state */ ! 249: #define COUNTER 6 ! 250: ! 251: /* BANK 3 -- not the same values as in smc9194! */ ! 252: #define MULTICAST0 0 ! 253: #define MULTICAST2 2 ! 254: #define MULTICAST4 4 ! 255: #define MULTICAST6 6 ! 256: #define MGMT 8 ! 257: #define REVISION 0x0a ! 258: ! 259: /* Transmit status bits. */ ! 260: #define TS_SUCCESS 0x0001 ! 261: #define TS_16COL 0x0010 ! 262: #define TS_LATCOL 0x0200 ! 263: #define TS_LOSTCAR 0x0400 ! 264: ! 265: /* Receive status bits. */ ! 266: #define RS_ALGNERR 0x8000 ! 267: #define RS_BADCRC 0x2000 ! 268: #define RS_ODDFRAME 0x1000 ! 269: #define RS_TOOLONG 0x0800 ! 270: #define RS_TOOSHORT 0x0400 ! 271: #define RS_MULTICAST 0x0001 ! 272: #define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT) ! 273: ! 274: #define set_bits(v, p) outw(inw(p)|(v), (p)) ! 275: #define mask_bits(v, p) outw(inw(p)&(v), (p)) ! 276: ! 277: /*====================================================================*/ ! 278: ! 279: static dev_link_t *smc91c92_attach(void); ! 280: static void smc91c92_detach(dev_link_t *); ! 281: static void smc91c92_config(dev_link_t *link); ! 282: static void smc91c92_release(u_long arg); ! 283: static int smc91c92_event(event_t event, int priority, ! 284: event_callback_args_t *args); ! 285: ! 286: static int smc_open(struct net_device *dev); ! 287: static int smc_close(struct net_device *dev); ! 288: static int smc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); ! 289: static void smc_tx_timeout(struct net_device *dev); ! 290: static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev); ! 291: static void smc_interrupt(int irq, void *dev_id, struct pt_regs *regs); ! 292: static void smc_rx(struct net_device *dev); ! 293: static struct net_device_stats *smc_get_stats(struct net_device *dev); ! 294: static void set_rx_mode(struct net_device *dev); ! 295: static int s9k_config(struct net_device *dev, struct ifmap *map); ! 296: static void smc_set_xcvr(struct net_device *dev, int if_port); ! 297: static void smc_reset(struct net_device *dev); ! 298: static void media_check(u_long arg); ! 299: static void mdio_sync(ioaddr_t addr); ! 300: static int mdio_read(struct net_device *dev, int phy_id, int loc); ! 301: static void mdio_write(struct net_device *dev, int phy_id, int loc, int value); ! 302: ! 303: /*====================================================================== ! 304: ! 305: This bit of code is used to avoid unregistering network devices ! 306: at inappropriate times. 2.2 and later kernels are fairly picky ! 307: about when this can happen. ! 308: ! 309: ======================================================================*/ ! 310: ! 311: static void flush_stale_links(void) ! 312: { ! 313: dev_link_t *link, *next; ! 314: for (link = dev_list; link; link = next) { ! 315: next = link->next; ! 316: if (link->state & DEV_STALE_LINK) ! 317: smc91c92_detach(link); ! 318: } ! 319: } ! 320: ! 321: /*====================================================================*/ ! 322: ! 323: static void cs_error(client_handle_t handle, int func, int ret) ! 324: { ! 325: error_info_t err = { func, ret }; ! 326: CardServices(ReportError, handle, &err); ! 327: } ! 328: ! 329: /*====================================================================== ! 330: ! 331: smc91c92_attach() creates an "instance" of the driver, allocating ! 332: local data structures for one device. The device is registered ! 333: with Card Services. ! 334: ! 335: ======================================================================*/ ! 336: ! 337: static dev_link_t *smc91c92_attach(void) ! 338: { ! 339: client_reg_t client_reg; ! 340: struct smc_private *smc; ! 341: dev_link_t *link; ! 342: struct net_device *dev; ! 343: int i, ret; ! 344: ! 345: DEBUG(0, "smc91c92_attach()\n"); ! 346: flush_stale_links(); ! 347: ! 348: /* Create new ethernet device */ ! 349: smc = kmalloc(sizeof(struct smc_private), GFP_KERNEL); ! 350: if (!smc) return NULL; ! 351: memset(smc, 0, sizeof(struct smc_private)); ! 352: link = &smc->link; dev = &smc->dev; ! 353: ! 354: init_timer(&link->release); ! 355: link->release.function = &smc91c92_release; ! 356: link->release.data = (u_long)link; ! 357: link->io.NumPorts1 = 16; ! 358: link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; ! 359: link->io.IOAddrLines = 4; ! 360: link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; ! 361: link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; ! 362: if (irq_list[0] == -1) ! 363: link->irq.IRQInfo2 = irq_mask; ! 364: else ! 365: for (i = 0; i < 4; i++) ! 366: link->irq.IRQInfo2 |= 1 << irq_list[i]; ! 367: link->irq.Handler = &smc_interrupt; ! 368: link->conf.Attributes = CONF_ENABLE_IRQ; ! 369: link->conf.Vcc = 50; ! 370: link->conf.IntType = INT_MEMORY_AND_IO; ! 371: ! 372: /* The SMC91c92-specific entries in the device structure. */ ! 373: dev->hard_start_xmit = &smc_start_xmit; ! 374: dev->get_stats = &smc_get_stats; ! 375: dev->set_config = &s9k_config; ! 376: dev->set_multicast_list = &set_rx_mode; ! 377: ether_setup(dev); ! 378: init_dev_name(dev, smc->node); ! 379: dev->open = &smc_open; ! 380: dev->stop = &smc_close; ! 381: dev->do_ioctl = &smc_ioctl; ! 382: #ifdef HAVE_TX_TIMEOUT ! 383: dev->tx_timeout = smc_tx_timeout; ! 384: dev->watchdog_timeo = TX_TIMEOUT; ! 385: #endif ! 386: dev->priv = link->priv = link->irq.Instance = smc; ! 387: ! 388: /* Register with Card Services */ ! 389: link->next = dev_list; ! 390: dev_list = link; ! 391: client_reg.dev_info = &dev_info; ! 392: client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; ! 393: client_reg.EventMask = CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | ! 394: CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | ! 395: CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; ! 396: client_reg.event_handler = &smc91c92_event; ! 397: client_reg.Version = 0x0210; ! 398: client_reg.event_callback_args.client_data = link; ! 399: ret = CardServices(RegisterClient, &link->handle, &client_reg); ! 400: if (ret != 0) { ! 401: cs_error(link->handle, RegisterClient, ret); ! 402: smc91c92_detach(link); ! 403: return NULL; ! 404: } ! 405: ! 406: return link; ! 407: } /* smc91c92_attach */ ! 408: ! 409: /*====================================================================== ! 410: ! 411: This deletes a driver "instance". The device is de-registered ! 412: with Card Services. If it has been released, all local data ! 413: structures are freed. Otherwise, the structures will be freed ! 414: when the device is released. ! 415: ! 416: ======================================================================*/ ! 417: ! 418: static void smc91c92_detach(dev_link_t *link) ! 419: { ! 420: struct smc_private *smc = link->priv; ! 421: dev_link_t **linkp; ! 422: ! 423: DEBUG(0, "smc91c92_detach(0x%p)\n", link); ! 424: ! 425: /* Locate device structure */ ! 426: for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) ! 427: if (*linkp == link) break; ! 428: if (*linkp == NULL) ! 429: return; ! 430: ! 431: del_timer(&link->release); ! 432: if (link->state & DEV_CONFIG) { ! 433: smc91c92_release((u_long)link); ! 434: if (link->state & DEV_STALE_CONFIG) { ! 435: link->state |= DEV_STALE_LINK; ! 436: return; ! 437: } ! 438: } ! 439: ! 440: if (link->handle) ! 441: CardServices(DeregisterClient, link->handle); ! 442: ! 443: /* Unlink device structure, free bits */ ! 444: *linkp = link->next; ! 445: if (link->dev) ! 446: unregister_netdev(&smc->dev); ! 447: kfree(smc); ! 448: ! 449: } /* smc91c92_detach */ ! 450: ! 451: /*====================================================================*/ ! 452: ! 453: static int cvt_ascii_address(struct net_device *dev, char *s) ! 454: { ! 455: int i, j, da, c; ! 456: ! 457: if (strlen(s) != 12) ! 458: return -1; ! 459: for (i = 0; i < 6; i++) { ! 460: da = 0; ! 461: for (j = 0; j < 2; j++) { ! 462: c = *s++; ! 463: da <<= 4; ! 464: da += ((c >= '0') && (c <= '9')) ? ! 465: (c - '0') : ((c & 0x0f) + 9); ! 466: } ! 467: dev->dev_addr[i] = da; ! 468: } ! 469: return 0; ! 470: } ! 471: ! 472: /*====================================================================*/ ! 473: ! 474: static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, ! 475: cisparse_t *parse) ! 476: { ! 477: int i; ! 478: i = CardServices(fn, handle, tuple); ! 479: if (i != CS_SUCCESS) return i; ! 480: i = CardServices(GetTupleData, handle, tuple); ! 481: if (i != CS_SUCCESS) return i; ! 482: return CardServices(ParseTuple, handle, tuple, parse); ! 483: } ! 484: ! 485: #define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c) ! 486: #define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c) ! 487: ! 488: /*====================================================================== ! 489: ! 490: Configuration stuff for Megahertz cards ! 491: ! 492: mhz_3288_power() is used to power up a 3288's ethernet chip. ! 493: mhz_mfc_config() handles socket setup for multifunction (1144 ! 494: and 3288) cards. mhz_setup() gets a card's hardware ethernet ! 495: address. ! 496: ! 497: ======================================================================*/ ! 498: ! 499: static int mhz_3288_power(dev_link_t *link) ! 500: { ! 501: struct smc_private *smc = link->priv; ! 502: u_char tmp; ! 503: ! 504: /* Read the ISR twice... */ ! 505: readb(smc->base+MEGAHERTZ_ISR); ! 506: udelay(5); ! 507: readb(smc->base+MEGAHERTZ_ISR); ! 508: ! 509: /* Pause 200ms... */ ! 510: mdelay(200); ! 511: ! 512: /* Now read and write the COR... */ ! 513: tmp = readb(smc->base + link->conf.ConfigBase + CISREG_COR); ! 514: udelay(5); ! 515: writeb(tmp, smc->base + link->conf.ConfigBase + CISREG_COR); ! 516: ! 517: return 0; ! 518: } ! 519: ! 520: static int mhz_mfc_config(dev_link_t *link) ! 521: { ! 522: struct smc_private *smc = link->priv; ! 523: struct net_device *dev = &smc->dev; ! 524: tuple_t tuple; ! 525: cisparse_t parse; ! 526: u_char buf[255]; ! 527: cistpl_cftable_entry_t *cf = &parse.cftable_entry; ! 528: win_req_t req; ! 529: memreq_t mem; ! 530: int i, k; ! 531: ! 532: link->conf.Attributes |= CONF_ENABLE_SPKR; ! 533: link->conf.Status = CCSR_AUDIO_ENA; ! 534: link->irq.Attributes = ! 535: IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT; ! 536: link->io.IOAddrLines = 16; ! 537: link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; ! 538: link->io.NumPorts2 = 8; ! 539: ! 540: tuple.Attributes = tuple.TupleOffset = 0; ! 541: tuple.TupleData = (cisdata_t *)buf; ! 542: tuple.TupleDataMax = sizeof(buf); ! 543: tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; ! 544: ! 545: i = first_tuple(link->handle, &tuple, &parse); ! 546: /* The Megahertz combo cards have modem-like CIS entries, so ! 547: we have to explicitly try a bunch of port combinations. */ ! 548: while (i == CS_SUCCESS) { ! 549: link->conf.ConfigIndex = cf->index; ! 550: link->io.BasePort2 = cf->io.win[0].base; ! 551: for (k = 0; k < 0x400; k += 0x10) { ! 552: if (k & 0x80) continue; ! 553: link->io.BasePort1 = k ^ 0x300; ! 554: i = CardServices(RequestIO, link->handle, &link->io); ! 555: if (i == CS_SUCCESS) break; ! 556: } ! 557: if (i == CS_SUCCESS) break; ! 558: i = next_tuple(link->handle, &tuple, &parse); ! 559: } ! 560: if (i != CS_SUCCESS) ! 561: return i; ! 562: dev->base_addr = link->io.BasePort1; ! 563: ! 564: /* Allocate a memory window, for accessing the ISR */ ! 565: req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; ! 566: req.Base = req.Size = 0; ! 567: req.AccessSpeed = 0; ! 568: link->win = (window_handle_t)link->handle; ! 569: i = CardServices(RequestWindow, &link->win, &req); ! 570: if (i != CS_SUCCESS) ! 571: return i; ! 572: smc->base = ioremap(req.Base, req.Size); ! 573: mem.CardOffset = mem.Page = 0; ! 574: if (smc->manfid == MANFID_MOTOROLA) ! 575: mem.CardOffset = link->conf.ConfigBase; ! 576: i = CardServices(MapMemPage, link->win, &mem); ! 577: ! 578: if ((i == CS_SUCCESS) ! 579: && (smc->manfid == MANFID_MEGAHERTZ) ! 580: && (smc->cardid == PRODID_MEGAHERTZ_EM3288)) ! 581: mhz_3288_power(link); ! 582: ! 583: return i; ! 584: } ! 585: ! 586: static int mhz_setup(dev_link_t *link) ! 587: { ! 588: client_handle_t handle = link->handle; ! 589: struct smc_private *smc = link->priv; ! 590: struct net_device *dev = &smc->dev; ! 591: tuple_t tuple; ! 592: cisparse_t parse; ! 593: u_char buf[255], *station_addr; ! 594: ! 595: tuple.Attributes = tuple.TupleOffset = 0; ! 596: tuple.TupleData = buf; ! 597: tuple.TupleDataMax = sizeof(buf); ! 598: ! 599: /* Read the station address from the CIS. It is stored as the last ! 600: (fourth) string in the Version 1 Version/ID tuple. */ ! 601: tuple.DesiredTuple = CISTPL_VERS_1; ! 602: if (first_tuple(handle, &tuple, &parse) != CS_SUCCESS) ! 603: return -1; ! 604: /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ ! 605: if (next_tuple(handle, &tuple, &parse) != CS_SUCCESS) ! 606: first_tuple(handle, &tuple, &parse); ! 607: if (parse.version_1.ns > 3) { ! 608: station_addr = parse.version_1.str + parse.version_1.ofs[3]; ! 609: if (cvt_ascii_address(dev, station_addr) == 0) ! 610: return 0; ! 611: } ! 612: ! 613: /* Another possibility: for the EM3288, in a special tuple */ ! 614: tuple.DesiredTuple = 0x81; ! 615: if (CardServices(GetFirstTuple, handle, &tuple) != CS_SUCCESS) ! 616: return -1; ! 617: if (CardServices(GetTupleData, handle, &tuple) != CS_SUCCESS) ! 618: return -1; ! 619: buf[12] = '\0'; ! 620: if (cvt_ascii_address(dev, buf) == 0) ! 621: return 0; ! 622: ! 623: return -1; ! 624: } ! 625: ! 626: /*====================================================================== ! 627: ! 628: Configuration stuff for the Motorola Mariner ! 629: ! 630: mot_config() writes directly to the Mariner configuration ! 631: registers because the CIS is just bogus. ! 632: ! 633: ======================================================================*/ ! 634: ! 635: static void mot_config(dev_link_t *link) ! 636: { ! 637: struct smc_private *smc = link->priv; ! 638: struct net_device *dev = &smc->dev; ! 639: ioaddr_t ioaddr = dev->base_addr; ! 640: ioaddr_t iouart = link->io.BasePort2; ! 641: ! 642: /* Set UART base address and force map with COR bit 1 */ ! 643: writeb(iouart & 0xff, smc->base + MOT_UART + CISREG_IOBASE_0); ! 644: writeb((iouart >> 8) & 0xff, smc->base + MOT_UART + CISREG_IOBASE_1); ! 645: writeb(MOT_NORMAL, smc->base + MOT_UART + CISREG_COR); ! 646: ! 647: /* Set SMC base address and force map with COR bit 1 */ ! 648: writeb(ioaddr & 0xff, smc->base + MOT_LAN + CISREG_IOBASE_0); ! 649: writeb((ioaddr >> 8) & 0xff, smc->base + MOT_LAN + CISREG_IOBASE_1); ! 650: writeb(MOT_NORMAL, smc->base + MOT_LAN + CISREG_COR); ! 651: ! 652: /* Wait for things to settle down */ ! 653: mdelay(100); ! 654: } ! 655: ! 656: static int mot_setup(dev_link_t *link) ! 657: { ! 658: struct smc_private *smc = link->priv; ! 659: struct net_device *dev = &smc->dev; ! 660: ioaddr_t ioaddr = dev->base_addr; ! 661: int i, wait, loop; ! 662: u_int addr; ! 663: ! 664: /* Read Ethernet address from Serial EEPROM */ ! 665: ! 666: for (i = 0; i < 3; i++) { ! 667: SMC_SELECT_BANK(2); ! 668: outw(MOT_EEPROM + i, ioaddr + POINTER); ! 669: SMC_SELECT_BANK(1); ! 670: outw((CTL_RELOAD | CTL_EE_SELECT), ioaddr + CONTROL); ! 671: ! 672: for (loop = wait = 0; loop < 200; loop++) { ! 673: udelay(10); ! 674: wait = ((CTL_RELOAD | CTL_STORE) & inw(ioaddr + CONTROL)); ! 675: if (wait == 0) break; ! 676: } ! 677: ! 678: if (wait) ! 679: return -1; ! 680: ! 681: addr = inw(ioaddr + GENERAL); ! 682: dev->dev_addr[2*i] = addr & 0xff; ! 683: dev->dev_addr[2*i+1] = (addr >> 8) & 0xff; ! 684: } ! 685: ! 686: return 0; ! 687: } ! 688: ! 689: /*====================================================================*/ ! 690: ! 691: static int smc_config(dev_link_t *link) ! 692: { ! 693: struct smc_private *smc = link->priv; ! 694: struct net_device *dev = &smc->dev; ! 695: tuple_t tuple; ! 696: cisparse_t parse; ! 697: u_char buf[255]; ! 698: cistpl_cftable_entry_t *cf = &parse.cftable_entry; ! 699: int i; ! 700: ! 701: tuple.Attributes = tuple.TupleOffset = 0; ! 702: tuple.TupleData = (cisdata_t *)buf; ! 703: tuple.TupleDataMax = sizeof(buf); ! 704: tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; ! 705: ! 706: link->io.NumPorts1 = 16; ! 707: i = first_tuple(link->handle, &tuple, &parse); ! 708: while (i != CS_NO_MORE_ITEMS) { ! 709: if (i == CS_SUCCESS) { ! 710: link->conf.ConfigIndex = cf->index; ! 711: link->io.BasePort1 = cf->io.win[0].base; ! 712: link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; ! 713: i = CardServices(RequestIO, link->handle, &link->io); ! 714: if (i == CS_SUCCESS) break; ! 715: } ! 716: i = next_tuple(link->handle, &tuple, &parse); ! 717: } ! 718: if (i == CS_SUCCESS) ! 719: dev->base_addr = link->io.BasePort1; ! 720: return i; ! 721: } ! 722: ! 723: static int smc_setup(dev_link_t *link) ! 724: { ! 725: client_handle_t handle = link->handle; ! 726: struct smc_private *smc = link->priv; ! 727: struct net_device *dev = &smc->dev; ! 728: tuple_t tuple; ! 729: cisparse_t parse; ! 730: cistpl_lan_node_id_t *node_id; ! 731: u_char buf[255], *station_addr; ! 732: int i; ! 733: ! 734: tuple.Attributes = tuple.TupleOffset = 0; ! 735: tuple.TupleData = buf; ! 736: tuple.TupleDataMax = sizeof(buf); ! 737: ! 738: /* Check for a LAN function extension tuple */ ! 739: tuple.DesiredTuple = CISTPL_FUNCE; ! 740: i = first_tuple(handle, &tuple, &parse); ! 741: while (i == CS_SUCCESS) { ! 742: if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID) ! 743: break; ! 744: i = next_tuple(handle, &tuple, &parse); ! 745: } ! 746: if (i == CS_SUCCESS) { ! 747: node_id = (cistpl_lan_node_id_t *)parse.funce.data; ! 748: if (node_id->nb == 6) { ! 749: for (i = 0; i < 6; i++) ! 750: dev->dev_addr[i] = node_id->id[i]; ! 751: return 0; ! 752: } ! 753: } ! 754: ! 755: /* Try the third string in the Version 1 Version/ID tuple. */ ! 756: tuple.DesiredTuple = CISTPL_VERS_1; ! 757: if (first_tuple(handle, &tuple, &parse) != CS_SUCCESS) ! 758: return -1; ! 759: station_addr = parse.version_1.str + parse.version_1.ofs[2]; ! 760: if (cvt_ascii_address(dev, station_addr) == 0) ! 761: return 0; ! 762: ! 763: return -1; ! 764: } ! 765: ! 766: /*====================================================================*/ ! 767: ! 768: static int osi_config(dev_link_t *link) ! 769: { ! 770: struct smc_private *smc = link->priv; ! 771: struct net_device *dev = &smc->dev; ! 772: static ioaddr_t com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; ! 773: int i, j; ! 774: ! 775: link->conf.Attributes |= CONF_ENABLE_SPKR; ! 776: link->conf.Status = CCSR_AUDIO_ENA; ! 777: link->irq.Attributes = ! 778: IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT; ! 779: link->io.NumPorts1 = 64; ! 780: link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; ! 781: link->io.NumPorts2 = 8; ! 782: link->io.IOAddrLines = 16; ! 783: ! 784: /* Enable Hard Decode, LAN, Modem */ ! 785: link->conf.ConfigIndex = 0x23; ! 786: ! 787: for (i = j = 0; j < 4; j++) { ! 788: link->io.BasePort2 = com[j]; ! 789: i = CardServices(RequestIO, link->handle, &link->io); ! 790: if (i == CS_SUCCESS) break; ! 791: } ! 792: if (i != CS_SUCCESS) { ! 793: /* Fallback: turn off hard decode */ ! 794: link->conf.ConfigIndex = 0x03; ! 795: link->io.NumPorts2 = 0; ! 796: i = CardServices(RequestIO, link->handle, &link->io); ! 797: } ! 798: dev->base_addr = link->io.BasePort1 + 0x10; ! 799: return i; ! 800: } ! 801: ! 802: static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid) ! 803: { ! 804: client_handle_t handle = link->handle; ! 805: struct smc_private *smc = link->priv; ! 806: struct net_device *dev = &smc->dev; ! 807: tuple_t tuple; ! 808: u_char buf[255]; ! 809: int i; ! 810: ! 811: tuple.Attributes = TUPLE_RETURN_COMMON; ! 812: tuple.TupleData = buf; ! 813: tuple.TupleDataMax = sizeof(buf); ! 814: tuple.TupleOffset = 0; ! 815: ! 816: /* Read the station address from tuple 0x90, subtuple 0x04 */ ! 817: tuple.DesiredTuple = 0x90; ! 818: i = CardServices(GetFirstTuple, handle, &tuple); ! 819: while (i == CS_SUCCESS) { ! 820: i = CardServices(GetTupleData, handle, &tuple); ! 821: if ((i != CS_SUCCESS) || (buf[0] == 0x04)) ! 822: break; ! 823: i = CardServices(GetNextTuple, handle, &tuple); ! 824: } ! 825: if (i != CS_SUCCESS) ! 826: return -1; ! 827: for (i = 0; i < 6; i++) ! 828: dev->dev_addr[i] = buf[i+2]; ! 829: ! 830: if (((manfid == MANFID_OSITECH) && ! 831: (cardid == PRODID_OSITECH_SEVEN)) || ! 832: ((manfid == MANFID_PSION) && ! 833: (cardid == PRODID_PSION_NET100))) { ! 834: /* Download the Seven of Diamonds firmware */ ! 835: for (i = 0; i < sizeof(__Xilinx7OD); i++) { ! 836: outb(__Xilinx7OD[i], link->io.BasePort1+2); ! 837: udelay(50); ! 838: } ! 839: } else if (manfid == MANFID_OSITECH) { ! 840: /* Make sure both functions are powered up */ ! 841: set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR); ! 842: /* Now, turn on the interrupt for both card functions */ ! 843: set_bits(0x300, link->io.BasePort1 + OSITECH_RESET_ISR); ! 844: DEBUG(2, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n", ! 845: inw(link->io.BasePort1 + OSITECH_AUI_PWR), ! 846: inw(link->io.BasePort1 + OSITECH_RESET_ISR)); ! 847: } ! 848: ! 849: return 0; ! 850: } ! 851: ! 852: /*====================================================================== ! 853: ! 854: This verifies that the chip is some SMC91cXX variant, and returns ! 855: the revision code if successful. Otherwise, it returns -ENODEV. ! 856: ! 857: ======================================================================*/ ! 858: ! 859: static int check_sig(dev_link_t *link) ! 860: { ! 861: struct smc_private *smc = link->priv; ! 862: struct net_device *dev = &smc->dev; ! 863: ioaddr_t ioaddr = dev->base_addr; ! 864: int width; ! 865: u_short s; ! 866: ! 867: SMC_SELECT_BANK(1); ! 868: if (inw(ioaddr + BANK_SELECT) >> 8 != 0x33) { ! 869: /* Try powering up the chip */ ! 870: outw(0, ioaddr + CONTROL); ! 871: mdelay(55); ! 872: } ! 873: ! 874: /* Try setting bus width */ ! 875: width = (link->io.Attributes1 == IO_DATA_PATH_WIDTH_AUTO); ! 876: s = inb(ioaddr + CONFIG); ! 877: if (width) ! 878: s |= CFG_16BIT; ! 879: else ! 880: s &= ~CFG_16BIT; ! 881: outb(s, ioaddr + CONFIG); ! 882: ! 883: /* Check Base Address Register to make sure bus width is OK */ ! 884: s = inw(ioaddr + BASE_ADDR); ! 885: if ((inw(ioaddr + BANK_SELECT) >> 8 == 0x33) && ! 886: ((s >> 8) != (s & 0xff))) { ! 887: SMC_SELECT_BANK(3); ! 888: s = inw(ioaddr + REVISION); ! 889: return (s & 0xff); ! 890: } ! 891: ! 892: if (width) { ! 893: event_callback_args_t args; ! 894: printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); ! 895: args.client_data = link; ! 896: smc91c92_event(CS_EVENT_RESET_PHYSICAL, 0, &args); ! 897: CardServices(ReleaseIO, link->handle, &link->io); ! 898: link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; ! 899: CardServices(RequestIO, link->handle, &link->io); ! 900: smc91c92_event(CS_EVENT_CARD_RESET, 0, &args); ! 901: return check_sig(link); ! 902: } ! 903: return -ENODEV; ! 904: } ! 905: ! 906: /*====================================================================== ! 907: ! 908: smc91c92_config() is scheduled to run after a CARD_INSERTION event ! 909: is received, to configure the PCMCIA socket, and to make the ! 910: ethernet device available to the system. ! 911: ! 912: ======================================================================*/ ! 913: ! 914: #define CS_EXIT_TEST(ret, svc, label) \ ! 915: if (ret != CS_SUCCESS) { cs_error(link->handle, svc, ret); goto label; } ! 916: ! 917: static void smc91c92_config(dev_link_t *link) ! 918: { ! 919: client_handle_t handle = link->handle; ! 920: struct smc_private *smc = link->priv; ! 921: struct net_device *dev = &smc->dev; ! 922: tuple_t tuple; ! 923: cisparse_t parse; ! 924: u_short buf[32]; ! 925: char *name; ! 926: int i, j, rev; ! 927: ioaddr_t ioaddr; ! 928: ! 929: DEBUG(0, "smc91c92_config(0x%p)\n", link); ! 930: ! 931: tuple.Attributes = tuple.TupleOffset = 0; ! 932: tuple.TupleData = (cisdata_t *)buf; ! 933: tuple.TupleDataMax = sizeof(buf); ! 934: ! 935: tuple.DesiredTuple = CISTPL_CONFIG; ! 936: i = first_tuple(handle, &tuple, &parse); ! 937: CS_EXIT_TEST(i, ParseTuple, config_failed); ! 938: link->conf.ConfigBase = parse.config.base; ! 939: link->conf.Present = parse.config.rmask[0]; ! 940: ! 941: tuple.DesiredTuple = CISTPL_MANFID; ! 942: tuple.Attributes = TUPLE_RETURN_COMMON; ! 943: if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) { ! 944: smc->manfid = parse.manfid.manf; ! 945: smc->cardid = parse.manfid.card; ! 946: } ! 947: ! 948: /* Configure card */ ! 949: link->state |= DEV_CONFIG; ! 950: ! 951: if ((smc->manfid == MANFID_OSITECH) && ! 952: (smc->cardid != PRODID_OSITECH_SEVEN)) { ! 953: i = osi_config(link); ! 954: } else if ((smc->manfid == MANFID_MOTOROLA) || ! 955: ((smc->manfid == MANFID_MEGAHERTZ) && ! 956: ((smc->cardid == PRODID_MEGAHERTZ_VARIOUS) || ! 957: (smc->cardid == PRODID_MEGAHERTZ_EM3288)))) { ! 958: i = mhz_mfc_config(link); ! 959: } else { ! 960: i = smc_config(link); ! 961: } ! 962: CS_EXIT_TEST(i, RequestIO, config_failed); ! 963: ! 964: i = CardServices(RequestIRQ, link->handle, &link->irq); ! 965: CS_EXIT_TEST(i, RequestIRQ, config_failed); ! 966: i = CardServices(RequestConfiguration, link->handle, &link->conf); ! 967: CS_EXIT_TEST(i, RequestConfiguration, config_failed); ! 968: ! 969: if (smc->manfid == MANFID_MOTOROLA) ! 970: mot_config(link); ! 971: ! 972: dev->irq = link->irq.AssignedIRQ; ! 973: ! 974: if ((if_port >= 0) && (if_port <= 2)) ! 975: dev->if_port = if_port; ! 976: else ! 977: printk(KERN_NOTICE "smc91c92_cs: invalid if_port requested\n"); ! 978: ! 979: if (register_netdev(dev) != 0) { ! 980: printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n"); ! 981: goto config_undo; ! 982: } ! 983: ! 984: switch (smc->manfid) { ! 985: case MANFID_OSITECH: ! 986: case MANFID_PSION: ! 987: i = osi_setup(link, smc->manfid, smc->cardid); break; ! 988: case MANFID_SMC: ! 989: case MANFID_NEW_MEDIA: ! 990: i = smc_setup(link); break; ! 991: case 0x128: /* For broken Megahertz cards */ ! 992: case MANFID_MEGAHERTZ: ! 993: i = mhz_setup(link); break; ! 994: case MANFID_MOTOROLA: ! 995: default: /* get the hw address from EEPROM */ ! 996: i = mot_setup(link); break; ! 997: } ! 998: ! 999: if (i != 0) { ! 1000: printk(KERN_NOTICE "smc91c92_cs: Unable to find hardware address.\n"); ! 1001: goto config_undo; ! 1002: } ! 1003: ! 1004: copy_dev_name(smc->node, dev); ! 1005: link->dev = &smc->node; ! 1006: smc->duplex = 0; ! 1007: smc->rx_ovrn = 0; ! 1008: ! 1009: rev = check_sig(link); ! 1010: name = "???"; ! 1011: if (rev > 0) ! 1012: switch (rev >> 4) { ! 1013: case 3: name = "92"; break; ! 1014: case 4: name = ((rev & 15) >= 6) ? "96" : "94"; break; ! 1015: case 5: name = "95"; break; ! 1016: case 7: name = "100"; break; ! 1017: case 8: name = "100-FD"; break; ! 1018: case 9: name = "110"; break; ! 1019: } ! 1020: printk(KERN_INFO "%s: smc91c%s rev %d: io %#3lx, irq %d, " ! 1021: "hw_addr ", dev->name, name, (rev & 0x0f), dev->base_addr, ! 1022: dev->irq); ! 1023: for (i = 0; i < 6; i++) ! 1024: printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); ! 1025: ! 1026: ioaddr = dev->base_addr; ! 1027: if (rev > 0) { ! 1028: u_long mir, mcr; ! 1029: SMC_SELECT_BANK(0); ! 1030: mir = inw(ioaddr + MEMINFO) & 0xff; ! 1031: if (mir == 0xff) mir++; ! 1032: /* Get scale factor for memory size */ ! 1033: mcr = ((rev >> 4) > 3) ? inw(ioaddr + MEMCFG) : 0x0200; ! 1034: mir *= 128 * (1<<((mcr >> 9) & 7)); ! 1035: if (mir & 0x3ff) ! 1036: printk(KERN_INFO " %lu byte", mir); ! 1037: else ! 1038: printk(KERN_INFO " %lu kb", mir>>10); ! 1039: SMC_SELECT_BANK(1); ! 1040: smc->cfg = inw(ioaddr + CONFIG) & ~CFG_AUI_SELECT; ! 1041: smc->cfg |= CFG_NO_WAIT | CFG_16BIT | CFG_STATIC; ! 1042: if (smc->manfid == MANFID_OSITECH) ! 1043: smc->cfg |= CFG_IRQ_SEL_1 | CFG_IRQ_SEL_0; ! 1044: if ((rev >> 4) >= 7) ! 1045: smc->cfg |= CFG_MII_SELECT; ! 1046: printk(" buffer, %s xcvr\n", (smc->cfg & CFG_MII_SELECT) ? ! 1047: "MII" : if_names[dev->if_port]); ! 1048: } ! 1049: ! 1050: if (smc->cfg & CFG_MII_SELECT) { ! 1051: SMC_SELECT_BANK(3); ! 1052: ! 1053: for (i = 0; i < 32; i++) { ! 1054: j = mdio_read(dev, i, 1); ! 1055: if ((j != 0) && (j != 0xffff)) break; ! 1056: } ! 1057: smc->phy_id = (i < 32) ? i : -1; ! 1058: if (i < 32) { ! 1059: DEBUG(0, " MII transceiver at index %d, status %x.\n", i, j); ! 1060: } else { ! 1061: printk(KERN_NOTICE " No MII transceivers found!\n"); ! 1062: } ! 1063: ! 1064: SMC_SELECT_BANK(0); ! 1065: } ! 1066: ! 1067: link->state &= ~DEV_CONFIG_PENDING; ! 1068: return; ! 1069: ! 1070: config_undo: ! 1071: unregister_netdev(dev); ! 1072: config_failed: /* CS_EXIT_TEST() calls jump to here... */ ! 1073: smc91c92_release((u_long)link); ! 1074: link->state &= ~DEV_CONFIG_PENDING; ! 1075: ! 1076: } /* smc91c92_config */ ! 1077: ! 1078: /*====================================================================== ! 1079: ! 1080: After a card is removed, smc91c92_release() will unregister the net ! 1081: device, and release the PCMCIA configuration. If the device is ! 1082: still open, this will be postponed until it is closed. ! 1083: ! 1084: ======================================================================*/ ! 1085: ! 1086: static void smc91c92_release(u_long arg) ! 1087: { ! 1088: dev_link_t *link = (dev_link_t *)arg; ! 1089: struct smc_private *smc = link->priv; ! 1090: ! 1091: DEBUG(0, "smc91c92_release(0x%p)\n", link); ! 1092: ! 1093: if (link->open) { ! 1094: DEBUG(1, "smc91c92_cs: release postponed, '%s' still open\n", ! 1095: link->dev->dev_name); ! 1096: link->state |= DEV_STALE_CONFIG; ! 1097: return; ! 1098: } ! 1099: ! 1100: CardServices(ReleaseConfiguration, link->handle); ! 1101: CardServices(ReleaseIO, link->handle, &link->io); ! 1102: CardServices(ReleaseIRQ, link->handle, &link->irq); ! 1103: if (link->win) { ! 1104: iounmap(smc->base); ! 1105: CardServices(ReleaseWindow, link->win); ! 1106: } ! 1107: ! 1108: link->state &= ~DEV_CONFIG; ! 1109: ! 1110: } /* smc91c92_release */ ! 1111: ! 1112: /*====================================================================== ! 1113: ! 1114: The card status event handler. Mostly, this schedules other ! 1115: stuff to run after an event is received. A CARD_REMOVAL event ! 1116: also sets some flags to discourage the net drivers from trying ! 1117: to talk to the card any more. ! 1118: ! 1119: ======================================================================*/ ! 1120: ! 1121: static int smc91c92_event(event_t event, int priority, ! 1122: event_callback_args_t *args) ! 1123: { ! 1124: dev_link_t *link = args->client_data; ! 1125: struct smc_private *smc = link->priv; ! 1126: struct net_device *dev = &smc->dev; ! 1127: int i; ! 1128: ! 1129: DEBUG(1, "smc91c92_event(0x%06x)\n", event); ! 1130: ! 1131: switch (event) { ! 1132: case CS_EVENT_CARD_REMOVAL: ! 1133: link->state &= ~DEV_PRESENT; ! 1134: if (link->state & DEV_CONFIG) { ! 1135: netif_device_detach(dev); ! 1136: mod_timer(&link->release, jiffies + HZ/20); ! 1137: } ! 1138: break; ! 1139: case CS_EVENT_CARD_INSERTION: ! 1140: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; ! 1141: smc91c92_config(link); ! 1142: break; ! 1143: case CS_EVENT_PM_SUSPEND: ! 1144: link->state |= DEV_SUSPEND; ! 1145: /* Fall through... */ ! 1146: case CS_EVENT_RESET_PHYSICAL: ! 1147: if (link->state & DEV_CONFIG) { ! 1148: if (link->open) ! 1149: netif_device_detach(dev); ! 1150: CardServices(ReleaseConfiguration, link->handle); ! 1151: } ! 1152: break; ! 1153: case CS_EVENT_PM_RESUME: ! 1154: link->state &= ~DEV_SUSPEND; ! 1155: /* Fall through... */ ! 1156: case CS_EVENT_CARD_RESET: ! 1157: if (link->state & DEV_CONFIG) { ! 1158: if ((smc->manfid == MANFID_MEGAHERTZ) && ! 1159: (smc->cardid == PRODID_MEGAHERTZ_EM3288)) ! 1160: mhz_3288_power(link); ! 1161: CardServices(RequestConfiguration, link->handle, &link->conf); ! 1162: if (smc->manfid == MANFID_MOTOROLA) ! 1163: mot_config(link); ! 1164: if ((smc->manfid == MANFID_OSITECH) && ! 1165: (smc->cardid != PRODID_OSITECH_SEVEN)) { ! 1166: /* Power up the card and enable interrupts */ ! 1167: set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR); ! 1168: set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR); ! 1169: } ! 1170: if (((smc->manfid == MANFID_OSITECH) && ! 1171: (smc->cardid == PRODID_OSITECH_SEVEN)) || ! 1172: ((smc->manfid == MANFID_PSION) && ! 1173: (smc->cardid == PRODID_PSION_NET100))) { ! 1174: /* Download the Seven of Diamonds firmware */ ! 1175: for (i = 0; i < sizeof(__Xilinx7OD); i++) { ! 1176: outb(__Xilinx7OD[i], link->io.BasePort1+2); ! 1177: udelay(50); ! 1178: } ! 1179: } ! 1180: if (link->open) { ! 1181: smc_reset(dev); ! 1182: netif_device_attach(dev); ! 1183: } ! 1184: } ! 1185: break; ! 1186: } ! 1187: return 0; ! 1188: } /* smc91c92_event */ ! 1189: ! 1190: /*====================================================================== ! 1191: ! 1192: MII interface support for SMC91cXX based cards ! 1193: ======================================================================*/ ! 1194: ! 1195: #define MDIO_SHIFT_CLK 0x04 ! 1196: #define MDIO_DATA_OUT 0x01 ! 1197: #define MDIO_DIR_WRITE 0x08 ! 1198: #define MDIO_DATA_WRITE0 (MDIO_DIR_WRITE) ! 1199: #define MDIO_DATA_WRITE1 (MDIO_DIR_WRITE | MDIO_DATA_OUT) ! 1200: #define MDIO_DATA_READ 0x02 ! 1201: ! 1202: static void mdio_sync(ioaddr_t addr) ! 1203: { ! 1204: int bits; ! 1205: for (bits = 0; bits < 32; bits++) { ! 1206: outb(MDIO_DATA_WRITE1, addr); ! 1207: outb(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, addr); ! 1208: } ! 1209: } ! 1210: ! 1211: static int mdio_read(struct net_device *dev, int phy_id, int loc) ! 1212: { ! 1213: ioaddr_t addr = dev->base_addr + MGMT; ! 1214: u_int cmd = (0x06<<10)|(phy_id<<5)|loc; ! 1215: int i, retval = 0; ! 1216: ! 1217: mdio_sync(addr); ! 1218: for (i = 13; i >= 0; i--) { ! 1219: int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0; ! 1220: outb(dat, addr); ! 1221: outb(dat | MDIO_SHIFT_CLK, addr); ! 1222: } ! 1223: for (i = 19; i > 0; i--) { ! 1224: outb(0, addr); ! 1225: retval = (retval << 1) | ((inb(addr) & MDIO_DATA_READ) != 0); ! 1226: outb(MDIO_SHIFT_CLK, addr); ! 1227: } ! 1228: return (retval>>1) & 0xffff; ! 1229: } ! 1230: ! 1231: static void mdio_write(struct net_device *dev, int phy_id, int loc, int value) ! 1232: { ! 1233: ioaddr_t addr = dev->base_addr + MGMT; ! 1234: u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value; ! 1235: int i; ! 1236: ! 1237: mdio_sync(addr); ! 1238: for (i = 31; i >= 0; i--) { ! 1239: int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0; ! 1240: outb(dat, addr); ! 1241: outb(dat | MDIO_SHIFT_CLK, addr); ! 1242: } ! 1243: for (i = 1; i >= 0; i--) { ! 1244: outb(0, addr); ! 1245: outb(MDIO_SHIFT_CLK, addr); ! 1246: } ! 1247: } ! 1248: ! 1249: /*====================================================================== ! 1250: ! 1251: The driver core code, most of which should be common with a ! 1252: non-PCMCIA implementation. ! 1253: ! 1254: ======================================================================*/ ! 1255: ! 1256: #ifdef PCMCIA_DEBUG ! 1257: static void smc_dump(struct net_device *dev) ! 1258: { ! 1259: ioaddr_t ioaddr = dev->base_addr; ! 1260: u_short i, w, save; ! 1261: save = inw(ioaddr + BANK_SELECT); ! 1262: for (w = 0; w < 4; w++) { ! 1263: SMC_SELECT_BANK(w); ! 1264: printk(KERN_DEBUG "bank %d: ", w); ! 1265: for (i = 0; i < 14; i += 2) ! 1266: printk(" %04x", inw(ioaddr + i)); ! 1267: printk("\n"); ! 1268: } ! 1269: outw(save, ioaddr + BANK_SELECT); ! 1270: } ! 1271: #endif ! 1272: ! 1273: static int smc_open(struct net_device *dev) ! 1274: { ! 1275: struct smc_private *smc = dev->priv; ! 1276: dev_link_t *link = &smc->link; ! 1277: ! 1278: #ifdef PCMCIA_DEBUG ! 1279: DEBUG(0, "%s: smc_open(%p), ID/Window %4.4x.\n", ! 1280: dev->name, dev, inw(dev->base_addr + BANK_SELECT)); ! 1281: if (pc_debug > 1) smc_dump(dev); ! 1282: #endif ! 1283: ! 1284: /* Check that the PCMCIA card is still here. */ ! 1285: if (!DEV_OK(link)) ! 1286: return -ENODEV; ! 1287: /* Physical device present signature. */ ! 1288: if (check_sig(link) < 0) { ! 1289: printk("smc91c92_cs: Yikes! Bad chip signature!\n"); ! 1290: return -ENODEV; ! 1291: } ! 1292: link->open++; ! 1293: MOD_INC_USE_COUNT; ! 1294: ! 1295: netif_start_queue(dev); ! 1296: netif_mark_up(dev); ! 1297: smc->saved_skb = 0; ! 1298: smc->packets_waiting = 0; ! 1299: ! 1300: smc_reset(dev); ! 1301: smc->media.function = &media_check; ! 1302: smc->media.data = (u_long)smc; ! 1303: smc->media.expires = jiffies + HZ; ! 1304: add_timer(&smc->media); ! 1305: ! 1306: return 0; ! 1307: } /* smc_open */ ! 1308: ! 1309: /*====================================================================*/ ! 1310: ! 1311: static int smc_close(struct net_device *dev) ! 1312: { ! 1313: struct smc_private *smc = dev->priv; ! 1314: dev_link_t *link = &smc->link; ! 1315: ioaddr_t ioaddr = dev->base_addr; ! 1316: ! 1317: DEBUG(0, "%s: smc_close(), status %4.4x.\n", ! 1318: dev->name, inw(ioaddr + BANK_SELECT)); ! 1319: ! 1320: netif_stop_queue(dev); ! 1321: netif_mark_down(dev); ! 1322: ! 1323: /* Shut off all interrupts, and turn off the Tx and Rx sections. ! 1324: Don't bother to check for chip present. */ ! 1325: SMC_SELECT_BANK(2); /* Nominally paranoia, but do no assume... */ ! 1326: outw(0, ioaddr + INTERRUPT); ! 1327: SMC_SELECT_BANK(0); ! 1328: mask_bits(0xff00, ioaddr + RCR); ! 1329: mask_bits(0xff00, ioaddr + TCR); ! 1330: ! 1331: /* Put the chip into power-down mode. */ ! 1332: SMC_SELECT_BANK(1); ! 1333: outw(CTL_POWERDOWN, ioaddr + CONTROL ); ! 1334: ! 1335: link->open--; ! 1336: del_timer(&smc->media); ! 1337: if (link->state & DEV_STALE_CONFIG) ! 1338: mod_timer(&link->release, jiffies + HZ/20); ! 1339: ! 1340: MOD_DEC_USE_COUNT; ! 1341: ! 1342: return 0; ! 1343: } /* smc_close */ ! 1344: ! 1345: static int smc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ! 1346: { ! 1347: struct smc_private *smc = dev->priv; ! 1348: u16 *data = (u16 *)&rq->ifr_data; ! 1349: ushort saved_bank; ! 1350: ioaddr_t ioaddr = dev->base_addr; ! 1351: ! 1352: if (!(smc->cfg & CFG_MII_SELECT)) ! 1353: return -EOPNOTSUPP; ! 1354: ! 1355: saved_bank = inw(ioaddr + BANK_SELECT); ! 1356: SMC_SELECT_BANK(3); ! 1357: ! 1358: switch (cmd) { ! 1359: case SIOCDEVPRIVATE: ! 1360: data[0] = smc->phy_id; ! 1361: case SIOCDEVPRIVATE+1: ! 1362: data[3] = mdio_read(dev, data[0], data[1] & 0x1f); ! 1363: SMC_SELECT_BANK(saved_bank); ! 1364: return 0; ! 1365: case SIOCDEVPRIVATE+2: ! 1366: if (!capable(CAP_NET_ADMIN)) { ! 1367: SMC_SELECT_BANK(saved_bank); ! 1368: return -EPERM; ! 1369: } ! 1370: mdio_write(dev, data[0], data[1] & 0x1f, data[2]); ! 1371: SMC_SELECT_BANK(saved_bank); ! 1372: return 0; ! 1373: } ! 1374: SMC_SELECT_BANK(saved_bank); ! 1375: return -EOPNOTSUPP; ! 1376: } ! 1377: /*====================================================================== ! 1378: ! 1379: Transfer a packet to the hardware and trigger the packet send. ! 1380: This may be called at either from either the Tx queue code ! 1381: or the interrupt handler. ! 1382: ! 1383: ======================================================================*/ ! 1384: ! 1385: static void smc_hardware_send_packet(struct net_device * dev) ! 1386: { ! 1387: struct smc_private *smc = dev->priv; ! 1388: struct sk_buff *skb = smc->saved_skb; ! 1389: ioaddr_t ioaddr = dev->base_addr; ! 1390: u_char packet_no; ! 1391: ! 1392: if (!skb) { ! 1393: printk(KERN_ERR "%s: In XMIT with no packet to send.\n", dev->name); ! 1394: return; ! 1395: } ! 1396: ! 1397: /* There should be a packet slot waiting. */ ! 1398: packet_no = inw(ioaddr + PNR_ARR) >> 8; ! 1399: if (packet_no & 0x80) { ! 1400: /* If not, there is a hardware problem! Likely an ejected card. */ ! 1401: printk(KERN_WARNING "%s: 91c92 hardware Tx buffer allocation" ! 1402: " failed, status %#2.2x.\n", dev->name, packet_no); ! 1403: dev_kfree_skb_irq(skb); ! 1404: smc->saved_skb = NULL; ! 1405: netif_start_queue(dev); ! 1406: return; ! 1407: } ! 1408: ! 1409: add_tx_bytes(&smc->stats, skb->len); ! 1410: /* The card should use the just-allocated buffer. */ ! 1411: outw(packet_no, ioaddr + PNR_ARR); ! 1412: /* point to the beginning of the packet */ ! 1413: outw(PTR_AUTOINC , ioaddr + POINTER); ! 1414: ! 1415: /* Send the packet length (+6 for status, length and ctl byte) ! 1416: and the status word (set to zeros). */ ! 1417: { ! 1418: u_char *buf = skb->data; ! 1419: u_int length = skb->len; /* The chip will pad to ethernet min. */ ! 1420: ! 1421: DEBUG(2, "%s: Trying to xmit packet of length %d.\n", ! 1422: dev->name, length); ! 1423: ! 1424: /* send the packet length: +6 for status word, length, and ctl */ ! 1425: outw(0, ioaddr + DATA_1); ! 1426: outw(length + 6, ioaddr + DATA_1); ! 1427: outsw(ioaddr + DATA_1, buf, length >> 1); ! 1428: ! 1429: /* The odd last byte, if there is one, goes in the control word. */ ! 1430: outw((length & 1) ? 0x2000 | buf[length-1] : 0, ioaddr + DATA_1); ! 1431: } ! 1432: ! 1433: /* Enable the Tx interrupts, both Tx (TxErr) and TxEmpty. */ ! 1434: outw(((IM_TX_INT|IM_TX_EMPTY_INT)<<8) | ! 1435: (inw(ioaddr + INTERRUPT) & 0xff00), ! 1436: ioaddr + INTERRUPT); ! 1437: ! 1438: /* The chip does the rest of the work. */ ! 1439: outw(MC_ENQUEUE , ioaddr + MMU_CMD); ! 1440: ! 1441: smc->saved_skb = NULL; ! 1442: dev_kfree_skb_irq(skb); ! 1443: dev->trans_start = jiffies; ! 1444: netif_start_queue(dev); ! 1445: return; ! 1446: } ! 1447: ! 1448: /*====================================================================*/ ! 1449: ! 1450: static void smc_tx_timeout(struct net_device *dev) ! 1451: { ! 1452: struct smc_private *smc = dev->priv; ! 1453: ioaddr_t ioaddr = dev->base_addr; ! 1454: ! 1455: printk(KERN_NOTICE "%s: SMC91c92 transmit timed out, " ! 1456: "Tx_status %2.2x status %4.4x.\n", ! 1457: dev->name, inw(ioaddr)&0xff, inw(ioaddr + 2)); ! 1458: smc->stats.tx_errors++; ! 1459: smc_reset(dev); ! 1460: dev->trans_start = jiffies; ! 1461: smc->saved_skb = NULL; ! 1462: netif_wake_queue(dev); ! 1463: } ! 1464: ! 1465: static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) ! 1466: { ! 1467: struct smc_private *smc = dev->priv; ! 1468: ioaddr_t ioaddr = dev->base_addr; ! 1469: u_short num_pages; ! 1470: short time_out, ir; ! 1471: ! 1472: tx_timeout_check(dev, smc_tx_timeout); ! 1473: skb_tx_check(dev, skb); ! 1474: ! 1475: DEBUG(2, "%s: smc_start_xmit(length = %ld) called," ! 1476: " status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2)); ! 1477: ! 1478: if (smc->saved_skb) { ! 1479: /* THIS SHOULD NEVER HAPPEN. */ ! 1480: smc->stats.tx_aborted_errors++; ! 1481: printk(KERN_DEBUG "%s: Internal error -- sent packet while busy.\n", ! 1482: dev->name); ! 1483: return 1; ! 1484: } ! 1485: smc->saved_skb = skb; ! 1486: ! 1487: num_pages = skb->len >> 8; ! 1488: ! 1489: if (num_pages > 7) { ! 1490: printk(KERN_ERR "%s: Far too big packet error.\n", dev->name); ! 1491: DEV_KFREE_SKB (skb); ! 1492: smc->saved_skb = NULL; ! 1493: smc->stats.tx_dropped++; ! 1494: return 0; /* Do not re-queue this packet. */ ! 1495: } ! 1496: /* A packet is now waiting. */ ! 1497: smc->packets_waiting++; ! 1498: ! 1499: SMC_SELECT_BANK(2); /* Paranoia, we should always be in window 2 */ ! 1500: ! 1501: /* need MC_RESET to keep the memory consistent. errata? */ ! 1502: if (smc->rx_ovrn) { ! 1503: outw(MC_RESET, ioaddr + MMU_CMD); ! 1504: smc->rx_ovrn = 0; ! 1505: } ! 1506: ! 1507: /* Allocate the memory; send the packet now if we win. */ ! 1508: outw(MC_ALLOC | num_pages, ioaddr + MMU_CMD); ! 1509: for (time_out = MEMORY_WAIT_TIME; time_out >= 0; time_out--) { ! 1510: ir = inw(ioaddr+INTERRUPT); ! 1511: if (ir & IM_ALLOC_INT) { ! 1512: /* Acknowledge the interrupt, send the packet. */ ! 1513: outw((ir&0xff00) | IM_ALLOC_INT, ioaddr + INTERRUPT); ! 1514: smc_hardware_send_packet(dev); /* Send the packet now.. */ ! 1515: return 0; ! 1516: } ! 1517: } ! 1518: ! 1519: /* Otherwise defer until the Tx-space-allocated interrupt. */ ! 1520: DEBUG(2, "%s: memory allocation deferred.\n", dev->name); ! 1521: outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT); ! 1522: ! 1523: return 0; ! 1524: } ! 1525: ! 1526: /*====================================================================== ! 1527: ! 1528: Handle a Tx anomolous event. Entered while in Window 2. ! 1529: ! 1530: ======================================================================*/ ! 1531: ! 1532: static void smc_tx_err(struct net_device * dev) ! 1533: { ! 1534: struct smc_private *smc = (struct smc_private *)dev->priv; ! 1535: ioaddr_t ioaddr = dev->base_addr; ! 1536: int saved_packet = inw(ioaddr + PNR_ARR) & 0xff; ! 1537: int packet_no = inw(ioaddr + FIFO_PORTS) & 0x7f; ! 1538: int tx_status; ! 1539: ! 1540: /* select this as the packet to read from */ ! 1541: outw(packet_no, ioaddr + PNR_ARR); ! 1542: ! 1543: /* read the first word from this packet */ ! 1544: outw(PTR_AUTOINC | PTR_READ | 0, ioaddr + POINTER); ! 1545: ! 1546: tx_status = inw(ioaddr + DATA_1); ! 1547: ! 1548: smc->stats.tx_errors++; ! 1549: if (tx_status & TS_LOSTCAR) smc->stats.tx_carrier_errors++; ! 1550: if (tx_status & TS_LATCOL) smc->stats.tx_window_errors++; ! 1551: if (tx_status & TS_16COL) { ! 1552: smc->stats.tx_aborted_errors++; ! 1553: smc->tx_err++; ! 1554: } ! 1555: ! 1556: if (tx_status & TS_SUCCESS) { ! 1557: printk(KERN_NOTICE "%s: Successful packet caused error " ! 1558: "interrupt?\n", dev->name); ! 1559: } ! 1560: /* re-enable transmit */ ! 1561: SMC_SELECT_BANK(0); ! 1562: outw(inw(ioaddr + TCR) | TCR_ENABLE | smc->duplex, ioaddr + TCR); ! 1563: SMC_SELECT_BANK(2); ! 1564: ! 1565: outw(MC_FREEPKT, ioaddr + MMU_CMD); /* Free the packet memory. */ ! 1566: ! 1567: /* one less packet waiting for me */ ! 1568: smc->packets_waiting--; ! 1569: ! 1570: outw(saved_packet, ioaddr + PNR_ARR); ! 1571: return; ! 1572: } ! 1573: ! 1574: /*====================================================================*/ ! 1575: ! 1576: static void smc_eph_irq(struct net_device *dev) ! 1577: { ! 1578: struct smc_private *smc = dev->priv; ! 1579: ioaddr_t ioaddr = dev->base_addr; ! 1580: u_short card_stats, ephs; ! 1581: ! 1582: SMC_SELECT_BANK(0); ! 1583: ephs = inw(ioaddr + EPH); ! 1584: DEBUG(2, "%s: Ethernet protocol handler interrupt, status" ! 1585: " %4.4x.\n", dev->name, ephs); ! 1586: /* Could be a counter roll-over warning: update stats. */ ! 1587: card_stats = inw(ioaddr + COUNTER); ! 1588: /* single collisions */ ! 1589: smc->stats.collisions += card_stats & 0xF; ! 1590: card_stats >>= 4; ! 1591: /* multiple collisions */ ! 1592: smc->stats.collisions += card_stats & 0xF; ! 1593: #if 0 /* These are for when linux supports these statistics */ ! 1594: card_stats >>= 4; /* deferred */ ! 1595: card_stats >>= 4; /* excess deferred */ ! 1596: #endif ! 1597: /* If we had a transmit error we must re-enable the transmitter. */ ! 1598: outw(inw(ioaddr + TCR) | TCR_ENABLE | smc->duplex, ioaddr + TCR); ! 1599: ! 1600: /* Clear a link error interrupt. */ ! 1601: SMC_SELECT_BANK(1); ! 1602: outw(CTL_AUTO_RELEASE | 0x0000, ioaddr + CONTROL); ! 1603: outw(CTL_AUTO_RELEASE | CTL_TE_ENABLE | CTL_CR_ENABLE, ! 1604: ioaddr + CONTROL); ! 1605: SMC_SELECT_BANK(2); ! 1606: } ! 1607: ! 1608: /*====================================================================*/ ! 1609: ! 1610: static void smc_interrupt(int irq, void *dev_id, struct pt_regs *regs) ! 1611: { ! 1612: struct smc_private *smc = dev_id; ! 1613: struct net_device *dev = &smc->dev; ! 1614: ioaddr_t ioaddr; ! 1615: u_short saved_bank, saved_pointer, mask, status; ! 1616: char bogus_cnt = INTR_WORK; /* Work we are willing to do. */ ! 1617: ! 1618: if (!netif_device_present(dev)) ! 1619: return; ! 1620: ioaddr = dev->base_addr; ! 1621: ! 1622: DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name, ! 1623: irq, ioaddr); ! 1624: ! 1625: smc->watchdog = 0; ! 1626: saved_bank = inw(ioaddr + BANK_SELECT); ! 1627: if ((saved_bank & 0xff00) != 0x3300) { ! 1628: /* The device does not exist -- the card could be off-line, or ! 1629: maybe it has been ejected. */ ! 1630: DEBUG(1, "%s: SMC91c92 interrupt %d for non-existent" ! 1631: "/ejected device.\n", dev->name, irq); ! 1632: goto irq_done; ! 1633: } ! 1634: ! 1635: SMC_SELECT_BANK(2); ! 1636: saved_pointer = inw(ioaddr + POINTER); ! 1637: mask = inw(ioaddr + INTERRUPT) >> 8; ! 1638: /* clear all interrupts */ ! 1639: outw(0, ioaddr + INTERRUPT); ! 1640: ! 1641: do { /* read the status flag, and mask it */ ! 1642: status = inw(ioaddr + INTERRUPT) & 0xff; ! 1643: DEBUG(3, "%s: Status is %#2.2x (mask %#2.2x).\n", dev->name, ! 1644: status, mask); ! 1645: if ((status & mask) == 0) ! 1646: break; ! 1647: ! 1648: if (status & IM_RCV_INT) { ! 1649: /* Got a packet(s). */ ! 1650: smc_rx(dev); ! 1651: } ! 1652: if (status & IM_TX_INT) { ! 1653: smc_tx_err(dev); ! 1654: outw(IM_TX_INT, ioaddr + INTERRUPT); ! 1655: } ! 1656: status &= mask; ! 1657: if (status & IM_TX_EMPTY_INT) { ! 1658: outw(IM_TX_EMPTY_INT, ioaddr + INTERRUPT); ! 1659: mask &= ~IM_TX_EMPTY_INT; ! 1660: smc->stats.tx_packets += smc->packets_waiting; ! 1661: smc->packets_waiting = 0; ! 1662: } ! 1663: if (status & IM_ALLOC_INT) { ! 1664: /* Clear this interrupt so it doesn't happen again */ ! 1665: mask &= ~IM_ALLOC_INT; ! 1666: ! 1667: smc_hardware_send_packet(dev); ! 1668: ! 1669: /* enable xmit interrupts based on this */ ! 1670: mask |= (IM_TX_EMPTY_INT | IM_TX_INT); ! 1671: ! 1672: /* and let the card send more packets to me */ ! 1673: netif_wake_queue(dev); ! 1674: } ! 1675: if (status & IM_RX_OVRN_INT) { ! 1676: smc->stats.rx_errors++; ! 1677: smc->stats.rx_fifo_errors++; ! 1678: if (smc->duplex) ! 1679: smc->rx_ovrn = 1; /* need MC_RESET outside smc_interrupt */ ! 1680: outw(IM_RX_OVRN_INT, ioaddr + INTERRUPT); ! 1681: } ! 1682: if (status & IM_EPH_INT) ! 1683: smc_eph_irq(dev); ! 1684: } while (--bogus_cnt); ! 1685: ! 1686: DEBUG(3, " Restoring saved registers mask %2.2x bank %4.4x" ! 1687: " pointer %4.4x.\n", mask, saved_bank, saved_pointer); ! 1688: ! 1689: /* restore state register */ ! 1690: outw((mask<<8), ioaddr + INTERRUPT); ! 1691: outw(saved_pointer, ioaddr + POINTER); ! 1692: SMC_SELECT_BANK(saved_bank); ! 1693: ! 1694: DEBUG(3, "%s: Exiting interrupt IRQ%d.\n", dev->name, irq); ! 1695: ! 1696: irq_done: ! 1697: ! 1698: if ((smc->manfid == MANFID_OSITECH) && ! 1699: (smc->cardid != PRODID_OSITECH_SEVEN)) { ! 1700: /* Retrigger interrupt if needed */ ! 1701: mask_bits(0x00ff, ioaddr-0x10+OSITECH_RESET_ISR); ! 1702: set_bits(0x0300, ioaddr-0x10+OSITECH_RESET_ISR); ! 1703: } ! 1704: if (smc->manfid == MANFID_MOTOROLA) { ! 1705: u_char cor; ! 1706: cor = readb(smc->base + MOT_UART + CISREG_COR); ! 1707: writeb(cor & ~COR_IREQ_ENA, smc->base + MOT_UART + CISREG_COR); ! 1708: writeb(cor, smc->base + MOT_UART + CISREG_COR); ! 1709: cor = readb(smc->base + MOT_LAN + CISREG_COR); ! 1710: writeb(cor & ~COR_IREQ_ENA, smc->base + MOT_LAN + CISREG_COR); ! 1711: writeb(cor, smc->base + MOT_LAN + CISREG_COR); ! 1712: } ! 1713: #ifdef DOES_NOT_WORK ! 1714: if (smc->base != NULL) { /* Megahertz MFC's */ ! 1715: readb(smc->base+MEGAHERTZ_ISR); ! 1716: readb(smc->base+MEGAHERTZ_ISR); ! 1717: } ! 1718: #endif ! 1719: } ! 1720: ! 1721: /*====================================================================*/ ! 1722: ! 1723: static void smc_rx(struct net_device *dev) ! 1724: { ! 1725: struct smc_private *smc = (struct smc_private *)dev->priv; ! 1726: ioaddr_t ioaddr = dev->base_addr; ! 1727: int rx_status; ! 1728: int packet_length; /* Caution: not frame length, rather words ! 1729: to transfer from the chip. */ ! 1730: ! 1731: /* Assertion: we are in Window 2. */ ! 1732: ! 1733: if (inw(ioaddr + FIFO_PORTS) & FP_RXEMPTY) { ! 1734: printk(KERN_ERR "%s: smc_rx() with nothing on Rx FIFO.\n", ! 1735: dev->name); ! 1736: return; ! 1737: } ! 1738: ! 1739: /* Reset the read pointer, and read the status and packet length. */ ! 1740: outw(PTR_READ | PTR_RCV | PTR_AUTOINC, ioaddr + POINTER); ! 1741: rx_status = inw(ioaddr + DATA_1); ! 1742: packet_length = inw(ioaddr + DATA_1) & 0x07ff; ! 1743: ! 1744: DEBUG(2, "%s: Receive status %4.4x length %d.\n", ! 1745: dev->name, rx_status, packet_length); ! 1746: ! 1747: if (!(rx_status & RS_ERRORS)) { ! 1748: /* do stuff to make a new packet */ ! 1749: struct sk_buff *skb; ! 1750: ! 1751: /* Note: packet_length adds 5 or 6 extra bytes here! */ ! 1752: skb = dev_alloc_skb(packet_length+2); ! 1753: ! 1754: if (skb == NULL) { ! 1755: DEBUG(1, "%s: Low memory, packet dropped.\n", dev->name); ! 1756: smc->stats.rx_dropped++; ! 1757: outw(MC_RELEASE, ioaddr + MMU_CMD); ! 1758: return; ! 1759: } ! 1760: ! 1761: packet_length -= (rx_status & RS_ODDFRAME ? 5 : 6); ! 1762: skb_reserve(skb, 2); ! 1763: insw(ioaddr+DATA_1, skb_put(skb, packet_length), ! 1764: (packet_length+1)>>1); ! 1765: skb->protocol = eth_type_trans(skb, dev); ! 1766: ! 1767: skb->dev = dev; ! 1768: netif_rx(skb); ! 1769: dev->last_rx = jiffies; ! 1770: smc->stats.rx_packets++; ! 1771: add_rx_bytes(&smc->stats, packet_length); ! 1772: if (rx_status & RS_MULTICAST) ! 1773: smc->stats.multicast++; ! 1774: } else { ! 1775: /* error ... */ ! 1776: smc->stats.rx_errors++; ! 1777: ! 1778: if (rx_status & RS_ALGNERR) smc->stats.rx_frame_errors++; ! 1779: if (rx_status & (RS_TOOSHORT | RS_TOOLONG)) ! 1780: smc->stats.rx_length_errors++; ! 1781: if (rx_status & RS_BADCRC) smc->stats.rx_crc_errors++; ! 1782: } ! 1783: /* Let the MMU free the memory of this packet. */ ! 1784: outw(MC_RELEASE, ioaddr + MMU_CMD); ! 1785: ! 1786: return; ! 1787: } ! 1788: ! 1789: /*====================================================================*/ ! 1790: ! 1791: static struct net_device_stats *smc_get_stats(struct net_device *dev) ! 1792: { ! 1793: struct smc_private *smc = (struct smc_private *)dev->priv; ! 1794: /* Nothing to update - the 91c92 is a pretty primative chip. */ ! 1795: return &smc->stats; ! 1796: } ! 1797: ! 1798: /*====================================================================== ! 1799: ! 1800: Calculate values for the hardware multicast filter hash table. ! 1801: ! 1802: ======================================================================*/ ! 1803: ! 1804: static void fill_multicast_tbl(int count, struct dev_mc_list *addrs, ! 1805: u_char *multicast_table) ! 1806: { ! 1807: struct dev_mc_list *mc_addr; ! 1808: ! 1809: for (mc_addr = addrs; mc_addr && --count > 0; mc_addr = mc_addr->next) { ! 1810: u_int position = ether_crc(6, mc_addr->dmi_addr); ! 1811: #ifndef final_version /* Verify multicast address. */ ! 1812: if ((mc_addr->dmi_addr[0] & 1) == 0) ! 1813: continue; ! 1814: #endif ! 1815: multicast_table[position >> 29] |= 1 << ((position >> 26) & 7); ! 1816: } ! 1817: } ! 1818: ! 1819: /*====================================================================== ! 1820: ! 1821: Set the receive mode. ! 1822: ! 1823: This routine is used by both the protocol level to notify us of ! 1824: promiscuous/multicast mode changes, and by the open/reset code to ! 1825: initialize the Rx registers. We always set the multicast list and ! 1826: leave the receiver running. ! 1827: ! 1828: ======================================================================*/ ! 1829: ! 1830: static void set_rx_mode(struct net_device *dev) ! 1831: { ! 1832: ioaddr_t ioaddr = dev->base_addr; ! 1833: u_int multicast_table[ 2 ] = { 0, }; ! 1834: unsigned long flags; ! 1835: u_short rx_cfg_setting; ! 1836: ! 1837: if (dev->flags & IFF_PROMISC) { ! 1838: printk(KERN_NOTICE "%s: setting Rx mode to promiscuous.\n", dev->name); ! 1839: rx_cfg_setting = RxStripCRC | RxEnable | RxPromisc | RxAllMulti; ! 1840: } else if (dev->flags & IFF_ALLMULTI) ! 1841: rx_cfg_setting = RxStripCRC | RxEnable | RxAllMulti; ! 1842: else { ! 1843: if (dev->mc_count) { ! 1844: fill_multicast_tbl(dev->mc_count, dev->mc_list, ! 1845: (u_char *)multicast_table); ! 1846: } ! 1847: rx_cfg_setting = RxStripCRC | RxEnable; ! 1848: } ! 1849: ! 1850: /* Load MC table and Rx setting into the chip without interrupts. */ ! 1851: save_flags(flags); ! 1852: cli(); ! 1853: SMC_SELECT_BANK(3); ! 1854: outl(multicast_table[0], ioaddr + MULTICAST0); ! 1855: outl(multicast_table[1], ioaddr + MULTICAST4); ! 1856: SMC_SELECT_BANK(0); ! 1857: outw(rx_cfg_setting, ioaddr + RCR); ! 1858: SMC_SELECT_BANK(2); ! 1859: restore_flags(flags); ! 1860: ! 1861: return; ! 1862: } ! 1863: ! 1864: /*====================================================================== ! 1865: ! 1866: Senses when a card's config changes. Here, it's coax or TP. ! 1867: ! 1868: ======================================================================*/ ! 1869: ! 1870: static int s9k_config(struct net_device *dev, struct ifmap *map) ! 1871: { ! 1872: struct smc_private *smc = dev->priv; ! 1873: if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { ! 1874: if (smc->cfg & CFG_MII_SELECT) ! 1875: return -EOPNOTSUPP; ! 1876: else if (map->port > 2) ! 1877: return -EINVAL; ! 1878: dev->if_port = map->port; ! 1879: printk(KERN_INFO "%s: switched to %s port\n", ! 1880: dev->name, if_names[dev->if_port]); ! 1881: smc_reset(dev); ! 1882: } ! 1883: return 0; ! 1884: } ! 1885: ! 1886: /*====================================================================== ! 1887: ! 1888: Reset the chip, reloading every register that might be corrupted. ! 1889: ! 1890: ======================================================================*/ ! 1891: ! 1892: /* ! 1893: Set transceiver type, perhaps to something other than what the user ! 1894: specified in dev->if_port. ! 1895: */ ! 1896: static void smc_set_xcvr(struct net_device *dev, int if_port) ! 1897: { ! 1898: struct smc_private *smc = (struct smc_private *)dev->priv; ! 1899: ioaddr_t ioaddr = dev->base_addr; ! 1900: u_short saved_bank; ! 1901: ! 1902: saved_bank = inw(ioaddr + BANK_SELECT); ! 1903: SMC_SELECT_BANK(1); ! 1904: if (if_port == 2) { ! 1905: outw(smc->cfg | CFG_AUI_SELECT, ioaddr + CONFIG); ! 1906: if ((smc->manfid == MANFID_OSITECH) && ! 1907: (smc->cardid != PRODID_OSITECH_SEVEN)) ! 1908: set_bits(OSI_AUI_PWR, ioaddr - 0x10 + OSITECH_AUI_PWR); ! 1909: smc->media_status = ((dev->if_port == 0) ? 0x0001 : 0x0002); ! 1910: } else { ! 1911: outw(smc->cfg, ioaddr + CONFIG); ! 1912: if ((smc->manfid == MANFID_OSITECH) && ! 1913: (smc->cardid != PRODID_OSITECH_SEVEN)) ! 1914: mask_bits(~OSI_AUI_PWR, ioaddr - 0x10 + OSITECH_AUI_PWR); ! 1915: smc->media_status = ((dev->if_port == 0) ? 0x0012 : 0x4001); ! 1916: } ! 1917: SMC_SELECT_BANK(saved_bank); ! 1918: } ! 1919: ! 1920: static void smc_reset(struct net_device *dev) ! 1921: { ! 1922: ioaddr_t ioaddr = dev->base_addr; ! 1923: struct smc_private *smc = dev->priv; ! 1924: int i; ! 1925: ! 1926: DEBUG(0, "%s: smc91c92 reset called.\n", dev->name); ! 1927: ! 1928: /* The first interaction must be a write to bring the chip out ! 1929: of sleep mode. */ ! 1930: SMC_SELECT_BANK(0); ! 1931: /* Reset the chip. */ ! 1932: outw(RCR_SOFTRESET, ioaddr + RCR); ! 1933: udelay(10); ! 1934: ! 1935: /* Clear the transmit and receive configuration registers. */ ! 1936: outw(RCR_CLEAR, ioaddr + RCR); ! 1937: outw(TCR_CLEAR, ioaddr + TCR); ! 1938: ! 1939: /* Set the Window 1 control, configuration and station addr registers. ! 1940: No point in writing the I/O base register ;-> */ ! 1941: SMC_SELECT_BANK(1); ! 1942: /* Automatically release succesfully transmitted packets, ! 1943: Accept link errors, counter and Tx error interrupts. */ ! 1944: outw(CTL_AUTO_RELEASE | CTL_TE_ENABLE | CTL_CR_ENABLE, ! 1945: ioaddr + CONTROL); ! 1946: smc_set_xcvr(dev, dev->if_port); ! 1947: if ((smc->manfid == MANFID_OSITECH) && ! 1948: (smc->cardid != PRODID_OSITECH_SEVEN)) ! 1949: outw((dev->if_port == 2 ? OSI_AUI_PWR : 0) | ! 1950: (inw(ioaddr-0x10+OSITECH_AUI_PWR) & 0xff00), ! 1951: ioaddr - 0x10 + OSITECH_AUI_PWR); ! 1952: ! 1953: /* Fill in the physical address. The databook is wrong about the order! */ ! 1954: for (i = 0; i < 6; i += 2) ! 1955: outw((dev->dev_addr[i+1]<<8)+dev->dev_addr[i], ! 1956: ioaddr + ADDR0 + i); ! 1957: ! 1958: /* Reset the MMU */ ! 1959: SMC_SELECT_BANK(2); ! 1960: outw(MC_RESET, ioaddr + MMU_CMD); ! 1961: outw(0, ioaddr + INTERRUPT); ! 1962: ! 1963: /* Re-enable the chip. */ ! 1964: SMC_SELECT_BANK(0); ! 1965: outw(((smc->cfg & CFG_MII_SELECT) ? 0 : TCR_MONCSN) | ! 1966: TCR_ENABLE | TCR_PAD_EN | smc->duplex, ioaddr + TCR); ! 1967: set_rx_mode(dev); ! 1968: ! 1969: if (smc->cfg & CFG_MII_SELECT) { ! 1970: SMC_SELECT_BANK(3); ! 1971: ! 1972: /* Reset MII */ ! 1973: mdio_write(dev, smc->phy_id, 0, 0x8000); ! 1974: ! 1975: /* Advertise 100F, 100H, 10F, 10H */ ! 1976: mdio_write(dev, smc->phy_id, 4, 0x01e1); ! 1977: ! 1978: /* Restart MII autonegotiation */ ! 1979: mdio_write(dev, smc->phy_id, 0, 0x0000); ! 1980: mdio_write(dev, smc->phy_id, 0, 0x1200); ! 1981: } ! 1982: ! 1983: /* Enable interrupts. */ ! 1984: SMC_SELECT_BANK(2); ! 1985: outw((IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT) << 8, ! 1986: ioaddr + INTERRUPT); ! 1987: } ! 1988: ! 1989: /*====================================================================== ! 1990: ! 1991: Media selection timer routine ! 1992: ! 1993: ======================================================================*/ ! 1994: ! 1995: static void media_check(u_long arg) ! 1996: { ! 1997: struct smc_private *smc = (struct smc_private *)(arg); ! 1998: struct net_device *dev = &smc->dev; ! 1999: ioaddr_t ioaddr = dev->base_addr; ! 2000: u_short i, media, saved_bank; ! 2001: u_short link; ! 2002: ! 2003: saved_bank = inw(ioaddr + BANK_SELECT); ! 2004: ! 2005: if (!netif_device_present(dev)) ! 2006: goto reschedule; ! 2007: ! 2008: SMC_SELECT_BANK(2); ! 2009: ! 2010: /* need MC_RESET to keep the memory consistent. errata? */ ! 2011: if (smc->rx_ovrn) { ! 2012: outw(MC_RESET, ioaddr + MMU_CMD); ! 2013: smc->rx_ovrn = 0; ! 2014: } ! 2015: i = inw(ioaddr + INTERRUPT); ! 2016: SMC_SELECT_BANK(0); ! 2017: media = inw(ioaddr + EPH) & EPH_LINK_OK; ! 2018: SMC_SELECT_BANK(1); ! 2019: media |= (inw(ioaddr + CONFIG) & CFG_AUI_SELECT) ? 2 : 1; ! 2020: ! 2021: /* Check for pending interrupt with watchdog flag set: with ! 2022: this, we can limp along even if the interrupt is blocked */ ! 2023: if (smc->watchdog++ && ((i>>8) & i)) { ! 2024: if (!smc->fast_poll) ! 2025: printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); ! 2026: smc_interrupt(dev->irq, smc, NULL); ! 2027: smc->fast_poll = HZ; ! 2028: } ! 2029: if (smc->fast_poll) { ! 2030: smc->fast_poll--; ! 2031: smc->media.expires = jiffies + 1; ! 2032: add_timer(&smc->media); ! 2033: SMC_SELECT_BANK(saved_bank); ! 2034: return; ! 2035: } ! 2036: ! 2037: if (smc->cfg & CFG_MII_SELECT) { ! 2038: if (smc->phy_id < 0) ! 2039: goto reschedule; ! 2040: ! 2041: SMC_SELECT_BANK(3); ! 2042: link = mdio_read(dev, smc->phy_id, 1); ! 2043: if (!link || (link == 0xffff)) { ! 2044: printk(KERN_INFO "%s: MII is missing!\n", dev->name); ! 2045: smc->phy_id = -1; ! 2046: goto reschedule; ! 2047: } ! 2048: ! 2049: link &= 0x0004; ! 2050: if (link != smc->link_status) { ! 2051: u_short p = mdio_read(dev, smc->phy_id, 5); ! 2052: printk(KERN_INFO "%s: %s link beat\n", dev->name, ! 2053: (link) ? "found" : "lost"); ! 2054: smc->duplex = (((p & 0x0100) || ((p & 0x1c0) == 0x40)) ! 2055: ? TCR_FDUPLX : 0); ! 2056: if (link) { ! 2057: printk(KERN_INFO "%s: autonegotiation complete: " ! 2058: "%sbaseT-%cD selected\n", dev->name, ! 2059: ((p & 0x0180) ? "100" : "10"), ! 2060: (smc->duplex ? 'F' : 'H')); ! 2061: } ! 2062: SMC_SELECT_BANK(0); ! 2063: outw(inw(ioaddr + TCR) | smc->duplex, ioaddr + TCR); ! 2064: smc->link_status = link; ! 2065: } ! 2066: goto reschedule; ! 2067: } ! 2068: ! 2069: /* Ignore collisions unless we've had no rx's recently */ ! 2070: if (jiffies - dev->last_rx > HZ) { ! 2071: if (smc->tx_err || (smc->media_status & EPH_16COL)) ! 2072: media |= EPH_16COL; ! 2073: } ! 2074: smc->tx_err = 0; ! 2075: ! 2076: if (media != smc->media_status) { ! 2077: if ((media & smc->media_status & 1) && ! 2078: ((smc->media_status ^ media) & EPH_LINK_OK)) ! 2079: printk(KERN_INFO "%s: %s link beat\n", dev->name, ! 2080: (smc->media_status & EPH_LINK_OK ? "lost" : "found")); ! 2081: else if ((media & smc->media_status & 2) && ! 2082: ((smc->media_status ^ media) & EPH_16COL)) ! 2083: printk(KERN_INFO "%s: coax cable %s\n", dev->name, ! 2084: (media & EPH_16COL ? "problem" : "ok")); ! 2085: if (dev->if_port == 0) { ! 2086: if (media & 1) { ! 2087: if (media & EPH_LINK_OK) ! 2088: printk(KERN_INFO "%s: flipped to 10baseT\n", ! 2089: dev->name); ! 2090: else ! 2091: smc_set_xcvr(dev, 2); ! 2092: } else { ! 2093: if (media & EPH_16COL) ! 2094: smc_set_xcvr(dev, 1); ! 2095: else ! 2096: printk(KERN_INFO "%s: flipped to 10base2\n", ! 2097: dev->name); ! 2098: } ! 2099: } ! 2100: smc->media_status = media; ! 2101: } ! 2102: ! 2103: reschedule: ! 2104: smc->media.expires = jiffies + HZ; ! 2105: add_timer(&smc->media); ! 2106: SMC_SELECT_BANK(saved_bank); ! 2107: } ! 2108: ! 2109: ! 2110: /*====================================================================*/ ! 2111: ! 2112: static int __init init_smc91c92_cs(void) ! 2113: { ! 2114: servinfo_t serv; ! 2115: DEBUG(0, "%s\n", version); ! 2116: CardServices(GetCardServicesInfo, &serv); ! 2117: if (serv.Revision != CS_RELEASE_CODE) { ! 2118: printk(KERN_ERR ! 2119: "smc91c92_cs: Card Services release does not match!\n"); ! 2120: return -EINVAL; ! 2121: } ! 2122: register_pccard_driver(&dev_info, &smc91c92_attach, &smc91c92_detach); ! 2123: return 0; ! 2124: } ! 2125: ! 2126: static void __exit exit_smc91c92_cs(void) ! 2127: { ! 2128: DEBUG(0, "smc91c92_cs: unloading\n"); ! 2129: unregister_pccard_driver(&dev_info); ! 2130: while (dev_list != NULL) ! 2131: smc91c92_detach(dev_list); ! 2132: } ! 2133: ! 2134: module_init(init_smc91c92_cs); ! 2135: module_exit(exit_smc91c92_cs);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.