|
|
1.1 ! root 1: /* ---------------------------------------------------------------------------- ! 2: Linux PCMCIA ethernet adapter driver for the New Media Ethernet LAN. ! 3: nmclan_cs.c,v 0.16 1995/07/01 06:42:17 rpao Exp rpao ! 4: ! 5: The Ethernet LAN uses the Advanced Micro Devices (AMD) Am79C940 Media ! 6: Access Controller for Ethernet (MACE). It is essentially the Am2150 ! 7: PCMCIA Ethernet card contained in the Am2150 Demo Kit. ! 8: ! 9: Written by Roger C. Pao <[email protected]> ! 10: Copyright 1995 Roger C. Pao ! 11: ! 12: This software may be used and distributed according to the terms of ! 13: the GNU General Public License. ! 14: ! 15: Ported to Linux 1.3.* network driver environment by ! 16: Matti Aarnio <[email protected]> ! 17: ! 18: References ! 19: ! 20: Am2150 Technical Reference Manual, Revision 1.0, August 17, 1993 ! 21: Am79C940 (MACE) Data Sheet, 1994 ! 22: Am79C90 (C-LANCE) Data Sheet, 1994 ! 23: Linux PCMCIA Programmer's Guide v1.17 ! 24: /usr/src/linux/net/inet/dev.c, Linux kernel 1.2.8 ! 25: ! 26: Eric Mears, New Media Corporation ! 27: Tom Pollard, New Media Corporation ! 28: Dean Siasoyco, New Media Corporation ! 29: Ken Lesniak, Silicon Graphics, Inc. <[email protected]> ! 30: Donald Becker <[email protected]> ! 31: David Hinds <[email protected]> ! 32: ! 33: The Linux client driver is based on the 3c589_cs.c client driver by ! 34: David Hinds. ! 35: ! 36: The Linux network driver outline is based on the 3c589_cs.c driver, ! 37: the 8390.c driver, and the example skeleton.c kernel code, which are ! 38: by Donald Becker. ! 39: ! 40: The Am2150 network driver hardware interface code is based on the ! 41: OS/9000 driver for the New Media Ethernet LAN by Eric Mears. ! 42: ! 43: Special thanks for testing and help in debugging this driver goes ! 44: to Ken Lesniak. ! 45: ! 46: ------------------------------------------------------------------------------- ! 47: Driver Notes and Issues ! 48: ------------------------------------------------------------------------------- ! 49: ! 50: 1. Developed on a Dell 320SLi ! 51: PCMCIA Card Services 2.6.2 ! 52: Linux dell 1.2.10 #1 Thu Jun 29 20:23:41 PDT 1995 i386 ! 53: ! 54: 2. rc.pcmcia may require loading pcmcia_core with io_speed=300: ! 55: 'insmod pcmcia_core.o io_speed=300'. ! 56: This will avoid problems with fast systems which causes rx_framecnt ! 57: to return random values. ! 58: ! 59: 3. If hot extraction does not work for you, use 'ifconfig eth0 down' ! 60: before extraction. ! 61: ! 62: 4. There is a bad slow-down problem in this driver. ! 63: ! 64: 5. Future: Multicast processing. In the meantime, do _not_ compile your ! 65: kernel with multicast ip enabled. ! 66: ! 67: ------------------------------------------------------------------------------- ! 68: History ! 69: ------------------------------------------------------------------------------- ! 70: Log: nmclan_cs.c,v ! 71: * Revision 0.16 1995/07/01 06:42:17 rpao ! 72: * Bug fix: nmclan_reset() called CardServices incorrectly. ! 73: * ! 74: * Revision 0.15 1995/05/24 08:09:47 rpao ! 75: * Re-implement MULTI_TX dev->tbusy handling. ! 76: * ! 77: * Revision 0.14 1995/05/23 03:19:30 rpao ! 78: * Added, in nmclan_config(), "tuple.Attributes = 0;". ! 79: * Modified MACE ID check to ignore chip revision level. ! 80: * Avoid tx_free_frames race condition between _start_xmit and _interrupt. ! 81: * ! 82: * Revision 0.13 1995/05/18 05:56:34 rpao ! 83: * Statistics changes. ! 84: * Bug fix: nmclan_reset did not enable TX and RX: call restore_multicast_list. ! 85: * Bug fix: mace_interrupt checks ~MACE_IMR_DEFAULT. Fixes driver lockup. ! 86: * ! 87: * Revision 0.12 1995/05/14 00:12:23 rpao ! 88: * Statistics overhaul. ! 89: * ! 90: ! 91: 95/05/13 rpao V0.10a ! 92: Bug fix: MACE statistics counters used wrong I/O ports. ! 93: Bug fix: mace_interrupt() needed to allow statistics to be ! 94: processed without RX or TX interrupts pending. ! 95: 95/05/11 rpao V0.10 ! 96: Multiple transmit request processing. ! 97: Modified statistics to use MACE counters where possible. ! 98: 95/05/10 rpao V0.09 Bug fix: Must use IO_DATA_PATH_WIDTH_AUTO. ! 99: *Released ! 100: 95/05/10 rpao V0.08 ! 101: Bug fix: Make all non-exported functions private by using ! 102: static keyword. ! 103: Bug fix: Test IntrCnt _before_ reading MACE_IR. ! 104: 95/05/10 rpao V0.07 Statistics. ! 105: 95/05/09 rpao V0.06 Fix rx_framecnt problem by addition of PCIC wait states. ! 106: ! 107: ---------------------------------------------------------------------------- */ ! 108: ! 109: /* ---------------------------------------------------------------------------- ! 110: Conditional Compilation Options ! 111: ---------------------------------------------------------------------------- */ ! 112: ! 113: #define MULTI_TX 0 ! 114: #define RESET_ON_TIMEOUT 1 ! 115: #define TX_INTERRUPTABLE 1 ! 116: #define RESET_XILINX 0 ! 117: ! 118: /* ---------------------------------------------------------------------------- ! 119: Include Files ! 120: ---------------------------------------------------------------------------- */ ! 121: ! 122: #include <linux/module.h> ! 123: #include <linux/kernel.h> ! 124: #include <linux/init.h> ! 125: #include <linux/sched.h> ! 126: #include <linux/ptrace.h> ! 127: #include <linux/slab.h> ! 128: #include <linux/string.h> ! 129: #include <linux/timer.h> ! 130: #include <linux/interrupt.h> ! 131: #include <linux/in.h> ! 132: #include <linux/delay.h> ! 133: #include <asm/io.h> ! 134: #include <asm/system.h> ! 135: #include <asm/bitops.h> ! 136: ! 137: #include <linux/netdevice.h> ! 138: #include <linux/etherdevice.h> ! 139: #include <linux/skbuff.h> ! 140: #include <linux/if_arp.h> ! 141: #include <linux/ioport.h> ! 142: ! 143: #include <pcmcia/version.h> ! 144: #include <pcmcia/cs_types.h> ! 145: #include <pcmcia/cs.h> ! 146: #include <pcmcia/cisreg.h> ! 147: #include <pcmcia/cistpl.h> ! 148: #include <pcmcia/ds.h> ! 149: ! 150: /* ---------------------------------------------------------------------------- ! 151: Defines ! 152: ---------------------------------------------------------------------------- */ ! 153: ! 154: #define ETHER_ADDR_LEN ETH_ALEN ! 155: /* 6 bytes in an Ethernet Address */ ! 156: #define MACE_LADRF_LEN 8 ! 157: /* 8 bytes in Logical Address Filter */ ! 158: ! 159: /* Loop Control Defines */ ! 160: #define MACE_MAX_IR_ITERATIONS 10 ! 161: #define MACE_MAX_RX_ITERATIONS 12 ! 162: /* ! 163: TBD: Dean brought this up, and I assumed the hardware would ! 164: handle it: ! 165: ! 166: If MACE_MAX_RX_ITERATIONS is > 1, rx_framecnt may still be ! 167: non-zero when the isr exits. We may not get another interrupt ! 168: to process the remaining packets for some time. ! 169: */ ! 170: ! 171: /* ! 172: The Am2150 has a Xilinx XC3042 field programmable gate array (FPGA) ! 173: which manages the interface between the MACE and the PCMCIA bus. It ! 174: also includes buffer management for the 32K x 8 SRAM to control up to ! 175: four transmit and 12 receive frames at a time. ! 176: */ ! 177: #define AM2150_MAX_TX_FRAMES 4 ! 178: #define AM2150_MAX_RX_FRAMES 12 ! 179: ! 180: /* Am2150 Ethernet Card I/O Mapping */ ! 181: #define AM2150_RCV 0x00 ! 182: #define AM2150_XMT 0x04 ! 183: #define AM2150_XMT_SKIP 0x09 ! 184: #define AM2150_RCV_NEXT 0x0A ! 185: #define AM2150_RCV_FRAME_COUNT 0x0B ! 186: #define AM2150_MACE_BANK 0x0C ! 187: #define AM2150_MACE_BASE 0x10 ! 188: ! 189: /* MACE Registers */ ! 190: #define MACE_RCVFIFO 0 ! 191: #define MACE_XMTFIFO 1 ! 192: #define MACE_XMTFC 2 ! 193: #define MACE_XMTFS 3 ! 194: #define MACE_XMTRC 4 ! 195: #define MACE_RCVFC 5 ! 196: #define MACE_RCVFS 6 ! 197: #define MACE_FIFOFC 7 ! 198: #define MACE_IR 8 ! 199: #define MACE_IMR 9 ! 200: #define MACE_PR 10 ! 201: #define MACE_BIUCC 11 ! 202: #define MACE_FIFOCC 12 ! 203: #define MACE_MACCC 13 ! 204: #define MACE_PLSCC 14 ! 205: #define MACE_PHYCC 15 ! 206: #define MACE_CHIPIDL 16 ! 207: #define MACE_CHIPIDH 17 ! 208: #define MACE_IAC 18 ! 209: /* Reserved */ ! 210: #define MACE_LADRF 20 ! 211: #define MACE_PADR 21 ! 212: /* Reserved */ ! 213: /* Reserved */ ! 214: #define MACE_MPC 24 ! 215: /* Reserved */ ! 216: #define MACE_RNTPC 26 ! 217: #define MACE_RCVCC 27 ! 218: /* Reserved */ ! 219: #define MACE_UTR 29 ! 220: #define MACE_RTR1 30 ! 221: #define MACE_RTR2 31 ! 222: ! 223: /* MACE Bit Masks */ ! 224: #define MACE_XMTRC_EXDEF 0x80 ! 225: #define MACE_XMTRC_XMTRC 0x0F ! 226: ! 227: #define MACE_XMTFS_XMTSV 0x80 ! 228: #define MACE_XMTFS_UFLO 0x40 ! 229: #define MACE_XMTFS_LCOL 0x20 ! 230: #define MACE_XMTFS_MORE 0x10 ! 231: #define MACE_XMTFS_ONE 0x08 ! 232: #define MACE_XMTFS_DEFER 0x04 ! 233: #define MACE_XMTFS_LCAR 0x02 ! 234: #define MACE_XMTFS_RTRY 0x01 ! 235: ! 236: #define MACE_RCVFS_RCVSTS 0xF000 ! 237: #define MACE_RCVFS_OFLO 0x8000 ! 238: #define MACE_RCVFS_CLSN 0x4000 ! 239: #define MACE_RCVFS_FRAM 0x2000 ! 240: #define MACE_RCVFS_FCS 0x1000 ! 241: ! 242: #define MACE_FIFOFC_RCVFC 0xF0 ! 243: #define MACE_FIFOFC_XMTFC 0x0F ! 244: ! 245: #define MACE_IR_JAB 0x80 ! 246: #define MACE_IR_BABL 0x40 ! 247: #define MACE_IR_CERR 0x20 ! 248: #define MACE_IR_RCVCCO 0x10 ! 249: #define MACE_IR_RNTPCO 0x08 ! 250: #define MACE_IR_MPCO 0x04 ! 251: #define MACE_IR_RCVINT 0x02 ! 252: #define MACE_IR_XMTINT 0x01 ! 253: ! 254: #define MACE_MACCC_PROM 0x80 ! 255: #define MACE_MACCC_DXMT2PD 0x40 ! 256: #define MACE_MACCC_EMBA 0x20 ! 257: #define MACE_MACCC_RESERVED 0x10 ! 258: #define MACE_MACCC_DRCVPA 0x08 ! 259: #define MACE_MACCC_DRCVBC 0x04 ! 260: #define MACE_MACCC_ENXMT 0x02 ! 261: #define MACE_MACCC_ENRCV 0x01 ! 262: ! 263: #define MACE_PHYCC_LNKFL 0x80 ! 264: #define MACE_PHYCC_DLNKTST 0x40 ! 265: #define MACE_PHYCC_REVPOL 0x20 ! 266: #define MACE_PHYCC_DAPC 0x10 ! 267: #define MACE_PHYCC_LRT 0x08 ! 268: #define MACE_PHYCC_ASEL 0x04 ! 269: #define MACE_PHYCC_RWAKE 0x02 ! 270: #define MACE_PHYCC_AWAKE 0x01 ! 271: ! 272: #define MACE_IAC_ADDRCHG 0x80 ! 273: #define MACE_IAC_PHYADDR 0x04 ! 274: #define MACE_IAC_LOGADDR 0x02 ! 275: ! 276: #define MACE_UTR_RTRE 0x80 ! 277: #define MACE_UTR_RTRD 0x40 ! 278: #define MACE_UTR_RPA 0x20 ! 279: #define MACE_UTR_FCOLL 0x10 ! 280: #define MACE_UTR_RCVFCSE 0x08 ! 281: #define MACE_UTR_LOOP_INCL_MENDEC 0x06 ! 282: #define MACE_UTR_LOOP_NO_MENDEC 0x04 ! 283: #define MACE_UTR_LOOP_EXTERNAL 0x02 ! 284: #define MACE_UTR_LOOP_NONE 0x00 ! 285: #define MACE_UTR_RESERVED 0x01 ! 286: ! 287: /* Switch MACE register bank (only 0 and 1 are valid) */ ! 288: #define MACEBANK(win_num) outb((win_num), ioaddr + AM2150_MACE_BANK) ! 289: ! 290: #define MACE_IMR_DEFAULT \ ! 291: (0xFF - \ ! 292: ( \ ! 293: MACE_IR_CERR | \ ! 294: MACE_IR_RCVCCO | \ ! 295: MACE_IR_RNTPCO | \ ! 296: MACE_IR_MPCO | \ ! 297: MACE_IR_RCVINT | \ ! 298: MACE_IR_XMTINT \ ! 299: ) \ ! 300: ) ! 301: #undef MACE_IMR_DEFAULT ! 302: #define MACE_IMR_DEFAULT 0x00 /* New statistics handling: grab everything */ ! 303: ! 304: #define TX_TIMEOUT ((400*HZ)/1000) ! 305: ! 306: /* ---------------------------------------------------------------------------- ! 307: Type Definitions ! 308: ---------------------------------------------------------------------------- */ ! 309: ! 310: typedef struct _mace_statistics { ! 311: /* MACE_XMTFS */ ! 312: int xmtsv; ! 313: int uflo; ! 314: int lcol; ! 315: int more; ! 316: int one; ! 317: int defer; ! 318: int lcar; ! 319: int rtry; ! 320: ! 321: /* MACE_XMTRC */ ! 322: int exdef; ! 323: int xmtrc; ! 324: ! 325: /* RFS1--Receive Status (RCVSTS) */ ! 326: int oflo; ! 327: int clsn; ! 328: int fram; ! 329: int fcs; ! 330: ! 331: /* RFS2--Runt Packet Count (RNTPC) */ ! 332: int rfs_rntpc; ! 333: ! 334: /* RFS3--Receive Collision Count (RCVCC) */ ! 335: int rfs_rcvcc; ! 336: ! 337: /* MACE_IR */ ! 338: int jab; ! 339: int babl; ! 340: int cerr; ! 341: int rcvcco; ! 342: int rntpco; ! 343: int mpco; ! 344: ! 345: /* MACE_MPC */ ! 346: int mpc; ! 347: ! 348: /* MACE_RNTPC */ ! 349: int rntpc; ! 350: ! 351: /* MACE_RCVCC */ ! 352: int rcvcc; ! 353: } mace_statistics; ! 354: ! 355: typedef struct _mace_private { ! 356: dev_link_t link; ! 357: struct net_device dev; ! 358: dev_node_t node; ! 359: struct net_device_stats linux_stats; /* Linux statistics counters */ ! 360: mace_statistics mace_stats; /* MACE chip statistics counters */ ! 361: ! 362: /* restore_multicast_list() state variables */ ! 363: int multicast_ladrf[MACE_LADRF_LEN]; /* Logical address filter */ ! 364: int multicast_num_addrs; ! 365: ! 366: char tx_free_frames; /* Number of free transmit frame buffers */ ! 367: char tx_irq_disabled; /* MACE TX interrupt disabled */ ! 368: } mace_private; ! 369: ! 370: /* ---------------------------------------------------------------------------- ! 371: Private Global Variables ! 372: ---------------------------------------------------------------------------- */ ! 373: ! 374: #ifdef PCMCIA_DEBUG ! 375: static char rcsid[] = ! 376: "nmclan_cs.c,v 0.16 1995/07/01 06:42:17 rpao Exp rpao"; ! 377: static char *version = ! 378: "nmclan_cs 0.16 (Roger C. Pao)"; ! 379: #endif ! 380: ! 381: static dev_info_t dev_info="nmclan_cs"; ! 382: static dev_link_t *dev_list=NULL; ! 383: ! 384: static char *if_names[]={ ! 385: "Auto", "10baseT", "BNC", ! 386: }; ! 387: ! 388: /* ---------------------------------------------------------------------------- ! 389: Parameters ! 390: These are the parameters that can be set during loading with ! 391: 'insmod'. ! 392: ---------------------------------------------------------------------------- */ ! 393: ! 394: MODULE_DESCRIPTION("New Media PCMCIA ethernet driver"); ! 395: MODULE_LICENSE("GPL"); ! 396: ! 397: #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") ! 398: ! 399: static int irq_list[4] = { -1 }; ! 400: MODULE_PARM(irq_list, "1-4i"); ! 401: ! 402: /* 0=auto, 1=10baseT, 2 = 10base2, default=auto */ ! 403: INT_MODULE_PARM(if_port, 0); ! 404: /* Bit map of interrupts to choose from */ ! 405: INT_MODULE_PARM(irq_mask, 0xdeb8); ! 406: ! 407: #ifdef PCMCIA_DEBUG ! 408: INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG); ! 409: #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) ! 410: #else ! 411: #define DEBUG(n, args...) ! 412: #endif ! 413: ! 414: /* ---------------------------------------------------------------------------- ! 415: Function Prototypes ! 416: ---------------------------------------------------------------------------- */ ! 417: ! 418: static void nmclan_config(dev_link_t *link); ! 419: static void nmclan_release(u_long arg); ! 420: static int nmclan_event(event_t event, int priority, ! 421: event_callback_args_t *args); ! 422: ! 423: static void nmclan_reset(struct net_device *dev); ! 424: static int mace_config(struct net_device *dev, struct ifmap *map); ! 425: static int mace_open(struct net_device *dev); ! 426: static int mace_close(struct net_device *dev); ! 427: static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev); ! 428: static void mace_tx_timeout(struct net_device *dev); ! 429: static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs); ! 430: static struct net_device_stats *mace_get_stats(struct net_device *dev); ! 431: static int mace_rx(struct net_device *dev, unsigned char RxCnt); ! 432: static void restore_multicast_list(struct net_device *dev); ! 433: ! 434: static void set_multicast_list(struct net_device *dev); ! 435: ! 436: static dev_link_t *nmclan_attach(void); ! 437: static void nmclan_detach(dev_link_t *); ! 438: ! 439: /* ---------------------------------------------------------------------------- ! 440: flush_stale_links ! 441: Clean up stale device structures ! 442: ---------------------------------------------------------------------------- */ ! 443: ! 444: static void flush_stale_links(void) ! 445: { ! 446: dev_link_t *link, *next; ! 447: for (link = dev_list; link; link = next) { ! 448: next = link->next; ! 449: if (link->state & DEV_STALE_LINK) ! 450: nmclan_detach(link); ! 451: } ! 452: } ! 453: ! 454: /* ---------------------------------------------------------------------------- ! 455: cs_error ! 456: Report a Card Services related error. ! 457: ---------------------------------------------------------------------------- */ ! 458: ! 459: static void cs_error(client_handle_t handle, int func, int ret) ! 460: { ! 461: error_info_t err = { func, ret }; ! 462: CardServices(ReportError, handle, &err); ! 463: } ! 464: ! 465: /* ---------------------------------------------------------------------------- ! 466: nmclan_attach ! 467: Creates an "instance" of the driver, allocating local data ! 468: structures for one device. The device is registered with Card ! 469: Services. ! 470: ---------------------------------------------------------------------------- */ ! 471: ! 472: static dev_link_t *nmclan_attach(void) ! 473: { ! 474: mace_private *lp; ! 475: dev_link_t *link; ! 476: struct net_device *dev; ! 477: client_reg_t client_reg; ! 478: int i, ret; ! 479: ! 480: DEBUG(0, "nmclan_attach()\n"); ! 481: DEBUG(1, "%s\n", rcsid); ! 482: flush_stale_links(); ! 483: ! 484: /* Create new ethernet device */ ! 485: lp = kmalloc(sizeof(*lp), GFP_KERNEL); ! 486: if (!lp) return NULL; ! 487: memset(lp, 0, sizeof(*lp)); ! 488: link = &lp->link; dev = &lp->dev; ! 489: link->priv = dev->priv = link->irq.Instance = lp; ! 490: ! 491: init_timer(&link->release); ! 492: link->release.function = &nmclan_release; ! 493: link->release.data = (u_long)link; ! 494: link->io.NumPorts1 = 32; ! 495: link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; ! 496: link->io.IOAddrLines = 5; ! 497: link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; ! 498: link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; ! 499: if (irq_list[0] == -1) ! 500: link->irq.IRQInfo2 = irq_mask; ! 501: else ! 502: for (i = 0; i < 4; i++) ! 503: link->irq.IRQInfo2 |= 1 << irq_list[i]; ! 504: link->irq.Handler = &mace_interrupt; ! 505: link->conf.Attributes = CONF_ENABLE_IRQ; ! 506: link->conf.Vcc = 50; ! 507: link->conf.IntType = INT_MEMORY_AND_IO; ! 508: link->conf.ConfigIndex = 1; ! 509: link->conf.Present = PRESENT_OPTION; ! 510: ! 511: lp->tx_free_frames=AM2150_MAX_TX_FRAMES; ! 512: ! 513: dev->hard_start_xmit = &mace_start_xmit; ! 514: dev->set_config = &mace_config; ! 515: dev->get_stats = &mace_get_stats; ! 516: dev->set_multicast_list = &set_multicast_list; ! 517: ether_setup(dev); ! 518: init_dev_name(dev, lp->node); ! 519: dev->open = &mace_open; ! 520: dev->stop = &mace_close; ! 521: #ifdef HAVE_TX_TIMEOUT ! 522: dev->tx_timeout = mace_tx_timeout; ! 523: dev->watchdog_timeo = TX_TIMEOUT; ! 524: #endif ! 525: ! 526: /* Register with Card Services */ ! 527: link->next = dev_list; ! 528: dev_list = link; ! 529: client_reg.dev_info = &dev_info; ! 530: client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; ! 531: client_reg.EventMask = ! 532: CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | ! 533: CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | ! 534: CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; ! 535: client_reg.event_handler = &nmclan_event; ! 536: client_reg.Version = 0x0210; ! 537: client_reg.event_callback_args.client_data = link; ! 538: ret = CardServices(RegisterClient, &link->handle, &client_reg); ! 539: if (ret != 0) { ! 540: cs_error(link->handle, RegisterClient, ret); ! 541: nmclan_detach(link); ! 542: return NULL; ! 543: } ! 544: ! 545: return link; ! 546: } /* nmclan_attach */ ! 547: ! 548: /* ---------------------------------------------------------------------------- ! 549: nmclan_detach ! 550: This deletes a driver "instance". The device is de-registered ! 551: with Card Services. If it has been released, all local data ! 552: structures are freed. Otherwise, the structures will be freed ! 553: when the device is released. ! 554: ---------------------------------------------------------------------------- */ ! 555: ! 556: static void nmclan_detach(dev_link_t *link) ! 557: { ! 558: mace_private *lp = link->priv; ! 559: dev_link_t **linkp; ! 560: ! 561: DEBUG(0, "nmclan_detach(0x%p)\n", link); ! 562: ! 563: /* Locate device structure */ ! 564: for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) ! 565: if (*linkp == link) break; ! 566: if (*linkp == NULL) ! 567: return; ! 568: ! 569: del_timer(&link->release); ! 570: if (link->state & DEV_CONFIG) { ! 571: nmclan_release((u_long)link); ! 572: if (link->state & DEV_STALE_CONFIG) { ! 573: link->state |= DEV_STALE_LINK; ! 574: return; ! 575: } ! 576: } ! 577: ! 578: if (link->handle) ! 579: CardServices(DeregisterClient, link->handle); ! 580: ! 581: /* Unlink device structure, free bits */ ! 582: *linkp = link->next; ! 583: if (link->dev) ! 584: unregister_netdev(&lp->dev); ! 585: kfree(lp); ! 586: ! 587: } /* nmclan_detach */ ! 588: ! 589: /* ---------------------------------------------------------------------------- ! 590: mace_read ! 591: Reads a MACE register. This is bank independent; however, the ! 592: caller must ensure that this call is not interruptable. We are ! 593: assuming that during normal operation, the MACE is always in ! 594: bank 0. ! 595: ---------------------------------------------------------------------------- */ ! 596: static int mace_read(ioaddr_t ioaddr, int reg) ! 597: { ! 598: int data = 0xFF; ! 599: unsigned long flags; ! 600: ! 601: switch (reg >> 4) { ! 602: case 0: /* register 0-15 */ ! 603: data = inb(ioaddr + AM2150_MACE_BASE + reg); ! 604: break; ! 605: case 1: /* register 16-31 */ ! 606: save_flags(flags); ! 607: cli(); ! 608: MACEBANK(1); ! 609: data = inb(ioaddr + AM2150_MACE_BASE + (reg & 0x0F)); ! 610: MACEBANK(0); ! 611: restore_flags(flags); ! 612: break; ! 613: } ! 614: return (data & 0xFF); ! 615: } /* mace_read */ ! 616: ! 617: /* ---------------------------------------------------------------------------- ! 618: mace_write ! 619: Writes to a MACE register. This is bank independent; however, ! 620: the caller must ensure that this call is not interruptable. We ! 621: are assuming that during normal operation, the MACE is always in ! 622: bank 0. ! 623: ---------------------------------------------------------------------------- */ ! 624: static void mace_write(ioaddr_t ioaddr, int reg, int data) ! 625: { ! 626: unsigned long flags; ! 627: ! 628: switch (reg >> 4) { ! 629: case 0: /* register 0-15 */ ! 630: outb(data & 0xFF, ioaddr + AM2150_MACE_BASE + reg); ! 631: break; ! 632: case 1: /* register 16-31 */ ! 633: save_flags(flags); ! 634: cli(); ! 635: MACEBANK(1); ! 636: outb(data & 0xFF, ioaddr + AM2150_MACE_BASE + (reg & 0x0F)); ! 637: MACEBANK(0); ! 638: restore_flags(flags); ! 639: break; ! 640: } ! 641: } /* mace_write */ ! 642: ! 643: /* ---------------------------------------------------------------------------- ! 644: mace_init ! 645: Resets the MACE chip. ! 646: ---------------------------------------------------------------------------- */ ! 647: static void mace_init(ioaddr_t ioaddr, char *enet_addr) ! 648: { ! 649: int i; ! 650: ! 651: /* MACE Software reset */ ! 652: mace_write(ioaddr, MACE_BIUCC, 1); ! 653: while (mace_read(ioaddr, MACE_BIUCC) & 0x01) { ! 654: /* Wait for reset bit to be cleared automatically after <= 200ns */; ! 655: } ! 656: mace_write(ioaddr, MACE_BIUCC, 0); ! 657: ! 658: /* The Am2150 requires that the MACE FIFOs operate in burst mode. */ ! 659: mace_write(ioaddr, MACE_FIFOCC, 0x0F); ! 660: ! 661: mace_write(ioaddr, MACE_RCVFC, 0); /* Disable Auto Strip Receive */ ! 662: mace_write(ioaddr, MACE_IMR, 0xFF); /* Disable all interrupts until _open */ ! 663: ! 664: /* ! 665: * Bit 2-1 PORTSEL[1-0] Port Select. ! 666: * 00 AUI/10Base-2 ! 667: * 01 10Base-T ! 668: * 10 DAI Port (reserved in Am2150) ! 669: * 11 GPSI ! 670: * For this card, only the first two are valid. ! 671: * So, PLSCC should be set to ! 672: * 0x00 for 10Base-2 ! 673: * 0x02 for 10Base-T ! 674: * Or just set ASEL in PHYCC below! ! 675: */ ! 676: switch (if_port) { ! 677: case 1: ! 678: mace_write(ioaddr, MACE_PLSCC, 0x02); ! 679: break; ! 680: case 2: ! 681: mace_write(ioaddr, MACE_PLSCC, 0x00); ! 682: break; ! 683: default: ! 684: mace_write(ioaddr, MACE_PHYCC, /* ASEL */ 4); ! 685: /* ASEL Auto Select. When set, the PORTSEL[1-0] bits are overridden, ! 686: and the MACE device will automatically select the operating media ! 687: interface port. */ ! 688: break; ! 689: } ! 690: ! 691: mace_write(ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_PHYADDR); ! 692: /* Poll ADDRCHG bit */ ! 693: while (mace_read(ioaddr, MACE_IAC) & MACE_IAC_ADDRCHG) ! 694: ; ! 695: /* Set PADR register */ ! 696: for (i = 0; i < ETHER_ADDR_LEN; i++) ! 697: mace_write(ioaddr, MACE_PADR, enet_addr[i]); ! 698: ! 699: /* MAC Configuration Control Register should be written last */ ! 700: /* Let set_multicast_list set this. */ ! 701: /* mace_write(ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV); */ ! 702: mace_write(ioaddr, MACE_MACCC, 0x00); ! 703: } /* mace_init */ ! 704: ! 705: /* ---------------------------------------------------------------------------- ! 706: nmclan_config ! 707: This routine is scheduled to run after a CARD_INSERTION event ! 708: is received, to configure the PCMCIA socket, and to make the ! 709: ethernet device available to the system. ! 710: ---------------------------------------------------------------------------- */ ! 711: ! 712: #define CS_CHECK(fn, args...) \ ! 713: while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed ! 714: ! 715: static void nmclan_config(dev_link_t *link) ! 716: { ! 717: client_handle_t handle = link->handle; ! 718: mace_private *lp = link->priv; ! 719: struct net_device *dev = &lp->dev; ! 720: tuple_t tuple; ! 721: cisparse_t parse; ! 722: u_char buf[64]; ! 723: int i, last_ret, last_fn; ! 724: ioaddr_t ioaddr; ! 725: ! 726: DEBUG(0, "nmclan_config(0x%p)\n", link); ! 727: ! 728: tuple.Attributes = 0; ! 729: tuple.TupleData = buf; ! 730: tuple.TupleDataMax = 64; ! 731: tuple.TupleOffset = 0; ! 732: tuple.DesiredTuple = CISTPL_CONFIG; ! 733: CS_CHECK(GetFirstTuple, handle, &tuple); ! 734: CS_CHECK(GetTupleData, handle, &tuple); ! 735: CS_CHECK(ParseTuple, handle, &tuple, &parse); ! 736: link->conf.ConfigBase = parse.config.base; ! 737: ! 738: /* Configure card */ ! 739: link->state |= DEV_CONFIG; ! 740: ! 741: CS_CHECK(RequestIO, handle, &link->io); ! 742: CS_CHECK(RequestIRQ, handle, &link->irq); ! 743: CS_CHECK(RequestConfiguration, handle, &link->conf); ! 744: dev->irq = link->irq.AssignedIRQ; ! 745: dev->base_addr = link->io.BasePort1; ! 746: i = register_netdev(dev); ! 747: if (i != 0) { ! 748: printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n"); ! 749: goto failed; ! 750: } ! 751: ! 752: ioaddr = dev->base_addr; ! 753: ! 754: /* Read the ethernet address from the CIS. */ ! 755: tuple.DesiredTuple = 0x80 /* CISTPL_CFTABLE_ENTRY_MISC */; ! 756: tuple.TupleData = buf; ! 757: tuple.TupleDataMax = 64; ! 758: tuple.TupleOffset = 0; ! 759: CS_CHECK(GetFirstTuple, handle, &tuple); ! 760: CS_CHECK(GetTupleData, handle, &tuple); ! 761: memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN); ! 762: ! 763: /* Verify configuration by reading the MACE ID. */ ! 764: { ! 765: char sig[2]; ! 766: ! 767: sig[0] = mace_read(ioaddr, MACE_CHIPIDL); ! 768: sig[1] = mace_read(ioaddr, MACE_CHIPIDH); ! 769: if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) { ! 770: DEBUG(0, "nmclan_cs configured: mace id=%x %x\n", ! 771: sig[0], sig[1]); ! 772: } else { ! 773: printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should" ! 774: " be 0x40 0x?9\n", sig[0], sig[1]); ! 775: link->state &= ~DEV_CONFIG_PENDING; ! 776: return; ! 777: } ! 778: } ! 779: ! 780: mace_init(ioaddr, dev->dev_addr); ! 781: ! 782: /* The if_port symbol can be set when the module is loaded */ ! 783: if (if_port <= 2) ! 784: dev->if_port = if_port; ! 785: else ! 786: printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n"); ! 787: ! 788: #if 0 ! 789: /* Determine which port we are using if auto is selected */ ! 790: if (if_port==0) { ! 791: mace_write(ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV); ! 792: DEBUG(2, "%s: mace_phycc 0x%X.\n", dev->name, ! 793: mace_read(ioaddr, MACE_PHYCC)); ! 794: if (mace_read(ioaddr, MACE_PHYCC) & MACE_PHYCC_LNKFL) ! 795: /* 10base-T receiver is in link fail, MACE is using AUI port. */ ! 796: dev->if_port = 2; ! 797: else ! 798: dev->if_port = 1; ! 799: mace_write(ioaddr, MACE_MACCC, 0x00); ! 800: } ! 801: /* Unfortunately, this doesn't seem to work. LNKFL is always set. ! 802: LNKFL is supposed to be opposite the green LED on the edge of the card. ! 803: It doesn't work if it is checked and printed in _open() either. ! 804: It does work if check in _start_xmit(), but that's not a good place ! 805: to printk. */ ! 806: #endif ! 807: ! 808: copy_dev_name(lp->node, dev); ! 809: link->dev = &lp->node; ! 810: link->state &= ~DEV_CONFIG_PENDING; ! 811: ! 812: printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port, hw_addr ", ! 813: dev->name, dev->base_addr, dev->irq, if_names[dev->if_port]); ! 814: for (i = 0; i < 6; i++) ! 815: printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); ! 816: return; ! 817: ! 818: cs_failed: ! 819: cs_error(link->handle, last_fn, last_ret); ! 820: failed: ! 821: nmclan_release((u_long)link); ! 822: link->state &= ~DEV_CONFIG_PENDING; ! 823: return; ! 824: ! 825: } /* nmclan_config */ ! 826: ! 827: /* ---------------------------------------------------------------------------- ! 828: nmclan_release ! 829: After a card is removed, nmclan_release() will unregister the ! 830: net device, and release the PCMCIA configuration. If the device ! 831: is still open, this will be postponed until it is closed. ! 832: ---------------------------------------------------------------------------- */ ! 833: static void nmclan_release(u_long arg) ! 834: { ! 835: dev_link_t *link = (dev_link_t *)arg; ! 836: ! 837: DEBUG(0, "nmclan_release(0x%p)\n", link); ! 838: ! 839: if (link->open) { ! 840: DEBUG(1, "nmclan_cs: release postponed, '%s' " ! 841: "still open\n", link->dev->dev_name); ! 842: link->state |= DEV_STALE_CONFIG; ! 843: return; ! 844: } ! 845: ! 846: CardServices(ReleaseConfiguration, link->handle); ! 847: CardServices(ReleaseIO, link->handle, &link->io); ! 848: CardServices(ReleaseIRQ, link->handle, &link->irq); ! 849: ! 850: link->state &= ~DEV_CONFIG; ! 851: ! 852: } /* nmclan_release */ ! 853: ! 854: /* ---------------------------------------------------------------------------- ! 855: nmclan_event ! 856: The card status event handler. Mostly, this schedules other ! 857: stuff to run after an event is received. A CARD_REMOVAL event ! 858: also sets some flags to discourage the net drivers from trying ! 859: to talk to the card any more. ! 860: ---------------------------------------------------------------------------- */ ! 861: static int nmclan_event(event_t event, int priority, ! 862: event_callback_args_t *args) ! 863: { ! 864: dev_link_t *link = args->client_data; ! 865: mace_private *lp = link->priv; ! 866: struct net_device *dev = &lp->dev; ! 867: ! 868: DEBUG(1, "nmclan_event(0x%06x)\n", event); ! 869: ! 870: switch (event) { ! 871: case CS_EVENT_CARD_REMOVAL: ! 872: link->state &= ~DEV_PRESENT; ! 873: if (link->state & DEV_CONFIG) { ! 874: netif_device_detach(dev); ! 875: mod_timer(&link->release, jiffies + HZ/20); ! 876: } ! 877: break; ! 878: case CS_EVENT_CARD_INSERTION: ! 879: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; ! 880: nmclan_config(link); ! 881: break; ! 882: case CS_EVENT_PM_SUSPEND: ! 883: link->state |= DEV_SUSPEND; ! 884: /* Fall through... */ ! 885: case CS_EVENT_RESET_PHYSICAL: ! 886: if (link->state & DEV_CONFIG) { ! 887: if (link->open) ! 888: netif_device_detach(dev); ! 889: CardServices(ReleaseConfiguration, link->handle); ! 890: } ! 891: break; ! 892: case CS_EVENT_PM_RESUME: ! 893: link->state &= ~DEV_SUSPEND; ! 894: /* Fall through... */ ! 895: case CS_EVENT_CARD_RESET: ! 896: if (link->state & DEV_CONFIG) { ! 897: CardServices(RequestConfiguration, link->handle, &link->conf); ! 898: if (link->open) { ! 899: nmclan_reset(dev); ! 900: netif_device_attach(dev); ! 901: } ! 902: } ! 903: break; ! 904: case CS_EVENT_RESET_REQUEST: ! 905: return 1; ! 906: break; ! 907: } ! 908: return 0; ! 909: } /* nmclan_event */ ! 910: ! 911: /* ---------------------------------------------------------------------------- ! 912: nmclan_reset ! 913: Reset and restore all of the Xilinx and MACE registers. ! 914: ---------------------------------------------------------------------------- */ ! 915: static void nmclan_reset(struct net_device *dev) ! 916: { ! 917: mace_private *lp = dev->priv; ! 918: ! 919: #if RESET_XILINX ! 920: dev_link_t *link = &lp->link; ! 921: conf_reg_t reg; ! 922: u_long OrigCorValue; ! 923: ! 924: /* Save original COR value */ ! 925: reg.Function = 0; ! 926: reg.Action = CS_READ; ! 927: reg.Offset = CISREG_COR; ! 928: reg.Value = 0; ! 929: CardServices(AccessConfigurationRegister, link->handle, ®); ! 930: OrigCorValue = reg.Value; ! 931: ! 932: /* Reset Xilinx */ ! 933: reg.Action = CS_WRITE; ! 934: reg.Offset = CISREG_COR; ! 935: DEBUG(1, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n", ! 936: OrigCorValue); ! 937: reg.Value = COR_SOFT_RESET; ! 938: CardServices(AccessConfigurationRegister, link->handle, ®); ! 939: /* Need to wait for 20 ms for PCMCIA to finish reset. */ ! 940: ! 941: /* Restore original COR configuration index */ ! 942: reg.Value = COR_LEVEL_REQ | (OrigCorValue & COR_CONFIG_MASK); ! 943: CardServices(AccessConfigurationRegister, link->handle, ®); ! 944: /* Xilinx is now completely reset along with the MACE chip. */ ! 945: lp->tx_free_frames=AM2150_MAX_TX_FRAMES; ! 946: ! 947: #endif /* #if RESET_XILINX */ ! 948: ! 949: /* Xilinx is now completely reset along with the MACE chip. */ ! 950: lp->tx_free_frames=AM2150_MAX_TX_FRAMES; ! 951: ! 952: /* Reinitialize the MACE chip for operation. */ ! 953: mace_init(dev->base_addr, dev->dev_addr); ! 954: mace_write(dev->base_addr, MACE_IMR, MACE_IMR_DEFAULT); ! 955: ! 956: /* Restore the multicast list and enable TX and RX. */ ! 957: restore_multicast_list(dev); ! 958: } /* nmclan_reset */ ! 959: ! 960: /* ---------------------------------------------------------------------------- ! 961: mace_config ! 962: [Someone tell me what this is supposed to do? Is if_port a defined ! 963: standard? If so, there should be defines to indicate 1=10Base-T, ! 964: 2=10Base-2, etc. including limited automatic detection.] ! 965: ---------------------------------------------------------------------------- */ ! 966: static int mace_config(struct net_device *dev, struct ifmap *map) ! 967: { ! 968: if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { ! 969: if (map->port <= 2) { ! 970: dev->if_port = map->port; ! 971: printk(KERN_INFO "%s: switched to %s port\n", dev->name, ! 972: if_names[dev->if_port]); ! 973: } else ! 974: return -EINVAL; ! 975: } ! 976: return 0; ! 977: } /* mace_config */ ! 978: ! 979: /* ---------------------------------------------------------------------------- ! 980: mace_open ! 981: Open device driver. ! 982: ---------------------------------------------------------------------------- */ ! 983: static int mace_open(struct net_device *dev) ! 984: { ! 985: ioaddr_t ioaddr = dev->base_addr; ! 986: mace_private *lp = dev->priv; ! 987: dev_link_t *link = &lp->link; ! 988: ! 989: if (!DEV_OK(link)) ! 990: return -ENODEV; ! 991: ! 992: link->open++; ! 993: MOD_INC_USE_COUNT; ! 994: ! 995: MACEBANK(0); ! 996: ! 997: netif_start_queue(dev); ! 998: netif_mark_up(dev); ! 999: nmclan_reset(dev); ! 1000: ! 1001: return 0; /* Always succeed */ ! 1002: } /* mace_open */ ! 1003: ! 1004: /* ---------------------------------------------------------------------------- ! 1005: mace_close ! 1006: Closes device driver. ! 1007: ---------------------------------------------------------------------------- */ ! 1008: static int mace_close(struct net_device *dev) ! 1009: { ! 1010: ioaddr_t ioaddr = dev->base_addr; ! 1011: mace_private *lp = dev->priv; ! 1012: dev_link_t *link = &lp->link; ! 1013: ! 1014: DEBUG(2, "%s: shutting down ethercard.\n", dev->name); ! 1015: ! 1016: /* Mask off all interrupts from the MACE chip. */ ! 1017: outb(0xFF, ioaddr + AM2150_MACE_BASE + MACE_IMR); ! 1018: ! 1019: link->open--; ! 1020: netif_stop_queue(dev); ! 1021: netif_mark_down(dev); ! 1022: if (link->state & DEV_STALE_CONFIG) ! 1023: mod_timer(&link->release, jiffies + HZ/20); ! 1024: ! 1025: MOD_DEC_USE_COUNT; ! 1026: ! 1027: return 0; ! 1028: } /* mace_close */ ! 1029: ! 1030: /* ---------------------------------------------------------------------------- ! 1031: mace_start_xmit ! 1032: This routine begins the packet transmit function. When completed, ! 1033: it will generate a transmit interrupt. ! 1034: ! 1035: According to /usr/src/linux/net/inet/dev.c, if _start_xmit ! 1036: returns 0, the "packet is now solely the responsibility of the ! 1037: driver." If _start_xmit returns non-zero, the "transmission ! 1038: failed, put skb back into a list." ! 1039: ---------------------------------------------------------------------------- */ ! 1040: ! 1041: static void mace_tx_timeout(struct net_device *dev) ! 1042: { ! 1043: mace_private *lp = (mace_private *)dev->priv; ! 1044: dev_link_t *link = &lp->link; ! 1045: ! 1046: printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name); ! 1047: #if RESET_ON_TIMEOUT ! 1048: printk("resetting card\n"); ! 1049: CardServices(ResetCard, link->handle); ! 1050: #else /* #if RESET_ON_TIMEOUT */ ! 1051: printk("NOT resetting card\n"); ! 1052: #endif /* #if RESET_ON_TIMEOUT */ ! 1053: dev->trans_start = jiffies; ! 1054: netif_wake_queue(dev); ! 1055: } ! 1056: ! 1057: static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev) ! 1058: { ! 1059: mace_private *lp = (mace_private *)dev->priv; ! 1060: ioaddr_t ioaddr = dev->base_addr; ! 1061: ! 1062: tx_timeout_check(dev, mace_tx_timeout); ! 1063: skb_tx_check(dev, skb); ! 1064: ! 1065: DEBUG(3, "%s: mace_start_xmit(length = %ld) called.\n", ! 1066: dev->name, (long)skb->len); ! 1067: ! 1068: #if (!TX_INTERRUPTABLE) ! 1069: /* Disable MACE TX interrupts. */ ! 1070: outb(MACE_IMR_DEFAULT | MACE_IR_XMTINT, ! 1071: ioaddr + AM2150_MACE_BASE + MACE_IMR); ! 1072: lp->tx_irq_disabled=1; ! 1073: #endif /* #if (!TX_INTERRUPTABLE) */ ! 1074: ! 1075: { ! 1076: /* This block must not be interrupted by another transmit request! ! 1077: mace_tx_timeout will take care of timer-based retransmissions from ! 1078: the upper layers. The interrupt handler is guaranteed never to ! 1079: service a transmit interrupt while we are in here. ! 1080: */ ! 1081: ! 1082: add_tx_bytes(&lp->linux_stats, skb->len); ! 1083: lp->tx_free_frames--; ! 1084: ! 1085: /* WARNING: Write the _exact_ number of bytes written in the header! */ ! 1086: /* Put out the word header [must be an outw()] . . . */ ! 1087: outw(skb->len, ioaddr + AM2150_XMT); ! 1088: /* . . . and the packet [may be any combination of outw() and outb()] */ ! 1089: outsw(ioaddr + AM2150_XMT, skb->data, skb->len >> 1); ! 1090: if (skb->len & 1) { ! 1091: /* Odd byte transfer */ ! 1092: outb(skb->data[skb->len-1], ioaddr + AM2150_XMT); ! 1093: } ! 1094: ! 1095: dev->trans_start = jiffies; ! 1096: ! 1097: #if MULTI_TX ! 1098: if (lp->tx_free_frames > 0) ! 1099: netif_start_queue(dev); ! 1100: #endif /* #if MULTI_TX */ ! 1101: } ! 1102: ! 1103: #if (!TX_INTERRUPTABLE) ! 1104: /* Re-enable MACE TX interrupts. */ ! 1105: lp->tx_irq_disabled=0; ! 1106: outb(MACE_IMR_DEFAULT, ioaddr + AM2150_MACE_BASE + MACE_IMR); ! 1107: #endif /* #if (!TX_INTERRUPTABLE) */ ! 1108: ! 1109: DEV_KFREE_SKB(skb); ! 1110: ! 1111: return 0; ! 1112: } /* mace_start_xmit */ ! 1113: ! 1114: /* ---------------------------------------------------------------------------- ! 1115: mace_interrupt ! 1116: The interrupt handler. ! 1117: ---------------------------------------------------------------------------- */ ! 1118: static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs) ! 1119: { ! 1120: mace_private *lp = (mace_private *)dev_id; ! 1121: struct net_device *dev = &lp->dev; ! 1122: ioaddr_t ioaddr = dev->base_addr; ! 1123: int status; ! 1124: int IntrCnt = MACE_MAX_IR_ITERATIONS; ! 1125: ! 1126: if (dev == NULL) { ! 1127: DEBUG(2, "mace_interrupt(): irq 0x%X for unknown device.\n", ! 1128: irq); ! 1129: return; ! 1130: } ! 1131: ! 1132: if (lp->tx_irq_disabled) { ! 1133: printk( ! 1134: (lp->tx_irq_disabled? ! 1135: KERN_NOTICE "%s: Interrupt with tx_irq_disabled " ! 1136: "[isr=%02X, imr=%02X]\n": ! 1137: KERN_NOTICE "%s: Re-entering the interrupt handler " ! 1138: "[isr=%02X, imr=%02X]\n"), ! 1139: dev->name, ! 1140: inb(ioaddr + AM2150_MACE_BASE + MACE_IR), ! 1141: inb(ioaddr + AM2150_MACE_BASE + MACE_IMR) ! 1142: ); ! 1143: /* WARNING: MACE_IR has been read! */ ! 1144: return; ! 1145: } ! 1146: ! 1147: if (!netif_device_present(dev)) { ! 1148: DEBUG(2, "%s: interrupt from dead card\n", dev->name); ! 1149: goto exception; ! 1150: } ! 1151: ! 1152: do { ! 1153: /* WARNING: MACE_IR is a READ/CLEAR port! */ ! 1154: status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR); ! 1155: ! 1156: DEBUG(3, "mace_interrupt: irq 0x%X status 0x%X.\n", irq, status); ! 1157: ! 1158: if (status & MACE_IR_RCVINT) { ! 1159: mace_rx(dev, MACE_MAX_RX_ITERATIONS); ! 1160: } ! 1161: ! 1162: if (status & MACE_IR_XMTINT) { ! 1163: unsigned char fifofc; ! 1164: unsigned char xmtrc; ! 1165: unsigned char xmtfs; ! 1166: ! 1167: fifofc = inb(ioaddr + AM2150_MACE_BASE + MACE_FIFOFC); ! 1168: if ((fifofc & MACE_FIFOFC_XMTFC)==0) { ! 1169: lp->linux_stats.tx_errors++; ! 1170: outb(0xFF, ioaddr + AM2150_XMT_SKIP); ! 1171: } ! 1172: ! 1173: /* Transmit Retry Count (XMTRC, reg 4) */ ! 1174: xmtrc = inb(ioaddr + AM2150_MACE_BASE + MACE_XMTRC); ! 1175: if (xmtrc & MACE_XMTRC_EXDEF) lp->mace_stats.exdef++; ! 1176: lp->mace_stats.xmtrc += (xmtrc & MACE_XMTRC_XMTRC); ! 1177: ! 1178: if ( ! 1179: (xmtfs = inb(ioaddr + AM2150_MACE_BASE + MACE_XMTFS)) & ! 1180: MACE_XMTFS_XMTSV /* Transmit Status Valid */ ! 1181: ) { ! 1182: lp->mace_stats.xmtsv++; ! 1183: ! 1184: if (xmtfs & ~MACE_XMTFS_XMTSV) { ! 1185: if (xmtfs & MACE_XMTFS_UFLO) { ! 1186: /* Underflow. Indicates that the Transmit FIFO emptied before ! 1187: the end of frame was reached. */ ! 1188: lp->mace_stats.uflo++; ! 1189: } ! 1190: if (xmtfs & MACE_XMTFS_LCOL) { ! 1191: /* Late Collision */ ! 1192: lp->mace_stats.lcol++; ! 1193: } ! 1194: if (xmtfs & MACE_XMTFS_MORE) { ! 1195: /* MORE than one retry was needed */ ! 1196: lp->mace_stats.more++; ! 1197: } ! 1198: if (xmtfs & MACE_XMTFS_ONE) { ! 1199: /* Exactly ONE retry occurred */ ! 1200: lp->mace_stats.one++; ! 1201: } ! 1202: if (xmtfs & MACE_XMTFS_DEFER) { ! 1203: /* Transmission was defered */ ! 1204: lp->mace_stats.defer++; ! 1205: } ! 1206: if (xmtfs & MACE_XMTFS_LCAR) { ! 1207: /* Loss of carrier */ ! 1208: lp->mace_stats.lcar++; ! 1209: } ! 1210: if (xmtfs & MACE_XMTFS_RTRY) { ! 1211: /* Retry error: transmit aborted after 16 attempts */ ! 1212: lp->mace_stats.rtry++; ! 1213: } ! 1214: } /* if (xmtfs & ~MACE_XMTFS_XMTSV) */ ! 1215: ! 1216: } /* if (xmtfs & MACE_XMTFS_XMTSV) */ ! 1217: ! 1218: lp->linux_stats.tx_packets++; ! 1219: lp->tx_free_frames++; ! 1220: netif_wake_queue(dev); ! 1221: } /* if (status & MACE_IR_XMTINT) */ ! 1222: ! 1223: if (status & ~MACE_IMR_DEFAULT & ~MACE_IR_RCVINT & ~MACE_IR_XMTINT) { ! 1224: if (status & MACE_IR_JAB) { ! 1225: /* Jabber Error. Excessive transmit duration (20-150ms). */ ! 1226: lp->mace_stats.jab++; ! 1227: } ! 1228: if (status & MACE_IR_BABL) { ! 1229: /* Babble Error. >1518 bytes transmitted. */ ! 1230: lp->mace_stats.babl++; ! 1231: } ! 1232: if (status & MACE_IR_CERR) { ! 1233: /* Collision Error. CERR indicates the absence of the ! 1234: Signal Quality Error Test message after a packet ! 1235: transmission. */ ! 1236: lp->mace_stats.cerr++; ! 1237: } ! 1238: if (status & MACE_IR_RCVCCO) { ! 1239: /* Receive Collision Count Overflow; */ ! 1240: lp->mace_stats.rcvcco++; ! 1241: } ! 1242: if (status & MACE_IR_RNTPCO) { ! 1243: /* Runt Packet Count Overflow */ ! 1244: lp->mace_stats.rntpco++; ! 1245: } ! 1246: if (status & MACE_IR_MPCO) { ! 1247: /* Missed Packet Count Overflow */ ! 1248: lp->mace_stats.mpco++; ! 1249: } ! 1250: } /* if (status & ~MACE_IMR_DEFAULT & ~MACE_IR_RCVINT & ~MACE_IR_XMTINT) */ ! 1251: ! 1252: } while ((status & ~MACE_IMR_DEFAULT) && (--IntrCnt)); ! 1253: ! 1254: exception: ! 1255: return; ! 1256: } /* mace_interrupt */ ! 1257: ! 1258: /* ---------------------------------------------------------------------------- ! 1259: mace_rx ! 1260: Receives packets. ! 1261: ---------------------------------------------------------------------------- */ ! 1262: static int mace_rx(struct net_device *dev, unsigned char RxCnt) ! 1263: { ! 1264: mace_private *lp = (mace_private *)dev->priv; ! 1265: ioaddr_t ioaddr = dev->base_addr; ! 1266: unsigned char rx_framecnt; ! 1267: unsigned short rx_status; ! 1268: ! 1269: while ( ! 1270: ((rx_framecnt = inb(ioaddr + AM2150_RCV_FRAME_COUNT)) > 0) && ! 1271: (rx_framecnt <= 12) && /* rx_framecnt==0xFF if card is extracted. */ ! 1272: (RxCnt--) ! 1273: ) { ! 1274: rx_status = inw(ioaddr + AM2150_RCV); ! 1275: ! 1276: DEBUG(3, "%s: in mace_rx(), framecnt 0x%X, rx_status" ! 1277: " 0x%X.\n", dev->name, rx_framecnt, rx_status); ! 1278: ! 1279: if (rx_status & MACE_RCVFS_RCVSTS) { /* Error, update stats. */ ! 1280: lp->linux_stats.rx_errors++; ! 1281: if (rx_status & MACE_RCVFS_OFLO) { ! 1282: lp->mace_stats.oflo++; ! 1283: } ! 1284: if (rx_status & MACE_RCVFS_CLSN) { ! 1285: lp->mace_stats.clsn++; ! 1286: } ! 1287: if (rx_status & MACE_RCVFS_FRAM) { ! 1288: lp->mace_stats.fram++; ! 1289: } ! 1290: if (rx_status & MACE_RCVFS_FCS) { ! 1291: lp->mace_stats.fcs++; ! 1292: } ! 1293: } else { ! 1294: short pkt_len = (rx_status & ~MACE_RCVFS_RCVSTS) - 4; ! 1295: /* Auto Strip is off, always subtract 4 */ ! 1296: struct sk_buff *skb; ! 1297: ! 1298: lp->mace_stats.rfs_rntpc += inb(ioaddr + AM2150_RCV); ! 1299: /* runt packet count */ ! 1300: lp->mace_stats.rfs_rcvcc += inb(ioaddr + AM2150_RCV); ! 1301: /* rcv collision count */ ! 1302: ! 1303: DEBUG(3, " receiving packet size 0x%X rx_status" ! 1304: " 0x%X.\n", pkt_len, rx_status); ! 1305: ! 1306: skb = dev_alloc_skb(pkt_len+2); ! 1307: ! 1308: if (skb != NULL) { ! 1309: skb->dev = dev; ! 1310: ! 1311: skb_reserve(skb, 2); ! 1312: insw(ioaddr + AM2150_RCV, skb_put(skb, pkt_len), pkt_len>>1); ! 1313: if (pkt_len & 1) ! 1314: *(skb->tail-1) = inb(ioaddr + AM2150_RCV); ! 1315: skb->protocol = eth_type_trans(skb, dev); ! 1316: ! 1317: netif_rx(skb); /* Send the packet to the upper (protocol) layers. */ ! 1318: ! 1319: dev->last_rx = jiffies; ! 1320: lp->linux_stats.rx_packets++; ! 1321: add_rx_bytes(&lp->linux_stats, skb->len); ! 1322: outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */ ! 1323: continue; ! 1324: } else { ! 1325: DEBUG(1, "%s: couldn't allocate a sk_buff of size" ! 1326: " %d.\n", dev->name, pkt_len); ! 1327: lp->linux_stats.rx_dropped++; ! 1328: } ! 1329: } ! 1330: outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */ ! 1331: } /* while */ ! 1332: ! 1333: return 0; ! 1334: } /* mace_rx */ ! 1335: ! 1336: /* ---------------------------------------------------------------------------- ! 1337: pr_linux_stats ! 1338: ---------------------------------------------------------------------------- */ ! 1339: static void pr_linux_stats(struct net_device_stats *pstats) ! 1340: { ! 1341: DEBUG(2, "pr_linux_stats\n"); ! 1342: DEBUG(2, " rx_packets=%-7ld tx_packets=%ld\n", ! 1343: (long)pstats->rx_packets, (long)pstats->tx_packets); ! 1344: DEBUG(2, " rx_errors=%-7ld tx_errors=%ld\n", ! 1345: (long)pstats->rx_errors, (long)pstats->tx_errors); ! 1346: DEBUG(2, " rx_dropped=%-7ld tx_dropped=%ld\n", ! 1347: (long)pstats->rx_dropped, (long)pstats->tx_dropped); ! 1348: DEBUG(2, " multicast=%-7ld collisions=%ld\n", ! 1349: (long)pstats->multicast, (long)pstats->collisions); ! 1350: ! 1351: DEBUG(2, " rx_length_errors=%-7ld rx_over_errors=%ld\n", ! 1352: (long)pstats->rx_length_errors, (long)pstats->rx_over_errors); ! 1353: DEBUG(2, " rx_crc_errors=%-7ld rx_frame_errors=%ld\n", ! 1354: (long)pstats->rx_crc_errors, (long)pstats->rx_frame_errors); ! 1355: DEBUG(2, " rx_fifo_errors=%-7ld rx_missed_errors=%ld\n", ! 1356: (long)pstats->rx_fifo_errors, (long)pstats->rx_missed_errors); ! 1357: ! 1358: DEBUG(2, " tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n", ! 1359: (long)pstats->tx_aborted_errors, (long)pstats->tx_carrier_errors); ! 1360: DEBUG(2, " tx_fifo_errors=%-7ld tx_heartbeat_errors=%ld\n", ! 1361: (long)pstats->tx_fifo_errors, (long)pstats->tx_heartbeat_errors); ! 1362: DEBUG(2, " tx_window_errors=%ld\n", ! 1363: (long)pstats->tx_window_errors); ! 1364: } /* pr_linux_stats */ ! 1365: ! 1366: /* ---------------------------------------------------------------------------- ! 1367: pr_mace_stats ! 1368: ---------------------------------------------------------------------------- */ ! 1369: static void pr_mace_stats(mace_statistics *pstats) ! 1370: { ! 1371: DEBUG(2, "pr_mace_stats\n"); ! 1372: ! 1373: DEBUG(2, " xmtsv=%-7d uflo=%d\n", ! 1374: pstats->xmtsv, pstats->uflo); ! 1375: DEBUG(2, " lcol=%-7d more=%d\n", ! 1376: pstats->lcol, pstats->more); ! 1377: DEBUG(2, " one=%-7d defer=%d\n", ! 1378: pstats->one, pstats->defer); ! 1379: DEBUG(2, " lcar=%-7d rtry=%d\n", ! 1380: pstats->lcar, pstats->rtry); ! 1381: ! 1382: /* MACE_XMTRC */ ! 1383: DEBUG(2, " exdef=%-7d xmtrc=%d\n", ! 1384: pstats->exdef, pstats->xmtrc); ! 1385: ! 1386: /* RFS1--Receive Status (RCVSTS) */ ! 1387: DEBUG(2, " oflo=%-7d clsn=%d\n", ! 1388: pstats->oflo, pstats->clsn); ! 1389: DEBUG(2, " fram=%-7d fcs=%d\n", ! 1390: pstats->fram, pstats->fcs); ! 1391: ! 1392: /* RFS2--Runt Packet Count (RNTPC) */ ! 1393: /* RFS3--Receive Collision Count (RCVCC) */ ! 1394: DEBUG(2, " rfs_rntpc=%-7d rfs_rcvcc=%d\n", ! 1395: pstats->rfs_rntpc, pstats->rfs_rcvcc); ! 1396: ! 1397: /* MACE_IR */ ! 1398: DEBUG(2, " jab=%-7d babl=%d\n", ! 1399: pstats->jab, pstats->babl); ! 1400: DEBUG(2, " cerr=%-7d rcvcco=%d\n", ! 1401: pstats->cerr, pstats->rcvcco); ! 1402: DEBUG(2, " rntpco=%-7d mpco=%d\n", ! 1403: pstats->rntpco, pstats->mpco); ! 1404: ! 1405: /* MACE_MPC */ ! 1406: DEBUG(2, " mpc=%d\n", pstats->mpc); ! 1407: ! 1408: /* MACE_RNTPC */ ! 1409: DEBUG(2, " rntpc=%d\n", pstats->rntpc); ! 1410: ! 1411: /* MACE_RCVCC */ ! 1412: DEBUG(2, " rcvcc=%d\n", pstats->rcvcc); ! 1413: ! 1414: } /* pr_mace_stats */ ! 1415: ! 1416: /* ---------------------------------------------------------------------------- ! 1417: update_stats ! 1418: Update statistics. We change to register window 1, so this ! 1419: should be run single-threaded if the device is active. This is ! 1420: expected to be a rare operation, and it's simpler for the rest ! 1421: of the driver to assume that window 0 is always valid rather ! 1422: than use a special window-state variable. ! 1423: ! 1424: oflo & uflo should _never_ occur since it would mean the Xilinx ! 1425: was not able to transfer data between the MACE FIFO and the ! 1426: card's SRAM fast enough. If this happens, something is ! 1427: seriously wrong with the hardware. ! 1428: ---------------------------------------------------------------------------- */ ! 1429: static void update_stats(ioaddr_t ioaddr, struct net_device *dev) ! 1430: { ! 1431: mace_private *lp = (mace_private *)dev->priv; ! 1432: ! 1433: lp->mace_stats.rcvcc += mace_read(ioaddr, MACE_RCVCC); ! 1434: lp->mace_stats.rntpc += mace_read(ioaddr, MACE_RNTPC); ! 1435: lp->mace_stats.mpc += mace_read(ioaddr, MACE_MPC); ! 1436: /* At this point, mace_stats is fully updated for this call. ! 1437: We may now update the linux_stats. */ ! 1438: ! 1439: /* The MACE has no equivalent for linux_stats field which are commented ! 1440: out. */ ! 1441: ! 1442: #if 0 ! 1443: /* These must be tracked in the main body of the driver. */ ! 1444: lp->linux_stats.rx_packets; ! 1445: lp->linux_stats.tx_packets; ! 1446: lp->linux_stats.rx_errors; ! 1447: lp->linux_stats.tx_errors; ! 1448: lp->linux_stats.rx_dropped; ! 1449: lp->linux_stats.tx_dropped; ! 1450: #endif ! 1451: /* lp->linux_stats.multicast; */ ! 1452: lp->linux_stats.collisions = ! 1453: lp->mace_stats.rcvcco * 256 + lp->mace_stats.rcvcc; ! 1454: /* Collision: The MACE may retry sending a packet 15 times ! 1455: before giving up. The retry count is in XMTRC. ! 1456: Does each retry constitute a collision? ! 1457: If so, why doesn't the RCVCC record these collisions? */ ! 1458: ! 1459: /* detailed rx_errors: */ ! 1460: lp->linux_stats.rx_length_errors = ! 1461: lp->mace_stats.rntpco * 256 + lp->mace_stats.rntpc; ! 1462: /* lp->linux_stats.rx_over_errors */ ! 1463: lp->linux_stats.rx_crc_errors = lp->mace_stats.fcs; ! 1464: lp->linux_stats.rx_frame_errors = lp->mace_stats.fram; ! 1465: lp->linux_stats.rx_fifo_errors = lp->mace_stats.oflo; ! 1466: lp->linux_stats.rx_missed_errors = ! 1467: lp->mace_stats.mpco * 256 + lp->mace_stats.mpc; ! 1468: ! 1469: /* detailed tx_errors */ ! 1470: lp->linux_stats.tx_aborted_errors = lp->mace_stats.rtry; ! 1471: lp->linux_stats.tx_carrier_errors = lp->mace_stats.lcar; ! 1472: /* LCAR usually results from bad cabling. */ ! 1473: lp->linux_stats.tx_fifo_errors = lp->mace_stats.uflo; ! 1474: lp->linux_stats.tx_heartbeat_errors = lp->mace_stats.cerr; ! 1475: /* lp->linux_stats.tx_window_errors; */ ! 1476: ! 1477: return; ! 1478: } /* update_stats */ ! 1479: ! 1480: /* ---------------------------------------------------------------------------- ! 1481: mace_get_stats ! 1482: Gathers ethernet statistics from the MACE chip. ! 1483: ---------------------------------------------------------------------------- */ ! 1484: static struct net_device_stats *mace_get_stats(struct net_device *dev) ! 1485: { ! 1486: mace_private *lp = (mace_private *)dev->priv; ! 1487: ! 1488: update_stats(dev->base_addr, dev); ! 1489: ! 1490: DEBUG(1, "%s: updating the statistics.\n", dev->name); ! 1491: pr_linux_stats(&lp->linux_stats); ! 1492: pr_mace_stats(&lp->mace_stats); ! 1493: ! 1494: return &lp->linux_stats; ! 1495: } /* net_device_stats */ ! 1496: ! 1497: /* ---------------------------------------------------------------------------- ! 1498: updateCRC ! 1499: Modified from Am79C90 data sheet. ! 1500: ---------------------------------------------------------------------------- */ ! 1501: ! 1502: #if BROKEN_MULTICAST ! 1503: ! 1504: static void updateCRC(int *CRC, int bit) ! 1505: { ! 1506: int poly[]={ ! 1507: 1,1,1,0, 1,1,0,1, ! 1508: 1,0,1,1, 1,0,0,0, ! 1509: 1,0,0,0, 0,0,1,1, ! 1510: 0,0,1,0, 0,0,0,0 ! 1511: }; /* CRC polynomial. poly[n] = coefficient of the x**n term of the ! 1512: CRC generator polynomial. */ ! 1513: ! 1514: int j; ! 1515: ! 1516: /* shift CRC and control bit (CRC[32]) */ ! 1517: for (j = 32; j > 0; j--) ! 1518: CRC[j] = CRC[j-1]; ! 1519: CRC[0] = 0; ! 1520: ! 1521: /* If bit XOR(control bit) = 1, set CRC = CRC XOR polynomial. */ ! 1522: if (bit ^ CRC[32]) ! 1523: for (j = 0; j < 32; j++) ! 1524: CRC[j] ^= poly[j]; ! 1525: } /* updateCRC */ ! 1526: ! 1527: /* ---------------------------------------------------------------------------- ! 1528: BuildLAF ! 1529: Build logical address filter. ! 1530: Modified from Am79C90 data sheet. ! 1531: ! 1532: Input ! 1533: ladrf: logical address filter (contents initialized to 0) ! 1534: adr: ethernet address ! 1535: ---------------------------------------------------------------------------- */ ! 1536: static void BuildLAF(int *ladrf, int *adr) ! 1537: { ! 1538: int CRC[33]={1}; /* CRC register, 1 word/bit + extra control bit */ ! 1539: ! 1540: int i, byte; /* temporary array indices */ ! 1541: int hashcode; /* the output object */ ! 1542: ! 1543: CRC[32]=0; ! 1544: ! 1545: for (byte = 0; byte < 6; byte++) ! 1546: for (i = 0; i < 8; i++) ! 1547: updateCRC(CRC, (adr[byte] >> i) & 1); ! 1548: ! 1549: hashcode = 0; ! 1550: for (i = 0; i < 6; i++) ! 1551: hashcode = (hashcode << 1) + CRC[i]; ! 1552: ! 1553: byte = hashcode >> 3; ! 1554: ladrf[byte] |= (1 << (hashcode & 7)); ! 1555: ! 1556: #ifdef PCMCIA_DEBUG ! 1557: if (pc_debug > 2) { ! 1558: printk(KERN_DEBUG " adr ="); ! 1559: for (i = 0; i < 6; i++) ! 1560: printk(" %02X", adr[i]); ! 1561: printk("\n" KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63]" ! 1562: " =", hashcode); ! 1563: for (i = 0; i < 8; i++) ! 1564: printk(" %02X", ladrf[i]); ! 1565: printk("\n"); ! 1566: } ! 1567: #endif ! 1568: } /* BuildLAF */ ! 1569: ! 1570: /* ---------------------------------------------------------------------------- ! 1571: restore_multicast_list ! 1572: Restores the multicast filter for MACE chip to the last ! 1573: set_multicast_list() call. ! 1574: ! 1575: Input ! 1576: multicast_num_addrs ! 1577: multicast_ladrf[] ! 1578: ---------------------------------------------------------------------------- */ ! 1579: static void restore_multicast_list(struct net_device *dev) ! 1580: { ! 1581: mace_private *lp = (mace_private *)dev->priv; ! 1582: int num_addrs = lp->multicast_num_addrs; ! 1583: int *ladrf = lp->multicast_ladrf; ! 1584: ioaddr_t ioaddr = dev->base_addr; ! 1585: int i; ! 1586: ! 1587: DEBUG(2, "%s: restoring Rx mode to %d addresses.\n", ! 1588: dev->name, num_addrs); ! 1589: ! 1590: if (num_addrs > 0) { ! 1591: ! 1592: DEBUG(1, "Attempt to restore multicast list detected.\n"); ! 1593: ! 1594: mace_write(ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_LOGADDR); ! 1595: /* Poll ADDRCHG bit */ ! 1596: while (mace_read(ioaddr, MACE_IAC) & MACE_IAC_ADDRCHG) ! 1597: ; ! 1598: /* Set LADRF register */ ! 1599: for (i = 0; i < MACE_LADRF_LEN; i++) ! 1600: mace_write(ioaddr, MACE_LADRF, ladrf[i]); ! 1601: ! 1602: mace_write(ioaddr, MACE_UTR, MACE_UTR_RCVFCSE | MACE_UTR_LOOP_EXTERNAL); ! 1603: mace_write(ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV); ! 1604: ! 1605: } else if (num_addrs < 0) { ! 1606: ! 1607: /* Promiscuous mode: receive all packets */ ! 1608: mace_write(ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL); ! 1609: mace_write(ioaddr, MACE_MACCC, ! 1610: MACE_MACCC_PROM | MACE_MACCC_ENXMT | MACE_MACCC_ENRCV ! 1611: ); ! 1612: ! 1613: } else { ! 1614: ! 1615: /* Normal mode */ ! 1616: mace_write(ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL); ! 1617: mace_write(ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV); ! 1618: ! 1619: } ! 1620: } /* restore_multicast_list */ ! 1621: ! 1622: /* ---------------------------------------------------------------------------- ! 1623: set_multicast_list ! 1624: Set or clear the multicast filter for this adaptor. ! 1625: ! 1626: Input ! 1627: num_addrs == -1 Promiscuous mode, receive all packets ! 1628: num_addrs == 0 Normal mode, clear multicast list ! 1629: num_addrs > 0 Multicast mode, receive normal and MC packets, and do ! 1630: best-effort filtering. ! 1631: Output ! 1632: multicast_num_addrs ! 1633: multicast_ladrf[] ! 1634: ---------------------------------------------------------------------------- */ ! 1635: ! 1636: static void set_multicast_list(struct net_device *dev) ! 1637: { ! 1638: mace_private *lp = (mace_private *)dev->priv; ! 1639: int adr[ETHER_ADDR_LEN] = {0}; /* Ethernet address */ ! 1640: int i; ! 1641: struct dev_mc_list *dmi = dev->mc_list; ! 1642: ! 1643: #ifdef PCMCIA_DEBUG ! 1644: if (pc_debug > 1) { ! 1645: static int old = 0; ! 1646: if (dev->mc_count != old) { ! 1647: old = dev->mc_count; ! 1648: DEBUG(0, "%s: setting Rx mode to %d addresses.\n", ! 1649: dev->name, old); ! 1650: } ! 1651: } ! 1652: #endif ! 1653: ! 1654: /* Set multicast_num_addrs. */ ! 1655: lp->multicast_num_addrs = dev->mc_count; ! 1656: ! 1657: /* Set multicast_ladrf. */ ! 1658: if (num_addrs > 0) { ! 1659: /* Calculate multicast logical address filter */ ! 1660: memset(lp->multicast_ladrf, 0, MACE_LADRF_LEN); ! 1661: for (i = 0; i < dev->mc_count; i++) { ! 1662: memcpy(adr, dmi->dmi_addr, ETHER_ADDR_LEN); ! 1663: dmi = dmi->next; ! 1664: BuildLAF(lp->multicast_ladrf, adr); ! 1665: } ! 1666: } ! 1667: ! 1668: restore_multicast_list(dev); ! 1669: ! 1670: } /* set_multicast_list */ ! 1671: ! 1672: #endif /* BROKEN_MULTICAST */ ! 1673: ! 1674: static void restore_multicast_list(struct net_device *dev) ! 1675: { ! 1676: ioaddr_t ioaddr = dev->base_addr; ! 1677: ! 1678: DEBUG(2, "%s: restoring Rx mode to %d addresses.\n", dev->name, ! 1679: ((mace_private *)(dev->priv))->multicast_num_addrs); ! 1680: ! 1681: if (dev->flags & IFF_PROMISC) { ! 1682: /* Promiscuous mode: receive all packets */ ! 1683: mace_write(ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL); ! 1684: mace_write(ioaddr, MACE_MACCC, ! 1685: MACE_MACCC_PROM | MACE_MACCC_ENXMT | MACE_MACCC_ENRCV ! 1686: ); ! 1687: } else { ! 1688: /* Normal mode */ ! 1689: mace_write(ioaddr, MACE_UTR, MACE_UTR_LOOP_EXTERNAL); ! 1690: mace_write(ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV); ! 1691: } ! 1692: } /* restore_multicast_list */ ! 1693: ! 1694: static void set_multicast_list(struct net_device *dev) ! 1695: { ! 1696: mace_private *lp = (mace_private *)dev->priv; ! 1697: ! 1698: #ifdef PCMCIA_DEBUG ! 1699: if (pc_debug > 1) { ! 1700: static int old = 0; ! 1701: if (dev->mc_count != old) { ! 1702: old = dev->mc_count; ! 1703: DEBUG(0, "%s: setting Rx mode to %d addresses.\n", ! 1704: dev->name, old); ! 1705: } ! 1706: } ! 1707: #endif ! 1708: ! 1709: lp->multicast_num_addrs = dev->mc_count; ! 1710: restore_multicast_list(dev); ! 1711: ! 1712: } /* set_multicast_list */ ! 1713: ! 1714: /* ---------------------------------------------------------------------------- ! 1715: init_nmclan_cs ! 1716: ---------------------------------------------------------------------------- */ ! 1717: ! 1718: static int __init init_nmclan_cs(void) ! 1719: { ! 1720: servinfo_t serv; ! 1721: DEBUG(0, "%s\n", version); ! 1722: CardServices(GetCardServicesInfo, &serv); ! 1723: if (serv.Revision != CS_RELEASE_CODE) { ! 1724: printk(KERN_NOTICE "nmclan_cs: Card Services release does not match!\n"); ! 1725: return -EINVAL; ! 1726: } ! 1727: register_pccard_driver(&dev_info, &nmclan_attach, &nmclan_detach); ! 1728: return 0; ! 1729: } ! 1730: ! 1731: /* ---------------------------------------------------------------------------- ! 1732: exit_nmclan_cs ! 1733: ---------------------------------------------------------------------------- */ ! 1734: ! 1735: static void __exit exit_nmclan_cs(void) ! 1736: { ! 1737: DEBUG(0, "nmclan_cs: unloading\n"); ! 1738: unregister_pccard_driver(&dev_info); ! 1739: while (dev_list != NULL) ! 1740: nmclan_detach(dev_list); ! 1741: } ! 1742: ! 1743: module_init(init_nmclan_cs); ! 1744: module_exit(exit_nmclan_cs);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.