root/net/rose/rose_dev.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rose_header
  2. rose_set_mac_address
  3. rose_open
  4. rose_close
  5. rose_xmit
  6. rose_setup

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *
   4  * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
   5  */
   6 #include <linux/module.h>
   7 #include <linux/proc_fs.h>
   8 #include <linux/kernel.h>
   9 #include <linux/interrupt.h>
  10 #include <linux/fs.h>
  11 #include <linux/types.h>
  12 #include <linux/sysctl.h>
  13 #include <linux/string.h>
  14 #include <linux/socket.h>
  15 #include <linux/errno.h>
  16 #include <linux/fcntl.h>
  17 #include <linux/in.h>
  18 #include <linux/if_ether.h>
  19 #include <linux/slab.h>
  20 
  21 #include <asm/io.h>
  22 
  23 #include <linux/inet.h>
  24 #include <linux/netdevice.h>
  25 #include <linux/etherdevice.h>
  26 #include <linux/if_arp.h>
  27 #include <linux/skbuff.h>
  28 
  29 #include <net/ip.h>
  30 #include <net/arp.h>
  31 
  32 #include <net/ax25.h>
  33 #include <net/rose.h>
  34 
  35 static int rose_header(struct sk_buff *skb, struct net_device *dev,
  36                        unsigned short type,
  37                        const void *daddr, const void *saddr, unsigned int len)
  38 {
  39         unsigned char *buff = skb_push(skb, ROSE_MIN_LEN + 2);
  40 
  41         if (daddr)
  42                 memcpy(buff + 7, daddr, dev->addr_len);
  43 
  44         *buff++ = ROSE_GFI | ROSE_Q_BIT;
  45         *buff++ = 0x00;
  46         *buff++ = ROSE_DATA;
  47         *buff++ = 0x7F;
  48         *buff++ = AX25_P_IP;
  49 
  50         if (daddr != NULL)
  51                 return 37;
  52 
  53         return -37;
  54 }
  55 
  56 static int rose_set_mac_address(struct net_device *dev, void *addr)
  57 {
  58         struct sockaddr *sa = addr;
  59         int err;
  60 
  61         if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len))
  62                 return 0;
  63 
  64         if (dev->flags & IFF_UP) {
  65                 err = rose_add_loopback_node((rose_address *)sa->sa_data);
  66                 if (err)
  67                         return err;
  68 
  69                 rose_del_loopback_node((rose_address *)dev->dev_addr);
  70         }
  71 
  72         memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
  73 
  74         return 0;
  75 }
  76 
  77 static int rose_open(struct net_device *dev)
  78 {
  79         int err;
  80 
  81         err = rose_add_loopback_node((rose_address *)dev->dev_addr);
  82         if (err)
  83                 return err;
  84 
  85         netif_start_queue(dev);
  86 
  87         return 0;
  88 }
  89 
  90 static int rose_close(struct net_device *dev)
  91 {
  92         netif_stop_queue(dev);
  93         rose_del_loopback_node((rose_address *)dev->dev_addr);
  94         return 0;
  95 }
  96 
  97 static netdev_tx_t rose_xmit(struct sk_buff *skb, struct net_device *dev)
  98 {
  99         struct net_device_stats *stats = &dev->stats;
 100         unsigned int len = skb->len;
 101 
 102         if (!netif_running(dev)) {
 103                 printk(KERN_ERR "ROSE: rose_xmit - called when iface is down\n");
 104                 return NETDEV_TX_BUSY;
 105         }
 106 
 107         if (!rose_route_frame(skb, NULL)) {
 108                 dev_kfree_skb(skb);
 109                 stats->tx_errors++;
 110                 return NETDEV_TX_OK;
 111         }
 112 
 113         stats->tx_packets++;
 114         stats->tx_bytes += len;
 115         return NETDEV_TX_OK;
 116 }
 117 
 118 static const struct header_ops rose_header_ops = {
 119         .create = rose_header,
 120 };
 121 
 122 static const struct net_device_ops rose_netdev_ops = {
 123         .ndo_open               = rose_open,
 124         .ndo_stop               = rose_close,
 125         .ndo_start_xmit         = rose_xmit,
 126         .ndo_set_mac_address    = rose_set_mac_address,
 127 };
 128 
 129 void rose_setup(struct net_device *dev)
 130 {
 131         dev->mtu                = ROSE_MAX_PACKET_SIZE - 2;
 132         dev->netdev_ops         = &rose_netdev_ops;
 133 
 134         dev->header_ops         = &rose_header_ops;
 135         dev->hard_header_len    = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN;
 136         dev->addr_len           = ROSE_ADDR_LEN;
 137         dev->type               = ARPHRD_ROSE;
 138 
 139         /* New-style flags. */
 140         dev->flags              = IFF_NOARP;
 141 }

/* [<][>][^][v][top][bottom][index][help] */