void mc_rint(struct mc_softc *sc) { struct ifnet *ifp = &sc->sc_arpcom.ac_if; #define rxf sc->sc_rxframe u_int len; len = (rxf.rx_rcvcnt | ((rxf.rx_rcvsts & 0xf) << 8)) - 4; #ifdef MCDEBUG if (rxf.rx_rcvsts & 0xf0) printf("%s: rcvcnt %02x rcvsts %02x rntpc 0x%02x rcvcc 0x%02x\n", sc->sc_dev.dv_xname, rxf.rx_rcvcnt, rxf.rx_rcvsts, rxf.rx_rntpc, rxf.rx_rcvcc); #endif if (rxf.rx_rcvsts & OFLO) { #ifdef MCDEBUG printf("%s: receive FIFO overflow\n", sc->sc_dev.dv_xname); #endif ifp->if_ierrors++; return; } if (rxf.rx_rcvsts & CLSN) ifp->if_collisions++; if (rxf.rx_rcvsts & FRAM) { #ifdef MCDEBUG printf("%s: framing error\n", sc->sc_dev.dv_xname); #endif ifp->if_ierrors++; return; } if (rxf.rx_rcvsts & FCS) { #ifdef MCDEBUG printf("%s: frame control checksum error\n", sc->sc_dev.dv_xname); #endif ifp->if_ierrors++; return; } mace_read(sc, rxf.rx_frame, len); #undef rxf }
static int nmclan_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; mace_private *lp = netdev_priv(dev); tuple_t tuple; u_char buf[64]; int i, last_ret, last_fn; kio_addr_t ioaddr; DEBUG(0, "nmclan_config(0x%p)\n", link); CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; ioaddr = dev->base_addr; /* Read the ethernet address from the CIS. */ tuple.DesiredTuple = 0x80 /* CISTPL_CFTABLE_ENTRY_MISC */; tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; tuple.Attributes = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN); /* Verify configuration by reading the MACE ID. */ { char sig[2]; sig[0] = mace_read(lp, ioaddr, MACE_CHIPIDL); sig[1] = mace_read(lp, ioaddr, MACE_CHIPIDH); if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) { DEBUG(0, "nmclan_cs configured: mace id=%x %x\n", sig[0], sig[1]); } else { printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should" " be 0x40 0x?9\n", sig[0], sig[1]); return -ENODEV; } } if(mace_init(lp, ioaddr, dev->dev_addr) == -1) goto failed; /* The if_port symbol can be set when the module is loaded */ if (if_port <= 2) dev->if_port = if_port; else printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n"); link->dev_node = &lp->node; SET_NETDEV_DEV(dev, &handle_to_dev(link)); i = register_netdev(dev); if (i != 0) { printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n"); link->dev_node = NULL; goto failed; } strcpy(lp->node.dev_name, dev->name); printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port, hw_addr ", dev->name, dev->base_addr, dev->irq, if_names[dev->if_port]); for (i = 0; i < 6; i++) printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n")); return 0; cs_failed: cs_error(link, last_fn, last_ret); failed: nmclan_release(link); return -ENODEV; } /* nmclan_config */
/* ---------------------------------------------------------------------------- mace_init Resets the MACE chip. ---------------------------------------------------------------------------- */ static int mace_init(mace_private *lp, kio_addr_t ioaddr, char *enet_addr) { int i; int ct = 0; /* MACE Software reset */ mace_write(lp, ioaddr, MACE_BIUCC, 1); while (mace_read(lp, ioaddr, MACE_BIUCC) & 0x01) { /* Wait for reset bit to be cleared automatically after <= 200ns */; if(++ct > 500) { printk(KERN_ERR "mace: reset failed, card removed ?\n"); return -1; } udelay(1); } mace_write(lp, ioaddr, MACE_BIUCC, 0); /* The Am2150 requires that the MACE FIFOs operate in burst mode. */ mace_write(lp, ioaddr, MACE_FIFOCC, 0x0F); mace_write(lp,ioaddr, MACE_RCVFC, 0); /* Disable Auto Strip Receive */ mace_write(lp, ioaddr, MACE_IMR, 0xFF); /* Disable all interrupts until _open */ /* * Bit 2-1 PORTSEL[1-0] Port Select. * 00 AUI/10Base-2 * 01 10Base-T * 10 DAI Port (reserved in Am2150) * 11 GPSI * For this card, only the first two are valid. * So, PLSCC should be set to * 0x00 for 10Base-2 * 0x02 for 10Base-T * Or just set ASEL in PHYCC below! */ switch (if_port) { case 1: mace_write(lp, ioaddr, MACE_PLSCC, 0x02); break; case 2: mace_write(lp, ioaddr, MACE_PLSCC, 0x00); break; default: mace_write(lp, ioaddr, MACE_PHYCC, /* ASEL */ 4); /* ASEL Auto Select. When set, the PORTSEL[1-0] bits are overridden, and the MACE device will automatically select the operating media interface port. */ break; } mace_write(lp, ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_PHYADDR); /* Poll ADDRCHG bit */ ct = 0; while (mace_read(lp, ioaddr, MACE_IAC) & MACE_IAC_ADDRCHG) { if(++ ct > 500) { printk(KERN_ERR "mace: ADDRCHG timeout, card removed ?\n"); return -1; } } /* Set PADR register */ for (i = 0; i < ETHER_ADDR_LEN; i++) mace_write(lp, ioaddr, MACE_PADR, enet_addr[i]); /* MAC Configuration Control Register should be written last */ /* Let set_multicast_list set this. */ /* mace_write(lp, ioaddr, MACE_MACCC, MACE_MACCC_ENXMT | MACE_MACCC_ENRCV); */ mace_write(lp, ioaddr, MACE_MACCC, 0x00); return 0; } /* mace_init */
static int nmclan_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; mace_private *lp = netdev_priv(dev); u8 *buf; size_t len; int i, ret; unsigned int ioaddr; dev_dbg(&link->dev, "nmclan_config\n"); ret = pcmcia_request_io(link, &link->io); if (ret) goto failed; ret = pcmcia_request_irq(link, &link->irq); if (ret) goto failed; ret = pcmcia_request_configuration(link, &link->conf); if (ret) goto failed; dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; ioaddr = dev->base_addr; /* Read the ethernet address from the CIS. */ len = pcmcia_get_tuple(link, 0x80, &buf); if (!buf || len < ETHER_ADDR_LEN) { kfree(buf); goto failed; } memcpy(dev->dev_addr, buf, ETHER_ADDR_LEN); kfree(buf); /* Verify configuration by reading the MACE ID. */ { char sig[2]; sig[0] = mace_read(lp, ioaddr, MACE_CHIPIDL); sig[1] = mace_read(lp, ioaddr, MACE_CHIPIDH); if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) { dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n", sig[0], sig[1]); } else { printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should" " be 0x40 0x?9\n", sig[0], sig[1]); return -ENODEV; } } if(mace_init(lp, ioaddr, dev->dev_addr) == -1) goto failed; /* The if_port symbol can be set when the module is loaded */ if (if_port <= 2) dev->if_port = if_port; else printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n"); link->dev_node = &lp->node; SET_NETDEV_DEV(dev, &link->dev); i = register_netdev(dev); if (i != 0) { printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n"); link->dev_node = NULL; goto failed; } strcpy(lp->node.dev_name, dev->name); printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port," " hw_addr %pM\n", dev->name, dev->base_addr, dev->irq, if_names[dev->if_port], dev->dev_addr); return 0; failed: nmclan_release(link); return -ENODEV; } /* nmclan_config */
static int nmclan_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; mace_private *lp = netdev_priv(dev); u8 *buf; size_t len; int i, ret; unsigned int ioaddr; dev_dbg(&link->dev, "nmclan_config\n"); link->io_lines = 5; ret = pcmcia_request_io(link); if (ret) goto failed; ret = pcmcia_request_exclusive_irq(link, mace_interrupt); if (ret) goto failed; ret = pcmcia_enable_device(link); if (ret) goto failed; dev->irq = link->irq; dev->base_addr = link->resource[0]->start; ioaddr = dev->base_addr; /* Read the ethernet address from the CIS. */ len = pcmcia_get_tuple(link, 0x80, &buf); if (!buf || len < ETH_ALEN) { kfree(buf); goto failed; } memcpy(dev->dev_addr, buf, ETH_ALEN); kfree(buf); /* Verify configuration by reading the MACE ID. */ { char sig[2]; sig[0] = mace_read(lp, ioaddr, MACE_CHIPIDL); sig[1] = mace_read(lp, ioaddr, MACE_CHIPIDH); if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) { dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n", sig[0], sig[1]); } else { pr_notice("mace id not found: %x %x should be 0x40 0x?9\n", sig[0], sig[1]); return -ENODEV; } } if(mace_init(lp, ioaddr, dev->dev_addr) == -1) goto failed; /* The if_port symbol can be set when the module is loaded */ if (if_port <= 2) dev->if_port = if_port; else pr_notice("invalid if_port requested\n"); SET_NETDEV_DEV(dev, &link->dev); i = register_netdev(dev); if (i != 0) { pr_notice("register_netdev() failed\n"); goto failed; } netdev_info(dev, "nmclan: port %#3lx, irq %d, %s port, hw_addr %pM\n", dev->base_addr, dev->irq, if_names[dev->if_port], dev->dev_addr); return 0; failed: nmclan_release(link); return -ENODEV; } /* nmclan_config */