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

📄 olympic.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	int i;	printk("init_srb(%p): ",init_srb);	for(i=0;i<20;i++)		printk("%x ",readb(init_srb+i));	printk("\n");}#endif		if(readw(init_srb+6)) {		printk(KERN_INFO "tokenring card intialization failed. errorcode : %x\n",readw(init_srb+6));		return -ENODEV;	}	if (olympic_priv->olympic_message_level) {		if ( readb(init_srb +2) & 0x40) { 			printk(KERN_INFO "Olympic: Adapter is FDX capable.\n") ;		} else { 			printk(KERN_INFO "Olympic: Adapter cannot do FDX.\n");		}	}  	uaa_addr=swab16(readw(init_srb+8));#if OLYMPIC_DEBUG	printk("UAA resides at %x\n",uaa_addr);#endif	writel(uaa_addr,olympic_mmio+LAPA);	adapter_addr=olympic_priv->olympic_lap + (uaa_addr & (~0xf800));#if OLYMPIC_DEBUG	printk("adapter address: %02x:%02x:%02x:%02x:%02x:%02x\n",			readb(adapter_addr), readb(adapter_addr+1),readb(adapter_addr+2),			readb(adapter_addr+3),readb(adapter_addr+4),readb(adapter_addr+5));#endif	memcpy_fromio(&dev->dev_addr[0], adapter_addr,6);	olympic_priv->olympic_addr_table_addr = swab16(readw(init_srb + 12)); 	olympic_priv->olympic_parms_addr = swab16(readw(init_srb + 14)); 	return 0;}static int olympic_open(struct net_device *dev) {	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;	u8 *olympic_mmio=olympic_priv->olympic_mmio,*init_srb;	unsigned long flags, t;	char open_error[255] ; 	int i, open_finished = 1 ;	if(request_irq(dev->irq, &olympic_interrupt, SA_SHIRQ , "olympic", dev)) {		return -EAGAIN;	}#if OLYMPIC_DEBUG	printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM));	printk("pending ints: %x\n",readl(olympic_mmio+SISR_RR));#endif	writel(SISR_MI,olympic_mmio+SISR_MASK_SUM);	writel(SISR_MI | SISR_SRB_REPLY, olympic_mmio+SISR_MASK); /* more ints later, doesn't stop arb cmd interrupt */	writel(LISR_LIE,olympic_mmio+LISR); /* more ints later */	/* adapter is closed, so SRB is pointed to by LAPWWO */	writel(readl(olympic_mmio+LAPWWO),olympic_mmio+LAPA);	init_srb=olympic_priv->olympic_lap + ((readl(olympic_mmio+LAPWWO)) & (~0xf800));	#if OLYMPIC_DEBUG	printk("LAPWWO: %x, LAPA: %x\n",readl(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA));	printk("SISR Mask = %04x\n", readl(olympic_mmio+SISR_MASK));	printk("Before the open command \n");#endif		do {		int i;		save_flags(flags);		cli();		for(i=0;i<SRB_COMMAND_SIZE;i+=4)			writel(0,init_srb+i);		if(SRB_COMMAND_SIZE & 2)			writew(0,init_srb+(SRB_COMMAND_SIZE & ~3));		if(SRB_COMMAND_SIZE & 1)			writeb(0,init_srb+(SRB_COMMAND_SIZE & ~1));		writeb(SRB_OPEN_ADAPTER,init_srb) ; 	/* open */		writeb(OLYMPIC_CLEAR_RET_CODE,init_srb+2);		/* If Network Monitor, instruct card to copy MAC frames through the ARB */		if (olympic_priv->olympic_network_monitor) 			writew(swab16(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON), init_srb+8);		else			writew(swab16(OPEN_ADAPTER_ENABLE_FDX), init_srb+8);		if (olympic_priv->olympic_laa[0]) {			writeb(olympic_priv->olympic_laa[0],init_srb+12);			writeb(olympic_priv->olympic_laa[1],init_srb+13);			writeb(olympic_priv->olympic_laa[2],init_srb+14);			writeb(olympic_priv->olympic_laa[3],init_srb+15);			writeb(olympic_priv->olympic_laa[4],init_srb+16);			writeb(olympic_priv->olympic_laa[5],init_srb+17);			memcpy(dev->dev_addr,olympic_priv->olympic_laa,dev->addr_len) ;  		} 			writeb(1,init_srb+30);			olympic_priv->srb_queued=1;		writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);		t = jiffies ;  		while(olympic_priv->srb_queued) {                		interruptible_sleep_on_timeout(&olympic_priv->srb_wait, 60*HZ);        		if(signal_pending(current))	{            				printk(KERN_WARNING "%s: Signal received in open.\n",                			dev->name);            			printk(KERN_WARNING "SISR=%x LISR=%x\n",                			readl(olympic_mmio+SISR),                			readl(olympic_mmio+LISR));            			olympic_priv->srb_queued=0;            			break;        		}			if ((jiffies-t) > 60*HZ) { 				printk(KERN_WARNING "%s: SRB timed out. \n",dev->name) ; 				olympic_priv->srb_queued=0;				break ; 			}     		}		restore_flags(flags);#if OLYMPIC_DEBUG		printk("init_srb(%p): ",init_srb);		for(i=0;i<20;i++)			printk("%02x ",readb(init_srb+i));		printk("\n");#endif				/* If we get the same return response as we set, the interrupt wasn't raised and the open                 * timed out.		 */		if(readb(init_srb+2)== OLYMPIC_CLEAR_RET_CODE) {			printk(KERN_WARNING "%s: Adapter Open time out or error.\n", dev->name) ; 			return -EIO ; 		}			if(readb(init_srb+2)!=0) {			if (readb(init_srb+2) == 0x07) {  				if (!olympic_priv->olympic_ring_speed && open_finished) { /* Autosense , first time around */					printk(KERN_WARNING "%s: Retrying at different ring speed \n", dev->name); 					open_finished = 0 ;  				} else {					strcpy(open_error, open_maj_error[(readb(init_srb+7) & 0xf0) >> 4]) ; 					strcat(open_error," - ") ; 					strcat(open_error, open_min_error[(readb(init_srb+7) & 0x0f)]) ;					if (!olympic_priv->olympic_ring_speed && ((readb(init_srb+7) & 0x0f) == 0x0d)) { 						printk(KERN_WARNING "%s: Tried to autosense ring speed with no monitors present\n",dev->name);						printk(KERN_WARNING "%s: Please try again with a specified ring speed \n",dev->name);						free_irq(dev->irq, dev);						return -EIO ;					}					printk(KERN_WARNING "%s: %s\n",dev->name,open_error);					free_irq(dev->irq,dev) ; 					return -EIO ;  				}	/* if autosense && open_finished */			} else {  				printk(KERN_WARNING "%s: Bad OPEN response: %x\n", dev->name,init_srb[2]);				free_irq(dev->irq, dev);				return -EIO;			} 		} else 			open_finished = 1 ; 	} while (!(open_finished)) ; /* Will only loop if ring speed mismatch re-open attempted && autosense is on */		if (readb(init_srb+18) & (1<<3)) 		if (olympic_priv->olympic_message_level) 			printk(KERN_INFO "%s: Opened in FDX Mode\n",dev->name);	if (readb(init_srb+18) & (1<<1))		olympic_priv->olympic_ring_speed = 100 ; 	else if (readb(init_srb+18) & 1)		olympic_priv->olympic_ring_speed = 16 ; 	else		olympic_priv->olympic_ring_speed = 4 ; 	if (olympic_priv->olympic_message_level) 		printk(KERN_INFO "%s: Opened in %d Mbps mode\n",dev->name, olympic_priv->olympic_ring_speed);	olympic_priv->asb = swab16(readw(init_srb+8));	olympic_priv->srb = swab16(readw(init_srb+10));	olympic_priv->arb = swab16(readw(init_srb+12));	olympic_priv->trb = swab16(readw(init_srb+16));	olympic_priv->olympic_receive_options = 0x01 ; 	olympic_priv->olympic_copy_all_options = 0 ; 		/* setup rx ring */		writel((3<<16),olympic_mmio+BMCTL_RWM); /* Ensure end of frame generated interrupts */ 	writel(BMCTL_RX_DIS|3,olympic_mmio+BMCTL_RWM); /* Yes, this the enables RX channel */	for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {		struct sk_buff *skb;				skb=dev_alloc_skb(olympic_priv->pkt_buf_sz);		if(skb == NULL)			break;		skb->dev = dev;		olympic_priv->olympic_rx_ring[i].buffer = cpu_to_le32(pci_map_single(olympic_priv->pdev, 							  skb->data,olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)) ; 		olympic_priv->olympic_rx_ring[i].res_length = cpu_to_le32(olympic_priv->pkt_buf_sz); 		olympic_priv->rx_ring_skb[i]=skb;	}	if (i==0) {		printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n",dev->name);		free_irq(dev->irq, dev);		return -EIO;	}	olympic_priv->rx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_rx_ring, 					 sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);	writel(olympic_priv->rx_ring_dma_addr, olympic_mmio+RXDESCQ);	writel(olympic_priv->rx_ring_dma_addr, olympic_mmio+RXCDA);	writew(i, olympic_mmio+RXDESCQCNT);			olympic_priv->rx_status_ring_dma_addr = pci_map_single(olympic_priv->pdev, olympic_priv->olympic_rx_status_ring, 						sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);	writel(olympic_priv->rx_status_ring_dma_addr, olympic_mmio+RXSTATQ);	writel(olympic_priv->rx_status_ring_dma_addr, olympic_mmio+RXCSA);	 	olympic_priv->rx_ring_last_received = OLYMPIC_RX_RING_SIZE - 1;	/* last processed rx status */	olympic_priv->rx_status_last_received = OLYMPIC_RX_RING_SIZE - 1;  	writew(i, olympic_mmio+RXSTATQCNT);#if OLYMPIC_DEBUG 	printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ));	printk("RXCSA: %x, rx_status_ring[0]: %p\n",readl(olympic_mmio+RXCSA),&olympic_priv->olympic_rx_status_ring[0]);	printk(" stat_ring[1]: %p, stat_ring[2]: %p, stat_ring[3]: %p\n", &(olympic_priv->olympic_rx_status_ring[1]), &(olympic_priv->olympic_rx_status_ring[2]), &(olympic_priv->olympic_rx_status_ring[3]) );	printk(" stat_ring[4]: %p, stat_ring[5]: %p, stat_ring[6]: %p\n", &(olympic_priv->olympic_rx_status_ring[4]), &(olympic_priv->olympic_rx_status_ring[5]), &(olympic_priv->olympic_rx_status_ring[6]) );	printk(" stat_ring[7]: %p\n", &(olympic_priv->olympic_rx_status_ring[7])  );	printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]);	printk("Rx_ring_dma_addr = %08x, rx_status_dma_addr =%08x\n",olympic_priv->rx_ring_dma_addr,olympic_priv->rx_status_ring_dma_addr) ; #endif	writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | i,olympic_mmio+RXENQ);#if OLYMPIC_DEBUG 	printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ));	printk("RXCSA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCSA),&olympic_priv->olympic_rx_status_ring[0]);	printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]);#endif 	writel(SISR_RX_STATUS | SISR_RX_NOBUF,olympic_mmio+SISR_MASK_SUM);	/* setup tx ring */	writel(BMCTL_TX1_DIS,olympic_mmio+BMCTL_RWM); /* Yes, this enables TX channel 1 */	for(i=0;i<OLYMPIC_TX_RING_SIZE;i++) 		olympic_priv->olympic_tx_ring[i].buffer=0xdeadbeef;	olympic_priv->free_tx_ring_entries=OLYMPIC_TX_RING_SIZE;	olympic_priv->tx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_tx_ring,					 sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE,PCI_DMA_TODEVICE) ; 	writel(olympic_priv->tx_ring_dma_addr, olympic_mmio+TXDESCQ_1);	writel(olympic_priv->tx_ring_dma_addr, olympic_mmio+TXCDA_1);	writew(OLYMPIC_TX_RING_SIZE, olympic_mmio+TXDESCQCNT_1);		olympic_priv->tx_status_ring_dma_addr = pci_map_single(olympic_priv->pdev, olympic_priv->olympic_tx_status_ring,						sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);	writel(olympic_priv->tx_status_ring_dma_addr,olympic_mmio+TXSTATQ_1);	writel(olympic_priv->tx_status_ring_dma_addr,olympic_mmio+TXCSA_1);	writew(OLYMPIC_TX_RING_SIZE,olympic_mmio+TXSTATQCNT_1);			olympic_priv->tx_ring_free=0; /* next entry in tx ring to use */	olympic_priv->tx_ring_last_status=OLYMPIC_TX_RING_SIZE-1; /* last processed tx status */	writel(SISR_TX1_EOF | SISR_ADAPTER_CHECK | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_ASB_FREE,olympic_mmio+SISR_MASK_SUM);#if OLYMPIC_DEBUG 	printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM));	printk("SISR MASK: %x\n",readl(olympic_mmio+SISR_MASK));#endif	if (olympic_priv->olympic_network_monitor) { 		u8 *oat ; 		u8 *opt ; 		oat = (u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; 		opt = (u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ; 		printk("%s: Node Address: %02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, 			readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)), 			readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+1),			readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+2),			readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+3),			readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+4),			readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+5));		printk("%s: Functional Address: %02x:%02x:%02x:%02x\n",dev->name, 			readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)), 			readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1),			readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2),			readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3));		printk("%s: NAUN Address: %02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, 			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)),			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+1),			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+2),			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+3),			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+4),			readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+5));	}		netif_start_queue(dev);	return 0;	}	/* *	When we enter the rx routine we do not know how many frames have been  *	queued on the rx channel.  Therefore we start at the next rx status *	position and travel around the receive ring until we have completed *	all the frames. * *	This means that we may process the frame before we receive the end *	of frame interrupt. This is why we always test the status instead *	of blindly processing the next frame. * *	We also remove the last 4 bytes from the packet as well, these are *	just token ring trailer info and upset protocols that don't check  *	their own length, i.e. SNA.  *	 */static void olympic_rx(struct net_device *dev){

⌨️ 快捷键说明

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