diff options
Diffstat (limited to 'drivers/net')
302 files changed, 3286 insertions, 1919 deletions
diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index bb44509fd40..07136ec423b 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -508,11 +508,11 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev) * speak of. We simply pull the packet out of its PIO buffer (which is slow) * and queue it for the kernel. Then we reset the card for the next packet. * - * We sometimes get suprise interrupts late both because the SMP IRQ delivery + * We sometimes get surprise interrupts late both because the SMP IRQ delivery * is message passing and because the card sometimes seems to deliver late. I * think if it is part way through a receive and the mode is changed it carries * on receiving and sends us an interrupt. We have to band aid all these cases - * to get a sensible 150kbytes/second performance. Even then you want a small + * to get a sensible 150kBytes/second performance. Even then you want a small * TCP window. */ diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index dc845f36fe4..cbdae54f715 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -68,7 +68,6 @@ /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ static int max_interrupt_work = 10; -#include <linux/config.h> #include <linux/module.h> #ifdef CONFIG_MCA #include <linux/mca.h> diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 91d1c4c24d9..4532b17e40e 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -57,7 +57,6 @@ static int max_interrupt_work = 20; #define RX_RING_SIZE 16 #define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/isapnp.h> #include <linux/kernel.h> @@ -761,7 +760,7 @@ static int corkscrew_open(struct net_device *dev) vp->product_name, dev)) return -EAGAIN; enable_dma(dev->dma); set_dma_mode(dev->dma, DMA_MODE_CASCADE); - } else if (request_irq(dev->irq, &corkscrew_interrupt, SA_SHIRQ, + } else if (request_irq(dev->irq, &corkscrew_interrupt, IRQF_SHARED, vp->product_name, dev)) { return -EAGAIN; } diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c index 4bf8510655c..5dfd97f0ba9 100644 --- a/drivers/net/3c523.c +++ b/drivers/net/3c523.c @@ -289,7 +289,7 @@ static int elmc_open(struct net_device *dev) elmc_id_attn586(); /* disable interrupts */ - ret = request_irq(dev->irq, &elmc_interrupt, SA_SHIRQ | SA_SAMPLE_RANDOM, + ret = request_irq(dev->irq, &elmc_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev); if (ret) { printk(KERN_ERR "%s: couldn't get irq %d\n", dev->name, dev->irq); diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c index 1b1cb002607..03c0f7176fc 100644 --- a/drivers/net/3c527.c +++ b/drivers/net/3c527.c @@ -435,7 +435,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot) * Grab the IRQ */ - err = request_irq(dev->irq, &mc32_interrupt, SA_SHIRQ | SA_SAMPLE_RANDOM, DRV_NAME, dev); + err = request_irq(dev->irq, &mc32_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, DRV_NAME, dev); if (err) { release_region(dev->base_addr, MC32_IO_EXTENT); printk(KERN_ERR "%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq); @@ -1031,8 +1031,7 @@ static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev) return 1; } - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) { + if (skb_padto(skb, ETH_ZLEN)) { netif_wake_queue(dev); return 0; } diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 274b0138d44..8ab03b4a885 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -236,7 +236,6 @@ static int vortex_debug = VORTEX_DEBUG; static int vortex_debug = 1; #endif -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/string.h> @@ -375,8 +374,7 @@ limit of 4K. of the drivers, and will likely be provided by some future kernel. */ enum pci_flags_bit { - PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, - PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, + PCI_USES_MASTER=4, }; enum { IS_VORTEX=1, IS_BOOMERANG=2, IS_CYCLONE=4, IS_TORNADO=8, @@ -446,95 +444,95 @@ static struct vortex_chip_info { int io_size; } vortex_info_tbl[] __devinitdata = { {"3c590 Vortex 10Mbps", - PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, + PCI_USES_MASTER, IS_VORTEX, 32, }, {"3c592 EISA 10Mbps Demon/Vortex", /* AKPM: from Don's 3c59x_cb.c 0.49H */ - PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, + PCI_USES_MASTER, IS_VORTEX, 32, }, {"3c597 EISA Fast Demon/Vortex", /* AKPM: from Don's 3c59x_cb.c 0.49H */ - PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, + PCI_USES_MASTER, IS_VORTEX, 32, }, {"3c595 Vortex 100baseTx", - PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, + PCI_USES_MASTER, IS_VORTEX, 32, }, {"3c595 Vortex 100baseT4", - PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, + PCI_USES_MASTER, IS_VORTEX, 32, }, {"3c595 Vortex 100base-MII", - PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, + PCI_USES_MASTER, IS_VORTEX, 32, }, {"3c900 Boomerang 10baseT", - PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, }, + PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, }, {"3c900 Boomerang 10Mbps Combo", - PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, }, + PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, }, {"3c900 Cyclone 10Mbps TPO", /* AKPM: from Don's 0.99M */ - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c900 Cyclone 10Mbps Combo", - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c900 Cyclone 10Mbps TPC", /* AKPM: from Don's 0.99M */ - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c900B-FL Cyclone 10base-FL", - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c905 Boomerang 100baseTx", - PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, }, + PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, }, {"3c905 Boomerang 100baseT4", - PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, }, + PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, }, {"3c905B Cyclone 100baseTx", - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, + PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, {"3c905B Cyclone 10/100/BNC", - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, {"3c905B-FX Cyclone 100baseFx", - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c905C Tornado", - PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, + PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, {"3c920B-EMB-WNM (ATI Radeon 9100 IGP)", - PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, }, {"3c980 Cyclone", - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c980C Python-T", - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, {"3cSOHO100-TX Hurricane", - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, {"3c555 Laptop Hurricane", - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|EEPROM_8BIT|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_CYCLONE|EEPROM_8BIT|HAS_HWCKSM, 128, }, {"3c556 Laptop Tornado", - PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_8BIT|HAS_CB_FNS|INVERT_MII_PWR| + PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_8BIT|HAS_CB_FNS|INVERT_MII_PWR| HAS_HWCKSM, 128, }, {"3c556B Laptop Hurricane", - PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR| + PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR| WNO_XCVR_PWR|HAS_HWCKSM, 128, }, {"3c575 [Megahertz] 10/100 LAN CardBus", - PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, + PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, {"3c575 Boomerang CardBus", - PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, + PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, {"3CCFE575BT Cyclone CardBus", - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT| + PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT| INVERT_LED_PWR|HAS_HWCKSM, 128, }, {"3CCFE575CT Tornado CardBus", - PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| + PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| MAX_COLLISION_RESET|HAS_HWCKSM, 128, }, {"3CCFE656 Cyclone CardBus", - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| + PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| INVERT_LED_PWR|HAS_HWCKSM, 128, }, {"3CCFEM656B Cyclone+Winmodem CardBus", - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| + PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| INVERT_LED_PWR|HAS_HWCKSM, 128, }, {"3CXFEM656C Tornado+Winmodem CardBus", /* From pcmcia-cs-3.1.5 */ - PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| + PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| MAX_COLLISION_RESET|HAS_HWCKSM, 128, }, {"3c450 HomePNA Tornado", /* AKPM: from Don's 0.99Q */ - PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, {"3c920 Tornado", - PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, {"3c982 Hydra Dual Port A", - PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, + PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, {"3c982 Hydra Dual Port B", - PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, + PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, {"3c905B-T4", - PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, + PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, {"3c920B-EMB-WNM Tornado", - PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, + PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, {NULL,}, /* NULL terminated list. */ }; @@ -998,7 +996,7 @@ static int vortex_resume(struct pci_dev *pdev) pci_enable_device(pdev); pci_set_master(pdev); if (request_irq(dev->irq, vp->full_bus_master_rx ? - &boomerang_interrupt : &vortex_interrupt, SA_SHIRQ, dev->name, dev)) { + &boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev)) { printk(KERN_WARNING "%s: Could not reserve IRQ %d\n", dev->name, dev->irq); pci_disable_device(pdev); return -EBUSY; @@ -1382,17 +1380,12 @@ static int __devinit vortex_probe1(struct device *gendev, for (i = 0; i < 6; i++) iowrite8(dev->dev_addr[i], ioaddr + i); -#ifdef __sparc__ - if (print_info) - printk(", IRQ %s\n", __irq_itoa(dev->irq)); -#else if (print_info) printk(", IRQ %d\n", dev->irq); /* Tell them about an invalid IRQ. */ if (dev->irq <= 0 || dev->irq >= NR_IRQS) printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n", dev->irq); -#endif EL3WINDOW(4); step = (ioread8(ioaddr + Wn4_NetDiag) & 0x1e) >> 1; @@ -1413,8 +1406,10 @@ static int __devinit vortex_probe1(struct device *gendev, } if (print_info) { - printk(KERN_INFO "%s: CardBus functions mapped %8.8lx->%p\n", - print_name, pci_resource_start(pdev, 2), + printk(KERN_INFO "%s: CardBus functions mapped " + "%16.16llx->%p\n", + print_name, + (unsigned long long)pci_resource_start(pdev, 2), vp->cb_fn_base); } EL3WINDOW(2); @@ -1838,7 +1833,7 @@ vortex_open(struct net_device *dev) /* Use the now-standard shared IRQ implementation. */ if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ? - &boomerang_interrupt : &vortex_interrupt, SA_SHIRQ, dev->name, dev))) { + &boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev))) { printk(KERN_ERR "%s: Could not reserve IRQ %d\n", dev->name, dev->irq); goto out; } diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 46d8c01437e..1959654cbec 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -52,7 +52,6 @@ #define DRV_RELDATE "Mar 22, 2004" -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> @@ -401,6 +400,11 @@ static void cp_clean_rings (struct cp_private *cp); #ifdef CONFIG_NET_POLL_CONTROLLER static void cp_poll_controller(struct net_device *dev); #endif +static int cp_get_eeprom_len(struct net_device *dev); +static int cp_get_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *data); +static int cp_set_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *data); static struct pci_device_id cp_pci_tbl[] = { { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139, @@ -792,7 +796,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) entry = cp->tx_head; eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0; if (dev->features & NETIF_F_TSO) - mss = skb_shinfo(skb)->tso_size; + mss = skb_shinfo(skb)->gso_size; if (skb_shinfo(skb)->nr_frags == 0) { struct cp_desc *txd = &cp->tx_ring[entry]; @@ -1199,7 +1203,7 @@ static int cp_open (struct net_device *dev) cp_init_hw(cp); - rc = request_irq(dev->irq, cp_interrupt, SA_SHIRQ, dev->name, dev); + rc = request_irq(dev->irq, cp_interrupt, IRQF_SHARED, dev->name, dev); if (rc) goto err_out_hw; @@ -1577,6 +1581,9 @@ static struct ethtool_ops cp_ethtool_ops = { .get_strings = cp_get_strings, .get_ethtool_stats = cp_get_ethtool_stats, .get_perm_addr = ethtool_op_get_perm_addr, + .get_eeprom_len = cp_get_eeprom_len, + .get_eeprom = cp_get_eeprom, + .set_eeprom = cp_set_eeprom, }; static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) @@ -1612,24 +1619,32 @@ static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) #define eeprom_delay() readl(ee_addr) /* The EEPROM commands include the alway-set leading bit. */ +#define EE_EXTEND_CMD (4) #define EE_WRITE_CMD (5) #define EE_READ_CMD (6) #define EE_ERASE_CMD (7) -static int read_eeprom (void __iomem *ioaddr, int location, int addr_len) -{ - int i; - unsigned retval = 0; - void __iomem *ee_addr = ioaddr + Cfg9346; - int read_cmd = location | (EE_READ_CMD << addr_len); +#define EE_EWDS_ADDR (0) +#define EE_WRAL_ADDR (1) +#define EE_ERAL_ADDR (2) +#define EE_EWEN_ADDR (3) + +#define CP_EEPROM_MAGIC PCI_DEVICE_ID_REALTEK_8139 +static void eeprom_cmd_start(void __iomem *ee_addr) +{ writeb (EE_ENB & ~EE_CS, ee_addr); writeb (EE_ENB, ee_addr); eeprom_delay (); +} - /* Shift the read command bits out. */ - for (i = 4 + addr_len; i >= 0; i--) { - int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; +static void eeprom_cmd(void __iomem *ee_addr, int cmd, int cmd_len) +{ + int i; + + /* Shift the command bits out. */ + for (i = cmd_len - 1; i >= 0; i--) { + int dataval = (cmd & (1 << i)) ? EE_DATA_WRITE : 0; writeb (EE_ENB | dataval, ee_addr); eeprom_delay (); writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); @@ -1637,6 +1652,33 @@ static int read_eeprom (void __iomem *ioaddr, int location, int addr_len) } writeb (EE_ENB, ee_addr); eeprom_delay (); +} + +static void eeprom_cmd_end(void __iomem *ee_addr) +{ + writeb (~EE_CS, ee_addr); + eeprom_delay (); +} + +static void eeprom_extend_cmd(void __iomem *ee_addr, int extend_cmd, + int addr_len) +{ + int cmd = (EE_EXTEND_CMD << addr_len) | (extend_cmd << (addr_len - 2)); + + eeprom_cmd_start(ee_addr); + eeprom_cmd(ee_addr, cmd, 3 + addr_len); + eeprom_cmd_end(ee_addr); +} + +static u16 read_eeprom (void __iomem *ioaddr, int location, int addr_len) +{ + int i; + u16 retval = 0; + void __iomem *ee_addr = ioaddr + Cfg9346; + int read_cmd = location | (EE_READ_CMD << addr_len); + + eeprom_cmd_start(ee_addr); + eeprom_cmd(ee_addr, read_cmd, 3 + addr_len); for (i = 16; i > 0; i--) { writeb (EE_ENB | EE_SHIFT_CLK, ee_addr); @@ -1648,13 +1690,125 @@ static int read_eeprom (void __iomem *ioaddr, int location, int addr_len) eeprom_delay (); } - /* Terminate the EEPROM access. */ - writeb (~EE_CS, ee_addr); - eeprom_delay (); + eeprom_cmd_end(ee_addr); return retval; } +static void write_eeprom(void __iomem *ioaddr, int location, u16 val, + int addr_len) +{ + int i; + void __iomem *ee_addr = ioaddr + Cfg9346; + int write_cmd = location | (EE_WRITE_CMD << addr_len); + + eeprom_extend_cmd(ee_addr, EE_EWEN_ADDR, addr_len); + + eeprom_cmd_start(ee_addr); + eeprom_cmd(ee_addr, write_cmd, 3 + addr_len); + eeprom_cmd(ee_addr, val, 16); + eeprom_cmd_end(ee_addr); + + eeprom_cmd_start(ee_addr); + for (i = 0; i < 20000; i++) + if (readb(ee_addr) & EE_DATA_READ) + break; + eeprom_cmd_end(ee_addr); + + eeprom_extend_cmd(ee_addr, EE_EWDS_ADDR, addr_len); +} + +static int cp_get_eeprom_len(struct net_device *dev) +{ + struct cp_private *cp = netdev_priv(dev); + int size; + + spin_lock_irq(&cp->lock); + size = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 256 : 128; + spin_unlock_irq(&cp->lock); + + return size; +} + +static int cp_get_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *data) +{ + struct cp_private *cp = netdev_priv(dev); + unsigned int addr_len; + u16 val; + u32 offset = eeprom->offset >> 1; + u32 len = eeprom->len; + u32 i = 0; + + eeprom->magic = CP_EEPROM_MAGIC; + + spin_lock_irq(&cp->lock); + + addr_len = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 8 : 6; + + if (eeprom->offset & 1) { + val = read_eeprom(cp->regs, offset, addr_len); + data[i++] = (u8)(val >> 8); + offset++; + } + + while (i < len - 1) { + val = read_eeprom(cp->regs, offset, addr_len); + data[i++] = (u8)val; + data[i++] = (u8)(val >> 8); + offset++; + } + + if (i < len) { + val = read_eeprom(cp->regs, offset, addr_len); + data[i] = (u8)val; + } + + spin_unlock_irq(&cp->lock); + return 0; +} + +static int cp_set_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *data) +{ + struct cp_private *cp = netdev_priv(dev); + unsigned int addr_len; + u16 val; + u32 offset = eeprom->offset >> 1; + u32 len = eeprom->len; + u32 i = 0; + + if (eeprom->magic != CP_EEPROM_MAGIC) + return -EINVAL; + + spin_lock_irq(&cp->lock); + + addr_len = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 8 : 6; + + if (eeprom->offset & 1) { + val = read_eeprom(cp->regs, offset, addr_len) & 0xff; + val |= (u16)data[i++] << 8; + write_eeprom(cp->regs, offset, val, addr_len); + offset++; + } + + while (i < len - 1) { + val = (u16)data[i++]; + val |= (u16)data[i++] << 8; + write_eeprom(cp->regs, offset, val, addr_len); + offset++; + } + + if (i < len) { + val = read_eeprom(cp->regs, offset, addr_len) & 0xff00; + val |= (u16)data[i]; + write_eeprom(cp->regs, offset, val, addr_len); + } + + spin_unlock_irq(&cp->lock); + return 0; +} + /* Put the board into D3cold state and wait for WakeUp signal */ static void cp_set_d3_state (struct cp_private *cp) { @@ -1668,7 +1822,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) struct cp_private *cp; int rc; void __iomem *regs; - long pciaddr; + resource_size_t pciaddr; unsigned int addr_len, i, pci_using_dac; u8 pci_rev; @@ -1728,8 +1882,8 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) } if (pci_resource_len(pdev, 1) < CP_REGS_SIZE) { rc = -EIO; - printk(KERN_ERR PFX "MMIO resource (%lx) too small on pci dev %s\n", - pci_resource_len(pdev, 1), pci_name(pdev)); + printk(KERN_ERR PFX "MMIO resource (%llx) too small on pci dev %s\n", + (unsigned long long)pci_resource_len(pdev, 1), pci_name(pdev)); goto err_out_res; } @@ -1761,8 +1915,9 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) regs = ioremap(pciaddr, CP_REGS_SIZE); if (!regs) { rc = -EIO; - printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n", - pci_resource_len(pdev, 1), pciaddr, pci_name(pdev)); + printk(KERN_ERR PFX "Cannot map PCI MMIO (%llx@%llx) on pci dev %s\n", + (unsigned long long)pci_resource_len(pdev, 1), + (unsigned long long)pciaddr, pci_name(pdev)); goto err_out_res; } dev->base_addr = (unsigned long) regs; diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index abd6261465f..717506b2b13 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -93,7 +93,6 @@ #define DRV_VERSION "0.9.27" -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/compiler.h> @@ -1311,7 +1310,7 @@ static int rtl8139_open (struct net_device *dev) int retval; void __iomem *ioaddr = tp->mmio_addr; - retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev); + retval = request_irq (dev->irq, rtl8139_interrupt, IRQF_SHARED, dev->name, dev); if (retval) return retval; @@ -1341,9 +1340,9 @@ static int rtl8139_open (struct net_device *dev) netif_start_queue (dev); if (netif_msg_ifup(tp)) - printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#lx IRQ %d" - " GP Pins %2.2x %s-duplex.\n", - dev->name, pci_resource_start (tp->pci_dev, 1), + printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#llx IRQ %d" + " GP Pins %2.2x %s-duplex.\n", dev->name, + (unsigned long long)pci_resource_start (tp->pci_dev, 1), dev->irq, RTL_R8 (MediaStatus), tp->mii.full_duplex ? "full" : "half"); diff --git a/drivers/net/82596.c b/drivers/net/82596.c index da0c878dcba..7e2ca957146 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -40,7 +40,6 @@ */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/string.h> @@ -1070,8 +1069,7 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) skb->len, (unsigned int)skb->data)); if (skb->len < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) return 0; length = ETH_ZLEN; } diff --git a/drivers/net/8390.c b/drivers/net/8390.c index f8702742008..86be96af9c8 100644 --- a/drivers/net/8390.c +++ b/drivers/net/8390.c @@ -275,12 +275,14 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev); int send_length = skb->len, output_page; unsigned long flags; + char buf[ETH_ZLEN]; + char *data = skb->data; if (skb->len < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) - return 0; + memset(buf, 0, ETH_ZLEN); /* more efficient than doing just the needed bits */ + memcpy(buf, data, skb->len); send_length = ETH_ZLEN; + data = buf; } /* Mask interrupts from the ethercard. @@ -347,7 +349,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) * trigger the send later, upon receiving a Tx done interrupt. */ - ei_block_output(dev, send_length, skb->data, output_page); + ei_block_output(dev, send_length, data, output_page); if (! ei_local->txing) { diff --git a/drivers/net/8390.h b/drivers/net/8390.h index 51e39dcd060..a9a58f518f4 100644 --- a/drivers/net/8390.h +++ b/drivers/net/8390.h @@ -7,7 +7,6 @@ #ifndef _8390_h #define _8390_h -#include <linux/config.h> #include <linux/if_ether.h> #include <linux/ioport.h> #include <linux/skbuff.h> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 0c6b45a11d1..39189903e35 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -854,6 +854,17 @@ config SMC9194 <file:Documentation/networking/net-modules.txt>. The module will be called smc9194. +config NET_NETX + tristate "NetX Ethernet support" + select MII + depends on NET_ETHERNET && ARCH_NETX + help + This is support for the Hilscher netX builtin Ethernet ports + + To compile this driver as a module, choose M here and read + <file:Documentation/networking/net-modules.txt>. The module + will be called netx-eth. + config DM9000 tristate "DM9000 support" depends on (ARM || MIPS) && NET_ETHERNET @@ -1376,8 +1387,8 @@ config APRICOT called apricot. config B44 - tristate "Broadcom 4400 ethernet support (EXPERIMENTAL)" - depends on NET_PCI && PCI && EXPERIMENTAL + tristate "Broadcom 4400 ethernet support" + depends on NET_PCI && PCI select MII help If you have a network (Ethernet) controller of this type, say Y and @@ -2190,7 +2201,7 @@ config BNX2 config SPIDER_NET tristate "Spider Gigabit Ethernet driver" - depends on PCI && PPC_CELL + depends on PCI && PPC_IBM_CELL_BLADE select FW_LOADER help This driver supports the Gigabit Ethernet chips present on the @@ -2198,11 +2209,11 @@ config SPIDER_NET config GIANFAR tristate "Gianfar Ethernet" - depends on 85xx || 83xx + depends on 85xx || 83xx || PPC_86xx select PHYLIB help - This driver supports the Gigabit TSEC on the MPC85xx - family of chips, and the FEC on the 8540 + This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx, + and MPC86xx family of chips, and the FEC on the 8540. config GFAR_NAPI bool "NAPI Support" diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 1eced328750..c91e95126f7 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -187,6 +187,7 @@ obj-$(CONFIG_MACSONIC) += macsonic.o obj-$(CONFIG_MACMACE) += macmace.o obj-$(CONFIG_MAC89x0) += mac89x0.o obj-$(CONFIG_TUN) += tun.o +obj-$(CONFIG_NET_NETX) += netx-eth.o obj-$(CONFIG_DL2K) += dl2k.o obj-$(CONFIG_R8169) += r8169.o obj-$(CONFIG_AMD8111_ETH) += amd8111e.o diff --git a/drivers/net/Space.c b/drivers/net/Space.c index 60304f7e7e5..a8c245a8226 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -27,7 +27,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/trdevice.h> diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c index 79bb56b8dce..f4ea62641ac 100644 --- a/drivers/net/a2065.c +++ b/drivers/net/a2065.c @@ -48,7 +48,6 @@ #include <linux/skbuff.h> #include <linux/slab.h> #include <linux/string.h> -#include <linux/config.h> #include <linux/init.h> #include <linux/crc32.h> #include <linux/zorro.h> @@ -496,7 +495,7 @@ static int lance_open (struct net_device *dev) ll->rdp = LE_C0_STOP; /* Install the Interrupt handler */ - ret = request_irq(IRQ_AMIGA_PORTS, lance_interrupt, SA_SHIRQ, + ret = request_irq(IRQ_AMIGA_PORTS, lance_interrupt, IRQF_SHARED, dev->name, dev); if (ret) return ret; @@ -573,8 +572,7 @@ static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) if (len < ETH_ZLEN) { len = ETH_ZLEN; - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) return 0; } diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index b508812e97a..1c01e9b3d07 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -50,7 +50,6 @@ * Grant Grundler <grundler@cup.hp.com>: PCI write posting fixes. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/version.h> @@ -579,11 +578,7 @@ static int __devinit acenic_probe_one(struct pci_dev *pdev, } printk("Gigabit Ethernet at 0x%08lx, ", dev->base_addr); -#ifdef __sparc__ - printk("irq %s\n", __irq_itoa(pdev->irq)); -#else - printk("irq %i\n", pdev->irq); -#endif + printk("irq %d\n", pdev->irq); #ifdef CONFIG_ACENIC_OMIT_TIGON_I if ((readl(&ap->regs->HostCtrl) >> 28) == 4) { @@ -1199,7 +1194,7 @@ static int __devinit ace_init(struct net_device *dev) goto init_error; } - ecode = request_irq(pdev->irq, ace_interrupt, SA_SHIRQ, + ecode = request_irq(pdev->irq, ace_interrupt, IRQF_SHARED, DRV_NAME, dev); if (ecode) { printk(KERN_WARNING "%s: Requested IRQ %d is busy\n", diff --git a/drivers/net/acenic.h b/drivers/net/acenic.h index a9710702349..62ec8ceee69 100644 --- a/drivers/net/acenic.h +++ b/drivers/net/acenic.h @@ -1,7 +1,6 @@ #ifndef _ACENIC_H_ #define _ACENIC_H_ -#include <linux/config.h> /* * Generate TX index update each time, when TX ring is closed. diff --git a/drivers/net/acenic_firmware.h b/drivers/net/acenic_firmware.h index d7882dd783c..ec146f60d77 100644 --- a/drivers/net/acenic_firmware.h +++ b/drivers/net/acenic_firmware.h @@ -1,4 +1,3 @@ -#include <linux/config.h> /* * Declare these here even if Tigon I support is disabled to avoid * the compiler complaining about undefined symbols. diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index d9ba8be72af..ed322a76980 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -69,7 +69,6 @@ Revision History: */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> @@ -1377,7 +1376,7 @@ static int amd8111e_open(struct net_device * dev ) { struct amd8111e_priv *lp = netdev_priv(dev); - if(dev->irq ==0 || request_irq(dev->irq, amd8111e_interrupt, SA_SHIRQ, + if(dev->irq ==0 || request_irq(dev->irq, amd8111e_interrupt, IRQF_SHARED, dev->name, dev)) return -EAGAIN; diff --git a/drivers/net/apne.c b/drivers/net/apne.c index b9820b86cdc..9cc13a0250d 100644 --- a/drivers/net/apne.c +++ b/drivers/net/apne.c @@ -313,7 +313,7 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr) dev->base_addr = ioaddr; /* Install the Interrupt handler */ - i = request_irq(IRQ_AMIGA_PORTS, apne_interrupt, SA_SHIRQ, DRV_NAME, dev); + i = request_irq(IRQ_AMIGA_PORTS, apne_interrupt, IRQF_SHARED, DRV_NAME, dev); if (i) return i; for(i = 0; i < ETHER_ADDR_LEN; i++) { diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index 9edaa183227..1d01ac0000e 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c @@ -48,7 +48,6 @@ static const char *version = * the driver figure it out. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> diff --git a/drivers/net/appletalk/cops_ffdrv.h b/drivers/net/appletalk/cops_ffdrv.h index 31cf8c9c947..b02005087c1 100644 --- a/drivers/net/appletalk/cops_ffdrv.h +++ b/drivers/net/appletalk/cops_ffdrv.h @@ -24,7 +24,6 @@ * - Jay Schulist <jschlst@samba.org> */ -#include <linux/config.h> #ifdef CONFIG_COPS_DAYNA diff --git a/drivers/net/appletalk/cops_ltdrv.h b/drivers/net/appletalk/cops_ltdrv.h index 4afb8e18ba6..c699b1ad31d 100644 --- a/drivers/net/appletalk/cops_ltdrv.h +++ b/drivers/net/appletalk/cops_ltdrv.h @@ -23,7 +23,6 @@ * - Jay Schulist <jschlst@samba.org> */ -#include <linux/config.h> #ifdef CONFIG_COPS_TANGENT diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c index 1a44a79ed06..7f7dd450226 100644 --- a/drivers/net/appletalk/ipddp.c +++ b/drivers/net/appletalk/ipddp.c @@ -23,7 +23,6 @@ * of the GNU General Public License, incorporated herein by reference. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index fabc0607b0f..5a95005253f 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -44,7 +44,6 @@ #define VERSION "arcnet: v3.93 BETA 2000/04/29 - by Avery Pennarun et al.\n" #include <linux/module.h> -#include <linux/config.h> #include <linux/types.h> #include <linux/delay.h> #include <linux/netdevice.h> diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c index 96636ca8754..979a33df0a8 100644 --- a/drivers/net/arcnet/com20020-pci.c +++ b/drivers/net/arcnet/com20020-pci.c @@ -120,7 +120,7 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de goto out_port; } - if ((err = com20020_found(dev, SA_SHIRQ)) != 0) + if ((err = com20020_found(dev, IRQF_SHARED)) != 0) goto out_port; return 0; diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c index d1b6b1f794e..cc721addd57 100644 --- a/drivers/net/ariadne.c +++ b/drivers/net/ariadne.c @@ -320,7 +320,7 @@ static int ariadne_open(struct net_device *dev) netif_start_queue(dev); - i = request_irq(IRQ_AMIGA_PORTS, ariadne_interrupt, SA_SHIRQ, + i = request_irq(IRQ_AMIGA_PORTS, ariadne_interrupt, IRQF_SHARED, dev->name, dev); if (i) return i; @@ -607,8 +607,7 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev) /* FIXME: is the 79C960 new enough to do its own padding right ? */ if (skb->len < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) return 0; len = ETH_ZLEN; } diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index 5503dc8a66e..85493b7b924 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c @@ -19,7 +19,6 @@ #include <linux/module.h> #include <linux/init.h> -#include <linux/config.h> #include <linux/mii.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> @@ -43,7 +42,9 @@ #define DRV_VERSION "1.0" static struct net_device *at91_dev; -static struct clk *ether_clk; + +static struct timer_list check_timer; +#define LINK_POLL_INTERVAL (HZ) /* ..................................................................... */ @@ -143,7 +144,7 @@ static void read_phy(unsigned char phy_addr, unsigned char address, unsigned int * MAC accordingly. * If no link or auto-negotiation is busy, then no changes are made. */ -static void update_linkspeed(struct net_device *dev) +static void update_linkspeed(struct net_device *dev, int silent) { struct at91_private *lp = (struct at91_private *) dev->priv; unsigned int bmsr, bmcr, lpa, mac_cfg; @@ -151,7 +152,8 @@ static void update_linkspeed(struct net_device *dev) if (!mii_link_ok(&lp->mii)) { /* no link */ netif_carrier_off(dev); - printk(KERN_INFO "%s: Link down.\n", dev->name); + if (!silent) + printk(KERN_INFO "%s: Link down.\n", dev->name); return; } @@ -186,7 +188,8 @@ static void update_linkspeed(struct net_device *dev) } at91_emac_write(AT91_EMAC_CFG, mac_cfg); - printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex"); + if (!silent) + printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex"); netif_carrier_on(dev); } @@ -226,7 +229,7 @@ static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id, struct pt_regs goto done; } - update_linkspeed(dev); + update_linkspeed(dev, 0); done: disable_mdi(); @@ -243,14 +246,17 @@ static void enable_phyirq(struct net_device *dev) unsigned int dsintr, irq_number; int status; - if (lp->phy_type == MII_RTL8201_ID) /* RTL8201 does not have an interrupt */ - return; - if (lp->phy_type == MII_DP83847_ID) /* DP83847 does not have an interrupt */ - return; - if (lp->phy_type == MII_AC101L_ID) /* AC101L interrupt not supported yet */ + irq_number = lp->board_data.phy_irq_pin; + if (!irq_number) { + /* + * PHY doesn't have an IRQ pin (RTL8201, DP83847, AC101L), + * or board does not have it connected. + */ + check_timer.expires = jiffies + LINK_POLL_INTERVAL; + add_timer(&check_timer); return; + } - irq_number = lp->board_data.phy_irq_pin; status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev); if (status) { printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status); @@ -292,12 +298,11 @@ static void disable_phyirq(struct net_device *dev) unsigned int dsintr; unsigned int irq_number; - if (lp->phy_type == MII_RTL8201_ID) /* RTL8201 does not have an interrupt */ - return; - if (lp->phy_type == MII_DP83847_ID) /* DP83847 does not have an interrupt */ - return; - if (lp->phy_type == MII_AC101L_ID) /* AC101L interrupt not supported yet */ + irq_number = lp->board_data.phy_irq_pin; + if (!irq_number) { + del_timer_sync(&check_timer); return; + } spin_lock_irq(&lp->lock); enable_mdi(); @@ -326,7 +331,6 @@ static void disable_phyirq(struct net_device *dev) disable_mdi(); spin_unlock_irq(&lp->lock); - irq_number = lp->board_data.phy_irq_pin; free_irq(irq_number, dev); /* Free interrupt handler */ } @@ -355,6 +359,18 @@ static void reset_phy(struct net_device *dev) } #endif +static void at91ether_check_link(unsigned long dev_id) +{ + struct net_device *dev = (struct net_device *) dev_id; + + enable_mdi(); + update_linkspeed(dev, 1); + disable_mdi(); + + check_timer.expires = jiffies + LINK_POLL_INTERVAL; + add_timer(&check_timer); +} + /* ......................... ADDRESS MANAGEMENT ........................ */ /* @@ -501,7 +517,7 @@ static int hash_get_index(__u8 *addr) hash_index |= (bitval << j); } - return hash_index; + return hash_index; } /* @@ -557,10 +573,8 @@ static void at91ether_set_rx_mode(struct net_device *dev) at91_emac_write(AT91_EMAC_CFG, cfg); } - /* ......................... ETHTOOL SUPPORT ........................... */ - static int mdio_read(struct net_device *dev, int phy_id, int location) { unsigned int value; @@ -642,6 +656,22 @@ static struct ethtool_ops at91ether_ethtool_ops = { .get_link = ethtool_op_get_link, }; +static int at91ether_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct at91_private *lp = (struct at91_private *) dev->priv; + int res; + + if (!netif_running(dev)) + return -EINVAL; + + spin_lock_irq(&lp->lock); + enable_mdi(); + res = generic_mii_ioctl(&lp->mii, if_mii(rq), cmd, NULL); + disable_mdi(); + spin_unlock_irq(&lp->lock); + + return res; +} /* ................................ MAC ................................ */ @@ -685,10 +715,10 @@ static int at91ether_open(struct net_device *dev) struct at91_private *lp = (struct at91_private *) dev->priv; unsigned long ctl; - if (!is_valid_ether_addr(dev->dev_addr)) - return -EADDRNOTAVAIL; + if (!is_valid_ether_addr(dev->dev_addr)) + return -EADDRNOTAVAIL; - clk_enable(ether_clk); /* Re-enable Peripheral clock */ + clk_enable(lp->ether_clk); /* Re-enable Peripheral clock */ /* Clear internal statistics */ ctl = at91_emac_read(AT91_EMAC_CTL); @@ -708,7 +738,7 @@ static int at91ether_open(struct net_device *dev) /* Determine current link speed */ spin_lock_irq(&lp->lock); enable_mdi(); - update_linkspeed(dev); + update_linkspeed(dev, 0); disable_mdi(); spin_unlock_irq(&lp->lock); @@ -722,6 +752,7 @@ static int at91ether_open(struct net_device *dev) */ static int at91ether_close(struct net_device *dev) { + struct at91_private *lp = (struct at91_private *) dev->priv; unsigned long ctl; /* Disable Receiver and Transmitter */ @@ -738,7 +769,7 @@ static int at91ether_close(struct net_device *dev) netif_stop_queue(dev); - clk_disable(ether_clk); /* Disable Peripheral clock */ + clk_disable(lp->ether_clk); /* Disable Peripheral clock */ return 0; } @@ -870,7 +901,7 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id, struct pt_regs *re if (intstatus & AT91_EMAC_RCOM) /* Receive complete */ at91ether_rx(dev); - if (intstatus & AT91_EMAC_TCOM) { /* Transmit complete */ + if (intstatus & AT91_EMAC_TCOM) { /* Transmit complete */ /* The TCOM bit is set even if the transmission failed. */ if (intstatus & (AT91_EMAC_TUND | AT91_EMAC_RTRY)) lp->stats.tx_errors += 1; @@ -899,7 +930,8 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id, struct pt_regs *re /* * Initialize the ethernet interface */ -static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_address, struct platform_device *pdev) +static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_address, + struct platform_device *pdev, struct clk *ether_clk) { struct at91_eth_data *board_data = pdev->dev.platform_data; struct net_device *dev; @@ -933,6 +965,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add return -ENOMEM; } lp->board_data = *board_data; + lp->ether_clk = ether_clk; platform_set_drvdata(pdev, dev); spin_lock_init(&lp->lock); @@ -945,6 +978,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add dev->set_multicast_list = at91ether_set_rx_mode; dev->set_mac_address = set_mac_address; dev->ethtool_ops = &at91ether_ethtool_ops; + dev->do_ioctl = at91ether_ioctl; SET_NETDEV_DEV(dev, &pdev->dev); @@ -975,6 +1009,9 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add lp->mii.dev = dev; /* Support for ethtool */ lp->mii.mdio_read = mdio_read; lp->mii.mdio_write = mdio_write; + lp->mii.phy_id = phy_address; + lp->mii.phy_id_mask = 0x1f; + lp->mii.reg_num_mask = 0x1f; lp->phy_type = phy_type; /* Type of PHY connected */ lp->phy_address = phy_address; /* MDI address of PHY */ @@ -992,11 +1029,18 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add /* Determine current link speed */ spin_lock_irq(&lp->lock); enable_mdi(); - update_linkspeed(dev); + update_linkspeed(dev, 0); disable_mdi(); spin_unlock_irq(&lp->lock); netif_carrier_off(dev); /* will be enabled in open() */ + /* If board has no PHY IRQ, use a timer to poll the PHY */ + if (!lp->board_data.phy_irq_pin) { + init_timer(&check_timer); + check_timer.data = (unsigned long)dev; + check_timer.function = at91ether_check_link; + } + /* Display ethernet banner */ printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%02x:%02x:%02x:%02x:%02x:%02x)\n", dev->name, (uint) dev->base_addr, dev->irq, @@ -1005,7 +1049,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) - printk(KERN_INFO "%s: Davicom 9196 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)"); + printk(KERN_INFO "%s: Davicom 9161 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)"); else if (phy_type == MII_LXT971A_ID) printk(KERN_INFO "%s: Intel LXT971A PHY\n", dev->name); else if (phy_type == MII_RTL8201_ID) @@ -1031,9 +1075,10 @@ static int __init at91ether_probe(struct platform_device *pdev) int detected = -1; unsigned long phy_id; unsigned short phy_address = 0; + struct clk *ether_clk; ether_clk = clk_get(&pdev->dev, "ether_clk"); - if (!ether_clk) { + if (IS_ERR(ether_clk)) { printk(KERN_ERR "at91_ether: no clock defined\n"); return -ENODEV; } @@ -1056,7 +1101,7 @@ static int __init at91ether_probe(struct platform_device *pdev) case MII_DP83847_ID: /* National Semiconductor DP83847: */ case MII_AC101L_ID: /* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */ case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */ - detected = at91ether_setup(phy_id, phy_address, pdev); + detected = at91ether_setup(phy_id, phy_address, pdev, ether_clk); break; } @@ -1075,17 +1120,61 @@ static int __devexit at91ether_remove(struct platform_device *pdev) unregister_netdev(at91_dev); free_irq(at91_dev->irq, at91_dev); dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys); - clk_put(ether_clk); + clk_put(lp->ether_clk); free_netdev(at91_dev); at91_dev = NULL; return 0; } +#ifdef CONFIG_PM + +static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg) +{ + struct at91_private *lp = (struct at91_private *) at91_dev->priv; + struct net_device *net_dev = platform_get_drvdata(pdev); + int phy_irq = lp->board_data.phy_irq_pin; + + if (netif_running(net_dev)) { + if (phy_irq) + disable_irq(phy_irq); + + netif_stop_queue(net_dev); + netif_device_detach(net_dev); + + clk_disable(lp->ether_clk); + } + return 0; +} + +static int at91ether_resume(struct platform_device *pdev) +{ + struct at91_private *lp = (struct at91_private *) at91_dev->priv; + struct net_device *net_dev = platform_get_drvdata(pdev); + int phy_irq = lp->board_data.phy_irq_pin; + + if (netif_running(net_dev)) { + clk_enable(lp->ether_clk); + + netif_device_attach(net_dev); + netif_start_queue(net_dev); + + if (phy_irq) + enable_irq(phy_irq); + } + return 0; +} + +#else +#define at91ether_suspend NULL +#define at91ether_resume NULL +#endif + static struct platform_driver at91ether_driver = { .probe = at91ether_probe, .remove = __devexit_p(at91ether_remove), - /* FIXME: support suspend and resume */ + .suspend = at91ether_suspend, + .resume = at91ether_resume, .driver = { .name = DRV_NAME, .owner = THIS_MODULE, diff --git a/drivers/net/arm/at91_ether.h b/drivers/net/arm/at91_ether.h index 9885735c9c8..d1e72e02be3 100644 --- a/drivers/net/arm/at91_ether.h +++ b/drivers/net/arm/at91_ether.h @@ -80,6 +80,7 @@ struct at91_private struct net_device_stats stats; struct mii_if_info mii; /* ethtool support */ struct at91_eth_data board_data; /* board-specific configuration */ + struct clk *ether_clk; /* clock */ /* PHY */ unsigned long phy_type; /* type of PHY (PHY_ID) */ diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c index 36475eb2727..312955d07b2 100644 --- a/drivers/net/arm/ether1.c +++ b/drivers/net/arm/ether1.c @@ -700,8 +700,7 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev) } if (skb->len < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) goto out; } diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c index f1d5b1027ff..081074180e6 100644 --- a/drivers/net/arm/ether3.c +++ b/drivers/net/arm/ether3.c @@ -518,8 +518,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev) length = (length + 1) & ~1; if (length != skb->len) { - skb = skb_padto(skb, length); - if (skb == NULL) + if (skb_padto(skb, length)) goto out; } diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index e613cc28974..5d7929c79bc 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -35,7 +35,6 @@ response to inb()s from other device probes! */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index 442b2cbeb58..91783a8008b 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -804,8 +804,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) ++len; if (len > skb->len) { - skb = skb_padto(skb, len); - if (skb == NULL) + if (skb_padto(skb, len)) return 0; } diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 038d5fcb15e..55f6e3f65b5 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -35,7 +35,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> diff --git a/drivers/net/b44.c b/drivers/net/b44.c index d8233e0b789..cd98d31dee8 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -29,8 +29,8 @@ #define DRV_MODULE_NAME "b44" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.00" -#define DRV_MODULE_RELDATE "Apr 7, 2006" +#define DRV_MODULE_VERSION "1.01" +#define DRV_MODULE_RELDATE "Jun 16, 2006" #define B44_DEF_MSG_ENABLE \ (NETIF_MSG_DRV | \ @@ -75,6 +75,15 @@ /* minimum number of free TX descriptors required to wake up TX process */ #define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4) +/* b44 internal pattern match filter info */ +#define B44_PATTERN_BASE 0x400 +#define B44_PATTERN_SIZE 0x80 +#define B44_PMASK_BASE 0x600 +#define B44_PMASK_SIZE 0x10 +#define B44_MAX_PATTERNS 16 +#define B44_ETHIPV6UDP_HLEN 62 +#define B44_ETHIPV4UDP_HLEN 42 + static char version[] __devinitdata = DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; @@ -101,7 +110,7 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl); static void b44_halt(struct b44 *); static void b44_init_rings(struct b44 *); -static void b44_init_hw(struct b44 *); +static void b44_init_hw(struct b44 *, int); static int dma_desc_align_mask; static int dma_desc_sync_size; @@ -873,7 +882,7 @@ static int b44_poll(struct net_device *netdev, int *budget) spin_lock_irq(&bp->lock); b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp); + b44_init_hw(bp, 1); netif_wake_queue(bp->dev); spin_unlock_irq(&bp->lock); done = 1; @@ -942,7 +951,7 @@ static void b44_tx_timeout(struct net_device *dev) b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp); + b44_init_hw(bp, 1); spin_unlock_irq(&bp->lock); @@ -1059,7 +1068,7 @@ static int b44_change_mtu(struct net_device *dev, int new_mtu) b44_halt(bp); dev->mtu = new_mtu; b44_init_rings(bp); - b44_init_hw(bp); + b44_init_hw(bp, 1); spin_unlock_irq(&bp->lock); b44_enable_ints(bp); @@ -1356,13 +1365,15 @@ static int b44_set_mac_addr(struct net_device *dev, void *p) * packet processing. Invoked with bp->lock held. */ static void __b44_set_rx_mode(struct net_device *); -static void b44_init_hw(struct b44 *bp) +static void b44_init_hw(struct b44 *bp, int full_reset) { u32 val; b44_chip_reset(bp); - b44_phy_reset(bp); - b44_setup_phy(bp); + if (full_reset) { + b44_phy_reset(bp); + b44_setup_phy(bp); + } /* Enable CRC32, set proper LED modes and power on PHY */ bw32(bp, B44_MAC_CTRL, MAC_CTRL_CRC32_ENAB | MAC_CTRL_PHY_LEDCTRL); @@ -1376,16 +1387,21 @@ static void b44_init_hw(struct b44 *bp) bw32(bp, B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN); bw32(bp, B44_TX_WMARK, 56); /* XXX magic */ - bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE); - bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset); - bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | - (bp->rx_offset << DMARX_CTRL_ROSHIFT))); - bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset); + if (full_reset) { + bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE); + bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset); + bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | + (bp->rx_offset << DMARX_CTRL_ROSHIFT))); + bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset); - bw32(bp, B44_DMARX_PTR, bp->rx_pending); - bp->rx_prod = bp->rx_pending; + bw32(bp, B44_DMARX_PTR, bp->rx_pending); + bp->rx_prod = bp->rx_pending; - bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ); + bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ); + } else { + bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | + (bp->rx_offset << DMARX_CTRL_ROSHIFT))); + } val = br32(bp, B44_ENET_CTRL); bw32(bp, B44_ENET_CTRL, (val | ENET_CTRL_ENABLE)); @@ -1401,11 +1417,11 @@ static int b44_open(struct net_device *dev) goto out; b44_init_rings(bp); - b44_init_hw(bp); + b44_init_hw(bp, 1); b44_check_phy(bp); - err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev); + err = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev); if (unlikely(err < 0)) { b44_chip_reset(bp); b44_free_rings(bp); @@ -1450,6 +1466,140 @@ static void b44_poll_controller(struct net_device *dev) } #endif +static void bwfilter_table(struct b44 *bp, u8 *pp, u32 bytes, u32 table_offset) +{ + u32 i; + u32 *pattern = (u32 *) pp; + + for (i = 0; i < bytes; i += sizeof(u32)) { + bw32(bp, B44_FILT_ADDR, table_offset + i); + bw32(bp, B44_FILT_DATA, pattern[i / sizeof(u32)]); + } +} + +static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset) +{ + int magicsync = 6; + int k, j, len = offset; + int ethaddr_bytes = ETH_ALEN; + + memset(ppattern + offset, 0xff, magicsync); + for (j = 0; j < magicsync; j++) + set_bit(len++, (unsigned long *) pmask); + + for (j = 0; j < B44_MAX_PATTERNS; j++) { + if ((B44_PATTERN_SIZE - len) >= ETH_ALEN) + ethaddr_bytes = ETH_ALEN; + else + ethaddr_bytes = B44_PATTERN_SIZE - len; + if (ethaddr_bytes <=0) + break; + for (k = 0; k< ethaddr_bytes; k++) { + ppattern[offset + magicsync + + (j * ETH_ALEN) + k] = macaddr[k]; + len++; + set_bit(len, (unsigned long *) pmask); + } + } + return len - 1; +} + +/* Setup magic packet patterns in the b44 WOL + * pattern matching filter. + */ +static void b44_setup_pseudo_magicp(struct b44 *bp) +{ + + u32 val; + int plen0, plen1, plen2; + u8 *pwol_pattern; + u8 pwol_mask[B44_PMASK_SIZE]; + + pwol_pattern = kmalloc(B44_PATTERN_SIZE, GFP_KERNEL); + if (!pwol_pattern) { + printk(KERN_ERR PFX "Memory not available for WOL\n"); + return; + } + + /* Ipv4 magic packet pattern - pattern 0.*/ + memset(pwol_pattern, 0, B44_PATTERN_SIZE); + memset(pwol_mask, 0, B44_PMASK_SIZE); + plen0 = b44_magic_pattern(bp->dev->dev_addr, pwol_pattern, pwol_mask, + B44_ETHIPV4UDP_HLEN); + + bwfilter_table(bp, pwol_pattern, B44_PATTERN_SIZE, B44_PATTERN_BASE); + bwfilter_table(bp, pwol_mask, B44_PMASK_SIZE, B44_PMASK_BASE); + + /* Raw ethernet II magic packet pattern - pattern 1 */ + memset(pwol_pattern, 0, B44_PATTERN_SIZE); + memset(pwol_mask, 0, B44_PMASK_SIZE); + plen1 = b44_magic_pattern(bp->dev->dev_addr, pwol_pattern, pwol_mask, + ETH_HLEN); + + bwfilter_table(bp, pwol_pattern, B44_PATTERN_SIZE, + B44_PATTERN_BASE + B44_PATTERN_SIZE); + bwfilter_table(bp, pwol_mask, B44_PMASK_SIZE, + B44_PMASK_BASE + B44_PMASK_SIZE); + + /* Ipv6 magic packet pattern - pattern 2 */ + memset(pwol_pattern, 0, B44_PATTERN_SIZE); + memset(pwol_mask, 0, B44_PMASK_SIZE); + plen2 = b44_magic_pattern(bp->dev->dev_addr, pwol_pattern, pwol_mask, + B44_ETHIPV6UDP_HLEN); + + bwfilter_table(bp, pwol_pattern, B44_PATTERN_SIZE, + B44_PATTERN_BASE + B44_PATTERN_SIZE + B44_PATTERN_SIZE); + bwfilter_table(bp, pwol_mask, B44_PMASK_SIZE, + B44_PMASK_BASE + B44_PMASK_SIZE + B44_PMASK_SIZE); + + kfree(pwol_pattern); + + /* set these pattern's lengths: one less than each real length */ + val = plen0 | (plen1 << 8) | (plen2 << 16) | WKUP_LEN_ENABLE_THREE; + bw32(bp, B44_WKUP_LEN, val); + + /* enable wakeup pattern matching */ + val = br32(bp, B44_DEVCTRL); + bw32(bp, B44_DEVCTRL, val | DEVCTRL_PFE); + +} + +static void b44_setup_wol(struct b44 *bp) +{ + u32 val; + u16 pmval; + + bw32(bp, B44_RXCONFIG, RXCONFIG_ALLMULTI); + + if (bp->flags & B44_FLAG_B0_ANDLATER) { + + bw32(bp, B44_WKUP_LEN, WKUP_LEN_DISABLE); + + val = bp->dev->dev_addr[2] << 24 | + bp->dev->dev_addr[3] << 16 | + bp->dev->dev_addr[4] << 8 | + bp->dev->dev_addr[5]; + bw32(bp, B44_ADDR_LO, val); + + val = bp->dev->dev_addr[0] << 8 | + bp->dev->dev_addr[1]; + bw32(bp, B44_ADDR_HI, val); + + val = br32(bp, B44_DEVCTRL); + bw32(bp, B44_DEVCTRL, val | DEVCTRL_MPM | DEVCTRL_PFE); + + } else { + b44_setup_pseudo_magicp(bp); + } + + val = br32(bp, B44_SBTMSLOW); + bw32(bp, B44_SBTMSLOW, val | SBTMSLOW_PE); + + pci_read_config_word(bp->pdev, SSB_PMCSR, &pmval); + pci_write_config_word(bp->pdev, SSB_PMCSR, pmval | SSB_PE); + +} + static int b44_close(struct net_device *dev) { struct b44 *bp = netdev_priv(dev); @@ -1475,6 +1625,11 @@ static int b44_close(struct net_device *dev) netif_poll_enable(dev); + if (bp->flags & B44_FLAG_WOL_ENABLE) { + b44_init_hw(bp, 0); + b44_setup_wol(bp); + } + b44_free_consistent(bp); return 0; @@ -1620,8 +1775,6 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct b44 *bp = netdev_priv(dev); - if (!netif_running(dev)) - return -EAGAIN; cmd->supported = (SUPPORTED_Autoneg); cmd->supported |= (SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | @@ -1649,6 +1802,12 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) XCVR_INTERNAL : XCVR_EXTERNAL; cmd->autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ? AUTONEG_DISABLE : AUTONEG_ENABLE; + if (cmd->autoneg == AUTONEG_ENABLE) + cmd->advertising |= ADVERTISED_Autoneg; + if (!netif_running(dev)){ + cmd->speed = 0; + cmd->duplex = 0xff; + } cmd->maxtxpkt = 0; cmd->maxrxpkt = 0; return 0; @@ -1658,9 +1817,6 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct b44 *bp = netdev_priv(dev); - if (!netif_running(dev)) - return -EAGAIN; - /* We do not support gigabit. */ if (cmd->autoneg == AUTONEG_ENABLE) { if (cmd->advertising & @@ -1677,28 +1833,39 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) spin_lock_irq(&bp->lock); if (cmd->autoneg == AUTONEG_ENABLE) { - bp->flags &= ~B44_FLAG_FORCE_LINK; - bp->flags &= ~(B44_FLAG_ADV_10HALF | + bp->flags &= ~(B44_FLAG_FORCE_LINK | + B44_FLAG_100_BASE_T | + B44_FLAG_FULL_DUPLEX | + B44_FLAG_ADV_10HALF | B44_FLAG_ADV_10FULL | B44_FLAG_ADV_100HALF | B44_FLAG_ADV_100FULL); - if (cmd->advertising & ADVERTISE_10HALF) - bp->flags |= B44_FLAG_ADV_10HALF; - if (cmd->advertising & ADVERTISE_10FULL) - bp->flags |= B44_FLAG_ADV_10FULL; - if (cmd->advertising & ADVERTISE_100HALF) - bp->flags |= B44_FLAG_ADV_100HALF; - if (cmd->advertising & ADVERTISE_100FULL) - bp->flags |= B44_FLAG_ADV_100FULL; + if (cmd->advertising == 0) { + bp->flags |= (B44_FLAG_ADV_10HALF | + B44_FLAG_ADV_10FULL | + B44_FLAG_ADV_100HALF | + B44_FLAG_ADV_100FULL); + } else { + if (cmd->advertising & ADVERTISED_10baseT_Half) + bp->flags |= B44_FLAG_ADV_10HALF; + if (cmd->advertising & ADVERTISED_10baseT_Full) + bp->flags |= B44_FLAG_ADV_10FULL; + if (cmd->advertising & ADVERTISED_100baseT_Half) + bp->flags |= B44_FLAG_ADV_100HALF; + if (cmd->advertising & ADVERTISED_100baseT_Full) + bp->flags |= B44_FLAG_ADV_100FULL; + } } else { bp->flags |= B44_FLAG_FORCE_LINK; + bp->flags &= ~(B44_FLAG_100_BASE_T | B44_FLAG_FULL_DUPLEX); if (cmd->speed == SPEED_100) bp->flags |= B44_FLAG_100_BASE_T; if (cmd->duplex == DUPLEX_FULL) bp->flags |= B44_FLAG_FULL_DUPLEX; } - b44_setup_phy(bp); + if (netif_running(dev)) + b44_setup_phy(bp); spin_unlock_irq(&bp->lock); @@ -1734,7 +1901,7 @@ static int b44_set_ringparam(struct net_device *dev, b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp); + b44_init_hw(bp, 1); netif_wake_queue(bp->dev); spin_unlock_irq(&bp->lock); @@ -1777,7 +1944,7 @@ static int b44_set_pauseparam(struct net_device *dev, if (bp->flags & B44_FLAG_PAUSE_AUTO) { b44_halt(bp); b44_init_rings(bp); - b44_init_hw(bp); + b44_init_hw(bp, 1); } else { __b44_set_flow_ctrl(bp, bp->flags); } @@ -1819,12 +1986,40 @@ static void b44_get_ethtool_stats(struct net_device *dev, spin_unlock_irq(&bp->lock); } +static void b44_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct b44 *bp = netdev_priv(dev); + + wol->supported = WAKE_MAGIC; + if (bp->flags & B44_FLAG_WOL_ENABLE) + wol->wolopts = WAKE_MAGIC; + else + wol->wolopts = 0; + memset(&wol->sopass, 0, sizeof(wol->sopass)); +} + +static int b44_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct b44 *bp = netdev_priv(dev); + + spin_lock_irq(&bp->lock); + if (wol->wolopts & WAKE_MAGIC) + bp->flags |= B44_FLAG_WOL_ENABLE; + else + bp->flags &= ~B44_FLAG_WOL_ENABLE; + spin_unlock_irq(&bp->lock); + + return 0; +} + static struct ethtool_ops b44_ethtool_ops = { .get_drvinfo = b44_get_drvinfo, .get_settings = b44_get_settings, .set_settings = b44_set_settings, .nway_reset = b44_nway_reset, .get_link = ethtool_op_get_link, + .get_wol = b44_get_wol, + .set_wol = b44_set_wol, .get_ringparam = b44_get_ringparam, .set_ringparam = b44_set_ringparam, .get_pauseparam = b44_get_pauseparam, @@ -1903,6 +2098,10 @@ static int __devinit b44_get_invariants(struct b44 *bp) /* XXX - really required? bp->flags |= B44_FLAG_BUGGY_TXPTR; */ + + if (ssb_get_core_rev(bp) >= 7) + bp->flags |= B44_FLAG_B0_ANDLATER; + out: return err; } @@ -2103,6 +2302,10 @@ static int b44_suspend(struct pci_dev *pdev, pm_message_t state) spin_unlock_irq(&bp->lock); free_irq(dev->irq, dev); + if (bp->flags & B44_FLAG_WOL_ENABLE) { + b44_init_hw(bp, 0); + b44_setup_wol(bp); + } pci_disable_device(pdev); return 0; } @@ -2119,13 +2322,13 @@ static int b44_resume(struct pci_dev *pdev) if (!netif_running(dev)) return 0; - if (request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev)) + if (request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev)) printk(KERN_ERR PFX "%s: request_irq failed\n", dev->name); spin_lock_irq(&bp->lock); b44_init_rings(bp); - b44_init_hw(bp); + b44_init_hw(bp, 1); netif_device_attach(bp->dev); spin_unlock_irq(&bp->lock); diff --git a/drivers/net/b44.h b/drivers/net/b44.h index b178662978f..4944507fad2 100644 --- a/drivers/net/b44.h +++ b/drivers/net/b44.h @@ -24,6 +24,9 @@ #define WKUP_LEN_P3_MASK 0x7f000000 /* Pattern 3 */ #define WKUP_LEN_P3_SHIFT 24 #define WKUP_LEN_D3 0x80000000 +#define WKUP_LEN_DISABLE 0x80808080 +#define WKUP_LEN_ENABLE_TWO 0x80800000 +#define WKUP_LEN_ENABLE_THREE 0x80000000 #define B44_ISTAT 0x0020UL /* Interrupt Status */ #define ISTAT_LS 0x00000020 /* Link Change (B0 only) */ #define ISTAT_PME 0x00000040 /* Power Management Event */ @@ -264,6 +267,8 @@ #define SBIDHIGH_VC_SHIFT 16 /* SSB PCI config space registers. */ +#define SSB_PMCSR 0x44 +#define SSB_PE 0x100 #define SSB_BAR0_WIN 0x80 #define SSB_BAR1_WIN 0x84 #define SSB_SPROM_CONTROL 0x88 @@ -420,6 +425,7 @@ struct b44 { u32 dma_offset; u32 flags; +#define B44_FLAG_B0_ANDLATER 0x00000001 #define B44_FLAG_BUGGY_TXPTR 0x00000002 #define B44_FLAG_REORDER_BUG 0x00000004 #define B44_FLAG_PAUSE_AUTO 0x00008000 @@ -435,6 +441,7 @@ struct b44 { #define B44_FLAG_INTERNAL_PHY 0x10000000 #define B44_FLAG_RX_RING_HACK 0x20000000 #define B44_FLAG_TX_RING_HACK 0x40000000 +#define B44_FLAG_WOL_ENABLE 0x80000000 u32 rx_offset; diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index bbca8ae8018..6fad83f24c4 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -7,7 +7,6 @@ * May 1999, Al Viro: proper release of /proc/net/bmac entry, switched to * dynamic procfs inode. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 702d546567a..4f4db5ae503 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -9,7 +9,6 @@ * Written by: Michael Chan (mchan@broadcom.com) */ -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> @@ -57,8 +56,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.4.42" -#define DRV_MODULE_RELDATE "June 12, 2006" +#define DRV_MODULE_VERSION "1.4.43" +#define DRV_MODULE_RELDATE "June 28, 2006" #define RUN_AT(x) (jiffies + (x)) @@ -1640,7 +1639,7 @@ bnx2_tx_int(struct bnx2 *bp) skb = tx_buf->skb; #ifdef BCM_TSO /* partial BD completions possible with TSO packets */ - if (skb_shinfo(skb)->tso_size) { + if (skb_shinfo(skb)->gso_size) { u16 last_idx, last_ring_idx; last_idx = sw_cons + @@ -1676,7 +1675,7 @@ bnx2_tx_int(struct bnx2 *bp) tx_free_bd += last + 1; - dev_kfree_skb_irq(skb); + dev_kfree_skb(skb); hw_cons = bp->hw_tx_cons = sblk->status_tx_quick_consumer_index0; @@ -1824,7 +1823,7 @@ reuse_rx: if ((len > (bp->dev->mtu + ETH_HLEN)) && (ntohs(skb->protocol) != 0x8100)) { - dev_kfree_skb_irq(skb); + dev_kfree_skb(skb); goto next_rx; } @@ -3643,7 +3642,7 @@ bnx2_free_tx_skbs(struct bnx2 *bp) skb_shinfo(skb)->frags[j].size, PCI_DMA_TODEVICE); } - dev_kfree_skb_any(skb); + dev_kfree_skb(skb); i += j + 1; } @@ -3669,7 +3668,7 @@ bnx2_free_rx_skbs(struct bnx2 *bp) rx_buf->skb = NULL; - dev_kfree_skb_any(skb); + dev_kfree_skb(skb); } } @@ -3999,7 +3998,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) udelay(5); pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE); - dev_kfree_skb_irq(skb); + dev_kfree_skb(skb); if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_prod) { goto loopback_test_done; @@ -4261,11 +4260,11 @@ bnx2_open(struct net_device *dev) } else { rc = request_irq(bp->pdev->irq, bnx2_interrupt, - SA_SHIRQ, dev->name, dev); + IRQF_SHARED, dev->name, dev); } } else { - rc = request_irq(bp->pdev->irq, bnx2_interrupt, SA_SHIRQ, + rc = request_irq(bp->pdev->irq, bnx2_interrupt, IRQF_SHARED, dev->name, dev); } if (rc) { @@ -4312,7 +4311,7 @@ bnx2_open(struct net_device *dev) if (!rc) { rc = request_irq(bp->pdev->irq, bnx2_interrupt, - SA_SHIRQ, dev->name, dev); + IRQF_SHARED, dev->name, dev); } if (rc) { bnx2_free_skbs(bp); @@ -4428,7 +4427,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); } #ifdef BCM_TSO - if ((mss = skb_shinfo(skb)->tso_size) && + if ((mss = skb_shinfo(skb)->gso_size) && (skb->len > (bp->dev->mtu + ETH_HLEN))) { u32 tcp_opt_len, ip_tcp_len; @@ -4541,7 +4540,7 @@ bnx2_close(struct net_device *dev) bnx2_netif_stop(bp); del_timer_sync(&bp->timer); if (bp->flags & NO_WOL_FLAG) - reset_code = BNX2_DRV_MSG_CODE_UNLOAD; + reset_code = BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN; else if (bp->wol) reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL; else @@ -5128,6 +5127,16 @@ bnx2_set_rx_csum(struct net_device *dev, u32 data) return 0; } +static int +bnx2_set_tso(struct net_device *dev, u32 data) +{ + if (data) + dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; + else + dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN); + return 0; +} + #define BNX2_NUM_STATS 46 static struct { @@ -5445,7 +5454,7 @@ static struct ethtool_ops bnx2_ethtool_ops = { .set_sg = ethtool_op_set_sg, #ifdef BCM_TSO .get_tso = ethtool_op_get_tso, - .set_tso = ethtool_op_set_tso, + .set_tso = bnx2_set_tso, #endif .self_test_count = bnx2_self_test_count, .self_test = bnx2_self_test, @@ -5926,7 +5935,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; #endif #ifdef BCM_TSO - dev->features |= NETIF_F_TSO; + dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; #endif netif_carrier_off(bp->dev); @@ -5968,7 +5977,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state) netif_device_detach(dev); del_timer_sync(&bp->timer); if (bp->flags & NO_WOL_FLAG) - reset_code = BNX2_DRV_MSG_CODE_UNLOAD; + reset_code = BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN; else if (bp->wol) reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL; else diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 5845e334941..658c5ee95c7 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -4174,6 +4174,7 @@ struct fw_info { #define BNX2_DRV_MSG_CODE_PULSE 0x06000000 #define BNX2_DRV_MSG_CODE_DIAG 0x07000000 #define BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL 0x09000000 +#define BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN 0x0b000000 #define BNX2_DRV_MSG_DATA 0x00ff0000 #define BNX2_DRV_MSG_DATA_WAIT0 0x00010000 diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 8171cae0668..8b951238f3a 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -33,7 +33,6 @@ //#define BONDING_DEBUG 1 -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/sched.h> diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 5a9bd95884b..cfe4dc3a93a 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -20,7 +20,6 @@ * file called LICENSE. * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/sched.h> diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 39f36aa05aa..d33130f6470 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -66,7 +66,6 @@ * by default, the selective clear mask is set up to process rx packets. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> @@ -2915,8 +2914,7 @@ static int cas_start_xmit(struct sk_buff *skb, struct net_device *dev) */ static int ring; - skb = skb_padto(skb, cp->min_frame_size); - if (!skb) + if (skb_padto(skb, cp->min_frame_size)) return 0; /* XXX: we need some higher-level QoS hooks to steer packets to @@ -4351,7 +4349,7 @@ static int cas_open(struct net_device *dev) * mapping to expose them */ if (request_irq(cp->pdev->irq, cas_interrupt, - SA_SHIRQ, dev->name, (void *) dev)) { + IRQF_SHARED, dev->name, (void *) dev)) { printk(KERN_ERR "%s: failed to request irq !\n", cp->dev->name); err = -EAGAIN; diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h index bf3e7b6a7a1..5d9dd14427c 100644 --- a/drivers/net/chelsio/common.h +++ b/drivers/net/chelsio/common.h @@ -39,7 +39,6 @@ #ifndef _CXGB_COMMON_H_ #define _CXGB_COMMON_H_ -#include <linux/config.h> #include <linux/module.h> #include <linux/netdevice.h> #include <linux/types.h> diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c index 7fe2638ae06..e67872433e9 100644 --- a/drivers/net/chelsio/cxgb2.c +++ b/drivers/net/chelsio/cxgb2.c @@ -37,7 +37,6 @@ ****************************************************************************/ #include "common.h" -#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/pci.h> @@ -219,7 +218,7 @@ static int cxgb_up(struct adapter *adapter) t1_interrupts_clear(adapter); if ((err = request_irq(adapter->pdev->irq, - t1_select_intr_handler(adapter), SA_SHIRQ, + t1_select_intr_handler(adapter), IRQF_SHARED, adapter->name, adapter))) { goto out_err; } diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index 4391bf4bf57..87f94d939ff 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -39,7 +39,6 @@ #include "common.h" -#include <linux/config.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/pci.h> @@ -1418,7 +1417,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) struct cpl_tx_pkt *cpl; #ifdef NETIF_F_TSO - if (skb_shinfo(skb)->tso_size) { + if (skb_shinfo(skb)->gso_size) { int eth_type; struct cpl_tx_pkt_lso *hdr; @@ -1433,7 +1432,7 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) hdr->ip_hdr_words = skb->nh.iph->ihl; hdr->tcp_hdr_words = skb->h.th->doff; hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type, - skb_shinfo(skb)->tso_size)); + skb_shinfo(skb)->gso_size)); hdr->len = htonl(skb->len - sizeof(*hdr)); cpl = (struct cpl_tx_pkt *)hdr; sge->stats.tx_lso_pkts++; diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c index 64105e4eaf3..0eb1f8787ed 100644 --- a/drivers/net/cris/eth_v10.c +++ b/drivers/net/cris/eth_v10.c @@ -218,7 +218,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> @@ -672,7 +671,7 @@ e100_open(struct net_device *dev) /* allocate the irq corresponding to the receiving DMA */ if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rxtx_interrupt, - SA_SAMPLE_RANDOM, cardname, (void *)dev)) { + IRQF_SAMPLE_RANDOM, cardname, (void *)dev)) { goto grace_exit0; } diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index ef54ebeb29b..47eecce35fa 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -100,7 +100,6 @@ /* Always include 'config.h' first in case the user wants to turn on or override something. */ -#include <linux/config.h> #include <linux/module.h> /* diff --git a/drivers/net/cs89x0.h b/drivers/net/cs89x0.h index bd954aaa636..968fe11a0bf 100644 --- a/drivers/net/cs89x0.h +++ b/drivers/net/cs89x0.h @@ -14,7 +14,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/config.h> #define PP_ChipID 0x0000 /* offset 0h -> Corp -ID */ /* offset 2h -> Model/Product Number */ diff --git a/drivers/net/declance.c b/drivers/net/declance.c index f130bdab3fd..2038ca7e49c 100644 --- a/drivers/net/declance.c +++ b/drivers/net/declance.c @@ -42,7 +42,6 @@ * bits. macro */ -#include <linux/config.h> #include <linux/crc32.h> #include <linux/delay.h> #include <linux/errno.h> @@ -885,8 +884,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) len = skblen; if (len < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) return 0; len = ETH_ZLEN; } diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c index 5acd35c312a..91cc8cbdd44 100644 --- a/drivers/net/defxx.c +++ b/drivers/net/defxx.c @@ -1228,7 +1228,7 @@ static int dfx_open(struct net_device *dev) /* Register IRQ - support shared interrupts by passing device ptr */ - ret = request_irq(dev->irq, dfx_interrupt, SA_SHIRQ, dev->name, dev); + ret = request_irq(dev->irq, dfx_interrupt, IRQF_SHARED, dev->name, dev); if (ret) { printk(KERN_ERR "%s: Requested IRQ %d is busy\n", dev->name, dev->irq); return ret; diff --git a/drivers/net/depca.c b/drivers/net/depca.c index 0941d40f046..b1cbe99249c 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -235,7 +235,6 @@ ========================================================================= */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/string.h> @@ -938,11 +937,8 @@ static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev) if (skb->len < 1) goto out; - if (skb->len < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) - goto out; - } + if (skb_padto(skb, ETH_ZLEN)) + goto out; netif_stop_queue(dev); diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c index e175d487668..fa4f0943297 100644 --- a/drivers/net/dgrs.c +++ b/drivers/net/dgrs.c @@ -1191,7 +1191,7 @@ dgrs_probe1(struct net_device *dev) if (priv->plxreg) OUTL(dev->base_addr + PLX_LCL2PCI_DOORBELL, 1); - rc = request_irq(dev->irq, &dgrs_intr, SA_SHIRQ, "RightSwitch", dev); + rc = request_irq(dev->irq, &dgrs_intr, IRQF_SHARED, "RightSwitch", dev); if (rc) goto err_out; diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index 038447fb5c5..4b6ddb70f92 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -390,7 +390,7 @@ parse_eeprom (struct net_device *dev) for (i = 0; i < 6; i++) dev->dev_addr[i] = psrom->mac_addr[i]; - /* Parse Software Infomation Block */ + /* Parse Software Information Block */ i = 0x30; psib = (u8 *) sromdata; do { @@ -440,7 +440,7 @@ rio_open (struct net_device *dev) int i; u16 macctrl; - i = request_irq (dev->irq, &rio_interrupt, SA_SHIRQ, dev->name, dev); + i = request_irq (dev->irq, &rio_interrupt, IRQF_SHARED, dev->name, dev); if (i) return i; diff --git a/drivers/net/dl2k.h b/drivers/net/dl2k.h index 6e75482d75f..53449207e53 100644 --- a/drivers/net/dl2k.h +++ b/drivers/net/dl2k.h @@ -683,11 +683,6 @@ struct netdev_private { }; /* The station address location in the EEPROM. */ -#ifdef MEM_MAPPING -#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1) -#else -#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0) -#endif /* The struct pci_device_id consist of: vendor, device Vendor and device ID to match (or PCI_ANY_ID) subvendor, subdevice Subsystem vendor and device ID to match (or PCI_ANY_ID) @@ -695,9 +690,10 @@ struct netdev_private { class_mask of the class are honored during the comparison. driver_data Data private to the driver. */ -static struct pci_device_id rio_pci_tbl[] = { - {0x1186, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0,} + +static const struct pci_device_id rio_pci_tbl[] = { + {0x1186, 0x4000, PCI_ANY_ID, PCI_ANY_ID, }, + { } }; MODULE_DEVICE_TABLE (pci, rio_pci_tbl); #define TX_TIMEOUT (4*HZ) diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 24996da4c1c..1b758b70713 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -410,10 +410,7 @@ dm9000_probe(struct platform_device *pdev) if (pdev->num_resources < 2) { ret = -ENODEV; goto out; - } - - switch (pdev->num_resources) { - case 2: + } else if (pdev->num_resources == 2) { base = pdev->resource[0].start; if (!request_mem_region(base, 4, ndev->name)) { @@ -423,17 +420,16 @@ dm9000_probe(struct platform_device *pdev) ndev->base_addr = base; ndev->irq = pdev->resource[1].start; - db->io_addr = (void *)base; - db->io_data = (void *)(base + 4); - - break; + db->io_addr = (void __iomem *)base; + db->io_data = (void __iomem *)(base + 4); - case 3: + } else { db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (db->addr_res == NULL || db->data_res == NULL) { + if (db->addr_res == NULL || db->data_res == NULL || + db->irq_res == NULL) { printk(KERN_ERR PFX "insufficient resources\n"); ret = -ENOENT; goto out; @@ -482,7 +478,6 @@ dm9000_probe(struct platform_device *pdev) /* ensure at least we have a default set of IO routines */ dm9000_set_io(db, iosize); - } /* check to see if anything is being over-ridden */ @@ -564,6 +559,13 @@ dm9000_probe(struct platform_device *pdev) for (i = 0; i < 6; i++) ndev->dev_addr[i] = db->srom[i]; + if (!is_valid_ether_addr(ndev->dev_addr)) { + /* try reading from mac */ + + for (i = 0; i < 6; i++) + ndev->dev_addr[i] = ior(db, i+DM9000_PAR); + } + if (!is_valid_ether_addr(ndev->dev_addr)) printk("%s: Invalid ethernet MAC address. Please " "set using ifconfig\n", ndev->name); @@ -601,7 +603,7 @@ dm9000_open(struct net_device *dev) PRINTK2("entering dm9000_open\n"); - if (request_irq(dev->irq, &dm9000_interrupt, SA_SHIRQ, dev->name, dev)) + if (request_irq(dev->irq, &dm9000_interrupt, IRQF_SHARED, dev->name, dev)) return -EAGAIN; /* Initialize DM9000 board */ @@ -663,7 +665,6 @@ dm9000_init_dm9000(struct net_device *dev) db->tx_pkt_cnt = 0; db->queue_pkt_len = 0; dev->trans_start = 0; - spin_lock_init(&db->lock); } /* @@ -767,7 +768,7 @@ dm9000_stop(struct net_device *ndev) * receive the packet to upper layer, free the transmitted packet */ -void +static void dm9000_tx_done(struct net_device *dev, board_info_t * db) { int tx_status = ior(db, DM9000_NSR); /* Got TX status */ @@ -1187,13 +1188,14 @@ dm9000_drv_remove(struct platform_device *pdev) } static struct platform_driver dm9000_driver = { + .driver = { + .name = "dm9000", + .owner = THIS_MODULE, + }, .probe = dm9000_probe, .remove = dm9000_drv_remove, .suspend = dm9000_drv_suspend, .resume = dm9000_drv_resume, - .driver = { - .name = "dm9000", - }, }; static int __init diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index dd8c15ac5c7..36d511729f7 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -28,7 +28,6 @@ Alan Cox, 30th May 1994 */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> diff --git a/drivers/net/e100.c b/drivers/net/e100.c index f37170cc1a3..91ef5f2fd76 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -138,7 +138,6 @@ * - Stratus87247: protect MDI control register manipulations */ -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> @@ -2064,7 +2063,7 @@ static int e100_up(struct nic *nic) e100_set_multicast_list(nic->netdev); e100_start_receiver(nic, NULL); mod_timer(&nic->watchdog, jiffies); - if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ, + if((err = request_irq(nic->pdev->irq, e100_intr, IRQF_SHARED, nic->netdev->name, nic->netdev))) goto err_no_irq; netif_wake_queue(nic->netdev); @@ -2678,9 +2677,9 @@ static int __devinit e100_probe(struct pci_dev *pdev, goto err_out_free; } - DPRINTK(PROBE, INFO, "addr 0x%lx, irq %d, " + DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, " "MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n", - pci_resource_start(pdev, 0), pdev->irq, + (unsigned long long)pci_resource_start(pdev, 0), pdev->irq, netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 2bc34fbfa69..3042d33e2d4 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -34,7 +34,6 @@ #define _E1000_H_ #include <linux/stddef.h> -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <asm/byteorder.h> diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 6ed7f599eba..d1966489176 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -871,10 +871,10 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) *data = 0; /* Hook up test interrupt handler just for this test */ - if (!request_irq(irq, &e1000_test_intr, SA_PROBEIRQ, netdev->name, - netdev)) { + if (!request_irq(irq, &e1000_test_intr, IRQF_PROBE_SHARED, + netdev->name, netdev)) { shared_int = FALSE; - } else if (request_irq(irq, &e1000_test_intr, SA_SHIRQ, + } else if (request_irq(irq, &e1000_test_intr, IRQF_SHARED, netdev->name, netdev)){ *data = 1; return -1; diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index a373ccb308d..f77624f5f17 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -426,7 +426,7 @@ e1000_up(struct e1000_adapter *adapter) } #endif if ((err = request_irq(adapter->pdev->irq, &e1000_intr, - SA_SHIRQ | SA_SAMPLE_RANDOM, + IRQF_SHARED | IRQF_SAMPLE_RANDOM, netdev->name, netdev))) { DPRINTK(PROBE, ERR, "Unable to allocate interrupt Error: %d\n", err); @@ -2394,7 +2394,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, uint8_t ipcss, ipcso, tucss, tucso, hdr_len; int err; - if (skb_shinfo(skb)->tso_size) { + if (skb_shinfo(skb)->gso_size) { if (skb_header_cloned(skb)) { err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); if (err) @@ -2402,7 +2402,7 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, } hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); - mss = skb_shinfo(skb)->tso_size; + mss = skb_shinfo(skb)->gso_size; if (skb->protocol == htons(ETH_P_IP)) { skb->nh.iph->tot_len = 0; skb->nh.iph->check = 0; @@ -2519,7 +2519,7 @@ e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, * tso gets written back prematurely before the data is fully * DMA'd to the controller */ if (!skb->data_len && tx_ring->last_tx_tso && - !skb_shinfo(skb)->tso_size) { + !skb_shinfo(skb)->gso_size) { tx_ring->last_tx_tso = 0; size -= 4; } @@ -2757,7 +2757,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } #ifdef NETIF_F_TSO - mss = skb_shinfo(skb)->tso_size; + mss = skb_shinfo(skb)->gso_size; /* The controller does a simple calculation to * make sure there is enough room in the FIFO before * initiating the DMA for each buffer. The calc is: @@ -2807,7 +2807,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) #ifdef NETIF_F_TSO /* Controller Erratum workaround */ if (!skb->data_len && tx_ring->last_tx_tso && - !skb_shinfo(skb)->tso_size) + !skb_shinfo(skb)->gso_size) count++; #endif diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index a806dfe54d2..20d31430c74 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -920,7 +920,7 @@ static int eepro_grab_irq(struct net_device *dev) eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */ - if (request_irq (*irqp, NULL, SA_SHIRQ, "bogus", dev) != EBUSY) { + if (request_irq (*irqp, NULL, IRQF_SHARED, "bogus", dev) != EBUSY) { unsigned long irq_mask; /* Twinkle the interrupt, and check if it's seen */ irq_mask = probe_irq_on(); @@ -1154,8 +1154,7 @@ static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev) printk(KERN_DEBUG "%s: entering eepro_send_packet routine.\n", dev->name); if (length < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) return 0; length = ETH_ZLEN; } diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 467fc861360..2ad32754292 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -87,7 +87,6 @@ static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1}; /* Size of an pre-allocated Rx buffer: <Ethernet MTU> + slack.*/ #define PKT_BUF_SZ 1536 -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> @@ -278,11 +277,6 @@ having to sign an Intel NDA when I'm helping Intel sell their own product! static int speedo_found1(struct pci_dev *pdev, void __iomem *ioaddr, int fnd_cnt, int acpi_idle_state); -enum pci_flags_bit { - PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, - PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, -}; - /* Offsets to the various registers. All accesses need not be longword aligned. */ enum speedo_offsets { @@ -983,7 +977,7 @@ speedo_open(struct net_device *dev) sp->in_interrupt = 0; /* .. we can safely take handler calls during init. */ - retval = request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ, dev->name, dev); + retval = request_irq(dev->irq, &speedo_interrupt, IRQF_SHARED, dev->name, dev); if (retval) { return retval; } diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c index 82bd356e4f3..33291bcf6d4 100644 --- a/drivers/net/eexpress.c +++ b/drivers/net/eexpress.c @@ -97,7 +97,6 @@ #define LOCKUP16 0 #endif -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> @@ -677,8 +676,7 @@ static int eexp_xmit(struct sk_buff *buf, struct net_device *dev) #endif if (buf->len < ETH_ZLEN) { - buf = skb_padto(buf, ETH_ZLEN); - if (buf == NULL) + if (skb_padto(buf, ETH_ZLEN)) return 0; length = ETH_ZLEN; } diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 8d680ce600d..9f3e09a3d88 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -114,7 +114,6 @@ static int rx_copybreak; #define TX_FIFO_THRESH 256 #define RX_FIFO_THRESH 1 /* 0-3, 0==32, 64,96, or 3==128 bytes */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/string.h> @@ -191,23 +190,10 @@ IVc. Errata */ -enum pci_id_flags_bits { - /* Set PCI command register bits before calling probe1(). */ - PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, - /* Read and map the single following PCI BAR. */ - PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4, - PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400, -}; - enum chip_capability_flags { MII_PWRDWN=1, TYPE2_INTR=2, NO_MII=4 }; #define EPIC_TOTAL_SIZE 0x100 #define USE_IO_OPS 1 -#ifdef USE_IO_OPS -#define EPIC_IOTYPE PCI_USES_MASTER|PCI_USES_IO|PCI_ADDR0 -#else -#define EPIC_IOTYPE PCI_USES_MASTER|PCI_USES_MEM|PCI_ADDR1 -#endif typedef enum { SMSC_83C170_0, @@ -218,7 +204,6 @@ typedef enum { struct epic_chip_info { const char *name; - enum pci_id_flags_bits pci_flags; int io_size; /* Needed for I/O region check or ioremap(). */ int drv_flags; /* Driver use, intended as capability flags. */ }; @@ -227,11 +212,11 @@ struct epic_chip_info { /* indexed by chip_t */ static const struct epic_chip_info pci_id_tbl[] = { { "SMSC EPIC/100 83c170", - EPIC_IOTYPE, EPIC_TOTAL_SIZE, TYPE2_INTR | NO_MII | MII_PWRDWN }, + EPIC_TOTAL_SIZE, TYPE2_INTR | NO_MII | MII_PWRDWN }, { "SMSC EPIC/100 83c170", - EPIC_IOTYPE, EPIC_TOTAL_SIZE, TYPE2_INTR }, + EPIC_TOTAL_SIZE, TYPE2_INTR }, { "SMSC EPIC/C 83c175", - EPIC_IOTYPE, EPIC_TOTAL_SIZE, TYPE2_INTR | MII_PWRDWN }, + EPIC_TOTAL_SIZE, TYPE2_INTR | MII_PWRDWN }, }; @@ -728,7 +713,7 @@ static int epic_open(struct net_device *dev) /* Soft reset the chip. */ outl(0x4001, ioaddr + GENCTL); - if ((retval = request_irq(dev->irq, &epic_interrupt, SA_SHIRQ, dev->name, dev))) + if ((retval = request_irq(dev->irq, &epic_interrupt, IRQF_SHARED, dev->name, dev))) return retval; epic_init_ring(dev); @@ -1027,11 +1012,8 @@ static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev) u32 ctrl_word; unsigned long flags; - if (skb->len < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) - return 0; - } + if (skb_padto(skb, ETH_ZLEN)) + return 0; /* Caution: the write order is important here, set the field with the "ownership" bit last. */ diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index b67545be2ca..4bf76f86d8e 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c @@ -1064,8 +1064,7 @@ static int eth16i_tx(struct sk_buff *skb, struct net_device *dev) unsigned long flags; if (length < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) return 0; length = ETH_ZLEN; } diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index a8449265e5f..c701951dcd6 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c @@ -126,16 +126,6 @@ MODULE_PARM_DESC(full_duplex, "fealnx full duplex setting(s) (1)"); #define MIN_REGION_SIZE 136 -enum pci_flags_bit { - PCI_USES_IO = 1, - PCI_USES_MEM = 2, - PCI_USES_MASTER = 4, - PCI_ADDR0 = 0x10 << 0, - PCI_ADDR1 = 0x10 << 1, - PCI_ADDR2 = 0x10 << 2, - PCI_ADDR3 = 0x10 << 3, -}; - /* A chip capabilities table, matching the entries in pci_tbl[] above. */ enum chip_capability_flags { HAS_MII_XCVR, @@ -844,7 +834,7 @@ static int netdev_open(struct net_device *dev) iowrite32(0x00000001, ioaddr + BCR); /* Reset */ - if (request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev)) + if (request_irq(dev->irq, &intr_handler, IRQF_SHARED, dev->name, dev)) return -EAGAIN; for (i = 0; i < 3; i++) diff --git a/drivers/net/fec.c b/drivers/net/fec.c index bd6983d1afb..9b403003174 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -22,10 +22,9 @@ * Copyright (c) 2001-2005 Greg Ungerer (gerg@snapgear.com) * * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be) - * Copyright (c) 2004-2005 Macq Electronique SA. + * Copyright (c) 2004-2006 Macq Electronique SA. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/string.h> @@ -51,7 +50,7 @@ #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \ defined(CONFIG_M5272) || defined(CONFIG_M528x) || \ - defined(CONFIG_M520x) + defined(CONFIG_M520x) || defined(CONFIG_M532x) #include <asm/coldfire.h> #include <asm/mcfsim.h> #include "fec.h" @@ -80,6 +79,8 @@ static unsigned int fec_hw[] = { (MCF_MBAR + 0x1000), #elif defined(CONFIG_M520x) (MCF_MBAR+0x30000), +#elif defined(CONFIG_M532x) + (MCF_MBAR+0xfc030000), #else &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), #endif @@ -143,7 +144,7 @@ typedef struct { #define TX_RING_MOD_MASK 15 /* for this to work */ #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE) -#error "FEC: descriptor ring size contants too large" +#error "FEC: descriptor ring size constants too large" #endif /* Interrupt events/masks. @@ -167,12 +168,12 @@ typedef struct { /* - * The 5270/5271/5280/5282 RX control register also contains maximum frame + * The 5270/5271/5280/5282/532x RX control register also contains maximum frame * size bits. Other FEC hardware does not, so we need to take that into * account when setting it. */ #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ - defined(CONFIG_M520x) + defined(CONFIG_M520x) || defined(CONFIG_M532x) #define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) #else #define OPT_FRAME_SIZE 0 @@ -308,6 +309,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) struct fec_enet_private *fep; volatile fec_t *fecp; volatile cbd_t *bdp; + unsigned short status; fep = netdev_priv(dev); fecp = (volatile fec_t*)dev->base_addr; @@ -320,8 +322,9 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Fill in a Tx ring entry */ bdp = fep->cur_tx; + status = bdp->cbd_sc; #ifndef final_version - if (bdp->cbd_sc & BD_ENET_TX_READY) { + if (status & BD_ENET_TX_READY) { /* Ooops. All transmit buffers are full. Bail out. * This should not happen, since dev->tbusy should be set. */ @@ -332,7 +335,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Clear all of the status flags. */ - bdp->cbd_sc &= ~BD_ENET_TX_STATS; + status &= ~BD_ENET_TX_STATS; /* Set buffer length and buffer pointer. */ @@ -366,21 +369,22 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_lock_irq(&fep->lock); - /* Send it on its way. Tell FEC its ready, interrupt when done, - * its the last BD of the frame, and to put the CRC on the end. + /* Send it on its way. Tell FEC it's ready, interrupt when done, + * it's the last BD of the frame, and to put the CRC on the end. */ - bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR + status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC); + bdp->cbd_sc = status; dev->trans_start = jiffies; /* Trigger transmission start */ - fecp->fec_x_des_active = 0x01000000; + fecp->fec_x_des_active = 0; /* If this was the last BD in the ring, start at the beginning again. */ - if (bdp->cbd_sc & BD_ENET_TX_WRAP) { + if (status & BD_ENET_TX_WRAP) { bdp = fep->tx_bd_base; } else { bdp++; @@ -491,43 +495,44 @@ fec_enet_tx(struct net_device *dev) { struct fec_enet_private *fep; volatile cbd_t *bdp; + unsigned short status; struct sk_buff *skb; fep = netdev_priv(dev); spin_lock(&fep->lock); bdp = fep->dirty_tx; - while ((bdp->cbd_sc&BD_ENET_TX_READY) == 0) { + while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) { if (bdp == fep->cur_tx && fep->tx_full == 0) break; skb = fep->tx_skbuff[fep->skb_dirty]; /* Check for errors. */ - if (bdp->cbd_sc & (BD_ENET_TX_HB | BD_ENET_TX_LC | + if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) { fep->stats.tx_errors++; - if (bdp->cbd_sc & BD_ENET_TX_HB) /* No heartbeat */ + if (status & BD_ENET_TX_HB) /* No heartbeat */ fep->stats.tx_heartbeat_errors++; - if (bdp->cbd_sc & BD_ENET_TX_LC) /* Late collision */ + if (status & BD_ENET_TX_LC) /* Late collision */ fep->stats.tx_window_errors++; - if (bdp->cbd_sc & BD_ENET_TX_RL) /* Retrans limit */ + if (status & BD_ENET_TX_RL) /* Retrans limit */ fep->stats.tx_aborted_errors++; - if (bdp->cbd_sc & BD_ENET_TX_UN) /* Underrun */ + if (status & BD_ENET_TX_UN) /* Underrun */ fep->stats.tx_fifo_errors++; - if (bdp->cbd_sc & BD_ENET_TX_CSL) /* Carrier lost */ + if (status & BD_ENET_TX_CSL) /* Carrier lost */ fep->stats.tx_carrier_errors++; } else { fep->stats.tx_packets++; } #ifndef final_version - if (bdp->cbd_sc & BD_ENET_TX_READY) + if (status & BD_ENET_TX_READY) printk("HEY! Enet xmit interrupt and TX_READY.\n"); #endif /* Deferred means some collisions occurred during transmit, * but we eventually sent the packet OK. */ - if (bdp->cbd_sc & BD_ENET_TX_DEF) + if (status & BD_ENET_TX_DEF) fep->stats.collisions++; /* Free the sk buffer associated with this last transmit. @@ -538,7 +543,7 @@ fec_enet_tx(struct net_device *dev) /* Update pointer to next buffer descriptor to be transmitted. */ - if (bdp->cbd_sc & BD_ENET_TX_WRAP) + if (status & BD_ENET_TX_WRAP) bdp = fep->tx_bd_base; else bdp++; @@ -568,9 +573,14 @@ fec_enet_rx(struct net_device *dev) struct fec_enet_private *fep; volatile fec_t *fecp; volatile cbd_t *bdp; + unsigned short status; struct sk_buff *skb; ushort pkt_len; __u8 *data; + +#ifdef CONFIG_M532x + flush_cache_all(); +#endif fep = netdev_priv(dev); fecp = (volatile fec_t*)dev->base_addr; @@ -580,13 +590,13 @@ fec_enet_rx(struct net_device *dev) */ bdp = fep->cur_rx; -while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { +while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { #ifndef final_version /* Since we have allocated space to hold a complete frame, * the last indicator should be set. */ - if ((bdp->cbd_sc & BD_ENET_RX_LAST) == 0) + if ((status & BD_ENET_RX_LAST) == 0) printk("FEC ENET: rcv is not +last\n"); #endif @@ -594,26 +604,26 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { goto rx_processing_done; /* Check for errors. */ - if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | + if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { fep->stats.rx_errors++; - if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { + if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { /* Frame too long or too short. */ fep->stats.rx_length_errors++; } - if (bdp->cbd_sc & BD_ENET_RX_NO) /* Frame alignment */ + if (status & BD_ENET_RX_NO) /* Frame alignment */ fep->stats.rx_frame_errors++; - if (bdp->cbd_sc & BD_ENET_RX_CR) /* CRC Error */ - fep->stats.rx_crc_errors++; - if (bdp->cbd_sc & BD_ENET_RX_OV) /* FIFO overrun */ + if (status & BD_ENET_RX_CR) /* CRC Error */ fep->stats.rx_crc_errors++; + if (status & BD_ENET_RX_OV) /* FIFO overrun */ + fep->stats.rx_fifo_errors++; } /* Report late collisions as a frame error. * On this error, the BD is closed, but we don't know what we * have in the buffer. So, just drop this frame on the floor. */ - if (bdp->cbd_sc & BD_ENET_RX_CL) { + if (status & BD_ENET_RX_CL) { fep->stats.rx_errors++; fep->stats.rx_frame_errors++; goto rx_processing_done; @@ -639,9 +649,7 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { } else { skb->dev = dev; skb_put(skb,pkt_len-4); /* Make room */ - eth_copy_and_sum(skb, - (unsigned char *)__va(bdp->cbd_bufaddr), - pkt_len-4, 0); + eth_copy_and_sum(skb, data, pkt_len-4, 0); skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); } @@ -649,15 +657,16 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { /* Clear the status flags for this buffer. */ - bdp->cbd_sc &= ~BD_ENET_RX_STATS; + status &= ~BD_ENET_RX_STATS; /* Mark the buffer empty. */ - bdp->cbd_sc |= BD_ENET_RX_EMPTY; + status |= BD_ENET_RX_EMPTY; + bdp->cbd_sc = status; /* Update BD pointer to next entry. */ - if (bdp->cbd_sc & BD_ENET_RX_WRAP) + if (status & BD_ENET_RX_WRAP) bdp = fep->rx_bd_base; else bdp++; @@ -667,9 +676,9 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { * incoming frames. On a heavily loaded network, we should be * able to keep up at the expense of system resources. */ - fecp->fec_r_des_active = 0x01000000; + fecp->fec_r_des_active = 0; #endif - } /* while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) */ + } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */ fep->cur_rx = (cbd_t *)bdp; #if 0 @@ -680,11 +689,12 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { * our way back to the interrupt return only to come right back * here. */ - fecp->fec_r_des_active = 0x01000000; + fecp->fec_r_des_active = 0; #endif } +/* called from interrupt context */ static void fec_enet_mii(struct net_device *dev) { @@ -696,10 +706,12 @@ fec_enet_mii(struct net_device *dev) fep = netdev_priv(dev); ep = fep->hwp; mii_reg = ep->fec_mii_data; + + spin_lock(&fep->lock); if ((mip = mii_head) == NULL) { printk("MII and no head!\n"); - return; + goto unlock; } if (mip->mii_func != NULL) @@ -711,6 +723,9 @@ fec_enet_mii(struct net_device *dev) if ((mip = mii_head) != NULL) ep->fec_mii_data = mip->mii_regval; + +unlock: + spin_unlock(&fep->lock); } static int @@ -728,8 +743,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi retval = 0; - save_flags(flags); - cli(); + spin_lock_irqsave(&fep->lock,flags); if ((mip = mii_free) != NULL) { mii_free = mip->mii_next; @@ -749,7 +763,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi retval = 1; } - restore_flags(flags); + spin_unlock_irqrestore(&fep->lock,flags); return(retval); } @@ -1216,7 +1230,7 @@ static phy_info_t const * const phy_info[] = { }; /* ------------------------------------------------------------------------- */ - +#if !defined(CONFIG_M532x) #ifdef CONFIG_RPXCLASSIC static void mii_link_interrupt(void *dev_id); @@ -1224,6 +1238,7 @@ mii_link_interrupt(void *dev_id); static irqreturn_t mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs); #endif +#endif #if defined(CONFIG_M5272) @@ -1384,13 +1399,13 @@ static void __inline__ fec_request_intrs(struct net_device *dev) { volatile unsigned char *icrp; volatile unsigned long *imrp; - int i; + int i, ilip; b = (fep->index) ? MCFICM_INTC1 : MCFICM_INTC0; icrp = (volatile unsigned char *) (MCF_IPSBAR + b + MCFINTC_ICR0); - for (i = 23; (i < 36); i++) - icrp[i] = 0x23; + for (i = 23, ilip = 0x28; (i < 36); i++) + icrp[i] = ilip--; imrp = (volatile unsigned long *) (MCF_IPSBAR + b + MCFINTC_IMRH); @@ -1618,6 +1633,159 @@ static void __inline__ fec_uncache(unsigned long addr) /* ------------------------------------------------------------------------- */ +#elif defined(CONFIG_M532x) +/* + * Code specific for M532x + */ +static void __inline__ fec_request_intrs(struct net_device *dev) +{ + struct fec_enet_private *fep; + int b; + static const struct idesc { + char *name; + unsigned short irq; + } *idp, id[] = { + { "fec(TXF)", 36 }, + { "fec(TXB)", 37 }, + { "fec(TXFIFO)", 38 }, + { "fec(TXCR)", 39 }, + { "fec(RXF)", 40 }, + { "fec(RXB)", 41 }, + { "fec(MII)", 42 }, + { "fec(LC)", 43 }, + { "fec(HBERR)", 44 }, + { "fec(GRA)", 45 }, + { "fec(EBERR)", 46 }, + { "fec(BABT)", 47 }, + { "fec(BABR)", 48 }, + { NULL }, + }; + + fep = netdev_priv(dev); + b = (fep->index) ? 128 : 64; + + /* Setup interrupt handlers. */ + for (idp = id; idp->name; idp++) { + if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0) + printk("FEC: Could not allocate %s IRQ(%d)!\n", + idp->name, b+idp->irq); + } + + /* Unmask interrupts */ + MCF_INTC0_ICR36 = 0x2; + MCF_INTC0_ICR37 = 0x2; + MCF_INTC0_ICR38 = 0x2; + MCF_INTC0_ICR39 = 0x2; + MCF_INTC0_ICR40 = 0x2; + MCF_INTC0_ICR41 = 0x2; + MCF_INTC0_ICR42 = 0x2; + MCF_INTC0_ICR43 = 0x2; + MCF_INTC0_ICR44 = 0x2; + MCF_INTC0_ICR45 = 0x2; + MCF_INTC0_ICR46 = 0x2; + MCF_INTC0_ICR47 = 0x2; + MCF_INTC0_ICR48 = 0x2; + + MCF_INTC0_IMRH &= ~( + MCF_INTC_IMRH_INT_MASK36 | + MCF_INTC_IMRH_INT_MASK37 | + MCF_INTC_IMRH_INT_MASK38 | + MCF_INTC_IMRH_INT_MASK39 | + MCF_INTC_IMRH_INT_MASK40 | + MCF_INTC_IMRH_INT_MASK41 | + MCF_INTC_IMRH_INT_MASK42 | + MCF_INTC_IMRH_INT_MASK43 | + MCF_INTC_IMRH_INT_MASK44 | + MCF_INTC_IMRH_INT_MASK45 | + MCF_INTC_IMRH_INT_MASK46 | + MCF_INTC_IMRH_INT_MASK47 | + MCF_INTC_IMRH_INT_MASK48 ); + + /* Set up gpio outputs for MII lines */ + MCF_GPIO_PAR_FECI2C |= (0 | + MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC | + MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO); + MCF_GPIO_PAR_FEC = (0 | + MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC | + MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC); +} + +static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) +{ + volatile fec_t *fecp; + + fecp = fep->hwp; + fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04; + fecp->fec_x_cntrl = 0x00; + + /* + * Set MII speed to 2.5 MHz + */ + fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2; + fecp->fec_mii_speed = fep->phy_speed; + + fec_restart(dev, 0); +} + +static void __inline__ fec_get_mac(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + volatile fec_t *fecp; + unsigned char *iap, tmpaddr[ETH_ALEN]; + + fecp = fep->hwp; + + if (FEC_FLASHMAC) { + /* + * Get MAC address from FLASH. + * If it is all 1's or 0's, use the default. + */ + iap = FEC_FLASHMAC; + if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) && + (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0)) + iap = fec_mac_default; + if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) && + (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) + iap = fec_mac_default; + } else { + *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low; + *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16); + iap = &tmpaddr[0]; + } + + memcpy(dev->dev_addr, iap, ETH_ALEN); + + /* Adjust MAC if using default MAC address */ + if (iap == fec_mac_default) + dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index; +} + +static void __inline__ fec_enable_phy_intr(void) +{ +} + +static void __inline__ fec_disable_phy_intr(void) +{ +} + +static void __inline__ fec_phy_ack_intr(void) +{ +} + +static void __inline__ fec_localhw_setup(void) +{ +} + +/* + * Do not need to make region uncached on 532x. + */ +static void __inline__ fec_uncache(unsigned long addr) +{ +} + +/* ------------------------------------------------------------------------- */ + + #else /* @@ -1985,9 +2153,12 @@ fec_enet_open(struct net_device *dev) mii_do_cmd(dev, fep->phy->config); mii_do_cmd(dev, phy_cmd_config); /* display configuration */ - /* FIXME: use netif_carrier_{on,off} ; this polls - * until link is up which is wrong... could be - * 30 seconds or more we are trapped in here. -jgarzik + /* Poll until the PHY tells us its configuration + * (not link state). + * Request is initiated by mii_do_cmd above, but answer + * comes by interrupt. + * This should take about 25 usec per register at 2.5 MHz, + * and we read approximately 5 registers. */ while(!fep->sequence_done) schedule(); @@ -2253,15 +2424,11 @@ int __init fec_enet_init(struct net_device *dev) */ fec_request_intrs(dev); - /* Clear and enable interrupts */ - fecp->fec_ievent = 0xffc00000; - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | - FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); fecp->fec_hash_table_high = 0; fecp->fec_hash_table_low = 0; fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; fecp->fec_ecntrl = 2; - fecp->fec_r_des_active = 0x01000000; + fecp->fec_r_des_active = 0; dev->base_addr = (unsigned long)fecp; @@ -2281,6 +2448,11 @@ int __init fec_enet_init(struct net_device *dev) /* setup MII interface */ fec_set_mii(dev, fep); + /* Clear and enable interrupts */ + fecp->fec_ievent = 0xffc00000; + fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | + FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); + /* Queue up command to detect the PHY and initialize the * remainder of the interface. */ @@ -2312,11 +2484,6 @@ fec_restart(struct net_device *dev, int duplex) fecp->fec_ecntrl = 1; udelay(10); - /* Enable interrupts we wish to service. - */ - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | - FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); - /* Clear any outstanding interrupt. */ fecp->fec_ievent = 0xffc00000; @@ -2408,7 +2575,12 @@ fec_restart(struct net_device *dev, int duplex) /* And last, enable the transmit and receive processing. */ fecp->fec_ecntrl = 2; - fecp->fec_r_des_active = 0x01000000; + fecp->fec_r_des_active = 0; + + /* Enable interrupts we wish to service. + */ + fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | + FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); } static void @@ -2420,9 +2592,16 @@ fec_stop(struct net_device *dev) fep = netdev_priv(dev); fecp = fep->hwp; - fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ - - while(!(fecp->fec_ievent & FEC_ENET_GRA)); + /* + ** We cannot expect a graceful transmit stop without link !!! + */ + if (fep->link) + { + fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ + udelay(10); + if (!(fecp->fec_ievent & FEC_ENET_GRA)) + printk("fec_stop : Graceful transmit stop did not complete !\n"); + } /* Whack a reset. We should wait for this. */ diff --git a/drivers/net/fec.h b/drivers/net/fec.h index 965c5c49fcd..1d421606984 100644 --- a/drivers/net/fec.h +++ b/drivers/net/fec.h @@ -14,7 +14,7 @@ /****************************************************************************/ #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ - defined(CONFIG_M520x) + defined(CONFIG_M520x) || defined(CONFIG_M532x) /* * Just figures, Motorola would have to change the offsets for * registers in the same peripheral device on different models diff --git a/drivers/net/fec_8xx/fec_8xx-netta.c b/drivers/net/fec_8xx/fec_8xx-netta.c index 29c275e1d56..790d9dbe42d 100644 --- a/drivers/net/fec_8xx/fec_8xx-netta.c +++ b/drivers/net/fec_8xx/fec_8xx-netta.c @@ -2,7 +2,6 @@ * FEC instantatiation file for NETTA */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/sched.h> diff --git a/drivers/net/fec_8xx/fec_main.c b/drivers/net/fec_8xx/fec_main.c index 7e433809713..282b1452c39 100644 --- a/drivers/net/fec_8xx/fec_main.c +++ b/drivers/net/fec_8xx/fec_main.c @@ -10,7 +10,6 @@ * Released under the GPL */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> diff --git a/drivers/net/fec_8xx/fec_mii.c b/drivers/net/fec_8xx/fec_mii.c index 3b44ac1a7bf..d3c16b85d9a 100644 --- a/drivers/net/fec_8xx/fec_mii.c +++ b/drivers/net/fec_8xx/fec_mii.c @@ -10,7 +10,6 @@ * Released under the GPL */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 04a53f1dfdb..3c90003f423 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -1495,8 +1495,8 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) np->tx_skbuff[nr] = skb; #ifdef NETIF_F_TSO - if (skb_shinfo(skb)->tso_size) - tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT); + if (skb_shinfo(skb)->gso_size) + tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->gso_size << NV_TX2_TSO_SHIFT); else #endif tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0); @@ -2076,7 +2076,7 @@ static void nv_set_multicast(struct net_device *dev) spin_unlock_irq(&np->lock); } -void nv_update_pause(struct net_device *dev, u32 pause_flags) +static void nv_update_pause(struct net_device *dev, u32 pause_flags) { struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); @@ -2622,21 +2622,21 @@ static int nv_request_irq(struct net_device *dev, int intr_test) np->msi_flags |= NV_MSI_X_ENABLED; if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT && !intr_test) { /* Request irq for rx handling */ - if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, &nv_nic_irq_rx, SA_SHIRQ, dev->name, dev) != 0) { + if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, &nv_nic_irq_rx, IRQF_SHARED, dev->name, dev) != 0) { printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret); pci_disable_msix(np->pci_dev); np->msi_flags &= ~NV_MSI_X_ENABLED; goto out_err; } /* Request irq for tx handling */ - if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, &nv_nic_irq_tx, SA_SHIRQ, dev->name, dev) != 0) { + if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, &nv_nic_irq_tx, IRQF_SHARED, dev->name, dev) != 0) { printk(KERN_INFO "forcedeth: request_irq failed for tx %d\n", ret); pci_disable_msix(np->pci_dev); np->msi_flags &= ~NV_MSI_X_ENABLED; goto out_free_rx; } /* Request irq for link and timer handling */ - if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector, &nv_nic_irq_other, SA_SHIRQ, dev->name, dev) != 0) { + if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector, &nv_nic_irq_other, IRQF_SHARED, dev->name, dev) != 0) { printk(KERN_INFO "forcedeth: request_irq failed for link %d\n", ret); pci_disable_msix(np->pci_dev); np->msi_flags &= ~NV_MSI_X_ENABLED; @@ -2651,9 +2651,9 @@ static int nv_request_irq(struct net_device *dev, int intr_test) } else { /* Request irq for all interrupts */ if ((!intr_test && - request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) || + request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq, IRQF_SHARED, dev->name, dev) != 0) || (intr_test && - request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq_test, SA_SHIRQ, dev->name, dev) != 0)) { + request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq_test, IRQF_SHARED, dev->name, dev) != 0)) { printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); pci_disable_msix(np->pci_dev); np->msi_flags &= ~NV_MSI_X_ENABLED; @@ -2669,8 +2669,8 @@ static int nv_request_irq(struct net_device *dev, int intr_test) if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { if ((ret = pci_enable_msi(np->pci_dev)) == 0) { np->msi_flags |= NV_MSI_ENABLED; - if ((!intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) || - (intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq_test, SA_SHIRQ, dev->name, dev) != 0)) { + if ((!intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq, IRQF_SHARED, dev->name, dev) != 0) || + (intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq_test, IRQF_SHARED, dev->name, dev) != 0)) { printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); pci_disable_msi(np->pci_dev); np->msi_flags &= ~NV_MSI_ENABLED; @@ -2685,8 +2685,8 @@ static int nv_request_irq(struct net_device *dev, int intr_test) } } if (ret != 0) { - if ((!intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) || - (intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq_test, SA_SHIRQ, dev->name, dev) != 0)) + if ((!intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq, IRQF_SHARED, dev->name, dev) != 0) || + (intr_test && request_irq(np->pci_dev->irq, &nv_nic_irq_test, IRQF_SHARED, dev->name, dev) != 0)) goto out_err; } @@ -2991,13 +2991,13 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) netif_carrier_off(dev); if (netif_running(dev)) { nv_disable_irq(dev); - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); spin_lock(&np->lock); /* stop engines */ nv_stop_rx(dev); nv_stop_tx(dev); spin_unlock(&np->lock); - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); } if (ecmd->autoneg == AUTONEG_ENABLE) { @@ -3131,13 +3131,13 @@ static int nv_nway_reset(struct net_device *dev) netif_carrier_off(dev); if (netif_running(dev)) { nv_disable_irq(dev); - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); spin_lock(&np->lock); /* stop engines */ nv_stop_rx(dev); nv_stop_tx(dev); spin_unlock(&np->lock); - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); printk(KERN_INFO "%s: link down.\n", dev->name); } @@ -3244,7 +3244,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri if (netif_running(dev)) { nv_disable_irq(dev); - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); spin_lock(&np->lock); /* stop engines */ nv_stop_rx(dev); @@ -3303,7 +3303,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri nv_start_rx(dev); nv_start_tx(dev); spin_unlock(&np->lock); - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); nv_enable_irq(dev); } return 0; @@ -3339,13 +3339,13 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* netif_carrier_off(dev); if (netif_running(dev)) { nv_disable_irq(dev); - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); spin_lock(&np->lock); /* stop engines */ nv_stop_rx(dev); nv_stop_tx(dev); spin_unlock(&np->lock); - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); } np->pause_flags &= ~(NV_PAUSEFRAME_RX_REQ|NV_PAUSEFRAME_TX_REQ); @@ -3729,7 +3729,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 if (test->flags & ETH_TEST_FL_OFFLINE) { if (netif_running(dev)) { netif_stop_queue(dev); - spin_lock_bh(&dev->xmit_lock); + netif_tx_lock_bh(dev); spin_lock_irq(&np->lock); nv_disable_hw_interrupts(dev, np->irqmask); if (!(np->msi_flags & NV_MSI_X_ENABLED)) { @@ -3745,7 +3745,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64 nv_drain_rx(dev); nv_drain_tx(dev); spin_unlock_irq(&np->lock); - spin_unlock_bh(&dev->xmit_lock); + netif_tx_unlock_bh(dev); } if (!nv_register_test(dev)) { diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 196298f33db..f6abff5846b 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -15,7 +15,6 @@ * kind, whether express or implied. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> @@ -672,7 +671,7 @@ static int fs_request_irq(struct net_device *dev, int irq, const char *name, struct fs_enet_private *fep = netdev_priv(dev); (*fep->ops->pre_request_irq)(dev, irq); - return request_irq(irq, irqf, SA_SHIRQ, name, dev); + return request_irq(irq, irqf, IRQF_SHARED, name, dev); } static void fs_free_irq(struct net_device *dev, int irq) diff --git a/drivers/net/fs_enet/fs_enet-mii.c b/drivers/net/fs_enet/fs_enet-mii.c index c6770377ef8..b7e6e21725c 100644 --- a/drivers/net/fs_enet/fs_enet-mii.c +++ b/drivers/net/fs_enet/fs_enet-mii.c @@ -16,7 +16,6 @@ */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> @@ -431,8 +430,7 @@ static struct fs_enet_mii_bus *create_bus(const struct fs_mii_bus_info *bi) return bus; err: - if (bus) - kfree(bus); + kfree(bus); return ERR_PTR(ret); } diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index 95e2bb8dd7b..64e20982c1f 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c @@ -12,7 +12,6 @@ * kind, whether express or implied. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index 3dad69dfdb2..e0954707752 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c @@ -12,7 +12,6 @@ * kind, whether express or implied. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index a772b286f96..eaa24fab645 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c @@ -12,7 +12,6 @@ * kind, whether express or implied. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c index 24a5e2e23d1..48f9cf83ab6 100644 --- a/drivers/net/fs_enet/mii-bitbang.c +++ b/drivers/net/fs_enet/mii-bitbang.c @@ -13,7 +13,6 @@ */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> diff --git a/drivers/net/fs_enet/mii-fixed.c b/drivers/net/fs_enet/mii-fixed.c index b3e192d612e..ae4a9c3bb39 100644 --- a/drivers/net/fs_enet/mii-fixed.c +++ b/drivers/net/fs_enet/mii-fixed.c @@ -13,7 +13,6 @@ */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 218d31764c5..ebbbd6ca620 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -64,7 +64,6 @@ * The driver then cleans up the buffer. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 127c98cf333..f87bbc408da 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -22,7 +22,6 @@ #ifndef __GIANFAR_H #define __GIANFAR_H -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index d69698c695e..e0f505285e5 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -15,7 +15,6 @@ * by reference. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c index c6b725529af..c92e65984fd 100644 --- a/drivers/net/gianfar_mii.c +++ b/drivers/net/gianfar_mii.c @@ -16,7 +16,6 @@ * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c index a6d5c43199c..e8a18f18d08 100644 --- a/drivers/net/gianfar_sysfs.c +++ b/drivers/net/gianfar_sysfs.c @@ -19,7 +19,6 @@ * Sysfs file creation and management */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> diff --git a/drivers/net/gt96100eth.c b/drivers/net/gt96100eth.c index 2d243540461..49dacc6e35a 100644 --- a/drivers/net/gt96100eth.c +++ b/drivers/net/gt96100eth.c @@ -1030,7 +1030,7 @@ gt96100_open(struct net_device *dev) } if ((retval = request_irq(dev->irq, >96100_interrupt, - SA_SHIRQ, dev->name, dev))) { + IRQF_SHARED, dev->name, dev))) { err("unable to get IRQ %d\n", dev->irq); return retval; } diff --git a/drivers/net/gt96100eth.h b/drivers/net/gt96100eth.h index 395869c5ed3..2a8331938b8 100644 --- a/drivers/net/gt96100eth.h +++ b/drivers/net/gt96100eth.h @@ -27,7 +27,6 @@ #ifndef _GT96100ETH_H #define _GT96100ETH_H -#include <linux/config.h> #include <asm/galileo-boards/gt96100.h> #define dbg(lvl, format, arg...) \ diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 0ea4cb4a0d8..7bcd939c6ed 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -871,7 +871,7 @@ static int hamachi_open(struct net_device *dev) u32 rx_int_var, tx_int_var; u16 fifo_info; - i = request_irq(dev->irq, &hamachi_interrupt, SA_SHIRQ, dev->name, dev); + i = request_irq(dev->irq, &hamachi_interrupt, IRQF_SHARED, dev->name, dev); if (i) return i; diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index d12605f0ac7..86b3bb9bec2 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -12,7 +12,6 @@ * Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> */ -#include <linux/config.h> #include <linux/module.h> #include <asm/system.h> #include <asm/uaccess.h> diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c index 232793d2ce6..55906c7b4bb 100644 --- a/drivers/net/hamradio/baycom_ser_fdx.c +++ b/drivers/net/hamradio/baycom_ser_fdx.c @@ -434,7 +434,7 @@ static int ser12_open(struct net_device *dev) outb(0, FCR(dev->base_addr)); /* disable FIFOs */ outb(0x0d, MCR(dev->base_addr)); outb(0, IER(dev->base_addr)); - if (request_irq(dev->irq, ser12_interrupt, SA_INTERRUPT | SA_SHIRQ, + if (request_irq(dev->irq, ser12_interrupt, IRQF_DISABLED | IRQF_SHARED, "baycom_ser_fdx", dev)) { release_region(dev->base_addr, SER12_EXTENT); return -EBUSY; diff --git a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c index be596a3eb3f..de95de8983d 100644 --- a/drivers/net/hamradio/baycom_ser_hdx.c +++ b/drivers/net/hamradio/baycom_ser_hdx.c @@ -488,7 +488,7 @@ static int ser12_open(struct net_device *dev) outb(0, FCR(dev->base_addr)); /* disable FIFOs */ outb(0x0d, MCR(dev->base_addr)); outb(0, IER(dev->base_addr)); - if (request_irq(dev->irq, ser12_interrupt, SA_INTERRUPT | SA_SHIRQ, + if (request_irq(dev->irq, ser12_interrupt, IRQF_DISABLED | IRQF_SHARED, "baycom_ser12", dev)) { release_region(dev->base_addr, SER12_EXTENT); return -EBUSY; diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index cb43a9d2877..0641f54fc63 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -54,7 +54,6 @@ * BPQ 004 Joerg(DL1BKE) Fixed to not lock up on ifconfig. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index 0d5fccc984b..c9a46b89942 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c @@ -436,7 +436,7 @@ static int __init dmascc_init(void) module_init(dmascc_init); module_exit(dmascc_exit); -static void dev_setup(struct net_device *dev) +static void __init dev_setup(struct net_device *dev) { dev->type = ARPHRD_AX25; dev->hard_header_len = AX25_MAX_HEADER_LEN; diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 3ebbbe56b6e..d8715b200c1 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -16,7 +16,6 @@ * Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf@linux-mips.org> * Copyright (C) 2004, 05 Thomas Osterried DL9SAU <thomas@x-berg.in-berlin.de> */ -#include <linux/config.h> #include <linux/module.h> #include <asm/system.h> #include <linux/bitops.h> diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 5927784df3f..df4b68142ac 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c @@ -148,7 +148,6 @@ /* ----------------------------------------------------------------------- */ -#include <linux/config.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/signal.h> @@ -1737,7 +1736,7 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (!Ivec[hwcfg.irq].used && hwcfg.irq) { - if (request_irq(hwcfg.irq, scc_isr, SA_INTERRUPT, "AX.25 SCC", NULL)) + if (request_irq(hwcfg.irq, scc_isr, IRQF_DISABLED, "AX.25 SCC", NULL)) printk(KERN_WARNING "z8530drv: warning, cannot get IRQ %d\n", hwcfg.irq); else Ivec[hwcfg.irq].used = 1; diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index b49884048ca..f98f5777dfb 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c @@ -42,7 +42,6 @@ /*****************************************************************************/ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/net.h> @@ -874,7 +873,7 @@ static int yam_open(struct net_device *dev) goto out_release_base; } outb(0, IER(dev->base_addr)); - if (request_irq(dev->irq, yam_interrupt, SA_INTERRUPT | SA_SHIRQ, dev->name, dev)) { + if (request_irq(dev->irq, yam_interrupt, IRQF_DISABLED | IRQF_SHARED, dev->name, dev)) { printk(KERN_ERR "%s: irq %d busy\n", dev->name, dev->irq); ret = -EBUSY; goto out_release_base; diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index 247c8ca8603..e7d9bf33028 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -1079,7 +1079,7 @@ static int hp100_open(struct net_device *dev) /* New: if bus is PCI or EISA, interrupts might be shared interrupts */ if (request_irq(dev->irq, hp100_interrupt, lp->bus == HP100_BUS_PCI || lp->bus == - HP100_BUS_EISA ? SA_SHIRQ : SA_INTERRUPT, + HP100_BUS_EISA ? IRQF_SHARED : IRQF_DISABLED, "hp100", dev)) { printk("hp100: %s: unable to get IRQ %d\n", dev->name, dev->irq); return -EAGAIN; @@ -1487,11 +1487,8 @@ static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev) if (skb->len <= 0) return 0; - if (skb->len < ETH_ZLEN && lp->chip == HP100_CHIPID_SHASTA) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) - return 0; - } + if (lp->chip == HP100_CHIPID_SHASTA && skb_padto(skb, ETH_ZLEN)) + return 0; /* Get Tx ring tail pointer */ if (lp->txrtail->next == lp->txrhead) { diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c index d9fb8e74e63..91326ea3e12 100644 --- a/drivers/net/hydra.c +++ b/drivers/net/hydra.c @@ -117,7 +117,7 @@ static int __devinit hydra_init(struct zorro_dev *z) dev->irq = IRQ_AMIGA_PORTS; /* Install the Interrupt handler */ - if (request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, "Hydra Ethernet", + if (request_irq(IRQ_AMIGA_PORTS, ei_interrupt, IRQF_SHARED, "Hydra Ethernet", dev)) { free_netdev(dev); return -EAGAIN; diff --git a/drivers/net/ibm_emac/ibm_emac.h b/drivers/net/ibm_emac/ibm_emac.h index c2dae6092c4..97ed22bb432 100644 --- a/drivers/net/ibm_emac/ibm_emac.h +++ b/drivers/net/ibm_emac/ibm_emac.h @@ -20,7 +20,6 @@ #ifndef __IBM_EMAC_H_ #define __IBM_EMAC_H_ -#include <linux/config.h> #include <linux/types.h> /* This is a simple check to prevent use of this driver on non-tested SoCs */ diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c index 7e49522b8b3..82468e2dc79 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.c +++ b/drivers/net/ibm_emac/ibm_emac_core.c @@ -19,7 +19,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> diff --git a/drivers/net/ibm_emac/ibm_emac_core.h b/drivers/net/ibm_emac/ibm_emac_core.h index f61273b2e94..dabb94afeb9 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.h +++ b/drivers/net/ibm_emac/ibm_emac_core.h @@ -20,7 +20,6 @@ #ifndef __IBM_EMAC_CORE_H_ #define __IBM_EMAC_CORE_H_ -#include <linux/config.h> #include <linux/netdevice.h> #include <linux/dma-mapping.h> #include <asm/ocp.h> diff --git a/drivers/net/ibm_emac/ibm_emac_debug.c b/drivers/net/ibm_emac/ibm_emac_debug.c index c7e1ecfa08f..c3645908034 100644 --- a/drivers/net/ibm_emac/ibm_emac_debug.c +++ b/drivers/net/ibm_emac/ibm_emac_debug.c @@ -12,7 +12,6 @@ * option) any later version. * */ -#include <linux/config.h> #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> diff --git a/drivers/net/ibm_emac/ibm_emac_debug.h b/drivers/net/ibm_emac/ibm_emac_debug.h index e85fbe0a8da..5761389495d 100644 --- a/drivers/net/ibm_emac/ibm_emac_debug.h +++ b/drivers/net/ibm_emac/ibm_emac_debug.h @@ -15,7 +15,6 @@ #ifndef __IBM_EMAC_DEBUG_H_ #define __IBM_EMAC_DEBUG_H_ -#include <linux/config.h> #include <linux/init.h> #include "ibm_emac_core.h" #include "ibm_emac_mal.h" diff --git a/drivers/net/ibm_emac/ibm_emac_mal.c b/drivers/net/ibm_emac/ibm_emac_mal.c index da88d43081c..af50e7b2e0d 100644 --- a/drivers/net/ibm_emac/ibm_emac_mal.c +++ b/drivers/net/ibm_emac/ibm_emac_mal.c @@ -19,7 +19,6 @@ * option) any later version. * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/net/ibm_emac/ibm_emac_mal.h b/drivers/net/ibm_emac/ibm_emac_mal.h index 2a2d3b24b03..f73f10a0a56 100644 --- a/drivers/net/ibm_emac/ibm_emac_mal.h +++ b/drivers/net/ibm_emac/ibm_emac_mal.h @@ -19,7 +19,6 @@ #ifndef __IBM_EMAC_MAL_H_ #define __IBM_EMAC_MAL_H_ -#include <linux/config.h> #include <linux/init.h> #include <linux/list.h> #include <linux/netdevice.h> diff --git a/drivers/net/ibm_emac/ibm_emac_phy.c b/drivers/net/ibm_emac/ibm_emac_phy.c index 67935dd33a6..4a97024061e 100644 --- a/drivers/net/ibm_emac/ibm_emac_phy.c +++ b/drivers/net/ibm_emac/ibm_emac_phy.c @@ -12,7 +12,6 @@ * (c) 2004-2005, Eugene Surovegin <ebs@ebshome.net> * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.c b/drivers/net/ibm_emac/ibm_emac_rgmii.c index f0b1ffb2dbb..53d281cb9a1 100644 --- a/drivers/net/ibm_emac/ibm_emac_rgmii.c +++ b/drivers/net/ibm_emac/ibm_emac_rgmii.c @@ -16,7 +16,6 @@ * option) any later version. * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/ethtool.h> #include <asm/io.h> diff --git a/drivers/net/ibm_emac/ibm_emac_rgmii.h b/drivers/net/ibm_emac/ibm_emac_rgmii.h index 7f03d536c9a..94abde55e2e 100644 --- a/drivers/net/ibm_emac/ibm_emac_rgmii.h +++ b/drivers/net/ibm_emac/ibm_emac_rgmii.h @@ -21,7 +21,6 @@ #ifndef _IBM_EMAC_RGMII_H_ #define _IBM_EMAC_RGMII_H_ -#include <linux/config.h> /* RGMII bridge */ struct rgmii_regs { diff --git a/drivers/net/ibm_emac/ibm_emac_tah.c b/drivers/net/ibm_emac/ibm_emac_tah.c index af08afc22f9..e287b451bb4 100644 --- a/drivers/net/ibm_emac/ibm_emac_tah.c +++ b/drivers/net/ibm_emac/ibm_emac_tah.c @@ -13,7 +13,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ -#include <linux/config.h> #include <asm/io.h> #include "ibm_emac_core.h" diff --git a/drivers/net/ibm_emac/ibm_emac_tah.h b/drivers/net/ibm_emac/ibm_emac_tah.h index 9299b5dd7eb..38153945a24 100644 --- a/drivers/net/ibm_emac/ibm_emac_tah.h +++ b/drivers/net/ibm_emac/ibm_emac_tah.h @@ -17,7 +17,6 @@ #ifndef _IBM_EMAC_TAH_H #define _IBM_EMAC_TAH_H -#include <linux/config.h> #include <linux/init.h> #include <asm/ocp.h> diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.c b/drivers/net/ibm_emac/ibm_emac_zmii.c index e129e0aaa04..37dc8f34286 100644 --- a/drivers/net/ibm_emac/ibm_emac_zmii.c +++ b/drivers/net/ibm_emac/ibm_emac_zmii.c @@ -16,7 +16,6 @@ * option) any later version. * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/ethtool.h> #include <asm/io.h> diff --git a/drivers/net/ibm_emac/ibm_emac_zmii.h b/drivers/net/ibm_emac/ibm_emac_zmii.h index 92c85441075..972e3a44a09 100644 --- a/drivers/net/ibm_emac/ibm_emac_zmii.h +++ b/drivers/net/ibm_emac/ibm_emac_zmii.h @@ -19,7 +19,6 @@ #ifndef _IBM_EMAC_ZMII_H_ #define _IBM_EMAC_ZMII_H_ -#include <linux/config.h> #include <linux/init.h> #include <asm/ocp.h> diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index 51fd51609ea..2a95d72fa59 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c @@ -782,7 +782,7 @@ static int ibmlana_open(struct net_device *dev) /* register resources - only necessary for IRQ */ - result = request_irq(priv->realirq, irq_handler, SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); + result = request_irq(priv->realirq, irq_handler, IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev); if (result != 0) { printk(KERN_ERR "%s: failed to register irq %d\n", dev->name, dev->irq); return result; diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 666346f6469..0464e78f733 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -33,7 +33,6 @@ - possibly remove procfs support */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/errno.h> @@ -61,7 +60,7 @@ #undef DEBUG #define ibmveth_printk(fmt, args...) \ - printk(KERN_INFO "%s: " fmt, __FILE__, ## args) + printk(KERN_DEBUG "%s: " fmt, __FILE__, ## args) #define ibmveth_error_printk(fmt, args...) \ printk(KERN_ERR "(%s:%3.3d ua:%x) ERROR: " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args) diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 2e222ef91e2..3a42afab503 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -27,7 +27,6 @@ */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index ae71ed57c12..68d8af7df08 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -30,7 +30,6 @@ #define IOC3_NAME "ioc3-eth" #define IOC3_VERSION "2.6.3-3" -#include <linux/config.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/kernel.h> @@ -145,7 +144,7 @@ static inline struct sk_buff * ioc3_alloc_skb(unsigned long length, static inline unsigned long ioc3_map(void *ptr, unsigned long vdev) { #ifdef CONFIG_SGI_IP27 - vdev <<= 58; /* Shift to PCI64_ATTR_VIRTUAL */ + vdev <<= 57; /* Shift to PCI64_ATTR_VIRTUAL */ return vdev | (0xaUL << PCI64_ATTR_TARG_SHFT) | PCI64_ATTR_PREF | ((unsigned long)ptr & TO_PHYS_MASK); @@ -1064,7 +1063,7 @@ static int ioc3_open(struct net_device *dev) { struct ioc3_private *ip = netdev_priv(dev); - if (request_irq(dev->irq, ioc3_interrupt, SA_SHIRQ, ioc3_str, dev)) { + if (request_irq(dev->irq, ioc3_interrupt, IRQF_SHARED, ioc3_str, dev)) { printk(KERN_ERR "%s: Can't get irq %d\n", dev->name, dev->irq); return -EAGAIN; diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index d2ce4896abf..e9e6d99a9ad 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig @@ -350,7 +350,7 @@ config TOSHIBA_FIR config AU1000_FIR tristate "Alchemy Au1000 SIR/FIR" - depends on MIPS_AU1000 && IRDA + depends on SOC_AU1000 && IRDA config SMC_IRCC_FIR tristate "SMSC IrCC (EXPERIMENTAL)" diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index e6b1985767c..7b2b4135bb2 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c @@ -18,7 +18,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/init.h> diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c index 910c0cab35b..33c07d5275d 100644 --- a/drivers/net/irda/donauboe.c +++ b/drivers/net/irda/donauboe.c @@ -1372,7 +1372,7 @@ toshoboe_net_open (struct net_device *dev) return 0; if (request_irq (self->io.irq, toshoboe_interrupt, - SA_SHIRQ | SA_INTERRUPT, dev->name, (void *) self)) + IRQF_SHARED | IRQF_DISABLED, dev->name, (void *) self)) { return -EAGAIN; } @@ -1573,7 +1573,7 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) self->io.fir_base = self->base; self->io.fir_ext = OBOE_IO_EXTENT; self->io.irq = pci_dev->irq; - self->io.irqflags = SA_SHIRQ | SA_INTERRUPT; + self->io.irqflags = IRQF_SHARED | IRQF_DISABLED; self->speed = self->io.speed = 9600; self->async = 0; diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 844fa74ac9e..2a0d538b387 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -1105,7 +1105,7 @@ static int stir421x_patch_device(struct irda_usb_cb *self) return ret; /* We get a patch from userspace */ - IRDA_MESSAGE("%s(): Received firmware %s (%u bytes)\n", + IRDA_MESSAGE("%s(): Received firmware %s (%zu bytes)\n", __FUNCTION__, stir421x_fw_name, fw->size); ret = -EINVAL; diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c index 98fa5319e5c..44efd49bf4a 100644 --- a/drivers/net/irda/irport.c +++ b/drivers/net/irda/irport.c @@ -386,7 +386,7 @@ static int __irport_change_speed(struct irda_task *task) /* Locking notes : this function may be called from irq context with * spinlock, via irport_write_wakeup(), or from non-interrupt without * spinlock (from the task timer). Yuck ! - * This is ugly, and unsafe is the spinlock is not already aquired. + * This is ugly, and unsafe is the spinlock is not already acquired. * This will be fixed when irda-task get rewritten. * Jean II */ if (!spin_is_locked(&self->lock)) { diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c index 754297fc8f2..47f6f64d604 100644 --- a/drivers/net/irda/mcs7780.c +++ b/drivers/net/irda/mcs7780.c @@ -101,7 +101,7 @@ static int transceiver_type = MCS_TSC_VISHAY; module_param(transceiver_type, int, 0444); MODULE_PARM_DESC(transceiver_type, "IR transceiver type, see mcs7780.h."); -struct usb_driver mcs_driver = { +static struct usb_driver mcs_driver = { .name = "mcs7780", .probe = mcs_probe, .disconnect = mcs_disconnect, diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index cc7ff8f00e4..cb62f2a9676 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -115,8 +115,12 @@ static nsc_chip_t chips[] = { /* Contributed by Jan Frey - IBM A30/A31 */ { "PC8739x", { 0x2e, 0x4e, 0x0 }, 0x20, 0xea, 0xff, nsc_ircc_probe_39x, nsc_ircc_init_39x }, - { "IBM", { 0x2e, 0x4e, 0x0 }, 0x20, 0xf4, 0xff, - nsc_ircc_probe_39x, nsc_ircc_init_39x }, + /* IBM ThinkPads using PC8738x (T60/X60/Z60) */ + { "IBM-PC8738x", { 0x2e, 0x4e, 0x0 }, 0x20, 0xf4, 0xff, + nsc_ircc_probe_39x, nsc_ircc_init_39x }, + /* IBM ThinkPads using PC8394T (T43/R52/?) */ + { "IBM-PC8394T", { 0x2e, 0x4e, 0x0 }, 0x20, 0xf9, 0xff, + nsc_ircc_probe_39x, nsc_ircc_init_39x }, { NULL } }; diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index e1aa9910503..afb19e8d95c 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -12,7 +12,6 @@ * Infra-red driver (SIR/FIR) for the PXA2xx embedded microprocessor * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/init.h> diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index f530686bd09..8d5a288d797 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c @@ -18,7 +18,6 @@ * power_leve:level - set the transmitter power level * tx_lpm:0|1 - set transmit low power mode */ -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/types.h> diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index d70b9e8d6e6..92d646cc9ed 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -21,7 +21,6 @@ * ********************************************************************/ -#include <linux/config.h> #include <linux/module.h> #define DRIVER_NAME "vlsi_ir" @@ -1518,7 +1517,7 @@ static int vlsi_open(struct net_device *ndev) outb(IRINTR_INT_MASK, ndev->base_addr+VLSI_PIO_IRINTR); - if (request_irq(ndev->irq, vlsi_interrupt, SA_SHIRQ, + if (request_irq(ndev->irq, vlsi_interrupt, IRQF_SHARED, drivername, ndev)) { IRDA_WARNING("%s: couldn't get IRQ: %d\n", __FUNCTION__, ndev->irq); diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index f0f04be989d..cdc14401cdb 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -56,7 +56,6 @@ * number of packets outstanding to a remote partition at a time. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/errno.h> @@ -69,6 +68,7 @@ #include <linux/delay.h> #include <linux/mm.h> #include <linux/ethtool.h> +#include <linux/if_ether.h> #include <asm/abs_addr.h> #include <asm/iseries/mf.h> @@ -1035,11 +1035,22 @@ static struct ethtool_ops ops = { .get_link = veth_get_link, }; -static struct net_device * __init veth_probe_one(int vlan, struct device *vdev) +static struct net_device * __init veth_probe_one(int vlan, + struct vio_dev *vio_dev) { struct net_device *dev; struct veth_port *port; + struct device *vdev = &vio_dev->dev; int i, rc; + const unsigned char *mac_addr; + + mac_addr = vio_get_attribute(vio_dev, "local-mac-address", NULL); + if (mac_addr == NULL) + mac_addr = vio_get_attribute(vio_dev, "mac-address", NULL); + if (mac_addr == NULL) { + veth_error("Unable to fetch MAC address from device tree.\n"); + return NULL; + } dev = alloc_etherdev(sizeof (struct veth_port)); if (! dev) { @@ -1064,16 +1075,11 @@ static struct net_device * __init veth_probe_one(int vlan, struct device *vdev) } port->dev = vdev; - dev->dev_addr[0] = 0x02; - dev->dev_addr[1] = 0x01; - dev->dev_addr[2] = 0xff; - dev->dev_addr[3] = vlan; - dev->dev_addr[4] = 0xff; - dev->dev_addr[5] = this_lp; + memcpy(dev->dev_addr, mac_addr, ETH_ALEN); dev->mtu = VETH_MAX_MTU; - memcpy(&port->mac_addr, dev->dev_addr, 6); + memcpy(&port->mac_addr, mac_addr, ETH_ALEN); dev->open = veth_open; dev->hard_start_xmit = veth_start_xmit; @@ -1608,7 +1614,7 @@ static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id) struct net_device *dev; struct veth_port *port; - dev = veth_probe_one(i, &vdev->dev); + dev = veth_probe_one(i, vdev); if (dev == NULL) { veth_remove(vdev); return 1; @@ -1641,7 +1647,7 @@ static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id) * support. */ static struct vio_device_id veth_device_table[] __devinitdata = { - { "vlan", "" }, + { "network", "IBM,iSeries-l-lan" }, { "", "" } }; MODULE_DEVICE_TABLE(vio, veth_device_table); diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h index a83ef28dadb..82b67af54c9 100644 --- a/drivers/net/ixgb/ixgb.h +++ b/drivers/net/ixgb/ixgb.h @@ -30,7 +30,6 @@ #define _IXGB_H_ #include <linux/stddef.h> -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <asm/byteorder.h> diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 57006fb8840..b91e082483f 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -253,7 +253,7 @@ ixgb_up(struct ixgb_adapter *adapter) #endif if((err = request_irq(adapter->pdev->irq, &ixgb_intr, - SA_SHIRQ | SA_SAMPLE_RANDOM, + IRQF_SHARED | IRQF_SAMPLE_RANDOM, netdev->name, netdev))) { DPRINTK(PROBE, ERR, "Unable to allocate interrupt Error: %d\n", err); @@ -1173,7 +1173,7 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) uint16_t ipcse, tucse, mss; int err; - if(likely(skb_shinfo(skb)->tso_size)) { + if(likely(skb_shinfo(skb)->gso_size)) { if (skb_header_cloned(skb)) { err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); if (err) @@ -1181,7 +1181,7 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) } hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); - mss = skb_shinfo(skb)->tso_size; + mss = skb_shinfo(skb)->gso_size; skb->nh.iph->tot_len = 0; skb->nh.iph->check = 0; skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr, diff --git a/drivers/net/ixp2000/caleb.c b/drivers/net/ixp2000/caleb.c index 3595e107df2..7dea5b95012 100644 --- a/drivers/net/ixp2000/caleb.c +++ b/drivers/net/ixp2000/caleb.c @@ -9,7 +9,6 @@ * (at your option) any later version. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/delay.h> #include <asm/io.h> diff --git a/drivers/net/ixp2000/enp2611.c b/drivers/net/ixp2000/enp2611.c index b67f586d739..d3f4235c585 100644 --- a/drivers/net/ixp2000/enp2611.c +++ b/drivers/net/ixp2000/enp2611.c @@ -9,7 +9,6 @@ * (at your option) any later version. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> diff --git a/drivers/net/ixp2000/ixp2400-msf.c b/drivers/net/ixp2000/ixp2400-msf.c index 48a3a891d3a..9ec38eebfb5 100644 --- a/drivers/net/ixp2000/ixp2400-msf.c +++ b/drivers/net/ixp2000/ixp2400-msf.c @@ -11,7 +11,6 @@ * License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/init.h> #include <asm/hardware.h> diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c index fbc2d21020f..6eeb965b4d7 100644 --- a/drivers/net/ixp2000/ixpdev.c +++ b/drivers/net/ixp2000/ixpdev.c @@ -9,7 +9,6 @@ * (at your option) any later version. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> @@ -236,7 +235,7 @@ static int ixpdev_open(struct net_device *dev) if (!nds_open++) { err = request_irq(IRQ_IXP2000_THDA0, ixpdev_interrupt, - SA_SHIRQ, "ixp2000_eth", nds); + IRQF_SHARED, "ixp2000_eth", nds); if (err) { nds_open--; return err; diff --git a/drivers/net/ixp2000/pm3386.c b/drivers/net/ixp2000/pm3386.c index 5224651c9aa..e08d3f9863b 100644 --- a/drivers/net/ixp2000/pm3386.c +++ b/drivers/net/ixp2000/pm3386.c @@ -9,7 +9,6 @@ * (at your option) any later version. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/delay.h> #include <linux/netdevice.h> diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index 272d331d29c..661d75b4cad 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c @@ -260,7 +260,7 @@ MODULE_DESCRIPTION("Jazz SONIC ethernet driver"); module_param(sonic_debug, int, 0); MODULE_PARM_DESC(sonic_debug, "jazzsonic debug level (1-4)"); -#define SONIC_IRQ_FLAG SA_INTERRUPT +#define SONIC_IRQ_FLAG IRQF_DISABLED #include "sonic.c" diff --git a/drivers/net/lance.c b/drivers/net/lance.c index bb5ad479210..c1c3452c90c 100644 --- a/drivers/net/lance.c +++ b/drivers/net/lance.c @@ -968,8 +968,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev) /* The old LANCE chips doesn't automatically pad buffers to min. size. */ if (chip_table[lp->chip_version].flags & LANCE_MUST_PAD) { if (skb->len < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) goto out; lp->tx_ring[entry].length = -ETH_ZLEN; } diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index 957888de3d7..1ab09447baa 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c @@ -1083,8 +1083,7 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) skb->len, skb->data)); if (length < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) return 0; length = ETH_ZLEN; } diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index b79d6e8d304..43fef7de8cb 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -74,7 +74,7 @@ static void emulate_large_send_offload(struct sk_buff *skb) struct iphdr *iph = skb->nh.iph; struct tcphdr *th = (struct tcphdr*)(skb->nh.raw + (iph->ihl * 4)); unsigned int doffset = (iph->ihl + th->doff) * 4; - unsigned int mtu = skb_shinfo(skb)->tso_size + doffset; + unsigned int mtu = skb_shinfo(skb)->gso_size + doffset; unsigned int offset = 0; u32 seq = ntohl(th->seq); u16 id = ntohs(iph->id); @@ -139,7 +139,7 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) #endif #ifdef LOOPBACK_TSO - if (skb_shinfo(skb)->tso_size) { + if (skb_shinfo(skb)->gso_size) { BUG_ON(skb->protocol != htons(ETH_P_IP)); BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP); diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c index 94d5ea1ce8b..b783a6984ab 100644 --- a/drivers/net/lp486e.c +++ b/drivers/net/lp486e.c @@ -851,7 +851,7 @@ static int i596_open(struct net_device *dev) { int i; - i = request_irq(dev->irq, &i596_interrupt, SA_SHIRQ, dev->name, dev); + i = request_irq(dev->irq, &i596_interrupt, IRQF_SHARED, dev->name, dev); if (i) { printk(KERN_ERR "%s: IRQ %d not free\n", dev->name, dev->irq); return i; @@ -877,8 +877,7 @@ static int i596_start_xmit (struct sk_buff *skb, struct net_device *dev) { length = skb->len; if (length < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) return 0; length = ETH_ZLEN; } diff --git a/drivers/net/mace.c b/drivers/net/mace.c index 77792b28602..f2c0bf89f0c 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -5,7 +5,6 @@ * Copyright (C) 1996 Paul Mackerras. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c index bbffb585b3b..07e58f4a291 100644 --- a/drivers/net/mipsnet.c +++ b/drivers/net/mipsnet.c @@ -179,7 +179,7 @@ static int mipsnet_open(struct net_device *dev) pr_debug("%s: mipsnet_open\n", dev->name); err = request_irq(dev->irq, &mipsnet_interrupt, - SA_SHIRQ, dev->name, (void *) dev); + IRQF_SHARED, dev->name, (void *) dev); if (err) { pr_debug("%s: %s(): can't get irq %d\n", diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 625ff61c998..760c61b9886 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -778,7 +778,7 @@ static int mv643xx_eth_open(struct net_device *dev) int err; err = request_irq(dev->irq, mv643xx_eth_int_handler, - SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); + IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev); if (err) { printk(KERN_ERR "Can not assign IRQ number to MV643XX_eth%d\n", port_num); diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h index 4262c1da6d4..33c5fafdbbd 100644 --- a/drivers/net/mv643xx_eth.h +++ b/drivers/net/mv643xx_eth.h @@ -258,7 +258,7 @@ struct pkt_info { struct sk_buff *return_info; /* User resource return information */ }; -/* Ethernet port specific infomation */ +/* Ethernet port specific information */ struct mv643xx_mib_counters { u64 good_octets_received; diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index e1feb58bd66..72aad42db7b 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -1879,7 +1879,7 @@ again: #ifdef NETIF_F_TSO if (skb->len > (dev->mtu + ETH_HLEN)) { - mss = skb_shinfo(skb)->tso_size; + mss = skb_shinfo(skb)->gso_size; if (mss != 0) max_segments = MYRI10GE_MAX_SEND_DESC_TSO; } @@ -1939,8 +1939,7 @@ again: /* pad frames to at least ETH_ZLEN bytes */ if (unlikely(skb->len < ETH_ZLEN)) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) { + if (skb_padto(skb, ETH_ZLEN)) { /* The packet is gone, so we must * return 0 */ mgp->stats.tx_dropped += 1; @@ -2113,14 +2112,14 @@ abort_linearize: } idx = (idx + 1) & tx->mask; } while (idx != last_idx); - if (skb_shinfo(skb)->tso_size) { + if (skb_shinfo(skb)->gso_size) { printk(KERN_ERR "myri10ge: %s: TSO but wanted to linearize?!?!?\n", mgp->dev->name); goto drop; } - if (skb_linearize(skb, GFP_ATOMIC)) + if (skb_linearize(skb)) goto drop; mgp->tx_linearized++; @@ -2251,12 +2250,6 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) } cap = pci_find_ext_capability(bridge, PCI_EXT_CAP_ID_ERR); - /* nvidia ext cap is not always linked in ext cap chain */ - if (!cap - && bridge->vendor == PCI_VENDOR_ID_NVIDIA - && bridge->device == PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_PCIE) - cap = 0x160; - if (!cap) return; @@ -2420,7 +2413,7 @@ static int myri10ge_resume(struct pci_dev *pdev) pci_enable_device(pdev); pci_set_master(pdev); - status = request_irq(pdev->irq, myri10ge_intr, SA_SHIRQ, + status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED, netdev->name, mgp); if (status != 0) { dev_err(&pdev->dev, "failed to allocate IRQ\n"); @@ -2701,7 +2694,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) mgp->msi_enabled = 1; } - status = request_irq(pdev->irq, myri10ge_intr, SA_SHIRQ, + status = request_irq(pdev->irq, myri10ge_intr, IRQF_SHARED, netdev->name, mgp); if (status != 0) { dev_err(&pdev->dev, "failed to allocate IRQ\n"); @@ -2732,8 +2725,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* Save configuration space to be restored if the * nic resets due to a parity error */ myri10ge_save_state(mgp); - /* Restore state immediately since pci_save_msi_state disables MSI */ - myri10ge_restore_state(mgp); /* Setup the watchdog timer */ setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer, diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 6c86dca62e2..1b965a2b56e 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -1,13 +1,12 @@ -/* myri_sbus.h: MyriCOM MyriNET SBUS card driver. +/* myri_sbus.c: MyriCOM MyriNET SBUS card driver. * - * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com) + * Copyright (C) 1996, 1999, 2006 David S. Miller (davem@davemloft.net) */ static char version[] = - "myri_sbus.c:v1.9 12/Sep/99 David S. Miller (davem@redhat.com)\n"; + "myri_sbus.c:v2.0 June 23, 2006 David S. Miller (davem@davemloft.net)\n"; #include <linux/module.h> -#include <linux/config.h> #include <linux/errno.h> #include <linux/kernel.h> #include <linux/types.h> @@ -81,10 +80,6 @@ static char version[] = #define DHDR(x) #endif -#ifdef MODULE -static struct myri_eth *root_myri_dev; -#endif - static void myri_reset_off(void __iomem *lp, void __iomem *cregs) { /* Clear IRQ mask. */ @@ -896,8 +891,9 @@ static void dump_eeprom(struct myri_eth *mp) } #endif -static int __init myri_ether_init(struct sbus_dev *sdev, int num) +static int __init myri_ether_init(struct sbus_dev *sdev) { + static int num; static unsigned version_printed; struct net_device *dev; struct myri_eth *mp; @@ -913,6 +909,9 @@ static int __init myri_ether_init(struct sbus_dev *sdev, int num) if (version_printed++ == 0) printk(version); + SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &sdev->ofdev.dev); + mp = (struct myri_eth *) dev->priv; spin_lock_init(&mp->irq_lock); mp->myri_sdev = sdev; @@ -1070,7 +1069,7 @@ static int __init myri_ether_init(struct sbus_dev *sdev, int num) /* Register interrupt handler now. */ DET(("Requesting MYRIcom IRQ line.\n")); if (request_irq(dev->irq, &myri_interrupt, - SA_SHIRQ, "MyriCOM Ethernet", (void *) dev)) { + IRQF_SHARED, "MyriCOM Ethernet", (void *) dev)) { printk("MyriCOM: Cannot register interrupt handler.\n"); goto err; } @@ -1092,10 +1091,9 @@ static int __init myri_ether_init(struct sbus_dev *sdev, int num) goto err_free_irq; } -#ifdef MODULE - mp->next_module = root_myri_dev; - root_myri_dev = mp; -#endif + dev_set_drvdata(&sdev->ofdev.dev, mp); + + num++; printk("%s: MyriCOM MyriNET Ethernet ", dev->name); @@ -1114,61 +1112,68 @@ err: return -ENODEV; } -static int __init myri_sbus_match(struct sbus_dev *sdev) -{ - char *name = sdev->prom_name; - if (!strcmp(name, "MYRICOM,mlanai") || - !strcmp(name, "myri")) - return 1; +static int __devinit myri_sbus_probe(struct of_device *dev, const struct of_device_id *match) +{ + struct sbus_dev *sdev = to_sbus_device(&dev->dev); - return 0; + return myri_ether_init(sdev); } -static int __init myri_sbus_probe(void) +static int __devexit myri_sbus_remove(struct of_device *dev) { - struct sbus_bus *bus; - struct sbus_dev *sdev = NULL; - static int called; - int cards = 0, v; + struct myri_eth *mp = dev_get_drvdata(&dev->dev); + struct net_device *net_dev = mp->dev; -#ifdef MODULE - root_myri_dev = NULL; -#endif + unregister_netdevice(net_dev); - if (called) - return -ENODEV; - called++; - - for_each_sbus(bus) { - for_each_sbusdev(sdev, bus) { - if (myri_sbus_match(sdev)) { - cards++; - DET(("Found myricom myrinet as %s\n", sdev->prom_name)); - if ((v = myri_ether_init(sdev, (cards - 1)))) - return v; - } - } + free_irq(net_dev->irq, net_dev); + + if (mp->eeprom.cpuvers < CPUVERS_4_0) { + sbus_iounmap(mp->regs, mp->reg_size); + } else { + sbus_iounmap(mp->cregs, PAGE_SIZE); + sbus_iounmap(mp->lregs, (256 * 1024)); + sbus_iounmap(mp->lanai, (512 * 1024)); } - if (!cards) - return -ENODEV; + + free_netdev(net_dev); + + dev_set_drvdata(&dev->dev, NULL); + return 0; } -static void __exit myri_sbus_cleanup(void) +static struct of_device_id myri_sbus_match[] = { + { + .name = "MYRICOM,mlanai", + }, + { + .name = "myri", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, myri_sbus_match); + +static struct of_platform_driver myri_sbus_driver = { + .name = "myri", + .match_table = myri_sbus_match, + .probe = myri_sbus_probe, + .remove = __devexit_p(myri_sbus_remove), +}; + +static int __init myri_sbus_init(void) +{ + return of_register_driver(&myri_sbus_driver, &sbus_bus_type); +} + +static void __exit myri_sbus_exit(void) { -#ifdef MODULE - while (root_myri_dev) { - struct myri_eth *next = root_myri_dev->next_module; - - unregister_netdev(root_myri_dev->dev); - /* this will also free the co-allocated 'root_myri_dev' */ - free_netdev(root_myri_dev->dev); - root_myri_dev = next; - } -#endif /* MODULE */ + of_unregister_driver(&myri_sbus_driver); } -module_init(myri_sbus_probe); -module_exit(myri_sbus_cleanup); +module_init(myri_sbus_init); +module_exit(myri_sbus_exit); + MODULE_LICENSE("GPL"); diff --git a/drivers/net/myri_sbus.h b/drivers/net/myri_sbus.h index 47722f708a4..2f69ef7cdcc 100644 --- a/drivers/net/myri_sbus.h +++ b/drivers/net/myri_sbus.h @@ -290,7 +290,6 @@ struct myri_eth { unsigned int reg_size; /* Size of register space. */ unsigned int shmem_base; /* Offset to shared ram. */ struct sbus_dev *myri_sdev; /* Our SBUS device struct. */ - struct myri_eth *next_module; /* Next in adapter chain. */ }; /* We use this to acquire receive skb's that we can DMA directly into. */ diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 2e4ecedba05..9df2628be1e 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -138,7 +138,6 @@ * big endian support with CFG:BEM instead of cpu_to_le32 */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/string.h> @@ -226,7 +225,6 @@ static int full_duplex[MAX_UNITS]; NATSEMI_PG1_NREGS) #define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */ #define NATSEMI_REGS_SIZE (NATSEMI_NREGS * sizeof(u32)) -#define NATSEMI_DEF_EEPROM_SIZE 24 /* 12 16-bit values */ /* Buffer sizes: * The nic writes 32-bit values, even if the upper bytes of @@ -344,18 +342,6 @@ None characterised. -enum pcistuff { - PCI_USES_IO = 0x01, - PCI_USES_MEM = 0x02, - PCI_USES_MASTER = 0x04, - PCI_ADDR0 = 0x08, - PCI_ADDR1 = 0x10, -}; - -/* MMIO operations required */ -#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1) - - /* * Support for fibre connections on Am79C874: * This phy needs a special setup when connected to a fibre cable. @@ -363,22 +349,25 @@ enum pcistuff { */ #define PHYID_AM79C874 0x0022561b -#define MII_MCTRL 0x15 /* mode control register */ -#define MII_FX_SEL 0x0001 /* 100BASE-FX (fiber) */ -#define MII_EN_SCRM 0x0004 /* enable scrambler (tp) */ +enum { + MII_MCTRL = 0x15, /* mode control register */ + MII_FX_SEL = 0x0001, /* 100BASE-FX (fiber) */ + MII_EN_SCRM = 0x0004, /* enable scrambler (tp) */ +}; /* array of board data directly indexed by pci_tbl[x].driver_data */ static const struct { const char *name; unsigned long flags; + unsigned int eeprom_size; } natsemi_pci_info[] __devinitdata = { - { "NatSemi DP8381[56]", PCI_IOTYPE }, + { "NatSemi DP8381[56]", 0, 24 }, }; -static struct pci_device_id natsemi_pci_tbl[] = { - { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815, PCI_ANY_ID, PCI_ANY_ID, }, - { 0, }, +static const struct pci_device_id natsemi_pci_tbl[] __devinitdata = { + { PCI_VENDOR_ID_NS, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, natsemi_pci_tbl); @@ -813,6 +802,42 @@ static void move_int_phy(struct net_device *dev, int addr) udelay(1); } +static void __devinit natsemi_init_media (struct net_device *dev) +{ + struct netdev_private *np = netdev_priv(dev); + u32 tmp; + + netif_carrier_off(dev); + + /* get the initial settings from hardware */ + tmp = mdio_read(dev, MII_BMCR); + np->speed = (tmp & BMCR_SPEED100)? SPEED_100 : SPEED_10; + np->duplex = (tmp & BMCR_FULLDPLX)? DUPLEX_FULL : DUPLEX_HALF; + np->autoneg = (tmp & BMCR_ANENABLE)? AUTONEG_ENABLE: AUTONEG_DISABLE; + np->advertising= mdio_read(dev, MII_ADVERTISE); + + if ((np->advertising & ADVERTISE_ALL) != ADVERTISE_ALL + && netif_msg_probe(np)) { + printk(KERN_INFO "natsemi %s: Transceiver default autonegotiation %s " + "10%s %s duplex.\n", + pci_name(np->pci_dev), + (mdio_read(dev, MII_BMCR) & BMCR_ANENABLE)? + "enabled, advertise" : "disabled, force", + (np->advertising & + (ADVERTISE_100FULL|ADVERTISE_100HALF))? + "0" : "", + (np->advertising & + (ADVERTISE_100FULL|ADVERTISE_10FULL))? + "full" : "half"); + } + if (netif_msg_probe(np)) + printk(KERN_INFO + "natsemi %s: Transceiver status %#04x advertising %#04x.\n", + pci_name(np->pci_dev), mdio_read(dev, MII_BMSR), + np->advertising); + +} + static int __devinit natsemi_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -852,8 +877,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, iosize = pci_resource_len(pdev, pcibar); irq = pdev->irq; - if (natsemi_pci_info[chip_idx].flags & PCI_USES_MASTER) - pci_set_master(pdev); + pci_set_master(pdev); dev = alloc_etherdev(sizeof (struct netdev_private)); if (!dev) @@ -892,7 +916,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, np->msg_enable = (debug >= 0) ? (1<<debug)-1 : NATSEMI_DEF_MSG; np->hands_off = 0; np->intr_status = 0; - np->eeprom_size = NATSEMI_DEF_EEPROM_SIZE; + np->eeprom_size = natsemi_pci_info[chip_idx].eeprom_size; /* Initial port: * - If the nic was configured to use an external phy and if find_mii @@ -957,34 +981,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, if (mtu) dev->mtu = mtu; - netif_carrier_off(dev); - - /* get the initial settings from hardware */ - tmp = mdio_read(dev, MII_BMCR); - np->speed = (tmp & BMCR_SPEED100)? SPEED_100 : SPEED_10; - np->duplex = (tmp & BMCR_FULLDPLX)? DUPLEX_FULL : DUPLEX_HALF; - np->autoneg = (tmp & BMCR_ANENABLE)? AUTONEG_ENABLE: AUTONEG_DISABLE; - np->advertising= mdio_read(dev, MII_ADVERTISE); - - if ((np->advertising & ADVERTISE_ALL) != ADVERTISE_ALL - && netif_msg_probe(np)) { - printk(KERN_INFO "natsemi %s: Transceiver default autonegotiation %s " - "10%s %s duplex.\n", - pci_name(np->pci_dev), - (mdio_read(dev, MII_BMCR) & BMCR_ANENABLE)? - "enabled, advertise" : "disabled, force", - (np->advertising & - (ADVERTISE_100FULL|ADVERTISE_100HALF))? - "0" : "", - (np->advertising & - (ADVERTISE_100FULL|ADVERTISE_10FULL))? - "full" : "half"); - } - if (netif_msg_probe(np)) - printk(KERN_INFO - "natsemi %s: Transceiver status %#04x advertising %#04x.\n", - pci_name(np->pci_dev), mdio_read(dev, MII_BMSR), - np->advertising); + natsemi_init_media(dev); /* save the silicon revision for later querying */ np->srr = readl(ioaddr + SiliconRev); @@ -1577,7 +1574,7 @@ static int netdev_open(struct net_device *dev) /* Reset the chip, just in case. */ natsemi_reset(dev); - i = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev); + i = request_irq(dev->irq, &intr_handler, IRQF_SHARED, dev->name, dev); if (i) return i; if (netif_msg_ifup(np)) diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c index ced9fdb8335..fa50eb88940 100644 --- a/drivers/net/ne2k-pci.c +++ b/drivers/net/ne2k-pci.c @@ -420,7 +420,7 @@ static int ne2k_pci_set_fdx(struct net_device *dev) static int ne2k_pci_open(struct net_device *dev) { - int ret = request_irq(dev->irq, ei_interrupt, SA_SHIRQ, dev->name, dev); + int ret = request_irq(dev->irq, ei_interrupt, IRQF_SHARED, dev->name, dev); if (ret) return ret; diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c new file mode 100644 index 00000000000..b1311ae8267 --- /dev/null +++ b/drivers/net/netx-eth.c @@ -0,0 +1,516 @@ +/* + * drivers/net/netx-eth.c + * + * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/delay.h> + +#include <linux/netdevice.h> +#include <linux/platform_device.h> +#include <linux/etherdevice.h> +#include <linux/skbuff.h> +#include <linux/mii.h> + +#include <asm/io.h> +#include <asm/hardware.h> +#include <asm/arch/hardware.h> +#include <asm/arch/netx-regs.h> +#include <asm/arch/pfifo.h> +#include <asm/arch/xc.h> +#include <asm/arch/eth.h> + +/* XC Fifo Offsets */ +#define EMPTY_PTR_FIFO(xcno) (0 + ((xcno) << 3)) /* Index of the empty pointer FIFO */ +#define IND_FIFO_PORT_HI(xcno) (1 + ((xcno) << 3)) /* Index of the FIFO where received */ + /* Data packages are indicated by XC */ +#define IND_FIFO_PORT_LO(xcno) (2 + ((xcno) << 3)) /* Index of the FIFO where received */ + /* Data packages are indicated by XC */ +#define REQ_FIFO_PORT_HI(xcno) (3 + ((xcno) << 3)) /* Index of the FIFO where Data packages */ + /* have to be indicated by ARM which */ + /* shall be sent */ +#define REQ_FIFO_PORT_LO(xcno) (4 + ((xcno) << 3)) /* Index of the FIFO where Data packages */ + /* have to be indicated by ARM which shall */ + /* be sent */ +#define CON_FIFO_PORT_HI(xcno) (5 + ((xcno) << 3)) /* Index of the FIFO where sent Data packages */ + /* are confirmed */ +#define CON_FIFO_PORT_LO(xcno) (6 + ((xcno) << 3)) /* Index of the FIFO where sent Data */ + /* packages are confirmed */ +#define PFIFO_MASK(xcno) (0x7f << (xcno*8)) + +#define FIFO_PTR_FRAMELEN_SHIFT 0 +#define FIFO_PTR_FRAMELEN_MASK (0x7ff << 0) +#define FIFO_PTR_FRAMELEN(len) (((len) << 0) & FIFO_PTR_FRAMELEN_MASK) +#define FIFO_PTR_TIMETRIG (1<<11) +#define FIFO_PTR_MULTI_REQ +#define FIFO_PTR_ORIGIN (1<<14) +#define FIFO_PTR_VLAN (1<<15) +#define FIFO_PTR_FRAMENO_SHIFT 16 +#define FIFO_PTR_FRAMENO_MASK (0x3f << 16) +#define FIFO_PTR_FRAMENO(no) (((no) << 16) & FIFO_PTR_FRAMENO_MASK) +#define FIFO_PTR_SEGMENT_SHIFT 22 +#define FIFO_PTR_SEGMENT_MASK (0xf << 22) +#define FIFO_PTR_SEGMENT(seg) (((seg) & 0xf) << 22) +#define FIFO_PTR_ERROR_SHIFT 28 +#define FIFO_PTR_ERROR_MASK (0xf << 28) + +#define ISR_LINK_STATUS_CHANGE (1<<4) +#define ISR_IND_LO (1<<3) +#define ISR_CON_LO (1<<2) +#define ISR_IND_HI (1<<1) +#define ISR_CON_HI (1<<0) + +#define ETH_MAC_LOCAL_CONFIG 0x1560 +#define ETH_MAC_4321 0x1564 +#define ETH_MAC_65 0x1568 + +#define MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT 16 +#define MAC_TRAFFIC_CLASS_ARRANGEMENT_MASK (0xf<<MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT) +#define MAC_TRAFFIC_CLASS_ARRANGEMENT(x) (((x)<<MAC_TRAFFIC_CLASS_ARRANGEMENT_SHIFT) & MAC_TRAFFIC_CLASS_ARRANGEMENT_MASK) +#define LOCAL_CONFIG_LINK_STATUS_IRQ_EN (1<<24) +#define LOCAL_CONFIG_CON_LO_IRQ_EN (1<<23) +#define LOCAL_CONFIG_CON_HI_IRQ_EN (1<<22) +#define LOCAL_CONFIG_IND_LO_IRQ_EN (1<<21) +#define LOCAL_CONFIG_IND_HI_IRQ_EN (1<<20) + +#define CARDNAME "netx-eth" + +/* LSB must be zero */ +#define INTERNAL_PHY_ADR 0x1c + +struct netx_eth_priv { + void __iomem *sram_base, *xpec_base, *xmac_base; + int id; + struct net_device_stats stats; + struct mii_if_info mii; + u32 msg_enable; + struct xc *xc; + spinlock_t lock; +}; + +static void netx_eth_set_multicast_list(struct net_device *ndev) +{ + /* implement me */ +} + +static int +netx_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + struct netx_eth_priv *priv = netdev_priv(ndev); + unsigned char *buf = skb->data; + unsigned int len = skb->len; + + spin_lock_irq(&priv->lock); + memcpy_toio(priv->sram_base + 1560, (void *)buf, len); + if (len < 60) { + memset_io(priv->sram_base + 1560 + len, 0, 60 - len); + len = 60; + } + + pfifo_push(REQ_FIFO_PORT_LO(priv->id), + FIFO_PTR_SEGMENT(priv->id) | + FIFO_PTR_FRAMENO(1) | + FIFO_PTR_FRAMELEN(len)); + + ndev->trans_start = jiffies; + priv->stats.tx_packets++; + priv->stats.tx_bytes += skb->len; + + netif_stop_queue(ndev); + spin_unlock_irq(&priv->lock); + dev_kfree_skb(skb); + + return 0; +} + +static void netx_eth_receive(struct net_device *ndev) +{ + struct netx_eth_priv *priv = netdev_priv(ndev); + unsigned int val, frameno, seg, len; + unsigned char *data; + struct sk_buff *skb; + + val = pfifo_pop(IND_FIFO_PORT_LO(priv->id)); + + frameno = (val & FIFO_PTR_FRAMENO_MASK) >> FIFO_PTR_FRAMENO_SHIFT; + seg = (val & FIFO_PTR_SEGMENT_MASK) >> FIFO_PTR_SEGMENT_SHIFT; + len = (val & FIFO_PTR_FRAMELEN_MASK) >> FIFO_PTR_FRAMELEN_SHIFT; + + skb = dev_alloc_skb(len); + if (unlikely(skb == NULL)) { + printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", + ndev->name); + priv->stats.rx_dropped++; + return; + } + + data = skb_put(skb, len); + + memcpy_fromio(data, priv->sram_base + frameno * 1560, len); + + pfifo_push(EMPTY_PTR_FIFO(priv->id), + FIFO_PTR_SEGMENT(seg) | FIFO_PTR_FRAMENO(frameno)); + + ndev->last_rx = jiffies; + skb->dev = ndev; + skb->protocol = eth_type_trans(skb, ndev); + netif_rx(skb); + priv->stats.rx_packets++; + priv->stats.rx_bytes += len; +} + +static irqreturn_t +netx_eth_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *ndev = dev_id; + struct netx_eth_priv *priv = netdev_priv(ndev); + int status; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + + status = readl(NETX_PFIFO_XPEC_ISR(priv->id)); + while (status) { + int fill_level; + writel(status, NETX_PFIFO_XPEC_ISR(priv->id)); + + if ((status & ISR_CON_HI) || (status & ISR_IND_HI)) + printk("%s: unexpected status: 0x%08x\n", + __FUNCTION__, status); + + fill_level = + readl(NETX_PFIFO_FILL_LEVEL(IND_FIFO_PORT_LO(priv->id))); + while (fill_level--) + netx_eth_receive(ndev); + + if (status & ISR_CON_LO) + netif_wake_queue(ndev); + + if (status & ISR_LINK_STATUS_CHANGE) + mii_check_media(&priv->mii, netif_msg_link(priv), 1); + + status = readl(NETX_PFIFO_XPEC_ISR(priv->id)); + } + spin_unlock_irqrestore(&priv->lock, flags); + return IRQ_HANDLED; +} + +static struct net_device_stats *netx_eth_query_statistics(struct net_device *ndev) +{ + struct netx_eth_priv *priv = netdev_priv(ndev); + return &priv->stats; +} + +static int netx_eth_open(struct net_device *ndev) +{ + struct netx_eth_priv *priv = netdev_priv(ndev); + + if (request_irq + (ndev->irq, &netx_eth_interrupt, IRQF_SHARED, ndev->name, ndev)) + return -EAGAIN; + + writel(ndev->dev_addr[0] | + ndev->dev_addr[1]<<8 | + ndev->dev_addr[2]<<16 | + ndev->dev_addr[3]<<24, + priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_4321); + writel(ndev->dev_addr[4] | + ndev->dev_addr[5]<<8, + priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_65); + + writel(LOCAL_CONFIG_LINK_STATUS_IRQ_EN | + LOCAL_CONFIG_CON_LO_IRQ_EN | + LOCAL_CONFIG_CON_HI_IRQ_EN | + LOCAL_CONFIG_IND_LO_IRQ_EN | + LOCAL_CONFIG_IND_HI_IRQ_EN, + priv->xpec_base + NETX_XPEC_RAM_START_OFS + + ETH_MAC_LOCAL_CONFIG); + + mii_check_media(&priv->mii, netif_msg_link(priv), 1); + netif_start_queue(ndev); + + return 0; +} + +static int netx_eth_close(struct net_device *ndev) +{ + struct netx_eth_priv *priv = netdev_priv(ndev); + + netif_stop_queue(ndev); + + writel(0, + priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_LOCAL_CONFIG); + + free_irq(ndev->irq, ndev); + + return 0; +} + +static void netx_eth_timeout(struct net_device *ndev) +{ + struct netx_eth_priv *priv = netdev_priv(ndev); + int i; + + printk(KERN_ERR "%s: transmit timed out, resetting\n", ndev->name); + + spin_lock_irq(&priv->lock); + + xc_reset(priv->xc); + xc_start(priv->xc); + + for (i=2; i<=18; i++) + pfifo_push(EMPTY_PTR_FIFO(priv->id), + FIFO_PTR_FRAMENO(i) | FIFO_PTR_SEGMENT(priv->id)); + + spin_unlock_irq(&priv->lock); + + netif_wake_queue(ndev); +} + +static int +netx_eth_phy_read(struct net_device *ndev, int phy_id, int reg) +{ + unsigned int val; + + val = MIIMU_SNRDY | MIIMU_PREAMBLE | MIIMU_PHYADDR(phy_id) | + MIIMU_REGADDR(reg) | MIIMU_PHY_NRES; + + writel(val, NETX_MIIMU); + while (readl(NETX_MIIMU) & MIIMU_SNRDY); + + return readl(NETX_MIIMU) >> 16; + +} + +static void +netx_eth_phy_write(struct net_device *ndev, int phy_id, int reg, int value) +{ + unsigned int val; + + val = MIIMU_SNRDY | MIIMU_PREAMBLE | MIIMU_PHYADDR(phy_id) | + MIIMU_REGADDR(reg) | MIIMU_PHY_NRES | MIIMU_OPMODE_WRITE | + MIIMU_DATA(value); + + writel(val, NETX_MIIMU); + while (readl(NETX_MIIMU) & MIIMU_SNRDY); +} + +static int netx_eth_enable(struct net_device *ndev) +{ + struct netx_eth_priv *priv = netdev_priv(ndev); + unsigned int mac4321, mac65; + int running, i; + + ether_setup(ndev); + + ndev->open = netx_eth_open; + ndev->stop = netx_eth_close; + ndev->hard_start_xmit = netx_eth_hard_start_xmit; + ndev->tx_timeout = netx_eth_timeout; + ndev->watchdog_timeo = msecs_to_jiffies(5000); + ndev->get_stats = netx_eth_query_statistics; + ndev->set_multicast_list = netx_eth_set_multicast_list; + + priv->msg_enable = NETIF_MSG_LINK; + priv->mii.phy_id_mask = 0x1f; + priv->mii.reg_num_mask = 0x1f; + priv->mii.force_media = 0; + priv->mii.full_duplex = 0; + priv->mii.dev = ndev; + priv->mii.mdio_read = netx_eth_phy_read; + priv->mii.mdio_write = netx_eth_phy_write; + priv->mii.phy_id = INTERNAL_PHY_ADR + priv->id; + + running = xc_running(priv->xc); + xc_stop(priv->xc); + + /* if the xc engine is already running, assume the bootloader has + * loaded the firmware for us + */ + if (running) { + /* get Node Address from hardware */ + mac4321 = readl(priv->xpec_base + + NETX_XPEC_RAM_START_OFS + ETH_MAC_4321); + mac65 = readl(priv->xpec_base + + NETX_XPEC_RAM_START_OFS + ETH_MAC_65); + + ndev->dev_addr[0] = mac4321 & 0xff; + ndev->dev_addr[1] = (mac4321 >> 8) & 0xff; + ndev->dev_addr[2] = (mac4321 >> 16) & 0xff; + ndev->dev_addr[3] = (mac4321 >> 24) & 0xff; + ndev->dev_addr[4] = mac65 & 0xff; + ndev->dev_addr[5] = (mac65 >> 8) & 0xff; + } else { + if (xc_request_firmware(priv->xc)) { + printk(CARDNAME ": requesting firmware failed\n"); + return -ENODEV; + } + } + + xc_reset(priv->xc); + xc_start(priv->xc); + + if (!is_valid_ether_addr(ndev->dev_addr)) + printk("%s: Invalid ethernet MAC address. Please " + "set using ifconfig\n", ndev->name); + + for (i=2; i<=18; i++) + pfifo_push(EMPTY_PTR_FIFO(priv->id), + FIFO_PTR_FRAMENO(i) | FIFO_PTR_SEGMENT(priv->id)); + + return register_netdev(ndev); + +} + +static int netx_eth_drv_probe(struct platform_device *pdev) +{ + struct netx_eth_priv *priv; + struct net_device *ndev; + struct netxeth_platform_data *pdata; + int ret; + + ndev = alloc_etherdev(sizeof (struct netx_eth_priv)); + if (!ndev) { + printk("%s: could not allocate device.\n", CARDNAME); + ret = -ENOMEM; + goto exit; + } + SET_MODULE_OWNER(ndev); + SET_NETDEV_DEV(ndev, &pdev->dev); + + platform_set_drvdata(pdev, ndev); + + priv = netdev_priv(ndev); + + pdata = (struct netxeth_platform_data *)pdev->dev.platform_data; + priv->xc = request_xc(pdata->xcno, &pdev->dev); + if (!priv->xc) { + dev_err(&pdev->dev, "unable to request xc engine\n"); + ret = -ENODEV; + goto exit_free_netdev; + } + + ndev->irq = priv->xc->irq; + priv->id = pdev->id; + priv->xpec_base = priv->xc->xpec_base; + priv->xmac_base = priv->xc->xmac_base; + priv->sram_base = priv->xc->sram_base; + + ret = pfifo_request(PFIFO_MASK(priv->id)); + if (ret) { + printk("unable to request PFIFO\n"); + goto exit_free_xc; + } + + ret = netx_eth_enable(ndev); + if (ret) + goto exit_free_pfifo; + + return 0; +exit_free_pfifo: + pfifo_free(PFIFO_MASK(priv->id)); +exit_free_xc: + free_xc(priv->xc); +exit_free_netdev: + platform_set_drvdata(pdev, NULL); + free_netdev(ndev); +exit: + return ret; +} + +static int netx_eth_drv_remove(struct platform_device *pdev) +{ + struct net_device *ndev = dev_get_drvdata(&pdev->dev); + struct netx_eth_priv *priv = netdev_priv(ndev); + + platform_set_drvdata(pdev, NULL); + + unregister_netdev(ndev); + xc_stop(priv->xc); + free_xc(priv->xc); + free_netdev(ndev); + pfifo_free(PFIFO_MASK(priv->id)); + + return 0; +} + +static int netx_eth_drv_suspend(struct platform_device *pdev, pm_message_t state) +{ + dev_err(&pdev->dev, "suspend not implemented\n"); + return 0; +} + +static int netx_eth_drv_resume(struct platform_device *pdev) +{ + dev_err(&pdev->dev, "resume not implemented\n"); + return 0; +} + +static struct platform_driver netx_eth_driver = { + .probe = netx_eth_drv_probe, + .remove = netx_eth_drv_remove, + .suspend = netx_eth_drv_suspend, + .resume = netx_eth_drv_resume, + .driver = { + .name = CARDNAME, + .owner = THIS_MODULE, + }, +}; + +static int __init netx_eth_init(void) +{ + unsigned int phy_control, val; + + printk("NetX Ethernet driver\n"); + + phy_control = PHY_CONTROL_PHY_ADDRESS(INTERNAL_PHY_ADR>>1) | + PHY_CONTROL_PHY1_MODE(PHY_MODE_ALL) | + PHY_CONTROL_PHY1_AUTOMDIX | + PHY_CONTROL_PHY1_EN | + PHY_CONTROL_PHY0_MODE(PHY_MODE_ALL) | + PHY_CONTROL_PHY0_AUTOMDIX | + PHY_CONTROL_PHY0_EN | + PHY_CONTROL_CLK_XLATIN; + + val = readl(NETX_SYSTEM_IOC_ACCESS_KEY); + writel(val, NETX_SYSTEM_IOC_ACCESS_KEY); + + writel(phy_control | PHY_CONTROL_RESET, NETX_SYSTEM_PHY_CONTROL); + udelay(100); + + val = readl(NETX_SYSTEM_IOC_ACCESS_KEY); + writel(val, NETX_SYSTEM_IOC_ACCESS_KEY); + + writel(phy_control, NETX_SYSTEM_PHY_CONTROL); + + return platform_driver_register(&netx_eth_driver); +} + +static void __exit netx_eth_cleanup(void) +{ + platform_driver_unregister(&netx_eth_driver); +} + +module_init(netx_eth_init); +module_exit(netx_eth_cleanup); + +MODULE_AUTHOR("Sascha Hauer, Pengutronix"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 706aed7d717..70429108c40 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -96,7 +96,6 @@ //#define dprintk printk #define dprintk(x...) do { } while (0) -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/types.h> @@ -1882,7 +1881,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ dev->IMR_cache = 0; - err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ, + err = request_irq(pci_dev->irq, ns83820_irq, IRQF_SHARED, DRV_NAME, ndev); if (err) { printk(KERN_INFO "ns83820: unable to register irq %d\n", diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c index a7bb54df75a..3388ee1313e 100644 --- a/drivers/net/pci-skeleton.c +++ b/drivers/net/pci-skeleton.c @@ -85,7 +85,6 @@ IVc. Errata */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/pci.h> @@ -1076,7 +1075,7 @@ static int netdrv_open (struct net_device *dev) DPRINTK ("ENTER\n"); - retval = request_irq (dev->irq, netdrv_interrupt, SA_SHIRQ, dev->name, dev); + retval = request_irq (dev->irq, netdrv_interrupt, IRQF_SHARED, dev->name, dev); if (retval) { DPRINTK ("EXIT, returning %d\n", retval); return retval; diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 2ea66aca648..297e9f80536 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -535,7 +535,7 @@ static int axnet_open(struct net_device *dev) link->open++; - request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, "axnet_cs", dev); + request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev); info->link_status = 0x00; init_timer(&info->watchdog); diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index 441de824ab6..48434d7924e 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c @@ -387,7 +387,10 @@ static int com20020_resume(struct pcmcia_device *link) } static struct pcmcia_device_id com20020_ids[] = { - PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.", "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf), + PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.", + "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf), + PCMCIA_DEVICE_PROD_ID12("SoHard AG", + "SH ARC PCMCIA", 0xf8991729, 0x69dff0c7), PCMCIA_DEVICE_NULL }; MODULE_DEVICE_TABLE(pcmcia, com20020_ids); diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 09b11761cdf..ea93b8f1860 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -831,8 +831,7 @@ static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev) if (length < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) return 0; length = ETH_ZLEN; } diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 661bfe54ff5..0ecebfc31f0 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -998,7 +998,7 @@ static int pcnet_open(struct net_device *dev) link->open++; set_misc_reg(dev); - request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, dev_info, dev); + request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev); info->phy_id = info->eth_phy; info->link_status = 0x00; diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index e74bf5014ef..a73d5455303 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -1883,7 +1883,7 @@ static void smc_reset(struct net_device *dev) /* Set the Window 1 control, configuration and station addr registers. No point in writing the I/O base register ;-> */ SMC_SELECT_BANK(1); - /* Automatically release succesfully transmitted packets, + /* Automatically release successfully transmitted packets, Accept link errors, counter and Tx error interrupts. */ outw(CTL_AUTO_RELEASE | CTL_TE_ENABLE | CTL_CR_ENABLE, ioaddr + CONTROL); diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index 71f45056a70..9bae77ce131 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -1359,7 +1359,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev) kio_addr_t ioaddr = dev->base_addr; int okay; unsigned freespace; - unsigned pktlen = skb? skb->len : 0; + unsigned pktlen = skb->len; DEBUG(1, "do_start_xmit(skb=%p, dev=%p) len=%u\n", skb, dev, pktlen); @@ -1374,8 +1374,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev) */ if (pktlen < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) return 0; pktlen = ETH_ZLEN; } diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index fc08c4af506..d768f3d1ac2 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -309,12 +309,6 @@ static int pcnet32_alloc_ring(struct net_device *dev, char *name); static void pcnet32_free_ring(struct net_device *dev); static void pcnet32_check_media(struct net_device *dev, int verbose); -enum pci_flags_bit { - PCI_USES_IO = 1, PCI_USES_MEM = 2, PCI_USES_MASTER = 4, - PCI_ADDR0 = 0x10 << 0, PCI_ADDR1 = 0x10 << 1, PCI_ADDR2 = - 0x10 << 2, PCI_ADDR3 = 0x10 << 3, -}; - static u16 pcnet32_wio_read_csr(unsigned long addr, int index) { outw(index, addr + PCNET32_WIO_RAP); @@ -1547,7 +1541,7 @@ static int pcnet32_open(struct net_device *dev) unsigned long flags; if (request_irq(dev->irq, &pcnet32_interrupt, - lp->shared_irq ? SA_SHIRQ : 0, dev->name, + lp->shared_irq ? IRQF_SHARED : 0, dev->name, (void *)dev)) { return -EAGAIN; } diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index cda3e53d691..2ba6d3a40e2 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -44,6 +44,11 @@ config CICADA_PHY depends on PHYLIB ---help--- Currently supports the cis8204 +config VITESSE_PHY + tristate "Drivers for the Vitesse PHYs" + depends on PHYLIB + ---help--- + Currently supports the vsc8244 config SMSC_PHY tristate "Drivers for SMSC PHYs" diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index d9614134cc0..a00e6194252 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_CICADA_PHY) += cicada.o obj-$(CONFIG_LXT_PHY) += lxt.o obj-$(CONFIG_QSEMI_PHY) += qsemi.o obj-$(CONFIG_SMSC_PHY) += smsc.o +obj-$(CONFIG_VITESSE_PHY) += vitesse.o diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c index 7d8d534255c..3efb715c28d 100644 --- a/drivers/net/phy/cicada.c +++ b/drivers/net/phy/cicada.c @@ -13,7 +13,6 @@ * option) any later version. * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c index 5e9002e444c..aa7983f5583 100644 --- a/drivers/net/phy/davicom.c +++ b/drivers/net/phy/davicom.c @@ -13,7 +13,6 @@ * option) any later version. * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c index bef79e454c3..69d2325f848 100644 --- a/drivers/net/phy/lxt.c +++ b/drivers/net/phy/lxt.c @@ -13,7 +13,6 @@ * option) any later version. * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> @@ -123,9 +122,9 @@ static int lxt971_config_intr(struct phy_device *phydev) } static struct phy_driver lxt970_driver = { - .phy_id = 0x07810000, + .phy_id = 0x78100000, .name = "LXT970", - .phy_id_mask = 0x0fffffff, + .phy_id_mask = 0xfffffff0, .features = PHY_BASIC_FEATURES, .flags = PHY_HAS_INTERRUPT, .config_init = lxt970_config_init, @@ -137,9 +136,9 @@ static struct phy_driver lxt970_driver = { }; static struct phy_driver lxt971_driver = { - .phy_id = 0x0001378e, + .phy_id = 0x001378e0, .name = "LXT971", - .phy_id_mask = 0x0fffffff, + .phy_id_mask = 0xfffffff0, .features = PHY_BASIC_FEATURES, .flags = PHY_HAS_INTERRUPT, .config_aneg = genphy_config_aneg, diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index a2d6386d13b..0ad253282d0 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -13,7 +13,6 @@ * option) any later version. * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 1b236bdf6b9..1dde390c164 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -13,7 +13,6 @@ * option) any later version. * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 33cec2dab94..7d5c2233c25 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -14,7 +14,6 @@ * option) any later version. * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> @@ -557,7 +556,7 @@ int phy_start_interrupts(struct phy_device *phydev) INIT_WORK(&phydev->phy_queue, phy_change, phydev); if (request_irq(phydev->irq, phy_interrupt, - SA_SHIRQ, + IRQF_SHARED, "phy_interrupt", phydev) < 0) { printk(KERN_WARNING "%s: Can't get IRQ %d (PHY)\n", diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 7da0e3dd5fe..1bc1e032c5d 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -14,7 +14,6 @@ * option) any later version. * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> diff --git a/drivers/net/phy/qsemi.c b/drivers/net/phy/qsemi.c index 65d995b02b2..2b50e1739aa 100644 --- a/drivers/net/phy/qsemi.c +++ b/drivers/net/phy/qsemi.c @@ -13,7 +13,6 @@ * option) any later version. * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/string.h> diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c new file mode 100644 index 00000000000..ffd215d9a9b --- /dev/null +++ b/drivers/net/phy/vitesse.c @@ -0,0 +1,112 @@ +/* + * Driver for Vitesse PHYs + * + * Author: Kriston Carson + * + * Copyright (c) 2005 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/mii.h> +#include <linux/ethtool.h> +#include <linux/phy.h> + +/* Vitesse Extended Control Register 1 */ +#define MII_VSC8244_EXT_CON1 0x17 +#define MII_VSC8244_EXTCON1_INIT 0x0000 + +/* Vitesse Interrupt Mask Register */ +#define MII_VSC8244_IMASK 0x19 +#define MII_VSC8244_IMASK_IEN 0x8000 +#define MII_VSC8244_IMASK_SPEED 0x4000 +#define MII_VSC8244_IMASK_LINK 0x2000 +#define MII_VSC8244_IMASK_DUPLEX 0x1000 +#define MII_VSC8244_IMASK_MASK 0xf000 + +/* Vitesse Interrupt Status Register */ +#define MII_VSC8244_ISTAT 0x1a +#define MII_VSC8244_ISTAT_STATUS 0x8000 +#define MII_VSC8244_ISTAT_SPEED 0x4000 +#define MII_VSC8244_ISTAT_LINK 0x2000 +#define MII_VSC8244_ISTAT_DUPLEX 0x1000 + +/* Vitesse Auxiliary Control/Status Register */ +#define MII_VSC8244_AUX_CONSTAT 0x1c +#define MII_VSC8244_AUXCONSTAT_INIT 0x0004 +#define MII_VSC8244_AUXCONSTAT_DUPLEX 0x0020 +#define MII_VSC8244_AUXCONSTAT_SPEED 0x0018 +#define MII_VSC8244_AUXCONSTAT_GBIT 0x0010 +#define MII_VSC8244_AUXCONSTAT_100 0x0008 + +MODULE_DESCRIPTION("Vitesse PHY driver"); +MODULE_AUTHOR("Kriston Carson"); +MODULE_LICENSE("GPL"); + +static int vsc824x_config_init(struct phy_device *phydev) +{ + int err; + + err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT, + MII_VSC8244_AUXCONSTAT_INIT); + if (err < 0) + return err; + + err = phy_write(phydev, MII_VSC8244_EXT_CON1, + MII_VSC8244_EXTCON1_INIT); + return err; +} + +static int vsc824x_ack_interrupt(struct phy_device *phydev) +{ + int err = phy_read(phydev, MII_VSC8244_ISTAT); + + return (err < 0) ? err : 0; +} + +static int vsc824x_config_intr(struct phy_device *phydev) +{ + int err; + + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) + err = phy_write(phydev, MII_VSC8244_IMASK, + MII_VSC8244_IMASK_MASK); + else + err = phy_write(phydev, MII_VSC8244_IMASK, 0); + return err; +} + +/* Vitesse 824x */ +static struct phy_driver vsc8244_driver = { + .phy_id = 0x000fc6c2, + .name = "Vitesse VSC8244", + .phy_id_mask = 0x000fffc0, + .features = PHY_GBIT_FEATURES, + .flags = PHY_HAS_INTERRUPT, + .config_init = &vsc824x_config_init, + .config_aneg = &genphy_config_aneg, + .read_status = &genphy_read_status, + .ack_interrupt = &vsc824x_ack_interrupt, + .config_intr = &vsc824x_config_intr, + .driver = { .owner = THIS_MODULE,}, +}; + +static int __init vsc8244_init(void) +{ + return phy_driver_register(&vsc8244_driver); +} + +static void __exit vsc8244_exit(void) +{ + phy_driver_unregister(&vsc8244_driver); +} + +module_init(vsc8244_init); +module_exit(vsc8244_exit); diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 01cd8ec751e..0ec6e9d57b9 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -22,13 +22,11 @@ * ==FILEVERSION 20041108== */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/kmod.h> #include <linux/init.h> #include <linux/list.h> -#include <linux/devfs_fs_kernel.h> #include <linux/netdevice.h> #include <linux/poll.h> #include <linux/ppp_defs.h> @@ -863,10 +861,6 @@ static int __init ppp_init(void) goto out_chrdev; } class_device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp"); - err = devfs_mk_cdev(MKDEV(PPP_MAJOR, 0), - S_IFCHR|S_IRUSR|S_IWUSR, "ppp"); - if (err) - goto out_class; } out: @@ -874,9 +868,6 @@ out: printk(KERN_ERR "failed to register PPP device (%d)\n", err); return err; -out_class: - class_device_destroy(ppp_class, MKDEV(PPP_MAJOR,0)); - class_destroy(ppp_class); out_chrdev: unregister_chrdev(PPP_MAJOR, "ppp"); goto out; @@ -2578,8 +2569,7 @@ ppp_find_channel(int unit) list_for_each_entry(pch, &new_channels, list) { if (pch->file.index == unit) { - list_del(&pch->list); - list_add(&pch->list, &all_channels); + list_move(&pch->list, &all_channels); return pch; } } @@ -2682,7 +2672,6 @@ static void __exit ppp_cleanup(void) cardmap_destroy(&all_ppp_units); if (unregister_chrdev(PPP_MAJOR, "ppp") != 0) printk(KERN_ERR "PPP: failed to unregister PPP device\n"); - devfs_remove("ppp"); class_device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); class_destroy(ppp_class); } diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c index 1985d1b57c4..51ff9a9d1bb 100644 --- a/drivers/net/ppp_mppe.c +++ b/drivers/net/ppp_mppe.c @@ -43,7 +43,6 @@ * deprecated in 2.6 */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/version.h> diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 9945cc6b8d9..16a0ef1b136 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1726,7 +1726,7 @@ static int rtl8169_open(struct net_device *dev) rtl8169_set_rxbufsize(tp, dev); retval = - request_irq(dev->irq, rtl8169_interrupt, SA_SHIRQ, dev->name, dev); + request_irq(dev->irq, rtl8169_interrupt, IRQF_SHARED, dev->name, dev); if (retval < 0) goto out; @@ -2172,7 +2172,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev) { if (dev->features & NETIF_F_TSO) { - u32 mss = skb_shinfo(skb)->tso_size; + u32 mss = skb_shinfo(skb)->gso_size; if (mss) return LargeSend | ((mss & MSSMask) << MSSShift); @@ -2222,8 +2222,7 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev) len = skb->len; if (unlikely(len < ETH_ZLEN)) { - skb = skb_padto(skb, ETH_ZLEN); - if (!skb) + if (skb_padto(skb, ETH_ZLEN)) goto err_update_stats; len = ETH_ZLEN; } diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 19c2df9c86f..c3ed734cbe3 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -28,7 +28,6 @@ #define RX_DMA_SKBUFF 1 #define PKT_COPY_THRESHOLD 512 -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/errno.h> @@ -1253,7 +1252,7 @@ static int rr_open(struct net_device *dev) readl(®s->HostCtrl); spin_unlock_irqrestore(&rrpriv->lock, flags); - if (request_irq(dev->irq, rr_interrupt, SA_SHIRQ, dev->name, dev)) { + if (request_irq(dev->irq, rr_interrupt, IRQF_SHARED, dev->name, dev)) { printk(KERN_WARNING "%s: Requested IRQ %d is busy\n", dev->name, dev->irq); ecode = -EAGAIN; diff --git a/drivers/net/rrunner.h b/drivers/net/rrunner.h index 10baae55953..2c3c91ebd99 100644 --- a/drivers/net/rrunner.h +++ b/drivers/net/rrunner.h @@ -1,7 +1,6 @@ #ifndef _RRUNNER_H_ #define _RRUNNER_H_ -#include <linux/config.h> #include <linux/interrupt.h> #if ((BITS_PER_LONG != 32) && (BITS_PER_LONG != 64)) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index cac9fdd2e1d..c6b77acb35e 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -44,7 +44,6 @@ * aggregated as a single large packet ************************************************************************/ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/errno.h> @@ -2627,6 +2626,50 @@ no_rx: #endif /** + * s2io_netpoll - Rx interrupt service handler for netpoll support + * @dev : pointer to the device structure. + * Description: + * Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routine is executing. + */ + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void s2io_netpoll(struct net_device *dev) +{ + nic_t *nic = dev->priv; + mac_info_t *mac_control; + struct config_param *config; + XENA_dev_config_t __iomem *bar0 = nic->bar0; + u64 val64; + int i; + + disable_irq(dev->irq); + + atomic_inc(&nic->isr_cnt); + mac_control = &nic->mac_control; + config = &nic->config; + + val64 = readq(&bar0->rx_traffic_int); + writeq(val64, &bar0->rx_traffic_int); + + for (i = 0; i < config->rx_ring_num; i++) + rx_intr_handler(&mac_control->rings[i]); + + for (i = 0; i < config->rx_ring_num; i++) { + if (fill_rx_buffers(nic, i) == -ENOMEM) { + DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name); + DBG_PRINT(ERR_DBG, " in Rx Netpoll!!\n"); + break; + } + } + atomic_dec(&nic->isr_cnt); + enable_irq(dev->irq); + return; +} +#endif + +/** * rx_intr_handler - Rx interrupt handler * @nic: device private variable. * Description: @@ -3718,7 +3761,7 @@ static int s2io_open(struct net_device *dev) /* After proper initialization of H/W, register ISR */ if (sp->intr_type == MSI) { err = request_irq((int) sp->pdev->irq, s2io_msi_handle, - SA_SHIRQ, sp->name, dev); + IRQF_SHARED, sp->name, dev); if (err) { DBG_PRINT(ERR_DBG, "%s: MSI registration \ failed\n", dev->name); @@ -3756,7 +3799,7 @@ failed\n", dev->name, i); } } if (sp->intr_type == INTA) { - err = request_irq((int) sp->pdev->irq, s2io_isr, SA_SHIRQ, + err = request_irq((int) sp->pdev->irq, s2io_isr, IRQF_SHARED, sp->name, dev); if (err) { DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n", @@ -3915,8 +3958,8 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Control_1 = 0; txdp->Control_2 = 0; #ifdef NETIF_F_TSO - mss = skb_shinfo(skb)->tso_size; - if (mss) { + mss = skb_shinfo(skb)->gso_size; + if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { txdp->Control_1 |= TXD_TCP_LSO_EN; txdp->Control_1 |= TXD_TCP_LSO_MSS(mss); } @@ -3936,10 +3979,10 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) } frg_len = skb->len - skb->data_len; - if (skb_shinfo(skb)->ufo_size) { + if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) { int ufo_size; - ufo_size = skb_shinfo(skb)->ufo_size; + ufo_size = skb_shinfo(skb)->gso_size; ufo_size &= ~7; txdp->Control_1 |= TXD_UFO_EN; txdp->Control_1 |= TXD_UFO_MSS(ufo_size); @@ -3965,7 +4008,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Host_Control = (unsigned long) skb; txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); - if (skb_shinfo(skb)->ufo_size) + if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) txdp->Control_1 |= TXD_UFO_EN; frg_cnt = skb_shinfo(skb)->nr_frags; @@ -3980,12 +4023,12 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) (sp->pdev, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE); txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size); - if (skb_shinfo(skb)->ufo_size) + if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) txdp->Control_1 |= TXD_UFO_EN; } txdp->Control_1 |= TXD_GATHER_CODE_LAST; - if (skb_shinfo(skb)->ufo_size) + if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) frg_cnt++; /* as Txd0 was used for inband header */ tx_fifo = mac_control->tx_FIFO_start[queue]; @@ -3999,7 +4042,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) if (mss) val64 |= TX_FIFO_SPECIAL_FUNC; #endif - if (skb_shinfo(skb)->ufo_size) + if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) val64 |= TX_FIFO_SPECIAL_FUNC; writeq(val64, &tx_fifo->List_Control); @@ -6967,12 +7010,19 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) dev->weight = 32; #endif +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = s2io_netpoll; +#endif + dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; if (sp->high_dma_flag == TRUE) dev->features |= NETIF_F_HIGHDMA; #ifdef NETIF_F_TSO dev->features |= NETIF_F_TSO; #endif +#ifdef NETIF_F_TSO6 + dev->features |= NETIF_F_TSO6; +#endif if (sp->device_type & XFRAME_II_DEVICE) { dev->features |= NETIF_F_UFO; dev->features |= NETIF_F_HW_CSUM; diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 3203732a668..c43f5217970 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -652,7 +652,7 @@ typedef struct fifo_info { nic_t *nic; }fifo_info_t; -/* Infomation related to the Tx and Rx FIFOs and Rings of Xena +/* Information related to the Tx and Rx FIFOs and Rings of Xena * is maintained in this structure. */ typedef struct mac_info { diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index f2be9f83f09..9ab1618e82a 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -31,7 +31,6 @@ #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/init.h> -#include <linux/config.h> #include <linux/bitops.h> #include <asm/processor.h> /* Processor type for cache alignment. */ #include <asm/io.h> @@ -2451,7 +2450,7 @@ static int sbmac_open(struct net_device *dev) */ __raw_readq(sc->sbm_isr); - if (request_irq(dev->irq, &sbmac_intr, SA_SHIRQ, dev->name, dev)) + if (request_irq(dev->irq, &sbmac_intr, IRQF_SHARED, dev->name, dev)) return -EBUSY; /* diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c index bcef03feb2f..efd0f235020 100644 --- a/drivers/net/seeq8005.c +++ b/drivers/net/seeq8005.c @@ -396,8 +396,7 @@ static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev) unsigned char *buf; if (length < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) return 0; length = ETH_ZLEN; } diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index 88e212043a4..c7832e69f17 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c @@ -69,7 +69,6 @@ * 2000/03 Andi Kleen */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fcntl.h> diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 31dd3f036fa..df0cbebb327 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c @@ -1054,7 +1054,7 @@ static int sis190_open(struct net_device *dev) sis190_request_timer(dev); - rc = request_irq(dev->irq, sis190_interrupt, SA_SHIRQ, dev->name, dev); + rc = request_irq(dev->irq, sis190_interrupt, IRQF_SHARED, dev->name, dev); if (rc < 0) goto err_release_timer_2; @@ -1156,8 +1156,7 @@ static int sis190_start_xmit(struct sk_buff *skb, struct net_device *dev) dma_addr_t mapping; if (unlikely(skb->len < ETH_ZLEN)) { - skb = skb_padto(skb, ETH_ZLEN); - if (!skb) { + if (skb_padto(skb, ETH_ZLEN)) { tp->stats.tx_dropped++; goto out; } diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index d0587417220..29ee7ffedff 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -1013,7 +1013,7 @@ sis900_open(struct net_device *net_dev) /* Equalizer workaround Rule */ sis630_set_eq(net_dev, sis_priv->chipset_rev); - ret = request_irq(net_dev->irq, &sis900_interrupt, SA_SHIRQ, + ret = request_irq(net_dev->irq, &sis900_interrupt, IRQF_SHARED, net_dev->name, net_dev); if (ret) return ret; diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c index 38a26df4095..ee62845d3ac 100644 --- a/drivers/net/sk98lin/skge.c +++ b/drivers/net/sk98lin/skge.c @@ -570,9 +570,9 @@ SK_BOOL DualNet; spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); if (pAC->GIni.GIMacsFound == 2) { - Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, "sk98lin", dev); + Ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev); } else if (pAC->GIni.GIMacsFound == 1) { - Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, + Ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED, "sk98lin", dev); } else { printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n", @@ -1525,7 +1525,7 @@ struct sk_buff *pMessage) /* pointer to send-message */ ** This is to resolve faulty padding by the HW with 0xaa bytes. */ if (BytesSend < C_LEN_ETHERNET_MINSIZE) { - if ((pMessage = skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) == NULL) { + if (skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) { spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); return 0; } @@ -5073,9 +5073,9 @@ static int skge_resume(struct pci_dev *pdev) pci_enable_device(pdev); pci_set_master(pdev); if (pAC->GIni.GIMacsFound == 2) - ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, "sk98lin", dev); + ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev); else - ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, "sk98lin", dev); + ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED, "sk98lin", dev); if (ret) { printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq); pAC->AllocFlag &= ~SK_ALLOC_IRQ; diff --git a/drivers/net/sk98lin/skvpd.c b/drivers/net/sk98lin/skvpd.c index 17786056c66..1e662aaebf8 100644 --- a/drivers/net/sk98lin/skvpd.c +++ b/drivers/net/sk98lin/skvpd.c @@ -22,7 +22,7 @@ ******************************************************************************/ /* - Please refer skvpd.txt for infomation how to include this module + Please refer skvpd.txt for information how to include this module */ static const char SysKonnectFileId[] = "@(#)$Id: skvpd.c,v 1.37 2003/01/13 10:42:45 rschmidt Exp $ (C) SK"; diff --git a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c index e5d6d95960c..799e0980193 100644 --- a/drivers/net/sk_mca.c +++ b/drivers/net/sk_mca.c @@ -824,7 +824,7 @@ static int skmca_open(struct net_device *dev) /* register resources - only necessary for IRQ */ result = request_irq(priv->realirq, irq_handler, - SA_SHIRQ | SA_SAMPLE_RANDOM, "sk_mca", dev); + IRQF_SHARED | IRQF_SAMPLE_RANDOM, "sk_mca", dev); if (result != 0) { printk("%s: failed to register irq %d\n", dev->name, dev->irq); diff --git a/drivers/net/skfp/h/sba.h b/drivers/net/skfp/h/sba.h index df716cd5784..638cf0283bc 100644 --- a/drivers/net/skfp/h/sba.h +++ b/drivers/net/skfp/h/sba.h @@ -13,7 +13,7 @@ ******************************************************************************/ /* - * Synchronous Bandwith Allocation (SBA) structs + * Synchronous Bandwidth Allocation (SBA) structs */ #ifndef _SBA_ diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index c7fb6133047..b5714a60237 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -497,7 +497,7 @@ static int skfp_open(struct net_device *dev) PRINTK(KERN_INFO "entering skfp_open\n"); /* Register IRQ - support shared interrupts by passing device ptr */ - err = request_irq(dev->irq, (void *) skfp_interrupt, SA_SHIRQ, + err = request_irq(dev->irq, (void *) skfp_interrupt, IRQF_SHARED, dev->name, dev); if (err) return err; diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 536dd1cf7f7..82200bfaa8e 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -24,7 +24,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/config.h> #include <linux/in.h> #include <linux/kernel.h> #include <linux/module.h> @@ -2310,8 +2309,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) u64 map; unsigned long flags; - skb = skb_padto(skb, ETH_ZLEN); - if (!skb) + if (skb_padto(skb, ETH_ZLEN)) return NETDEV_TX_OK; if (!spin_trylock_irqsave(&skge->tx_lock, flags)) @@ -3343,7 +3341,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, goto err_out_free_hw; } - err = request_irq(pdev->irq, skge_intr, SA_SHIRQ, DRV_NAME, hw); + err = request_irq(pdev->irq, skge_intr, IRQF_SHARED, DRV_NAME, hw); if (err) { printk(KERN_ERR PFX "%s: cannot assign irq %d\n", pci_name(pdev), pdev->irq); @@ -3355,8 +3353,8 @@ static int __devinit skge_probe(struct pci_dev *pdev, if (err) goto err_out_free_irq; - printk(KERN_INFO PFX DRV_VERSION " addr 0x%lx irq %d chip %s rev %d\n", - pci_resource_start(pdev, 0), pdev->irq, + printk(KERN_INFO PFX DRV_VERSION " addr 0x%llx irq %d chip %s rev %d\n", + (unsigned long long)pci_resource_start(pdev, 0), pdev->irq, skge_board_name(hw), hw->chip_rev); if ((dev = skge_devinit(hw, 0, using_dac)) == NULL) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index fba1e4d4d83..418f169a6a3 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -23,7 +23,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/config.h> #include <linux/crc32.h> #include <linux/kernel.h> #include <linux/version.h> @@ -1160,7 +1159,7 @@ static unsigned tx_le_req(const struct sk_buff *skb) count = sizeof(dma_addr_t) / sizeof(u32); count += skb_shinfo(skb)->nr_frags * count; - if (skb_shinfo(skb)->tso_size) + if (skb_shinfo(skb)->gso_size) ++count; if (skb->ip_summed == CHECKSUM_HW) @@ -1232,7 +1231,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) } /* Check for TCP Segmentation Offload */ - mss = skb_shinfo(skb)->tso_size; + mss = skb_shinfo(skb)->gso_size; if (mss != 0) { /* just drop the packet if non-linear expansion fails */ if (skb_header_cloned(skb) && @@ -3189,7 +3188,7 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW); - err = request_irq(pdev->irq, sky2_test_intr, SA_SHIRQ, DRV_NAME, hw); + err = request_irq(pdev->irq, sky2_test_intr, IRQF_SHARED, DRV_NAME, hw); if (err) { printk(KERN_ERR PFX "%s: cannot assign irq %d\n", pci_name(pdev), pdev->irq); @@ -3311,9 +3310,9 @@ static int __devinit sky2_probe(struct pci_dev *pdev, if (err) goto err_out_iounmap; - printk(KERN_INFO PFX "v%s addr 0x%lx irq %d Yukon-%s (0x%x) rev %d\n", - DRV_VERSION, pci_resource_start(pdev, 0), pdev->irq, - yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], + printk(KERN_INFO PFX "v%s addr 0x%llx irq %d Yukon-%s (0x%x) rev %d\n", + DRV_VERSION, (unsigned long long)pci_resource_start(pdev, 0), + pdev->irq, yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], hw->chip_id, hw->chip_rev); dev = sky2_init_netdev(hw, 0, using_dac); @@ -3349,7 +3348,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, goto err_out_unregister; } - err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw); + err = request_irq(pdev->irq, sky2_intr, IRQF_SHARED, DRV_NAME, hw); if (err) { printk(KERN_ERR PFX "%s: cannot assign irq %d\n", pci_name(pdev), pdev->irq); diff --git a/drivers/net/slhc.c b/drivers/net/slhc.c index c6fbb1ede0e..3a1b7131681 100644 --- a/drivers/net/slhc.c +++ b/drivers/net/slhc.c @@ -50,7 +50,6 @@ * driver code belonging close to PPP and SLIP */ -#include <linux/config.h> #include <linux/module.h> #include <linux/types.h> #include <linux/string.h> diff --git a/drivers/net/slip.c b/drivers/net/slip.c index b2e18d28850..1588cb7f6c8 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -55,7 +55,6 @@ */ #define SL_CHECK_TRANSMIT -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> diff --git a/drivers/net/slip.h b/drivers/net/slip.h index ab3efe66a64..29d87dd45a2 100644 --- a/drivers/net/slip.h +++ b/drivers/net/slip.h @@ -22,7 +22,6 @@ #ifndef _LINUX_SLIP_H #define _LINUX_SLIP_H -#include <linux/config.h> #if defined(CONFIG_INET) && defined(CONFIG_SLIP_COMPRESSED) # define SL_INCLUDE_CSLIP diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c index 5b4e8529d4a..45449353a95 100644 --- a/drivers/net/smc-ultra.c +++ b/drivers/net/smc-ultra.c @@ -57,7 +57,6 @@ static const char version[] = "smc-ultra.c:v2.02 2/3/98 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/net/smc-ultra32.c b/drivers/net/smc-ultra32.c index ff9bd97746d..85be22a0597 100644 --- a/drivers/net/smc-ultra32.c +++ b/drivers/net/smc-ultra32.c @@ -290,7 +290,7 @@ out: static int ultra32_open(struct net_device *dev) { int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* ASIC addr */ - int irq_flags = (inb(ioaddr + ULTRA32_CFG5) & 0x08) ? 0 : SA_SHIRQ; + int irq_flags = (inb(ioaddr + ULTRA32_CFG5) & 0x08) ? 0 : IRQF_SHARED; int retval; retval = request_irq(dev->irq, ei_interrupt, irq_flags, dev->name, dev); diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index bdd8702ead5..d37bd860b33 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -2081,7 +2081,7 @@ static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr) lp->ctl_rspeed = 100; /* Grab the IRQ */ - retval = request_irq(dev->irq, &smc911x_interrupt, SA_SHIRQ, dev->name, dev); + retval = request_irq(dev->irq, &smc911x_interrupt, IRQF_SHARED, dev->name, dev); if (retval) goto err_out; diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c index 6cf16f322ad..8b0321f1976 100644 --- a/drivers/net/smc9194.c +++ b/drivers/net/smc9194.c @@ -523,8 +523,7 @@ static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * de length = skb->len; if (length < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) { + if (skb_padto(skb, ETH_ZLEN)) { netif_wake_queue(dev); return 0; } diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 0e9833adf9f..3d8dcb6c875 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -66,7 +66,6 @@ static const char version[] = #endif -#include <linux/config.h> #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index f72a4f57905..b4028049ed7 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -207,7 +207,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) machine_is_omap_h2() \ || machine_is_omap_h3() \ || (machine_is_omap_innovator() && !cpu_is_omap1510()) \ - ) ? SA_TRIGGER_FALLING : SA_TRIGGER_RISING) + ) ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING) #elif defined(CONFIG_SH_SH4202_MICRODEV) @@ -260,15 +260,17 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define RPC_LSA_DEFAULT RPC_LED_TX_RX #define RPC_LSB_DEFAULT RPC_LED_100_10 -#elif defined(CONFIG_MACH_LPD7A400) || defined(CONFIG_MACH_LPD7A404) +#elif defined(CONFIG_MACH_LPD79520) \ + || defined(CONFIG_MACH_LPD7A400) \ + || defined(CONFIG_MACH_LPD7A404) -/* The LPD7A40X_IOBARRIER is necessary to overcome a mismatch between - * the way that the CPU handles chip selects and the way that the SMC - * chip expects the chip select to operate. Refer to +/* The LPD7X_IOBARRIER is necessary to overcome a mismatch between the + * way that the CPU handles chip selects and the way that the SMC chip + * expects the chip select to operate. Refer to * Documentation/arm/Sharp-LH/IOBarrier for details. The read from - * IOBARRIER is a byte as a least-common denominator of possible - * regions to use as the barrier. It would be wasteful to read 32 - * bits from a byte oriented region. + * IOBARRIER is a byte, in order that we read the least-common + * denominator. It would be wasteful to read 32 bits from an 8-bit + * accessible region. * * There is no explicit protection against interrupts intervening * between the writew and the IOBARRIER. In SMC ISR there is a @@ -287,25 +289,35 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define SMC_CAN_USE_16BIT 1 #define SMC_CAN_USE_32BIT 0 #define SMC_NOWAIT 0 -#define LPD7A40X_IOBARRIER readb (IOBARRIER_VIRT) +#define LPD7X_IOBARRIER readb (IOBARRIER_VIRT) -#define SMC_inw(a,r) readw ((void*) ((a) + (r))) -#define SMC_insw(a,r,p,l) readsw ((void*) ((a) + (r)), p, l) -#define SMC_outw(v,a,r) ({ writew ((v), (a) + (r)); LPD7A40X_IOBARRIER; }) +#define SMC_inw(a,r)\ + ({ unsigned short v = readw ((void*) ((a) + (r))); LPD7X_IOBARRIER; v; }) +#define SMC_outw(v,a,r) ({ writew ((v), (a) + (r)); LPD7X_IOBARRIER; }) -#define SMC_outsw LPD7A40X_SMC_outsw +#define SMC_insw LPD7_SMC_insw +static inline void LPD7_SMC_insw (unsigned char* a, int r, + unsigned char* p, int l) +{ + unsigned short* ps = (unsigned short*) p; + while (l-- > 0) { + *ps++ = readw (a + r); + LPD7X_IOBARRIER; + } +} -static inline void LPD7A40X_SMC_outsw(unsigned long a, int r, - unsigned char* p, int l) +#define SMC_outsw LPD7_SMC_outsw +static inline void LPD7_SMC_outsw (unsigned char* a, int r, + unsigned char* p, int l) { unsigned short* ps = (unsigned short*) p; while (l-- > 0) { writew (*ps++, a + r); - LPD7A40X_IOBARRIER; + LPD7X_IOBARRIER; } } -#define SMC_INTERRUPT_PREAMBLE LPD7A40X_IOBARRIER +#define SMC_INTERRUPT_PREAMBLE LPD7X_IOBARRIER #define RPC_LSA_DEFAULT RPC_LED_TX_RX #define RPC_LSB_DEFAULT RPC_LED_100_10 @@ -528,7 +540,7 @@ smc_pxa_dma_irq(int dma, void *dummy, struct pt_regs *regs) #endif #ifndef SMC_IRQ_FLAGS -#define SMC_IRQ_FLAGS SA_TRIGGER_RISING +#define SMC_IRQ_FLAGS IRQF_TRIGGER_RISING #endif #ifndef SMC_INTERRUPT_PREAMBLE diff --git a/drivers/net/sonic.c b/drivers/net/sonic.c index 90b818a8de6..cab0dd95849 100644 --- a/drivers/net/sonic.c +++ b/drivers/net/sonic.c @@ -231,8 +231,7 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) length = skb->len; if (length < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) return 0; length = ETH_ZLEN; } diff --git a/drivers/net/sonic.h b/drivers/net/sonic.h index cede969a8ba..7f5c4ebcc17 100644 --- a/drivers/net/sonic.h +++ b/drivers/net/sonic.h @@ -22,7 +22,6 @@ #ifndef SONIC_H #define SONIC_H -#include <linux/config.h> /* * SONIC register offsets diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 394339d5e87..fb1d5a8a45c 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -21,7 +21,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/config.h> #include <linux/compiler.h> #include <linux/crc32.h> #include <linux/delay.h> @@ -1745,7 +1744,7 @@ spider_net_open(struct net_device *netdev) result = -EBUSY; if (request_irq(netdev->irq, spider_net_interrupt, - SA_SHIRQ, netdev->name, netdev)) + IRQF_SHARED, netdev->name, netdev)) goto register_int_failed; spider_net_enable_card(card); diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 9b7805be21d..ed1f59901ff 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -146,7 +146,6 @@ TODO: - fix forced speed/duplexing code (broken a long time ago, when #define DRV_VERSION "1.03+LK1.4.2.1" #define DRV_RELDATE "October 3, 2005" -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/pci.h> @@ -1071,7 +1070,7 @@ static int netdev_open(struct net_device *dev) /* Do we ever need to reset the chip??? */ - retval = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev); + retval = request_irq(dev->irq, &intr_handler, IRQF_SHARED, dev->name, dev); if (retval) return retval; @@ -1349,8 +1348,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) #if defined(ZEROCOPY) && defined(HAS_BROKEN_FIRMWARE) if (skb->ip_summed == CHECKSUM_HW) { - skb = skb_padto(skb, (skb->len + PADDING_MASK) & ~PADDING_MASK); - if (skb == NULL) + if (skb_padto(skb, (skb->len + PADDING_MASK) & ~PADDING_MASK)) return NETDEV_TX_OK; } #endif /* ZEROCOPY && HAS_BROKEN_FIRMWARE */ diff --git a/drivers/net/stnic.c b/drivers/net/stnic.c index b6dfdf8f44d..74228348995 100644 --- a/drivers/net/stnic.c +++ b/drivers/net/stnic.c @@ -7,7 +7,6 @@ * Copyright (C) 1999 kaz Kojima */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index d4c0002b43d..2dcadb169a2 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c @@ -55,7 +55,7 @@ static char *version = "sun3lance.c: v1.2 1/12/2001 Sam Creasey (sammy@sammy.ne /* sun3/60 addr/irq for the lance chip. If your sun is different, change this. */ #define LANCE_OBIO 0x120000 -#define LANCE_IRQ IRQ3 +#define LANCE_IRQ IRQ_AUTO_3 /* Debug level: * 0 = silent, print only serious errors @@ -341,7 +341,7 @@ static int __init lance_probe( struct net_device *dev) REGA(CSR0) = CSR0_STOP; - request_irq(LANCE_IRQ, lance_interrupt, SA_INTERRUPT, "SUN3 Lance", dev); + request_irq(LANCE_IRQ, lance_interrupt, IRQF_DISABLED, "SUN3 Lance", dev); dev->irq = (unsigned short)LANCE_IRQ; diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index cfaf47c63c5..d4689151076 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -72,8 +72,6 @@ MODULE_LICENSE("GPL"); #define DIRQ(x) #endif -static struct bigmac *root_bigmac_dev; - #define DEFAULT_JAMSIZE 4 /* Toe jam */ #define QEC_RESET_TRIES 200 @@ -491,7 +489,7 @@ static void bigmac_tcvr_init(struct bigmac *bp) } } -static int bigmac_init(struct bigmac *, int); +static int bigmac_init_hw(struct bigmac *, int); static int try_next_permutation(struct bigmac *bp, void __iomem *tregs) { @@ -551,7 +549,7 @@ static void bigmac_timer(unsigned long data) if (ret == -1) { printk(KERN_ERR "%s: Link down, cable problem?\n", bp->dev->name); - ret = bigmac_init(bp, 0); + ret = bigmac_init_hw(bp, 0); if (ret) { printk(KERN_ERR "%s: Error, cannot re-init the " "BigMAC.\n", bp->dev->name); @@ -621,7 +619,7 @@ static void bigmac_begin_auto_negotiation(struct bigmac *bp) add_timer(&bp->bigmac_timer); } -static int bigmac_init(struct bigmac *bp, int from_irq) +static int bigmac_init_hw(struct bigmac *bp, int from_irq) { void __iomem *gregs = bp->gregs; void __iomem *cregs = bp->creg; @@ -752,7 +750,7 @@ static void bigmac_is_medium_rare(struct bigmac *bp, u32 qec_status, u32 bmac_st } printk(" RESET\n"); - bigmac_init(bp, 1); + bigmac_init_hw(bp, 1); } /* BigMAC transmit complete service routines. */ @@ -920,13 +918,13 @@ static int bigmac_open(struct net_device *dev) struct bigmac *bp = (struct bigmac *) dev->priv; int ret; - ret = request_irq(dev->irq, &bigmac_interrupt, SA_SHIRQ, dev->name, bp); + ret = request_irq(dev->irq, &bigmac_interrupt, IRQF_SHARED, dev->name, bp); if (ret) { printk(KERN_ERR "BIGMAC: Can't order irq %d to go.\n", dev->irq); return ret; } init_timer(&bp->bigmac_timer); - ret = bigmac_init(bp, 0); + ret = bigmac_init_hw(bp, 0); if (ret) free_irq(dev->irq, bp); return ret; @@ -950,7 +948,7 @@ static void bigmac_tx_timeout(struct net_device *dev) { struct bigmac *bp = (struct bigmac *) dev->priv; - bigmac_init(bp, 0); + bigmac_init_hw(bp, 0); netif_wake_queue(dev); } @@ -1104,6 +1102,8 @@ static int __init bigmac_ether_init(struct sbus_dev *qec_sdev) bp->qec_sdev = qec_sdev; bp->bigmac_sdev = qec_sdev->child; + SET_NETDEV_DEV(dev, &bp->bigmac_sdev->ofdev.dev); + spin_lock_init(&bp->lock); /* Verify the registers we expect, are actually there. */ @@ -1226,11 +1226,7 @@ static int __init bigmac_ether_init(struct sbus_dev *qec_sdev) goto fail_and_cleanup; } - /* Put us into the list of instances attached for later driver - * exit. - */ - bp->next_module = root_bigmac_dev; - root_bigmac_dev = bp; + dev_set_drvdata(&bp->bigmac_sdev->ofdev.dev, bp); printk(KERN_INFO "%s: BigMAC 100baseT Ethernet ", dev->name); for (i = 0; i < 6; i++) @@ -1266,69 +1262,68 @@ fail_and_cleanup: /* QEC can be the parent of either QuadEthernet or * a BigMAC. We want the latter. */ -static int __init bigmac_match(struct sbus_dev *sdev) +static int __devinit bigmac_sbus_probe(struct of_device *dev, const struct of_device_id *match) { - struct sbus_dev *child = sdev->child; + struct sbus_dev *sdev = to_sbus_device(&dev->dev); + struct device_node *dp = dev->node; - if (strcmp(sdev->prom_name, "qec") != 0) - return 0; + if (!strcmp(dp->name, "be")) + sdev = sdev->parent; - if (child == NULL) - return 0; - - if (strcmp(child->prom_name, "be") != 0) - return 0; - - return 1; + return bigmac_ether_init(sdev); } -static int __init bigmac_probe(void) +static int __devexit bigmac_sbus_remove(struct of_device *dev) { - struct sbus_bus *sbus; - struct sbus_dev *sdev = NULL; - static int called; - int cards = 0, v; - - root_bigmac_dev = NULL; - - if (called) - return -ENODEV; - called++; - - for_each_sbus(sbus) { - for_each_sbusdev(sdev, sbus) { - if (bigmac_match(sdev)) { - cards++; - if ((v = bigmac_ether_init(sdev))) - return v; - } - } - } - if (!cards) - return -ENODEV; + struct bigmac *bp = dev_get_drvdata(&dev->dev); + struct net_device *net_dev = bp->dev; + + unregister_netdevice(net_dev); + + sbus_iounmap(bp->gregs, GLOB_REG_SIZE); + sbus_iounmap(bp->creg, CREG_REG_SIZE); + sbus_iounmap(bp->bregs, BMAC_REG_SIZE); + sbus_iounmap(bp->tregs, TCVR_REG_SIZE); + sbus_free_consistent(bp->bigmac_sdev, + PAGE_SIZE, + bp->bmac_block, + bp->bblock_dvma); + + free_netdev(net_dev); + + dev_set_drvdata(&dev->dev, NULL); + return 0; } -static void __exit bigmac_cleanup(void) -{ - while (root_bigmac_dev) { - struct bigmac *bp = root_bigmac_dev; - struct bigmac *bp_nxt = root_bigmac_dev->next_module; +static struct of_device_id bigmac_sbus_match[] = { + { + .name = "qec", + }, + { + .name = "be", + }, + {}, +}; - sbus_iounmap(bp->gregs, GLOB_REG_SIZE); - sbus_iounmap(bp->creg, CREG_REG_SIZE); - sbus_iounmap(bp->bregs, BMAC_REG_SIZE); - sbus_iounmap(bp->tregs, TCVR_REG_SIZE); - sbus_free_consistent(bp->bigmac_sdev, - PAGE_SIZE, - bp->bmac_block, - bp->bblock_dvma); +MODULE_DEVICE_TABLE(of, bigmac_sbus_match); - unregister_netdev(bp->dev); - free_netdev(bp->dev); - root_bigmac_dev = bp_nxt; - } +static struct of_platform_driver bigmac_sbus_driver = { + .name = "sunbmac", + .match_table = bigmac_sbus_match, + .probe = bigmac_sbus_probe, + .remove = __devexit_p(bigmac_sbus_remove), +}; + +static int __init bigmac_init(void) +{ + return of_register_driver(&bigmac_sbus_driver, &sbus_bus_type); +} + +static void __exit bigmac_exit(void) +{ + of_unregister_driver(&bigmac_sbus_driver); } -module_init(bigmac_probe); -module_exit(bigmac_cleanup); +module_init(bigmac_init); +module_exit(bigmac_exit); diff --git a/drivers/net/sunbmac.h b/drivers/net/sunbmac.h index b0dbc518714..b563d3c2993 100644 --- a/drivers/net/sunbmac.h +++ b/drivers/net/sunbmac.h @@ -332,7 +332,6 @@ struct bigmac { struct sbus_dev *qec_sdev; struct sbus_dev *bigmac_sdev; struct net_device *dev; - struct bigmac *next_module; }; /* We use this to acquire receive skb's that we can DMA directly into. */ diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 61eec46cb11..643fceae3db 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -94,11 +94,13 @@ Version LK1.10 (Philippe De Muyter phdm@macqel.be): - Make 'unblock interface after Tx underrun' work + Version LK1.11 (Pedro Alejandro Lopez-Valencia palopezv at gmail.com): + - Add support for IC Plus Corporation IP100A chipset */ #define DRV_NAME "sundance" -#define DRV_VERSION "1.01+LK1.10" -#define DRV_RELDATE "28-Oct-2005" +#define DRV_VERSION "1.01+LK1.11" +#define DRV_RELDATE "14-Jun-2006" /* The user-configurable values. @@ -287,6 +289,7 @@ static struct pci_device_id sundance_pci_tbl[] = { {0x1186, 0x1002, 0x1186, 0x1040, 0, 0, 3}, {0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, {0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, + {0x13F0, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6}, {0,} }; MODULE_DEVICE_TABLE(pci, sundance_pci_tbl); @@ -305,6 +308,7 @@ static const struct pci_id_info pci_id_tbl[] = { {"D-Link DFE-530TXS FAST Ethernet Adapter"}, {"D-Link DL10050-based FAST Ethernet Adapter"}, {"Sundance Technology Alta"}, + {"IC Plus Corporation IP100A FAST Ethernet Adapter"}, {NULL,}, /* 0 terminated list. */ }; @@ -866,7 +870,7 @@ static int netdev_open(struct net_device *dev) /* Do we need to reset the chip??? */ - i = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev); + i = request_irq(dev->irq, &intr_handler, IRQF_SHARED, dev->name, dev); if (i) return i; diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 38cd30cb7c7..b70bbd74897 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -2220,7 +2220,7 @@ static int gem_do_start(struct net_device *dev) spin_unlock_irqrestore(&gp->lock, flags); if (request_irq(gp->pdev->irq, gem_interrupt, - SA_SHIRQ, dev->name, (void *)dev)) { + IRQF_SHARED, dev->name, (void *)dev)) { printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name); spin_lock_irqsave(&gp->lock, flags); @@ -2880,17 +2880,20 @@ static int __devinit gem_get_device_address(struct gem *gp) #if defined(__sparc__) struct pci_dev *pdev = gp->pdev; struct pcidev_cookie *pcp = pdev->sysdata; - int node = -1; + int use_idprom = 1; if (pcp != NULL) { - node = pcp->prom_node; - if (prom_getproplen(node, "local-mac-address") == 6) - prom_getproperty(node, "local-mac-address", - dev->dev_addr, 6); - else - node = -1; + unsigned char *addr; + int len; + + addr = of_get_property(pcp->prom_node, "local-mac-address", + &len); + if (addr && len == 6) { + use_idprom = 0; + memcpy(dev->dev_addr, addr, 6); + } } - if (node == -1) + if (use_idprom) memcpy(dev->dev_addr, idprom->id_ethaddr, 6); #elif defined(CONFIG_PPC_PMAC) unsigned char *addr; diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c index 9282b4b0c02..278c7cb2221 100644 --- a/drivers/net/sungem_phy.c +++ b/drivers/net/sungem_phy.c @@ -19,7 +19,6 @@ * of darwin, still need to reverse engineer that */ -#include <linux/config.h> #include <linux/module.h> diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index 9f046cae2f7..8673fd4c08c 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -1,9 +1,9 @@ -/* $Id: sunhme.c,v 1.124 2002/01/15 06:25:51 davem Exp $ - * sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching, +/* sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching, * auto carrier detecting ethernet driver. Also known as the * "Happy Meal Ethernet" found on SunSwift SBUS cards. * - * Copyright (C) 1996, 1998, 1999, 2002, 2003 David S. Miller (davem@redhat.com) + * Copyright (C) 1996, 1998, 1999, 2002, 2003, + 2006 David S. Miller (davem@davemloft.net) * * Changes : * 2000/11/11 Willy Tarreau <willy AT meta-x.org> @@ -13,7 +13,6 @@ * argument : macaddr=0x00,0x10,0x20,0x30,0x40,0x50 */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> @@ -40,15 +39,13 @@ #include <asm/dma.h> #include <asm/byteorder.h> -#ifdef __sparc__ +#ifdef CONFIG_SPARC #include <asm/idprom.h> #include <asm/sbus.h> #include <asm/openprom.h> #include <asm/oplib.h> +#include <asm/prom.h> #include <asm/auxio.h> -#ifndef __sparc_v9__ -#include <asm/io-unit.h> -#endif #endif #include <asm/uaccess.h> @@ -57,7 +54,7 @@ #ifdef CONFIG_PCI #include <linux/pci.h> -#ifdef __sparc__ +#ifdef CONFIG_SPARC #include <asm/pbm.h> #endif #endif @@ -65,9 +62,9 @@ #include "sunhme.h" #define DRV_NAME "sunhme" -#define DRV_VERSION "2.02" -#define DRV_RELDATE "8/24/03" -#define DRV_AUTHOR "David S. Miller (davem@redhat.com)" +#define DRV_VERSION "3.00" +#define DRV_RELDATE "June 23, 2006" +#define DRV_AUTHOR "David S. Miller (davem@davemloft.net)" static char version[] = DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; @@ -83,8 +80,6 @@ static int macaddr[6]; module_param_array(macaddr, int, NULL, 0); MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set"); -static struct happy_meal *root_happy_dev; - #ifdef CONFIG_SBUS static struct quattro *qfe_sbus_list; #endif @@ -181,26 +176,6 @@ static __inline__ void tx_dump_ring(struct happy_meal *hp) #define DEFAULT_IPG2 4 /* For all modes */ #define DEFAULT_JAMSIZE 4 /* Toe jam */ -#if defined(CONFIG_PCI) && defined(MODULE) -/* This happy_pci_ids is declared __initdata because it is only used - as an advisory to depmod. If this is ported to the new PCI interface - where it could be referenced at any time due to hot plugging, - the __initdata reference should be removed. */ - -static struct pci_device_id happymeal_pci_ids[] = { - { - .vendor = PCI_VENDOR_ID_SUN, - .device = PCI_DEVICE_ID_SUN_HAPPYMEAL, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(pci, happymeal_pci_ids); - -#endif - /* NOTE: In the descriptor writes one _must_ write the address * member _first_. The card must not be allowed to see * the updated descriptor flags until the address is @@ -1610,7 +1585,7 @@ static int happy_meal_init(struct happy_meal *hp) HMD(("happy_meal_init: old[%08x] bursts<", hme_read32(hp, gregs + GREG_CFG))); -#ifndef __sparc__ +#ifndef CONFIG_SPARC /* It is always PCI and can handle 64byte bursts. */ hme_write32(hp, gregs + GREG_CFG, GREG_CFG_BURST64); #else @@ -1647,7 +1622,7 @@ static int happy_meal_init(struct happy_meal *hp) HMD(("XXX>")); hme_write32(hp, gregs + GREG_CFG, 0); } -#endif /* __sparc__ */ +#endif /* CONFIG_SPARC */ /* Turn off interrupts we do not want to hear. */ HMD((", enable global interrupts, ")); @@ -2219,15 +2194,10 @@ static int happy_meal_open(struct net_device *dev) */ if ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO) { if (request_irq(dev->irq, &happy_meal_interrupt, - SA_SHIRQ, dev->name, (void *)dev)) { + IRQF_SHARED, dev->name, (void *)dev)) { HMD(("EAGAIN\n")); -#ifdef __sparc__ - printk(KERN_ERR "happy_meal(SBUS): Can't order irq %s to go.\n", - __irq_itoa(dev->irq)); -#else printk(KERN_ERR "happy_meal(SBUS): Can't order irq %d to go.\n", dev->irq); -#endif return -EAGAIN; } @@ -2552,7 +2522,7 @@ static struct ethtool_ops hme_ethtool_ops = { static int hme_version_printed; #ifdef CONFIG_SBUS -void __init quattro_get_ranges(struct quattro *qp) +void __devinit quattro_get_ranges(struct quattro *qp) { struct sbus_dev *sdev = qp->quattro_dev; int err; @@ -2568,7 +2538,7 @@ void __init quattro_get_ranges(struct quattro *qp) qp->nranges = (err / sizeof(struct linux_prom_ranges)); } -static void __init quattro_apply_ranges(struct quattro *qp, struct happy_meal *hp) +static void __devinit quattro_apply_ranges(struct quattro *qp, struct happy_meal *hp) { struct sbus_dev *sdev = hp->happy_dev; int rng; @@ -2595,16 +2565,12 @@ static void __init quattro_apply_ranges(struct quattro *qp, struct happy_meal *h * * Return NULL on failure. */ -static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev) +static struct quattro * __devinit quattro_sbus_find(struct sbus_dev *goal_sdev) { - struct sbus_bus *sbus; struct sbus_dev *sdev; struct quattro *qp; int i; - if (qfe_sbus_list == NULL) - goto found; - for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { for (i = 0, sdev = qp->quattro_dev; (sdev != NULL) && (i < 4); @@ -2613,17 +2579,7 @@ static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev) return qp; } } - for_each_sbus(sbus) { - for_each_sbusdev(sdev, sbus) { - if (sdev == goal_sdev) - goto found; - } - } - /* Cannot find quattro parent, fail. */ - return NULL; - -found: qp = kmalloc(sizeof(struct quattro), GFP_KERNEL); if (qp != NULL) { int i; @@ -2652,7 +2608,7 @@ static void __init quattro_sbus_register_irqs(void) err = request_irq(sdev->irqs[0], quattro_sbus_interrupt, - SA_SHIRQ, "Quattro", + IRQF_SHARED, "Quattro", qp); if (err != 0) { printk(KERN_ERR "Quattro: Fatal IRQ registery error %d.\n", err); @@ -2660,6 +2616,17 @@ static void __init quattro_sbus_register_irqs(void) } } } + +static void quattro_sbus_free_irqs(void) +{ + struct quattro *qp; + + for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { + struct sbus_dev *sdev = qp->quattro_dev; + + free_irq(sdev->irqs[0], qp); + } +} #endif /* CONFIG_SBUS */ #ifdef CONFIG_PCI @@ -2694,8 +2661,9 @@ static struct quattro * __init quattro_pci_find(struct pci_dev *pdev) #endif /* CONFIG_PCI */ #ifdef CONFIG_SBUS -static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) +static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) { + struct device_node *dp = sdev->ofdev.node; struct quattro *qp = NULL; struct happy_meal *hp; struct net_device *dev; @@ -2718,6 +2686,7 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) if (!dev) goto err_out; SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &sdev->ofdev.dev); if (hme_version_printed++ == 0) printk(KERN_INFO "%s", version); @@ -2733,13 +2702,16 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) for (i = 0; i < 6; i++) dev->dev_addr[i] = macaddr[i]; macaddr[5]++; - } else if (qfe_slot != -1 && - prom_getproplen(sdev->prom_node, - "local-mac-address") == 6) { - prom_getproperty(sdev->prom_node, "local-mac-address", - dev->dev_addr, 6); } else { - memcpy(dev->dev_addr, idprom->id_ethaddr, 6); + unsigned char *addr; + int len; + + addr = of_get_property(dp, "local-mac-address", &len); + + if (qfe_slot != -1 && addr && len == 6) + memcpy(dev->dev_addr, addr, 6); + else + memcpy(dev->dev_addr, idprom->id_ethaddr, 6); } hp = dev->priv; @@ -2750,9 +2722,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) err = -ENODEV; if (sdev->num_registers != 5) { - printk(KERN_ERR "happymeal: Device does not have 5 regs, it has %d.\n", + printk(KERN_ERR "happymeal: Device needs 5 regs, has %d.\n", sdev->num_registers); - printk(KERN_ERR "happymeal: Would you like that for here or to go?\n"); goto err_out_free_netdev; } @@ -2766,39 +2737,39 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) hp->gregs = sbus_ioremap(&sdev->resource[0], 0, GREG_REG_SIZE, "HME Global Regs"); if (!hp->gregs) { - printk(KERN_ERR "happymeal: Cannot map Happy Meal global registers.\n"); + printk(KERN_ERR "happymeal: Cannot map global registers.\n"); goto err_out_free_netdev; } hp->etxregs = sbus_ioremap(&sdev->resource[1], 0, ETX_REG_SIZE, "HME TX Regs"); if (!hp->etxregs) { - printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Transmit registers.\n"); + printk(KERN_ERR "happymeal: Cannot map MAC TX registers.\n"); goto err_out_iounmap; } hp->erxregs = sbus_ioremap(&sdev->resource[2], 0, ERX_REG_SIZE, "HME RX Regs"); if (!hp->erxregs) { - printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Receive registers.\n"); + printk(KERN_ERR "happymeal: Cannot map MAC RX registers.\n"); goto err_out_iounmap; } hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0, BMAC_REG_SIZE, "HME BIGMAC Regs"); if (!hp->bigmacregs) { - printk(KERN_ERR "happymeal: Cannot map Happy Meal BIGMAC registers.\n"); + printk(KERN_ERR "happymeal: Cannot map BIGMAC registers.\n"); goto err_out_iounmap; } hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0, TCVR_REG_SIZE, "HME Tranceiver Regs"); if (!hp->tcvregs) { - printk(KERN_ERR "happymeal: Cannot map Happy Meal Tranceiver registers.\n"); + printk(KERN_ERR "happymeal: Cannot map TCVR registers.\n"); goto err_out_iounmap; } - hp->hm_revision = prom_getintdefault(sdev->prom_node, "hm-rev", 0xff); + hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff); if (hp->hm_revision == 0xff) hp->hm_revision = 0xa0; @@ -2812,8 +2783,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) hp->happy_flags |= HFLAG_QUATTRO; /* Get the supported DVMA burst sizes from our Happy SBUS. */ - hp->happy_bursts = prom_getintdefault(sdev->bus->prom_node, - "burst-sizes", 0x00); + hp->happy_bursts = of_getintprop_default(sdev->bus->ofdev.node, + "burst-sizes", 0x00); hp->happy_block = sbus_alloc_consistent(hp->happy_dev, PAGE_SIZE, @@ -2876,6 +2847,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) goto err_out_free_consistent; } + dev_set_drvdata(&sdev->ofdev.dev, hp); + if (qfe_slot != -1) printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ", dev->name, qfe_slot); @@ -2888,12 +2861,6 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) dev->dev_addr[i], i == 5 ? ' ' : ':'); printk("\n"); - /* We are home free at this point, link us in to the happy - * device list. - */ - hp->next_module = root_happy_dev; - root_happy_dev = hp; - return 0; err_out_free_consistent: @@ -2923,7 +2890,7 @@ err_out: #endif #ifdef CONFIG_PCI -#ifndef __sparc__ +#ifndef CONFIG_SPARC static int is_quattro_p(struct pci_dev *pdev) { struct pci_dev *busdev = pdev->bus->self; @@ -3011,14 +2978,14 @@ static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr) get_random_bytes(&dev_addr[3], 3); return; } -#endif /* !(__sparc__) */ +#endif /* !(CONFIG_SPARC) */ -static int __init happy_meal_pci_init(struct pci_dev *pdev) +static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) { struct quattro *qp = NULL; -#ifdef __sparc__ +#ifdef CONFIG_SPARC struct pcidev_cookie *pcp; - int node; #endif struct happy_meal *hp; struct net_device *dev; @@ -3029,15 +2996,14 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) int err; /* Now make sure pci_dev cookie is there. */ -#ifdef __sparc__ +#ifdef CONFIG_SPARC pcp = pdev->sysdata; - if (pcp == NULL || pcp->prom_node == -1) { + if (pcp == NULL) { printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n"); return -ENODEV; } - node = pcp->prom_node; - prom_getstring(node, "name", prom_name, sizeof(prom_name)); + strcpy(prom_name, pcp->prom_node->name); #else if (is_quattro_p(pdev)) strcpy(prom_name, "SUNW,qfe"); @@ -3108,11 +3074,15 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) dev->dev_addr[i] = macaddr[i]; macaddr[5]++; } else { -#ifdef __sparc__ +#ifdef CONFIG_SPARC + unsigned char *addr; + int len; + if (qfe_slot != -1 && - prom_getproplen(node, "local-mac-address") == 6) { - prom_getproperty(node, "local-mac-address", - dev->dev_addr, 6); + (addr = of_get_property(pcp->prom_node, + "local-mac-address", &len)) != NULL + && len == 6) { + memcpy(dev->dev_addr, addr, 6); } else { memcpy(dev->dev_addr, idprom->id_ethaddr, 6); } @@ -3128,8 +3098,8 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) hp->bigmacregs = (hpreg_base + 0x6000UL); hp->tcvregs = (hpreg_base + 0x7000UL); -#ifdef __sparc__ - hp->hm_revision = prom_getintdefault(node, "hm-rev", 0xff); +#ifdef CONFIG_SPARC + hp->hm_revision = of_getintprop_default(pcp->prom_node, "hm-rev", 0xff); if (hp->hm_revision == 0xff) { unsigned char prev; @@ -3153,7 +3123,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) /* And of course, indicate this is PCI. */ hp->happy_flags |= HFLAG_PCI; -#ifdef __sparc__ +#ifdef CONFIG_SPARC /* Assume PCI happy meals can handle all burst sizes. */ hp->happy_bursts = DMA_BURSTBITS; #endif @@ -3216,6 +3186,8 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) goto err_out_iounmap; } + dev_set_drvdata(&pdev->dev, hp); + if (!qfe_slot) { struct pci_dev *qpdev = qp->quattro_dev; @@ -3245,12 +3217,6 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) printk("\n"); - /* We are home free at this point, link us in to the happy - * device list. - */ - hp->next_module = root_happy_dev; - root_happy_dev = hp; - return 0; err_out_iounmap: @@ -3268,136 +3234,146 @@ err_out_clear_quattro: err_out: return err; } -#endif -#ifdef CONFIG_SBUS -static int __init happy_meal_sbus_probe(void) +static void __devexit happy_meal_pci_remove(struct pci_dev *pdev) { - struct sbus_bus *sbus; - struct sbus_dev *sdev; - int cards = 0; - char model[128]; - - for_each_sbus(sbus) { - for_each_sbusdev(sdev, sbus) { - char *name = sdev->prom_name; - - if (!strcmp(name, "SUNW,hme")) { - cards++; - prom_getstring(sdev->prom_node, "model", - model, sizeof(model)); - if (!strcmp(model, "SUNW,sbus-qfe")) - happy_meal_sbus_init(sdev, 1); - else - happy_meal_sbus_init(sdev, 0); - } else if (!strcmp(name, "qfe") || - !strcmp(name, "SUNW,qfe")) { - cards++; - happy_meal_sbus_init(sdev, 1); - } - } - } - if (cards != 0) - quattro_sbus_register_irqs(); - return cards; + struct happy_meal *hp = dev_get_drvdata(&pdev->dev); + struct net_device *net_dev = hp->dev; + + unregister_netdev(net_dev); + + pci_free_consistent(hp->happy_dev, + PAGE_SIZE, + hp->happy_block, + hp->hblock_dvma); + iounmap(hp->gregs); + pci_release_regions(hp->happy_dev); + + free_netdev(net_dev); + + dev_set_drvdata(&pdev->dev, NULL); } -#endif -#ifdef CONFIG_PCI -static int __init happy_meal_pci_probe(void) +static struct pci_device_id happymeal_pci_ids[] = { + { + .vendor = PCI_VENDOR_ID_SUN, + .device = PCI_DEVICE_ID_SUN_HAPPYMEAL, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(pci, happymeal_pci_ids); + +static struct pci_driver hme_pci_driver = { + .name = "hme", + .id_table = happymeal_pci_ids, + .probe = happy_meal_pci_probe, + .remove = __devexit_p(happy_meal_pci_remove), +}; + +static int __init happy_meal_pci_init(void) { - struct pci_dev *pdev = NULL; - int cards = 0; + return pci_module_init(&hme_pci_driver); +} - while ((pdev = pci_find_device(PCI_VENDOR_ID_SUN, - PCI_DEVICE_ID_SUN_HAPPYMEAL, pdev)) != NULL) { - if (pci_enable_device(pdev)) - continue; - pci_set_master(pdev); - cards++; - happy_meal_pci_init(pdev); +static void happy_meal_pci_exit(void) +{ + pci_unregister_driver(&hme_pci_driver); + + while (qfe_pci_list) { + struct quattro *qfe = qfe_pci_list; + struct quattro *next = qfe->next; + + kfree(qfe); + + qfe_pci_list = next; } - return cards; } + #endif -static int __init happy_meal_probe(void) +#ifdef CONFIG_SBUS +static int __devinit hme_sbus_probe(struct of_device *dev, const struct of_device_id *match) { - static int called = 0; - int cards; + struct sbus_dev *sdev = to_sbus_device(&dev->dev); + struct device_node *dp = dev->node; + char *model = of_get_property(dp, "model", NULL); + int is_qfe = (match->data != NULL); - root_happy_dev = NULL; + if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe")) + is_qfe = 1; - if (called) - return -ENODEV; - called++; + return happy_meal_sbus_probe_one(sdev, is_qfe); +} + +static int __devexit hme_sbus_remove(struct of_device *dev) +{ + struct happy_meal *hp = dev_get_drvdata(&dev->dev); + struct net_device *net_dev = hp->dev; + + unregister_netdevice(net_dev); + + /* XXX qfe parent interrupt... */ + + sbus_iounmap(hp->gregs, GREG_REG_SIZE); + sbus_iounmap(hp->etxregs, ETX_REG_SIZE); + sbus_iounmap(hp->erxregs, ERX_REG_SIZE); + sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE); + sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE); + sbus_free_consistent(hp->happy_dev, + PAGE_SIZE, + hp->happy_block, + hp->hblock_dvma); + + free_netdev(net_dev); + + dev_set_drvdata(&dev->dev, NULL); - cards = 0; -#ifdef CONFIG_SBUS - cards += happy_meal_sbus_probe(); -#endif -#ifdef CONFIG_PCI - cards += happy_meal_pci_probe(); -#endif - if (!cards) - return -ENODEV; return 0; } +static struct of_device_id hme_sbus_match[] = { + { + .name = "SUNW,hme", + }, + { + .name = "SUNW,qfe", + .data = (void *) 1, + }, + { + .name = "qfe", + .data = (void *) 1, + }, + {}, +}; -static void __exit happy_meal_cleanup_module(void) -{ -#ifdef CONFIG_SBUS - struct quattro *last_seen_qfe = NULL; -#endif +MODULE_DEVICE_TABLE(of, hme_sbus_match); - while (root_happy_dev) { - struct happy_meal *hp = root_happy_dev; - struct happy_meal *next = root_happy_dev->next_module; - struct net_device *dev = hp->dev; +static struct of_platform_driver hme_sbus_driver = { + .name = "hme", + .match_table = hme_sbus_match, + .probe = hme_sbus_probe, + .remove = __devexit_p(hme_sbus_remove), +}; - /* Unregister netdev before unmapping registers as this - * call can end up trying to access those registers. - */ - unregister_netdev(dev); +static int __init happy_meal_sbus_init(void) +{ + int err; -#ifdef CONFIG_SBUS - if (!(hp->happy_flags & HFLAG_PCI)) { - if (hp->happy_flags & HFLAG_QUATTRO) { - if (hp->qfe_parent != last_seen_qfe) { - free_irq(dev->irq, hp->qfe_parent); - last_seen_qfe = hp->qfe_parent; - } - } + err = of_register_driver(&hme_sbus_driver, &sbus_bus_type); + if (!err) + quattro_sbus_register_irqs(); - sbus_iounmap(hp->gregs, GREG_REG_SIZE); - sbus_iounmap(hp->etxregs, ETX_REG_SIZE); - sbus_iounmap(hp->erxregs, ERX_REG_SIZE); - sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE); - sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE); - sbus_free_consistent(hp->happy_dev, - PAGE_SIZE, - hp->happy_block, - hp->hblock_dvma); - } -#endif -#ifdef CONFIG_PCI - if ((hp->happy_flags & HFLAG_PCI)) { - pci_free_consistent(hp->happy_dev, - PAGE_SIZE, - hp->happy_block, - hp->hblock_dvma); - iounmap(hp->gregs); - pci_release_regions(hp->happy_dev); - } -#endif - free_netdev(dev); + return err; +} - root_happy_dev = next; - } +static void happy_meal_sbus_exit(void) +{ + of_unregister_driver(&hme_sbus_driver); + quattro_sbus_free_irqs(); - /* Now cleanup the quattro lists. */ -#ifdef CONFIG_SBUS while (qfe_sbus_list) { struct quattro *qfe = qfe_sbus_list; struct quattro *next = qfe->next; @@ -3406,18 +3382,39 @@ static void __exit happy_meal_cleanup_module(void) qfe_sbus_list = next; } +} #endif -#ifdef CONFIG_PCI - while (qfe_pci_list) { - struct quattro *qfe = qfe_pci_list; - struct quattro *next = qfe->next; - kfree(qfe); +static int __init happy_meal_probe(void) +{ + int err = 0; - qfe_pci_list = next; +#ifdef CONFIG_SBUS + err = happy_meal_sbus_init(); +#endif +#ifdef CONFIG_PCI + if (!err) { + err = happy_meal_pci_init(); +#ifdef CONFIG_SBUS + if (err) + happy_meal_sbus_exit(); +#endif } #endif + + return err; +} + + +static void __exit happy_meal_exit(void) +{ +#ifdef CONFIG_SBUS + happy_meal_sbus_exit(); +#endif +#ifdef CONFIG_PCI + happy_meal_pci_exit(); +#endif } module_init(happy_meal_probe); -module_exit(happy_meal_cleanup_module); +module_exit(happy_meal_exit); diff --git a/drivers/net/sunhme.h b/drivers/net/sunhme.h index 34e9f953cea..90f446db9ba 100644 --- a/drivers/net/sunhme.h +++ b/drivers/net/sunhme.h @@ -8,7 +8,6 @@ #ifndef _SUNHME_H #define _SUNHME_H -#include <linux/config.h> #include <linux/pci.h> /* Happy Meal global registers. */ @@ -461,7 +460,6 @@ struct happy_meal { struct net_device *dev; /* Backpointer */ struct quattro *qfe_parent; /* For Quattro cards */ int qfe_ent; /* Which instance on quattro */ - struct happy_meal *next_module; }; /* Here are the happy flags. */ diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index b7d87d4690b..1ef9fd39a79 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -71,7 +71,6 @@ static char lancestr[] = "LANCE"; -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> @@ -266,7 +265,6 @@ struct lance_private { char *name; dma_addr_t init_block_dvma; struct net_device *dev; /* Backpointer */ - struct lance_private *next_module; struct sbus_dev *sdev; struct timer_list multicast_timer; }; @@ -298,8 +296,6 @@ int sparc_lance_debug = 2; #define LANCE_ADDR(x) ((long)(x) & ~0xff000000) -static struct lance_private *root_lance_dev; - /* Load the CSR registers */ static void load_csrs(struct lance_private *lp) { @@ -934,9 +930,9 @@ static int lance_open(struct net_device *dev) STOP_LANCE(lp); - if (request_irq(dev->irq, &lance_interrupt, SA_SHIRQ, + if (request_irq(dev->irq, &lance_interrupt, IRQF_SHARED, lancestr, (void *) dev)) { - printk(KERN_ERR "Lance: Can't get irq %s\n", __irq_itoa(dev->irq)); + printk(KERN_ERR "Lance: Can't get irq %d\n", dev->irq); return -EAGAIN; } @@ -1327,9 +1323,9 @@ static struct ethtool_ops sparc_lance_ethtool_ops = { .get_link = sparc_lance_get_link, }; -static int __init sparc_lance_init(struct sbus_dev *sdev, - struct sbus_dma *ledma, - struct sbus_dev *lebuffer) +static int __init sparc_lance_probe_one(struct sbus_dev *sdev, + struct sbus_dma *ledma, + struct sbus_dev *lebuffer) { static unsigned version_printed; struct net_device *dev; @@ -1473,6 +1469,7 @@ no_link_test: lp->dev = dev; SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &sdev->ofdev.dev); dev->open = &lance_open; dev->stop = &lance_close; dev->hard_start_xmit = &lance_start_xmit; @@ -1500,8 +1497,7 @@ no_link_test: goto fail; } - lp->next_module = root_lance_dev; - root_lance_dev = lp; + dev_set_drvdata(&sdev->ofdev.dev, lp); printk(KERN_INFO "%s: LANCE ", dev->name); @@ -1536,88 +1532,112 @@ static inline struct sbus_dma *find_ledma(struct sbus_dev *sdev) #include <asm/machines.h> /* Find all the lance cards on the system and initialize them */ -static int __init sparc_lance_probe(void) +static struct sbus_dev sun4_sdev; +static int __init sparc_lance_init(void) { - static struct sbus_dev sdev; - static int called; - - root_lance_dev = NULL; - - if (called) - return -ENODEV; - called++; - if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || (idprom->id_machtype == (SM_SUN4|SM_4_470))) { - memset(&sdev, 0, sizeof(sdev)); - sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; - sdev.irqs[0] = 6; - return sparc_lance_init(&sdev, NULL, NULL); + memset(&sun4_sdev, 0, sizeof(sdev)); + 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; } -#else /* !CONFIG_SUN4 */ - -/* Find all the lance cards on the system and initialize them */ -static int __init sparc_lance_probe(void) +static int __exit sunlance_sun4_remove(void) { - struct sbus_bus *bus; - struct sbus_dev *sdev = NULL; - struct sbus_dma *ledma = NULL; - static int called; - int cards = 0, v; - - root_lance_dev = NULL; - - if (called) - return -ENODEV; - called++; - - for_each_sbus (bus) { - for_each_sbusdev (sdev, bus) { - if (strcmp(sdev->prom_name, "le") == 0) { - cards++; - if ((v = sparc_lance_init(sdev, NULL, NULL))) - return v; - continue; - } - if (strcmp(sdev->prom_name, "ledma") == 0) { - cards++; - ledma = find_ledma(sdev); - if ((v = sparc_lance_init(sdev->child, - ledma, NULL))) - return v; - continue; - } - if (strcmp(sdev->prom_name, "lebuffer") == 0){ - cards++; - if ((v = sparc_lance_init(sdev->child, - NULL, sdev))) - return v; - continue; - } - } /* for each sbusdev */ - } /* for each sbus */ - if (!cards) - return -ENODEV; + struct lance_private *lp = dev_get_drvdata(&sun4_sdev->dev); + struct net_device *net_dev = lp->dev; + + unregister_netdevice(net_dev); + + lance_free_hwresources(root_lance_dev); + + free_netdev(net_dev); + + dev_set_drvdata(&sun4_sdev->dev, NULL); + return 0; } -#endif /* !CONFIG_SUN4 */ -static void __exit sparc_lance_cleanup(void) +#else /* !CONFIG_SUN4 */ + +static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match) { - struct lance_private *lp; + struct sbus_dev *sdev = to_sbus_device(&dev->dev); + struct device_node *dp = dev->node; + int err; + + if (!strcmp(dp->name, "le")) { + err = sparc_lance_probe_one(sdev, NULL, NULL); + } else if (!strcmp(dp->name, "ledma")) { + struct sbus_dma *ledma = find_ledma(sdev); - while (root_lance_dev) { - lp = root_lance_dev->next_module; + err = sparc_lance_probe_one(sdev->child, ledma, NULL); + } else { + BUG_ON(strcmp(dp->name, "lebuffer")); - unregister_netdev(root_lance_dev->dev); - lance_free_hwresources(root_lance_dev); - free_netdev(root_lance_dev->dev); - root_lance_dev = lp; + err = sparc_lance_probe_one(sdev->child, NULL, sdev); } + + return err; +} + +static int __devexit sunlance_sbus_remove(struct of_device *dev) +{ + struct lance_private *lp = dev_get_drvdata(&dev->dev); + struct net_device *net_dev = lp->dev; + + unregister_netdevice(net_dev); + + lance_free_hwresources(lp); + + free_netdev(net_dev); + + dev_set_drvdata(&dev->dev, NULL); + + return 0; +} + +static struct of_device_id sunlance_sbus_match[] = { + { + .name = "le", + }, + { + .name = "ledma", + }, + { + .name = "lebuffer", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, sunlance_sbus_match); + +static struct of_platform_driver sunlance_sbus_driver = { + .name = "sunlance", + .match_table = sunlance_sbus_match, + .probe = sunlance_sbus_probe, + .remove = __devexit_p(sunlance_sbus_remove), +}; + + +/* 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); +} +#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_probe); -module_exit(sparc_lance_cleanup); +module_init(sparc_lance_init); +module_exit(sparc_lance_exit); diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 1f2323be60d..817a40b6663 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -1,10 +1,9 @@ -/* $Id: sunqe.c,v 1.55 2002/01/15 06:48:55 davem Exp $ - * sunqe.c: Sparc QuadEthernet 10baseT SBUS card driver. +/* sunqe.c: Sparc QuadEthernet 10baseT SBUS card driver. * Once again I am out to prove that every ethernet * controller out there can be most efficiently programmed * if you make it look like a LANCE. * - * Copyright (C) 1996, 1999, 2003 David S. Miller (davem@redhat.com) + * Copyright (C) 1996, 1999, 2003, 2006 David S. Miller (davem@davemloft.net) */ #include <linux/module.h> @@ -41,9 +40,9 @@ #include "sunqe.h" #define DRV_NAME "sunqe" -#define DRV_VERSION "3.0" -#define DRV_RELDATE "8/24/03" -#define DRV_AUTHOR "David S. Miller (davem@redhat.com)" +#define DRV_VERSION "4.0" +#define DRV_RELDATE "June 23, 2006" +#define DRV_AUTHOR "David S. Miller (davem@davemloft.net)" static char version[] = DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; @@ -755,298 +754,269 @@ static inline void qec_init_once(struct sunqec *qecp, struct sbus_dev *qsdev) qecp->gregs + GLOB_RSIZE); } -/* Four QE's per QEC card. */ -static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev) +static u8 __init qec_get_burst(struct device_node *dp) { - static unsigned version_printed; - struct net_device *qe_devs[4]; - struct sunqe *qeps[4]; - struct sbus_dev *qesdevs[4]; - struct sbus_dev *child; - struct sunqec *qecp = NULL; u8 bsizes, bsizes_more; - int i, j, res = -ENOMEM; - for (i = 0; i < 4; i++) { - qe_devs[i] = alloc_etherdev(sizeof(struct sunqe)); - if (!qe_devs[i]) - goto out; - } + /* Find and set the burst sizes for the QEC, since it + * does the actual dma for all 4 channels. + */ + bsizes = of_getintprop_default(dp, "burst-sizes", 0xff); + bsizes &= 0xff; + bsizes_more = of_getintprop_default(dp->parent, "burst-sizes", 0xff); - if (version_printed++ == 0) - printk(KERN_INFO "%s", version); + if (bsizes_more != 0xff) + bsizes &= bsizes_more; + if (bsizes == 0xff || (bsizes & DMA_BURST16) == 0 || + (bsizes & DMA_BURST32)==0) + bsizes = (DMA_BURST32 - 1); - for (i = 0; i < 4; i++) { - qeps[i] = (struct sunqe *) qe_devs[i]->priv; - for (j = 0; j < 6; j++) - qe_devs[i]->dev_addr[j] = idprom->id_ethaddr[j]; - qeps[i]->channel = i; - spin_lock_init(&qeps[i]->lock); - } + return bsizes; +} - qecp = kmalloc(sizeof(struct sunqec), GFP_KERNEL); - if (qecp == NULL) - goto out1; - qecp->qec_sdev = sdev; +static struct sunqec * __init get_qec(struct sbus_dev *child_sdev) +{ + struct sbus_dev *qec_sdev = child_sdev->parent; + struct sunqec *qecp; - for (i = 0; i < 4; i++) { - qecp->qes[i] = qeps[i]; - qeps[i]->dev = qe_devs[i]; - qeps[i]->parent = qecp; + for (qecp = root_qec_dev; qecp; qecp = qecp->next_module) { + if (qecp->qec_sdev == qec_sdev) + break; } + if (!qecp) { + qecp = kzalloc(sizeof(struct sunqec), GFP_KERNEL); + if (qecp) { + u32 ctrl; + + qecp->qec_sdev = qec_sdev; + qecp->gregs = sbus_ioremap(&qec_sdev->resource[0], 0, + GLOB_REG_SIZE, + "QEC Global Registers"); + if (!qecp->gregs) + goto fail; + + /* Make sure the QEC is in MACE mode. */ + ctrl = sbus_readl(qecp->gregs + GLOB_CTRL); + ctrl &= 0xf0000000; + if (ctrl != GLOB_CTRL_MMODE) { + printk(KERN_ERR "qec: Not in MACE mode!\n"); + goto fail; + } - res = -ENODEV; + if (qec_global_reset(qecp->gregs)) + goto fail; - for (i = 0, child = sdev->child; i < 4; i++, child = child->next) { - /* Link in channel */ - j = prom_getintdefault(child->prom_node, "channel#", -1); - if (j == -1) - goto out2; - qesdevs[j] = child; - } + qecp->qec_bursts = qec_get_burst(qec_sdev->ofdev.node); - for (i = 0; i < 4; i++) - qeps[i]->qe_sdev = qesdevs[i]; + qec_init_once(qecp, qec_sdev); - /* Now map in the registers, QEC globals first. */ - qecp->gregs = sbus_ioremap(&sdev->resource[0], 0, - GLOB_REG_SIZE, "QEC Global Registers"); - if (!qecp->gregs) { - printk(KERN_ERR "QuadEther: Cannot map QEC global registers.\n"); - goto out2; - } + if (request_irq(qec_sdev->irqs[0], &qec_interrupt, + IRQF_SHARED, "qec", (void *) qecp)) { + printk(KERN_ERR "qec: Can't register irq.\n"); + goto fail; + } - /* Make sure the QEC is in MACE mode. */ - if ((sbus_readl(qecp->gregs + GLOB_CTRL) & 0xf0000000) != GLOB_CTRL_MMODE) { - printk(KERN_ERR "QuadEther: AIEEE, QEC is not in MACE mode!\n"); - goto out3; + qecp->next_module = root_qec_dev; + root_qec_dev = qecp; + } } - /* Reset the QEC. */ - if (qec_global_reset(qecp->gregs)) - goto out3; + return qecp; - /* Find and set the burst sizes for the QEC, since it does - * the actual dma for all 4 channels. - */ - bsizes = prom_getintdefault(sdev->prom_node, "burst-sizes", 0xff); - bsizes &= 0xff; - bsizes_more = prom_getintdefault(sdev->bus->prom_node, "burst-sizes", 0xff); +fail: + if (qecp->gregs) + sbus_iounmap(qecp->gregs, GLOB_REG_SIZE); + kfree(qecp); + return NULL; +} - if (bsizes_more != 0xff) - bsizes &= bsizes_more; - if (bsizes == 0xff || (bsizes & DMA_BURST16) == 0 || - (bsizes & DMA_BURST32)==0) - bsizes = (DMA_BURST32 - 1); +static int __init qec_ether_init(struct sbus_dev *sdev) +{ + static unsigned version_printed; + struct net_device *dev; + struct sunqe *qe; + struct sunqec *qecp; + int i, res; - qecp->qec_bursts = bsizes; + if (version_printed++ == 0) + printk(KERN_INFO "%s", version); - /* Perform one time QEC initialization, we never touch the QEC - * globals again after this. - */ - qec_init_once(qecp, sdev); - - for (i = 0; i < 4; i++) { - struct sunqe *qe = qeps[i]; - /* Map in QEC per-channel control registers. */ - qe->qcregs = sbus_ioremap(&qe->qe_sdev->resource[0], 0, - CREG_REG_SIZE, "QEC Channel Registers"); - if (!qe->qcregs) { - printk(KERN_ERR "QuadEther: Cannot map QE %d's channel registers.\n", i); - goto out4; - } + dev = alloc_etherdev(sizeof(struct sunqe)); + if (!dev) + return -ENOMEM; - /* Map in per-channel AMD MACE registers. */ - qe->mregs = sbus_ioremap(&qe->qe_sdev->resource[1], 0, - MREGS_REG_SIZE, "QE MACE Registers"); - if (!qe->mregs) { - printk(KERN_ERR "QuadEther: Cannot map QE %d's MACE registers.\n", i); - goto out4; - } + qe = netdev_priv(dev); - qe->qe_block = sbus_alloc_consistent(qe->qe_sdev, - PAGE_SIZE, - &qe->qblock_dvma); - qe->buffers = sbus_alloc_consistent(qe->qe_sdev, - sizeof(struct sunqe_buffers), - &qe->buffers_dvma); - if (qe->qe_block == NULL || qe->qblock_dvma == 0 || - qe->buffers == NULL || qe->buffers_dvma == 0) { - goto out4; + i = of_getintprop_default(sdev->ofdev.node, "channel#", -1); + if (i == -1) { + struct sbus_dev *td = sdev->parent->child; + i = 0; + while (td != sdev) { + td = td->next; + i++; } - - /* Stop this QE. */ - qe_stop(qe); } + qe->channel = i; + spin_lock_init(&qe->lock); + + res = -ENODEV; + qecp = get_qec(sdev); + if (!qecp) + goto fail; - for (i = 0; i < 4; i++) { - SET_MODULE_OWNER(qe_devs[i]); - qe_devs[i]->open = qe_open; - qe_devs[i]->stop = qe_close; - qe_devs[i]->hard_start_xmit = qe_start_xmit; - qe_devs[i]->get_stats = qe_get_stats; - qe_devs[i]->set_multicast_list = qe_set_multicast; - qe_devs[i]->tx_timeout = qe_tx_timeout; - qe_devs[i]->watchdog_timeo = 5*HZ; - qe_devs[i]->irq = sdev->irqs[0]; - qe_devs[i]->dma = 0; - qe_devs[i]->ethtool_ops = &qe_ethtool_ops; - } + qecp->qes[qe->channel] = qe; + qe->dev = dev; + qe->parent = qecp; + qe->qe_sdev = sdev; - /* QEC receives interrupts from each QE, then it sends the actual - * IRQ to the cpu itself. Since QEC is the single point of - * interrupt for all QE channels we register the IRQ handler - * for it now. - */ - if (request_irq(sdev->irqs[0], &qec_interrupt, - SA_SHIRQ, "QuadEther", (void *) qecp)) { - printk(KERN_ERR "QuadEther: Can't register QEC master irq handler.\n"); - res = -EAGAIN; - goto out4; + res = -ENOMEM; + qe->qcregs = sbus_ioremap(&qe->qe_sdev->resource[0], 0, + CREG_REG_SIZE, "QEC Channel Registers"); + if (!qe->qcregs) { + printk(KERN_ERR "qe: Cannot map channel registers.\n"); + goto fail; } - for (i = 0; i < 4; i++) { - if (register_netdev(qe_devs[i]) != 0) - goto out5; + qe->mregs = sbus_ioremap(&qe->qe_sdev->resource[1], 0, + MREGS_REG_SIZE, "QE MACE Registers"); + if (!qe->mregs) { + printk(KERN_ERR "qe: Cannot map MACE registers.\n"); + goto fail; } - /* Report the QE channels. */ - for (i = 0; i < 4; i++) { - printk(KERN_INFO "%s: QuadEthernet channel[%d] ", qe_devs[i]->name, i); - for (j = 0; j < 6; j++) - printk ("%2.2x%c", - qe_devs[i]->dev_addr[j], - j == 5 ? ' ': ':'); - printk("\n"); - } + qe->qe_block = sbus_alloc_consistent(qe->qe_sdev, + PAGE_SIZE, + &qe->qblock_dvma); + qe->buffers = sbus_alloc_consistent(qe->qe_sdev, + sizeof(struct sunqe_buffers), + &qe->buffers_dvma); + if (qe->qe_block == NULL || qe->qblock_dvma == 0 || + qe->buffers == NULL || qe->buffers_dvma == 0) + goto fail; + + /* Stop this QE. */ + qe_stop(qe); + + SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &sdev->ofdev.dev); + + dev->open = qe_open; + dev->stop = qe_close; + dev->hard_start_xmit = qe_start_xmit; + dev->get_stats = qe_get_stats; + dev->set_multicast_list = qe_set_multicast; + dev->tx_timeout = qe_tx_timeout; + dev->watchdog_timeo = 5*HZ; + dev->irq = sdev->irqs[0]; + dev->dma = 0; + dev->ethtool_ops = &qe_ethtool_ops; + + res = register_netdev(dev); + if (res) + goto fail; + + dev_set_drvdata(&sdev->ofdev.dev, qe); + + printk(KERN_INFO "%s: qe channel[%d] ", dev->name, qe->channel); + for (i = 0; i < 6; i++) + printk ("%2.2x%c", + dev->dev_addr[i], + i == 5 ? ' ': ':'); + printk("\n"); - /* We are home free at this point, link the qe's into - * the master list for later driver exit. - */ - qecp->next_module = root_qec_dev; - root_qec_dev = qecp; return 0; -out5: - while (i--) - unregister_netdev(qe_devs[i]); - free_irq(sdev->irqs[0], (void *)qecp); -out4: - for (i = 0; i < 4; i++) { - struct sunqe *qe = (struct sunqe *)qe_devs[i]->priv; - - if (qe->qcregs) - sbus_iounmap(qe->qcregs, CREG_REG_SIZE); - if (qe->mregs) - sbus_iounmap(qe->mregs, MREGS_REG_SIZE); - if (qe->qe_block) - sbus_free_consistent(qe->qe_sdev, - PAGE_SIZE, - qe->qe_block, - qe->qblock_dvma); - if (qe->buffers) - sbus_free_consistent(qe->qe_sdev, - sizeof(struct sunqe_buffers), - qe->buffers, - qe->buffers_dvma); - } -out3: - sbus_iounmap(qecp->gregs, GLOB_REG_SIZE); -out2: - kfree(qecp); -out1: - i = 4; -out: - while (i--) - free_netdev(qe_devs[i]); +fail: + if (qe->qcregs) + sbus_iounmap(qe->qcregs, CREG_REG_SIZE); + if (qe->mregs) + sbus_iounmap(qe->mregs, MREGS_REG_SIZE); + if (qe->qe_block) + sbus_free_consistent(qe->qe_sdev, + PAGE_SIZE, + qe->qe_block, + qe->qblock_dvma); + if (qe->buffers) + sbus_free_consistent(qe->qe_sdev, + sizeof(struct sunqe_buffers), + qe->buffers, + qe->buffers_dvma); + + free_netdev(dev); + return res; } -static int __init qec_match(struct sbus_dev *sdev) +static int __devinit qec_sbus_probe(struct of_device *dev, const struct of_device_id *match) { - struct sbus_dev *sibling; - int i; - - if (strcmp(sdev->prom_name, "qec") != 0) - return 0; + struct sbus_dev *sdev = to_sbus_device(&dev->dev); - /* QEC can be parent of either QuadEthernet or BigMAC - * children. Do not confuse this with qfe/SUNW,qfe - * which is a quad-happymeal card and handled by - * a different driver. - */ - sibling = sdev->child; - for (i = 0; i < 4; i++) { - if (sibling == NULL) - return 0; - if (strcmp(sibling->prom_name, "qe") != 0) - return 0; - sibling = sibling->next; - } - return 1; + return qec_ether_init(sdev); } -static int __init qec_probe(void) +static int __devexit qec_sbus_remove(struct of_device *dev) { - struct net_device *dev = NULL; - struct sbus_bus *bus; - struct sbus_dev *sdev = NULL; - static int called; - int cards = 0, v; - - root_qec_dev = NULL; - - if (called) - return -ENODEV; - called++; - - for_each_sbus(bus) { - for_each_sbusdev(sdev, bus) { - if (cards) - dev = NULL; - - if (qec_match(sdev)) { - cards++; - if ((v = qec_ether_init(dev, sdev))) - return v; - } - } - } - if (!cards) - return -ENODEV; + struct sunqe *qp = dev_get_drvdata(&dev->dev); + struct net_device *net_dev = qp->dev; + + unregister_netdevice(net_dev); + + sbus_iounmap(qp->qcregs, CREG_REG_SIZE); + sbus_iounmap(qp->mregs, MREGS_REG_SIZE); + sbus_free_consistent(qp->qe_sdev, + PAGE_SIZE, + qp->qe_block, + qp->qblock_dvma); + sbus_free_consistent(qp->qe_sdev, + sizeof(struct sunqe_buffers), + qp->buffers, + qp->buffers_dvma); + + free_netdev(net_dev); + + dev_set_drvdata(&dev->dev, NULL); + return 0; } -static void __exit qec_cleanup(void) +static struct of_device_id qec_sbus_match[] = { + { + .name = "qe", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, qec_sbus_match); + +static struct of_platform_driver qec_sbus_driver = { + .name = "qec", + .match_table = qec_sbus_match, + .probe = qec_sbus_probe, + .remove = __devexit_p(qec_sbus_remove), +}; + +static int __init qec_init(void) +{ + return of_register_driver(&qec_sbus_driver, &sbus_bus_type); +} + +static void __exit qec_exit(void) { - struct sunqec *next_qec; - int i; + of_unregister_driver(&qec_sbus_driver); while (root_qec_dev) { - next_qec = root_qec_dev->next_module; - - /* Release all four QE channels, then the QEC itself. */ - for (i = 0; i < 4; i++) { - unregister_netdev(root_qec_dev->qes[i]->dev); - sbus_iounmap(root_qec_dev->qes[i]->qcregs, CREG_REG_SIZE); - sbus_iounmap(root_qec_dev->qes[i]->mregs, MREGS_REG_SIZE); - sbus_free_consistent(root_qec_dev->qes[i]->qe_sdev, - PAGE_SIZE, - root_qec_dev->qes[i]->qe_block, - root_qec_dev->qes[i]->qblock_dvma); - sbus_free_consistent(root_qec_dev->qes[i]->qe_sdev, - sizeof(struct sunqe_buffers), - root_qec_dev->qes[i]->buffers, - root_qec_dev->qes[i]->buffers_dvma); - free_netdev(root_qec_dev->qes[i]->dev); - } - free_irq(root_qec_dev->qec_sdev->irqs[0], (void *)root_qec_dev); + struct sunqec *next = root_qec_dev->next_module; + + free_irq(root_qec_dev->qec_sdev->irqs[0], + (void *) root_qec_dev); sbus_iounmap(root_qec_dev->gregs, GLOB_REG_SIZE); + kfree(root_qec_dev); - root_qec_dev = next_qec; + + root_qec_dev = next; } } -module_init(qec_probe); -module_exit(qec_cleanup); +module_init(qec_init); +module_exit(qec_exit); diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index c2ec9fd8c31..8b53ded66d3 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c @@ -880,7 +880,7 @@ tc35815_open(struct net_device *dev) */ if (dev->irq == 0 || - request_irq(dev->irq, &tc35815_interrupt, SA_SHIRQ, cardname, dev)) { + request_irq(dev->irq, &tc35815_interrupt, IRQF_SHARED, cardname, dev)) { return -EAGAIN; } diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index b2ddd4522a8..e5e1b296293 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -15,7 +15,6 @@ * notice is accompanying it. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> @@ -69,8 +68,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.60" -#define DRV_MODULE_RELDATE "June 17, 2006" +#define DRV_MODULE_VERSION "3.61" +#define DRV_MODULE_RELDATE "June 29, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -3195,7 +3194,7 @@ static int tg3_vlan_rx(struct tg3 *tp, struct sk_buff *skb, u16 vlan_tag) */ static int tg3_rx(struct tg3 *tp, int budget) { - u32 work_mask; + u32 work_mask, rx_std_posted = 0; u32 sw_idx = tp->rx_rcb_ptr; u16 hw_idx; int received; @@ -3222,6 +3221,7 @@ static int tg3_rx(struct tg3 *tp, int budget) mapping); skb = tp->rx_std_buffers[desc_idx].skb; post_ptr = &tp->rx_std_ptr; + rx_std_posted++; } else if (opaque_key == RXD_OPAQUE_RING_JUMBO) { dma_addr = pci_unmap_addr(&tp->rx_jumbo_buffers[desc_idx], mapping); @@ -3309,6 +3309,15 @@ static int tg3_rx(struct tg3 *tp, int budget) next_pkt: (*post_ptr)++; + + if (unlikely(rx_std_posted >= tp->rx_std_max_post)) { + u32 idx = *post_ptr % TG3_RX_RING_SIZE; + + tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX + + TG3_64BIT_REG_LOW, idx); + work_mask &= ~RXD_OPAQUE_RING_STD; + rx_std_posted = 0; + } next_pkt_nopost: sw_idx++; sw_idx %= TG3_RX_RCB_RING_SIZE(tp); @@ -3780,7 +3789,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) #if TG3_TSO_SUPPORT != 0 mss = 0; if (skb->len > (tp->dev->mtu + ETH_HLEN) && - (mss = skb_shinfo(skb)->tso_size) != 0) { + (mss = skb_shinfo(skb)->gso_size) != 0) { int tcp_opt_len, ip_tcp_len; if (skb_header_cloned(skb) && @@ -3870,6 +3879,40 @@ out_unlock: return NETDEV_TX_OK; } +#if TG3_TSO_SUPPORT != 0 +static int tg3_start_xmit_dma_bug(struct sk_buff *, struct net_device *); + +/* Use GSO to workaround a rare TSO bug that may be triggered when the + * TSO header is greater than 80 bytes. + */ +static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb) +{ + struct sk_buff *segs, *nskb; + + /* Estimate the number of fragments in the worst case */ + if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->gso_segs * 3))) { + netif_stop_queue(tp->dev); + return NETDEV_TX_BUSY; + } + + segs = skb_gso_segment(skb, tp->dev->features & ~NETIF_F_TSO); + if (unlikely(IS_ERR(segs))) + goto tg3_tso_bug_end; + + do { + nskb = segs; + segs = segs->next; + nskb->next = NULL; + tg3_start_xmit_dma_bug(nskb, tp->dev); + } while (segs); + +tg3_tso_bug_end: + dev_kfree_skb(skb); + + return NETDEV_TX_OK; +} +#endif + /* hard_start_xmit for devices that have the 4G bug and/or 40-bit bug and * support TG3_FLG2_HW_TSO_1 or firmware TSO only. */ @@ -3905,8 +3948,8 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) #if TG3_TSO_SUPPORT != 0 mss = 0; if (skb->len > (tp->dev->mtu + ETH_HLEN) && - (mss = skb_shinfo(skb)->tso_size) != 0) { - int tcp_opt_len, ip_tcp_len; + (mss = skb_shinfo(skb)->gso_size) != 0) { + int tcp_opt_len, ip_tcp_len, hdr_len; if (skb_header_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { @@ -3917,11 +3960,16 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) tcp_opt_len = ((skb->h.th->doff - 5) * 4); ip_tcp_len = (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr); + hdr_len = ip_tcp_len + tcp_opt_len; + if (unlikely((ETH_HLEN + hdr_len) > 80) && + (tp->tg3_flags2 & TG3_FLG2_HW_TSO_1_BUG)) + return (tg3_tso_bug(tp, skb)); + base_flags |= (TXD_FLAG_CPU_PRE_DMA | TXD_FLAG_CPU_POST_DMA); skb->nh.iph->check = 0; - skb->nh.iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len); + skb->nh.iph->tot_len = htons(mss + hdr_len); if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) { skb->h.th->check = 0; base_flags &= ~TXD_FLAG_TCPUDP_CSUM; @@ -5981,7 +6029,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) } /* Setup replenish threshold. */ - tw32(RCVBDI_STD_THRESH, tp->rx_pending / 8); + val = tp->rx_pending / 8; + if (val == 0) + val = 1; + else if (val > tp->rx_std_max_post) + val = tp->rx_std_max_post; + + tw32(RCVBDI_STD_THRESH, val); /* Initialize TG3_BDINFO's at: * RCVDBDI_STD_BD: standard eth size rx ring @@ -6141,8 +6195,12 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) #endif /* Receive/send statistics. */ - if ((rdmac_mode & RDMAC_MODE_FIFO_SIZE_128) && - (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) { + if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) { + val = tr32(RCVLPC_STATS_ENABLE); + val &= ~RCVLPC_STATSENAB_DACK_FIX; + tw32(RCVLPC_STATS_ENABLE, val); + } else if ((rdmac_mode & RDMAC_MODE_FIFO_SIZE_128) && + (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) { val = tr32(RCVLPC_STATS_ENABLE); val &= ~RCVLPC_STATSENAB_LNGBRST_RFIX; tw32(RCVLPC_STATS_ENABLE, val); @@ -6644,12 +6702,12 @@ static int tg3_request_irq(struct tg3 *tp) fn = tg3_msi; if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI) fn = tg3_msi_1shot; - flags = SA_SAMPLE_RANDOM; + flags = IRQF_SAMPLE_RANDOM; } else { fn = tg3_interrupt; if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) fn = tg3_interrupt_tagged; - flags = SA_SHIRQ | SA_SAMPLE_RANDOM; + flags = IRQF_SHARED | IRQF_SAMPLE_RANDOM; } return (request_irq(tp->pdev->irq, fn, flags, dev->name, dev)); } @@ -6668,7 +6726,7 @@ static int tg3_test_interrupt(struct tg3 *tp) free_irq(tp->pdev->irq, dev); err = request_irq(tp->pdev->irq, tg3_test_isr, - SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); + IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev); if (err) return err; @@ -8738,6 +8796,9 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) { struct tg3 *tp = netdev_priv(dev); + if (netif_running(dev)) + tg3_netif_stop(tp); + tg3_full_lock(tp, 0); tp->vlgrp = grp; @@ -8746,16 +8807,25 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) __tg3_set_rx_mode(dev); tg3_full_unlock(tp); + + if (netif_running(dev)) + tg3_netif_start(tp); } static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) { struct tg3 *tp = netdev_priv(dev); + if (netif_running(dev)) + tg3_netif_stop(tp); + tg3_full_lock(tp, 0); if (tp->vlgrp) tp->vlgrp->vlan_devices[vid] = NULL; tg3_full_unlock(tp); + + if (netif_running(dev)) + tg3_netif_start(tp); } #endif @@ -10160,8 +10230,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) { tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2; tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI; - } else - tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1; + } else { + tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 | + TG3_FLG2_HW_TSO_1_BUG; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == + ASIC_REV_5750 && + tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2) + tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_1_BUG; + } } if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 && @@ -10533,6 +10609,16 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) tp->rx_offset = 0; + tp->rx_std_max_post = TG3_RX_RING_SIZE; + + /* Increment the rx prod index on the rx std ring by at most + * 8 for these chips to workaround hw errata. + */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) + tp->rx_std_max_post = 8; + /* By default, disable wake-on-lan. User can change this * using ETHTOOL_SWOL. */ @@ -10549,11 +10635,13 @@ static int __devinit tg3_get_macaddr_sparc(struct tg3 *tp) struct pcidev_cookie *pcp = pdev->sysdata; if (pcp != NULL) { - int node = pcp->prom_node; + unsigned char *addr; + int len; - if (prom_getproplen(node, "local-mac-address") == 6) { - prom_getproperty(node, "local-mac-address", - dev->dev_addr, 6); + addr = of_get_property(pcp->prom_node, "local-mac-address", + &len); + if (addr && len == 6) { + memcpy(dev->dev_addr, addr, 6); memcpy(dev->perm_addr, dev->dev_addr, 6); return 0; } diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 8209da5dd15..ba2c98711c8 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -125,6 +125,7 @@ #define CHIPREV_ID_5750_A0 0x4000 #define CHIPREV_ID_5750_A1 0x4001 #define CHIPREV_ID_5750_A3 0x4003 +#define CHIPREV_ID_5750_C2 0x4202 #define CHIPREV_ID_5752_A0_HW 0x5000 #define CHIPREV_ID_5752_A0 0x6000 #define CHIPREV_ID_5752_A1 0x6001 @@ -760,6 +761,7 @@ #define RCVLPC_STATSCTRL_ENABLE 0x00000001 #define RCVLPC_STATSCTRL_FASTUPD 0x00000002 #define RCVLPC_STATS_ENABLE 0x00002018 +#define RCVLPC_STATSENAB_DACK_FIX 0x00040000 #define RCVLPC_STATSENAB_LNGBRST_RFIX 0x00400000 #define RCVLPC_STATS_INCMASK 0x0000201c /* 0x2020 --> 0x2100 unused */ @@ -2137,6 +2139,7 @@ struct tg3 { struct tg3_rx_buffer_desc *rx_std; struct ring_info *rx_std_buffers; dma_addr_t rx_std_mapping; + u32 rx_std_max_post; struct tg3_rx_buffer_desc *rx_jumbo; struct ring_info *rx_jumbo_buffers; @@ -2191,7 +2194,7 @@ struct tg3 { #define TG3_FLAG_INIT_COMPLETE 0x80000000 u32 tg3_flags2; #define TG3_FLG2_RESTART_TIMER 0x00000001 -/* 0x00000002 available */ +#define TG3_FLG2_HW_TSO_1_BUG 0x00000002 #define TG3_FLG2_NO_ETH_WIRE_SPEED 0x00000004 #define TG3_FLG2_IS_5788 0x00000008 #define TG3_FLG2_MAX_RXPEND_64 0x00000010 diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index 12076f8f942..23c0017f25a 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -943,7 +943,7 @@ static int TLan_Open( struct net_device *dev ) int err; priv->tlanRev = TLan_DioRead8( dev->base_addr, TLAN_DEF_REVISION ); - err = request_irq( dev->irq, TLan_HandleInterrupt, SA_SHIRQ, TLanSignature, dev ); + err = request_irq( dev->irq, TLan_HandleInterrupt, IRQF_SHARED, TLanSignature, dev ); if ( err ) { printk(KERN_ERR "TLAN: Cannot open %s because IRQ %d is already in use.\n", dev->name, dev->irq ); diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c index 41e0cd8f478..465921e3874 100644 --- a/drivers/net/tokenring/3c359.c +++ b/drivers/net/tokenring/3c359.c @@ -42,7 +42,6 @@ #define XL_DEBUG 0 -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -577,7 +576,7 @@ static int xl_open(struct net_device *dev) u16 switchsettings, switchsettings_eeprom ; - if(request_irq(dev->irq, &xl_interrupt, SA_SHIRQ , "3c359", dev)) { + if(request_irq(dev->irq, &xl_interrupt, IRQF_SHARED , "3c359", dev)) { return -EAGAIN; } diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c index 649d8ea354f..1bdd3beefbe 100644 --- a/drivers/net/tokenring/abyss.c +++ b/drivers/net/tokenring/abyss.c @@ -123,7 +123,7 @@ static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_ goto err_out_trdev; } - ret = request_irq(pdev->irq, tms380tr_interrupt, SA_SHIRQ, + ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED, dev->name, dev); if (ret) goto err_out_region; diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c index c58a4c31d0d..28d968ffd5d 100644 --- a/drivers/net/tokenring/lanstreamer.c +++ b/drivers/net/tokenring/lanstreamer.c @@ -100,7 +100,6 @@ #define STREAMER_IOCTL 0 -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -602,7 +601,7 @@ static int streamer_open(struct net_device *dev) rc=streamer_reset(dev); } - if (request_irq(dev->irq, &streamer_interrupt, SA_SHIRQ, "lanstreamer", dev)) { + if (request_irq(dev->irq, &streamer_interrupt, IRQF_SHARED, "lanstreamer", dev)) { return -EAGAIN; } #if STREAMER_DEBUG diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index 19e6f4dfd69..666bbaaae82 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c @@ -311,7 +311,7 @@ static int __devinit madgemc_probe(struct device *device) */ outb(0, dev->base_addr + MC_CONTROL_REG0); /* sanity */ madgemc_setsifsel(dev, 1); - if (request_irq(dev->irq, madgemc_interrupt, SA_SHIRQ, + if (request_irq(dev->irq, madgemc_interrupt, IRQF_SHARED, "madgemc", dev)) { ret = -EBUSY; goto getout3; diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c index 23032a7bc0a..85831484bc4 100644 --- a/drivers/net/tokenring/olympic.c +++ b/drivers/net/tokenring/olympic.c @@ -80,7 +80,6 @@ #define OLYMPIC_DEBUG 0 -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -217,7 +216,7 @@ static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device dev = alloc_trdev(sizeof(struct olympic_private)) ; if (!dev) { i = -ENOMEM; - goto op_free_dev; + goto op_release_dev; } olympic_priv = dev->priv ; @@ -282,8 +281,8 @@ op_free_iomap: if (olympic_priv->olympic_lap) iounmap(olympic_priv->olympic_lap); -op_free_dev: free_netdev(dev); +op_release_dev: pci_release_regions(pdev); op_disable_dev: @@ -446,7 +445,7 @@ static int olympic_open(struct net_device *dev) olympic_init(dev); - if(request_irq(dev->irq, &olympic_interrupt, SA_SHIRQ , "olympic", dev)) { + if(request_irq(dev->irq, &olympic_interrupt, IRQF_SHARED , "olympic", dev)) { return -EAGAIN; } diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index 67d2b596ce2..cd2e0251e2b 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -29,7 +29,6 @@ */ #include <linux/module.h> -#include <linux/config.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/fcntl.h> @@ -532,7 +531,7 @@ static int __init smctr_chk_mca(struct net_device *dev) dev->irq = 15; break; } - if (request_irq(dev->irq, smctr_interrupt, SA_SHIRQ, smctr_name, dev)) { + if (request_irq(dev->irq, smctr_interrupt, IRQF_SHARED, smctr_name, dev)) { release_region(dev->base_addr, SMCTR_IO_EXTENT); return -ENODEV; } @@ -1062,7 +1061,7 @@ static int __init smctr_chk_isa(struct net_device *dev) goto out2; } - if (request_irq(dev->irq, smctr_interrupt, SA_SHIRQ, smctr_name, dev)) + if (request_irq(dev->irq, smctr_interrupt, IRQF_SHARED, smctr_name, dev)) goto out2; /* Get 58x Rom Base */ diff --git a/drivers/net/tokenring/smctr_firmware.h b/drivers/net/tokenring/smctr_firmware.h index 48994b043b7..292e50ddf01 100644 --- a/drivers/net/tokenring/smctr_firmware.h +++ b/drivers/net/tokenring/smctr_firmware.h @@ -17,7 +17,6 @@ * - Jay Schulist <jschlst@samba.org> */ -#include <linux/config.h> #if defined(CONFIG_SMCTR) || defined(CONFIG_SMCTR_MODULE) diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c index ab47c0547a3..7d3e270c4f4 100644 --- a/drivers/net/tokenring/tmspci.c +++ b/drivers/net/tokenring/tmspci.c @@ -122,7 +122,7 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic goto err_out_trdev; } - ret = request_irq(pdev->irq, tms380tr_interrupt, SA_SHIRQ, + ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED, dev->name, dev); if (ret) goto err_out_region; diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 5f743b97294..d05c5aa254e 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -31,7 +31,6 @@ #define DRV_VERSION "0.7" #define DRV_RELDATE "Mar 17, 2004" -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/netdevice.h> @@ -1372,7 +1371,7 @@ static int de_open (struct net_device *dev) dw32(IntrMask, 0); - rc = request_irq(dev->irq, de_interrupt, SA_SHIRQ, dev->name, dev); + rc = request_irq(dev->irq, de_interrupt, IRQF_SHARED, dev->name, dev); if (rc) { printk(KERN_ERR "%s: IRQ %d request failure, err=%d\n", dev->name, dev->irq, rc); @@ -2007,8 +2006,8 @@ static int __init de_init_one (struct pci_dev *pdev, } if (pci_resource_len(pdev, 1) < DE_REGS_SIZE) { rc = -EIO; - printk(KERN_ERR PFX "MMIO resource (%lx) too small on pci dev %s\n", - pci_resource_len(pdev, 1), pci_name(pdev)); + printk(KERN_ERR PFX "MMIO resource (%llx) too small on pci dev %s\n", + (unsigned long long)pci_resource_len(pdev, 1), pci_name(pdev)); goto err_out_res; } @@ -2016,8 +2015,9 @@ static int __init de_init_one (struct pci_dev *pdev, regs = ioremap_nocache(pciaddr, DE_REGS_SIZE); if (!regs) { rc = -EIO; - printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n", - pci_resource_len(pdev, 1), pciaddr, pci_name(pdev)); + printk(KERN_ERR PFX "Cannot map PCI MMIO (%llx@%lx) on pci dev %s\n", + (unsigned long long)pci_resource_len(pdev, 1), + pciaddr, pci_name(pdev)); goto err_out_res; } dev->base_addr = (unsigned long) regs; diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index da8bd0d62a3..75ff14a5523 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -292,7 +292,7 @@ 0.41 21-Mar-96 Don't check for get_hw_addr checksum unless DEC card only <niles@axp745gsfc.nasa.gov> Fix for multiple PCI cards reported by <jos@xos.nl> - Duh, put the SA_SHIRQ flag into request_interrupt(). + Duh, put the IRQF_SHARED flag into request_interrupt(). Fix SMC ethernet address in enet_det[]. Print chip name instead of "UNKNOWN" during boot. 0.42 26-Apr-96 Fix MII write TA bit error. @@ -353,7 +353,7 @@ infoblocks. Added DC21142 and DC21143 functions. Added byte counters from <phil@tazenda.demon.co.uk> - Added SA_INTERRUPT temporary fix from + Added IRQF_DISABLED temporary fix from <mjacob@feral.com>. 0.53 12-Nov-97 Fix the *_probe() to include 'eth??' name during module load: bug reported by @@ -443,7 +443,6 @@ ========================================================================= */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/string.h> @@ -1320,10 +1319,10 @@ de4x5_open(struct net_device *dev) lp->state = OPEN; de4x5_dbg_open(dev); - if (request_irq(dev->irq, (void *)de4x5_interrupt, SA_SHIRQ, + if (request_irq(dev->irq, (void *)de4x5_interrupt, IRQF_SHARED, lp->adapter_name, dev)) { printk("de4x5_open(): Requested IRQ%d is busy - attemping FAST/SHARE...", dev->irq); - if (request_irq(dev->irq, de4x5_interrupt, SA_INTERRUPT | SA_SHIRQ, + if (request_irq(dev->irq, de4x5_interrupt, IRQF_DISABLED | IRQF_SHARED, lp->adapter_name, dev)) { printk("\n Cannot get IRQ- reconfigure your hardware.\n"); disable_ast(dev); diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index ba5b112093f..4e5b0f2acc3 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -506,7 +506,7 @@ static int dmfe_open(struct DEVICE *dev) DMFE_DBUG(0, "dmfe_open", 0); - ret = request_irq(dev->irq, &dmfe_interrupt, SA_SHIRQ, dev->name, dev); + ret = request_irq(dev->irq, &dmfe_interrupt, IRQF_SHARED, dev->name, dev); if (ret) return ret; diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c index da4f7593c50..99ccf2ebb34 100644 --- a/drivers/net/tulip/interrupt.c +++ b/drivers/net/tulip/interrupt.c @@ -16,7 +16,6 @@ #include <linux/pci.h> #include "tulip.h" -#include <linux/config.h> #include <linux/etherdevice.h> int tulip_rx_copybreak; diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h index d25020da679..3bcfbf3d23e 100644 --- a/drivers/net/tulip/tulip.h +++ b/drivers/net/tulip/tulip.h @@ -16,7 +16,6 @@ #ifndef __NET_TULIP_H__ #define __NET_TULIP_H__ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/spinlock.h> diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index cabdf894e21..7351831f57c 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -14,7 +14,6 @@ */ -#include <linux/config.h> #define DRV_NAME "tulip" #ifdef CONFIG_TULIP_NAPI @@ -490,7 +489,7 @@ tulip_open(struct net_device *dev) { int retval; - if ((retval = request_irq(dev->irq, &tulip_interrupt, SA_SHIRQ, dev->name, dev))) + if ((retval = request_irq(dev->irq, &tulip_interrupt, IRQF_SHARED, dev->name, dev))) return retval; tulip_init_ring (dev); @@ -1350,10 +1349,10 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) { - printk (KERN_ERR PFX "%s: I/O region (0x%lx@0x%lx) too small, " + printk (KERN_ERR PFX "%s: I/O region (0x%llx@0x%llx) too small, " "aborting\n", pci_name(pdev), - pci_resource_len (pdev, 0), - pci_resource_start (pdev, 0)); + (unsigned long long)pci_resource_len (pdev, 0), + (unsigned long long)pci_resource_start (pdev, 0)); goto err_out_free_netdev; } @@ -1550,10 +1549,14 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, dev->dev_addr[i] = last_phys_addr[i]; dev->dev_addr[i] = last_phys_addr[i] + 1; #if defined(__sparc__) - if ((pcp != NULL) && prom_getproplen(pcp->prom_node, - "local-mac-address") == 6) { - prom_getproperty(pcp->prom_node, "local-mac-address", - dev->dev_addr, 6); + if (pcp) { + unsigned char *addr; + int len; + + addr = of_get_property(pcp->prom_node, + "local-mac-address", &len); + if (addr && len == 6) + memcpy(dev->dev_addr, addr, 6); } #endif #if defined(__i386__) || defined(__x86_64__) /* Patch up x86 BIOS bug. */ @@ -1767,7 +1770,7 @@ static int tulip_resume(struct pci_dev *pdev) pci_enable_device(pdev); - if ((retval = request_irq(dev->irq, &tulip_interrupt, SA_SHIRQ, dev->name, dev))) { + if ((retval = request_irq(dev->irq, &tulip_interrupt, IRQF_SHARED, dev->name, dev))) { printk (KERN_ERR "tulip: request_irq failed in resume\n"); return retval; } diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index 8b3a28f53c3..fd64b2b3e99 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c @@ -436,7 +436,7 @@ static int uli526x_open(struct net_device *dev) ULI526X_DBUG(0, "uli526x_open", 0); - ret = request_irq(dev->irq, &uli526x_interrupt, SA_SHIRQ, dev->name, dev); + ret = request_irq(dev->irq, &uli526x_interrupt, IRQF_SHARED, dev->name, dev); if (ret) return ret; diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 8fea2aa455d..b4c0d101a7d 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -212,26 +212,15 @@ Test with 'ping -s 10000' on a fast computer. /* PCI probe table. */ -enum pci_id_flags_bits { - /* Set PCI command register bits before calling probe1(). */ - PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, - /* Read and map the single following PCI BAR. */ - PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4, - PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400, -}; enum chip_capability_flags { - CanHaveMII=1, HasBrokenTx=2, AlwaysFDX=4, FDXOnNoMII=8,}; -#ifdef USE_IO_OPS -#define W840_FLAGS (PCI_USES_IO | PCI_ADDR0 | PCI_USES_MASTER) -#else -#define W840_FLAGS (PCI_USES_MEM | PCI_ADDR1 | PCI_USES_MASTER) -#endif + CanHaveMII=1, HasBrokenTx=2, AlwaysFDX=4, FDXOnNoMII=8, +}; -static struct pci_device_id w840_pci_tbl[] = { +static const struct pci_device_id w840_pci_tbl[] = { { 0x1050, 0x0840, PCI_ANY_ID, 0x8153, 0, 0, 0 }, { 0x1050, 0x0840, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, { 0x11f6, 0x2011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, - { 0, } + { } }; MODULE_DEVICE_TABLE(pci, w840_pci_tbl); @@ -241,18 +230,17 @@ struct pci_id_info { int pci, pci_mask, subsystem, subsystem_mask; int revision, revision_mask; /* Only 8 bits. */ } id; - enum pci_id_flags_bits pci_flags; int io_size; /* Needed for I/O region check or ioremap(). */ int drv_flags; /* Driver use, intended as capability flags. */ }; static struct pci_id_info pci_id_tbl[] = { {"Winbond W89c840", /* Sometime a Level-One switch card. */ { 0x08401050, 0xffffffff, 0x81530000, 0xffff0000 }, - W840_FLAGS, 128, CanHaveMII | HasBrokenTx | FDXOnNoMII}, + 128, CanHaveMII | HasBrokenTx | FDXOnNoMII}, {"Winbond W89c840", { 0x08401050, 0xffffffff, }, - W840_FLAGS, 128, CanHaveMII | HasBrokenTx}, + 128, CanHaveMII | HasBrokenTx}, {"Compex RL100-ATX", { 0x201111F6, 0xffffffff,}, - W840_FLAGS, 128, CanHaveMII | HasBrokenTx}, + 128, CanHaveMII | HasBrokenTx}, {NULL,}, /* 0 terminated list. */ }; @@ -670,7 +658,7 @@ static int netdev_open(struct net_device *dev) iowrite32(0x00000001, ioaddr + PCIBusCfg); /* Reset */ netif_device_detach(dev); - i = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev); + i = request_irq(dev->irq, &intr_handler, IRQF_SHARED, dev->name, dev); if (i) goto out_err; diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c index 63c2175ed13..f874e4f6ccf 100644 --- a/drivers/net/tulip/xircom_cb.c +++ b/drivers/net/tulip/xircom_cb.c @@ -457,7 +457,7 @@ static int xircom_open(struct net_device *dev) int retval; enter("xircom_open"); printk(KERN_INFO "xircom cardbus adaptor found, registering as %s, using irq %i \n",dev->name,dev->irq); - retval = request_irq(dev->irq, &xircom_interrupt, SA_SHIRQ, dev->name, dev); + retval = request_irq(dev->irq, &xircom_interrupt, IRQF_SHARED, dev->name, dev); if (retval) { leave("xircom_open - No IRQ"); return retval; diff --git a/drivers/net/tulip/xircom_tulip_cb.c b/drivers/net/tulip/xircom_tulip_cb.c index 887d7245fe7..091ebb7a62f 100644 --- a/drivers/net/tulip/xircom_tulip_cb.c +++ b/drivers/net/tulip/xircom_tulip_cb.c @@ -98,7 +98,6 @@ static int csr0 = 0x00A00000 | 0x4800; /* PCI registers */ #define PCI_POWERMGMT 0x40 -#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> @@ -808,7 +807,7 @@ xircom_open(struct net_device *dev) { struct xircom_private *tp = netdev_priv(dev); - if (request_irq(dev->irq, &xircom_interrupt, SA_SHIRQ, dev->name, dev)) + if (request_irq(dev->irq, &xircom_interrupt, IRQF_SHARED, dev->name, dev)) return -EAGAIN; xircom_up(dev); diff --git a/drivers/net/tun.c b/drivers/net/tun.c index a1ed2d98374..329d9feb9b8 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -39,7 +39,6 @@ #define DRV_DESCRIPTION "Universal TUN/TAP device driver" #define DRV_COPYRIGHT "(C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>" -#include <linux/config.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/kernel.h> @@ -490,6 +489,9 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr) err = -EINVAL; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + /* Set dev type */ if (ifr->ifr_flags & IFF_TUN) { /* TUN device */ @@ -777,7 +779,6 @@ static struct miscdevice tun_miscdev = { .minor = TUN_MINOR, .name = "tun", .fops = &tun_fops, - .devfs_name = "net/tun", }; /* ethtool interface */ diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index d9258d42090..063816f2b11 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -340,7 +340,7 @@ enum state_values { #endif #if defined(NETIF_F_TSO) -#define skb_tso_size(x) (skb_shinfo(x)->tso_size) +#define skb_tso_size(x) (skb_shinfo(x)->gso_size) #define TSO_NUM_DESCRIPTORS 2 #define TSO_OFFLOAD_ON TYPHOON_OFFLOAD_TCP_SEGMENT #else @@ -2131,7 +2131,7 @@ typhoon_open(struct net_device *dev) goto out_sleep; } - err = request_irq(dev->irq, &typhoon_interrupt, SA_SHIRQ, + err = request_irq(dev->irq, &typhoon_interrupt, IRQF_SHARED, dev->name, dev); if(err < 0) goto out_sleep; @@ -2568,9 +2568,10 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, dev); - printk(KERN_INFO "%s: %s at %s 0x%lx, ", + printk(KERN_INFO "%s: %s at %s 0x%llx, ", dev->name, typhoon_card_info[card_id].name, - use_mmio ? "MMIO" : "IO", pci_resource_start(pdev, use_mmio)); + use_mmio ? "MMIO" : "IO", + (unsigned long long)pci_resource_start(pdev, use_mmio)); for(i = 0; i < 5; i++) printk("%2.2x:", dev->dev_addr[i]); printk("%2.2x\n", dev->dev_addr[i]); diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index fdc21037f6d..98b6f3207d3 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -1210,7 +1210,7 @@ static int rhine_open(struct net_device *dev) void __iomem *ioaddr = rp->base; int rc; - rc = request_irq(rp->pdev->irq, &rhine_interrupt, SA_SHIRQ, dev->name, + rc = request_irq(rp->pdev->irq, &rhine_interrupt, IRQF_SHARED, dev->name, dev); if (rc) return rc; @@ -1284,11 +1284,8 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev) /* Calculate the next Tx descriptor entry. */ entry = rp->cur_tx % TX_RING_SIZE; - if (skb->len < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) - return 0; - } + if (skb_padto(skb, ETH_ZLEN)) + return 0; rp->tx_skbuff[entry] = skb; @@ -2002,7 +1999,7 @@ static int rhine_resume(struct pci_dev *pdev) if (!netif_running(dev)) return 0; - if (request_irq(dev->irq, rhine_interrupt, SA_SHIRQ, dev->name, dev)) + if (request_irq(dev->irq, rhine_interrupt, IRQF_SHARED, dev->name, dev)) printk(KERN_ERR "via-rhine %s: request_irq failed\n", dev->name); ret = pci_set_power_state(pdev, PCI_D0); diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 2eb6b5f9ba0..ba2972ba375 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -47,7 +47,6 @@ #include <linux/module.h> #include <linux/types.h> -#include <linux/config.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/errno.h> @@ -65,7 +64,6 @@ #include <linux/wait.h> #include <asm/io.h> #include <linux/if.h> -#include <linux/config.h> #include <asm/uaccess.h> #include <linux/proc_fs.h> #include <linux/inetdevice.h> @@ -248,6 +246,7 @@ static void velocity_free_rd_ring(struct velocity_info *vptr); static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *); static int velocity_soft_reset(struct velocity_info *vptr); static void mii_init(struct velocity_info *vptr, u32 mii_status); +static u32 velocity_get_link(struct net_device *dev); static u32 velocity_get_opt_media_mode(struct velocity_info *vptr); static void velocity_print_link_status(struct velocity_info *vptr); static void safe_disable_mii_autopoll(struct mac_regs __iomem * regs); @@ -798,6 +797,9 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi if (ret < 0) goto err_iounmap; + if (velocity_get_link(dev)) + netif_carrier_off(dev); + velocity_print_info(vptr); pci_set_drvdata(pdev, dev); @@ -1653,8 +1655,10 @@ static void velocity_error(struct velocity_info *vptr, int status) if (linked) { vptr->mii_status &= ~VELOCITY_LINK_FAIL; + netif_carrier_on(vptr->dev); } else { vptr->mii_status |= VELOCITY_LINK_FAIL; + netif_carrier_off(vptr->dev); } velocity_print_link_status(vptr); @@ -1746,7 +1750,7 @@ static int velocity_open(struct net_device *dev) velocity_init_registers(vptr, VELOCITY_INIT_COLD); - ret = request_irq(vptr->pdev->irq, &velocity_intr, SA_SHIRQ, + ret = request_irq(vptr->pdev->irq, &velocity_intr, IRQF_SHARED, dev->name, dev); if (ret < 0) { /* Power down the chip */ diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c index 43d854ace23..c92ac9fde08 100644 --- a/drivers/net/wan/c101.c +++ b/drivers/net/wan/c101.c @@ -7,7 +7,7 @@ * under the terms of version 2 of the GNU General Public License * as published by the Free Software Foundation. * - * For information see http://hq.pm.waw.pl/hdlc/ + * For information see <http://www.kernel.org/pub/linux/utils/net/hdlc/> * * Sources of information: * Hitachi HD64570 SCA User's Manual @@ -326,21 +326,21 @@ static int __init c101_run(unsigned long irq, unsigned long winbase) if (request_irq(irq, sca_intr, 0, devname, card)) { printk(KERN_ERR "c101: could not allocate IRQ\n"); c101_destroy_card(card); - return(-EBUSY); + return -EBUSY; } card->irq = irq; if (!request_mem_region(winbase, C101_MAPPED_RAM_SIZE, devname)) { printk(KERN_ERR "c101: could not request RAM window\n"); c101_destroy_card(card); - return(-EBUSY); + return -EBUSY; } card->phy_winbase = winbase; card->win0base = ioremap(winbase, C101_MAPPED_RAM_SIZE); if (!card->win0base) { printk(KERN_ERR "c101: could not map I/O address\n"); c101_destroy_card(card); - return -EBUSY; + return -EFAULT; } card->tx_ring_buffers = TX_RING_BUFFERS; diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index e392ee8b37a..1f95b4864ea 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c @@ -79,13 +79,11 @@ /* ---------- Headers, macros, data structures ---------- */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/slab.h> #include <linux/poll.h> #include <linux/fs.h> -#include <linux/devfs_fs_kernel.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/errno.h> @@ -393,7 +391,6 @@ static int __init cosa_init(void) err = -ENODEV; goto out; } - devfs_mk_dir("cosa"); cosa_class = class_create(THIS_MODULE, "cosa"); if (IS_ERR(cosa_class)) { err = PTR_ERR(cosa_class); @@ -402,13 +399,6 @@ static int __init cosa_init(void) for (i=0; i<nr_cards; i++) { class_device_create(cosa_class, NULL, MKDEV(cosa_major, i), NULL, "cosa%d", i); - err = devfs_mk_cdev(MKDEV(cosa_major, i), - S_IFCHR|S_IRUSR|S_IWUSR, - "cosa/%d", i); - if (err) { - class_device_destroy(cosa_class, MKDEV(cosa_major, i)); - goto out_chrdev; - } } err = 0; goto out; @@ -426,12 +416,9 @@ static void __exit cosa_exit(void) int i; printk(KERN_INFO "Unloading the cosa module\n"); - for (i=0; i<nr_cards; i++) { + for (i=0; i<nr_cards; i++) class_device_destroy(cosa_class, MKDEV(cosa_major, i)); - devfs_remove("cosa/%d", i); - } class_destroy(cosa_class); - devfs_remove("cosa"); for (cosa=cosa_cards; nr_cards--; cosa++) { /* Clean up the per-channel data */ for (i=0; i<cosa->nchannels; i++) { diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 4505540e3c5..684af4316ff 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c @@ -732,15 +732,15 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev, ioaddr = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); if (!ioaddr) { - printk(KERN_ERR "%s: cannot remap MMIO region %lx @ %lx\n", - DRV_NAME, pci_resource_len(pdev, 0), - pci_resource_start(pdev, 0)); + printk(KERN_ERR "%s: cannot remap MMIO region %llx @ %llx\n", + DRV_NAME, (unsigned long long)pci_resource_len(pdev, 0), + (unsigned long long)pci_resource_start(pdev, 0)); rc = -EIO; goto err_free_mmio_regions_2; } - printk(KERN_DEBUG "Siemens DSCC4, MMIO at %#lx (regs), %#lx (lbi), IRQ %d\n", - pci_resource_start(pdev, 0), - pci_resource_start(pdev, 1), pdev->irq); + printk(KERN_DEBUG "Siemens DSCC4, MMIO at %#llx (regs), %#llx (lbi), IRQ %d\n", + (unsigned long long)pci_resource_start(pdev, 0), + (unsigned long long)pci_resource_start(pdev, 1), pdev->irq); /* Cf errata DS5 p.2 */ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xf8); @@ -752,7 +752,7 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev, priv = pci_get_drvdata(pdev); - rc = request_irq(pdev->irq, dscc4_irq, SA_SHIRQ, DRV_NAME, priv->root); + rc = request_irq(pdev->irq, dscc4_irq, IRQF_SHARED, DRV_NAME, priv->root); if (rc < 0) { printk(KERN_WARNING "%s: IRQ %d busy\n", DRV_NAME, pdev->irq); goto err_release_4; diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index 7981a2c7906..3705db04a34 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -2519,7 +2519,7 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent) dbg(DBG_PCI, "kernel mem %p, ctlmem %p\n", card->mem, card->ctlmem); /* Register the interrupt handler */ - if (request_irq(pdev->irq, fst_intr, SA_SHIRQ, FST_DEV_NAME, card)) { + if (request_irq(pdev->irq, fst_intr, IRQF_SHARED, FST_DEV_NAME, card)) { printk_err("Unable to register interrupt %d\n", card->irq); pci_release_regions(pdev); pci_disable_device(pdev); diff --git a/drivers/net/wan/hdlc_generic.c b/drivers/net/wan/hdlc_generic.c index 46cef8f9213..b7da55140fb 100644 --- a/drivers/net/wan/hdlc_generic.c +++ b/drivers/net/wan/hdlc_generic.c @@ -22,7 +22,6 @@ * - proto.start() and stop() are called with spin_lock_irq held. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/slab.h> @@ -259,7 +258,7 @@ int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } } -static void hdlc_setup(struct net_device *dev) +void hdlc_setup(struct net_device *dev) { hdlc_device *hdlc = dev_to_hdlc(dev); @@ -288,26 +287,6 @@ struct net_device *alloc_hdlcdev(void *priv) return dev; } -int register_hdlc_device(struct net_device *dev) -{ - int result = dev_alloc_name(dev, "hdlc%d"); - if (result < 0) - return result; - - result = register_netdev(dev); - if (result != 0) - return -EIO; - -#if 0 - if (netif_carrier_ok(dev)) - netif_carrier_off(dev); /* no carrier until DCD goes up */ -#endif - - return 0; -} - - - void unregister_hdlc_device(struct net_device *dev) { rtnl_lock(); @@ -326,8 +305,8 @@ EXPORT_SYMBOL(hdlc_open); EXPORT_SYMBOL(hdlc_close); EXPORT_SYMBOL(hdlc_set_carrier); EXPORT_SYMBOL(hdlc_ioctl); +EXPORT_SYMBOL(hdlc_setup); EXPORT_SYMBOL(alloc_hdlcdev); -EXPORT_SYMBOL(register_hdlc_device); EXPORT_SYMBOL(unregister_hdlc_device); static struct packet_type hdlc_packet_type = { diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c index cf5c805452a..a4f735723c4 100644 --- a/drivers/net/wan/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c @@ -264,7 +264,7 @@ static struct sv11_device *sv11_init(int iobase, int irq) /* We want a fast IRQ for this device. Actually we'd like an even faster IRQ ;) - This is one driver RtLinux is made for */ - if(request_irq(irq, &z8530_interrupt, SA_INTERRUPT, "Hostess SV11", dev)<0) + if(request_irq(irq, &z8530_interrupt, IRQF_DISABLED, "Hostess SV11", dev)<0) { printk(KERN_WARNING "hostess: IRQ %d already in use.\n", irq); goto fail1; diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c index 40926d77916..39f44241a72 100644 --- a/drivers/net/wan/lmc/lmc_main.c +++ b/drivers/net/wan/lmc/lmc_main.c @@ -1058,7 +1058,7 @@ static int lmc_open (struct net_device *dev) /*fold00*/ lmc_softreset (sc); /* Since we have to use PCI bus, this should work on x86,alpha,ppc */ - if (request_irq (dev->irq, &lmc_interrupt, SA_SHIRQ, dev->name, dev)){ + if (request_irq (dev->irq, &lmc_interrupt, IRQF_SHARED, dev->name, dev)){ printk(KERN_WARNING "%s: could not get irq: %d\n", dev->name, dev->irq); lmc_trace(dev, "lmc_open irq failed out"); return -EAGAIN; diff --git a/drivers/net/wan/lmc/lmc_media.c b/drivers/net/wan/lmc/lmc_media.c index af8b55fdd9d..ae01555d24c 100644 --- a/drivers/net/wan/lmc/lmc_media.c +++ b/drivers/net/wan/lmc/lmc_media.c @@ -1,6 +1,5 @@ /* $Id: lmc_media.c,v 1.13 2000/04/11 05:25:26 asj Exp $ */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/string.h> #include <linux/timer.h> diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c index cd32751b64e..e013b817cab 100644 --- a/drivers/net/wan/n2.c +++ b/drivers/net/wan/n2.c @@ -7,7 +7,7 @@ * under the terms of version 2 of the GNU General Public License * as published by the Free Software Foundation. * - * For information see http://hq.pm.waw.pl/hdlc/ + * For information see <http://www.kernel.org/pub/linux/utils/net/hdlc/> * * Note: integrated CSU/DSU/DDS are not supported by this driver * @@ -387,6 +387,11 @@ static int __init n2_run(unsigned long io, unsigned long irq, } card->phy_winbase = winbase; card->winbase = ioremap(winbase, USE_WINDOWSIZE); + if (!card->winbase) { + printk(KERN_ERR "n2: ioremap() failed\n"); + n2_destroy_card(card); + return -EFAULT; + } outb(0, io + N2_PCR); outb(winbase >> 12, io + N2_BAR); diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index a3e65d1bc19..567effff4a3 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c @@ -3445,9 +3445,9 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) card = (pc300_t *) kmalloc(sizeof(pc300_t), GFP_KERNEL); if (card == NULL) { - printk("PC300 found at RAM 0x%08lx, " + printk("PC300 found at RAM 0x%016llx, " "but could not allocate card structure.\n", - pci_resource_start(pdev, 3)); + (unsigned long long)pci_resource_start(pdev, 3)); err = -ENOMEM; goto err_disable_dev; } @@ -3600,7 +3600,7 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } /* Allocate IRQ */ - if (request_irq(card->hw.irq, cpc_intr, SA_SHIRQ, "Cyclades-PC300", card)) { + if (request_irq(card->hw.irq, cpc_intr, IRQF_SHARED, "Cyclades-PC300", card)) { printk ("PC300 found at RAM 0x%08x, but could not allocate IRQ%d.\n", card->hw.ramphys, card->hw.irq); goto err_io_unmap; diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index f485a97844c..4df61fa3214 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c @@ -7,7 +7,7 @@ * under the terms of version 2 of the GNU General Public License * as published by the Free Software Foundation. * - * For information see http://hq.pm.waw.pl/hdlc/ + * For information see <http://www.kernel.org/pub/linux/utils/net/hdlc/> * * Sources of information: * Hitachi HD64572 SCA-II User's Manual @@ -354,6 +354,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, card->rambase == NULL) { printk(KERN_ERR "pci200syn: ioremap() failed\n"); pci200_pci_remove_one(pdev); + return -EFAULT; } /* Reset PLX */ @@ -401,7 +402,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, writew(readw(p) | 0x0040, p); /* Allocate IRQ */ - if (request_irq(pdev->irq, sca_intr, SA_SHIRQ, devname, card)) { + if (request_irq(pdev->irq, sca_intr, IRQF_SHARED, devname, card)) { printk(KERN_WARNING "pci200syn: could not allocate IRQ%d.\n", pdev->irq); pci200_pci_remove_one(pdev); diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index 175ba13bce4..fc75bec1902 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c @@ -37,7 +37,6 @@ * Known problem: this driver wasn't tested on multiprocessor machine. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/ptrace.h> @@ -1193,7 +1192,7 @@ sbni_open( struct net_device *dev ) } } - if( request_irq(dev->irq, sbni_interrupt, SA_SHIRQ, dev->name, dev) ) { + if( request_irq(dev->irq, sbni_interrupt, IRQF_SHARED, dev->name, dev) ) { printk( KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq ); return -EAGAIN; diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c index 22e794071cf..7628c2d81f4 100644 --- a/drivers/net/wan/sdla.c +++ b/drivers/net/wan/sdla.c @@ -60,9 +60,9 @@ static const char* version = "SDLA driver v0.30, 12 Sep 1996, mike.mclagan@linux.org"; -static unsigned int valid_port[] __initdata = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390}; +static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390}; -static unsigned int valid_mem[] __initdata = { +static unsigned int valid_mem[] = { 0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000, 0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000, 0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000, diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c index 050e854e777..70fb1b98b1d 100644 --- a/drivers/net/wan/sealevel.c +++ b/drivers/net/wan/sealevel.c @@ -322,7 +322,7 @@ static __init struct slvl_board *slvl_init(int iobase, int irq, /* We want a fast IRQ for this device. Actually we'd like an even faster IRQ ;) - This is one driver RtLinux is made for */ - if(request_irq(irq, &z8530_interrupt, SA_INTERRUPT, "SeaLevel", dev)<0) + if(request_irq(irq, &z8530_interrupt, IRQF_DISABLED, "SeaLevel", dev)<0) { printk(KERN_WARNING "sealevel: IRQ %d already in use.\n", irq); goto fail1_1; diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c index 2d1bba06a08..c13b459a013 100644 --- a/drivers/net/wan/syncppp.c +++ b/drivers/net/wan/syncppp.c @@ -37,7 +37,6 @@ */ #undef DEBUG -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c index 29a756dd979..d564224cdca 100644 --- a/drivers/net/wan/wanxl.c +++ b/drivers/net/wan/wanxl.c @@ -634,7 +634,13 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, /* set up PLX mapping */ plx_phy = pci_resource_start(pdev, 0); + card->plx = ioremap_nocache(plx_phy, 0x70); + if (!card->plx) { + printk(KERN_ERR "wanxl: ioremap() failed\n"); + wanxl_pci_remove_one(pdev); + return -EFAULT; + } #if RESET_WHILE_LOADING wanxl_reset(card); @@ -700,6 +706,12 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, } mem = ioremap_nocache(mem_phy, PDM_OFFSET + sizeof(firmware)); + if (!mem) { + printk(KERN_ERR "wanxl: ioremap() failed\n"); + wanxl_pci_remove_one(pdev); + return -EFAULT; + } + for (i = 0; i < sizeof(firmware); i += 4) writel(htonl(*(u32*)(firmware + i)), mem + PDM_OFFSET + i); @@ -743,7 +755,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, pci_name(pdev), plx_phy, ramsize / 1024, mem_phy, pdev->irq); /* Allocate IRQ */ - if (request_irq(pdev->irq, wanxl_intr, SA_SHIRQ, "wanXL", card)) { + if (request_irq(pdev->irq, wanxl_intr, IRQF_SHARED, "wanXL", card)) { printk(KERN_WARNING "wanXL %s: could not allocate IRQ%i.\n", pci_name(pdev), pdev->irq); wanxl_pci_remove_one(pdev); diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 4069b79d825..a4dd1394271 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -19,7 +19,6 @@ ======================================================================*/ -#include <linux/config.h> #include <linux/init.h> #include <linux/kernel.h> @@ -2849,7 +2848,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port, reset_card (dev, 1); msleep(400); - rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev ); + rc = request_irq( dev->irq, airo_interrupt, IRQF_SHARED, dev->name, dev ); if (rc) { airo_print_err(dev->name, "register interrupt %d failed, rc %d", irq, rc); diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index af0cbb6c5c0..ac9437d497f 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c @@ -20,7 +20,6 @@ ======================================================================*/ -#include <linux/config.h> #ifdef __IN_PCMCIA_PACKAGE__ #include <pcmcia/k_compat.h> #endif diff --git a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c index 7b321f7cf35..38fac3bbcd8 100644 --- a/drivers/net/wireless/airport.c +++ b/drivers/net/wireless/airport.c @@ -14,7 +14,6 @@ #define DRIVER_NAME "airport" #define PFX DRIVER_NAME ": " -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c index bed6823d980..bb6bea4f323 100644 --- a/drivers/net/wireless/arlan-main.c +++ b/drivers/net/wireless/arlan-main.c @@ -5,7 +5,6 @@ * This module provides support for the Arlan 655 card made by Aironet */ -#include <linux/config.h> #include "arlan.h" #if BITS_PER_LONG != 32 diff --git a/drivers/net/wireless/arlan-proc.c b/drivers/net/wireless/arlan-proc.c index a2cca521f44..5fa985435ff 100644 --- a/drivers/net/wireless/arlan-proc.c +++ b/drivers/net/wireless/arlan-proc.c @@ -1,4 +1,3 @@ -#include <linux/config.h> #include "arlan.h" #include <linux/sysctl.h> diff --git a/drivers/net/wireless/arlan.h b/drivers/net/wireless/arlan.h index 70a6d7b83c4..3ed1df75900 100644 --- a/drivers/net/wireless/arlan.h +++ b/drivers/net/wireless/arlan.h @@ -5,7 +5,6 @@ */ #include <linux/module.h> -#include <linux/config.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/skbuff.h> diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 8606c88886f..995c7bea589 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -39,7 +39,6 @@ ******************************************************************************/ -#include <linux/config.h> #include <linux/init.h> #include <linux/kernel.h> @@ -1578,7 +1577,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, SET_NETDEV_DEV(dev, sys_dev); - if ((rc = request_irq(dev->irq, service_interrupt, SA_SHIRQ, dev->name, dev))) { + if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) { printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc); goto err_out_free; } diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index 26bf1127524..785664090bb 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -29,7 +29,6 @@ ******************************************************************************/ -#include <linux/config.h> #ifdef __IN_PCMCIA_PACKAGE__ #include <pcmcia/k_compat.h> #endif diff --git a/drivers/net/wireless/atmel_pci.c b/drivers/net/wireless/atmel_pci.c index a61b3bc6ccc..d425c3cefde 100644 --- a/drivers/net/wireless/atmel_pci.c +++ b/drivers/net/wireless/atmel_pci.c @@ -19,7 +19,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ******************************************************************************/ -#include <linux/config.h> #include <linux/pci.h> #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/net/wireless/bcm43xx/Kconfig b/drivers/net/wireless/bcm43xx/Kconfig index 25ea4748f0b..533993f538f 100644 --- a/drivers/net/wireless/bcm43xx/Kconfig +++ b/drivers/net/wireless/bcm43xx/Kconfig @@ -2,6 +2,7 @@ config BCM43XX tristate "Broadcom BCM43xx wireless support" depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && NET_RADIO && EXPERIMENTAL select FW_LOADER + select HW_RANDOM ---help--- This is an experimental driver for the Broadcom 43xx wireless chip, found in the Apple Airport Extreme and various other devices. diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h index e66fdb1f3cf..17a56828e23 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx.h @@ -1,6 +1,7 @@ #ifndef BCM43xx_H_ #define BCM43xx_H_ +#include <linux/hw_random.h> #include <linux/version.h> #include <linux/kernel.h> #include <linux/spinlock.h> @@ -82,6 +83,7 @@ #define BCM43xx_MMIO_TSF_1 0x634 /* core rev < 3 only */ #define BCM43xx_MMIO_TSF_2 0x636 /* core rev < 3 only */ #define BCM43xx_MMIO_TSF_3 0x638 /* core rev < 3 only */ +#define BCM43xx_MMIO_RNG 0x65A #define BCM43xx_MMIO_POWERUP_DELAY 0x6A8 /* SPROM offsets. */ @@ -636,6 +638,17 @@ struct bcm43xx_key { u8 algorithm; }; +/* Driver initialization status. */ +enum { + BCM43xx_STAT_UNINIT, /* Uninitialized. */ + BCM43xx_STAT_INITIALIZING, /* init_board() in progress. */ + BCM43xx_STAT_INITIALIZED, /* Fully operational. */ + BCM43xx_STAT_SHUTTINGDOWN, /* free_board() in progress. */ + BCM43xx_STAT_RESTARTING, /* controller_restart() called. */ +}; +#define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status) +#define bcm43xx_set_status(bcm, stat) atomic_set(&(bcm)->init_status, (stat)) + struct bcm43xx_private { struct ieee80211_device *ieee; struct ieee80211softmac_device *softmac; @@ -646,18 +659,17 @@ struct bcm43xx_private { void __iomem *mmio_addr; - /* Do not use the lock directly. Use the bcm43xx_lock* helper - * functions, to be MMIO-safe. */ - spinlock_t _lock; + /* Locking, see "theory of locking" text below. */ + spinlock_t irq_lock; + struct mutex mutex; + + /* Driver initialization status BCM43xx_STAT_*** */ + atomic_t init_status; - /* Driver status flags. */ - u32 initialized:1, /* init_board() succeed */ - was_initialized:1, /* for PCI suspend/resume. */ - shutting_down:1, /* free_board() in progress */ + u16 was_initialized:1, /* for PCI suspend/resume. */ __using_pio:1, /* Internal, use bcm43xx_using_pio(). */ bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */ reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */ - powersaving:1, /* TRUE if we are in PowerSaving mode. FALSE otherwise. */ short_preamble:1, /* TRUE, if short preamble is enabled. */ firmware_norelease:1; /* Do not release the firmware. Used on suspend. */ @@ -721,7 +733,7 @@ struct bcm43xx_private { struct tasklet_struct isr_tasklet; /* Periodic tasks */ - struct timer_list periodic_tasks; + struct work_struct periodic_work; unsigned int periodic_state; struct work_struct restart_work; @@ -740,27 +752,65 @@ struct bcm43xx_private { const struct firmware *initvals0; const struct firmware *initvals1; + /* Random Number Generator. */ + struct hwrng rng; + char rng_name[20 + 1]; + /* Debugging stuff follows. */ #ifdef CONFIG_BCM43XX_DEBUG struct bcm43xx_dfsentry *dfsentry; #endif }; -/* bcm43xx_(un)lock() protect struct bcm43xx_private. - * Note that _NO_ MMIO writes are allowed. If you want to - * write to the device through MMIO in the critical section, use - * the *_mmio lock functions. - * MMIO read-access is allowed, though. - */ -#define bcm43xx_lock(bcm, flags) spin_lock_irqsave(&(bcm)->_lock, flags) -#define bcm43xx_unlock(bcm, flags) spin_unlock_irqrestore(&(bcm)->_lock, flags) -/* bcm43xx_(un)lock_mmio() protect struct bcm43xx_private and MMIO. - * MMIO write-access to the device is allowed. - * All MMIO writes are flushed on unlock, so it is guaranteed to not - * interfere with other threads writing MMIO registers. + +/* *** THEORY OF LOCKING *** + * + * We have two different locks in the bcm43xx driver. + * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private + * and the device registers. + * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency. + * + * We have three types of helper function pairs to utilize these locks. + * (Always use the helper functions.) + * 1) bcm43xx_{un}lock_noirq(): + * Takes bcm->mutex. Does _not_ protect against IRQ concurrency, + * so it is almost always unsafe, if device IRQs are enabled. + * So only use this, if device IRQs are masked. + * Locking may sleep. + * You can sleep within the critical section. + * 2) bcm43xx_{un}lock_irqonly(): + * Takes bcm->irq_lock. Does _not_ protect against + * bcm43xx_lock_noirq() critical sections. + * Does only protect against the IRQ handler path and other + * irqonly() critical sections. + * Locking does not sleep. + * You must not sleep within the critical section. + * 3) bcm43xx_{un}lock_irqsafe(): + * This is the cummulative lock and takes both, mutex and irq_lock. + * Protects against noirq() and irqonly() critical sections (and + * the IRQ handler path). + * Locking may sleep. + * You must not sleep within the critical section. */ -#define bcm43xx_lock_mmio(bcm, flags) bcm43xx_lock(bcm, flags) -#define bcm43xx_unlock_mmio(bcm, flags) do { mmiowb(); bcm43xx_unlock(bcm, flags); } while (0) + +/* Lock type 1 */ +#define bcm43xx_lock_noirq(bcm) mutex_lock(&(bcm)->mutex) +#define bcm43xx_unlock_noirq(bcm) mutex_unlock(&(bcm)->mutex) +/* Lock type 2 */ +#define bcm43xx_lock_irqonly(bcm, flags) \ + spin_lock_irqsave(&(bcm)->irq_lock, flags) +#define bcm43xx_unlock_irqonly(bcm, flags) \ + spin_unlock_irqrestore(&(bcm)->irq_lock, flags) +/* Lock type 3 */ +#define bcm43xx_lock_irqsafe(bcm, flags) do { \ + bcm43xx_lock_noirq(bcm); \ + bcm43xx_lock_irqonly(bcm, flags); \ + } while (0) +#define bcm43xx_unlock_irqsafe(bcm, flags) do { \ + bcm43xx_unlock_irqonly(bcm, flags); \ + bcm43xx_unlock_noirq(bcm); \ + } while (0) + static inline struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) @@ -843,16 +893,6 @@ struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm) return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio); } -/* Are we running in init_board() context? */ -static inline -int bcm43xx_is_initializing(struct bcm43xx_private *bcm) -{ - if (bcm->initialized) - return 0; - if (bcm->shutting_down) - return 0; - return 1; -} static inline struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy, diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c index 7497fb16076..ce2e40b29b4 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c @@ -77,8 +77,8 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf, down(&big_buffer_sem); - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { fappend("Board not initialized.\n"); goto out; } @@ -121,7 +121,7 @@ static ssize_t devinfo_read_file(struct file *file, char __user *userbuf, fappend("\n"); out: - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); up(&big_buffer_sem); return res; @@ -159,8 +159,8 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf, unsigned long flags; down(&big_buffer_sem); - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { fappend("Board not initialized.\n"); goto out; } @@ -169,7 +169,7 @@ static ssize_t spromdump_read_file(struct file *file, char __user *userbuf, fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags); out: - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); up(&big_buffer_sem); return res; @@ -188,8 +188,8 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf, u64 tsf; down(&big_buffer_sem); - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { fappend("Board not initialized.\n"); goto out; } @@ -199,7 +199,7 @@ static ssize_t tsf_read_file(struct file *file, char __user *userbuf, (unsigned int)(tsf & 0xFFFFFFFFULL)); out: - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); up(&big_buffer_sem); return res; @@ -221,8 +221,8 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf, res = -EFAULT; goto out_up; } - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) { printk(KERN_INFO PFX "debugfs: Board not initialized.\n"); res = -EFAULT; goto out_unlock; @@ -233,10 +233,11 @@ static ssize_t tsf_write_file(struct file *file, const char __user *user_buf, goto out_unlock; } bcm43xx_tsf_write(bcm, tsf); + mmiowb(); res = buf_size; out_unlock: - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); out_up: up(&big_buffer_sem); return res; @@ -257,7 +258,7 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf, int i, cnt, j = 0; down(&big_buffer_sem); - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); fappend("Last %d logged xmitstatus blobs (Latest first):\n\n", BCM43xx_NR_LOGGED_XMITSTATUS); @@ -293,14 +294,14 @@ static ssize_t txstat_read_file(struct file *file, char __user *userbuf, i = BCM43xx_NR_LOGGED_XMITSTATUS - 1; } - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); if (*ppos == pos) { /* Done. Drop the copied data. */ e->xmitstatus_printing = 0; } - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); up(&big_buffer_sem); return res; } diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c index 4b2c02c0b31..ec80692d638 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c @@ -51,12 +51,12 @@ static void bcm43xx_led_blink(unsigned long d) struct bcm43xx_private *bcm = led->bcm; unsigned long flags; - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqonly(bcm, flags); if (led->blink_interval) { bcm43xx_led_changestate(led); mod_timer(&led->blink_timer, jiffies + led->blink_interval); } - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqonly(bcm, flags); } static void bcm43xx_led_blink_start(struct bcm43xx_led *led, diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 736dde96c4a..d8f5600578b 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -498,20 +498,31 @@ static inline u32 bcm43xx_interrupt_disable(struct bcm43xx_private *bcm, u32 mas return old_mask; } +/* Synchronize IRQ top- and bottom-half. + * IRQs must be masked before calling this. + * This must not be called with the irq_lock held. + */ +static void bcm43xx_synchronize_irq(struct bcm43xx_private *bcm) +{ + synchronize_irq(bcm->irq); + tasklet_disable(&bcm->isr_tasklet); +} + /* Make sure we don't receive more data from the device. */ static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *oldstate) { - u32 old; unsigned long flags; + u32 old; - bcm43xx_lock_mmio(bcm, flags); - if (bcm43xx_is_initializing(bcm) || bcm->shutting_down) { - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_lock_irqonly(bcm, flags); + if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) { + bcm43xx_unlock_irqonly(bcm, flags); return -EBUSY; } old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - tasklet_disable(&bcm->isr_tasklet); - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqonly(bcm, flags); + bcm43xx_synchronize_irq(bcm); + if (oldstate) *oldstate = old; @@ -1389,7 +1400,7 @@ void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy) bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE); #endif } - if (bcm->shutting_down) { + if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) { bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002)); @@ -1709,7 +1720,7 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) # define bcmirq_handled(irq) do { /* nothing */ } while (0) #endif /* CONFIG_BCM43XX_DEBUG*/ - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqonly(bcm, flags); reason = bcm->irq_reason; dma_reason[0] = bcm->dma_reason[0]; dma_reason[1] = bcm->dma_reason[1]; @@ -1734,7 +1745,8 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) dma_reason[0], dma_reason[1], dma_reason[2], dma_reason[3]); bcm43xx_controller_restart(bcm, "DMA error"); - bcm43xx_unlock_mmio(bcm, flags); + mmiowb(); + bcm43xx_unlock_irqonly(bcm, flags); return; } if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) | @@ -1821,7 +1833,8 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) if (!modparam_noleds) bcm43xx_leds_update(bcm, activity); bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); - bcm43xx_unlock_mmio(bcm, flags); + mmiowb(); + bcm43xx_unlock_irqonly(bcm, flags); } static void pio_irq_workaround(struct bcm43xx_private *bcm, @@ -1870,7 +1883,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re if (!bcm) return IRQ_NONE; - spin_lock(&bcm->_lock); + spin_lock(&bcm->irq_lock); reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); if (reason == 0xffffffff) { @@ -1899,7 +1912,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re * completely, but some careful work is needed to fix this. I think it * is best to stay with this cheap workaround for now... . */ - if (likely(bcm->initialized)) { + if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) { /* disable all IRQs. They are enabled again in the bottom half. */ bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); /* save the reason code and call our bottom half. */ @@ -1909,7 +1922,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re out: mmiowb(); - spin_unlock(&bcm->_lock); + spin_unlock(&bcm->irq_lock); return ret; } @@ -2133,6 +2146,13 @@ out: return err; } +#ifdef CONFIG_BCM947XX +static struct pci_device_id bcm43xx_47xx_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) }, + { 0 } +}; +#endif + static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm) { int res; @@ -2142,16 +2162,20 @@ static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm) bcm->irq = bcm->pci_dev->irq; #ifdef CONFIG_BCM947XX if (bcm->pci_dev->bus->number == 0) { - struct pci_dev *d = NULL; - /* FIXME: we will probably need more device IDs here... */ - d = pci_find_device(PCI_VENDOR_ID_BROADCOM, 0x4324, NULL); - if (d != NULL) { - bcm->irq = d->irq; + struct pci_dev *d; + struct pci_device_id *id; + for (id = bcm43xx_47xx_ids; id->vendor; id++) { + d = pci_get_device(id->vendor, id->device, NULL); + if (d != NULL) { + bcm->irq = d->irq; + pci_dev_put(d); + break; + } } } #endif res = request_irq(bcm->irq, bcm43xx_interrupt_handler, - SA_SHIRQ, KBUILD_MODNAME, bcm); + IRQF_SHARED, KBUILD_MODNAME, bcm); if (res) { printk(KERN_ERR PFX "Cannot register IRQ%d\n", bcm->irq); return -ENODEV; @@ -3106,15 +3130,10 @@ static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm) //TODO for APHY (temperature?) } -static void bcm43xx_periodic_task_handler(unsigned long d) +static void do_periodic_work(struct bcm43xx_private *bcm) { - struct bcm43xx_private *bcm = (struct bcm43xx_private *)d; - unsigned long flags; unsigned int state; - bcm43xx_lock_mmio(bcm, flags); - - assert(bcm->initialized); state = bcm->periodic_state; if (state % 8 == 0) bcm43xx_periodic_every120sec(bcm); @@ -3122,29 +3141,93 @@ static void bcm43xx_periodic_task_handler(unsigned long d) bcm43xx_periodic_every60sec(bcm); if (state % 2 == 0) bcm43xx_periodic_every30sec(bcm); - bcm43xx_periodic_every15sec(bcm); + if (state % 1 == 0) + bcm43xx_periodic_every15sec(bcm); bcm->periodic_state = state + 1; - mod_timer(&bcm->periodic_tasks, jiffies + (HZ * 15)); + schedule_delayed_work(&bcm->periodic_work, HZ * 15); +} + +/* Estimate a "Badness" value based on the periodic work + * state-machine state. "Badness" is worse (bigger), if the + * periodic work will take longer. + */ +static int estimate_periodic_work_badness(unsigned int state) +{ + int badness = 0; - bcm43xx_unlock_mmio(bcm, flags); + if (state % 8 == 0) /* every 120 sec */ + badness += 10; + if (state % 4 == 0) /* every 60 sec */ + badness += 5; + if (state % 2 == 0) /* every 30 sec */ + badness += 1; + if (state % 1 == 0) /* every 15 sec */ + badness += 1; + +#define BADNESS_LIMIT 4 + return badness; +} + +static void bcm43xx_periodic_work_handler(void *d) +{ + struct bcm43xx_private *bcm = d; + unsigned long flags; + u32 savedirqs = 0; + int badness; + + badness = estimate_periodic_work_badness(bcm->periodic_state); + if (badness > BADNESS_LIMIT) { + /* Periodic work will take a long time, so we want it to + * be preemtible. + */ + bcm43xx_lock_irqonly(bcm, flags); + netif_stop_queue(bcm->net_dev); + if (bcm43xx_using_pio(bcm)) + bcm43xx_pio_freeze_txqueues(bcm); + savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); + bcm43xx_unlock_irqonly(bcm, flags); + bcm43xx_lock_noirq(bcm); + bcm43xx_synchronize_irq(bcm); + } else { + /* Periodic work should take short time, so we want low + * locking overhead. + */ + bcm43xx_lock_irqsafe(bcm, flags); + } + + do_periodic_work(bcm); + + if (badness > BADNESS_LIMIT) { + bcm43xx_lock_irqonly(bcm, flags); + if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) { + tasklet_enable(&bcm->isr_tasklet); + bcm43xx_interrupt_enable(bcm, savedirqs); + if (bcm43xx_using_pio(bcm)) + bcm43xx_pio_thaw_txqueues(bcm); + } + netif_wake_queue(bcm->net_dev); + mmiowb(); + bcm43xx_unlock_irqonly(bcm, flags); + bcm43xx_unlock_noirq(bcm); + } else { + mmiowb(); + bcm43xx_unlock_irqsafe(bcm, flags); + } } static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) { - del_timer_sync(&bcm->periodic_tasks); + cancel_rearming_delayed_work(&bcm->periodic_work); } static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) { - struct timer_list *timer = &(bcm->periodic_tasks); + struct work_struct *work = &(bcm->periodic_work); - assert(bcm->initialized); - setup_timer(timer, - bcm43xx_periodic_task_handler, - (unsigned long)bcm); - timer->expires = jiffies; - add_timer(timer); + assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); + INIT_WORK(work, bcm43xx_periodic_work_handler, bcm); + schedule_work(work); } static void bcm43xx_security_init(struct bcm43xx_private *bcm) @@ -3154,21 +3237,51 @@ static void bcm43xx_security_init(struct bcm43xx_private *bcm) bcm43xx_clear_keys(bcm); } +static int bcm43xx_rng_read(struct hwrng *rng, u32 *data) +{ + struct bcm43xx_private *bcm = (struct bcm43xx_private *)rng->priv; + unsigned long flags; + + bcm43xx_lock_irqonly(bcm, flags); + *data = bcm43xx_read16(bcm, BCM43xx_MMIO_RNG); + bcm43xx_unlock_irqonly(bcm, flags); + + return (sizeof(u16)); +} + +static void bcm43xx_rng_exit(struct bcm43xx_private *bcm) +{ + hwrng_unregister(&bcm->rng); +} + +static int bcm43xx_rng_init(struct bcm43xx_private *bcm) +{ + int err; + + snprintf(bcm->rng_name, ARRAY_SIZE(bcm->rng_name), + "%s_%s", KBUILD_MODNAME, bcm->net_dev->name); + bcm->rng.name = bcm->rng_name; + bcm->rng.data_read = bcm43xx_rng_read; + bcm->rng.priv = (unsigned long)bcm; + err = hwrng_register(&bcm->rng); + if (err) + printk(KERN_ERR PFX "RNG init failed (%d)\n", err); + + return err; +} + /* This is the opposite of bcm43xx_init_board() */ static void bcm43xx_free_board(struct bcm43xx_private *bcm) { int i, err; - unsigned long flags; + bcm43xx_lock_noirq(bcm); bcm43xx_sysfs_unregister(bcm); - bcm43xx_periodic_tasks_delete(bcm); - bcm43xx_lock(bcm, flags); - bcm->initialized = 0; - bcm->shutting_down = 1; - bcm43xx_unlock(bcm, flags); + bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN); + bcm43xx_rng_exit(bcm); for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { if (!bcm->core_80211[i].available) continue; @@ -3182,23 +3295,19 @@ static void bcm43xx_free_board(struct bcm43xx_private *bcm) bcm43xx_pctl_set_crystal(bcm, 0); - bcm43xx_lock(bcm, flags); - bcm->shutting_down = 0; - bcm43xx_unlock(bcm, flags); + bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); + bcm43xx_unlock_noirq(bcm); } static int bcm43xx_init_board(struct bcm43xx_private *bcm) { int i, err; int connect_phy; - unsigned long flags; might_sleep(); - bcm43xx_lock(bcm, flags); - bcm->initialized = 0; - bcm->shutting_down = 0; - bcm43xx_unlock(bcm, flags); + bcm43xx_lock_noirq(bcm); + bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING); err = bcm43xx_pctl_set_crystal(bcm, 1); if (err) @@ -3250,6 +3359,9 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) bcm43xx_switch_core(bcm, &bcm->core_80211[0]); bcm43xx_mac_enable(bcm); } + err = bcm43xx_rng_init(bcm); + if (err) + goto err_80211_unwind; bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC); bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr)); dprintk(KERN_INFO PFX "80211 cores initialized\n"); @@ -3265,9 +3377,7 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) } /* Initialization of the board is done. Flag it as such. */ - bcm43xx_lock(bcm, flags); - bcm->initialized = 1; - bcm43xx_unlock(bcm, flags); + bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED); bcm43xx_periodic_tasks_setup(bcm); bcm43xx_sysfs_register(bcm); @@ -3278,6 +3388,8 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) assert(err == 0); out: + bcm43xx_unlock_noirq(bcm); + return err; err_80211_unwind: @@ -3534,8 +3646,8 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev, struct bcm43xx_radioinfo *radio; unsigned long flags; - bcm43xx_lock_mmio(bcm, flags); - if (bcm->initialized) { + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { bcm43xx_mac_suspend(bcm); bcm43xx_radio_selectchannel(bcm, channel, 0); bcm43xx_mac_enable(bcm); @@ -3543,7 +3655,7 @@ static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev, radio = bcm43xx_current_radio(bcm); radio->initial_channel = channel; } - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); } /* set_security() callback in struct ieee80211_device */ @@ -3557,7 +3669,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, dprintk(KERN_INFO PFX "set security called"); - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) if (sec->flags & (1<<keyidx)) { @@ -3587,7 +3699,8 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, dprintk(", .encrypt = %d", sec->encrypt); } dprintk("\n"); - if (bcm->initialized && !bcm->ieee->host_encrypt) { + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED && + !bcm->ieee->host_encrypt) { if (secinfo->enabled) { /* upload WEP keys to hardware */ char null_address[6] = { 0 }; @@ -3621,7 +3734,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, } else bcm43xx_clear_keys(bcm); } - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); } /* hard_start_xmit() callback in struct ieee80211_device */ @@ -3633,10 +3746,10 @@ static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb, int err = -ENODEV; unsigned long flags; - bcm43xx_lock_mmio(bcm, flags); - if (likely(bcm->initialized)) + bcm43xx_lock_irqonly(bcm, flags); + if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) err = bcm43xx_tx(bcm, txb); - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqonly(bcm, flags); return err; } @@ -3651,9 +3764,9 @@ static void bcm43xx_net_tx_timeout(struct net_device *net_dev) struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqonly(bcm, flags); bcm43xx_controller_restart(bcm, "TX timeout"); - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqonly(bcm, flags); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -3678,9 +3791,11 @@ static int bcm43xx_net_open(struct net_device *net_dev) static int bcm43xx_net_stop(struct net_device *net_dev) { struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); + int err; ieee80211softmac_stop(net_dev); - bcm43xx_disable_interrupts_sync(bcm, NULL); + err = bcm43xx_disable_interrupts_sync(bcm, NULL); + assert(!err); bcm43xx_free_board(bcm); return 0; @@ -3692,6 +3807,7 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, { int err; + bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); bcm->ieee = netdev_priv(net_dev); bcm->softmac = ieee80211_priv(net_dev); bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan; @@ -3700,7 +3816,8 @@ static int bcm43xx_init_private(struct bcm43xx_private *bcm, bcm->pci_dev = pci_dev; bcm->net_dev = net_dev; bcm->bad_frames_preempt = modparam_bad_frames_preempt; - spin_lock_init(&bcm->_lock); + spin_lock_init(&bcm->irq_lock); + mutex_init(&bcm->mutex); tasklet_init(&bcm->isr_tasklet, (void (*)(unsigned long))bcm43xx_interrupt_tasklet, (unsigned long)bcm); @@ -3831,7 +3948,7 @@ static void bcm43xx_chip_reset(void *_bcm) struct net_device *net_dev = bcm->net_dev; struct pci_dev *pci_dev = bcm->pci_dev; int err; - int was_initialized = bcm->initialized; + int was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); netif_stop_queue(bcm->net_dev); tasklet_disable(&bcm->isr_tasklet); @@ -3866,6 +3983,7 @@ failure: */ void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason) { + bcm43xx_set_status(bcm, BCM43xx_STAT_RESTARTING); bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason); @@ -3884,11 +4002,11 @@ static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state) dprintk(KERN_INFO PFX "Suspending...\n"); - bcm43xx_lock(bcm, flags); - bcm->was_initialized = bcm->initialized; - if (bcm->initialized) + bcm43xx_lock_irqsafe(bcm, flags); + bcm->was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); + if (bcm->was_initialized) try_to_shutdown = 1; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); netif_device_detach(net_dev); if (try_to_shutdown) { diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c index b0abac51553..f8200deecc8 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c @@ -1410,7 +1410,10 @@ static inline u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control) { struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); + u16 ret; + unsigned long flags; + local_irq_save(flags); if (phy->connected) { bcm43xx_phy_write(bcm, 0x15, 0xE300); control <<= 8; @@ -1430,8 +1433,10 @@ u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control) bcm43xx_phy_write(bcm, 0x0015, control | 0xFFE0); udelay(8); } + ret = bcm43xx_phy_read(bcm, 0x002D); + local_irq_restore(flags); - return bcm43xx_phy_read(bcm, 0x002D); + return ret; } static u32 bcm43xx_phy_lo_g_singledeviation(struct bcm43xx_private *bcm, u16 control) @@ -1648,7 +1653,7 @@ void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm, void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm) { static const u8 pairorder[10] = { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8 }; - const int is_initializing = bcm43xx_is_initializing(bcm); + const int is_initializing = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZING); struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); u16 h, i, oldi = 0, j; diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c index 0aa1bd269a2..574085c4615 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c @@ -262,8 +262,10 @@ static void tx_tasklet(unsigned long d) int err; u16 txctl; - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqonly(bcm, flags); + if (queue->tx_frozen) + goto out_unlock; txctl = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL); if (txctl & BCM43xx_PIO_TXCTL_SUSPEND) goto out_unlock; @@ -298,7 +300,7 @@ static void tx_tasklet(unsigned long d) continue; } out_unlock: - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqonly(bcm, flags); } static void setup_txqueues(struct bcm43xx_pioqueue *queue) @@ -374,7 +376,6 @@ static void cancel_transfers(struct bcm43xx_pioqueue *queue) struct bcm43xx_pio_txpacket *packet, *tmp_packet; netif_tx_disable(queue->bcm->net_dev); - assert(queue->bcm->shutting_down); tasklet_disable(&queue->txtask); list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) @@ -634,5 +635,40 @@ void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue) bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL) & ~BCM43xx_PIO_TXCTL_SUSPEND); bcm43xx_power_saving_ctl_bits(queue->bcm, -1, -1); - tasklet_schedule(&queue->txtask); + if (!list_empty(&queue->txqueue)) + tasklet_schedule(&queue->txtask); +} + +void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm) +{ + struct bcm43xx_pio *pio; + + assert(bcm43xx_using_pio(bcm)); + pio = bcm43xx_current_pio(bcm); + pio->queue0->tx_frozen = 1; + pio->queue1->tx_frozen = 1; + pio->queue2->tx_frozen = 1; + pio->queue3->tx_frozen = 1; } + +void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm) +{ + struct bcm43xx_pio *pio; + + assert(bcm43xx_using_pio(bcm)); + pio = bcm43xx_current_pio(bcm); + pio->queue0->tx_frozen = 0; + pio->queue1->tx_frozen = 0; + pio->queue2->tx_frozen = 0; + pio->queue3->tx_frozen = 0; + if (!list_empty(&pio->queue0->txqueue)) + tasklet_schedule(&pio->queue0->txtask); + if (!list_empty(&pio->queue1->txqueue)) + tasklet_schedule(&pio->queue1->txtask); + if (!list_empty(&pio->queue2->txqueue)) + tasklet_schedule(&pio->queue2->txtask); + if (!list_empty(&pio->queue3->txqueue)) + tasklet_schedule(&pio->queue3->txtask); +} + + diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h index dfc78209e3a..bc78a3c2caf 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h @@ -54,6 +54,7 @@ struct bcm43xx_pioqueue { u16 mmio_base; u8 tx_suspended:1, + tx_frozen:1, need_workarounds:1; /* Workarounds needed for core.rev < 3 */ /* Adjusted size of the device internal TX buffer. */ @@ -108,8 +109,12 @@ void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm, struct bcm43xx_xmitstatus *status); void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue); +/* Suspend a TX queue on hardware level. */ void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue); void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue); +/* Suspend (freeze) the TX tasklet (software level). */ +void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm); +void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm); #else /* CONFIG_BCM43XX_PIO */ @@ -145,6 +150,14 @@ static inline void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue) { } +static inline +void bcm43xx_pio_freeze_txqueues(struct bcm43xx_private *bcm) +{ +} +static inline +void bcm43xx_pio_thaw_txqueues(struct bcm43xx_private *bcm) +{ +} #endif /* CONFIG_BCM43XX_PIO */ #endif /* BCM43xx_PIO_H_ */ diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c index b438f48e891..6a23bdc7541 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c @@ -120,12 +120,12 @@ static ssize_t bcm43xx_attr_sprom_show(struct device *dev, GFP_KERNEL); if (!sprom) return -ENOMEM; - bcm43xx_lock_mmio(bcm, flags); - assert(bcm->initialized); + bcm43xx_lock_irqsafe(bcm, flags); err = bcm43xx_sprom_read(bcm, sprom); if (!err) err = sprom2hex(sprom, buf, PAGE_SIZE); - bcm43xx_unlock_mmio(bcm, flags); + mmiowb(); + bcm43xx_unlock_irqsafe(bcm, flags); kfree(sprom); return err; @@ -150,10 +150,10 @@ static ssize_t bcm43xx_attr_sprom_store(struct device *dev, err = hex2sprom(sprom, buf, count); if (err) goto out_kfree; - bcm43xx_lock_mmio(bcm, flags); - assert(bcm->initialized); + bcm43xx_lock_irqsafe(bcm, flags); err = bcm43xx_sprom_write(bcm, sprom); - bcm43xx_unlock_mmio(bcm, flags); + mmiowb(); + bcm43xx_unlock_irqsafe(bcm, flags); out_kfree: kfree(sprom); @@ -170,15 +170,13 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, char *buf) { struct bcm43xx_private *bcm = dev_to_bcm(dev); - unsigned long flags; int err; ssize_t count = 0; if (!capable(CAP_NET_ADMIN)) return -EPERM; - bcm43xx_lock(bcm, flags); - assert(bcm->initialized); + bcm43xx_lock_noirq(bcm); switch (bcm43xx_current_radio(bcm)->interfmode) { case BCM43xx_RADIO_INTERFMODE_NONE: @@ -195,7 +193,7 @@ static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, } err = 0; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_noirq(bcm); return err ? err : count; @@ -231,16 +229,15 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev, return -EINVAL; } - bcm43xx_lock_mmio(bcm, flags); - assert(bcm->initialized); + bcm43xx_lock_irqsafe(bcm, flags); err = bcm43xx_radio_set_interference_mitigation(bcm, mode); if (err) { printk(KERN_ERR PFX "Interference Mitigation not " "supported by device\n"); } - - bcm43xx_unlock_mmio(bcm, flags); + mmiowb(); + bcm43xx_unlock_irqsafe(bcm, flags); return err ? err : count; } @@ -254,15 +251,13 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev, char *buf) { struct bcm43xx_private *bcm = dev_to_bcm(dev); - unsigned long flags; int err; ssize_t count; if (!capable(CAP_NET_ADMIN)) return -EPERM; - bcm43xx_lock(bcm, flags); - assert(bcm->initialized); + bcm43xx_lock_noirq(bcm); if (bcm->short_preamble) count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n"); @@ -270,7 +265,7 @@ static ssize_t bcm43xx_attr_preamble_show(struct device *dev, count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n"); err = 0; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_noirq(bcm); return err ? err : count; } @@ -290,13 +285,12 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev, value = get_boolean(buf, count); if (value < 0) return value; - bcm43xx_lock(bcm, flags); - assert(bcm->initialized); + bcm43xx_lock_irqsafe(bcm, flags); bcm->short_preamble = !!value; err = 0; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err ? err : count; } @@ -310,7 +304,7 @@ int bcm43xx_sysfs_register(struct bcm43xx_private *bcm) struct device *dev = &bcm->pci_dev->dev; int err; - assert(bcm->initialized); + assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); err = device_create_file(dev, &dev_attr_sprom); if (err) diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c index b45063974ae..c35cb3a0777 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c @@ -55,13 +55,13 @@ static int bcm43xx_wx_get_name(struct net_device *net_dev, char *extra) { struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; int i; + unsigned long flags; struct bcm43xx_phyinfo *phy; char suffix[7] = { 0 }; int have_a = 0, have_b = 0, have_g = 0; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); for (i = 0; i < bcm->nr_80211_available; i++) { phy = &(bcm->core_80211_ext[i].phy); switch (phy->type) { @@ -77,7 +77,7 @@ static int bcm43xx_wx_get_name(struct net_device *net_dev, assert(0); } } - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); i = 0; if (have_a) { @@ -111,7 +111,7 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev, int freq; int err = -EINVAL; - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); if ((data->freq.m >= 0) && (data->freq.m <= 1000)) { channel = data->freq.m; freq = bcm43xx_channel_to_freq(bcm, channel); @@ -121,7 +121,7 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev, } if (!bcm43xx_is_valid_channel(bcm, channel)) goto out_unlock; - if (bcm->initialized) { + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { //ieee80211softmac_disassoc(softmac, $REASON); bcm43xx_mac_suspend(bcm); err = bcm43xx_radio_selectchannel(bcm, channel, 0); @@ -131,7 +131,7 @@ static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev, err = 0; } out_unlock: - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err; } @@ -147,11 +147,10 @@ static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev, int err = -ENODEV; u16 channel; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); radio = bcm43xx_current_radio(bcm); channel = radio->channel; if (channel == 0xFF) { - assert(!bcm->initialized); channel = radio->initial_channel; if (channel == 0xFF) goto out_unlock; @@ -163,7 +162,7 @@ static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev, err = 0; out_unlock: - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err; } @@ -181,13 +180,13 @@ static int bcm43xx_wx_set_mode(struct net_device *net_dev, if (mode == IW_MODE_AUTO) mode = BCM43xx_INITIAL_IWMODE; - bcm43xx_lock_mmio(bcm, flags); - if (bcm->initialized) { + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { if (bcm->ieee->iw_mode != mode) bcm43xx_set_iwmode(bcm, mode); } else bcm->ieee->iw_mode = mode; - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return 0; } @@ -200,9 +199,9 @@ static int bcm43xx_wx_get_mode(struct net_device *net_dev, struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); data->mode = bcm->ieee->iw_mode; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return 0; } @@ -255,7 +254,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev, IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); phy = bcm43xx_current_phy(bcm); range->num_bitrates = 0; @@ -302,7 +301,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev, } range->num_frequency = j; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return 0; } @@ -313,14 +312,13 @@ static int bcm43xx_wx_set_nick(struct net_device *net_dev, char *extra) { struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; size_t len; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_noirq(bcm); len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE); memcpy(bcm->nick, extra, len); bcm->nick[len] = '\0'; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_noirq(bcm); return 0; } @@ -331,15 +329,14 @@ static int bcm43xx_wx_get_nick(struct net_device *net_dev, char *extra) { struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; size_t len; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_noirq(bcm); len = strlen(bcm->nick) + 1; memcpy(extra, bcm->nick, len); data->data.length = (__u16)len; data->data.flags = 1; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_noirq(bcm); return 0; } @@ -353,7 +350,7 @@ static int bcm43xx_wx_set_rts(struct net_device *net_dev, unsigned long flags; int err = -EINVAL; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); if (data->rts.disabled) { bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD; err = 0; @@ -364,7 +361,7 @@ static int bcm43xx_wx_set_rts(struct net_device *net_dev, err = 0; } } - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err; } @@ -377,11 +374,11 @@ static int bcm43xx_wx_get_rts(struct net_device *net_dev, struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); data->rts.value = bcm->rts_threshold; data->rts.fixed = 0; data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD); - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return 0; } @@ -395,7 +392,7 @@ static int bcm43xx_wx_set_frag(struct net_device *net_dev, unsigned long flags; int err = -EINVAL; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); if (data->frag.disabled) { bcm->ieee->fts = MAX_FRAG_THRESHOLD; err = 0; @@ -406,7 +403,7 @@ static int bcm43xx_wx_set_frag(struct net_device *net_dev, err = 0; } } - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err; } @@ -419,11 +416,11 @@ static int bcm43xx_wx_get_frag(struct net_device *net_dev, struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); unsigned long flags; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); data->frag.value = bcm->ieee->fts; data->frag.fixed = 0; data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD); - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return 0; } @@ -445,8 +442,8 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev, return -EOPNOTSUPP; } - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) goto out_unlock; radio = bcm43xx_current_radio(bcm); phy = bcm43xx_current_phy(bcm); @@ -469,7 +466,7 @@ static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev, err = 0; out_unlock: - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err; } @@ -484,8 +481,8 @@ static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev, unsigned long flags; int err = -ENODEV; - bcm43xx_lock(bcm, flags); - if (!bcm->initialized) + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) goto out_unlock; radio = bcm43xx_current_radio(bcm); /* desired dBm value is in Q5.2 */ @@ -496,7 +493,7 @@ static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev, err = 0; out_unlock: - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err; } @@ -583,8 +580,8 @@ static int bcm43xx_wx_set_interfmode(struct net_device *net_dev, return -EINVAL; } - bcm43xx_lock_mmio(bcm, flags); - if (bcm->initialized) { + bcm43xx_lock_irqsafe(bcm, flags); + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) { err = bcm43xx_radio_set_interference_mitigation(bcm, mode); if (err) { printk(KERN_ERR PFX "Interference Mitigation not " @@ -598,7 +595,7 @@ static int bcm43xx_wx_set_interfmode(struct net_device *net_dev, } else bcm43xx_current_radio(bcm)->interfmode = mode; } - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return err; } @@ -612,9 +609,9 @@ static int bcm43xx_wx_get_interfmode(struct net_device *net_dev, unsigned long flags; int mode; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); mode = bcm43xx_current_radio(bcm)->interfmode; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); switch (mode) { case BCM43xx_RADIO_INTERFMODE_NONE: @@ -644,9 +641,9 @@ static int bcm43xx_wx_set_shortpreamble(struct net_device *net_dev, int on; on = *((int *)extra); - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); bcm->short_preamble = !!on; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return 0; } @@ -660,9 +657,9 @@ static int bcm43xx_wx_get_shortpreamble(struct net_device *net_dev, unsigned long flags; int on; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); on = bcm->short_preamble; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); if (on) strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING); @@ -684,11 +681,11 @@ static int bcm43xx_wx_set_swencryption(struct net_device *net_dev, on = *((int *)extra); - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); bcm->ieee->host_encrypt = !!on; bcm->ieee->host_decrypt = !!on; bcm->ieee->host_build_iv = !on; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); return 0; } @@ -702,9 +699,9 @@ static int bcm43xx_wx_get_swencryption(struct net_device *net_dev, unsigned long flags; int on; - bcm43xx_lock(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); on = bcm->ieee->host_encrypt; - bcm43xx_unlock(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); if (on) strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING); @@ -767,11 +764,11 @@ static int bcm43xx_wx_sprom_read(struct net_device *net_dev, if (!sprom) goto out; - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); err = -ENODEV; - if (bcm->initialized) + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) err = bcm43xx_sprom_read(bcm, sprom); - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); if (!err) data->data.length = sprom2hex(sprom, extra); kfree(sprom); @@ -812,11 +809,11 @@ static int bcm43xx_wx_sprom_write(struct net_device *net_dev, if (err) goto out_kfree; - bcm43xx_lock_mmio(bcm, flags); + bcm43xx_lock_irqsafe(bcm, flags); err = -ENODEV; - if (bcm->initialized) + if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) err = bcm43xx_sprom_write(bcm, sprom); - bcm43xx_unlock_mmio(bcm, flags); + bcm43xx_unlock_irqsafe(bcm, flags); out_kfree: kfree(sprom); out: diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c index 2aa2f389c0d..29d39105f5b 100644 --- a/drivers/net/wireless/hermes.c +++ b/drivers/net/wireless/hermes.c @@ -38,7 +38,6 @@ * under either the MPL or the GPL. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index db03dc2646d..52e6df5c1a9 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -1,6 +1,5 @@ #define PRISM2_PCCARD -#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/if.h> @@ -844,7 +843,7 @@ static struct pcmcia_device_id hostap_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x02d2, 0x0001), PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x0001), PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), - PCMCIA_DEVICE_MANF_CARD(0xc00f, 0x0000), +/* PCMCIA_DEVICE_MANF_CARD(0xc00f, 0x0000), conflict with pcnet_cs */ PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0010), diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index 328e9a1d13b..b764cfda6e8 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -30,7 +30,6 @@ */ -#include <linux/config.h> #include <asm/delay.h> #include <asm/uaccess.h> diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 93786f4218f..53374fcba77 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c @@ -12,7 +12,6 @@ * more details. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c index 194f0709758..c2fa011be29 100644 --- a/drivers/net/wireless/hostap/hostap_pci.c +++ b/drivers/net/wireless/hostap/hostap_pci.c @@ -4,7 +4,6 @@ * driver patches from Reyk Floeter <reyk@vantronix.net> and * Andy Warner <andyw@pobox.com> */ -#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/if.h> @@ -338,7 +337,7 @@ static int prism2_pci_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, dev); - if (request_irq(dev->irq, prism2_interrupt, SA_SHIRQ, dev->name, + if (request_irq(dev->irq, prism2_interrupt, IRQF_SHARED, dev->name, dev)) { printk(KERN_WARNING "%s: request_irq failed\n", dev->name); goto fail; diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c index edaaa943eb8..49860fa61c3 100644 --- a/drivers/net/wireless/hostap/hostap_plx.c +++ b/drivers/net/wireless/hostap/hostap_plx.c @@ -7,7 +7,6 @@ */ -#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/if.h> @@ -551,7 +550,7 @@ static int prism2_plx_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, dev); - if (request_irq(dev->irq, prism2_interrupt, SA_SHIRQ, dev->name, + if (request_irq(dev->irq, prism2_interrupt, IRQF_SHARED, dev->name, dev)) { printk(KERN_WARNING "%s: request_irq failed\n", dev->name); goto fail; diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c index 72335c8eb97..e955db435b3 100644 --- a/drivers/net/wireless/ipw2100.c +++ b/drivers/net/wireless/ipw2100.c @@ -134,7 +134,6 @@ that only one external action is invoked at a time. */ #include <linux/compiler.h> -#include <linux/config.h> #include <linux/errno.h> #include <linux/if_arp.h> #include <linux/in6.h> @@ -1485,7 +1484,7 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv) * * Sending the PREPARE_FOR_POWER_DOWN will restrict the * hardware from going into standby mode and will transition - * out of D0-standy if it is already in that state. + * out of D0-standby if it is already in that state. * * STATUS_PREPARE_POWER_DOWN_COMPLETE will be sent by the * driver upon completion. Once received, the driver can @@ -5358,7 +5357,7 @@ static int ipw2100_set_key(struct ipw2100_priv *priv, idx, keylen, len); /* NOTE: We don't check cached values in case the firmware was reset - * or some other problem is occuring. If the user is setting the key, + * or some other problem is occurring. If the user is setting the key, * then we push the change */ wep_key->idx = idx; @@ -6230,7 +6229,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, ipw2100_queues_initialize(priv); err = request_irq(pci_dev->irq, - ipw2100_interrupt, SA_SHIRQ, dev->name, priv); + ipw2100_interrupt, IRQF_SHARED, dev->name, priv); if (err) { printk(KERN_WARNING DRV_NAME "Error calling request_irq: %d.\n", pci_dev->irq); diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 39f82f21974..b3300ffe4ee 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c @@ -533,7 +533,7 @@ static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask) ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask); } -static inline void ipw_enable_interrupts(struct ipw_priv *priv) +static inline void __ipw_enable_interrupts(struct ipw_priv *priv) { if (priv->status & STATUS_INT_ENABLED) return; @@ -541,7 +541,7 @@ static inline void ipw_enable_interrupts(struct ipw_priv *priv) ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL); } -static inline void ipw_disable_interrupts(struct ipw_priv *priv) +static inline void __ipw_disable_interrupts(struct ipw_priv *priv) { if (!(priv->status & STATUS_INT_ENABLED)) return; @@ -549,6 +549,24 @@ static inline void ipw_disable_interrupts(struct ipw_priv *priv) ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL); } +static inline void ipw_enable_interrupts(struct ipw_priv *priv) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->irq_lock, flags); + __ipw_enable_interrupts(priv); + spin_unlock_irqrestore(&priv->irq_lock, flags); +} + +static inline void ipw_disable_interrupts(struct ipw_priv *priv) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->irq_lock, flags); + __ipw_disable_interrupts(priv); + spin_unlock_irqrestore(&priv->irq_lock, flags); +} + #ifdef CONFIG_IPW2200_DEBUG static char *ipw_error_desc(u32 val) { @@ -1211,12 +1229,6 @@ static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv) return error; } -static void ipw_free_error_log(struct ipw_fw_error *error) -{ - if (error) - kfree(error); -} - static ssize_t show_event_log(struct device *d, struct device_attribute *attr, char *buf) { @@ -1278,10 +1290,9 @@ static ssize_t clear_error(struct device *d, const char *buf, size_t count) { struct ipw_priv *priv = dev_get_drvdata(d); - if (priv->error) { - ipw_free_error_log(priv->error); - priv->error = NULL; - } + + kfree(priv->error); + priv->error = NULL; return count; } @@ -1856,7 +1867,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) unsigned long flags; int rc = 0; - spin_lock_irqsave(&priv->lock, flags); + spin_lock_irqsave(&priv->irq_lock, flags); inta = ipw_read32(priv, IPW_INTA_RW); inta_mask = ipw_read32(priv, IPW_INTA_MASK_R); @@ -1865,6 +1876,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) /* Add any cached INTA values that need to be handled */ inta |= priv->isr_inta; + spin_unlock_irqrestore(&priv->irq_lock, flags); + + spin_lock_irqsave(&priv->lock, flags); + /* handle all the justifications for the interrupt */ if (inta & IPW_INTA_BIT_RX_TRANSFER) { ipw_rx(priv); @@ -1948,8 +1963,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) struct ipw_fw_error *error = ipw_alloc_error_log(priv); ipw_dump_error_log(priv, error); - if (error) - ipw_free_error_log(error); + kfree(error); } #endif } else { @@ -1993,10 +2007,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled); } + spin_unlock_irqrestore(&priv->lock, flags); + /* enable all interrupts */ ipw_enable_interrupts(priv); - - spin_unlock_irqrestore(&priv->lock, flags); } #define IPW_CMD(x) case IPW_CMD_ ## x : return #x @@ -10460,7 +10474,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) if (!priv) return IRQ_NONE; - spin_lock(&priv->lock); + spin_lock(&priv->irq_lock); if (!(priv->status & STATUS_INT_ENABLED)) { /* Shared IRQ */ @@ -10482,7 +10496,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) } /* tell the device to stop sending interrupts */ - ipw_disable_interrupts(priv); + __ipw_disable_interrupts(priv); /* ack current interrupts */ inta &= (IPW_INTA_MASK_ALL & inta_mask); @@ -10493,11 +10507,11 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) tasklet_schedule(&priv->irq_tasklet); - spin_unlock(&priv->lock); + spin_unlock(&priv->irq_lock); return IRQ_HANDLED; none: - spin_unlock(&priv->lock); + spin_unlock(&priv->irq_lock); return IRQ_NONE; } @@ -11477,6 +11491,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) #ifdef CONFIG_IPW2200_DEBUG ipw_debug_level = debug; #endif + spin_lock_init(&priv->irq_lock); spin_lock_init(&priv->lock); for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); @@ -11530,7 +11545,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ipw_sw_reset(priv, 1); - err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, priv); + err = request_irq(pdev->irq, ipw_isr, IRQF_SHARED, DRV_NAME, priv); if (err) { IPW_ERROR("Error allocating IRQ %d\n", pdev->irq); goto out_destroy_workqueue; @@ -11670,10 +11685,8 @@ static void ipw_pci_remove(struct pci_dev *pdev) } } - if (priv->error) { - ipw_free_error_log(priv->error); - priv->error = NULL; - } + kfree(priv->error); + priv->error = NULL; #ifdef CONFIG_IPW2200_PROMISCUOUS ipw_prom_free(priv); diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h index 6044c0be2c8..8b1cd7c749a 100644 --- a/drivers/net/wireless/ipw2200.h +++ b/drivers/net/wireless/ipw2200.h @@ -31,7 +31,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> -#include <linux/config.h> #include <linux/init.h> #include <linux/mutex.h> @@ -1173,6 +1172,7 @@ struct ipw_priv { struct ieee80211_device *ieee; spinlock_t lock; + spinlock_t irq_lock; struct mutex mutex; /* basic pci-network driver stuff */ diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c index 9343d970537..36b5e004305 100644 --- a/drivers/net/wireless/netwave_cs.c +++ b/drivers/net/wireless/netwave_cs.c @@ -37,7 +37,6 @@ /* To have statistics (just packets sent) define this */ #undef NETWAVE_STATS -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index 8a31b591a90..d6ed5781b93 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c @@ -76,7 +76,6 @@ #define DRIVER_NAME "orinoco" -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c index b2aec4d9fbb..bc14689cbf2 100644 --- a/drivers/net/wireless/orinoco_cs.c +++ b/drivers/net/wireless/orinoco_cs.c @@ -13,7 +13,6 @@ #define DRIVER_NAME "orinoco_cs" #define PFX DRIVER_NAME ": " -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c index 74b9d5b2ba9..bf05b907747 100644 --- a/drivers/net/wireless/orinoco_nortel.c +++ b/drivers/net/wireless/orinoco_nortel.c @@ -40,7 +40,6 @@ #define DRIVER_NAME "orinoco_nortel" #define PFX DRIVER_NAME ": " -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> @@ -199,7 +198,7 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev, hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING); - err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, + err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED, dev->name, dev); if (err) { printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq); diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c index 1c105f40f8d..1759c543fbe 100644 --- a/drivers/net/wireless/orinoco_pci.c +++ b/drivers/net/wireless/orinoco_pci.c @@ -44,7 +44,6 @@ #define DRIVER_NAME "orinoco_pci" #define PFX DRIVER_NAME ": " -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> @@ -154,7 +153,7 @@ static int orinoco_pci_init_one(struct pci_dev *pdev, hermes_struct_init(&priv->hw, hermes_io, HERMES_32BIT_REGSPACING); - err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, + err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED, dev->name, dev); if (err) { printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq); diff --git a/drivers/net/wireless/orinoco_pci.h b/drivers/net/wireless/orinoco_pci.h index 7eb1e08113e..be1abea4b64 100644 --- a/drivers/net/wireless/orinoco_pci.h +++ b/drivers/net/wireless/orinoco_pci.h @@ -63,7 +63,7 @@ static int orinoco_pci_resume(struct pci_dev *pdev) pci_enable_device(pdev); pci_restore_state(pdev); - err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, + err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED, dev->name, dev); if (err) { printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n", diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c index 84f696c7755..7f006f62417 100644 --- a/drivers/net/wireless/orinoco_plx.c +++ b/drivers/net/wireless/orinoco_plx.c @@ -86,7 +86,6 @@ #define DRIVER_NAME "orinoco_plx" #define PFX DRIVER_NAME ": " -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> @@ -238,7 +237,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING); - err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, + err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED, dev->name, dev); if (err) { printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq); diff --git a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c index d2b4decb7a7..0831721e4d6 100644 --- a/drivers/net/wireless/orinoco_tmd.c +++ b/drivers/net/wireless/orinoco_tmd.c @@ -40,7 +40,6 @@ #define DRIVER_NAME "orinoco_tmd" #define PFX DRIVER_NAME ": " -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> @@ -140,7 +139,7 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev, hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING); - err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, + err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED, dev->name, dev); if (err) { printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq); diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c index bfa0cc319a0..09fc17a0f02 100644 --- a/drivers/net/wireless/prism54/islpci_hotplug.c +++ b/drivers/net/wireless/prism54/islpci_hotplug.c @@ -189,7 +189,7 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* request for the interrupt before uploading the firmware */ rvalue = request_irq(pdev->irq, &islpci_interrupt, - SA_SHIRQ, ndev->name, priv); + IRQF_SHARED, ndev->name, priv); if (rvalue) { /* error, could not hook the handler to the irq */ diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c index 6a60c5970cb..2e061a80b29 100644 --- a/drivers/net/wireless/prism54/islpci_mgt.c +++ b/drivers/net/wireless/prism54/islpci_mgt.c @@ -18,7 +18,6 @@ * */ -#include <linux/config.h> #include <linux/netdevice.h> #include <linux/module.h> #include <linux/pci.h> diff --git a/drivers/net/wireless/prism54/prismcompat.h b/drivers/net/wireless/prism54/prismcompat.h index 55541c01752..d71eca55a30 100644 --- a/drivers/net/wireless/prism54/prismcompat.h +++ b/drivers/net/wireless/prism54/prismcompat.h @@ -29,7 +29,6 @@ #include <linux/device.h> #include <linux/firmware.h> -#include <linux/config.h> #include <linux/moduleparam.h> #include <linux/workqueue.h> #include <linux/compiler.h> diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 879eb427607..61b83a5e737 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -30,7 +30,6 @@ * =============================================================================*/ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/proc_fs.h> @@ -924,8 +923,7 @@ static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev) if (length < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) return 0; length = ETH_ZLEN; } diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c index 7f9aa139c34..15465278c78 100644 --- a/drivers/net/wireless/spectrum_cs.c +++ b/drivers/net/wireless/spectrum_cs.c @@ -21,7 +21,6 @@ #define DRIVER_NAME "spectrum_cs" #define PFX DRIVER_NAME ": " -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index 18a44580b53..fd31885c684 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -81,7 +81,6 @@ static const char StripVersion[] = "1.3A-STUART.CHESHIRE"; /************************************************************************/ /* Header files */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c index dade4b90357..5b69befdab7 100644 --- a/drivers/net/wireless/wavelan.c +++ b/drivers/net/wireless/wavelan.c @@ -1695,8 +1695,8 @@ static int wv_frequency_list(unsigned long ioaddr, /* I/O port of the card */ /* Look in the table if the frequency is allowed */ if (table[9 - (freq / 16)] & (1 << (freq % 16))) { /* Compute approximate channel number */ - while ((((channel_bands[c] >> 1) - 24) < freq) && - (c < NELS(channel_bands))) + while ((c < NELS(channel_bands)) && + (((channel_bands[c] >> 1) - 24) < freq)) c++; list[i].i = c; /* Set the list index */ @@ -2903,6 +2903,7 @@ static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev) { net_local *lp = (net_local *) dev->priv; unsigned long flags; + char data[ETH_ZLEN]; #ifdef DEBUG_TX_TRACE printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name, @@ -2937,15 +2938,16 @@ static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev) * able to detect collisions, therefore in theory we don't really * need to pad. Jean II */ if (skb->len < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) - return 0; + memset(data, 0, ETH_ZLEN); + memcpy(data, skb->data, skb->len); + /* Write packet on the card */ + if(wv_packet_write(dev, data, ETH_ZLEN)) + return 1; /* We failed */ } - - /* Write packet on the card */ - if(wv_packet_write(dev, skb->data, skb->len)) + else if(wv_packet_write(dev, skb->data, skb->len)) return 1; /* We failed */ + dev_kfree_skb(skb); #ifdef DEBUG_TX_TRACE diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index f7724eb2fa7..561250f73fd 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c @@ -3194,11 +3194,8 @@ wavelan_packet_xmit(struct sk_buff * skb, * and we don't have the Ethernet specific requirement of beeing * able to detect collisions, therefore in theory we don't really * need to pad. Jean II */ - if (skb->len < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) - return 0; - } + if (skb_padto(skb, ETH_ZLEN)) + return 0; wv_packet_write(dev, skb->data, skb->len); diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h index c65fe7a391e..f34a36b0c7b 100644 --- a/drivers/net/wireless/wavelan_cs.p.h +++ b/drivers/net/wireless/wavelan_cs.p.h @@ -411,7 +411,6 @@ /***************************** INCLUDES *****************************/ /* Linux headers that we need */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index e52a650f673..c03e400face 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -28,7 +28,6 @@ */ #undef REALLY_SLOW_IO /* most systems can safely undef this */ -#include <linux/config.h> #include <linux/delay.h> #include <linux/types.h> #include <linux/ethtool.h> diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index fd0f43b7db5..bbbf7e274a2 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -234,14 +234,6 @@ See Packet Engines confidential appendix (prototype chips only). -enum pci_id_flags_bits { - /* Set PCI command register bits before calling probe1(). */ - PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, - /* Read and map the single following PCI BAR. */ - PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4, - PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400, - PCI_UNUSED_IRQ=0x800, -}; enum capability_flags { HasMII=1, FullTxStatus=2, IsGigabit=4, HasMulticastBug=8, FullRxStatus=16, HasMACAddrBug=32, /* Only on early revs. */ @@ -249,11 +241,6 @@ enum capability_flags { }; /* The PCI I/O space extent. */ #define YELLOWFIN_SIZE 0x100 -#ifdef USE_IO_OPS -#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0) -#else -#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1) -#endif struct pci_id_info { const char *name; @@ -261,24 +248,23 @@ struct pci_id_info { int pci, pci_mask, subsystem, subsystem_mask; int revision, revision_mask; /* Only 8 bits. */ } id; - enum pci_id_flags_bits pci_flags; int io_size; /* Needed for I/O region check or ioremap(). */ int drv_flags; /* Driver use, intended as capability flags. */ }; static const struct pci_id_info pci_id_tbl[] = { {"Yellowfin G-NIC Gigabit Ethernet", { 0x07021000, 0xffffffff}, - PCI_IOTYPE, YELLOWFIN_SIZE, + YELLOWFIN_SIZE, FullTxStatus | IsGigabit | HasMulticastBug | HasMACAddrBug | DontUseEeprom}, {"Symbios SYM83C885", { 0x07011000, 0xffffffff}, - PCI_IOTYPE, YELLOWFIN_SIZE, HasMII | DontUseEeprom }, - {NULL,}, + YELLOWFIN_SIZE, HasMII | DontUseEeprom }, + { } }; -static struct pci_device_id yellowfin_pci_tbl[] = { +static const struct pci_device_id yellowfin_pci_tbl[] = { { 0x1000, 0x0702, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0x1000, 0x0701, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, - { 0, } + { } }; MODULE_DEVICE_TABLE (pci, yellowfin_pci_tbl); @@ -616,7 +602,7 @@ static int yellowfin_open(struct net_device *dev) /* Reset the chip. */ iowrite32(0x80000000, ioaddr + DMACtrl); - i = request_irq(dev->irq, &yellowfin_interrupt, SA_SHIRQ, dev->name, dev); + i = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev); if (i) return i; if (yellowfin_debug > 1) @@ -862,13 +848,11 @@ static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Fix GX chipset errata. */ if (cacheline_end > 24 || cacheline_end == 0) { len = skb->len + 32 - cacheline_end + 1; - if (len != skb->len) - skb = skb_padto(skb, len); - } - if (skb == NULL) { - yp->tx_skbuff[entry] = NULL; - netif_wake_queue(dev); - return 0; + if (skb_padto(skb, len)) { + yp->tx_skbuff[entry] = NULL; + netif_wake_queue(dev); + return 0; + } } } yp->tx_skbuff[entry] = skb; diff --git a/drivers/net/znet.c b/drivers/net/znet.c index 3ac047bc727..9f0291f3529 100644 --- a/drivers/net/znet.c +++ b/drivers/net/znet.c @@ -85,7 +85,6 @@ - Understand why some traffic patterns add a 1s latency... */ -#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/string.h> @@ -544,8 +543,7 @@ static int znet_send_packet(struct sk_buff *skb, struct net_device *dev) printk(KERN_DEBUG "%s: ZNet_send_packet.\n", dev->name); if (length < ETH_ZLEN) { - skb = skb_padto(skb, ETH_ZLEN); - if (skb == NULL) + if (skb_padto(skb, ETH_ZLEN)) return 0; length = ETH_ZLEN; } diff --git a/drivers/net/zorro8390.c b/drivers/net/zorro8390.c index 8037e5806d0..df04e050c64 100644 --- a/drivers/net/zorro8390.c +++ b/drivers/net/zorro8390.c @@ -201,7 +201,7 @@ static int __devinit zorro8390_init(struct net_device *dev, dev->irq = IRQ_AMIGA_PORTS; /* Install the Interrupt handler */ - i = request_irq(IRQ_AMIGA_PORTS, ei_interrupt, SA_SHIRQ, DRV_NAME, dev); + i = request_irq(IRQ_AMIGA_PORTS, ei_interrupt, IRQF_SHARED, DRV_NAME, dev); if (i) return i; for(i = 0; i < ETHER_ADDR_LEN; i++) { |