Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
[linux-2.6.git] / drivers / net / hamradio / dmascc.c
index e6e721a..9ee76b4 100644 (file)
@@ -21,6 +21,7 @@
 
 
 #include <linux/module.h>
+#include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/if_arp.h>
@@ -35,7 +36,6 @@
 #include <linux/sockios.h>
 #include <linux/workqueue.h>
 #include <asm/atomic.h>
-#include <asm/bitops.h>
 #include <asm/dma.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -195,7 +195,7 @@ struct scc_priv {
        int chip;
        struct net_device *dev;
        struct scc_info *info;
-       struct net_device_stats stats;
+
        int channel;
        int card_base, scc_cmd, scc_data;
        int tmr_cnt, tmr_ctrl, tmr_mode;
@@ -239,7 +239,6 @@ static int scc_open(struct net_device *dev);
 static int scc_close(struct net_device *dev);
 static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
 static int scc_send_packet(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats *scc_get_stats(struct net_device *dev);
 static int scc_set_mac_address(struct net_device *dev, void *sa);
 
 static inline void tx_on(struct scc_priv *priv);
@@ -262,14 +261,8 @@ static void tm_isr(struct scc_priv *priv);
 
 static int io[MAX_NUM_DEVS] __initdata = { 0, };
 
-/* Beware! hw[] is also used in cleanup_module(). */
-static struct scc_hardware hw[NUM_TYPES] __initdata_or_module = HARDWARE;
-static char ax25_broadcast[7] __initdata =
-    { 'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1,
-'0' << 1 };
-static char ax25_test[7] __initdata =
-    { 'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1,
-'1' << 1 };
+/* Beware! hw[] is also used in dmascc_exit(). */
+static struct scc_hardware hw[NUM_TYPES] = HARDWARE;
 
 
 /* Global variables */
@@ -338,8 +331,8 @@ static int __init dmascc_init(void)
                        for (i = 0; i < MAX_NUM_DEVS && io[i]; i++) {
                                j = (io[i] -
                                     hw[h].io_region) / hw[h].io_delta;
-                               if (j >= 0 && j < hw[h].num_devs
-                                   && hw[h].io_region +
+                               if (j >= 0 && j < hw[h].num_devs &&
+                                   hw[h].io_region +
                                    j * hw[h].io_delta == io[i]) {
                                        base[j] = io[i];
                                }
@@ -403,8 +396,8 @@ static int __init dmascc_init(void)
                                        t_val =
                                            inb(t1[i]) + (inb(t1[i]) << 8);
                                        /* Also check whether counter did wrap */
-                                       if (t_val == 0
-                                           || t_val > TMR_0_HZ / HZ * 10)
+                                       if (t_val == 0 ||
+                                           t_val > TMR_0_HZ / HZ * 10)
                                                counting[i] = 0;
                                        delay[i] = jiffies - start[i];
                                }
@@ -443,10 +436,18 @@ static void __init dev_setup(struct net_device *dev)
        dev->mtu = 1500;
        dev->addr_len = AX25_ADDR_LEN;
        dev->tx_queue_len = 64;
-       memcpy(dev->broadcast, ax25_broadcast, AX25_ADDR_LEN);
-       memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN);
+       memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
+       memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN);
 }
 
+static const struct net_device_ops scc_netdev_ops = {
+       .ndo_open = scc_open,
+       .ndo_stop = scc_close,
+       .ndo_start_xmit = scc_send_packet,
+       .ndo_do_ioctl = scc_ioctl,
+       .ndo_set_mac_address = scc_set_mac_address,
+};
+
 static int __init setup_adapter(int card_base, int type, int n)
 {
        int i, irq, chip;
@@ -459,8 +460,8 @@ static int __init setup_adapter(int card_base, int type, int n)
        int scc_base = card_base + hw[type].scc_offset;
        char *chipnames[] = CHIPNAMES;
 
-       /* Allocate memory */
-       info = kmalloc(sizeof(struct scc_info), GFP_KERNEL | GFP_DMA);
+       /* Initialize what is necessary for write_scc and write_scc_data */
+       info = kzalloc(sizeof(struct scc_info), GFP_KERNEL | GFP_DMA);
        if (!info) {
                printk(KERN_ERR "dmascc: "
                       "could not allocate memory for %s at %#3x\n",
@@ -468,8 +469,6 @@ static int __init setup_adapter(int card_base, int type, int n)
                goto out;
        }
 
-       /* Initialize what is necessary for write_scc and write_scc_data */
-       memset(info, 0, sizeof(struct scc_info));
 
        info->dev[0] = alloc_netdev(0, "", dev_setup);
        if (!info->dev[0]) {
@@ -580,18 +579,12 @@ static int __init setup_adapter(int card_base, int type, int n)
                priv->param.persist = 256;
                priv->param.dma = -1;
                INIT_WORK(&priv->rx_work, rx_bh);
-               dev->priv = priv;
+               dev->ml_priv = priv;
                sprintf(dev->name, "dmascc%i", 2 * n + i);
                dev->base_addr = card_base;
                dev->irq = irq;
-               dev->open = scc_open;
-               dev->stop = scc_close;
-               dev->do_ioctl = scc_ioctl;
-               dev->hard_start_xmit = scc_send_packet;
-               dev->get_stats = scc_get_stats;
-               dev->hard_header = ax25_hard_header;
-               dev->rebuild_header = ax25_rebuild_header;
-               dev->set_mac_address = scc_set_mac_address;
+               dev->netdev_ops = &scc_netdev_ops;
+               dev->header_ops = &ax25_header_ops;
        }
        if (register_netdev(info->dev[0])) {
                printk(KERN_ERR "dmascc: could not register %s\n",
@@ -729,7 +722,7 @@ static int read_scc_data(struct scc_priv *priv)
 
 static int scc_open(struct net_device *dev)
 {
-       struct scc_priv *priv = dev->priv;
+       struct scc_priv *priv = dev->ml_priv;
        struct scc_info *info = priv->info;
        int card_base = priv->card_base;
 
@@ -871,7 +864,7 @@ static int scc_open(struct net_device *dev)
 
 static int scc_close(struct net_device *dev)
 {
-       struct scc_priv *priv = dev->priv;
+       struct scc_priv *priv = dev->ml_priv;
        struct scc_info *info = priv->info;
        int card_base = priv->card_base;
 
@@ -900,7 +893,7 @@ static int scc_close(struct net_device *dev)
 
 static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-       struct scc_priv *priv = dev->priv;
+       struct scc_priv *priv = dev->ml_priv;
 
        switch (cmd) {
        case SIOCGSCCPARAM:
@@ -927,7 +920,7 @@ static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
 static int scc_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
-       struct scc_priv *priv = dev->priv;
+       struct scc_priv *priv = dev->ml_priv;
        unsigned long flags;
        int i;
 
@@ -936,7 +929,7 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev)
 
        /* Transfer data to DMA buffer */
        i = priv->tx_head;
-       memcpy(priv->tx_buf[i], skb->data + 1, skb->len - 1);
+       skb_copy_from_linear_data_offset(skb, 1, priv->tx_buf[i], skb->len - 1);
        priv->tx_len[i] = skb->len - 1;
 
        /* Clear interrupts while we touch our circular buffers */
@@ -966,15 +959,7 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev)
        spin_unlock_irqrestore(&priv->ring_lock, flags);
        dev_kfree_skb(skb);
 
-       return 0;
-}
-
-
-static struct net_device_stats *scc_get_stats(struct net_device *dev)
-{
-       struct scc_priv *priv = dev->priv;
-
-       return &priv->stats;
+       return NETDEV_TX_OK;
 }
 
 
@@ -1086,21 +1071,16 @@ static inline void rx_off(struct scc_priv *priv)
 
 static void start_timer(struct scc_priv *priv, int t, int r15)
 {
-       unsigned long flags;
-
        outb(priv->tmr_mode, priv->tmr_ctrl);
        if (t == 0) {
                tm_isr(priv);
        } else if (t > 0) {
-               save_flags(flags);
-               cli();
                outb(t & 0xFF, priv->tmr_cnt);
                outb((t >> 8) & 0xFF, priv->tmr_cnt);
                if (priv->type != TYPE_TWIN) {
                        write_scc(priv, R15, r15 | CTSIE);
                        priv->rr0 |= CTS;
                }
-               restore_flags(flags);
        }
 }
 
@@ -1230,17 +1210,17 @@ static void special_condition(struct scc_priv *priv, int rc)
                }
                if (priv->rx_over) {
                        /* We had an overrun */
-                       priv->stats.rx_errors++;
+                       priv->dev->stats.rx_errors++;
                        if (priv->rx_over == 2)
-                               priv->stats.rx_length_errors++;
+                               priv->dev->stats.rx_length_errors++;
                        else
-                               priv->stats.rx_fifo_errors++;
+                               priv->dev->stats.rx_fifo_errors++;
                        priv->rx_over = 0;
                } else if (rc & CRC_ERR) {
                        /* Count invalid CRC only if packet length >= minimum */
                        if (cb >= 15) {
-                               priv->stats.rx_errors++;
-                               priv->stats.rx_crc_errors++;
+                               priv->dev->stats.rx_errors++;
+                               priv->dev->stats.rx_crc_errors++;
                        }
                } else {
                        if (cb >= 15) {
@@ -1253,8 +1233,8 @@ static void special_condition(struct scc_priv *priv, int rc)
                                        priv->rx_count++;
                                        schedule_work(&priv->rx_work);
                                } else {
-                                       priv->stats.rx_errors++;
-                                       priv->stats.rx_over_errors++;
+                                       priv->dev->stats.rx_errors++;
+                                       priv->dev->stats.rx_over_errors++;
                                }
                        }
                }
@@ -1289,7 +1269,7 @@ static void rx_bh(struct work_struct *ugli_api)
                skb = dev_alloc_skb(cb + 1);
                if (skb == NULL) {
                        /* Drop packet */
-                       priv->stats.rx_dropped++;
+                       priv->dev->stats.rx_dropped++;
                } else {
                        /* Fill buffer */
                        data = skb_put(skb, cb + 1);
@@ -1297,9 +1277,8 @@ static void rx_bh(struct work_struct *ugli_api)
                        memcpy(&data[1], priv->rx_buf[i], cb);
                        skb->protocol = ax25_type_trans(skb, priv->dev);
                        netif_rx(skb);
-                       priv->dev->last_rx = jiffies;
-                       priv->stats.rx_packets++;
-                       priv->stats.rx_bytes += cb;
+                       priv->dev->stats.rx_packets++;
+                       priv->dev->stats.rx_bytes += cb;
                }
                spin_lock_irqsave(&priv->ring_lock, flags);
                /* Move tail */
@@ -1366,15 +1345,15 @@ static void es_isr(struct scc_priv *priv)
                        write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN);
                if (res) {
                        /* Update packet statistics */
-                       priv->stats.tx_errors++;
-                       priv->stats.tx_fifo_errors++;
+                       priv->dev->stats.tx_errors++;
+                       priv->dev->stats.tx_fifo_errors++;
                        /* Other underrun interrupts may already be waiting */
                        write_scc(priv, R0, RES_EXT_INT);
                        write_scc(priv, R0, RES_EXT_INT);
                } else {
                        /* Update packet statistics */
-                       priv->stats.tx_packets++;
-                       priv->stats.tx_bytes += priv->tx_len[i];
+                       priv->dev->stats.tx_packets++;
+                       priv->dev->stats.tx_bytes += priv->tx_len[i];
                        /* Remove frame from FIFO */
                        priv->tx_tail = (i + 1) % NUM_TX_BUF;
                        priv->tx_count--;
@@ -1440,7 +1419,7 @@ static void tm_isr(struct scc_priv *priv)
                write_scc(priv, R15, DCDIE);
                priv->rr0 = read_scc(priv, R0);
                if (priv->rr0 & DCD) {
-                       priv->stats.collisions++;
+                       priv->dev->stats.collisions++;
                        rx_on(priv);
                        priv->state = RX_ON;
                } else {