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