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

📄 p80211netdev.c

📁 对于无线网卡采用prism芯片的linux的开源驱动.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* src/p80211/p80211knetdev.c** Linux Kernel net device interface** Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.* --------------------------------------------------------------------** linux-wlan**   The contents of this file are subject to the Mozilla Public*   License Version 1.1 (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.**   Alternatively, the contents of this file may be used under the*   terms of the GNU Public License version 2 (the "GPL"), in which*   case the provisions of the GPL are applicable instead of the*   above.  If you wish to allow the use of your version of this file*   only under the terms of the GPL and not to allow others to use*   your version of this file under the MPL, indicate your decision*   by deleting the provisions above and replace them with the notice*   and other provisions required by the GPL.  If you do not delete*   the provisions above, a recipient may use your version of this*   file under either the MPL or the GPL.** --------------------------------------------------------------------** Inquiries regarding the linux-wlan Open Source project can be* made directly to:** AbsoluteValue Systems Inc.* info@linux-wlan.com* http://www.linux-wlan.com** --------------------------------------------------------------------** Portions of the development of this software were funded by * Intersil Corporation as part of PRISM(R) chipset product development.** --------------------------------------------------------------------** The functions required for a Linux network device are defined here.** --------------------------------------------------------------------*//*================================================================*//* System Includes */#include <linux/config.h>#include <linux/version.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/types.h>#include <linux/skbuff.h>#include <linux/slab.h>#include <linux/proc_fs.h>#include <linux/interrupt.h>#include <linux/netdevice.h>#include <linux/kmod.h>#include <linux/if_arp.h>#include <linux/wireless.h>#include <linux/sockios.h>#include <linux/etherdevice.h>#include <asm/bitops.h>#include <asm/uaccess.h>#include <asm/byteorder.h>#ifdef SIOCETHTOOL#include <linux/ethtool.h>#endif#if WIRELESS_EXT > 12#include <net/iw_handler.h>#endif/*================================================================*//* Project Includes */#include <wlan/version.h>#include <wlan/wlan_compat.h>#include <wlan/p80211types.h>#include <wlan/p80211hdr.h>#include <wlan/p80211conv.h>#include <wlan/p80211mgmt.h>#include <wlan/p80211msg.h>#include <wlan/p80211netdev.h>#include <wlan/p80211ioctl.h>#include <wlan/p80211req.h>#include <wlan/p80211metastruct.h>#include <wlan/p80211metadef.h>/*================================================================*//* Local Constants *//*================================================================*//* Local Macros *//*================================================================*//* Local Types *//*================================================================*//* Local Static Definitions */#define __NO_VERSION__		/* prevent the static definition */#ifdef CONFIG_PROC_FSstatic struct proc_dir_entry	*proc_p80211;#endif/*================================================================*//* Local Function Declarations *//* Support functions */static void p80211netdev_rx_bh(unsigned long arg);/* netdevice method functions */static int p80211knetdev_init( netdevice_t *netdev);static struct net_device_stats* p80211knetdev_get_stats(netdevice_t *netdev);static int p80211knetdev_open( netdevice_t *netdev);static int p80211knetdev_stop( netdevice_t *netdev );static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev);static void p80211knetdev_set_multicast_list(netdevice_t *dev);static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd);static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr);static void p80211knetdev_tx_timeout(netdevice_t *netdev);static int p80211_rx_typedrop( wlandevice_t *wlandev, UINT16 fc);#ifdef CONFIG_PROC_FSstatic intp80211netdev_proc_read(	char	*page, 	char	**start, 	off_t	offset, 	int	count,	int	*eof,	void	*data);#endif/*================================================================*//* Function Definitions *//*----------------------------------------------------------------* p80211knetdev_startup** Initialize the wlandevice/netdevice part of 802.11 services at * load time.** Arguments:*	none** Returns: *	nothing----------------------------------------------------------------*/void p80211netdev_startup(void){	DBFENTER;#ifdef CONFIG_PROC_FS	if (proc_net != NULL) {		proc_p80211 = create_proc_entry(				"p80211", 				(S_IFDIR|S_IRUGO|S_IXUGO),				proc_net);	}#endif	DBFEXIT;	return;}/*----------------------------------------------------------------* p80211knetdev_shutdown** Shutdown the wlandevice/netdevice part of 802.11 services at * unload time.** Arguments:*	none** Returns: *	nothing----------------------------------------------------------------*/voidp80211netdev_shutdown(void){	DBFENTER;#ifdef CONFIG_PROC_FS	if (proc_p80211 != NULL) {		remove_proc_entry("p80211", proc_net);	}#endif	DBFEXIT;}/*----------------------------------------------------------------* p80211knetdev_init** Init method for a Linux netdevice.  Called in response to* register_netdev.** Arguments:*	none** Returns: *	nothing----------------------------------------------------------------*/int p80211knetdev_init( netdevice_t *netdev){	DBFENTER;	/* Called in response to register_netdev */	/* This is usually the probe function, but the probe has */	/* already been done by the MSD and the create_kdev */	/* function.  All we do here is return success */	DBFEXIT;	return 0;}/*----------------------------------------------------------------* p80211knetdev_get_stats** Statistics retrieval for linux netdevices.  Here we're reporting* the Linux i/f level statistics.  Hence, for the primary numbers,* we don't want to report the numbers from the MIB.  Eventually,* it might be useful to collect some of the error counters though.** Arguments:*	netdev		Linux netdevice** Returns: *	the address of the statistics structure----------------------------------------------------------------*/struct net_device_stats*p80211knetdev_get_stats(netdevice_t *netdev){	wlandevice_t	*wlandev = (wlandevice_t*)netdev->priv;	DBFENTER;	/* TODO: review the MIB stats for items that correspond to 		linux stats */	DBFEXIT;	return &(wlandev->linux_stats);}/*----------------------------------------------------------------* p80211knetdev_open** Linux netdevice open method.  Following a successful call here,* the device is supposed to be ready for tx and rx.  In our* situation that may not be entirely true due to the state of the* MAC below.** Arguments:*	netdev		Linux network device structure** Returns: *	zero on success, non-zero otherwise----------------------------------------------------------------*/int p80211knetdev_open( netdevice_t *netdev ){	int 		result = 0; /* success */	wlandevice_t	*wlandev = (wlandevice_t*)(netdev->priv);	DBFENTER;	/* Check to make sure the MSD is running */	if ( wlandev->msdstate != WLAN_MSD_RUNNING ) {		return -ENODEV;	}	/* Tell the MSD to open */	if ( wlandev->open != NULL) {		result = wlandev->open(wlandev);		if ( result == 0 ) {#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) )			netdev->interrupt = 0;#endif			p80211netdev_start_queue(wlandev);			wlandev->state = WLAN_DEVICE_OPEN;		}	} else {		result = -EAGAIN;	}	DBFEXIT;	return result;}/*----------------------------------------------------------------* p80211knetdev_stop** Linux netdevice stop (close) method.  Following this call,* no frames should go up or down through this interface.** Arguments:*	netdev		Linux network device structure** Returns: *	zero on success, non-zero otherwise----------------------------------------------------------------*/int p80211knetdev_stop( netdevice_t *netdev ){	int		result = 0;	wlandevice_t	*wlandev = (wlandevice_t*)(netdev->priv);	DBFENTER;	if ( wlandev->close != NULL ) {		result = wlandev->close(wlandev);	}	p80211netdev_stop_queue(wlandev);	wlandev->state = WLAN_DEVICE_CLOSED;	DBFEXIT;	return result;}/*----------------------------------------------------------------* p80211netdev_rx** Frame receive function called by the mac specific driver.** Arguments:*	wlandev		WLAN network device structure*	skb		skbuff containing a full 802.11 frame.* Returns: *	nothing* Side effects:*	----------------------------------------------------------------*/void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb ) {	DBFENTER;	/* Enqueue for post-irq processing */	skb_queue_tail(&wlandev->nsd_rxq, skb);		tasklet_schedule(&wlandev->rx_bh);	        DBFEXIT;	return;}/*----------------------------------------------------------------* p80211netdev_rx_bh** Deferred processing of all received frames.** Arguments:*	wlandev		WLAN network device structure*	skb		skbuff containing a full 802.11 frame.* Returns: *	nothing* Side effects:*	----------------------------------------------------------------*/void p80211netdev_rx_bh(unsigned long arg){	wlandevice_t *wlandev = (wlandevice_t *) arg;	struct sk_buff *skb = NULL; 	netdevice_t     *dev = wlandev->netdev;	p80211_hdr_a3_t *hdr;	UINT16 fc;        DBFENTER;	/* Let's empty our our queue */	while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) {		if (wlandev->state == WLAN_DEVICE_OPEN) {			if (dev->type != ARPHRD_ETHER) {				/* RAW frame; we shouldn't convert it */				// XXX Append the Prism Header here instead.				/* set up various data fields */				skb->dev = dev;				skb->mac.raw = skb->data ;				skb->ip_summed = CHECKSUM_NONE;				skb->pkt_type = PACKET_OTHERHOST;				skb->protocol = htons(ETH_P_80211_RAW); 				dev->last_rx = jiffies;				wlandev->linux_stats.rx_packets++;				wlandev->linux_stats.rx_bytes += skb->len;				netif_rx_ni(skb);				continue;			} else {				hdr = (p80211_hdr_a3_t *)skb->data;				fc = ieee2host16(hdr->fc);				if (p80211_rx_typedrop(wlandev, fc)) {					dev_kfree_skb(skb);					continue;				}				/* perform mcast filtering */				if (wlandev->netdev->flags & IFF_ALLMULTI) {					/* allow my local address through */ 					if (memcmp(hdr->a1, wlandev->netdev->dev_addr, WLAN_ADDR_LEN) != 0) {						/* but reject anything else that isn't multicast */						if (!(hdr->a1[0] & 0x01)) {							dev_kfree_skb(skb);							continue;						}					}				}				if ( skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0 ) {					skb->dev->last_rx = jiffies;					wlandev->linux_stats.rx_packets++;					wlandev->linux_stats.rx_bytes += skb->len;					netif_rx_ni(skb);					continue;				} 				WLAN_LOG_DEBUG(1, "p80211_to_ether failed.\n");			}		}		dev_kfree_skb(skb);	}        DBFEXIT;}/*----------------------------------------------------------------* p80211knetdev_hard_start_xmit** Linux netdevice method for transmitting a frame.** Arguments:*	skb	Linux sk_buff containing the frame.*	netdev	Linux netdevice.** Side effects:*	If the lower layers report that buffers are full. netdev->tbusy*	will be set to prevent higher layers from sending more traffic.**	Note: If this function returns non-zero, higher layers retain*	      ownership of the skb.** Returns: *	zero on success, non-zero on failure.----------------------------------------------------------------*/int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev){	int		result = 0;	int		txresult = -1;	wlandevice_t	*wlandev = (wlandevice_t*)netdev->priv;	p80211_hdr_t    p80211_hdr;	p80211_metawep_t p80211_wep;	DBFENTER;	if (skb == NULL) {		return 0;	}        if (wlandev->state != WLAN_DEVICE_OPEN) {		result = 1;		goto failed;	}	memset(&p80211_hdr, 0, sizeof(p80211_hdr_t));	memset(&p80211_wep, 0, sizeof(p80211_metawep_t));#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )	if ( test_and_set_bit(0, (void*)&(netdev->tbusy)) != 0 ) {		/* We've been called w/ tbusy set, has the tx */		/* path stalled?   */		WLAN_LOG_DEBUG(1, "called when tbusy set\n");		result = 1;		goto failed;	} #else	if ( netif_queue_stopped(netdev) ) {		WLAN_LOG_DEBUG(1, "called when queue stopped.\n");		result = 1;		goto failed;	}	netif_stop_queue(netdev);	/* No timeout handling here, 2.3.38+ kernels call the 	 * timeout function directly.	 * TODO: Add timeout handling.	*/#endif

⌨️ 快捷键说明

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