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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [net/] [802/] [psnap.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *      SNAP data link layer. Derived from 802.2
3
 *
4
 *              Alan Cox <Alan.Cox@linux.org>,
5
 *              from the 802.2 layer by Greg Page.
6
 *              Merged in additions from Greg Page's psnap.c.
7
 *
8
 *              This program is free software; you can redistribute it and/or
9
 *              modify it under the terms of the GNU General Public License
10
 *              as published by the Free Software Foundation; either version
11
 *              2 of the License, or (at your option) any later version.
12
 */
13
 
14
#include <linux/module.h>
15
#include <linux/netdevice.h>
16
#include <linux/skbuff.h>
17
#include <net/datalink.h>
18
#include <net/llc.h>
19
#include <net/psnap.h>
20
#include <linux/mm.h>
21
#include <linux/in.h>
22
#include <linux/init.h>
23
 
24
static LIST_HEAD(snap_list);
25
static DEFINE_SPINLOCK(snap_lock);
26
static struct llc_sap *snap_sap;
27
 
28
/*
29
 *      Find a snap client by matching the 5 bytes.
30
 */
31
static struct datalink_proto *find_snap_client(unsigned char *desc)
32
{
33
        struct list_head *entry;
34
        struct datalink_proto *proto = NULL, *p;
35
 
36
        list_for_each_rcu(entry, &snap_list) {
37
                p = list_entry(entry, struct datalink_proto, node);
38
                if (!memcmp(p->type, desc, 5)) {
39
                        proto = p;
40
                        break;
41
                }
42
        }
43
        return proto;
44
}
45
 
46
/*
47
 *      A SNAP packet has arrived
48
 */
49
static int snap_rcv(struct sk_buff *skb, struct net_device *dev,
50
                    struct packet_type *pt, struct net_device *orig_dev)
51
{
52
        int rc = 1;
53
        struct datalink_proto *proto;
54
        static struct packet_type snap_packet_type = {
55
                .type = __constant_htons(ETH_P_SNAP),
56
        };
57
 
58
        if (unlikely(!pskb_may_pull(skb, 5)))
59
                goto drop;
60
 
61
        rcu_read_lock();
62
        proto = find_snap_client(skb_transport_header(skb));
63
        if (proto) {
64
                /* Pass the frame on. */
65
                skb->transport_header += 5;
66
                skb_pull_rcsum(skb, 5);
67
                rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev);
68
        }
69
        rcu_read_unlock();
70
 
71
        if (unlikely(!proto))
72
                goto drop;
73
 
74
out:
75
        return rc;
76
 
77
drop:
78
        kfree_skb(skb);
79
        goto out;
80
}
81
 
82
/*
83
 *      Put a SNAP header on a frame and pass to 802.2
84
 */
85
static int snap_request(struct datalink_proto *dl,
86
                        struct sk_buff *skb, u8 *dest)
87
{
88
        memcpy(skb_push(skb, 5), dl->type, 5);
89
        llc_build_and_send_ui_pkt(snap_sap, skb, dest, snap_sap->laddr.lsap);
90
        return 0;
91
}
92
 
93
/*
94
 *      Set up the SNAP layer
95
 */
96
EXPORT_SYMBOL(register_snap_client);
97
EXPORT_SYMBOL(unregister_snap_client);
98
 
99
static char snap_err_msg[] __initdata =
100
        KERN_CRIT "SNAP - unable to register with 802.2\n";
101
 
102
static int __init snap_init(void)
103
{
104
        snap_sap = llc_sap_open(0xAA, snap_rcv);
105
 
106
        if (!snap_sap)
107
                printk(snap_err_msg);
108
 
109
        return 0;
110
}
111
 
112
module_init(snap_init);
113
 
114
static void __exit snap_exit(void)
115
{
116
        llc_sap_put(snap_sap);
117
}
118
 
119
module_exit(snap_exit);
120
 
121
 
122
/*
123
 *      Register SNAP clients. We don't yet use this for IP.
124
 */
125
struct datalink_proto *register_snap_client(unsigned char *desc,
126
                                            int (*rcvfunc)(struct sk_buff *,
127
                                                           struct net_device *,
128
                                                           struct packet_type *,
129
                                                           struct net_device *))
130
{
131
        struct datalink_proto *proto = NULL;
132
 
133
        spin_lock_bh(&snap_lock);
134
 
135
        if (find_snap_client(desc))
136
                goto out;
137
 
138
        proto = kmalloc(sizeof(*proto), GFP_ATOMIC);
139
        if (proto) {
140
                memcpy(proto->type, desc,5);
141
                proto->rcvfunc          = rcvfunc;
142
                proto->header_length    = 5 + 3; /* snap + 802.2 */
143
                proto->request          = snap_request;
144
                list_add_rcu(&proto->node, &snap_list);
145
        }
146
out:
147
        spin_unlock_bh(&snap_lock);
148
 
149
        synchronize_net();
150
        return proto;
151
}
152
 
153
/*
154
 *      Unregister SNAP clients. Protocols no longer want to play with us ...
155
 */
156
void unregister_snap_client(struct datalink_proto *proto)
157
{
158
        spin_lock_bh(&snap_lock);
159
        list_del_rcu(&proto->node);
160
        spin_unlock_bh(&snap_lock);
161
 
162
        synchronize_net();
163
 
164
        kfree(proto);
165
}
166
 
167
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

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