diff options
Diffstat (limited to 'drivers/net/hamradio/dmascc.c')
| -rw-r--r-- | drivers/net/hamradio/dmascc.c | 131 |
1 files changed, 53 insertions, 78 deletions
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index c9a46b89942..6636022a102 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c @@ -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> @@ -31,11 +32,11 @@ #include <linux/kernel.h> #include <linux/mm.h> #include <linux/netdevice.h> +#include <linux/slab.h> #include <linux/rtnetlink.h> #include <linux/sockios.h> #include <linux/workqueue.h> -#include <asm/atomic.h> -#include <asm/bitops.h> +#include <linux/atomic.h> #include <asm/dma.h> #include <asm/io.h> #include <asm/irq.h> @@ -195,7 +196,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 +240,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); @@ -249,10 +249,10 @@ static void start_timer(struct scc_priv *priv, int t, int r15); static inline unsigned char random(void); static inline void z8530_isr(struct scc_info *info); -static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t scc_isr(int irq, void *dev_id); static void rx_isr(struct scc_priv *priv); static void special_condition(struct scc_priv *priv, int rc); -static void rx_bh(void *arg); +static void rx_bh(struct work_struct *); static void tx_isr(struct scc_priv *priv); static void es_isr(struct scc_priv *priv); static void tm_isr(struct scc_priv *priv); @@ -262,14 +262,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 +332,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 +397,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 +437,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,17 +461,10 @@ 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); - if (!info) { - printk(KERN_ERR "dmascc: " - "could not allocate memory for %s at %#3x\n", - hw[type].name, card_base); - goto out; - } - /* Initialize what is necessary for write_scc and write_scc_data */ - memset(info, 0, sizeof(struct scc_info)); + info = kzalloc(sizeof(struct scc_info), GFP_KERNEL | GFP_DMA); + if (!info) + goto out; info->dev[0] = alloc_netdev(0, "", dev_setup); if (!info->dev[0]) { @@ -579,19 +574,13 @@ static int __init setup_adapter(int card_base, int type, int n) priv->param.clocks = TCTRxCP | RCRTxCP; priv->param.persist = 256; priv->param.dma = -1; - INIT_WORK(&priv->rx_work, rx_bh, priv); - dev->priv = priv; + INIT_WORK(&priv->rx_work, rx_bh); + 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 +718,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 +860,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 +889,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 +916,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 +925,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 +955,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 +1067,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); } } @@ -1142,7 +1118,7 @@ static inline void z8530_isr(struct scc_info *info) } -static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t scc_isr(int irq, void *dev_id) { struct scc_info *info = dev_id; @@ -1230,17 +1206,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 +1229,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++; } } } @@ -1272,9 +1248,9 @@ static void special_condition(struct scc_priv *priv, int rc) } -static void rx_bh(void *arg) +static void rx_bh(struct work_struct *ugli_api) { - struct scc_priv *priv = arg; + struct scc_priv *priv = container_of(ugli_api, struct scc_priv, rx_work); int i = priv->rx_tail; int cb; unsigned long flags; @@ -1289,7 +1265,7 @@ static void rx_bh(void *arg) 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 +1273,8 @@ static void rx_bh(void *arg) 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 +1341,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 +1415,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 { |
