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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [net/] [netrom/] [nr_dev.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1629 jcastillo
/*
2
 *      NET/ROM release 006
3
 *
4
 *      This code REQUIRES 1.3.0 or higher/ NET3.029
5
 *
6
 *      This module:
7
 *              This module is free software; you can redistribute it and/or
8
 *              modify it under the terms of the GNU General Public License
9
 *              as published by the Free Software Foundation; either version
10
 *              2 of the License, or (at your option) any later version.
11
 *
12
 *      History
13
 *      NET/ROM 001     Jonathan(G4KLX) Cloned from loopback.c
14
 *      NET/ROM 002     Steve Whitehouse(GW7RRM) fixed the set_mac_address
15
 *      NET/ROM 003     Jonathan(G4KLX) Put nr_rebuild_header into line with
16
 *                                      ax25_rebuild_header
17
 *      NET/ROM 004     Jonathan(G4KLX) Callsign registration with AX.25.
18
 */
19
 
20
#include <linux/config.h>
21
#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)
22
#include <linux/proc_fs.h>
23
#include <linux/kernel.h>
24
#include <linux/sched.h>
25
#include <linux/interrupt.h>
26
#include <linux/fs.h>
27
#include <linux/types.h>
28
#include <linux/string.h>
29
#include <linux/socket.h>
30
#include <linux/errno.h>
31
#include <linux/fcntl.h>
32
#include <linux/in.h>
33
#include <linux/if_ether.h>     /* For the statistics structure. */
34
 
35
#include <asm/system.h>
36
#include <asm/segment.h>
37
#include <asm/io.h>
38
 
39
#include <linux/inet.h>
40
#include <linux/netdevice.h>
41
#include <linux/etherdevice.h>
42
#include <linux/if_arp.h>
43
#include <linux/skbuff.h>
44
 
45
#include <net/ip.h>
46
#include <net/arp.h>
47
 
48
#include <net/ax25.h>
49
#include <net/netrom.h>
50
 
51
/*
52
 *      Only allow IP over NET/ROM frames through if the netrom device is up.
53
 */
54
 
55
int nr_rx_ip(struct sk_buff *skb, struct device *dev)
56
{
57
        struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
58
 
59
        if (!dev->start) {
60
                stats->rx_errors++;
61
                return 0;
62
        }
63
 
64
        stats->rx_packets++;
65
        skb->protocol = htons(ETH_P_IP);
66
 
67
        /* Spoof incoming device */
68
        skb->dev = dev;
69
 
70
        skb->h.raw = skb->data;
71
        ip_rcv(skb, skb->dev, NULL);
72
 
73
        return 1;
74
}
75
 
76
static int nr_header(struct sk_buff *skb, struct device *dev, unsigned short type,
77
        void *daddr, void *saddr, unsigned len)
78
{
79
        unsigned char *buff = skb_push(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
80
 
81
        memcpy(buff, (saddr != NULL) ? saddr : dev->dev_addr, dev->addr_len);
82
        buff[6] &= ~AX25_CBIT;
83
        buff[6] &= ~AX25_EBIT;
84
        buff[6] |= AX25_SSSID_SPARE;
85
        buff    += AX25_ADDR_LEN;
86
 
87
        if (daddr != NULL)
88
                memcpy(buff, daddr, dev->addr_len);
89
        buff[6] &= ~AX25_CBIT;
90
        buff[6] |= AX25_EBIT;
91
        buff[6] |= AX25_SSSID_SPARE;
92
        buff    += AX25_ADDR_LEN;
93
 
94
        *buff++ = sysctl_netrom_network_ttl_initialiser;
95
 
96
        *buff++ = NR_PROTO_IP;
97
        *buff++ = NR_PROTO_IP;
98
        *buff++ = 0;
99
        *buff++ = 0;
100
        *buff++ = NR_PROTOEXT;
101
 
102
        if (daddr != NULL)
103
                return 37;
104
 
105
        return -37;
106
}
107
 
108
static int nr_rebuild_header(void *buff, struct device *dev,
109
        unsigned long raddr, struct sk_buff *skb)
110
{
111
        struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
112
        unsigned char *bp = (unsigned char *)buff;
113
        struct sk_buff *skbn;
114
 
115
        if (!arp_query(bp + 7, raddr, dev)) {
116
                dev_kfree_skb(skb, FREE_WRITE);
117
                return 1;
118
        }
119
 
120
        bp[6] &= ~AX25_CBIT;
121
        bp[6] &= ~AX25_EBIT;
122
        bp[6] |= AX25_SSSID_SPARE;
123
        bp    += AX25_ADDR_LEN;
124
 
125
        bp[6] &= ~AX25_CBIT;
126
        bp[6] |= AX25_EBIT;
127
        bp[6] |= AX25_SSSID_SPARE;
128
 
129
        if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
130
                dev_kfree_skb(skb, FREE_WRITE);
131
                return 1;
132
        }
133
 
134
        skbn->sk = skb->sk;
135
 
136
        if (skbn->sk != NULL)
137
                atomic_add(skbn->truesize, &skbn->sk->wmem_alloc);
138
 
139
        dev_kfree_skb(skb, FREE_WRITE);
140
 
141
        if (!nr_route_frame(skbn, NULL)) {
142
                dev_kfree_skb(skbn, FREE_WRITE);
143
                stats->tx_errors++;
144
        }
145
 
146
        stats->tx_packets++;
147
 
148
        return 1;
149
}
150
 
151
static int nr_set_mac_address(struct device *dev, void *addr)
152
{
153
        struct sockaddr *sa = addr;
154
 
155
        ax25_listen_release((ax25_address *)dev->dev_addr, NULL);
156
 
157
        memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
158
 
159
        ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
160
 
161
        return 0;
162
}
163
 
164
static int nr_open(struct device *dev)
165
{
166
        dev->tbusy = 0;
167
        dev->start = 1;
168
 
169
        ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
170
 
171
        return 0;
172
}
173
 
174
static int nr_close(struct device *dev)
175
{
176
        dev->tbusy = 1;
177
        dev->start = 0;
178
 
179
        ax25_listen_release((ax25_address *)dev->dev_addr, NULL);
180
 
181
        return 0;
182
}
183
 
184
static int nr_xmit(struct sk_buff *skb, struct device *dev)
185
{
186
        struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
187
 
188
        if (skb == NULL || dev == NULL)
189
                return 0;
190
 
191
        if (!dev->start) {
192
                printk(KERN_ERR "netrom: xmit call when iface is down\n");
193
                return 1;
194
        }
195
 
196
        cli();
197
 
198
        if (dev->tbusy != 0) {
199
                sti();
200
                stats->tx_errors++;
201
                return 1;
202
        }
203
 
204
        dev->tbusy = 1;
205
 
206
        sti();
207
 
208
        dev_kfree_skb(skb, FREE_WRITE);
209
 
210
        stats->tx_errors++;
211
 
212
        dev->tbusy = 0;
213
 
214
        mark_bh(NET_BH);
215
 
216
        return 0;
217
}
218
 
219
static struct enet_statistics *nr_get_stats(struct device *dev)
220
{
221
        return (struct enet_statistics *)dev->priv;
222
}
223
 
224
int nr_init(struct device *dev)
225
{
226
        int i;
227
 
228
        dev->mtu                = NR_MAX_PACKET_SIZE;
229
        dev->tbusy              = 0;
230
        dev->hard_start_xmit    = nr_xmit;
231
        dev->open               = nr_open;
232
        dev->stop               = nr_close;
233
 
234
        dev->hard_header        = nr_header;
235
        dev->hard_header_len    = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + NR_NETWORK_LEN + NR_TRANSPORT_LEN;
236
        dev->addr_len           = AX25_ADDR_LEN;
237
        dev->type               = ARPHRD_NETROM;
238
        dev->rebuild_header     = nr_rebuild_header;
239
        dev->set_mac_address    = nr_set_mac_address;
240
 
241
        /* New-style flags. */
242
        dev->flags              = 0;
243
        dev->family             = AF_INET;
244
 
245
#ifdef CONFIG_INET
246
        dev->pa_addr            = in_aton("192.168.0.1");
247
        dev->pa_brdaddr         = in_aton("192.168.0.255");
248
        dev->pa_mask            = in_aton("255.255.255.0");
249
        dev->pa_alen            = 4;
250
#endif
251
 
252
        if ((dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL)) == NULL)
253
                return -ENOMEM;
254
 
255
        memset(dev->priv, 0, sizeof(struct enet_statistics));
256
 
257
        dev->get_stats = nr_get_stats;
258
 
259
        /* Fill in the generic fields of the device structure. */
260
        for (i = 0; i < DEV_NUMBUFFS; i++)
261
                skb_queue_head_init(&dev->buffs[i]);
262
 
263
        return 0;
264
};
265
 
266
#endif

powered by: WebSVN 2.1.0

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