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

📄 arlan.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
		break;				case 8:		{			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)				printk("arlan intr: transmit dest mail box full\n");			priv->bad += 1;			priv->reset = 0;			//arlan_drop_tx(dev);			arlan_queue_retransmit(dev);		}		break;		case 9:		{			IFDEBUG(ARLAN_DEBUG_TX_CHAIN)				printk("arlan intr: transmit root dest not reg.\n");			priv->bad += 1;			priv->reset = 1;			//arlan_drop_tx(dev);			arlan_queue_retransmit(dev);		}		break;		default:		{			printk(KERN_ERR "arlan intr: transmit status unknown\n");			priv->bad += 1;			priv->reset = 1;			arlan_drop_tx(dev);		}	}	ARLAN_DEBUG_EXIT("arlan_tx_done_interrupt");}static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short rxOffset, u_short pkt_len){	char *skbtmp;	int i = 0;	struct arlan_private *priv = (struct arlan_private *) dev->priv;	volatile struct arlan_shmem *arlan = priv->card;	struct arlan_conf_stru *conf = priv->Conf;	ARLAN_DEBUG_ENTRY("arlan_rx_interrupt");	// by spec,   not                WRITESHMB(arlan->rxStatus,0x00);	// prohibited here              arlan_command(dev, ARLAN_COMMAND_RX);	if (pkt_len < 10 || pkt_len > 2048)	{		printk(KERN_WARNING "%s: got too short or long packet, len %d \n", dev->name, pkt_len);		return;	}	if (rxOffset + pkt_len > 0x2000)	{		printk("%s: got too long packet, len %d offset %x\n", dev->name, pkt_len, rxOffset);		return;	}	priv->in_bytes += pkt_len;	priv->in_bytes10 += pkt_len;	if (conf->measure_rate < 1)		conf->measure_rate = 1;	if (jiffies - priv->in_time > conf->measure_rate * HZ)	{		conf->in_speed = priv->in_bytes / conf->measure_rate;		priv->in_bytes = 0;		priv->in_time = jiffies;	}	if (jiffies - priv->in_time10 > conf->measure_rate * HZ * 10)	{		conf->in_speed10 = priv->in_bytes10 / (10 * conf->measure_rate);		priv->in_bytes10 = 0;		priv->in_time10 = jiffies;	}	DEBUGSHM(1, "arlan rcv pkt rxStatus= %d ", arlan->rxStatus, u_char);	switch (rxStatus)	{		case 1:		case 2:		case 3:		{			/* Malloc up new buffer. */			struct sk_buff *skb;			DEBUGSHM(50, "arlan recv pkt offs=%d\n", arlan->rxOffset, u_short);			DEBUGSHM(1, "arlan rxFrmType = %d \n", arlan->rxFrmType, u_char);			DEBUGSHM(1, KERN_INFO "arlan rx scrambled = %d \n", arlan->scrambled, u_char);			/* here we do multicast filtering to avoid slow 8-bit memcopy */#ifdef ARLAN_MULTICAST			if (!(dev->flags & IFF_ALLMULTI) &&				!(dev->flags & IFF_PROMISC) &&				dev->mc_list)			{				char hw_dst_addr[6];				struct dev_mc_list *dmi = dev->mc_list;				int i;				memcpy_fromio(hw_dst_addr, arlan->ultimateDestAddress, 6);				if (hw_dst_addr[0] == 0x01)				{					if (mdebug)						if (hw_dst_addr[1] == 0x00)							printk(KERN_ERR "%s mcast 0x0100 \n", dev->name);						else if (hw_dst_addr[1] == 0x40)							printk(KERN_ERR "%s m/bcast 0x0140 \n", dev->name);					while (dmi)					{							if (dmi->dmi_addrlen == 6)						{							if (arlan_debug & ARLAN_DEBUG_HEADER_DUMP)								printk(KERN_ERR "%s mcl %2x:%2x:%2x:%2x:%2x:%2x \n", dev->name,										 dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2],										 dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]);							for (i = 0; i < 6; i++)								if (dmi->dmi_addr[i] != hw_dst_addr[i])									break;							if (i == 6)								break;						}						else							printk(KERN_ERR "%s: invalid multicast address length given.\n", dev->name);						dmi = dmi->next;					}					/* we reach here if multicast filtering is on and packet 					 * is multicast and not for receive */					goto end_of_interrupt;				}			}#endif				// ARLAN_MULTICAST			/* multicast filtering ends here */			pkt_len += ARLAN_FAKE_HDR_LEN;			skb = dev_alloc_skb(pkt_len + 4);			if (skb == NULL)			{				printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name);				priv->stats.rx_dropped++;				break;			}			skb_reserve(skb, 2);			skb->dev = dev;			skbtmp = skb_put(skb, pkt_len);			memcpy_fromio(skbtmp + ARLAN_FAKE_HDR_LEN, ((char *) arlan) + rxOffset, pkt_len - ARLAN_FAKE_HDR_LEN);			memcpy_fromio(skbtmp, arlan->ultimateDestAddress, 6);			memcpy_fromio(skbtmp + 6, arlan->rxSrc, 6);			WRITESHMB(arlan->rxStatus, 0x00);			arlan_command(dev, ARLAN_COMMAND_RX);			IFDEBUG(ARLAN_DEBUG_HEADER_DUMP)			{				char immedDestAddress[6];				char immedSrcAddress[6];				memcpy_fromio(immedDestAddress, arlan->immedDestAddress, 6);				memcpy_fromio(immedSrcAddress, arlan->immedSrcAddress, 6);				printk(KERN_WARNING "%s t %2x:%2x:%2x:%2x:%2x:%2x f %2x:%2x:%2x:%2x:%2x:%2x imd %2x:%2x:%2x:%2x:%2x:%2x ims %2x:%2x:%2x:%2x:%2x:%2x\n", dev->name,					(unsigned char) skbtmp[0], (unsigned char) skbtmp[1], (unsigned char) skbtmp[2], (unsigned char) skbtmp[3],					(unsigned char) skbtmp[4], (unsigned char) skbtmp[5], (unsigned char) skbtmp[6], (unsigned char) skbtmp[7],					(unsigned char) skbtmp[8], (unsigned char) skbtmp[9], (unsigned char) skbtmp[10], (unsigned char) skbtmp[11],					immedDestAddress[0], immedDestAddress[1], immedDestAddress[2],					immedDestAddress[3], immedDestAddress[4], immedDestAddress[5],					immedSrcAddress[0], immedSrcAddress[1], immedSrcAddress[2],					immedSrcAddress[3], immedSrcAddress[4], immedSrcAddress[5]);			}			skb->protocol = eth_type_trans(skb, dev);			IFDEBUG(ARLAN_DEBUG_HEADER_DUMP)				if (skb->protocol != 0x608 && skb->protocol != 0x8)				{					for (i = 0; i <= 22; i++)						printk("%02x:", (u_char) skbtmp[i + 12]);					printk(KERN_ERR "\n");					printk(KERN_WARNING "arlan kernel pkt type trans %x \n", skb->protocol);				}			netif_rx(skb);			dev->last_rx = jiffies;			priv->stats.rx_packets++;			priv->stats.rx_bytes += pkt_len;		}		break;				default:			printk(KERN_ERR "arlan intr: received unknown status\n");			priv->stats.rx_crc_errors++;			break;	}	ARLAN_DEBUG_EXIT("arlan_rx_interrupt");}static void arlan_process_interrupt(struct net_device *dev){	struct arlan_private *priv = (struct arlan_private *) dev->priv;	volatile struct arlan_shmem *arlan = priv->card;	u_char rxStatus = READSHMB(arlan->rxStatus);	u_char txStatus = READSHMB(arlan->txStatus);	u_short rxOffset = READSHMS(arlan->rxOffset);	u_short pkt_len = READSHMS(arlan->rxLength);	int interrupt_count = 0;	ARLAN_DEBUG_ENTRY("arlan_process_interrupt");	if (test_and_set_bit(0, (void *) &priv->interrupt_processing_active))	{		if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS)			printk(KERN_ERR "interrupt chain reentering \n");		goto end_int_process;	}	while ((rxStatus || txStatus || priv->interrupt_ack_requested)			&& (interrupt_count < 5))	{		if (rxStatus)			priv->last_rx_int_ack_time = arlan_time();		arlan_command(dev, ARLAN_COMMAND_INT_ACK);		arlan_command(dev, ARLAN_COMMAND_INT_ENABLE);				IFDEBUG(ARLAN_DEBUG_INTERRUPT)			printk(KERN_ERR "%s:  got IRQ rx %x tx %x comm %x rxOff %x rxLen %x \n",					dev->name, rxStatus, txStatus, READSHMB(arlan->commandByte),					rxOffset, pkt_len);		if (rxStatus == 0 && txStatus == 0)		{			priv->last_command_was_rx = 0;			if (priv->irq_test_done)			{				if (!registrationBad(dev))					IFDEBUG(ARLAN_DEBUG_INTERRUPT) printk(KERN_ERR "%s unknown interrupt(nop? regLost ?) reason tx %d rx %d ",										    dev->name, txStatus, rxStatus);			} else {				IFDEBUG(ARLAN_DEBUG_INTERRUPT)					printk(KERN_INFO "%s irq $%d test OK \n", dev->name, dev->irq);			}			priv->interrupt_ack_requested = 0;			goto ends;		}		if (txStatus != 0)		{			WRITESHMB(arlan->txStatus, 0x00);			arlan_tx_done_interrupt(dev, txStatus);			goto ends;		}		if (rxStatus == 1 || rxStatus == 2)		{		/* a packet waiting */			arlan_rx_interrupt(dev, rxStatus, rxOffset, pkt_len);			goto ends;		}		if (rxStatus > 2 && rxStatus < 0xff)		{			priv->last_command_was_rx = 0;			WRITESHMB(arlan->rxStatus, 0x00);			printk(KERN_ERR "%s unknown rxStatus reason tx %d rx %d ",				dev->name, txStatus, rxStatus);			goto ends;		}		if (rxStatus == 0xff)		{			priv->last_command_was_rx = 0;			WRITESHMB(arlan->rxStatus, 0x00);			arlan_command(dev, ARLAN_COMMAND_RX);			if (registrationBad(dev))				netif_device_detach(dev);			if (!registrationBad(dev))			{				priv->registrationLastSeen = jiffies;				if (!netif_queue_stopped(dev) && !priv->under_reset && !priv->under_config)					netif_wake_queue (dev);			}			goto ends;		}ends:		arlan_command_process(dev);		rxStatus = READSHMB(arlan->rxStatus);		txStatus = READSHMB(arlan->txStatus);		rxOffset = READSHMS(arlan->rxOffset);		pkt_len = READSHMS(arlan->rxLength);		priv->irq_test_done = 1;		interrupt_count++;	}	priv->interrupt_processing_active = 0;end_int_process:	arlan_command_process(dev);	ARLAN_DEBUG_EXIT("arlan_process_interrupt");	return;}static void arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs){	struct net_device *dev = dev_id;	struct arlan_private *priv = (struct arlan_private *) dev->priv;	volatile struct arlan_shmem *arlan = priv->card;	u_char rxStatus = READSHMB(arlan->rxStatus);	u_char txStatus = READSHMB(arlan->txStatus);	ARLAN_DEBUG_ENTRY("arlan_interrupt");	if (!rxStatus && !txStatus)		priv->interrupt_ack_requested++;	arlan_process_interrupt(dev);		priv->irq_test_done = 1;	ARLAN_DEBUG_EXIT("arlan_interrupt");	return;}static int arlan_close(struct net_device *dev){	struct arlan_private *priv = (struct arlan_private *) dev->priv;	if (!dev)	{		printk(KERN_CRIT "arlan: No Device\n");		return 0;	}	priv = (struct arlan_private *) dev->priv;	if (!priv)	{		printk(KERN_CRIT "arlan: No Device priv \n");		return 0;	}	ARLAN_DEBUG_ENTRY("arlan_close");	del_timer(&priv->timer);	arlan_command(dev, ARLAN_COMMAND_POWERDOWN);	IFDEBUG(ARLAN_DEBUG_STARTUP)		printk(KERN_NOTICE "%s: Closing device\n", dev->name);	priv->open_time = 0;	netif_stop_queue(dev);	free_irq(dev->irq, dev);	ARLAN_DEBUG_EXIT("arlan_close");	return 0;}#ifdef ARLAN_DEBUGGINGstatic long alignLong(volatile u_char * ptr){	long ret;	memcpy_fromio(&ret, (void *) ptr, 4);	return ret;}#endif/* * Get the current statistics. * This may be called with the card open or closed. */static struct net_device_stats *arlan_statistics(struct net_device *dev){	struct arlan_private *priv = (struct arlan_private *) dev->priv;	volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card;	ARLAN_DEBUG_ENTRY("arlan_statistics");	/* Update the statistics from the device registers. */	READSHM(priv->stats.collisions, arlan->numReTransmissions, u_int);	READSHM(priv->stats.rx_crc_errors, arlan->numCRCErrors, u_int);	READSHM(priv->stats.rx_dropped, arlan->numFramesDiscarded, u_int);	READSHM(priv->stats.rx_fifo_errors, arlan->numRXBufferOverflows, u_int);	READSHM(priv->stats.rx_frame_errors, arlan->numReceiveFramesLost, u_int);	READSHM(priv->stats.rx_over_errors, arlan->numRXOverruns, u_int);	READSHM(priv->stats.rx_packets, arlan->numDatagramsReceived, u_int);	READSHM(priv->stats.tx_aborted_errors, arlan->numAbortErrors, u_int);	READSHM(priv->stats.tx_carrier_errors, arlan->numStatusTimeouts, u_int);	READSHM(priv->stats.tx_dropped, arlan->numDatagramsDiscarded, u_int);	READSHM(priv->stats.tx_fifo_errors, arlan->numTXUnderruns, u_int);	READSHM(priv->stats.tx_packets, arlan->numDatagramsTransmitted, u_int);	READSHM(priv->stats.tx_window_errors, arlan->numHoldOffs, u_int);	ARLAN_DEBUG_EXIT("arlan_statistics");	return &priv->stats;}static void arlan_set_multicast(struct net_device *dev){	volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card;	struct arlan_conf_stru *conf = ((struct arlan_private *) dev->priv)->Conf;	int board_conf_needed = 0;	ARLAN_DEBUG_ENTRY("arlan_set_multicast");	if (dev->flags & IFF_PROMISC)	{		unsigned char recMode;		READSHM(recMode, arlan->receiveMode, u_char);		conf->receiveMode = (ARLAN_RCV_PROMISC | ARLAN_RCV_CONTROL);		if (conf->receiveMode != recMode)			board_conf_needed = 1;	}	else	{		/* turn off promiscuous mode  */		unsigned char recMode;		READSHM(recMode, arlan->receiveMode, u_char);		conf->receiveMode = ARLAN_RCV_CLEAN | ARLAN_RCV_CONTROL;		if (conf->receiveMode != recMode)			board_conf_needed = 1;	}	if (board_conf_needed)		arlan_command(dev, ARLAN_COMMAND_CONF);	ARLAN_DEBUG_EXIT("arlan_set_multicast");}int __init arlan_probe(struct net_device *dev){	printk("Arlan driver %s\n", arlan_version);	if (arlan_probe_everywhere(dev))		return -ENODEV;	arlans_found++;	if (arlans_found == 1)		siteName = kmalloc(100, GFP_KERNEL);	return 0;}#ifdef  MODULEint init_module(void){	int i = 0;	ARLAN_DEBUG_ENTRY("init_module");	if (channelSet != channelSetUNKNOWN || channelNumber != channelNumberUNKNOWN || systemId != systemIdUNKNOWN)	{		printk(KERN_WARNING "arlan: wrong module params for multiple devices\n ");		return -1;	}	numDevices = arlan_find_devices();	if (numDevices == 0)	{		printk(KERN_ERR "arlan: no devices found \n");		return -1;	}	siteName = kmalloc(100, GFP_KERNEL);	if(siteName==NULL)	{		printk(KERN_ERR "arlan: No memory for site name.\n");		return -1;	}	for (i = 0; i < numDevices && i < MAX_ARLANS; i++)	{		if (!arlan_allocate_device(i, NULL))			return -1;		if (arlan_device[i] == NULL)		{			printk(KERN_CRIT "arlan: Not Enough memory \n");			return -1;		}		if (probe)			arlan_probe_everywhere(arlan_device[i]);//		arlan_command(arlan_device[i], ARLAN_COMMAND_POWERDOWN );	}	printk(KERN_INFO "Arlan driver %s\n", arlan_version);	ARLAN_DEBUG_EXIT("init_module");	return 0;}void cleanup_module(void){	int i = 0;	ARLAN_DEBUG_ENTRY("cleanup_module");	IFDEBUG(ARLAN_DEBUG_SHUTDOWN)		printk(KERN_INFO "arlan: unloading module\n");	for (i = 0; i < MAX_ARLANS; i++)	{		if (arlan_device[i])		{			arlan_command(arlan_device[i], ARLAN_COMMAND_POWERDOWN );//			release_mem_region(virt_to_phys(arlan_device[i]->mem_start), 0x2000 );			unregister_netdev(arlan_device[i]);			if (arlan_device[i]->priv)			{				if (((struct arlan_private *) arlan_device[i]->priv)->conf)					kfree(((struct arlan_private *) arlan_device[i]->priv)->conf);				kfree(arlan_device[i]);			}			arlan_device[i] = NULL;		}	}	ARLAN_DEBUG_EXIT("cleanup_module");}#endifMODULE_LICENSE("GPL");

⌨️ 快捷键说明

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