aboutsummaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-09-24 15:13:11 -0700
committerDavid S. Miller <davem@davemloft.net>2009-09-24 15:13:11 -0700
commit8b3f6af86378d0a10ca2f1ded1da124aef13b62c (patch)
treede6ca90295730343c495be8d98be8efa322140ef /drivers/net
parent139d6065c83071d5f66cd013a274a43699f8e2c1 (diff)
parent94e0fb086fc5663c38bbc0fe86d698be8314f82f (diff)
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Conflicts: drivers/staging/Kconfig drivers/staging/Makefile drivers/staging/cpc-usb/TODO drivers/staging/cpc-usb/cpc-usb_drv.c drivers/staging/cpc-usb/cpc.h drivers/staging/cpc-usb/cpc_int.h drivers/staging/cpc-usb/cpcusb.h
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/Kconfig11
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/arcnet/arc-rawmode.c1
-rw-r--r--drivers/net/arcnet/capmode.c1
-rw-r--r--drivers/net/bcm63xx_enet.c1971
-rw-r--r--drivers/net/bcm63xx_enet.h303
-rw-r--r--drivers/net/bnx2x_reg.h2
-rw-r--r--drivers/net/bonding/bond_3ad.c2
-rw-r--r--drivers/net/e1000/e1000_hw.c2
-rw-r--r--drivers/net/ehea/ehea_qmr.c2
-rw-r--r--drivers/net/enc28j60.c1
-rw-r--r--drivers/net/fec.c18
-rw-r--r--drivers/net/gianfar_ethtool.c2
-rw-r--r--drivers/net/ibm_newemac/core.c8
-rw-r--r--drivers/net/igb/igb_main.c2
-rw-r--r--drivers/net/ks8851.c1
-rw-r--r--drivers/net/ll_temac_main.c2
-rw-r--r--drivers/net/macb.c2
-rw-r--r--drivers/net/ni52.c4
-rw-r--r--drivers/net/niu.c2
-rw-r--r--drivers/net/qlge/qlge_main.c4
-rw-r--r--drivers/net/rionet.c2
-rw-r--r--drivers/net/sfc/efx.c3
-rw-r--r--drivers/net/skfp/pcmplc.c2
-rw-r--r--drivers/net/skfp/pmf.c8
-rw-r--r--drivers/net/skge.c2
-rw-r--r--drivers/net/sky2.c2
-rw-r--r--drivers/net/slip.c96
-rw-r--r--drivers/net/smc91x.c4
-rw-r--r--drivers/net/smc91x.h2
-rw-r--r--drivers/net/tun.c2
-rw-r--r--drivers/net/usb/cdc_eem.c17
-rw-r--r--drivers/net/virtio_net.c15
-rw-r--r--drivers/net/vxge/vxge-config.h2
-rw-r--r--drivers/net/vxge/vxge-main.c2
-rw-r--r--drivers/net/wireless/arlan-proc.c28
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h2
-rw-r--r--drivers/net/wireless/atmel.c2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/Kconfig6
-rw-r--r--drivers/net/wireless/libertas/if_spi.c1
-rw-r--r--drivers/net/wireless/p54/p54spi.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c2
43 files changed, 2386 insertions, 158 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index f9fbd52b799..2bea67c134f 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -209,7 +209,7 @@ config MII
config MACB
tristate "Atmel MACB support"
- depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91CAP9
+ depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45 || ARCH_AT91CAP9
select PHYLIB
help
The Atmel MACB ethernet interface is found on many AT32 and AT91
@@ -1934,6 +1934,15 @@ config XILINX_EMACLITE
help
This driver supports the 10/100 Ethernet Lite from Xilinx.
+config BCM63XX_ENET
+ tristate "Broadcom 63xx internal mac support"
+ depends on BCM63XX
+ select MII
+ select PHYLIB
+ help
+ This driver supports the ethernet MACs in the Broadcom 63xx
+ MIPS chipset family (BCM63XX).
+
source "drivers/net/fs_enet/Kconfig"
endif # NET_ETHERNET
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 99ae6d7fe6a..ae8cd30f13d 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -137,6 +137,7 @@ obj-$(CONFIG_B44) += b44.o
obj-$(CONFIG_FORCEDETH) += forcedeth.o
obj-$(CONFIG_NE_H8300) += ne-h8300.o 8390.o
obj-$(CONFIG_AX88796) += ax88796.o
+obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o
obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
diff --git a/drivers/net/arcnet/arc-rawmode.c b/drivers/net/arcnet/arc-rawmode.c
index 646dfc5f50c..8ea9c7545c1 100644
--- a/drivers/net/arcnet/arc-rawmode.c
+++ b/drivers/net/arcnet/arc-rawmode.c
@@ -123,7 +123,6 @@ static void rx(struct net_device *dev, int bufnum,
BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
skb->protocol = cpu_to_be16(ETH_P_ARCNET);
-;
netif_rx(skb);
}
diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c
index 083e21094b2..66bcbbb6bab 100644
--- a/drivers/net/arcnet/capmode.c
+++ b/drivers/net/arcnet/capmode.c
@@ -149,7 +149,6 @@ static void rx(struct net_device *dev, int bufnum,
BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
skb->protocol = cpu_to_be16(ETH_P_ARCNET);
-;
netif_rx(skb);
}
diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c
new file mode 100644
index 00000000000..09d270913c5
--- /dev/null
+++ b/drivers/net/bcm63xx_enet.c
@@ -0,0 +1,1971 @@
+/*
+ * Driver for BCM963xx builtin Ethernet mac
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/ethtool.h>
+#include <linux/crc32.h>
+#include <linux/err.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/if_vlan.h>
+
+#include <bcm63xx_dev_enet.h>
+#include "bcm63xx_enet.h"
+
+static char bcm_enet_driver_name[] = "bcm63xx_enet";
+static char bcm_enet_driver_version[] = "1.0";
+
+static int copybreak __read_mostly = 128;
+module_param(copybreak, int, 0);
+MODULE_PARM_DESC(copybreak, "Receive copy threshold");
+
+/* io memory shared between all devices */
+static void __iomem *bcm_enet_shared_base;
+
+/*
+ * io helpers to access mac registers
+ */
+static inline u32 enet_readl(struct bcm_enet_priv *priv, u32 off)
+{
+ return bcm_readl(priv->base + off);
+}
+
+static inline void enet_writel(struct bcm_enet_priv *priv,
+ u32 val, u32 off)
+{
+ bcm_writel(val, priv->base + off);
+}
+
+/*
+ * io helpers to access shared registers
+ */
+static inline u32 enet_dma_readl(struct bcm_enet_priv *priv, u32 off)
+{
+ return bcm_readl(bcm_enet_shared_base + off);
+}
+
+static inline void enet_dma_writel(struct bcm_enet_priv *priv,
+ u32 val, u32 off)
+{
+ bcm_writel(val, bcm_enet_shared_base + off);
+}
+
+/*
+ * write given data into mii register and wait for transfer to end
+ * with timeout (average measured transfer time is 25us)
+ */
+static int do_mdio_op(struct bcm_enet_priv *priv, unsigned int data)
+{
+ int limit;
+
+ /* make sure mii interrupt status is cleared */
+ enet_writel(priv, ENET_IR_MII, ENET_IR_REG);
+
+ enet_writel(priv, data, ENET_MIIDATA_REG);
+ wmb();
+
+ /* busy wait on mii interrupt bit, with timeout */
+ limit = 1000;
+ do {
+ if (enet_readl(priv, ENET_IR_REG) & ENET_IR_MII)
+ break;
+ udelay(1);
+ } while (limit-- >= 0);
+
+ return (limit < 0) ? 1 : 0;
+}
+
+/*
+ * MII internal read callback
+ */
+static int bcm_enet_mdio_read(struct bcm_enet_priv *priv, int mii_id,
+ int regnum)
+{
+ u32 tmp, val;
+
+ tmp = regnum << ENET_MIIDATA_REG_SHIFT;
+ tmp |= 0x2 << ENET_MIIDATA_TA_SHIFT;
+ tmp |= mii_id << ENET_MIIDATA_PHYID_SHIFT;
+ tmp |= ENET_MIIDATA_OP_READ_MASK;
+
+ if (do_mdio_op(priv, tmp))
+ return -1;
+
+ val = enet_readl(priv, ENET_MIIDATA_REG);
+ val &= 0xffff;
+ return val;
+}
+
+/*
+ * MII internal write callback
+ */
+static int bcm_enet_mdio_write(struct bcm_enet_priv *priv, int mii_id,
+ int regnum, u16 value)
+{
+ u32 tmp;
+
+ tmp = (value & 0xffff) << ENET_MIIDATA_DATA_SHIFT;
+ tmp |= 0x2 << ENET_MIIDATA_TA_SHIFT;
+ tmp |= regnum << ENET_MIIDATA_REG_SHIFT;
+ tmp |= mii_id << ENET_MIIDATA_PHYID_SHIFT;
+ tmp |= ENET_MIIDATA_OP_WRITE_MASK;
+
+ (void)do_mdio_op(priv, tmp);
+ return 0;
+}
+
+/*
+ * MII read callback from phylib
+ */
+static int bcm_enet_mdio_read_phylib(struct mii_bus *bus, int mii_id,
+ int regnum)
+{
+ return bcm_enet_mdio_read(bus->priv, mii_id, regnum);
+}
+
+/*
+ * MII write callback from phylib
+ */
+static int bcm_enet_mdio_write_phylib(struct mii_bus *bus, int mii_id,
+ int regnum, u16 value)
+{
+ return bcm_enet_mdio_write(bus->priv, mii_id, regnum, value);
+}
+
+/*
+ * MII read callback from mii core
+ */
+static int bcm_enet_mdio_read_mii(struct net_device *dev, int mii_id,
+ int regnum)
+{
+ return bcm_enet_mdio_read(netdev_priv(dev), mii_id, regnum);
+}
+
+/*
+ * MII write callback from mii core
+ */
+static void bcm_enet_mdio_write_mii(struct net_device *dev, int mii_id,
+ int regnum, int value)
+{
+ bcm_enet_mdio_write(netdev_priv(dev), mii_id, regnum, value);
+}
+
+/*
+ * refill rx queue
+ */
+static int bcm_enet_refill_rx(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+
+ while (priv->rx_desc_count < priv->rx_ring_size) {
+ struct bcm_enet_desc *desc;
+ struct sk_buff *skb;
+ dma_addr_t p;
+ int desc_idx;
+ u32 len_stat;
+
+ desc_idx = priv->rx_dirty_desc;
+ desc = &priv->rx_desc_cpu[desc_idx];
+
+ if (!priv->rx_skb[desc_idx]) {
+ skb = netdev_alloc_skb(dev, priv->rx_skb_size);
+ if (!skb)
+ break;
+ priv->rx_skb[desc_idx] = skb;
+
+ p = dma_map_single(&priv->pdev->dev, skb->data,
+ priv->rx_skb_size,
+ DMA_FROM_DEVICE);
+ desc->address = p;
+ }
+
+ len_stat = priv->rx_skb_size << DMADESC_LENGTH_SHIFT;
+ len_stat |= DMADESC_OWNER_MASK;
+ if (priv->rx_dirty_desc == priv->rx_ring_size - 1) {
+ len_stat |= DMADESC_WRAP_MASK;
+ priv->rx_dirty_desc = 0;
+ } else {
+ priv->rx_dirty_desc++;
+ }
+ wmb();
+ desc->len_stat = len_stat;
+
+ priv->rx_desc_count++;
+
+ /* tell dma engine we allocated one buffer */
+ enet_dma_writel(priv, 1, ENETDMA_BUFALLOC_REG(priv->rx_chan));
+ }
+
+ /* If rx ring is still empty, set a timer to try allocating
+ * again at a later time. */
+ if (priv->rx_desc_count == 0 && netif_running(dev)) {
+ dev_warn(&priv->pdev->dev, "unable to refill rx ring\n");
+ priv->rx_timeout.expires = jiffies + HZ;
+ add_timer(&priv->rx_timeout);
+ }
+
+ return 0;
+}
+
+/*
+ * timer callback to defer refill rx queue in case we're OOM
+ */
+static void bcm_enet_refill_rx_timer(unsigned long data)
+{
+ struct net_device *dev;
+ struct bcm_enet_priv *priv;
+
+ dev = (struct net_device *)data;
+ priv = netdev_priv(dev);
+
+ spin_lock(&priv->rx_lock);
+ bcm_enet_refill_rx((struct net_device *)data);
+ spin_unlock(&priv->rx_lock);
+}
+
+/*
+ * extract packet from rx queue
+ */
+static int bcm_enet_receive_queue(struct net_device *dev, int budget)
+{
+ struct bcm_enet_priv *priv;
+ struct device *kdev;
+ int processed;
+
+ priv = netdev_priv(dev);
+ kdev = &priv->pdev->dev;
+ processed = 0;
+
+ /* don't scan ring further than number of refilled
+ * descriptor */
+ if (budget > priv->rx_desc_count)
+ budget = priv->rx_desc_count;
+
+ do {
+ struct bcm_enet_desc *desc;
+ struct sk_buff *skb;
+ int desc_idx;
+ u32 len_stat;
+ unsigned int len;
+
+ desc_idx = priv->rx_curr_desc;
+ desc = &priv->rx_desc_cpu[desc_idx];
+
+ /* make sure we actually read the descriptor status at
+ * each loop */
+ rmb();
+
+ len_stat = desc->len_stat;
+
+ /* break if dma ownership belongs to hw */
+ if (len_stat & DMADESC_OWNER_MASK)
+ break;
+
+ processed++;
+ priv->rx_curr_desc++;
+ if (priv->rx_curr_desc == priv->rx_ring_size)
+ priv->rx_curr_desc = 0;
+ priv->rx_desc_count--;
+
+ /* if the packet does not have start of packet _and_
+ * end of packet flag set, then just recycle it */
+ if ((len_stat & DMADESC_ESOP_MASK) != DMADESC_ESOP_MASK) {
+ priv->stats.rx_dropped++;
+ continue;
+ }
+
+ /* recycle packet if it's marked as bad */
+ if (unlikely(len_stat & DMADESC_ERR_MASK)) {
+ priv->stats.rx_errors++;
+
+ if (len_stat & DMADESC_OVSIZE_MASK)
+ priv->stats.rx_length_errors++;
+ if (len_stat & DMADESC_CRC_MASK)
+ priv->stats.rx_crc_errors++;
+ if (len_stat & DMADESC_UNDER_MASK)
+ priv->stats.rx_frame_errors++;
+ if (len_stat & DMADESC_OV_MASK)
+ priv->stats.rx_fifo_errors++;
+ continue;
+ }
+
+ /* valid packet */
+ skb = priv->rx_skb[desc_idx];
+ len = (len_stat & DMADESC_LENGTH_MASK) >> DMADESC_LENGTH_SHIFT;
+ /* don't include FCS */
+ len -= 4;
+
+ if (len < copybreak) {
+ struct sk_buff *nskb;
+
+ nskb = netdev_alloc_skb(dev, len + NET_IP_ALIGN);
+ if (!nskb) {
+ /* forget packet, just rearm desc */
+ priv->stats.rx_dropped++;
+ continue;
+ }
+
+ /* since we're copying the data, we can align
+ * them properly */
+ skb_reserve(nskb, NET_IP_ALIGN);
+ dma_sync_single_for_cpu(kdev, desc->address,
+ len, DMA_FROM_DEVICE);
+ memcpy(nskb->data, skb->data, len);
+ dma_sync_single_for_device(kdev, desc->address,
+ len, DMA_FROM_DEVICE);
+ skb = nskb;
+ } else {
+ dma_unmap_single(&priv->pdev->dev, desc->address,
+ priv->rx_skb_size, DMA_FROM_DEVICE);
+ priv->rx_skb[desc_idx] = NULL;
+ }
+
+ skb_put(skb, len);
+ skb->dev = dev;
+ skb->protocol = eth_type_trans(skb, dev);
+ priv->stats.rx_packets++;
+ priv->stats.rx_bytes += len;
+ dev->last_rx = jiffies;
+ netif_receive_skb(skb);
+
+ } while (--budget > 0);
+
+ if (processed || !priv->rx_desc_count) {
+ bcm_enet_refill_rx(dev);
+
+ /* kick rx dma */
+ enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
+ ENETDMA_CHANCFG_REG(priv->rx_chan));
+ }
+
+ return processed;
+}
+
+
+/*
+ * try to or force reclaim of transmitted buffers
+ */
+static int bcm_enet_tx_reclaim(struct net_device *dev, int force)
+{
+ struct bcm_enet_priv *priv;
+ int released;
+
+ priv = netdev_priv(dev);
+ released = 0;
+
+ while (priv->tx_desc_count < priv->tx_ring_size) {
+ struct bcm_enet_desc *desc;
+ struct sk_buff *skb;
+
+ /* We run in a bh and fight against start_xmit, which
+ * is called with bh disabled */
+ spin_lock(&priv->tx_lock);
+
+ desc = &priv->tx_desc_cpu[priv->tx_dirty_desc];
+
+ if (!force && (desc->len_stat & DMADESC_OWNER_MASK)) {
+ spin_unlock(&priv->tx_lock);
+ break;
+ }
+
+ /* ensure other field of the descriptor were not read
+ * before we checked ownership */
+ rmb();
+
+ skb = priv->tx_skb[priv->tx_dirty_desc];
+ priv->tx_skb[priv->tx_dirty_desc] = NULL;
+ dma_unmap_single(&priv->pdev->dev, desc->address, skb->len,
+ DMA_TO_DEVICE);
+
+ priv->tx_dirty_desc++;
+ if (priv->tx_dirty_desc == priv->tx_ring_size)
+ priv->tx_dirty_desc = 0;
+ priv->tx_desc_count++;
+
+ spin_unlock(&priv->tx_lock);
+
+ if (desc->len_stat & DMADESC_UNDER_MASK)
+ priv->stats.tx_errors++;
+
+ dev_kfree_skb(skb);
+ released++;
+ }
+
+ if (netif_queue_stopped(dev) && released)
+ netif_wake_queue(dev);
+
+ return released;
+}
+
+/*
+ * poll func, called by network core
+ */
+static int bcm_enet_poll(struct napi_struct *napi, int budget)
+{
+ struct bcm_enet_priv *priv;
+ struct net_device *dev;
+ int tx_work_done, rx_work_done;
+
+ priv = container_of(napi, struct bcm_enet_priv, napi);
+ dev = priv->net_dev;
+
+ /* ack interrupts */
+ enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+ ENETDMA_IR_REG(priv->rx_chan));
+ enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+ ENETDMA_IR_REG(priv->tx_chan));
+
+ /* reclaim sent skb */
+ tx_work_done = bcm_enet_tx_reclaim(dev, 0);
+
+ spin_lock(&priv->rx_lock);
+ rx_work_done = bcm_enet_receive_queue(dev, budget);
+ spin_unlock(&priv->rx_lock);
+
+ if (rx_work_done >= budget || tx_work_done > 0) {
+ /* rx/tx queue is not yet empty/clean */
+ return rx_work_done;
+ }
+
+ /* no more packet in rx/tx queue, remove device from poll
+ * queue */
+ napi_complete(napi);
+
+ /* restore rx/tx interrupt */
+ enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+ ENETDMA_IRMASK_REG(priv->rx_chan));
+ enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+ ENETDMA_IRMASK_REG(priv->tx_chan));
+
+ return rx_work_done;
+}
+
+/*
+ * mac interrupt handler
+ */
+static irqreturn_t bcm_enet_isr_mac(int irq, void *dev_id)
+{
+ struct net_device *dev;
+ struct bcm_enet_priv *priv;
+ u32 stat;
+
+ dev = dev_id;
+ priv = netdev_priv(dev);
+
+ stat = enet_readl(priv, ENET_IR_REG);
+ if (!(stat & ENET_IR_MIB))
+ return IRQ_NONE;
+
+ /* clear & mask interrupt */
+ enet_writel(priv, ENET_IR_MIB, ENET_IR_REG);
+ enet_writel(priv, 0, ENET_IRMASK_REG);
+
+ /* read mib registers in workqueue */
+ schedule_work(&priv->mib_update_task);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * rx/tx dma interrupt handler
+ */
+static irqreturn_t bcm_enet_isr_dma(int irq, void *dev_id)
+{
+ struct net_device *dev;
+ struct bcm_enet_priv *priv;
+
+ dev = dev_id;
+ priv = netdev_priv(dev);
+
+ /* mask rx/tx interrupts */
+ enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
+ enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
+
+ napi_schedule(&priv->napi);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * tx request callback
+ */
+static int bcm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+ struct bcm_enet_desc *desc;
+ u32 len_stat;
+ int ret;
+
+ priv = netdev_priv(dev);
+
+ /* lock against tx reclaim */
+ spin_lock(&priv->tx_lock);
+
+ /* make sure the tx hw queue is not full, should not happen
+ * since we stop queue before it's the case */
+ if (unlikely(!priv->tx_desc_count)) {
+ netif_stop_queue(dev);
+ dev_err(&priv->pdev->dev, "xmit called with no tx desc "
+ "available?\n");
+ ret = NETDEV_TX_BUSY;
+ goto out_unlock;
+ }
+
+ /* point to the next available desc */
+ desc = &priv->tx_desc_cpu[priv->tx_curr_desc];
+ priv->tx_skb[priv->tx_curr_desc] = skb;
+
+ /* fill descriptor */
+ desc->address = dma_map_single(&priv->pdev->dev, skb->data, skb->len,
+ DMA_TO_DEVICE);
+
+ len_stat = (skb->len << DMADESC_LENGTH_SHIFT) & DMADESC_LENGTH_MASK;
+ len_stat |= DMADESC_ESOP_MASK |
+ DMADESC_APPEND_CRC |
+ DMADESC_OWNER_MASK;
+
+ priv->tx_curr_desc++;
+ if (priv->tx_curr_desc == priv->tx_ring_size) {
+ priv->tx_curr_desc = 0;
+ len_stat |= DMADESC_WRAP_MASK;
+ }
+ priv->tx_desc_count--;
+
+ /* dma might be already polling, make sure we update desc
+ * fields in correct order */
+ wmb();
+ desc->len_stat = len_stat;
+ wmb();
+
+ /* kick tx dma */
+ enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
+ ENETDMA_CHANCFG_REG(priv->tx_chan));
+
+ /* stop queue if no more desc available */
+ if (!priv->tx_desc_count)
+ netif_stop_queue(dev);
+
+ priv->stats.tx_bytes += skb->len;
+ priv->stats.tx_packets++;
+ dev->trans_start = jiffies;
+ ret = NETDEV_TX_OK;
+
+out_unlock:
+ spin_unlock(&priv->tx_lock);
+ return ret;
+}
+
+/*
+ * Change the interface's mac address.
+ */
+static int bcm_enet_set_mac_address(struct net_device *dev, void *p)
+{
+ struct bcm_enet_priv *priv;
+ struct sockaddr *addr = p;
+ u32 val;
+
+ priv = netdev_priv(dev);
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+
+ /* use perfect match register 0 to store my mac address */
+ val = (dev->dev_addr[2] << 24) | (dev->dev_addr[3] << 16) |
+ (dev->dev_addr[4] << 8) | dev->dev_addr[5];
+ enet_writel(priv, val, ENET_PML_REG(0));
+
+ val = (dev->dev_addr[0] << 8 | dev->dev_addr[1]);
+ val |= ENET_PMH_DATAVALID_MASK;
+ enet_writel(priv, val, ENET_PMH_REG(0));
+
+ return 0;
+}
+
+/*
+ * Change rx mode (promiscous/allmulti) and update multicast list
+ */
+static void bcm_enet_set_multicast_list(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+ struct dev_mc_list *mc_list;
+ u32 val;
+ int i;
+
+ priv = netdev_priv(dev);
+
+ val = enet_readl(priv, ENET_RXCFG_REG);
+
+ if (dev->flags & IFF_PROMISC)
+ val |= ENET_RXCFG_PROMISC_MASK;
+ else
+ val &= ~ENET_RXCFG_PROMISC_MASK;
+
+ /* only 3 perfect match registers left, first one is used for
+ * own mac address */
+ if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 3)
+ val |= ENET_RXCFG_ALLMCAST_MASK;
+ else
+ val &= ~ENET_RXCFG_ALLMCAST_MASK;
+
+ /* no need to set perfect match registers if we catch all
+ * multicast */
+ if (val & ENET_RXCFG_ALLMCAST_MASK) {
+ enet_writel(priv, val, ENET_RXCFG_REG);
+ return;
+ }
+
+ for (i = 0, mc_list = dev->mc_list;
+ (mc_list != NULL) && (i < dev->mc_count) && (i < 3);
+ i++, mc_list = mc_list->next) {
+ u8 *dmi_addr;
+ u32 tmp;
+
+ /* filter non ethernet address */
+ if (mc_list->dmi_addrlen != 6)
+ continue;
+
+ /* update perfect match registers */
+ dmi_addr = mc_list->dmi_addr;
+ tmp = (dmi_addr[2] << 24) | (dmi_addr[3] << 16) |
+ (dmi_addr[4] << 8) | dmi_addr[5];
+ enet_writel(priv, tmp, ENET_PML_REG(i + 1));
+
+ tmp = (dmi_addr[0] << 8 | dmi_addr[1]);
+ tmp |= ENET_PMH_DATAVALID_MASK;
+ enet_writel(priv, tmp, ENET_PMH_REG(i + 1));
+ }
+
+ for (; i < 3; i++) {
+ enet_writel(priv, 0, ENET_PML_REG(i + 1));
+ enet_writel(priv, 0, ENET_PMH_REG(i + 1));
+ }
+
+ enet_writel(priv, val, ENET_RXCFG_REG);
+}
+
+/*
+ * set mac duplex parameters
+ */
+static void bcm_enet_set_duplex(struct bcm_enet_priv *priv, int fullduplex)
+{
+ u32 val;
+
+ val = enet_readl(priv, ENET_TXCTL_REG);
+ if (fullduplex)
+ val |= ENET_TXCTL_FD_MASK;
+ else
+ val &= ~ENET_TXCTL_FD_MASK;
+ enet_writel(priv, val, ENET_TXCTL_REG);
+}
+
+/*
+ * set mac flow control parameters
+ */
+static void bcm_enet_set_flow(struct bcm_enet_priv *priv, int rx_en, int tx_en)
+{
+ u32 val;
+
+ /* rx flow control (pause frame handling) */
+ val = enet_readl(priv, ENET_RXCFG_REG);
+ if (rx_en)
+ val |= ENET_RXCFG_ENFLOW_MASK;
+ else
+ val &= ~ENET_RXCFG_ENFLOW_MASK;
+ enet_writel(priv, val, ENET_RXCFG_REG);
+
+ /* tx flow control (pause frame generation) */
+ val = enet_dma_readl(priv, ENETDMA_CFG_REG);
+ if (tx_en)
+ val |= ENETDMA_CFG_FLOWCH_MASK(priv->rx_chan);
+ else
+ val &= ~ENETDMA_CFG_FLOWCH_MASK(priv->rx_chan);
+ enet_dma_writel(priv, val, ENETDMA_CFG_REG);
+}
+
+/*
+ * link changed callback (from phylib)
+ */
+static void bcm_enet_adjust_phy_link(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+ struct phy_device *phydev;
+ int status_changed;
+
+ priv = netdev_priv(dev);
+ phydev = priv->phydev;
+ status_changed = 0;
+
+ if (priv->old_link != phydev->link) {
+ status_changed = 1;
+ priv->old_link = phydev->link;
+ }
+
+ /* reflect duplex change in mac configuration */
+ if (phydev->link && phydev->duplex != priv->old_duplex) {
+ bcm_enet_set_duplex(priv,
+ (phydev->duplex == DUPLEX_FULL) ? 1 : 0);
+ status_changed = 1;
+ priv->old_duplex = phydev->duplex;
+ }
+
+ /* enable flow control if remote advertise it (trust phylib to
+ * check that duplex is full */
+ if (phydev->link && phydev->pause != priv->old_pause) {
+ int rx_pause_en, tx_pause_en;
+
+ if (phydev->pause) {
+ /* pause was advertised by lpa and us */
+ rx_pause_en = 1;
+ tx_pause_en = 1;
+ } else if (!priv->pause_auto) {
+ /* pause setting overrided by user */
+ rx_pause_en = priv->pause_rx;
+ tx_pause_en = priv->pause_tx;
+ } else {
+ rx_pause_en = 0;
+ tx_pause_en = 0;
+ }
+
+ bcm_enet_set_flow(priv, rx_pause_en, tx_pause_en);
+ status_changed = 1;
+ priv->old_pause = phydev->pause;
+ }
+
+ if (status_changed) {
+ pr_info("%s: link %s", dev->name, phydev->link ?
+ "UP" : "DOWN");
+ if (phydev->link)
+ pr_cont(" - %d/%s - flow control %s", phydev->speed,
+ DUPLEX_FULL == phydev->duplex ? "full" : "half",
+ phydev->pause == 1 ? "rx&tx" : "off");
+
+ pr_cont("\n");
+ }
+}
+
+/*
+ * link changed callback (if phylib is not used)
+ */
+static void bcm_enet_adjust_link(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+ bcm_enet_set_duplex(priv, priv->force_duplex_full);
+ bcm_enet_set_flow(priv, priv->pause_rx, priv->pause_tx);
+ netif_carrier_on(dev);
+
+ pr_info("%s: link forced UP - %d/%s - flow control %s/%s\n",
+ dev->name,
+ priv->force_speed_100 ? 100 : 10,
+ priv->force_duplex_full ? "full" : "half",
+ priv->pause_rx ? "rx" : "off",
+ priv->pause_tx ? "tx" : "off");
+}
+
+/*
+ * open callback, allocate dma rings & buffers and start rx operation
+ */
+static int bcm_enet_open(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+ struct sockaddr addr;
+ struct device *kdev;
+ struct phy_device *phydev;
+ int i, ret;
+ unsigned int size;
+ char phy_id[MII_BUS_ID_SIZE + 3];
+ void *p;
+ u32 val;
+
+ priv = netdev_priv(dev);
+ kdev = &priv->pdev->dev;
+
+ if (priv->has_phy) {
+ /* connect to PHY */
+ snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
+ priv->mac_id ? "1" : "0", priv->phy_id);
+
+ phydev = phy_connect(dev, phy_id, &bcm_enet_adjust_phy_link, 0,
+ PHY_INTERFACE_MODE_MII);
+
+ if (IS_ERR(phydev)) {
+ dev_err(kdev, "could not attach to PHY\n");
+ return PTR_ERR(phydev);
+ }
+
+ /* mask with MAC supported features */
+ phydev->supported &= (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_MII);
+ phydev->advertising = phydev->supported;
+
+ if (priv->pause_auto && priv->pause_rx && priv->pause_tx)
+ phydev->advertising |= SUPPORTED_Pause;
+ else
+ phydev->advertising &= ~SUPPORTED_Pause;
+
+ dev_info(kdev, "attached PHY at address %d [%s]\n",
+ phydev->addr, phydev->drv->name);
+
+ priv->old_link = 0;
+ priv->old_duplex = -1;
+ priv->old_pause = -1;
+ priv->phydev = phydev;
+ }
+
+ /* mask all interrupts and request them */
+ enet_writel(priv, 0, ENET_IRMASK_REG);
+ enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
+ enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
+
+ ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev);
+ if (ret)
+ goto out_phy_disconnect;
+
+ ret = request_irq(priv->irq_rx, bcm_enet_isr_dma,
+ IRQF_SAMPLE_RANDOM | IRQF_DISABLED, dev->name, dev);
+ if (ret)
+ goto out_freeirq;
+
+ ret = request_irq(priv->irq_tx, bcm_enet_isr_dma,
+ IRQF_DISABLED, dev->name, dev);
+ if (ret)
+ goto out_freeirq_rx;
+
+ /* initialize perfect match registers */
+ for (i = 0; i < 4; i++) {
+ enet_writel(priv, 0, ENET_PML_REG(i));
+ enet_writel(priv, 0, ENET_PMH_REG(i));
+ }
+
+ /* write device mac address */
+ memcpy(addr.sa_data, dev->dev_addr, ETH_ALEN);
+ bcm_enet_set_mac_address(dev, &addr);
+
+ /* allocate rx dma ring */
+ size = priv->rx_ring_size * sizeof(struct bcm_enet_desc);
+ p = dma_alloc_coherent(kdev, size, &priv->rx_desc_dma, GFP_KERNEL);
+ if (!p) {
+ dev_err(kdev, "cannot allocate rx ring %u\n", size);
+ ret = -ENOMEM;
+ goto out_freeirq_tx;
+ }
+
+ memset(p, 0, size);
+ priv->rx_desc_alloc_size = size;
+ priv->rx_desc_cpu = p;
+
+ /* allocate tx dma ring */
+ size = priv->tx_ring_size * sizeof(struct bcm_enet_desc);
+ p = dma_alloc_coherent(kdev, size, &priv->tx_desc_dma, GFP_KERNEL);
+ if (!p) {
+ dev_err(kdev, "cannot allocate tx ring\n");
+ ret = -ENOMEM;
+ goto out_free_rx_ring;
+ }
+
+ memset(p, 0, size);
+ priv->tx_desc_alloc_size = size;
+ priv->tx_desc_cpu = p;
+
+ priv->tx_skb = kzalloc(sizeof(struct sk_buff *) * priv->tx_ring_size,
+ GFP_KERNEL);
+ if (!priv->tx_skb) {
+ dev_err(kdev, "cannot allocate rx skb queue\n");
+ ret = -ENOMEM;
+ goto out_free_tx_ring;
+ }
+
+ priv->tx_desc_count = priv->tx_ring_size;
+ priv->tx_dirty_desc = 0;
+ priv->tx_curr_desc = 0;
+ spin_lock_init(&priv->tx_lock);
+
+ /* init & fill rx ring with skbs */
+ priv->rx_skb = kzalloc(sizeof(struct sk_buff *) * priv->rx_ring_size,
+ GFP_KERNEL);
+ if (!priv->rx_skb) {
+ dev_err(kdev, "cannot allocate rx skb queue\n");
+ ret = -ENOMEM;
+ goto out_free_tx_skb;
+ }
+
+ priv->rx_desc_count = 0;
+ priv->rx_dirty_desc = 0;
+ priv->rx_curr_desc = 0;
+
+ /* initialize flow control buffer allocation */
+ enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
+ ENETDMA_BUFALLOC_REG(priv->rx_chan));
+
+ if (bcm_enet_refill_rx(dev)) {
+ dev_err(kdev, "cannot allocate rx skb queue\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* write rx & tx ring addresses */
+ enet_dma_writel(priv, priv->rx_desc_dma,
+ ENETDMA_RSTART_REG(priv->rx_chan));
+ enet_dma_writel(priv, priv->tx_desc_dma,
+ ENETDMA_RSTART_REG(priv->tx_chan));
+
+ /* clear remaining state ram for rx & tx channel */
+ enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->rx_chan));
+ enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->tx_chan));
+ enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->rx_chan));
+ enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->tx_chan));
+ enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->rx_chan));
+ enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->tx_chan));
+
+ /* set max rx/tx length */
+ enet_writel(priv, priv->hw_mtu, ENET_RXMAXLEN_REG);
+ enet_writel(priv, priv->hw_mtu, ENET_TXMAXLEN_REG);
+
+ /* set dma maximum burst len */
+ enet_dma_writel(priv, BCMENET_DMA_MAXBURST,
+ ENETDMA_MAXBURST_REG(priv->rx_chan));
+ enet_dma_writel(priv, BCMENET_DMA_MAXBURST,
+ ENETDMA_MAXBURST_REG(priv->tx_chan));
+
+ /* set correct transmit fifo watermark */
+ enet_writel(priv, BCMENET_TX_FIFO_TRESH, ENET_TXWMARK_REG);
+
+ /* set flow control low/high threshold to 1/3 / 2/3 */
+ val = priv->rx_ring_size / 3;
+ enet_dma_writel(priv, val, ENETDMA_FLOWCL_REG(priv->rx_chan));
+ val = (priv->rx_ring_size * 2) / 3;
+ enet_dma_writel(priv, val, ENETDMA_FLOWCH_REG(priv->rx_chan));
+
+ /* all set, enable mac and interrupts, start dma engine and
+ * kick rx dma channel */
+ wmb();
+ enet_writel(priv, ENET_CTL_ENABLE_MASK, ENET_CTL_REG);
+ enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG);
+ enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
+ ENETDMA_CHANCFG_REG(priv->rx_chan));
+
+ /* watch "mib counters about to overflow" interrupt */
+ enet_writel(priv, ENET_IR_MIB, ENET_IR_REG);
+ enet_writel(priv, ENET_IR_MIB, ENET_IRMASK_REG);
+
+ /* watch "packet transferred" interrupt in rx and tx */
+ enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+ ENETDMA_IR_REG(priv->rx_chan));
+ enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+ ENETDMA_IR_REG(priv->tx_chan));
+
+ /* make sure we enable napi before rx interrupt */
+ napi_enable(&priv->napi);
+
+ enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+ ENETDMA_IRMASK_REG(priv->rx_chan));
+ enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+ ENETDMA_IRMASK_REG(priv->tx_chan));
+
+ if (priv->has_phy)
+ phy_start(priv->phydev);
+ else
+ bcm_enet_adjust_link(dev);
+
+ netif_start_queue(dev);
+ return 0;
+
+out:
+ for (i = 0; i < priv->rx_ring_size; i++) {
+ struct bcm_enet_desc *desc;
+
+ if (!priv->rx_skb[i])
+ continue;
+
+ desc = &priv->rx_desc_cpu[i];
+ dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
+ DMA_FROM_DEVICE);
+ kfree_skb(priv->rx_skb[i]);
+ }
+ kfree(priv->rx_skb);
+
+out_free_tx_skb:
+ kfree(priv->tx_skb);
+
+out_free_tx_ring:
+ dma_free_coherent(kdev, priv->tx_desc_alloc_size,
+ priv->tx_desc_cpu, priv->tx_desc_dma);
+
+out_free_rx_ring:
+ dma_free_coherent(kdev, priv->rx_desc_alloc_size,
+ priv->rx_desc_cpu, priv->rx_desc_dma);
+
+out_freeirq_tx:
+ free_irq(priv->irq_tx, dev);
+
+out_freeirq_rx:
+ free_irq(priv->irq_rx, dev);
+
+out_freeirq:
+ free_irq(dev->irq, dev);
+
+out_phy_disconnect:
+ phy_disconnect(priv->phydev);
+
+ return ret;
+}
+
+/*
+ * disable mac
+ */
+static void bcm_enet_disable_mac(struct bcm_enet_priv *priv)
+{
+ int limit;
+ u32 val;
+
+ val = enet_readl(priv, ENET_CTL_REG);
+ val |= ENET_CTL_DISABLE_MASK;
+ enet_writel(priv, val, ENET_CTL_REG);
+
+ limit = 1000;
+ do {
+ u32 val;
+
+ val = enet_readl(priv, ENET_CTL_REG);
+ if (!(val & ENET_CTL_DISABLE_MASK))
+ break;
+ udelay(1);
+ } while (limit--);
+}
+
+/*
+ * disable dma in given channel
+ */
+static void bcm_enet_disable_dma(struct bcm_enet_priv *priv, int chan)
+{
+ int limit;
+
+ enet_dma_writel(priv, 0, ENETDMA_CHANCFG_REG(chan));
+
+ limit = 1000;
+ do {
+ u32 val;
+
+ val = enet_dma_readl(priv, ENETDMA_CHANCFG_REG(chan));
+ if (!(val & ENETDMA_CHANCFG_EN_MASK))
+ break;
+ udelay(1);
+ } while (limit--);
+}
+
+/*
+ * stop callback
+ */
+static int bcm_enet_stop(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+ struct device *kdev;
+ int i;
+
+ priv = netdev_priv(dev);
+ kdev = &priv->pdev->dev;
+
+ netif_stop_queue(dev);
+ napi_disable(&priv->napi);
+ if (priv->has_phy)
+ phy_stop(priv->phydev);
+ del_timer_sync(&priv->rx_timeout);
+
+ /* mask all interrupts */
+ enet_writel(priv, 0, ENET_IRMASK_REG);
+ enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
+ enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
+
+ /* make sure no mib update is scheduled */
+ flush_scheduled_work();
+
+ /* disable dma & mac */
+ bcm_enet_disable_dma(priv, priv->tx_chan);
+ bcm_enet_disable_dma(priv, priv->rx_chan);
+ bcm_enet_disable_mac(priv);
+
+ /* force reclaim of all tx buffers */
+ bcm_enet_tx_reclaim(dev, 1);
+
+ /* free the rx skb ring */
+ for (i = 0; i < priv->rx_ring_size; i++) {
+ struct bcm_enet_desc *desc;
+
+ if (!priv->rx_skb[i])
+ continue;
+
+ desc = &priv->rx_desc_cpu[i];
+ dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
+ DMA_FROM_DEVICE);
+ kfree_skb(priv->rx_skb[i]);
+ }
+
+ /* free remaining allocated memory */
+ kfree(priv->rx_skb);
+ kfree(priv->tx_skb);
+ dma_free_coherent(kdev, priv->rx_desc_alloc_size,
+ priv->rx_desc_cpu, priv->rx_desc_dma);
+ dma_free_coherent(kdev, priv->tx_desc_alloc_size,
+ priv->tx_desc_cpu, priv->tx_desc_dma);
+ free_irq(priv->irq_tx, dev);
+ free_irq(priv->irq_rx, dev);
+ free_irq(dev->irq, dev);
+
+ /* release phy */
+ if (priv->has_phy) {
+ phy_disconnect(priv->phydev);
+ priv->phydev = NULL;
+ }
+
+ return 0;
+}
+
+/*
+ * core request to return device rx/tx stats
+ */
+static struct net_device_stats *bcm_enet_get_stats(struct net_device *dev)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+ return &priv->stats;
+}
+
+/*
+ * ethtool callbacks
+ */
+struct bcm_enet_stats {
+ char stat_string[ETH_GSTRING_LEN];
+ int sizeof_stat;
+ int stat_offset;
+ int mib_reg;
+};
+
+#define GEN_STAT(m) sizeof(((struct bcm_enet_priv *)0)->m), \
+ offsetof(struct bcm_enet_priv, m)
+
+static const struct bcm_enet_stats bcm_enet_gstrings_stats[] = {
+ { "rx_packets", GEN_STAT(stats.rx_packets), -1 },
+ { "tx_packets", GEN_STAT(stats.tx_packets), -1 },
+ { "rx_bytes", GEN_STAT(stats.rx_bytes), -1 },
+ { "tx_bytes", GEN_STAT(stats.tx_bytes), -1 },
+ { "rx_errors", GEN_STAT(stats.rx_errors), -1 },
+ { "tx_errors", GEN_STAT(stats.tx_errors), -1 },
+ { "rx_dropped", GEN_STAT(stats.rx_dropped), -1 },
+ { "tx_dropped", GEN_STAT(stats.tx_dropped), -1 },
+
+ { "rx_good_octets", GEN_STAT(mib.rx_gd_octets), ETH_MIB_RX_GD_OCTETS},
+ { "rx_good_pkts", GEN_STAT(mib.rx_gd_pkts), ETH_MIB_RX_GD_PKTS },
+ { "rx_broadcast", GEN_STAT(mib.rx_brdcast), ETH_MIB_RX_BRDCAST },
+ { "rx_multicast", GEN_STAT(mib.rx_mult), ETH_MIB_RX_MULT },
+ { "rx_64_octets", GEN_STAT(mib.rx_64), ETH_MIB_RX_64 },
+ { "rx_65_127_oct", GEN_STAT(mib.rx_65_127), ETH_MIB_RX_65_127 },
+ { "rx_128_255_oct", GEN_STAT(mib.rx_128_255), ETH_MIB_RX_128_255 },
+ { "rx_256_511_oct", GEN_STAT(mib.rx_256_511), ETH_MIB_RX_256_511 },
+ { "rx_512_1023_oct", GEN_STAT(mib.rx_512_1023), ETH_MIB_RX_512_1023 },
+ { "rx_1024_max_oct", GEN_STAT(mib.rx_1024_max), ETH_MIB_RX_1024_MAX },
+ { "rx_jabber", GEN_STAT(mib.rx_jab), ETH_MIB_RX_JAB },
+ { "rx_oversize", GEN_STAT(mib.rx_ovr), ETH_MIB_RX_OVR },
+ { "rx_fragment", GEN_STAT(mib.rx_frag), ETH_MIB_RX_FRAG },
+ { "rx_dropped", GEN_STAT(mib.rx_drop), ETH_MIB_RX_DROP },
+ { "rx_crc_align", GEN_STAT(mib.rx_crc_align), ETH_MIB_RX_CRC_ALIGN },
+ { "rx_undersize", GEN_STAT(mib.rx_und), ETH_MIB_RX_UND },
+ { "rx_crc", GEN_STAT(mib.rx_crc), ETH_MIB_RX_CRC },
+ { "rx_align", GEN_STAT(mib.rx_align), ETH_MIB_RX_ALIGN },
+ { "rx_symbol_error", GEN_STAT(mib.rx_sym), ETH_MIB_RX_SYM },
+ { "rx_pause", GEN_STAT(mib.rx_pause), ETH_MIB_RX_PAUSE },
+ { "rx_control", GEN_STAT(mib.rx_cntrl), ETH_MIB_RX_CNTRL },
+
+ { "tx_good_octets", GEN_STAT(mib.tx_gd_octets), ETH_MIB_TX_GD_OCTETS },
+ { "tx_good_pkts", GEN_STAT(mib.tx_gd_pkts), ETH_MIB_TX_GD_PKTS },
+ { "tx_broadcast", GEN_STAT(mib.tx_brdcast), ETH_MIB_TX_BRDCAST },
+ { "tx_multicast", GEN_STAT(mib.tx_mult), ETH_MIB_TX_MULT },
+ { "tx_64_oct", GEN_STAT(mib.tx_64), ETH_MIB_TX_64 },
+ { "tx_65_127_oct", GEN_STAT(mib.tx_65_127), ETH_MIB_TX_65_127 },
+ { "tx_128_255_oct", GEN_STAT(mib.tx_128_255), ETH_MIB_TX_128_255 },
+ { "tx_256_511_oct", GEN_STAT(mib.tx_256_511), ETH_MIB_TX_256_511 },
+ { "tx_512_1023_oct", GEN_STAT(mib.tx_512_1023), ETH_MIB_TX_512_1023},
+ { "tx_1024_max_oct", GEN_STAT(mib.tx_1024_max), ETH_MIB_TX_1024_MAX },
+ { "tx_jabber", GEN_STAT(mib.tx_jab), ETH_MIB_TX_JAB },
+ { "tx_oversize", GEN_STAT(mib.tx_ovr), ETH_MIB_TX_OVR },
+ { "tx_fragment", GEN_STAT(mib.tx_frag), ETH_MIB_TX_FRAG },
+ { "tx_underrun", GEN_STAT(mib.tx_underrun), ETH_MIB_TX_UNDERRUN },
+ { "tx_collisions", GEN_STAT(mib.tx_col), ETH_MIB_TX_COL },
+ { "tx_single_collision", GEN_STAT(mib.tx_1_col), ETH_MIB_TX_1_COL },
+ { "tx_multiple_collision", GEN_STAT(mib.tx_m_col), ETH_MIB_TX_M_COL },
+ { "tx_excess_collision", GEN_STAT(mib.tx_ex_col), ETH_MIB_TX_EX_COL },
+ { "tx_late_collision", GEN_STAT(mib.tx_late), ETH_MIB_TX_LATE },
+ { "tx_deferred", GEN_STAT(mib.tx_def), ETH_MIB_TX_DEF },
+ { "tx_carrier_sense", GEN_STAT(mib.tx_crs), ETH_MIB_TX_CRS },
+ { "tx_pause", GEN_STAT(mib.tx_pause), ETH_MIB_TX_PAUSE },
+
+};
+
+#define BCM_ENET_STATS_LEN \
+ (sizeof(bcm_enet_gstrings_stats) / sizeof(struct bcm_enet_stats))
+
+static const u32 unused_mib_regs[] = {
+ ETH_MIB_TX_ALL_OCTETS,
+ ETH_MIB_TX_ALL_PKTS,
+ ETH_MIB_RX_ALL_OCTETS,
+ ETH_MIB_RX_ALL_PKTS,
+};
+
+
+static void bcm_enet_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ strncpy(drvinfo->driver, bcm_enet_driver_name, 32);
+ strncpy(drvinfo->version, bcm_enet_driver_version, 32);
+ strncpy(drvinfo->fw_version, "N/A", 32);
+ strncpy(drvinfo->bus_info, "bcm63xx", 32);
+ drvinfo->n_stats = BCM_ENET_STATS_LEN;
+}
+
+static int bcm_enet_get_stats_count(struct net_device *netdev)
+{
+ return BCM_ENET_STATS_LEN;
+}
+
+static void bcm_enet_get_strings(struct net_device *netdev,
+ u32 stringset, u8 *data)
+{
+ int i;
+
+ switch (stringset) {
+ case ETH_SS_STATS:
+ for (i = 0; i < BCM_ENET_STATS_LEN; i++) {
+ memcpy(data + i * ETH_GSTRING_LEN,
+ bcm_enet_gstrings_stats[i].stat_string,
+ ETH_GSTRING_LEN);
+ }
+ break;
+ }
+}
+
+static void update_mib_counters(struct bcm_enet_priv *priv)
+{
+ int i;
+
+ for (i = 0; i < BCM_ENET_STATS_LEN; i++) {
+ const struct bcm_enet_stats *s;
+ u32 val;
+ char *p;
+
+ s = &bcm_enet_gstrings_stats[i];
+ if (s->mib_reg == -1)
+ continue;
+
+ val = enet_readl(priv, ENET_MIB_REG(s->mib_reg));
+ p = (char *)priv + s->stat_offset;
+
+ if (s->sizeof_stat == sizeof(u64))
+ *(u64 *)p += val;
+ else
+ *(u32 *)p += val;
+ }
+
+ /* also empty unused mib counters to make sure mib counter
+ * overflow interrupt is cleared */
+ for (i = 0; i < ARRAY_SIZE(unused_mib_regs); i++)
+ (void)enet_readl(priv, ENET_MIB_REG(unused_mib_regs[i]));
+}
+
+static void bcm_enet_update_mib_counters_defer(struct work_struct *t)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = container_of(t, struct bcm_enet_priv, mib_update_task);
+ mutex_lock(&priv->mib_update_lock);
+ update_mib_counters(priv);
+ mutex_unlock(&priv->mib_update_lock);
+
+ /* reenable mib interrupt */
+ if (netif_running(priv->net_dev))
+ enet_writel(priv, ENET_IR_MIB, ENET_IRMASK_REG);
+}
+
+static void bcm_enet_get_ethtool_stats(struct net_device *netdev,
+ struct ethtool_stats *stats,
+ u64 *data)
+{
+ struct bcm_enet_priv *priv;
+ int i;
+
+ priv = netdev_priv(netdev);
+
+ mutex_lock(&priv->mib_update_lock);
+ update_mib_counters(priv);
+
+ for (i = 0; i < BCM_ENET_STATS_LEN; i++) {
+ const struct bcm_enet_stats *s;
+ char *p;
+
+ s = &bcm_enet_gstrings_stats[i];
+ p = (char *)priv + s->stat_offset;
+ data[i] = (s->sizeof_stat == sizeof(u64)) ?
+ *(u64 *)p : *(u32 *)p;
+ }
+ mutex_unlock(&priv->mib_update_lock);
+}
+
+static int bcm_enet_get_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+
+ cmd->maxrxpkt = 0;
+ cmd->maxtxpkt = 0;
+
+ if (priv->has_phy) {
+ if (!priv->phydev)
+ return -ENODEV;
+ return phy_ethtool_gset(priv->phydev, cmd);
+ } else {
+ cmd->autoneg = 0;
+ cmd->speed = (priv->force_speed_100) ? SPEED_100 : SPEED_10;
+ cmd->duplex = (priv->force_duplex_full) ?
+ DUPLEX_FULL : DUPLEX_HALF;
+ cmd->supported = ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full;
+ cmd->advertising = 0;
+ cmd->port = PORT_MII;
+ cmd->transceiver = XCVR_EXTERNAL;
+ }
+ return 0;
+}
+
+static int bcm_enet_set_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+ if (priv->has_phy) {
+ if (!priv->phydev)
+ return -ENODEV;
+ return phy_ethtool_sset(priv->phydev, cmd);
+ } else {
+
+ if (cmd->autoneg ||
+ (cmd->speed != SPEED_100 && cmd->speed != SPEED_10) ||
+ cmd->port != PORT_MII)
+ return -EINVAL;
+
+ priv->force_speed_100 = (cmd->speed == SPEED_100) ? 1 : 0;
+ priv->force_duplex_full = (cmd->duplex == DUPLEX_FULL) ? 1 : 0;
+
+ if (netif_running(dev))
+ bcm_enet_adjust_link(dev);
+ return 0;
+ }
+}
+
+static void bcm_enet_get_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ering)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+
+ /* rx/tx ring is actually only limited by memory */
+ ering->rx_max_pending = 8192;
+ ering->tx_max_pending = 8192;
+ ering->rx_mini_max_pending = 0;
+ ering->rx_jumbo_max_pending = 0;
+ ering->rx_pending = priv->rx_ring_size;
+ ering->tx_pending = priv->tx_ring_size;
+}
+
+static int bcm_enet_set_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *ering)
+{
+ struct bcm_enet_priv *priv;
+ int was_running;
+
+ priv = netdev_priv(dev);
+
+ was_running = 0;
+ if (netif_running(dev)) {
+ bcm_enet_stop(dev);
+ was_running = 1;
+ }
+
+ priv->rx_ring_size = ering->rx_pending;
+ priv->tx_ring_size = ering->tx_pending;
+
+ if (was_running) {
+ int err;
+
+ err = bcm_enet_open(dev);
+ if (err)
+ dev_close(dev);
+ else
+ bcm_enet_set_multicast_list(dev);
+ }
+ return 0;
+}
+
+static void bcm_enet_get_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *ecmd)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+ ecmd->autoneg = priv->pause_auto;
+ ecmd->rx_pause = priv->pause_rx;
+ ecmd->tx_pause = priv->pause_tx;
+}
+
+static int bcm_enet_set_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *ecmd)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+
+ if (priv->has_phy) {
+ if (ecmd->autoneg && (ecmd->rx_pause != ecmd->tx_pause)) {
+ /* asymetric pause mode not supported,
+ * actually possible but integrated PHY has RO
+ * asym_pause bit */
+ return -EINVAL;
+ }
+ } else {
+ /* no pause autoneg on direct mii connection */
+ if (ecmd->autoneg)
+ return -EINVAL;
+ }
+
+ priv->pause_auto = ecmd->autoneg;
+ priv->pause_rx = ecmd->rx_pause;
+ priv->pause_tx = ecmd->tx_pause;
+
+ return 0;
+}
+
+static struct ethtool_ops bcm_enet_ethtool_ops = {
+ .get_strings = bcm_enet_get_strings,
+ .get_stats_count = bcm_enet_get_stats_count,
+ .get_ethtool_stats = bcm_enet_get_ethtool_stats,
+ .get_settings = bcm_enet_get_settings,
+ .set_settings = bcm_enet_set_settings,
+ .get_drvinfo = bcm_enet_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+ .get_ringparam = bcm_enet_get_ringparam,
+ .set_ringparam = bcm_enet_set_ringparam,
+ .get_pauseparam = bcm_enet_get_pauseparam,
+ .set_pauseparam = bcm_enet_set_pauseparam,
+};
+
+static int bcm_enet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct bcm_enet_priv *priv;
+
+ priv = netdev_priv(dev);
+ if (priv->has_phy) {
+ if (!priv->phydev)
+ return -ENODEV;
+ return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
+ } else {
+ struct mii_if_info mii;
+
+ mii.dev = dev;
+ mii.mdio_read = bcm_enet_mdio_read_mii;
+ mii.mdio_write = bcm_enet_mdio_write_mii;
+ mii.phy_id = 0;
+ mii.phy_id_mask = 0x3f;
+ mii.reg_num_mask = 0x1f;
+ return generic_mii_ioctl(&mii, if_mii(rq), cmd, NULL);
+ }
+}
+
+/*
+ * calculate actual hardware mtu
+ */
+static int compute_hw_mtu(struct bcm_enet_priv *priv, int mtu)
+{
+ int actual_mtu;
+
+ actual_mtu = mtu;
+
+ /* add ethernet header + vlan tag size */
+ actual_mtu += VLAN_ETH_HLEN;
+
+ if (actual_mtu < 64 || actual_mtu > BCMENET_MAX_MTU)
+ return -EINVAL;
+
+ /*
+ * setup maximum size before we get overflow mark in
+ * descriptor, note that this will not prevent reception of
+ * big frames, they will be split into multiple buffers
+ * anyway
+ */
+ priv->hw_mtu = actual_mtu;
+
+ /*
+ * align rx buffer size to dma burst len, account FCS since
+ * it's appended
+ */
+ priv->rx_skb_size = ALIGN(actual_mtu + ETH_FCS_LEN,
+ BCMENET_DMA_MAXBURST * 4);
+ return 0;
+}
+
+/*
+ * adjust mtu, can't be called while device is running
+ */
+static int bcm_enet_change_mtu(struct net_device *dev, int new_mtu)
+{
+ int ret;
+
+ if (netif_running(dev))
+ return -EBUSY;
+
+ ret = compute_hw_mtu(netdev_priv(dev), new_mtu);
+ if (ret)
+ return ret;
+ dev->mtu = new_mtu;
+ return 0;
+}
+
+/*
+ * preinit hardware to allow mii operation while device is down
+ */
+static void bcm_enet_hw_preinit(struct bcm_enet_priv *priv)
+{
+ u32 val;
+ int limit;
+
+ /* make sure mac is disabled */
+ bcm_enet_disable_mac(priv);
+
+ /* soft reset mac */
+ val = ENET_CTL_SRESET_MASK;
+ enet_writel(priv, val, ENET_CTL_REG);
+ wmb();
+
+ limit = 1000;
+ do {
+ val = enet_readl(priv, ENET_CTL_REG);
+ if (!(val & ENET_CTL_SRESET_MASK))
+ break;
+ udelay(1);
+ } while (limit--);
+
+ /* select correct mii interface */
+ val = enet_readl(priv, ENET_CTL_REG);
+ if (priv->use_external_mii)
+ val |= ENET_CTL_EPHYSEL_MASK;
+ else
+ val &= ~ENET_CTL_EPHYSEL_MASK;
+ enet_writel(priv, val, ENET_CTL_REG);
+
+ /* turn on mdc clock */
+ enet_writel(priv, (0x1f << ENET_MIISC_MDCFREQDIV_SHIFT) |
+ ENET_MIISC_PREAMBLEEN_MASK, ENET_MIISC_REG);
+
+ /* set mib counters to self-clear when read */
+ val = enet_readl(priv, ENET_MIBCTL_REG);
+ val |= ENET_MIBCTL_RDCLEAR_MASK;
+ enet_writel(priv, val, ENET_MIBCTL_REG);
+}
+
+static const struct net_device_ops bcm_enet_ops = {
+ .ndo_open = bcm_enet_open,
+ .ndo_stop = bcm_enet_stop,
+ .ndo_start_xmit = bcm_enet_start_xmit,
+ .ndo_get_stats = bcm_enet_get_stats,
+ .ndo_set_mac_address = bcm_enet_set_mac_address,
+ .ndo_set_multicast_list = bcm_enet_set_multicast_list,
+ .ndo_do_ioctl = bcm_enet_ioctl,
+ .ndo_change_mtu = bcm_enet_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = bcm_enet_netpoll,
+#endif
+};
+
+/*
+ * allocate netdevice, request register memory and register device.
+ */
+static int __devinit bcm_enet_probe(struct platform_device *pdev)
+{
+ struct bcm_enet_priv *priv;
+ struct net_device *dev;
+ struct bcm63xx_enet_platform_data *pd;
+ struct resource *res_mem, *res_irq, *res_irq_rx, *res_irq_tx;
+ struct mii_bus *bus;
+ const char *clk_name;
+ unsigned int iomem_size;
+ int i, ret;
+
+ /* stop if shared driver failed, assume driver->probe will be
+ * called in the same order we register devices (correct ?) */
+ if (!bcm_enet_shared_base)
+ return -ENODEV;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ res_irq_rx = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+ res_irq_tx = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
+ if (!res_mem || !res_irq || !res_irq_rx || !res_irq_tx)
+ return -ENODEV;
+
+ ret = 0;
+ dev = alloc_etherdev(sizeof(*priv));
+ if (!dev)
+ return -ENOMEM;
+ priv = netdev_priv(dev);
+ memset(priv, 0, sizeof(*priv));
+
+ ret = compute_hw_mtu(priv, dev->mtu);
+ if (ret)
+ goto out;
+
+ iomem_size = res_mem->end - res_mem->start + 1;
+ if (!request_mem_region(res_mem->start, iomem_size, "bcm63xx_enet")) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ priv->base = ioremap(res_mem->start, iomem_size);
+ if (priv->base == NULL) {
+ ret = -ENOMEM;
+ goto out_release_mem;
+ }
+ dev->irq = priv->irq = res_irq->start;
+ priv->irq_rx = res_irq_rx->start;
+ priv->irq_tx = res_irq_tx->start;
+ priv->mac_id = pdev->id;
+
+ /* get rx & tx dma channel id for this mac */
+ if (priv->mac_id == 0) {
+ priv->rx_chan = 0;
+ priv->tx_chan = 1;
+ clk_name = "enet0";
+ } else {
+ priv->rx_chan = 2;
+ priv->tx_chan = 3;
+ clk_name = "enet1";
+ }
+
+ priv->mac_clk = clk_get(&pdev->dev, clk_name);
+ if (IS_ERR(priv->mac_clk)) {
+ ret = PTR_ERR(priv->mac_clk);
+ goto out_unmap;
+ }
+ clk_enable(priv->mac_clk);
+
+ /* initialize default and fetch platform data */
+ priv->rx_ring_size = BCMENET_DEF_RX_DESC;
+ priv->tx_ring_size = BCMENET_DEF_TX_DESC;
+
+ pd = pdev->dev.platform_data;
+ if (pd) {
+ memcpy(dev->dev_addr, pd->mac_addr, ETH_ALEN);
+ priv->has_phy = pd->has_phy;
+ priv->phy_id = pd->phy_id;
+ priv->has_phy_interrupt = pd->has_phy_interrupt;
+ priv->phy_interrupt = pd->phy_interrupt;
+ priv->use_external_mii = !pd->use_internal_phy;
+ priv->pause_auto = pd->pause_auto;
+ priv->pause_rx = pd->pause_rx;
+ priv->pause_tx = pd->pause_tx;
+ priv->force_duplex_full = pd->force_duplex_full;
+ priv->force_speed_100 = pd->force_speed_100;
+ }
+
+ if (priv->mac_id == 0 && priv->has_phy && !priv->use_external_mii) {
+ /* using internal PHY, enable clock */
+ priv->phy_clk = clk_get(&pdev->dev, "ephy");
+ if (IS_ERR(priv->phy_clk)) {
+ ret = PTR_ERR(priv->phy_clk);
+ priv->phy_clk = NULL;
+ goto out_put_clk_mac;
+ }
+ clk_enable(priv->phy_clk);
+ }
+
+ /* do minimal hardware init to be able to probe mii bus */
+ bcm_enet_hw_preinit(priv);
+
+ /* MII bus registration */
+ if (priv->has_phy) {
+
+ priv->mii_bus = mdiobus_alloc();
+ if (!priv->mii_bus) {
+ ret = -ENOMEM;
+ goto out_uninit_hw;
+ }
+
+ bus = priv->mii_bus;
+ bus->name = "bcm63xx_enet MII bus";
+ bus->parent = &pdev->dev;
+ bus->priv = priv;
+ bus->read = bcm_enet_mdio_read_phylib;
+ bus->write = bcm_enet_mdio_write_phylib;
+ sprintf(bus->id, "%d", priv->mac_id);
+
+ /* only probe bus where we think the PHY is, because
+ * the mdio read operation return 0 instead of 0xffff
+ * if a slave is not present on hw */
+ bus->phy_mask = ~(1 << priv->phy_id);
+
+ bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+ if (!bus->irq) {
+ ret = -ENOMEM;
+ goto out_free_mdio;
+ }
+
+ if (priv->has_phy_interrupt)
+ bus->irq[priv->phy_id] = priv->phy_interrupt;
+ else
+ bus->irq[priv->phy_id] = PHY_POLL;
+
+ ret = mdiobus_register(bus);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to register mdio bus\n");
+ goto out_free_mdio;
+ }
+ } else {
+
+ /* run platform code to initialize PHY device */
+ if (pd->mii_config &&
+ pd->mii_config(dev, 1, bcm_enet_mdio_read_mii,
+ bcm_enet_mdio_write_mii)) {
+ dev_err(&pdev->dev, "unable to configure mdio bus\n");
+ goto out_uninit_hw;
+ }
+ }
+
+ spin_lock_init(&priv->rx_lock);
+
+ /* init rx timeout (used for oom) */
+ init_timer(&priv->rx_timeout);
+ priv->rx_timeout.function = bcm_enet_refill_rx_timer;
+ priv->rx_timeout.data = (unsigned long)dev;
+
+ /* init the mib update lock&work */
+ mutex_init(&priv->mib_update_lock);
+ INIT_WORK(&priv->mib_update_task, bcm_enet_update_mib_counters_defer);
+
+ /* zero mib counters */
+ for (i = 0; i < ENET_MIB_REG_COUNT; i++)
+ enet_writel(priv, 0, ENET_MIB_REG(i));
+
+ /* register netdevice */
+ dev->netdev_ops = &bcm_enet_ops;
+ netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16);
+
+ SET_ETHTOOL_OPS(dev, &bcm_enet_ethtool_ops);
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ ret = register_netdev(dev);
+ if (ret)
+ goto out_unregister_mdio;
+
+ netif_carrier_off(dev);
+ platform_set_drvdata(pdev, dev);
+ priv->pdev = pdev;
+ priv->net_dev = dev;
+
+ return 0;
+
+out_unregister_mdio:
+ if (priv->mii_bus) {
+ mdiobus_unregister(priv->mii_bus);
+ kfree(priv->mii_bus->irq);
+ }
+
+out_free_mdio:
+ if (priv->mii_bus)
+ mdiobus_free(priv->mii_bus);
+
+out_uninit_hw:
+ /* turn off mdc clock */
+ enet_writel(priv, 0, ENET_MIISC_REG);
+ if (priv->phy_clk) {
+ clk_disable(priv->phy_clk);
+ clk_put(priv->phy_clk);
+ }
+
+out_put_clk_mac:
+ clk_disable(priv->mac_clk);
+ clk_put(priv->mac_clk);
+
+out_unmap:
+ iounmap(priv->base);
+
+out_release_mem:
+ release_mem_region(res_mem->start, iomem_size);
+out:
+ free_netdev(dev);
+ return ret;
+}
+
+
+/*
+ * exit func, stops hardware and unregisters netdevice
+ */
+static int __devexit bcm_enet_remove(struct platform_device *pdev)
+{
+ struct bcm_enet_priv *priv;
+ struct net_device *dev;
+ struct resource *res;
+
+ /* stop netdevice */
+ dev = platform_get_drvdata(pdev);
+ priv = netdev_priv(dev);
+ unregister_netdev(dev);
+
+ /* turn off mdc clock */
+ enet_writel(priv, 0, ENET_MIISC_REG);
+
+ if (priv->has_phy) {
+ mdiobus_unregister(priv->mii_bus);
+ kfree(priv->mii_bus->irq);
+ mdiobus_free(priv->mii_bus);
+ } else {
+ struct bcm63xx_enet_platform_data *pd;
+
+ pd = pdev->dev.platform_data;
+ if (pd && pd->mii_config)
+ pd->mii_config(dev, 0, bcm_enet_mdio_read_mii,
+ bcm_enet_mdio_write_mii);
+ }
+
+ /* release device resources */
+ iounmap(priv->base);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, res->end - res->start + 1);
+
+ /* disable hw block clocks */
+ if (priv->phy_clk) {
+ clk_disable(priv->phy_clk);
+ clk_put(priv->phy_clk);
+ }
+ clk_disable(priv->mac_clk);
+ clk_put(priv->mac_clk);
+
+ platform_set_drvdata(pdev, NULL);
+ free_netdev(dev);
+ return 0;
+}
+
+struct platform_driver bcm63xx_enet_driver = {
+ .probe = bcm_enet_probe,
+ .remove = __devexit_p(bcm_enet_remove),
+ .driver = {
+ .name = "bcm63xx_enet",
+ .owner = THIS_MODULE,
+ },
+};
+
+/*
+ * reserve & remap memory space shared between all macs
+ */
+static int __devinit bcm_enet_shared_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ unsigned int iomem_size;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ iomem_size = res->end - res->start + 1;
+ if (!request_mem_region(res->start, iomem_size, "bcm63xx_enet_dma"))
+ return -EBUSY;
+
+ bcm_enet_shared_base = ioremap(res->start, iomem_size);
+ if (!bcm_enet_shared_base) {
+ release_mem_region(res->start, iomem_size);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static int __devexit bcm_enet_shared_remove(struct platform_device *pdev)
+{
+ struct resource *res;
+
+ iounmap(bcm_enet_shared_base);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, res->end - res->start + 1);
+ return 0;
+}
+
+/*
+ * this "shared" driver is needed because both macs share a single
+ * address space
+ */
+struct platform_driver bcm63xx_enet_shared_driver = {
+ .probe = bcm_enet_shared_probe,
+ .remove = __devexit_p(bcm_enet_shared_remove),
+ .driver = {
+ .name = "bcm63xx_enet_shared",
+ .owner = THIS_MODULE,
+ },
+};
+
+/*
+ * entry point
+ */
+static int __init bcm_enet_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&bcm63xx_enet_shared_driver);
+ if (ret)
+ return ret;
+
+ ret = platform_driver_register(&bcm63xx_enet_driver);
+ if (ret)
+ platform_driver_unregister(&bcm63xx_enet_shared_driver);
+
+ return ret;
+}
+
+static void __exit bcm_enet_exit(void)
+{
+ platform_driver_unregister(&bcm63xx_enet_driver);
+ platform_driver_unregister(&bcm63xx_enet_shared_driver);
+}
+
+
+module_init(bcm_enet_init);
+module_exit(bcm_enet_exit);
+
+MODULE_DESCRIPTION("BCM63xx internal ethernet mac driver");
+MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/bcm63xx_enet.h b/drivers/net/bcm63xx_enet.h
new file mode 100644
index 00000000000..bd3684d42d7
--- /dev/null
+++ b/drivers/net/bcm63xx_enet.h
@@ -0,0 +1,303 @@
+#ifndef BCM63XX_ENET_H_
+#define BCM63XX_ENET_H_
+
+#include <linux/types.h>
+#include <linux/mii.h>
+#include <linux/mutex.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+
+#include <bcm63xx_regs.h>
+#include <bcm63xx_irq.h>
+#include <bcm63xx_io.h>
+
+/* default number of descriptor */
+#define BCMENET_DEF_RX_DESC 64
+#define BCMENET_DEF_TX_DESC 32
+
+/* maximum burst len for dma (4 bytes unit) */
+#define BCMENET_DMA_MAXBURST 16
+
+/* tx transmit threshold (4 bytes unit), fifo is 256 bytes, the value
+ * must be low enough so that a DMA transfer of above burst length can
+ * not overflow the fifo */
+#define BCMENET_TX_FIFO_TRESH 32
+
+/*
+ * hardware maximum rx/tx packet size including FCS, max mtu is
+ * actually 2047, but if we set max rx size register to 2047 we won't
+ * get overflow information if packet size is 2048 or above
+ */
+#define BCMENET_MAX_MTU 2046
+
+/*
+ * rx/tx dma descriptor
+ */
+struct bcm_enet_desc {
+ u32 len_stat;
+ u32 address;
+};
+
+#define DMADESC_LENGTH_SHIFT 16
+#define DMADESC_LENGTH_MASK (0xfff << DMADESC_LENGTH_SHIFT)
+#define DMADESC_OWNER_MASK (1 << 15)
+#define DMADESC_EOP_MASK (1 << 14)
+#define DMADESC_SOP_MASK (1 << 13)
+#define DMADESC_ESOP_MASK (DMADESC_EOP_MASK | DMADESC_SOP_MASK)
+#define DMADESC_WRAP_MASK (1 << 12)
+
+#define DMADESC_UNDER_MASK (1 << 9)
+#define DMADESC_APPEND_CRC (1 << 8)
+#define DMADESC_OVSIZE_MASK (1 << 4)
+#define DMADESC_RXER_MASK (1 << 2)
+#define DMADESC_CRC_MASK (1 << 1)
+#define DMADESC_OV_MASK (1 << 0)
+#define DMADESC_ERR_MASK (DMADESC_UNDER_MASK | \
+ DMADESC_OVSIZE_MASK | \
+ DMADESC_RXER_MASK | \
+ DMADESC_CRC_MASK | \
+ DMADESC_OV_MASK)
+
+
+/*
+ * MIB Counters register definitions
+*/
+#define ETH_MIB_TX_GD_OCTETS 0
+#define ETH_MIB_TX_GD_PKTS 1
+#define ETH_MIB_TX_ALL_OCTETS 2
+#define ETH_MIB_TX_ALL_PKTS 3
+#define ETH_MIB_TX_BRDCAST 4
+#define ETH_MIB_TX_MULT 5
+#define ETH_MIB_TX_64 6
+#define ETH_MIB_TX_65_127 7
+#define ETH_MIB_TX_128_255 8
+#define ETH_MIB_TX_256_511 9
+#define ETH_MIB_TX_512_1023 10
+#define ETH_MIB_TX_1024_MAX 11
+#define ETH_MIB_TX_JAB 12
+#define ETH_MIB_TX_OVR 13
+#define ETH_MIB_TX_FRAG 14
+#define ETH_MIB_TX_UNDERRUN 15
+#define ETH_MIB_TX_COL 16
+#define ETH_MIB_TX_1_COL 17
+#define ETH_MIB_TX_M_COL 18
+#define ETH_MIB_TX_EX_COL 19
+#define ETH_MIB_TX_LATE 20
+#define ETH_MIB_TX_DEF 21
+#define ETH_MIB_TX_CRS 22
+#define ETH_MIB_TX_PAUSE 23
+
+#define ETH_MIB_RX_GD_OCTETS 32
+#define ETH_MIB_RX_GD_PKTS 33
+#define ETH_MIB_RX_ALL_OCTETS 34
+#define ETH_MIB_RX_ALL_PKTS 35
+#define ETH_MIB_RX_BRDCAST 36
+#define ETH_MIB_RX_MULT 37
+#define ETH_MIB_RX_64 38
+#define ETH_MIB_RX_65_127 39
+#define ETH_MIB_RX_128_255 40
+#define ETH_MIB_RX_256_511 41
+#define ETH_MIB_RX_512_1023 42
+#define ETH_MIB_RX_1024_MAX 43
+#define ETH_MIB_RX_JAB 44
+#define ETH_MIB_RX_OVR 45
+#define ETH_MIB_RX_FRAG 46
+#define ETH_MIB_RX_DROP 47
+#define ETH_MIB_RX_CRC_ALIGN 48
+#define ETH_MIB_RX_UND 49
+#define ETH_MIB_RX_CRC 50
+#define ETH_MIB_RX_ALIGN 51
+#define ETH_MIB_RX_SYM 52
+#define ETH_MIB_RX_PAUSE 53
+#define ETH_MIB_RX_CNTRL 54
+
+
+struct bcm_enet_mib_counters {
+ u64 tx_gd_octets;
+ u32 tx_gd_pkts;
+ u32 tx_all_octets;
+ u32 tx_all_pkts;
+ u32 tx_brdcast;
+ u32 tx_mult;
+ u32 tx_64;
+ u32 tx_65_127;
+ u32 tx_128_255;
+ u32 tx_256_511;
+ u32 tx_512_1023;
+ u32 tx_1024_max;
+ u32 tx_jab;
+ u32 tx_ovr;
+ u32 tx_frag;
+ u32 tx_underrun;
+ u32 tx_col;
+ u32 tx_1_col;
+ u32 tx_m_col;
+ u32 tx_ex_col;
+ u32 tx_late;
+ u32 tx_def;
+ u32 tx_crs;
+ u32 tx_pause;
+ u64 rx_gd_octets;
+ u32 rx_gd_pkts;
+ u32 rx_all_octets;
+ u32 rx_all_pkts;
+ u32 rx_brdcast;
+ u32 rx_mult;
+ u32 rx_64;
+ u32 rx_65_127;
+ u32 rx_128_255;
+ u32 rx_256_511;
+ u32 rx_512_1023;
+ u32 rx_1024_max;
+ u32 rx_jab;
+ u32 rx_ovr;
+ u32 rx_frag;
+ u32 rx_drop;
+ u32 rx_crc_align;
+ u32 rx_und;
+ u32 rx_crc;
+ u32 rx_align;
+ u32 rx_sym;
+ u32 rx_pause;
+ u32 rx_cntrl;
+};
+
+
+struct bcm_enet_priv {
+
+ /* mac id (from platform device id) */
+ int mac_id;
+
+ /* base remapped address of device */
+ void __iomem *base;
+
+ /* mac irq, rx_dma irq, tx_dma irq */
+ int irq;
+ int irq_rx;
+ int irq_tx;
+
+ /* hw view of rx & tx dma ring */
+ dma_addr_t rx_desc_dma;
+ dma_addr_t tx_desc_dma;
+
+ /* allocated size (in bytes) for rx & tx dma ring */
+ unsigned int rx_desc_alloc_size;
+ unsigned int tx_desc_alloc_size;
+
+
+ struct napi_struct napi;
+
+ /* dma channel id for rx */
+ int rx_chan;
+
+ /* number of dma desc in rx ring */
+ int rx_ring_size;
+
+ /* cpu view of rx dma ring */
+ struct bcm_enet_desc *rx_desc_cpu;
+
+ /* current number of armed descriptor given to hardware for rx */
+ int rx_desc_count;
+
+ /* next rx descriptor to fetch from hardware */
+ int rx_curr_desc;
+
+ /* next dirty rx descriptor to refill */
+ int rx_dirty_desc;
+
+ /* size of allocated rx skbs */
+ unsigned int rx_skb_size;
+
+ /* list of skb given to hw for rx */
+ struct sk_buff **rx_skb;
+
+ /* used when rx skb allocation failed, so we defer rx queue
+ * refill */
+ struct timer_list rx_timeout;
+
+ /* lock rx_timeout against rx normal operation */
+ spinlock_t rx_lock;
+
+
+ /* dma channel id for tx */
+ int tx_chan;
+
+ /* number of dma desc in tx ring */
+ int tx_ring_size;
+
+ /* cpu view of rx dma ring */
+ struct bcm_enet_desc *tx_desc_cpu;
+
+ /* number of available descriptor for tx */
+ int tx_desc_count;
+
+ /* next tx descriptor avaiable */
+ int tx_curr_desc;
+
+ /* next dirty tx descriptor to reclaim */
+ int tx_dirty_desc;
+
+ /* list of skb given to hw for tx */
+ struct sk_buff **tx_skb;
+
+ /* lock used by tx reclaim and xmit */
+ spinlock_t tx_lock;
+
+
+ /* set if internal phy is ignored and external mii interface
+ * is selected */
+ int use_external_mii;
+
+ /* set if a phy is connected, phy address must be known,
+ * probing is not possible */
+ int has_phy;
+ int phy_id;
+
+ /* set if connected phy has an associated irq */
+ int has_phy_interrupt;
+ int phy_interrupt;
+
+ /* used when a phy is connected (phylib used) */
+ struct mii_bus *mii_bus;
+ struct phy_device *phydev;
+ int old_link;
+ int old_duplex;
+ int old_pause;
+
+ /* used when no phy is connected */
+ int force_speed_100;
+ int force_duplex_full;
+
+ /* pause parameters */
+ int pause_auto;
+ int pause_rx;
+ int pause_tx;
+
+ /* stats */
+ struct net_device_stats stats;
+ struct bcm_enet_mib_counters mib;
+
+ /* after mib interrupt, mib registers update is done in this
+ * work queue */
+ struct work_struct mib_update_task;
+
+ /* lock mib update between userspace request and workqueue */
+ struct mutex mib_update_lock;
+
+ /* mac clock */
+ struct clk *mac_clk;
+
+ /* phy clock if internal phy is used */
+ struct clk *phy_clk;
+
+ /* network device reference */
+ struct net_device *net_dev;
+
+ /* platform device reference */
+ struct platform_device *pdev;
+
+ /* maximum hardware transmit/receive size */
+ unsigned int hw_mtu;
+};
+
+#endif /* ! BCM63XX_ENET_H_ */
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h
index 0695be14cf9..aa76cbada5e 100644
--- a/drivers/net/bnx2x_reg.h
+++ b/drivers/net/bnx2x_reg.h
@@ -3122,7 +3122,7 @@
The fields are:[4:0] - tail pointer; [10:5] - Link List size; 15:11] -
header pointer. */
#define TCM_REG_XX_TABLE 0x50240
-/* [RW 4] Load value for for cfc ac credit cnt. */
+/* [RW 4] Load value for cfc ac credit cnt. */
#define TM_REG_CFC_AC_CRDCNT_VAL 0x164208
/* [RW 4] Load value for cfc cld credit cnt. */
#define TM_REG_CFC_CLD_CRDCNT_VAL 0x164210
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index cea5cfe23b7..c3fa31c9f2a 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -1987,7 +1987,7 @@ void bond_3ad_unbind_slave(struct slave *slave)
// find new aggregator for the related port(s)
new_aggregator = __get_first_agg(port);
for (; new_aggregator; new_aggregator = __get_next_agg(new_aggregator)) {
- // if the new aggregator is empty, or it connected to to our port only
+ // if the new aggregator is empty, or it is connected to our port only
if (!new_aggregator->lag_ports || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator)) {
break;
}
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index cda6b397550..45ac225a7aa 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -3035,7 +3035,7 @@ s32 e1000_check_for_link(struct e1000_hw *hw)
/* If TBI compatibility is was previously off, turn it on. For
* compatibility with a TBI link partner, we will store bad
* packets. Some frames have an additional byte on the end and
- * will look like CRC errors to to the hardware.
+ * will look like CRC errors to the hardware.
*/
if (!hw->tbi_compatibility_on) {
hw->tbi_compatibility_on = true;
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index 3747457f5e6..bc7c5b7abb8 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -751,7 +751,7 @@ int ehea_create_busmap(void)
mutex_lock(&ehea_busmap_mutex);
ehea_mr_len = 0;
- ret = walk_memory_resource(0, 1ULL << MAX_PHYSMEM_BITS, NULL,
+ ret = walk_system_ram_range(0, 1ULL << MAX_PHYSMEM_BITS, NULL,
ehea_create_busmap_callback);
mutex_unlock(&ehea_busmap_mutex);
return ret;
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c
index 117fc6c12e3..66813c91a72 100644
--- a/drivers/net/enc28j60.c
+++ b/drivers/net/enc28j60.c
@@ -1666,3 +1666,4 @@ MODULE_AUTHOR("Claudio Lanconelli <lanconelli.claudio@eptar.com>");
MODULE_LICENSE("GPL");
module_param_named(debug, debug.msg_enable, int, 0);
MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., ffff=all)");
+MODULE_ALIAS("spi:" DRV_NAME);
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index b47201874d8..29234380e6c 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1154,19 +1154,9 @@ static void __inline__ fec_request_mii_intr(struct net_device *dev)
printk("FEC: Could not allocate fec(MII) IRQ(66)!\n");
}
-static void __inline__ fec_disable_phy_intr(void)
+static void __inline__ fec_disable_phy_intr(struct net_device *dev)
{
- volatile unsigned long *icrp;
- icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
- *icrp = 0x08000000;
-}
-
-static void __inline__ fec_phy_ack_intr(void)
-{
- volatile unsigned long *icrp;
- /* Acknowledge the interrupt */
- icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
- *icrp = 0x0d000000;
+ free_irq(66, dev);
}
#endif
@@ -1398,7 +1388,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
writel(0, fep->hwp + FEC_MII_SPEED);
fep->phy_speed = 0;
#ifdef HAVE_mii_link_interrupt
- fec_disable_phy_intr();
+ fec_disable_phy_intr(dev);
#endif
}
}
@@ -1411,8 +1401,6 @@ mii_link_interrupt(int irq, void * dev_id)
struct net_device *dev = dev_id;
struct fec_enet_private *fep = netdev_priv(dev);
- fec_phy_ack_intr();
-
mii_do_cmd(dev, fep->phy->ack_int);
mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 2234118eedb..6c144b525b4 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -293,7 +293,7 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
rxtime = get_ictt_value(priv->rxic);
rxcount = get_icft_value(priv->rxic);
txtime = get_ictt_value(priv->txic);
- txcount = get_icft_value(priv->txic);;
+ txcount = get_icft_value(priv->txic);
cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, rxtime);
cvals->rx_max_coalesced_frames = rxcount;
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 1d7d7fef414..89c82c5e63e 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -2556,13 +2556,13 @@ static int __devinit emac_init_config(struct emac_instance *dev)
if (emac_read_uint_prop(np, "mdio-device", &dev->mdio_ph, 0))
dev->mdio_ph = 0;
if (emac_read_uint_prop(np, "zmii-device", &dev->zmii_ph, 0))
- dev->zmii_ph = 0;;
+ dev->zmii_ph = 0;
if (emac_read_uint_prop(np, "zmii-channel", &dev->zmii_port, 0))
- dev->zmii_port = 0xffffffff;;
+ dev->zmii_port = 0xffffffff;
if (emac_read_uint_prop(np, "rgmii-device", &dev->rgmii_ph, 0))
- dev->rgmii_ph = 0;;
+ dev->rgmii_ph = 0;
if (emac_read_uint_prop(np, "rgmii-channel", &dev->rgmii_port, 0))
- dev->rgmii_port = 0xffffffff;;
+ dev->rgmii_port = 0xffffffff;
if (emac_read_uint_prop(np, "fifo-entry-size", &dev->fifo_entry_size, 0))
dev->fifo_entry_size = 16;
if (emac_read_uint_prop(np, "mal-burst-size", &dev->mal_burst_size, 0))
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index d2639c4a086..5d6c1530a8c 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3966,7 +3966,7 @@ static int igb_set_vf_multicasts(struct igb_adapter *adapter,
/* VFs are limited to using the MTA hash table for their multicast
* addresses */
for (i = 0; i < n; i++)
- vf_data->vf_mc_hashes[i] = hash_list[i];;
+ vf_data->vf_mc_hashes[i] = hash_list[i];
/* Flush and reset the mta with the new values */
igb_set_rx_mode(adapter->netdev);
diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c
index 547ac7c7479..23783586435 100644
--- a/drivers/net/ks8851.c
+++ b/drivers/net/ks8851.c
@@ -1321,3 +1321,4 @@ MODULE_LICENSE("GPL");
module_param_named(message, msg_enable, int, 0);
MODULE_PARM_DESC(message, "Message verbosity level (0=none, 31=all)");
+MODULE_ALIAS("spi:ks8851");
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c
index da8d0a0ca94..f2a197fd47a 100644
--- a/drivers/net/ll_temac_main.c
+++ b/drivers/net/ll_temac_main.c
@@ -865,7 +865,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)
dcrs = dcr_resource_start(np, 0);
if (dcrs == 0) {
dev_err(&op->dev, "could not get DMA register address\n");
- goto nodev;;
+ goto nodev;
}
lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0));
dev_dbg(&op->dev, "DCR base: %x\n", dcrs);
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index fb65b427c69..1d0d4d9ab62 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -241,7 +241,7 @@ static int macb_mii_init(struct macb *bp)
struct eth_platform_data *pdata;
int err = -ENXIO, i;
- /* Enable managment port */
+ /* Enable management port */
macb_writel(bp, NCR, MACB_BIT(MPE));
bp->mii_bus = mdiobus_alloc();
diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c
index bd0ac690d12..aad3b370c56 100644
--- a/drivers/net/ni52.c
+++ b/drivers/net/ni52.c
@@ -615,10 +615,10 @@ static int init586(struct net_device *dev)
/* addr_len |!src_insert |pre-len |loopback */
writeb(0x2e, &cfg_cmd->adr_len);
writeb(0x00, &cfg_cmd->priority);
- writeb(0x60, &cfg_cmd->ifs);;
+ writeb(0x60, &cfg_cmd->ifs);
writeb(0x00, &cfg_cmd->time_low);
writeb(0xf2, &cfg_cmd->time_high);
- writeb(0x00, &cfg_cmd->promisc);;
+ writeb(0x00, &cfg_cmd->promisc);
if (dev->flags & IFF_ALLMULTI) {
int len = ((char __iomem *)p->iscp - (char __iomem *)ptr - 8) / 6;
if (num_addrs > len) {
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 76cc2614f48..f9364d0678f 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -5615,7 +5615,7 @@ static void niu_init_tx_mac(struct niu *np)
/* The XMAC_MIN register only accepts values for TX min which
* have the low 3 bits cleared.
*/
- BUILD_BUG_ON(min & 0x7);
+ BUG_ON(min & 0x7);
if (np->flags & NIU_FLAGS_XMAC)
niu_init_tx_xmac(np, min, max);
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 22052925782..7783c5db81d 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -2630,7 +2630,7 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
FLAGS_LI; /* Load irq delay values */
if (rx_ring->lbq_len) {
cqicb->flags |= FLAGS_LL; /* Load lbq values */
- tmp = (u64)rx_ring->lbq_base_dma;;
+ tmp = (u64)rx_ring->lbq_base_dma;
base_indirect_ptr = (__le64 *) rx_ring->lbq_base_indirect;
page_entries = 0;
do {
@@ -2654,7 +2654,7 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
}
if (rx_ring->sbq_len) {
cqicb->flags |= FLAGS_LS; /* Load sbq values */
- tmp = (u64)rx_ring->sbq_base_dma;;
+ tmp = (u64)rx_ring->sbq_base_dma;
base_indirect_ptr = (__le64 *) rx_ring->sbq_base_indirect;
page_entries = 0;
do {
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index bc98e7f69ee..ede937ee50c 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -72,7 +72,7 @@ static int rionet_check = 0;
static int rionet_capable = 1;
/*
- * This is a fast lookup table for for translating TX
+ * This is a fast lookup table for translating TX
* Ethernet packets into a destination RIO device. It
* could be made into a hash table to save memory depending
* on system trade-offs.
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 07a7e4b8f8f..cc4b2f99989 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -884,13 +884,12 @@ static int efx_wanted_rx_queues(void)
int count;
int cpu;
- if (unlikely(!alloc_cpumask_var(&core_mask, GFP_KERNEL))) {
+ if (unlikely(!zalloc_cpumask_var(&core_mask, GFP_KERNEL))) {
printk(KERN_WARNING
"sfc: RSS disabled due to allocation failure\n");
return 1;
}
- cpumask_clear(core_mask);
count = 0;
for_each_online_cpu(cpu) {
if (!cpumask_test_cpu(cpu, core_mask)) {
diff --git a/drivers/net/skfp/pcmplc.c b/drivers/net/skfp/pcmplc.c
index f1df2ec8ad4..e6b33ee05ed 100644
--- a/drivers/net/skfp/pcmplc.c
+++ b/drivers/net/skfp/pcmplc.c
@@ -960,7 +960,7 @@ static void pcm_fsm(struct s_smc *smc, struct s_phy *phy, int cmd)
/*PC88b*/
if (!phy->cf_join) {
phy->cf_join = TRUE ;
- queue_event(smc,EVENT_CFM,CF_JOIN+np) ; ;
+ queue_event(smc,EVENT_CFM,CF_JOIN+np) ;
}
if (cmd == PC_JOIN)
GO_STATE(PC8_ACTIVE) ;
diff --git a/drivers/net/skfp/pmf.c b/drivers/net/skfp/pmf.c
index 79e665e0853..a320fdb3727 100644
--- a/drivers/net/skfp/pmf.c
+++ b/drivers/net/skfp/pmf.c
@@ -807,9 +807,9 @@ void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para,
mib_p->fddiPORTLerFlag ;
sp->p4050_pad = 0 ;
sp->p4050_cutoff =
- mib_p->fddiPORTLer_Cutoff ; ;
+ mib_p->fddiPORTLer_Cutoff ;
sp->p4050_alarm =
- mib_p->fddiPORTLer_Alarm ; ;
+ mib_p->fddiPORTLer_Alarm ;
sp->p4050_estimate =
mib_p->fddiPORTLer_Estimate ;
sp->p4050_reject_ct =
@@ -829,7 +829,7 @@ void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para,
sp->p4051_porttype =
mib_p->fddiPORTMy_Type ;
sp->p4051_connectstate =
- mib_p->fddiPORTConnectState ; ;
+ mib_p->fddiPORTConnectState ;
sp->p4051_pc_neighbor =
mib_p->fddiPORTNeighborType ;
sp->p4051_pc_withhold =
@@ -853,7 +853,7 @@ void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para,
struct smt_p_4053 *sp ;
sp = (struct smt_p_4053 *) to ;
sp->p4053_multiple =
- mib_p->fddiPORTMultiple_P ; ;
+ mib_p->fddiPORTMultiple_P ;
sp->p4053_availablepaths =
mib_p->fddiPORTAvailablePaths ;
sp->p4053_currentpath =
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 62e852e21ab..55bad408196 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -215,7 +215,7 @@ static void skge_wol_init(struct skge_port *skge)
if (skge->wol & WAKE_MAGIC)
ctrl |= WOL_CTL_ENA_PME_ON_MAGIC_PKT|WOL_CTL_ENA_MAGIC_PKT_UNIT;
else
- ctrl |= WOL_CTL_DIS_PME_ON_MAGIC_PKT|WOL_CTL_DIS_MAGIC_PKT_UNIT;;
+ ctrl |= WOL_CTL_DIS_PME_ON_MAGIC_PKT|WOL_CTL_DIS_MAGIC_PKT_UNIT;
ctrl |= WOL_CTL_DIS_PME_ON_PATTERN|WOL_CTL_DIS_PATTERN_UNIT;
skge_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), ctrl);
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 68d256b9638..ef1165718dd 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -765,7 +765,7 @@ static void sky2_wol_init(struct sky2_port *sky2)
if (sky2->wol & WAKE_MAGIC)
ctrl |= WOL_CTL_ENA_PME_ON_MAGIC_PKT|WOL_CTL_ENA_MAGIC_PKT_UNIT;
else
- ctrl |= WOL_CTL_DIS_PME_ON_MAGIC_PKT|WOL_CTL_DIS_MAGIC_PKT_UNIT;;
+ ctrl |= WOL_CTL_DIS_PME_ON_MAGIC_PKT|WOL_CTL_DIS_MAGIC_PKT_UNIT;
ctrl |= WOL_CTL_DIS_PME_ON_PATTERN|WOL_CTL_DIS_PATTERN_UNIT;
sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), ctrl);
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 26f6ee93a06..e17c535a577 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -616,6 +616,14 @@ static void sl_uninit(struct net_device *dev)
sl_free_bufs(sl);
}
+/* Hook the destructor so we can free slip devices at the right point in time */
+static void sl_free_netdev(struct net_device *dev)
+{
+ int i = dev->base_addr;
+ free_netdev(dev);
+ slip_devs[i] = NULL;
+}
+
static const struct net_device_ops sl_netdev_ops = {
.ndo_init = sl_init,
.ndo_uninit = sl_uninit,
@@ -634,7 +642,7 @@ static const struct net_device_ops sl_netdev_ops = {
static void sl_setup(struct net_device *dev)
{
dev->netdev_ops = &sl_netdev_ops;
- dev->destructor = free_netdev;
+ dev->destructor = sl_free_netdev;
dev->hard_header_len = 0;
dev->addr_len = 0;
@@ -712,8 +720,6 @@ static void sl_sync(void)
static struct slip *sl_alloc(dev_t line)
{
int i;
- int sel = -1;
- int score = -1;
struct net_device *dev = NULL;
struct slip *sl;
@@ -724,55 +730,7 @@ static struct slip *sl_alloc(dev_t line)
dev = slip_devs[i];
if (dev == NULL)
break;
-
- sl = netdev_priv(dev);
- if (sl->leased) {
- if (sl->line != line)
- continue;
- if (sl->tty)
- return NULL;
-
- /* Clear ESCAPE & ERROR flags */
- sl->flags &= (1 << SLF_INUSE);
- return sl;
- }
-
- if (sl->tty)
- continue;
-
- if (current->pid == sl->pid) {
- if (sl->line == line && score < 3) {
- sel = i;
- score = 3;
- continue;
- }
- if (score < 2) {
- sel = i;
- score = 2;
- }
- continue;
- }
- if (sl->line == line && score < 1) {
- sel = i;
- score = 1;
- continue;
- }
- if (score < 0) {
- sel = i;
- score = 0;
- }
- }
-
- if (sel >= 0) {
- i = sel;
- dev = slip_devs[i];
- if (score > 1) {
- sl = netdev_priv(dev);
- sl->flags &= (1 << SLF_INUSE);
- return sl;
- }
}
-
/* Sorry, too many, all slots in use */
if (i >= slip_maxdev)
return NULL;
@@ -909,30 +867,13 @@ err_exit:
}
/*
-
- FIXME: 1,2 are fixed 3 was never true anyway.
-
- Let me to blame a bit.
- 1. TTY module calls this funstion on soft interrupt.
- 2. TTY module calls this function WITH MASKED INTERRUPTS!
- 3. TTY module does not notify us about line discipline
- shutdown,
-
- Seems, now it is clean. The solution is to consider netdevice and
- line discipline sides as two independent threads.
-
- By-product (not desired): sl? does not feel hangups and remains open.
- It is supposed, that user level program (dip, diald, slattach...)
- will catch SIGHUP and make the rest of work.
-
- I see no way to make more with current tty code. --ANK
- */
-
-/*
* Close down a SLIP channel.
* This means flushing out any pending queues, and then returning. This
* call is serialized against other ldisc functions.
+ *
+ * We also use this method fo a hangup event
*/
+
static void slip_close(struct tty_struct *tty)
{
struct slip *sl = tty->disc_data;
@@ -951,10 +892,16 @@ static void slip_close(struct tty_struct *tty)
del_timer_sync(&sl->keepalive_timer);
del_timer_sync(&sl->outfill_timer);
#endif
-
- /* Count references from TTY module */
+ /* Flush network side */
+ unregister_netdev(sl->dev);
+ /* This will complete via sl_free_netdev */
}
+static int slip_hangup(struct tty_struct *tty)
+{
+ slip_close(tty);
+ return 0;
+}
/************************************************************************
* STANDARD SLIP ENCAPSULATION *
************************************************************************/
@@ -1311,6 +1258,7 @@ static struct tty_ldisc_ops sl_ldisc = {
.name = "slip",
.open = slip_open,
.close = slip_close,
+ .hangup = slip_hangup,
.ioctl = slip_ioctl,
.receive_buf = slip_receive_buf,
.write_wakeup = slip_write_wakeup,
@@ -1384,6 +1332,8 @@ static void __exit slip_exit(void)
}
} while (busy && time_before(jiffies, timeout));
+ /* FIXME: hangup is async so we should wait when doing this second
+ phase */
for (i = 0; i < slip_maxdev; i++) {
dev = slip_devs[i];
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 61be6d7680f..05c91ee6921 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -35,7 +35,7 @@
*
* contributors:
* Daris A Nevil <dnevil@snmc.com>
- * Nicolas Pitre <nico@cam.org>
+ * Nicolas Pitre <nico@fluxnic.net>
* Russell King <rmk@arm.linux.org.uk>
*
* History:
@@ -58,7 +58,7 @@
* 22/09/04 Nicolas Pitre big update (see commit log for details)
*/
static const char version[] =
- "smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <nico@cam.org>\n";
+ "smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <nico@fluxnic.net>\n";
/* Debugging level */
#ifndef SMC_DEBUG
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 9c8c6ed4a3c..3911be7c0cb 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -28,7 +28,7 @@
. Authors
. Erik Stahlman <erik@vt.edu>
. Daris A Nevil <dnevil@snmc.com>
- . Nicolas Pitre <nico@cam.org>
+ . Nicolas Pitre <nico@fluxnic.net>
.
---------------------------------------------------------------------------*/
#ifndef _SMC91X_H_
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index e091756166a..4fdfa2ae541 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1368,7 +1368,7 @@ static const struct file_operations tun_fops = {
static struct miscdevice tun_miscdev = {
.minor = TUN_MINOR,
.name = "tun",
- .devnode = "net/tun",
+ .nodename = "net/tun",
.fops = &tun_fops,
};
diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c
index 45cebfb302c..23300656c26 100644
--- a/drivers/net/usb/cdc_eem.c
+++ b/drivers/net/usb/cdc_eem.c
@@ -300,20 +300,23 @@ static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
return 0;
}
- crc = get_unaligned_le32(skb2->data
- + len - ETH_FCS_LEN);
- skb_trim(skb2, len - ETH_FCS_LEN);
-
/*
* The bmCRC helps to denote when the CRC field in
* the Ethernet frame contains a calculated CRC:
* bmCRC = 1 : CRC is calculated
* bmCRC = 0 : CRC = 0xDEADBEEF
*/
- if (header & BIT(14))
- crc2 = ~crc32_le(~0, skb2->data, skb2->len);
- else
+ if (header & BIT(14)) {
+ crc = get_unaligned_le32(skb2->data
+ + len - ETH_FCS_LEN);
+ crc2 = ~crc32_le(~0, skb2->data, skb2->len
+ - ETH_FCS_LEN);
+ } else {
+ crc = get_unaligned_be32(skb2->data
+ + len - ETH_FCS_LEN);
crc2 = 0xdeadbeef;
+ }
+ skb_trim(skb2, len - ETH_FCS_LEN);
if (is_last)
return crc == crc2;
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 32266fb89c2..5c498d2b043 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -22,6 +22,7 @@
#include <linux/ethtool.h>
#include <linux/module.h>
#include <linux/virtio.h>
+#include <linux/virtio_ids.h>
#include <linux/virtio_net.h>
#include <linux/scatterlist.h>
#include <linux/if_vlan.h>
@@ -320,7 +321,7 @@ static bool try_fill_recv_maxbufs(struct virtnet_info *vi, gfp_t gfp)
skb_queue_head(&vi->recv, skb);
err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb);
- if (err) {
+ if (err < 0) {
skb_unlink(skb, &vi->recv);
trim_pages(vi, skb);
kfree_skb(skb);
@@ -373,7 +374,7 @@ static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
skb_queue_head(&vi->recv, skb);
err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, 1, skb);
- if (err) {
+ if (err < 0) {
skb_unlink(skb, &vi->recv);
kfree_skb(skb);
break;
@@ -527,7 +528,7 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1;
err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb);
- if (!err && !vi->free_in_tasklet)
+ if (err >= 0 && !vi->free_in_tasklet)
mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10));
return err;
@@ -538,7 +539,7 @@ static void xmit_tasklet(unsigned long data)
struct virtnet_info *vi = (void *)data;
netif_tx_lock_bh(vi->dev);
- if (vi->last_xmit_skb && xmit_skb(vi, vi->last_xmit_skb) == 0) {
+ if (vi->last_xmit_skb && xmit_skb(vi, vi->last_xmit_skb) >= 0) {
vi->svq->vq_ops->kick(vi->svq);
vi->last_xmit_skb = NULL;
}
@@ -557,7 +558,7 @@ again:
/* If we has a buffer left over from last time, send it now. */
if (unlikely(vi->last_xmit_skb) &&
- xmit_skb(vi, vi->last_xmit_skb) != 0)
+ xmit_skb(vi, vi->last_xmit_skb) < 0)
goto stop_queue;
vi->last_xmit_skb = NULL;
@@ -565,7 +566,7 @@ again:
/* Put new one in send queue and do transmit */
if (likely(skb)) {
__skb_queue_head(&vi->send, skb);
- if (xmit_skb(vi, skb) != 0) {
+ if (xmit_skb(vi, skb) < 0) {
vi->last_xmit_skb = skb;
skb = NULL;
goto stop_queue;
@@ -668,7 +669,7 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
sg_set_buf(&sg[i + 1], sg_virt(s), s->length);
sg_set_buf(&sg[out + in - 1], &status, sizeof(status));
- BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi));
+ BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi) < 0);
vi->cvq->vq_ops->kick(vi->cvq);
diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h
index 62779a520ca..3e94f0ce090 100644
--- a/drivers/net/vxge/vxge-config.h
+++ b/drivers/net/vxge/vxge-config.h
@@ -1541,7 +1541,7 @@ void vxge_hw_ring_rxd_1b_info_get(
rxd_info->l4_cksum_valid =
(u32)VXGE_HW_RING_RXD_L4_CKSUM_CORRECT_GET(rxdp->control_0);
rxd_info->l4_cksum =
- (u32)VXGE_HW_RING_RXD_L4_CKSUM_GET(rxdp->control_0);;
+ (u32)VXGE_HW_RING_RXD_L4_CKSUM_GET(rxdp->control_0);
rxd_info->frame =
(u32)VXGE_HW_RING_RXD_ETHER_ENCAP_GET(rxdp->control_0);
rxd_info->proto =
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index b378037a29b..068d7a9d3e3 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -2350,7 +2350,7 @@ static int vxge_enable_msix(struct vxgedev *vdev)
enum vxge_hw_status status;
/* 0 - Tx, 1 - Rx */
int tim_msix_id[4];
- int alarm_msix_id = 0, msix_intr_vect = 0;;
+ int alarm_msix_id = 0, msix_intr_vect = 0;
vdev->intr_cnt = 0;
/* allocate msix vectors */
diff --git a/drivers/net/wireless/arlan-proc.c b/drivers/net/wireless/arlan-proc.c
index 2ab1d59870f..a8b689635a3 100644
--- a/drivers/net/wireless/arlan-proc.c
+++ b/drivers/net/wireless/arlan-proc.c
@@ -402,7 +402,7 @@ static int arlan_setup_card_by_book(struct net_device *dev)
static char arlan_drive_info[ARLAN_STR_SIZE] = "A655\n\0";
-static int arlan_sysctl_info(ctl_table * ctl, int write, struct file *filp,
+static int arlan_sysctl_info(ctl_table * ctl, int write,
void __user *buffer, size_t * lenp, loff_t *ppos)
{
int i;
@@ -629,7 +629,7 @@ final:
*lenp = pos;
if (!write)
- retv = proc_dostring(ctl, write, filp, buffer, lenp, ppos);
+ retv = proc_dostring(ctl, write, buffer, lenp, ppos);
else
{
*lenp = 0;
@@ -639,7 +639,7 @@ final:
}
-static int arlan_sysctl_info161719(ctl_table * ctl, int write, struct file *filp,
+static int arlan_sysctl_info161719(ctl_table * ctl, int write,
void __user *buffer, size_t * lenp, loff_t *ppos)
{
int i;
@@ -669,11 +669,11 @@ static int arlan_sysctl_info161719(ctl_table * ctl, int write, struct file *filp
final:
*lenp = pos;
- retv = proc_dostring(ctl, write, filp, buffer, lenp, ppos);
+ retv = proc_dostring(ctl, write, buffer, lenp, ppos);
return retv;
}
-static int arlan_sysctl_infotxRing(ctl_table * ctl, int write, struct file *filp,
+static int arlan_sysctl_infotxRing(ctl_table * ctl, int write,
void __user *buffer, size_t * lenp, loff_t *ppos)
{
int i;
@@ -698,11 +698,11 @@ static int arlan_sysctl_infotxRing(ctl_table * ctl, int write, struct file *filp
SARLBNpln(u_char, txBuffer, 0x800);
final:
*lenp = pos;
- retv = proc_dostring(ctl, write, filp, buffer, lenp, ppos);
+ retv = proc_dostring(ctl, write, buffer, lenp, ppos);
return retv;
}
-static int arlan_sysctl_inforxRing(ctl_table * ctl, int write, struct file *filp,
+static int arlan_sysctl_inforxRing(ctl_table * ctl, int write,
void __user *buffer, size_t * lenp, loff_t *ppos)
{
int i;
@@ -726,11 +726,11 @@ static int arlan_sysctl_inforxRing(ctl_table * ctl, int write, struct file *filp
SARLBNpln(u_char, rxBuffer, 0x800);
final:
*lenp = pos;
- retv = proc_dostring(ctl, write, filp, buffer, lenp, ppos);
+ retv = proc_dostring(ctl, write, buffer, lenp, ppos);
return retv;
}
-static int arlan_sysctl_info18(ctl_table * ctl, int write, struct file *filp,
+static int arlan_sysctl_info18(ctl_table * ctl, int write,
void __user *buffer, size_t * lenp, loff_t *ppos)
{
int i;
@@ -756,7 +756,7 @@ static int arlan_sysctl_info18(ctl_table * ctl, int write, struct file *filp,
final:
*lenp = pos;
- retv = proc_dostring(ctl, write, filp, buffer, lenp, ppos);
+ retv = proc_dostring(ctl, write, buffer, lenp, ppos);
return retv;
}
@@ -766,7 +766,7 @@ final:
static char conf_reset_result[200];
-static int arlan_configure(ctl_table * ctl, int write, struct file *filp,
+static int arlan_configure(ctl_table * ctl, int write,
void __user *buffer, size_t * lenp, loff_t *ppos)
{
int pos = 0;
@@ -788,10 +788,10 @@ static int arlan_configure(ctl_table * ctl, int write, struct file *filp,
return -1;
*lenp = pos;
- return proc_dostring(ctl, write, filp, buffer, lenp, ppos);
+ return proc_dostring(ctl, write, buffer, lenp, ppos);
}
-static int arlan_sysctl_reset(ctl_table * ctl, int write, struct file *filp,
+static int arlan_sysctl_reset(ctl_table * ctl, int write,
void __user *buffer, size_t * lenp, loff_t *ppos)
{
int pos = 0;
@@ -811,7 +811,7 @@ static int arlan_sysctl_reset(ctl_table * ctl, int write, struct file *filp,
} else
return -1;
*lenp = pos + 3;
- return proc_dostring(ctl, write, filp, buffer, lenp, ppos);
+ return proc_dostring(ctl, write, buffer, lenp, ppos);
}
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index debad07d990..c63ea6afd96 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -982,7 +982,7 @@
#define AR5K_5414_CBCFG_BUF_DIS 0x10 /* Disable buffer */
/*
- * PCI-E Power managment configuration
+ * PCI-E Power management configuration
* and status register [5424+]
*/
#define AR5K_PCIE_PM_CTL 0x4068 /* Register address */
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index a3b36b3a9d6..cce188837d1 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -3330,7 +3330,7 @@ static void atmel_smooth_qual(struct atmel_private *priv)
priv->wstats.qual.updated &= ~IW_QUAL_QUAL_INVALID;
}
-/* deals with incoming managment frames. */
+/* deals with incoming management frames. */
static void atmel_management_frame(struct atmel_private *priv,
struct ieee80211_hdr *header,
u16 frame_len, u8 rssi)
diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig
index c62da435285..c25a04371ca 100644
--- a/drivers/net/wireless/iwmc3200wifi/Kconfig
+++ b/drivers/net/wireless/iwmc3200wifi/Kconfig
@@ -24,8 +24,8 @@ config IWM_DEBUG
To see the list of debug modules and levels, see iwm/debug.h
For example, if you want the full MLME debug output:
- echo 0xff > /debug/iwm/phyN/debug/mlme
+ echo 0xff > /sys/kernel/debug/iwm/phyN/debug/mlme
Or, if you want the full debug, for all modules:
- echo 0xff > /debug/iwm/phyN/debug/level
- echo 0xff > /debug/iwm/phyN/debug/modules
+ echo 0xff > /sys/kernel/debug/iwm/phyN/debug/level
+ echo 0xff > /sys/kernel/debug/iwm/phyN/debug/modules
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 446e327180f..cb8be8d7abc 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -1222,3 +1222,4 @@ MODULE_DESCRIPTION("Libertas SPI WLAN Driver");
MODULE_AUTHOR("Andrey Yurovsky <andrey@cozybit.com>, "
"Colin McCabe <colin@cozybit.com>");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:libertas_spi");
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index 05458d9249c..afd26bf0664 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -731,3 +731,4 @@ module_exit(p54spi_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
+MODULE_ALIAS("spi:cx3110x");
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 5809ef5b18f..1103256ad98 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -1426,3 +1426,4 @@ EXPORT_SYMBOL_GPL(wl1251_free_hw);
MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
+MODULE_ALIAS("spi:wl12xx");
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 5e110a2328a..4e79a980013 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -368,7 +368,7 @@ error:
return r;
}
-/* MAC address: if custom mac addresses are to to be used CR_MAC_ADDR_P1 and
+/* MAC address: if custom mac addresses are to be used CR_MAC_ADDR_P1 and
* CR_MAC_ADDR_P2 must be overwritten
*/
int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)