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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [net/] [rose/] [rose_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 (C) 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>
22
 
23
#include <asm/system.h>
24
#include <asm/io.h>
25
 
26
#include <linux/inet.h>
27
#include <linux/netdevice.h>
28
#include <linux/etherdevice.h>
29
#include <linux/if_arp.h>
30
#include <linux/skbuff.h>
31
 
32
#include <net/ip.h>
33
#include <net/arp.h>
34
 
35
#include <net/ax25.h>
36
#include <net/rose.h>
37
 
38
static int rose_header(struct sk_buff *skb, struct net_device *dev,
39
                       unsigned short type,
40
                       const void *daddr, const void *saddr, unsigned len)
41
{
42
        unsigned char *buff = skb_push(skb, ROSE_MIN_LEN + 2);
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_rebuild_header(struct sk_buff *skb)
57
{
58
#ifdef CONFIG_INET
59
        struct net_device *dev = skb->dev;
60
        struct net_device_stats *stats = netdev_priv(dev);
61
        unsigned char *bp = (unsigned char *)skb->data;
62
        struct sk_buff *skbn;
63
        unsigned int len;
64
 
65
        if (arp_find(bp + 7, skb)) {
66
                return 1;
67
        }
68
 
69
        if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
70
                kfree_skb(skb);
71
                return 1;
72
        }
73
 
74
        if (skb->sk != NULL)
75
                skb_set_owner_w(skbn, skb->sk);
76
 
77
        kfree_skb(skb);
78
 
79
        len = skbn->len;
80
 
81
        if (!rose_route_frame(skbn, NULL)) {
82
                kfree_skb(skbn);
83
                stats->tx_errors++;
84
                return 1;
85
        }
86
 
87
        stats->tx_packets++;
88
        stats->tx_bytes += len;
89
#endif
90
        return 1;
91
}
92
 
93
static int rose_set_mac_address(struct net_device *dev, void *addr)
94
{
95
        struct sockaddr *sa = addr;
96
        int err;
97
 
98
        if (!memcpy(dev->dev_addr, sa->sa_data, dev->addr_len))
99
                return 0;
100
 
101
        if (dev->flags & IFF_UP) {
102
                err = rose_add_loopback_node((rose_address *)dev->dev_addr);
103
                if (err)
104
                        return err;
105
 
106
                rose_del_loopback_node((rose_address *)dev->dev_addr);
107
        }
108
 
109
        memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
110
 
111
        return 0;
112
}
113
 
114
static int rose_open(struct net_device *dev)
115
{
116
        int err;
117
 
118
        err = rose_add_loopback_node((rose_address *)dev->dev_addr);
119
        if (err)
120
                return err;
121
 
122
        netif_start_queue(dev);
123
 
124
        return 0;
125
}
126
 
127
static int rose_close(struct net_device *dev)
128
{
129
        netif_stop_queue(dev);
130
        rose_del_loopback_node((rose_address *)dev->dev_addr);
131
        return 0;
132
}
133
 
134
static int rose_xmit(struct sk_buff *skb, struct net_device *dev)
135
{
136
        struct net_device_stats *stats = netdev_priv(dev);
137
 
138
        if (!netif_running(dev)) {
139
                printk(KERN_ERR "ROSE: rose_xmit - called when iface is down\n");
140
                return 1;
141
        }
142
        dev_kfree_skb(skb);
143
        stats->tx_errors++;
144
        return 0;
145
}
146
 
147
static struct net_device_stats *rose_get_stats(struct net_device *dev)
148
{
149
        return netdev_priv(dev);
150
}
151
 
152
static const struct header_ops rose_header_ops = {
153
        .create = rose_header,
154
        .rebuild= rose_rebuild_header,
155
};
156
 
157
void rose_setup(struct net_device *dev)
158
{
159
        dev->mtu                = ROSE_MAX_PACKET_SIZE - 2;
160
        dev->hard_start_xmit    = rose_xmit;
161
        dev->open               = rose_open;
162
        dev->stop               = rose_close;
163
 
164
        dev->header_ops         = &rose_header_ops;
165
        dev->hard_header_len    = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + ROSE_MIN_LEN;
166
        dev->addr_len           = ROSE_ADDR_LEN;
167
        dev->type               = ARPHRD_ROSE;
168
        dev->set_mac_address    = rose_set_mac_address;
169
 
170
        /* New-style flags. */
171
        dev->flags              = IFF_NOARP;
172
        dev->get_stats = rose_get_stats;
173
}

powered by: WebSVN 2.1.0

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