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

📄 olympic.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	return IRQ_HANDLED;}	static int olympic_xmit(struct sk_buff *skb, struct net_device *dev) {	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;	u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio;	unsigned long flags ; 	spin_lock_irqsave(&olympic_priv->olympic_lock, flags);	netif_stop_queue(dev);		if(olympic_priv->free_tx_ring_entries) {		olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].buffer = 			cpu_to_le32(pci_map_single(olympic_priv->pdev, skb->data, skb->len,PCI_DMA_TODEVICE));		olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].status_length = cpu_to_le32(skb->len | (0x80000000));		olympic_priv->tx_ring_skb[olympic_priv->tx_ring_free]=skb;		olympic_priv->free_tx_ring_entries--;        	olympic_priv->tx_ring_free++;        	olympic_priv->tx_ring_free &= (OLYMPIC_TX_RING_SIZE-1);		writew((((readw(olympic_mmio+TXENQ_1)) & 0x8000) ^ 0x8000) | 1,olympic_mmio+TXENQ_1);		netif_wake_queue(dev);		spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);		return 0;	} else {		spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);		return 1;	} }	static int olympic_close(struct net_device *dev) {	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;	u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio,*srb;	unsigned long t,flags;	DECLARE_WAITQUEUE(wait,current) ; 	netif_stop_queue(dev);		writel(olympic_priv->srb,olympic_mmio+LAPA);	srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));	    	writeb(SRB_CLOSE_ADAPTER,srb+0);	writeb(0,srb+1);	writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);	add_wait_queue(&olympic_priv->srb_wait,&wait) ;	set_current_state(TASK_INTERRUPTIBLE) ; 	spin_lock_irqsave(&olympic_priv->olympic_lock,flags);	olympic_priv->srb_queued=1;	writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);	spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);	while(olympic_priv->srb_queued) {		t = schedule_timeout_interruptible(60*HZ);        	if(signal_pending(current))	{            			printk(KERN_WARNING "%s: SRB timed out.\n",dev->name);            		printk(KERN_WARNING "SISR=%x MISR=%x\n",readl(olympic_mmio+SISR),readl(olympic_mmio+LISR));            		olympic_priv->srb_queued=0;            		break;        	}		if (t == 0) { 			printk(KERN_WARNING "%s: SRB timed out. May not be fatal. \n",dev->name) ; 		} 		olympic_priv->srb_queued=0;    	}	remove_wait_queue(&olympic_priv->srb_wait,&wait) ; 	olympic_priv->rx_status_last_received++;	olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;	olympic_freemem(dev) ; 		/* reset tx/rx fifo's and busmaster logic */	writel(readl(olympic_mmio+BCTL)|(3<<13),olympic_mmio+BCTL);	udelay(1);	writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL);#if OLYMPIC_DEBUG	{	int i ; 	printk("srb(%p): ",srb);	for(i=0;i<4;i++)		printk("%x ",readb(srb+i));	printk("\n");	}#endif	free_irq(dev->irq,dev);	return 0;	}static void olympic_set_rx_mode(struct net_device *dev) {	struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv ;    	u8 __iomem *olympic_mmio = olympic_priv->olympic_mmio ; 	u8 options = 0; 	u8 __iomem *srb;	struct dev_mc_list *dmi ; 	unsigned char dev_mc_address[4] ; 	int i ; 	writel(olympic_priv->srb,olympic_mmio+LAPA);	srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));	options = olympic_priv->olympic_copy_all_options; 	if (dev->flags&IFF_PROMISC)  		options |= 0x61 ;	else		options &= ~0x61 ; 	/* Only issue the srb if there is a change in options */	if ((options ^ olympic_priv->olympic_copy_all_options)) { 			/* Now to issue the srb command to alter the copy.all.options */			writeb(SRB_MODIFY_RECEIVE_OPTIONS,srb);		writeb(0,srb+1);		writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);		writeb(0,srb+3);		writeb(olympic_priv->olympic_receive_options,srb+4);		writeb(options,srb+5);		olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */		writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);		olympic_priv->olympic_copy_all_options = options ;				return ;  	} 	/* Set the functional addresses we need for multicast */	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] ; 	}	writeb(SRB_SET_FUNC_ADDRESS,srb+0);	writeb(0,srb+1);	writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);	writeb(0,srb+3);	writeb(0,srb+4);	writeb(0,srb+5);	writeb(dev_mc_address[0],srb+6);	writeb(dev_mc_address[1],srb+7);	writeb(dev_mc_address[2],srb+8);	writeb(dev_mc_address[3],srb+9);	olympic_priv->srb_queued = 2 ;	writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);}static void olympic_srb_bh(struct net_device *dev) { 	struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv ;    	u8 __iomem *olympic_mmio = olympic_priv->olympic_mmio ; 	u8 __iomem *srb;	writel(olympic_priv->srb,olympic_mmio+LAPA);	srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));	switch (readb(srb)) { 		/* SRB_MODIFY_RECEIVE_OPTIONS i.e. set_multicast_list options (promiscuous)                  * At some point we should do something if we get an error, such as                 * resetting the IFF_PROMISC flag in dev		 */		case SRB_MODIFY_RECEIVE_OPTIONS:			switch (readb(srb+2)) { 				case 0x01:					printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name) ; 					break ; 				case 0x04:					printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name);					break ; 				default:					if (olympic_priv->olympic_message_level) 						printk(KERN_WARNING "%s: Receive Options Modified to %x,%x\n",dev->name,olympic_priv->olympic_copy_all_options, olympic_priv->olympic_receive_options) ; 					break ; 				} /* switch srb[2] */ 			break ;				/* SRB_SET_GROUP_ADDRESS - Multicast group setting                  */		case SRB_SET_GROUP_ADDRESS:			switch (readb(srb+2)) { 				case 0x00:					break ; 				case 0x01:					printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ; 					break ;				case 0x04:					printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name); 					break ;				case 0x3c:					printk(KERN_WARNING "%s: Group/Functional address indicator bits not set correctly\n",dev->name) ; 					break ;				case 0x3e: /* If we ever implement individual multicast addresses, will need to deal with this */					printk(KERN_WARNING "%s: Group address registers full\n",dev->name) ; 					break ;  				case 0x55:					printk(KERN_INFO "%s: Group Address already set.\n",dev->name) ; 					break ;				default:					break ; 			} /* switch srb[2] */ 			break ; 		/* SRB_RESET_GROUP_ADDRESS - Remove a multicast address from group list 		 */		case SRB_RESET_GROUP_ADDRESS:			switch (readb(srb+2)) { 				case 0x00:					break ; 				case 0x01:					printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ; 					break ; 				case 0x04:					printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; 					break ; 				case 0x39: /* Must deal with this if individual multicast addresses used */					printk(KERN_INFO "%s: Group address not found \n",dev->name); 					break ;				default:					break ; 			} /* switch srb[2] */			break ; 				/* SRB_SET_FUNC_ADDRESS - Called by the set_rx_mode 		 */		case SRB_SET_FUNC_ADDRESS:			switch (readb(srb+2)) { 				case 0x00:					if (olympic_priv->olympic_message_level)						printk(KERN_INFO "%s: Functional Address Mask Set \n",dev->name) ; 					break ;				case 0x01:					printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ; 					break ; 				case 0x04:					printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; 					break ; 				default:					break ; 			} /* switch srb[2] */			break ; 			/* SRB_READ_LOG - Read and reset the adapter error counters 		 */		case SRB_READ_LOG:			switch (readb(srb+2)) { 				case 0x00: 					if (olympic_priv->olympic_message_level) 						printk(KERN_INFO "%s: Read Log issued\n",dev->name) ; 					break ; 				case 0x01:					printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ; 					break ; 				case 0x04:					printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; 					break ; 						} /* switch srb[2] */			break ; 				/* SRB_READ_SR_COUNTERS - Read and reset the source routing bridge related counters */		case SRB_READ_SR_COUNTERS:			switch (readb(srb+2)) { 				case 0x00: 					if (olympic_priv->olympic_message_level) 						printk(KERN_INFO "%s: Read Source Routing Counters issued\n",dev->name) ; 					break ; 				case 0x01:					printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ; 					break ; 				case 0x04:					printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ; 					break ; 				default:					break ; 			} /* switch srb[2] */			break ; 		default:			printk(KERN_WARNING "%s: Unrecognized srb bh return value.\n",dev->name);			break ; 	} /* switch srb[0] */} static struct net_device_stats * olympic_get_stats(struct net_device *dev){	struct olympic_private *olympic_priv ;	olympic_priv=(struct olympic_private *) dev->priv;	return (struct net_device_stats *) &olympic_priv->olympic_stats; }static int olympic_set_mac_address (struct net_device *dev, void *addr) {	struct sockaddr *saddr = addr ; 	struct olympic_private *olympic_priv = (struct olympic_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(olympic_priv->olympic_laa, saddr->sa_data,dev->addr_len) ; 		if (olympic_priv->olympic_message_level) {  		printk(KERN_INFO "%s: MAC/LAA Set to  = %x.%x.%x.%x.%x.%x\n",dev->name, olympic_priv->olympic_laa[0],		olympic_priv->olympic_laa[1], olympic_priv->olympic_laa[2],		olympic_priv->olympic_laa[3], olympic_priv->olympic_laa[4],		olympic_priv->olympic_laa[5]);	} 	return 0 ; }static void olympic_arb_cmd(struct net_device *dev)

⌨️ 快捷键说明

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