X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fnet%2Fsunlance.c;h=afc7b351e5ec43a5723290ca7e958a08806bf544;hb=4142a969175302bc843d1505133488bfdbfa4732;hp=17d66c1185cd260276bf02936a829774dc1a1a5e;hpb=10d024c1b2fd58af8362670d7d6e5ae52fc33353;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 17d66c1..afc7b35 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -91,6 +91,9 @@ static char lancestr[] = "LANCE"; #include #include #include +#include +#include +#include #include #include @@ -98,7 +101,6 @@ static char lancestr[] = "LANCE"; #include #include /* Used by the checksum routines */ #include -#include #include #include /* For tpe-link-test? setting */ #include @@ -248,8 +250,7 @@ struct lance_private { int rx_new, tx_new; int rx_old, tx_old; - struct net_device_stats stats; - struct sbus_dma *ledma; /* If set this points to ledma */ + struct of_device *ledma; /* If set this points to ledma */ char tpe; /* cable-selection is TPE */ char auto_select; /* cable-selection by carrier */ char burst_sizes; /* ledma SBus burst sizes */ @@ -264,7 +265,8 @@ struct lance_private { char *name; dma_addr_t init_block_dvma; struct net_device *dev; /* Backpointer */ - struct sbus_dev *sdev; + struct of_device *op; + struct of_device *lebuffer; struct timer_list multicast_timer; }; @@ -341,7 +343,7 @@ static void lance_init_ring_dvma(struct net_device *dev) ib->phys_addr [5] = dev->dev_addr [4]; /* Setup the Tx ring entries */ - for (i = 0; i <= TX_RING_SIZE; i++) { + for (i = 0; i < TX_RING_SIZE; i++) { leptr = LANCE_ADDR(aib + libbuff_offset(tx_buf, i)); ib->btx_ring [i].tmd0 = leptr; ib->btx_ring [i].tmd1_hadr = leptr >> 16; @@ -397,7 +399,7 @@ static void lance_init_ring_pio(struct net_device *dev) sbus_writeb(dev->dev_addr[4], &ib->phys_addr[5]); /* Setup the Tx ring entries */ - for (i = 0; i <= TX_RING_SIZE; i++) { + for (i = 0; i < TX_RING_SIZE; i++) { leptr = libbuff_offset(tx_buf, i); sbus_writew(leptr, &ib->btx_ring [i].tmd0); sbus_writeb(leptr >> 16,&ib->btx_ring [i].tmd1_hadr); @@ -519,17 +521,17 @@ static void lance_rx_dvma(struct net_device *dev) /* We got an incomplete frame? */ if ((bits & LE_R1_POK) != LE_R1_POK) { - lp->stats.rx_over_errors++; - lp->stats.rx_errors++; + dev->stats.rx_over_errors++; + dev->stats.rx_errors++; } else if (bits & LE_R1_ERR) { /* Count only the end frame as a rx error, * not the beginning */ - if (bits & LE_R1_BUF) lp->stats.rx_fifo_errors++; - if (bits & LE_R1_CRC) lp->stats.rx_crc_errors++; - if (bits & LE_R1_OFL) lp->stats.rx_over_errors++; - if (bits & LE_R1_FRA) lp->stats.rx_frame_errors++; - if (bits & LE_R1_EOP) lp->stats.rx_errors++; + if (bits & LE_R1_BUF) dev->stats.rx_fifo_errors++; + if (bits & LE_R1_CRC) dev->stats.rx_crc_errors++; + if (bits & LE_R1_OFL) dev->stats.rx_over_errors++; + if (bits & LE_R1_FRA) dev->stats.rx_frame_errors++; + if (bits & LE_R1_EOP) dev->stats.rx_errors++; } else { len = (rd->mblength & 0xfff) - 4; skb = dev_alloc_skb(len + 2); @@ -537,14 +539,14 @@ static void lance_rx_dvma(struct net_device *dev) if (skb == NULL) { printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; rd->mblength = 0; rd->rmd1_bits = LE_R1_OWN; lp->rx_new = RX_NEXT(entry); return; } - lp->stats.rx_bytes += len; + dev->stats.rx_bytes += len; skb_reserve(skb, 2); /* 16 byte align */ skb_put(skb, len); /* make room */ @@ -553,8 +555,7 @@ static void lance_rx_dvma(struct net_device *dev) len); skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); - dev->last_rx = jiffies; - lp->stats.rx_packets++; + dev->stats.rx_packets++; } /* Return the packet to the pool */ @@ -586,12 +587,12 @@ static void lance_tx_dvma(struct net_device *dev) if (bits & LE_T1_ERR) { u16 status = td->misc; - lp->stats.tx_errors++; - if (status & LE_T3_RTY) lp->stats.tx_aborted_errors++; - if (status & LE_T3_LCOL) lp->stats.tx_window_errors++; + dev->stats.tx_errors++; + if (status & LE_T3_RTY) dev->stats.tx_aborted_errors++; + if (status & LE_T3_LCOL) dev->stats.tx_window_errors++; if (status & LE_T3_CLOS) { - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (lp->auto_select) { lp->tpe = 1 - lp->tpe; printk(KERN_NOTICE "%s: Carrier Lost, trying %s\n", @@ -608,7 +609,7 @@ static void lance_tx_dvma(struct net_device *dev) * transmitter, restart the adapter. */ if (status & (LE_T3_BUF|LE_T3_UFL)) { - lp->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; printk(KERN_ERR "%s: Tx: ERR_BUF|ERR_UFL, restarting\n", dev->name); @@ -626,13 +627,13 @@ static void lance_tx_dvma(struct net_device *dev) /* One collision before packet was sent. */ if (bits & LE_T1_EONE) - lp->stats.collisions++; + dev->stats.collisions++; /* More than one collision, be optimistic. */ if (bits & LE_T1_EMORE) - lp->stats.collisions += 2; + dev->stats.collisions += 2; - lp->stats.tx_packets++; + dev->stats.tx_packets++; } j = TX_NEXT(j); @@ -692,17 +693,17 @@ static void lance_rx_pio(struct net_device *dev) /* We got an incomplete frame? */ if ((bits & LE_R1_POK) != LE_R1_POK) { - lp->stats.rx_over_errors++; - lp->stats.rx_errors++; + dev->stats.rx_over_errors++; + dev->stats.rx_errors++; } else if (bits & LE_R1_ERR) { /* Count only the end frame as a rx error, * not the beginning */ - if (bits & LE_R1_BUF) lp->stats.rx_fifo_errors++; - if (bits & LE_R1_CRC) lp->stats.rx_crc_errors++; - if (bits & LE_R1_OFL) lp->stats.rx_over_errors++; - if (bits & LE_R1_FRA) lp->stats.rx_frame_errors++; - if (bits & LE_R1_EOP) lp->stats.rx_errors++; + if (bits & LE_R1_BUF) dev->stats.rx_fifo_errors++; + if (bits & LE_R1_CRC) dev->stats.rx_crc_errors++; + if (bits & LE_R1_OFL) dev->stats.rx_over_errors++; + if (bits & LE_R1_FRA) dev->stats.rx_frame_errors++; + if (bits & LE_R1_EOP) dev->stats.rx_errors++; } else { len = (sbus_readw(&rd->mblength) & 0xfff) - 4; skb = dev_alloc_skb(len + 2); @@ -710,22 +711,21 @@ static void lance_rx_pio(struct net_device *dev) if (skb == NULL) { printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n", dev->name); - lp->stats.rx_dropped++; + dev->stats.rx_dropped++; sbus_writew(0, &rd->mblength); sbus_writeb(LE_R1_OWN, &rd->rmd1_bits); lp->rx_new = RX_NEXT(entry); return; } - lp->stats.rx_bytes += len; + dev->stats.rx_bytes += len; skb_reserve (skb, 2); /* 16 byte align */ skb_put(skb, len); /* make room */ lance_piocopy_to_skb(skb, &(ib->rx_buf[entry][0]), len); skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); - dev->last_rx = jiffies; - lp->stats.rx_packets++; + dev->stats.rx_packets++; } /* Return the packet to the pool */ @@ -757,12 +757,12 @@ static void lance_tx_pio(struct net_device *dev) if (bits & LE_T1_ERR) { u16 status = sbus_readw(&td->misc); - lp->stats.tx_errors++; - if (status & LE_T3_RTY) lp->stats.tx_aborted_errors++; - if (status & LE_T3_LCOL) lp->stats.tx_window_errors++; + dev->stats.tx_errors++; + if (status & LE_T3_RTY) dev->stats.tx_aborted_errors++; + if (status & LE_T3_LCOL) dev->stats.tx_window_errors++; if (status & LE_T3_CLOS) { - lp->stats.tx_carrier_errors++; + dev->stats.tx_carrier_errors++; if (lp->auto_select) { lp->tpe = 1 - lp->tpe; printk(KERN_NOTICE "%s: Carrier Lost, trying %s\n", @@ -779,7 +779,7 @@ static void lance_tx_pio(struct net_device *dev) * transmitter, restart the adapter. */ if (status & (LE_T3_BUF|LE_T3_UFL)) { - lp->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; printk(KERN_ERR "%s: Tx: ERR_BUF|ERR_UFL, restarting\n", dev->name); @@ -797,13 +797,13 @@ static void lance_tx_pio(struct net_device *dev) /* One collision before packet was sent. */ if (bits & LE_T1_EONE) - lp->stats.collisions++; + dev->stats.collisions++; /* More than one collision, be optimistic. */ if (bits & LE_T1_EMORE) - lp->stats.collisions += 2; + dev->stats.collisions += 2; - lp->stats.tx_packets++; + dev->stats.tx_packets++; } j = TX_NEXT(j); @@ -844,10 +844,10 @@ static irqreturn_t lance_interrupt(int irq, void *dev_id) lp->tx(dev); if (csr0 & LE_C0_BABL) - lp->stats.tx_errors++; + dev->stats.tx_errors++; if (csr0 & LE_C0_MISS) - lp->stats.rx_errors++; + dev->stats.rx_errors++; if (csr0 & LE_C0_MERR) { if (lp->dregs) { @@ -916,15 +916,11 @@ static void build_fake_packet(struct lance_private *lp) lp->tx_new = TX_NEXT(entry); } -struct net_device *last_dev; - static int lance_open(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); int status = 0; - last_dev = dev; - STOP_LANCE(lp); if (request_irq(dev->irq, &lance_interrupt, IRQF_SHARED, @@ -1127,7 +1123,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_lock_irq(&lp->lock); - lp->stats.tx_bytes += len; + dev->stats.tx_bytes += len; entry = lp->tx_new & TX_RING_MOD_MASK; if (lp->pio_buffer) { @@ -1170,13 +1166,6 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } -static struct net_device_stats *lance_get_stats(struct net_device *dev) -{ - struct lance_private *lp = netdev_priv(dev); - - return &lp->stats; -} - /* taken from the depca driver */ static void lance_load_multicast(struct net_device *dev) { @@ -1284,27 +1273,29 @@ static void lance_set_multicast_retry(unsigned long _opaque) static void lance_free_hwresources(struct lance_private *lp) { if (lp->lregs) - sbus_iounmap(lp->lregs, LANCE_REG_SIZE); + of_iounmap(&lp->op->resource[0], lp->lregs, LANCE_REG_SIZE); + if (lp->dregs) { + struct of_device *ledma = lp->ledma; + + of_iounmap(&ledma->resource[0], lp->dregs, + resource_size(&ledma->resource[0])); + } if (lp->init_block_iomem) { - sbus_iounmap(lp->init_block_iomem, - sizeof(struct lance_init_block)); + of_iounmap(&lp->lebuffer->resource[0], lp->init_block_iomem, + sizeof(struct lance_init_block)); } else if (lp->init_block_mem) { - sbus_free_consistent(lp->sdev, - sizeof(struct lance_init_block), - lp->init_block_mem, - lp->init_block_dvma); + dma_free_coherent(&lp->op->dev, + sizeof(struct lance_init_block), + lp->init_block_mem, + lp->init_block_dvma); } } /* Ethtool support... */ static void sparc_lance_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct lance_private *lp = netdev_priv(dev); - strcpy(info->driver, "sunlance"); strcpy(info->version, "2.02"); - sprintf(info->bus_info, "SBUS:%d", - lp->sdev->slot); } static u32 sparc_lance_get_link(struct net_device *dev) @@ -1320,14 +1311,25 @@ static const struct ethtool_ops sparc_lance_ethtool_ops = { .get_link = sparc_lance_get_link, }; -static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev, - struct sbus_dma *ledma, - struct sbus_dev *lebuffer) +static const struct net_device_ops sparc_lance_ops = { + .ndo_open = lance_open, + .ndo_stop = lance_close, + .ndo_start_xmit = lance_start_xmit, + .ndo_set_multicast_list = lance_set_multicast, + .ndo_tx_timeout = lance_tx_timeout, + .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, +}; + +static int __devinit sparc_lance_probe_one(struct of_device *op, + struct of_device *ledma, + struct of_device *lebuffer) { + struct device_node *dp = op->node; static unsigned version_printed; - struct device_node *dp = sdev->ofdev.node; - struct net_device *dev; struct lance_private *lp; + struct net_device *dev; int i; dev = alloc_etherdev(sizeof(struct lance_private) + 8); @@ -1349,14 +1351,27 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev, dev->dev_addr[i] = idprom->id_ethaddr[i]; /* Get the IO region */ - lp->lregs = sbus_ioremap(&sdev->resource[0], 0, - LANCE_REG_SIZE, lancestr); + lp->lregs = of_ioremap(&op->resource[0], 0, + LANCE_REG_SIZE, lancestr); if (!lp->lregs) { printk(KERN_ERR "SunLance: Cannot map registers.\n"); goto fail; } - lp->sdev = sdev; + lp->ledma = ledma; + if (lp->ledma) { + lp->dregs = of_ioremap(&ledma->resource[0], 0, + resource_size(&ledma->resource[0]), + "ledma"); + if (!lp->dregs) { + printk(KERN_ERR "SunLance: Cannot map " + "ledma registers.\n"); + goto fail; + } + } + + lp->op = op; + lp->lebuffer = lebuffer; if (lebuffer) { /* sanity check */ if (lebuffer->resource[0].start & 7) { @@ -1364,8 +1379,8 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev, goto fail; } lp->init_block_iomem = - sbus_ioremap(&lebuffer->resource[0], 0, - sizeof(struct lance_init_block), "lebuffer"); + of_ioremap(&lebuffer->resource[0], 0, + sizeof(struct lance_init_block), "lebuffer"); if (!lp->init_block_iomem) { printk(KERN_ERR "SunLance: Cannot map PIO buffer.\n"); goto fail; @@ -1377,9 +1392,10 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev, lp->tx = lance_tx_pio; } else { lp->init_block_mem = - sbus_alloc_consistent(sdev, sizeof(struct lance_init_block), - &lp->init_block_dvma); - if (!lp->init_block_mem || lp->init_block_dvma == 0) { + dma_alloc_coherent(&op->dev, + sizeof(struct lance_init_block), + &lp->init_block_dvma, GFP_ATOMIC); + if (!lp->init_block_mem) { printk(KERN_ERR "SunLance: Cannot allocate consistent DMA memory.\n"); goto fail; } @@ -1394,13 +1410,13 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev, LE_C3_BCON)); lp->name = lancestr; - lp->ledma = ledma; lp->burst_sizes = 0; if (lp->ledma) { - struct device_node *ledma_dp = ledma->sdev->ofdev.node; - const char *prop; + struct device_node *ledma_dp = ledma->node; + struct device_node *sbus_dp; unsigned int sbmask; + const char *prop; u32 csr; /* Find burst-size property for ledma */ @@ -1408,7 +1424,8 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev, "burst-sizes", 0); /* ledma may be capable of fast bursts, but sbus may not. */ - sbmask = of_getintprop_default(ledma_dp, "burst-sizes", + sbus_dp = ledma_dp->parent; + sbmask = of_getintprop_default(sbus_dp, "burst-sizes", DMA_BURSTBITS); lp->burst_sizes &= sbmask; @@ -1446,8 +1463,6 @@ no_link_test: lp->tpe = 1; } - lp->dregs = ledma->regs; - /* Reset ledma */ csr = sbus_readl(lp->dregs + DMA_CSR); sbus_writel(csr | DMA_RST_ENET, lp->dregs + DMA_CSR); @@ -1457,19 +1472,12 @@ no_link_test: lp->dregs = NULL; lp->dev = dev; - SET_NETDEV_DEV(dev, &sdev->ofdev.dev); - dev->open = &lance_open; - dev->stop = &lance_close; - dev->hard_start_xmit = &lance_start_xmit; - dev->tx_timeout = &lance_tx_timeout; + SET_NETDEV_DEV(dev, &op->dev); dev->watchdog_timeo = 5*HZ; - dev->get_stats = &lance_get_stats; - dev->set_multicast_list = &lance_set_multicast; dev->ethtool_ops = &sparc_lance_ethtool_ops; + dev->netdev_ops = &sparc_lance_ops; - dev->irq = sdev->irqs[0]; - - dev->dma = 0; + dev->irq = op->irqs[0]; /* We cannot sleep if the chip is busy during a * multicast list update event, because such events @@ -1485,14 +1493,10 @@ no_link_test: goto fail; } - dev_set_drvdata(&sdev->ofdev.dev, lp); + dev_set_drvdata(&op->dev, lp); - printk(KERN_INFO "%s: LANCE ", dev->name); - - for (i = 0; i < 6; i++) - printk("%2.2x%c", dev->dev_addr[i], - i == 5 ? ' ': ':'); - printk("\n"); + printk(KERN_INFO "%s: LANCE %pM\n", + dev->name, dev->dev_addr); return 0; @@ -1502,80 +1506,25 @@ fail: return -ENODEV; } -/* On 4m, find the associated dma for the lance chip */ -static struct sbus_dma * __devinit find_ledma(struct sbus_dev *sdev) +static int __devinit sunlance_sbus_probe(struct of_device *op, const struct of_device_id *match) { - struct sbus_dma *p; - - for_each_dvma(p) { - if (p->sdev == sdev) - return p; - } - return NULL; -} - -#ifdef CONFIG_SUN4 - -#include -#include - -/* Find all the lance cards on the system and initialize them */ -static struct sbus_dev sun4_sdev; -static int __devinit sparc_lance_init(void) -{ - if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || - (idprom->id_machtype == (SM_SUN4|SM_4_470))) { - memset(&sun4_sdev, 0, sizeof(struct sbus_dev)); - sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; - sun4_sdev.irqs[0] = 6; - return sparc_lance_probe_one(&sun4_sdev, NULL, NULL); - } - return -ENODEV; -} - -static int __exit sunlance_sun4_remove(void) -{ - struct lance_private *lp = dev_get_drvdata(&sun4_sdev.ofdev.dev); - struct net_device *net_dev = lp->dev; - - unregister_netdev(net_dev); - - lance_free_hwresources(lp); - - free_netdev(net_dev); - - dev_set_drvdata(&sun4_sdev.ofdev.dev, NULL); - - return 0; -} - -#else /* !CONFIG_SUN4 */ - -static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match) -{ - struct sbus_dev *sdev = to_sbus_device(&dev->dev); + struct of_device *parent = to_of_device(op->dev.parent); + struct device_node *parent_dp = parent->node; int err; - if (sdev->parent) { - struct of_device *parent = &sdev->parent->ofdev; - - if (!strcmp(parent->node->name, "ledma")) { - struct sbus_dma *ledma = find_ledma(to_sbus_device(&parent->dev)); - - err = sparc_lance_probe_one(sdev, ledma, NULL); - } else if (!strcmp(parent->node->name, "lebuffer")) { - err = sparc_lance_probe_one(sdev, NULL, to_sbus_device(&parent->dev)); - } else - err = sparc_lance_probe_one(sdev, NULL, NULL); + if (!strcmp(parent_dp->name, "ledma")) { + err = sparc_lance_probe_one(op, parent, NULL); + } else if (!strcmp(parent_dp->name, "lebuffer")) { + err = sparc_lance_probe_one(op, NULL, parent); } else - err = sparc_lance_probe_one(sdev, NULL, NULL); + err = sparc_lance_probe_one(op, NULL, NULL); return err; } -static int __devexit sunlance_sbus_remove(struct of_device *dev) +static int __devexit sunlance_sbus_remove(struct of_device *op) { - struct lance_private *lp = dev_get_drvdata(&dev->dev); + struct lance_private *lp = dev_get_drvdata(&op->dev); struct net_device *net_dev = lp->dev; unregister_netdev(net_dev); @@ -1584,12 +1533,12 @@ static int __devexit sunlance_sbus_remove(struct of_device *dev) free_netdev(net_dev); - dev_set_drvdata(&dev->dev, NULL); + dev_set_drvdata(&op->dev, NULL); return 0; } -static struct of_device_id sunlance_sbus_match[] = { +static const struct of_device_id sunlance_sbus_match[] = { { .name = "le", }, @@ -1609,17 +1558,12 @@ static struct of_platform_driver sunlance_sbus_driver = { /* Find all the lance cards on the system and initialize them */ static int __init sparc_lance_init(void) { - return of_register_driver(&sunlance_sbus_driver, &sbus_bus_type); + return of_register_driver(&sunlance_sbus_driver, &of_bus_type); } -#endif /* !CONFIG_SUN4 */ static void __exit sparc_lance_exit(void) { -#ifdef CONFIG_SUN4 - sunlance_sun4_remove(); -#else of_unregister_driver(&sunlance_sbus_driver); -#endif } module_init(sparc_lance_init);