OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [net/] [netrom/] [nr_dev.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * This program is free software; you can redistribute it and/or modify
3
 * it under the terms of the GNU General Public License as published by
4
 * the Free Software Foundation; either version 2 of the License, or
5
 * (at your option) any later version.
6
 *
7
 * Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
8
 */
9
#include <linux/module.h>
10
#include <linux/proc_fs.h>
11
#include <linux/kernel.h>
12
#include <linux/interrupt.h>
13
#include <linux/fs.h>
14
#include <linux/types.h>
15
#include <linux/sysctl.h>
16
#include <linux/string.h>
17
#include <linux/socket.h>
18
#include <linux/errno.h>
19
#include <linux/fcntl.h>
20
#include <linux/in.h>
21
#include <linux/if_ether.h>     /* For the statistics structure. */
22
 
23
#include <asm/system.h>
24
#include <asm/uaccess.h>
25
#include <asm/io.h>
26
 
27
#include <linux/inet.h>
28
#include <linux/netdevice.h>
29
#include <linux/etherdevice.h>
30
#include <linux/if_arp.h>
31
#include <linux/skbuff.h>
32
 
33
#include <net/ip.h>
34
#include <net/arp.h>
35
 
36
#include <net/ax25.h>
37
#include <net/netrom.h>
38
 
39
/*
40
 *      Only allow IP over NET/ROM frames through if the netrom device is up.
41
 */
42
 
43
int nr_rx_ip(struct sk_buff *skb, struct net_device *dev)
44
{
45
        struct net_device_stats *stats = netdev_priv(dev);
46
 
47
        if (!netif_running(dev)) {
48
                stats->rx_dropped++;
49
                return 0;
50
        }
51
 
52
        stats->rx_packets++;
53
        stats->rx_bytes += skb->len;
54
 
55
        skb->protocol = htons(ETH_P_IP);
56
 
57
        /* Spoof incoming device */
58
        skb->dev      = dev;
59
        skb->mac_header = skb->network_header;
60
        skb_reset_network_header(skb);
61
        skb->pkt_type = PACKET_HOST;
62
 
63
        netif_rx(skb);
64
 
65
        return 1;
66
}
67
 
68
#ifdef CONFIG_INET
69
 
70
static int nr_rebuild_header(struct sk_buff *skb)
71
{
72
        unsigned char *bp = skb->data;
73
 
74
        if (arp_find(bp + 7, skb))
75
                return 1;
76
 
77
        bp[6] &= ~AX25_CBIT;
78
        bp[6] &= ~AX25_EBIT;
79
        bp[6] |= AX25_SSSID_SPARE;
80
        bp    += AX25_ADDR_LEN;
81
 
82
        bp[6] &= ~AX25_CBIT;
83
        bp[6] |= AX25_EBIT;
84
        bp[6] |= AX25_SSSID_SPARE;
85
 
86
        return 0;
87
}
88
 
89
#else
90
 
91
static int nr_rebuild_header(struct sk_buff *skb)
92
{
93
        return 1;
94
}
95
 
96
#endif
97
 
98
static int nr_header(struct sk_buff *skb, struct net_device *dev,
99
                     unsigned short type,
100
                     const void *daddr, const void *saddr, unsigned len)
101
{
102
        unsigned char *buff = skb_push(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
103
 
104
        memcpy(buff, (saddr != NULL) ? saddr : dev->dev_addr, dev->addr_len);
105
        buff[6] &= ~AX25_CBIT;
106
        buff[6] &= ~AX25_EBIT;
107
        buff[6] |= AX25_SSSID_SPARE;
108
        buff    += AX25_ADDR_LEN;
109
 
110
        if (daddr != NULL)
111
                memcpy(buff, daddr, dev->addr_len);
112
        buff[6] &= ~AX25_CBIT;
113
        buff[6] |= AX25_EBIT;
114
        buff[6] |= AX25_SSSID_SPARE;
115
        buff    += AX25_ADDR_LEN;
116
 
117
        *buff++ = sysctl_netrom_network_ttl_initialiser;
118
 
119
        *buff++ = NR_PROTO_IP;
120
        *buff++ = NR_PROTO_IP;
121
        *buff++ = 0;
122
        *buff++ = 0;
123
        *buff++ = NR_PROTOEXT;
124
 
125
        if (daddr != NULL)
126
                return 37;
127
 
128
        return -37;
129
}
130
 
131
static int __must_check nr_set_mac_address(struct net_device *dev, void *addr)
132
{
133
        struct sockaddr *sa = addr;
134
        int err;
135
 
136
        if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len))
137
                return 0;
138
 
139
        if (dev->flags & IFF_UP) {
140
                err = ax25_listen_register((ax25_address *)sa->sa_data, NULL);
141
                if (err)
142
                        return err;
143
 
144
                ax25_listen_release((ax25_address *)dev->dev_addr, NULL);
145
        }
146
 
147
        memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
148
 
149
        return 0;
150
}
151
 
152
static int nr_open(struct net_device *dev)
153
{
154
        int err;
155
 
156
        err = ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
157
        if (err)
158
                return err;
159
 
160
        netif_start_queue(dev);
161
 
162
        return 0;
163
}
164
 
165
static int nr_close(struct net_device *dev)
166
{
167
        ax25_listen_release((ax25_address *)dev->dev_addr, NULL);
168
        netif_stop_queue(dev);
169
        return 0;
170
}
171
 
172
static int nr_xmit(struct sk_buff *skb, struct net_device *dev)
173
{
174
        struct nr_private *nr = netdev_priv(dev);
175
        struct net_device_stats *stats = &nr->stats;
176
        unsigned int len = skb->len;
177
 
178
        if (!nr_route_frame(skb, NULL)) {
179
                kfree_skb(skb);
180
                stats->tx_errors++;
181
                return 0;
182
        }
183
 
184
        stats->tx_packets++;
185
        stats->tx_bytes += len;
186
 
187
        return 0;
188
}
189
 
190
static struct net_device_stats *nr_get_stats(struct net_device *dev)
191
{
192
        struct nr_private *nr = netdev_priv(dev);
193
 
194
        return &nr->stats;
195
}
196
 
197
static const struct header_ops nr_header_ops = {
198
        .create = nr_header,
199
        .rebuild= nr_rebuild_header,
200
};
201
 
202
 
203
void nr_setup(struct net_device *dev)
204
{
205
        dev->mtu                = NR_MAX_PACKET_SIZE;
206
        dev->hard_start_xmit    = nr_xmit;
207
        dev->open               = nr_open;
208
        dev->stop               = nr_close;
209
 
210
        dev->header_ops         = &nr_header_ops;
211
        dev->hard_header_len    = NR_NETWORK_LEN + NR_TRANSPORT_LEN;
212
        dev->addr_len           = AX25_ADDR_LEN;
213
        dev->type               = ARPHRD_NETROM;
214
        dev->set_mac_address    = nr_set_mac_address;
215
 
216
        /* New-style flags. */
217
        dev->flags              = IFF_NOARP;
218
 
219
        dev->get_stats          = nr_get_stats;
220
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.