aboutsummaryrefslogtreecommitdiffstats
path: root/net/irda/irlmp_frame.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/irda/irlmp_frame.c')
-rw-r--r--net/irda/irlmp_frame.c122
1 files changed, 61 insertions, 61 deletions
diff --git a/net/irda/irlmp_frame.c b/net/irda/irlmp_frame.c
index 39761a1d18f5..559302d3fe66 100644
--- a/net/irda/irlmp_frame.c
+++ b/net/irda/irlmp_frame.c
@@ -1,5 +1,5 @@
1/********************************************************************* 1/*********************************************************************
2 * 2 *
3 * Filename: irlmp_frame.c 3 * Filename: irlmp_frame.c
4 * Version: 0.9 4 * Version: 0.9
5 * Description: IrLMP frame implementation 5 * Description: IrLMP frame implementation
@@ -8,18 +8,18 @@
8 * Created at: Tue Aug 19 02:09:59 1997 8 * Created at: Tue Aug 19 02:09:59 1997
9 * Modified at: Mon Dec 13 13:41:12 1999 9 * Modified at: Mon Dec 13 13:41:12 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no> 10 * Modified by: Dag Brattli <dagb@cs.uit.no>
11 * 11 *
12 * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no> 12 * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>
13 * All Rights Reserved. 13 * All Rights Reserved.
14 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com> 14 * Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.com>
15 * 15 *
16 * This program is free software; you can redistribute it and/or 16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as 17 * modify it under the terms of the GNU General Public License as
18 * published by the Free Software Foundation; either version 2 of 18 * published by the Free Software Foundation; either version 2 of
19 * the License, or (at your option) any later version. 19 * the License, or (at your option) any later version.
20 * 20 *
21 * Neither Dag Brattli nor University of Tromsų admit liability nor 21 * Neither Dag Brattli nor University of Tromsų admit liability nor
22 * provide warranty for any of this software. This material is 22 * provide warranty for any of this software. This material is
23 * provided "AS-IS" and at no charge. 23 * provided "AS-IS" and at no charge.
24 * 24 *
25 ********************************************************************/ 25 ********************************************************************/
@@ -34,7 +34,7 @@
34#include <net/irda/irlmp_frame.h> 34#include <net/irda/irlmp_frame.h>
35#include <net/irda/discovery.h> 35#include <net/irda/discovery.h>
36 36
37static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap, 37static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap,
38 __u8 slsap, int status, hashbin_t *); 38 __u8 slsap, int status, hashbin_t *);
39 39
40inline void irlmp_send_data_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap, 40inline void irlmp_send_data_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap,
@@ -56,18 +56,18 @@ inline void irlmp_send_data_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap,
56 * Send Link Control Frame to IrLAP 56 * Send Link Control Frame to IrLAP
57 */ 57 */
58void irlmp_send_lcf_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap, 58void irlmp_send_lcf_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap,
59 __u8 opcode, struct sk_buff *skb) 59 __u8 opcode, struct sk_buff *skb)
60{ 60{
61 __u8 *frame; 61 __u8 *frame;
62 62
63 IRDA_DEBUG(2, "%s()\n", __FUNCTION__); 63 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
64 64
65 IRDA_ASSERT(self != NULL, return;); 65 IRDA_ASSERT(self != NULL, return;);
66 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;); 66 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
67 IRDA_ASSERT(skb != NULL, return;); 67 IRDA_ASSERT(skb != NULL, return;);
68 68
69 frame = skb->data; 69 frame = skb->data;
70 70
71 frame[0] = dlsap | CONTROL_BIT; 71 frame[0] = dlsap | CONTROL_BIT;
72 frame[1] = slsap; 72 frame[1] = slsap;
73 73
@@ -87,14 +87,14 @@ void irlmp_send_lcf_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap,
87 * Used by IrLAP to pass received data frames to IrLMP layer 87 * Used by IrLAP to pass received data frames to IrLMP layer
88 * 88 *
89 */ 89 */
90void irlmp_link_data_indication(struct lap_cb *self, struct sk_buff *skb, 90void irlmp_link_data_indication(struct lap_cb *self, struct sk_buff *skb,
91 int unreliable) 91 int unreliable)
92{ 92{
93 struct lsap_cb *lsap; 93 struct lsap_cb *lsap;
94 __u8 slsap_sel; /* Source (this) LSAP address */ 94 __u8 slsap_sel; /* Source (this) LSAP address */
95 __u8 dlsap_sel; /* Destination LSAP address */ 95 __u8 dlsap_sel; /* Destination LSAP address */
96 __u8 *fp; 96 __u8 *fp;
97 97
98 IRDA_DEBUG(4, "%s()\n", __FUNCTION__); 98 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
99 99
100 IRDA_ASSERT(self != NULL, return;); 100 IRDA_ASSERT(self != NULL, return;);
@@ -104,11 +104,11 @@ void irlmp_link_data_indication(struct lap_cb *self, struct sk_buff *skb,
104 fp = skb->data; 104 fp = skb->data;
105 105
106 /* 106 /*
107 * The next statements may be confusing, but we do this so that 107 * The next statements may be confusing, but we do this so that
108 * destination LSAP of received frame is source LSAP in our view 108 * destination LSAP of received frame is source LSAP in our view
109 */ 109 */
110 slsap_sel = fp[0] & LSAP_MASK; 110 slsap_sel = fp[0] & LSAP_MASK;
111 dlsap_sel = fp[1]; 111 dlsap_sel = fp[1];
112 112
113 /* 113 /*
114 * Check if this is an incoming connection, since we must deal with 114 * Check if this is an incoming connection, since we must deal with
@@ -118,11 +118,11 @@ void irlmp_link_data_indication(struct lap_cb *self, struct sk_buff *skb,
118 IRDA_DEBUG(3, "%s(), incoming connection, " 118 IRDA_DEBUG(3, "%s(), incoming connection, "
119 "source LSAP=%d, dest LSAP=%d\n", 119 "source LSAP=%d, dest LSAP=%d\n",
120 __FUNCTION__, slsap_sel, dlsap_sel); 120 __FUNCTION__, slsap_sel, dlsap_sel);
121 121
122 /* Try to find LSAP among the unconnected LSAPs */ 122 /* Try to find LSAP among the unconnected LSAPs */
123 lsap = irlmp_find_lsap(self, dlsap_sel, slsap_sel, CONNECT_CMD, 123 lsap = irlmp_find_lsap(self, dlsap_sel, slsap_sel, CONNECT_CMD,
124 irlmp->unconnected_lsaps); 124 irlmp->unconnected_lsaps);
125 125
126 /* Maybe LSAP was already connected, so try one more time */ 126 /* Maybe LSAP was already connected, so try one more time */
127 if (!lsap) { 127 if (!lsap) {
128 IRDA_DEBUG(1, "%s(), incoming connection for LSAP already connected\n", __FUNCTION__); 128 IRDA_DEBUG(1, "%s(), incoming connection for LSAP already connected\n", __FUNCTION__);
@@ -130,9 +130,9 @@ void irlmp_link_data_indication(struct lap_cb *self, struct sk_buff *skb,
130 self->lsaps); 130 self->lsaps);
131 } 131 }
132 } else 132 } else
133 lsap = irlmp_find_lsap(self, dlsap_sel, slsap_sel, 0, 133 lsap = irlmp_find_lsap(self, dlsap_sel, slsap_sel, 0,
134 self->lsaps); 134 self->lsaps);
135 135
136 if (lsap == NULL) { 136 if (lsap == NULL) {
137 IRDA_DEBUG(2, "IrLMP, Sorry, no LSAP for received frame!\n"); 137 IRDA_DEBUG(2, "IrLMP, Sorry, no LSAP for received frame!\n");
138 IRDA_DEBUG(2, "%s(), slsap_sel = %02x, dlsap_sel = %02x\n", 138 IRDA_DEBUG(2, "%s(), slsap_sel = %02x, dlsap_sel = %02x\n",
@@ -146,8 +146,8 @@ void irlmp_link_data_indication(struct lap_cb *self, struct sk_buff *skb,
146 return; 146 return;
147 } 147 }
148 148
149 /* 149 /*
150 * Check if we received a control frame? 150 * Check if we received a control frame?
151 */ 151 */
152 if (fp[0] & CONTROL_BIT) { 152 if (fp[0] & CONTROL_BIT) {
153 switch (fp[2]) { 153 switch (fp[2]) {
@@ -161,7 +161,7 @@ void irlmp_link_data_indication(struct lap_cb *self, struct sk_buff *skb,
161 case DISCONNECT: 161 case DISCONNECT:
162 IRDA_DEBUG(4, "%s(), Disconnect indication!\n", 162 IRDA_DEBUG(4, "%s(), Disconnect indication!\n",
163 __FUNCTION__); 163 __FUNCTION__);
164 irlmp_do_lsap_event(lsap, LM_DISCONNECT_INDICATION, 164 irlmp_do_lsap_event(lsap, LM_DISCONNECT_INDICATION,
165 skb); 165 skb);
166 break; 166 break;
167 case ACCESSMODE_CMD: 167 case ACCESSMODE_CMD:
@@ -181,7 +181,7 @@ void irlmp_link_data_indication(struct lap_cb *self, struct sk_buff *skb,
181 irlmp_udata_indication(lsap, skb); 181 irlmp_udata_indication(lsap, skb);
182 else 182 else
183 irlmp_do_lsap_event(lsap, LM_UDATA_INDICATION, skb); 183 irlmp_do_lsap_event(lsap, LM_UDATA_INDICATION, skb);
184 } else { 184 } else {
185 /* Optimize and bypass the state machine if possible */ 185 /* Optimize and bypass the state machine if possible */
186 if (lsap->lsap_state == LSAP_DATA_TRANSFER_READY) 186 if (lsap->lsap_state == LSAP_DATA_TRANSFER_READY)
187 irlmp_data_indication(lsap, skb); 187 irlmp_data_indication(lsap, skb);
@@ -193,7 +193,7 @@ void irlmp_link_data_indication(struct lap_cb *self, struct sk_buff *skb,
193/* 193/*
194 * Function irlmp_link_unitdata_indication (self, skb) 194 * Function irlmp_link_unitdata_indication (self, skb)
195 * 195 *
196 * 196 *
197 * 197 *
198 */ 198 */
199#ifdef CONFIG_IRDA_ULTRA 199#ifdef CONFIG_IRDA_ULTRA
@@ -205,7 +205,7 @@ void irlmp_link_unitdata_indication(struct lap_cb *self, struct sk_buff *skb)
205 __u8 pid; /* Protocol identifier */ 205 __u8 pid; /* Protocol identifier */
206 __u8 *fp; 206 __u8 *fp;
207 unsigned long flags; 207 unsigned long flags;
208 208
209 IRDA_DEBUG(4, "%s()\n", __FUNCTION__); 209 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
210 210
211 IRDA_ASSERT(self != NULL, return;); 211 IRDA_ASSERT(self != NULL, return;);
@@ -215,13 +215,13 @@ void irlmp_link_unitdata_indication(struct lap_cb *self, struct sk_buff *skb)
215 fp = skb->data; 215 fp = skb->data;
216 216
217 /* 217 /*
218 * The next statements may be confusing, but we do this so that 218 * The next statements may be confusing, but we do this so that
219 * destination LSAP of received frame is source LSAP in our view 219 * destination LSAP of received frame is source LSAP in our view
220 */ 220 */
221 slsap_sel = fp[0] & LSAP_MASK; 221 slsap_sel = fp[0] & LSAP_MASK;
222 dlsap_sel = fp[1]; 222 dlsap_sel = fp[1];
223 pid = fp[2]; 223 pid = fp[2];
224 224
225 if (pid & 0x80) { 225 if (pid & 0x80) {
226 IRDA_DEBUG(0, "%s(), extension in PID not supp!\n", 226 IRDA_DEBUG(0, "%s(), extension in PID not supp!\n",
227 __FUNCTION__); 227 __FUNCTION__);
@@ -233,7 +233,7 @@ void irlmp_link_unitdata_indication(struct lap_cb *self, struct sk_buff *skb)
233 IRDA_DEBUG(0, "%s(), dropping frame!\n", __FUNCTION__); 233 IRDA_DEBUG(0, "%s(), dropping frame!\n", __FUNCTION__);
234 return; 234 return;
235 } 235 }
236 236
237 /* Search the connectionless LSAP */ 237 /* Search the connectionless LSAP */
238 spin_lock_irqsave(&irlmp->unconnected_lsaps->hb_spinlock, flags); 238 spin_lock_irqsave(&irlmp->unconnected_lsaps->hb_spinlock, flags);
239 lsap = (struct lsap_cb *) hashbin_get_first(irlmp->unconnected_lsaps); 239 lsap = (struct lsap_cb *) hashbin_get_first(irlmp->unconnected_lsaps);
@@ -241,10 +241,10 @@ void irlmp_link_unitdata_indication(struct lap_cb *self, struct sk_buff *skb)
241 /* 241 /*
242 * Check if source LSAP and dest LSAP selectors and PID match. 242 * Check if source LSAP and dest LSAP selectors and PID match.
243 */ 243 */
244 if ((lsap->slsap_sel == slsap_sel) && 244 if ((lsap->slsap_sel == slsap_sel) &&
245 (lsap->dlsap_sel == dlsap_sel) && 245 (lsap->dlsap_sel == dlsap_sel) &&
246 (lsap->pid == pid)) 246 (lsap->pid == pid))
247 { 247 {
248 break; 248 break;
249 } 249 }
250 lsap = (struct lsap_cb *) hashbin_get_next(irlmp->unconnected_lsaps); 250 lsap = (struct lsap_cb *) hashbin_get_next(irlmp->unconnected_lsaps);
@@ -262,12 +262,12 @@ void irlmp_link_unitdata_indication(struct lap_cb *self, struct sk_buff *skb)
262/* 262/*
263 * Function irlmp_link_disconnect_indication (reason, userdata) 263 * Function irlmp_link_disconnect_indication (reason, userdata)
264 * 264 *
265 * IrLAP has disconnected 265 * IrLAP has disconnected
266 * 266 *
267 */ 267 */
268void irlmp_link_disconnect_indication(struct lap_cb *lap, 268void irlmp_link_disconnect_indication(struct lap_cb *lap,
269 struct irlap_cb *irlap, 269 struct irlap_cb *irlap,
270 LAP_REASON reason, 270 LAP_REASON reason,
271 struct sk_buff *skb) 271 struct sk_buff *skb)
272{ 272{
273 IRDA_DEBUG(2, "%s()\n", __FUNCTION__); 273 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
@@ -278,8 +278,8 @@ void irlmp_link_disconnect_indication(struct lap_cb *lap,
278 lap->reason = reason; 278 lap->reason = reason;
279 lap->daddr = DEV_ADDR_ANY; 279 lap->daddr = DEV_ADDR_ANY;
280 280
281 /* FIXME: must do something with the skb if any */ 281 /* FIXME: must do something with the skb if any */
282 282
283 /* 283 /*
284 * Inform station state machine 284 * Inform station state machine
285 */ 285 */
@@ -292,9 +292,9 @@ void irlmp_link_disconnect_indication(struct lap_cb *lap,
292 * Incoming LAP connection! 292 * Incoming LAP connection!
293 * 293 *
294 */ 294 */
295void irlmp_link_connect_indication(struct lap_cb *self, __u32 saddr, 295void irlmp_link_connect_indication(struct lap_cb *self, __u32 saddr,
296 __u32 daddr, struct qos_info *qos, 296 __u32 daddr, struct qos_info *qos,
297 struct sk_buff *skb) 297 struct sk_buff *skb)
298{ 298{
299 IRDA_DEBUG(4, "%s()\n", __FUNCTION__); 299 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
300 300
@@ -314,7 +314,7 @@ void irlmp_link_connect_indication(struct lap_cb *self, __u32 saddr,
314 * LAP connection confirmed! 314 * LAP connection confirmed!
315 * 315 *
316 */ 316 */
317void irlmp_link_connect_confirm(struct lap_cb *self, struct qos_info *qos, 317void irlmp_link_connect_confirm(struct lap_cb *self, struct qos_info *qos,
318 struct sk_buff *skb) 318 struct sk_buff *skb)
319{ 319{
320 IRDA_DEBUG(4, "%s()\n", __FUNCTION__); 320 IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
@@ -359,7 +359,7 @@ void irlmp_link_connect_confirm(struct lap_cb *self, struct qos_info *qos,
359 * 359 *
360 * Jean II 360 * Jean II
361 */ 361 */
362void irlmp_link_discovery_indication(struct lap_cb *self, 362void irlmp_link_discovery_indication(struct lap_cb *self,
363 discovery_t *discovery) 363 discovery_t *discovery)
364{ 364{
365 IRDA_ASSERT(self != NULL, return;); 365 IRDA_ASSERT(self != NULL, return;);
@@ -367,7 +367,7 @@ void irlmp_link_discovery_indication(struct lap_cb *self,
367 367
368 /* Add to main log, cleanup */ 368 /* Add to main log, cleanup */
369 irlmp_add_discovery(irlmp->cachelog, discovery); 369 irlmp_add_discovery(irlmp->cachelog, discovery);
370 370
371 /* Just handle it the same way as a discovery confirm, 371 /* Just handle it the same way as a discovery confirm,
372 * bypass the LM_LAP state machine (see below) */ 372 * bypass the LM_LAP state machine (see below) */
373 irlmp_discovery_confirm(irlmp->cachelog, DISCOVERY_PASSIVE); 373 irlmp_discovery_confirm(irlmp->cachelog, DISCOVERY_PASSIVE);
@@ -387,7 +387,7 @@ void irlmp_link_discovery_confirm(struct lap_cb *self, hashbin_t *log)
387 387
388 IRDA_ASSERT(self != NULL, return;); 388 IRDA_ASSERT(self != NULL, return;);
389 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;); 389 IRDA_ASSERT(self->magic == LMP_LAP_MAGIC, return;);
390 390
391 /* Add to main log, cleanup */ 391 /* Add to main log, cleanup */
392 irlmp_add_discovery_log(irlmp->cachelog, log); 392 irlmp_add_discovery_log(irlmp->cachelog, log);
393 393
@@ -420,7 +420,7 @@ static inline void irlmp_update_cache(struct lap_cb *lap,
420 * Find handle associated with destination and source LSAP 420 * Find handle associated with destination and source LSAP
421 * 421 *
422 * Any IrDA connection (LSAP/TSAP) is uniquely identified by 422 * Any IrDA connection (LSAP/TSAP) is uniquely identified by
423 * 3 parameters, the local lsap, the remote lsap and the remote address. 423 * 3 parameters, the local lsap, the remote lsap and the remote address.
424 * We may initiate multiple connections to the same remote service 424 * We may initiate multiple connections to the same remote service
425 * (they will have different local lsap), a remote device may initiate 425 * (they will have different local lsap), a remote device may initiate
426 * multiple connections to the same local service (they will have 426 * multiple connections to the same local service (they will have
@@ -433,20 +433,20 @@ static inline void irlmp_update_cache(struct lap_cb *lap,
433 */ 433 */
434static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel, 434static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel,
435 __u8 slsap_sel, int status, 435 __u8 slsap_sel, int status,
436 hashbin_t *queue) 436 hashbin_t *queue)
437{ 437{
438 struct lsap_cb *lsap; 438 struct lsap_cb *lsap;
439 unsigned long flags; 439 unsigned long flags;
440 440
441 /* 441 /*
442 * Optimize for the common case. We assume that the last frame 442 * Optimize for the common case. We assume that the last frame
443 * received is in the same connection as the last one, so check in 443 * received is in the same connection as the last one, so check in
444 * cache first to avoid the linear search 444 * cache first to avoid the linear search
445 */ 445 */
446#ifdef CONFIG_IRDA_CACHE_LAST_LSAP 446#ifdef CONFIG_IRDA_CACHE_LAST_LSAP
447 if ((self->cache.valid) && 447 if ((self->cache.valid) &&
448 (self->cache.slsap_sel == slsap_sel) && 448 (self->cache.slsap_sel == slsap_sel) &&
449 (self->cache.dlsap_sel == dlsap_sel)) 449 (self->cache.dlsap_sel == dlsap_sel))
450 { 450 {
451 return (self->cache.lsap); 451 return (self->cache.lsap);
452 } 452 }
@@ -456,14 +456,14 @@ static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel,
456 456
457 lsap = (struct lsap_cb *) hashbin_get_first(queue); 457 lsap = (struct lsap_cb *) hashbin_get_first(queue);
458 while (lsap != NULL) { 458 while (lsap != NULL) {
459 /* 459 /*
460 * If this is an incoming connection, then the destination 460 * If this is an incoming connection, then the destination
461 * LSAP selector may have been specified as LM_ANY so that 461 * LSAP selector may have been specified as LM_ANY so that
462 * any client can connect. In that case we only need to check 462 * any client can connect. In that case we only need to check
463 * if the source LSAP (in our view!) match! 463 * if the source LSAP (in our view!) match!
464 */ 464 */
465 if ((status == CONNECT_CMD) && 465 if ((status == CONNECT_CMD) &&
466 (lsap->slsap_sel == slsap_sel) && 466 (lsap->slsap_sel == slsap_sel) &&
467 (lsap->dlsap_sel == LSAP_ANY)) { 467 (lsap->dlsap_sel == LSAP_ANY)) {
468 /* This is where the dest lsap sel is set on incoming 468 /* This is where the dest lsap sel is set on incoming
469 * lsaps */ 469 * lsaps */
@@ -473,8 +473,8 @@ static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel,
473 /* 473 /*
474 * Check if source LSAP and dest LSAP selectors match. 474 * Check if source LSAP and dest LSAP selectors match.
475 */ 475 */
476 if ((lsap->slsap_sel == slsap_sel) && 476 if ((lsap->slsap_sel == slsap_sel) &&
477 (lsap->dlsap_sel == dlsap_sel)) 477 (lsap->dlsap_sel == dlsap_sel))
478 break; 478 break;
479 479
480 lsap = (struct lsap_cb *) hashbin_get_next(queue); 480 lsap = (struct lsap_cb *) hashbin_get_next(queue);