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

📄 tms380tr.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	int i, loop_cnt, retry_cnt;	/* Normalize: byte order low/high, word order high/low! (only IPB!) */	tp->ipb.SCB_Addr = SWAPW(((char *)&tp->scb - (char *)tp) + tp->dmabuffer);	tp->ipb.SSB_Addr = SWAPW(((char *)&tp->ssb - (char *)tp) + tp->dmabuffer);	if(tms380tr_debug > 3)	{		printk(KERN_DEBUG "%s: buffer (real): %lx\n", dev->name, (long) &tp->scb);		printk(KERN_DEBUG "%s: buffer (virt): %lx\n", dev->name, (long) ((char *)&tp->scb - (char *)tp) + (long) tp->dmabuffer);		printk(KERN_DEBUG "%s: buffer (DMA) : %lx\n", dev->name, (long) tp->dmabuffer);		printk(KERN_DEBUG "%s: buffer (tp)  : %lx\n", dev->name, (long) tp);	}	/* Maximum: three initialization retries */	retry_cnt = INIT_MAX_RETRIES;	do {		retry_cnt--;		/* Transfer initialization block */		SIFWRITEW(0x0001, SIFADX);		/* To address 0001:0A00 of adapter RAM */		SIFWRITEW(0x0A00, SIFADD);		/* Write 11 words to adapter RAM */		for(i = 0; i < 11; i++)			SIFWRITEW(ipb_ptr[i], SIFINC);		/* Execute SCB adapter command */		tms380tr_exec_sifcmd(dev, CMD_EXECUTE);		loop_cnt = INIT_MAX_LOOPCNT;	/* Maximum: 11 seconds */		/* While remaining retries, no error and not completed */		do {			Status = 0;			loop_cnt--;			tms380tr_wait(HALF_SECOND);			/* Mask interesting status bits */			Status = SIFREADW(SIFSTS);			Status &= STS_MASK;		} while(((Status &(STS_INITIALIZE | STS_ERROR | STS_TEST)) != 0)			&& ((Status & STS_ERROR) == 0) && (loop_cnt != 0));		if((Status & (STS_INITIALIZE | STS_ERROR | STS_TEST)) == 0)		{			/* Initialization completed without error */			i = 0;			do {	/* Test if contents of SCB is valid */				if(SCB_Test[i] != *(cb_ptr + i))				{					printk(KERN_INFO "%s: DMA failed\n", dev->name);					/* DMA data error: wrong data in SCB */					return (-1);				}				i++;			} while(i < 6);			i = 0;			do {	/* Test if contents of SSB is valid */				if(SSB_Test[i] != *(sb_ptr + i))					/* DMA data error: wrong data in SSB */					return (-1);				i++;			} while (i < 8);			return (1);	/* Adapter successfully initialized */		}		else		{			if((Status & STS_ERROR) != 0)			{				/* Initialization error occurred */				Status = SIFREADW(SIFSTS);				Status &= STS_ERROR_MASK;				/* ShowInitialisationErrorCode(Status); */				printk(KERN_INFO "%s: Status error: %d\n", dev->name, Status);				return (-1); /* Unrecoverable error */			}			else			{				if(retry_cnt > 0)				{					/* Reset adapter and try init again */					tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET);					tms380tr_wait(HALF_SECOND);				}			}		}	} while(retry_cnt > 0);	printk(KERN_INFO "%s: Retry exceeded\n", dev->name);	return (-1);}/* * Check for outstanding commands in command queue and tries to execute * command immediately. Corresponding command flag in command queue is cleared. */static void tms380tr_chk_outstanding_cmds(struct net_device *dev){	struct net_local *tp = netdev_priv(dev);	unsigned long Addr = 0;	if(tp->CMDqueue == 0)		return;		/* No command execution */	/* If SCB in use: no command */	if(tp->ScbInUse == 1)		return;	/* Check if adapter is opened, avoiding COMMAND_REJECT	 * interrupt by the adapter!	 */	if(tp->AdapterOpenFlag == 0)	{		if(tp->CMDqueue & OC_OPEN)		{			/* Execute OPEN command	*/			tp->CMDqueue ^= OC_OPEN;			Addr = htonl(((char *)&tp->ocpl - (char *)tp) + tp->dmabuffer);			tp->scb.Parm[0] = LOWORD(Addr);			tp->scb.Parm[1] = HIWORD(Addr);			tp->scb.CMD = OPEN;		}		else			/* No OPEN command queued, but adapter closed. Note:			 * We'll try to re-open the adapter in DriverPoll()			 */			return;		/* No adapter command issued */	}	else	{		/* Adapter is open; evaluate command queue: try to execute		 * outstanding commands (depending on priority!) CLOSE		 * command queued		 */		if(tp->CMDqueue & OC_CLOSE)		{			tp->CMDqueue ^= OC_CLOSE;			tp->AdapterOpenFlag = 0;			tp->scb.Parm[0] = 0; /* Parm[0], Parm[1] are ignored */			tp->scb.Parm[1] = 0; /* but should be set to zero! */			tp->scb.CMD = CLOSE;			if(!tp->HaltInProgress)				tp->CMDqueue |= OC_OPEN; /* re-open adapter */			else				tp->CMDqueue = 0;	/* no more commands */		}		else		{			if(tp->CMDqueue & OC_RECEIVE)			{				tp->CMDqueue ^= OC_RECEIVE;				Addr = htonl(((char *)tp->RplHead - (char *)tp) + tp->dmabuffer);				tp->scb.Parm[0] = LOWORD(Addr);				tp->scb.Parm[1] = HIWORD(Addr);				tp->scb.CMD = RECEIVE;			}			else			{				if(tp->CMDqueue & OC_TRANSMIT_HALT)				{					/* NOTE: TRANSMIT.HALT must be checked 					 * before TRANSMIT.					 */					tp->CMDqueue ^= OC_TRANSMIT_HALT;					tp->scb.CMD = TRANSMIT_HALT;					/* Parm[0] and Parm[1] are ignored					 * but should be set to zero!					 */					tp->scb.Parm[0] = 0;					tp->scb.Parm[1] = 0;				}				else				{					if(tp->CMDqueue & OC_TRANSMIT)					{						/* NOTE: TRANSMIT must be 						 * checked after TRANSMIT.HALT						 */						if(tp->TransmitCommandActive)						{							if(!tp->TransmitHaltScheduled)							{								tp->TransmitHaltScheduled = 1;								tms380tr_exec_cmd(dev, OC_TRANSMIT_HALT) ;							}							tp->TransmitCommandActive = 0;							return;						}						tp->CMDqueue ^= OC_TRANSMIT;						tms380tr_cancel_tx_queue(tp);						Addr = htonl(((char *)tp->TplBusy - (char *)tp) + tp->dmabuffer);						tp->scb.Parm[0] = LOWORD(Addr);						tp->scb.Parm[1] = HIWORD(Addr);						tp->scb.CMD = TRANSMIT;						tp->TransmitCommandActive = 1;					}					else					{						if(tp->CMDqueue & OC_MODIFY_OPEN_PARMS)						{							tp->CMDqueue ^= OC_MODIFY_OPEN_PARMS;							tp->scb.Parm[0] = tp->ocpl.OPENOptions; /* new OPEN options*/							tp->scb.Parm[0] |= ENABLE_FULL_DUPLEX_SELECTION;							tp->scb.Parm[1] = 0; /* is ignored but should be zero */							tp->scb.CMD = MODIFY_OPEN_PARMS;						}						else						{							if(tp->CMDqueue & OC_SET_FUNCT_ADDR)							{								tp->CMDqueue ^= OC_SET_FUNCT_ADDR;								tp->scb.Parm[0] = LOWORD(tp->ocpl.FunctAddr);								tp->scb.Parm[1] = HIWORD(tp->ocpl.FunctAddr);								tp->scb.CMD = SET_FUNCT_ADDR;							}							else							{								if(tp->CMDqueue & OC_SET_GROUP_ADDR)								{									tp->CMDqueue ^= OC_SET_GROUP_ADDR;									tp->scb.Parm[0] = LOWORD(tp->ocpl.GroupAddr);									tp->scb.Parm[1] = HIWORD(tp->ocpl.GroupAddr);									tp->scb.CMD = SET_GROUP_ADDR;								}								else								{									if(tp->CMDqueue & OC_READ_ERROR_LOG)									{										tp->CMDqueue ^= OC_READ_ERROR_LOG;										Addr = htonl(((char *)&tp->errorlogtable - (char *)tp) + tp->dmabuffer);										tp->scb.Parm[0] = LOWORD(Addr);										tp->scb.Parm[1] = HIWORD(Addr);										tp->scb.CMD = READ_ERROR_LOG;									}									else									{										printk(KERN_WARNING "CheckForOutstandingCommand: unknown Command\n");										tp->CMDqueue = 0;										return;									}								}							}						}					}				}			}		}	}	tp->ScbInUse = 1;	/* Set semaphore: SCB in use. */	/* Execute SCB and generate IRQ when done. */	tms380tr_exec_sifcmd(dev, CMD_EXECUTE | CMD_SCB_REQUEST);	return;}/* * IRQ conditions: signal loss on the ring, transmit or receive of beacon * frames (disabled if bit 1 of OPEN option is set); report error MAC * frame transmit (disabled if bit 2 of OPEN option is set); open or short * circuit fault on the lobe is detected; remove MAC frame received; * error counter overflow (255); opened adapter is the only station in ring. * After some of the IRQs the adapter is closed! */static void tms380tr_ring_status_irq(struct net_device *dev){	struct net_local *tp = netdev_priv(dev);	tp->CurrentRingStatus = be16_to_cpu((unsigned short)tp->ssb.Parm[0]);	/* First: fill up statistics */	if(tp->ssb.Parm[0] & SIGNAL_LOSS)	{		printk(KERN_INFO "%s: Signal Loss\n", dev->name);		tp->MacStat.line_errors++;	}	/* Adapter is closed, but initialized */	if(tp->ssb.Parm[0] & LOBE_WIRE_FAULT)	{		printk(KERN_INFO "%s: Lobe Wire Fault, Reopen Adapter\n", 			dev->name);		tp->MacStat.line_errors++;	}	if(tp->ssb.Parm[0] & RING_RECOVERY)		printk(KERN_INFO "%s: Ring Recovery\n", dev->name);	/* Counter overflow: read error log */	if(tp->ssb.Parm[0] & COUNTER_OVERFLOW)	{		printk(KERN_INFO "%s: Counter Overflow\n", dev->name);		tms380tr_exec_cmd(dev, OC_READ_ERROR_LOG);	}	/* Adapter is closed, but initialized */	if(tp->ssb.Parm[0] & REMOVE_RECEIVED)		printk(KERN_INFO "%s: Remove Received, Reopen Adapter\n", 			dev->name);	/* Adapter is closed, but initialized */	if(tp->ssb.Parm[0] & AUTO_REMOVAL_ERROR)		printk(KERN_INFO "%s: Auto Removal Error, Reopen Adapter\n", 			dev->name);	if(tp->ssb.Parm[0] & HARD_ERROR)		printk(KERN_INFO "%s: Hard Error\n", dev->name);	if(tp->ssb.Parm[0] & SOFT_ERROR)		printk(KERN_INFO "%s: Soft Error\n", dev->name);	if(tp->ssb.Parm[0] & TRANSMIT_BEACON)		printk(KERN_INFO "%s: Transmit Beacon\n", dev->name);	if(tp->ssb.Parm[0] & SINGLE_STATION)		printk(KERN_INFO "%s: Single Station\n", dev->name);	/* Check if adapter has been closed */	if(tp->ssb.Parm[0] & ADAPTER_CLOSED)	{		printk(KERN_INFO "%s: Adapter closed (Reopening)," 			"CurrentRingStat %x\n",			dev->name, tp->CurrentRingStatus);		tp->AdapterOpenFlag = 0;		tms380tr_open_adapter(dev);	}	return;}/* * Issued if adapter has encountered an unrecoverable hardware * or software error. */static void tms380tr_chk_irq(struct net_device *dev){	int i;	unsigned short AdapterCheckBlock[4];	struct net_local *tp = netdev_priv(dev);	tp->AdapterOpenFlag = 0;	/* Adapter closed now */	/* Page number of adapter memory */	SIFWRITEW(0x0001, SIFADX);	/* Address offset */	SIFWRITEW(CHECKADDR, SIFADR);	/* Reading 8 byte adapter check block. */	for(i = 0; i < 4; i++)		AdapterCheckBlock[i] = SIFREADW(SIFINC);	if(tms380tr_debug > 3)	{		printk(KERN_DEBUG "%s: AdapterCheckBlock: ", dev->name);		for (i = 0; i < 4; i++)			printk("%04X", AdapterCheckBlock[i]);		printk("\n");	}	switch(AdapterCheckBlock[0])	{		case DIO_PARITY:			printk(KERN_INFO "%s: DIO parity error\n", dev->name);			break;		case DMA_READ_ABORT:			printk(KERN_INFO "%s DMA read operation aborted:\n",				dev->name);			switch (AdapterCheckBlock[1])			{				case 0:					printk(KERN_INFO "Timeout\n");					printk(KERN_INFO "Address: %04X %04X\n",						AdapterCheckBlock[2],						AdapterCheckBlock[3]);					break;				case 1:					printk(KERN_INFO "Parity error\n");					printk(KERN_INFO "Address: %04X %04X\n",						AdapterCheckBlock[2], 						AdapterCheckBlock[3]);					break;				case 2: 					printk(KERN_INFO "Bus error\n");					printk(KERN_INFO "Address: %04X %04X\n",						AdapterCheckBlock[2], 						AdapterCheckBlock[3]);					break;				default:					printk(KERN_INFO "Unknown error.\n");					break;			}			break;		case DMA_WRITE_ABORT:			printk(KERN_INFO "%s: DMA write operation aborted: \n",				dev->name);			switch (AdapterCheckBlock[1])			{				case 0: 					printk(KERN_INFO "Timeout\n");					printk(KERN_INFO "Address: %04X %04X\n",						AdapterCheckBlock[2], 						AdapterCheckBlock[3]);					break;				case 1: 					printk(KERN_INFO "Parity error\n");					printk(KERN_INFO "Address: %04X %04X\n",						AdapterCheckBlock[2], 						AdapterCheckBlock[3]);					break;				case 2: 					printk(KERN_INFO "Bus error\n");					printk(KERN_INFO "Address: %04X %04X\n",						AdapterCheckBlock[2], 						AdapterCheckBlock[3]);					break;				default:					printk(KERN_INFO "Unknown error.\n");					break;			}			break;		case ILLEGAL_OP_CODE:			printk(KERN_INFO "%s: Illegal operation code in firmware\n",				dev->name);			/* Parm[0-3]: adapter internal register R13-R15 */			break;		case PARITY_ERRORS:			printk(KERN_INFO "%s: Adapter internal bus parity error\n",				dev->name);			/* Parm[0-3]: adapter internal register R13-R15 */			break;		case RAM_DATA_ERROR:			printk(KERN_INFO "%s: RAM data error\n", dev->name);			/* Parm[0-1]: MSW/LSW address of RAM location. */			break;		case RAM_PARITY_ERROR:			printk(KERN_INFO "%s: RAM parity error\n", dev->name);			/* Parm[0-1]: MSW/LSW address of RAM location. */			break;		case RING_UNDERRUN:			printk(KERN_INFO "%s: Internal DMA underrun detected\n",				dev->name);			break;		case INVALID_IRQ:			printk(KERN_INFO "%s: Unrecognized interrupt detected\n",				dev->name);			/* Parm[0-3]: adapter internal register R13-R15 */			break;		case INVALID_ERROR_IRQ:			printk(KERN_INFO "%s: Unrecognized error interrupt detected\n",				dev->name);			/* Parm[0-3]: adapter internal register R13-R15 */			break;		case INVALID_XOP:			printk(KERN_INFO "%s: Unrecognized XOP request detected\n",				dev->name);

⌨️ 快捷键说明

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