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