|
|
1.1 ! root 1: /*====================================================================== ! 2: fmvj18x_cs.c 2.8 2002/03/23 ! 3: ! 4: A fmvj18x (and its compatibles) PCMCIA client driver ! 5: ! 6: Contributed by Shingo Fujimoto, [email protected] ! 7: ! 8: TDK LAK-CD021 and CONTEC C-NET(PC)C support added by ! 9: Nobuhiro Katayama, [email protected] ! 10: ! 11: The PCMCIA client code is based on code written by David Hinds. ! 12: Network code is based on the "FMV-18x driver" by Yutaka TAMIYA ! 13: but is actually largely Donald Becker's AT1700 driver, which ! 14: carries the following attribution: ! 15: ! 16: Written 1993-94 by Donald Becker. ! 17: ! 18: Copyright 1993 United States Government as represented by the ! 19: Director, National Security Agency. ! 20: ! 21: This software may be used and distributed according to the terms ! 22: of the GNU General Public License, incorporated herein by reference. ! 23: ! 24: The author may be reached as [email protected], or C/O ! 25: Scyld Computing Corporation ! 26: 410 Severn Ave., Suite 210 ! 27: Annapolis MD 21403 ! 28: ! 29: ======================================================================*/ ! 30: ! 31: #include <linux/module.h> ! 32: #include <linux/kernel.h> ! 33: #include <linux/init.h> ! 34: #include <linux/sched.h> ! 35: #include <linux/ptrace.h> ! 36: #include <linux/slab.h> ! 37: #include <linux/string.h> ! 38: #include <linux/timer.h> ! 39: #include <linux/interrupt.h> ! 40: #include <linux/in.h> ! 41: #include <linux/delay.h> ! 42: #include <asm/io.h> ! 43: #include <asm/system.h> ! 44: ! 45: #include <linux/netdevice.h> ! 46: #include <linux/etherdevice.h> ! 47: #include <linux/skbuff.h> ! 48: #include <linux/if_arp.h> ! 49: #include <linux/ioport.h> ! 50: #include <linux/crc32.h> ! 51: ! 52: #include <pcmcia/version.h> ! 53: #include <pcmcia/cs_types.h> ! 54: #include <pcmcia/cs.h> ! 55: #include <pcmcia/cistpl.h> ! 56: #include <pcmcia/ciscode.h> ! 57: #include <pcmcia/ds.h> ! 58: ! 59: /*====================================================================*/ ! 60: ! 61: /* Module parameters */ ! 62: ! 63: MODULE_DESCRIPTION("fmvj18x and compatible PCMCIA ethernet driver"); ! 64: MODULE_LICENSE("GPL"); ! 65: ! 66: #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") ! 67: ! 68: /* Bit map of interrupts to choose from */ ! 69: /* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */ ! 70: INT_MODULE_PARM(irq_mask, 0xdeb8); ! 71: static int irq_list[4] = { -1 }; ! 72: MODULE_PARM(irq_list, "1-4i"); ! 73: ! 74: /* SRAM configuration */ ! 75: /* 0:4KB*2 TX buffer else:8KB*2 TX buffer */ ! 76: INT_MODULE_PARM(sram_config, 0); ! 77: ! 78: #ifdef PCMCIA_DEBUG ! 79: INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG); ! 80: #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) ! 81: static char *version = "fmvj18x_cs.c 2.8 2002/03/23"; ! 82: #else ! 83: #define DEBUG(n, args...) ! 84: #endif ! 85: ! 86: /*====================================================================*/ ! 87: /* ! 88: PCMCIA event handlers ! 89: */ ! 90: static void fmvj18x_config(dev_link_t *link); ! 91: static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id); ! 92: static int fmvj18x_setup_mfc(dev_link_t *link); ! 93: static void fmvj18x_release(u_long arg); ! 94: static int fmvj18x_event(event_t event, int priority, ! 95: event_callback_args_t *args); ! 96: static dev_link_t *fmvj18x_attach(void); ! 97: static void fmvj18x_detach(dev_link_t *); ! 98: ! 99: /* ! 100: LAN controller(MBH86960A) specific routines ! 101: */ ! 102: static int fjn_config(struct net_device *dev, struct ifmap *map); ! 103: static int fjn_open(struct net_device *dev); ! 104: static int fjn_close(struct net_device *dev); ! 105: static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev); ! 106: static void fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs); ! 107: static void fjn_rx(struct net_device *dev); ! 108: static void fjn_reset(struct net_device *dev); ! 109: static struct net_device_stats *fjn_get_stats(struct net_device *dev); ! 110: static void set_rx_mode(struct net_device *dev); ! 111: static void fjn_tx_timeout(struct net_device *dev); ! 112: ! 113: static dev_info_t dev_info = "fmvj18x_cs"; ! 114: static dev_link_t *dev_list; ! 115: ! 116: /* ! 117: card type ! 118: */ ! 119: typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN, ! 120: XXX10304 ! 121: } cardtype_t; ! 122: ! 123: /* ! 124: driver specific data structure ! 125: */ ! 126: typedef struct local_info_t { ! 127: dev_link_t link; ! 128: struct net_device dev; ! 129: dev_node_t node; ! 130: struct net_device_stats stats; ! 131: long open_time; ! 132: uint tx_started:1; ! 133: uint tx_queue; ! 134: u_short tx_queue_len; ! 135: cardtype_t cardtype; ! 136: u_short sent; ! 137: u_char mc_filter[8]; ! 138: } local_info_t; ! 139: ! 140: #define MC_FILTERBREAK 64 ! 141: ! 142: /*====================================================================*/ ! 143: /* ! 144: ioport offset from the base address ! 145: */ ! 146: #define TX_STATUS 0 /* transmit status register */ ! 147: #define RX_STATUS 1 /* receive status register */ ! 148: #define TX_INTR 2 /* transmit interrupt mask register */ ! 149: #define RX_INTR 3 /* receive interrupt mask register */ ! 150: #define TX_MODE 4 /* transmit mode register */ ! 151: #define RX_MODE 5 /* receive mode register */ ! 152: #define CONFIG_0 6 /* configuration register 0 */ ! 153: #define CONFIG_1 7 /* configuration register 1 */ ! 154: ! 155: #define NODE_ID 8 /* node ID register (bank 0) */ ! 156: #define MAR_ADR 8 /* multicast address registers (bank 1) */ ! 157: ! 158: #define DATAPORT 8 /* buffer mem port registers (bank 2) */ ! 159: #define TX_START 10 /* transmit start register */ ! 160: #define COL_CTRL 11 /* 16 collision control register */ ! 161: #define BMPR12 12 /* reserved */ ! 162: #define BMPR13 13 /* reserved */ ! 163: #define RX_SKIP 14 /* skip received packet register */ ! 164: ! 165: #define LAN_CTRL 16 /* LAN card control register */ ! 166: ! 167: #define MAC_ID 0x1a /* hardware address */ ! 168: #define UNGERMANN_MAC_ID 0x18 /* UNGERMANN-BASS hardware address */ ! 169: ! 170: /* ! 171: control bits ! 172: */ ! 173: #define ENA_TMT_OK 0x80 ! 174: #define ENA_TMT_REC 0x20 ! 175: #define ENA_COL 0x04 ! 176: #define ENA_16_COL 0x02 ! 177: #define ENA_TBUS_ERR 0x01 ! 178: ! 179: #define ENA_PKT_RDY 0x80 ! 180: #define ENA_BUS_ERR 0x40 ! 181: #define ENA_LEN_ERR 0x08 ! 182: #define ENA_ALG_ERR 0x04 ! 183: #define ENA_CRC_ERR 0x02 ! 184: #define ENA_OVR_FLO 0x01 ! 185: ! 186: /* flags */ ! 187: #define F_TMT_RDY 0x80 /* can accept new packet */ ! 188: #define F_NET_BSY 0x40 /* carrier is detected */ ! 189: #define F_TMT_OK 0x20 /* send packet successfully */ ! 190: #define F_SRT_PKT 0x10 /* short packet error */ ! 191: #define F_COL_ERR 0x04 /* collision error */ ! 192: #define F_16_COL 0x02 /* 16 collision error */ ! 193: #define F_TBUS_ERR 0x01 /* bus read error */ ! 194: ! 195: #define F_PKT_RDY 0x80 /* packet(s) in buffer */ ! 196: #define F_BUS_ERR 0x40 /* bus read error */ ! 197: #define F_LEN_ERR 0x08 /* short packet */ ! 198: #define F_ALG_ERR 0x04 /* frame error */ ! 199: #define F_CRC_ERR 0x02 /* CRC error */ ! 200: #define F_OVR_FLO 0x01 /* overflow error */ ! 201: ! 202: #define F_BUF_EMP 0x40 /* receive buffer is empty */ ! 203: ! 204: #define F_SKP_PKT 0x05 /* drop packet in buffer */ ! 205: ! 206: /* default bitmaps */ ! 207: #define D_TX_INTR ( ENA_TMT_OK ) ! 208: #define D_RX_INTR ( ENA_PKT_RDY | ENA_LEN_ERR \ ! 209: | ENA_ALG_ERR | ENA_CRC_ERR | ENA_OVR_FLO ) ! 210: #define TX_STAT_M ( F_TMT_RDY ) ! 211: #define RX_STAT_M ( F_PKT_RDY | F_LEN_ERR \ ! 212: | F_ALG_ERR | F_CRC_ERR | F_OVR_FLO ) ! 213: ! 214: /* commands */ ! 215: #define D_TX_MODE 0x06 /* no tests, detect carrier */ ! 216: #define ID_MATCHED 0x02 /* (RX_MODE) */ ! 217: #define RECV_ALL 0x03 /* (RX_MODE) */ ! 218: #define CONFIG0_DFL 0x5a /* 16bit bus, 4K x 2 Tx queues */ ! 219: #define CONFIG0_DFL_1 0x5e /* 16bit bus, 8K x 2 Tx queues */ ! 220: #define CONFIG0_RST 0xda /* Data Link Controller off (CONFIG_0) */ ! 221: #define CONFIG0_RST_1 0xde /* Data Link Controller off (CONFIG_0) */ ! 222: #define BANK_0 0xa0 /* bank 0 (CONFIG_1) */ ! 223: #define BANK_1 0xa4 /* bank 1 (CONFIG_1) */ ! 224: #define BANK_2 0xa8 /* bank 2 (CONFIG_1) */ ! 225: #define CHIP_OFF 0x80 /* contrl chip power off (CONFIG_1) */ ! 226: #define DO_TX 0x80 /* do transmit packet */ ! 227: #define SEND_PKT 0x81 /* send a packet */ ! 228: #define AUTO_MODE 0x07 /* Auto skip packet on 16 col detected */ ! 229: #define MANU_MODE 0x03 /* Stop and skip packet on 16 col */ ! 230: #define TDK_AUTO_MODE 0x47 /* Auto skip packet on 16 col detected */ ! 231: #define TDK_MANU_MODE 0x43 /* Stop and skip packet on 16 col */ ! 232: #define INTR_OFF 0x0d /* LAN controller ignores interrupts */ ! 233: #define INTR_ON 0x1d /* LAN controller will catch interrupts */ ! 234: ! 235: #define TX_TIMEOUT ((400*HZ)/1000) ! 236: ! 237: #define BANK_0U 0x20 /* bank 0 (CONFIG_1) */ ! 238: #define BANK_1U 0x24 /* bank 1 (CONFIG_1) */ ! 239: #define BANK_2U 0x28 /* bank 2 (CONFIG_1) */ ! 240: ! 241: /*====================================================================== ! 242: ! 243: This bit of code is used to avoid unregistering network devices ! 244: at inappropriate times. 2.2 and later kernels are fairly picky ! 245: about when this can happen. ! 246: ! 247: ======================================================================*/ ! 248: ! 249: static void flush_stale_links(void) ! 250: { ! 251: dev_link_t *link, *next; ! 252: for (link = dev_list; link; link = next) { ! 253: next = link->next; ! 254: if (link->state & DEV_STALE_LINK) ! 255: fmvj18x_detach(link); ! 256: } ! 257: } ! 258: ! 259: /*====================================================================*/ ! 260: ! 261: static void cs_error(client_handle_t handle, int func, int ret) ! 262: { ! 263: error_info_t err = { func, ret }; ! 264: CardServices(ReportError, handle, &err); ! 265: } ! 266: ! 267: /*====================================================================*/ ! 268: ! 269: static dev_link_t *fmvj18x_attach(void) ! 270: { ! 271: local_info_t *lp; ! 272: dev_link_t *link; ! 273: struct net_device *dev; ! 274: client_reg_t client_reg; ! 275: int i, ret; ! 276: ! 277: DEBUG(0, "fmvj18x_attach()\n"); ! 278: flush_stale_links(); ! 279: ! 280: /* Make up a FMVJ18x specific data structure */ ! 281: lp = kmalloc(sizeof(*lp), GFP_KERNEL); ! 282: if (!lp) return NULL; ! 283: memset(lp, 0, sizeof(*lp)); ! 284: link = &lp->link; dev = &lp->dev; ! 285: link->priv = dev->priv = link->irq.Instance = lp; ! 286: ! 287: init_timer(&link->release); ! 288: link->release.function = &fmvj18x_release; ! 289: link->release.data = (u_long)link; ! 290: ! 291: /* The io structure describes IO port mapping */ ! 292: link->io.NumPorts1 = 32; ! 293: link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; ! 294: link->io.IOAddrLines = 5; ! 295: ! 296: /* Interrupt setup */ ! 297: link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; ! 298: link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; ! 299: if (irq_list[0] == -1) ! 300: link->irq.IRQInfo2 = irq_mask; ! 301: else ! 302: for (i = 0; i < 4; i++) ! 303: link->irq.IRQInfo2 |= 1 << irq_list[i]; ! 304: link->irq.Handler = &fjn_interrupt; ! 305: ! 306: /* General socket configuration */ ! 307: link->conf.Attributes = CONF_ENABLE_IRQ; ! 308: link->conf.Vcc = 50; ! 309: link->conf.IntType = INT_MEMORY_AND_IO; ! 310: ! 311: /* The FMVJ18x specific entries in the device structure. */ ! 312: dev->hard_start_xmit = &fjn_start_xmit; ! 313: dev->set_config = &fjn_config; ! 314: dev->get_stats = &fjn_get_stats; ! 315: dev->set_multicast_list = &set_rx_mode; ! 316: ether_setup(dev); ! 317: init_dev_name(dev, lp->node); ! 318: dev->open = &fjn_open; ! 319: dev->stop = &fjn_close; ! 320: #ifdef HAVE_TX_TIMEOUT ! 321: dev->tx_timeout = fjn_tx_timeout; ! 322: dev->watchdog_timeo = TX_TIMEOUT; ! 323: #endif ! 324: ! 325: /* Register with Card Services */ ! 326: link->next = dev_list; ! 327: dev_list = link; ! 328: client_reg.dev_info = &dev_info; ! 329: client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; ! 330: client_reg.EventMask = ! 331: CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | ! 332: CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | ! 333: CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; ! 334: client_reg.event_handler = &fmvj18x_event; ! 335: client_reg.Version = 0x0210; ! 336: client_reg.event_callback_args.client_data = link; ! 337: ret = CardServices(RegisterClient, &link->handle, &client_reg); ! 338: if (ret != 0) { ! 339: cs_error(link->handle, RegisterClient, ret); ! 340: fmvj18x_detach(link); ! 341: return NULL; ! 342: } ! 343: ! 344: return link; ! 345: } /* fmvj18x_attach */ ! 346: ! 347: /*====================================================================*/ ! 348: ! 349: static void fmvj18x_detach(dev_link_t *link) ! 350: { ! 351: local_info_t *lp = link->priv; ! 352: dev_link_t **linkp; ! 353: ! 354: DEBUG(0, "fmvj18x_detach(0x%p)\n", link); ! 355: ! 356: /* Locate device structure */ ! 357: for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) ! 358: if (*linkp == link) break; ! 359: if (*linkp == NULL) ! 360: return; ! 361: ! 362: del_timer(&link->release); ! 363: if (link->state & DEV_CONFIG) { ! 364: fmvj18x_release((u_long)link); ! 365: if (link->state & DEV_STALE_CONFIG) { ! 366: link->state |= DEV_STALE_LINK; ! 367: return; ! 368: } ! 369: } ! 370: ! 371: /* Break the link with Card Services */ ! 372: if (link->handle) ! 373: CardServices(DeregisterClient, link->handle); ! 374: ! 375: /* Unlink device structure, free pieces */ ! 376: *linkp = link->next; ! 377: if (link->dev) ! 378: unregister_netdev(&lp->dev); ! 379: kfree(lp); ! 380: ! 381: } /* fmvj18x_detach */ ! 382: ! 383: /*====================================================================*/ ! 384: ! 385: #define CS_CHECK(fn, args...) \ ! 386: while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed ! 387: ! 388: static int mfc_try_io_port(dev_link_t *link) ! 389: { ! 390: int i, ret; ! 391: static ioaddr_t serial_base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; ! 392: ! 393: for (i = 0; i < 5; i++) { ! 394: link->io.BasePort2 = serial_base[i]; ! 395: link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; ! 396: if (link->io.BasePort2 == 0) { ! 397: link->io.NumPorts2 = 0; ! 398: printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n"); ! 399: } ! 400: ret = CardServices(RequestIO, link->handle, &link->io); ! 401: if (ret == CS_SUCCESS) return ret; ! 402: } ! 403: return ret; ! 404: } ! 405: ! 406: static int ungermann_try_io_port(dev_link_t *link) ! 407: { ! 408: int ret; ! 409: ioaddr_t ioaddr; ! 410: /* ! 411: Ungermann-Bass Access/CARD accepts 0x300,0x320,0x340,0x360 ! 412: 0x380,0x3c0 only for ioport. ! 413: */ ! 414: for (ioaddr = 0x300; ioaddr < 0x3e0; ioaddr += 0x20) { ! 415: link->io.BasePort1 = ioaddr; ! 416: ret = CardServices(RequestIO, link->handle, &link->io); ! 417: if (ret == CS_SUCCESS) { ! 418: /* calculate ConfigIndex value */ ! 419: link->conf.ConfigIndex = ! 420: ((link->io.BasePort1 & 0x0f0) >> 3) | 0x22; ! 421: return ret; ! 422: } ! 423: } ! 424: return ret; /* RequestIO failed */ ! 425: } ! 426: ! 427: static void fmvj18x_config(dev_link_t *link) ! 428: { ! 429: client_handle_t handle = link->handle; ! 430: local_info_t *lp = link->priv; ! 431: struct net_device *dev = &lp->dev; ! 432: tuple_t tuple; ! 433: cisparse_t parse; ! 434: u_short buf[32]; ! 435: int i, last_fn, last_ret, ret; ! 436: ioaddr_t ioaddr; ! 437: cardtype_t cardtype; ! 438: char *card_name = "unknown"; ! 439: u_char *node_id; ! 440: ! 441: DEBUG(0, "fmvj18x_config(0x%p)\n", link); ! 442: ! 443: /* ! 444: This reads the card's CONFIG tuple to find its configuration ! 445: registers. ! 446: */ ! 447: tuple.DesiredTuple = CISTPL_CONFIG; ! 448: CS_CHECK(GetFirstTuple, handle, &tuple); ! 449: tuple.TupleData = (u_char *)buf; ! 450: tuple.TupleDataMax = 64; ! 451: tuple.TupleOffset = 0; ! 452: CS_CHECK(GetTupleData, handle, &tuple); ! 453: CS_CHECK(ParseTuple, handle, &tuple, &parse); ! 454: ! 455: /* Configure card */ ! 456: link->state |= DEV_CONFIG; ! 457: ! 458: link->conf.ConfigBase = parse.config.base; ! 459: link->conf.Present = parse.config.rmask[0]; ! 460: ! 461: tuple.DesiredTuple = CISTPL_FUNCE; ! 462: tuple.TupleOffset = 0; ! 463: if (CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) { ! 464: /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */ ! 465: tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; ! 466: CS_CHECK(GetFirstTuple, handle, &tuple); ! 467: CS_CHECK(GetTupleData, handle, &tuple); ! 468: CS_CHECK(ParseTuple, handle, &tuple, &parse); ! 469: link->conf.ConfigIndex = parse.cftable_entry.index; ! 470: tuple.DesiredTuple = CISTPL_MANFID; ! 471: if (CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) ! 472: CS_CHECK(GetTupleData, handle, &tuple); ! 473: else ! 474: buf[0] = 0xffff; ! 475: switch (le16_to_cpu(buf[0])) { ! 476: case MANFID_TDK: ! 477: cardtype = TDK; ! 478: if (le16_to_cpu(buf[1]) == PRODID_TDK_CF010) { ! 479: cs_status_t status; ! 480: CardServices(GetStatus, handle, &status); ! 481: if (status.CardState & CS_EVENT_3VCARD) ! 482: link->conf.Vcc = 33; /* inserted in 3.3V slot */ ! 483: } else if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410) { ! 484: /* MultiFunction Card */ ! 485: link->conf.ConfigBase = 0x800; ! 486: link->conf.ConfigIndex = 0x47; ! 487: link->io.NumPorts2 = 8; ! 488: } ! 489: break; ! 490: case MANFID_CONTEC: ! 491: cardtype = CONTEC; ! 492: break; ! 493: case MANFID_FUJITSU: ! 494: if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10302) ! 495: /* RATOC REX-5588/9822/4886's PRODID are 0004(=MBH10302), ! 496: but these are MBH10304 based card. */ ! 497: cardtype = MBH10304; ! 498: else if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304) ! 499: cardtype = MBH10304; ! 500: else ! 501: cardtype = LA501; ! 502: break; ! 503: default: ! 504: cardtype = MBH10304; ! 505: } ! 506: } else { ! 507: /* old type card */ ! 508: tuple.DesiredTuple = CISTPL_MANFID; ! 509: if (CardServices(GetFirstTuple, handle, &tuple) == CS_SUCCESS) ! 510: CS_CHECK(GetTupleData, handle, &tuple); ! 511: else ! 512: buf[0] = 0xffff; ! 513: switch (le16_to_cpu(buf[0])) { ! 514: case MANFID_FUJITSU: ! 515: if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304) { ! 516: cardtype = XXX10304; /* MBH10304 with buggy CIS */ ! 517: link->conf.ConfigIndex = 0x20; ! 518: } else { ! 519: cardtype = MBH10302; /* NextCom NC5310, etc. */ ! 520: link->conf.ConfigIndex = 1; ! 521: } ! 522: break; ! 523: case MANFID_UNGERMANN: ! 524: cardtype = UNGERMANN; ! 525: break; ! 526: default: ! 527: cardtype = MBH10302; ! 528: link->conf.ConfigIndex = 1; ! 529: } ! 530: } ! 531: ! 532: if (link->io.NumPorts2 != 0) { ! 533: link->irq.Attributes = ! 534: IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT; ! 535: ret = mfc_try_io_port(link); ! 536: if (ret != CS_SUCCESS) goto cs_failed; ! 537: } else if (cardtype == UNGERMANN) { ! 538: ret = ungermann_try_io_port(link); ! 539: if (ret != CS_SUCCESS) goto cs_failed; ! 540: } else { ! 541: CS_CHECK(RequestIO, link->handle, &link->io); ! 542: } ! 543: CS_CHECK(RequestIRQ, link->handle, &link->irq); ! 544: CS_CHECK(RequestConfiguration, link->handle, &link->conf); ! 545: dev->irq = link->irq.AssignedIRQ; ! 546: dev->base_addr = link->io.BasePort1; ! 547: if (register_netdev(dev) != 0) { ! 548: printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n"); ! 549: goto failed; ! 550: } ! 551: ! 552: if (link->io.BasePort2 != 0) ! 553: fmvj18x_setup_mfc(link); ! 554: ! 555: ioaddr = dev->base_addr; ! 556: ! 557: /* Reset controller */ ! 558: if (sram_config == 0) ! 559: outb(CONFIG0_RST, ioaddr + CONFIG_0); ! 560: else ! 561: outb(CONFIG0_RST_1, ioaddr + CONFIG_0); ! 562: ! 563: /* Power On chip and select bank 0 */ ! 564: if (cardtype == MBH10302) ! 565: outb(BANK_0, ioaddr + CONFIG_1); ! 566: else ! 567: outb(BANK_0U, ioaddr + CONFIG_1); ! 568: ! 569: /* Set hardware address */ ! 570: switch (cardtype) { ! 571: case MBH10304: ! 572: case TDK: ! 573: case LA501: ! 574: case CONTEC: ! 575: tuple.DesiredTuple = CISTPL_FUNCE; ! 576: tuple.TupleOffset = 0; ! 577: CS_CHECK(GetFirstTuple, handle, &tuple); ! 578: tuple.TupleOffset = 0; ! 579: CS_CHECK(GetTupleData, handle, &tuple); ! 580: if (cardtype == MBH10304) { ! 581: /* MBH10304's CIS_FUNCE is corrupted */ ! 582: node_id = &(tuple.TupleData[5]); ! 583: card_name = "FMV-J182"; ! 584: } else { ! 585: while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) { ! 586: CS_CHECK(GetNextTuple, handle, &tuple) ; ! 587: CS_CHECK(GetTupleData, handle, &tuple) ; ! 588: } ! 589: node_id = &(tuple.TupleData[2]); ! 590: if( cardtype == TDK ) { ! 591: card_name = "TDK LAK-CD021"; ! 592: } else if( cardtype == LA501 ) { ! 593: card_name = "LA501"; ! 594: } else { ! 595: card_name = "C-NET(PC)C"; ! 596: } ! 597: } ! 598: /* Read MACID from CIS */ ! 599: for (i = 0; i < 6; i++) ! 600: dev->dev_addr[i] = node_id[i]; ! 601: break; ! 602: case UNGERMANN: ! 603: /* Read MACID from register */ ! 604: for (i = 0; i < 6; i++) ! 605: dev->dev_addr[i] = inb(ioaddr + UNGERMANN_MAC_ID + i); ! 606: card_name = "Access/CARD"; ! 607: break; ! 608: case XXX10304: ! 609: /* Read MACID from Buggy CIS */ ! 610: if (fmvj18x_get_hwinfo(link, tuple.TupleData) == -1) { ! 611: printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address."); ! 612: unregister_netdev(dev); ! 613: goto failed; ! 614: } ! 615: for (i = 0 ; i < 6; i++) { ! 616: dev->dev_addr[i] = tuple.TupleData[i]; ! 617: } ! 618: card_name = "FMV-J182"; ! 619: break; ! 620: case MBH10302: ! 621: default: ! 622: /* Read MACID from register */ ! 623: for (i = 0; i < 6; i++) ! 624: dev->dev_addr[i] = inb(ioaddr + MAC_ID + i); ! 625: card_name = "FMV-J181"; ! 626: break; ! 627: } ! 628: ! 629: copy_dev_name(lp->node, dev); ! 630: link->dev = &lp->node; ! 631: ! 632: lp->cardtype = cardtype; ! 633: /* print current configuration */ ! 634: printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, hw_addr ", ! 635: dev->name, card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2", ! 636: dev->base_addr, dev->irq); ! 637: for (i = 0; i < 6; i++) ! 638: printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); ! 639: ! 640: link->state &= ~DEV_CONFIG_PENDING; ! 641: return; ! 642: ! 643: cs_failed: ! 644: /* All Card Services errors end up here */ ! 645: cs_error(link->handle, last_fn, last_ret); ! 646: failed: ! 647: fmvj18x_release((u_long)link); ! 648: link->state &= ~DEV_CONFIG_PENDING; ! 649: ! 650: } /* fmvj18x_config */ ! 651: /*====================================================================*/ ! 652: ! 653: static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id) ! 654: { ! 655: win_req_t req; ! 656: memreq_t mem; ! 657: u_char *base; ! 658: int i, j; ! 659: ! 660: /* Allocate a small memory window */ ! 661: req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; ! 662: req.Base = 0; req.Size = 0; ! 663: req.AccessSpeed = 0; ! 664: link->win = (window_handle_t)link->handle; ! 665: i = CardServices(RequestWindow, &link->win, &req); ! 666: if (i != CS_SUCCESS) { ! 667: cs_error(link->handle, RequestWindow, i); ! 668: return -1; ! 669: } ! 670: ! 671: base = ioremap(req.Base, req.Size); ! 672: mem.Page = 0; ! 673: mem.CardOffset = 0; ! 674: CardServices(MapMemPage, link->win, &mem); ! 675: ! 676: /* ! 677: * MBH10304 CISTPL_FUNCE_LAN_NODE_ID format ! 678: * 22 0d xx xx xx 04 06 yy yy yy yy yy yy ff ! 679: * 'xx' is garbage. ! 680: * 'yy' is MAC address. ! 681: */ ! 682: for (i = 0; i < 0x200; i++) { ! 683: if (readb(base+i*2) == 0x22) { ! 684: if (readb(base+(i-1)*2) == 0xff ! 685: && readb(base+(i+5)*2) == 0x04 ! 686: && readb(base+(i+6)*2) == 0x06 ! 687: && readb(base+(i+13)*2) == 0xff) ! 688: break; ! 689: } ! 690: } ! 691: ! 692: if (i != 0x200) { ! 693: for (j = 0 ; j < 6; j++,i++) { ! 694: node_id[j] = readb(base+(i+7)*2); ! 695: } ! 696: } ! 697: ! 698: iounmap(base); ! 699: j = CardServices(ReleaseWindow, link->win); ! 700: if (j != CS_SUCCESS) ! 701: cs_error(link->handle, ReleaseWindow, j); ! 702: return (i != 0x200) ? 0 : -1; ! 703: ! 704: } /* fmvj18x_get_hwinfo */ ! 705: /*====================================================================*/ ! 706: ! 707: static int fmvj18x_setup_mfc(dev_link_t *link) ! 708: { ! 709: win_req_t req; ! 710: memreq_t mem; ! 711: u_char *base; ! 712: int i, j; ! 713: local_info_t *lp = link->priv; ! 714: struct net_device *dev = &lp->dev; ! 715: ioaddr_t ioaddr; ! 716: ! 717: /* Allocate a small memory window */ ! 718: req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; ! 719: req.Base = 0; req.Size = 0; ! 720: req.AccessSpeed = 0; ! 721: link->win = (window_handle_t)link->handle; ! 722: i = CardServices(RequestWindow, &link->win, &req); ! 723: if (i != CS_SUCCESS) { ! 724: cs_error(link->handle, RequestWindow, i); ! 725: return -1; ! 726: } ! 727: ! 728: base = ioremap(req.Base, req.Size); ! 729: mem.Page = 0; ! 730: mem.CardOffset = 0; ! 731: CardServices(MapMemPage, link->win, &mem); ! 732: ! 733: ioaddr = dev->base_addr; ! 734: writeb(0x47, base+0x800); /* Config Option Register of LAN */ ! 735: writeb(0x0, base+0x802); /* Config and Status Register */ ! 736: ! 737: writeb(ioaddr & 0xff, base+0x80a); /* I/O Base(Low) of LAN */ ! 738: writeb((ioaddr >> 8) & 0xff, base+0x80c); /* I/O Base(High) of LAN */ ! 739: ! 740: writeb(0x45, base+0x820); /* Config Option Register of Modem */ ! 741: writeb(0x8, base+0x822); /* Config and Status Register */ ! 742: ! 743: iounmap(base); ! 744: j = CardServices(ReleaseWindow, link->win); ! 745: if (j != CS_SUCCESS) ! 746: cs_error(link->handle, ReleaseWindow, j); ! 747: return 0; ! 748: ! 749: } ! 750: /*====================================================================*/ ! 751: ! 752: static void fmvj18x_release(u_long arg) ! 753: { ! 754: dev_link_t *link = (dev_link_t *)arg; ! 755: ! 756: DEBUG(0, "fmvj18x_release(0x%p)\n", link); ! 757: ! 758: /* ! 759: If the device is currently in use, we won't release until it ! 760: is actually closed. ! 761: */ ! 762: if (link->open) { ! 763: DEBUG(1, "fmvj18x_cs: release postponed, '%s' " ! 764: "still open\n", link->dev->dev_name); ! 765: link->state |= DEV_STALE_CONFIG; ! 766: return; ! 767: } ! 768: ! 769: /* Don't bother checking to see if these succeed or not */ ! 770: CardServices(ReleaseWindow, link->win); ! 771: CardServices(ReleaseConfiguration, link->handle); ! 772: CardServices(ReleaseIO, link->handle, &link->io); ! 773: CardServices(ReleaseIRQ, link->handle, &link->irq); ! 774: ! 775: link->state &= ~DEV_CONFIG; ! 776: ! 777: } /* fmvj18x_release */ ! 778: ! 779: /*====================================================================*/ ! 780: ! 781: static int fmvj18x_event(event_t event, int priority, ! 782: event_callback_args_t *args) ! 783: { ! 784: dev_link_t *link = args->client_data; ! 785: local_info_t *lp = link->priv; ! 786: struct net_device *dev = &lp->dev; ! 787: ! 788: DEBUG(1, "fmvj18x_event(0x%06x)\n", event); ! 789: ! 790: switch (event) { ! 791: case CS_EVENT_CARD_REMOVAL: ! 792: link->state &= ~DEV_PRESENT; ! 793: if (link->state & DEV_CONFIG) { ! 794: netif_device_detach(dev); ! 795: mod_timer(&link->release, jiffies + HZ/20); ! 796: } ! 797: break; ! 798: case CS_EVENT_CARD_INSERTION: ! 799: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; ! 800: fmvj18x_config(link); ! 801: break; ! 802: case CS_EVENT_PM_SUSPEND: ! 803: link->state |= DEV_SUSPEND; ! 804: /* Fall through... */ ! 805: case CS_EVENT_RESET_PHYSICAL: ! 806: if (link->state & DEV_CONFIG) { ! 807: if (link->open) ! 808: netif_device_detach(dev); ! 809: CardServices(ReleaseConfiguration, link->handle); ! 810: } ! 811: break; ! 812: case CS_EVENT_PM_RESUME: ! 813: link->state &= ~DEV_SUSPEND; ! 814: /* Fall through... */ ! 815: case CS_EVENT_CARD_RESET: ! 816: if (link->state & DEV_CONFIG) { ! 817: CardServices(RequestConfiguration, link->handle, &link->conf); ! 818: if (link->open) { ! 819: fjn_reset(dev); ! 820: netif_device_attach(dev); ! 821: } ! 822: } ! 823: break; ! 824: } ! 825: return 0; ! 826: } /* fmvj18x_event */ ! 827: ! 828: /*====================================================================*/ ! 829: ! 830: static int __init init_fmvj18x_cs(void) ! 831: { ! 832: servinfo_t serv; ! 833: DEBUG(0, "%s\n", version); ! 834: CardServices(GetCardServicesInfo, &serv); ! 835: if (serv.Revision != CS_RELEASE_CODE) { ! 836: printk(KERN_NOTICE "fmvj18x: Card Services release " ! 837: "does not match!\n"); ! 838: return -EINVAL; ! 839: } ! 840: register_pccard_driver(&dev_info, &fmvj18x_attach, &fmvj18x_detach); ! 841: return 0; ! 842: } ! 843: ! 844: static void __exit exit_fmvj18x_cs(void) ! 845: { ! 846: DEBUG(0, "fmvj18x_cs: unloading\n"); ! 847: unregister_pccard_driver(&dev_info); ! 848: while (dev_list != NULL) ! 849: fmvj18x_detach(dev_list); ! 850: } ! 851: ! 852: module_init(init_fmvj18x_cs); ! 853: module_exit(exit_fmvj18x_cs); ! 854: ! 855: /*====================================================================*/ ! 856: ! 857: static void fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs) ! 858: { ! 859: local_info_t *lp = dev_id; ! 860: struct net_device *dev = &lp->dev; ! 861: ioaddr_t ioaddr; ! 862: unsigned short tx_stat, rx_stat; ! 863: ! 864: if (lp == NULL) { ! 865: printk(KERN_NOTICE "fjn_interrupt(): irq %d for " ! 866: "unknown device.\n", irq); ! 867: return; ! 868: } ! 869: ioaddr = dev->base_addr; ! 870: ! 871: /* avoid multiple interrupts */ ! 872: outw(0x0000, ioaddr + TX_INTR); ! 873: ! 874: /* wait for a while */ ! 875: udelay(1); ! 876: ! 877: /* get status */ ! 878: tx_stat = inb(ioaddr + TX_STATUS); ! 879: rx_stat = inb(ioaddr + RX_STATUS); ! 880: ! 881: /* clear status */ ! 882: outb(tx_stat, ioaddr + TX_STATUS); ! 883: outb(rx_stat, ioaddr + RX_STATUS); ! 884: ! 885: DEBUG(4, "%s: interrupt, rx_status %02x.\n", dev->name, rx_stat); ! 886: DEBUG(4, " tx_status %02x.\n", tx_stat); ! 887: ! 888: if (rx_stat || (inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) { ! 889: /* there is packet(s) in rx buffer */ ! 890: fjn_rx(dev); ! 891: } ! 892: if (tx_stat & F_TMT_RDY) { ! 893: lp->stats.tx_packets += lp->sent ; ! 894: lp->sent = 0 ; ! 895: if (lp->tx_queue) { ! 896: outb(DO_TX | lp->tx_queue, ioaddr + TX_START); ! 897: lp->sent = lp->tx_queue ; ! 898: lp->tx_queue = 0; ! 899: lp->tx_queue_len = 0; ! 900: dev->trans_start = jiffies; ! 901: } else { ! 902: lp->tx_started = 0; ! 903: } ! 904: netif_wake_queue(dev); ! 905: } ! 906: DEBUG(4, "%s: exiting interrupt,\n", dev->name); ! 907: DEBUG(4, " tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat); ! 908: ! 909: outb(D_TX_INTR, ioaddr + TX_INTR); ! 910: outb(D_RX_INTR, ioaddr + RX_INTR); ! 911: ! 912: } /* fjn_interrupt */ ! 913: ! 914: /*====================================================================*/ ! 915: ! 916: static void fjn_tx_timeout(struct net_device *dev) ! 917: { ! 918: struct local_info_t *lp = (struct local_info_t *)dev->priv; ! 919: ioaddr_t ioaddr = dev->base_addr; ! 920: ! 921: printk(KERN_NOTICE "%s: transmit timed out with status %04x, %s?\n", ! 922: dev->name, htons(inw(ioaddr + TX_STATUS)), ! 923: inb(ioaddr + TX_STATUS) & F_TMT_RDY ! 924: ? "IRQ conflict" : "network cable problem"); ! 925: printk(KERN_NOTICE "%s: timeout registers: %04x %04x %04x " ! 926: "%04x %04x %04x %04x %04x.\n", ! 927: dev->name, htons(inw(ioaddr + 0)), ! 928: htons(inw(ioaddr + 2)), htons(inw(ioaddr + 4)), ! 929: htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)), ! 930: htons(inw(ioaddr +10)), htons(inw(ioaddr +12)), ! 931: htons(inw(ioaddr +14))); ! 932: lp->stats.tx_errors++; ! 933: /* ToDo: We should try to restart the adaptor... */ ! 934: cli(); ! 935: ! 936: fjn_reset(dev); ! 937: ! 938: lp->tx_started = 0; ! 939: lp->tx_queue = 0; ! 940: lp->tx_queue_len = 0; ! 941: lp->sent = 0; ! 942: lp->open_time = jiffies; ! 943: sti(); ! 944: netif_wake_queue(dev); ! 945: } ! 946: ! 947: static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev) ! 948: { ! 949: struct local_info_t *lp = (struct local_info_t *)dev->priv; ! 950: ioaddr_t ioaddr = dev->base_addr; ! 951: ! 952: tx_timeout_check(dev, fjn_tx_timeout); ! 953: skb_tx_check(dev, skb); ! 954: ! 955: { ! 956: short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; ! 957: unsigned char *buf = skb->data; ! 958: ! 959: if (length > ETH_FRAME_LEN) { ! 960: printk(KERN_NOTICE "%s: Attempting to send a large packet" ! 961: " (%d bytes).\n", dev->name, length); ! 962: return 1; ! 963: } ! 964: ! 965: DEBUG(4, "%s: Transmitting a packet of length %lu.\n", ! 966: dev->name, (unsigned long)skb->len); ! 967: add_tx_bytes(&lp->stats, skb->len); ! 968: ! 969: /* Disable both interrupts. */ ! 970: outw(0x0000, ioaddr + TX_INTR); ! 971: ! 972: /* wait for a while */ ! 973: udelay(1); ! 974: ! 975: outw(length, ioaddr + DATAPORT); ! 976: outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1); ! 977: ! 978: lp->tx_queue++; ! 979: lp->tx_queue_len += ((length+3) & ~1); ! 980: ! 981: if (lp->tx_started == 0) { ! 982: /* If the Tx is idle, always trigger a transmit. */ ! 983: outb(DO_TX | lp->tx_queue, ioaddr + TX_START); ! 984: lp->sent = lp->tx_queue ; ! 985: lp->tx_queue = 0; ! 986: lp->tx_queue_len = 0; ! 987: dev->trans_start = jiffies; ! 988: lp->tx_started = 1; ! 989: netif_start_queue(dev); ! 990: } else { ! 991: if( sram_config == 0 ) { ! 992: if (lp->tx_queue_len < (4096 - (ETH_FRAME_LEN +2)) ) ! 993: /* Yes, there is room for one more packet. */ ! 994: netif_start_queue(dev); ! 995: } else { ! 996: if (lp->tx_queue_len < (8192 - (ETH_FRAME_LEN +2)) && ! 997: lp->tx_queue < 127 ) ! 998: /* Yes, there is room for one more packet. */ ! 999: netif_start_queue(dev); ! 1000: } ! 1001: } ! 1002: ! 1003: /* Re-enable interrupts */ ! 1004: outb(D_TX_INTR, ioaddr + TX_INTR); ! 1005: outb(D_RX_INTR, ioaddr + RX_INTR); ! 1006: } ! 1007: DEV_KFREE_SKB (skb); ! 1008: ! 1009: return 0; ! 1010: } /* fjn_start_xmit */ ! 1011: ! 1012: /*====================================================================*/ ! 1013: ! 1014: static void fjn_reset(struct net_device *dev) ! 1015: { ! 1016: struct local_info_t *lp = (struct local_info_t *)dev->priv; ! 1017: ioaddr_t ioaddr = dev->base_addr; ! 1018: int i; ! 1019: ! 1020: DEBUG(4, "fjn_reset(%s) called.\n",dev->name); ! 1021: ! 1022: /* Reset controller */ ! 1023: if( sram_config == 0 ) ! 1024: outb(CONFIG0_RST, ioaddr + CONFIG_0); ! 1025: else ! 1026: outb(CONFIG0_RST_1, ioaddr + CONFIG_0); ! 1027: ! 1028: /* Power On chip and select bank 0 */ ! 1029: if (lp->cardtype == MBH10302) ! 1030: outb(BANK_0, ioaddr + CONFIG_1); ! 1031: else ! 1032: outb(BANK_0U, ioaddr + CONFIG_1); ! 1033: ! 1034: /* Set Tx modes */ ! 1035: outb(D_TX_MODE, ioaddr + TX_MODE); ! 1036: /* set Rx modes */ ! 1037: outb(ID_MATCHED, ioaddr + RX_MODE); ! 1038: ! 1039: /* Set hardware address */ ! 1040: for (i = 0; i < 6; i++) ! 1041: outb(dev->dev_addr[i], ioaddr + NODE_ID + i); ! 1042: ! 1043: /* Switch to bank 1 */ ! 1044: if (lp->cardtype == MBH10302) ! 1045: outb(BANK_1, ioaddr + CONFIG_1); ! 1046: else ! 1047: outb(BANK_1U, ioaddr + CONFIG_1); ! 1048: ! 1049: /* set the multicast table to accept none. */ ! 1050: for (i = 0; i < 6; i++) ! 1051: outb(0x00, ioaddr + MAR_ADR + i); ! 1052: ! 1053: /* Switch to bank 2 (runtime mode) */ ! 1054: if (lp->cardtype == MBH10302) ! 1055: outb(BANK_2, ioaddr + CONFIG_1); ! 1056: else ! 1057: outb(BANK_2U, ioaddr + CONFIG_1); ! 1058: ! 1059: /* set 16col ctrl bits */ ! 1060: if( lp->cardtype == TDK || lp->cardtype == CONTEC) ! 1061: outb(TDK_AUTO_MODE, ioaddr + COL_CTRL); ! 1062: else ! 1063: outb(AUTO_MODE, ioaddr + COL_CTRL); ! 1064: ! 1065: /* clear Reserved Regs */ ! 1066: outb(0x00, ioaddr + BMPR12); ! 1067: outb(0x00, ioaddr + BMPR13); ! 1068: ! 1069: /* reset Skip packet reg. */ ! 1070: outb(0x01, ioaddr + RX_SKIP); ! 1071: ! 1072: /* Enable Tx and Rx */ ! 1073: if( sram_config == 0 ) ! 1074: outb(CONFIG0_DFL, ioaddr + CONFIG_0); ! 1075: else ! 1076: outb(CONFIG0_DFL_1, ioaddr + CONFIG_0); ! 1077: ! 1078: /* Init receive pointer ? */ ! 1079: inw(ioaddr + DATAPORT); ! 1080: inw(ioaddr + DATAPORT); ! 1081: ! 1082: /* Clear all status */ ! 1083: outb(0xff, ioaddr + TX_STATUS); ! 1084: outb(0xff, ioaddr + RX_STATUS); ! 1085: ! 1086: if (lp->cardtype == MBH10302) ! 1087: outb(INTR_OFF, ioaddr + LAN_CTRL); ! 1088: ! 1089: /* Turn on Rx interrupts */ ! 1090: outb(D_TX_INTR, ioaddr + TX_INTR); ! 1091: outb(D_RX_INTR, ioaddr + RX_INTR); ! 1092: ! 1093: /* Turn on interrupts from LAN card controller */ ! 1094: if (lp->cardtype == MBH10302) ! 1095: outb(INTR_ON, ioaddr + LAN_CTRL); ! 1096: } /* fjn_reset */ ! 1097: ! 1098: /*====================================================================*/ ! 1099: ! 1100: static void fjn_rx(struct net_device *dev) ! 1101: { ! 1102: struct local_info_t *lp = (struct local_info_t *)dev->priv; ! 1103: ioaddr_t ioaddr = dev->base_addr; ! 1104: int boguscount = 10; /* 5 -> 10: by agy 19940922 */ ! 1105: ! 1106: DEBUG(4, "%s: in rx_packet(), rx_status %02x.\n", ! 1107: dev->name, inb(ioaddr + RX_STATUS)); ! 1108: ! 1109: while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) { ! 1110: u_short status = inw(ioaddr + DATAPORT); ! 1111: ! 1112: DEBUG(4, "%s: Rxing packet mode %02x status %04x.\n", ! 1113: dev->name, inb(ioaddr + RX_MODE), status); ! 1114: #ifndef final_version ! 1115: if (status == 0) { ! 1116: outb(F_SKP_PKT, ioaddr + RX_SKIP); ! 1117: break; ! 1118: } ! 1119: #endif ! 1120: if ((status & 0xF0) != 0x20) { /* There was an error. */ ! 1121: lp->stats.rx_errors++; ! 1122: if (status & F_LEN_ERR) lp->stats.rx_length_errors++; ! 1123: if (status & F_ALG_ERR) lp->stats.rx_frame_errors++; ! 1124: if (status & F_CRC_ERR) lp->stats.rx_crc_errors++; ! 1125: if (status & F_OVR_FLO) lp->stats.rx_over_errors++; ! 1126: } else { ! 1127: u_short pkt_len = inw(ioaddr + DATAPORT); ! 1128: /* Malloc up new buffer. */ ! 1129: struct sk_buff *skb; ! 1130: ! 1131: if (pkt_len > 1550) { ! 1132: printk(KERN_NOTICE "%s: The FMV-18x claimed a very " ! 1133: "large packet, size %d.\n", dev->name, pkt_len); ! 1134: outb(F_SKP_PKT, ioaddr + RX_SKIP); ! 1135: lp->stats.rx_errors++; ! 1136: break; ! 1137: } ! 1138: skb = dev_alloc_skb(pkt_len+2); ! 1139: if (skb == NULL) { ! 1140: printk(KERN_NOTICE "%s: Memory squeeze, dropping " ! 1141: "packet (len %d).\n", dev->name, pkt_len); ! 1142: outb(F_SKP_PKT, ioaddr + RX_SKIP); ! 1143: lp->stats.rx_dropped++; ! 1144: break; ! 1145: } ! 1146: skb->dev = dev; ! 1147: ! 1148: skb_reserve(skb, 2); ! 1149: insw(ioaddr + DATAPORT, skb_put(skb, pkt_len), ! 1150: (pkt_len + 1) >> 1); ! 1151: skb->protocol = eth_type_trans(skb, dev); ! 1152: ! 1153: #ifdef PCMCIA_DEBUG ! 1154: if (pc_debug > 5) { ! 1155: int i; ! 1156: printk(KERN_DEBUG "%s: Rxed packet of length %d: ", ! 1157: dev->name, pkt_len); ! 1158: for (i = 0; i < 14; i++) ! 1159: printk(" %02x", skb->data[i]); ! 1160: printk(".\n"); ! 1161: } ! 1162: #endif ! 1163: ! 1164: netif_rx(skb); ! 1165: dev->last_rx = jiffies; ! 1166: lp->stats.rx_packets++; ! 1167: add_rx_bytes(&lp->stats, pkt_len); ! 1168: } ! 1169: if (--boguscount <= 0) ! 1170: break; ! 1171: } ! 1172: ! 1173: /* If any worth-while packets have been received, dev_rint() ! 1174: has done a netif_wake_queue() for us and will work on them ! 1175: when we get to the bottom-half routine. */ ! 1176: /* ! 1177: if (lp->cardtype != TDK) { ! 1178: int i; ! 1179: for (i = 0; i < 20; i++) { ! 1180: if ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == F_BUF_EMP) ! 1181: break; ! 1182: (void)inw(ioaddr + DATAPORT); /+ dummy status read +/ ! 1183: outb(F_SKP_PKT, ioaddr + RX_SKIP); ! 1184: } ! 1185: ! 1186: if (i > 0) ! 1187: DEBUG(5, "%s: Exint Rx packet with mode %02x after " ! 1188: "%d ticks.\n", dev->name, inb(ioaddr + RX_MODE), i); ! 1189: } ! 1190: */ ! 1191: ! 1192: return; ! 1193: } /* fjn_rx */ ! 1194: ! 1195: /*====================================================================*/ ! 1196: ! 1197: static int fjn_config(struct net_device *dev, struct ifmap *map){ ! 1198: return 0; ! 1199: } ! 1200: ! 1201: static int fjn_open(struct net_device *dev) ! 1202: { ! 1203: struct local_info_t *lp = (struct local_info_t *)dev->priv; ! 1204: dev_link_t *link = &lp->link; ! 1205: ! 1206: DEBUG(4, "fjn_open('%s').\n", dev->name); ! 1207: ! 1208: if (!DEV_OK(link)) ! 1209: return -ENODEV; ! 1210: ! 1211: link->open++; ! 1212: ! 1213: fjn_reset(dev); ! 1214: ! 1215: lp->tx_started = 0; ! 1216: lp->tx_queue = 0; ! 1217: lp->tx_queue_len = 0; ! 1218: lp->open_time = jiffies; ! 1219: netif_mark_up(dev); ! 1220: netif_start_queue(dev); ! 1221: ! 1222: MOD_INC_USE_COUNT; ! 1223: ! 1224: return 0; ! 1225: } /* fjn_open */ ! 1226: ! 1227: /*====================================================================*/ ! 1228: ! 1229: static int fjn_close(struct net_device *dev) ! 1230: { ! 1231: struct local_info_t *lp = (struct local_info_t *)dev->priv; ! 1232: dev_link_t *link = &lp->link; ! 1233: ioaddr_t ioaddr = dev->base_addr; ! 1234: ! 1235: DEBUG(4, "fjn_close('%s').\n", dev->name); ! 1236: ! 1237: lp->open_time = 0; ! 1238: netif_stop_queue(dev); ! 1239: netif_mark_down(dev); ! 1240: ! 1241: /* Set configuration register 0 to disable Tx and Rx. */ ! 1242: if( sram_config == 0 ) ! 1243: outb(CONFIG0_RST ,ioaddr + CONFIG_0); ! 1244: else ! 1245: outb(CONFIG0_RST_1 ,ioaddr + CONFIG_0); ! 1246: ! 1247: /* Update the statistics -- ToDo. */ ! 1248: ! 1249: /* Power-down the chip. Green, green, green! */ ! 1250: outb(CHIP_OFF ,ioaddr + CONFIG_1); ! 1251: ! 1252: /* Set the ethernet adaptor disable IRQ */ ! 1253: if (lp->cardtype == MBH10302) ! 1254: outb(INTR_OFF, ioaddr + LAN_CTRL); ! 1255: ! 1256: link->open--; ! 1257: if (link->state & DEV_STALE_CONFIG) ! 1258: mod_timer(&link->release, jiffies + HZ/20); ! 1259: MOD_DEC_USE_COUNT; ! 1260: ! 1261: return 0; ! 1262: } /* fjn_close */ ! 1263: ! 1264: /*====================================================================*/ ! 1265: ! 1266: static struct net_device_stats *fjn_get_stats(struct net_device *dev) ! 1267: { ! 1268: local_info_t *lp = (local_info_t *)dev->priv; ! 1269: return &lp->stats; ! 1270: } /* fjn_get_stats */ ! 1271: ! 1272: /*====================================================================*/ ! 1273: ! 1274: /* ! 1275: Set the multicast/promiscuous mode for this adaptor. ! 1276: */ ! 1277: ! 1278: static void set_rx_mode(struct net_device *dev) ! 1279: { ! 1280: ioaddr_t ioaddr = dev->base_addr; ! 1281: struct local_info_t *lp = (struct local_info_t *)dev->priv; ! 1282: u_char mc_filter[8]; /* Multicast hash filter */ ! 1283: u_long flags; ! 1284: int i; ! 1285: ! 1286: if (dev->flags & IFF_PROMISC) { ! 1287: /* Unconditionally log net taps. */ ! 1288: printk("%s: Promiscuous mode enabled.\n", dev->name); ! 1289: memset(mc_filter, 0xff, sizeof(mc_filter)); ! 1290: outb(3, ioaddr + RX_MODE); /* Enable promiscuous mode */ ! 1291: } else if (dev->mc_count > MC_FILTERBREAK ! 1292: || (dev->flags & IFF_ALLMULTI)) { ! 1293: /* Too many to filter perfectly -- accept all multicasts. */ ! 1294: memset(mc_filter, 0xff, sizeof(mc_filter)); ! 1295: outb(2, ioaddr + RX_MODE); /* Use normal mode. */ ! 1296: } else if (dev->mc_count == 0) { ! 1297: memset(mc_filter, 0x00, sizeof(mc_filter)); ! 1298: outb(1, ioaddr + RX_MODE); /* Ignore almost all multicasts. */ ! 1299: } else { ! 1300: struct dev_mc_list *mclist; ! 1301: int i; ! 1302: ! 1303: memset(mc_filter, 0, sizeof(mc_filter)); ! 1304: for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; ! 1305: i++, mclist = mclist->next) ! 1306: set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f, ! 1307: mc_filter); ! 1308: } ! 1309: ! 1310: save_flags(flags); ! 1311: cli(); ! 1312: if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) { ! 1313: int saved_bank = inb(ioaddr + CONFIG_1); ! 1314: /* Switch to bank 1 and set the multicast table. */ ! 1315: outb(0xe4, ioaddr + CONFIG_1); ! 1316: for (i = 0; i < 8; i++) ! 1317: outb(mc_filter[i], ioaddr + 8 + i); ! 1318: memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter)); ! 1319: outb(saved_bank, ioaddr + CONFIG_1); ! 1320: } ! 1321: restore_flags(flags); ! 1322: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.