diff options
Diffstat (limited to 'drivers/net/pcmcia/axnet_cs.c')
-rw-r--r-- | drivers/net/pcmcia/axnet_cs.c | 153 |
1 files changed, 73 insertions, 80 deletions
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index ce95c5d168fe..b37a498939ae 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -262,7 +262,7 @@ static int try_io_port(struct pcmcia_device *link) if (link->io.NumPorts2 > 0) { /* for master/slave multifunction cards */ link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - link->irq.Attributes = + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; } } else { @@ -276,7 +276,8 @@ static int try_io_port(struct pcmcia_device *link) link->io.BasePort1 = j ^ 0x300; link->io.BasePort2 = (j ^ 0x300) + 0x10; ret = pcmcia_request_io(link, &link->io); - if (ret == CS_SUCCESS) return ret; + if (ret == 0) + return ret; } return ret; } else { @@ -284,59 +285,50 @@ static int try_io_port(struct pcmcia_device *link) } } +static int axnet_configcheck(struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data) +{ + int i; + cistpl_io_t *io = &cfg->io; + + if (cfg->index == 0 || cfg->io.nwin == 0) + return -ENODEV; + + p_dev->conf.ConfigIndex = 0x05; + /* For multifunction cards, by convention, we configure the + network function with window 0, and serial with window 1 */ + if (io->nwin > 1) { + i = (io->win[1].len > io->win[0].len); + p_dev->io.BasePort2 = io->win[1-i].base; + p_dev->io.NumPorts2 = io->win[1-i].len; + } else { + i = p_dev->io.NumPorts2 = 0; + } + p_dev->io.BasePort1 = io->win[i].base; + p_dev->io.NumPorts1 = io->win[i].len; + p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32) + return try_io_port(p_dev); + + return -ENODEV; +} + static int axnet_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; axnet_dev_t *info = PRIV(dev); - tuple_t tuple; - cisparse_t parse; int i, j, last_ret, last_fn; - u_short buf[64]; DECLARE_MAC_BUF(mac); DEBUG(0, "axnet_config(0x%p)\n", link); - tuple.Attributes = 0; - tuple.TupleData = (cisdata_t *)buf; - tuple.TupleDataMax = sizeof(buf); - tuple.TupleOffset = 0; - /* don't trust the CIS on this; Linksys got it wrong */ link->conf.Present = 0x63; - - tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - tuple.Attributes = 0; - CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); - while (last_ret == CS_SUCCESS) { - cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); - cistpl_io_t *io = &(parse.cftable_entry.io); - - if (pcmcia_get_tuple_data(link, &tuple) != 0 || - pcmcia_parse_tuple(link, &tuple, &parse) != 0 || - cfg->index == 0 || cfg->io.nwin == 0) - goto next_entry; - - link->conf.ConfigIndex = 0x05; - /* For multifunction cards, by convention, we configure the - network function with window 0, and serial with window 1 */ - if (io->nwin > 1) { - i = (io->win[1].len > io->win[0].len); - link->io.BasePort2 = io->win[1-i].base; - link->io.NumPorts2 = io->win[1-i].len; - } else { - i = link->io.NumPorts2 = 0; - } - link->io.BasePort1 = io->win[i].base; - link->io.NumPorts1 = io->win[i].len; - link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; - if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) { - last_ret = try_io_port(link); - if (last_ret == CS_SUCCESS) break; - } - next_entry: - last_ret = pcmcia_get_next_tuple(link, &tuple); - } - if (last_ret != CS_SUCCESS) { + last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL); + if (last_ret != 0) { cs_error(link, RequestIO, last_ret); goto failed; } @@ -525,12 +517,14 @@ static int axnet_open(struct net_device *dev) int ret; axnet_dev_t *info = PRIV(dev); struct pcmcia_device *link = info->p_dev; + unsigned int nic_base = dev->base_addr; DEBUG(2, "axnet_open('%s')\n", dev->name); if (!pcmcia_dev_present(link)) return -ENODEV; + outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */ ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev); if (ret) return ret; @@ -782,6 +776,7 @@ static struct pcmcia_device_id axnet_ids[] = { PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEther PCC-TXD", 0x5261440f, 0x436768c5), PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEtherII PCC-TXD", 0x5261440f, 0x730df72e), PCMCIA_DEVICE_PROD_ID12("Dynalink", "L100C16", 0x55632fd5, 0x66bc2a90), + PCMCIA_DEVICE_PROD_ID12("IO DATA", "ETXPCM", 0x547e66dc, 0x233adac2), PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V3)", 0x0733cc81, 0x232019a8), PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC3-TX", 0x481e0094, 0xf91af609), PCMCIA_DEVICE_PROD_ID12("PCMCIA", "100BASE", 0x281f1c5d, 0x7c2add04), @@ -1021,7 +1016,7 @@ static void ei_tx_timeout(struct net_device *dev) int txsr, isr, tickssofar = jiffies - dev->trans_start; unsigned long flags; - ei_local->stat.tx_errors++; + dev->stats.tx_errors++; spin_lock_irqsave(&ei_local->page_lock, flags); txsr = inb(e8390_base+EN0_TSR); @@ -1032,7 +1027,7 @@ static void ei_tx_timeout(struct net_device *dev) dev->name, (txsr & ENTSR_ABT) ? "excess collisions." : (isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar); - if (!isr && !ei_local->stat.tx_packets) + if (!isr && !dev->stats.tx_packets) { /* The 8390 probably hasn't gotten on the cable yet. */ ei_local->interface_num ^= 1; /* Try a different xcvr. */ @@ -1122,7 +1117,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); outb_p(ENISR_ALL, e8390_base + EN0_IMR); spin_unlock_irqrestore(&ei_local->page_lock, flags); - ei_local->stat.tx_errors++; + dev->stats.tx_errors++; return 1; } @@ -1170,7 +1165,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_unlock_irqrestore(&ei_local->page_lock, flags); dev_kfree_skb (skb); - ei_local->stat.tx_bytes += send_length; + dev->stats.tx_bytes += send_length; return 0; } @@ -1262,9 +1257,9 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id) if (interrupts & ENISR_COUNTERS) { - ei_local->stat.rx_frame_errors += inb_p(e8390_base + EN0_COUNTER0); - ei_local->stat.rx_crc_errors += inb_p(e8390_base + EN0_COUNTER1); - ei_local->stat.rx_missed_errors+= inb_p(e8390_base + EN0_COUNTER2); + dev->stats.rx_frame_errors += inb_p(e8390_base + EN0_COUNTER0); + dev->stats.rx_crc_errors += inb_p(e8390_base + EN0_COUNTER1); + dev->stats.rx_missed_errors+= inb_p(e8390_base + EN0_COUNTER2); } } @@ -1309,7 +1304,6 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id) static void ei_tx_err(struct net_device *dev) { long e8390_base = dev->base_addr; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); unsigned char txsr = inb_p(e8390_base+EN0_TSR); unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU); @@ -1332,10 +1326,10 @@ static void ei_tx_err(struct net_device *dev) ei_tx_intr(dev); else { - ei_local->stat.tx_errors++; - if (txsr & ENTSR_CRS) ei_local->stat.tx_carrier_errors++; - if (txsr & ENTSR_CDH) ei_local->stat.tx_heartbeat_errors++; - if (txsr & ENTSR_OWC) ei_local->stat.tx_window_errors++; + dev->stats.tx_errors++; + if (txsr & ENTSR_CRS) dev->stats.tx_carrier_errors++; + if (txsr & ENTSR_CDH) dev->stats.tx_heartbeat_errors++; + if (txsr & ENTSR_OWC) dev->stats.tx_window_errors++; } } @@ -1397,25 +1391,25 @@ static void ei_tx_intr(struct net_device *dev) /* Minimize Tx latency: update the statistics after we restart TXing. */ if (status & ENTSR_COL) - ei_local->stat.collisions++; + dev->stats.collisions++; if (status & ENTSR_PTX) - ei_local->stat.tx_packets++; + dev->stats.tx_packets++; else { - ei_local->stat.tx_errors++; + dev->stats.tx_errors++; if (status & ENTSR_ABT) { - ei_local->stat.tx_aborted_errors++; - ei_local->stat.collisions += 16; + dev->stats.tx_aborted_errors++; + dev->stats.collisions += 16; } if (status & ENTSR_CRS) - ei_local->stat.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (status & ENTSR_FU) - ei_local->stat.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; if (status & ENTSR_CDH) - ei_local->stat.tx_heartbeat_errors++; + dev->stats.tx_heartbeat_errors++; if (status & ENTSR_OWC) - ei_local->stat.tx_window_errors++; + dev->stats.tx_window_errors++; } netif_wake_queue(dev); } @@ -1476,8 +1470,8 @@ static void ei_receive(struct net_device *dev) printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n", dev->name, rx_frame.count, rx_frame.status, rx_frame.next); - ei_local->stat.rx_errors++; - ei_local->stat.rx_length_errors++; + dev->stats.rx_errors++; + dev->stats.rx_length_errors++; } else if ((pkt_stat & 0x0F) == ENRSR_RXOK) { @@ -1489,7 +1483,7 @@ static void ei_receive(struct net_device *dev) if (ei_debug > 1) printk(KERN_DEBUG "%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len); - ei_local->stat.rx_dropped++; + dev->stats.rx_dropped++; break; } else @@ -1500,10 +1494,10 @@ static void ei_receive(struct net_device *dev) skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); dev->last_rx = jiffies; - ei_local->stat.rx_packets++; - ei_local->stat.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; if (pkt_stat & ENRSR_PHY) - ei_local->stat.multicast++; + dev->stats.multicast++; } } else @@ -1512,10 +1506,10 @@ static void ei_receive(struct net_device *dev) printk(KERN_DEBUG "%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n", dev->name, rx_frame.status, rx_frame.next, rx_frame.count); - ei_local->stat.rx_errors++; + dev->stats.rx_errors++; /* NB: The NIC counts CRC, frame and missed errors. */ if (pkt_stat & ENRSR_FO) - ei_local->stat.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; } next_frame = rx_frame.next; @@ -1550,7 +1544,6 @@ static void ei_rx_overrun(struct net_device *dev) axnet_dev_t *info = PRIV(dev); long e8390_base = dev->base_addr; unsigned char was_txing, must_resend = 0; - struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); /* * Record whether a Tx was in progress and then issue the @@ -1561,7 +1554,7 @@ static void ei_rx_overrun(struct net_device *dev) if (ei_debug > 1) printk(KERN_DEBUG "%s: Receiver overrun.\n", dev->name); - ei_local->stat.rx_over_errors++; + dev->stats.rx_over_errors++; /* * Wait a full Tx time (1.2ms) + some guard time, NS says 1.6ms total. @@ -1622,16 +1615,16 @@ static struct net_device_stats *get_stats(struct net_device *dev) /* If the card is stopped, just return the present stats. */ if (!netif_running(dev)) - return &ei_local->stat; + return &dev->stats; spin_lock_irqsave(&ei_local->page_lock,flags); /* Read the counter registers, assuming we are in page 0. */ - ei_local->stat.rx_frame_errors += inb_p(ioaddr + EN0_COUNTER0); - ei_local->stat.rx_crc_errors += inb_p(ioaddr + EN0_COUNTER1); - ei_local->stat.rx_missed_errors+= inb_p(ioaddr + EN0_COUNTER2); + dev->stats.rx_frame_errors += inb_p(ioaddr + EN0_COUNTER0); + dev->stats.rx_crc_errors += inb_p(ioaddr + EN0_COUNTER1); + dev->stats.rx_missed_errors+= inb_p(ioaddr + EN0_COUNTER2); spin_unlock_irqrestore(&ei_local->page_lock, flags); - return &ei_local->stat; + return &dev->stats; } /* |