⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ieee80211_skb.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 2007 Michael Taylor, Apprion * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $Id: ieee80211_linux.c 2829 2007-11-05 20:43:50Z mtaylor $ */#ifndef EXPORT_SYMTAB#define	EXPORT_SYMTAB#endif/* * IEEE 802.11 support (Linux-specific code) */#ifndef AUTOCONF_INCLUDED#include <linux/config.h>#endif#include <linux/version.h>#include <linux/module.h>#include <linux/kmod.h>#include <linux/init.h>#include <linux/skbuff.h>#include <linux/sysctl.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/if_vlan.h>#include <linux/vmalloc.h>#include <linux/proc_fs.h>#include <net/iw_handler.h>#include <linux/wireless.h>#include <linux/if_arp.h>		/* XXX for ARPHRD_* */#include <asm/uaccess.h>#include "if_media.h"#include "if_ethersubr.h"#include <net80211/ieee80211_var.h>#include <net80211/ieee80211_monitor.h>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17)#include <linux/device.h>#endif#undef alloc_skb#undef dev_alloc_skb#undef dev_kfree_skb#undef dev_kfree_skb_any#undef dev_kfree_skb_irq#undef dev_queue_xmit#undef kfree_skb#undef kfree_skb_fast#undef netif_rx#undef pskb_copy#undef skb_clone#undef skb_copy#undef skb_copy_expand#undef skb_get#undef skb_realloc_headroom#undef skb_share_check#undef skb_unshare#undef vlan_hwaccel_rxatomic_t skb_total_counter = ATOMIC_INIT(0);EXPORT_SYMBOL(skb_total_counter);#ifdef IEEE80211_DEBUG_REFCNTatomic_t skb_refs_counter  = ATOMIC_INIT(0);EXPORT_SYMBOL(skb_refs_counter);#endif/******************************************************************************* * Debug Helpers ******************************************************************************/static void skb_print_message(		int show_counter, 		const struct sk_buff *skb, 		const char *func, int line,		const char *message,		...){	va_list args;	char skb_count[32] = { '\0' };	char expanded_message[1024] = { '\0' };	if (show_counter) {#ifdef IEEE80211_DEBUG_REFCNT		snprintf(skb_count, 			 sizeof(skb_count), 			 "[#SKB=%05d #REF=%05d] ", 			 atomic_read(&skb_total_counter),			 atomic_read(&skb_refs_counter));#else		snprintf(skb_count, 			 sizeof(skb_count), 			 "[#SKB=%05d] ", 			 atomic_read(&skb_total_counter));#endif	}	va_start(args, message);	vsnprintf(expanded_message, sizeof(expanded_message), message, args);	printk(KERN_DEBUG "%s: %s%s:%d %s\n",		((skb != NULL) ? DEV_NAME(skb->dev) : "none"),		skb_count, 		func, line,		expanded_message);	va_end(args);#ifdef IEEE80211_DEBUG_REFCNT	dump_stack();#endif}#ifdef IEEE80211_DEBUG_REFCNTstatic void print_skb_refchange_message(		const struct sk_buff *skb, int users_adjustment, 		const char *func, int line);static void print_skb_trackchange_message(		const struct sk_buff *skb, int users_adjustment, 		const char *func, int line,		char *message);/* Called automatically when an SKB reaches zero users,  * reporting any leaked node references. */#ifdef IEEE80211_DEBUG_REFCNT_SKBDESTstatic void skb_destructor(struct sk_buff *skb);#endifstatic void get_skb_description(char *dst, int dst_size, const char *label,		const struct sk_buff *skb, int users_adjustment);static struct sk_buff *clean_clone_or_copy(struct sk_buff *skb);static struct sk_buff *track_skb(struct sk_buff *skb, int users_adjustment, 		      const char *func, int line);static struct sk_buff *untrack_skb(struct sk_buff *skb, int users_adjustment, 	      const char *func, int line);#define UNREF_USE_KFREE_SKB 	   	0#define UNREF_USE_DEV_KFREE_SKB_ANY   	1#define UNREF_USE_DEV_KFREE_SKB 	2#define UNREF_USE_DEV_KFREE_SKB_IRQ   	3/* Assumes SKB is not yet freed at the time of the call and shows the new users * count as (users - 1). */static void unref_skb(struct sk_buff *skb, int type,	  const char *func, int line);/* Assumes SKB reference counter has already been updated and reports count as * atomic_read(&skb->users). */static struct sk_buff *ref_skb(struct sk_buff *skb, 	const char *func, int line);#ifdef IEEE80211_DEBUG_REFCNT_SKBDEST/* Destructor for reporting node reference leaks */static void skb_destructor(struct sk_buff *skb) {	/* Report any node reference leaks - caused by kernel net device queue 	 * dropping buffer, rather than passing it to the driver. */	if (SKB_NI(skb) != NULL) {		printk(KERN_ERR "%s:%d - ERROR: non-NULL node pointer in %p, %p<" MAC_FMT ">!  "				"Leak Detected!\n", 		       __func__, __LINE__, 		       skb, SKB_NI(skb), MAC_ADDR(SKB_NI(skb)->ni_macaddr));		dump_stack();	}	if (SKB_CB(skb)->next_destructor != NULL) {		SKB_CB(skb)->next_destructor(skb);	}}EXPORT_SYMBOL(skb_destructor);#endif /* #ifdef IEEE80211_DEBUG_REFCNT_SKBDEST */static void get_skb_description(char *dst, int dst_size, const char *label, const struct sk_buff *skb, int users_adjustment) { 	dst[0] = '\0';	if (NULL != skb) {		int adj_users = atomic_read(&skb->users) + users_adjustment;		if (SKB_NI(skb) != NULL) {			snprintf(dst, dst_size, 				 " [%s%s%p,users=%d,node=%p<" MAC_FMT ">,aid=%d%s%s]",				 label,				 (label != NULL ? ": " : ""),				 skb,				 adj_users,				 SKB_NI(skb),				 MAC_ADDR(SKB_NI(skb)->ni_macaddr),				 SKB_NI(skb)->ni_associd,				 ((adj_users  < 0) ? " ** CORRUPTED **" : ""),				 ((adj_users == 0) ? " ** RELEASED **" : "")				 );		}		else {			snprintf(dst, dst_size, 				 " [%s%s%p,users=%d,node=NULL,aid=N/A%s%s]",				 label,				 (label != NULL ? ": " : ""),				 skb,				 adj_users,				 ((adj_users  < 0) ? " ** CORRUPTED **" : ""),				 ((adj_users == 0) ? " ** RELEASED **" : "")				 );		}		dst[dst_size-1] = '\0';	}}static void print_skb_refchange_message(		const struct sk_buff *skb, int users_adjustment, 		const char *func, int line){	char skb_desc[128] = { '\0' };	if (0 == (ath_debug_global & GLOBAL_DEBUG_SKB_REF))		return;	get_skb_description(skb_desc, sizeof(skb_desc),  			     "skb",  skb,  users_adjustment);	skb_print_message(0 /* no global count */, skb, 			  func, line,			  skb_desc);}static void print_skb_trackchange_message(		const struct sk_buff *skb, int users_adjustment, 		const char *func, int line,		char *message){	char skb_desc[128] = { '\0' };	if (0 == (ath_debug_global & GLOBAL_DEBUG_SKB))		return;	get_skb_description(skb_desc, sizeof(skb_desc),  			     "skb",  skb,  users_adjustment);	skb_print_message(1 /* show global count */, skb, 			  func, line,			  "%s%s", skb_desc, message);}static struct sk_buff *clean_clone_or_copy(struct sk_buff *skb) {	if (skb != NULL)		M_FLAG_CLR(skb, M_SKB_TRACKED);	return skb;}static struct sk_buff *track_skb(struct sk_buff *skb, int users_adjustment, 		      const char *func, int line) {	if (NULL == skb) {		skb_print_message(0 /* show_counter */, 			skb, func2, line2,			"ERROR: NULL skb received.  Skipping.");		return NULL;	}	if (M_FLAG_GET(skb, M_SKB_TRACKED)) {		skb_print_message(0 /* show_counter */, 			skb, func2, line2,			"ERROR: Already tracked skb received.  Skipping.");		dump_stack();		return skb;	}	if (skb_shared(skb)) {		skb_print_message(0 /* show_counter */, 			skb, func2, line2,			"ERROR: Shared skb received.  References leaked??");		dump_stack();	}	atomic_inc(&skb_total_counter);	atomic_inc(&skb_refs_counter);	M_FLAG_SET(skb, M_SKB_TRACKED);	print_skb_trackchange_message(skb, users_adjustment,				      func2, line2, 				      " is now ** TRACKED **");#ifdef IEEE80211_DEBUG_REFCNT_SKBDEST	/* Install our debug destructor, chaining to the original... */	if (skb->destructor != skb_destructor) {		SKB_CB(skb)->next_destructor = skb->destructor;		skb->destructor = skb_destructor;	}#endif /* #ifdef IEEE80211_DEBUG_REFCNT_SKBDEST */	return skb;}static struct sk_buff *untrack_skb(struct sk_buff *skb, int users_adjustment, 	      const char *func, int line){	if (NULL == skb) {		skb_print_message(0 /* show_counter */, 			skb, func, line,			"ERROR: NULL skb received.  No changes made.");		return NULL;	}	if (!M_FLAG_GET(skb, M_SKB_TRACKED)) {		skb_print_message(0 /* show_counter */, 			skb, func, line,			"ERROR: Untracked skb received.  No changes made.");		return skb;	}	if (skb_shared(skb)) {		skb_print_message(0 /* show_counter */, 			skb, func, line,			"ERROR: Shared skb received.  References leaked??");	}	atomic_dec(&skb_total_counter);	atomic_dec(&skb_refs_counter);	M_FLAG_CLR(skb, M_SKB_TRACKED);#ifdef IEEE80211_DEBUG_REFCNT_SKBDEST	/* Uninstall our debug destructor, restoring any original... */	if (skb->destructor == skb_destructor) {		skb->destructor = SKB_CB(skb)->next_destructor;		SKB_CB(skb)->next_destructor = NULL;	}#endif /* #ifdef IEEE80211_DEBUG_REFCNT_SKBDEST */	print_skb_trackchange_message(skb, users_adjustment,				      func, line, 				      " is now ** UNTRACKED **");	return skb;}#define UNREF_USE_KFREE_SKB 	   	0#define UNREF_USE_DEV_KFREE_SKB_ANY   	1#define UNREF_USE_DEV_KFREE_SKB 	2#define UNREF_USE_DEV_KFREE_SKB_IRQ   	3/* Assumes SKB is not yet freed at the time of the call and shows the new users * count as (users - 1). */static voidunref_skb(struct sk_buff *skb, int type,	  const char *func, int line) {	if (NULL == skb) {		skb_print_message(0 /* show_counter */, 			skb, func, line,			"ERROR: NULL skb received.");		dump_stack();		return;	}	if (!M_FLAG_GET(skb, M_SKB_TRACKED)) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -