X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fnet%2Fbmac.c;h=406f06424251bad893c7fce9d53c680046cab377;hb=6d898b1983b62ad52f862014748ddce35aad005a;hp=711609665632a9c713b24984b1c010aea9e7d56e;hpb=1a2509c946bfd4d4a4c5a6e816082d3a7de45db8;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 7116096..406f064 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -73,7 +75,6 @@ struct bmac_data { int tx_fill; int tx_empty; unsigned char tx_fullup; - struct net_device_stats stats; struct timer_list tx_timeout; int timeout_active; int sleeping; @@ -140,11 +141,9 @@ static unsigned char *bmac_emergency_rxbuf; + (N_RX_RING + N_TX_RING + 4) * sizeof(struct dbdma_cmd) \ + sizeof(struct sk_buff_head)) -static unsigned char bitrev(unsigned char b); static int bmac_open(struct net_device *dev); static int bmac_close(struct net_device *dev); static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev); -static struct net_device_stats *bmac_stats(struct net_device *dev); static void bmac_set_multicast(struct net_device *dev); static void bmac_reset_and_enable(struct net_device *dev); static void bmac_start_chip(struct net_device *dev); @@ -152,9 +151,9 @@ static void bmac_init_chip(struct net_device *dev); static void bmac_init_registers(struct net_device *dev); static void bmac_enable_and_reset_chip(struct net_device *dev); static int bmac_set_address(struct net_device *dev, void *addr); -static irqreturn_t bmac_misc_intr(int irq, void *dev_id, struct pt_regs *regs); -static irqreturn_t bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs); -static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t bmac_misc_intr(int irq, void *dev_id); +static irqreturn_t bmac_txdma_intr(int irq, void *dev_id); +static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id); static void bmac_set_timeout(struct net_device *dev); static void bmac_tx_timeout(unsigned long data); static int bmac_output(struct sk_buff *skb, struct net_device *dev); @@ -333,7 +332,7 @@ bmac_init_registers(struct net_device *dev) udelay(10000); } - bmwrite(dev, RSEED, (unsigned short)0x1968); + bmwrite(dev, RSEED, (unsigned short)0x1968); regValue = bmread(dev, XIFC); regValue |= TxOutputEnable; @@ -373,7 +372,7 @@ bmac_init_registers(struct net_device *dev) bmwrite(dev, BHASH2, bp->hash_table_mask[1]); /* bits 31 - 16 */ bmwrite(dev, BHASH1, bp->hash_table_mask[2]); /* bits 47 - 32 */ bmwrite(dev, BHASH0, bp->hash_table_mask[3]); /* bits 63 - 48 */ - + pWord16 = (unsigned short *)dev->dev_addr; bmwrite(dev, MADD0, *pWord16++); bmwrite(dev, MADD1, *pWord16++); @@ -411,11 +410,11 @@ bmac_start_chip(struct net_device *dev) /* enable rx dma channel */ dbdma_continue(rd); - oldConfig = bmread(dev, TXCFG); + oldConfig = bmread(dev, TXCFG); bmwrite(dev, TXCFG, oldConfig | TxMACEnable ); /* turn on rx plus any other bits already on (promiscuous possibly) */ - oldConfig = bmread(dev, RXCFG); + oldConfig = bmread(dev, RXCFG); bmwrite(dev, RXCFG, oldConfig | RxMACEnable ); udelay(20000); } @@ -429,10 +428,11 @@ bmac_init_phy(struct net_device *dev) printk(KERN_DEBUG "phy registers:"); for (addr = 0; addr < 32; ++addr) { if ((addr & 7) == 0) - printk("\n" KERN_DEBUG); - printk(" %.4x", bmac_mif_read(dev, addr)); + printk(KERN_DEBUG); + printk(KERN_CONT " %.4x", bmac_mif_read(dev, addr)); } - printk("\n"); + printk(KERN_CONT "\n"); + if (bp->is_bmac_plus) { unsigned int capable, ctrl; @@ -456,12 +456,12 @@ static void bmac_init_chip(struct net_device *dev) #ifdef CONFIG_PM static int bmac_suspend(struct macio_dev *mdev, pm_message_t state) { - struct net_device* dev = macio_get_drvdata(mdev); + struct net_device* dev = macio_get_drvdata(mdev); struct bmac_data *bp = netdev_priv(dev); unsigned long flags; unsigned short config; int i; - + netif_device_detach(dev); /* prolly should wait for dma to finish & turn off the chip */ spin_lock_irqsave(&bp->lock, flags); @@ -477,7 +477,7 @@ static int bmac_suspend(struct macio_dev *mdev, pm_message_t state) if (bp->opened) { volatile struct dbdma_regs __iomem *rd = bp->rx_dma; volatile struct dbdma_regs __iomem *td = bp->tx_dma; - + config = bmread(dev, RXCFG); bmwrite(dev, RXCFG, (config & ~RxMACEnable)); config = bmread(dev, TXCFG); @@ -506,7 +506,7 @@ static int bmac_suspend(struct macio_dev *mdev, pm_message_t state) static int bmac_resume(struct macio_dev *mdev) { - struct net_device* dev = macio_get_drvdata(mdev); + struct net_device* dev = macio_get_drvdata(mdev); struct bmac_data *bp = netdev_priv(dev); /* see if this is enough */ @@ -586,18 +586,6 @@ bmac_construct_rxbuff(struct sk_buff *skb, volatile struct dbdma_cmd *cp) virt_to_bus(addr), 0); } -/* Bit-reverse one byte of an ethernet hardware address. */ -static unsigned char -bitrev(unsigned char b) -{ - int d = 0, i; - - for (i = 0; i < 8; ++i, b >>= 1) - d = (d << 1) | (b & 1); - return d; -} - - static void bmac_init_tx_ring(struct bmac_data *bp) { @@ -679,7 +667,7 @@ static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev) bp->tx_bufs[bp->tx_fill] = skb; bp->tx_fill = i; - bp->stats.tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; dbdma_continue(td); @@ -688,7 +676,7 @@ static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev) static int rxintcount; -static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id) { struct net_device *dev = (struct net_device *) dev_id; struct bmac_data *bp = netdev_priv(dev); @@ -718,8 +706,8 @@ static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) nb = RX_BUFLEN - residual - 2; if (nb < (ETHERMINPACKET - ETHERCRC)) { skb = NULL; - bp->stats.rx_length_errors++; - bp->stats.rx_errors++; + dev->stats.rx_length_errors++; + dev->stats.rx_errors++; } else { skb = bp->rx_bufs[i]; bp->rx_bufs[i] = NULL; @@ -727,16 +715,13 @@ static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) if (skb != NULL) { nb -= ETHERCRC; skb_put(skb, nb); - skb->dev = dev; skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); - dev->last_rx = jiffies; - ++bp->stats.rx_packets; - bp->stats.rx_bytes += nb; + ++dev->stats.rx_packets; + dev->stats.rx_bytes += nb; } else { - ++bp->stats.rx_dropped; + ++dev->stats.rx_dropped; } - dev->last_rx = jiffies; if ((skb = bp->rx_bufs[i]) == NULL) { bp->rx_bufs[i] = skb = dev_alloc_skb(RX_BUFLEN+2); if (skb != NULL) @@ -765,7 +750,7 @@ static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) static int txintcount; -static irqreturn_t bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t bmac_txdma_intr(int irq, void *dev_id) { struct net_device *dev = (struct net_device *) dev_id; struct bmac_data *bp = netdev_priv(dev); @@ -797,7 +782,7 @@ static irqreturn_t bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs) } if (bp->tx_bufs[bp->tx_empty]) { - ++bp->stats.tx_packets; + ++dev->stats.tx_packets; dev_kfree_skb_irq(bp->tx_bufs[bp->tx_empty]); } bp->tx_bufs[bp->tx_empty] = NULL; @@ -819,13 +804,6 @@ static irqreturn_t bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs) return IRQ_HANDLED; } -static struct net_device_stats *bmac_stats(struct net_device *dev) -{ - struct bmac_data *p = netdev_priv(dev); - - return &p->stats; -} - #ifndef SUNHME_MULTICAST /* Real fast bit-reversal algorithm, 6-bit values */ static int reverse6[64] = { @@ -855,12 +833,12 @@ crc416(unsigned int curval, unsigned short nxtval) else high_crc_set = 1; cur = cur << 1; - + if ((next & 0x0001) == 0) low_data_set = 0; else low_data_set = 1; next = next >> 1; - + /* do the XOR */ if (high_crc_set ^ low_data_set) cur = cur ^ ENET_CRCPOLY; } @@ -869,7 +847,7 @@ crc416(unsigned int curval, unsigned short nxtval) static unsigned int bmac_crc(unsigned short *address) -{ +{ unsigned int newcrc; XXDEBUG(("bmac_crc: addr=%#04x, %#04x, %#04x\n", *address, address[1], address[2])); @@ -887,7 +865,7 @@ bmac_crc(unsigned short *address) static void bmac_addhash(struct bmac_data *bp, unsigned char *addr) -{ +{ unsigned int crc; unsigned short mask; @@ -902,7 +880,7 @@ bmac_addhash(struct bmac_data *bp, unsigned char *addr) static void bmac_removehash(struct bmac_data *bp, unsigned char *addr) -{ +{ unsigned int crc; unsigned char mask; @@ -1054,13 +1032,13 @@ static void bmac_set_multicast(struct net_device *dev) bmwrite(dev, RXCFG, rx_cfg); } else { u16 hash_table[4]; - + rx_cfg = bmread(dev, RXCFG); rx_cfg &= ~RxPromiscEnable; bmwrite(dev, RXCFG, rx_cfg); for(i = 0; i < 4; i++) hash_table[i] = 0; - + for(i = 0; i < dev->mc_count; i++) { addrs = dmi->dmi_addr; dmi = dmi->next; @@ -1082,27 +1060,26 @@ static void bmac_set_multicast(struct net_device *dev) static int miscintcount; -static irqreturn_t bmac_misc_intr(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t bmac_misc_intr(int irq, void *dev_id) { struct net_device *dev = (struct net_device *) dev_id; - struct bmac_data *bp = netdev_priv(dev); unsigned int status = bmread(dev, STATUS); if (miscintcount++ < 10) { XXDEBUG(("bmac_misc_intr\n")); } /* XXDEBUG(("bmac_misc_intr, status=%#08x\n", status)); */ - /* bmac_txdma_intr_inner(irq, dev_id, regs); */ - /* if (status & FrameReceived) bp->stats.rx_dropped++; */ - if (status & RxErrorMask) bp->stats.rx_errors++; - if (status & RxCRCCntExp) bp->stats.rx_crc_errors++; - if (status & RxLenCntExp) bp->stats.rx_length_errors++; - if (status & RxOverFlow) bp->stats.rx_over_errors++; - if (status & RxAlignCntExp) bp->stats.rx_frame_errors++; - - /* if (status & FrameSent) bp->stats.tx_dropped++; */ - if (status & TxErrorMask) bp->stats.tx_errors++; - if (status & TxUnderrun) bp->stats.tx_fifo_errors++; - if (status & TxNormalCollExp) bp->stats.collisions++; + /* bmac_txdma_intr_inner(irq, dev_id); */ + /* if (status & FrameReceived) dev->stats.rx_dropped++; */ + if (status & RxErrorMask) dev->stats.rx_errors++; + if (status & RxCRCCntExp) dev->stats.rx_crc_errors++; + if (status & RxLenCntExp) dev->stats.rx_length_errors++; + if (status & RxOverFlow) dev->stats.rx_over_errors++; + if (status & RxAlignCntExp) dev->stats.rx_frame_errors++; + + /* if (status & FrameSent) dev->stats.tx_dropped++; */ + if (status & TxErrorMask) dev->stats.tx_errors++; + if (status & TxUnderrun) dev->stats.tx_fifo_errors++; + if (status & TxNormalCollExp) dev->stats.collisions++; return IRQ_HANDLED; } @@ -1220,12 +1197,12 @@ bmac_get_station_address(struct net_device *dev, unsigned char *ea) int i; unsigned short data; - for (i = 0; i < 6; i++) + for (i = 0; i < 6; i++) { reset_and_select_srom(dev); data = read_srom(dev, i + EnetAddressOffset/2, SROMAddressBits); - ea[2*i] = bitrev(data & 0x0ff); - ea[2*i+1] = bitrev((data >> 8) & 0x0ff); + ea[2*i] = bitrev8(data & 0x0ff); + ea[2*i+1] = bitrev8((data >> 8) & 0x0ff); } } @@ -1244,7 +1221,7 @@ static void bmac_reset_and_enable(struct net_device *dev) bmac_start_chip(dev); bmwrite(dev, INTDISABLE, EnableNormal); bp->sleeping = 0; - + /* * It seems that the bmac can't receive until it's transmitted * a packet. So we give it a dummy packet to transmit. @@ -1259,6 +1236,27 @@ static void bmac_reset_and_enable(struct net_device *dev) } spin_unlock_irqrestore(&bp->lock, flags); } +static void bmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct bmac_data *bp = netdev_priv(dev); + strcpy(info->driver, "bmac"); + strcpy(info->bus_info, dev_name(&bp->mdev->ofdev.dev)); +} + +static const struct ethtool_ops bmac_ethtool_ops = { + .get_drvinfo = bmac_get_drvinfo, + .get_link = ethtool_op_get_link, +}; + +static const struct net_device_ops bmac_netdev_ops = { + .ndo_open = bmac_open, + .ndo_stop = bmac_close, + .ndo_start_xmit = bmac_output, + .ndo_set_multicast_list = bmac_set_multicast, + .ndo_set_mac_address = bmac_set_address, + .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, +}; static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_id *match) { @@ -1273,9 +1271,10 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i printk(KERN_ERR "BMAC: can't use, need 3 addrs and 3 intrs\n"); return -ENODEV; } - prop_addr = get_property(macio_get_of_node(mdev), "mac-address", NULL); + prop_addr = of_get_property(macio_get_of_node(mdev), + "mac-address", NULL); if (prop_addr == NULL) { - prop_addr = get_property(macio_get_of_node(mdev), + prop_addr = of_get_property(macio_get_of_node(mdev), "local-mac-address", NULL); if (prop_addr == NULL) { printk(KERN_ERR "BMAC: Can't get mac-address\n"); @@ -1289,9 +1288,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i printk(KERN_ERR "BMAC: alloc_etherdev failed, out of memory\n"); return -ENOMEM; } - + bp = netdev_priv(dev); - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &mdev->ofdev.dev); macio_set_drvdata(mdev, dev); @@ -1315,18 +1313,14 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i rev = addr[0] == 0 && addr[1] == 0xA0; for (j = 0; j < 6; ++j) - dev->dev_addr[j] = rev? bitrev(addr[j]): addr[j]; + dev->dev_addr[j] = rev ? bitrev8(addr[j]): addr[j]; /* Enable chip without interrupts for now */ bmac_enable_and_reset_chip(dev); bmwrite(dev, INTDISABLE, DisableAll); - dev->open = bmac_open; - dev->stop = bmac_close; - dev->hard_start_xmit = bmac_output; - dev->get_stats = bmac_stats; - dev->set_multicast_list = bmac_set_multicast; - dev->set_mac_address = bmac_set_address; + dev->netdev_ops = &bmac_netdev_ops; + dev->ethtool_ops = &bmac_ethtool_ops; bmac_get_station_address(dev, addr); if (bmac_verify_checksum(dev) != 0) @@ -1377,12 +1371,11 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i goto err_out_irq2; } - printk(KERN_INFO "%s: BMAC%s at", dev->name, (is_bmac_plus? "+": "")); - for (j = 0; j < 6; ++j) - printk("%c%.2x", (j? ':': ' '), dev->dev_addr[j]); + printk(KERN_INFO "%s: BMAC%s at %pM", + dev->name, (is_bmac_plus ? "+" : ""), dev->dev_addr); XXDEBUG((", base_addr=%#0lx", dev->base_addr)); printk("\n"); - + return 0; err_out_irq2: @@ -1474,7 +1467,7 @@ bmac_start(struct net_device *dev) if (bp->sleeping) return; - + spin_lock_irqsave(&bp->lock, flags); while (1) { i = bp->tx_fill + 1; @@ -1496,7 +1489,7 @@ bmac_output(struct sk_buff *skb, struct net_device *dev) struct bmac_data *bp = netdev_priv(dev); skb_queue_tail(bp->queue, skb); bmac_start(dev); - return 0; + return NETDEV_TX_OK; } static void bmac_tx_timeout(unsigned long data) @@ -1542,7 +1535,7 @@ static void bmac_tx_timeout(unsigned long data) XXDEBUG((KERN_DEBUG "bmac: tx empty=%d fill=%d fullup=%d\n", bp->tx_empty, bp->tx_fill, bp->tx_fullup)); i = bp->tx_empty; - ++bp->stats.tx_errors; + ++dev->stats.tx_errors; if (i != bp->tx_fill) { dev_kfree_skb(bp->tx_bufs[i]); bp->tx_bufs[i] = NULL; @@ -1562,9 +1555,9 @@ static void bmac_tx_timeout(unsigned long data) } /* turn it back on */ - oldConfig = bmread(dev, RXCFG); + oldConfig = bmread(dev, RXCFG); bmwrite(dev, RXCFG, oldConfig | RxMACEnable ); - oldConfig = bmread(dev, TXCFG); + oldConfig = bmread(dev, TXCFG); bmwrite(dev, TXCFG, oldConfig | TxMACEnable ); spin_unlock_irqrestore(&bp->lock, flags); @@ -1574,10 +1567,10 @@ static void bmac_tx_timeout(unsigned long data) static void dump_dbdma(volatile struct dbdma_cmd *cp,int count) { int i,*ip; - + for (i=0;i< count;i++) { ip = (int*)(cp+i); - + printk("dbdma req 0x%x addr 0x%x baddr 0x%x xfer/res 0x%x\n", ld_le32(ip+0), ld_le32(ip+1), @@ -1633,7 +1626,7 @@ static int __devexit bmac_remove(struct macio_dev *mdev) unregister_netdev(dev); free_irq(dev->irq, dev); - free_irq(bp->tx_dma_intr, dev); + free_irq(bp->tx_dma_intr, dev); free_irq(bp->rx_dma_intr, dev); iounmap((void __iomem *)dev->base_addr); @@ -1647,7 +1640,7 @@ static int __devexit bmac_remove(struct macio_dev *mdev) return 0; } -static struct of_device_id bmac_match[] = +static struct of_device_id bmac_match[] = { { .name = "bmac", @@ -1662,7 +1655,7 @@ static struct of_device_id bmac_match[] = }; MODULE_DEVICE_TABLE (of, bmac_match); -static struct macio_driver bmac_driver = +static struct macio_driver bmac_driver = { .name = "bmac", .match_table = bmac_match,