Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *
0004  * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
0005  */
0006 #include <linux/module.h>
0007 #include <linux/proc_fs.h>
0008 #include <linux/kernel.h>
0009 #include <linux/interrupt.h>
0010 #include <linux/fs.h>
0011 #include <linux/types.h>
0012 #include <linux/sysctl.h>
0013 #include <linux/string.h>
0014 #include <linux/socket.h>
0015 #include <linux/errno.h>
0016 #include <linux/fcntl.h>
0017 #include <linux/in.h>
0018 #include <linux/if_ether.h>
0019 #include <linux/slab.h>
0020 
0021 #include <asm/io.h>
0022 
0023 #include <linux/inet.h>
0024 #include <linux/netdevice.h>
0025 #include <linux/etherdevice.h>
0026 #include <linux/if_arp.h>
0027 #include <linux/skbuff.h>
0028 
0029 #include <net/ip.h>
0030 #include <net/arp.h>
0031 
0032 #include <net/ax25.h>
0033 #include <net/rose.h>
0034 
0035 static int rose_header(struct sk_buff *skb, struct net_device *dev,
0036                unsigned short type,
0037                const void *daddr, const void *saddr, unsigned int len)
0038 {
0039     unsigned char *buff = skb_push(skb, ROSE_MIN_LEN + 2);
0040 
0041     if (daddr)
0042         memcpy(buff + 7, daddr, dev->addr_len);
0043 
0044     *buff++ = ROSE_GFI | ROSE_Q_BIT;
0045     *buff++ = 0x00;
0046     *buff++ = ROSE_DATA;
0047     *buff++ = 0x7F;
0048     *buff++ = AX25_P_IP;
0049 
0050     if (daddr != NULL)
0051         return 37;
0052 
0053     return -37;
0054 }
0055 
0056 static int rose_set_mac_address(struct net_device *dev, void *addr)
0057 {
0058     struct sockaddr *sa = addr;
0059     int err;
0060 
0061     if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len))
0062         return 0;
0063 
0064     if (dev->flags & IFF_UP) {
0065         err = rose_add_loopback_node((rose_address *)sa->sa_data);
0066         if (err)
0067             return err;
0068 
0069         rose_del_loopback_node((const rose_address *)dev->dev_addr);
0070     }
0071 
0072     dev_addr_set(dev, sa->sa_data);
0073 
0074     return 0;
0075 }
0076 
0077 static int rose_open(struct net_device *dev)
0078 {
0079     int err;
0080 
0081     err = rose_add_loopback_node((const rose_address *)dev->dev_addr);
0082     if (err)
0083         return err;
0084 
0085     netif_start_queue(dev);
0086 
0087     return 0;
0088 }
0089 
0090 static int rose_close(struct net_device *dev)
0091 {
0092     netif_stop_queue(dev);
0093     rose_del_loopback_node((const rose_address *)dev->dev_addr);
0094     return 0;
0095 }
0096 
0097 static netdev_tx_t rose_xmit(struct sk_buff *skb, struct net_device *dev)
0098 {
0099     struct net_device_stats *stats = &dev->stats;
0100     unsigned int len = skb->len;
0101 
0102     if (!netif_running(dev)) {
0103         printk(KERN_ERR "ROSE: rose_xmit - called when iface is down\n");
0104         return NETDEV_TX_BUSY;
0105     }
0106 
0107     if (!rose_route_frame(skb, NULL)) {
0108         dev_kfree_skb(skb);
0109         stats->tx_errors++;
0110         return NETDEV_TX_OK;
0111     }
0112 
0113     stats->tx_packets++;
0114     stats->tx_bytes += len;
0115     return NETDEV_TX_OK;
0116 }
0117 
0118 static const struct header_ops rose_header_ops = {
0119     .create = rose_header,
0120 };
0121 
0122 static const struct net_device_ops rose_netdev_ops = {
0123     .ndo_open       = rose_open,
0124     .ndo_stop       = rose_close,
0125     .ndo_start_xmit     = rose_xmit,
0126     .ndo_set_mac_address    = rose_set_mac_address,
0127 };
0128 
0129 void rose_setup(struct net_device *dev)
0130 {
0131     dev->mtu        = ROSE_MAX_PACKET_SIZE - 2;
0132     dev->netdev_ops     = &rose_netdev_ops;
0133 
0134     dev->header_ops     = &rose_header_ops;
0135     dev->hard_header_len    = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN;
0136     dev->addr_len       = ROSE_ADDR_LEN;
0137     dev->type       = ARPHRD_ROSE;
0138 
0139     /* New-style flags. */
0140     dev->flags      = IFF_NOARP;
0141 }