/* ----------------------------------------------------------------------- */
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/seq_file.h>
#include <linux/bitops.h>
+#include <net/net_namespace.h>
#include <net/ax25.h>
#include <asm/irq.h>
#include "z8530.h"
-static char banner[] __initdata = KERN_INFO "AX.25: Z8530 SCC driver version "VERSION".dl1bke\n";
+static const char banner[] __initdata = KERN_INFO \
+ "AX.25: Z8530 SCC driver version "VERSION".dl1bke\n";
static void t_dwait(unsigned long);
static void t_txdelay(unsigned long);
static void init_channel(struct scc_channel *scc);
static void scc_key_trx (struct scc_channel *scc, char tx);
-static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs);
static void scc_init_timer(struct scc_channel *scc);
static int scc_net_alloc(const char *name, struct scc_channel *scc);
static int scc_net_open(struct net_device *dev);
static int scc_net_close(struct net_device *dev);
static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb);
-static int scc_net_tx(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t scc_net_tx(struct sk_buff *skb,
+ struct net_device *dev);
static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
static int scc_net_set_mac_address(struct net_device *dev, void *addr);
static struct net_device_stats * scc_net_get_stats(struct net_device *dev);
#define SCC_IRQTIMEOUT 30000
-static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t scc_isr(int irq, void *dev_id)
{
+ int chip_irq = (long) dev_id;
unsigned char vector;
struct scc_channel *scc;
struct scc_ctrl *ctrl;
ctrl = SCC_ctrl;
while (ctrl->chan_A)
{
- if (ctrl->irq != irq)
+ if (ctrl->irq != chip_irq)
{
ctrl++;
continue;
case PARAM_RTS:
if ( !(scc->wreg[R5] & RTS) )
{
- if (arg != TX_OFF)
+ if (arg != TX_OFF) {
scc_key_trx(scc, TX_ON);
scc_start_tx_timer(scc, t_txdelay, scc->kiss.txdelay);
+ }
} else {
if (arg == TX_OFF)
{
printk(KERN_INFO "Init Z8530 driver: %u channels, IRQ", Nchips*2);
flag=" ";
- for (k = 0; k < NR_IRQS; k++)
+ for (k = 0; k < nr_irqs; k++)
if (Ivec[k].used)
{
printk("%s%d", flag, k);
if (!dev)
return -ENOMEM;
- dev->priv = scc;
+ dev->ml_priv = scc;
scc->dev = dev;
spin_lock_init(&scc->lock);
init_timer(&scc->tx_t);
/* * Network driver methods * */
/* ******************************************************************** */
-static unsigned char ax25_bcast[AX25_ADDR_LEN] =
-{'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1};
-static unsigned char ax25_nocall[AX25_ADDR_LEN] =
-{'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1};
+static const struct net_device_ops scc_netdev_ops = {
+ .ndo_open = scc_net_open,
+ .ndo_stop = scc_net_close,
+ .ndo_start_xmit = scc_net_tx,
+ .ndo_set_mac_address = scc_net_set_mac_address,
+ .ndo_get_stats = scc_net_get_stats,
+ .ndo_do_ioctl = scc_net_ioctl,
+};
/* ----> Initialize device <----- */
{
dev->tx_queue_len = 16; /* should be enough... */
- dev->open = scc_net_open;
- dev->stop = scc_net_close;
+ dev->netdev_ops = &scc_netdev_ops;
+ dev->header_ops = &ax25_header_ops;
- dev->hard_start_xmit = scc_net_tx;
- dev->hard_header = ax25_hard_header;
- dev->rebuild_header = ax25_rebuild_header;
- dev->set_mac_address = scc_net_set_mac_address;
- dev->get_stats = scc_net_get_stats;
- dev->do_ioctl = scc_net_ioctl;
- dev->tx_timeout = NULL;
-
- memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
- memcpy(dev->dev_addr, ax25_nocall, AX25_ADDR_LEN);
+ memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
+ memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN);
dev->flags = 0;
static int scc_net_open(struct net_device *dev)
{
- struct scc_channel *scc = (struct scc_channel *) dev->priv;
+ struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
if (!scc->init)
return -EINVAL;
static int scc_net_close(struct net_device *dev)
{
- struct scc_channel *scc = (struct scc_channel *) dev->priv;
+ struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
unsigned long flags;
netif_stop_queue(dev);
skb->protocol = ax25_type_trans(skb, scc->dev);
netif_rx(skb);
- scc->dev->last_rx = jiffies;
return;
}
/* ----> transmit frame <---- */
-static int scc_net_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t scc_net_tx(struct sk_buff *skb, struct net_device *dev)
{
- struct scc_channel *scc = (struct scc_channel *) dev->priv;
+ struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
unsigned long flags;
char kisscmd;
if (skb->len > scc->stat.bufsize || skb->len < 2) {
scc->dev_stat.tx_dropped++; /* bogus frame */
dev_kfree_skb(skb);
- return 0;
+ return NETDEV_TX_OK;
}
scc->dev_stat.tx_packets++;
if (kisscmd) {
scc_set_param(scc, kisscmd, *skb->data);
dev_kfree_skb(skb);
- return 0;
+ return NETDEV_TX_OK;
}
spin_lock_irqsave(&scc->lock, flags);
__scc_start_tx_timer(scc, t_dwait, 0);
}
spin_unlock_irqrestore(&scc->lock, flags);
- return 0;
+ return NETDEV_TX_OK;
}
/* ----> ioctl functions <---- */
struct scc_mem_config memcfg;
struct scc_hw_config hwcfg;
struct scc_calibrate cal;
- struct scc_channel *scc = (struct scc_channel *) dev->priv;
+ struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
int chan;
unsigned char device_name[IFNAMSIZ];
void __user *arg = ifr->ifr_data;
if (hwcfg.irq == 2) hwcfg.irq = 9;
- if (hwcfg.irq < 0 || hwcfg.irq >= NR_IRQS)
+ if (hwcfg.irq < 0 || hwcfg.irq >= nr_irqs)
return -EINVAL;
if (!Ivec[hwcfg.irq].used && hwcfg.irq)
{
- if (request_irq(hwcfg.irq, scc_isr, SA_INTERRUPT, "AX.25 SCC", NULL))
+ if (request_irq(hwcfg.irq, scc_isr,
+ IRQF_DISABLED, "AX.25 SCC",
+ (void *)(long) hwcfg.irq))
printk(KERN_WARNING "z8530drv: warning, cannot get IRQ %d\n", hwcfg.irq);
else
Ivec[hwcfg.irq].used = 1;
static struct net_device_stats *scc_net_get_stats(struct net_device *dev)
{
- struct scc_channel *scc = (struct scc_channel *) dev->priv;
+ struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
scc->dev_stat.rx_errors = scc->stat.rxerrs + scc->stat.rx_over;
scc->dev_stat.tx_errors = scc->stat.txerrs + scc->stat.tx_under;
return 0;
}
-static struct seq_operations scc_net_seq_ops = {
+static const struct seq_operations scc_net_seq_ops = {
.start = scc_net_seq_start,
.next = scc_net_seq_next,
.stop = scc_net_seq_stop,
return seq_open(file, &scc_net_seq_ops);
}
-static struct file_operations scc_net_seq_fops = {
+static const struct file_operations scc_net_seq_fops = {
.owner = THIS_MODULE,
.open = scc_net_seq_open,
.read = seq_read,
}
rtnl_unlock();
- proc_net_fops_create("z8530drv", 0, &scc_net_seq_fops);
+ proc_net_fops_create(&init_net, "z8530drv", 0, &scc_net_seq_fops);
return 0;
}
}
/* To unload the port must be closed so no real IRQ pending */
- for (k=0; k < NR_IRQS ; k++)
+ for (k = 0; k < nr_irqs ; k++)
if (Ivec[k].used) free_irq(k, NULL);
local_irq_enable();
if (Vector_Latch)
release_region(Vector_Latch, 1);
- proc_net_remove("z8530drv");
+ proc_net_remove(&init_net, "z8530drv");
}
MODULE_AUTHOR("Joerg Reuter <jreuter@yaina.de>");