diff options
| author | Jeff Garzik <jgarzik@redhat.com> | 2004-04-16 04:55:41 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@redhat.com> | 2004-04-16 04:55:41 -0400 |
| commit | 86014f1b6c5d06f063c2cc89d93387e583a65833 (patch) | |
| tree | bc8a072e5bbeda50b2cccbd212ac00e9a884da30 | |
| parent | fbd532e3977a9c785b9fb2c7f9b698febaaf3a6a (diff) | |
| parent | ce99046f5b8e8219b43d038204b15b106cb891a6 (diff) | |
Merge redhat.com:/spare/repo/netdev-2.6/misc
into redhat.com:/spare/repo/net-drivers-2.6
| -rw-r--r-- | MAINTAINERS | 20 | ||||
| -rw-r--r-- | drivers/net/8390.c | 2 | ||||
| -rw-r--r-- | drivers/net/8390.h | 15 | ||||
| -rw-r--r-- | drivers/net/Kconfig | 3 | ||||
| -rwxr-xr-x | drivers/net/amd8111e.c | 227 | ||||
| -rwxr-xr-x | drivers/net/amd8111e.h | 3 | ||||
| -rw-r--r-- | drivers/net/arcnet/com20020-isa.c | 2 | ||||
| -rw-r--r-- | drivers/net/arm/etherh.c | 318 | ||||
| -rw-r--r-- | drivers/net/fc/iph5526.c | 4 | ||||
| -rw-r--r-- | drivers/net/natsemi.c | 2 | ||||
| -rw-r--r-- | drivers/net/sk_mca.c | 4 | ||||
| -rw-r--r-- | include/linux/netdevice.h | 5 | ||||
| -rw-r--r-- | net/core/netpoll.c | 31 |
13 files changed, 433 insertions, 203 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index cfa5bca2922e..d1a672b01c07 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1061,23 +1061,33 @@ M: tigran@veritas.com S: Maintained INTEL PRO/100 ETHERNET SUPPORT +P: John Ronciak +M: john.ronciak@intel.com +P: Ganesh Venkatesan +M: ganesh.venkatesan@intel.com P: Scott Feldman M: scott.feldman@intel.com +W: http://sourceforge.net/projects/e1000/ S: Supported INTEL PRO/1000 GIGABIT ETHERNET SUPPORT P: Jeb Cramer M: cramerj@intel.com -P: Scott Feldman -M: scott.feldman@intel.com +P: John Ronciak +M: john.ronciak@intel.com +P: Ganesh Venkatesan +M: ganesh.venkatesan@intel.com W: http://sourceforge.net/projects/e1000/ S: Supported INTEL PRO/10GbE SUPPORT +P: Ayyappan Veeraiyan +M: ayyappan.veeraiyan@intel.com P: Ganesh Venkatesan -M: Ganesh.Venkatesan@intel.com -P: Scott Feldman -M: scott.feldman@intel.com +M: ganesh.venkatesan@intel.com +P: John Ronciak +M: john.ronciak@intel.com +W: http://sourceforge.net/projects/e1000/ S: Supported INTERMEZZO FILE SYSTEM diff --git a/drivers/net/8390.c b/drivers/net/8390.c index 224da326dd8e..22e7dfb47666 100644 --- a/drivers/net/8390.c +++ b/drivers/net/8390.c @@ -1084,7 +1084,7 @@ void NS8390_init(struct net_device *dev, int startp) for(i = 0; i < 6; i++) { outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS_SHIFT(i)); - if(inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i]) + if (ei_debug > 1 && inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i]) printk(KERN_ERR "Hw. address read/write mismap %d\n",i); } diff --git a/drivers/net/8390.h b/drivers/net/8390.h index 442048bdb9cb..2dd2c7317d3a 100644 --- a/drivers/net/8390.h +++ b/drivers/net/8390.h @@ -131,8 +131,19 @@ struct ei_device { #define inb_p(port) in_8(port) #define outb_p(val,port) out_8(port,val) -#elif defined(CONFIG_ARM_ETHERH) || defined(CONFIG_ARM_ETHERH_MODULE) || \ - defined(CONFIG_NET_CBUS) +#elif defined(CONFIG_ARM_ETHERH) || defined(CONFIG_ARM_ETHERH_MODULE) +#define EI_SHIFT(x) (ei_local->reg_offset[x]) +#undef inb +#undef inb_p +#undef outb +#undef outb_p + +#define inb(_p) readb(_p) +#define outb(_v,_p) writeb(_v,_p) +#define inb_p(_p) inb(_p) +#define outb_p(_v,_p) outb(_v,_p) + +#elif defined(CONFIG_NET_CBUS) #define EI_SHIFT(x) (ei_local->reg_offset[x]) #else #define EI_SHIFT(x) (x) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 391e438f127b..a6817f339774 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1219,6 +1219,9 @@ config AMD8111_ETH To compile this driver as a module, choose M here and read <file:Documentation/networking/net-modules.txt>. The module will be called amd8111e. +config AMD8111E_NAPI + bool "Enable NAPI support" + depends on AMD8111_ETH config ADAPTEC_STARFIRE tristate "Adaptec Starfire/DuraLAN support" diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index 140f2834a529..2552945aba18 100755 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -1,6 +1,6 @@ /* Advanced Micro Devices Inc. AMD8111E Linux Network Driver - * Copyright (C) 2003 Advanced Micro Devices + * Copyright (C) 2004 Advanced Micro Devices * * * Copyright 2001,2002 Jeff Garzik <jgarzik@mandrakesoft.com> [ 8139cp.c,tg3.c ] @@ -55,6 +55,16 @@ Revision History: 4. Dynamic IPG support is disabled by default. 3.0.3 06/05/2003 1. Bug fix: Fixed failure to close the interface if SMP is enabled. + 3.0.4 12/09/2003 + 1. Added set_mac_address routine for bonding driver support. + 2. Tested the driver for bonding support + 3. Bug fix: Fixed mismach in actual receive buffer lenth and lenth + indicated to the h/w. + 4. Modified amd8111e_rx() routine to receive all the received packets + in the first interrupt. + 5. Bug fix: Corrected rx_errors reported in get_stats() function. + 3.0.5 03/22/2004 + 1. Added NAPI support */ @@ -91,7 +101,7 @@ Revision History: #include "amd8111e.h" #define MODULE_NAME "amd8111e" -#define MODULE_VERS "3.0.3" +#define MODULE_VERS "3.0.5" MODULE_AUTHOR("Advanced Micro Devices, Inc."); MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version 3.0.3"); MODULE_LICENSE("GPL"); @@ -276,8 +286,10 @@ static inline void amd8111e_set_rx_buff_len(struct net_device* dev) unsigned int mtu = dev->mtu; if (mtu > ETH_DATA_LEN){ - /* MTU + ethernet header + FCS + optional VLAN tag */ - lp->rx_buff_len = mtu + ETH_HLEN + 8; + /* MTU + ethernet header + FCS + + optional VLAN tag + skb reserve space 2 */ + + lp->rx_buff_len = mtu + ETH_HLEN + 10; lp->options |= OPTION_JUMBO_ENABLE; } else{ lp->rx_buff_len = PKT_BUFF_SZ; @@ -337,7 +349,7 @@ static int amd8111e_init_ring(struct net_device *dev) lp->rx_skbuff[i]->data,lp->rx_buff_len-2, PCI_DMA_FROMDEVICE); lp->rx_ring[i].buff_phy_addr = cpu_to_le32(lp->rx_dma_addr[i]); - lp->rx_ring[i].buff_count = cpu_to_le16(lp->rx_buff_len); + lp->rx_ring[i].buff_count = cpu_to_le16(lp->rx_buff_len-2); lp->rx_ring[i].rx_flags = cpu_to_le16(OWN_BIT); } @@ -513,6 +525,9 @@ static void amd8111e_init_hw_default( struct amd8111e_priv* lp) void * mmio = lp->mmio; + /* stop the chip */ + writel(RUN, mmio + CMD0); + /* AUTOPOLL0 Register *//*TBD default value is 8100 in FPS */ writew( 0x8101, mmio + AUTOPOLL0); @@ -654,7 +669,11 @@ This is the receive indication function for packets with vlan tag. */ static int amd8111e_vlan_rx(struct amd8111e_priv *lp, struct sk_buff *skb, u16 vlan_tag) { +#ifdef CONFIG_AMD8111E_NAPI + vlan_hwaccel_receive_skb(skb, lp->vlgrp,vlan_tag); +#else return vlan_hwaccel_rx(skb, lp->vlgrp, vlan_tag); +#endif /* CONFIG_AMD8111E_NAPI */ } #endif @@ -700,6 +719,142 @@ static int amd8111e_tx(struct net_device *dev) return 0; } +#if CONFIG_AMD8111E_NAPI +/* This function handles the driver receive operation in polling mode */ +static int amd8111e_rx_poll(struct net_device *dev, int * budget) +{ + struct amd8111e_priv *lp = dev->priv; + int rx_index = lp->rx_idx & RX_RING_DR_MOD_MASK; + void * mmio = lp->mmio; + struct sk_buff *skb,*new_skb; + int min_pkt_len, status; + unsigned int intr0; + int num_rx_pkt = 0; + /*int max_rx_pkt = NUM_RX_BUFFERS;*/ + short pkt_len; +#if AMD8111E_VLAN_TAG_USED + short vtag; +#endif + int rx_pkt_limit = dev->quota; + + do{ + /* process receive packets until we use the quota*/ + /* If we own the next entry, it's a new packet. Send it up. */ + while(!(lp->rx_ring[rx_index].rx_flags & OWN_BIT)){ + + /* check if err summary bit is set */ + if(le16_to_cpu(lp->rx_ring[rx_index].rx_flags) + & ERR_BIT){ + /* + * There is a tricky error noted by John Murphy, + * <murf@perftech.com> to Russ Nelson: Even with + * full-sized * buffers it's possible for a + * jabber packet to use two buffers, with only + * the last correctly noting the error. + */ + + /* reseting flags */ + lp->rx_ring[rx_index].rx_flags &=RESET_RX_FLAGS; + goto err_next_pkt; + + } + /* check for STP and ENP */ + status = le16_to_cpu(lp->rx_ring[rx_index].rx_flags); + if(!((status & STP_BIT) && (status & ENP_BIT))){ + /* reseting flags */ + lp->rx_ring[rx_index].rx_flags &=RESET_RX_FLAGS; + goto err_next_pkt; + } + pkt_len = le16_to_cpu(lp->rx_ring[rx_index].msg_count) - 4; + +#if AMD8111E_VLAN_TAG_USED + vtag = le16_to_cpu(lp->rx_ring[rx_index].rx_flags) & TT_MASK; + /*MAC will strip vlan tag*/ + if(lp->vlgrp != NULL && vtag !=0) + min_pkt_len =MIN_PKT_LEN - 4; + else +#endif + min_pkt_len =MIN_PKT_LEN; + + if (pkt_len < min_pkt_len) { + lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; + lp->drv_rx_errors++; + goto err_next_pkt; + } + if(--rx_pkt_limit < 0) + goto rx_not_empty; + if(!(new_skb = dev_alloc_skb(lp->rx_buff_len))){ + /* if allocation fail, + ignore that pkt and go to next one */ + lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; + lp->drv_rx_errors++; + goto err_next_pkt; + } + + skb_reserve(new_skb, 2); + skb = lp->rx_skbuff[rx_index]; + pci_unmap_single(lp->pci_dev,lp->rx_dma_addr[rx_index], + lp->rx_buff_len-2, PCI_DMA_FROMDEVICE); + skb_put(skb, pkt_len); + skb->dev = dev; + lp->rx_skbuff[rx_index] = new_skb; + new_skb->dev = dev; + lp->rx_dma_addr[rx_index] = pci_map_single(lp->pci_dev, + new_skb->data, lp->rx_buff_len-2,PCI_DMA_FROMDEVICE); + + skb->protocol = eth_type_trans(skb, dev); + +#if AMD8111E_VLAN_TAG_USED + + vtag = lp->rx_ring[rx_index].rx_flags & TT_MASK; + if(lp->vlgrp != NULL && (vtag == TT_VLAN_TAGGED)){ + amd8111e_vlan_rx(lp, skb, + lp->rx_ring[rx_index].tag_ctrl_info); + } else +#endif + + netif_receive_skb(skb); + /*COAL update rx coalescing parameters*/ + lp->coal_conf.rx_packets++; + lp->coal_conf.rx_bytes += pkt_len; + num_rx_pkt++; + dev->last_rx = jiffies; + +err_next_pkt: + lp->rx_ring[rx_index].buff_phy_addr + = cpu_to_le32(lp->rx_dma_addr[rx_index]); + lp->rx_ring[rx_index].buff_count = + cpu_to_le16(lp->rx_buff_len-2); + lp->rx_ring[rx_index].rx_flags |= cpu_to_le16(OWN_BIT); + rx_index = (++lp->rx_idx) & RX_RING_DR_MOD_MASK; + } + /* Check the interrupt status register for more packets in the + mean time. Process them since we have not used up our quota.*/ + + intr0 = readl(mmio + INT0); + /*Ack receive packets */ + writel(intr0 & RINT0,mmio + INT0); + + }while(intr0 & RINT0); + + /* Receive descriptor is empty now */ + dev->quota -= num_rx_pkt; + *budget -= num_rx_pkt; + netif_rx_complete(dev); + /* enable receive interrupt */ + writel(VAL0|RINTEN0, mmio + INTEN0); + writel(VAL2 | RDMD0, mmio + CMD0); + return 0; +rx_not_empty: + /* Do not call a netif_rx_complete */ + dev->quota -= num_rx_pkt; + *budget -= num_rx_pkt; + return 1; + + +} + +#else /* This function will check the ownership of receive buffers and descriptors. It will indicate to kernel up to half the number of maximum receive buffers in the descriptor ring, in a single receive interrupt. It will also replenish the descriptors with new skbs. */ @@ -710,7 +865,7 @@ static int amd8111e_rx(struct net_device *dev) int rx_index = lp->rx_idx & RX_RING_DR_MOD_MASK; int min_pkt_len, status; int num_rx_pkt = 0; - int max_rx_pkt = NUM_RX_BUFFERS/2; + int max_rx_pkt = NUM_RX_BUFFERS; short pkt_len; #if AMD8111E_VLAN_TAG_USED short vtag; @@ -752,14 +907,14 @@ static int amd8111e_rx(struct net_device *dev) if (pkt_len < min_pkt_len) { lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; - lp->stats.rx_errors++; + lp->drv_rx_errors++; goto err_next_pkt; } if(!(new_skb = dev_alloc_skb(lp->rx_buff_len))){ /* if allocation fail, ignore that pkt and go to next one */ lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS; - lp->stats.rx_errors++; + lp->drv_rx_errors++; goto err_next_pkt; } @@ -803,7 +958,7 @@ err_next_pkt: return 0; } - +#endif /* CONFIG_AMD8111E_NAPI */ /* This function will indicate the link status to the kernel. */ @@ -896,12 +1051,14 @@ static struct net_device_stats *amd8111e_get_stats(struct net_device * dev) new_stats->tx_bytes = amd8111e_read_mib(mmio, xmt_octets); /* stats.rx_errors */ + /* hw errors + errors driver reported */ new_stats->rx_errors = amd8111e_read_mib(mmio, rcv_undersize_pkts)+ amd8111e_read_mib(mmio, rcv_fragments)+ amd8111e_read_mib(mmio, rcv_jabbers)+ amd8111e_read_mib(mmio, rcv_alignment_errors)+ amd8111e_read_mib(mmio, rcv_fcs_errors)+ - amd8111e_read_mib(mmio, rcv_miss_pkts); + amd8111e_read_mib(mmio, rcv_miss_pkts)+ + lp->drv_rx_errors; /* stats.tx_errors */ new_stats->tx_errors = amd8111e_read_mib(mmio, xmt_underrun_pkts); @@ -1119,20 +1276,36 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg /* Process all the INT event until INTR bit is clear. */ - if (!(intr0 & INTR)) { + if (!(intr0 & INTR)){ handled = 0; goto err_no_interrupt; } - /* Current driver processes 3 interrupts : RINT,TINT,LCINT */ + /* Current driver processes 4 interrupts : RINT,TINT,LCINT,STINT */ writel(intr0, mmio + INT0); /* Check if Receive Interrupt has occurred. */ +#if CONFIG_AMD8111E_NAPI + if(intr0 & RINT0){ + if(netif_rx_schedule_prep(dev)){ + /* Disable receive interupts */ + writel(RINTEN0, mmio + INTEN0); + /* Schedule a polling routine */ + __netif_rx_schedule(dev); + } + else { + printk("************Driver bug! \ + interrupt while in poll\n"); + /* Fix by disabling interrupts */ + writel(RINT0, mmio + INT0); + } + } +#else if(intr0 & RINT0){ amd8111e_rx(dev); writel(VAL2 | RDMD0, mmio + CMD0); } - +#endif /* CONFIG_AMD8111E_NAPI */ /* Check if Transmit Interrupt has occurred. */ if(intr0 & TINT0) amd8111e_tx(dev); @@ -1164,6 +1337,7 @@ static void amd8111e_poll(struct net_device *dev) } #endif + /* This function closes the network interface and updates the statistics so that most recent statistics will be available after the interface is down. */ @@ -1186,7 +1360,7 @@ static int amd8111e_close(struct net_device * dev) spin_unlock_irq(&lp->lock); free_irq(dev->irq, dev); - + /* Update the statistics before closing */ amd8111e_get_stats(dev); lp->opened = 0; @@ -1560,6 +1734,23 @@ static int amd8111e_ioctl(struct net_device * dev , struct ifreq *ifr, int cmd) } return -EOPNOTSUPP; } +static int amd8111e_set_mac_address(struct net_device *dev, void *p) +{ + struct amd8111e_priv *lp = dev->priv; + int i; + struct sockaddr *addr = p; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + spin_lock_irq(&lp->lock); + /* Setting the MAC address to the device */ + for(i = 0; i < ETH_ADDR_LEN; i++) + writeb( dev->dev_addr[i], lp->mmio + PADR + i ); + + spin_unlock_irq(&lp->lock); + + return 0; +} + /* This function changes the mtu of the device. It restarts the device to initialize the descriptor with new receive buffers. */ @@ -1890,11 +2081,16 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, dev->stop = amd8111e_close; dev->get_stats = amd8111e_get_stats; dev->set_multicast_list = amd8111e_set_multicast_list; + dev->set_mac_address = amd8111e_set_mac_address; dev->do_ioctl = amd8111e_ioctl; dev->change_mtu = amd8111e_change_mtu; dev->irq =pdev->irq; dev->tx_timeout = amd8111e_tx_timeout; dev->watchdog_timeo = AMD8111E_TX_TIMEOUT; +#ifdef CONFIG_AMD8111E_NAPI + dev->poll = amd8111e_rx_poll; + dev->weight = 32; +#endif #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = amd8111e_poll; #endif @@ -1908,6 +2104,7 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, /* Set receive buffer length and set jumbo option*/ amd8111e_set_rx_buff_len(dev); + err = register_netdev(dev); if (err) { printk(KERN_ERR "amd8111e: Cannot register net device, " @@ -1954,7 +2151,7 @@ err_disable_pdev: } static struct pci_driver amd8111e_driver = { - .name = MODULE_NAME, + .name = MODULE_NAME, .id_table = amd8111e_pci_tbl, .probe = amd8111e_probe_one, .remove = __devexit_p(amd8111e_remove_one), diff --git a/drivers/net/amd8111e.h b/drivers/net/amd8111e.h index 836277399b8a..f95425d5f687 100755 --- a/drivers/net/amd8111e.h +++ b/drivers/net/amd8111e.h @@ -606,7 +606,7 @@ typedef enum { /* ipg parameters */ #define DEFAULT_IPG 0x60 #define IFS1_DELTA 36 -#define IPG_CONVERGE_JIFFIES (HZ / 2) +#define IPG_CONVERGE_JIFFIES (HZ/2) #define IPG_STABLE_TIME 5 #define MIN_IPG 96 #define MAX_IPG 255 @@ -790,6 +790,7 @@ struct amd8111e_priv{ #endif char opened; struct net_device_stats stats; + unsigned int drv_rx_errors; struct dev_mc_list* mc_list; struct amd8111e_coalesce_conf coal_conf; diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c index d94940de3ec9..09af99a724b2 100644 --- a/drivers/net/arcnet/com20020-isa.c +++ b/drivers/net/arcnet/com20020-isa.c @@ -185,8 +185,6 @@ static void __exit com20020_exit(void) #ifndef MODULE static int __init com20020isa_setup(char *s) { - struct net_device *dev; - struct arcnet_local *lp; int ints[8]; s = get_options(s, 8, ints); diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index 02ecb36bc186..2bdba2fd8ef5 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c @@ -60,11 +60,28 @@ static unsigned int net_debug = NET_DEBUG; struct etherh_priv { struct ei_device eidev; + void *ioc_fast; + void *memc; unsigned int id; - unsigned int ctrl_port; + void *ctrl_port; unsigned int ctrl; }; +struct etherh_data { + unsigned long ns8390_offset; + unsigned long dataport_offset; + unsigned long ctrlport_offset; + int ctrl_ioc; + const char name[16]; + /* + * netdev flags and port + */ + unsigned short flags; + unsigned char if_port; + unsigned char tx_start_page; + unsigned char stop_page; +}; + MODULE_AUTHOR("Russell King"); MODULE_DESCRIPTION("EtherH/EtherM driver"); MODULE_LICENSE("GPL"); @@ -72,13 +89,13 @@ MODULE_LICENSE("GPL"); static char version[] __initdata = "EtherH/EtherM Driver (c) 2002 Russell King v1.09\n"; -#define ETHERH500_DATAPORT 0x200 /* MEMC */ +#define ETHERH500_DATAPORT 0x800 /* MEMC */ #define ETHERH500_NS8390 0x000 /* MEMC */ -#define ETHERH500_CTRLPORT 0x200 /* IOC */ +#define ETHERH500_CTRLPORT 0x800 /* IOC */ -#define ETHERH600_DATAPORT 16 /* MEMC */ -#define ETHERH600_NS8390 0x200 /* MEMC */ -#define ETHERH600_CTRLPORT 0x080 /* MEMC */ +#define ETHERH600_DATAPORT 0x040 /* MEMC */ +#define ETHERH600_NS8390 0x800 /* MEMC */ +#define ETHERH600_CTRLPORT 0x200 /* MEMC */ #define ETHERH_CP_IE 1 #define ETHERH_CP_IF 2 @@ -90,9 +107,9 @@ static char version[] __initdata = /* * These came from CK/TEW */ -#define ETHERM_DATAPORT 0x080 /* MEMC */ -#define ETHERM_NS8390 0x200 /* MEMC */ -#define ETHERM_CTRLPORT 0x08f /* MEMC */ +#define ETHERM_DATAPORT 0x200 /* MEMC */ +#define ETHERM_NS8390 0x800 /* MEMC */ +#define ETHERM_CTRLPORT 0x23c /* MEMC */ #define ETHERM_TX_START_PAGE 64 #define ETHERM_STOP_PAGE 127 @@ -102,18 +119,18 @@ static char version[] __initdata = static inline void etherh_set_ctrl(struct etherh_priv *eh, unsigned int mask) { eh->ctrl |= mask; - outb(eh->ctrl, eh->ctrl_port); + writeb(eh->ctrl, eh->ctrl_port); } static inline void etherh_clr_ctrl(struct etherh_priv *eh, unsigned int mask) { eh->ctrl &= ~mask; - outb(eh->ctrl, eh->ctrl_port); + writeb(eh->ctrl, eh->ctrl_port); } static inline unsigned int etherh_get_stat(struct etherh_priv *eh) { - return inb(eh->ctrl_port); + return readb(eh->ctrl_port); } @@ -158,10 +175,10 @@ etherh_setif(struct net_device *dev) switch (dev->if_port) { case IF_PORT_10BASE2: - outb((inb(addr) & 0xf8) | 1, addr); + writeb((readb(addr) & 0xf8) | 1, addr); break; case IF_PORT_10BASET: - outb((inb(addr) & 0xf8), addr); + writeb((readb(addr) & 0xf8), addr); break; } break; @@ -200,7 +217,7 @@ etherh_getifstat(struct net_device *dev) stat = 1; break; case IF_PORT_10BASET: - stat = inb(dev->base_addr+EN0_RCNTHI) & 4; + stat = readb(dev->base_addr+EN0_RCNTHI) & 4; break; } break; @@ -258,7 +275,7 @@ etherh_reset(struct net_device *dev) { struct ei_device *ei_local = netdev_priv(dev); - outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, dev->base_addr); + writeb(E8390_NODMA+E8390_PAGE0+E8390_STOP, dev->base_addr); /* * See if we need to change the interface type. @@ -306,31 +323,31 @@ etherh_block_output (struct net_device *dev, int count, const unsigned char *buf dma_addr = dev->mem_start; count = (count + 1) & ~1; - outb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); + writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); - outb (0x42, addr + EN0_RCNTLO); - outb (0x00, addr + EN0_RCNTHI); - outb (0x42, addr + EN0_RSARLO); - outb (0x00, addr + EN0_RSARHI); - outb (E8390_RREAD | E8390_START, addr + E8390_CMD); + writeb (0x42, addr + EN0_RCNTLO); + writeb (0x00, addr + EN0_RCNTHI); + writeb (0x42, addr + EN0_RSARLO); + writeb (0x00, addr + EN0_RSARHI); + writeb (E8390_RREAD | E8390_START, addr + E8390_CMD); udelay (1); - outb (ENISR_RDC, addr + EN0_ISR); - outb (count, addr + EN0_RCNTLO); - outb (count >> 8, addr + EN0_RCNTHI); - outb (0, addr + EN0_RSARLO); - outb (start_page, addr + EN0_RSARHI); - outb (E8390_RWRITE | E8390_START, addr + E8390_CMD); + writeb (ENISR_RDC, addr + EN0_ISR); + writeb (count, addr + EN0_RCNTLO); + writeb (count >> 8, addr + EN0_RCNTHI); + writeb (0, addr + EN0_RSARLO); + writeb (start_page, addr + EN0_RSARHI); + writeb (E8390_RWRITE | E8390_START, addr + E8390_CMD); if (ei_local->word16) - outsw (dma_addr, buf, count >> 1); + writesw (dma_addr, buf, count >> 1); else - outsb (dma_addr, buf, count); + writesb (dma_addr, buf, count); dma_start = jiffies; - while ((inb (addr + EN0_ISR) & ENISR_RDC) == 0) + while ((readb (addr + EN0_ISR) & ENISR_RDC) == 0) if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ printk(KERN_ERR "%s: timeout waiting for TX RDC\n", dev->name); @@ -339,7 +356,7 @@ etherh_block_output (struct net_device *dev, int count, const unsigned char *buf break; } - outb (ENISR_RDC, addr + EN0_ISR); + writeb (ENISR_RDC, addr + EN0_ISR); ei_local->dmaing = 0; } @@ -366,21 +383,21 @@ etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int dma_addr = dev->mem_start; buf = skb->data; - outb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); - outb (count, addr + EN0_RCNTLO); - outb (count >> 8, addr + EN0_RCNTHI); - outb (ring_offset, addr + EN0_RSARLO); - outb (ring_offset >> 8, addr + EN0_RSARHI); - outb (E8390_RREAD | E8390_START, addr + E8390_CMD); + writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); + writeb (count, addr + EN0_RCNTLO); + writeb (count >> 8, addr + EN0_RCNTHI); + writeb (ring_offset, addr + EN0_RSARLO); + writeb (ring_offset >> 8, addr + EN0_RSARHI); + writeb (E8390_RREAD | E8390_START, addr + E8390_CMD); if (ei_local->word16) { - insw (dma_addr, buf, count >> 1); + readsw (dma_addr, buf, count >> 1); if (count & 1) - buf[count - 1] = inb (dma_addr); + buf[count - 1] = readb (dma_addr); } else - insb (dma_addr, buf, count); + readsb (dma_addr, buf, count); - outb (ENISR_RDC, addr + EN0_ISR); + writeb (ENISR_RDC, addr + EN0_ISR); ei_local->dmaing = 0; } @@ -405,19 +422,19 @@ etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_p addr = dev->base_addr; dma_addr = dev->mem_start; - outb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); - outb (sizeof (*hdr), addr + EN0_RCNTLO); - outb (0, addr + EN0_RCNTHI); - outb (0, addr + EN0_RSARLO); - outb (ring_page, addr + EN0_RSARHI); - outb (E8390_RREAD | E8390_START, addr + E8390_CMD); + writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); + writeb (sizeof (*hdr), addr + EN0_RCNTLO); + writeb (0, addr + EN0_RCNTHI); + writeb (0, addr + EN0_RSARLO); + writeb (ring_page, addr + EN0_RSARHI); + writeb (E8390_RREAD | E8390_START, addr + E8390_CMD); if (ei_local->word16) - insw (dma_addr, hdr, sizeof (*hdr) >> 1); + readsw (dma_addr, hdr, sizeof (*hdr) >> 1); else - insb (dma_addr, hdr, sizeof (*hdr)); + readsb (dma_addr, hdr, sizeof (*hdr)); - outb (ENISR_RDC, addr + EN0_ISR); + writeb (ENISR_RDC, addr + EN0_ISR); ei_local->dmaing = 0; } @@ -543,18 +560,22 @@ static u32 etherm_regoffsets[16]; static int __init etherh_probe(struct expansion_card *ec, const struct ecard_id *id) { + const struct etherh_data *data = id->data; struct ei_device *ei_local; struct net_device *dev; struct etherh_priv *eh; - const char *dev_type; - int i, size, ret; + int i, ret; etherh_banner(); + ret = ecard_request_resources(ec); + if (ret) + goto out; + dev = alloc_ei_netdev(); if (!dev) { ret = -ENOMEM; - goto out; + goto release; } eh = netdev_priv(dev); @@ -562,111 +583,64 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id) spin_lock_init(&eh->eidev.page_lock); SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &ec->dev); dev->open = etherh_open; dev->stop = etherh_close; dev->set_config = etherh_set_config; dev->irq = ec->irq; - dev->base_addr = ecard_address(ec, ECARD_MEMC, 0); + dev->if_port = data->if_port; + dev->flags |= data->flags; - /* - * IRQ and control port handling - */ - if (ec->irq != 11) { - ec->ops = ðerh_ops; - ec->irq_data = eh; - } eh->ctrl = 0; eh->id = ec->cid.product; - - switch (ec->cid.product) { - case PROD_ANT_ETHERM: - etherm_addr(dev->dev_addr); - dev->base_addr += ETHERM_NS8390; - dev->mem_start = dev->base_addr + ETHERM_DATAPORT; - eh->ctrl_port = dev->base_addr + ETHERM_CTRLPORT; - break; - - case PROD_I3_ETHERLAN500: - etherh_addr(dev->dev_addr, ec); - dev->base_addr += ETHERH500_NS8390; - dev->mem_start = dev->base_addr + ETHERH500_DATAPORT; - eh->ctrl_port = ecard_address (ec, ECARD_IOC, ECARD_FAST) - + ETHERH500_CTRLPORT; - break; - - case PROD_I3_ETHERLAN600: - case PROD_I3_ETHERLAN600A: - etherh_addr(dev->dev_addr, ec); - dev->base_addr += ETHERH600_NS8390; - dev->mem_start = dev->base_addr + ETHERH600_DATAPORT; - eh->ctrl_port = dev->base_addr + ETHERH600_CTRLPORT; - break; - - default: - printk(KERN_ERR "%s: unknown card type %x\n", - dev->name, ec->cid.product); - ret = -ENODEV; + eh->memc = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC), PAGE_SIZE); + if (!eh->memc) { + ret = -ENOMEM; goto free; } - size = 16; - if (ec->cid.product == PROD_ANT_ETHERM) - size <<= 3; - - if (!request_region(dev->base_addr, size, dev->name)) { - ret = -EBUSY; - goto free; + eh->ctrl_port = eh->memc; + if (data->ctrl_ioc) { + eh->ioc_fast = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST), PAGE_SIZE); + if (!eh->ioc_fast) { + ret = -ENOMEM; + goto free; + } + eh->ctrl_port = eh->ioc_fast; } + dev->base_addr = (unsigned long)eh->memc + data->ns8390_offset; + dev->mem_start = (unsigned long)eh->memc + data->dataport_offset; + eh->ctrl_port += data->ctrlport_offset; + /* - * If we're in the NIC slot, make sure the IRQ is enabled + * IRQ and control port handling - only for non-NIC slot cards. */ - if (dev->irq == 11) + if (ec->slot_no != 8) { + ec->ops = ðerh_ops; + ec->irq_data = eh; + } else { + /* + * If we're in the NIC slot, make sure the IRQ is enabled + */ etherh_set_ctrl(eh, ETHERH_CP_IE); - - switch (ec->cid.product) { - case PROD_ANT_ETHERM: - dev_type = "ANT EtherM"; - dev->if_port = IF_PORT_UNKNOWN; - break; - - case PROD_I3_ETHERLAN500: - dev_type = "i3 EtherH 500"; - dev->if_port = IF_PORT_UNKNOWN; - break; - - case PROD_I3_ETHERLAN600: - dev_type = "i3 EtherH 600"; - dev->flags |= IFF_PORTSEL | IFF_AUTOMEDIA; - dev->if_port = IF_PORT_10BASET; - break; - - case PROD_I3_ETHERLAN600A: - dev_type = "i3 EtherH 600A"; - dev->flags |= IFF_PORTSEL | IFF_AUTOMEDIA; - dev->if_port = IF_PORT_10BASET; - break; - - default: - dev_type = "unknown"; - break; } - ei_local = netdev_priv(dev); + ei_local = &eh->eidev; if (ec->cid.product == PROD_ANT_ETHERM) { - ei_local->tx_start_page = ETHERM_TX_START_PAGE; - ei_local->stop_page = ETHERM_STOP_PAGE; - ei_local->reg_offset = etherm_regoffsets; + etherm_addr(dev->dev_addr); + ei_local->reg_offset = etherm_regoffsets; } else { - ei_local->tx_start_page = ETHERH_TX_START_PAGE; - ei_local->stop_page = ETHERH_STOP_PAGE; - ei_local->reg_offset = etherh_regoffsets; + etherh_addr(dev->dev_addr, ec); + ei_local->reg_offset = etherh_regoffsets; } ei_local->name = dev->name; ei_local->word16 = 1; + ei_local->tx_start_page = data->tx_start_page; ei_local->rx_start_page = ei_local->tx_start_page + TX_PAGES; + ei_local->stop_page = data->stop_page; ei_local->reset_8390 = etherh_reset; ei_local->block_input = etherh_block_input; ei_local->block_output = etherh_block_output; @@ -678,10 +652,10 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id) ret = register_netdev(dev); if (ret) - goto release; + goto free; printk(KERN_INFO "%s: %s in slot %d, ", - dev->name, dev_type, ec->slot_no); + dev->name, data->name, ec->slot_no); for (i = 0; i < 6; i++) printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); @@ -690,10 +664,14 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id) return 0; - release: - release_region(dev->base_addr, 16); free: + if (eh->ioc_fast) + iounmap(eh->ioc_fast); + if (eh->memc) + iounmap(eh->memc); free_netdev(dev); + release: + ecard_release_resources(ec); out: return ret; } @@ -701,25 +679,69 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id) static void __devexit etherh_remove(struct expansion_card *ec) { struct net_device *dev = ecard_get_drvdata(ec); - int size = 16; + struct etherh_priv *eh = netdev_priv(dev); ecard_set_drvdata(ec, NULL); unregister_netdev(dev); - if (ec->cid.product == PROD_ANT_ETHERM) - size <<= 3; - release_region(dev->base_addr, size); + if (eh->ioc_fast) + iounmap(eh->ioc_fast); + iounmap(eh->memc); free_netdev(dev); ec->ops = NULL; kfree(ec->irq_data); + ecard_release_resources(ec); } +static struct etherh_data etherm_data = { + .ns8390_offset = ETHERM_NS8390, + .dataport_offset = ETHERM_NS8390 + ETHERM_DATAPORT, + .ctrlport_offset = ETHERM_NS8390 + ETHERM_CTRLPORT, + .name = "ANT EtherM", + .if_port = IF_PORT_UNKNOWN, + .tx_start_page = ETHERM_TX_START_PAGE, + .stop_page = ETHERM_STOP_PAGE, +}; + +static struct etherh_data etherlan500_data = { + .ns8390_offset = ETHERH500_NS8390, + .dataport_offset = ETHERH500_NS8390 + ETHERH500_DATAPORT, + .ctrlport_offset = ETHERH500_CTRLPORT, + .ctrl_ioc = 1, + .name = "i3 EtherH 500", + .if_port = IF_PORT_UNKNOWN, + .tx_start_page = ETHERH_TX_START_PAGE, + .stop_page = ETHERH_STOP_PAGE, +}; + +static struct etherh_data etherlan600_data = { + .ns8390_offset = ETHERH600_NS8390, + .dataport_offset = ETHERH600_NS8390 + ETHERH600_DATAPORT, + .ctrlport_offset = ETHERH600_NS8390 + ETHERH600_CTRLPORT, + .name = "i3 EtherH 600", + .flags = IFF_PORTSEL | IFF_AUTOMEDIA, + .if_port = IF_PORT_10BASET, + .tx_start_page = ETHERH_TX_START_PAGE, + .stop_page = ETHERH_STOP_PAGE, +}; + +static struct etherh_data etherlan600a_data = { + .ns8390_offset = ETHERH600_NS8390, + .dataport_offset = ETHERH600_NS8390 + ETHERH600_DATAPORT, + .ctrlport_offset = ETHERH600_NS8390 + ETHERH600_CTRLPORT, + .name = "i3 EtherH 600A", + .flags = IFF_PORTSEL | IFF_AUTOMEDIA, + .if_port = IF_PORT_10BASET, + .tx_start_page = ETHERH_TX_START_PAGE, + .stop_page = ETHERH_STOP_PAGE, +}; + static const struct ecard_id etherh_ids[] = { - { MANU_ANT, PROD_ANT_ETHERM }, - { MANU_I3, PROD_I3_ETHERLAN500 }, - { MANU_I3, PROD_I3_ETHERLAN600 }, - { MANU_I3, PROD_I3_ETHERLAN600A }, + { MANU_ANT, PROD_ANT_ETHERM, ðerm_data }, + { MANU_I3, PROD_I3_ETHERLAN500, ðerlan500_data }, + { MANU_I3, PROD_I3_ETHERLAN600, ðerlan600_data }, + { MANU_I3, PROD_I3_ETHERLAN600A, ðerlan600a_data }, { 0xffff, 0xffff } }; @@ -737,8 +759,8 @@ static int __init etherh_init(void) int i; for (i = 0; i < 16; i++) { - etherh_regoffsets[i] = i; - etherm_regoffsets[i] = i << 3; + etherh_regoffsets[i] = i << 2; + etherm_regoffsets[i] = i << 5; } return ecard_register_driver(ðerh_driver); diff --git a/drivers/net/fc/iph5526.c b/drivers/net/fc/iph5526.c index f69d0c18d572..ec3fff4e62f5 100644 --- a/drivers/net/fc/iph5526.c +++ b/drivers/net/fc/iph5526.c @@ -2910,7 +2910,7 @@ static void iph5526_timeout(struct net_device *dev) { struct fc_info *fi = dev->priv; printk(KERN_WARNING "%s: timed out on send.\n", dev->name); - fi->fc_stats.rx_dropped++; + fi->fc_stats.tx_dropped++; dev->trans_start = jiffies; netif_wake_queue(dev); } @@ -2953,7 +2953,7 @@ static int iph5526_send_packet(struct sk_buff *skb, struct net_device *dev) fi->fc_stats.tx_packets++; } else - fi->fc_stats.rx_dropped++; + fi->fc_stats.tx_dropped++; dev->trans_start = jiffies; /* We free up the IP buffers in the OCI_interrupt handler. * status == 0 implies that the frame was not transmitted. So the diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index f89bd77a72ff..9bae8d9abcd1 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -387,7 +387,7 @@ enum register_offsets { IntrStatus = 0x10, IntrMask = 0x14, IntrEnable = 0x18, - IntrHoldoff = 0x16, /* DP83816 only */ + IntrHoldoff = 0x1C, /* DP83816 only */ TxRingPtr = 0x20, TxConfig = 0x24, RxRingPtr = 0x30, diff --git a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c index 7c02aba66179..2d0d92954f4f 100644 --- a/drivers/net/sk_mca.c +++ b/drivers/net/sk_mca.c @@ -997,13 +997,13 @@ static void skmca_set_multicast_list(struct net_device *dev) block.Mode &= ~LANCE_INIT_PROM; if (dev->flags & IFF_ALLMULTI) { /* get all multicasts */ - memset(block.LAdrF, 8, 0xff); + memset(block.LAdrF, 0xff, sizeof(block.LAdrF)); } else { /* get selected/no multicasts */ struct dev_mc_list *mptr; int code; - memset(block.LAdrF, 8, 0x00); + memset(block.LAdrF, 0, sizeof(block.LAdrF)); for (mptr = dev->mc_list; mptr != NULL; mptr = mptr->next) { code = GetHash(mptr->dmi_addr); block.LAdrF[(code >> 3) & 7] |= 1 << (code & 7); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 5c5a551fe630..6a821e7dbb03 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -42,13 +42,14 @@ struct divert_blk; struct vlan_group; struct ethtool_ops; - /* source back-compat hook */ + /* source back-compat hooks */ #define SET_ETHTOOL_OPS(netdev,ops) \ ( (netdev)->ethtool_ops = (ops) ) #define HAVE_ALLOC_NETDEV /* feature macro: alloc_xxxdev functions are available. */ -#define HAVE_FREE_NETDEV +#define HAVE_FREE_NETDEV /* free_netdev() */ +#define HAVE_NETDEV_PRIV /* netdev_priv() */ #define NET_XMIT_SUCCESS 0 #define NET_XMIT_DROP 1 /* skb dropped */ diff --git a/net/core/netpoll.c b/net/core/netpoll.c index dc8e76808546..32f946ee687e 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -163,21 +163,15 @@ repeat: spin_lock(&np->dev->xmit_lock); np->dev->xmit_lock_owner = smp_processor_id(); - if (netif_queue_stopped(np->dev)) { - np->dev->xmit_lock_owner = -1; - spin_unlock(&np->dev->xmit_lock); - - netpoll_poll(np); - goto repeat; - } - status = np->dev->hard_start_xmit(skb, np->dev); np->dev->xmit_lock_owner = -1; spin_unlock(&np->dev->xmit_lock); /* transmit busy */ - if(status) + if(status) { + netpoll_poll(np); goto repeat; + } } void netpoll_send_udp(struct netpoll *np, const char *msg, int len) @@ -231,9 +225,8 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len) static void arp_reply(struct sk_buff *skb) { - struct in_device *in_dev = (struct in_device *) skb->dev->ip_ptr; struct arphdr *arp; - unsigned char *arp_ptr, *sha, *tha; + unsigned char *arp_ptr; int size, type = ARPOP_REPLY, ptype = ETH_P_ARP; u32 sip, tip; struct sk_buff *send_skb; @@ -253,7 +246,7 @@ static void arp_reply(struct sk_buff *skb) if (!np) return; /* No arp on this interface */ - if (!in_dev || skb->dev->flags & IFF_NOARP) + if (skb->dev->flags & IFF_NOARP) return; if (!pskb_may_pull(skb, (sizeof(struct arphdr) + @@ -270,21 +263,15 @@ static void arp_reply(struct sk_buff *skb) arp->ar_op != htons(ARPOP_REQUEST)) return; - arp_ptr= (unsigned char *)(arp+1); - sha = arp_ptr; - arp_ptr += skb->dev->addr_len; + arp_ptr = (unsigned char *)(arp+1) + skb->dev->addr_len; memcpy(&sip, arp_ptr, 4); - arp_ptr += 4; - tha = arp_ptr; - arp_ptr += skb->dev->addr_len; + arp_ptr += 4 + skb->dev->addr_len; memcpy(&tip, arp_ptr, 4); /* Should we ignore arp? */ - if (tip != in_dev->ifa_list->ifa_address || - LOOPBACK(tip) || MULTICAST(tip)) + if (tip != htonl(np->local_ip) || LOOPBACK(tip) || MULTICAST(tip)) return; - size = sizeof(struct arphdr) + 2 * (skb->dev->addr_len + 4); send_skb = find_skb(np, size + LL_RESERVED_SPACE(np->dev), LL_RESERVED_SPACE(np->dev)); @@ -325,7 +312,7 @@ static void arp_reply(struct sk_buff *skb) arp_ptr += np->dev->addr_len; memcpy(arp_ptr, &tip, 4); arp_ptr += 4; - memcpy(arp_ptr, np->local_mac, np->dev->addr_len); + memcpy(arp_ptr, np->remote_mac, np->dev->addr_len); arp_ptr += np->dev->addr_len; memcpy(arp_ptr, &sip, 4); |
