aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/micrel
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/micrel')
-rw-r--r--drivers/net/ethernet/micrel/Kconfig4
-rw-r--r--drivers/net/ethernet/micrel/ks8695net.c49
-rw-r--r--drivers/net/ethernet/micrel/ks8842.c29
-rw-r--r--drivers/net/ethernet/micrel/ks8851.c221
-rw-r--r--drivers/net/ethernet/micrel/ks8851.h2
-rw-r--r--drivers/net/ethernet/micrel/ks8851_mll.c111
-rw-r--r--drivers/net/ethernet/micrel/ksz884x.c95
7 files changed, 275 insertions, 236 deletions
diff --git a/drivers/net/ethernet/micrel/Kconfig b/drivers/net/ethernet/micrel/Kconfig
index fe42fc00d8d..d16b11ed2e5 100644
--- a/drivers/net/ethernet/micrel/Kconfig
+++ b/drivers/net/ethernet/micrel/Kconfig
@@ -22,7 +22,6 @@ if NET_VENDOR_MICREL
config ARM_KS8695_ETHER
tristate "KS8695 Ethernet support"
depends on ARM && ARCH_KS8695
- select NET_CORE
select MII
---help---
If you wish to compile a kernel for the KS8695 and want to
@@ -39,7 +38,6 @@ config KS8842
config KS8851
tristate "Micrel KS8851 SPI"
depends on SPI
- select NET_CORE
select MII
select CRC32
select EEPROM_93CX6
@@ -49,7 +47,6 @@ config KS8851
config KS8851_MLL
tristate "Micrel KS8851 MLL"
depends on HAS_IOMEM
- select NET_CORE
select MII
---help---
This platform driver is for Micrel KS8851 Address/data bus
@@ -58,7 +55,6 @@ config KS8851_MLL
config KSZ884X_PCI
tristate "Micrel KSZ8841/2 PCI"
depends on PCI
- select NET_CORE
select MII
select CRC32
---help---
diff --git a/drivers/net/ethernet/micrel/ks8695net.c b/drivers/net/ethernet/micrel/ks8695net.c
index ab81c0dc96e..6c7c78baedc 100644
--- a/drivers/net/ethernet/micrel/ks8695net.c
+++ b/drivers/net/ethernet/micrel/ks8695net.c
@@ -21,7 +21,6 @@
#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
-#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
@@ -278,7 +277,8 @@ ks8695_refill_rxbuffers(struct ks8695_priv *ksp)
for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) {
if (!ksp->rx_buffers[buff_n].skb) {
- struct sk_buff *skb = dev_alloc_skb(MAX_RXBUF_SIZE);
+ struct sk_buff *skb =
+ netdev_alloc_skb(ksp->ndev, MAX_RXBUF_SIZE);
dma_addr_t mapping;
ksp->rx_buffers[buff_n].skb = skb;
@@ -299,7 +299,6 @@ ks8695_refill_rxbuffers(struct ks8695_priv *ksp)
break;
}
ksp->rx_buffers[buff_n].dma_ptr = mapping;
- skb->dev = ksp->ndev;
ksp->rx_buffers[buff_n].length = MAX_RXBUF_SIZE;
/* Record this into the DMA ring */
@@ -1249,9 +1248,6 @@ ks8695_open(struct net_device *ndev)
struct ks8695_priv *ksp = netdev_priv(ndev);
int ret;
- if (!is_valid_ether_addr(ndev->dev_addr))
- return -EADDRNOTAVAIL;
-
ks8695_reset(ksp);
ks8695_update_mac(ksp);
@@ -1277,7 +1273,7 @@ ks8695_open(struct net_device *ndev)
* This initialises the LAN switch in the KS8695 to a known-good
* set of defaults.
*/
-static void __devinit
+static void
ks8695_init_switch(struct ks8695_priv *ksp)
{
u32 ctrl;
@@ -1305,7 +1301,7 @@ ks8695_init_switch(struct ks8695_priv *ksp)
* This initialises a KS8695's WAN phy to sensible values for
* autonegotiation etc.
*/
-static void __devinit
+static void
ks8695_init_wan_phy(struct ks8695_priv *ksp)
{
u32 ctrl;
@@ -1349,7 +1345,7 @@ static const struct net_device_ops ks8695_netdev_ops = {
* wan ports, and an IORESOURCE_IRQ for the link IRQ for the wan
* port.
*/
-static int __devinit
+static int
ks8695_probe(struct platform_device *pdev)
{
struct ks8695_priv *ksp;
@@ -1362,10 +1358,8 @@ ks8695_probe(struct platform_device *pdev)
/* Initialise a net_device */
ndev = alloc_etherdev(sizeof(struct ks8695_priv));
- if (!ndev) {
- dev_err(&pdev->dev, "could not allocate device.\n");
+ if (!ndev)
return -ENOMEM;
- }
SET_NETDEV_DEV(ndev, &pdev->dev);
@@ -1510,15 +1504,15 @@ ks8695_probe(struct platform_device *pdev)
if (ksp->phyiface_regs && ksp->link_irq == -1) {
ks8695_init_switch(ksp);
ksp->dtype = KS8695_DTYPE_LAN;
- SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
+ ndev->ethtool_ops = &ks8695_ethtool_ops;
} else if (ksp->phyiface_regs && ksp->link_irq != -1) {
ks8695_init_wan_phy(ksp);
ksp->dtype = KS8695_DTYPE_WAN;
- SET_ETHTOOL_OPS(ndev, &ks8695_wan_ethtool_ops);
+ ndev->ethtool_ops = &ks8695_wan_ethtool_ops;
} else {
/* No initialisation since HPNA does not have a PHY */
ksp->dtype = KS8695_DTYPE_HPNA;
- SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
+ ndev->ethtool_ops = &ks8695_ethtool_ops;
}
/* And bring up the net_device with the net core */
@@ -1599,13 +1593,12 @@ ks8695_drv_resume(struct platform_device *pdev)
*
* This unregisters and releases a KS8695 ethernet device.
*/
-static int __devexit
+static int
ks8695_drv_remove(struct platform_device *pdev)
{
struct net_device *ndev = platform_get_drvdata(pdev);
struct ks8695_priv *ksp = netdev_priv(ndev);
- platform_set_drvdata(pdev, NULL);
netif_napi_del(&ksp->napi);
unregister_netdev(ndev);
@@ -1622,30 +1615,12 @@ static struct platform_driver ks8695_driver = {
.owner = THIS_MODULE,
},
.probe = ks8695_probe,
- .remove = __devexit_p(ks8695_drv_remove),
+ .remove = ks8695_drv_remove,
.suspend = ks8695_drv_suspend,
.resume = ks8695_drv_resume,
};
-/* Module interface */
-
-static int __init
-ks8695_init(void)
-{
- printk(KERN_INFO "%s Ethernet driver, V%s\n",
- MODULENAME, MODULEVERSION);
-
- return platform_driver_register(&ks8695_driver);
-}
-
-static void __exit
-ks8695_cleanup(void)
-{
- platform_driver_unregister(&ks8695_driver);
-}
-
-module_init(ks8695_init);
-module_exit(ks8695_cleanup);
+module_platform_driver(ks8695_driver);
MODULE_AUTHOR("Simtec Electronics");
MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver");
diff --git a/drivers/net/ethernet/micrel/ks8842.c b/drivers/net/ethernet/micrel/ks8842.c
index 0a85690a132..822616e3c37 100644
--- a/drivers/net/ethernet/micrel/ks8842.c
+++ b/drivers/net/ethernet/micrel/ks8842.c
@@ -458,9 +458,8 @@ static int ks8842_tx_frame_dma(struct sk_buff *skb, struct net_device *netdev)
if (sg_dma_len(&ctl->sg) % 4)
sg_dma_len(&ctl->sg) += 4 - sg_dma_len(&ctl->sg) % 4;
- ctl->adesc = ctl->chan->device->device_prep_slave_sg(ctl->chan,
- &ctl->sg, 1, DMA_MEM_TO_DEV,
- DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP);
+ ctl->adesc = dmaengine_prep_slave_sg(ctl->chan,
+ &ctl->sg, 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
if (!ctl->adesc)
return NETDEV_TX_BUSY;
@@ -570,9 +569,8 @@ static int __ks8842_start_new_rx_dma(struct net_device *netdev)
sg_dma_len(sg) = DMA_BUFFER_SIZE;
- ctl->adesc = ctl->chan->device->device_prep_slave_sg(ctl->chan,
- sg, 1, DMA_DEV_TO_MEM,
- DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP);
+ ctl->adesc = dmaengine_prep_slave_sg(ctl->chan,
+ sg, 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
if (!ctl->adesc)
goto out;
@@ -705,7 +703,8 @@ static void ks8842_rx_frame(struct net_device *netdev,
ks8842_enable_bits(adapter, 0, 1 << 12, REG_QRFCR);
}
-void ks8842_handle_rx(struct net_device *netdev, struct ks8842_adapter *adapter)
+static void ks8842_handle_rx(struct net_device *netdev,
+ struct ks8842_adapter *adapter)
{
u16 rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff;
netdev_dbg(netdev, "%s Entry - rx_data: %d\n", __func__, rx_data);
@@ -715,7 +714,8 @@ void ks8842_handle_rx(struct net_device *netdev, struct ks8842_adapter *adapter)
}
}
-void ks8842_handle_tx(struct net_device *netdev, struct ks8842_adapter *adapter)
+static void ks8842_handle_tx(struct net_device *netdev,
+ struct ks8842_adapter *adapter)
{
u16 sr = ks8842_read16(adapter, 16, REG_TXSR);
netdev_dbg(netdev, "%s - entry, sr: %x\n", __func__, sr);
@@ -724,7 +724,7 @@ void ks8842_handle_tx(struct net_device *netdev, struct ks8842_adapter *adapter)
netif_wake_queue(netdev);
}
-void ks8842_handle_rx_overrun(struct net_device *netdev,
+static void ks8842_handle_rx_overrun(struct net_device *netdev,
struct ks8842_adapter *adapter)
{
netdev_dbg(netdev, "%s: entry\n", __func__);
@@ -732,7 +732,7 @@ void ks8842_handle_rx_overrun(struct net_device *netdev,
netdev->stats.rx_fifo_errors++;
}
-void ks8842_tasklet(unsigned long arg)
+static void ks8842_tasklet(unsigned long arg)
{
struct net_device *netdev = (struct net_device *)arg;
struct ks8842_adapter *adapter = netdev_priv(netdev);
@@ -1140,13 +1140,13 @@ static const struct ethtool_ops ks8842_ethtool_ops = {
.get_link = ethtool_op_get_link,
};
-static int __devinit ks8842_probe(struct platform_device *pdev)
+static int ks8842_probe(struct platform_device *pdev)
{
int err = -ENOMEM;
struct resource *iomem;
struct net_device *netdev;
struct ks8842_adapter *adapter;
- struct ks8842_platform_data *pdata = pdev->dev.platform_data;
+ struct ks8842_platform_data *pdata = dev_get_platdata(&pdev->dev);
u16 id;
unsigned i;
@@ -1211,7 +1211,7 @@ static int __devinit ks8842_probe(struct platform_device *pdev)
ks8842_read_mac_addr(adapter, netdev->dev_addr);
if (!is_valid_ether_addr(netdev->dev_addr))
- random_ether_addr(netdev->dev_addr);
+ eth_hw_addr_random(netdev);
}
id = ks8842_read16(adapter, 32, REG_SW_ID_AND_ENABLE);
@@ -1239,7 +1239,7 @@ err_mem_region:
return err;
}
-static int __devexit ks8842_remove(struct platform_device *pdev)
+static int ks8842_remove(struct platform_device *pdev)
{
struct net_device *netdev = platform_get_drvdata(pdev);
struct ks8842_adapter *adapter = netdev_priv(netdev);
@@ -1250,7 +1250,6 @@ static int __devexit ks8842_remove(struct platform_device *pdev)
iounmap(adapter->hw_addr);
free_netdev(netdev);
release_mem_region(iomem->start, resource_size(iomem));
- platform_set_drvdata(pdev, NULL);
return 0;
}
diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c
index 0c3e4005224..66d4ab703f4 100644
--- a/drivers/net/ethernet/micrel/ks8851.c
+++ b/drivers/net/ethernet/micrel/ks8851.c
@@ -1,4 +1,4 @@
-/* drivers/net/ks8851.c
+/* drivers/net/ethernet/micrel/ks8851.c
*
* Copyright 2009 Simtec Electronics
* http://www.simtec.co.uk/
@@ -23,8 +23,11 @@
#include <linux/crc32.h>
#include <linux/mii.h>
#include <linux/eeprom_93cx6.h>
+#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
#include "ks8851.h"
@@ -69,7 +72,6 @@ union ks8851_tx_hdr {
* @mii: The MII state information for the mii calls.
* @rxctrl: RX settings for @rxctrl_work.
* @tx_work: Work queue for tx packets
- * @irq_work: Work queue for servicing interrupts
* @rxctrl_work: Work queue for updating RX mode and multicast lists
* @txq: Queue of packets for transmission.
* @spi_msg1: pre-setup SPI transfer with one message, @spi_xfer1.
@@ -84,6 +86,9 @@ union ks8851_tx_hdr {
* @rc_rxqcr: Cached copy of KS_RXQCR.
* @eeprom_size: Companion eeprom size in Bytes, 0 if no eeprom
* @eeprom: 93CX6 EEPROM state for accessing on-board EEPROM.
+ * @vdd_reg: Optional regulator supplying the chip
+ * @vdd_io: Optional digital power supply for IO
+ * @gpio: Optional reset_n gpio
*
* The @lock ensures that the chip is protected when certain operations are
* in progress. When the read or write packet transfer is in progress, most
@@ -121,7 +126,6 @@ struct ks8851_net {
struct ks8851_rxctrl rxctrl;
struct work_struct tx_work;
- struct work_struct irq_work;
struct work_struct rxctrl_work;
struct sk_buff_head txq;
@@ -132,6 +136,9 @@ struct ks8851_net {
struct spi_transfer spi_xfer2[2];
struct eeprom_93cx6 eeprom;
+ struct regulator *vdd_reg;
+ struct regulator *vdd_io;
+ int gpio;
};
static int msg_enable;
@@ -422,7 +429,7 @@ static void ks8851_read_mac_addr(struct net_device *dev)
*
* Get or create the initial mac address for the device and then set that
* into the station address register. If there is an EEPROM present, then
- * we try that. If no valid mac address is found we use random_ether_addr()
+ * we try that. If no valid mac address is found we use eth_random_addr()
* to create a new one.
*/
static void ks8851_init_mac(struct ks8851_net *ks)
@@ -439,28 +446,11 @@ static void ks8851_init_mac(struct ks8851_net *ks)
dev->dev_addr);
}
- random_ether_addr(dev->dev_addr);
+ eth_hw_addr_random(dev);
ks8851_write_mac_addr(dev);
}
/**
- * ks8851_irq - device interrupt handler
- * @irq: Interrupt number passed from the IRQ hnalder.
- * @pw: The private word passed to register_irq(), our struct ks8851_net.
- *
- * Disable the interrupt from happening again until we've processed the
- * current status by scheduling ks8851_irq_work().
- */
-static irqreturn_t ks8851_irq(int irq, void *pw)
-{
- struct ks8851_net *ks = pw;
-
- disable_irq_nosync(irq);
- schedule_work(&ks->irq_work);
- return IRQ_HANDLED;
-}
-
-/**
* ks8851_rdfifo - read data from the receive fifo
* @ks: The device state.
* @buff: The buffer address
@@ -547,7 +537,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks)
for (; rxfc != 0; rxfc--) {
rxh = ks8851_rdreg32(ks, KS_RXFHSR);
rxstat = rxh & 0xffff;
- rxlen = rxh >> 16;
+ rxlen = (rxh >> 16) & 0xfff;
netif_dbg(ks, rx_status, ks->netdev,
"rx: stat 0x%04x, len 0x%04x\n", rxstat, rxlen);
@@ -595,19 +585,20 @@ static void ks8851_rx_pkts(struct ks8851_net *ks)
}
/**
- * ks8851_irq_work - work queue handler for dealing with interrupt requests
- * @work: The work structure that was scheduled by schedule_work()
+ * ks8851_irq - IRQ handler for dealing with interrupt requests
+ * @irq: IRQ number
+ * @_ks: cookie
*
- * This is the handler invoked when the ks8851_irq() is called to find out
- * what happened, as we cannot allow ourselves to sleep whilst waiting for
- * anything other process has the chip's lock.
+ * This handler is invoked when the IRQ line asserts to find out what happened.
+ * As we cannot allow ourselves to sleep in HARDIRQ context, this handler runs
+ * in thread context.
*
* Read the interrupt status, work out what needs to be done and then clear
* any of the interrupts that are not needed.
*/
-static void ks8851_irq_work(struct work_struct *work)
+static irqreturn_t ks8851_irq(int irq, void *_ks)
{
- struct ks8851_net *ks = container_of(work, struct ks8851_net, irq_work);
+ struct ks8851_net *ks = _ks;
unsigned status;
unsigned handled = 0;
@@ -618,10 +609,8 @@ static void ks8851_irq_work(struct work_struct *work)
netif_dbg(ks, intr, ks->netdev,
"%s: status 0x%04x\n", __func__, status);
- if (status & IRQ_LCI) {
- /* should do something about checking link status */
+ if (status & IRQ_LCI)
handled |= IRQ_LCI;
- }
if (status & IRQ_LDI) {
u16 pmecr = ks8851_rdreg16(ks, KS_PMECR);
@@ -684,10 +673,13 @@ static void ks8851_irq_work(struct work_struct *work)
mutex_unlock(&ks->lock);
+ if (status & IRQ_LCI)
+ mii_check_link(&ks->mii);
+
if (status & IRQ_TXI)
netif_wake_queue(ks->netdev);
- enable_irq(ks->netdev->irq);
+ return IRQ_HANDLED;
}
/**
@@ -889,16 +881,16 @@ static int ks8851_net_stop(struct net_device *dev)
netif_stop_queue(dev);
mutex_lock(&ks->lock);
+ /* turn off the IRQs and ack any outstanding */
+ ks8851_wrreg16(ks, KS_IER, 0x0000);
+ ks8851_wrreg16(ks, KS_ISR, 0xffff);
+ mutex_unlock(&ks->lock);
/* stop any outstanding work */
- flush_work(&ks->irq_work);
flush_work(&ks->tx_work);
flush_work(&ks->rxctrl_work);
- /* turn off the IRQs and ack any outstanding */
- ks8851_wrreg16(ks, KS_IER, 0x0000);
- ks8851_wrreg16(ks, KS_ISR, 0xffff);
-
+ mutex_lock(&ks->lock);
/* shutdown RX process */
ks8851_wrreg16(ks, KS_RXCR1, 0x0000);
@@ -907,6 +899,7 @@ static int ks8851_net_stop(struct net_device *dev)
/* set powermode to soft power down to save power */
ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN);
+ mutex_unlock(&ks->lock);
/* ensure any queued tx buffers are dumped */
while (!skb_queue_empty(&ks->txq)) {
@@ -918,7 +911,6 @@ static int ks8851_net_stop(struct net_device *dev)
dev_kfree_skb(txb);
}
- mutex_unlock(&ks->lock);
return 0;
}
@@ -1381,48 +1373,48 @@ static int ks8851_read_selftest(struct ks8851_net *ks)
/* driver bus management functions */
-#ifdef CONFIG_PM
-static int ks8851_suspend(struct spi_device *spi, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+
+static int ks8851_suspend(struct device *dev)
{
- struct ks8851_net *ks = dev_get_drvdata(&spi->dev);
- struct net_device *dev = ks->netdev;
+ struct ks8851_net *ks = dev_get_drvdata(dev);
+ struct net_device *netdev = ks->netdev;
- if (netif_running(dev)) {
- netif_device_detach(dev);
- ks8851_net_stop(dev);
+ if (netif_running(netdev)) {
+ netif_device_detach(netdev);
+ ks8851_net_stop(netdev);
}
return 0;
}
-static int ks8851_resume(struct spi_device *spi)
+static int ks8851_resume(struct device *dev)
{
- struct ks8851_net *ks = dev_get_drvdata(&spi->dev);
- struct net_device *dev = ks->netdev;
+ struct ks8851_net *ks = dev_get_drvdata(dev);
+ struct net_device *netdev = ks->netdev;
- if (netif_running(dev)) {
- ks8851_net_open(dev);
- netif_device_attach(dev);
+ if (netif_running(netdev)) {
+ ks8851_net_open(netdev);
+ netif_device_attach(netdev);
}
return 0;
}
-#else
-#define ks8851_suspend NULL
-#define ks8851_resume NULL
#endif
-static int __devinit ks8851_probe(struct spi_device *spi)
+static SIMPLE_DEV_PM_OPS(ks8851_pm_ops, ks8851_suspend, ks8851_resume);
+
+static int ks8851_probe(struct spi_device *spi)
{
struct net_device *ndev;
struct ks8851_net *ks;
int ret;
+ unsigned cider;
+ int gpio;
ndev = alloc_etherdev(sizeof(struct ks8851_net));
- if (!ndev) {
- dev_err(&spi->dev, "failed to alloc ethernet device\n");
+ if (!ndev)
return -ENOMEM;
- }
spi->bits_per_word = 8;
@@ -1432,11 +1424,58 @@ static int __devinit ks8851_probe(struct spi_device *spi)
ks->spidev = spi;
ks->tx_space = 6144;
+ gpio = of_get_named_gpio_flags(spi->dev.of_node, "reset-gpios",
+ 0, NULL);
+ if (gpio == -EPROBE_DEFER) {
+ ret = gpio;
+ goto err_gpio;
+ }
+
+ ks->gpio = gpio;
+ if (gpio_is_valid(gpio)) {
+ ret = devm_gpio_request_one(&spi->dev, gpio,
+ GPIOF_OUT_INIT_LOW, "ks8851_rst_n");
+ if (ret) {
+ dev_err(&spi->dev, "reset gpio request failed\n");
+ goto err_gpio;
+ }
+ }
+
+ ks->vdd_io = devm_regulator_get(&spi->dev, "vdd-io");
+ if (IS_ERR(ks->vdd_io)) {
+ ret = PTR_ERR(ks->vdd_io);
+ goto err_reg_io;
+ }
+
+ ret = regulator_enable(ks->vdd_io);
+ if (ret) {
+ dev_err(&spi->dev, "regulator vdd_io enable fail: %d\n",
+ ret);
+ goto err_reg_io;
+ }
+
+ ks->vdd_reg = devm_regulator_get(&spi->dev, "vdd");
+ if (IS_ERR(ks->vdd_reg)) {
+ ret = PTR_ERR(ks->vdd_reg);
+ goto err_reg;
+ }
+
+ ret = regulator_enable(ks->vdd_reg);
+ if (ret) {
+ dev_err(&spi->dev, "regulator vdd enable fail: %d\n",
+ ret);
+ goto err_reg;
+ }
+
+ if (gpio_is_valid(gpio)) {
+ usleep_range(10000, 11000);
+ gpio_set_value(gpio, 1);
+ }
+
mutex_init(&ks->lock);
spin_lock_init(&ks->statelock);
INIT_WORK(&ks->tx_work, ks8851_tx_work);
- INIT_WORK(&ks->irq_work, ks8851_irq_work);
INIT_WORK(&ks->rxctrl_work, ks8851_rxctrl_work);
/* initialise pre-made spi transfer messages */
@@ -1472,10 +1511,10 @@ static int __devinit ks8851_probe(struct spi_device *spi)
skb_queue_head_init(&ks->txq);
- SET_ETHTOOL_OPS(ndev, &ks8851_ethtool_ops);
+ ndev->ethtool_ops = &ks8851_ethtool_ops;
SET_NETDEV_DEV(ndev, &spi->dev);
- dev_set_drvdata(&spi->dev, ks);
+ spi_set_drvdata(spi, ks);
ndev->if_port = IF_PORT_100BASET;
ndev->netdev_ops = &ks8851_netdev_ops;
@@ -1485,8 +1524,8 @@ static int __devinit ks8851_probe(struct spi_device *spi)
ks8851_soft_reset(ks, GRR_GSR);
/* simple check for a valid chip being connected to the bus */
-
- if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) {
+ cider = ks8851_rdreg16(ks, KS_CIDER);
+ if ((cider & ~CIDER_REV_MASK) != CIDER_ID) {
dev_err(&spi->dev, "failed to read device ID\n");
ret = -ENODEV;
goto err_id;
@@ -1503,8 +1542,9 @@ static int __devinit ks8851_probe(struct spi_device *spi)
ks8851_read_selftest(ks);
ks8851_init_mac(ks);
- ret = request_irq(spi->irq, ks8851_irq, IRQF_TRIGGER_LOW,
- ndev->name, ks);
+ ret = request_threaded_irq(spi->irq, NULL, ks8851_irq,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ ndev->name, ks);
if (ret < 0) {
dev_err(&spi->dev, "failed to get irq\n");
goto err_irq;
@@ -1517,59 +1557,62 @@ static int __devinit ks8851_probe(struct spi_device *spi)
}
netdev_info(ndev, "revision %d, MAC %pM, IRQ %d, %s EEPROM\n",
- CIDER_REV_GET(ks8851_rdreg16(ks, KS_CIDER)),
- ndev->dev_addr, ndev->irq,
+ CIDER_REV_GET(cider), ndev->dev_addr, ndev->irq,
ks->rc_ccr & CCR_EEPROM ? "has" : "no");
return 0;
err_netdev:
- free_irq(ndev->irq, ndev);
+ free_irq(ndev->irq, ks);
-err_id:
err_irq:
+ if (gpio_is_valid(gpio))
+ gpio_set_value(gpio, 0);
+err_id:
+ regulator_disable(ks->vdd_reg);
+err_reg:
+ regulator_disable(ks->vdd_io);
+err_reg_io:
+err_gpio:
free_netdev(ndev);
return ret;
}
-static int __devexit ks8851_remove(struct spi_device *spi)
+static int ks8851_remove(struct spi_device *spi)
{
- struct ks8851_net *priv = dev_get_drvdata(&spi->dev);
+ struct ks8851_net *priv = spi_get_drvdata(spi);
if (netif_msg_drv(priv))
dev_info(&spi->dev, "remove\n");
unregister_netdev(priv->netdev);
free_irq(spi->irq, priv);
+ if (gpio_is_valid(priv->gpio))
+ gpio_set_value(priv->gpio, 0);
+ regulator_disable(priv->vdd_reg);
+ regulator_disable(priv->vdd_io);
free_netdev(priv->netdev);
return 0;
}
+static const struct of_device_id ks8851_match_table[] = {
+ { .compatible = "micrel,ks8851" },
+ { }
+};
+
static struct spi_driver ks8851_driver = {
.driver = {
.name = "ks8851",
+ .of_match_table = ks8851_match_table,
.owner = THIS_MODULE,
+ .pm = &ks8851_pm_ops,
},
.probe = ks8851_probe,
- .remove = __devexit_p(ks8851_remove),
- .suspend = ks8851_suspend,
- .resume = ks8851_resume,
+ .remove = ks8851_remove,
};
-
-static int __init ks8851_init(void)
-{
- return spi_register_driver(&ks8851_driver);
-}
-
-static void __exit ks8851_exit(void)
-{
- spi_unregister_driver(&ks8851_driver);
-}
-
-module_init(ks8851_init);
-module_exit(ks8851_exit);
+module_spi_driver(ks8851_driver);
MODULE_DESCRIPTION("KS8851 Network driver");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
diff --git a/drivers/net/ethernet/micrel/ks8851.h b/drivers/net/ethernet/micrel/ks8851.h
index b0fae86aaca..852256ef1f2 100644
--- a/drivers/net/ethernet/micrel/ks8851.h
+++ b/drivers/net/ethernet/micrel/ks8851.h
@@ -1,4 +1,4 @@
-/* drivers/net/ks8851.h
+/* drivers/net/ethernet/micrel/ks8851.h
*
* Copyright 2009 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c
index 2784bc706f1..c83d16dc7cd 100644
--- a/drivers/net/ethernet/micrel/ks8851_mll.c
+++ b/drivers/net/ethernet/micrel/ks8851_mll.c
@@ -1,5 +1,5 @@
/**
- * drivers/net/ks8851_mll.c
+ * drivers/net/ethernet/micrel/ks8851_mll.c
* Copyright (c) 2009 Micrel Inc.
*
* This program is free software; you can redistribute it and/or modify
@@ -16,8 +16,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/**
- * Supports:
+/* Supports:
* KS8851 16bit MLL chip from Micrel Inc.
*/
@@ -35,12 +34,15 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/slab.h>
-#include <asm/io.h>
+#include <linux/ks8851_mll.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_net.h>
#define DRV_NAME "ks8851_mll"
static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 };
-#define MAX_RECV_FRAMES 32
+#define MAX_RECV_FRAMES 255
#define MAX_BUF_SIZE 2048
#define TX_BUF_SIZE 2000
#define RX_BUF_SIZE 2000
@@ -465,8 +467,7 @@ static int msg_enable;
#define BE1 0x2000 /* Byte Enable 1 */
#define BE0 0x1000 /* Byte Enable 0 */
-/**
- * register read/write calls.
+/* register read/write calls.
*
* All these calls issue transactions to access the chip's registers. They
* all require that the necessary lock is held to prevent accesses when the
@@ -687,7 +688,7 @@ static void ks_soft_reset(struct ks_net *ks, unsigned op)
}
-void ks_enable_qmu(struct ks_net *ks)
+static void ks_enable_qmu(struct ks_net *ks)
{
u16 w;
@@ -794,20 +795,35 @@ static void ks_rcv(struct ks_net *ks, struct net_device *netdev)
frame_hdr = ks->frame_head_info;
while (ks->frame_cnt--) {
- skb = dev_alloc_skb(frame_hdr->len + 16);
- if (likely(skb && (frame_hdr->sts & RXFSHR_RXFV) &&
- (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) {
+ if (unlikely(!(frame_hdr->sts & RXFSHR_RXFV) ||
+ frame_hdr->len >= RX_BUF_SIZE ||
+ frame_hdr->len <= 0)) {
+
+ /* discard an invalid packet */
+ ks_wrreg16(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF));
+ netdev->stats.rx_dropped++;
+ if (!(frame_hdr->sts & RXFSHR_RXFV))
+ netdev->stats.rx_frame_errors++;
+ else
+ netdev->stats.rx_length_errors++;
+ frame_hdr++;
+ continue;
+ }
+
+ skb = netdev_alloc_skb(netdev, frame_hdr->len + 16);
+ if (likely(skb)) {
skb_reserve(skb, 2);
/* read data block including CRC 4 bytes */
ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len);
- skb_put(skb, frame_hdr->len);
+ skb_put(skb, frame_hdr->len - 4);
skb->protocol = eth_type_trans(skb, netdev);
netif_rx(skb);
+ /* exclude CRC size */
+ netdev->stats.rx_bytes += frame_hdr->len - 4;
+ netdev->stats.rx_packets++;
} else {
- pr_err("%s: err:skb alloc\n", __func__);
ks_wrreg16(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF));
- if (skb)
- dev_kfree_skb_irq(skb);
+ netdev->stats.rx_dropped++;
}
frame_hdr++;
}
@@ -837,7 +853,7 @@ static void ks_update_link_status(struct net_device *netdev, struct ks_net *ks)
/**
* ks_irq - device interrupt handler
- * @irq: Interrupt number passed from the IRQ hnalder.
+ * @irq: Interrupt number passed from the IRQ handler.
* @pw: The private word passed to register_irq(), our struct ks_net.
*
* This is the handler invoked to find out what happened
@@ -879,6 +895,8 @@ static irqreturn_t ks_irq(int irq, void *pw)
ks_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK);
}
+ if (unlikely(status & IRQ_RXOI))
+ ks->netdev->stats.rx_over_errors++;
/* this should be the last in IRQ handler*/
ks_restore_cmd_reg(ks);
return IRQ_HANDLED;
@@ -897,7 +915,7 @@ static int ks_net_open(struct net_device *netdev)
struct ks_net *ks = netdev_priv(netdev);
int err;
-#define KS_INT_FLAGS (IRQF_DISABLED|IRQF_TRIGGER_LOW)
+#define KS_INT_FLAGS IRQF_TRIGGER_LOW
/* lock the card, even if we may not actually do anything
* else at the moment.
*/
@@ -1017,6 +1035,9 @@ static int ks_start_xmit(struct sk_buff *skb, struct net_device *netdev)
if (likely(ks_tx_fifo_space(ks) >= skb->len + 12)) {
ks_write_qmu(ks, skb->data, skb->len);
+ /* add tx statistics */
+ netdev->stats.tx_bytes += skb->len;
+ netdev->stats.tx_packets++;
dev_kfree_skb(skb);
} else
retv = NETDEV_TX_BUSY;
@@ -1103,7 +1124,7 @@ static void ks_set_grpaddr(struct ks_net *ks)
}
} /* ks_set_grpaddr */
-/*
+/**
* ks_clear_mcast - clear multicast information
*
* @ks : The chip information
@@ -1227,7 +1248,7 @@ static void ks_set_mac(struct ks_net *ks, u8 *data)
w = ((u & 0xFF) << 8) | ((u >> 8) & 0xFF);
ks_wrreg16(ks, KS_MARL, w);
- memcpy(ks->mac_addr, data, 6);
+ memcpy(ks->mac_addr, data, ETH_ALEN);
if (ks->enabled)
ks_start_rx(ks);
@@ -1499,23 +1520,29 @@ static int ks_hw_init(struct ks_net *ks)
ks->mcast_lst_size = 0;
ks->frame_head_info = kmalloc(MHEADER_SIZE, GFP_KERNEL);
- if (!ks->frame_head_info) {
- pr_err("Error: Fail to allocate frame memory\n");
+ if (!ks->frame_head_info)
return false;
- }
ks_set_mac(ks, KS_DEFAULT_MAC_ADDRESS);
return true;
}
+#if defined(CONFIG_OF)
+static const struct of_device_id ks8851_ml_dt_ids[] = {
+ { .compatible = "micrel,ks8851-mll" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ks8851_ml_dt_ids);
+#endif
-static int __devinit ks8851_probe(struct platform_device *pdev)
+static int ks8851_probe(struct platform_device *pdev)
{
int err = -ENOMEM;
struct resource *io_d, *io_c;
struct net_device *netdev;
struct ks_net *ks;
u16 id, data;
+ const char *mac;
io_d = platform_get_resource(pdev, IORESOURCE_MEM, 0);
io_c = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -1597,17 +1624,35 @@ static int __devinit ks8851_probe(struct platform_device *pdev)
ks_disable_qmu(ks);
ks_setup(ks);
ks_setup_int(ks);
- memcpy(netdev->dev_addr, ks->mac_addr, 6);
data = ks_rdreg16(ks, KS_OBCR);
ks_wrreg16(ks, KS_OBCR, data | OBCR_ODS_16MA);
- /**
- * If you want to use the default MAC addr,
- * comment out the 2 functions below.
- */
+ /* overwriting the default MAC address */
+ if (pdev->dev.of_node) {
+ mac = of_get_mac_address(pdev->dev.of_node);
+ if (mac)
+ memcpy(ks->mac_addr, mac, ETH_ALEN);
+ } else {
+ struct ks8851_mll_platform_data *pdata;
+
+ pdata = dev_get_platdata(&pdev->dev);
+ if (!pdata) {
+ netdev_err(netdev, "No platform data\n");
+ err = -ENODEV;
+ goto err_pdata;
+ }
+ memcpy(ks->mac_addr, pdata->mac_addr, ETH_ALEN);
+ }
+ if (!is_valid_ether_addr(ks->mac_addr)) {
+ /* Use random MAC address if none passed */
+ eth_random_addr(ks->mac_addr);
+ netdev_info(netdev, "Using random mac address\n");
+ }
+ netdev_info(netdev, "Mac address is: %pM\n", ks->mac_addr);
+
+ memcpy(netdev->dev_addr, ks->mac_addr, ETH_ALEN);
- random_ether_addr(netdev->dev_addr);
ks_set_mac(ks, netdev->dev_addr);
id = ks_rdreg16(ks, KS_CIDER);
@@ -1616,6 +1661,8 @@ static int __devinit ks8851_probe(struct platform_device *pdev)
(id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7);
return 0;
+err_pdata:
+ unregister_netdev(netdev);
err_register:
err_get_irq:
iounmap(ks->hw_addr_cmd);
@@ -1631,7 +1678,7 @@ err_mem_region:
return err;
}
-static int __devexit ks8851_remove(struct platform_device *pdev)
+static int ks8851_remove(struct platform_device *pdev)
{
struct net_device *netdev = platform_get_drvdata(pdev);
struct ks_net *ks = netdev_priv(netdev);
@@ -1642,7 +1689,6 @@ static int __devexit ks8851_remove(struct platform_device *pdev)
iounmap(ks->hw_addr);
free_netdev(netdev);
release_mem_region(iomem->start, resource_size(iomem));
- platform_set_drvdata(pdev, NULL);
return 0;
}
@@ -1651,9 +1697,10 @@ static struct platform_driver ks8851_platform_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(ks8851_ml_dt_ids),
},
.probe = ks8851_probe,
- .remove = __devexit_p(ks8851_remove),
+ .remove = ks8851_remove,
};
module_platform_driver(ks8851_platform_driver);
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c
index e52cd310ae7..064a48d0c36 100644
--- a/drivers/net/ethernet/micrel/ksz884x.c
+++ b/drivers/net/ethernet/micrel/ksz884x.c
@@ -1,5 +1,5 @@
/**
- * drivers/net/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver
+ * drivers/net/ethernet/micrel/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver
*
* Copyright (c) 2009-2010 Micrel, Inc.
* Tristram Ha <Tristram.Ha@micrel.com>
@@ -1487,7 +1487,7 @@ struct dev_priv {
#define DRV_VERSION "1.0.0"
#define DRV_RELDATE "Feb 8, 2010"
-static char version[] __devinitdata =
+static char version[] =
"Micrel " DEVICE_NAME " " DRV_VERSION " (" DRV_RELDATE ")";
static u8 DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x88, 0x42, 0x01 };
@@ -3913,7 +3913,7 @@ static void hw_start_rx(struct ksz_hw *hw)
hw->rx_stop = 2;
}
-/*
+/**
* hw_stop_rx - stop receiving
* @hw: The hardware instance.
*
@@ -4128,10 +4128,10 @@ static int hw_add_addr(struct ksz_hw *hw, u8 *mac_addr)
int i;
int j = ADDITIONAL_ENTRIES;
- if (!memcmp(hw->override_addr, mac_addr, ETH_ALEN))
+ if (ether_addr_equal(hw->override_addr, mac_addr))
return 0;
for (i = 0; i < hw->addr_list_size; i++) {
- if (!memcmp(hw->address[i], mac_addr, ETH_ALEN))
+ if (ether_addr_equal(hw->address[i], mac_addr))
return 0;
if (ADDITIONAL_ENTRIES == j && empty_addr(hw->address[i]))
j = i;
@@ -4149,7 +4149,7 @@ static int hw_del_addr(struct ksz_hw *hw, u8 *mac_addr)
int i;
for (i = 0; i < hw->addr_list_size; i++) {
- if (!memcmp(hw->address[i], mac_addr, ETH_ALEN)) {
+ if (ether_addr_equal(hw->address[i], mac_addr)) {
memset(hw->address[i], 0, ETH_ALEN);
writel(0, hw->io + ADD_ADDR_INCR * i +
KS_ADD_ADDR_0_HI);
@@ -4480,14 +4480,12 @@ static void ksz_init_rx_buffers(struct dev_info *adapter)
dma_buf->len = adapter->mtu;
if (!dma_buf->skb)
dma_buf->skb = alloc_skb(dma_buf->len, GFP_ATOMIC);
- if (dma_buf->skb && !dma_buf->dma) {
- dma_buf->skb->dev = adapter->dev;
+ if (dma_buf->skb && !dma_buf->dma)
dma_buf->dma = pci_map_single(
adapter->pdev,
skb_tail_pointer(dma_buf->skb),
dma_buf->len,
PCI_DMA_FROMDEVICE);
- }
/* Set descriptor. */
set_rx_buf(desc, dma_buf->dma);
@@ -4763,7 +4761,7 @@ static void transmit_cleanup(struct dev_info *hw_priv, int normal)
struct ksz_dma_buf *dma_buf;
struct net_device *dev = NULL;
- spin_lock(&hw_priv->hwlock);
+ spin_lock_irq(&hw_priv->hwlock);
last = info->last;
while (info->avail < info->alloc) {
@@ -4797,7 +4795,7 @@ static void transmit_cleanup(struct dev_info *hw_priv, int normal)
info->avail++;
}
info->last = last;
- spin_unlock(&hw_priv->hwlock);
+ spin_unlock_irq(&hw_priv->hwlock);
/* Notify the network subsystem that the packet has been sent. */
if (dev)
@@ -4834,7 +4832,7 @@ static inline void copy_old_skb(struct sk_buff *old, struct sk_buff *skb)
skb->csum = old->csum;
skb_set_network_header(skb, ETH_HLEN);
- dev_kfree_skb(old);
+ dev_consume_skb_any(old);
}
/**
@@ -4863,7 +4861,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev)
memset(&skb->data[skb->len], 0, 50 - skb->len);
skb->len = 50;
} else {
- skb = dev_alloc_skb(50);
+ skb = netdev_alloc_skb(dev, 50);
if (!skb)
return NETDEV_TX_BUSY;
memcpy(skb->data, org_skb->data, org_skb->len);
@@ -4881,11 +4879,11 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev)
left = hw_alloc_pkt(hw, skb->len, num);
if (left) {
if (left < num ||
- ((CHECKSUM_PARTIAL == skb->ip_summed) &&
- (ETH_P_IPV6 == htons(skb->protocol)))) {
+ (CHECKSUM_PARTIAL == skb->ip_summed &&
+ skb->protocol == htons(ETH_P_IPV6))) {
struct sk_buff *org_skb = skb;
- skb = dev_alloc_skb(org_skb->len);
+ skb = netdev_alloc_skb(dev, org_skb->len);
if (!skb) {
rc = NETDEV_TX_BUSY;
goto unlock;
@@ -4932,7 +4930,7 @@ static void netdev_tx_timeout(struct net_device *dev)
* Only reset the hardware if time between calls is long
* enough.
*/
- if (jiffies - last_reset <= dev->watchdog_timeo)
+ if (time_before_eq(jiffies, last_reset + dev->watchdog_timeo))
hw_priv = NULL;
}
@@ -5019,7 +5017,7 @@ static inline int rx_proc(struct net_device *dev, struct ksz_hw* hw,
do {
/* skb->data != skb->head */
- skb = dev_alloc_skb(packet_len + 2);
+ skb = netdev_alloc_skb(dev, packet_len + 2);
if (!skb) {
dev->stats.rx_dropped++;
return -ENOMEM;
@@ -5261,11 +5259,15 @@ static irqreturn_t netdev_intr(int irq, void *dev_id)
struct dev_info *hw_priv = priv->adapter;
struct ksz_hw *hw = &hw_priv->hw;
+ spin_lock(&hw_priv->hwlock);
+
hw_read_intr(hw, &int_enable);
/* Not our interrupt! */
- if (!int_enable)
+ if (!int_enable) {
+ spin_unlock(&hw_priv->hwlock);
return IRQ_NONE;
+ }
do {
hw_ack_intr(hw, int_enable);
@@ -5312,6 +5314,8 @@ static irqreturn_t netdev_intr(int irq, void *dev_id)
hw_ena_intr(hw);
+ spin_unlock(&hw_priv->hwlock);
+
return IRQ_HANDLED;
}
@@ -5409,8 +5413,8 @@ static int netdev_close(struct net_device *dev)
/* Delay for receive task to stop scheduling itself. */
msleep(2000 / HZ);
- tasklet_disable(&hw_priv->rx_tasklet);
- tasklet_disable(&hw_priv->tx_tasklet);
+ tasklet_kill(&hw_priv->rx_tasklet);
+ tasklet_kill(&hw_priv->tx_tasklet);
free_irq(dev->irq, hw_priv->dev);
transmit_cleanup(hw_priv, 0);
@@ -5461,8 +5465,10 @@ static int prepare_hardware(struct net_device *dev)
rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev);
if (rc)
return rc;
- tasklet_enable(&hw_priv->rx_tasklet);
- tasklet_enable(&hw_priv->tx_tasklet);
+ tasklet_init(&hw_priv->rx_tasklet, rx_proc_task,
+ (unsigned long) hw_priv);
+ tasklet_init(&hw_priv->tx_tasklet, tx_proc_task,
+ (unsigned long) hw_priv);
hw->promiscuous = 0;
hw->all_multi = 0;
@@ -5675,7 +5681,7 @@ static int netdev_set_mac_address(struct net_device *dev, void *addr)
memcpy(hw->override_addr, mac->sa_data, ETH_ALEN);
}
- memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN);
+ memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN);
interrupt = hw_block_intr(hw);
@@ -5847,15 +5853,12 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
struct dev_info *hw_priv = priv->adapter;
struct ksz_hw *hw = &hw_priv->hw;
struct ksz_port *port = &priv->port;
- int rc;
int result = 0;
struct mii_ioctl_data *data = if_mii(ifr);
if (down_interruptible(&priv->proc_sem))
return -ERESTARTSYS;
- /* assume success */
- rc = 0;
switch (cmd) {
/* Get address of MII PHY in use. */
case SIOCGMIIPHY:
@@ -6769,7 +6772,7 @@ static int stp;
/*
* This enables fast aging in the KSZ8842 switch. Not sure what situation
* needs that. However, fast aging is used to flush the dynamic MAC table when
- * STP suport is enabled.
+ * STP support is enabled.
*/
static int fast_aging;
@@ -6919,8 +6922,7 @@ static void read_other_addr(struct ksz_hw *hw)
#define PCI_VENDOR_ID_MICREL_KS 0x16c6
#endif
-static int __devinit pcidev_init(struct pci_dev *pdev,
- const struct pci_device_id *id)
+static int pcidev_init(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct net_device *dev;
struct dev_priv *priv;
@@ -7035,16 +7037,6 @@ static int __devinit pcidev_init(struct pci_dev *pdev,
spin_lock_init(&hw_priv->hwlock);
mutex_init(&hw_priv->lock);
- /* tasklet is enabled. */
- tasklet_init(&hw_priv->rx_tasklet, rx_proc_task,
- (unsigned long) hw_priv);
- tasklet_init(&hw_priv->tx_tasklet, tx_proc_task,
- (unsigned long) hw_priv);
-
- /* tasklet_enable will decrement the atomic counter. */
- tasklet_disable(&hw_priv->rx_tasklet);
- tasklet_disable(&hw_priv->tx_tasklet);
-
for (i = 0; i < TOTAL_PORT_NUM; i++)
init_waitqueue_head(&hw_priv->counter[i].counter);
@@ -7080,6 +7072,7 @@ static int __devinit pcidev_init(struct pci_dev *pdev,
dev = alloc_etherdev(sizeof(struct dev_priv));
if (!dev)
goto pcidev_init_reg_err;
+ SET_NETDEV_DEV(dev, &pdev->dev);
info->netdev[i] = dev;
priv = netdev_priv(dev);
@@ -7109,13 +7102,12 @@ static int __devinit pcidev_init(struct pci_dev *pdev,
ETH_ALEN);
else {
memcpy(dev->dev_addr, sw->other_addr, ETH_ALEN);
- if (!memcmp(sw->other_addr, hw->override_addr,
- ETH_ALEN))
+ if (ether_addr_equal(sw->other_addr, hw->override_addr))
dev->dev_addr[5] += port->first_port;
}
dev->netdev_ops = &netdev_ops;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+ dev->ethtool_ops = &netdev_ethtool_ops;
if (register_netdev(dev))
goto pcidev_init_reg_err;
port_set_power_saving(port, true);
@@ -7155,8 +7147,6 @@ static void pcidev_exit(struct pci_dev *pdev)
struct platform_info *info = pci_get_drvdata(pdev);
struct dev_info *hw_priv = &info->dev_info;
- pci_set_drvdata(pdev, NULL);
-
release_mem_region(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
for (i = 0; i < hw_priv->hw.dev_count; i++) {
@@ -7232,7 +7222,7 @@ static int pcidev_suspend(struct pci_dev *pdev, pm_message_t state)
static char pcidev_name[] = "ksz884xp";
-static struct pci_device_id pcidev_table[] = {
+static DEFINE_PCI_DEVICE_TABLE(pcidev_table) = {
{ PCI_VENDOR_ID_MICREL_KS, 0x8841,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ PCI_VENDOR_ID_MICREL_KS, 0x8842,
@@ -7253,18 +7243,7 @@ static struct pci_driver pci_device_driver = {
.remove = pcidev_exit
};
-static int __init ksz884x_init_module(void)
-{
- return pci_register_driver(&pci_device_driver);
-}
-
-static void __exit ksz884x_cleanup_module(void)
-{
- pci_unregister_driver(&pci_device_driver);
-}
-
-module_init(ksz884x_init_module);
-module_exit(ksz884x_cleanup_module);
+module_pci_driver(pci_device_driver);
MODULE_DESCRIPTION("KSZ8841/2 PCI network driver");
MODULE_AUTHOR("Tristram Ha <Tristram.Ha@micrel.com>");