upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / uwb / wlp / txrx.c
1 /*
2  * WiMedia Logical Link Control Protocol (WLP)
3  * Message exchange infrastructure
4  *
5  * Copyright (C) 2007 Intel Corporation
6  * Reinette Chatre <reinette.chatre@intel.com>
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 version
10  * 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301, USA.
21  *
22  *
23  * FIXME: Docs
24  *
25  */
26
27 #include <linux/etherdevice.h>
28 #include <linux/slab.h>
29 #include <linux/wlp.h>
30
31 #include "wlp-internal.h"
32
33 /*
34  * Direct incoming association msg to correct parsing routine
35  *
36  * We only expect D1, E1, C1, C3 messages as new. All other incoming
37  * association messages should form part of an established session that is
38  * handled elsewhere.
39  * The handling of these messages often require calling sleeping functions
40  * - this cannot be done in interrupt context. We use the kernel's
41  * workqueue to handle these messages.
42  */
43 static
44 void wlp_direct_assoc_frame(struct wlp *wlp, struct sk_buff *skb,
45                            struct uwb_dev_addr *src)
46 {
47         struct device *dev = &wlp->rc->uwb_dev.dev;
48         struct wlp_frame_assoc *assoc = (void *) skb->data;
49         struct wlp_assoc_frame_ctx *frame_ctx;
50
51         frame_ctx = kmalloc(sizeof(*frame_ctx), GFP_ATOMIC);
52         if (frame_ctx == NULL) {
53                 dev_err(dev, "WLP: Unable to allocate memory for association "
54                         "frame handling.\n");
55                 kfree_skb(skb);
56                 return;
57         }
58         frame_ctx->wlp = wlp;
59         frame_ctx->skb = skb;
60         frame_ctx->src = *src;
61         switch (assoc->type) {
62         case WLP_ASSOC_D1:
63                 INIT_WORK(&frame_ctx->ws, wlp_handle_d1_frame);
64                 schedule_work(&frame_ctx->ws);
65                 break;
66         case WLP_ASSOC_E1:
67                 kfree_skb(skb); /* Temporary until we handle it */
68                 kfree(frame_ctx); /* Temporary until we handle it */
69                 break;
70         case WLP_ASSOC_C1:
71                 INIT_WORK(&frame_ctx->ws, wlp_handle_c1_frame);
72                 schedule_work(&frame_ctx->ws);
73                 break;
74         case WLP_ASSOC_C3:
75                 INIT_WORK(&frame_ctx->ws, wlp_handle_c3_frame);
76                 schedule_work(&frame_ctx->ws);
77                 break;
78         default:
79                 dev_err(dev, "Received unexpected association frame. "
80                         "Type = %d \n", assoc->type);
81                 kfree_skb(skb);
82                 kfree(frame_ctx);
83                 break;
84         }
85 }
86
87 /*
88  * Process incoming association frame
89  *
90  * Although it could be possible to deal with some incoming association
91  * messages without creating a new session we are keeping things simple. We
92  * do not accept new association messages if there is a session in progress
93  * and the messages do not belong to that session.
94  *
95  * If an association message arrives that causes the creation of a session
96  * (WLP_ASSOC_E1) while we are in the process of creating a session then we
97  * rely on the neighbor mutex to protect the data. That is, the new session
98  * will not be started until the previous is completed.
99  */
100 static
101 void wlp_receive_assoc_frame(struct wlp *wlp, struct sk_buff *skb,
102                              struct uwb_dev_addr *src)
103 {
104         struct device *dev = &wlp->rc->uwb_dev.dev;
105         struct wlp_frame_assoc *assoc = (void *) skb->data;
106         struct wlp_session *session = wlp->session;
107         u8 version;
108
109         if (wlp_get_version(wlp, &assoc->version, &version,
110                             sizeof(assoc->version)) < 0)
111                 goto error;
112         if (version != WLP_VERSION) {
113                 dev_err(dev, "Unsupported WLP version in association "
114                         "message.\n");
115                 goto error;
116         }
117         if (session != NULL) {
118                 /* Function that created this session is still holding the
119                  * &wlp->mutex to protect this session. */
120                 if (assoc->type == session->exp_message ||
121                     assoc->type == WLP_ASSOC_F0) {
122                         if (!memcmp(&session->neighbor_addr, src,
123                                    sizeof(*src))) {
124                                 session->data = skb;
125                                 (session->cb)(wlp);
126                         } else {
127                                 dev_err(dev, "Received expected message from "
128                                         "unexpected source.  Expected message "
129                                         "%d or F0 from %02x:%02x, but received "
130                                         "it from %02x:%02x. Dropping.\n",
131                                         session->exp_message,
132                                         session->neighbor_addr.data[1],
133                                         session->neighbor_addr.data[0],
134                                         src->data[1], src->data[0]);
135                                 goto error;
136                         }
137                 } else {
138                         dev_err(dev, "Association already in progress. "
139                                 "Dropping.\n");
140                         goto error;
141                 }
142         } else {
143                 wlp_direct_assoc_frame(wlp, skb, src);
144         }
145         return;
146 error:
147         kfree_skb(skb);
148 }
149
150 /*
151  * Verify incoming frame is from connected neighbor, prep to pass to WLP client
152  *
153  * Verification proceeds according to WLP 0.99 [7.3.1]. The source address
154  * is used to determine which neighbor is sending the frame and the WSS tag
155  * is used to know to which WSS the frame belongs (we only support one WSS
156  * so this test is straight forward).
157  * With the WSS found we need to ensure that we are connected before
158  * allowing the exchange of data frames.
159  */
160 static
161 int wlp_verify_prep_rx_frame(struct wlp *wlp, struct sk_buff *skb,
162                              struct uwb_dev_addr *src)
163 {
164         struct device *dev = &wlp->rc->uwb_dev.dev;
165         int result = -EINVAL;
166         struct wlp_eda_node eda_entry;
167         struct wlp_frame_std_abbrv_hdr *hdr = (void *) skb->data;
168
169         /*verify*/
170         result = wlp_copy_eda_node(&wlp->eda, src, &eda_entry);
171         if (result < 0) {
172                 if (printk_ratelimit())
173                         dev_err(dev, "WLP: Incoming frame is from unknown "
174                                 "neighbor %02x:%02x.\n", src->data[1],
175                                 src->data[0]);
176                 goto out;
177         }
178         if (hdr->tag != eda_entry.tag) {
179                 if (printk_ratelimit())
180                         dev_err(dev, "WLP: Tag of incoming frame from "
181                                 "%02x:%02x does not match expected tag. "
182                                 "Received 0x%02x, expected 0x%02x. \n",
183                                 src->data[1], src->data[0], hdr->tag,
184                                 eda_entry.tag);
185                 result = -EINVAL;
186                 goto out;
187         }
188         if (eda_entry.state != WLP_WSS_CONNECTED) {
189                 if (printk_ratelimit())
190                         dev_err(dev, "WLP: Incoming frame from "
191                                 "%02x:%02x does is not from connected WSS.\n",
192                                 src->data[1], src->data[0]);
193                 result = -EINVAL;
194                 goto out;
195         }
196         /*prep*/
197         skb_pull(skb, sizeof(*hdr));
198 out:
199         return result;
200 }
201
202 /*
203  * Receive a WLP frame from device
204  *
205  * @returns: 1 if calling function should free the skb
206  *           0 if it successfully handled skb and freed it
207  *           0 if error occured, will free skb in this case
208  */
209 int wlp_receive_frame(struct device *dev, struct wlp *wlp, struct sk_buff *skb,
210                       struct uwb_dev_addr *src)
211 {
212         unsigned len = skb->len;
213         void *ptr = skb->data;
214         struct wlp_frame_hdr *hdr;
215         int result = 0;
216
217         if (len < sizeof(*hdr)) {
218                 dev_err(dev, "Not enough data to parse WLP header.\n");
219                 result = -EINVAL;
220                 goto out;
221         }
222         hdr = ptr;
223         if (le16_to_cpu(hdr->mux_hdr) != WLP_PROTOCOL_ID) {
224                 dev_err(dev, "Not a WLP frame type.\n");
225                 result = -EINVAL;
226                 goto out;
227         }
228         switch (hdr->type) {
229         case WLP_FRAME_STANDARD:
230                 if (len < sizeof(struct wlp_frame_std_abbrv_hdr)) {
231                         dev_err(dev, "Not enough data to parse Standard "
232                                 "WLP header.\n");
233                         goto out;
234                 }
235                 result = wlp_verify_prep_rx_frame(wlp, skb, src);
236                 if (result < 0) {
237                         if (printk_ratelimit())
238                                 dev_err(dev, "WLP: Verification of frame "
239                                         "from neighbor %02x:%02x failed.\n",
240                                         src->data[1], src->data[0]);
241                         goto out;
242                 }
243                 result = 1;
244                 break;
245         case WLP_FRAME_ABBREVIATED:
246                 dev_err(dev, "Abbreviated frame received. FIXME?\n");
247                 kfree_skb(skb);
248                 break;
249         case WLP_FRAME_CONTROL:
250                 dev_err(dev, "Control frame received. FIXME?\n");
251                 kfree_skb(skb);
252                 break;
253         case WLP_FRAME_ASSOCIATION:
254                 if (len < sizeof(struct wlp_frame_assoc)) {
255                         dev_err(dev, "Not enough data to parse Association "
256                                 "WLP header.\n");
257                         goto out;
258                 }
259                 wlp_receive_assoc_frame(wlp, skb, src);
260                 break;
261         default:
262                 dev_err(dev, "Invalid frame received.\n");
263                 result = -EINVAL;
264                 break;
265         }
266 out:
267         if (result < 0) {
268                 kfree_skb(skb);
269                 result = 0;
270         }
271         return result;
272 }
273 EXPORT_SYMBOL_GPL(wlp_receive_frame);
274
275
276 /*
277  * Verify frame from network stack, prepare for further transmission
278  *
279  * @skb:   the socket buffer that needs to be prepared for transmission (it
280  *         is in need of a WLP header). If this is a broadcast frame we take
281  *         over the entire transmission.
282  *         If it is a unicast the WSS connection should already be established
283  *         and transmission will be done by the calling function.
284  * @dst:   On return this will contain the device address to which the
285  *         frame is destined.
286  * @returns: 0 on success no tx : WLP header successfully applied to skb buffer,
287  *                                calling function can proceed with tx
288  *           1 on success with tx : WLP will take over transmission of this
289  *                                  frame
290  *           <0 on error
291  *
292  * The network stack (WLP client) is attempting to transmit a frame. We can
293  * only transmit data if a local WSS is at least active (connection will be
294  * done here if this is a broadcast frame and neighbor also has the WSS
295  * active).
296  *
297  * The frame can be either broadcast or unicast. Broadcast in a WSS is
298  * supported via multicast, but we don't support multicast yet (until
299  * devices start to support MAB IEs). If a broadcast frame needs to be
300  * transmitted it is treated as a unicast frame to each neighbor. In this
301  * case the WLP takes over transmission of the skb and returns 1
302  * to the caller to indicate so. Also, in this case, if a neighbor has the
303  * same WSS activated but is not connected then the WSS connection will be
304  * done at this time. The neighbor's virtual address will be learned at
305  * this time.
306  *
307  * The destination address in a unicast frame is the virtual address of the
308  * neighbor. This address only becomes known when a WSS connection is
309  * established. We thus rely on a broadcast frame to trigger the setup of
310  * WSS connections to all neighbors before we are able to send unicast
311  * frames to them. This seems reasonable as IP would usually use ARP first
312  * before any unicast frames are sent.
313  *
314  * If we are already connected to the neighbor (neighbor's virtual address
315  * is known) we just prepare the WLP header and the caller will continue to
316  * send the frame.
317  *
318  * A failure in this function usually indicates something that cannot be
319  * fixed automatically. So, if this function fails (@return < 0) the calling
320  * function should not retry to send the frame as it will very likely keep
321  * failing.
322  *
323  */
324 int wlp_prepare_tx_frame(struct device *dev, struct wlp *wlp,
325                          struct sk_buff *skb, struct uwb_dev_addr *dst)
326 {
327         int result = -EINVAL;
328         struct ethhdr *eth_hdr = (void *) skb->data;
329
330         if (is_multicast_ether_addr(eth_hdr->h_dest)) {
331                 result = wlp_eda_for_each(&wlp->eda, wlp_wss_send_copy, skb);
332                 if (result < 0) {
333                         if (printk_ratelimit())
334                                 dev_err(dev, "Unable to handle broadcast "
335                                         "frame from WLP client.\n");
336                         goto out;
337                 }
338                 dev_kfree_skb_irq(skb);
339                 result = 1;
340                 /* Frame will be transmitted by WLP. */
341         } else {
342                 result = wlp_eda_for_virtual(&wlp->eda, eth_hdr->h_dest, dst,
343                                              wlp_wss_prep_hdr, skb);
344                 if (unlikely(result < 0)) {
345                         if (printk_ratelimit())
346                                 dev_err(dev, "Unable to prepare "
347                                         "skb for transmission. \n");
348                         goto out;
349                 }
350         }
351 out:
352         return result;
353 }
354 EXPORT_SYMBOL_GPL(wlp_prepare_tx_frame);