2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/*********************************************************************
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Filename :       irlap_frame . c 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Version :        1.0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Description :    Build  and  transmit  IrLAP  frames 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Status :         Stable 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Author :         Dag  Brattli  < dagb @ cs . uit . no > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Created  at :     Tue  Aug  19  10 : 27 : 26  1997 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Modified  at :    Wed  Jan   5  08 : 59 : 04  2000 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Modified  by :    Dag  Brattli  < dagb @ cs . uit . no > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *      Copyright  ( c )  1998 - 2000  Dag  Brattli  < dagb @ cs . uit . no > , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *      All  Rights  Reserved . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *      Copyright  ( c )  2000 - 2003  Jean  Tourrilhes  < jt @ hpl . hp . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *      This  program  is  free  software ;  you  can  redistribute  it  and / or 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *      modify  it  under  the  terms  of  the  GNU  General  Public  License  as 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *      published  by  the  Free  Software  Foundation ;  either  version  2  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *      the  License ,  or  ( at  your  option )  any  later  version . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-19 23:21:04 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 *      Neither  Dag  Brattli  nor  University  of  Tromsø  admit  liability  nor 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 *      provide  warranty  for  any  of  this  software .  This  material  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *      provided  " AS-IS "  and  at  no  charge . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <linux/skbuff.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <linux/if.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <linux/if_ether.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <linux/netdevice.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <linux/irda.h> 
 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h
percpu.h is included by sched.h and module.h and thus ends up being
included when building most .c files.  percpu.h includes slab.h which
in turn includes gfp.h making everything defined by the two files
universally available and complicating inclusion dependencies.
percpu.h -> slab.h dependency is about to be removed.  Prepare for
this change by updating users of gfp and slab facilities include those
headers directly instead of assuming availability.  As this conversion
needs to touch large number of source files, the following script is
used as the basis of conversion.
  http://userweb.kernel.org/~tj/misc/slabh-sweep.py
The script does the followings.
* Scan files for gfp and slab usages and update includes such that
  only the necessary includes are there.  ie. if only gfp is used,
  gfp.h, if slab is used, slab.h.
* When the script inserts a new include, it looks at the include
  blocks and try to put the new include such that its order conforms
  to its surrounding.  It's put in the include block which contains
  core kernel includes, in the same order that the rest are ordered -
  alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
  doesn't seem to be any matching order.
* If the script can't find a place to put a new include (mostly
  because the file doesn't have fitting include block), it prints out
  an error message indicating which .h file needs to be added to the
  file.
The conversion was done in the following steps.
1. The initial automatic conversion of all .c files updated slightly
   over 4000 files, deleting around 700 includes and adding ~480 gfp.h
   and ~3000 slab.h inclusions.  The script emitted errors for ~400
   files.
2. Each error was manually checked.  Some didn't need the inclusion,
   some needed manual addition while adding it to implementation .h or
   embedding .c file was more appropriate for others.  This step added
   inclusions to around 150 files.
3. The script was run again and the output was compared to the edits
   from #2 to make sure no file was left behind.
4. Several build tests were done and a couple of problems were fixed.
   e.g. lib/decompress_*.c used malloc/free() wrappers around slab
   APIs requiring slab.h to be added manually.
5. The script was run on all .h files but without automatically
   editing them as sprinkling gfp.h and slab.h inclusions around .h
   files could easily lead to inclusion dependency hell.  Most gfp.h
   inclusion directives were ignored as stuff from gfp.h was usually
   wildly available and often used in preprocessor macros.  Each
   slab.h inclusion directive was examined and added manually as
   necessary.
6. percpu.h was updated not to include slab.h.
7. Build test were done on the following configurations and failures
   were fixed.  CONFIG_GCOV_KERNEL was turned off for all tests (as my
   distributed build env didn't work with gcov compiles) and a few
   more options had to be turned off depending on archs to make things
   build (like ipr on powerpc/64 which failed due to missing writeq).
   * x86 and x86_64 UP and SMP allmodconfig and a custom test config.
   * powerpc and powerpc64 SMP allmodconfig
   * sparc and sparc64 SMP allmodconfig
   * ia64 SMP allmodconfig
   * s390 SMP allmodconfig
   * alpha SMP allmodconfig
   * um on x86_64 SMP allmodconfig
8. percpu.h modifications were reverted so that it could be applied as
   a separate patch and serve as bisection point.
Given the fact that I had only a couple of failures from tests on step
6, I'm fairly confident about the coverage of this conversion patch.
If there is a breakage, it's likely to be something in one of the arch
headers which should be easily discoverable easily on most builds of
the specific arch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
											 
										 
										
											2010-03-24 17:04:11 +09:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <linux/slab.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <net/pkt_sched.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <net/sock.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <asm/byteorder.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <net/irda/irda.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <net/irda/irda_device.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <net/irda/irlap.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <net/irda/wrapper.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <net/irda/timer.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <net/irda/irlap_frame.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <net/irda/qos.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  irlap_send_i_frame ( struct  irlap_cb  * self ,  struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											       int  command ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_insert_info  ( self ,  skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Insert  minimum  turnaround  time  and  speed  information  into  the  skb .  We 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     need  to  do  this  since  it ' s  per  packet  relevant  information .  Safe  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     have  this  function  inlined  since  it ' s  only  called  from  one  place 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  irlap_insert_info ( struct  irlap_cb  * self , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												     struct  sk_buff  * skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  irda_skb_cb  * cb  =  ( struct  irda_skb_cb  * )  skb - > cb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Insert  MTT  ( min .  turn  time )  and  speed  into  skb ,  so  that  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  device  driver  knows  which  settings  to  use 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									cb - > magic  =  LAP_MAGIC ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									cb - > mtt  =  self - > mtt_required ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									cb - > next_speed  =  self - > speed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Reset */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									self - > mtt_required  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Delay  equals  negotiated  BOFs  count ,  plus  the  number  of  BOFs  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  force  the  negotiated  minimum  turnaround  time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									cb - > xbofs  =  self - > bofs_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									cb - > next_xbofs  =  self - > next_bofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									cb - > xbofs_delay  =  self - > xbofs_delay ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Reset XBOF's delay (used only for getting min turn time) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									self - > xbofs_delay  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Put the correct xbofs value for the next packet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									self - > bofs_count  =  self - > next_bofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_queue_xmit  ( self ,  skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     A  little  wrapper  for  dev_queue_xmit ,  so  we  can  insert  some  common 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     code  into  it . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_queue_xmit ( struct  irlap_cb  * self ,  struct  sk_buff  * skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Some common init stuff */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									skb - > dev  =  self - > netdev ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-19 15:30:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									skb_reset_mac_header ( skb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-10 20:45:18 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									skb_reset_network_header ( skb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-13 13:06:52 -03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									skb_reset_transport_header ( skb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									skb - > protocol  =  htons ( ETH_P_IRDA ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									skb - > priority  =  TC_PRIO_BESTEFFORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_insert_info ( self ,  skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-02 22:55:31 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( unlikely ( self - > mode  &  IRDA_MODE_MONITOR ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pr_debug ( " %s(): %s is in monitor mode \n " ,  __func__ , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 self - > netdev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-02 22:55:31 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										dev_kfree_skb ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									dev_queue_xmit ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_send_snrm_cmd  ( void ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Transmits  a  connect  SNRM  command  frame 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_send_snrm_frame ( struct  irlap_cb  * self ,  struct  qos_info  * qos ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * tx_skb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  snrm_frame  * frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self - > magic  = =  LAP_MAGIC ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Allocate frame */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tx_skb  =  alloc_skb ( sizeof ( struct  snrm_frame )  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											   IRLAP_NEGOCIATION_PARAMS_LEN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											   GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! tx_skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame  =  ( struct  snrm_frame  * )  skb_put ( tx_skb ,  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Insert connection address field */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( qos ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > caddr  =  CMD_FRAME  |  CBROADCAST ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > caddr  =  CMD_FRAME  |  self - > caddr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Insert control field */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame - > control  =  SNRM_CMD  |  PF_BIT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-20 14:00:51 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									 *   If  we  are  establishing  a  connection  then  insert  QoS  parameters 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( qos )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										skb_put ( tx_skb ,  9 ) ;  /* 25 left */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										frame - > saddr  =  cpu_to_le32 ( self - > saddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > daddr  =  cpu_to_le32 ( self - > daddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > ncaddr  =  self - > caddr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ret  =  irlap_insert_qos_negotiation_params ( self ,  tx_skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ret  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											dev_kfree_skb ( tx_skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_queue_xmit ( self ,  tx_skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_recv_snrm_cmd  ( skb ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Received  SNRM  ( Set  Normal  Response  Mode )  command  frame 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  irlap_recv_snrm_cmd ( struct  irlap_cb  * self ,  struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												struct  irlap_info  * info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  snrm_frame  * frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( pskb_may_pull ( skb , sizeof ( struct  snrm_frame ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame  =  ( struct  snrm_frame  * )  skb - > data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Copy the new connection address ignoring the C/R bit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										info - > caddr  =  frame - > ncaddr  &  0xFE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Check if the new connection address is valid */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ( info - > caddr  = =  0x00 )  | |  ( info - > caddr  = =  0xfe ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											pr_debug ( " %s(), invalid connection address! \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Copy peer device address */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										info - > daddr  =  le32_to_cpu ( frame - > saddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										info - > saddr  =  le32_to_cpu ( frame - > daddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Only accept if addressed directly to us */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( info - > saddr  ! =  self - > saddr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											pr_debug ( " %s(), not addressed to us! \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_SNRM_CMD ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Signal that this SNRM frame does not contain and I-field */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_SNRM_CMD ,  skb ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_send_ua_response_frame  ( qos ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Send  UA  ( Unnumbered  Acknowledgement )  frame 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_send_ua_response_frame ( struct  irlap_cb  * self ,  struct  qos_info  * qos ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * tx_skb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ua_frame  * frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pr_debug ( " %s() <%ld> \n " ,  __func__ ,  jiffies ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self - > magic  = =  LAP_MAGIC ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Allocate frame */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tx_skb  =  alloc_skb ( sizeof ( struct  ua_frame )  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											   IRLAP_NEGOCIATION_PARAMS_LEN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											   GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! tx_skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame  =  ( struct  ua_frame  * )  skb_put ( tx_skb ,  10 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Build UA response */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame - > caddr  =  self - > caddr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame - > control  =  UA_RSP  |  PF_BIT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame - > saddr  =  cpu_to_le32 ( self - > saddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame - > daddr  =  cpu_to_le32 ( self - > daddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Should we send QoS negotiation parameters? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( qos )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ret  =  irlap_insert_qos_negotiation_params ( self ,  tx_skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ret  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											dev_kfree_skb ( tx_skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_queue_xmit ( self ,  tx_skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_send_dm_frame  ( void ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Send  disconnected  mode  ( DM )  frame 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_send_dm_frame (  struct  irlap_cb  * self ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * tx_skb  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  dm_frame  * frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self - > magic  = =  LAP_MAGIC ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tx_skb  =  alloc_skb ( sizeof ( struct  dm_frame ) ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! tx_skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									frame  =  ( struct  dm_frame  * ) skb_put ( tx_skb ,  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( self - > state  = =  LAP_NDM ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										frame - > caddr  =  CBROADCAST ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										frame - > caddr  =  self - > caddr ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									frame - > control  =  DM_RSP  |  PF_BIT ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_queue_xmit ( self ,  tx_skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_send_disc_frame  ( void ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Send  disconnect  ( DISC )  frame 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_send_disc_frame ( struct  irlap_cb  * self ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * tx_skb  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  disc_frame  * frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self - > magic  = =  LAP_MAGIC ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tx_skb  =  alloc_skb ( sizeof ( struct  disc_frame ) ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! tx_skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									frame  =  ( struct  disc_frame  * ) skb_put ( tx_skb ,  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									frame - > caddr  =  self - > caddr  |  CMD_FRAME ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame - > control  =  DISC_CMD  |  PF_BIT ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_queue_xmit ( self ,  tx_skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_send_discovery_xid_frame  ( S ,  s ,  command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Build  and  transmit  a  XID  ( eXchange  station  IDentifier )  discovery 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     frame . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_send_discovery_xid_frame ( struct  irlap_cb  * self ,  int  S ,  __u8  s , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												    __u8  command ,  discovery_t  * discovery ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * tx_skb  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  xid_frame  * frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									__u32  bcast  =  BROADCAST ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									__u8  * info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pr_debug ( " %s(), s=%d, S=%d, command=%d \n " ,  __func__ , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 s ,  S ,  command ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self - > magic  = =  LAP_MAGIC ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( discovery  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tx_skb  =  alloc_skb ( sizeof ( struct  xid_frame )  +  IRLAP_DISCOVERY_INFO_LEN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											   GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! tx_skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									skb_put ( tx_skb ,  14 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame  =  ( struct  xid_frame  * )  tx_skb - > data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( command )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > caddr  =  CBROADCAST  |  CMD_FRAME ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > control  =   XID_CMD  |  PF_BIT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > caddr  =  CBROADCAST ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > control  =   XID_RSP  |  PF_BIT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame - > ident  =  XID_FORMAT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame - > saddr  =  cpu_to_le32 ( self - > saddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > daddr  =  cpu_to_le32 ( bcast ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > daddr  =  cpu_to_le32 ( discovery - > data . daddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( S )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > flags  =  0x00 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  6 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > flags  =  0x01 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  8 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > flags  =  0x02 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  16 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > flags  =  0x03 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > flags  =  0x02 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame - > slotnr  =  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame - > version  =  0x00 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *   Provide  info  for  final  slot  only  in  commands ,  and  for  all 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *   responses .  Send  the  second  byte  of  the  hint  only  if  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *   EXTENSION  bit  is  set  in  the  first  byte . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! command  | |  ( frame - > slotnr  = =  0xff ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( discovery - > data . hints [ 0 ]  &  HINT_EXTENSION )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											info  =  skb_put ( tx_skb ,  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											info [ 0 ]  =  discovery - > data . hints [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											info [ 1 ]  =  discovery - > data . hints [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											info  =  skb_put ( tx_skb ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											info [ 0 ]  =  discovery - > data . hints [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										info  =  skb_put ( tx_skb ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										info [ 0 ]  =  discovery - > data . charset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										len  =  IRDA_MIN ( discovery - > name_len ,  skb_tailroom ( tx_skb ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										info  =  skb_put ( tx_skb ,  len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										memcpy ( info ,  discovery - > data . info ,  len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_queue_xmit ( self ,  tx_skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_recv_discovery_xid_rsp  ( skb ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Received  a  XID  discovery  response 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  irlap_recv_discovery_xid_rsp ( struct  irlap_cb  * self , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													 struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													 struct  irlap_info  * info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  xid_frame  * xid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									discovery_t  * discovery  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									__u8  * discovery_info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  * text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self - > magic  = =  LAP_MAGIC ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! pskb_may_pull ( skb ,  sizeof ( struct  xid_frame ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 13:37:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										net_err_ratelimited ( " %s: frame too short! \n " ,  __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-09 23:24:53 +09:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									xid  =  ( struct  xid_frame  * )  skb - > data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > daddr  =  le32_to_cpu ( xid - > saddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > saddr  =  le32_to_cpu ( xid - > daddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Make sure frame is addressed to us */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( info - > saddr  ! =  self - > saddr )  & &  ( info - > saddr  ! =  BROADCAST ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pr_debug ( " %s(), frame is not addressed to us! \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-07-21 14:51:30 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ( discovery  =  kzalloc ( sizeof ( discovery_t ) ,  GFP_ATOMIC ) )  = =  NULL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 13:37:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										net_warn_ratelimited ( " %s: kmalloc failed! \n " ,  __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									discovery - > data . daddr  =  info - > daddr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									discovery - > data . saddr  =  self - > saddr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									discovery - > timestamp  =  jiffies ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pr_debug ( " %s(), daddr=%08x \n " ,  __func__ , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 discovery - > data . daddr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									discovery_info  =  skb_pull ( skb ,  sizeof ( struct  xid_frame ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Get info returned from peer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									discovery - > data . hints [ 0 ]  =  discovery_info [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( discovery_info [ 0 ]  &  HINT_EXTENSION )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pr_debug ( " EXTENSION \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										discovery - > data . hints [ 1 ]  =  discovery_info [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										discovery - > data . charset  =  discovery_info [ 2 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										text  =  ( char  * )  & discovery_info [ 3 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										discovery - > data . hints [ 1 ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										discovery - > data . charset  =  discovery_info [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										text  =  ( char  * )  & discovery_info [ 2 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *   Terminate  info  string ,  should  be  safe  since  this  is  where  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *   FCS  bytes  resides . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									skb - > data [ skb - > len ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									strncpy ( discovery - > data . info ,  text ,  NICKNAME_MAX_LEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									discovery - > name_len  =  strlen ( discovery - > data . info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > discovery  =  discovery ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_do_event ( self ,  RECV_DISCOVERY_XID_RSP ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_recv_discovery_xid_cmd  ( skb ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Received  a  XID  discovery  command 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  irlap_recv_discovery_xid_cmd ( struct  irlap_cb  * self , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													 struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													 struct  irlap_info  * info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  xid_frame  * xid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									discovery_t  * discovery  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									__u8  * discovery_info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  * text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! pskb_may_pull ( skb ,  sizeof ( struct  xid_frame ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 13:37:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										net_err_ratelimited ( " %s: frame too short! \n " ,  __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-09 23:24:53 +09:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									xid  =  ( struct  xid_frame  * )  skb - > data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > daddr  =  le32_to_cpu ( xid - > saddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > saddr  =  le32_to_cpu ( xid - > daddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Make sure frame is addressed to us */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( info - > saddr  ! =  self - > saddr )  & &  ( info - > saddr  ! =  BROADCAST ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pr_debug ( " %s(), frame is not addressed to us! \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( xid - > flags  &  0x03 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  0x00 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										info - > S  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  0x01 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										info - > S  =  6 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  0x02 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										info - > S  =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  0x03 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										info - > S  =  16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Error!! */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > s  =  xid - > slotnr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									discovery_info  =  skb_pull ( skb ,  sizeof ( struct  xid_frame ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *   Check  if  last  frame 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( info - > s  = =  0xff )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Check if things are sane at this point... */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-09 23:24:53 +09:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if ( ( discovery_info  = =  NULL )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										   ! pskb_may_pull ( skb ,  3 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 13:37:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											net_err_ratelimited ( " %s: discovery frame too short! \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													    __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   We  now  have  some  discovery  info  to  deliver ! 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-16 23:13:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										discovery  =  kzalloc ( sizeof ( discovery_t ) ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 13:37:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! discovery ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										discovery - > data . daddr  =  info - > daddr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										discovery - > data . saddr  =  self - > saddr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										discovery - > timestamp  =  jiffies ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										discovery - > data . hints [ 0 ]  =  discovery_info [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( discovery_info [ 0 ]  &  HINT_EXTENSION )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											discovery - > data . hints [ 1 ]  =  discovery_info [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											discovery - > data . charset  =  discovery_info [ 2 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											text  =  ( char  * )  & discovery_info [ 3 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											discovery - > data . hints [ 1 ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											discovery - > data . charset  =  discovery_info [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											text  =  ( char  * )  & discovery_info [ 2 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Terminate  string ,  should  be  safe  since  this  is  where  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   FCS  bytes  resides . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										skb - > data [ skb - > len ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										strncpy ( discovery - > data . info ,  text ,  NICKNAME_MAX_LEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										discovery - > name_len  =  strlen ( discovery - > data . info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										info - > discovery  =  discovery ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										info - > discovery  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_do_event ( self ,  RECV_DISCOVERY_XID_CMD ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_send_rr_frame  ( self ,  command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Build  and  transmit  RR  ( Receive  Ready )  frame .  Notice  that  it  is  currently 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     only  possible  to  send  RR  frames  with  the  poll  bit  set . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_send_rr_frame ( struct  irlap_cb  * self ,  int  command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * tx_skb ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  rr_frame  * frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tx_skb  =  alloc_skb ( sizeof ( struct  rr_frame ) ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! tx_skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									frame  =  ( struct  rr_frame  * ) skb_put ( tx_skb ,  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									frame - > caddr  =  self - > caddr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame - > caddr  | =  ( command )  ?  CMD_FRAME  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									frame - > control  =  RR  |  PF_BIT  |  ( self - > vr  < <  5 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_queue_xmit ( self ,  tx_skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_send_rd_frame  ( self ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Request  disconnect .  Used  by  a  secondary  station  to  request  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     disconnection  of  the  link . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_send_rd_frame ( struct  irlap_cb  * self ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * tx_skb ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  rd_frame  * frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tx_skb  =  alloc_skb ( sizeof ( struct  rd_frame ) ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! tx_skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									frame  =  ( struct  rd_frame  * ) skb_put ( tx_skb ,  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									frame - > caddr  =  self - > caddr ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-08-12 11:28:41 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									frame - > control  =  RD_RSP  |  PF_BIT ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_queue_xmit ( self ,  tx_skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_recv_rr_frame  ( skb ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Received  RR  ( Receive  Ready )  frame  from  peer  station ,  no  harm  in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     making  it  inline  since  its  called  only  from  one  single  place 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     ( irlap_driver_rcv ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  irlap_recv_rr_frame ( struct  irlap_cb  * self , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												       struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												       struct  irlap_info  * info ,  int  command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > nr  =  skb - > data [ 1 ]  > >  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Check if this is a command or a response frame */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_RR_CMD ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_RR_RSP ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_recv_rnr_frame  ( self ,  skb ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Received  RNR  ( Receive  Not  Ready )  frame  from  peer  station 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  irlap_recv_rnr_frame ( struct  irlap_cb  * self ,  struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 struct  irlap_info  * info ,  int  command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > nr  =  skb - > data [ 1 ]  > >  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pr_debug ( " %s(), nr=%d, %ld \n " ,  __func__ ,  info - > nr ,  jiffies ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_RNR_CMD ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_RNR_RSP ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  irlap_recv_rej_frame ( struct  irlap_cb  * self ,  struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 struct  irlap_info  * info ,  int  command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > nr  =  skb - > data [ 1 ]  > >  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Check if this is a command or a response frame */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_REJ_CMD ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_REJ_RSP ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  irlap_recv_srej_frame ( struct  irlap_cb  * self ,  struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												  struct  irlap_info  * info ,  int  command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > nr  =  skb - > data [ 1 ]  > >  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Check if this is a command or a response frame */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_SREJ_CMD ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_SREJ_RSP ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  irlap_recv_disc_frame ( struct  irlap_cb  * self ,  struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												  struct  irlap_info  * info ,  int  command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Check if this is a command or a response frame */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_DISC_CMD ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_RD_RSP ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_recv_ua_frame  ( skb ,  frame ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Received  UA  ( Unnumbered  Acknowledgement )  frame 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  irlap_recv_ua_frame ( struct  irlap_cb  * self , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												       struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												       struct  irlap_info  * info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_do_event ( self ,  RECV_UA_RSP ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_send_data_primary ( self ,  skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Send  I - frames  as  the  primary  station  but  without  the  poll  bit  set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_send_data_primary ( struct  irlap_cb  * self ,  struct  sk_buff  * skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * tx_skb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( skb - > data [ 1 ]  = =  I_FRAME )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Insert  frame  sequence  number  ( Vs )  in  control  field  before 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   inserting  into  transmit  window  queue . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										skb - > data [ 1 ]  =  I_FRAME  |  ( self - > vs  < <  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Insert  frame  in  store ,  in  case  of  retransmissions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Increase  skb  reference  count ,  see  irlap_do_event ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										skb_get ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										skb_queue_tail ( & self - > wx_list ,  skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Copy buffer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tx_skb  =  skb_clone ( skb ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( tx_skb  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										self - > vs  =  ( self - > vs  +  1 )  %  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										self - > ack_required  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										self - > window  - =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_send_i_frame (  self ,  tx_skb ,  CMD_FRAME ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pr_debug ( " %s(), sending unreliable frame \n " ,  __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										irlap_send_ui_frame ( self ,  skb_get ( skb ) ,  self - > caddr ,  CMD_FRAME ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										self - > window  - =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_send_data_primary_poll  ( self ,  skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Send  I ( nformation )  frame  as  primary  with  poll  bit  set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_send_data_primary_poll ( struct  irlap_cb  * self ,  struct  sk_buff  * skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * tx_skb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  transmission_time ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Stop P timer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									del_timer ( & self - > poll_timer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Is this reliable or unreliable data? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( skb - > data [ 1 ]  = =  I_FRAME )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Insert  frame  sequence  number  ( Vs )  in  control  field  before 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   inserting  into  transmit  window  queue . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										skb - > data [ 1 ]  =  I_FRAME  |  ( self - > vs  < <  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Insert  frame  in  store ,  in  case  of  retransmissions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Increase  skb  reference  count ,  see  irlap_do_event ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										skb_get ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										skb_queue_tail ( & self - > wx_list ,  skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Copy buffer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tx_skb  =  skb_clone ( skb ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( tx_skb  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Set  poll  bit  if  necessary .  We  do  this  to  the  copied 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   skb ,  since  retransmitted  need  to  set  or  clear  the  poll 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   bit  depending  on  when  they  are  sent . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tx_skb - > data [ 1 ]  | =  PF_BIT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										self - > vs  =  ( self - > vs  +  1 )  %  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										self - > ack_required  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-08 19:15:17 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										irlap_next_state ( self ,  LAP_NRM_P ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										irlap_send_i_frame ( self ,  tx_skb ,  CMD_FRAME ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pr_debug ( " %s(), sending unreliable frame \n " ,  __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( self - > ack_required )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											irlap_send_ui_frame ( self ,  skb_get ( skb ) ,  self - > caddr ,  CMD_FRAME ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-08 19:15:17 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											irlap_next_state ( self ,  LAP_NRM_P ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											irlap_send_rr_frame ( self ,  CMD_FRAME ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											self - > ack_required  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											skb - > data [ 1 ]  | =  PF_BIT ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-08 19:15:17 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											irlap_next_state ( self ,  LAP_NRM_P ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											irlap_send_ui_frame ( self ,  skb_get ( skb ) ,  self - > caddr ,  CMD_FRAME ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* How much time we took for transmission of all frames.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  We  don ' t  know ,  so  let  assume  we  used  the  full  window .  Jean  II  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									transmission_time  =  self - > final_timeout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Reset parameter so that we can fill next window */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									self - > window  =  self - > window_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef CONFIG_IRDA_DYNAMIC_WINDOW 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Remove what we have not used. Just do a prorata of the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  bytes  left  in  window  to  window  capacity . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  See  max_line_capacities [ ] [ ]  in  qos . c  for  details .  Jean  II  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									transmission_time  - =  ( self - > final_timeout  *  self - > bytes_left 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											      /  self - > line_capacity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pr_debug ( " %s() adjusting transmission_time : ft=%d, bl=%d, lc=%d -> tt=%d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 __func__ ,  self - > final_timeout ,  self - > bytes_left , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 self - > line_capacity ,  transmission_time ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* We are allowed to transmit a maximum number of bytes again. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									self - > bytes_left  =  self - > line_capacity ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif  /* CONFIG_IRDA_DYNAMIC_WINDOW */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  The  network  layer  has  a  intermediate  buffer  between  IrLAP 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  and  the  IrDA  driver  which  can  contain  8  frames .  So ,  even 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  though  IrLAP  is  currently  sending  the  * last *  frame  of  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  tx - window ,  the  driver  most  likely  has  only  just  started 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  sending  the  * first *  frame  of  the  same  tx - window . 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-30 22:57:33 -03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									 *  I . e .  we  are  always  at  the  very  beginning  of  or  Tx  window . 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									 *  Now ,  we  are  supposed  to  set  the  final  timer  from  the  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  of  our  tx - window  to  let  the  other  peer  reply .  So ,  we  need 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  to  add  extra  time  to  compensate  for  the  fact  that  we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  are  really  at  the  start  of  tx - window ,  otherwise  the  final  timer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  might  expire  before  he  can  answer . . . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Jean  II 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_start_final_timer ( self ,  self - > final_timeout  +  transmission_time ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  The  clever  amongst  you  might  ask  why  we  do  this  adjustement 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  only  here ,  and  not  in  all  the  other  cases  in  irlap_event . c . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  In  all  those  other  case ,  we  only  send  a  very  short  management 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  frame  ( few  bytes ) ,  so  the  adjustement  would  be  lost  in  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  noise . . . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  The  exception  of  course  is  irlap_resend_rejected_frame ( ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Jean  II  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_send_data_secondary_final  ( self ,  skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Send  I ( nformation )  frame  as  secondary  with  final  bit  set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_send_data_secondary_final ( struct  irlap_cb  * self , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												     struct  sk_buff  * skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * tx_skb  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self - > magic  = =  LAP_MAGIC ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( skb  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Is this reliable or unreliable data? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( skb - > data [ 1 ]  = =  I_FRAME )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Insert  frame  sequence  number  ( Vs )  in  control  field  before 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   inserting  into  transmit  window  queue . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										skb - > data [ 1 ]  =  I_FRAME  |  ( self - > vs  < <  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Insert  frame  in  store ,  in  case  of  retransmissions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Increase  skb  reference  count ,  see  irlap_do_event ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										skb_get ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										skb_queue_tail ( & self - > wx_list ,  skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tx_skb  =  skb_clone ( skb ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( tx_skb  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tx_skb - > data [ 1 ]  | =  PF_BIT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										self - > vs  =  ( self - > vs  +  1 )  %  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										self - > ack_required  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_send_i_frame ( self ,  tx_skb ,  RSP_FRAME ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( self - > ack_required )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											irlap_send_ui_frame ( self ,  skb_get ( skb ) ,  self - > caddr ,  RSP_FRAME ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											irlap_send_rr_frame ( self ,  RSP_FRAME ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											self - > ack_required  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											skb - > data [ 1 ]  | =  PF_BIT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											irlap_send_ui_frame ( self ,  skb_get ( skb ) ,  self - > caddr ,  RSP_FRAME ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									self - > window  =  self - > window_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef CONFIG_IRDA_DYNAMIC_WINDOW 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* We are allowed to transmit a maximum number of bytes again. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									self - > bytes_left  =  self - > line_capacity ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif  /* CONFIG_IRDA_DYNAMIC_WINDOW */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_start_wd_timer ( self ,  self - > wd_timeout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_send_data_secondary  ( self ,  skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Send  I ( nformation )  frame  as  secondary  without  final  bit  set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_send_data_secondary ( struct  irlap_cb  * self ,  struct  sk_buff  * skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * tx_skb  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Is this reliable or unreliable data? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( skb - > data [ 1 ]  = =  I_FRAME )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Insert  frame  sequence  number  ( Vs )  in  control  field  before 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   inserting  into  transmit  window  queue . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										skb - > data [ 1 ]  =  I_FRAME  |  ( self - > vs  < <  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Insert  frame  in  store ,  in  case  of  retransmissions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Increase  skb  reference  count ,  see  irlap_do_event ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										skb_get ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										skb_queue_tail ( & self - > wx_list ,  skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tx_skb  =  skb_clone ( skb ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( tx_skb  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										self - > vs  =  ( self - > vs  +  1 )  %  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										self - > ack_required  =  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										self - > window  - =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_send_i_frame ( self ,  tx_skb ,  RSP_FRAME ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_send_ui_frame ( self ,  skb_get ( skb ) ,  self - > caddr ,  RSP_FRAME ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										self - > window  - =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_resend_rejected_frames  ( nr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Resend  frames  which  has  not  been  acknowledged .  Should  be  safe  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     traverse  the  list  without  locking  it  since  this  function  will  only  be 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     called  from  interrupt  context  ( BH ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_resend_rejected_frames ( struct  irlap_cb  * self ,  int  command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * tx_skb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * skb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self - > magic  = =  LAP_MAGIC ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*  Resend unacknowledged frame(s) */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-28 23:26:33 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									skb_queue_walk ( & self - > wx_list ,  skb )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										irlap_wait_min_turn_around ( self ,  & self - > qos_tx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* We copy the skb to be retransmitted since we will have to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  modify  it .  Cloning  will  confuse  packet  sniffers 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* tx_skb = skb_clone( skb, GFP_ATOMIC); */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tx_skb  =  skb_copy ( skb ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! tx_skb )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											pr_debug ( " %s(), unable to copy \n " ,  __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Clear old Nr field + poll bit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tx_skb - > data [ 1 ]  & =  0x0f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Set  poll  bit  on  the  last  frame  retransmitted 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-28 23:26:33 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( skb_queue_is_last ( & self - > wx_list ,  skb ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											tx_skb - > data [ 1 ]  | =  PF_BIT ;  /* Set p/f bit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											tx_skb - > data [ 1 ]  & =  ~ PF_BIT ;  /* Clear p/f bit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_send_i_frame ( self ,  tx_skb ,  command ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								#if 0  /* Not yet */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *   We  can  now  fill  the  window  with  additional  data  frames 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 14:57:23 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									while  ( ! skb_queue_empty ( & self - > txq ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pr_debug ( " %s(), sending additional frames! \n " ,  __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 14:57:23 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( self - > window  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											skb  =  skb_dequeue (  & self - > txq ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											IRDA_ASSERT ( skb  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *   If  send  window  >  1  then  send  frame  with  pf 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *   bit  cleared 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ( self - > window  >  1 )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 14:57:23 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											    ! skb_queue_empty ( & self - > txq ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
												irlap_send_data_primary ( self ,  skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												irlap_send_data_primary_poll ( self ,  skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											kfree_skb ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_resend_rejected_frame ( struct  irlap_cb  * self ,  int  command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * tx_skb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * skb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self - > magic  = =  LAP_MAGIC ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*  Resend unacknowledged frame(s) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									skb  =  skb_peek ( & self - > wx_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( skb  ! =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_wait_min_turn_around ( self ,  & self - > qos_tx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* We copy the skb to be retransmitted since we will have to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  modify  it .  Cloning  will  confuse  packet  sniffers 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* tx_skb = skb_clone( skb, GFP_ATOMIC); */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tx_skb  =  skb_copy ( skb ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! tx_skb )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											pr_debug ( " %s(), unable to copy \n " ,  __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Clear old Nr field + poll bit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tx_skb - > data [ 1 ]  & =  0x0f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*  Set poll/final bit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tx_skb - > data [ 1 ]  | =  PF_BIT ;  /* Set p/f bit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_send_i_frame ( self ,  tx_skb ,  command ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_send_ui_frame  ( self ,  skb ,  command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Contruct  and  transmit  an  Unnumbered  Information  ( UI )  frame 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_send_ui_frame ( struct  irlap_cb  * self ,  struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 __u8  caddr ,  int  command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self - > magic  = =  LAP_MAGIC ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( skb  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Insert connection address */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									skb - > data [ 0 ]  =  caddr  |  ( ( command )  ?  CMD_FRAME  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_queue_xmit ( self ,  skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_send_i_frame  ( skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Contruct  and  transmit  Information  ( I )  frame 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  irlap_send_i_frame ( struct  irlap_cb  * self ,  struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											       int  command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Insert connection address */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									skb - > data [ 0 ]  =  self - > caddr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									skb - > data [ 0 ]  | =  ( command )  ?  CMD_FRAME  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Insert next to receive (Vr) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									skb - > data [ 1 ]  | =  ( self - > vr  < <  5 ) ;   /* insert nr */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_queue_xmit ( self ,  skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_recv_i_frame  ( skb ,  frame ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Receive  and  parse  an  I  ( Information )  frame ,  no  harm  in  making  it  inline 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     since  it ' s  called  only  from  one  single  place  ( irlap_driver_rcv ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  irlap_recv_i_frame ( struct  irlap_cb  * self , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												      struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												      struct  irlap_info  * info ,  int  command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > nr  =  skb - > data [ 1 ]  > >  5 ;           /* Next to receive */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > pf  =  skb - > data [ 1 ]  &  PF_BIT ;       /* Final bit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > ns  =  ( skb - > data [ 1 ]  > >  1 )  &  0x07 ;  /* Next to send */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Check if this is a command or a response frame */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_I_CMD ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_I_RSP ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_recv_ui_frame  ( self ,  skb ,  info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Receive  and  parse  an  Unnumbered  Information  ( UI )  frame 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  irlap_recv_ui_frame ( struct  irlap_cb  * self ,  struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												struct  irlap_info  * info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > pf  =  skb - > data [ 1 ]  &  PF_BIT ;       /* Final bit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_do_event ( self ,  RECV_UI_FRAME ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_recv_frmr_frame  ( skb ,  frame ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Received  Frame  Reject  response . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  irlap_recv_frmr_frame ( struct  irlap_cb  * self ,  struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												  struct  irlap_info  * info ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									__u8  * frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  w ,  x ,  y ,  z ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( self - > magic  = =  LAP_MAGIC ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( skb  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									IRDA_ASSERT ( info  ! =  NULL ,  return ; ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! pskb_may_pull ( skb ,  4 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 13:37:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										net_err_ratelimited ( " %s: frame too short! \n " ,  __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame  =  skb - > data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > nr  =  frame [ 2 ]  > >  5 ;           /* Next to receive */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > pf  =  frame [ 2 ]  &  PF_BIT ;       /* Final bit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info - > ns  =  ( frame [ 2 ]  > >  1 )  &  0x07 ;  /* Next to send */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									w  =  frame [ 3 ]  &  0x01 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									x  =  frame [ 3 ]  &  0x02 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									y  =  frame [ 3 ]  &  0x04 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									z  =  frame [ 3 ]  &  0x08 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( w )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pr_debug ( " Rejected control field is undefined or not implemented \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( x )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pr_debug ( " Rejected control field was invalid because it contained a non permitted I field \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( y )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pr_debug ( " Received I field exceeded the maximum negotiated for the existing connection or exceeded the maximum this station supports if no connection exists \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( z )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pr_debug ( " Rejected control field control field contained an invalid Nr count \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_do_event ( self ,  RECV_FRMR_RSP ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_send_test_frame  ( self ,  daddr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Send  a  test  frame  response 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  irlap_send_test_frame ( struct  irlap_cb  * self ,  __u8  caddr ,  __u32  daddr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											   struct  sk_buff  * cmd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  sk_buff  * tx_skb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  test_frame  * frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									__u8  * info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-27 20:06:44 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tx_skb  =  alloc_skb ( cmd - > len  +  sizeof ( struct  test_frame ) ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! tx_skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Broadcast frames must include saddr and daddr fields */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( caddr  = =  CBROADCAST )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame  =  ( struct  test_frame  * ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											skb_put ( tx_skb ,  sizeof ( struct  test_frame ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Insert the swapped addresses */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > saddr  =  cpu_to_le32 ( self - > saddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > daddr  =  cpu_to_le32 ( daddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame  =  ( struct  test_frame  * )  skb_put ( tx_skb ,  LAP_ADDR_HEADER  +  LAP_CTRL_HEADER ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame - > caddr  =  caddr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame - > control  =  TEST_RSP  |  PF_BIT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Copy info */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info  =  skb_put ( tx_skb ,  cmd - > len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									memcpy ( info ,  cmd - > data ,  cmd - > len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Return to sender */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_wait_min_turn_around ( self ,  & self - > qos_tx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									irlap_queue_xmit ( self ,  tx_skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_recv_test_frame  ( self ,  skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Receive  a  test  frame 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  irlap_recv_test_frame ( struct  irlap_cb  * self ,  struct  sk_buff  * skb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												  struct  irlap_info  * info ,  int  command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  test_frame  * frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! pskb_may_pull ( skb ,  sizeof ( * frame ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 13:37:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										net_err_ratelimited ( " %s: frame too short! \n " ,  __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									frame  =  ( struct  test_frame  * )  skb - > data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Broadcast frames must carry saddr and daddr fields */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( info - > caddr  = =  CBROADCAST )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( skb - > len  <  sizeof ( struct  test_frame ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											pr_debug ( " %s() test frame too short! \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Read and swap addresses */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										info - > daddr  =  le32_to_cpu ( frame - > saddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										info - > saddr  =  le32_to_cpu ( frame - > daddr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Make sure frame is addressed to us */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ( info - > saddr  ! =  self - > saddr )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										    ( info - > saddr  ! =  BROADCAST ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( command ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_TEST_CMD ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_TEST_RSP ,  skb ,  info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Function  irlap_driver_rcv  ( skb ,  netdev ,  ptype ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     Called  when  a  frame  is  received .  Dispatches  the  right  receive  function 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *     for  processing  of  the  frame . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Note  on  skb  management  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  After  calling  the  higher  layers  of  the  IrDA  stack ,  we  always 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  kfree ( )  the  skb ,  which  drop  the  reference  count  ( and  potentially 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  destroy  it ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  If  a  higher  layer  of  the  stack  want  to  keep  the  skb  around  ( to  put 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  in  a  queue  or  pass  it  to  the  higher  layer ) ,  it  will  need  to  use 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  skb_get ( )  to  keep  a  reference  on  it .  This  is  usually  done  at  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  LMP  level  in  irlmp . c . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Jean  II 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  irlap_driver_rcv ( struct  sk_buff  * skb ,  struct  net_device  * dev , 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 19:34:12 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										     struct  packet_type  * ptype ,  struct  net_device  * orig_dev ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  irlap_info  info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  irlap_cb  * self ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  command ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									__u8  control ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-14 23:18:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  ret  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-19 22:34:43 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! net_eq ( dev_net ( dev ) ,  & init_net ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-17 11:53:39 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									/* FIXME: should we get our own field? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									self  =  ( struct  irlap_cb  * )  dev - > atalk_ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* If the net device is down, then IrLAP is gone! */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-14 23:18:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! self  | |  self - > magic  ! =  LAP_MAGIC ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										goto  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* We are no longer an "old" protocol, so we need to handle
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  share  and  non  linear  skbs .  This  should  never  happen ,  so 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  we  don ' t  need  to  be  clever  about  it .  Jean  II  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( skb  =  skb_share_check ( skb ,  GFP_ATOMIC ) )  = =  NULL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 13:37:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										net_err_ratelimited ( " %s: can't clone shared skb! \n " ,  __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-14 23:18:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										goto  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Check if frame is large enough for parsing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! pskb_may_pull ( skb ,  2 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 13:37:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										net_err_ratelimited ( " %s: frame too short! \n " ,  __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-14 23:18:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										goto  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									command     =  skb - > data [ 0 ]  &  CMD_FRAME ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info . caddr  =  skb - > data [ 0 ]  &  CBROADCAST ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info . pf       =  skb - > data [ 1 ]  &   PF_BIT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									info . control  =  skb - > data [ 1 ]  &  ~ PF_BIT ;  /* Mask away poll/final bit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									control  =  info . control ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*  First we check if this frame has a valid connection address */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( info . caddr  ! =  self - > caddr )  & &  ( info . caddr  ! =  CBROADCAST ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 14:44:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pr_debug ( " %s(), wrong connection address! \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 __func__ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *   Optimize  for  the  common  case  and  check  if  the  frame  is  an 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *   I ( nformation )  frame .  Only  I - frames  have  bit  0  set  to  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ~ control  &  0x01 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_recv_i_frame ( self ,  skb ,  & info ,  command ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *   We  now  check  is  the  frame  is  an  S ( upervisory )  frame .  Only 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *   S - frames  have  bit  0  set  to  1  and  bit  1  set  to  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ~ control  &  0x02 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   Received  S ( upervisory )  frame ,  check  which  frame  type  it  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *   only  the  first  nibble  is  of  interest 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  ( control  &  0x0f )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  RR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											irlap_recv_rr_frame ( self ,  skb ,  & info ,  command ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  RNR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											irlap_recv_rnr_frame ( self ,  skb ,  & info ,  command ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  REJ : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											irlap_recv_rej_frame ( self ,  skb ,  & info ,  command ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  SREJ : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											irlap_recv_srej_frame ( self ,  skb ,  & info ,  command ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 13:37:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											net_warn_ratelimited ( " %s: Unknown S-frame %02x received! \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													     __func__ ,  info . control ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *   This  must  be  a  C ( ontrol )  frame 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( control )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  XID_RSP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_recv_discovery_xid_rsp ( self ,  skb ,  & info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  XID_CMD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_recv_discovery_xid_cmd ( self ,  skb ,  & info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  SNRM_CMD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_recv_snrm_cmd ( self ,  skb ,  & info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  DM_RSP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_do_event ( self ,  RECV_DM_RSP ,  skb ,  & info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  DISC_CMD :  /* And RD_RSP since they have the same value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_recv_disc_frame ( self ,  skb ,  & info ,  command ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  TEST_CMD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_recv_test_frame ( self ,  skb ,  & info ,  command ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  UA_RSP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_recv_ua_frame ( self ,  skb ,  & info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  FRMR_RSP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_recv_frmr_frame ( self ,  skb ,  & info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  UI_FRAME : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										irlap_recv_ui_frame ( self ,  skb ,  & info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
									
										
										
										
											2014-11-11 13:37:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										net_warn_ratelimited ( " %s: Unknown frame %02x received! \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												     __func__ ,  info . control ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								out : 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-14 23:18:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ret  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								err : 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									/* Always drop our reference on the skb */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dev_kfree_skb ( skb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-14 23:18:30 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ret ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								}