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

📄 arlan.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
	return 0;}static int lastFoundAt = 0xbe000;/* * This is the real probe routine. Linux has a history of friendly device * probes on the ISA bus. A good device probes avoids doing writes, and * verifies that the correct device exists and functions. */static int __init arlan_check_fingerprint(int memaddr){	static char probeText[] = "TELESYSTEM SLW INC.    ARLAN \0";	char tempBuf[49];	volatile struct arlan_shmem *arlan = (struct arlan_shmem *) memaddr;	ARLAN_DEBUG_ENTRY("arlan_check_fingerprint");	if (check_mem_region(virt_to_phys((void *)memaddr),0x2000 )){		// printk(KERN_WARNING "arlan: memory region %lx excluded from probing \n",virt_to_phys((void*)memaddr));		return -ENODEV;	};	memcpy_fromio(tempBuf, arlan->textRegion, 29);	tempBuf[30] = 0;	/* check for card at this address */	if (0 != strncmp(tempBuf, probeText, 29)){// not 		release_mem_region(virt_to_phys((void*)memaddr),0x2000);		return -ENODEV;	}//   printk(KERN_INFO "arlan found at 0x%x \n",memaddr);	ARLAN_DEBUG_EXIT("arlan_check_fingerprint");	return 0;}static int __init arlan_probe_everywhere(struct net_device *dev){	int m;	int probed = 0;	int found = 0;	SET_MODULE_OWNER(dev);	ARLAN_DEBUG_ENTRY("arlan_probe_everywhere");	if (mem != 0 && numDevices == 1)	/* Check a single specified location. */	{		if (arlan_probe_here(dev, (int) phys_to_virt(  mem) ) == 0)			return 0;		else			return -ENODEV;	}	for (m = (int)phys_to_virt(lastFoundAt) + 0x2000; m <= (int)phys_to_virt(0xDE000); m += 0x2000)	{		if (arlan_probe_here(dev, m) == 0)		{			found++;			lastFoundAt = (int)virt_to_phys((void*)m);			break;		}		probed++;	}	if (found == 0 && probed != 0)	{		if (lastFoundAt == 0xbe000)			printk(KERN_ERR "arlan: No Arlan devices found \n");		return -ENODEV;	}	else		return 0;	ARLAN_DEBUG_EXIT("arlan_probe_everywhere");	return -ENODEV;}static int __init arlan_find_devices(void){	int m;	int found = 0;	ARLAN_DEBUG_ENTRY("arlan_find_devices");	if (mem != 0 && numDevices == 1)	/* Check a single specified location. */		return 1;	for (m =(int) phys_to_virt(0xc0000); m <=(int) phys_to_virt(0xDE000); m += 0x2000)	{		if (arlan_check_fingerprint(m) == 0)			found++;	}	ARLAN_DEBUG_EXIT("arlan_find_devices");	return found;}static int arlan_change_mtu(struct net_device *dev, int new_mtu){	struct arlan_conf_stru *conf = ((struct arlan_private *) dev->priv)->Conf;	ARLAN_DEBUG_ENTRY("arlan_change_mtu");	if (new_mtu > 2032)		return -EINVAL;	dev->mtu = new_mtu;	if (new_mtu < 256)		new_mtu = 256;	/* cards book suggests 1600 */	conf->maxDatagramSize = new_mtu;	conf->maxFrameSize = new_mtu + 48;	arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_CONF);	printk(KERN_NOTICE "%s mtu changed to %d \n", dev->name, new_mtu);	ARLAN_DEBUG_EXIT("arlan_change_mtu");	return 0;}static int arlan_mac_addr(struct net_device *dev, void *p){	struct sockaddr *addr = p;	ARLAN_DEBUG_ENTRY("arlan_mac_addr");	return -EINVAL;	if (!netif_running(dev))		return -EBUSY;	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);	ARLAN_DEBUG_EXIT("arlan_mac_addr");	return 0;}static int __init	      arlan_allocate_device(int num, struct net_device *devs){	struct net_device *dev;	ARLAN_DEBUG_ENTRY("arlan_allocate_device");	if (!devs)		dev = init_etherdev(0, sizeof(struct arlan_private));	else	{		dev = devs;		dev->priv = kmalloc(sizeof(struct arlan_private), GFP_KERNEL);	};	if (dev == NULL || dev->priv == NULL)	{		printk(KERN_CRIT "init_etherdev failed ");		return 0;	}	memset(dev->priv,0,sizeof(struct arlan_private));	((struct arlan_private *) dev->priv)->conf =	    kmalloc(sizeof(struct arlan_shmem), GFP_KERNEL);	if (dev == NULL || dev->priv == NULL ||	    ((struct arlan_private *) dev->priv)->conf == NULL)	{		return 0;		printk(KERN_CRIT " No memory at arlan_allocate_device \n");	}	/* Fill in the 'dev' fields. */	dev->base_addr = 0;	dev->mem_start = 0;	dev->mem_end = 0;	dev->mtu = 1500;	dev->flags = 0;		/* IFF_BROADCAST & IFF_MULTICAST & IFF_PROMISC; */	dev->irq = 0;	dev->dma = 0;	dev->tx_queue_len = tx_queue_len;	ether_setup(dev);	dev->tx_queue_len = tx_queue_len;	dev->open = arlan_open;	dev->stop = arlan_close;	dev->hard_start_xmit = arlan_tx;	dev->get_stats = arlan_statistics;	dev->set_multicast_list = arlan_set_multicast;	dev->change_mtu = arlan_change_mtu;	dev->set_mac_address = arlan_mac_addr;	dev->tx_timeout = arlan_tx_timeout;	dev->watchdog_timeo = 3*HZ;		((struct arlan_private *) dev->priv)->irq_test_done = 0;	arlan_device[num] = dev;	((struct arlan_private *) arlan_device[num]->priv)->Conf = &(arlan_conf[num]);	((struct arlan_private *) dev->priv)->Conf->pre_Command_Wait = 40;	((struct arlan_private *) dev->priv)->Conf->rx_tweak1 = 30;	((struct arlan_private *) dev->priv)->Conf->rx_tweak2 = 0;	ARLAN_DEBUG_EXIT("arlan_allocate_device");	return (int) dev;}static int __init arlan_probe_here(struct net_device *dev, int memaddr){	volatile struct arlan_shmem *arlan;	ARLAN_DEBUG_ENTRY("arlan_probe_here");	if (arlan_check_fingerprint(memaddr))		return -ENODEV;	printk(KERN_NOTICE "%s: Arlan found at %x, \n ", dev->name, (int) virt_to_phys((void*)memaddr));	if (!arlan_allocate_device(arlans_found, dev))		return -1;	((struct arlan_private *) dev->priv)->card = (struct arlan_shmem *) memaddr;	arlan = (void *) memaddr;	dev->mem_start = memaddr;	dev->mem_end = memaddr + 0x1FFF;	if (dev->irq < 2)	{		READSHM(dev->irq, arlan->irqLevel, u_char);	} else if (dev->irq == 2)		dev->irq = 9;	arlan_read_card_configuration(dev);	ARLAN_DEBUG_EXIT("arlan_probe_here");	return 0;}static int arlan_open(struct net_device *dev){	struct arlan_private *priv = (struct arlan_private *) dev->priv;	volatile struct arlan_shmem *arlan = priv->card;	int ret = 0;	ARLAN_DEBUG_ENTRY("arlan_open");	if (dev->mem_start == 0)		ret = arlan_probe_everywhere(dev);	if (ret != 0)		return ret;	arlan = ((struct arlan_private *) dev->priv)->card;	ret = request_irq(dev->irq, &arlan_interrupt, 0, dev->name, dev);	if (ret)	{		printk(KERN_ERR "%s: unable to get IRQ %d .\n",			dev->name, dev->irq);		return ret;	}	priv->bad = 0;	priv->lastReset = 0;	priv->reset = 0;	priv->open_time = jiffies;	memcpy_fromio(dev->dev_addr, arlan->lanCardNodeId, 6);	memset(dev->broadcast, 0xff, 6);	priv->txOffset = 0;	dev->tx_queue_len = tx_queue_len;	priv->interrupt_processing_active = 0;	priv->command_lock = 0;	netif_start_queue (dev);	init_MUTEX(&priv->card_lock);	myATOMIC_INIT(priv->card_users, 1);	/* damn 2.0.33 */	priv->registrationLostCount = 0;	priv->registrationLastSeen = jiffies;	priv->txLast = 0;	priv->tx_command_given = 0;	priv->rx_command_given = 0;		priv->reRegisterExp = 1;	priv->nof_tx = 0;	priv->nof_tx_ack = 0;	priv->last_command_was_rx = 0;	priv->tx_last_sent = jiffies - 1;	priv->tx_last_cleared = jiffies;	priv->Conf->writeEEPROM = 0;	priv->Conf->registrationInterrupts = 1;	init_timer(&priv->timer);	priv->timer.expires = jiffies + HZ / 10;	priv->timer.data = (unsigned long) dev;	priv->timer.function = &arlan_registration_timer;	/* timer handler */	arlan_command(dev, ARLAN_COMMAND_POWERUP | ARLAN_COMMAND_LONG_WAIT_NOW);	mdelay(200);	add_timer(&priv->timer);#ifdef CONFIG_PROC_FS#ifndef MODULE	if (arlan_device[0])		init_arlan_proc();#endif#endif	ARLAN_DEBUG_EXIT("arlan_open");	return 0;}static void arlan_tx_timeout (struct net_device *dev){	printk(KERN_ERR "%s: arlan transmit timed out, kernel decided\n", dev->name);	/* Try to restart the adaptor. */	arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET);	// dev->trans_start = jiffies;	// netif_start_queue (dev);}static int arlan_tx(struct sk_buff *skb, struct net_device *dev){	struct arlan_private *priv = ((struct arlan_private *) dev->priv);	short length;	unsigned char *buf;	ARLAN_DEBUG_ENTRY("arlan_tx");		length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;	buf = skb->data;	if (priv->txOffset + length + 0x12 > 0x800) {		printk(KERN_ERR "TX RING overflow \n");		netif_stop_queue (dev);	}	if (arlan_hw_tx(dev, buf, length) == -1)		goto bad_end;	dev->trans_start = jiffies;	dev_kfree_skb(skb);	arlan_process_interrupt(dev);	priv->tx_chain_active = 0;	ARLAN_DEBUG_EXIT("arlan_tx");	return 0;bad_end:	arlan_process_interrupt(dev);	priv->tx_chain_active = 0;	netif_stop_queue (dev);	ARLAN_DEBUG_EXIT("arlan_tx");	return 1;}extern inline int DoNotReTransmitCrap(struct net_device *dev){	struct arlan_private *priv = ((struct arlan_private *) dev->priv);	if (TXLAST(dev).length < priv->Conf->ReTransmitPacketMaxSize)		return 1;	return 0;}extern inline int DoNotWaitReTransmitCrap(struct net_device *dev){	struct arlan_private *priv = ((struct arlan_private *) dev->priv);	if (TXLAST(dev).length < priv->Conf->waitReTransmitPacketMaxSize)		return 1;	return 0;}extern inline void arlan_queue_retransmit(struct net_device *dev){	struct arlan_private *priv = ((struct arlan_private *) dev->priv);	ARLAN_DEBUG_ENTRY("arlan_queue_retransmit");	if (DoNotWaitReTransmitCrap(dev))	{		  arlan_drop_tx(dev);	} else		priv->ReTransmitRequested++;	ARLAN_DEBUG_EXIT("arlan_queue_retransmit");};static inline void RetryOrFail(struct net_device *dev){	struct arlan_private *priv = ((struct arlan_private *) dev->priv);	ARLAN_DEBUG_ENTRY("RetryOrFail");	if (priv->retransmissions > priv->Conf->retries ||	    DoNotReTransmitCrap(dev))	{		arlan_drop_tx(dev);	}	else if (priv->bad <= priv->Conf->fastReTransCount)	{		arlan_retransmit_now(dev);	}	else arlan_queue_retransmit(dev);	ARLAN_DEBUG_EXIT("RetryOrFail");}static void arlan_tx_done_interrupt(struct net_device *dev, int status){	struct arlan_private *priv = ((struct arlan_private *) dev->priv);	ARLAN_DEBUG_ENTRY("arlan_tx_done_interrupt");	priv->tx_last_cleared = jiffies;	priv->tx_command_given = 0;	priv->nof_tx_ack++;	switch (status)	{		case 1:		{			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)				printk("arlan intr: transmit OK\n");			priv->stats.tx_packets++;			priv->bad = 0;			priv->reset = 0;			priv->retransmissions = 0;			if (priv->Conf->tx_delay_ms)			{				priv->tx_done_delayed = jiffies + (priv->Conf->tx_delay_ms * HZ) / 1000 + 1;;			}			else			{				TXLAST(dev).offset = 0;				if (priv->txLast)					priv->txLast = 0;				else if (TXTAIL(dev).offset)					priv->txLast = 1;				if (TXLAST(dev).offset)				{					arlan_retransmit_now(dev);					dev->trans_start = jiffies;				}				if (!TXHEAD(dev).offset || !TXTAIL(dev).offset)				{					priv->txOffset = 0;					netif_wake_queue (dev);				}			}		}		break;				case 2:		{			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)				printk("arlan intr: transmit timed out\n");			priv->bad += 1;			//arlan_queue_retransmit(dev);			RetryOrFail(dev);		}		break;		case 3:		{			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)				printk("arlan intr: transmit max retries\n");			priv->bad += 1;			priv->reset = 0;			//arlan_queue_retransmit(dev);			RetryOrFail(dev);		}		break;				case 4:		{			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)				printk("arlan intr: transmit aborted\n");			priv->bad += 1;			arlan_queue_retransmit(dev);			//RetryOrFail(dev);		}		break;		case 5:		{			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)				printk("arlan intr: transmit not registered\n");			priv->bad += 1;			//debug=101;			arlan_queue_retransmit(dev);		}		break;		case 6:		{			IFDEBUG(ARLAN_DEBUG_TX_CHAIN) 				printk("arlan intr: transmit destination full\n");			priv->bad += 1;			priv->reset = 0;			//arlan_drop_tx(dev);			arlan_queue_retransmit(dev);		}		break;		case 7:		{			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)				printk("arlan intr: transmit unknown ack\n");			priv->bad += 1;			priv->reset = 0;			arlan_queue_retransmit(dev);		}

⌨️ 快捷键说明

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