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

📄 arlan-main.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
	priv->in_bytes10 += pkt_len;	if (conf->measure_rate < 1)		conf->measure_rate = 1;	if (time_after(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 (time_after(jiffies, priv->in_time10 + conf->measure_rate * 10*HZ))	{		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 __iomem *) 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 = netdev_priv(dev);	volatile struct arlan_shmem __iomem *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 = jiffies;		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)		{			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)		{			WRITESHMB(arlan->rxStatus, 0x00);			printk(KERN_ERR "%s unknown rxStatus reason tx %d rx %d ",				dev->name, txStatus, rxStatus);			goto ends;		}		if (rxStatus == 0xff)		{			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 irqreturn_t arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs){	struct net_device *dev = dev_id;	struct arlan_private *priv = netdev_priv(dev);	volatile struct arlan_shmem __iomem *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 IRQ_HANDLED;}static int arlan_close(struct net_device *dev){	struct arlan_private *priv = netdev_priv(dev);	ARLAN_DEBUG_ENTRY("arlan_close");	del_timer_sync(&priv->timer);	arlan_command(dev, ARLAN_COMMAND_POWERDOWN);	IFDEBUG(ARLAN_DEBUG_STARTUP)		printk(KERN_NOTICE "%s: Closing device\n", dev->name);	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 = netdev_priv(dev);	volatile struct arlan_shmem __iomem *arlan = 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){	struct arlan_private *priv = netdev_priv(dev);	volatile struct arlan_shmem __iomem *arlan = priv->card;	struct arlan_conf_stru *conf = 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");}struct net_device * __init arlan_probe(int unit){	struct net_device *dev;	int err;	int m;	ARLAN_DEBUG_ENTRY("arlan_probe");	if (arlans_found == MAX_ARLANS)		return ERR_PTR(-ENODEV);	/* 	 * Reserve space for local data and a copy of the shared memory	 * that is used by the /proc interface.	 */	dev = alloc_etherdev(sizeof(struct arlan_private)			     + sizeof(struct arlan_shmem));	if (!dev)		return ERR_PTR(-ENOMEM);	SET_MODULE_OWNER(dev);	if (unit >= 0) {		sprintf(dev->name, "eth%d", unit);		netdev_boot_setup_check(dev);				if (dev->mem_start) {			if (arlan_probe_here(dev, dev->mem_start) == 0)				goto found;			goto not_found;		}				}	for (m = (int)phys_to_virt(lastFoundAt) + ARLAN_SHMEM_SIZE; 	     m <= (int)phys_to_virt(0xDE000); 	     m += ARLAN_SHMEM_SIZE)	{		if (arlan_probe_here(dev, m) == 0)		{			lastFoundAt = (int)virt_to_phys((void*)m);			goto found;		}	}	if (lastFoundAt == 0xbe000)		printk(KERN_ERR "arlan: No Arlan devices found \n"); not_found:	free_netdev(dev);	return ERR_PTR(-ENODEV); found:	err = arlan_setup_device(dev, arlans_found);	if (err)		dev = ERR_PTR(err);	else if (!arlans_found++)		printk(KERN_INFO "Arlan driver %s\n", arlan_version);	return dev;}#ifdef  MODULEint init_module(void){	int i = 0;	ARLAN_DEBUG_ENTRY("init_module");	if (channelSet != channelSetUNKNOWN || channelNumber != channelNumberUNKNOWN || systemId != systemIdUNKNOWN)		return -EINVAL;	for (i = 0; i < MAX_ARLANS; i++) {		struct net_device *dev = arlan_probe(i);		if (IS_ERR(dev)) 			return PTR_ERR(dev);	}	init_arlan_proc();	printk(KERN_INFO "Arlan driver %s\n", arlan_version);	ARLAN_DEBUG_EXIT("init_module");	return 0;}void cleanup_module(void){	int i = 0;	struct net_device *dev;	ARLAN_DEBUG_ENTRY("cleanup_module");	IFDEBUG(ARLAN_DEBUG_SHUTDOWN)		printk(KERN_INFO "arlan: unloading module\n");	cleanup_arlan_proc();	for (i = 0; i < MAX_ARLANS; i++)	{		dev = arlan_device[i];		if (dev) {			arlan_command(dev, ARLAN_COMMAND_POWERDOWN );			unregister_netdev(dev);			release_mem_region(virt_to_phys((void *) dev->mem_start), 					   ARLAN_SHMEM_SIZE);			free_netdev(dev);			arlan_device[i] = NULL;		}	}	ARLAN_DEBUG_EXIT("cleanup_module");}#endifMODULE_LICENSE("GPL");

⌨️ 快捷键说明

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