]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - net/phonet/pep-gprs.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6-omap-h63xx.git] / net / phonet / pep-gprs.c
1 /*
2  * File: pep-gprs.c
3  *
4  * GPRS over Phonet pipe end point socket
5  *
6  * Copyright (C) 2008 Nokia Corporation.
7  *
8  * Author: RĂ©mi Denis-Courmont <remi.denis-courmont@nokia.com>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * version 2 as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22  * 02110-1301 USA
23  */
24
25 #include <linux/kernel.h>
26 #include <linux/netdevice.h>
27 #include <linux/if_ether.h>
28 #include <linux/if_arp.h>
29 #include <net/sock.h>
30
31 #include <linux/if_phonet.h>
32 #include <net/tcp_states.h>
33 #include <net/phonet/gprs.h>
34
35 #define GPRS_DEFAULT_MTU 1400
36
37 struct gprs_dev {
38         struct sock             *sk;
39         void                    (*old_state_change)(struct sock *);
40         void                    (*old_data_ready)(struct sock *, int);
41         void                    (*old_write_space)(struct sock *);
42
43         struct net_device       *net;
44
45         struct sk_buff_head     tx_queue;
46         struct work_struct      tx_work;
47         spinlock_t              tx_lock;
48         unsigned                tx_max;
49 };
50
51 static __be16 gprs_type_trans(struct sk_buff *skb)
52 {
53         const u8 *pvfc;
54         u8 buf;
55
56         pvfc = skb_header_pointer(skb, 0, 1, &buf);
57         if (!pvfc)
58                 return htons(0);
59         /* Look at IP version field */
60         switch (*pvfc >> 4) {
61         case 4:
62                 return htons(ETH_P_IP);
63         case 6:
64                 return htons(ETH_P_IPV6);
65         }
66         return htons(0);
67 }
68
69 /*
70  * Socket callbacks
71  */
72
73 static void gprs_state_change(struct sock *sk)
74 {
75         struct gprs_dev *dev = sk->sk_user_data;
76
77         if (sk->sk_state == TCP_CLOSE_WAIT) {
78                 netif_stop_queue(dev->net);
79                 netif_carrier_off(dev->net);
80         }
81 }
82
83 static int gprs_recv(struct gprs_dev *dev, struct sk_buff *skb)
84 {
85         struct net_device *net = dev->net;
86         int err = 0;
87         __be16 protocol = gprs_type_trans(skb);
88
89         if (!protocol) {
90                 err = -EINVAL;
91                 goto drop;
92         }
93
94         if (likely(skb_headroom(skb) & 3)) {
95                 struct sk_buff *rskb, *fs;
96                 int flen = 0;
97
98                 /* Phonet Pipe data header is misaligned (3 bytes),
99                  * so wrap the IP packet as a single fragment of an head-less
100                  * socket buffer. The network stack will pull what it needs,
101                  * but at least, the whole IP payload is not memcpy'd. */
102                 rskb = netdev_alloc_skb(net, 0);
103                 if (!rskb) {
104                         err = -ENOBUFS;
105                         goto drop;
106                 }
107                 skb_shinfo(rskb)->frag_list = skb;
108                 rskb->len += skb->len;
109                 rskb->data_len += rskb->len;
110                 rskb->truesize += rskb->len;
111
112                 /* Avoid nested fragments */
113                 for (fs = skb_shinfo(skb)->frag_list; fs; fs = fs->next)
114                         flen += fs->len;
115                 skb->next = skb_shinfo(skb)->frag_list;
116                 skb_shinfo(skb)->frag_list = NULL;
117                 skb->len -= flen;
118                 skb->data_len -= flen;
119                 skb->truesize -= flen;
120
121                 skb = rskb;
122         }
123
124         skb->protocol = protocol;
125         skb_reset_mac_header(skb);
126         skb->dev = net;
127
128         if (likely(net->flags & IFF_UP)) {
129                 net->stats.rx_packets++;
130                 net->stats.rx_bytes += skb->len;
131                 netif_rx(skb);
132                 skb = NULL;
133         } else
134                 err = -ENODEV;
135
136 drop:
137         if (skb) {
138                 dev_kfree_skb(skb);
139                 net->stats.rx_dropped++;
140         }
141         return err;
142 }
143
144 static void gprs_data_ready(struct sock *sk, int len)
145 {
146         struct gprs_dev *dev = sk->sk_user_data;
147         struct sk_buff *skb;
148
149         while ((skb = pep_read(sk)) != NULL) {
150                 skb_orphan(skb);
151                 gprs_recv(dev, skb);
152         }
153 }
154
155 static void gprs_write_space(struct sock *sk)
156 {
157         struct gprs_dev *dev = sk->sk_user_data;
158         struct net_device *net = dev->net;
159         unsigned credits = pep_writeable(sk);
160
161         spin_lock_bh(&dev->tx_lock);
162         dev->tx_max = credits;
163         if (credits > skb_queue_len(&dev->tx_queue) && netif_running(net))
164                 netif_wake_queue(net);
165         spin_unlock_bh(&dev->tx_lock);
166 }
167
168 /*
169  * Network device callbacks
170  */
171
172 static int gprs_open(struct net_device *dev)
173 {
174         struct gprs_dev *gp = netdev_priv(dev);
175
176         gprs_write_space(gp->sk);
177         return 0;
178 }
179
180 static int gprs_close(struct net_device *dev)
181 {
182         struct gprs_dev *gp = netdev_priv(dev);
183
184         netif_stop_queue(dev);
185         flush_work(&gp->tx_work);
186         return 0;
187 }
188
189 static int gprs_xmit(struct sk_buff *skb, struct net_device *net)
190 {
191         struct gprs_dev *dev = netdev_priv(net);
192
193         switch (skb->protocol) {
194         case  htons(ETH_P_IP):
195         case  htons(ETH_P_IPV6):
196                 break;
197         default:
198                 dev_kfree_skb(skb);
199                 return 0;
200         }
201
202         spin_lock(&dev->tx_lock);
203         if (likely(skb_queue_len(&dev->tx_queue) < dev->tx_max)) {
204                 skb_queue_tail(&dev->tx_queue, skb);
205                 skb = NULL;
206         }
207         if (skb_queue_len(&dev->tx_queue) >= dev->tx_max)
208                 netif_stop_queue(net);
209         spin_unlock(&dev->tx_lock);
210
211         schedule_work(&dev->tx_work);
212         if (unlikely(skb))
213                 dev_kfree_skb(skb);
214         return 0;
215 }
216
217 static void gprs_tx(struct work_struct *work)
218 {
219         struct gprs_dev *dev = container_of(work, struct gprs_dev, tx_work);
220         struct net_device *net = dev->net;
221         struct sock *sk = dev->sk;
222         struct sk_buff *skb;
223
224         while ((skb = skb_dequeue(&dev->tx_queue)) != NULL) {
225                 int err;
226
227                 net->stats.tx_bytes += skb->len;
228                 net->stats.tx_packets++;
229
230                 skb_orphan(skb);
231                 skb_set_owner_w(skb, sk);
232
233                 lock_sock(sk);
234                 err = pep_write(sk, skb);
235                 if (err) {
236                         LIMIT_NETDEBUG(KERN_WARNING"%s: TX error (%d)\n",
237                                         net->name, err);
238                         net->stats.tx_aborted_errors++;
239                         net->stats.tx_errors++;
240                 }
241                 release_sock(sk);
242         }
243
244         lock_sock(sk);
245         gprs_write_space(sk);
246         release_sock(sk);
247 }
248
249 static int gprs_set_mtu(struct net_device *net, int new_mtu)
250 {
251         if ((new_mtu < 576) || (new_mtu > (PHONET_MAX_MTU - 11)))
252                 return -EINVAL;
253
254         net->mtu = new_mtu;
255         return 0;
256 }
257
258 static void gprs_setup(struct net_device *net)
259 {
260         net->features           = NETIF_F_FRAGLIST;
261         net->type               = ARPHRD_NONE;
262         net->flags              = IFF_POINTOPOINT | IFF_NOARP;
263         net->mtu                = GPRS_DEFAULT_MTU;
264         net->hard_header_len    = 0;
265         net->addr_len           = 0;
266         net->tx_queue_len       = 10;
267
268         net->destructor         = free_netdev;
269         net->open               = gprs_open;
270         net->stop               = gprs_close;
271         net->hard_start_xmit    = gprs_xmit; /* mandatory */
272         net->change_mtu         = gprs_set_mtu;
273 }
274
275 /*
276  * External interface
277  */
278
279 /*
280  * Attach a GPRS interface to a datagram socket.
281  * Returns the interface index on success, negative error code on error.
282  */
283 int gprs_attach(struct sock *sk)
284 {
285         static const char ifname[] = "gprs%d";
286         struct gprs_dev *dev;
287         struct net_device *net;
288         int err;
289
290         if (unlikely(sk->sk_type == SOCK_STREAM))
291                 return -EINVAL; /* need packet boundaries */
292
293         /* Create net device */
294         net = alloc_netdev(sizeof(*dev), ifname, gprs_setup);
295         if (!net)
296                 return -ENOMEM;
297         dev = netdev_priv(net);
298         dev->net = net;
299         dev->tx_max = 0;
300         spin_lock_init(&dev->tx_lock);
301         skb_queue_head_init(&dev->tx_queue);
302         INIT_WORK(&dev->tx_work, gprs_tx);
303
304         netif_stop_queue(net);
305         err = register_netdev(net);
306         if (err) {
307                 free_netdev(net);
308                 return err;
309         }
310
311         lock_sock(sk);
312         if (unlikely(sk->sk_user_data)) {
313                 err = -EBUSY;
314                 goto out_rel;
315         }
316         if (unlikely((1 << sk->sk_state & (TCPF_CLOSE|TCPF_LISTEN)) ||
317                         sock_flag(sk, SOCK_DEAD))) {
318                 err = -EINVAL;
319                 goto out_rel;
320         }
321         sk->sk_user_data        = dev;
322         dev->old_state_change   = sk->sk_state_change;
323         dev->old_data_ready     = sk->sk_data_ready;
324         dev->old_write_space    = sk->sk_write_space;
325         sk->sk_state_change     = gprs_state_change;
326         sk->sk_data_ready       = gprs_data_ready;
327         sk->sk_write_space      = gprs_write_space;
328         release_sock(sk);
329
330         sock_hold(sk);
331         dev->sk = sk;
332
333         printk(KERN_DEBUG"%s: attached\n", net->name);
334         return net->ifindex;
335
336 out_rel:
337         release_sock(sk);
338         unregister_netdev(net);
339         return err;
340 }
341
342 void gprs_detach(struct sock *sk)
343 {
344         struct gprs_dev *dev = sk->sk_user_data;
345         struct net_device *net = dev->net;
346
347         lock_sock(sk);
348         sk->sk_user_data        = NULL;
349         sk->sk_state_change     = dev->old_state_change;
350         sk->sk_data_ready       = dev->old_data_ready;
351         sk->sk_write_space      = dev->old_write_space;
352         release_sock(sk);
353
354         printk(KERN_DEBUG"%s: detached\n", net->name);
355         unregister_netdev(net);
356         sock_put(sk);
357 }