summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/3c59x.c1
-rw-r--r--drivers/net/8139cp.c1
-rw-r--r--drivers/net/8139too.c1
-rw-r--r--drivers/net/82596.c1
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/Makefile4
-rw-r--r--drivers/net/acenic.c6
-rw-r--r--drivers/net/atl1/atl1_hw.h9
-rw-r--r--drivers/net/atl1/atl1_main.c28
-rw-r--r--drivers/net/ax88796.c3
-rw-r--r--drivers/net/b44.c1
-rw-r--r--drivers/net/bfin_mac.c6
-rw-r--r--drivers/net/bnx2.c1
-rw-r--r--drivers/net/bonding/bond_main.c52
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c1
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.c2
-rw-r--r--drivers/net/defxx.c17
-rw-r--r--drivers/net/e100.c1
-rw-r--r--drivers/net/e1000/e1000_ethtool.c1
-rw-r--r--drivers/net/ehea/ehea.h2
-rw-r--r--drivers/net/ehea/ehea_main.c22
-rw-r--r--drivers/net/fec.c49
-rw-r--r--drivers/net/forcedeth.c45
-rw-r--r--drivers/net/gianfar_mii.c2
-rw-r--r--drivers/net/gianfar_mii.h2
-rw-r--r--drivers/net/hamradio/bpqether.c6
-rw-r--r--drivers/net/ixgb/ixgb_ethtool.c1
-rw-r--r--drivers/net/lguest_net.c237
-rw-r--r--drivers/net/lib8390.c55
-rw-r--r--drivers/net/loopback.c7
-rw-r--r--drivers/net/mlx4/mr.c15
-rw-r--r--drivers/net/ne2k-pci.c1
-rw-r--r--drivers/net/netxen/netxen_nic.h3
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c1
-rw-r--r--drivers/net/netxen/netxen_nic_main.c92
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c4
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c23
-rw-r--r--drivers/net/pcnet32.c1
-rw-r--r--drivers/net/phy/vitesse.c2
-rw-r--r--drivers/net/pppoe.c37
-rw-r--r--drivers/net/pppol2tp.c4
-rw-r--r--drivers/net/pppox.c11
-rw-r--r--drivers/net/ps3_gelic_net.c215
-rw-r--r--drivers/net/ps3_gelic_net.h24
-rwxr-xr-xdrivers/net/qla3xxx.c1
-rw-r--r--drivers/net/r8169.c1
-rw-r--r--drivers/net/s2io-regs.h5
-rw-r--r--drivers/net/s2io.c542
-rw-r--r--drivers/net/s2io.h11
-rw-r--r--drivers/net/sc92031.c1
-rw-r--r--drivers/net/skfp/pmf.c2
-rw-r--r--drivers/net/skge.c1
-rw-r--r--drivers/net/sky2.c1
-rw-r--r--drivers/net/sundance.c1
-rw-r--r--drivers/net/sunlance.c48
-rw-r--r--drivers/net/sunvnet.c1
-rw-r--r--drivers/net/tc35815.c1
-rw-r--r--drivers/net/tg3.c1
-rw-r--r--drivers/net/tulip/tulip_core.c8
-rw-r--r--drivers/net/ucc_geth.c334
-rw-r--r--drivers/net/ucc_geth.h6
-rw-r--r--drivers/net/ucc_geth_ethtool.c388
-rw-r--r--drivers/net/ucc_geth_mii.c6
-rw-r--r--drivers/net/usb/pegasus.c4
-rw-r--r--drivers/net/via-rhine.c1
-rw-r--r--drivers/net/via-velocity.c2
66 files changed, 1432 insertions, 933 deletions
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 6deb20fc7a08..001c66dd3a94 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -2886,7 +2886,6 @@ static const struct ethtool_ops vortex_ethtool_ops = {
.set_settings = vortex_set_settings,
.get_link = ethtool_op_get_link,
.nway_reset = vortex_nway_reset,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
#ifdef CONFIG_PCI
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index e970e64bf966..a79f28c7a100 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -1578,7 +1578,6 @@ static const struct ethtool_ops cp_ethtool_ops = {
.set_wol = cp_set_wol,
.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,
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 327eaa7b4999..f4e4298d24b9 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -2452,7 +2452,6 @@ static const struct ethtool_ops rtl8139_ethtool_ops = {
.get_strings = rtl8139_get_strings,
.get_stats_count = rtl8139_get_stats_count,
.get_ethtool_stats = rtl8139_get_ethtool_stats,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/82596.c b/drivers/net/82596.c
index 3ff1155459a3..d915837193cc 100644
--- a/drivers/net/82596.c
+++ b/drivers/net/82596.c
@@ -57,6 +57,7 @@
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/pgtable.h>
+#include <asm/cacheflush.h>
static char version[] __initdata =
"82596.c $Revision: 1.5 $\n";
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index f8a602caabcb..81ef81c9a584 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2851,7 +2851,7 @@ config PPPOATM
config PPPOL2TP
tristate "PPP over L2TP (EXPERIMENTAL)"
- depends on EXPERIMENTAL && PPP
+ depends on EXPERIMENTAL && PPP && INET
help
Support for PPP-over-L2TP socket family. L2TP is a protocol
used by ISPs and enterprises to tunnel PPP traffic over UDP
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 336af0635df8..e684212fd8e2 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -18,7 +18,7 @@ gianfar_driver-objs := gianfar.o \
gianfar_sysfs.o
obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
-ucc_geth_driver-objs := ucc_geth.o ucc_geth_mii.o
+ucc_geth_driver-objs := ucc_geth.o ucc_geth_mii.o ucc_geth_ethtool.o
#
# link order important here
@@ -177,7 +177,7 @@ obj-$(CONFIG_ZORRO8390) += zorro8390.o
obj-$(CONFIG_HPLANCE) += hplance.o 7990.o
obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o
obj-$(CONFIG_EQUALIZER) += eql.o
-obj-$(CONFIG_LGUEST_GUEST) += lguest_net.o
+obj-$(CONFIG_LGUEST_NET) += lguest_net.o
obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o
obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index b78a4e5ceeb2..62e660a79387 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -3128,12 +3128,6 @@ static int __devinit read_eeprom_byte(struct net_device *dev,
int result = 0;
short i;
- if (!dev) {
- printk(KERN_ERR "No device!\n");
- result = -ENODEV;
- goto out;
- }
-
/*
* Don't take interrupts on this CPU will bit banging
* the %#%#@$ I2C device
diff --git a/drivers/net/atl1/atl1_hw.h b/drivers/net/atl1/atl1_hw.h
index 100c09c66e64..939aa0f53f6e 100644
--- a/drivers/net/atl1/atl1_hw.h
+++ b/drivers/net/atl1/atl1_hw.h
@@ -680,11 +680,6 @@ void atl1_check_options(struct atl1_adapter *adapter);
#define AUTONEG_ADVERTISE_10_100_ALL 0x000F /* All 10/100 speeds */
#define AUTONEG_ADVERTISE_10_ALL 0x0003 /* 10Mbps Full & Half speeds */
-/* The size (in bytes) of a ethernet packet */
-#define ENET_HEADER_SIZE 14
-#define MAXIMUM_ETHERNET_FRAME_SIZE 1518 /* with FCS */
-#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* with FCS */
-#define ETHERNET_FCS_SIZE 4
#define MAX_JUMBO_FRAME_SIZE 0x2800
#define PHY_AUTO_NEG_TIME 45 /* 4.5 Seconds */
@@ -929,8 +924,8 @@ enum atl1_dma_req_block {
atl1_dma_req_128 = 0,
atl1_dma_req_256 = 1,
atl1_dma_req_512 = 2,
- atl1_dam_req_1024 = 3,
- atl1_dam_req_2048 = 4,
+ atl1_dma_req_1024 = 3,
+ atl1_dma_req_2048 = 4,
atl1_dma_req_4096 = 5
};
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index fd1e156f1747..56f6389a300e 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -59,6 +59,7 @@
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
+#include <linux/if_ether.h>
#include <linux/irqreturn.h>
#include <linux/workqueue.h>
#include <linux/timer.h>
@@ -120,8 +121,8 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter)
struct atl1_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
- hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
- hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
+ hw->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
+ hw->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
adapter->wol = 0;
adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7;
@@ -314,7 +315,7 @@ err_nomem:
return -ENOMEM;
}
-void atl1_init_ring_ptrs(struct atl1_adapter *adapter)
+static void atl1_init_ring_ptrs(struct atl1_adapter *adapter)
{
struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
@@ -688,9 +689,9 @@ static int atl1_change_mtu(struct net_device *netdev, int new_mtu)
{
struct atl1_adapter *adapter = netdev_priv(netdev);
int old_mtu = netdev->mtu;
- int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
+ int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
- if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
+ if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
(max_frame > MAX_JUMBO_FRAME_SIZE)) {
dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
return -EINVAL;
@@ -908,8 +909,8 @@ static u32 atl1_configure(struct atl1_adapter *adapter)
/* config DMA Engine */
value = ((((u32) hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
<< DMA_CTRL_DMAR_BURST_LEN_SHIFT) |
- ((((u32) hw->dmaw_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
- << DMA_CTRL_DMAR_BURST_LEN_SHIFT) | DMA_CTRL_DMAR_EN |
+ ((((u32) hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK)
+ << DMA_CTRL_DMAW_BURST_LEN_SHIFT) | DMA_CTRL_DMAR_EN |
DMA_CTRL_DMAW_EN;
value |= (u32) hw->dma_ord;
if (atl1_rcb_128 == hw->rcb_value)
@@ -917,7 +918,10 @@ static u32 atl1_configure(struct atl1_adapter *adapter)
iowrite32(value, hw->hw_addr + REG_DMA_CTRL);
/* config CMB / SMB */
- value = hw->cmb_rrd | ((u32) hw->cmb_tpd << 16);
+ value = (hw->cmb_tpd > adapter->tpd_ring.count) ?
+ hw->cmb_tpd : adapter->tpd_ring.count;
+ value <<= 16;
+ value |= hw->cmb_rrd;
iowrite32(value, hw->hw_addr + REG_CMB_WRITE_TH);
value = hw->cmb_rx_timer | ((u32) hw->cmb_tx_timer << 16);
iowrite32(value, hw->hw_addr + REG_CMB_WRITE_TIMER);
@@ -1334,7 +1338,7 @@ rrd_ok:
skb = buffer_info->skb;
length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size);
- skb_put(skb, length - ETHERNET_FCS_SIZE);
+ skb_put(skb, length - ETH_FCS_LEN);
/* Receive Checksum Offload */
atl1_rx_checksum(adapter, rrd, skb);
@@ -1422,7 +1426,7 @@ static void atl1_intr_tx(struct atl1_adapter *adapter)
netif_wake_queue(adapter->netdev);
}
-static u16 tpd_avail(struct atl1_tpd_ring *tpd_ring)
+static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring)
{
u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
u16 next_to_use = atomic_read(&tpd_ring->next_to_use);
@@ -1453,7 +1457,7 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
iph->daddr, 0, IPPROTO_TCP, 0);
ipofst = skb_network_offset(skb);
- if (ipofst != ENET_HEADER_SIZE) /* 802.3 frame */
+ if (ipofst != ETH_HLEN) /* 802.3 frame */
tso->tsopl |= 1 << TSO_PARAM_ETHTYPE_SHIFT;
tso->tsopl |= (iph->ihl &
@@ -1708,7 +1712,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_LOCKED;
}
- if (tpd_avail(&adapter->tpd_ring) < count) {
+ if (atl1_tpd_avail(&adapter->tpd_ring) < count) {
/* not enough descriptors */
netif_stop_queue(netdev);
spin_unlock_irqrestore(&adapter->lock, flags);
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index 1d882360b34d..83da1770bafb 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -580,7 +580,6 @@ static const struct ethtool_ops ax_ethtool_ops = {
.set_settings = ax_set_settings,
.nway_reset = ax_nway_reset,
.get_link = ax_get_link,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
/* setup code */
@@ -819,7 +818,7 @@ static int ax_probe(struct platform_device *pdev)
}
ei_status.mem = ioremap(res->start, size);
- dev->base_addr = (long)ei_status.mem;
+ dev->base_addr = (unsigned long)ei_status.mem;
if (ei_status.mem == NULL) {
dev_err(&pdev->dev, "Cannot ioremap area (%08zx,%08zx)\n",
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 37f1b6ff5c12..0795df235492 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -2033,7 +2033,6 @@ static const struct ethtool_ops b44_ethtool_ops = {
.get_strings = b44_get_strings,
.get_stats_count = b44_get_stats_count,
.get_ethtool_stats = b44_get_ethtool_stats,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 9a08d656f1ce..2bb97d464689 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -798,6 +798,7 @@ static void bf537mac_shutdown(struct net_device *dev)
*/
static int bf537mac_open(struct net_device *dev)
{
+ int retval;
pr_debug("%s: %s\n", dev->name, __FUNCTION__);
/*
@@ -811,7 +812,10 @@ static int bf537mac_open(struct net_device *dev)
}
/* initial rx and tx list */
- desc_list_init();
+ retval = desc_list_init();
+
+ if (retval)
+ return retval;
bf537mac_setphy(dev);
setup_system_regs(dev);
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index a729da061bbb..d53dfc5bbae0 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -6269,7 +6269,6 @@ static const struct ethtool_ops bnx2_ethtool_ops = {
.phys_id = bnx2_phys_id,
.get_stats_count = bnx2_get_stats_count,
.get_ethtool_stats = bnx2_get_ethtool_stats,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
/* Called with rtnl_lock */
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index cb9cb3013f42..070b78d959cc 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -613,38 +613,20 @@ down:
static int bond_update_speed_duplex(struct slave *slave)
{
struct net_device *slave_dev = slave->dev;
- static int (* ioctl)(struct net_device *, struct ifreq *, int);
- struct ifreq ifr;
struct ethtool_cmd etool;
+ int res;
/* Fake speed and duplex */
slave->speed = SPEED_100;
slave->duplex = DUPLEX_FULL;
- if (slave_dev->ethtool_ops) {
- int res;
-
- if (!slave_dev->ethtool_ops->get_settings) {
- return -1;
- }
-
- res = slave_dev->ethtool_ops->get_settings(slave_dev, &etool);
- if (res < 0) {
- return -1;
- }
-
- goto verify;
- }
+ if (!slave_dev->ethtool_ops || !slave_dev->ethtool_ops->get_settings)
+ return -1;
- ioctl = slave_dev->do_ioctl;
- strncpy(ifr.ifr_name, slave_dev->name, IFNAMSIZ);
- etool.cmd = ETHTOOL_GSET;
- ifr.ifr_data = (char*)&etool;
- if (!ioctl || (IOCTL(slave_dev, &ifr, SIOCETHTOOL) < 0)) {
+ res = slave_dev->ethtool_ops->get_settings(slave_dev, &etool);
+ if (res < 0)
return -1;
- }
-verify:
switch (etool.speed) {
case SPEED_10:
case SPEED_100:
@@ -690,7 +672,6 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
static int (* ioctl)(struct net_device *, struct ifreq *, int);
struct ifreq ifr;
struct mii_ioctl_data *mii;
- struct ethtool_value etool;
if (bond->params.use_carrier) {
return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
@@ -721,9 +702,10 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
}
}
- /* try SIOCETHTOOL ioctl, some drivers cache ETHTOOL_GLINK */
- /* for a period of time so we attempt to get link status */
- /* from it last if the above MII ioctls fail... */
+ /*
+ * Some drivers cache ETHTOOL_GLINK for a period of time so we only
+ * attempt to get link status from it if the above MII ioctls fail.
+ */
if (slave_dev->ethtool_ops) {
if (slave_dev->ethtool_ops->get_link) {
u32 link;
@@ -734,23 +716,9 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
}
}
- if (ioctl) {
- strncpy(ifr.ifr_name, slave_dev->name, IFNAMSIZ);
- etool.cmd = ETHTOOL_GLINK;
- ifr.ifr_data = (char*)&etool;
- if (IOCTL(slave_dev, &ifr, SIOCETHTOOL) == 0) {
- if (etool.data == 1) {
- return BMSR_LSTATUS;
- } else {
- dprintk("SIOCETHTOOL shows link down\n");
- return 0;
- }
- }
- }
-
/*
* If reporting, report that either there's no dev->do_ioctl,
- * or both SIOCGMIIREG and SIOCETHTOOL failed (meaning that we
+ * or both SIOCGMIIREG and get_link failed (meaning that we
* cannot report link status). If not reporting, pretend
* we're ok.
*/
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 6fd1e5241833..dc5d26988bb3 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1583,7 +1583,6 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
.get_wol = get_wol,
.get_tso = ethtool_op_get_tso,
.set_tso = ethtool_op_set_tso,
- .get_perm_addr = ethtool_op_get_perm_addr
};
static int in_range(int val, int lo, int hi)
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index ebcf35e4cf5b..e620ed4c3ff0 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -699,7 +699,7 @@ static int do_cr(struct t3cdev *dev, struct sk_buff *skb)
* the buffer.
*/
static struct sk_buff *cxgb3_get_cpl_reply_skb(struct sk_buff *skb, size_t len,
- int gfp)
+ gfp_t gfp)
{
if (likely(!skb_cloned(skb))) {
BUG_ON(skb->len < len);
diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c
index 7df23dc28190..9c8e3f9f5e58 100644
--- a/drivers/net/defxx.c
+++ b/drivers/net/defxx.c
@@ -200,6 +200,7 @@
/* Include files */
#include <linux/bitops.h>
+#include <linux/compiler.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/eisa.h>
@@ -240,8 +241,6 @@ static char version[] __devinitdata =
*/
#define NEW_SKB_SIZE (PI_RCV_DATA_K_SIZE_MAX+128)
-#define __unused __attribute__ ((unused))
-
#ifdef CONFIG_PCI
#define DFX_BUS_PCI(dev) (dev->bus == &pci_bus_type)
#else
@@ -375,7 +374,7 @@ static inline void dfx_outl(DFX_board_t *bp, int offset, u32 data)
static void dfx_port_write_long(DFX_board_t *bp, int offset, u32 data)
{
- struct device __unused *bdev = bp->bus_dev;
+ struct device __maybe_unused *bdev = bp->bus_dev;
int dfx_bus_tc = DFX_BUS_TC(bdev);
int dfx_use_mmio = DFX_MMIO || dfx_bus_tc;
@@ -399,7 +398,7 @@ static inline void dfx_inl(DFX_board_t *bp, int offset, u32 *data)
static void dfx_port_read_long(DFX_board_t *bp, int offset, u32 *data)
{
- struct device __unused *bdev = bp->bus_dev;
+ struct device __maybe_unused *bdev = bp->bus_dev;
int dfx_bus_tc = DFX_BUS_TC(bdev);
int dfx_use_mmio = DFX_MMIO || dfx_bus_tc;
@@ -866,7 +865,7 @@ static void __devinit dfx_bus_uninit(struct net_device *dev)
static void __devinit dfx_bus_config_check(DFX_board_t *bp)
{
- struct device __unused *bdev = bp->bus_dev;
+ struct device __maybe_unused *bdev = bp->bus_dev;
int dfx_bus_eisa = DFX_BUS_EISA(bdev);
int status; /* return code from adapter port control call */
u32 host_data; /* LW data returned from port control call */
@@ -3624,8 +3623,8 @@ static void __devexit dfx_unregister(struct device *bdev)
}
-static int __devinit __unused dfx_dev_register(struct device *);
-static int __devexit __unused dfx_dev_unregister(struct device *);
+static int __devinit __maybe_unused dfx_dev_register(struct device *);
+static int __devexit __maybe_unused dfx_dev_unregister(struct device *);
#ifdef CONFIG_PCI
static int __devinit dfx_pci_register(struct pci_dev *,
@@ -3699,7 +3698,7 @@ static struct tc_driver dfx_tc_driver = {
};
#endif /* CONFIG_TC */
-static int __devinit __unused dfx_dev_register(struct device *dev)
+static int __devinit __maybe_unused dfx_dev_register(struct device *dev)
{
int status;
@@ -3709,7 +3708,7 @@ static int __devinit __unused dfx_dev_register(struct device *dev)
return status;
}
-static int __devexit __unused dfx_dev_unregister(struct device *dev)
+static int __devexit __maybe_unused dfx_dev_unregister(struct device *dev)
{
put_device(dev);
dfx_unregister(dev);
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 6b6401e9304e..280313b9b069 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -2506,7 +2506,6 @@ static const struct ethtool_ops e100_ethtool_ops = {
.phys_id = e100_phys_id,
.get_stats_count = e100_get_stats_count,
.get_ethtool_stats = e100_get_ethtool_stats,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index bb08375b5f13..c90c92e72d2a 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1973,7 +1973,6 @@ static const struct ethtool_ops e1000_ethtool_ops = {
.phys_id = e1000_phys_id,
.get_stats_count = e1000_get_stats_count,
.get_ethtool_stats = e1000_get_ethtool_stats,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
void e1000_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 489c8b260dd8..8ee2c2c86b42 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,7 @@
#include <asm/io.h>
#define DRV_NAME "ehea"
-#define DRV_VERSION "EHEA_0071"
+#define DRV_VERSION "EHEA_0072"
/* eHEA capability flags */
#define DLPAR_PORT_ADD_REM 1
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 4c70a9301c1b..58702f54c3fb 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -589,6 +589,23 @@ static int ehea_poll(struct net_device *dev, int *budget)
return 1;
}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void ehea_netpoll(struct net_device *dev)
+{
+ struct ehea_port *port = netdev_priv(dev);
+
+ netif_rx_schedule(port->port_res[0].d_netdev);
+}
+#endif
+
+static int ehea_poll_firstqueue(struct net_device *dev, int *budget)
+{
+ struct ehea_port *port = netdev_priv(dev);
+ struct net_device *d_dev = port->port_res[0].d_netdev;
+
+ return ehea_poll(d_dev, budget);
+}
+
static irqreturn_t ehea_recv_irq_handler(int irq, void *param)
{
struct ehea_port_res *pr = param;
@@ -2626,7 +2643,10 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
memcpy(dev->dev_addr, &port->mac_addr, ETH_ALEN);
dev->open = ehea_open;
- dev->poll = ehea_poll;
+ dev->poll = ehea_poll_firstqueue;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ dev->poll_controller = ehea_netpoll;
+#endif
dev->weight = 64;
dev->stop = ehea_stop;
dev->hard_start_xmit = ehea_start_xmit;
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 03023dd17829..4e8df910c00d 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -47,6 +47,7 @@
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/pgtable.h>
+#include <asm/cacheflush.h>
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \
defined(CONFIG_M5272) || defined(CONFIG_M528x) || \
@@ -98,8 +99,6 @@ static unsigned char fec_mac_default[] = {
#define FEC_FLASHMAC 0xf0006006
#elif defined(CONFIG_GILBARCONAP) || defined(CONFIG_SCALES)
#define FEC_FLASHMAC 0xf0006000
-#elif defined (CONFIG_MTD_KeyTechnology)
-#define FEC_FLASHMAC 0xffe04000
#elif defined(CONFIG_CANCam)
#define FEC_FLASHMAC 0xf0020000
#elif defined (CONFIG_M5272C3)
@@ -191,6 +190,8 @@ struct fec_enet_private {
/* Hardware registers of the FEC device */
volatile fec_t *hwp;
+ struct net_device *netdev;
+
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
unsigned char *tx_bounce[TX_RING_SIZE];
struct sk_buff* tx_skbuff[TX_RING_SIZE];
@@ -1269,7 +1270,7 @@ static void __inline__ fec_request_intrs(struct net_device *dev)
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR3);
*icrp = 0x00000ddd;
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
- *icrp = (*icrp & 0x70777777) | 0x0d000000;
+ *icrp = 0x0d000000;
}
static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
@@ -1331,7 +1332,7 @@ static void __inline__ fec_disable_phy_intr(void)
{
volatile unsigned long *icrp;
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
- *icrp = (*icrp & 0x70777777) | 0x08000000;
+ *icrp = 0x08000000;
}
static void __inline__ fec_phy_ack_intr(void)
@@ -1339,7 +1340,7 @@ static void __inline__ fec_phy_ack_intr(void)
volatile unsigned long *icrp;
/* Acknowledge the interrupt */
icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
- *icrp = (*icrp & 0x77777777) | 0x08000000;
+ *icrp = 0x0d000000;
}
static void __inline__ fec_localhw_setup(void)
@@ -1426,6 +1427,29 @@ static void __inline__ fec_request_intrs(struct net_device *dev)
*gpio_pehlpar = 0xc0;
}
#endif
+
+#if defined(CONFIG_M527x)
+ /* Set up gpio outputs for MII lines */
+ {
+ volatile u8 *gpio_par_fec;
+ volatile u16 *gpio_par_feci2c;
+
+ gpio_par_feci2c = (volatile u16 *)(MCF_IPSBAR + 0x100082);
+ /* Set up gpio outputs for FEC0 MII lines */
+ gpio_par_fec = (volatile u8 *)(MCF_IPSBAR + 0x100078);
+
+ *gpio_par_feci2c |= 0x0f00;
+ *gpio_par_fec |= 0xc0;
+
+#if defined(CONFIG_FEC2)
+ /* Set up gpio outputs for FEC1 MII lines */
+ gpio_par_fec = (volatile u8 *)(MCF_IPSBAR + 0x100079);
+
+ *gpio_par_feci2c |= 0x00a0;
+ *gpio_par_fec |= 0xc0;
+#endif /* CONFIG_FEC2 */
+ }
+#endif /* CONFIG_M527x */
}
static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
@@ -1940,9 +1964,10 @@ static void mii_display_status(struct net_device *dev)
printk(".\n");
}
-static void mii_display_config(struct net_device *dev)
+static void mii_display_config(struct work_struct *work)
{
- struct fec_enet_private *fep = netdev_priv(dev);
+ struct fec_enet_private *fep = container_of(work, struct fec_enet_private, phy_task);
+ struct net_device *dev = fep->netdev;
uint status = fep->phy_status;
/*
@@ -1976,9 +2001,10 @@ static void mii_display_config(struct net_device *dev)
fep->sequence_done = 1;
}
-static void mii_relink(struct net_device *dev)
+static void mii_relink(struct work_struct *work)
{
- struct fec_enet_private *fep = netdev_priv(dev);
+ struct fec_enet_private *fep = container_of(work, struct fec_enet_private, phy_task);
+ struct net_device *dev = fep->netdev;
int duplex;
/*
@@ -2022,7 +2048,7 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev)
return;
fep->mii_phy_task_queued = 1;
- INIT_WORK(&fep->phy_task, (void*)mii_relink, dev);
+ INIT_WORK(&fep->phy_task, mii_relink);
schedule_work(&fep->phy_task);
}
@@ -2035,7 +2061,7 @@ static void mii_queue_config(uint mii_reg, struct net_device *dev)
return;
fep->mii_phy_task_queued = 1;
- INIT_WORK(&fep->phy_task, (void*)mii_display_config, dev);
+ INIT_WORK(&fep->phy_task, mii_display_config);
schedule_work(&fep->phy_task);
}
@@ -2330,6 +2356,7 @@ int __init fec_enet_init(struct net_device *dev)
fep->index = index;
fep->hwp = fecp;
+ fep->netdev = dev;
/* Whack a reset. We should wait for this.
*/
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 6d1d50a19783..69f5f365239a 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -178,6 +178,7 @@
#define DEV_HAS_STATISTICS_V2 0x0800 /* device supports hw statistics version 2 */
#define DEV_HAS_TEST_EXTENDED 0x1000 /* device supports extended diagnostic test */
#define DEV_HAS_MGMT_UNIT 0x2000 /* device supports management unit */
+#define DEV_HAS_CORRECT_MACADDR 0x4000 /* device supports correct mac address order */
enum {
NvRegIrqStatus = 0x000,
@@ -4706,7 +4707,6 @@ static const struct ethtool_ops ops = {
.get_regs_len = nv_get_regs_len,
.get_regs = nv_get_regs,
.nway_reset = nv_nway_reset,
- .get_perm_addr = ethtool_op_get_perm_addr,
.get_tso = ethtool_op_get_tso,
.set_tso = nv_set_tso,
.get_ringparam = nv_get_ringparam,
@@ -5172,7 +5172,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
/* check the workaround bit for correct mac address order */
txreg = readl(base + NvRegTransmitPoll);
- if (txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) {
+ if ((txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) ||
+ (id->driver_data & DEV_HAS_CORRECT_MACADDR)) {
/* mac address is already in correct order */
dev->dev_addr[0] = (np->orig_mac[0] >> 0) & 0xff;
dev->dev_addr[1] = (np->orig_mac[0] >> 8) & 0xff;
@@ -5500,51 +5501,67 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ },
+ { /* MCP73 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28),
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ },
+ { /* MCP73 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29),
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ },
+ { /* MCP73 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30),
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ },
+ { /* MCP73 Ethernet Controller */
+ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31),
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{0,},
};
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index ac3596f45dd8..100bf410bf5f 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -245,7 +245,7 @@ int __init gfar_mdio_init(void)
return driver_register(&gianfar_mdio_driver);
}
-void __exit gfar_mdio_exit(void)
+void gfar_mdio_exit(void)
{
driver_unregister(&gianfar_mdio_driver);
}
diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h
index 5d3400469514..b373091c7031 100644
--- a/drivers/net/gianfar_mii.h
+++ b/drivers/net/gianfar_mii.h
@@ -42,5 +42,5 @@ struct gfar_mii {
int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
int __init gfar_mdio_init(void);
-void __exit gfar_mdio_exit(void);
+void gfar_mdio_exit(void);
#endif /* GIANFAR_PHY_H */
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 656f2789c9ba..cc0ee93669ea 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -413,12 +413,12 @@ static void *bpq_seq_next(struct seq_file *seq, void *v, loff_t *pos)
++*pos;
if (v == SEQ_START_TOKEN)
- p = bpq_devices.next;
+ p = rcu_dereference(bpq_devices.next);
else
- p = ((struct bpqdev *)v)->bpq_list.next;
+ p = rcu_dereference(((struct bpqdev *)v)->bpq_list.next);
return (p == &bpq_devices) ? NULL
- : rcu_dereference(list_entry(p, struct bpqdev, bpq_list));
+ : list_entry(p, struct bpqdev, bpq_list);
}
static void bpq_seq_stop(struct seq_file *seq, void *v)
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index afde84868bea..0413cd95eda7 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -724,7 +724,6 @@ static const struct ethtool_ops ixgb_ethtool_ops = {
.phys_id = ixgb_phys_id,
.get_stats_count = ixgb_get_stats_count,
.get_ethtool_stats = ixgb_get_ethtool_stats,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
void ixgb_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/lguest_net.c b/drivers/net/lguest_net.c
index 112778652f7d..cab57911a80e 100644
--- a/drivers/net/lguest_net.c
+++ b/drivers/net/lguest_net.c
@@ -1,6 +1,13 @@
-/* A simple network driver for lguest.
+/*D:500
+ * The Guest network driver.
*
- * Copyright 2006 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
+ * This is very simple a virtual network driver, and our last Guest driver.
+ * The only trick is that it can talk directly to multiple other recipients
+ * (ie. other Guests on the same network). It can also be used with only the
+ * Host on the network.
+ :*/
+
+/* Copyright 2006 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
*
* 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
@@ -28,23 +35,47 @@
#define MAX_LANS 4
#define NUM_SKBS 8
+/*M:011 Network code master Jeff Garzik points out numerous shortcomings in
+ * this driver if it aspires to greatness.
+ *
+ * Firstly, it doesn't use "NAPI": the networking's New API, and is poorer for
+ * it. As he says "NAPI means system-wide load leveling, across multiple
+ * network interfaces. Lack of NAPI can mean competition at higher loads."
+ *
+ * He also points out that we don't implement set_mac_address, so users cannot
+ * change the devices hardware address. When I asked why one would want to:
+ * "Bonding, and situations where you /do/ want the MAC address to "leak" out
+ * of the host onto the wider net."
+ *
+ * Finally, he would like module unloading: "It is not unrealistic to think of
+ * [un|re|]loading the net support module in an lguest guest. And, adding
+ * module support makes the programmer more responsible, because they now have
+ * to learn to clean up after themselves. Any driver that cannot clean up
+ * after itself is an incomplete driver in my book."
+ :*/
+
+/*D:530 The "struct lguestnet_info" contains all the information we need to
+ * know about the network device. */
struct lguestnet_info
{
- /* The shared page(s). */
+ /* The mapped device page(s) (an array of "struct lguest_net"). */
struct lguest_net *peer;
+ /* The physical address of the device page(s) */
unsigned long peer_phys;
+ /* The size of the device page(s). */
unsigned long mapsize;
/* The lguest_device I come from */
struct lguest_device *lgdev;
- /* My peerid. */
+ /* My peerid (ie. my slot in the array). */
unsigned int me;
- /* Receive queue. */
+ /* Receive queue: the network packets waiting to be filled. */
struct sk_buff *skb[NUM_SKBS];
struct lguest_dma dma[NUM_SKBS];
};
+/*:*/
/* How many bytes left in this page. */
static unsigned int rest_of_page(void *data)
@@ -52,39 +83,82 @@ static unsigned int rest_of_page(void *data)
return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE);
}
-/* Simple convention: offset 4 * peernum. */
+/*D:570 Each peer (ie. Guest or Host) on the network binds their receive
+ * buffers to a different key: we simply use the physical address of the
+ * device's memory page plus the peer number. The Host insists that all keys
+ * be a multiple of 4, so we multiply the peer number by 4. */
static unsigned long peer_key(struct lguestnet_info *info, unsigned peernum)
{
return info->peer_phys + 4 * peernum;
}
+/* This is the routine which sets up a "struct lguest_dma" to point to a
+ * network packet, similar to req_to_dma() in lguest_blk.c. The structure of a
+ * "struct sk_buff" has grown complex over the years: it consists of a "head"
+ * linear section pointed to by "skb->data", and possibly an array of
+ * "fragments" in the case of a non-linear packet.
+ *
+ * Our receive buffers don't use fragments at all but outgoing skbs might, so
+ * we handle it. */
static void skb_to_dma(const struct sk_buff *skb, unsigned int headlen,
struct lguest_dma *dma)
{
unsigned int i, seg;
+ /* First, we put the linear region into the "struct lguest_dma". Each
+ * entry can't go over a page boundary, so even though all our packets
+ * are 1514 bytes or less, we might need to use two entries here: */
for (i = seg = 0; i < headlen; seg++, i += rest_of_page(skb->data+i)) {
dma->addr[seg] = virt_to_phys(skb->data + i);
dma->len[seg] = min((unsigned)(headlen - i),
rest_of_page(skb->data + i));
}
+
+ /* Now we handle the fragments: at least they're guaranteed not to go
+ * over a page. skb_shinfo(skb) returns a pointer to the structure
+ * which tells us about the number of fragments and the fragment
+ * array. */
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++, seg++) {
const skb_frag_t *f = &skb_shinfo(skb)->frags[i];
/* Should not happen with MTU less than 64k - 2 * PAGE_SIZE. */
if (seg == LGUEST_MAX_DMA_SECTIONS) {
+ /* We will end up sending a truncated packet should
+ * this ever happen. Plus, a cool log message! */
printk("Woah dude! Megapacket!\n");
break;
}
dma->addr[seg] = page_to_phys(f->page) + f->page_offset;
dma->len[seg] = f->size;
}
+
+ /* If after all that we didn't use the entire "struct lguest_dma"
+ * array, we terminate it with a 0 length. */
if (seg < LGUEST_MAX_DMA_SECTIONS)
dma->len[seg] = 0;
}
-/* We overload multicast bit to show promiscuous mode. */
+/*
+ * Packet transmission.
+ *
+ * Our packet transmission is a little unusual. A real network card would just
+ * send out the packet and leave the receivers to decide if they're interested.
+ * Instead, we look through the network device memory page and see if any of
+ * the ethernet addresses match the packet destination, and if so we send it to
+ * that Guest.
+ *
+ * This is made a little more complicated in two cases. The first case is
+ * broadcast packets: for that we send the packet to all Guests on the network,
+ * one at a time. The second case is "promiscuous" mode, where a Guest wants
+ * to see all the packets on the network. We need a way for the Guest to tell
+ * us it wants to see all packets, so it sets the "multicast" bit on its
+ * published MAC address, which is never valid in a real ethernet address.
+ */
#define PROMISC_BIT 0x01
+/* This is the callback which is summoned whenever the network device's
+ * multicast or promiscuous state changes. If the card is in promiscuous mode,
+ * we advertise that in our ethernet address in the device's memory. We do the
+ * same if Linux wants any or all multicast traffic. */
static void lguestnet_set_multicast(struct net_device *dev)
{
struct lguestnet_info *info = netdev_priv(dev);
@@ -95,11 +169,14 @@ static void lguestnet_set_multicast(struct net_device *dev)
info->peer[info->me].mac[0] &= ~PROMISC_BIT;
}
+/* A simple test function to see if a peer wants to see all packets.*/
static int promisc(struct lguestnet_info *info, unsigned int peer)
{
return info->peer[peer].mac[0] & PROMISC_BIT;
}
+/* Another simple function to see if a peer's advertised ethernet address
+ * matches a packet's destination ethernet address. */
static int mac_eq(const unsigned char mac[ETH_ALEN],
struct lguestnet_info *info, unsigned int peer)
{
@@ -109,6 +186,8 @@ static int mac_eq(const unsigned char mac[ETH_ALEN],
return memcmp(mac+1, info->peer[peer].mac+1, ETH_ALEN-1) == 0;
}
+/* This is the function which actually sends a packet once we've decided a
+ * peer wants it: */
static void transfer_packet(struct net_device *dev,
struct sk_buff *skb,
unsigned int peernum)
@@ -116,76 +195,134 @@ static void transfer_packet(struct net_device *dev,
struct lguestnet_info *info = netdev_priv(dev);
struct lguest_dma dma;
+ /* We use our handy "struct lguest_dma" packing function to prepare
+ * the skb for sending. */
skb_to_dma(skb, skb_headlen(skb), &dma);
pr_debug("xfer length %04x (%u)\n", htons(skb->len), skb->len);
+ /* This is the actual send call which copies the packet. */
lguest_send_dma(peer_key(info, peernum), &dma);
+
+ /* Check that the entire packet was transmitted. If not, it could mean
+ * that the other Guest registered a short receive buffer, but this
+ * driver should never do that. More likely, the peer is dead. */
if (dma.used_len != skb->len) {
dev->stats.tx_carrier_errors++;
pr_debug("Bad xfer to peer %i: %i of %i (dma %p/%i)\n",
peernum, dma.used_len, skb->len,
(void *)dma.addr[0], dma.len[0]);
} else {
+ /* On success we update the stats. */
dev->stats.tx_bytes += skb->len;
dev->stats.tx_packets++;
}
}
+/* Another helper function to tell is if a slot in the device memory is unused.
+ * Since we always set the Local Assignment bit in the ethernet address, the
+ * first byte can never be 0. */
static int unused_peer(const struct lguest_net peer[], unsigned int num)
{
return peer[num].mac[0] == 0;
}
+/* Finally, here is the routine which handles an outgoing packet. It's called
+ * "start_xmit" for traditional reasons. */
static int lguestnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
unsigned int i;
int broadcast;
struct lguestnet_info *info = netdev_priv(dev);
+ /* Extract the destination ethernet address from the packet. */
const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
pr_debug("%s: xmit %02x:%02x:%02x:%02x:%02x:%02x\n",
dev->name, dest[0],dest[1],dest[2],dest[3],dest[4],dest[5]);
+ /* If it's a multicast packet, we broadcast to everyone. That's not
+ * very efficient, but there are very few applications which actually
+ * use multicast, which is a shame really.
+ *
+ * As etherdevice.h points out: "By definition the broadcast address is
+ * also a multicast address." So we don't have to test for broadcast
+ * packets separately. */
broadcast = is_multicast_ether_addr(dest);
+
+ /* Look through all the published ethernet addresses to see if we
+ * should send this packet. */
for (i = 0; i < info->mapsize/sizeof(struct lguest_net); i++) {
+ /* We don't send to ourselves (we actually can't SEND_DMA to
+ * ourselves anyway), and don't send to unused slots.*/
if (i == info->me || unused_peer(info->peer, i))
continue;
+ /* If it's broadcast we send it. If they want every packet we
+ * send it. If the destination matches their address we send
+ * it. Otherwise we go to the next peer. */
if (!broadcast && !promisc(info, i) && !mac_eq(dest, info, i))
continue;
pr_debug("lguestnet %s: sending from %i to %i\n",
dev->name, info->me, i);
+ /* Our routine which actually does the transfer. */
transfer_packet(dev, skb, i);
}
+
+ /* An xmit routine is expected to dispose of the packet, so we do. */
dev_kfree_skb(skb);
+
+ /* As per kernel convention, 0 means success. This is why I love
+ * networking: even if we never sent to anyone, that's still
+ * success! */
return 0;
}
-/* Find a new skb to put in this slot in shared mem. */
+/*D:560
+ * Packet receiving.
+ *
+ * First, here's a helper routine which fills one of our array of receive
+ * buffers: */
static int fill_slot(struct net_device *dev, unsigned int slot)
{
struct lguestnet_info *info = netdev_priv(dev);
- /* Try to create and register a new one. */
+
+ /* We can receive ETH_DATA_LEN (1500) byte packets, plus a standard
+ * ethernet header of ETH_HLEN (14) bytes. */
info->skb[slot] = netdev_alloc_skb(dev, ETH_HLEN + ETH_DATA_LEN);
if (!info->skb[slot]) {
printk("%s: could not fill slot %i\n", dev->name, slot);
return -ENOMEM;
}
+ /* skb_to_dma() is a helper which sets up the "struct lguest_dma" to
+ * point to the data in the skb: we also use it for sending out a
+ * packet. */
skb_to_dma(info->skb[slot], ETH_HLEN + ETH_DATA_LEN, &info->dma[slot]);
+
+ /* This is a Write Memory Barrier: it ensures that the entry in the
+ * receive buffer array is written *before* we set the "used_len" entry
+ * to 0. If the Host were looking at the receive buffer array from a
+ * different CPU, it could potentially see "used_len = 0" and not see
+ * the updated receive buffer information. This would be a horribly
+ * nasty bug, so make sure the compiler and CPU know this has to happen
+ * first. */
wmb();
- /* Now we tell hypervisor it can use the slot. */
+ /* Writing 0 to "used_len" tells the Host it can use this receive
+ * buffer now. */
info->dma[slot].used_len = 0;
return 0;
}
+/* This is the actual receive routine. When we receive an interrupt from the
+ * Host to tell us a packet has been delivered, we arrive here: */
static irqreturn_t lguestnet_rcv(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
struct lguestnet_info *info = netdev_priv(dev);
unsigned int i, done = 0;
+ /* Look through our entire receive array for an entry which has data
+ * in it. */
for (i = 0; i < ARRAY_SIZE(info->dma); i++) {
unsigned int length;
struct sk_buff *skb;
@@ -194,10 +331,16 @@ static irqreturn_t lguestnet_rcv(int irq, void *dev_id)
if (length == 0)
continue;
+ /* We've found one! Remember the skb (we grabbed the length
+ * above), and immediately refill the slot we've taken it
+ * from. */
done++;
skb = info->skb[i];
fill_slot(dev, i);
+ /* This shouldn't happen: micropackets could be sent by a
+ * badly-behaved Guest on the network, but the Host will never
+ * stuff more data in the buffer than the buffer length. */
if (length < ETH_HLEN || length > ETH_HLEN + ETH_DATA_LEN) {
pr_debug(KERN_WARNING "%s: unbelievable skb len: %i\n",
dev->name, length);
@@ -205,36 +348,72 @@ static irqreturn_t lguestnet_rcv(int irq, void *dev_id)
continue;
}
+ /* skb_put(), what a great function! I've ranted about this
+ * function before (http://lkml.org/lkml/1999/9/26/24). You
+ * call it after you've added data to the end of an skb (in
+ * this case, it was the Host which wrote the data). */
skb_put(skb, length);
+
+ /* The ethernet header contains a protocol field: we use the
+ * standard helper to extract it, and place the result in
+ * skb->protocol. The helper also sets up skb->pkt_type and
+ * eats up the ethernet header from the front of the packet. */
skb->protocol = eth_type_trans(skb, dev);
- /* This is a reliable transport. */
+
+ /* If this device doesn't need checksums for sending, we also
+ * don't need to check the packets when they come in. */
if (dev->features & NETIF_F_NO_CSUM)
skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ /* As a last resort for debugging the driver or the lguest I/O
+ * subsystem, you can uncomment the "#define DEBUG" at the top
+ * of this file, which turns all the pr_debug() into printk()
+ * and floods the logs. */
pr_debug("Receiving skb proto 0x%04x len %i type %i\n",
ntohs(skb->protocol), skb->len, skb->pkt_type);
+ /* Update the packet and byte counts (visible from ifconfig,
+ * and good for debugging). */
dev->stats.rx_bytes += skb->len;
dev->stats.rx_packets++;
+
+ /* Hand our fresh network packet into the stack's "network
+ * interface receive" routine. That will free the packet
+ * itself when it's finished. */
netif_rx(skb);
}
+
+ /* If we found any packets, we assume the interrupt was for us. */
return done ? IRQ_HANDLED : IRQ_NONE;
}
+/*D:550 This is where we start: when the device is brought up by dhcpd or
+ * ifconfig. At this point we advertise our MAC address to the rest of the
+ * network, and register receive buffers ready for incoming packets. */
static int lguestnet_open(struct net_device *dev)
{
int i;
struct lguestnet_info *info = netdev_priv(dev);
- /* Set up our MAC address */
+ /* Copy our MAC address into the device page, so others on the network
+ * can find us. */
memcpy(info->peer[info->me].mac, dev->dev_addr, ETH_ALEN);
- /* Turn on promisc mode if needed */
+ /* We might already be in promisc mode (dev->flags & IFF_PROMISC). Our
+ * set_multicast callback handles this already, so we call it now. */
lguestnet_set_multicast(dev);
+ /* Allocate packets and put them into our "struct lguest_dma" array.
+ * If we fail to allocate all the packets we could still limp along,
+ * but it's a sign of real stress so we should probably give up now. */
for (i = 0; i < ARRAY_SIZE(info->dma); i++) {
if (fill_slot(dev, i) != 0)
goto cleanup;
}
+
+ /* Finally we tell the Host where our array of "struct lguest_dma"
+ * receive buffers is, binding it to the key corresponding to the
+ * device's physical memory plus our peerid. */
if (lguest_bind_dma(peer_key(info,info->me), info->dma,
NUM_SKBS, lgdev_irq(info->lgdev)) != 0)
goto cleanup;
@@ -245,22 +424,29 @@ cleanup:
dev_kfree_skb(info->skb[i]);
return -ENOMEM;
}
+/*:*/
+/* The close routine is called when the device is no longer in use: we clean up
+ * elegantly. */
static int lguestnet_close(struct net_device *dev)
{
unsigned int i;
struct lguestnet_info *info = netdev_priv(dev);
- /* Clear all trace: others might deliver packets, we'll ignore it. */
+ /* Clear all trace of our existence out of the device memory by setting
+ * the slot which held our MAC address to 0 (unused). */
memset(&info->peer[info->me], 0, sizeof(info->peer[info->me]));
- /* Deregister sg lists. */
+ /* Unregister our array of receive buffers */
lguest_unbind_dma(peer_key(info, info->me), info->dma);
for (i = 0; i < ARRAY_SIZE(info->dma); i++)
dev_kfree_skb(info->skb[i]);
return 0;
}
+/*D:510 The network device probe function is basically a standard ethernet
+ * device setup. It reads the "struct lguest_device_desc" and sets the "struct
+ * net_device". Oh, the line-by-line excitement! Let's skip over it. :*/
static int lguestnet_probe(struct lguest_device *lgdev)
{
int err, irqf = IRQF_SHARED;
@@ -290,10 +476,16 @@ static int lguestnet_probe(struct lguest_device *lgdev)
dev->stop = lguestnet_close;
dev->hard_start_xmit = lguestnet_start_xmit;
- /* Turning on/off promisc will call dev->set_multicast_list.
- * We don't actually support multicast yet */
+ /* We don't actually support multicast yet, but turning on/off
+ * promisc also calls dev->set_multicast_list. */
dev->set_multicast_list = lguestnet_set_multicast;
SET_NETDEV_DEV(dev, &lgdev->dev);
+
+ /* The network code complains if you have "scatter-gather" capability
+ * if you don't also handle checksums (it seem that would be
+ * "illogical"). So we use a lie of omission and don't tell it that we
+ * can handle scattered packets unless we also don't want checksums,
+ * even though to us they're completely independent. */
if (desc->features & LGUEST_NET_F_NOCSUM)
dev->features = NETIF_F_SG|NETIF_F_NO_CSUM;
@@ -325,6 +517,9 @@ static int lguestnet_probe(struct lguest_device *lgdev)
}
pr_debug("lguestnet: registered device %s\n", dev->name);
+ /* Finally, we put the "struct net_device" in the generic "struct
+ * lguest_device"s private pointer. Again, it's not necessary, but
+ * makes sure the cool kernel kids don't tease us. */
lgdev->private = dev;
return 0;
@@ -352,3 +547,11 @@ module_init(lguestnet_init);
MODULE_DESCRIPTION("Lguest network driver");
MODULE_LICENSE("GPL");
+
+/*D:580
+ * This is the last of the Drivers, and with this we have covered the many and
+ * wonderous and fine (and boring) details of the Guest.
+ *
+ * "make Launcher" beckons, where we answer questions like "Where do Guests
+ * come from?", and "What do you do when someone asks for optimization?"
+ */
diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c
index 5c86e737f954..c429a5002dd6 100644
--- a/drivers/net/lib8390.c
+++ b/drivers/net/lib8390.c
@@ -143,6 +143,52 @@ static void __NS8390_init(struct net_device *dev, int startp);
* annoying the transmit function is called bh atomic. That places
* restrictions on the user context callers as disable_irq won't save
* them.
+ *
+ * Additional explanation of problems with locking by Alan Cox:
+ *
+ * "The author (me) didn't use spin_lock_irqsave because the slowness of the
+ * card means that approach caused horrible problems like losing serial data
+ * at 38400 baud on some chips. Rememeber many 8390 nics on PCI were ISA
+ * chips with FPGA front ends.
+ *
+ * Ok the logic behind the 8390 is very simple:
+ *
+ * Things to know
+ * - IRQ delivery is asynchronous to the PCI bus
+ * - Blocking the local CPU IRQ via spin locks was too slow
+ * - The chip has register windows needing locking work
+ *
+ * So the path was once (I say once as people appear to have changed it
+ * in the mean time and it now looks rather bogus if the changes to use
+ * disable_irq_nosync_irqsave are disabling the local IRQ)
+ *
+ *
+ * Take the page lock
+ * Mask the IRQ on chip
+ * Disable the IRQ (but not mask locally- someone seems to have
+ * broken this with the lock validator stuff)
+ * [This must be _nosync as the page lock may otherwise
+ * deadlock us]
+ * Drop the page lock and turn IRQs back on
+ *
+ * At this point an existing IRQ may still be running but we can't
+ * get a new one
+ *
+ * Take the lock (so we know the IRQ has terminated) but don't mask
+ * the IRQs on the processor
+ * Set irqlock [for debug]
+ *
+ * Transmit (slow as ****)
+ *
+ * re-enable the IRQ
+ *
+ *
+ * We have to use disable_irq because otherwise you will get delayed
+ * interrupts on the APIC bus deadlocking the transmit path.
+ *
+ * Quite hairy but the chip simply wasn't designed for SMP and you can't
+ * even ACK an interrupt without risking corrupting other parallel
+ * activities on the chip." [lkml, 25 Jul 2007]
*/
@@ -219,15 +265,6 @@ static void ei_tx_timeout(struct net_device *dev)
int txsr, isr, tickssofar = jiffies - dev->trans_start;
unsigned long flags;
-#if defined(CONFIG_M32R) && defined(CONFIG_SMP)
- unsigned long icucr;
-
- local_irq_save(flags);
- icucr = inl(M32R_ICU_CR1_PORTL);
- icucr |= M32R_ICUCR_ISMOD11;
- outl(icucr, M32R_ICU_CR1_PORTL);
- local_irq_restore(flags);
-#endif
ei_local->stat.tx_errors++;
spin_lock_irqsave(&ei_local->page_lock, flags);
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 6ba6ed2b480a..5106c2328d12 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -229,7 +229,12 @@ struct net_device loopback_dev = {
/* Setup and register the loopback device. */
static int __init loopback_init(void)
{
- return register_netdev(&loopback_dev);
+ int err = register_netdev(&loopback_dev);
+
+ if (err)
+ panic("loopback: Failed to register netdevice: %d\n", err);
+
+ return err;
};
module_init(loopback_init);
diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c
index d0808fa3ec82..5b87183e62ce 100644
--- a/drivers/net/mlx4/mr.c
+++ b/drivers/net/mlx4/mr.c
@@ -255,10 +255,8 @@ int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access,
int err;
index = mlx4_bitmap_alloc(&priv->mr_table.mpt_bitmap);
- if (index == -1) {
- err = -ENOMEM;
- goto err;
- }
+ if (index == -1)
+ return -ENOMEM;
mr->iova = iova;
mr->size = size;
@@ -269,15 +267,8 @@ int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access,
err = mlx4_mtt_init(dev, npages, page_shift, &mr->mtt);
if (err)
- goto err_index;
-
- return 0;
-
-err_index:
- mlx4_bitmap_free(&priv->mr_table.mpt_bitmap, index);
+ mlx4_bitmap_free(&priv->mr_table.mpt_bitmap, index);
-err:
- kfree(mr);
return err;
}
EXPORT_SYMBOL_GPL(mlx4_mr_alloc);
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index cfdeaf7aa163..f81d9398d605 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -638,7 +638,6 @@ static const struct ethtool_ops ne2k_pci_ethtool_ops = {
.get_drvinfo = ne2k_pci_get_drvinfo,
.get_tx_csum = ethtool_op_get_tx_csum,
.get_sg = ethtool_op_get_sg,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 325269d8ae38..d4c92cc879d4 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1179,8 +1179,7 @@ dma_watchdog_shutdown_poll_result(struct netxen_adapter *adapter)
NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
printk(KERN_ERR "failed to read dma watchdog status\n");
- return ((netxen_get_dma_watchdog_enabled(ctrl) == 0) &&
- (netxen_get_dma_watchdog_disabled(ctrl) == 0));
+ return (netxen_get_dma_watchdog_enabled(ctrl) == 0);
}
static inline int
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 0175f6c353f6..a6138b474b4a 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -755,5 +755,4 @@ struct ethtool_ops netxen_nic_ethtool_ops = {
.get_strings = netxen_nic_get_strings,
.get_stats_count = netxen_nic_get_stats_count,
.get_ethtool_stats = netxen_nic_get_ethtool_stats,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index b703ccfe040b..08a62acde8bf 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -46,7 +46,7 @@ MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID);
-char netxen_nic_driver_name[] = "netxen-nic";
+char netxen_nic_driver_name[] = "netxen_nic";
static char netxen_nic_driver_string[] = "NetXen Network Driver version "
NETXEN_NIC_LINUX_VERSIONID;
@@ -335,7 +335,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->ahw.pdev = pdev;
adapter->ahw.pci_func = pci_func_id;
spin_lock_init(&adapter->tx_lock);
- spin_lock_init(&adapter->lock);
/* remap phys address */
mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */
@@ -640,6 +639,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
NETXEN_CRB_NORMALIZE(adapter,
NETXEN_ROMUSB_GLB_PEGTUNE_DONE));
/* Handshake with the card before we register the devices. */
+ writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+ netxen_pinit_from_rom(adapter, 0);
+ msleep(1);
+ netxen_load_firmware(adapter);
netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
}
@@ -782,19 +785,18 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
if (adapter->portnum == 0) {
if (init_firmware_done) {
- dma_watchdog_shutdown_request(adapter);
- msleep(100);
i = 100;
- while ((dma_watchdog_shutdown_poll_result(adapter) != 1) && i) {
- printk(KERN_INFO "dma_watchdog_shutdown_poll still in progress\n");
+ do {
+ if (dma_watchdog_shutdown_request(adapter) == 1)
+ break;
msleep(100);
- i--;
- }
+ if (dma_watchdog_shutdown_poll_result(adapter) == 1)
+ break;
+ } while (--i);
- if (i == 0) {
- printk(KERN_ERR "dma_watchdog_shutdown_request failed\n");
- return;
- }
+ if (i == 0)
+ printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
+ netdev->name);
/* clear the register for future unloads/loads */
writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc)));
@@ -803,11 +805,9 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
/* leave the hw in the same state as reboot */
writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
- if (netxen_pinit_from_rom(adapter, 0))
- return;
+ netxen_pinit_from_rom(adapter, 0);
msleep(1);
- if (netxen_load_firmware(adapter))
- return;
+ netxen_load_firmware(adapter);
netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
}
@@ -816,22 +816,21 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
printk(KERN_INFO "State: 0x%0x\n",
readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)));
- dma_watchdog_shutdown_request(adapter);
- msleep(100);
i = 100;
- while ((dma_watchdog_shutdown_poll_result(adapter) != 1) && i) {
- printk(KERN_INFO "dma_watchdog_shutdown_poll still in progress\n");
+ do {
+ if (dma_watchdog_shutdown_request(adapter) == 1)
+ break;
msleep(100);
- i--;
- }
+ if (dma_watchdog_shutdown_poll_result(adapter) == 1)
+ break;
+ } while (--i);
if (i) {
netxen_free_adapter_offload(adapter);
} else {
- printk(KERN_ERR "failed to dma shutdown\n");
- return;
+ printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
+ netdev->name);
}
-
}
iounmap(adapter->ahw.db_base);
@@ -895,8 +894,6 @@ static int netxen_nic_open(struct net_device *netdev)
/* Done here again so that even if phantom sw overwrote it,
* we set it */
- if (adapter->macaddr_set)
- adapter->macaddr_set(adapter, netdev->dev_addr);
if (adapter->init_port
&& adapter->init_port(adapter, adapter->portnum) != 0) {
del_timer_sync(&adapter->watchdog_timer);
@@ -904,6 +901,8 @@ static int netxen_nic_open(struct net_device *netdev)
netxen_nic_driver_name, adapter->portnum);
return -EIO;
}
+ if (adapter->macaddr_set)
+ adapter->macaddr_set(adapter, netdev->dev_addr);
netxen_nic_set_link_parameters(adapter);
@@ -930,6 +929,8 @@ static int netxen_nic_close(struct net_device *netdev)
netif_carrier_off(netdev);
netif_stop_queue(netdev);
+ netxen_nic_disable_int(adapter);
+
cmd_buff = adapter->cmd_buf_arr;
for (i = 0; i < adapter->max_tx_desc_count; i++) {
buffrag = cmd_buff->frag_array;
@@ -1226,15 +1227,12 @@ static void netxen_tx_timeout_task(struct work_struct *work)
{
struct netxen_adapter *adapter =
container_of(work, struct netxen_adapter, tx_timeout_task);
- unsigned long flags;
printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
netxen_nic_driver_name, adapter->netdev->name);
- spin_lock_irqsave(&adapter->lock, flags);
netxen_nic_close(adapter->netdev);
netxen_nic_open(adapter->netdev);
- spin_unlock_irqrestore(&adapter->lock, flags);
adapter->netdev->trans_start = jiffies;
netif_wake_queue(adapter->netdev);
}
@@ -1243,28 +1241,12 @@ static int
netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev)
{
u32 ret = 0;
- u32 our_int = 0;
DPRINTK(INFO, "Entered handle ISR\n");
adapter->stats.ints++;
- if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
- our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
- /* not our interrupt */
- if ((our_int & (0x80 << adapter->portnum)) == 0)
- return ret;
- }
-
netxen_nic_disable_int(adapter);
- if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
- /* claim interrupt */
- if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
- writel(our_int & ~((u32)(0x80 << adapter->portnum)),
- NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
- }
- }
-
if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) {
if (netif_rx_schedule_prep(netdev)) {
/*
@@ -1298,6 +1280,7 @@ irqreturn_t netxen_intr(int irq, void *data)
{
struct netxen_adapter *adapter;
struct net_device *netdev;
+ u32 our_int = 0;
if (unlikely(!irq)) {
return IRQ_NONE; /* Not our interrupt */
@@ -1305,7 +1288,22 @@ irqreturn_t netxen_intr(int irq, void *data)
adapter = (struct netxen_adapter *)data;
netdev = adapter->netdev;
- /* process our status queue (for all 4 ports) */
+
+ if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+ our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
+ /* not our interrupt */
+ if ((our_int & (0x80 << adapter->portnum)) == 0)
+ return IRQ_NONE;
+ }
+
+ if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
+ /* claim interrupt */
+ if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+ writel(our_int & ~((u32)(0x80 << adapter->portnum)),
+ NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
+ }
+ }
+
if (netif_running(netdev))
netxen_handle_int(adapter, netdev);
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 73da611fd536..997c2d0c83bb 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -996,7 +996,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *) dev_id;
mace_private *lp = netdev_priv(dev);
- kio_addr_t ioaddr = dev->base_addr;
+ kio_addr_t ioaddr;
int status;
int IntrCnt = MACE_MAX_IR_ITERATIONS;
@@ -1006,6 +1006,8 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
return IRQ_NONE;
}
+ ioaddr = dev->base_addr;
+
if (lp->tx_irq_disabled) {
printk(
(lp->tx_irq_disabled?
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 7912dbd14251..af6728cb49c3 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -1368,6 +1368,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
kio_addr_t ioaddr = dev->base_addr;
u_short num_pages;
short time_out, ir;
+ unsigned long flags;
netif_stop_queue(dev);
@@ -1395,6 +1396,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* A packet is now waiting. */
smc->packets_waiting++;
+ spin_lock_irqsave(&smc->lock, flags);
SMC_SELECT_BANK(2); /* Paranoia, we should always be in window 2 */
/* need MC_RESET to keep the memory consistent. errata? */
@@ -1411,6 +1413,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Acknowledge the interrupt, send the packet. */
outw((ir&0xff00) | IM_ALLOC_INT, ioaddr + INTERRUPT);
smc_hardware_send_packet(dev); /* Send the packet now.. */
+ spin_unlock_irqrestore(&smc->lock, flags);
return 0;
}
}
@@ -1418,6 +1421,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Otherwise defer until the Tx-space-allocated interrupt. */
DEBUG(2, "%s: memory allocation deferred.\n", dev->name);
outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT);
+ spin_unlock_irqrestore(&smc->lock, flags);
return 0;
}
@@ -1523,6 +1527,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
irq, ioaddr);
+ spin_lock(&smc->lock);
smc->watchdog = 0;
saved_bank = inw(ioaddr + BANK_SELECT);
if ((saved_bank & 0xff00) != 0x3300) {
@@ -1620,6 +1625,7 @@ irq_done:
readb(smc->base+MEGAHERTZ_ISR);
}
#endif
+ spin_unlock(&smc->lock);
return IRQ_RETVAL(handled);
}
@@ -1902,6 +1908,9 @@ static void media_check(u_long arg)
kio_addr_t ioaddr = dev->base_addr;
u_short i, media, saved_bank;
u_short link;
+ unsigned long flags;
+
+ spin_lock_irqsave(&smc->lock, flags);
saved_bank = inw(ioaddr + BANK_SELECT);
@@ -1934,6 +1943,7 @@ static void media_check(u_long arg)
smc->media.expires = jiffies + HZ/100;
add_timer(&smc->media);
SMC_SELECT_BANK(saved_bank);
+ spin_unlock_irqrestore(&smc->lock, flags);
return;
}
@@ -2007,6 +2017,7 @@ reschedule:
smc->media.expires = jiffies + HZ;
add_timer(&smc->media);
SMC_SELECT_BANK(saved_bank);
+ spin_unlock_irqrestore(&smc->lock, flags);
}
static int smc_link_ok(struct net_device *dev)
@@ -2094,14 +2105,14 @@ static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
u16 saved_bank = inw(ioaddr + BANK_SELECT);
int ret;
- SMC_SELECT_BANK(3);
spin_lock_irq(&smc->lock);
+ SMC_SELECT_BANK(3);
if (smc->cfg & CFG_MII_SELECT)
ret = mii_ethtool_gset(&smc->mii_if, ecmd);
else
ret = smc_netdev_get_ecmd(dev, ecmd);
- spin_unlock_irq(&smc->lock);
SMC_SELECT_BANK(saved_bank);
+ spin_unlock_irq(&smc->lock);
return ret;
}
@@ -2112,14 +2123,14 @@ static int smc_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
u16 saved_bank = inw(ioaddr + BANK_SELECT);
int ret;
- SMC_SELECT_BANK(3);
spin_lock_irq(&smc->lock);
+ SMC_SELECT_BANK(3);
if (smc->cfg & CFG_MII_SELECT)
ret = mii_ethtool_sset(&smc->mii_if, ecmd);
else
ret = smc_netdev_set_ecmd(dev, ecmd);
- spin_unlock_irq(&smc->lock);
SMC_SELECT_BANK(saved_bank);
+ spin_unlock_irq(&smc->lock);
return ret;
}
@@ -2130,11 +2141,11 @@ static u32 smc_get_link(struct net_device *dev)
u16 saved_bank = inw(ioaddr + BANK_SELECT);
u32 ret;
- SMC_SELECT_BANK(3);
spin_lock_irq(&smc->lock);
+ SMC_SELECT_BANK(3);
ret = smc_link_ok(dev);
- spin_unlock_irq(&smc->lock);
SMC_SELECT_BANK(saved_bank);
+ spin_unlock_irq(&smc->lock);
return ret;
}
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 465485a3fbc6..e6a67531de99 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -1515,7 +1515,6 @@ static const struct ethtool_ops pcnet32_ethtool_ops = {
.phys_id = pcnet32_phys_id,
.get_regs_len = pcnet32_get_regs_len,
.get_regs = pcnet32_get_regs,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
/* only probes for non-PCI devices, the rest are handled by
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index 6a5385647911..8874497b6bbf 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -109,7 +109,7 @@ static int vsc824x_config_intr(struct phy_device *phydev)
*/
err = phy_read(phydev, MII_VSC8244_ISTAT);
- if (err)
+ if (err < 0)
return err;
err = phy_write(phydev, MII_VSC8244_IMASK, 0);
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 6f98834e6ace..68631a5721ac 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -108,19 +108,24 @@ static inline int cmp_addr(struct pppoe_addr *a, unsigned long sid, char *addr)
(memcmp(a->remote,addr,ETH_ALEN) == 0));
}
-static int hash_item(unsigned long sid, unsigned char *addr)
+#if 8%PPPOE_HASH_BITS
+#error 8 must be a multiple of PPPOE_HASH_BITS
+#endif
+
+static int hash_item(unsigned int sid, unsigned char *addr)
{
- char hash = 0;
- int i, j;
+ unsigned char hash = 0;
+ unsigned int i;
- for (i = 0; i < ETH_ALEN ; ++i) {
- for (j = 0; j < 8/PPPOE_HASH_BITS ; ++j) {
- hash ^= addr[i] >> ( j * PPPOE_HASH_BITS );
- }
+ for (i = 0 ; i < ETH_ALEN ; i++) {
+ hash ^= addr[i];
+ }
+ for (i = 0 ; i < sizeof(sid_t)*8 ; i += 8 ){
+ hash ^= sid>>i;
+ }
+ for (i = 8 ; (i>>=1) >= PPPOE_HASH_BITS ; ) {
+ hash ^= hash>>i;
}
-
- for (i = 0; i < (sizeof(unsigned long)*8) / PPPOE_HASH_BITS ; ++i)
- hash ^= sid >> (i*PPPOE_HASH_BITS);
return hash & ( PPPOE_HASH_SIZE - 1 );
}
@@ -664,8 +669,8 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
{
struct sock *sk = sock->sk;
struct pppox_sock *po = pppox_sk(sk);
- int val = 0;
- int err = 0;
+ int val;
+ int err;
switch (cmd) {
case PPPIOCGMRU:
@@ -754,8 +759,9 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
err = 0;
break;
- default:;
- };
+ default:
+ err = -ENOTTY;
+ }
return err;
}
@@ -773,6 +779,7 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock,
struct net_device *dev;
char *start;
+ lock_sock(sk);
if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) {
error = -ENOTCONN;
goto end;
@@ -783,8 +790,6 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock,
hdr.code = 0;
hdr.sid = po->num;
- lock_sock(sk);
-
dev = po->pppoe_dev;
error = -EMSGSIZE;
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index f87176055d0e..266e8b38fe10 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -2054,7 +2054,7 @@ end:
*/
static int pppol2tp_tunnel_getsockopt(struct sock *sk,
struct pppol2tp_tunnel *tunnel,
- int optname, int __user *val)
+ int optname, int *val)
{
int err = 0;
@@ -2077,7 +2077,7 @@ static int pppol2tp_tunnel_getsockopt(struct sock *sk,
*/
static int pppol2tp_session_getsockopt(struct sock *sk,
struct pppol2tp_session *session,
- int optname, int __user *val)
+ int optname, int *val)
{
int err = 0;
diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c
index f3e47d0c2b3c..25c52b55c38f 100644
--- a/drivers/net/pppox.c
+++ b/drivers/net/pppox.c
@@ -73,7 +73,7 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct sock *sk = sock->sk;
struct pppox_sock *po = pppox_sk(sk);
- int rc = 0;
+ int rc;
lock_sock(sk);
@@ -94,12 +94,9 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
break;
}
default:
- if (pppox_protos[sk->sk_protocol]->ioctl)
- rc = pppox_protos[sk->sk_protocol]->ioctl(sock, cmd,
- arg);
-
- break;
- };
+ rc = pppox_protos[sk->sk_protocol]->ioctl ?
+ pppox_protos[sk->sk_protocol]->ioctl(sock, cmd, arg) : -ENOTTY;
+ }
release_sock(sk);
return rc;
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 08d25066f051..13d1c0a2a25f 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -290,7 +290,8 @@ static void gelic_net_release_rx_chain(struct gelic_net_card *card)
descr->buf_addr = 0;
dev_kfree_skb_any(descr->skb);
descr->skb = NULL;
- descr->dmac_cmd_status = GELIC_NET_DESCR_NOT_IN_USE;
+ gelic_net_set_descr_status(descr,
+ GELIC_NET_DESCR_NOT_IN_USE);
}
descr = descr->next;
} while (descr != card->rx_chain.head);
@@ -374,7 +375,7 @@ static void gelic_net_release_tx_descr(struct gelic_net_card *card,
descr->skb = NULL;
/* set descr status */
- descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE;
+ gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
}
/**
@@ -403,26 +404,29 @@ static void gelic_net_release_tx_chain(struct gelic_net_card *card, int stop)
"%s: forcing end of tx descriptor " \
"with status %x\n",
__func__, status);
- card->netdev_stats.tx_dropped++;
+ card->netdev->stats.tx_dropped++;
break;
case GELIC_NET_DESCR_COMPLETE:
- card->netdev_stats.tx_packets++;
- card->netdev_stats.tx_bytes +=
- tx_chain->tail->skb->len;
+ if (tx_chain->tail->skb) {
+ card->netdev->stats.tx_packets++;
+ card->netdev->stats.tx_bytes +=
+ tx_chain->tail->skb->len;
+ }
break;
case GELIC_NET_DESCR_CARDOWNED:
/* pending tx request */
default:
/* any other value (== GELIC_NET_DESCR_NOT_IN_USE) */
- goto out;
+ if (!stop)
+ goto out;
}
gelic_net_release_tx_descr(card, tx_chain->tail);
- release = 1;
+ release ++;
}
out:
- if (!stop && release)
+ if (!stop && (2 < release))
netif_wake_queue(card->netdev);
}
@@ -659,19 +663,21 @@ static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
{
dma_addr_t buf[2];
unsigned int vlan_len;
+ struct gelic_net_descr *sec_descr = descr->next;
if (skb->len < GELIC_NET_VLAN_POS)
return -EINVAL;
- memcpy(&descr->vlan, skb->data, GELIC_NET_VLAN_POS);
+ vlan_len = GELIC_NET_VLAN_POS;
+ memcpy(&descr->vlan, skb->data, vlan_len);
if (card->vlan_index != -1) {
+ /* internal vlan tag used */
descr->vlan.h_vlan_proto = htons(ETH_P_8021Q); /* vlan 0x8100*/
descr->vlan.h_vlan_TCI = htons(card->vlan_id[card->vlan_index]);
- vlan_len = GELIC_NET_VLAN_POS + VLAN_HLEN; /* VLAN_HLEN=4 */
- } else
- vlan_len = GELIC_NET_VLAN_POS; /* no vlan tag */
+ vlan_len += VLAN_HLEN; /* added for above two lines */
+ }
- /* first descr */
+ /* map data area */
buf[0] = dma_map_single(ctodev(card), &descr->vlan,
vlan_len, DMA_TO_DEVICE);
@@ -682,20 +688,6 @@ static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
return -ENOMEM;
}
- descr->buf_addr = buf[0];
- descr->buf_size = vlan_len;
- descr->skb = skb; /* not used */
- descr->data_status = 0;
- gelic_net_set_txdescr_cmdstat(descr, skb, 1); /* not the frame end */
-
- /* second descr */
- card->tx_chain.head = card->tx_chain.head->next;
- descr->next_descr_addr = descr->next->bus_addr;
- descr = descr->next;
- if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE)
- /* XXX will be removed */
- dev_err(ctodev(card), "descr is not free!\n");
-
buf[1] = dma_map_single(ctodev(card), skb->data + GELIC_NET_VLAN_POS,
skb->len - GELIC_NET_VLAN_POS,
DMA_TO_DEVICE);
@@ -710,13 +702,24 @@ static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
return -ENOMEM;
}
- descr->buf_addr = buf[1];
- descr->buf_size = skb->len - GELIC_NET_VLAN_POS;
- descr->skb = skb;
+ /* first descr */
+ descr->buf_addr = buf[0];
+ descr->buf_size = vlan_len;
+ descr->skb = NULL; /* not used */
descr->data_status = 0;
- descr->next_descr_addr = 0; /* terminate hw descr */
- gelic_net_set_txdescr_cmdstat(descr, skb, 0);
+ descr->next_descr_addr = descr->next->bus_addr;
+ gelic_net_set_txdescr_cmdstat(descr, skb, 1); /* not the frame end */
+ /* second descr */
+ sec_descr->buf_addr = buf[1];
+ sec_descr->buf_size = skb->len - GELIC_NET_VLAN_POS;
+ sec_descr->skb = skb;
+ sec_descr->data_status = 0;
+ sec_descr->next_descr_addr = 0; /* terminate hw descr */
+ gelic_net_set_txdescr_cmdstat(sec_descr, skb, 0);
+
+ /* bump free descriptor pointer */
+ card->tx_chain.head = sec_descr->next;
return 0;
}
@@ -729,7 +732,7 @@ static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
static int gelic_net_kick_txdma(struct gelic_net_card *card,
struct gelic_net_descr *descr)
{
- int status = -ENXIO;
+ int status = 0;
int count = 10;
if (card->tx_dma_progress)
@@ -763,47 +766,62 @@ static int gelic_net_kick_txdma(struct gelic_net_card *card,
static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct gelic_net_card *card = netdev_priv(netdev);
- struct gelic_net_descr *descr = NULL;
+ struct gelic_net_descr *descr;
int result;
unsigned long flags;
spin_lock_irqsave(&card->tx_dma_lock, flags);
gelic_net_release_tx_chain(card, 0);
- if (!skb)
- goto kick;
+
descr = gelic_net_get_next_tx_descr(card);
if (!descr) {
+ /*
+ * no more descriptors free
+ */
netif_stop_queue(netdev);
spin_unlock_irqrestore(&card->tx_dma_lock, flags);
return NETDEV_TX_BUSY;
}
- result = gelic_net_prepare_tx_descr_v(card, descr, skb);
-
- if (result)
- goto error;
- card->tx_chain.head = card->tx_chain.head->next;
-
- if (descr->prev)
- descr->prev->next_descr_addr = descr->bus_addr;
-kick:
+ result = gelic_net_prepare_tx_descr_v(card, descr, skb);
+ if (result) {
+ /*
+ * DMA map failed. As chanses are that failure
+ * would continue, just release skb and return
+ */
+ card->netdev->stats.tx_dropped++;
+ dev_kfree_skb_any(skb);
+ spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+ return NETDEV_TX_OK;
+ }
+ /*
+ * link this prepared descriptor to previous one
+ * to achieve high performance
+ */
+ descr->prev->next_descr_addr = descr->bus_addr;
/*
* as hardware descriptor is modified in the above lines,
* ensure that the hardware sees it
*/
wmb();
- if (gelic_net_kick_txdma(card, card->tx_chain.tail))
- goto error;
+ if (gelic_net_kick_txdma(card, descr)) {
+ /*
+ * kick failed.
+ * release descriptors which were just prepared
+ */
+ card->netdev->stats.tx_dropped++;
+ gelic_net_release_tx_descr(card, descr);
+ gelic_net_release_tx_descr(card, descr->next);
+ card->tx_chain.tail = descr->next->next;
+ dev_info(ctodev(card), "%s: kick failure\n", __func__);
+ } else {
+ /* OK, DMA started/reserved */
+ netdev->trans_start = jiffies;
+ }
- netdev->trans_start = jiffies;
spin_unlock_irqrestore(&card->tx_dma_lock, flags);
return NETDEV_TX_OK;
-
-error:
- card->netdev_stats.tx_dropped++;
- spin_unlock_irqrestore(&card->tx_dma_lock, flags);
- return NETDEV_TX_LOCKED;
}
/**
@@ -854,8 +872,8 @@ static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
skb->ip_summed = CHECKSUM_NONE;
/* update netdevice statistics */
- card->netdev_stats.rx_packets++;
- card->netdev_stats.rx_bytes += skb->len;
+ card->netdev->stats.rx_packets++;
+ card->netdev->stats.rx_bytes += skb->len;
/* pass skb up to stack */
netif_receive_skb(skb);
@@ -895,38 +913,67 @@ static int gelic_net_decode_one_descr(struct gelic_net_card *card)
(status == GELIC_NET_DESCR_FORCE_END)) {
dev_info(ctodev(card), "dropping RX descriptor with state %x\n",
status);
- card->netdev_stats.rx_dropped++;
+ card->netdev->stats.rx_dropped++;
goto refill;
}
- if ((status != GELIC_NET_DESCR_COMPLETE) &&
- (status != GELIC_NET_DESCR_FRAME_END)) {
+ if (status == GELIC_NET_DESCR_BUFFER_FULL) {
+ /*
+ * Buffer full would occur if and only if
+ * the frame length was longer than the size of this
+ * descriptor's buffer. If the frame length was equal
+ * to or shorter than buffer'size, FRAME_END condition
+ * would occur.
+ * Anyway this frame was longer than the MTU,
+ * just drop it.
+ */
+ dev_info(ctodev(card), "overlength frame\n");
+ goto refill;
+ }
+ /*
+ * descriptoers any other than FRAME_END here should
+ * be treated as error.
+ */
+ if (status != GELIC_NET_DESCR_FRAME_END) {
dev_dbg(ctodev(card), "RX descriptor with state %x\n",
status);
goto refill;
}
/* ok, we've got a packet in descr */
- gelic_net_pass_skb_up(descr, card); /* 1: skb_up sccess */
-
+ gelic_net_pass_skb_up(descr, card);
refill:
- descr->next_descr_addr = 0; /* unlink the descr */
+ /*
+ * So that always DMAC can see the end
+ * of the descriptor chain to avoid
+ * from unwanted DMAC overrun.
+ */
+ descr->next_descr_addr = 0;
/* change the descriptor state: */
gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
- /* refill one desc
- * FIXME: this can fail, but for now, just leave this
- * descriptor without skb
+ /*
+ * this call can fail, but for now, just leave this
+ * decriptor without skb
*/
gelic_net_prepare_rx_descr(card, descr);
+
chain->head = descr;
chain->tail = descr->next;
+
+ /*
+ * Set this descriptor the end of the chain.
+ */
descr->prev->next_descr_addr = descr->bus_addr;
+ /*
+ * If dmac chain was met, DMAC stopped.
+ * thus re-enable it
+ */
if (dmac_chain_ended) {
- gelic_net_enable_rxdmac(card);
- dev_dbg(ctodev(card), "reenable rx dma\n");
+ card->rx_dma_restart_required = 1;
+ dev_dbg(ctodev(card), "reenable rx dma scheduled\n");
}
return 1;
@@ -968,20 +1015,6 @@ static int gelic_net_poll(struct net_device *netdev, int *budget)
} else
return 1;
}
-
-/**
- * gelic_net_get_stats - get interface statistics
- * @netdev: interface device structure
- *
- * returns the interface statistics residing in the gelic_net_card struct
- */
-static struct net_device_stats *gelic_net_get_stats(struct net_device *netdev)
-{
- struct gelic_net_card *card = netdev_priv(netdev);
-
- return &card->netdev_stats;
-}
-
/**
* gelic_net_change_mtu - changes the MTU of an interface
* @netdev: interface device structure
@@ -1016,6 +1049,11 @@ static irqreturn_t gelic_net_interrupt(int irq, void *ptr)
if (!status)
return IRQ_NONE;
+ if (card->rx_dma_restart_required) {
+ card->rx_dma_restart_required = 0;
+ gelic_net_enable_rxdmac(card);
+ }
+
if (status & GELIC_NET_RXINT) {
gelic_net_rx_irq_off(card);
netif_rx_schedule(netdev);
@@ -1024,9 +1062,10 @@ static irqreturn_t gelic_net_interrupt(int irq, void *ptr)
if (status & GELIC_NET_TXINT) {
spin_lock_irqsave(&card->tx_dma_lock, flags);
card->tx_dma_progress = 0;
+ gelic_net_release_tx_chain(card, 0);
+ /* kick outstanding tx descriptor if any */
+ gelic_net_kick_txdma(card, card->tx_chain.tail);
spin_unlock_irqrestore(&card->tx_dma_lock, flags);
- /* start pending DMA */
- gelic_net_xmit(NULL, netdev);
}
return IRQ_HANDLED;
}
@@ -1068,7 +1107,7 @@ static int gelic_net_open_device(struct gelic_net_card *card)
}
result = request_irq(card->netdev->irq, gelic_net_interrupt,
- IRQF_DISABLED, "gelic network", card->netdev);
+ IRQF_DISABLED, card->netdev->name, card->netdev);
if (result) {
dev_info(ctodev(card), "%s:%d: request_irq failed (%d)\n",
@@ -1107,7 +1146,7 @@ static int gelic_net_open(struct net_device *netdev)
card->descr, GELIC_NET_TX_DESCRIPTORS))
goto alloc_tx_failed;
if (gelic_net_init_chain(card, &card->rx_chain,
- card->descr + GELIC_NET_RX_DESCRIPTORS,
+ card->descr + GELIC_NET_TX_DESCRIPTORS,
GELIC_NET_RX_DESCRIPTORS))
goto alloc_rx_failed;
@@ -1129,7 +1168,6 @@ static int gelic_net_open(struct net_device *netdev)
netif_start_queue(netdev);
netif_carrier_on(netdev);
- netif_poll_enable(netdev);
return 0;
@@ -1141,7 +1179,6 @@ alloc_tx_failed:
return -ENOMEM;
}
-#ifdef GELIC_NET_ETHTOOL
static void gelic_net_get_drvinfo (struct net_device *netdev,
struct ethtool_drvinfo *info)
{
@@ -1261,7 +1298,6 @@ static struct ethtool_ops gelic_net_ethtool_ops = {
.get_rx_csum = gelic_net_get_rx_csum,
.set_rx_csum = gelic_net_set_rx_csum,
};
-#endif
/**
* gelic_net_tx_timeout_task - task scheduled by the watchdog timeout
@@ -1320,7 +1356,6 @@ static void gelic_net_setup_netdev_ops(struct net_device *netdev)
netdev->open = &gelic_net_open;
netdev->stop = &gelic_net_stop;
netdev->hard_start_xmit = &gelic_net_xmit;
- netdev->get_stats = &gelic_net_get_stats;
netdev->set_multicast_list = &gelic_net_set_multi;
netdev->change_mtu = &gelic_net_change_mtu;
/* tx watchdog */
@@ -1329,9 +1364,7 @@ static void gelic_net_setup_netdev_ops(struct net_device *netdev)
/* NAPI */
netdev->poll = &gelic_net_poll;
netdev->weight = GELIC_NET_NAPI_WEIGHT;
-#ifdef GELIC_NET_ETHTOOL
netdev->ethtool_ops = &gelic_net_ethtool_ops;
-#endif
}
/**
diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h
index 5e1c28654e16..a9c4c4fc2547 100644
--- a/drivers/net/ps3_gelic_net.h
+++ b/drivers/net/ps3_gelic_net.h
@@ -28,21 +28,12 @@
#ifndef _GELIC_NET_H
#define _GELIC_NET_H
-#define GELIC_NET_DRV_NAME "Gelic Network Driver"
-#define GELIC_NET_DRV_VERSION "1.0"
-
-#define GELIC_NET_ETHTOOL /* use ethtool */
-
-/* ioctl */
-#define GELIC_NET_GET_MODE (SIOCDEVPRIVATE + 0)
-#define GELIC_NET_SET_MODE (SIOCDEVPRIVATE + 1)
-
/* descriptors */
#define GELIC_NET_RX_DESCRIPTORS 128 /* num of descriptors */
#define GELIC_NET_TX_DESCRIPTORS 128 /* num of descriptors */
-#define GELIC_NET_MAX_MTU 2308
-#define GELIC_NET_MIN_MTU 64
+#define GELIC_NET_MAX_MTU VLAN_ETH_FRAME_LEN
+#define GELIC_NET_MIN_MTU VLAN_ETH_ZLEN
#define GELIC_NET_RXBUF_ALIGN 128
#define GELIC_NET_RX_CSUM_DEFAULT 1 /* hw chksum */
#define GELIC_NET_WATCHDOG_TIMEOUT 5*HZ
@@ -90,7 +81,8 @@ enum gelic_net_int1_status {
*/
#define GELIC_NET_RXVLNPKT 0x00200000 /* VLAN packet */
/* bit 20..16 reserved */
-#define GELIC_NET_RXRECNUM 0x0000ff00 /* reception receipt number */
+#define GELIC_NET_RXRRECNUM 0x0000ff00 /* reception receipt number */
+#define GELIC_NET_RXRRECNUM_SHIFT 8
/* bit 7..0 reserved */
#define GELIC_NET_TXDESC_TAIL 0
@@ -133,19 +125,19 @@ enum gelic_net_int1_status {
* interrupt status */
#define GELIC_NET_DMAC_CMDSTAT_CHAIN_END 0x00000002 /* RXDCEIS:DMA stopped */
-#define GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE 0xb0000000
#define GELIC_NET_DESCR_IND_PROC_SHIFT 28
#define GELIC_NET_DESCR_IND_PROC_MASKO 0x0fffffff
enum gelic_net_descr_status {
- GELIC_NET_DESCR_COMPLETE = 0x00, /* used in rx and tx */
+ GELIC_NET_DESCR_COMPLETE = 0x00, /* used in tx */
+ GELIC_NET_DESCR_BUFFER_FULL = 0x00, /* used in rx */
GELIC_NET_DESCR_RESPONSE_ERROR = 0x01, /* used in rx and tx */
GELIC_NET_DESCR_PROTECTION_ERROR = 0x02, /* used in rx and tx */
GELIC_NET_DESCR_FRAME_END = 0x04, /* used in rx */
GELIC_NET_DESCR_FORCE_END = 0x05, /* used in rx and tx */
GELIC_NET_DESCR_CARDOWNED = 0x0a, /* used in rx and tx */
- GELIC_NET_DESCR_NOT_IN_USE /* any other value */
+ GELIC_NET_DESCR_NOT_IN_USE = 0x0b /* any other value */
};
/* for lv1_net_control */
#define GELIC_NET_GET_MAC_ADDRESS 0x0000000000000001
@@ -216,10 +208,10 @@ struct gelic_net_card {
struct gelic_net_descr_chain tx_chain;
struct gelic_net_descr_chain rx_chain;
+ int rx_dma_restart_required;
/* gurad dmac descriptor chain*/
spinlock_t chain_lock;
- struct net_device_stats netdev_stats;
int rx_csum;
/* guard tx_dma_progress */
spinlock_t tx_dma_lock;
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 8be8be451ada..69da95b5ad0c 100755
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -1904,7 +1904,6 @@ static void ql_get_pauseparam(struct net_device *ndev,
static const struct ethtool_ops ql3xxx_ethtool_ops = {
.get_settings = ql_get_settings,
.get_drvinfo = ql_get_drvinfo,
- .get_perm_addr = ethtool_op_get_perm_addr,
.get_link = ethtool_op_get_link,
.get_msglevel = ql_get_msglevel,
.set_msglevel = ql_set_msglevel,
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index bb6896ae3151..c9333b9dd51a 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1066,7 +1066,6 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
.get_strings = rtl8169_get_strings,
.get_stats_count = rtl8169_get_stats_count,
.get_ethtool_stats = rtl8169_get_ethtool_stats,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg,
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h
index 4cb710bbe729..cfa267914476 100644
--- a/drivers/net/s2io-regs.h
+++ b/drivers/net/s2io-regs.h
@@ -747,10 +747,9 @@ struct XENA_dev_config {
#define MC_ERR_REG_MIRI_CRI_ERR_1 BIT(23)
#define MC_ERR_REG_SM_ERR BIT(31)
#define MC_ERR_REG_ECC_ALL_SNG (BIT(2) | BIT(3) | BIT(4) | BIT(5) |\
- BIT(6) | BIT(7) | BIT(17) | BIT(19))
+ BIT(17) | BIT(19))
#define MC_ERR_REG_ECC_ALL_DBL (BIT(10) | BIT(11) | BIT(12) |\
- BIT(13) | BIT(14) | BIT(15) |\
- BIT(18) | BIT(20))
+ BIT(13) | BIT(18) | BIT(20))
u64 mc_err_mask;
u64 mc_err_alarm;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index afef6c0c59fe..2be0a0f1b48f 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -32,12 +32,12 @@
* rx_ring_sz: This defines the number of receive blocks each ring can have.
* This is also an array of size 8.
* rx_ring_mode: This defines the operation mode of all 8 rings. The valid
- * values are 1, 2 and 3.
+ * values are 1, 2.
* tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver.
* tx_fifo_len: This too is an array of 8. Each element defines the number of
* Tx descriptors that can be associated with each corresponding FIFO.
* intr_type: This defines the type of interrupt. The values can be 0(INTA),
- * 1(MSI), 2(MSI_X). Default value is '0(INTA)'
+ * 2(MSI_X). Default value is '0(INTA)'
* lro: Specifies whether to enable Large Receive Offload (LRO) or not.
* Possible values '1' for enable '0' for disable. Default is '0'
* lro_max_pkts: This parameter defines maximum number of packets can be
@@ -84,14 +84,14 @@
#include "s2io.h"
#include "s2io-regs.h"
-#define DRV_VERSION "2.0.23.1"
+#define DRV_VERSION "2.0.25.1"
/* S2io Driver name & version. */
static char s2io_driver_name[] = "Neterion";
static char s2io_driver_version[] = DRV_VERSION;
-static int rxd_size[4] = {32,48,48,64};
-static int rxd_count[4] = {127,85,85,63};
+static int rxd_size[2] = {32,48};
+static int rxd_count[2] = {127,85};
static inline int RXD_IS_UP2DT(struct RxD_t *rxdp)
{
@@ -282,6 +282,7 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
("lro_flush_due_to_max_pkts"),
("lro_avg_aggr_pkts"),
("mem_alloc_fail_cnt"),
+ ("pci_map_fail_cnt"),
("watchdog_timer_cnt"),
("mem_allocated"),
("mem_freed"),
@@ -426,7 +427,7 @@ S2IO_PARM_INT(bimodal, 0);
S2IO_PARM_INT(l3l4hdr_size, 128);
/* Frequency of Rx desc syncs expressed as power of 2 */
S2IO_PARM_INT(rxsync_frequency, 3);
-/* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */
+/* Interrupt type. Values can be 0(INTA), 2(MSI_X) */
S2IO_PARM_INT(intr_type, 0);
/* Large receive offload feature */
S2IO_PARM_INT(lro, 0);
@@ -701,7 +702,7 @@ static int init_shared_mem(struct s2io_nic *nic)
(u64) tmp_p_addr_next;
}
}
- if (nic->rxd_mode >= RXD_MODE_3A) {
+ if (nic->rxd_mode == RXD_MODE_3B) {
/*
* Allocation of Storages for buffer addresses in 2BUFF mode
* and the buffers as well.
@@ -870,7 +871,7 @@ static void free_shared_mem(struct s2io_nic *nic)
}
}
- if (nic->rxd_mode >= RXD_MODE_3A) {
+ if (nic->rxd_mode == RXD_MODE_3B) {
/* Freeing buffer storage addresses in 2BUFF mode. */
for (i = 0; i < config->rx_ring_num; i++) {
blk_cnt = config->rx_cfg[i].num_rxd /
@@ -2233,44 +2234,6 @@ static void stop_nic(struct s2io_nic *nic)
writeq(val64, &bar0->adapter_control);
}
-static int fill_rxd_3buf(struct s2io_nic *nic, struct RxD_t *rxdp, struct \
- sk_buff *skb)
-{
- struct net_device *dev = nic->dev;
- struct sk_buff *frag_list;
- void *tmp;
-
- /* Buffer-1 receives L3/L4 headers */
- ((struct RxD3*)rxdp)->Buffer1_ptr = pci_map_single
- (nic->pdev, skb->data, l3l4hdr_size + 4,
- PCI_DMA_FROMDEVICE);
-
- /* skb_shinfo(skb)->frag_list will have L4 data payload */
- skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE);
- if (skb_shinfo(skb)->frag_list == NULL) {
- nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
- DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n ", dev->name);
- return -ENOMEM ;
- }
- frag_list = skb_shinfo(skb)->frag_list;
- skb->truesize += frag_list->truesize;
- nic->mac_control.stats_info->sw_stat.mem_allocated
- += frag_list->truesize;
- frag_list->next = NULL;
- tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1);
- frag_list->data = tmp;
- skb_reset_tail_pointer(frag_list);
-
- /* Buffer-2 receives L4 data payload */
- ((struct RxD3*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev,
- frag_list->data, dev->mtu,
- PCI_DMA_FROMDEVICE);
- rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4);
- rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu);
-
- return SUCCESS;
-}
-
/**
* fill_rx_buffers - Allocates the Rx side skbs
* @nic: device private variable
@@ -2307,6 +2270,9 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
unsigned long flags;
struct RxD_t *first_rxdp = NULL;
u64 Buffer0_ptr = 0, Buffer1_ptr = 0;
+ struct RxD1 *rxdp1;
+ struct RxD3 *rxdp3;
+ struct swStat *stats = &nic->mac_control.stats_info->sw_stat;
mac_control = &nic->mac_control;
config = &nic->config;
@@ -2359,7 +2325,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
(block_no * (rxd_count[nic->rxd_mode] + 1)) + off;
}
if ((rxdp->Control_1 & RXD_OWN_XENA) &&
- ((nic->rxd_mode >= RXD_MODE_3A) &&
+ ((nic->rxd_mode == RXD_MODE_3B) &&
(rxdp->Control_2 & BIT(0)))) {
mac_control->rings[ring_no].rx_curr_put_info.
offset = off;
@@ -2370,10 +2336,8 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
HEADER_802_2_SIZE + HEADER_SNAP_SIZE;
if (nic->rxd_mode == RXD_MODE_1)
size += NET_IP_ALIGN;
- else if (nic->rxd_mode == RXD_MODE_3B)
- size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4;
else
- size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4;
+ size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4;
/* allocate skb */
skb = dev_alloc_skb(size);
@@ -2392,33 +2356,35 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
+= skb->truesize;
if (nic->rxd_mode == RXD_MODE_1) {
/* 1 buffer mode - normal operation mode */
+ rxdp1 = (struct RxD1*)rxdp;
memset(rxdp, 0, sizeof(struct RxD1));
skb_reserve(skb, NET_IP_ALIGN);
- ((struct RxD1*)rxdp)->Buffer0_ptr = pci_map_single
+ rxdp1->Buffer0_ptr = pci_map_single
(nic->pdev, skb->data, size - NET_IP_ALIGN,
PCI_DMA_FROMDEVICE);
+ if( (rxdp1->Buffer0_ptr == 0) ||
+ (rxdp1->Buffer0_ptr ==
+ DMA_ERROR_CODE))
+ goto pci_map_failed;
+
rxdp->Control_2 =
SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN);
- } else if (nic->rxd_mode >= RXD_MODE_3A) {
+ } else if (nic->rxd_mode == RXD_MODE_3B) {
/*
- * 2 or 3 buffer mode -
- * Both 2 buffer mode and 3 buffer mode provides 128
+ * 2 buffer mode -
+ * 2 buffer mode provides 128
* byte aligned receive buffers.
- *
- * 3 buffer mode provides header separation where in
- * skb->data will have L3/L4 headers where as
- * skb_shinfo(skb)->frag_list will have the L4 data
- * payload
*/
+ rxdp3 = (struct RxD3*)rxdp;
/* save buffer pointers to avoid frequent dma mapping */
- Buffer0_ptr = ((struct RxD3*)rxdp)->Buffer0_ptr;
- Buffer1_ptr = ((struct RxD3*)rxdp)->Buffer1_ptr;
+ Buffer0_ptr = rxdp3->Buffer0_ptr;
+ Buffer1_ptr = rxdp3->Buffer1_ptr;
memset(rxdp, 0, sizeof(struct RxD3));
/* restore the buffer pointers for dma sync*/
- ((struct RxD3*)rxdp)->Buffer0_ptr = Buffer0_ptr;
- ((struct RxD3*)rxdp)->Buffer1_ptr = Buffer1_ptr;
+ rxdp3->Buffer0_ptr = Buffer0_ptr;
+ rxdp3->Buffer1_ptr = Buffer1_ptr;
ba = &mac_control->rings[ring_no].ba[block_no][off];
skb_reserve(skb, BUF0_LEN);
@@ -2428,14 +2394,18 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
skb->data = (void *) (unsigned long)tmp;
skb_reset_tail_pointer(skb);
- if (!(((struct RxD3*)rxdp)->Buffer0_ptr))
- ((struct RxD3*)rxdp)->Buffer0_ptr =
+ if (!(rxdp3->Buffer0_ptr))
+ rxdp3->Buffer0_ptr =
pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN,
PCI_DMA_FROMDEVICE);
else
pci_dma_sync_single_for_device(nic->pdev,
- (dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr,
+ (dma_addr_t) rxdp3->Buffer0_ptr,
BUF0_LEN, PCI_DMA_FROMDEVICE);
+ if( (rxdp3->Buffer0_ptr == 0) ||
+ (rxdp3->Buffer0_ptr == DMA_ERROR_CODE))
+ goto pci_map_failed;
+
rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
if (nic->rxd_mode == RXD_MODE_3B) {
/* Two buffer mode */
@@ -2444,33 +2414,30 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
* Buffer2 will have L3/L4 header plus
* L4 payload
*/
- ((struct RxD3*)rxdp)->Buffer2_ptr = pci_map_single
+ rxdp3->Buffer2_ptr = pci_map_single
(nic->pdev, skb->data, dev->mtu + 4,
PCI_DMA_FROMDEVICE);
- /* Buffer-1 will be dummy buffer. Not used */
- if (!(((struct RxD3*)rxdp)->Buffer1_ptr)) {
- ((struct RxD3*)rxdp)->Buffer1_ptr =
+ if( (rxdp3->Buffer2_ptr == 0) ||
+ (rxdp3->Buffer2_ptr == DMA_ERROR_CODE))
+ goto pci_map_failed;
+
+ rxdp3->Buffer1_ptr =
pci_map_single(nic->pdev,
ba->ba_1, BUF1_LEN,
PCI_DMA_FROMDEVICE);
+ if( (rxdp3->Buffer1_ptr == 0) ||
+ (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) {
+ pci_unmap_single
+ (nic->pdev,
+ (dma_addr_t)skb->data,
+ dev->mtu + 4,
+ PCI_DMA_FROMDEVICE);
+ goto pci_map_failed;
}
rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
rxdp->Control_2 |= SET_BUFFER2_SIZE_3
(dev->mtu + 4);
- } else {
- /* 3 buffer mode */
- if (fill_rxd_3buf(nic, rxdp, skb) == -ENOMEM) {
- nic->mac_control.stats_info->sw_stat.\
- mem_freed += skb->truesize;
- dev_kfree_skb_irq(skb);
- if (first_rxdp) {
- wmb();
- first_rxdp->Control_1 |=
- RXD_OWN_XENA;
- }
- return -ENOMEM ;
- }
}
rxdp->Control_2 |= BIT(0);
}
@@ -2505,6 +2472,11 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
}
return SUCCESS;
+pci_map_failed:
+ stats->pci_map_fail_cnt++;
+ stats->mem_freed += skb->truesize;
+ dev_kfree_skb_irq(skb);
+ return -ENOMEM;
}
static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
@@ -2515,6 +2487,8 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
struct RxD_t *rxdp;
struct mac_info *mac_control;
struct buffAdd *ba;
+ struct RxD1 *rxdp1;
+ struct RxD3 *rxdp3;
mac_control = &sp->mac_control;
for (j = 0 ; j < rxd_count[sp->rxd_mode]; j++) {
@@ -2526,40 +2500,30 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
continue;
}
if (sp->rxd_mode == RXD_MODE_1) {
+ rxdp1 = (struct RxD1*)rxdp;
pci_unmap_single(sp->pdev, (dma_addr_t)
- ((struct RxD1*)rxdp)->Buffer0_ptr,
- dev->mtu +
- HEADER_ETHERNET_II_802_3_SIZE
- + HEADER_802_2_SIZE +
- HEADER_SNAP_SIZE,
- PCI_DMA_FROMDEVICE);
+ rxdp1->Buffer0_ptr,
+ dev->mtu +
+ HEADER_ETHERNET_II_802_3_SIZE
+ + HEADER_802_2_SIZE +
+ HEADER_SNAP_SIZE,
+ PCI_DMA_FROMDEVICE);
memset(rxdp, 0, sizeof(struct RxD1));
} else if(sp->rxd_mode == RXD_MODE_3B) {
+ rxdp3 = (struct RxD3*)rxdp;
ba = &mac_control->rings[ring_no].
ba[blk][j];
pci_unmap_single(sp->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer0_ptr,
- BUF0_LEN,
- PCI_DMA_FROMDEVICE);
- pci_unmap_single(sp->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer1_ptr,
- BUF1_LEN,
- PCI_DMA_FROMDEVICE);
- pci_unmap_single(sp->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer2_ptr,
- dev->mtu + 4,
- PCI_DMA_FROMDEVICE);
- memset(rxdp, 0, sizeof(struct RxD3));
- } else {
- pci_unmap_single(sp->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN,
+ rxdp3->Buffer0_ptr,
+ BUF0_LEN,
PCI_DMA_FROMDEVICE);
pci_unmap_single(sp->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer1_ptr,
- l3l4hdr_size + 4,
+ rxdp3->Buffer1_ptr,
+ BUF1_LEN,
PCI_DMA_FROMDEVICE);
pci_unmap_single(sp->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer2_ptr, dev->mtu,
+ rxdp3->Buffer2_ptr,
+ dev->mtu + 4,
PCI_DMA_FROMDEVICE);
memset(rxdp, 0, sizeof(struct RxD3));
}
@@ -2756,6 +2720,8 @@ static void rx_intr_handler(struct ring_info *ring_data)
struct sk_buff *skb;
int pkt_cnt = 0;
int i;
+ struct RxD1* rxdp1;
+ struct RxD3* rxdp3;
spin_lock(&nic->rx_lock);
if (atomic_read(&nic->card_state) == CARD_DOWN) {
@@ -2796,32 +2762,23 @@ static void rx_intr_handler(struct ring_info *ring_data)
return;
}
if (nic->rxd_mode == RXD_MODE_1) {
+ rxdp1 = (struct RxD1*)rxdp;
pci_unmap_single(nic->pdev, (dma_addr_t)
- ((struct RxD1*)rxdp)->Buffer0_ptr,
- dev->mtu +
- HEADER_ETHERNET_II_802_3_SIZE +
- HEADER_802_2_SIZE +
- HEADER_SNAP_SIZE,
- PCI_DMA_FROMDEVICE);
+ rxdp1->Buffer0_ptr,
+ dev->mtu +
+ HEADER_ETHERNET_II_802_3_SIZE +
+ HEADER_802_2_SIZE +
+ HEADER_SNAP_SIZE,
+ PCI_DMA_FROMDEVICE);
} else if (nic->rxd_mode == RXD_MODE_3B) {
+ rxdp3 = (struct RxD3*)rxdp;
pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer0_ptr,
- BUF0_LEN, PCI_DMA_FROMDEVICE);
- pci_unmap_single(nic->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer2_ptr,
- dev->mtu + 4,
- PCI_DMA_FROMDEVICE);
- } else {
- pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer0_ptr, BUF0_LEN,
- PCI_DMA_FROMDEVICE);
- pci_unmap_single(nic->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer1_ptr,
- l3l4hdr_size + 4,
- PCI_DMA_FROMDEVICE);
+ rxdp3->Buffer0_ptr,
+ BUF0_LEN, PCI_DMA_FROMDEVICE);
pci_unmap_single(nic->pdev, (dma_addr_t)
- ((struct RxD3*)rxdp)->Buffer2_ptr,
- dev->mtu, PCI_DMA_FROMDEVICE);
+ rxdp3->Buffer2_ptr,
+ dev->mtu + 4,
+ PCI_DMA_FROMDEVICE);
}
prefetch(skb->data);
rx_osm_handler(ring_data, rxdp);
@@ -3425,23 +3382,8 @@ static void s2io_reset(struct s2io_nic * sp)
/* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */
pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd));
- if (sp->device_type == XFRAME_II_DEVICE) {
- int ret;
- ret = pci_set_power_state(sp->pdev, 3);
- if (!ret)
- ret = pci_set_power_state(sp->pdev, 0);
- else {
- DBG_PRINT(ERR_DBG,"%s PME based SW_Reset failed!\n",
- __FUNCTION__);
- goto old_way;
- }
- msleep(20);
- goto new_way;
- }
-old_way:
val64 = SW_RESET_ALL;
writeq(val64, &bar0->sw_reset);
-new_way:
if (strstr(sp->product_name, "CX4")) {
msleep(750);
}
@@ -3731,56 +3673,6 @@ static void store_xmsi_data(struct s2io_nic *nic)
}
}
-int s2io_enable_msi(struct s2io_nic *nic)
-{
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- u16 msi_ctrl, msg_val;
- struct config_param *config = &nic->config;
- struct net_device *dev = nic->dev;
- u64 val64, tx_mat, rx_mat;
- int i, err;
-
- val64 = readq(&bar0->pic_control);
- val64 &= ~BIT(1);
- writeq(val64, &bar0->pic_control);
-
- err = pci_enable_msi(nic->pdev);
- if (err) {
- DBG_PRINT(ERR_DBG, "%s: enabling MSI failed\n",
- nic->dev->name);
- return err;
- }
-
- /*
- * Enable MSI and use MSI-1 in stead of the standard MSI-0
- * for interrupt handling.
- */
- pci_read_config_word(nic->pdev, 0x4c, &msg_val);
- msg_val ^= 0x1;
- pci_write_config_word(nic->pdev, 0x4c, msg_val);
- pci_read_config_word(nic->pdev, 0x4c, &msg_val);
-
- pci_read_config_word(nic->pdev, 0x42, &msi_ctrl);
- msi_ctrl |= 0x10;
- pci_write_config_word(nic->pdev, 0x42, msi_ctrl);
-
- /* program MSI-1 into all usable Tx_Mat and Rx_Mat fields */
- tx_mat = readq(&bar0->tx_mat0_n[0]);
- for (i=0; i<config->tx_fifo_num; i++) {
- tx_mat |= TX_MAT_SET(i, 1);
- }
- writeq(tx_mat, &bar0->tx_mat0_n[0]);
-
- rx_mat = readq(&bar0->rx_mat);
- for (i=0; i<config->rx_ring_num; i++) {
- rx_mat |= RX_MAT_SET(i, 1);
- }
- writeq(rx_mat, &bar0->rx_mat);
-
- dev->irq = nic->pdev->irq;
- return 0;
-}
-
static int s2io_enable_msi_x(struct s2io_nic *nic)
{
struct XENA_dev_config __iomem *bar0 = nic->bar0;
@@ -4001,6 +3893,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
struct mac_info *mac_control;
struct config_param *config;
int offload_type;
+ struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
mac_control = &sp->mac_control;
config = &sp->config;
@@ -4085,11 +3978,18 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
txdp->Buffer_Pointer = pci_map_single(sp->pdev,
sp->ufo_in_band_v,
sizeof(u64), PCI_DMA_TODEVICE);
+ if((txdp->Buffer_Pointer == 0) ||
+ (txdp->Buffer_Pointer == DMA_ERROR_CODE))
+ goto pci_map_failed;
txdp++;
}
txdp->Buffer_Pointer = pci_map_single
(sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE);
+ if((txdp->Buffer_Pointer == 0) ||
+ (txdp->Buffer_Pointer == DMA_ERROR_CODE))
+ goto pci_map_failed;
+
txdp->Host_Control = (unsigned long) skb;
txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
if (offload_type == SKB_GSO_UDP)
@@ -4146,6 +4046,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&sp->tx_lock, flags);
return 0;
+pci_map_failed:
+ stats->pci_map_fail_cnt++;
+ netif_stop_queue(dev);
+ stats->mem_freed += skb->truesize;
+ dev_kfree_skb(skb);
+ spin_unlock_irqrestore(&sp->tx_lock, flags);
+ return 0;
}
static void
@@ -4186,39 +4093,6 @@ static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n)
return 0;
}
-static irqreturn_t s2io_msi_handle(int irq, void *dev_id)
-{
- struct net_device *dev = (struct net_device *) dev_id;
- struct s2io_nic *sp = dev->priv;
- int i;
- struct mac_info *mac_control;
- struct config_param *config;
-
- atomic_inc(&sp->isr_cnt);
- mac_control = &sp->mac_control;
- config = &sp->config;
- DBG_PRINT(INTR_DBG, "%s: MSI handler\n", __FUNCTION__);
-
- /* If Intr is because of Rx Traffic */
- for (i = 0; i < config->rx_ring_num; i++)
- rx_intr_handler(&mac_control->rings[i]);
-
- /* If Intr is because of Tx Traffic */
- for (i = 0; i < config->tx_fifo_num; i++)
- tx_intr_handler(&mac_control->fifos[i]);
-
- /*
- * If the Rx buffer count is below the panic threshold then
- * reallocate the buffers from the interrupt handler itself,
- * else schedule a tasklet to reallocate the buffers.
- */
- for (i = 0; i < config->rx_ring_num; i++)
- s2io_chk_rx_buffers(sp, i);
-
- atomic_dec(&sp->isr_cnt);
- return IRQ_HANDLED;
-}
-
static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id)
{
struct ring_info *ring = (struct ring_info *)dev_id;
@@ -4927,19 +4801,17 @@ static void s2io_ethtool_gringparam(struct net_device *dev,
ering->rx_max_pending = MAX_RX_DESC_1;
else if (sp->rxd_mode == RXD_MODE_3B)
ering->rx_max_pending = MAX_RX_DESC_2;
- else if (sp->rxd_mode == RXD_MODE_3A)
- ering->rx_max_pending = MAX_RX_DESC_3;
ering->tx_max_pending = MAX_TX_DESC;
- for (i = 0 ; i < sp->config.tx_fifo_num ; i++) {
+ for (i = 0 ; i < sp->config.tx_fifo_num ; i++)
tx_desc_count += sp->config.tx_cfg[i].fifo_len;
- }
+
DBG_PRINT(INFO_DBG,"\nmax txds : %d\n",sp->config.max_txds);
ering->tx_pending = tx_desc_count;
rx_desc_count = 0;
- for (i = 0 ; i < sp->config.rx_ring_num ; i++) {
+ for (i = 0 ; i < sp->config.rx_ring_num ; i++)
rx_desc_count += sp->config.rx_cfg[i].num_rxd;
- }
+
ering->rx_pending = rx_desc_count;
ering->rx_mini_max_pending = 0;
@@ -5923,6 +5795,7 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
else
tmp_stats[i++] = 0;
tmp_stats[i++] = stat_info->sw_stat.mem_alloc_fail_cnt;
+ tmp_stats[i++] = stat_info->sw_stat.pci_map_fail_cnt;
tmp_stats[i++] = stat_info->sw_stat.watchdog_timer_cnt;
tmp_stats[i++] = stat_info->sw_stat.mem_allocated;
tmp_stats[i++] = stat_info->sw_stat.mem_freed;
@@ -6266,9 +6139,10 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
u64 *temp2, int size)
{
struct net_device *dev = sp->dev;
- struct sk_buff *frag_list;
+ struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
if ((sp->rxd_mode == RXD_MODE_1) && (rxdp->Host_Control == 0)) {
+ struct RxD1 *rxdp1 = (struct RxD1 *)rxdp;
/* allocate skb */
if (*skb) {
DBG_PRINT(INFO_DBG, "SKB is not NULL\n");
@@ -6277,7 +6151,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
* using same mapped address for the Rxd
* buffer pointer
*/
- ((struct RxD1*)rxdp)->Buffer0_ptr = *temp0;
+ rxdp1->Buffer0_ptr = *temp0;
} else {
*skb = dev_alloc_skb(size);
if (!(*skb)) {
@@ -6294,18 +6168,23 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
* such it will be used for next rxd whose
* Host Control is NULL
*/
- ((struct RxD1*)rxdp)->Buffer0_ptr = *temp0 =
+ rxdp1->Buffer0_ptr = *temp0 =
pci_map_single( sp->pdev, (*skb)->data,
size - NET_IP_ALIGN,
PCI_DMA_FROMDEVICE);
+ if( (rxdp1->Buffer0_ptr == 0) ||
+ (rxdp1->Buffer0_ptr == DMA_ERROR_CODE)) {
+ goto memalloc_failed;
+ }
rxdp->Host_Control = (unsigned long) (*skb);
}
} else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) {
+ struct RxD3 *rxdp3 = (struct RxD3 *)rxdp;
/* Two buffer Mode */
if (*skb) {
- ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2;
- ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0;
- ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1;
+ rxdp3->Buffer2_ptr = *temp2;
+ rxdp3->Buffer0_ptr = *temp0;
+ rxdp3->Buffer1_ptr = *temp1;
} else {
*skb = dev_alloc_skb(size);
if (!(*skb)) {
@@ -6318,73 +6197,47 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
}
sp->mac_control.stats_info->sw_stat.mem_allocated
+= (*skb)->truesize;
- ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 =
+ rxdp3->Buffer2_ptr = *temp2 =
pci_map_single(sp->pdev, (*skb)->data,
dev->mtu + 4,
PCI_DMA_FROMDEVICE);
- ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 =
+ if( (rxdp3->Buffer2_ptr == 0) ||
+ (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) {
+ goto memalloc_failed;
+ }
+ rxdp3->Buffer0_ptr = *temp0 =
pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN,
PCI_DMA_FROMDEVICE);
+ if( (rxdp3->Buffer0_ptr == 0) ||
+ (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) {
+ pci_unmap_single (sp->pdev,
+ (dma_addr_t)(*skb)->data,
+ dev->mtu + 4, PCI_DMA_FROMDEVICE);
+ goto memalloc_failed;
+ }
rxdp->Host_Control = (unsigned long) (*skb);
/* Buffer-1 will be dummy buffer not used */
- ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1 =
+ rxdp3->Buffer1_ptr = *temp1 =
pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN,
- PCI_DMA_FROMDEVICE);
- }
- } else if ((rxdp->Host_Control == 0)) {
- /* Three buffer mode */
- if (*skb) {
- ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0;
- ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1;
- ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2;
- } else {
- *skb = dev_alloc_skb(size);
- if (!(*skb)) {
- DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
- DBG_PRINT(INFO_DBG, "memory to allocate ");
- DBG_PRINT(INFO_DBG, "3 buf mode SKBs\n");
- sp->mac_control.stats_info->sw_stat. \
- mem_alloc_fail_cnt++;
- return -ENOMEM;
- }
- sp->mac_control.stats_info->sw_stat.mem_allocated
- += (*skb)->truesize;
- ((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 =
- pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN,
- PCI_DMA_FROMDEVICE);
- /* Buffer-1 receives L3/L4 headers */
- ((struct RxD3*)rxdp)->Buffer1_ptr = *temp1 =
- pci_map_single( sp->pdev, (*skb)->data,
- l3l4hdr_size + 4,
PCI_DMA_FROMDEVICE);
- /*
- * skb_shinfo(skb)->frag_list will have L4
- * data payload
- */
- skb_shinfo(*skb)->frag_list = dev_alloc_skb(dev->mtu +
- ALIGN_SIZE);
- if (skb_shinfo(*skb)->frag_list == NULL) {
- DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb \
- failed\n ", dev->name);
- sp->mac_control.stats_info->sw_stat. \
- mem_alloc_fail_cnt++;
- return -ENOMEM ;
+ if( (rxdp3->Buffer1_ptr == 0) ||
+ (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) {
+ pci_unmap_single (sp->pdev,
+ (dma_addr_t)(*skb)->data,
+ dev->mtu + 4, PCI_DMA_FROMDEVICE);
+ goto memalloc_failed;
}
- frag_list = skb_shinfo(*skb)->frag_list;
- frag_list->next = NULL;
- sp->mac_control.stats_info->sw_stat.mem_allocated
- += frag_list->truesize;
- /*
- * Buffer-2 receives L4 data payload
- */
- ((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 =
- pci_map_single( sp->pdev, frag_list->data,
- dev->mtu, PCI_DMA_FROMDEVICE);
}
}
return 0;
+ memalloc_failed:
+ stats->pci_map_fail_cnt++;
+ stats->mem_freed += (*skb)->truesize;
+ dev_kfree_skb(*skb);
+ return -ENOMEM;
}
+
static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp,
int size)
{
@@ -6395,10 +6248,6 @@ static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp,
rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
rxdp->Control_2 |= SET_BUFFER2_SIZE_3( dev->mtu + 4);
- } else {
- rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
- rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4);
- rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu);
}
}
@@ -6420,8 +6269,6 @@ static int rxd_owner_bit_reset(struct s2io_nic *sp)
size += NET_IP_ALIGN;
else if (sp->rxd_mode == RXD_MODE_3B)
size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4;
- else
- size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4;
for (i = 0; i < config->rx_ring_num; i++) {
blk_cnt = config->rx_cfg[i].num_rxd /
@@ -6431,7 +6278,7 @@ static int rxd_owner_bit_reset(struct s2io_nic *sp)
for (k = 0; k < rxd_count[sp->rxd_mode]; k++) {
rxdp = mac_control->rings[i].
rx_blocks[j].rxds[k].virt_addr;
- if(sp->rxd_mode >= RXD_MODE_3A)
+ if(sp->rxd_mode == RXD_MODE_3B)
ba = &mac_control->rings[i].ba[j][k];
if (set_rxd_buffer_pointer(sp, rxdp, ba,
&skb,(u64 *)&temp0_64,
@@ -6458,9 +6305,7 @@ static int s2io_add_isr(struct s2io_nic * sp)
struct net_device *dev = sp->dev;
int err = 0;
- if (sp->intr_type == MSI)
- ret = s2io_enable_msi(sp);
- else if (sp->intr_type == MSI_X)
+ if (sp->intr_type == MSI_X)
ret = s2io_enable_msi_x(sp);
if (ret) {
DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name);
@@ -6471,16 +6316,6 @@ static int s2io_add_isr(struct s2io_nic * sp)
store_xmsi_data(sp);
/* After proper initialization of H/W, register ISR */
- if (sp->intr_type == MSI) {
- err = request_irq((int) sp->pdev->irq, s2io_msi_handle,
- IRQF_SHARED, sp->name, dev);
- if (err) {
- pci_disable_msi(sp->pdev);
- DBG_PRINT(ERR_DBG, "%s: MSI registration failed\n",
- dev->name);
- return -1;
- }
- }
if (sp->intr_type == MSI_X) {
int i, msix_tx_cnt=0,msix_rx_cnt=0;
@@ -6567,14 +6402,6 @@ static void s2io_rem_isr(struct s2io_nic * sp)
pci_disable_msix(sp->pdev);
} else {
free_irq(sp->pdev->irq, dev);
- if (sp->intr_type == MSI) {
- u16 val;
-
- pci_disable_msi(sp->pdev);
- pci_read_config_word(sp->pdev, 0x4c, &val);
- val ^= 0x1;
- pci_write_config_word(sp->pdev, 0x4c, val);
- }
}
/* Waiting till all Interrupt handlers are complete */
cnt = 0;
@@ -6907,6 +6734,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
}
/* Updating statistics */
+ sp->stats.rx_packets++;
rxdp->Host_Control = 0;
if (sp->rxd_mode == RXD_MODE_1) {
int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2);
@@ -6914,7 +6742,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
sp->stats.rx_bytes += len;
skb_put(skb, len);
- } else if (sp->rxd_mode >= RXD_MODE_3A) {
+ } else if (sp->rxd_mode == RXD_MODE_3B) {
int get_block = ring_data->rx_curr_get_info.block_index;
int get_off = ring_data->rx_curr_get_info.offset;
int buf0_len = RXD_GET_BUFFER0_SIZE_3(rxdp->Control_2);
@@ -6924,18 +6752,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
struct buffAdd *ba = &ring_data->ba[get_block][get_off];
sp->stats.rx_bytes += buf0_len + buf2_len;
memcpy(buff, ba->ba_0, buf0_len);
-
- if (sp->rxd_mode == RXD_MODE_3A) {
- int buf1_len = RXD_GET_BUFFER1_SIZE_3(rxdp->Control_2);
-
- skb_put(skb, buf1_len);
- skb->len += buf2_len;
- skb->data_len += buf2_len;
- skb_put(skb_shinfo(skb)->frag_list, buf2_len);
- sp->stats.rx_bytes += buf1_len;
-
- } else
- skb_put(skb, buf2_len);
+ skb_put(skb, buf2_len);
}
if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && ((!sp->lro) ||
@@ -7131,7 +6948,7 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type)
*dev_intr_type = INTA;
}
#else
- if (*dev_intr_type > MSI_X) {
+ if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) {
DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. "
"Defaulting to INTA\n");
*dev_intr_type = INTA;
@@ -7145,10 +6962,10 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type)
*dev_intr_type = INTA;
}
- if (rx_ring_mode > 3) {
+ if ((rx_ring_mode != 1) && (rx_ring_mode != 2)) {
DBG_PRINT(ERR_DBG, "s2io: Requested ring mode not supported\n");
- DBG_PRINT(ERR_DBG, "s2io: Defaulting to 3-buffer mode\n");
- rx_ring_mode = 3;
+ DBG_PRINT(ERR_DBG, "s2io: Defaulting to 1-buffer mode\n");
+ rx_ring_mode = 1;
}
return SUCCESS;
}
@@ -7240,28 +7057,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
pci_disable_device(pdev);
return -ENOMEM;
}
- if (dev_intr_type != MSI_X) {
- if (pci_request_regions(pdev, s2io_driver_name)) {
- DBG_PRINT(ERR_DBG, "Request Regions failed\n");
- pci_disable_device(pdev);
- return -ENODEV;
- }
- }
- else {
- if (!(request_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0), s2io_driver_name))) {
- DBG_PRINT(ERR_DBG, "bar0 Request Regions failed\n");
- pci_disable_device(pdev);
- return -ENODEV;
- }
- if (!(request_mem_region(pci_resource_start(pdev, 2),
- pci_resource_len(pdev, 2), s2io_driver_name))) {
- DBG_PRINT(ERR_DBG, "bar1 Request Regions failed\n");
- release_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- pci_disable_device(pdev);
- return -ENODEV;
- }
+ if ((ret = pci_request_regions(pdev, s2io_driver_name))) {
+ DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __FUNCTION__, ret);
+ pci_disable_device(pdev);
+ return -ENODEV;
}
dev = alloc_etherdev(sizeof(struct s2io_nic));
@@ -7288,8 +7087,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
sp->rxd_mode = RXD_MODE_1;
if (rx_ring_mode == 2)
sp->rxd_mode = RXD_MODE_3B;
- if (rx_ring_mode == 3)
- sp->rxd_mode = RXD_MODE_3A;
sp->intr_type = dev_intr_type;
@@ -7565,10 +7362,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
DBG_PRINT(ERR_DBG, "%s: 2-Buffer receive mode enabled\n",
dev->name);
break;
- case RXD_MODE_3A:
- DBG_PRINT(ERR_DBG, "%s: 3-Buffer receive mode enabled\n",
- dev->name);
- break;
}
if (napi)
@@ -7577,9 +7370,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
case INTA:
DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name);
break;
- case MSI:
- DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI\n", dev->name);
- break;
case MSI_X:
DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name);
break;
@@ -7619,14 +7409,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
mem_alloc_failed:
free_shared_mem(sp);
pci_disable_device(pdev);
- if (dev_intr_type != MSI_X)
- pci_release_regions(pdev);
- else {
- release_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- release_mem_region(pci_resource_start(pdev, 2),
- pci_resource_len(pdev, 2));
- }
+ pci_release_regions(pdev);
pci_set_drvdata(pdev, NULL);
free_netdev(dev);
@@ -7661,14 +7444,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev)
free_shared_mem(sp);
iounmap(sp->bar0);
iounmap(sp->bar1);
- if (sp->intr_type != MSI_X)
- pci_release_regions(pdev);
- else {
- release_mem_region(pci_resource_start(pdev, 0),
- pci_resource_len(pdev, 0));
- release_mem_region(pci_resource_start(pdev, 2),
- pci_resource_len(pdev, 2));
- }
+ pci_release_regions(pdev);
pci_set_drvdata(pdev, NULL);
free_netdev(dev);
pci_disable_device(pdev);
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 3887fe63a908..92983ee7df8c 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -74,6 +74,10 @@ static int debug_level = ERR_DBG;
/* DEBUG message print. */
#define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args)
+#ifndef DMA_ERROR_CODE
+#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
+#endif
+
/* Protocol assist features of the NIC */
#define L3_CKSUM_OK 0xFFFF
#define L4_CKSUM_OK 0xFFFF
@@ -97,6 +101,7 @@ struct swStat {
unsigned long long num_aggregations;
/* Other statistics */
unsigned long long mem_alloc_fail_cnt;
+ unsigned long long pci_map_fail_cnt;
unsigned long long watchdog_timer_cnt;
unsigned long long mem_allocated;
unsigned long long mem_freed;
@@ -575,8 +580,7 @@ struct RxD_block {
#define SIZE_OF_BLOCK 4096
#define RXD_MODE_1 0 /* One Buffer mode */
-#define RXD_MODE_3A 1 /* Three Buffer mode */
-#define RXD_MODE_3B 2 /* Two Buffer mode */
+#define RXD_MODE_3B 1 /* Two Buffer mode */
/* Structure to hold virtual addresses of Buf0 and Buf1 in
* 2buf mode. */
@@ -876,7 +880,6 @@ struct s2io_nic {
u16 lro_max_aggr_per_sess;
#define INTA 0
-#define MSI 1
#define MSI_X 2
u8 intr_type;
@@ -1020,8 +1023,6 @@ static int s2io_poll(struct net_device *dev, int *budget);
static void s2io_init_pci(struct s2io_nic * sp);
static int s2io_set_mac_addr(struct net_device *dev, u8 * addr);
static void s2io_alarm_handle(unsigned long data);
-static int s2io_enable_msi(struct s2io_nic *nic);
-static irqreturn_t s2io_msi_handle(int irq, void *dev_id);
static irqreturn_t
s2io_msix_ring_handle(int irq, void *dev_id);
static irqreturn_t
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index 5b7284c955dc..872cb1cc9c41 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -1402,7 +1402,6 @@ static struct ethtool_ops sc92031_ethtool_ops = {
.get_strings = sc92031_ethtool_get_strings,
.get_stats_count = sc92031_ethtool_get_stats_count,
.get_ethtool_stats = sc92031_ethtool_get_ethtool_stats,
- .get_perm_addr = ethtool_op_get_perm_addr,
.get_ufo = ethtool_op_get_ufo,
};
diff --git a/drivers/net/skfp/pmf.c b/drivers/net/skfp/pmf.c
index efc639c013fd..ea85de918233 100644
--- a/drivers/net/skfp/pmf.c
+++ b/drivers/net/skfp/pmf.c
@@ -575,7 +575,7 @@ void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para,
int sp_len ;
/*
- * skip if errror
+ * skip if error
*/
if (pcon->pc_err)
return ;
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 776692946562..e3d8520209b8 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -821,7 +821,6 @@ static const struct ethtool_ops skge_ethtool_ops = {
.phys_id = skge_phys_id,
.get_stats_count = skge_get_stats_count,
.get_ethtool_stats = skge_get_ethtool_stats,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
/*
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 13f08a390e1f..e7a2eadcc3b0 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -3548,7 +3548,6 @@ static const struct ethtool_ops sky2_ethtool_ops = {
.phys_id = sky2_phys_id,
.get_stats_count = sky2_get_stats_count,
.get_ethtool_stats = sky2_get_ethtool_stats,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
#ifdef CONFIG_SKY2_DEBUG
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index af0c9831074c..a8f2af8f778a 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -1586,7 +1586,6 @@ static const struct ethtool_ops ethtool_ops = {
.get_link = get_link,
.get_msglevel = get_msglevel,
.set_msglevel = set_msglevel,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 053b7cb0d944..68e4f660367d 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -99,8 +99,7 @@ static char lancestr[] = "LANCE";
#include <asm/byteorder.h> /* Used by the checksum routines */
#include <asm/idprom.h>
#include <asm/sbus.h>
-#include <asm/openprom.h>
-#include <asm/oplib.h>
+#include <asm/prom.h>
#include <asm/auxio.h> /* For tpe-link-test? setting */
#include <asm/irq.h>
@@ -1326,6 +1325,7 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
struct sbus_dev *lebuffer)
{
static unsigned version_printed;
+ struct device_node *dp = sdev->ofdev.node;
struct net_device *dev;
struct lance_private *lp;
int i;
@@ -1389,54 +1389,46 @@ static int __devinit sparc_lance_probe_one(struct sbus_dev *sdev,
lp->rx = lance_rx_dvma;
lp->tx = lance_tx_dvma;
}
- lp->busmaster_regval = prom_getintdefault(sdev->prom_node,
- "busmaster-regval",
- (LE_C3_BSWP | LE_C3_ACON |
- LE_C3_BCON));
+ lp->busmaster_regval = of_getintprop_default(dp, "busmaster-regval",
+ (LE_C3_BSWP |
+ LE_C3_ACON |
+ LE_C3_BCON));
lp->name = lancestr;
lp->ledma = ledma;
lp->burst_sizes = 0;
if (lp->ledma) {
- char prop[6];
+ struct device_node *ledma_dp = ledma->sdev->ofdev.node;
+ const char *prop;
unsigned int sbmask;
u32 csr;
/* Find burst-size property for ledma */
- lp->burst_sizes = prom_getintdefault(ledma->sdev->prom_node,
- "burst-sizes", 0);
+ lp->burst_sizes = of_getintprop_default(ledma_dp,
+ "burst-sizes", 0);
/* ledma may be capable of fast bursts, but sbus may not. */
- sbmask = prom_getintdefault(ledma->sdev->bus->prom_node,
- "burst-sizes", DMA_BURSTBITS);
+ sbmask = of_getintprop_default(ledma_dp, "burst-sizes",
+ DMA_BURSTBITS);
lp->burst_sizes &= sbmask;
/* Get the cable-selection property */
- memset(prop, 0, sizeof(prop));
- prom_getstring(ledma->sdev->prom_node, "cable-selection",
- prop, sizeof(prop));
- if (prop[0] == 0) {
- int topnd, nd;
+ prop = of_get_property(ledma_dp, "cable-selection", NULL);
+ if (!prop || prop[0] == '\0') {
+ struct device_node *nd;
- printk(KERN_INFO "SunLance: using auto-carrier-detection.\n");
+ printk(KERN_INFO "SunLance: using "
+ "auto-carrier-detection.\n");
- /* Is this found at /options .attributes in all
- * Prom versions? XXX
- */
- topnd = prom_getchild(prom_root_node);
-
- nd = prom_searchsiblings(topnd, "options");
+ nd = of_find_node_by_path("/options");
if (!nd)
goto no_link_test;
- if (!prom_node_has_property(nd, "tpe-link-test?"))
+ prop = of_get_property(nd, "tpe-link-test?", NULL);
+ if (!prop)
goto no_link_test;
- memset(prop, 0, sizeof(prop));
- prom_getstring(nd, "tpe-link-test?", prop,
- sizeof(prop));
-
if (strcmp(prop, "true")) {
printk(KERN_NOTICE "SunLance: warning: overriding option "
"'tpe-link-test?'\n");
diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c
index 61f98251feab..ff1028a597df 100644
--- a/drivers/net/sunvnet.c
+++ b/drivers/net/sunvnet.c
@@ -906,7 +906,6 @@ static const struct ethtool_ops vnet_ethtool_ops = {
.get_msglevel = vnet_get_msglevel,
.set_msglevel = vnet_set_msglevel,
.get_link = ethtool_op_get_link,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
static void vnet_port_free_tx_bufs(struct vnet_port *port)
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index 7f94ca930988..ec41469eee82 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -2198,7 +2198,6 @@ static const struct ethtool_ops tc35815_ethtool_ops = {
.get_strings = tc35815_get_strings,
.get_stats_count = tc35815_get_stats_count,
.get_ethtool_stats = tc35815_get_ethtool_stats,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
static int tc35815_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 887b9a5cfe48..dc41c055ebb5 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -9294,7 +9294,6 @@ static const struct ethtool_ops tg3_ethtool_ops = {
.get_ethtool_stats = tg3_get_ethtool_stats,
.get_coalesce = tg3_get_coalesce,
.set_coalesce = tg3_set_coalesce,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index f87d76981ab7..eca984f89bbf 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -1471,14 +1471,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
sa_offset = 2; /* Grrr, damn Matrox boards. */
multiport_cnt = 4;
}
-#ifdef CONFIG_DDB5477
- if ((pdev->bus->number == 0) && (PCI_SLOT(pdev->devfn) == 4)) {
- /* DDB5477 MAC address in first EEPROM locations. */
- sa_offset = 0;
- /* No media table either */
- tp->flags &= ~HAS_MEDIA_TABLE;
- }
-#endif
#ifdef CONFIG_MIPS_COBALT
if ((pdev->bus->number == 0) &&
((PCI_SLOT(pdev->devfn) == 7) ||
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index e4736a3b1b7a..12e01b24105a 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -43,10 +43,6 @@
#undef DEBUG
-#define DRV_DESC "QE UCC Gigabit Ethernet Controller"
-#define DRV_NAME "ucc_geth"
-#define DRV_VERSION "1.1"
-
#define ugeth_printk(level, format, arg...) \
printk(level format "\n", ## arg)
@@ -64,9 +60,19 @@
#else
#define ugeth_vdbg(fmt, args...) do { } while (0)
#endif /* UGETH_VERBOSE_DEBUG */
+#define UGETH_MSG_DEFAULT (NETIF_MSG_IFUP << 1 ) - 1
+void uec_set_ethtool_ops(struct net_device *netdev);
+
static DEFINE_SPINLOCK(ugeth_lock);
+static struct {
+ u32 msg_enable;
+} debug = { -1 };
+
+module_param_named(debug, debug.msg_enable, int, 0);
+MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 0xffff=all)");
+
static struct ucc_geth_info ugeth_primary_info = {
.uf_info = {
.bd_mem_part = MEM_PART_SYSTEM,
@@ -104,6 +110,7 @@ static struct ucc_geth_info ugeth_primary_info = {
.maxRetransmission = 0xf,
.collisionWindow = 0x37,
.receiveFlowControl = 1,
+ .transmitFlowControl = 1,
.maxGroupAddrInHash = 4,
.maxIndAddrInHash = 4,
.prel = 7,
@@ -139,7 +146,9 @@ static struct ucc_geth_info ugeth_primary_info = {
.numStationAddresses = UCC_GETH_NUM_OF_STATION_ADDRESSES_1,
.largestexternallookupkeysize =
QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE,
- .statisticsMode = UCC_GETH_STATISTICS_GATHERING_MODE_NONE,
+ .statisticsMode = UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE |
+ UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX |
+ UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX,
.vlanOperationTagged = UCC_GETH_VLAN_OPERATION_TAGGED_NOP,
.vlanOperationNonTagged = UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP,
.rxQoSMode = UCC_GETH_QOS_MODE_DEFAULT,
@@ -281,7 +290,8 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
for (i = 0; i < num_entries; i++) {
if ((snum = qe_get_snum()) < 0) {
- ugeth_err("fill_init_enet_entries: Can not get SNUM.");
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("fill_init_enet_entries: Can not get SNUM.");
return snum;
}
if ((i == 0) && skip_page_for_first_entry)
@@ -291,8 +301,8 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
init_enet_offset =
qe_muram_alloc(thread_size, thread_alignment);
if (IS_ERR_VALUE(init_enet_offset)) {
- ugeth_err
- ("fill_init_enet_entries: Can not allocate DPRAM memory.");
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("fill_init_enet_entries: Can not allocate DPRAM memory.");
qe_put_snum((u8) snum);
return -ENOMEM;
}
@@ -1200,7 +1210,7 @@ static int init_inter_frame_gap_params(u8 non_btb_cs_ipg,
return 0;
}
-static int init_flow_control_params(u32 automatic_flow_control_mode,
+int init_flow_control_params(u32 automatic_flow_control_mode,
int rx_flow_control_enable,
int tx_flow_control_enable,
u16 pause_period,
@@ -1486,9 +1496,9 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
ret_val = init_preamble_length(ug_info->prel, &ug_regs->maccfg2);
if (ret_val != 0) {
- ugeth_err
- ("%s: Preamble length must be between 3 and 7 inclusive.",
- __FUNCTION__);
+ if (netif_msg_probe(ugeth))
+ ugeth_err("%s: Preamble length must be between 3 and 7 inclusive.",
+ __FUNCTION__);
return ret_val;
}
@@ -1726,7 +1736,8 @@ static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode)
/* check if the UCC number is in range. */
if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
- ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
+ if (netif_msg_probe(ugeth))
+ ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
return -EINVAL;
}
@@ -1754,7 +1765,8 @@ static int ugeth_disable(struct ucc_geth_private * ugeth, enum comm_dir mode)
/* check if the UCC number is in range. */
if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
- ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
+ if (netif_msg_probe(ugeth))
+ ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
return -EINVAL;
}
@@ -2306,7 +2318,9 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
if (!((uf_info->bd_mem_part == MEM_PART_SYSTEM) ||
(uf_info->bd_mem_part == MEM_PART_MURAM))) {
- ugeth_err("%s: Bad memory partition value.", __FUNCTION__);
+ if (netif_msg_probe(ugeth))
+ ugeth_err("%s: Bad memory partition value.",
+ __FUNCTION__);
return -EINVAL;
}
@@ -2315,9 +2329,10 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
if ((ug_info->bdRingLenRx[i] < UCC_GETH_RX_BD_RING_SIZE_MIN) ||
(ug_info->bdRingLenRx[i] %
UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT)) {
- ugeth_err
- ("%s: Rx BD ring length must be multiple of 4,"
- " no smaller than 8.", __FUNCTION__);
+ if (netif_msg_probe(ugeth))
+ ugeth_err
+ ("%s: Rx BD ring length must be multiple of 4, no smaller than 8.",
+ __FUNCTION__);
return -EINVAL;
}
}
@@ -2325,9 +2340,10 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
/* Tx BD lengths */
for (i = 0; i < ug_info->numQueuesTx; i++) {
if (ug_info->bdRingLenTx[i] < UCC_GETH_TX_BD_RING_SIZE_MIN) {
- ugeth_err
- ("%s: Tx BD ring length must be no smaller than 2.",
- __FUNCTION__);
+ if (netif_msg_probe(ugeth))
+ ugeth_err
+ ("%s: Tx BD ring length must be no smaller than 2.",
+ __FUNCTION__);
return -EINVAL;
}
}
@@ -2335,31 +2351,35 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
/* mrblr */
if ((uf_info->max_rx_buf_length == 0) ||
(uf_info->max_rx_buf_length % UCC_GETH_MRBLR_ALIGNMENT)) {
- ugeth_err
- ("%s: max_rx_buf_length must be non-zero multiple of 128.",
- __FUNCTION__);
+ if (netif_msg_probe(ugeth))
+ ugeth_err
+ ("%s: max_rx_buf_length must be non-zero multiple of 128.",
+ __FUNCTION__);
return -EINVAL;
}
/* num Tx queues */
if (ug_info->numQueuesTx > NUM_TX_QUEUES) {
- ugeth_err("%s: number of tx queues too large.", __FUNCTION__);
+ if (netif_msg_probe(ugeth))
+ ugeth_err("%s: number of tx queues too large.", __FUNCTION__);
return -EINVAL;
}
/* num Rx queues */
if (ug_info->numQueuesRx > NUM_RX_QUEUES) {
- ugeth_err("%s: number of rx queues too large.", __FUNCTION__);
+ if (netif_msg_probe(ugeth))
+ ugeth_err("%s: number of rx queues too large.", __FUNCTION__);
return -EINVAL;
}
/* l2qt */
for (i = 0; i < UCC_GETH_VLAN_PRIORITY_MAX; i++) {
if (ug_info->l2qt[i] >= ug_info->numQueuesRx) {
- ugeth_err
- ("%s: VLAN priority table entry must not be"
- " larger than number of Rx queues.",
- __FUNCTION__);
+ if (netif_msg_probe(ugeth))
+ ugeth_err
+ ("%s: VLAN priority table entry must not be"
+ " larger than number of Rx queues.",
+ __FUNCTION__);
return -EINVAL;
}
}
@@ -2367,26 +2387,29 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
/* l3qt */
for (i = 0; i < UCC_GETH_IP_PRIORITY_MAX; i++) {
if (ug_info->l3qt[i] >= ug_info->numQueuesRx) {
- ugeth_err
- ("%s: IP priority table entry must not be"
- " larger than number of Rx queues.",
- __FUNCTION__);
+ if (netif_msg_probe(ugeth))
+ ugeth_err
+ ("%s: IP priority table entry must not be"
+ " larger than number of Rx queues.",
+ __FUNCTION__);
return -EINVAL;
}
}
if (ug_info->cam && !ug_info->ecamptr) {
- ugeth_err("%s: If cam mode is chosen, must supply cam ptr.",
- __FUNCTION__);
+ if (netif_msg_probe(ugeth))
+ ugeth_err("%s: If cam mode is chosen, must supply cam ptr.",
+ __FUNCTION__);
return -EINVAL;
}
if ((ug_info->numStationAddresses !=
UCC_GETH_NUM_OF_STATION_ADDRESSES_1)
&& ug_info->rxExtendedFiltering) {
- ugeth_err("%s: Number of station addresses greater than 1 "
- "not allowed in extended parsing mode.",
- __FUNCTION__);
+ if (netif_msg_probe(ugeth))
+ ugeth_err("%s: Number of station addresses greater than 1 "
+ "not allowed in extended parsing mode.",
+ __FUNCTION__);
return -EINVAL;
}
@@ -2399,7 +2422,8 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
uf_info->uccm_mask |= (UCCE_TXBF_SINGLE_MASK << i);
/* Initialize the general fast UCC block. */
if (ucc_fast_init(uf_info, &ugeth->uccf)) {
- ugeth_err("%s: Failed to init uccf.", __FUNCTION__);
+ if (netif_msg_probe(ugeth))
+ ugeth_err("%s: Failed to init uccf.", __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2452,7 +2476,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
numThreadsRxNumerical = 8;
break;
default:
- ugeth_err("%s: Bad number of Rx threads value.", __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Bad number of Rx threads value.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -EINVAL;
break;
@@ -2475,7 +2501,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
numThreadsTxNumerical = 8;
break;
default:
- ugeth_err("%s: Bad number of Tx threads value.", __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Bad number of Tx threads value.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -EINVAL;
break;
@@ -2507,7 +2535,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
/* For more details see the hardware spec. */
init_flow_control_params(ug_info->aufc,
ug_info->receiveFlowControl,
- 1,
+ ug_info->transmitFlowControl,
ug_info->pausePeriod,
ug_info->extensionField,
&uf_regs->upsmr,
@@ -2527,8 +2555,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
ug_info->backToBackInterFrameGap,
&ug_regs->ipgifg);
if (ret_val != 0) {
- ugeth_err("%s: IPGIFG initialization parameter too large.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: IPGIFG initialization parameter too large.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return ret_val;
}
@@ -2544,7 +2573,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
ug_info->collisionWindow,
&ug_regs->hafdup);
if (ret_val != 0) {
- ugeth_err("%s: Half Duplex initialization parameter too large.",
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Half Duplex initialization parameter too large.",
__FUNCTION__);
ucc_geth_memclean(ugeth);
return ret_val;
@@ -2597,9 +2627,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
tx_bd_ring_offset[j]);
}
if (!ugeth->p_tx_bd_ring[j]) {
- ugeth_err
- ("%s: Can not allocate memory for Tx bd rings.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err
+ ("%s: Can not allocate memory for Tx bd rings.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2632,9 +2663,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
rx_bd_ring_offset[j]);
}
if (!ugeth->p_rx_bd_ring[j]) {
- ugeth_err
- ("%s: Can not allocate memory for Rx bd rings.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err
+ ("%s: Can not allocate memory for Rx bd rings.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2648,8 +2680,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
GFP_KERNEL);
if (ugeth->tx_skbuff[j] == NULL) {
- ugeth_err("%s: Could not allocate tx_skbuff",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Could not allocate tx_skbuff",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2679,8 +2712,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
GFP_KERNEL);
if (ugeth->rx_skbuff[j] == NULL) {
- ugeth_err("%s: Could not allocate rx_skbuff",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Could not allocate rx_skbuff",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2711,9 +2745,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
qe_muram_alloc(sizeof(struct ucc_geth_tx_global_pram),
UCC_GETH_TX_GLOBAL_PRAM_ALIGNMENT);
if (IS_ERR_VALUE(ugeth->tx_glbl_pram_offset)) {
- ugeth_err
- ("%s: Can not allocate DPRAM memory for p_tx_glbl_pram.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err
+ ("%s: Can not allocate DPRAM memory for p_tx_glbl_pram.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2733,9 +2768,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
32 * (numThreadsTxNumerical == 1),
UCC_GETH_THREAD_DATA_ALIGNMENT);
if (IS_ERR_VALUE(ugeth->thread_dat_tx_offset)) {
- ugeth_err
- ("%s: Can not allocate DPRAM memory for p_thread_data_tx.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err
+ ("%s: Can not allocate DPRAM memory for p_thread_data_tx.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2761,9 +2797,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
sizeof(struct ucc_geth_send_queue_qd),
UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT);
if (IS_ERR_VALUE(ugeth->send_q_mem_reg_offset)) {
- ugeth_err
- ("%s: Can not allocate DPRAM memory for p_send_q_mem_reg.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err
+ ("%s: Can not allocate DPRAM memory for p_send_q_mem_reg.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2804,9 +2841,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
qe_muram_alloc(sizeof(struct ucc_geth_scheduler),
UCC_GETH_SCHEDULER_ALIGNMENT);
if (IS_ERR_VALUE(ugeth->scheduler_offset)) {
- ugeth_err
- ("%s: Can not allocate DPRAM memory for p_scheduler.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err
+ ("%s: Can not allocate DPRAM memory for p_scheduler.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2852,9 +2890,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
(struct ucc_geth_tx_firmware_statistics_pram),
UCC_GETH_TX_STATISTICS_ALIGNMENT);
if (IS_ERR_VALUE(ugeth->tx_fw_statistics_pram_offset)) {
- ugeth_err
- ("%s: Can not allocate DPRAM memory for"
- " p_tx_fw_statistics_pram.", __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err
+ ("%s: Can not allocate DPRAM memory for"
+ " p_tx_fw_statistics_pram.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2891,9 +2931,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
qe_muram_alloc(sizeof(struct ucc_geth_rx_global_pram),
UCC_GETH_RX_GLOBAL_PRAM_ALIGNMENT);
if (IS_ERR_VALUE(ugeth->rx_glbl_pram_offset)) {
- ugeth_err
- ("%s: Can not allocate DPRAM memory for p_rx_glbl_pram.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err
+ ("%s: Can not allocate DPRAM memory for p_rx_glbl_pram.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2912,9 +2953,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
sizeof(struct ucc_geth_thread_data_rx),
UCC_GETH_THREAD_DATA_ALIGNMENT);
if (IS_ERR_VALUE(ugeth->thread_dat_rx_offset)) {
- ugeth_err
- ("%s: Can not allocate DPRAM memory for p_thread_data_rx.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err
+ ("%s: Can not allocate DPRAM memory for p_thread_data_rx.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2935,9 +2977,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
(struct ucc_geth_rx_firmware_statistics_pram),
UCC_GETH_RX_STATISTICS_ALIGNMENT);
if (IS_ERR_VALUE(ugeth->rx_fw_statistics_pram_offset)) {
- ugeth_err
- ("%s: Can not allocate DPRAM memory for"
- " p_rx_fw_statistics_pram.", __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err
+ ("%s: Can not allocate DPRAM memory for"
+ " p_rx_fw_statistics_pram.", __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -2957,9 +3000,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
sizeof(struct ucc_geth_rx_interrupt_coalescing_entry)
+ 4, UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT);
if (IS_ERR_VALUE(ugeth->rx_irq_coalescing_tbl_offset)) {
- ugeth_err
- ("%s: Can not allocate DPRAM memory for"
- " p_rx_irq_coalescing_tbl.", __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err
+ ("%s: Can not allocate DPRAM memory for"
+ " p_rx_irq_coalescing_tbl.", __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3025,9 +3069,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
sizeof(struct ucc_geth_rx_prefetched_bds)),
UCC_GETH_RX_BD_QUEUES_ALIGNMENT);
if (IS_ERR_VALUE(ugeth->rx_bd_qs_tbl_offset)) {
- ugeth_err
- ("%s: Can not allocate DPRAM memory for p_rx_bd_qs_tbl.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err
+ ("%s: Can not allocate DPRAM memory for p_rx_bd_qs_tbl.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3102,8 +3147,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
/* initialize extended filtering */
if (ug_info->rxExtendedFiltering) {
if (!ug_info->extendedFilteringChainPointer) {
- ugeth_err("%s: Null Extended Filtering Chain Pointer.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Null Extended Filtering Chain Pointer.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -EINVAL;
}
@@ -3114,9 +3160,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
qe_muram_alloc(sizeof(struct ucc_geth_exf_global_pram),
UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT);
if (IS_ERR_VALUE(ugeth->exf_glbl_param_offset)) {
- ugeth_err
- ("%s: Can not allocate DPRAM memory for"
- " p_exf_glbl_param.", __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err
+ ("%s: Can not allocate DPRAM memory for"
+ " p_exf_glbl_param.", __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3161,9 +3208,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
*/
if (!(ugeth->p_init_enet_param_shadow =
kmalloc(sizeof(struct ucc_geth_init_pram), GFP_KERNEL))) {
- ugeth_err
- ("%s: Can not allocate memory for"
- " p_UccInitEnetParamShadows.", __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err
+ ("%s: Can not allocate memory for"
+ " p_UccInitEnetParamShadows.", __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3196,8 +3244,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES)
&& (ug_info->largestexternallookupkeysize !=
QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES)) {
- ugeth_err("%s: Invalid largest External Lookup Key Size.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Invalid largest External Lookup Key Size.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -EINVAL;
}
@@ -3222,8 +3271,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
/* Rx needs one extra for terminator */
, size, UCC_GETH_THREAD_RX_PRAM_ALIGNMENT,
ug_info->riscRx, 1)) != 0) {
- ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return ret_val;
}
@@ -3237,8 +3287,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
sizeof(struct ucc_geth_thread_tx_pram),
UCC_GETH_THREAD_TX_PRAM_ALIGNMENT,
ug_info->riscTx, 0)) != 0) {
- ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return ret_val;
}
@@ -3246,8 +3297,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
/* Load Rx bds with buffers */
for (i = 0; i < ug_info->numQueuesRx; i++) {
if ((ret_val = rx_bd_buffer_set(ugeth, (u8) i)) != 0) {
- ugeth_err("%s: Can not fill Rx bds with buffers.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Can not fill Rx bds with buffers.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return ret_val;
}
@@ -3256,9 +3308,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
/* Allocate InitEnet command parameter structure */
init_enet_pram_offset = qe_muram_alloc(sizeof(struct ucc_geth_init_pram), 4);
if (IS_ERR_VALUE(init_enet_pram_offset)) {
- ugeth_err
- ("%s: Can not allocate DPRAM memory for p_init_enet_pram.",
- __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err
+ ("%s: Can not allocate DPRAM memory for p_init_enet_pram.",
+ __FUNCTION__);
ucc_geth_memclean(ugeth);
return -ENOMEM;
}
@@ -3428,8 +3481,9 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
if (!skb ||
(!(bd_status & (R_F | R_L))) ||
(bd_status & R_ERRORS_FATAL)) {
- ugeth_vdbg("%s, %d: ERROR!!! skb - 0x%08x",
- __FUNCTION__, __LINE__, (u32) skb);
+ if (netif_msg_rx_err(ugeth))
+ ugeth_err("%s, %d: ERROR!!! skb - 0x%08x",
+ __FUNCTION__, __LINE__, (u32) skb);
if (skb)
dev_kfree_skb_any(skb);
@@ -3458,7 +3512,8 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
skb = get_new_skb(ugeth, bd);
if (!skb) {
- ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__);
+ if (netif_msg_rx_err(ugeth))
+ ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__);
ugeth->stats.rx_dropped++;
break;
}
@@ -3649,28 +3704,32 @@ static int ucc_geth_open(struct net_device *dev)
/* Test station address */
if (dev->dev_addr[0] & ENET_GROUP_ADDR) {
- ugeth_err("%s: Multicast address used for station address"
- " - is this what you wanted?", __FUNCTION__);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Multicast address used for station address"
+ " - is this what you wanted?", __FUNCTION__);
return -EINVAL;
}
err = ucc_struct_init(ugeth);
if (err) {
- ugeth_err("%s: Cannot configure internal struct, aborting.", dev->name);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Cannot configure internal struct, aborting.", dev->name);
return err;
}
err = ucc_geth_startup(ugeth);
if (err) {
- ugeth_err("%s: Cannot configure net device, aborting.",
- dev->name);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Cannot configure net device, aborting.",
+ dev->name);
return err;
}
err = adjust_enet_interface(ugeth);
if (err) {
- ugeth_err("%s: Cannot configure net device, aborting.",
- dev->name);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Cannot configure net device, aborting.",
+ dev->name);
return err;
}
@@ -3687,7 +3746,8 @@ static int ucc_geth_open(struct net_device *dev)
err = init_phy(dev);
if (err) {
- ugeth_err("%s: Cannot initialize PHY, aborting.", dev->name);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Cannot initialize PHY, aborting.", dev->name);
return err;
}
@@ -3697,15 +3757,17 @@ static int ucc_geth_open(struct net_device *dev)
request_irq(ugeth->ug_info->uf_info.irq, ucc_geth_irq_handler, 0,
"UCC Geth", dev);
if (err) {
- ugeth_err("%s: Cannot get IRQ for net device, aborting.",
- dev->name);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Cannot get IRQ for net device, aborting.",
+ dev->name);
ucc_geth_stop(ugeth);
return err;
}
err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
if (err) {
- ugeth_err("%s: Cannot enable net device, aborting.", dev->name);
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Cannot enable net device, aborting.", dev->name);
ucc_geth_stop(ugeth);
return err;
}
@@ -3732,8 +3794,6 @@ static int ucc_geth_close(struct net_device *dev)
return 0;
}
-const struct ethtool_ops ucc_geth_ethtool_ops = { };
-
static phy_interface_t to_phy_interface(const char *phy_connection_type)
{
if (strcasecmp(phy_connection_type, "mii") == 0)
@@ -3790,6 +3850,13 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
return -ENODEV;
ug_info = &ugeth_info[ucc_num];
+ if (ug_info == NULL) {
+ if (netif_msg_probe(&debug))
+ ugeth_err("%s: [%d] Missing additional data!",
+ __FUNCTION__, ucc_num);
+ return -ENODEV;
+ }
+
ug_info->uf_info.ucc_num = ucc_num;
prop = of_get_property(np, "rx-clock", NULL);
@@ -3868,15 +3935,10 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
ug_info->mdio_bus = res.start;
- printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n",
- ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs,
- ug_info->uf_info.irq);
-
- if (ug_info == NULL) {
- ugeth_err("%s: [%d] Missing additional data!", __FUNCTION__,
- ucc_num);
- return -ENODEV;
- }
+ if (netif_msg_probe(&debug))
+ printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n",
+ ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs,
+ ug_info->uf_info.irq);
/* Create an ethernet device instance */
dev = alloc_etherdev(sizeof(*ugeth));
@@ -3896,6 +3958,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
SET_NETDEV_DEV(dev, device);
/* Fill in the dev structure */
+ uec_set_ethtool_ops(dev);
dev->open = ucc_geth_open;
dev->hard_start_xmit = ucc_geth_start_xmit;
dev->tx_timeout = ucc_geth_timeout;
@@ -3909,16 +3972,16 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
// dev->change_mtu = ucc_geth_change_mtu;
dev->mtu = 1500;
dev->set_multicast_list = ucc_geth_set_multi;
- dev->ethtool_ops = &ucc_geth_ethtool_ops;
- ugeth->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
+ ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT);
ugeth->phy_interface = phy_interface;
ugeth->max_speed = max_speed;
err = register_netdev(dev);
if (err) {
- ugeth_err("%s: Cannot register net device, aborting.",
- dev->name);
+ if (netif_msg_probe(ugeth))
+ ugeth_err("%s: Cannot register net device, aborting.",
+ dev->name);
free_netdev(dev);
return err;
}
@@ -3972,7 +4035,8 @@ static int __init ucc_geth_init(void)
if (ret)
return ret;
- printk(KERN_INFO "ucc_geth: " DRV_DESC "\n");
+ if (netif_msg_drv(&debug))
+ printk(KERN_INFO "ucc_geth: " DRV_DESC "\n");
for (i = 0; i < 8; i++)
memcpy(&(ugeth_info[i]), &ugeth_primary_info,
sizeof(ugeth_primary_info));
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index a29e1c3ca4b7..bb4dac8c0c65 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -30,6 +30,10 @@
#include "ucc_geth_mii.h"
+#define DRV_DESC "QE UCC Gigabit Ethernet Controller"
+#define DRV_NAME "ucc_geth"
+#define DRV_VERSION "1.1"
+
#define NUM_TX_QUEUES 8
#define NUM_RX_QUEUES 8
#define NUM_BDS_IN_PREFETCHED_BDS 4
@@ -896,6 +900,7 @@ struct ucc_geth_hardware_statistics {
#define UCC_GETH_TX_VTAG_TABLE_ENTRY_MAX 8
#define UCC_GETH_RX_BD_RING_SIZE_MIN 8
#define UCC_GETH_TX_BD_RING_SIZE_MIN 2
+#define UCC_GETH_BD_RING_SIZE_MAX 0xffff
#define UCC_GETH_SIZE_OF_BD QE_SIZEOF_BD
@@ -1135,6 +1140,7 @@ struct ucc_geth_info {
int bro;
int ecm;
int receiveFlowControl;
+ int transmitFlowControl;
u8 maxGroupAddrInHash;
u8 maxIndAddrInHash;
u8 prel;
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c
new file mode 100644
index 000000000000..a8994c7b8583
--- /dev/null
+++ b/drivers/net/ucc_geth_ethtool.c
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Description: QE UCC Gigabit Ethernet Ethtool API Set
+ *
+ * Author: Li Yang <leoli@freescale.com>
+ *
+ * Limitation:
+ * Can only get/set setttings of the first queue.
+ * Need to re-open the interface manually after changing some paramters.
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/stddef.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/fsl_devices.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/types.h>
+#include <asm/uaccess.h>
+
+#include "ucc_geth.h"
+#include "ucc_geth_mii.h"
+
+static char hw_stat_gstrings[][ETH_GSTRING_LEN] = {
+ "tx-64-frames",
+ "tx-65-127-frames",
+ "tx-128-255-frames",
+ "rx-64-frames",
+ "rx-65-127-frames",
+ "rx-128-255-frames",
+ "tx-bytes-ok",
+ "tx-pause-frames",
+ "tx-multicast-frames",
+ "tx-broadcast-frames",
+ "rx-frames",
+ "rx-bytes-ok",
+ "rx-bytes-all",
+ "rx-multicast-frames",
+ "rx-broadcast-frames",
+ "stats-counter-carry",
+ "stats-counter-mask",
+ "rx-dropped-frames",
+};
+
+static char tx_fw_stat_gstrings[][ETH_GSTRING_LEN] = {
+ "tx-single-collision",
+ "tx-multiple-collision",
+ "tx-late-collsion",
+ "tx-aborted-frames",
+ "tx-lost-frames",
+ "tx-carrier-sense-errors",
+ "tx-frames-ok",
+ "tx-excessive-differ-frames",
+ "tx-256-511-frames",
+ "tx-1024-1518-frames",
+ "tx-jumbo-frames",
+};
+
+static char rx_fw_stat_gstrings[][ETH_GSTRING_LEN] = {
+ "rx-crc-errors",
+ "rx-alignment-errors",
+ "rx-in-range-length-errors",
+ "rx-out-of-range-length-errors",
+ "rx-too-long-frames",
+ "rx-runt",
+ "rx-very-long-event",
+ "rx-symbol-errors",
+ "rx-busy-drop-frames",
+ "reserved",
+ "reserved",
+ "rx-mismatch-drop-frames",
+ "rx-small-than-64",
+ "rx-256-511-frames",
+ "rx-512-1023-frames",
+ "rx-1024-1518-frames",
+ "rx-jumbo-frames",
+ "rx-mac-error-loss",
+ "rx-pause-frames",
+ "reserved",
+ "rx-vlan-removed",
+ "rx-vlan-replaced",
+ "rx-vlan-inserted",
+ "rx-ip-checksum-errors",
+};
+
+#define UEC_HW_STATS_LEN ARRAY_SIZE(hw_stat_gstrings)
+#define UEC_TX_FW_STATS_LEN ARRAY_SIZE(tx_fw_stat_gstrings)
+#define UEC_RX_FW_STATS_LEN ARRAY_SIZE(rx_fw_stat_gstrings)
+
+extern int init_flow_control_params(u32 automatic_flow_control_mode,
+ int rx_flow_control_enable,
+ int tx_flow_control_enable, u16 pause_period,
+ u16 extension_field, volatile u32 *upsmr_register,
+ volatile u32 *uempr_register, volatile u32 *maccfg1_register);
+
+static int
+uec_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
+ struct phy_device *phydev = ugeth->phydev;
+ struct ucc_geth_info *ug_info = ugeth->ug_info;
+
+ if (!phydev)
+ return -ENODEV;
+
+ ecmd->maxtxpkt = 1;
+ ecmd->maxrxpkt = ug_info->interruptcoalescingmaxvalue[0];
+
+ return phy_ethtool_gset(phydev, ecmd);
+}
+
+static int
+uec_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
+ struct phy_device *phydev = ugeth->phydev;
+
+ if (!phydev)
+ return -ENODEV;
+
+ return phy_ethtool_sset(phydev, ecmd);
+}
+
+static void
+uec_get_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pause)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
+
+ pause->autoneg = ugeth->phydev->autoneg;
+
+ if (ugeth->ug_info->receiveFlowControl)
+ pause->rx_pause = 1;
+ if (ugeth->ug_info->transmitFlowControl)
+ pause->tx_pause = 1;
+}
+
+static int
+uec_set_pauseparam(struct net_device *netdev,
+ struct ethtool_pauseparam *pause)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
+ int ret = 0;
+
+ ugeth->ug_info->receiveFlowControl = pause->rx_pause;
+ ugeth->ug_info->transmitFlowControl = pause->tx_pause;
+
+ if (ugeth->phydev->autoneg) {
+ if (netif_running(netdev)) {
+ /* FIXME: automatically restart */
+ printk(KERN_INFO
+ "Please re-open the interface.\n");
+ }
+ } else {
+ struct ucc_geth_info *ug_info = ugeth->ug_info;
+
+ ret = init_flow_control_params(ug_info->aufc,
+ ug_info->receiveFlowControl,
+ ug_info->transmitFlowControl,
+ ug_info->pausePeriod,
+ ug_info->extensionField,
+ &ugeth->uccf->uf_regs->upsmr,
+ &ugeth->ug_regs->uempr,
+ &ugeth->ug_regs->maccfg1);
+ }
+
+ return ret;
+}
+
+static uint32_t
+uec_get_msglevel(struct net_device *netdev)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
+ return ugeth->msg_enable;
+}
+
+static void
+uec_set_msglevel(struct net_device *netdev, uint32_t data)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
+ ugeth->msg_enable = data;
+}
+
+static int
+uec_get_regs_len(struct net_device *netdev)
+{
+ return sizeof(struct ucc_geth);
+}
+
+static void
+uec_get_regs(struct net_device *netdev,
+ struct ethtool_regs *regs, void *p)
+{
+ int i;
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
+ u32 __iomem *ug_regs = (u32 __iomem *)ugeth->ug_regs;
+ u32 *buff = p;
+
+ for (i = 0; i < sizeof(struct ucc_geth) / sizeof(u32); i++)
+ buff[i] = in_be32(&ug_regs[i]);
+}
+
+static void
+uec_get_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
+ struct ucc_geth_info *ug_info = ugeth->ug_info;
+ int queue = 0;
+
+ ring->rx_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
+ ring->rx_mini_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
+ ring->rx_jumbo_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
+ ring->tx_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
+
+ ring->rx_pending = ug_info->bdRingLenRx[queue];
+ ring->rx_mini_pending = ug_info->bdRingLenRx[queue];
+ ring->rx_jumbo_pending = ug_info->bdRingLenRx[queue];
+ ring->tx_pending = ug_info->bdRingLenTx[queue];
+}
+
+static int
+uec_set_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
+ struct ucc_geth_info *ug_info = ugeth->ug_info;
+ int queue = 0, ret = 0;
+
+ if (ring->rx_pending < UCC_GETH_RX_BD_RING_SIZE_MIN) {
+ printk("%s: RxBD ring size must be no smaller than %d.\n",
+ netdev->name, UCC_GETH_RX_BD_RING_SIZE_MIN);
+ return -EINVAL;
+ }
+ if (ring->rx_pending % UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT) {
+ printk("%s: RxBD ring size must be multiple of %d.\n",
+ netdev->name, UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT);
+ return -EINVAL;
+ }
+ if (ring->tx_pending < UCC_GETH_TX_BD_RING_SIZE_MIN) {
+ printk("%s: TxBD ring size must be no smaller than %d.\n",
+ netdev->name, UCC_GETH_TX_BD_RING_SIZE_MIN);
+ return -EINVAL;
+ }
+
+ ug_info->bdRingLenRx[queue] = ring->rx_pending;
+ ug_info->bdRingLenTx[queue] = ring->tx_pending;
+
+ if (netif_running(netdev)) {
+ /* FIXME: restart automatically */
+ printk(KERN_INFO
+ "Please re-open the interface.\n");
+ }
+
+ return ret;
+}
+
+static int uec_get_stats_count(struct net_device *netdev)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
+ u32 stats_mode = ugeth->ug_info->statisticsMode;
+ int len = 0;
+
+ if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE)
+ len += UEC_HW_STATS_LEN;
+ if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX)
+ len += UEC_TX_FW_STATS_LEN;
+ if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX)
+ len += UEC_RX_FW_STATS_LEN;
+
+ return len;
+}
+
+static void uec_get_strings(struct net_device *netdev, u32 stringset, u8 *buf)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
+ u32 stats_mode = ugeth->ug_info->statisticsMode;
+
+ if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE) {
+ memcpy(buf, hw_stat_gstrings, UEC_HW_STATS_LEN *
+ ETH_GSTRING_LEN);
+ buf += UEC_HW_STATS_LEN * ETH_GSTRING_LEN;
+ }
+ if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) {
+ memcpy(buf, tx_fw_stat_gstrings, UEC_TX_FW_STATS_LEN *
+ ETH_GSTRING_LEN);
+ buf += UEC_TX_FW_STATS_LEN * ETH_GSTRING_LEN;
+ }
+ if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX)
+ memcpy(buf, tx_fw_stat_gstrings, UEC_RX_FW_STATS_LEN *
+ ETH_GSTRING_LEN);
+}
+
+static void uec_get_ethtool_stats(struct net_device *netdev,
+ struct ethtool_stats *stats, uint64_t *data)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
+ u32 stats_mode = ugeth->ug_info->statisticsMode;
+ u32 __iomem *base;
+ int i, j = 0;
+
+ if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE) {
+ base = (u32 __iomem *)&ugeth->ug_regs->tx64;
+ for (i = 0; i < UEC_HW_STATS_LEN; i++)
+ data[j++] = (u64)in_be32(&base[i]);
+ }
+ if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) {
+ base = (u32 __iomem *)ugeth->p_tx_fw_statistics_pram;
+ for (i = 0; i < UEC_TX_FW_STATS_LEN; i++)
+ data[j++] = (u64)in_be32(&base[i]);
+ }
+ if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) {
+ base = (u32 __iomem *)ugeth->p_rx_fw_statistics_pram;
+ for (i = 0; i < UEC_RX_FW_STATS_LEN; i++)
+ data[j++] = (u64)in_be32(&base[i]);
+ }
+}
+
+static int uec_nway_reset(struct net_device *netdev)
+{
+ struct ucc_geth_private *ugeth = netdev_priv(netdev);
+
+ return phy_start_aneg(ugeth->phydev);
+}
+
+/* Report driver information */
+static void
+uec_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ strncpy(drvinfo->driver, DRV_NAME, 32);
+ strncpy(drvinfo->version, DRV_VERSION, 32);
+ strncpy(drvinfo->fw_version, "N/A", 32);
+ strncpy(drvinfo->bus_info, "QUICC ENGINE", 32);
+ drvinfo->n_stats = uec_get_stats_count(netdev);
+ drvinfo->testinfo_len = 0;
+ drvinfo->eedump_len = 0;
+ drvinfo->regdump_len = uec_get_regs_len(netdev);
+}
+
+static const struct ethtool_ops uec_ethtool_ops = {
+ .get_settings = uec_get_settings,
+ .set_settings = uec_set_settings,
+ .get_drvinfo = uec_get_drvinfo,
+ .get_regs_len = uec_get_regs_len,
+ .get_regs = uec_get_regs,
+ .get_msglevel = uec_get_msglevel,
+ .set_msglevel = uec_set_msglevel,
+ .nway_reset = uec_nway_reset,
+ .get_link = ethtool_op_get_link,
+ .get_ringparam = uec_get_ringparam,
+ .set_ringparam = uec_set_ringparam,
+ .get_pauseparam = uec_get_pauseparam,
+ .set_pauseparam = uec_set_pauseparam,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+ .get_tso = ethtool_op_get_tso,
+ .get_stats_count = uec_get_stats_count,
+ .get_strings = uec_get_strings,
+ .get_ethtool_stats = uec_get_ethtool_stats,
+ .get_perm_addr = ethtool_op_get_perm_addr,
+};
+
+void uec_set_ethtool_ops(struct net_device *netdev)
+{
+ SET_ETHTOOL_OPS(netdev, &uec_ethtool_ops);
+}
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
index 7bcb82f50cf7..5f8c2d30a328 100644
--- a/drivers/net/ucc_geth_mii.c
+++ b/drivers/net/ucc_geth_mii.c
@@ -54,8 +54,8 @@
#define vdbg(format, arg...) do {} while(0)
#endif
-#define DRV_DESC "QE UCC Ethernet Controller MII Bus"
-#define DRV_NAME "fsl-uec_mdio"
+#define MII_DRV_DESC "QE UCC Ethernet Controller MII Bus"
+#define MII_DRV_NAME "fsl-uec_mdio"
/* Write value to the PHY for this device to the register at regnum, */
/* waiting until the write is done before it returns. All PHY */
@@ -261,7 +261,7 @@ static struct of_device_id uec_mdio_match[] = {
};
static struct of_platform_driver uec_mdio_driver = {
- .name = DRV_NAME,
+ .name = MII_DRV_NAME,
.probe = uec_mdio_probe,
.remove = uec_mdio_remove,
.match_table = uec_mdio_match,
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index a05fd97e5bc2..04cba6bf3d54 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -768,11 +768,13 @@ done:
static void write_bulk_callback(struct urb *urb)
{
pegasus_t *pegasus = urb->context;
- struct net_device *net = pegasus->net;
+ struct net_device *net;
if (!pegasus)
return;
+ net = pegasus->net;
+
if (!netif_device_present(net) || !netif_running(net))
return;
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index f51c2c138f10..c3fe230695a0 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -1805,7 +1805,6 @@ static const struct ethtool_ops netdev_ethtool_ops = {
.set_wol = rhine_set_wol,
.get_sg = ethtool_op_get_sg,
.get_tx_csum = ethtool_op_get_tx_csum,
- .get_perm_addr = ethtool_op_get_perm_addr,
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index f331843d1102..93574add4063 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1613,7 +1613,7 @@ static void velocity_error(struct velocity_info *vptr, int status)
if (status & ISR_TXSTLI) {
struct mac_regs __iomem * regs = vptr->mac_regs;
- printk(KERN_ERR "TD structure errror TDindex=%hx\n", readw(&regs->TDIdx[0]));
+ printk(KERN_ERR "TD structure error TDindex=%hx\n", readw(&regs->TDIdx[0]));
BYTE_REG_BITS_ON(TXESR_TDSTR, &regs->TXESR);
writew(TRDCSR_RUN, &regs->TDCSRClr);
netif_stop_queue(vptr->dev);