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

📄 sktr.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	if(sktr_debug > 3)	{		printk("%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("%s: Illegal operation code in firmware\n",				dev->name);			/* Parm[0-3]: adapter internal register R13-R15 */			break;		case PARITY_ERRORS:			printk("%s: Adapter internal bus parity error\n",				dev->name);			/* Parm[0-3]: adapter internal register R13-R15 */			break;		case RAM_DATA_ERROR:			printk("%s: RAM data error\n", dev->name);			/* Parm[0-1]: MSW/LSW address of RAM location. */			break;		case RAM_PARITY_ERROR:			printk("%s: RAM parity error\n", dev->name);			/* Parm[0-1]: MSW/LSW address of RAM location. */			break;		case RING_UNDERRUN:			printk("%s: Internal DMA underrun detected\n",				dev->name);			break;		case INVALID_IRQ:			printk("%s: Unrecognized interrupt detected\n",				dev->name);			/* Parm[0-3]: adapter internal register R13-R15 */			break;		case INVALID_ERROR_IRQ:			printk("%s: Unrecognized error interrupt detected\n",				dev->name);			/* Parm[0-3]: adapter internal register R13-R15 */			break;		case INVALID_XOP:			printk("%s: Unrecognized XOP request detected\n",				dev->name);			/* Parm[0-3]: adapter internal register R13-R15 */			break;		default:			printk("%s: Unknown status", dev->name);			break;	}	if(sktr_chipset_init(dev) == 1)	{		/* Restart of firmware successful */		tp->AdapterOpenFlag = 1;	}	return;}/* * Internal adapter pointer to RAM data are copied from adapter into * host system. */static void sktr_read_ptr(struct device *dev){	struct net_local *tp = (struct net_local *)dev->priv;	unsigned short adapterram;	sktr_read_ram(dev, (unsigned char *)&tp->intptrs.BurnedInAddrPtr,			ADAPTER_INT_PTRS, 16);	sktr_read_ram(dev, (unsigned char *)&adapterram,			(unsigned short)SWAPB(tp->intptrs.AdapterRAMPtr), 2);	printk(KERN_INFO "%s: Adapter RAM size: %d K\n", 		dev->name, SWAPB(adapterram));	return;}/* * Reads a number of bytes from adapter to system memory. */static void sktr_read_ram(struct device *dev, unsigned char *Data,				unsigned short Address, int Length){	int i;	unsigned short old_sifadx, old_sifadr, InWord;	unsigned short ioaddr = dev->base_addr;	/* Save the current values */	old_sifadx = inw(ioaddr + SIFADX);	old_sifadr = inw(ioaddr + SIFADR);	/* Page number of adapter memory */	outw(0x0001, ioaddr + SIFADX);	/* Address offset in adapter RAM */	outw(Address, ioaddr + SIFADR);	/* Copy len byte from adapter memory to system data area. */	i = 0;	for(;;)	{		InWord = inw(ioaddr + SIFINC);		*(Data + i) = HIBYTE(InWord);	/* Write first byte */		if(++i == Length)		/* All is done break */			break;		*(Data + i) = LOBYTE(InWord);	/* Write second byte */		if (++i == Length)		/* All is done break */			break;	}	/* Restore original values */	outw(old_sifadx, ioaddr + SIFADX);	outw(old_sifadr, ioaddr + SIFADR);	return;}/* * Reads MAC address from adapter ROM. */static void sktr_read_addr(struct device *dev, unsigned char *Address){	int i, In;	unsigned short ioaddr = dev->base_addr;	/* Address: 0000:0000 */	outw(0, ioaddr + SIFADX);	outw(0, ioaddr + SIFADR);	/* Read six byte MAC address data */	for(i = 0; i < 6; i++)	{		In = inw(ioaddr + SIFINC);		*(Address + i) = (unsigned char)(In >> 8);	}	return;}/* * Cancel all queued packets in the transmission queue. */static void sktr_cancel_tx_queue(struct net_local* tp){	TPL *tpl;	struct sk_buff *skb;	/*	 * NOTE: There must not be an active TRANSMIT command pending, when	 * this function is called.	 */	if(tp->TransmitCommandActive)		return;	for(;;)	{		tpl = tp->TplBusy;		if(!tpl->BusyFlag)			break;		/* "Remove" TPL from busy list. */		tp->TplBusy = tpl->NextTPLPtr;		sktr_write_tpl_status(tpl, 0);	/* Clear VALID bit */		tpl->BusyFlag = 0;		/* "free" TPL */		printk(KERN_INFO "Cancel tx (%08lXh).\n", (unsigned long)tpl);		dev_kfree_skb(tpl->Skb);	}	for(;;)	{		skb = skb_dequeue(&tp->SendSkbQueue);		if(skb == NULL)			break;		tp->QueueSkb++;		dev_kfree_skb(skb);	}	return;}/* * This function is called whenever a transmit interrupt is generated by the * adapter. For a command complete interrupt, it is checked if we have to * issue a new transmit command or not. */static void sktr_tx_status_irq(struct device *dev){	struct net_local *tp = (struct net_local *)dev->priv;	unsigned char HighByte, HighAc, LowAc;	TPL *tpl;	/* NOTE: At this point the SSB from TRANSMIT STATUS is no longer	 * available, because the CLEAR SSB command has already been issued.	 *	 * Process all complete transmissions.	 */	for(;;)	{		tpl = tp->TplBusy;		if(!tpl->BusyFlag || (tpl->Status			& (TX_VALID | TX_FRAME_COMPLETE))			!= TX_FRAME_COMPLETE)		{			break;		}		/* "Remove" TPL from busy list. */		tp->TplBusy = tpl->NextTPLPtr ;		if(sktr_debug > 3)			sktr_dump(tpl->MData, SWAPB(tpl->FrameSize));		/* Check the transmit status field only for directed frames*/		if(DIRECTED_FRAME(tpl) && (tpl->Status & TX_ERROR) == 0)		{			HighByte = GET_TRANSMIT_STATUS_HIGH_BYTE(tpl->Status);			HighAc   = GET_FRAME_STATUS_HIGH_AC(HighByte);			LowAc    = GET_FRAME_STATUS_LOW_AC(HighByte);			if((HighAc != LowAc) || (HighAc == AC_NOT_RECOGNIZED))			{				printk(KERN_INFO "%s: (DA=%08lX not recognized)",					dev->name,					*(unsigned long *)&tpl->MData[2+2]);			}			else			{				if(sktr_debug > 3)					printk("%s: Directed frame tx'd\n", 						dev->name);			}		}		else		{			if(!DIRECTED_FRAME(tpl))			{				if(sktr_debug > 3)					printk("%s: Broadcast frame tx'd\n",						dev->name);			}		}                tp->MacStat.tx_packets++;		dev_kfree_skb(tpl->Skb);		tpl->BusyFlag = 0;	/* "free" TPL */	}	dev->tbusy = 0;	if(tp->QueueSkb < MAX_TX_QUEUE)		sktr_hardware_send_packet(dev, tp);	return;}/* * Called if a frame receive interrupt is generated by the adapter. * Check if the frame is valid and indicate it to system. */static void sktr_rcv_status_irq(struct device *dev){	struct net_local *tp = (struct net_local *)dev->priv;	unsigned char *ReceiveDataPtr;	struct sk_buff *skb;	unsigned int Length, Length2;	RPL *rpl;	RPL *SaveHead;	/* NOTE: At this point the SSB from RECEIVE STATUS is no longer	 * available, because the CLEAR SSB command has already been issued.	 *	 * Process all complete receives.	 */	for(;;)	{		rpl = tp->RplHead;		if(rpl->Status & RX_VALID)			break;		/* RPL still in use by adapter */		/* Forward RPLHead pointer to next list. */		SaveHead = tp->RplHead;		tp->RplHead = rpl->NextRPLPtr;		/* Get the frame size (Byte swap for Intel).		 * Do this early (see workaround comment below)		 */		Length = (unsigned short)SWAPB(rpl->FrameSize);		/* Check if the Frame_Start, Frame_End and		 * Frame_Complete bits are set.		 */		if((rpl->Status & VALID_SINGLE_BUFFER_FRAME)			== VALID_SINGLE_BUFFER_FRAME)		{			ReceiveDataPtr = rpl->MData;			/* Workaround for delayed write of FrameSize on ISA			 * (FrameSize is false but valid-bit is reset)			 * Frame size is set to zero when the RPL is freed.			 * Length2 is there because there have also been			 * cases where the FrameSize was partially written			 */			Length2 = (unsigned short)SWAPB(rpl->FrameSize);			if(Length == 0 || Length != Length2)			{				tp->RplHead = SaveHead;				break;	/* Return to sktr_interrupt */			}			/* Drop frames sent by myself */			if(sktr_chk_frame(dev, rpl->MData))			{				printk(KERN_INFO "%s: Received my own frame\n",					dev->name);				if(rpl->Skb != NULL)					dev_kfree_skb(rpl->Skb);			}			else			{				sktr_update_rcv_stats(tp,ReceiveDataPtr,Length);				if(sktr_debug > 3)					printk("%s: Packet Length %04X (%d)\n",						dev->name, Length, Length);				/* Indicate the received frame to system the				 * adapter does the Source-Routing padding for 				 * us. See: OpenOptions in sktr_init_opb()				 */				skb = rpl->Skb;				if(rpl->SkbStat == SKB_UNAVAILABLE)				{					/* Try again to allocate skb */					skb = dev_alloc_skb(tp->MaxPacketSize);					if(skb == NULL)					{						/* Update Stats ?? */					}					else					{						skb->dev	= dev;						skb_put(skb, tp->MaxPacketSize);						rpl->SkbStat 	= SKB_DATA_COPY;						ReceiveDataPtr 	= rpl->MData;					}				}				if(rpl->SkbStat == SKB_DATA_COPY					|| rpl->SkbStat == SKB_DMA_DIRECT)				{					if(rpl->SkbStat == SKB_DATA_COPY)					{						memmove(skb->data, ReceiveDataPtr, Length);					}					/* Deliver frame to system */					rpl->Skb = NULL;					skb_trim(skb,Length);					skb->protocol = tr_type_trans(skb,dev);					netif_rx(skb);				}			}		}		else	/* Invalid frame */		{			if(rpl->Skb != NULL)				dev_kfree_skb(rpl->Skb);			/* Skip list. */			if(rpl->Status & RX_START_FRAME)				/* Frame start bit is set -> overflow. */				tp->MacStat.rx_errors++;		}		/* Allocate new skb for rpl */		rpl->Skb = dev_alloc_skb(tp->MaxPacketSize);		/* skb == NULL ? then use local buffer */		if(rpl->Skb == NULL)		{			rpl->SkbStat = SKB_UNAVAILABLE;			rpl->FragList[0].DataAddr = htonl(virt_to_bus(tp->LocalRxBuffers[rpl->RPLIndex]));			rpl->MData = tp->LocalRxBuffers[rpl->RPLIndex];		}		else	/* skb != NULL */		{			rpl->Skb->dev = dev;			skb_put(rpl->Skb, tp->MaxPacketSize);			/* Data unreachable for DMA ? then use local buffer */			if(virt_to_bus(rpl->Skb->data) + tp->MaxPacketSize				> ISA_MAX_ADDRESS)			{				rpl->SkbStat = SKB_DATA_COPY;				rpl->FragList[0].DataAddr = htonl(virt_to_bus(tp->LocalRxBuffers[rpl->RPLIndex]));				rpl->MData = tp->LocalRxBuffers[rpl->RPLIndex];			}			else			{				/* DMA directly in skb->data */				rpl->SkbStat = SKB_DMA_DIRECT;				rpl->FragList[0].DataAddr = htonl(virt_to_bus(rpl->Skb->data));				rpl->MData = rpl->Skb->data;			}		}		rpl->FragList[0].DataCount = SWAPB(tp->MaxPacketSize);		rpl->FrameSize = 0;		/* Pass the last RPL back to the adapter */		tp->RplTail->FrameSize = 0;		/* Reset the CSTAT field in the list. */		sktr_write_rpl_status(tp->RplTail, RX_VALID | RX_FRAME_IRQ);		/* Current RPL becomes last one in list. */		tp->RplTail = tp->RplTail->NextRPLPtr;		/* Inform adapter about RPL valid. */		sktr_exec_sifcmd(dev, CMD_RX_VALID);	}	return;}/* * This function should be used whenever the status of any RPL must be * modified by the driver, because the compile

⌨️ 快捷键说明

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