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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [net/] [rose/] [rose_dev.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 *      ROSE release 003
3
 *
4
 *      This code REQUIRES 2.1.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
 *      ROSE 001        Jonathan(G4KLX) Cloned from nr_dev.c.
14
 */
15
 
16
#include <linux/config.h>
17
#if defined(CONFIG_ROSE) || defined(CONFIG_ROSE_MODULE)
18
#include <linux/proc_fs.h>
19
#include <linux/kernel.h>
20
#include <linux/sched.h>
21
#include <linux/interrupt.h>
22
#include <linux/fs.h>
23
#include <linux/types.h>
24
#include <linux/string.h>
25
#include <linux/socket.h>
26
#include <linux/errno.h>
27
#include <linux/fcntl.h>
28
#include <linux/in.h>
29
#include <linux/if_ether.h>     /* For the statistics structure. */
30
 
31
#include <asm/system.h>
32
#include <asm/segment.h>
33
#include <asm/io.h>
34
 
35
#include <linux/inet.h>
36
#include <linux/netdevice.h>
37
#include <linux/etherdevice.h>
38
#include <linux/if_arp.h>
39
#include <linux/skbuff.h>
40
 
41
#include <net/ip.h>
42
#include <net/arp.h>
43
 
44
#include <net/ax25.h>
45
#include <net/rose.h>
46
 
47
/*
48
 *      Only allow IP over ROSE frames through if the netrom device is up.
49
 */
50
 
51
int rose_rx_ip(struct sk_buff *skb, struct device *dev)
52
{
53
        struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
54
 
55
        if (!dev->start) {
56
                stats->rx_errors++;
57
                return 0;
58
        }
59
 
60
        stats->rx_packets++;
61
        skb->protocol = htons(ETH_P_IP);
62
 
63
        /* Spoof incoming device */
64
        skb->dev = dev;
65
 
66
        skb->h.raw = skb->data;
67
        ip_rcv(skb, skb->dev, NULL);
68
 
69
        return 1;
70
}
71
 
72
static int rose_header(struct sk_buff *skb, struct device *dev, unsigned short type,
73
        void *daddr, void *saddr, unsigned len)
74
{
75
        unsigned char *buff = skb_push(skb, ROSE_MIN_LEN + 2);
76
 
77
        *buff++ = ROSE_GFI | ROSE_Q_BIT;
78
        *buff++ = 0x00;
79
        *buff++ = ROSE_DATA;
80
        *buff++ = 0x7F;
81
        *buff++ = AX25_P_IP;
82
 
83
        if (daddr != NULL)
84
                return 37;
85
 
86
        return -37;
87
}
88
 
89
static int rose_rebuild_header(void *buff, struct device *dev,
90
        unsigned long raddr, struct sk_buff *skb)
91
{
92
        struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
93
        unsigned char *bp = (unsigned char *)buff;
94
        struct sk_buff *skbn;
95
 
96
        if (!arp_query(bp + 7, raddr, dev)) {
97
                dev_kfree_skb(skb, FREE_WRITE);
98
                return 1;
99
        }
100
 
101
        if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
102
                dev_kfree_skb(skb, FREE_WRITE);
103
                return 1;
104
        }
105
 
106
        skbn->sk = skb->sk;
107
 
108
        if (skbn->sk != NULL)
109
                atomic_add(skbn->truesize, &skbn->sk->wmem_alloc);
110
 
111
        dev_kfree_skb(skb, FREE_WRITE);
112
 
113
        if (!rose_route_frame(skbn, NULL)) {
114
                dev_kfree_skb(skbn, FREE_WRITE);
115
                stats->tx_errors++;
116
        }
117
 
118
        stats->tx_packets++;
119
 
120
        return 1;
121
}
122
 
123
static int rose_set_mac_address(struct device *dev, void *addr)
124
{
125
        struct sockaddr *sa = addr;
126
 
127
        ax25_listen_release((ax25_address *)dev->dev_addr, NULL);
128
 
129
        memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
130
 
131
        ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
132
 
133
        return 0;
134
}
135
 
136
static int rose_open(struct device *dev)
137
{
138
        dev->tbusy = 0;
139
        dev->start = 1;
140
 
141
        ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
142
 
143
        return 0;
144
}
145
 
146
static int rose_close(struct device *dev)
147
{
148
        dev->tbusy = 1;
149
        dev->start = 0;
150
 
151
        ax25_listen_release((ax25_address *)dev->dev_addr, NULL);
152
 
153
        return 0;
154
}
155
 
156
static int rose_xmit(struct sk_buff *skb, struct device *dev)
157
{
158
        struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
159
 
160
        if (skb == NULL || dev == NULL)
161
                return 0;
162
 
163
        if (!dev->start) {
164
                printk(KERN_ERR "rose: xmit call when iface is down\n");
165
                return 1;
166
        }
167
 
168
        cli();
169
 
170
        if (dev->tbusy != 0) {
171
                sti();
172
                stats->tx_errors++;
173
                return 1;
174
        }
175
 
176
        dev->tbusy = 1;
177
 
178
        sti();
179
 
180
        dev_kfree_skb(skb, FREE_WRITE);
181
 
182
        stats->tx_errors++;
183
 
184
        dev->tbusy = 0;
185
 
186
        mark_bh(NET_BH);
187
 
188
        return 0;
189
}
190
 
191
static struct enet_statistics *rose_get_stats(struct device *dev)
192
{
193
        return (struct enet_statistics *)dev->priv;
194
}
195
 
196
int rose_init(struct device *dev)
197
{
198
        int i;
199
 
200
        dev->mtu                = ROSE_MAX_PACKET_SIZE - 2;
201
        dev->tbusy              = 0;
202
        dev->hard_start_xmit    = rose_xmit;
203
        dev->open               = rose_open;
204
        dev->stop               = rose_close;
205
 
206
        dev->hard_header        = rose_header;
207
        dev->hard_header_len    = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN;
208
        dev->addr_len           = ROSE_ADDR_LEN;
209
        dev->type               = ARPHRD_ROSE;
210
        dev->rebuild_header     = rose_rebuild_header;
211
        dev->set_mac_address    = rose_set_mac_address;
212
 
213
        /* New-style flags. */
214
        dev->flags              = 0;
215
        dev->family             = AF_INET;
216
 
217
#ifdef CONFIG_INET
218
        dev->pa_addr            = in_aton("192.168.0.1");
219
        dev->pa_brdaddr         = in_aton("192.168.0.255");
220
        dev->pa_mask            = in_aton("255.255.255.0");
221
        dev->pa_alen            = 4;
222
#endif
223
 
224
        if ((dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL)) == NULL)
225
                return -ENOMEM;
226
 
227
        memset(dev->priv, 0, sizeof(struct enet_statistics));
228
 
229
        dev->get_stats = rose_get_stats;
230
 
231
        /* Fill in the generic fields of the device structure. */
232
        for (i = 0; i < DEV_NUMBUFFS; i++)
233
                skb_queue_head_init(&dev->buffs[i]);
234
 
235
        return 0;
236
};
237
 
238
#endif

powered by: WebSVN 2.1.0

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