aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/cris
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/cris')
-rw-r--r--drivers/net/cris/eth_v10.c131
1 files changed, 68 insertions, 63 deletions
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index 65d0a910329..29e272cc7a9 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -18,7 +18,6 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
-#include <linux/slab.h>
#include <linux/string.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
@@ -32,14 +31,13 @@
#include <linux/skbuff.h>
#include <linux/ethtool.h>
-#include <asm/arch/svinto.h>/* DMA and register descriptions */
+#include <arch/svinto.h>/* DMA and register descriptions */
#include <asm/io.h> /* CRIS_LED_* I/O functions */
#include <asm/irq.h>
#include <asm/dma.h>
-#include <asm/system.h>
#include <asm/ethernet.h>
#include <asm/cache.h>
-#include <asm/arch/io_interface_mux.h>
+#include <arch/io_interface_mux.h>
//#define ETHDEBUG
#define D(x)
@@ -60,7 +58,6 @@ static struct sockaddr default_mac = {
/* Information that need to be kept for each board. */
struct net_local {
- struct net_device_stats stats;
struct mii_if_info mii_if;
/* Tx control lock. This protects the transmit buffer ring
@@ -257,6 +254,23 @@ struct transceiver_ops transceivers[] =
struct transceiver_ops* transceiver = &transceivers[0];
+static const struct net_device_ops e100_netdev_ops = {
+ .ndo_open = e100_open,
+ .ndo_stop = e100_close,
+ .ndo_start_xmit = e100_send_packet,
+ .ndo_tx_timeout = e100_tx_timeout,
+ .ndo_get_stats = e100_get_stats,
+ .ndo_set_rx_mode = set_multicast_list,
+ .ndo_do_ioctl = e100_ioctl,
+ .ndo_set_mac_address = e100_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_config = e100_set_config,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = e100_netpoll,
+#endif
+};
+
#define tx_done(dev) (*R_DMA_CH0_CMD == 0)
/*
@@ -300,19 +314,8 @@ etrax_ethernet_init(void)
/* fill in our handlers so the network layer can talk to us in the future */
- dev->open = e100_open;
- dev->hard_start_xmit = e100_send_packet;
- dev->stop = e100_close;
- dev->get_stats = e100_get_stats;
- dev->set_multicast_list = set_multicast_list;
- dev->set_mac_address = e100_set_mac_address;
dev->ethtool_ops = &e100_ethtool_ops;
- dev->do_ioctl = e100_ioctl;
- dev->set_config = e100_set_config;
- dev->tx_timeout = e100_tx_timeout;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = e100_netpoll;
-#endif
+ dev->netdev_ops = &e100_netdev_ops;
spin_lock_init(&np->lock);
spin_lock_init(&np->led_lock);
@@ -419,7 +422,6 @@ e100_set_mac_address(struct net_device *dev, void *p)
{
struct net_local *np = netdev_priv(dev);
struct sockaddr *addr = p;
- DECLARE_MAC_BUF(mac);
spin_lock(&np->lock); /* preemption protection */
@@ -440,8 +442,7 @@ e100_set_mac_address(struct net_device *dev, void *p)
/* show it in the log as well */
- printk(KERN_INFO "%s: changed MAC to %s\n",
- dev->name, print_mac(mac, dev->dev_addr));
+ printk(KERN_INFO "%s: changed MAC to %pM\n", dev->name, dev->dev_addr);
spin_unlock(&np->lock);
@@ -489,8 +490,8 @@ e100_open(struct net_device *dev)
/* allocate the irq corresponding to the receiving DMA */
- if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rxtx_interrupt,
- IRQF_SAMPLE_RANDOM, cardname, (void *)dev)) {
+ if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rxtx_interrupt, 0, cardname,
+ (void *)dev)) {
goto grace_exit0;
}
@@ -764,10 +765,24 @@ e100_negotiate(struct net_device* dev)
e100_set_mdio_reg(dev, np->mii_if.phy_id, MII_ADVERTISE, data);
- /* Renegotiate with link partner */
+ data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR);
if (autoneg_normal) {
- data = e100_get_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR);
- data |= BMCR_ANENABLE | BMCR_ANRESTART;
+ /* Renegotiate with link partner */
+ data |= BMCR_ANENABLE | BMCR_ANRESTART;
+ } else {
+ /* Don't negotiate speed or duplex */
+ data &= ~(BMCR_ANENABLE | BMCR_ANRESTART);
+
+ /* Set speed and duplex static */
+ if (current_speed_selection == 10)
+ data &= ~BMCR_SPEED100;
+ else
+ data |= BMCR_SPEED100;
+
+ if (current_duplex != full)
+ data &= ~BMCR_FULLDPLX;
+ else
+ data |= BMCR_FULLDPLX;
}
e100_set_mdio_reg(dev, np->mii_if.phy_id, MII_BMCR, data);
}
@@ -993,7 +1008,7 @@ e100_send_mdio_bit(unsigned char bit)
}
static unsigned char
-e100_receive_mdio_bit()
+e100_receive_mdio_bit(void)
{
unsigned char bit;
*R_NETWORK_MGM_CTRL = 0;
@@ -1042,7 +1057,7 @@ e100_tx_timeout(struct net_device *dev)
/* remember we got an error */
- np->stats.tx_errors++;
+ dev->stats.tx_errors++;
/* reset the TX DMA in case it has hung on something */
@@ -1091,7 +1106,7 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev)
myNextTxDesc->skb = skb;
- dev->trans_start = jiffies;
+ dev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
e100_hardware_send_packet(np, buf, skb->len);
@@ -1104,7 +1119,7 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&np->lock, flags);
- return 0;
+ return NETDEV_TX_OK;
}
/*
@@ -1116,7 +1131,6 @@ static irqreturn_t
e100rxtx_interrupt(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *)dev_id;
- struct net_local *np = netdev_priv(dev);
unsigned long irqbits;
/*
@@ -1140,7 +1154,7 @@ e100rxtx_interrupt(int irq, void *dev_id)
* allocate a new buffer to put a packet in.
*/
e100_rx(dev);
- np->stats.rx_packets++;
+ dev->stats.rx_packets++;
/* restart/continue on the channel, for safety */
*R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, restart);
/* clear dma channel 1 eop/descr irq bits */
@@ -1156,8 +1170,8 @@ e100rxtx_interrupt(int irq, void *dev_id)
/* Report any packets that have been sent */
while (virt_to_phys(myFirstTxDesc) != *R_DMA_CH0_FIRST &&
(netif_queue_stopped(dev) || myFirstTxDesc != myNextTxDesc)) {
- np->stats.tx_bytes += myFirstTxDesc->skb->len;
- np->stats.tx_packets++;
+ dev->stats.tx_bytes += myFirstTxDesc->skb->len;
+ dev->stats.tx_packets++;
/* dma is ready with the transmission of the data in tx_skb, so now
we can release the skb memory */
@@ -1180,7 +1194,6 @@ static irqreturn_t
e100nw_interrupt(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *)dev_id;
- struct net_local *np = netdev_priv(dev);
unsigned long irqbits = *R_IRQ_MASK0_RD;
/* check for underrun irq */
@@ -1188,13 +1201,13 @@ e100nw_interrupt(int irq, void *dev_id)
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr);
*R_NETWORK_TR_CTRL = network_tr_ctrl_shadow;
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop);
- np->stats.tx_errors++;
+ dev->stats.tx_errors++;
D(printk("ethernet receiver underrun!\n"));
}
/* check for overrun irq */
if (irqbits & IO_STATE(R_IRQ_MASK0_RD, overrun, active)) {
- update_rx_stats(&np->stats); /* this will ack the irq */
+ update_rx_stats(&dev->stats); /* this will ack the irq */
D(printk("ethernet receiver overrun!\n"));
}
/* check for excessive collision irq */
@@ -1202,7 +1215,7 @@ e100nw_interrupt(int irq, void *dev_id)
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr);
*R_NETWORK_TR_CTRL = network_tr_ctrl_shadow;
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop);
- np->stats.tx_errors++;
+ dev->stats.tx_errors++;
D(printk("ethernet excessive collisions!\n"));
}
return IRQ_HANDLED;
@@ -1233,7 +1246,7 @@ e100_rx(struct net_device *dev)
spin_unlock(&np->led_lock);
length = myNextRxDesc->descr.hw_len - 4;
- np->stats.rx_bytes += length;
+ dev->stats.rx_bytes += length;
#ifdef ETHDEBUG
printk("Got a packet of length %d:\n", length);
@@ -1251,7 +1264,7 @@ e100_rx(struct net_device *dev)
/* Small packet, copy data */
skb = dev_alloc_skb(length - ETHER_HEAD_LEN);
if (!skb) {
- np->stats.rx_errors++;
+ dev->stats.rx_errors++;
printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
goto update_nextrxdesc;
}
@@ -1277,7 +1290,7 @@ e100_rx(struct net_device *dev)
int align;
struct sk_buff *new_skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES);
if (!new_skb) {
- np->stats.rx_errors++;
+ dev->stats.rx_errors++;
printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
goto update_nextrxdesc;
}
@@ -1316,8 +1329,6 @@ e100_rx(struct net_device *dev)
static int
e100_close(struct net_device *dev)
{
- struct net_local *np = netdev_priv(dev);
-
printk(KERN_INFO "Closing %s.\n", dev->name);
netif_stop_queue(dev);
@@ -1349,8 +1360,8 @@ e100_close(struct net_device *dev)
/* Update the statistics here. */
- update_rx_stats(&np->stats);
- update_tx_stats(&np->stats);
+ update_rx_stats(&dev->stats);
+ update_tx_stats(&dev->stats);
/* Stop speed/duplex timers */
del_timer(&speed_timer);
@@ -1370,7 +1381,7 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
spin_lock(&np->lock); /* Preempt protection */
switch (cmd) {
/* The ioctls below should be considered obsolete but are */
- /* still present for compatability with old scripts/apps */
+ /* still present for compatibility with old scripts/apps */
case SET_ETH_SPEED_10: /* 10 Mbps */
e100_set_speed(dev, 10);
break;
@@ -1437,10 +1448,10 @@ static int e100_set_settings(struct net_device *dev,
static void e100_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
- strncpy(info->driver, "ETRAX 100LX", sizeof(info->driver) - 1);
- strncpy(info->version, "$Revision: 1.31 $", sizeof(info->version) - 1);
- strncpy(info->fw_version, "N/A", sizeof(info->fw_version) - 1);
- strncpy(info->bus_info, "N/A", sizeof(info->bus_info) - 1);
+ strlcpy(info->driver, "ETRAX 100LX", sizeof(info->driver));
+ strlcpy(info->version, "$Revision: 1.31 $", sizeof(info->version));
+ strlcpy(info->fw_version, "N/A", sizeof(info->fw_version));
+ strlcpy(info->bus_info, "N/A", sizeof(info->bus_info));
}
static int e100_nway_reset(struct net_device *dev)
@@ -1528,11 +1539,11 @@ e100_get_stats(struct net_device *dev)
spin_lock_irqsave(&lp->lock, flags);
- update_rx_stats(&lp->stats);
- update_tx_stats(&lp->stats);
+ update_rx_stats(&dev->stats);
+ update_tx_stats(&dev->stats);
spin_unlock_irqrestore(&lp->lock, flags);
- return &lp->stats;
+ return &dev->stats;
}
/*
@@ -1546,7 +1557,7 @@ static void
set_multicast_list(struct net_device *dev)
{
struct net_local *lp = netdev_priv(dev);
- int num_addr = dev->mc_count;
+ int num_addr = netdev_mc_count(dev);
unsigned long int lo_bits;
unsigned long int hi_bits;
@@ -1578,17 +1589,16 @@ set_multicast_list(struct net_device *dev)
} else {
/* MC mode, receive normal and MC packets */
char hash_ix;
- struct dev_mc_list *dmi = dev->mc_list;
- int i;
+ struct netdev_hw_addr *ha;
char *baddr;
lo_bits = 0x00000000ul;
hi_bits = 0x00000000ul;
- for (i = 0; i < num_addr; i++) {
+ netdev_for_each_mc_addr(ha, dev) {
/* Calculate the hash index for the GA registers */
hash_ix = 0;
- baddr = dmi->dmi_addr;
+ baddr = ha->addr;
hash_ix ^= (*baddr) & 0x3f;
hash_ix ^= ((*baddr) >> 6) & 0x03;
++baddr;
@@ -1614,7 +1624,6 @@ set_multicast_list(struct net_device *dev)
} else {
lo_bits |= (1 << hash_ix);
}
- dmi = dmi->next;
}
/* Disable individual receive */
SETS(network_rec_config_shadow, R_NETWORK_REC_CONFIG, individual, discard);
@@ -1687,11 +1696,7 @@ e100_set_network_leds(int active)
if (!current_speed) {
/* Make LED red, link is down */
-#if defined(CONFIG_ETRAX_NETWORK_RED_ON_NO_CONNECTION)
- CRIS_LED_NETWORK_SET(CRIS_LED_RED);
-#else
CRIS_LED_NETWORK_SET(CRIS_LED_OFF);
-#endif
} else if (light_leds) {
if (current_speed == 10) {
CRIS_LED_NETWORK_SET(CRIS_LED_ORANGE);
@@ -1707,7 +1712,7 @@ e100_set_network_leds(int active)
static void
e100_netpoll(struct net_device* netdev)
{
- e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev, NULL);
+ e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev);
}
#endif