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

📄 olympic.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
#if OLYMPIC_DEBUG	printk("GPR = %x\n",readw(olympic_mmio + GPR) ) ; #endif	/* Solo has been paused to meet the Cardbus power	 * specs if the adapter is cardbus. Check to 	 * see its been paused and then restart solo. The	 * adapter should set the pause bit within 1 second.	 */	if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) { 		t=jiffies;		while (!readl(olympic_mmio+CLKCTL) & CLKCTL_PAUSE) { 			schedule() ; 			if(jiffies-t > 2*HZ) { 				printk(KERN_ERR "IBM Cardbus tokenring adapter not responsing.\n") ; 				return -ENODEV;			}		}		writel(readl(olympic_mmio+CLKCTL) & ~CLKCTL_PAUSE, olympic_mmio+CLKCTL) ; 	}		/* start solo init */	writel((1<<15),olympic_mmio+SISR_MASK_SUM);	t=jiffies;	while(!((readl(olympic_mmio+SISR_RR)) & SISR_SRB_REPLY)) {		schedule();				if(jiffies-t > 15*HZ) {			printk(KERN_ERR "IBM PCI tokenring card not responding.\n");			return -ENODEV;		}	}		writel(readw(olympic_mmio+LAPWWO),olympic_mmio+LAPA);#if OLYMPIC_DEBUG	printk("LAPWWO: %x, LAPA: %x\n",readl(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA));#endif	init_srb=olympic_priv->olympic_lap + ((readw(olympic_mmio+LAPWWO)) & (~0xf800));#if OLYMPIC_DEBUG		{	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 initialization 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 __iomem *olympic_mmio=olympic_priv->olympic_mmio,*init_srb;	unsigned long flags, t;	int i, open_finished = 1 ;	u8 resp, err;	DECLARE_WAITQUEUE(wait,current) ; 	olympic_init(dev);	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(readw(olympic_mmio+LAPWWO),olympic_mmio+LAPA);	init_srb=olympic_priv->olympic_lap + ((readw(olympic_mmio+LAPWWO)) & (~0xf800));	#if OLYMPIC_DEBUG	printk("LAPWWO: %x, LAPA: %x\n",readw(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 {		memset_io(init_srb,0,SRB_COMMAND_SIZE);		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);			/* Test OR of first 3 bytes as its totally possible for 		 * someone to set the first 2 bytes to be zero, although this 		 * is an error, the first byte must have bit 6 set to 1  */		if (olympic_priv->olympic_laa[0] | olympic_priv->olympic_laa[1] | olympic_priv->olympic_laa[2]) {			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);		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);		t = jiffies ; 			add_wait_queue(&olympic_priv->srb_wait,&wait) ;		set_current_state(TASK_INTERRUPTIBLE) ;   		while(olympic_priv->srb_queued) {        			schedule() ;         		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) > 10*HZ) { 				printk(KERN_WARNING "%s: SRB timed out. \n",dev->name) ; 				olympic_priv->srb_queued=0;				break ; 			} 			set_current_state(TASK_INTERRUPTIBLE) ;     		}		remove_wait_queue(&olympic_priv->srb_wait,&wait) ; 		set_current_state(TASK_RUNNING) ; 		olympic_priv->srb_queued = 0 ; #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.		 */		switch (resp = readb(init_srb+2)) {		case OLYMPIC_CLEAR_RET_CODE:			printk(KERN_WARNING "%s: Adapter Open time out or error.\n", dev->name) ; 			goto out;		case 0:			open_finished = 1;			break;		case 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 ;  				continue;			}			err = readb(init_srb+7);			if (!olympic_priv->olympic_ring_speed && ((err & 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);			} else {				printk(KERN_WARNING "%s: %s - %s\n", dev->name,					open_maj_error[(err & 0xf0) >> 4],					open_min_error[(err & 0x0f)]);			}			goto out;		case 0x32:			printk(KERN_WARNING "%s: Invalid LAA: %02x:%02x:%02x:%02x:%02x:%02x\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]) ; 			goto out;		default:			printk(KERN_WARNING "%s: Bad OPEN response: %x\n", dev->name, resp);			goto out;		}	} 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);		goto out;	}	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 */

⌨️ 快捷键说明

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