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

📄 am930mac.c

📁 Linux Wireless LAN Project 的目标是开发一个完整的
💻 C
📖 第 1 页 / 共 4 页
字号:
/* am930_mac.c: Handles the 802.11 mac functions*	--------------------------------------------------------------------**   Linux WLAN **   The contents of this file are subject to the Mozilla Public*   License Version 1.0 (the "License"); you may not use this file*   except in compliance with the License. You may obtain a copy of*   the License at http://www.mozilla.org/MPL/**   Software distributed under the License is distributed on an "AS*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or*   implied. See the License for the specific language governing*   rights and limitations under the License.**   The initial developer of the original code is Mark S. Mathews*   <mark@absoval.com>.  Portions created by Mark S. Mathews*   are Copyright (C) 1998 AbsoluteValue Software, Inc.  All Rights Reserved.*   *	--------------------------------------------------------------------**	The author may be reached as mark@absoval.com, or C/O AbsoluteValue*	Software Inc., P.O. Box 941149, Maitland, FL, 32794-1149**	Thanks to David Hinds, Donald Becker, and the rest of the Linux*	developers worldwide for making all of this possible.**	--------------------------------------------------------------------**/#include <linux/config.h>#include <wlan/wlan_compat.h>#if (WLAN_OS == WLAN_LINUX_KERNEL)/* The following prevents "kernel_version" from being set in this file. */#define __NO_VERSION__/* PCMCIA headers generated during PCMCIA package installation */#ifdef WLAN_PCMCIA#include <pcmcia/config.h>#include <pcmcia/k_compat.h>#endif/* Module related headers, non-module drivers should not include */#include <linux/version.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>/* Ethernet and network includes */#include <linux/if_ether.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/if_arp.h>#include <linux/ioport.h>/* Standard driver includes */#include <linux/delay.h>#include <linux/types.h>#include <linux/fcntl.h>#include <asm/system.h>#include <asm/io.h>#include <linux/in.h>#include <linux/ptrace.h>#include <linux/interrupt.h>#include <linux/malloc.h>#include <linux/string.h>#include <linux/timer.h>#include <linux/kernel_stat.h>#include <asm/bitops.h>#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,11)#include <asm/spinlock.h>#else#include <linux/spinlock.h>#endif#include <linux/errno.h>/* Card and Driver services includes */#ifdef WLAN_PCMCIA#include <pcmcia/version.h>#include <pcmcia/cs_types.h>#include <pcmcia/cs.h>#include <pcmcia/cistpl.h>#include <pcmcia/ds.h>#endif/* Local Includes */#include <wlan/version.h>#include <wlan/p80211hdr.h>#include <wlan/p80211mgmt.h>#include <wlan/am930mib.h>#include <wlan/wlan_stable.h>#include <wlan/wlan_ioctl.h>#ifdef WLAN_PCMCIA#include "am930di.h"#endif#include "am930llc.h"#include "am930mac.h"#include "am930hw.h"#include "am930mgr.h"#elif ( WLAN_OS == WLAN_LWOS )#include <wlan/wlan_compat.h>#include <stddef.h>#include <stdlibsys.h>#include <direct.h>#include <hal.h>#include <mem.h>#include <kernel.h>#include <clock.h>#include <wlan/version.h>#include <wlan/p80211hdr.h>#include <wlan/p80211mgmt.h>#include <wlan/am930mib.h>#include <wlan/wlan_stable.h>#include <lw-wlan.h>#include <wlan/am930mac.h>#include <wlan/am930hw.h>#include <wlan/am930mgr.h>#else	#error "No WLAN_OS match!"#endif/*================================================================*//* Local Constants  */#define LLCQ_LEN	20#define MACQ_LEN	20#define RXQ_LEN		40#define WLAN_CRC32_POLY_LE	(0xedb88320UL)#define WLAN_CRC32_POLY_BE 	(0x04c11db7UL)/*================================================================*//* Local Functions  */static void am930mac_rxmgmt( am930mac_t *mac, wlan_pb_t *pb, am930rxstats_t *stats);static void am930mac_rxdata( am930mac_t *mac, wlan_pb_t *pb, am930rxstats_t *stats);static wlan_pb_t *am930mac_defrag( am930mac_t *mac, wlan_pb_t *pb);static wlan_pb_t *am930mac_defragfinish( am930mac_t *mac, UINT8 hash );static void am930mac_timerfunc(am930mac_t *mac);static void am930mac_crc32_mktable(am930mac_t *mac);static UINT32 am930mac_crc32_block(am930mac_t *mac, UINT32 reg, UINT8 *p, UINT len);static UINT32 am930mac_crc32_blockfinish(am930mac_t *mac, UINT32 reg);/*  static UINT32 am930mac_crc32_accum(am930mac_t *mac, UINT32 reg, UINT8 d); *//*================================================================*//* Externals  */#if (WLAN_OS == WLAN_LWOS)am930mac_t gmac;#endif/*----------------------------------------------------------------*	am930mac_construct**	Allocates and initializes the mac object and it's subobjects.**	returns: NULL on failure, the address of the new object*            otherwise.----------------------------------------------------------------*/#if (WLAN_OS == WLAN_LINUX_KERNEL)am930mac_t* am930mac_construct(void *di, UINT32 iobase, UINT32 membase, UINT32 irq)#elif (WLAN_OS == WLAN_LWOS )am930mac_t* am930mac_construct(wlanInfo_t *lw, UINT32 iobase, UINT32 membase, UINT32 irq)#else	#error "No WLAN_OS match!"#endif{	am930mac_t	*mac;	int			i;	DBFENTER;#if (WLAN_OS == WLAN_LINUX_KERNEL)	/* Allocate the memory */	mac = kmalloc( sizeof(am930mac_t), GFP_KERNEL);#elif (WLAN_OS == WLAN_LWOS )	mac = &gmac;#else	#error "No WLAN_OS match!"#endif	if ( mac == NULL )	{		WLAN_LOG_ERROR0("mac allocation failed!\n");	}	else	{		/* zero the mac object */		memset( mac, 0, sizeof(am930mac_t));		/* init the crc table */		am930mac_crc32_mktable(mac);		/* mark all the frag pools as avail */		for ( i = 0; i < AM930MAC_FRAGPOOLS_MAX; i++)		{			mac->defragpool[i].seq = AM930MAC_FRAGPOOL_FREE;		}		/* intialize the locks */		mac->fragpool_lock = SPIN_LOCK_UNLOCKED;#if  (WLAN_OS == WLAN_LINUX_KERNEL)#ifdef WLAN_PCMCIA		/* save a reference to the di */		mac->di = di;		/* set the di priv ptr to mac */		((dev_link_t*)di)->priv = mac;#endif		/* Create the hw instance */		mac->hw = am930hw_construct( irq, iobase, membase, mac) ;#elif (WLAN_OS == WLAN_LWOS )		mac->lw = lw;		mac->llc = lw;		/* Create the hw instance */		mac->hw = am930hw_construct( irq, iobase, membase, mac) ;#else	#error "No WLAN_OS match!"#endif		if ( mac->hw  == NULL)		{			WLAN_LOG_ERROR0("hw allocation failed!\n");			am930mac_destruct(mac);			mac = NULL;#if (WLAN_OS == WLAN_LINUX_KERNEL)#ifdef WLAN_PCMCIA			((dev_link_t*)di)->priv = NULL;#endif#endif		}		else		{			/* Set up the transmit queues */			mac->llcq = am930q_init( LLCQ_LEN );			mac->macq = am930q_init( MACQ_LEN );			mac->rxq = am930q_init( RXQ_LEN );			/* Set the default MIB values (where zero is unacceptable) */			mac->maxrxlifetime = 1024;			/* Now, call the second part of the hw initialization */			if ( am930hw_init_rx_tx( mac->hw ) != 0 )			{				WLAN_LOG_ERROR0("hw_init_rx_tx failed!\n");				am930mac_destruct(mac);				mac = NULL; #if (WLAN_OS == WLAN_LINUX_KERNEL)#ifdef WLAN_PCMCIA				((dev_link_t*)di)->priv = NULL;#endif#endif			}			else			{				mac->mgr = am930mgr_construct( mac, mac->hw );				if ( mac->mgr == NULL )				{					WLAN_LOG_ERROR0("mgr allocation failed!\n");					am930mac_destruct(mac);					mac = NULL; #if (WLAN_OS == WLAN_LWOS)				}#elif (WLAN_OS == WLAN_LINUX_KERNEL)#ifdef WLAN_PCMCIA					((dev_link_t*)di)->priv = NULL;#endif				}				else				{					mac->llc = am930llc_construct( mac, mac->mgr);					if ( mac->llc == NULL )					{						WLAN_LOG_ERROR0("llc allocation failed!\n");						am930mac_destruct(mac);						mac = NULL; #ifdef WLAN_PCMCIA						((dev_link_t*)di)->priv = NULL;#endif					}				}#else	#error "No WLAN_OS match!"#endif				mac->timerfunc = am930mac_timerfunc;				/* Hard coded to match the AM930 phy mib default. */				/* Lame, I know....the new UI will fix it. */				mac->oprates[0] = 1;				mac->oprates[1] = 2;				mac->oprates[2] = 0x82;				mac->oprates[3] = 0x84;			}		}	}	DBFEXIT;	return mac;}/*----------------------------------------------------------------*	am930mac_destruct**	Destroys the subobjects and the mac object. Caller needs to be*   aware that the pointer passed in is invalid after this call.**	returns: nothing----------------------------------------------------------------*/void am930mac_destruct( am930mac_t* mac){	wlan_pb_t*	pb;	DBFENTER;	mac->timerfunc = NULL;	if ( mac->hw != NULL )	{		am930hw_destruct( mac->hw );		mac->hw = NULL;	}#if (WLAN_OS == WLAN_LINUX_KERNEL)	if ( mac->llc != NULL )	{		am930llc_destruct( mac->llc);		mac->llc = NULL;	}#endif	/* TODO: handle destruction cleanly, call subobject destructors	         after testing subobject pointers for NULL */	/* get rid of the queues */	while ( (mac->llcq != NULL) && (pb = (wlan_pb_t*)am930q_dequeue(mac->llcq)) )	{		am930shim_pbfree(pb);	}	kfree_s( mac->llcq, sizeof(am930q_t));	while ( (mac->macq != NULL) && (pb = (wlan_pb_t*)am930q_dequeue(mac->macq)) )	{		am930shim_pbfree(pb);	}	kfree_s( mac->macq, sizeof(am930q_t));	/* all subobjects handled, now free the mac object */	kfree_s( mac, sizeof(am930mac_t));	DBFEXIT;	return;}/*----------------------------------------------------------------*	am930mac_crc32_block**	Calculate the crc over a block of bytes.  To get the final crc value,*	don't forget to call crc32_blockfinish.*	Arguments: *		reg		initial accumulator value, passing it in allows us to *				crc non-contiguous blocks.  On the first call to this *				function for a given crc calculation, reg should be*				0xffffffffUL.*		p		ptr to the block*		len		size of block*	returns: *		crc32 value----------------------------------------------------------------*/UINT32 am930mac_crc32_block(am930mac_t *mac, UINT32 reg, UINT8 *p, UINT len){	while(len)	{		reg = mac->crc32_table[(reg ^ *p) & 0x000000ffUL] ^ (reg >> 8);		len--;		p++;	}	return reg;}UINT32 am930mac_crc32_blockfinish(am930mac_t *mac, UINT32 reg){	return reg ^ 0xffffffffUL;}/*----------------------------------------------------------------*	am930mac_crc32_accum**	Accumulates, in a given register, the crc of a series of bytes*	passed to this function.*	Arguments: *		reg		current accumulated crc value*		d		next byte in series*	returns: *		new accumulated crc32 value----------------------------------------------------------------*/#ifdef NOTUSED	/* we're not using it right now, ifdef'd to stop warning */UINT32 am930mac_crc32_accum(am930mac_t *mac, UINT32 reg, UINT8 d){	reg = mac->crc32_table[(reg ^ d) & 0x000000ffUL] ^ (reg >> 8);	return reg;}#endif/*----------------------------------------------------------------*	am930mac_crc32_mktable**	Constructs the table used for the crc32 calculation.*	Arguments: none*	returns:   nothing----------------------------------------------------------------*/void am930mac_crc32_mktable(am930mac_t *mac){	UINT	i;	UINT	k;	UINT32	c;	mac->crc32_table[0] = 0;	for ( i = 1; i < 256; i++)	{		c = 0;		for ( k = i | 256; k != 1; k >>= 1)		{			c = (c & 1) ? 				((c >> 1) ^ WLAN_CRC32_POLY_LE) : 				(c >> 1);			if ( k & 1 )			{				c ^= WLAN_CRC32_POLY_LE;			}		}		mac->crc32_table[i] = c;	}}/*----------------------------------------------------------------*	am930mac_ISR**	ISR called from the di ISR. I know this is kindof a waste, but*	I didn't want the di to know anything about the hw interface.**	returns: nothing----------------------------------------------------------------*/void am930mac_ISR( am930mac_t *mac ){

⌨️ 快捷键说明

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