2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/*
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 23:46:58 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * Copyright (c) 2008, 2009 open80211s Ltd.
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * Author:     Luis Carlos Cobo <luisca@cozybit.com>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * This program is free software; you can redistribute it and/or modify
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * it under the terms of the GNU General Public License version 2 as
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * published by the Free Software Foundation.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												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/gfp.h>
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:19 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <linux/kernel.h>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include <linux/random.h>
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include "ieee80211_i.h"
							 | 
						
					
						
							
								
									
										
										
										
											2008-04-08 15:14:40 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include "rate.h"
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include "mesh.h"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define mpl_dbg(fmt, args...)	printk(KERN_DEBUG fmt, ##args)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define mpl_dbg(fmt, args...)	do { (void)(0); } while (0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 23:46:43 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define PLINK_GET_LLID(p) (p + 4)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define PLINK_GET_PLID(p) (p + 6)
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												jiffies + HZ * t / 1000))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/* Peer link cancel reasons, all subject to ANA approval */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MESH_LINK_CANCELLED			2
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MESH_MAX_NEIGHBORS			3
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MESH_CAPABILITY_POLICY_VIOLATION	4
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MESH_CLOSE_RCVD				5
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MESH_MAX_RETRIES			6
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MESH_CONFIRM_TIMEOUT			7
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MESH_SECURITY_ROLE_NEGOTIATION_DIFFERS	8
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MESH_SECURITY_AUTHENTICATION_IMPOSSIBLE	9
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define MESH_SECURITY_FAILED_VERIFICATION	10
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:01:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#define dot11MeshMaxRetries(s) (s->u.mesh.mshcfg.dot11MeshMaxRetries)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define dot11MeshRetryTimeout(s) (s->u.mesh.mshcfg.dot11MeshRetryTimeout)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define dot11MeshConfirmTimeout(s) (s->u.mesh.mshcfg.dot11MeshConfirmTimeout)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								enum plink_frame_type {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									PLINK_OPEN = 0,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									PLINK_CONFIRM,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									PLINK_CLOSE
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								enum plink_event {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									PLINK_UNDEFINED,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									OPN_ACPT,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									OPN_RJCT,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									OPN_IGNR,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									CNF_ACPT,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									CNF_RJCT,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									CNF_IGNR,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									CLS_ACPT,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									CLS_IGNR
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static inline
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:01:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									atomic_inc(&sdata->u.mesh.mshstats.estab_plinks);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									mesh_accept_plinks_update(sdata);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static inline
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:01:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									atomic_dec(&sdata->u.mesh.mshstats.estab_plinks);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									mesh_accept_plinks_update(sdata);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 23:46:42 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * @sta: mesh peer link to restart
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * Locking: this function must be called holding sta->lock
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static inline void mesh_plink_fsm_restart(struct sta_info *sta)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									sta->plink_state = PLINK_LISTEN;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 12:13:38 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									sta->llid = sta->plid = sta->reason = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									sta->plink_retries = 0;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-04-01 15:21:00 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								/*
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * NOTE: This is just an alias for sta_info_alloc(), see notes
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *       on it in the lifecycle management section!
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-27 09:56:40 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
							 | 
						
					
						
							
								
									
										
										
										
											2009-01-21 15:13:48 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
													 u8 *hw_addr, u32 rates)
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct ieee80211_local *local = sdata->local;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct sta_info *sta;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (local->num_sta >= MESH_MAX_PLINKS)
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:47 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										return NULL;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-03 13:59:58 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:47 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (!sta)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return NULL;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									sta->flags = WLAN_STA_AUTHORIZED;
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 02:45:11 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
							 | 
						
					
						
							
								
									
										
										
										
											2008-12-27 22:19:49 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									rate_control_rate_init(sta);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return sta;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * __mesh_plink_deactivate - deactivate mesh peer link
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * @sta: mesh peer link to deactivate
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * All mesh paths with this peer as next hop will be flushed
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * Locking: the caller must hold sta->lock
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static bool __mesh_plink_deactivate(struct sta_info *sta)
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct ieee80211_sub_if_data *sdata = sta->sdata;
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									bool deactivated = false;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (sta->plink_state == PLINK_ESTAB) {
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										mesh_plink_dec_estab_count(sdata);
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										deactivated = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									sta->plink_state = PLINK_BLOCKED;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									mesh_path_flush_by_nexthop(sta);
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return deactivated;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:19 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								/**
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 * mesh_plink_deactivate - deactivate mesh peer link
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:19 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * @sta: mesh peer link to deactivate
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 *
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * All mesh paths with this peer as next hop will be flushed
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void mesh_plink_deactivate(struct sta_info *sta)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct ieee80211_sub_if_data *sdata = sta->sdata;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									bool deactivated;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									spin_lock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									deactivated = __mesh_plink_deactivate(sta);
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (deactivated)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:19 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-08-03 12:04:37 +12:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										__le16 reason) {
							 | 
						
					
						
							
								
									
										
										
										
											2008-08-03 12:04:37 +12:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct ieee80211_local *local = sdata->local;
							 | 
						
					
						
							
								
									
										
										
										
											2010-12-16 17:37:49 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											sdata->u.mesh.vendor_ie_len);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct ieee80211_mgmt *mgmt;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									bool include_plid = false;
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 23:46:43 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									static const u8 meshpeeringproto[] = { 0x00, 0x0F, 0xAC, 0x2A };
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									u8 *pos;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									int ie_len;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (!skb)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return -1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									skb_reserve(skb, local->hw.extra_tx_headroom);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* 25 is the size of the common mgmt part (24) plus the size of the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * common action part (1)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									mgmt = (struct ieee80211_mgmt *)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										skb_put(skb, 25 + sizeof(mgmt->u.action.u.plink_action));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.plink_action));
							 | 
						
					
						
							
								
									
										
										
										
											2008-07-15 18:44:13 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
													  IEEE80211_STYPE_ACTION);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									memcpy(mgmt->da, da, ETH_ALEN);
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-25 17:46:19 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* BSSID is left zeroed, wildcard value */
							 | 
						
					
						
							
								
									
										
										
										
											2010-03-29 11:00:21 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									mgmt->u.action.category = WLAN_CATEGORY_MESH_PLINK;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									mgmt->u.action.u.plink_action.action_code = action;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (action == PLINK_CLOSE)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										mgmt->u.action.u.plink_action.aux = reason;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										mgmt->u.action.u.plink_action.aux = cpu_to_le16(0x0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (action == PLINK_CONFIRM) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											pos = skb_put(skb, 4);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											/* two-byte status code followed by two-byte AID */
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 23:46:52 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											memset(pos, 0, 2);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											memcpy(pos + 2, &plid, 2);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2008-08-03 12:04:37 +12:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										mesh_mgmt_ies_add(skb, sdata);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Add Peer Link Management element */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									switch (action) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case PLINK_OPEN:
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 23:46:43 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										ie_len = 6;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case PLINK_CONFIRM:
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 23:46:43 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										ie_len = 8;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										include_plid = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case PLINK_CLOSE:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									default:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (!plid)
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 23:46:43 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											ie_len = 8;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										else {
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 23:46:43 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											ie_len = 10;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											include_plid = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									pos = skb_put(skb, 2 + ie_len);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									*pos++ = WLAN_EID_PEER_LINK;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									*pos++ = ie_len;
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 23:46:43 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									memcpy(pos, meshpeeringproto, sizeof(meshpeeringproto));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									pos += 4;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									memcpy(pos, &llid, 2);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (include_plid) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										pos += 2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										memcpy(pos, &plid, 2);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (action == PLINK_CLOSE) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										pos += 2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										memcpy(pos, &reason, 2);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-18 18:42:05 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									ieee80211_tx_skb(sdata, skb);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-01-21 15:13:48 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void mesh_neighbour_update(u8 *hw_addr, u32 rates, struct ieee80211_sub_if_data *sdata,
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											   bool peer_accepting_plinks)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2008-08-03 12:04:37 +12:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct ieee80211_local *local = sdata->local;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct sta_info *sta;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									rcu_read_lock();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-25 17:46:18 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									sta = sta_info_get(sdata, hw_addr);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (!sta) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-03 13:59:58 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										rcu_read_unlock();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-27 09:56:40 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										sta = mesh_plink_alloc(sdata, hw_addr, rates);
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-03 13:59:58 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (!sta)
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:47 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											return;
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-03 13:59:58 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (sta_info_insert_rcu(sta)) {
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											rcu_read_unlock();
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									sta->last_rx = jiffies;
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 02:45:11 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (peer_accepting_plinks && sta->plink_state == PLINK_LISTEN &&
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:01:49 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											sdata->u.mesh.accepting_plinks &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											sdata->u.mesh.mshcfg.auto_open_plinks)
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										mesh_plink_open(sta);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									rcu_read_unlock();
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static void mesh_plink_timer(unsigned long data)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct sta_info *sta;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									__le16 llid, plid, reason;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct ieee80211_sub_if_data *sdata;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									/*
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * This STA is valid because sta_info_destroy() will
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * del_timer_sync() this timer after having made sure
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * it cannot be readded (by deleting the plink.)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 */
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									sta = (struct sta_info *) data;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-05-17 11:40:42 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (sta->sdata->local->quiescing) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										sta->plink_timer_was_running = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									spin_lock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (sta->ignore_plink_timer) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										sta->ignore_plink_timer = false;
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2008-10-27 15:56:10 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									mpl_dbg("Mesh plink timer for %pM fired on state %d\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										sta->sta.addr, sta->plink_state);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									reason = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									llid = sta->llid;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									plid = sta->plid;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									sdata = sta->sdata;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									switch (sta->plink_state) {
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									case PLINK_OPN_RCVD:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case PLINK_OPN_SNT:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* retry timer */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (sta->plink_retries < dot11MeshMaxRetries(sdata)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											u32 rand;
							 | 
						
					
						
							
								
									
										
										
										
											2008-10-27 15:56:10 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mpl_dbg("Mesh plink for %pM (retry, timeout): %d %d\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												sta->sta.addr, sta->plink_retries,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												sta->plink_timeout);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											get_random_bytes(&rand, sizeof(u32));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											sta->plink_timeout = sta->plink_timeout +
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
													     rand % sta->plink_timeout;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											++sta->plink_retries;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mod_plink_timer(sta, sta->plink_timeout);
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mesh_plink_frame_tx(sdata, PLINK_OPEN, sta->sta.addr, llid,
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
													    0, 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										reason = cpu_to_le16(MESH_MAX_RETRIES);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* fall through on else */
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									case PLINK_CNF_RCVD:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* confirm timer */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (!reason)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										sta->plink_state = PLINK_HOLDING;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, plid,
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
												    reason);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									case PLINK_HOLDING:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* holding timer */
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										del_timer(&sta->plink_timer);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										mesh_plink_fsm_restart(sta);
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									default:
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-05-17 11:40:42 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#ifdef CONFIG_PM
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void mesh_plink_quiesce(struct sta_info *sta)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (del_timer_sync(&sta->plink_timer))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										sta->plink_timer_was_running = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void mesh_plink_restart(struct sta_info *sta)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (sta->plink_timer_was_running) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										add_timer(&sta->plink_timer);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										sta->plink_timer_was_running = false;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									sta->plink_timer.expires = jiffies + (HZ * timeout / 1000);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									sta->plink_timer.data = (unsigned long) sta;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									sta->plink_timer.function = mesh_plink_timer;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									sta->plink_timeout = timeout;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									add_timer(&sta->plink_timer);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								int mesh_plink_open(struct sta_info *sta)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									__le16 llid;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct ieee80211_sub_if_data *sdata = sta->sdata;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									spin_lock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									get_random_bytes(&llid, 2);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									sta->llid = llid;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (sta->plink_state != PLINK_LISTEN) {
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return -EBUSY;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									sta->plink_state = PLINK_OPN_SNT;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-10-27 15:56:10 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									mpl_dbg("Mesh plink: starting establishment with %pM\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										sta->sta.addr);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-08-03 12:04:37 +12:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return mesh_plink_frame_tx(sdata, PLINK_OPEN,
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
												   sta->sta.addr, llid, 0, 0);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void mesh_plink_block(struct sta_info *sta)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct ieee80211_sub_if_data *sdata = sta->sdata;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									bool deactivated;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									spin_lock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									deactivated = __mesh_plink_deactivate(sta);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									sta->plink_state = PLINK_BLOCKED;
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (deactivated)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-08-03 12:04:37 +12:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt,
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											 size_t len, struct ieee80211_rx_status *rx_status)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct ieee80211_local *local = sdata->local;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct ieee802_11_elems elems;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct sta_info *sta;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									enum plink_event event;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									enum plink_frame_type ftype;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									size_t baselen;
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-08 22:27:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									bool deactivated, matches_local = true;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									u8 ie_len;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									u8 *baseaddr;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									__le16 plid, llid, reason;
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 23:46:48 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									static const char *mplstates[] = {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										[PLINK_LISTEN] = "LISTEN",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										[PLINK_OPN_SNT] = "OPN-SNT",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										[PLINK_OPN_RCVD] = "OPN-RCVD",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										[PLINK_CNF_RCVD] = "CNF_RCVD",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										[PLINK_ESTAB] = "ESTAB",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										[PLINK_HOLDING] = "HOLDING",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										[PLINK_BLOCKED] = "BLOCKED"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									};
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#endif
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-08 15:41:59 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									/* need action_code, aux */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (len < IEEE80211_MIN_ACTION_SIZE + 3)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (is_multicast_ether_addr(mgmt->da)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										mpl_dbg("Mesh plink: ignore frame from multicast address");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									baseaddr = mgmt->u.action.u.plink_action.variable;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									baselen = (u8 *) mgmt->u.action.u.plink_action.variable - (u8 *) mgmt;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (mgmt->u.action.u.plink_action.action_code == PLINK_CONFIRM) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										baseaddr += 4;
							 | 
						
					
						
							
								
									
										
										
										
											2009-08-12 11:03:44 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										baselen += 4;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									ieee802_11_parse_elems(baseaddr, len - baselen, &elems);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (!elems.peer_link) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										mpl_dbg("Mesh plink: missing necessary peer link ie\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 23:46:43 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									ftype = mgmt->u.action.u.plink_action.action_code;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									ie_len = elems.peer_link_len;
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 23:46:43 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if ((ftype == PLINK_OPEN && ie_len != 6) ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    (ftype == PLINK_CONFIRM && ie_len != 8) ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    (ftype == PLINK_CLOSE && ie_len != 8 && ie_len != 10)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										mpl_dbg("Mesh plink: incorrect plink ie length %d %d\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										    ftype, ie_len);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (ftype != PLINK_CLOSE && (!elems.mesh_id || !elems.mesh_config)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										mpl_dbg("Mesh plink: missing necessary ie\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Note the lines below are correct, the llid in the frame is the plid
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * from the point of view of this host.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									memcpy(&plid, PLINK_GET_LLID(elems.peer_link), 2);
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 23:46:43 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (ftype == PLINK_CONFIRM || (ftype == PLINK_CLOSE && ie_len == 10))
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										memcpy(&llid, PLINK_GET_PLID(elems.peer_link), 2);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									rcu_read_lock();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-25 17:46:18 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									sta = sta_info_get(sdata, mgmt->sa);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (!sta && ftype != PLINK_OPEN) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										mpl_dbg("Mesh plink: cls or cnf from unknown peer\n");
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										rcu_read_unlock();
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (sta && sta->plink_state == PLINK_BLOCKED) {
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										rcu_read_unlock();
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Now we will figure out the appropriate event... */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									event = PLINK_UNDEFINED;
							 | 
						
					
						
							
								
									
										
										
										
											2008-08-03 12:04:37 +12:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) {
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-08 22:27:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										matches_local = false;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										switch (ftype) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case PLINK_OPEN:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											event = OPN_RJCT;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case PLINK_CONFIRM:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											event = CNF_RJCT;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case PLINK_CLOSE:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											/* avoid warning */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-08 22:27:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (!sta && !matches_local) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										rcu_read_unlock();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										llid = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												    plid, reason);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else if (!sta) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* ftype == PLINK_OPEN */
							 | 
						
					
						
							
								
									
										
										
										
											2009-01-21 15:13:48 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										u32 rates;
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-03 13:59:58 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										rcu_read_unlock();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (!mesh_plink_free_count(sdata)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											mpl_dbg("Mesh plink error: no more free plinks\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										rates = ieee80211_sta_get_rates(local, &elems, rx_status->band);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-27 09:56:40 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										sta = mesh_plink_alloc(sdata, mgmt->sa, rates);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:47 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (!sta) {
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											mpl_dbg("Mesh plink error: plink table full\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2010-02-03 13:59:58 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										if (sta_info_insert_rcu(sta)) {
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:47 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											rcu_read_unlock();
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										event = OPN_ACPT;
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										spin_lock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-08 22:27:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									} else if (matches_local) {
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										spin_lock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										switch (ftype) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case PLINK_OPEN:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if (!mesh_plink_free_count(sdata) ||
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											    (sta->plid && sta->plid != plid))
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
												event = OPN_IGNR;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												event = OPN_ACPT;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case PLINK_CONFIRM:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if (!mesh_plink_free_count(sdata) ||
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											    (sta->llid != llid || sta->plid != plid))
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
												event = CNF_IGNR;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												event = CNF_ACPT;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case PLINK_CLOSE:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if (sta->plink_state == PLINK_ESTAB)
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
												/* Do not check for llid or plid. This does not
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												 * follow the standard but since multiple plinks
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												 * per sta are not supported, it is necessary in
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												 * order to avoid a livelock when MP A sees an
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												 * establish peer link to MP B but MP B does not
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												 * see it. This can be caused by a timeout in
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												 * B's peer link establishment or B beign
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												 * restarted.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												 */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												event = CLS_ACPT;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											else if (sta->plid != plid)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												event = CLS_IGNR;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											else if (ie_len == 7 && sta->llid != llid)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												event = CLS_IGNR;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												event = CLS_ACPT;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										default:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											mpl_dbg("Mesh plink: unknown frame subtype\n");
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											rcu_read_unlock();
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							
								
									
										
										
										
											2010-10-08 22:27:07 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										spin_lock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-11-09 23:46:48 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										mgmt->sa, mplstates[sta->plink_state],
							 | 
						
					
						
							
								
									
										
										
										
											2008-10-27 15:56:10 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										le16_to_cpu(sta->llid), le16_to_cpu(sta->plid),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										event);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									reason = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									switch (sta->plink_state) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* spin_unlock as soon as state is updated at each case */
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									case PLINK_LISTEN:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										switch (event) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case CLS_ACPT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											mesh_plink_fsm_restart(sta);
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case OPN_ACPT:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											sta->plink_state = PLINK_OPN_RCVD;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											sta->plid = plid;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											get_random_bytes(&llid, 2);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											sta->llid = llid;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mesh_plink_frame_tx(sdata, PLINK_OPEN, sta->sta.addr, llid,
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
													    0, 0);
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr,
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
													    llid, plid, 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										default:
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									case PLINK_OPN_SNT:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										switch (event) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case OPN_RJCT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case CNF_RJCT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case CLS_ACPT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if (!reason)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												reason = cpu_to_le16(MESH_CLOSE_RCVD);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											sta->reason = reason;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											sta->plink_state = PLINK_HOLDING;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if (!mod_plink_timer(sta,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
													     dot11MeshHoldingTimeout(sdata)))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												sta->ignore_plink_timer = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											llid = sta->llid;
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid,
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
													    plid, reason);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case OPN_ACPT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											/* retry timer is left untouched */
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											sta->plink_state = PLINK_OPN_RCVD;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											sta->plid = plid;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											llid = sta->llid;
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid,
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
													    plid, 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case CNF_ACPT:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											sta->plink_state = PLINK_CNF_RCVD;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if (!mod_plink_timer(sta,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
													     dot11MeshConfirmTimeout(sdata)))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												sta->ignore_plink_timer = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										default:
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									case PLINK_OPN_RCVD:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										switch (event) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case OPN_RJCT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case CNF_RJCT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case CLS_ACPT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if (!reason)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												reason = cpu_to_le16(MESH_CLOSE_RCVD);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											sta->reason = reason;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											sta->plink_state = PLINK_HOLDING;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if (!mod_plink_timer(sta,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
													     dot11MeshHoldingTimeout(sdata)))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												sta->ignore_plink_timer = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											llid = sta->llid;
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid,
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
													    plid, reason);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case OPN_ACPT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											llid = sta->llid;
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid,
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
													    plid, 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case CNF_ACPT:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											del_timer(&sta->plink_timer);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											sta->plink_state = PLINK_ESTAB;
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mesh_plink_inc_estab_count(sdata);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
							 | 
						
					
						
							
								
									
										
										
										
											2008-10-27 15:56:10 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mpl_dbg("Mesh plink with %pM ESTABLISHED\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												sta->sta.addr);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										default:
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									case PLINK_CNF_RCVD:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										switch (event) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case OPN_RJCT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case CNF_RJCT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case CLS_ACPT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if (!reason)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												reason = cpu_to_le16(MESH_CLOSE_RCVD);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											sta->reason = reason;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											sta->plink_state = PLINK_HOLDING;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											if (!mod_plink_timer(sta,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
													     dot11MeshHoldingTimeout(sdata)))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												sta->ignore_plink_timer = true;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											llid = sta->llid;
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid,
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
													    plid, reason);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 10:11:50 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case OPN_ACPT:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											del_timer(&sta->plink_timer);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											sta->plink_state = PLINK_ESTAB;
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mesh_plink_inc_estab_count(sdata);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
							 | 
						
					
						
							
								
									
										
										
										
											2008-10-27 15:56:10 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mpl_dbg("Mesh plink with %pM ESTABLISHED\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												sta->sta.addr);
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid,
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
													    plid, 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										default:
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									case PLINK_ESTAB:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										switch (event) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case CLS_ACPT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											reason = cpu_to_le16(MESH_CLOSE_RCVD);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											sta->reason = reason;
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											deactivated = __mesh_plink_deactivate(sta);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											sta->plink_state = PLINK_HOLDING;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											llid = sta->llid;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2010-06-21 17:14:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if (deactivated)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid,
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
													    plid, reason);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case OPN_ACPT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											llid = sta->llid;
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid,
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
													    plid, 0);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										default:
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									case PLINK_HOLDING:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										switch (event) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case CLS_ACPT:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											if (del_timer(&sta->plink_timer))
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
												sta->ignore_plink_timer = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											mesh_plink_fsm_restart(sta);
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case OPN_ACPT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case CNF_ACPT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case OPN_RJCT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										case CNF_RJCT:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											llid = sta->llid;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											reason = sta->reason;
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-09-11 00:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
													    llid, plid, reason);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										default:
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									default:
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-29 15:46:08 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										/* should not get here, PLINK_BLOCKED is dealt with at the
							 | 
						
					
						
							
								
									
										
										
											
												tree-wide: Assorted spelling fixes
In particular, several occurances of funny versions of 'success',
'unknown', 'therefore', 'acknowledge', 'argument', 'achieve', 'address',
'beginning', 'desirable', 'separate' and 'necessary' are fixed.
Signed-off-by: Daniel Mack <daniel@caiaq.de>
Cc: Joe Perches <joe@perches.com>
Cc: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
											
										 
										
											2010-02-03 08:01:28 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										 * beginning of the function
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										 */
							 | 
						
					
						
							
								
									
										
										
										
											2008-05-03 01:02:02 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										spin_unlock_bh(&sta->lock);
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-25 16:27:46 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									rcu_read_unlock();
							 | 
						
					
						
							
								
									
										
										
										
											2008-02-23 15:17:13 +01:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 |