diff options
Diffstat (limited to 'drivers/net/wan/dlci.c')
| -rw-r--r-- | drivers/net/wan/dlci.c | 229 |
1 files changed, 101 insertions, 128 deletions
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index 96b232446c0..19f7cb2cdef 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c @@ -28,6 +28,8 @@ * 2 of the License, or (at your option) any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> @@ -48,7 +50,6 @@ #include <net/sock.h> -#include <asm/system.h> #include <asm/io.h> #include <asm/dma.h> #include <asm/uaccess.h> @@ -70,14 +71,11 @@ static int dlci_header(struct sk_buff *skb, struct net_device *dev, const void *saddr, unsigned len) { struct frhdr hdr; - struct dlci_local *dlp; unsigned int hlen; char *dest; - dlp = dev->priv; - hdr.control = FRAD_I_UI; - switch(type) + switch (type) { case ETH_P_IP: hdr.IP_NLPID = FRAD_P_IP; @@ -97,24 +95,21 @@ static int dlci_header(struct sk_buff *skb, struct net_device *dev, dest = skb_push(skb, hlen); if (!dest) - return(0); + return 0; memcpy(dest, &hdr, hlen); - return(hlen); + return hlen; } static void dlci_receive(struct sk_buff *skb, struct net_device *dev) { - struct dlci_local *dlp; struct frhdr *hdr; int process, header; - dlp = dev->priv; if (!pskb_may_pull(skb, sizeof(*hdr))) { - printk(KERN_NOTICE "%s: invalid data no header\n", - dev->name); - dlp->stats.rx_errors++; + netdev_notice(dev, "invalid data no header\n"); + dev->stats.rx_errors++; kfree_skb(skb); return; } @@ -126,24 +121,29 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev) if (hdr->control != FRAD_I_UI) { - printk(KERN_NOTICE "%s: Invalid header flag 0x%02X.\n", dev->name, hdr->control); - dlp->stats.rx_errors++; + netdev_notice(dev, "Invalid header flag 0x%02X\n", + hdr->control); + dev->stats.rx_errors++; } else - switch(hdr->IP_NLPID) + switch (hdr->IP_NLPID) { case FRAD_P_PADDING: if (hdr->NLPID != FRAD_P_SNAP) { - printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->NLPID); - dlp->stats.rx_errors++; + netdev_notice(dev, "Unsupported NLPID 0x%02X\n", + hdr->NLPID); + dev->stats.rx_errors++; break; } if (hdr->OUI[0] + hdr->OUI[1] + hdr->OUI[2] != 0) { - printk(KERN_NOTICE "%s: Unsupported organizationally unique identifier 0x%02X-%02X-%02X.\n", dev->name, hdr->OUI[0], hdr->OUI[1], hdr->OUI[2]); - dlp->stats.rx_errors++; + netdev_notice(dev, "Unsupported organizationally unique identifier 0x%02X-%02X-%02X\n", + hdr->OUI[0], + hdr->OUI[1], + hdr->OUI[2]); + dev->stats.rx_errors++; break; } @@ -163,13 +163,15 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev) case FRAD_P_SNAP: case FRAD_P_Q933: case FRAD_P_CLNP: - printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->pad); - dlp->stats.rx_errors++; + netdev_notice(dev, "Unsupported NLPID 0x%02X\n", + hdr->pad); + dev->stats.rx_errors++; break; default: - printk(KERN_NOTICE "%s: Invalid pad byte 0x%02X.\n", dev->name, hdr->pad); - dlp->stats.rx_errors++; + netdev_notice(dev, "Invalid pad byte 0x%02X\n", + hdr->pad); + dev->stats.rx_errors++; break; } @@ -178,54 +180,21 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev) /* we've set up the protocol, so discard the header */ skb_reset_mac_header(skb); skb_pull(skb, header); - dlp->stats.rx_bytes += skb->len; + dev->stats.rx_bytes += skb->len; netif_rx(skb); - dlp->stats.rx_packets++; - dev->last_rx = jiffies; + dev->stats.rx_packets++; } else dev_kfree_skb(skb); } -static int dlci_transmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t dlci_transmit(struct sk_buff *skb, struct net_device *dev) { - struct dlci_local *dlp; - int ret; - - ret = 0; - - if (!skb || !dev) - return(0); - - dlp = dev->priv; - - netif_stop_queue(dev); - - ret = dlp->slave->hard_start_xmit(skb, dlp->slave); - switch (ret) - { - case DLCI_RET_OK: - dlp->stats.tx_packets++; - ret = 0; - break; - case DLCI_RET_ERR: - dlp->stats.tx_errors++; - ret = 0; - break; - case DLCI_RET_DROP: - dlp->stats.tx_dropped++; - ret = 1; - break; - } - /* Alan Cox recommends always returning 0, and always freeing the packet */ - /* experience suggest a slightly more conservative approach */ + struct dlci_local *dlp = netdev_priv(dev); - if (!ret) - { - dev_kfree_skb(skb); - netif_wake_queue(dev); - } - return(ret); + if (skb) + dlp->slave->netdev_ops->ndo_start_xmit(skb, dlp->slave); + return NETDEV_TX_OK; } static int dlci_config(struct net_device *dev, struct dlci_conf __user *conf, int get) @@ -235,31 +204,31 @@ static int dlci_config(struct net_device *dev, struct dlci_conf __user *conf, in struct frad_local *flp; int err; - dlp = dev->priv; + dlp = netdev_priv(dev); - flp = dlp->slave->priv; + flp = netdev_priv(dlp->slave); if (!get) { - if(copy_from_user(&config, conf, sizeof(struct dlci_conf))) + if (copy_from_user(&config, conf, sizeof(struct dlci_conf))) return -EFAULT; if (config.flags & ~DLCI_VALID_FLAGS) - return(-EINVAL); + return -EINVAL; memcpy(&dlp->config, &config, sizeof(struct dlci_conf)); dlp->configured = 1; } err = (*flp->dlci_conf)(dlp->slave, dev, get); if (err) - return(err); + return err; if (get) { - if(copy_to_user(conf, &dlp->config, sizeof(struct dlci_conf))) + if (copy_to_user(conf, &dlp->config, sizeof(struct dlci_conf))) return -EFAULT; } - return(0); + return 0; } static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) @@ -267,15 +236,15 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) struct dlci_local *dlp; if (!capable(CAP_NET_ADMIN)) - return(-EPERM); + return -EPERM; - dlp = dev->priv; + dlp = netdev_priv(dev); - switch(cmd) + switch (cmd) { case DLCI_GET_SLAVE: if (!*(short *)(dev->dev_addr)) - return(-EINVAL); + return -EINVAL; strncpy(ifr->ifr_slave, dlp->slave->name, sizeof(ifr->ifr_slave)); break; @@ -283,24 +252,22 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case DLCI_GET_CONF: case DLCI_SET_CONF: if (!*(short *)(dev->dev_addr)) - return(-EINVAL); + return -EINVAL; - return(dlci_config(dev, ifr->ifr_data, cmd == DLCI_GET_CONF)); + return dlci_config(dev, ifr->ifr_data, cmd == DLCI_GET_CONF); break; default: - return(-EOPNOTSUPP); + return -EOPNOTSUPP; } - return(0); + return 0; } static int dlci_change_mtu(struct net_device *dev, int new_mtu) { - struct dlci_local *dlp; - - dlp = dev->priv; + struct dlci_local *dlp = netdev_priv(dev); - return((*dlp->slave->change_mtu)(dlp->slave, new_mtu)); + return dev_set_mtu(dlp->slave, new_mtu); } static int dlci_open(struct net_device *dev) @@ -309,18 +276,18 @@ static int dlci_open(struct net_device *dev) struct frad_local *flp; int err; - dlp = dev->priv; + dlp = netdev_priv(dev); if (!*(short *)(dev->dev_addr)) - return(-EINVAL); + return -EINVAL; if (!netif_running(dlp->slave)) - return(-ENOTCONN); + return -ENOTCONN; - flp = dlp->slave->priv; + flp = netdev_priv(dlp->slave); err = (*flp->activate)(dlp->slave, dev); if (err) - return(err); + return err; netif_start_queue(dev); @@ -335,23 +302,14 @@ static int dlci_close(struct net_device *dev) netif_stop_queue(dev); - dlp = dev->priv; + dlp = netdev_priv(dev); - flp = dlp->slave->priv; + flp = netdev_priv(dlp->slave); err = (*flp->deactivate)(dlp->slave, dev); return 0; } -static struct net_device_stats *dlci_get_stats(struct net_device *dev) -{ - struct dlci_local *dlp; - - dlp = dev->priv; - - return(&dlp->stats); -} - static int dlci_add(struct dlci_add *dlci) { struct net_device *master, *slave; @@ -365,7 +323,7 @@ static int dlci_add(struct dlci_add *dlci) if (!slave) return -ENODEV; - if (slave->type != ARPHRD_FRAD || slave->priv == NULL) + if (slave->type != ARPHRD_FRAD || netdev_priv(slave) == NULL) goto err1; /* create device name */ @@ -385,17 +343,13 @@ static int dlci_add(struct dlci_add *dlci) } } - err = dev_alloc_name(master, master->name); - if (err < 0) - goto err2; - *(short *)(master->dev_addr) = dlci->dlci; - dlp = (struct dlci_local *) master->priv; + dlp = netdev_priv(master); dlp->slave = slave; dlp->master = master; - flp = slave->priv; + flp = netdev_priv(slave); err = (*flp->assoc)(slave, master); if (err < 0) goto err2; @@ -409,14 +363,14 @@ static int dlci_add(struct dlci_add *dlci) list_add(&dlp->list, &dlci_devs); rtnl_unlock(); - return(0); + return 0; err2: rtnl_unlock(); free_netdev(master); err1: dev_put(slave); - return(err); + return err; } static int dlci_del(struct dlci_add *dlci) @@ -425,21 +379,37 @@ static int dlci_del(struct dlci_add *dlci) struct frad_local *flp; struct net_device *master, *slave; int err; + bool found = false; + + rtnl_lock(); /* validate slave device */ master = __dev_get_by_name(&init_net, dlci->devname); - if (!master) - return(-ENODEV); + if (!master) { + err = -ENODEV; + goto out; + } + + list_for_each_entry(dlp, &dlci_devs, list) { + if (dlp->master == master) { + found = true; + break; + } + } + if (!found) { + err = -ENODEV; + goto out; + } if (netif_running(master)) { - return(-EBUSY); + err = -EBUSY; + goto out; } - dlp = master->priv; + dlp = netdev_priv(master); slave = dlp->slave; - flp = slave->priv; + flp = netdev_priv(slave); - rtnl_lock(); err = (*flp->deassoc)(slave, master); if (!err) { list_del(&dlp->list); @@ -448,9 +418,9 @@ static int dlci_del(struct dlci_add *dlci) dev_put(slave); } +out: rtnl_unlock(); - - return(err); + return err; } static int dlci_ioctl(unsigned int cmd, void __user *arg) @@ -459,9 +429,9 @@ static int dlci_ioctl(unsigned int cmd, void __user *arg) int err; if (!capable(CAP_NET_ADMIN)) - return(-EPERM); + return -EPERM; - if(copy_from_user(&add, arg, sizeof(struct dlci_add))) + if (copy_from_user(&add, arg, sizeof(struct dlci_add))) return -EFAULT; switch (cmd) @@ -470,7 +440,7 @@ static int dlci_ioctl(unsigned int cmd, void __user *arg) err = dlci_add(&add); if (!err) - if(copy_to_user(arg, &add, sizeof(struct dlci_add))) + if (copy_to_user(arg, &add, sizeof(struct dlci_add))) return -EFAULT; break; @@ -482,25 +452,28 @@ static int dlci_ioctl(unsigned int cmd, void __user *arg) err = -EINVAL; } - return(err); + return err; } static const struct header_ops dlci_header_ops = { .create = dlci_header, }; +static const struct net_device_ops dlci_netdev_ops = { + .ndo_open = dlci_open, + .ndo_stop = dlci_close, + .ndo_do_ioctl = dlci_dev_ioctl, + .ndo_start_xmit = dlci_transmit, + .ndo_change_mtu = dlci_change_mtu, +}; + static void dlci_setup(struct net_device *dev) { - struct dlci_local *dlp = dev->priv; + struct dlci_local *dlp = netdev_priv(dev); dev->flags = 0; - dev->open = dlci_open; - dev->stop = dlci_close; - dev->do_ioctl = dlci_dev_ioctl; - dev->hard_start_xmit = dlci_transmit; dev->header_ops = &dlci_header_ops; - dev->get_stats = dlci_get_stats; - dev->change_mtu = dlci_change_mtu; + dev->netdev_ops = &dlci_netdev_ops; dev->destructor = free_netdev; dlp->receive = dlci_receive; @@ -515,9 +488,9 @@ static void dlci_setup(struct net_device *dev) static int dlci_dev_event(struct notifier_block *unused, unsigned long event, void *ptr) { - struct net_device *dev = (struct net_device *) ptr; + struct net_device *dev = netdev_notifier_info_to_dev(ptr); - if (dev->nd_net != &init_net) + if (dev_net(dev) != &init_net) return NOTIFY_DONE; if (event == NETDEV_UNREGISTER) { |
