static int tc589_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; __be16 *phys_addr; int ret, i, j, multi = 0, fifo; unsigned int ioaddr; char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; u8 *buf; size_t len; dev_dbg(&link->dev, "3c589_config\n"); phys_addr = (__be16 *)dev->dev_addr; /* Is this a 3c562? */ if (link->manf_id != MANFID_3COM) printk(KERN_INFO "3c589_cs: hmmm, is this really a " "3Com card??\n"); multi = (link->card_id == PRODID_3COM_3C562); link->io_lines = 16; /* For the 3c562, the base address must be xx00-xx7f */ for (i = j = 0; j < 0x400; j += 0x10) { if (multi && (j & 0x80)) continue; link->resource[0]->start = j ^ 0x300; i = pcmcia_request_io(link); if (i == 0) break; } if (i != 0) goto failed; ret = pcmcia_request_irq(link, el3_interrupt); if (ret) goto failed; ret = pcmcia_request_configuration(link, &link->conf); if (ret) goto failed; dev->irq = link->irq; dev->base_addr = link->resource[0]->start; ioaddr = dev->base_addr; EL3WINDOW(0); /* The 3c589 has an extra EEPROM for configuration info, including the hardware address. The 3c562 puts the address in the CIS. */ len = pcmcia_get_tuple(link, 0x88, &buf); if (buf && len >= 6) { for (i = 0; i < 3; i++) phys_addr[i] = htons(le16_to_cpu(buf[i*2])); kfree(buf); } else { kfree(buf); /* 0 < len < 6 */ for (i = 0; i < 3; i++) phys_addr[i] = htons(read_eeprom(ioaddr, i)); if (phys_addr[0] == htons(0x6060)) { printk(KERN_ERR "3c589_cs: IO port conflict at 0x%03lx" "-0x%03lx\n", dev->base_addr, dev->base_addr+15); goto failed; } } /* The address and resource configuration register aren't loaded from the EEPROM and *must* be set to 0 and IRQ3 for the PCMCIA version. */ outw(0x3f00, ioaddr + 8); fifo = inl(ioaddr); /* The if_port symbol can be set when the module is loaded */ if ((if_port >= 0) && (if_port <= 3)) dev->if_port = if_port; else printk(KERN_ERR "3c589_cs: invalid if_port requested\n"); SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev) != 0) { printk(KERN_ERR "3c589_cs: register_netdev() failed\n"); goto failed; } netdev_info(dev, "3Com 3c%s, io %#3lx, irq %d, hw_addr %pM\n", (multi ? "562" : "589"), dev->base_addr, dev->irq, dev->dev_addr); netdev_info(dev, " %dK FIFO split %s Rx:Tx, %s xcvr\n", (fifo & 7) ? 32 : 8, ram_split[(fifo >> 16) & 3], if_names[dev->if_port]); return 0; failed: tc589_release(link); return -ENODEV; } /* tc589_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"); 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 xirc2ps_config(struct pcmcia_device * link) { struct net_device *dev = link->priv; local_info_t *local = netdev_priv(dev); unsigned int ioaddr; int err; u8 *buf; size_t len; local->dingo_ccr = NULL; dev_dbg(&link->dev, "config\n"); if (link->has_manf_id == 0) { pr_notice("manfid not found in CIS\n"); goto failure; } switch (link->manf_id) { case MANFID_XIRCOM: local->manf_str = "Xircom"; break; case MANFID_ACCTON: local->manf_str = "Accton"; break; case MANFID_COMPAQ: case MANFID_COMPAQ2: local->manf_str = "Compaq"; break; case MANFID_INTEL: local->manf_str = "Intel"; break; case MANFID_TOSHIBA: local->manf_str = "Toshiba"; break; default: pr_notice("Unknown Card Manufacturer ID: 0x%04x\n", (unsigned)link->manf_id); goto failure; } dev_dbg(&link->dev, "found %s card\n", local->manf_str); if (!set_card_type(link)) { pr_notice("this card is not supported\n"); goto failure; } err = pcmcia_get_mac_from_cis(link, dev); if (err) { len = pcmcia_get_tuple(link, 0x89, &buf); if (buf && len == 8) { if (*buf == CISTPL_FUNCE_LAN_NODE_ID) { int i; for (i = 2; i < 6; i++) dev->dev_addr[i] = buf[i+2]; } else err = -1; } kfree(buf); } if (err) err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev); if (err) { pr_notice("node-id not found in CIS\n"); goto failure; } if (local->modem) { int pass; link->config_flags |= CONF_AUTO_SET_IO; if (local->dingo) { if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL)) goto port_found; } else { for (pass=0; pass < 2; pass++) if (!pcmcia_loop_config(link, xirc2ps_config_check, &pass)) goto port_found; } pr_notice("no ports available\n"); } else { link->io_lines = 10; link->resource[0]->end = 16; link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16; for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { link->resource[0]->start = ioaddr; if (!(err = pcmcia_request_io(link))) goto port_found; } link->resource[0]->start = 0; if ((err = pcmcia_request_io(link))) goto config_error; } port_found: if (err) goto config_error; if ((err=pcmcia_request_irq(link, xirc2ps_interrupt))) goto config_error; link->config_flags |= CONF_ENABLE_IRQ; if (do_sound) link->config_flags |= CONF_ENABLE_SPKR; if ((err = pcmcia_enable_device(link))) goto config_error; if (local->dingo) { /* Reset the modem's BAR to the correct value * This is necessary because in the RequestConfiguration call, * the base address of the ethernet port (BasePort1) is written * to the BAR registers of the modem. */ err = pcmcia_write_config_byte(link, CISREG_IOBASE_0, (u8) link->resource[1]->start & 0xff); if (err) goto config_error; err = pcmcia_write_config_byte(link, CISREG_IOBASE_1, (link->resource[1]->start >> 8) & 0xff); if (err) goto config_error; link->resource[2]->flags = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE; link->resource[2]->start = link->resource[2]->end = 0; if ((err = pcmcia_request_window(link, link->resource[2], 0))) goto config_error; local->dingo_ccr = ioremap(link->resource[2]->start, 0x1000) + 0x0800; if ((err = pcmcia_map_mem_page(link, link->resource[2], 0))) goto config_error; writeb(0x47, local->dingo_ccr + CISREG_COR); ioaddr = link->resource[0]->start; writeb(ioaddr & 0xff , local->dingo_ccr + CISREG_IOBASE_0); writeb((ioaddr >> 8)&0xff , local->dingo_ccr + CISREG_IOBASE_1); #if 0 { u_char tmp; pr_info("ECOR:"); for (i=0; i < 7; i++) { tmp = readb(local->dingo_ccr + i*2); pr_cont(" %02x", tmp); } pr_cont("\n"); pr_info("DCOR:"); for (i=0; i < 4; i++) { tmp = readb(local->dingo_ccr + 0x20 + i*2); pr_cont(" %02x", tmp); } pr_cont("\n"); pr_info("SCOR:"); for (i=0; i < 10; i++) { tmp = readb(local->dingo_ccr + 0x40 + i*2); pr_cont(" %02x", tmp); } pr_cont("\n"); } #endif writeb(0x01, local->dingo_ccr + 0x20); writeb(0x0c, local->dingo_ccr + 0x22); writeb(0x00, local->dingo_ccr + 0x24); writeb(0x00, local->dingo_ccr + 0x26); writeb(0x00, local->dingo_ccr + 0x28); }
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 */
static int set_card_type(struct pcmcia_device *link) { struct net_device *dev = link->priv; local_info_t *local = netdev_priv(dev); u8 *buf; unsigned int cisrev, mediaid, prodid; size_t len; len = pcmcia_get_tuple(link, CISTPL_MANFID, &buf); if (len < 5) { dev_err(&link->dev, "invalid CIS -- sorry\n"); return 0; } cisrev = buf[2]; mediaid = buf[3]; prodid = buf[4]; dev_dbg(&link->dev, "cisrev=%02x mediaid=%02x prodid=%02x\n", cisrev, mediaid, prodid); local->mohawk = 0; local->dingo = 0; local->modem = 0; local->card_type = XIR_UNKNOWN; if (!(prodid & 0x40)) { pr_notice("Oops: Not a creditcard\n"); return 0; } if (!(mediaid & 0x01)) { pr_notice("Not an Ethernet card\n"); return 0; } if (mediaid & 0x10) { local->modem = 1; switch(prodid & 15) { case 1: local->card_type = XIR_CEM ; break; case 2: local->card_type = XIR_CEM2 ; break; case 3: local->card_type = XIR_CEM3 ; break; case 4: local->card_type = XIR_CEM33 ; break; case 5: local->card_type = XIR_CEM56M; local->mohawk = 1; break; case 6: case 7: local->card_type = XIR_CEM56 ; local->mohawk = 1; local->dingo = 1; break; } } else { switch(prodid & 15) { case 1: local->card_type = has_ce2_string(link)? XIR_CE2 : XIR_CE ; break; case 2: local->card_type = XIR_CE2; break; case 3: local->card_type = XIR_CE3; local->mohawk = 1; break; } } if (local->card_type == XIR_CE || local->card_type == XIR_CEM) { pr_notice("Sorry, this is an old CE card\n"); return 0; } if (local->card_type == XIR_UNKNOWN) pr_notice("unknown card (mediaid=%02x prodid=%02x)\n", mediaid, prodid); return 1; }