include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h
percpu.h is included by sched.h and module.h and thus ends up being
included when building most .c files.  percpu.h includes slab.h which
in turn includes gfp.h making everything defined by the two files
universally available and complicating inclusion dependencies.
percpu.h -> slab.h dependency is about to be removed.  Prepare for
this change by updating users of gfp and slab facilities include those
headers directly instead of assuming availability.  As this conversion
needs to touch large number of source files, the following script is
used as the basis of conversion.
  http://userweb.kernel.org/~tj/misc/slabh-sweep.py
The script does the followings.
* Scan files for gfp and slab usages and update includes such that
  only the necessary includes are there.  ie. if only gfp is used,
  gfp.h, if slab is used, slab.h.
* When the script inserts a new include, it looks at the include
  blocks and try to put the new include such that its order conforms
  to its surrounding.  It's put in the include block which contains
  core kernel includes, in the same order that the rest are ordered -
  alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
  doesn't seem to be any matching order.
* If the script can't find a place to put a new include (mostly
  because the file doesn't have fitting include block), it prints out
  an error message indicating which .h file needs to be added to the
  file.
The conversion was done in the following steps.
1. The initial automatic conversion of all .c files updated slightly
   over 4000 files, deleting around 700 includes and adding ~480 gfp.h
   and ~3000 slab.h inclusions.  The script emitted errors for ~400
   files.
2. Each error was manually checked.  Some didn't need the inclusion,
   some needed manual addition while adding it to implementation .h or
   embedding .c file was more appropriate for others.  This step added
   inclusions to around 150 files.
3. The script was run again and the output was compared to the edits
   from #2 to make sure no file was left behind.
4. Several build tests were done and a couple of problems were fixed.
   e.g. lib/decompress_*.c used malloc/free() wrappers around slab
   APIs requiring slab.h to be added manually.
5. The script was run on all .h files but without automatically
   editing them as sprinkling gfp.h and slab.h inclusions around .h
   files could easily lead to inclusion dependency hell.  Most gfp.h
   inclusion directives were ignored as stuff from gfp.h was usually
   wildly available and often used in preprocessor macros.  Each
   slab.h inclusion directive was examined and added manually as
   necessary.
6. percpu.h was updated not to include slab.h.
7. Build test were done on the following configurations and failures
   were fixed.  CONFIG_GCOV_KERNEL was turned off for all tests (as my
   distributed build env didn't work with gcov compiles) and a few
   more options had to be turned off depending on archs to make things
   build (like ipr on powerpc/64 which failed due to missing writeq).
   * x86 and x86_64 UP and SMP allmodconfig and a custom test config.
   * powerpc and powerpc64 SMP allmodconfig
   * sparc and sparc64 SMP allmodconfig
   * ia64 SMP allmodconfig
   * s390 SMP allmodconfig
   * alpha SMP allmodconfig
   * um on x86_64 SMP allmodconfig
8. percpu.h modifications were reverted so that it could be applied as
   a separate patch and serve as bisection point.
Given the fact that I had only a couple of failures from tests on step
6, I'm fairly confident about the coverage of this conversion patch.
If there is a breakage, it's likely to be something in one of the arch
headers which should be easily discoverable easily on most builds of
the specific arch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
											
										 
										
											2010-03-24 17:04:11 +09:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <linux/slab.h>
							 | 
						
					
						
							
								
									
										
										
										
											2011-05-27 16:14:23 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include <linux/export.h>
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h
percpu.h is included by sched.h and module.h and thus ends up being
included when building most .c files.  percpu.h includes slab.h which
in turn includes gfp.h making everything defined by the two files
universally available and complicating inclusion dependencies.
percpu.h -> slab.h dependency is about to be removed.  Prepare for
this change by updating users of gfp and slab facilities include those
headers directly instead of assuming availability.  As this conversion
needs to touch large number of source files, the following script is
used as the basis of conversion.
  http://userweb.kernel.org/~tj/misc/slabh-sweep.py
The script does the followings.
* Scan files for gfp and slab usages and update includes such that
  only the necessary includes are there.  ie. if only gfp is used,
  gfp.h, if slab is used, slab.h.
* When the script inserts a new include, it looks at the include
  blocks and try to put the new include such that its order conforms
  to its surrounding.  It's put in the include block which contains
  core kernel includes, in the same order that the rest are ordered -
  alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
  doesn't seem to be any matching order.
* If the script can't find a place to put a new include (mostly
  because the file doesn't have fitting include block), it prints out
  an error message indicating which .h file needs to be added to the
  file.
The conversion was done in the following steps.
1. The initial automatic conversion of all .c files updated slightly
   over 4000 files, deleting around 700 includes and adding ~480 gfp.h
   and ~3000 slab.h inclusions.  The script emitted errors for ~400
   files.
2. Each error was manually checked.  Some didn't need the inclusion,
   some needed manual addition while adding it to implementation .h or
   embedding .c file was more appropriate for others.  This step added
   inclusions to around 150 files.
3. The script was run again and the output was compared to the edits
   from #2 to make sure no file was left behind.
4. Several build tests were done and a couple of problems were fixed.
   e.g. lib/decompress_*.c used malloc/free() wrappers around slab
   APIs requiring slab.h to be added manually.
5. The script was run on all .h files but without automatically
   editing them as sprinkling gfp.h and slab.h inclusions around .h
   files could easily lead to inclusion dependency hell.  Most gfp.h
   inclusion directives were ignored as stuff from gfp.h was usually
   wildly available and often used in preprocessor macros.  Each
   slab.h inclusion directive was examined and added manually as
   necessary.
6. percpu.h was updated not to include slab.h.
7. Build test were done on the following configurations and failures
   were fixed.  CONFIG_GCOV_KERNEL was turned off for all tests (as my
   distributed build env didn't work with gcov compiles) and a few
   more options had to be turned off depending on archs to make things
   build (like ipr on powerpc/64 which failed due to missing writeq).
   * x86 and x86_64 UP and SMP allmodconfig and a custom test config.
   * powerpc and powerpc64 SMP allmodconfig
   * sparc and sparc64 SMP allmodconfig
   * ia64 SMP allmodconfig
   * s390 SMP allmodconfig
   * alpha SMP allmodconfig
   * um on x86_64 SMP allmodconfig
8. percpu.h modifications were reverted so that it could be applied as
   a separate patch and serve as bisection point.
Given the fact that I had only a couple of failures from tests on step
6, I'm fairly confident about the coverage of this conversion patch.
If there is a breakage, it's likely to be something in one of the arch
headers which should be easily discoverable easily on most builds of
the specific arch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
											
										 
										
											2010-03-24 17:04:11 +09:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2006-01-14 03:09:34 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#include "hostap_80211.h"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include "hostap_common.h"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include "hostap_wlan.h"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include "hostap.h"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#include "hostap_ap.h"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static unsigned char rfc1042_header[] =
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								static unsigned char bridge_tunnel_header[] =
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/* No encapsulation header if EtherType < 0x600 (=length) */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct ieee80211_hdr *hdr;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									u16 fc;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									hdr = (struct ieee80211_hdr *) skb->data;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									printk(KERN_DEBUG "%s: TX len=%d jiffies=%ld\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									       name, skb->len, jiffies);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (skb->len < 2)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									fc = le16_to_cpu(hdr->frame_control);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									printk(KERN_DEBUG "   FC=0x%04x (type=%d:%d)%s%s",
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									       fc, (fc & IEEE80211_FCTL_FTYPE) >> 2,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									       (fc & IEEE80211_FCTL_STYPE) >> 4,
							 | 
						
					
						
							
								
									
										
										
										
											2005-08-14 21:00:01 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									       fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									       fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (skb->len < IEEE80211_DATA_HDR3_LEN) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										printk("\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id),
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									       le16_to_cpu(hdr->seq_ctrl));
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2008-10-27 15:59:26 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									printk(KERN_DEBUG "   A1=%pM", hdr->addr1);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									printk(" A2=%pM", hdr->addr2);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									printk(" A3=%pM", hdr->addr3);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (skb->len >= 30)
							 | 
						
					
						
							
								
									
										
										
										
											2008-10-27 15:59:26 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										printk(" A4=%pM", hdr->addr4);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									printk("\n");
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/* hard_start_xmit function for data interfaces (wlan#, wlan#wds#, wlan#sta)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * Convert Ethernet header into a suitable IEEE 802.11 header depending on
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * device configuration. */
							 | 
						
					
						
							
								
									
										
										
										
											2009-08-31 19:50:57 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								netdev_tx_t hostap_data_start_xmit(struct sk_buff *skb,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												   struct net_device *dev)
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct hostap_interface *iface;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									local_info_t *local;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									int need_headroom, need_tailroom = 0;
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct ieee80211_hdr hdr;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									u16 fc, ethertype = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									enum {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} use_wds = WDS_NO;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									u8 *encaps_data;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									int hdr_len, encaps_len, skip_header_bytes;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									int to_assoc_ap = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct hostap_skb_tx_data *meta;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									iface = netdev_priv(dev);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									local = iface->local;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (skb->len < ETH_HLEN) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										printk(KERN_DEBUG "%s: hostap_data_start_xmit: short skb "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										       "(len=%d)\n", dev->name, skb->len);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										return NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (local->ddev != dev) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										use_wds = (local->iw_mode == IW_MODE_MASTER &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											   !(local->wds_type & HOSTAP_WDS_STANDARD_FRAME)) ?
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											WDS_OWN_FRAME : WDS_COMPLIANT_FRAME;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (dev == local->stadev) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											to_assoc_ap = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											use_wds = WDS_NO;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										} else if (dev == local->apdev) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											printk(KERN_DEBUG "%s: prism2_tx: trying to use "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											       "AP device with Ethernet net dev\n", dev->name);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											kfree_skb(skb);
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											return NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (local->iw_mode == IW_MODE_REPEAT) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											printk(KERN_DEBUG "%s: prism2_tx: trying to use "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											       "non-WDS link in Repeater mode\n", dev->name);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											kfree_skb(skb);
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											return NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										} else if (local->iw_mode == IW_MODE_INFRA &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											   (local->wds_type & HOSTAP_WDS_AP_CLIENT) &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											   memcmp(skb->data + ETH_ALEN, dev->dev_addr,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												  ETH_ALEN) != 0) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											/* AP client mode: send frames with foreign src addr
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											 * using 4-addr WDS frames */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											use_wds = WDS_COMPLIANT_FRAME;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Incoming skb->data: dst_addr[6], src_addr[6], proto[2], payload
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * ==>
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * Prism2 TX frame with 802.11 header:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * txdesc (address order depending on used mode; includes dst_addr and
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * src_addr), possible encapsulation (RFC1042/Bridge-Tunnel;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * proto[2], payload {, possible addr4[6]} */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									ethertype = (skb->data[12] << 8) | skb->data[13];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									memset(&hdr, 0, sizeof(hdr));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Length of data after IEEE 802.11 header */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									encaps_data = NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									encaps_len = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									skip_header_bytes = ETH_HLEN;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (ethertype == ETH_P_AARP || ethertype == ETH_P_IPX) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										encaps_data = bridge_tunnel_header;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										encaps_len = sizeof(bridge_tunnel_header);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										skip_header_bytes -= 2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else if (ethertype >= 0x600) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										encaps_data = rfc1042_header;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										encaps_len = sizeof(rfc1042_header);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										skip_header_bytes -= 2;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2005-08-14 19:08:44 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									hdr_len = IEEE80211_DATA_HDR3_LEN;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (use_wds != WDS_NO) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* Note! Prism2 station firmware has problems with sending real
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										 * 802.11 frames with four addresses; until these problems can
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										 * be fixed or worked around, 4-addr frames needed for WDS are
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										 * using incompatible format: FromDS flag is not set and the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										 * fourth address is added after the frame payload; it is
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										 * assumed, that the receiving station knows how to handle this
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										 * frame format */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (use_wds == WDS_COMPLIANT_FRAME) {
							 | 
						
					
						
							
								
									
										
										
										
											2005-08-14 21:00:01 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											fc |= IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											/* From&To DS: Addr1 = RA, Addr2 = TA, Addr3 = DA,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											 * Addr4 = SA */
							 | 
						
					
						
							
								
									
										
										
										
											2007-03-27 18:55:52 -03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											skb_copy_from_linear_data_offset(skb, ETH_ALEN,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
															 &hdr.addr4, ETH_ALEN);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											hdr_len += ETH_ALEN;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											/* bogus 4-addr format to workaround Prism2 station
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											 * f/w bug */
							 | 
						
					
						
							
								
									
										
										
										
											2005-08-14 21:00:01 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											fc |= IEEE80211_FCTL_TODS;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											/* From DS: Addr1 = DA (used as RA),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											 * Addr2 = BSSID (used as TA), Addr3 = SA (used as DA),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											 */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											/* SA from skb->data + ETH_ALEN will be added after
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											 * frame payload; use hdr.addr4 as a temporary buffer
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											 */
							 | 
						
					
						
							
								
									
										
										
										
											2007-03-27 18:55:52 -03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											skb_copy_from_linear_data_offset(skb, ETH_ALEN,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
															 &hdr.addr4, ETH_ALEN);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											need_tailroom += ETH_ALEN;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* send broadcast and multicast frames to broadcast RA, if
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										 * configured; otherwise, use unicast RA of the WDS link */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if ((local->wds_type & HOSTAP_WDS_BROADCAST_RA) &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										    skb->data[0] & 0x01)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											memset(&hdr.addr1, 0xff, ETH_ALEN);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										else if (iface->type == HOSTAP_INTERFACE_WDS)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											memcpy(&hdr.addr1, iface->u.wds.remote_addr,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											       ETH_ALEN);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											memcpy(&hdr.addr1, local->bssid, ETH_ALEN);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										memcpy(&hdr.addr2, dev->dev_addr, ETH_ALEN);
							 | 
						
					
						
							
								
									
										
										
										
											2007-03-27 18:55:52 -03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										skb_copy_from_linear_data(skb, &hdr.addr3, ETH_ALEN);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else if (local->iw_mode == IW_MODE_MASTER && !to_assoc_ap) {
							 | 
						
					
						
							
								
									
										
										
										
											2005-08-14 21:00:01 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										fc |= IEEE80211_FCTL_FROMDS;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* From DS: Addr1 = DA, Addr2 = BSSID, Addr3 = SA */
							 | 
						
					
						
							
								
									
										
										
										
											2007-03-27 18:55:52 -03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										skb_copy_from_linear_data(skb, &hdr.addr1, ETH_ALEN);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										memcpy(&hdr.addr2, dev->dev_addr, ETH_ALEN);
							 | 
						
					
						
							
								
									
										
										
										
											2007-03-27 18:55:52 -03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										skb_copy_from_linear_data_offset(skb, ETH_ALEN, &hdr.addr3,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
														 ETH_ALEN);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else if (local->iw_mode == IW_MODE_INFRA || to_assoc_ap) {
							 | 
						
					
						
							
								
									
										
										
										
											2005-08-14 21:00:01 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										fc |= IEEE80211_FCTL_TODS;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										memcpy(&hdr.addr1, to_assoc_ap ?
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										       local->assoc_ap_addr : local->bssid, ETH_ALEN);
							 | 
						
					
						
							
								
									
										
										
										
											2007-03-27 18:55:52 -03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										skb_copy_from_linear_data_offset(skb, ETH_ALEN, &hdr.addr2,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
														 ETH_ALEN);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										skb_copy_from_linear_data(skb, &hdr.addr3, ETH_ALEN);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else if (local->iw_mode == IW_MODE_ADHOC) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */
							 | 
						
					
						
							
								
									
										
										
										
											2007-03-27 18:55:52 -03:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										skb_copy_from_linear_data(skb, &hdr.addr1, ETH_ALEN);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										skb_copy_from_linear_data_offset(skb, ETH_ALEN, &hdr.addr2,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
														 ETH_ALEN);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										memcpy(&hdr.addr3, local->bssid, ETH_ALEN);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									hdr.frame_control = cpu_to_le16(fc);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									skb_pull(skb, skip_header_bytes);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									need_headroom = local->func->need_tx_headroom + hdr_len + encaps_len;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (skb_tailroom(skb) < need_tailroom) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										skb = skb_unshare(skb, GFP_ATOMIC);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (skb == NULL) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											iface->stats.tx_dropped++;
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											return NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (pskb_expand_head(skb, need_headroom, need_tailroom,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												     GFP_ATOMIC)) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											kfree_skb(skb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											iface->stats.tx_dropped++;
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											return NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else if (skb_headroom(skb) < need_headroom) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										struct sk_buff *tmp = skb;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										skb = skb_realloc_headroom(skb, need_headroom);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(tmp);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (skb == NULL) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											iface->stats.tx_dropped++;
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											return NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										skb = skb_unshare(skb, GFP_ATOMIC);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (skb == NULL) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											iface->stats.tx_dropped++;
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											return NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (encaps_data)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										memcpy(skb_push(skb, encaps_len), encaps_data, encaps_len);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									memcpy(skb_push(skb, hdr_len), &hdr, hdr_len);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (use_wds == WDS_OWN_FRAME) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										memcpy(skb_put(skb, ETH_ALEN), &hdr.addr4, ETH_ALEN);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									iface->stats.tx_packets++;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									iface->stats.tx_bytes += skb->len;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-03-19 15:30:44 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									skb_reset_mac_header(skb);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									meta = (struct hostap_skb_tx_data *) skb->cb;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									memset(meta, 0, sizeof(*meta));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
							 | 
						
					
						
							
								
									
										
										
										
											2005-08-14 19:08:39 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (use_wds)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										meta->flags |= HOSTAP_TX_FLAGS_WDS;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									meta->ethertype = ethertype;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									meta->iface = iface;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Send IEEE 802.11 encapsulated frame using the master radio device */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									skb->dev = local->dev;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									dev_queue_xmit(skb);
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/* hard_start_xmit function for hostapd wlan#ap interfaces */
							 | 
						
					
						
							
								
									
										
										
										
											2009-08-31 19:50:57 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								netdev_tx_t hostap_mgmt_start_xmit(struct sk_buff *skb,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												   struct net_device *dev)
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct hostap_interface *iface;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									local_info_t *local;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct hostap_skb_tx_data *meta;
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct ieee80211_hdr *hdr;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									u16 fc;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									iface = netdev_priv(dev);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									local = iface->local;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (skb->len < 10) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										printk(KERN_DEBUG "%s: hostap_mgmt_start_xmit: short skb "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										       "(len=%d)\n", dev->name, skb->len);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										return NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									iface->stats.tx_packets++;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									iface->stats.tx_bytes += skb->len;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									meta = (struct hostap_skb_tx_data *) skb->cb;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									memset(meta, 0, sizeof(*meta));
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									meta->magic = HOSTAP_SKB_TX_DATA_MAGIC;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									meta->iface = iface;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (skb->len >= IEEE80211_DATA_HDR3_LEN + sizeof(rfc1042_header) + 2) {
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										hdr = (struct ieee80211_hdr *) skb->data;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										fc = le16_to_cpu(hdr->frame_control);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (ieee80211_is_data(hdr->frame_control) &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										    (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DATA) {
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											u8 *pos = &skb->data[IEEE80211_DATA_HDR3_LEN +
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
													     sizeof(rfc1042_header)];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											meta->ethertype = (pos[0] << 8) | pos[1];
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Send IEEE 802.11 encapsulated frame using the master radio device */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									skb->dev = local->dev;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									dev_queue_xmit(skb);
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									return NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/* Called only from software IRQ */
							 | 
						
					
						
							
								
									
										
										
										
											2006-03-24 21:24:54 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
							 | 
						
					
						
							
								
									
										
										
										
											2008-10-29 11:35:05 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
													  struct lib80211_crypt_data *crypt)
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct hostap_interface *iface;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									local_info_t *local;
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct ieee80211_hdr *hdr;
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-28 09:38:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									int prefix_len, postfix_len, hdr_len, res;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									iface = netdev_priv(skb->dev);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									local = iface->local;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (skb->len < IEEE80211_DATA_HDR3_LEN) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (local->tkip_countermeasures &&
							 | 
						
					
						
							
								
									
										
										
										
											2006-03-24 21:24:54 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									    strcmp(crypt->ops->name, "TKIP") == 0) {
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										hdr = (struct ieee80211_hdr *) skb->data;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (net_ratelimit()) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
							 | 
						
					
						
							
								
									
										
										
										
											2008-10-27 15:59:26 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											       "TX packet to %pM\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											       local->dev->name, hdr->addr1);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									skb = skb_unshare(skb, GFP_ATOMIC);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (skb == NULL)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2007-05-28 09:38:46 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									prefix_len = crypt->ops->extra_mpdu_prefix_len +
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										crypt->ops->extra_msdu_prefix_len;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									postfix_len = crypt->ops->extra_mpdu_postfix_len +
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										crypt->ops->extra_msdu_postfix_len;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if ((skb_headroom(skb) < prefix_len ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									     skb_tailroom(skb) < postfix_len) &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    pskb_expand_head(skb, prefix_len, postfix_len, GFP_ATOMIC)) {
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									hdr = (struct ieee80211_hdr *) skb->data;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									hdr_len = hostap_80211_get_hdrlen(hdr->frame_control);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * call both MSDU and MPDU encryption functions from here. */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									atomic_inc(&crypt->refcnt);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									res = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (crypt->ops->encrypt_msdu)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										res = crypt->ops->encrypt_msdu(skb, hdr_len, crypt->priv);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (res == 0 && crypt->ops->encrypt_mpdu)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										res = crypt->ops->encrypt_mpdu(skb, hdr_len, crypt->priv);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									atomic_dec(&crypt->refcnt);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (res < 0) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										kfree_skb(skb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										return NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return skb;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								/* hard_start_xmit function for master radio interface wifi#.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * AP processing (TX rate control, power save buffering, etc.).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 * Use hardware TX function to send the frame. */
							 | 
						
					
						
							
								
									
										
										
										
											2009-08-31 19:50:57 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								netdev_tx_t hostap_master_start_xmit(struct sk_buff *skb,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
												     struct net_device *dev)
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								{
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct hostap_interface *iface;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									local_info_t *local;
							 | 
						
					
						
							
								
									
										
										
										
											2009-08-31 19:50:57 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									netdev_tx_t ret = NETDEV_TX_BUSY;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									u16 fc;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct hostap_tx_data tx;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									ap_tx_ret tx_ret;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									struct hostap_skb_tx_data *meta;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									int no_encrypt = 0;
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									struct ieee80211_hdr *hdr;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									iface = netdev_priv(dev);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									local = iface->local;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									tx.skb = skb;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									tx.sta_ptr = NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									meta = (struct hostap_skb_tx_data *) skb->cb;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (meta->magic != HOSTAP_SKB_TX_DATA_MAGIC) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										printk(KERN_DEBUG "%s: invalid skb->cb magic (0x%08x, "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										       "expected 0x%08x)\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										       dev->name, meta->magic, HOSTAP_SKB_TX_DATA_MAGIC);
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										ret = NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										iface->stats.tx_dropped++;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto fail;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (local->host_encrypt) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* Set crypt to default algorithm and key; will be replaced in
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										 * AP code if STA has own alg/key */
							 | 
						
					
						
							
								
									
										
										
										
											2008-10-29 11:35:05 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										tx.crypt = local->crypt_info.crypt[local->crypt_info.tx_keyidx];
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										tx.host_encrypt = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										tx.crypt = NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										tx.host_encrypt = 0;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (skb->len < 24) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										printk(KERN_DEBUG "%s: hostap_master_start_xmit: short skb "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										       "(len=%d)\n", dev->name, skb->len);
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										ret = NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										iface->stats.tx_dropped++;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto fail;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* FIX (?):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * Wi-Fi 802.11b test plan suggests that AP should ignore power save
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * bit in authentication and (re)association frames and assume tha
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * STA remains awake for the response. */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									tx_ret = hostap_handle_sta_tx(local, &tx);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									skb = tx.skb;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									meta = (struct hostap_skb_tx_data *) skb->cb;
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									hdr = (struct ieee80211_hdr *) skb->data;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									fc = le16_to_cpu(hdr->frame_control);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									switch (tx_ret) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case AP_TX_CONTINUE:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case AP_TX_CONTINUE_NOT_AUTHORIZED:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (local->ieee_802_1x &&
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										    ieee80211_is_data(hdr->frame_control) &&
							 | 
						
					
						
							
								
									
										
										
										
											2005-08-14 19:08:39 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										    meta->ethertype != ETH_P_PAE &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										    !(meta->flags & HOSTAP_TX_FLAGS_WDS)) {
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											printk(KERN_DEBUG "%s: dropped frame to unauthorized "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											       "port (IEEE 802.1X): ethertype=0x%04x\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											       dev->name, meta->ethertype);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											hostap_dump_tx_80211(dev->name, skb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											ret = NETDEV_TX_OK; /* drop packet */
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											iface->stats.tx_dropped++;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											goto fail;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										break;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case AP_TX_DROP:
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										ret = NETDEV_TX_OK; /* drop packet */
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										iface->stats.tx_dropped++;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto fail;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case AP_TX_RETRY:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto fail;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									case AP_TX_BUFFERED:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* do not free skb here, it will be freed when the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										 * buffered frame is sent/timed out */
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										ret = NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto tx_exit;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									/* Request TX callback if protocol version is 2 in 802.11 header;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * this version 2 is a special case used between hostapd and kernel
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									 * driver */
							 | 
						
					
						
							
								
									
										
										
										
											2005-08-14 21:00:01 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (((fc & IEEE80211_FCTL_VERS) == BIT(1)) &&
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									    local->ap && local->ap->tx_callback_idx && meta->tx_cb_idx == 0) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										meta->tx_cb_idx = local->ap->tx_callback_idx;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* remove special version from the frame header */
							 | 
						
					
						
							
								
									
										
										
										
											2005-08-14 21:00:01 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										fc &= ~IEEE80211_FCTL_VERS;
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										hdr->frame_control = cpu_to_le16(fc);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (!ieee80211_is_data(hdr->frame_control)) {
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										no_encrypt = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										tx.crypt = NULL;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (local->ieee_802_1x && meta->ethertype == ETH_P_PAE && tx.crypt &&
							 | 
						
					
						
							
								
									
										
										
										
											2006-03-24 21:24:55 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									    !(fc & IEEE80211_FCTL_PROTECTED)) {
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										no_encrypt = 1;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										PDEBUG(DEBUG_EXTRA2, "%s: TX: IEEE 802.1X - passing "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										       "unencrypted EAPOL frame\n", dev->name);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										tx.crypt = NULL; /* no encryption for IEEE 802.1X frames */
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (tx.crypt && (!tx.crypt->ops || !tx.crypt->ops->encrypt_mpdu))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										tx.crypt = NULL;
							 | 
						
					
						
							
								
									
										
										
										
											2008-10-29 11:35:05 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									else if ((tx.crypt ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										 local->crypt_info.crypt[local->crypt_info.tx_keyidx]) &&
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										 !no_encrypt) {
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										/* Add ISWEP flag both for firmware and host based encryption
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										 */
							 | 
						
					
						
							
								
									
										
										
										
											2005-08-25 20:59:10 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										fc |= IEEE80211_FCTL_PROTECTED;
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										hdr->frame_control = cpu_to_le16(fc);
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else if (local->drop_unencrypted &&
							 | 
						
					
						
							
								
									
										
										
										
											2009-02-11 17:17:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										   ieee80211_is_data(hdr->frame_control) &&
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										   meta->ethertype != ETH_P_PAE) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (net_ratelimit()) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											printk(KERN_DEBUG "%s: dropped unencrypted TX data "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											       "frame (drop_unencrypted=1)\n", dev->name);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										iface->stats.tx_dropped++;
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										ret = NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										goto fail;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (tx.crypt) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										skb = hostap_tx_encrypt(skb, tx.crypt);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (skb == NULL) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											printk(KERN_DEBUG "%s: TX - encryption failed\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											       dev->name);
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											ret = NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											goto fail;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										meta = (struct hostap_skb_tx_data *) skb->cb;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										if (meta->magic != HOSTAP_SKB_TX_DATA_MAGIC) {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											printk(KERN_DEBUG "%s: invalid skb->cb magic (0x%08x, "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											       "expected 0x%08x) after hostap_tx_encrypt\n",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											       dev->name, meta->magic,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											       HOSTAP_SKB_TX_DATA_MAGIC);
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
											ret = NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
											iface->stats.tx_dropped++;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
											goto fail;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (local->func->tx == NULL || local->func->tx(skb, dev)) {
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										ret = NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										iface->stats.tx_dropped++;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									} else {
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
										ret = NETDEV_TX_OK;
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										iface->stats.tx_packets++;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										iface->stats.tx_bytes += skb->len;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 fail:
							 | 
						
					
						
							
								
									
										
										
										
											2009-07-05 19:23:38 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
									if (ret == NETDEV_TX_OK && skb)
							 | 
						
					
						
							
								
									
										
										
										
											2005-05-12 22:54:16 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
										dev_kfree_skb(skb);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								 tx_exit:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									if (tx.sta_ptr)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
										hostap_handle_sta_release(tx.sta_ptr);
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
									return ret;
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								EXPORT_SYMBOL(hostap_master_start_xmit);
							 |