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

📄 3c359.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
	int i ; 	if (dev->flags & IFF_PROMISC)		options = 0x0004 ; 	else		options = 0x0000 ; 	if (options ^ xl_priv->xl_copy_all_options) { /* Changed, must send command */		xl_priv->xl_copy_all_options = options ; 		xl_srb_cmd(dev, SET_RECEIVE_MODE) ;		return ;  	}	dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ;        for (i=0,dmi=dev->mc_list;i < dev->mc_count; i++,dmi = dmi->next) {                dev_mc_address[0] |= dmi->dmi_addr[2] ;                dev_mc_address[1] |= dmi->dmi_addr[3] ;                dev_mc_address[2] |= dmi->dmi_addr[4] ;                dev_mc_address[3] |= dmi->dmi_addr[5] ;        }	if (memcmp(xl_priv->xl_functional_addr,dev_mc_address,4) != 0) { /* Options have changed, run the command */		memcpy(xl_priv->xl_functional_addr, dev_mc_address,4) ; 		xl_srb_cmd(dev, SET_FUNC_ADDRESS) ; 	}	return ; }/* *	We issued an srb command and now we must read *	the response from the completed command. */static void xl_srb_bh(struct net_device *dev) { 	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 	u8 srb_cmd, ret_code ; 	int i ; 	writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ;	srb_cmd = readb(xl_mmio + MMIO_MACDATA) ; 	writel((MEM_BYTE_READ | 0xd0000 | xl_priv->srb) +2, xl_mmio + MMIO_MAC_ACCESS_CMD) ;	ret_code = readb(xl_mmio + MMIO_MACDATA) ; 	/* Ret_code is standard across all commands */	switch (ret_code) { 	case 1:		printk(KERN_INFO "%s: Command: %d - Invalid Command code\n",dev->name,srb_cmd) ; 		break ; 	case 4:		printk(KERN_INFO "%s: Command: %d - Adapter is closed, must be open for this command \n",dev->name,srb_cmd) ; 		break ;		case 6:		printk(KERN_INFO "%s: Command: %d - Options Invalid for command \n",dev->name,srb_cmd) ;		break ;	case 0: /* Successful command execution */ 		switch (srb_cmd) { 		case READ_LOG: /* Returns 14 bytes of data from the NIC */			if(xl_priv->xl_message_level)				printk(KERN_INFO "%s: READ.LOG 14 bytes of data ",dev->name) ; 			/* 			 * We still have to read the log even if message_level = 0 and we don't want			 * to see it			 */			for (i=0;i<14;i++) { 				writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 				if(xl_priv->xl_message_level) 					printk("%02x:",readb(xl_mmio + MMIO_MACDATA)) ; 				} 			printk("\n") ; 			break ; 		case SET_FUNC_ADDRESS:			if(xl_priv->xl_message_level) 				printk(KERN_INFO "%s: Functional Address Set \n",dev->name) ;  			break ; 		case CLOSE_NIC:			if(xl_priv->xl_message_level)				printk(KERN_INFO "%s: Received CLOSE_NIC interrupt in interrupt handler \n",dev->name) ; 				break ; 		case SET_MULTICAST_MODE:			if(xl_priv->xl_message_level)				printk(KERN_INFO "%s: Multicast options successfully changed\n",dev->name) ; 			break ;		case SET_RECEIVE_MODE:			if(xl_priv->xl_message_level) {  				if (xl_priv->xl_copy_all_options == 0x0004) 					printk(KERN_INFO "%s: Entering promiscuous mode \n", dev->name) ; 				else					printk(KERN_INFO "%s: Entering normal receive mode \n",dev->name) ; 			}			break ;  		} /* switch */		break ; 	} /* switch */	return ; 	} static struct net_device_stats * xl_get_stats(struct net_device *dev){	struct xl_private *xl_priv = (struct xl_private *) dev->priv ;	return (struct net_device_stats *) &xl_priv->xl_stats; }static int xl_set_mac_address (struct net_device *dev, void *addr) {	struct sockaddr *saddr = addr ; 	struct xl_private *xl_priv = (struct xl_private *)dev->priv ; 	if (netif_running(dev)) { 		printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name) ; 		return -EIO ; 	}	memcpy(xl_priv->xl_laa, saddr->sa_data,dev->addr_len) ; 		if (xl_priv->xl_message_level) {  		printk(KERN_INFO "%s: MAC/LAA Set to  = %x.%x.%x.%x.%x.%x\n",dev->name, xl_priv->xl_laa[0],		xl_priv->xl_laa[1], xl_priv->xl_laa[2],		xl_priv->xl_laa[3], xl_priv->xl_laa[4],		xl_priv->xl_laa[5]);	} 	return 0 ; }static void xl_arb_cmd(struct net_device *dev){	struct xl_private *xl_priv = (struct xl_private *) dev->priv;	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 	u8 arb_cmd ; 	u16 lan_status, lan_status_diff ; 	writel( ( MEM_BYTE_READ | 0xD0000 | xl_priv->arb), xl_mmio + MMIO_MAC_ACCESS_CMD) ; 	arb_cmd = readb(xl_mmio + MMIO_MACDATA) ; 		if (arb_cmd == RING_STATUS_CHANGE) { /* Ring.Status.Change */		writel( ( (MEM_WORD_READ | 0xD0000 | xl_priv->arb) + 6), xl_mmio + MMIO_MAC_ACCESS_CMD) ;		 		printk(KERN_INFO "%s: Ring Status Change: New Status = %04x\n", dev->name, ntohs(readw(xl_mmio + MMIO_MACDATA) )) ; 		lan_status = ntohs(readw(xl_mmio + MMIO_MACDATA));			/* Acknowledge interrupt, this tells nic we are done with the arb */		writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; 					lan_status_diff = xl_priv->xl_lan_status ^ lan_status ; 		if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR) ) { 			if (lan_status_diff & LSC_LWF) 				printk(KERN_WARNING "%s: Short circuit detected on the lobe\n",dev->name);			if (lan_status_diff & LSC_ARW) 				printk(KERN_WARNING "%s: Auto removal error\n",dev->name);			if (lan_status_diff & LSC_FPE)				printk(KERN_WARNING "%s: FDX Protocol Error\n",dev->name);			if (lan_status_diff & LSC_RR) 				printk(KERN_WARNING "%s: Force remove MAC frame received\n",dev->name);					/* Adapter has been closed by the hardware */			netif_stop_queue(dev);			xl_freemem(dev) ; 			free_irq(dev->irq,dev);						printk(KERN_WARNING "%s: Adapter has been closed \n", dev->name) ; 		} /* If serious error */				if (xl_priv->xl_message_level) { 			if (lan_status_diff & LSC_SIG_LOSS) 					printk(KERN_WARNING "%s: No receive signal detected \n", dev->name) ; 			if (lan_status_diff & LSC_HARD_ERR)					printk(KERN_INFO "%s: Beaconing \n",dev->name);			if (lan_status_diff & LSC_SOFT_ERR)					printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame \n",dev->name);			if (lan_status_diff & LSC_TRAN_BCN) 					printk(KERN_INFO "%s: We are tranmitting the beacon, aaah\n",dev->name);			if (lan_status_diff & LSC_SS) 					printk(KERN_INFO "%s: Single Station on the ring \n", dev->name);			if (lan_status_diff & LSC_RING_REC)					printk(KERN_INFO "%s: Ring recovery ongoing\n",dev->name);			if (lan_status_diff & LSC_FDX_MODE)					printk(KERN_INFO "%s: Operating in FDX mode\n",dev->name);		} 					if (lan_status_diff & LSC_CO) { 				if (xl_priv->xl_message_level) 					printk(KERN_INFO "%s: Counter Overflow \n", dev->name);				/* Issue READ.LOG command */				xl_srb_cmd(dev, READ_LOG) ; 			}		/* There is no command in the tech docs to issue the read_sr_counters */		if (lan_status_diff & LSC_SR_CO) { 			if (xl_priv->xl_message_level)				printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name);		}		xl_priv->xl_lan_status = lan_status ; 		}  /* Lan.change.status */	else if ( arb_cmd == RECEIVE_DATA) { /* Received.Data */#if XL_DEBUG		printk(KERN_INFO "Received.Data \n") ; #endif 				writel( ((MEM_WORD_READ | 0xD0000 | xl_priv->arb) + 6), xl_mmio + MMIO_MAC_ACCESS_CMD) ;		xl_priv->mac_buffer = ntohs(readw(xl_mmio + MMIO_MACDATA)) ;				/* Now we are going to be really basic here and not do anything		 * with the data at all. The tech docs do not give me enough		 * information to calculate the buffers properly so we're		 * just going to tell the nic that we've dealt with the frame		 * anyway.		 */		dev->last_rx = jiffies ; 		/* Acknowledge interrupt, this tells nic we are done with the arb */		writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ; 		/* Is the ASB free ? */ 						xl_priv->asb_queued = 0 ; 					writel( ((MEM_BYTE_READ | 0xD0000 | xl_priv->asb) + 2), xl_mmio + MMIO_MAC_ACCESS_CMD) ;		if (readb(xl_mmio + MMIO_MACDATA) != 0xff) { 			xl_priv->asb_queued = 1 ;			xl_wait_misr_flags(dev) ;  			writel(MEM_BYTE_WRITE | MF_ASBFR, xl_mmio + MMIO_MAC_ACCESS_CMD); 			writeb(0xff, xl_mmio + MMIO_MACDATA) ;			writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 			writeb(MISR_ASBFR, xl_mmio + MMIO_MACDATA) ; 			return ; 				/* Drop out and wait for the bottom half to be run */		}			xl_asb_cmd(dev) ; 			} else {		printk(KERN_WARNING "%s: Received unknown arb (xl_priv) command: %02x \n",dev->name,arb_cmd) ; 	}	/* Acknowledge the arb interrupt */	writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ; 	return ; }/* *	There is only one asb command, but we can get called from different *	places. */static void xl_asb_cmd(struct net_device *dev){	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 	if (xl_priv->asb_queued == 1) 		writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ; 			writel(MEM_BYTE_WRITE | 0xd0000 | xl_priv->asb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 	writeb(0x81, xl_mmio + MMIO_MACDATA) ; 	writel(MEM_WORD_WRITE | 0xd0000 | xl_priv->asb | 6, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 	writew(ntohs(xl_priv->mac_buffer), xl_mmio + MMIO_MACDATA) ; 	xl_wait_misr_flags(dev) ; 		writel(MEM_BYTE_WRITE | MF_RASB, xl_mmio + MMIO_MAC_ACCESS_CMD); 	writeb(0xff, xl_mmio + MMIO_MACDATA) ;	writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 	writeb(MISR_RASB, xl_mmio + MMIO_MACDATA) ; 	xl_priv->asb_queued = 2 ; 	return ; }/* * 	This will only get called if there was an error *	from the asb cmd. */static void xl_asb_bh(struct net_device *dev) {	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 	u8 ret_code ; 	writel(MMIO_BYTE_READ | 0xd0000 | xl_priv->asb | 2, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 	ret_code = readb(xl_mmio + MMIO_MACDATA) ; 	switch (ret_code) { 		case 0x01:			printk(KERN_INFO "%s: ASB Command, unrecognized command code \n",dev->name) ;			break ;		case 0x26:			printk(KERN_INFO "%s: ASB Command, unexpected receive buffer \n", dev->name) ; 			break ; 		case 0x40:			printk(KERN_INFO "%s: ASB Command, Invalid Station ID \n", dev->name) ; 			break ;  	}	xl_priv->asb_queued = 0 ; 	writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ;	return ;  }/* 	 *	Issue srb commands to the nic  */static void xl_srb_cmd(struct net_device *dev, int srb_cmd) {	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 	switch (srb_cmd) { 	case READ_LOG:		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 		writeb(READ_LOG, xl_mmio + MMIO_MACDATA) ; 		break; 	case CLOSE_NIC:		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 		writeb(CLOSE_NIC, xl_mmio + MMIO_MACDATA) ; 		break ;	case SET_RECEIVE_MODE:		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 		writeb(SET_RECEIVE_MODE, xl_mmio + MMIO_MACDATA) ; 		writel(MEM_WORD_WRITE | 0xD0000 | xl_priv->srb | 4, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 		writew(xl_priv->xl_copy_all_options, xl_mmio + MMIO_MACDATA) ; 		break ;	case SET_FUNC_ADDRESS:		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 		writeb(SET_FUNC_ADDRESS, xl_mmio + MMIO_MACDATA) ; 		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 6 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; 		writeb(xl_priv->xl_functional_addr[0], xl_mmio + MMIO_MACDATA) ; 		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 7 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; 		writeb(xl_priv->xl_functional_addr[1], xl_mmio + MMIO_MACDATA) ; 		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 8 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; 		writeb(xl_priv->xl_functional_addr[2], xl_mmio + MMIO_MACDATA) ; 		writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 9 , xl_mmio + MMIO_MAC_ACCESS_CMD) ; 		writeb(xl_priv->xl_functional_addr[3], xl_mmio + MMIO_MACDATA) ;		break ;  	} /* switch */	xl_wait_misr_flags(dev)  ; 	/* Write 0xff to the CSRB flag */	writel(MEM_BYTE_WRITE | MF_CSRB , xl_mmio + MMIO_MAC_ACCESS_CMD) ; 	writeb(0xFF, xl_mmio + MMIO_MACDATA) ; 	/* Set csrb bit in MISR register to process command */	writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 	writeb(MISR_CSRB, xl_mmio + MMIO_MACDATA) ; 	xl_priv->srb_queued = 1 ; 	return ; }/* * This is nasty, to use the MISR command you have to wait for 6 memory locations * to be zero. This is the way the driver does on other OS'es so we should be ok with  * the empty loop. */static void xl_wait_misr_flags(struct net_device *dev) {	struct xl_private *xl_priv = (struct xl_private *) dev->priv ; 	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 		int i  ; 		writel(MMIO_BYTE_READ | MISR_RW, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 	if (readb(xl_mmio + MMIO_MACDATA) != 0) {  /* Misr not clear */		for (i=0; i<6; i++) { 			writel(MEM_BYTE_READ | 0xDFFE0 | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 			while (readb(xl_mmio + MMIO_MACDATA) != 0 ) {} ; /* Empty Loop */		} 	}	writel(MMIO_BYTE_WRITE | MISR_AND, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 	writeb(0x80, xl_mmio + MMIO_MACDATA) ; 	return ; } /* *	Change mtu size, this should work the same as olympic */static int xl_change_mtu(struct net_device *dev, int mtu) {	struct xl_private *xl_priv = (struct xl_private *) dev->priv;	u16 max_mtu ; 	if (xl_priv->xl_ring_speed == 4)		max_mtu = 4500 ; 	else		max_mtu = 18000 ; 		if (mtu > max_mtu)		return -EINVAL ; 	if (mtu < 100) 		return -EINVAL ; 	dev->mtu = mtu ; 	xl_priv->pkt_buf_sz = mtu + TR_HLEN ; 	return 0 ; }static void __devexit xl_remove_one (struct pci_dev *pdev){	struct net_device *dev = pci_get_drvdata(pdev);	struct xl_private *xl_priv=(struct xl_private *)dev->priv;		unregister_netdev(dev);	iounmap(xl_priv->xl_mmio) ; 	pci_release_regions(pdev) ; 	pci_set_drvdata(pdev,NULL) ; 	free_netdev(dev);	return ; }static struct pci_driver xl_3c359_driver = {	.name		= "3c359",	.id_table	= xl_pci_tbl,	.probe		= xl_probe,	.remove		= __devexit_p(xl_remove_one),};static int __init xl_pci_init (void){	return pci_module_init (&xl_3c359_driver);}static void __exit xl_pci_cleanup (void){	pci_unregister_driver (&xl_3c359_driver);}module_init(xl_pci_init);module_exit(xl_pci_cleanup);MODULE_LICENSE("GPL") ; 

⌨️ 快捷键说明

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