diff options
Diffstat (limited to 'net/rose/rose_dev.c')
| -rw-r--r-- | net/rose/rose_dev.c | 73 |
1 files changed, 45 insertions, 28 deletions
diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c index d297af737d1..50005888be5 100644 --- a/net/rose/rose_dev.c +++ b/net/rose/rose_dev.c @@ -6,11 +6,9 @@ * * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk) */ -#include <linux/config.h> #include <linux/module.h> #include <linux/proc_fs.h> #include <linux/kernel.h> -#include <linux/sched.h> #include <linux/interrupt.h> #include <linux/fs.h> #include <linux/types.h> @@ -21,8 +19,8 @@ #include <linux/fcntl.h> #include <linux/in.h> #include <linux/if_ether.h> +#include <linux/slab.h> -#include <asm/system.h> #include <asm/io.h> #include <linux/inet.h> @@ -37,8 +35,9 @@ #include <net/ax25.h> #include <net/rose.h> -static int rose_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) +static int rose_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, + const void *daddr, const void *saddr, unsigned int len) { unsigned char *buff = skb_push(skb, ROSE_MIN_LEN + 2); @@ -56,12 +55,13 @@ static int rose_header(struct sk_buff *skb, struct net_device *dev, unsigned sho static int rose_rebuild_header(struct sk_buff *skb) { +#ifdef CONFIG_INET struct net_device *dev = skb->dev; - struct net_device_stats *stats = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; unsigned char *bp = (unsigned char *)skb->data; struct sk_buff *skbn; + unsigned int len; -#ifdef CONFIG_INET if (arp_find(bp + 7, skb)) { return 1; } @@ -76,6 +76,8 @@ static int rose_rebuild_header(struct sk_buff *skb) kfree_skb(skb); + len = skbn->len; + if (!rose_route_frame(skbn, NULL)) { kfree_skb(skbn); stats->tx_errors++; @@ -83,7 +85,7 @@ static int rose_rebuild_header(struct sk_buff *skb) } stats->tx_packets++; - stats->tx_bytes += skbn->len; + stats->tx_bytes += len; #endif return 1; } @@ -91,20 +93,34 @@ static int rose_rebuild_header(struct sk_buff *skb) static int rose_set_mac_address(struct net_device *dev, void *addr) { struct sockaddr *sa = addr; + int err; - rose_del_loopback_node((rose_address *)dev->dev_addr); + if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len)) + return 0; - memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); + if (dev->flags & IFF_UP) { + err = rose_add_loopback_node((rose_address *)sa->sa_data); + if (err) + return err; + + rose_del_loopback_node((rose_address *)dev->dev_addr); + } - rose_add_loopback_node((rose_address *)dev->dev_addr); + memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); return 0; } static int rose_open(struct net_device *dev) { + int err; + + err = rose_add_loopback_node((rose_address *)dev->dev_addr); + if (err) + return err; + netif_start_queue(dev); - rose_add_loopback_node((rose_address *)dev->dev_addr); + return 0; } @@ -115,40 +131,41 @@ static int rose_close(struct net_device *dev) return 0; } -static int rose_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t rose_xmit(struct sk_buff *skb, struct net_device *dev) { - struct net_device_stats *stats = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; if (!netif_running(dev)) { printk(KERN_ERR "ROSE: rose_xmit - called when iface is down\n"); - return 1; + return NETDEV_TX_BUSY; } dev_kfree_skb(skb); stats->tx_errors++; - return 0; + return NETDEV_TX_OK; } -static struct net_device_stats *rose_get_stats(struct net_device *dev) -{ - return netdev_priv(dev); -} +static const struct header_ops rose_header_ops = { + .create = rose_header, + .rebuild = rose_rebuild_header, +}; + +static const struct net_device_ops rose_netdev_ops = { + .ndo_open = rose_open, + .ndo_stop = rose_close, + .ndo_start_xmit = rose_xmit, + .ndo_set_mac_address = rose_set_mac_address, +}; void rose_setup(struct net_device *dev) { - SET_MODULE_OWNER(dev); dev->mtu = ROSE_MAX_PACKET_SIZE - 2; - dev->hard_start_xmit = rose_xmit; - dev->open = rose_open; - dev->stop = rose_close; + dev->netdev_ops = &rose_netdev_ops; - dev->hard_header = rose_header; + dev->header_ops = &rose_header_ops; dev->hard_header_len = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN; dev->addr_len = ROSE_ADDR_LEN; dev->type = ARPHRD_ROSE; - dev->rebuild_header = rose_rebuild_header; - dev->set_mac_address = rose_set_mac_address; /* New-style flags. */ dev->flags = IFF_NOARP; - dev->get_stats = rose_get_stats; } |
