summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@redhat.com>2004-04-16 04:55:41 -0400
committerJeff Garzik <jgarzik@redhat.com>2004-04-16 04:55:41 -0400
commit86014f1b6c5d06f063c2cc89d93387e583a65833 (patch)
treebc8a072e5bbeda50b2cccbd212ac00e9a884da30
parentfbd532e3977a9c785b9fb2c7f9b698febaaf3a6a (diff)
parentce99046f5b8e8219b43d038204b15b106cb891a6 (diff)
Merge redhat.com:/spare/repo/netdev-2.6/misc
into redhat.com:/spare/repo/net-drivers-2.6
-rw-r--r--MAINTAINERS20
-rw-r--r--drivers/net/8390.c2
-rw-r--r--drivers/net/8390.h15
-rw-r--r--drivers/net/Kconfig3
-rwxr-xr-xdrivers/net/amd8111e.c227
-rwxr-xr-xdrivers/net/amd8111e.h3
-rw-r--r--drivers/net/arcnet/com20020-isa.c2
-rw-r--r--drivers/net/arm/etherh.c318
-rw-r--r--drivers/net/fc/iph5526.c4
-rw-r--r--drivers/net/natsemi.c2
-rw-r--r--drivers/net/sk_mca.c4
-rw-r--r--include/linux/netdevice.h5
-rw-r--r--net/core/netpoll.c31
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 = &etherh_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 = &etherh_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, &etherm_data },
+ { MANU_I3, PROD_I3_ETHERLAN500, &etherlan500_data },
+ { MANU_I3, PROD_I3_ETHERLAN600, &etherlan600_data },
+ { MANU_I3, PROD_I3_ETHERLAN600A, &etherlan600a_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(&etherh_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);