fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / net / cris / eth_v10.c
index 4426708..a03d781 100644 (file)
  *
  */
 
-#include <linux/config.h>
 
 #include <linux/module.h>
 
@@ -384,8 +383,8 @@ static unsigned int mdio_phy_addr; /* Transciever address */
 static unsigned int network_tr_ctrl_shadow = 0;
 
 /* Network speed indication. */
-static struct timer_list speed_timer = TIMER_INITIALIZER(NULL, 0, 0);
-static struct timer_list clear_led_timer = TIMER_INITIALIZER(NULL, 0, 0);
+static DEFINE_TIMER(speed_timer, NULL, 0, 0);
+static DEFINE_TIMER(clear_led_timer, NULL, 0, 0);
 static int current_speed; /* Speed read from transceiver */
 static int current_speed_selection; /* Speed selected by user */
 static unsigned long led_next_time;
@@ -393,7 +392,7 @@ static int led_active;
 static int rx_queue_len;
 
 /* Duplex */
-static struct timer_list duplex_timer = TIMER_INITIALIZER(NULL, 0, 0);
+static DEFINE_TIMER(duplex_timer, NULL, 0, 0);
 static int full_duplex;
 static enum duplex current_duplex;
 
@@ -404,12 +403,11 @@ static int etrax_ethernet_init(void);
 static int e100_open(struct net_device *dev);
 static int e100_set_mac_address(struct net_device *dev, void *addr);
 static int e100_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t e100rxtx_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t e100nw_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t e100rxtx_interrupt(int irq, void *dev_id);
+static irqreturn_t e100nw_interrupt(int irq, void *dev_id);
 static void e100_rx(struct net_device *dev);
 static int e100_close(struct net_device *dev);
 static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
-static int e100_ethtool_ioctl(struct net_device* dev, struct ifreq *ifr);
 static int e100_set_config(struct net_device* dev, struct ifmap* map);
 static void e100_tx_timeout(struct net_device *dev);
 static struct net_device_stats *e100_get_stats(struct net_device *dev);
@@ -436,6 +434,8 @@ static void e100_reset_transceiver(struct net_device* net);
 static void e100_clear_network_leds(unsigned long dummy);
 static void e100_set_network_leds(int active);
 
+static const struct ethtool_ops e100_ethtool_ops;
+
 static void broadcom_check_speed(struct net_device* dev);
 static void broadcom_check_duplex(struct net_device* dev);
 static void tdk_check_speed(struct net_device* dev);
@@ -495,6 +495,7 @@ etrax_ethernet_init(void)
        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;
@@ -508,6 +509,8 @@ etrax_ethernet_init(void)
                 * does not share cacheline with any other data (to avoid cache bug)
                 */
                RxDescList[i].skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES);
+               if (!RxDescList[i].skb)
+                       return -ENOMEM;
                RxDescList[i].descr.ctrl   = 0;
                RxDescList[i].descr.sw_len = MAX_MEDIA_DATA_SIZE;
                RxDescList[i].descr.next   = virt_to_phys(&RxDescList[i + 1]);
@@ -670,7 +673,7 @@ e100_open(struct net_device *dev)
        /* allocate the irq corresponding to the receiving DMA */
 
        if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rxtx_interrupt,
-                       SA_SAMPLE_RANDOM, cardname, (void *)dev)) {
+                       IRQF_SAMPLE_RANDOM, cardname, (void *)dev)) {
                goto grace_exit0;
        }
 
@@ -1196,7 +1199,7 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev)
  */
 
 static irqreturn_t
-e100rxtx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+e100rxtx_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
        struct net_local *np = (struct net_local *)dev->priv;
@@ -1263,7 +1266,7 @@ e100rxtx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 }
 
 static irqreturn_t
-e100nw_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+e100nw_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
        struct net_local *np = (struct net_local *)dev->priv;
@@ -1448,8 +1451,6 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
        spin_lock(&np->lock); /* Preempt protection */
        switch (cmd) {
-               case SIOCETHTOOL:
-                       return e100_ethtool_ioctl(dev,ifr);
                case SIOCGMIIPHY: /* Get PHY address */
                        data->phy_id = mdio_phy_addr;
                        break;
@@ -1486,88 +1487,81 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        return 0;
 }
 
-static int
-e100_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr)
+static int e100_set_settings(struct net_device *dev,
+                            struct ethtool_cmd *ecmd)
 {
-       struct ethtool_cmd ecmd;
-
-       if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd)))
-               return -EFAULT;
-
-       switch (ecmd.cmd) {
-               case ETHTOOL_GSET:
-               {
-                       memset((void *) &ecmd, 0, sizeof (ecmd));
-                       ecmd.supported =
-                         SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
+       ecmd->supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
                          SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
                          SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full;
-                       ecmd.port = PORT_TP;
-                       ecmd.transceiver = XCVR_EXTERNAL;
-                       ecmd.phy_address = mdio_phy_addr;
-                       ecmd.speed = current_speed;
-                       ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
-                       ecmd.advertising = ADVERTISED_TP;
-                       if (current_duplex == autoneg && current_speed_selection == 0)
-                               ecmd.advertising |= ADVERTISED_Autoneg;
-                       else {
-                               ecmd.advertising |=
-                                 ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
-                                 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
-                               if (current_speed_selection == 10)
-                                       ecmd.advertising &= ~(ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full);
-                               else if (current_speed_selection == 100)
-                                       ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full);
-                               if (current_duplex == half)
-                                       ecmd.advertising &= ~(ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Full);
-                               else if (current_duplex == full)
-                                       ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_100baseT_Half);
-                       }
-                       ecmd.autoneg = AUTONEG_ENABLE;
-                       if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd)))
-                               return -EFAULT;
-               }
-               break;
-               case ETHTOOL_SSET:
-               {
-                       if (!capable(CAP_NET_ADMIN)) {
-                               return -EPERM;
-                       }
-                       if (ecmd.autoneg == AUTONEG_ENABLE) {
-                               e100_set_duplex(dev, autoneg);
-                               e100_set_speed(dev, 0);
-                       } else {
-                               e100_set_duplex(dev, ecmd.duplex == DUPLEX_HALF ? half : full);
-                               e100_set_speed(dev, ecmd.speed == SPEED_10 ? 10: 100);
-                       }
-               }
-               break;
-               case ETHTOOL_GDRVINFO:
-               {
-                       struct ethtool_drvinfo info;
-                       memset((void *) &info, 0, sizeof (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);
-                       info.regdump_len = 0;
-                       info.eedump_len = 0;
-                       info.testinfo_len = 0;
-                       if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
-                               return -EFAULT;
-               }
-               break;
-               case ETHTOOL_NWAY_RST:
-                       if (current_duplex == autoneg && current_speed_selection == 0)
-                               e100_negotiate(dev);
-               break;
-               default:
-                       return -EOPNOTSUPP;
-               break;
+       ecmd->port = PORT_TP;
+       ecmd->transceiver = XCVR_EXTERNAL;
+       ecmd->phy_address = mdio_phy_addr;
+       ecmd->speed = current_speed;
+       ecmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
+       ecmd->advertising = ADVERTISED_TP;
+
+       if (current_duplex == autoneg && current_speed_selection == 0)
+               ecmd->advertising |= ADVERTISED_Autoneg;
+       else {
+               ecmd->advertising |=
+                       ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+                       ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
+               if (current_speed_selection == 10)
+                       ecmd->advertising &= ~(ADVERTISED_100baseT_Half |
+                                              ADVERTISED_100baseT_Full);
+               else if (current_speed_selection == 100)
+                       ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
+                                              ADVERTISED_10baseT_Full);
+               if (current_duplex == half)
+                       ecmd->advertising &= ~(ADVERTISED_10baseT_Full |
+                                              ADVERTISED_100baseT_Full);
+               else if (current_duplex == full)
+                       ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
+                                              ADVERTISED_100baseT_Half);
+       }
+
+       ecmd->autoneg = AUTONEG_ENABLE;
+       return 0;
+}
+
+static int e100_set_settings(struct net_device *dev,
+                            struct ethtool_cmd *ecmd)
+{
+       if (ecmd->autoneg == AUTONEG_ENABLE) {
+               e100_set_duplex(dev, autoneg);
+               e100_set_speed(dev, 0);
+       } else {
+               e100_set_duplex(dev, ecmd->duplex == DUPLEX_HALF ? half : full);
+               e100_set_speed(dev, ecmd->speed == SPEED_10 ? 10: 100);
        }
+
+       return 0;
+}
+
+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);
+}
+
+static int e100_nway_reset(struct net_device *dev)
+{
+       if (current_duplex == autoneg && current_speed_selection == 0)
+               e100_negotiate(dev);
        return 0;
 }
 
+static const struct ethtool_ops e100_ethtool_ops = {
+       .get_settings   = e100_get_settings,
+       .set_settings   = e100_set_settings,
+       .get_drvinfo    = e100_get_drvinfo,
+       .nway_reset     = e100_nway_reset,
+       .get_link       = ethtool_op_get_link,
+};
+
 static int
 e100_set_config(struct net_device *dev, struct ifmap *map)
 {