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

📄 airo.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	clear_bit(JOB_XMIT11, &priv->flags);	clear_bit(FLAG_PENDING_XMIT11, &priv->flags);	status = transmit_802_11_packet (priv, fids[fid], skb->data);	up(&priv->sem);	i = MAX_FIDS / 2;	if ( status == SUCCESS ) {		dev->trans_start = jiffies;		for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++);	} else {		priv->fids[fid] &= 0xffff;		priv->stats.tx_window_errors++;	}	if (i < MAX_FIDS)		netif_wake_queue(dev);	dev_kfree_skb(skb);}static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {	s16 len;	int i, j;	struct airo_info *priv = dev->priv;	u32 *fids = priv->fids;	if ( skb == NULL ) {		printk( KERN_ERR "airo:  skb == NULL!!!\n" );		return 0;	}	/* Find a vacant FID */	for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ );	for( j = i + 1; j < MAX_FIDS && (fids[j] & 0xffff0000); j++ );	if ( j >= MAX_FIDS ) {		netif_stop_queue(dev);		if (i == MAX_FIDS) {			priv->stats.tx_fifo_errors++;			return 1;		}	}	/* check min length*/	len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;        /* Mark fid as used & save length for later */	fids[i] |= (len << 16);	priv->xmit11.skb = skb;	priv->xmit11.fid = i;	if (down_trylock(&priv->sem) != 0) {		set_bit(FLAG_PENDING_XMIT11, &priv->flags);		netif_stop_queue(dev);		set_bit(JOB_XMIT11, &priv->flags);		wake_up_interruptible(&priv->thr_wait);	} else		airo_end_xmit11(dev);	return 0;}static void airo_read_stats(struct airo_info *ai) {	StatsRid stats_rid;	u32 *vals = stats_rid.vals;	clear_bit(JOB_STATS, &ai->flags);	readStatsRid(ai, &stats_rid, RID_STATS, 0);	up(&ai->sem);	ai->stats.rx_packets = vals[43] + vals[44] + vals[45];	ai->stats.tx_packets = vals[39] + vals[40] + vals[41];	ai->stats.rx_bytes = vals[92];	ai->stats.tx_bytes = vals[91];	ai->stats.rx_errors = vals[0] + vals[2] + vals[3] + vals[4];	ai->stats.tx_errors = vals[42] + ai->stats.tx_fifo_errors;	ai->stats.multicast = vals[43];	ai->stats.collisions = vals[89];	/* detailed rx_errors: */	ai->stats.rx_length_errors = vals[3];	ai->stats.rx_crc_errors = vals[4];	ai->stats.rx_frame_errors = vals[2];	ai->stats.rx_fifo_errors = vals[0];}struct net_device_stats *airo_get_stats(struct net_device *dev){	struct airo_info *local =  dev->priv;	/* Get stats out of the card if available */	if (down_trylock(&local->sem) != 0) {		set_bit(JOB_STATS, &local->flags);		wake_up_interruptible(&local->thr_wait);	} else		airo_read_stats(local);	return &local->stats;}static void airo_set_promisc(struct airo_info *ai) {	Cmd cmd;	Resp rsp;	memset(&cmd, 0, sizeof(cmd));	cmd.cmd=CMD_SETMODE;	clear_bit(JOB_PROMISC, &ai->flags);	cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC;	issuecommand(ai, &cmd, &rsp);	up(&ai->sem);}static void airo_set_multicast_list(struct net_device *dev) {	struct airo_info *ai = dev->priv;	if ((dev->flags ^ ai->flags) & IFF_PROMISC) {		change_bit(FLAG_PROMISC, &ai->flags);		if (down_trylock(&ai->sem) != 0) {			set_bit(JOB_PROMISC, &ai->flags);			wake_up_interruptible(&ai->thr_wait);		} else			airo_set_promisc(ai);	}	if ((dev->flags&IFF_ALLMULTI)||dev->mc_count>0) {		/* Turn on multicast.  (Should be already setup...) */	}}static int airo_set_mac_address(struct net_device *dev, void *p){	struct airo_info *ai = dev->priv;	struct sockaddr *addr = p;	Resp rsp;	readConfigRid(ai, 1);	memcpy (ai->config.macAddr, addr->sa_data, dev->addr_len);	ai->need_commit = 1;	disable_MAC(ai, 1);	writeConfigRid (ai, 1);	enable_MAC(ai, &rsp, 1);	memcpy (ai->dev->dev_addr, addr->sa_data, dev->addr_len);	if (ai->wifidev)		memcpy (ai->wifidev->dev_addr, addr->sa_data, dev->addr_len);	return 0;}static int airo_change_mtu(struct net_device *dev, int new_mtu){	if ((new_mtu < 68) || (new_mtu > 2400))		return -EINVAL;	dev->mtu = new_mtu;	return 0;}static int airo_close(struct net_device *dev) {	struct airo_info *ai = dev->priv;	netif_stop_queue(dev);	if (ai->wifidev != dev) {#ifdef POWER_ON_DOWN		/* Shut power to the card. The idea is that the user can save		 * power when he doesn't need the card with "ifconfig down".		 * That's the method that is most friendly towards the network		 * stack (i.e. the network stack won't try to broadcast		 * anything on the interface and routes are gone. Jean II */		set_bit(FLAG_RADIO_DOWN, &ai->flags);		disable_MAC(ai, 1);#endif		disable_interrupts( ai );	}	return 0;}static void del_airo_dev( struct net_device *dev );void stop_airo_card( struct net_device *dev, int freeres ){	struct airo_info *ai = dev->priv;	disable_interrupts(ai);	free_irq( dev->irq, dev );	takedown_proc_entry( dev, ai );	if (ai->registered) {		unregister_netdev( dev );		if (ai->wifidev) {			unregister_netdev(ai->wifidev);			free_netdev(ai->wifidev);			ai->wifidev = 0;		}		ai->registered = 0;	}	set_bit(JOB_DIE, &ai->flags);	kill_proc(ai->thr_pid, SIGTERM, 1);	wait_for_completion(&ai->thr_exited);	if (ai->flash)		kfree(ai->flash);	if (ai->rssi)		kfree(ai->rssi);	if (freeres) {		/* PCMCIA frees this stuff, so only for PCI and ISA */	        release_region( dev->base_addr, 64 );        }#ifdef MICSUPPORT	if (ai->tfm)		crypto_free_tfm(ai->tfm);#endif	del_airo_dev( dev );	free_netdev( dev );}EXPORT_SYMBOL(stop_airo_card);static int add_airo_dev( struct net_device *dev );int wll_header_parse(struct sk_buff *skb, unsigned char *haddr){	memcpy(haddr, skb->mac.raw + 10, ETH_ALEN);	return ETH_ALEN;}static void wifi_setup(struct net_device *dev, struct net_device *ethdev){	struct airo_info *ai = ethdev->priv;	dev->priv = ai;	dev->hard_header        = 0;	dev->rebuild_header     = 0;	dev->hard_header_cache  = 0;	dev->header_cache_update= 0;	dev->hard_header_parse  = wll_header_parse;	dev->hard_start_xmit = &airo_start_xmit11;	dev->get_stats = &airo_get_stats;	dev->set_mac_address = &airo_set_mac_address;	dev->do_ioctl = &airo_ioctl;#ifdef WIRELESS_EXT	dev->get_wireless_stats = airo_get_wireless_stats;#if WIRELESS_EXT > 12	dev->wireless_handlers = (struct iw_handler_def *)&airo_handler_def;#endif /* WIRELESS_EXT > 12 */#endif /* WIRELESS_EXT */	dev->change_mtu = &airo_change_mtu;	dev->open = &airo_open;	dev->stop = &airo_close;	dev->irq = ethdev->irq;	dev->base_addr = ethdev->base_addr;	dev->type               = ARPHRD_IEEE80211;	dev->hard_header_len    = ETH_HLEN;	dev->mtu                = 2312;	dev->addr_len           = ETH_ALEN;	memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len);	dev->tx_queue_len       = 100; 	memset(dev->broadcast,0xFF, ETH_ALEN);	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;}static struct net_device *init_wifidev(struct airo_info *ai,					struct net_device *ethdev){	int err;	struct net_device *dev = (struct net_device*)kmalloc(sizeof *dev,GFP_KERNEL);	if (!dev) return 0;	memset(dev, 0, sizeof(*dev));	strcpy(dev->name, "wifi%d");	dev->priv = ai;	wifi_setup(dev, ethdev);	err = register_netdev(dev);	if (err<0) {		kfree(dev);		return 0;	}	return dev;}struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia ){	struct net_device *dev;	struct airo_info *ai;	int i, rc;	/* Create the network device object. */        dev = alloc_etherdev(sizeof(*ai));        if (!dev) {		printk(KERN_ERR "airo:  Couldn't alloc_etherdev\n");		return NULL;        }	if (dev_alloc_name(dev, dev->name) < 0) {		printk(KERN_ERR "airo:  Couldn't get name!\n");		goto err_out_free;	}	ai = dev->priv;	ai->wifidev = 0;	ai->registered = 0;        ai->dev = dev;	ai->aux_lock = SPIN_LOCK_UNLOCKED;	sema_init(&ai->sem, 1);	ai->need_commit = 0;	ai->config.len = 0;	init_waitqueue_head (&ai->thr_wait);	init_completion (&ai->thr_exited);	ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES);	if (ai->thr_pid < 0)		goto err_out_free;#ifdef MICSUPPORT	ai->tfm = NULL;#endif	rc = add_airo_dev( dev );	if (rc)		goto err_out_thr;	/* The Airo-specific entries in the device structure. */	dev->hard_start_xmit = &airo_start_xmit;	dev->get_stats = &airo_get_stats;	dev->set_multicast_list = &airo_set_multicast_list;	dev->set_mac_address = &airo_set_mac_address;	dev->do_ioctl = &airo_ioctl;#ifdef WIRELESS_EXT	dev->get_wireless_stats = airo_get_wireless_stats;#if WIRELESS_EXT > 12	dev->wireless_handlers = (struct iw_handler_def *)&airo_handler_def;#endif /* WIRELESS_EXT > 12 */#endif /* WIRELESS_EXT */	dev->change_mtu = &airo_change_mtu;	dev->open = &airo_open;	dev->stop = &airo_close;	dev->irq = irq;	dev->base_addr = port;	rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev );	if (rc) {		printk(KERN_ERR "airo: register interrupt %d failed, rc %d\n", irq, rc );		goto err_out_unlink;	}	if (!is_pcmcia) {		if (!request_region( dev->base_addr, 64, dev->name )) {			rc = -EBUSY;			goto err_out_irq;		}	}	if (probe) {		if ( setup_card( ai, dev->dev_addr ) != SUCCESS ) {			printk( KERN_ERR "airo: MAC could not be enabled\n" );			rc = -EIO;			goto err_out_res;		}	} else {		ai->bap_read = fast_bap_read;		set_bit(FLAG_FLASHING, &ai->flags);	}	rc = register_netdev(dev);	if (rc)		goto err_out_res;	ai->wifidev = init_wifidev(ai, dev);	ai->registered = 1;	printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",		dev->name,		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );	/* Allocate the transmit buffers */	if (probe)		for( i = 0; i < MAX_FIDS; i++ )			ai->fids[i] = transmit_allocate(ai,2312,i>=MAX_FIDS/2);	setup_proc_entry( dev, dev->priv ); /* XXX check for failure */	netif_start_queue(dev);	SET_MODULE_OWNER(dev);	return dev;err_out_res:	if (!is_pcmcia)	        release_region( dev->base_addr, 64 );err_out_irq:	free_irq(dev->irq, dev);err_out_unlink:	del_airo_dev(dev);err_out_thr:	set_bit(JOB_DIE, &ai->flags);	kill_proc(ai->thr_pid, SIGTERM, 1);	wait_for_completion(&ai->thr_exited);err_out_free:	kfree(dev);	return NULL;}EXPORT_SYMBOL(init_airo_card);static int waitbusy (struct airo_info *ai) {	int delay = 0;	while ((IN4500 (ai, COMMAND) & COMMAND_BUSY) & (delay < 10000)) {		udelay (10);		if (++delay % 20)			OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);	}	return delay < 10000;}int reset_airo_card( struct net_device *dev ) {	int i;	struct airo_info *ai = dev->priv;	if (down_interruptible(&ai->sem))		return -1;	waitbusy (ai);	OUT4500(ai,COMMAND,CMD_SOFTRESET);	set_current_state (TASK_UNINTERRUPTIBLE);	schedule_timeout (HZ/5);	waitbusy (ai);	set_current_state (TASK_UNINTERRUPTIBLE);	schedule_timeout (HZ/5);	if ( setup_card(ai, dev->dev_addr ) != SUCCESS ) {		printk( KERN_ERR "airo: MAC could not be enabled\n" );		up(&ai->sem);		return -1;	} else {		printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",			dev->name,			dev->dev_addr[0],			dev->dev_addr[1],			dev->dev_addr[2],			dev->dev_addr[3],			dev->dev_addr[4],			dev->dev_addr[5]			);		/* Allocate the transmit buffers */		for( i = 0; i < MAX_FIDS; i++ )			ai->fids[i] = transmit_allocate(ai,2312,i>=MAX_FIDS/2);	}	enable_interrupts( ai );	netif_wake_queue(dev);	up(&ai->sem);	return 0;}EXPORT_SYMBOL(reset_airo_card);#if WIRELESS_EXT > 13static void airo_send_event(struct net_device *dev) {	struct airo_info *ai = dev->priv;	union iwreq_data wrqu;	StatusRid status_rid;	clear_bit(JOB_EVENT, &ai->flags);	PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0);	up(&ai->sem);	wrqu.data.length = 0;	wrqu.data.flags = 0;	memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN);	wrqu.ap_addr.sa_family = ARPHRD_ETHER;	/* Send event to user space */	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);}#endifstatic int airo_thread(void *data) {	struct net_device *dev = data;	struct airo_info *ai = dev->priv;	int locked;		daemonize();	reparent_to_init();	spin_lock_irq(&current->sigmask_lock);	sigemptyset(&current->blocked);	recalc_sigpending(current

⌨️ 快捷键说明

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