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

📄 skge.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 5 页
字号:
	return (0);} /* SkGeOpen *//**************************************************************************** * *	SkGeClose - Stop initialized adapter * * Description: *	Close initialized adapter. * * Returns: *	0 - on success *	error code - on error */#if 0static int SkGeClose(#elseint SkGeClose(#endifstruct SK_NET_DEVICE	*dev){	DEV_NET			*pNet;	SK_AC			*pAC;	unsigned long	Flags;		/* for spin lock */	int				i;	int				PortIdx;	SK_EVPARA		EvPara;	netif_stop_queue(dev);	pNet = (DEV_NET*) dev->priv;	pAC = pNet->pAC;	if (pAC->RlmtNets == 1)		PortIdx = pAC->ActivePort;	else		PortIdx = pNet->NetNr;	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,		("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));	/*	 * Clear multicast table, promiscuous mode ....	 */	SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);	SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,		SK_PROM_MODE_NONE);	if (pAC->MaxPorts == 1) {		spin_lock_irqsave(&pAC->SlowPathLock, Flags);		/* disable interrupts */		SK_OUT32(pAC->IoBase, B0_IMSK, 0);		EvPara.Para32[0] = pNet->NetNr;		EvPara.Para32[1] = -1;		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);		SkEventDispatcher(pAC, pAC->IoBase);		SK_OUT32(pAC->IoBase, B0_IMSK, 0);		/* stop the hardware */		SkGeDeInit(pAC, pAC->IoBase);		pAC->BoardLevel = 0;		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);	} else {		spin_lock_irqsave(&pAC->SlowPathLock, Flags);		EvPara.Para32[0] = pNet->NetNr;		EvPara.Para32[1] = -1;		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);		SkEventDispatcher(pAC, pAC->IoBase);		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);		/* Stop port */		spin_lock_irqsave(&pAC->TxPort[pNet->PortNr]			[TX_PRIO_LOW].TxDesRingLock, Flags);		SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,			SK_STOP_ALL, SK_HARD_RST);		spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr]			[TX_PRIO_LOW].TxDesRingLock, Flags);	}	if (pAC->RlmtNets == 1) {		/* clear all descriptor rings */		for (i=0; i<pAC->GIni.GIMacsFound; i++) {			ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);			ClearRxRing(pAC, &pAC->RxPort[i]);			ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);		}	} else {		/* clear port descriptor rings */		ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE);		ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);		ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);	}	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,		("SkGeClose: done "));	pAC->MaxPorts--;	pNet->Up = 0;	MOD_DEC_USE_COUNT;	return (0);} /* SkGeClose *//***************************************************************************** * * 	SkGeXmit - Linux frame transmit function * * Description: *	The system calls this function to send frames onto the wire. *	It puts the frame in the tx descriptor ring. If the ring is *	full then, the 'tbusy' flag is set. * * Returns: *	0, if everything is ok *	!=0, on error * WARNING: returning 1 in 'tbusy' case caused system crashes (double *	allocated skb's) !!! */#if 0static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev)#elseint SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev)#endif{DEV_NET		*pNet;SK_AC		*pAC;int			Rc;	/* return code of XmitFrame */	pNet = (DEV_NET*) dev->priv;	pAC = pNet->pAC;#if 0	if ((!skb_shinfo(skb)->nr_frags) ||#else	if (1 ||#endif		(pAC->GIni.GIChipId == CHIP_ID_GENESIS)) {		/* Don't activate scatter-gather and hardware checksum */		if (pAC->RlmtNets == 2)			Rc = XmitFrame(				pAC,				&pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],				skb);		else			Rc = XmitFrame(				pAC,				&pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],				skb);	} else {#if 0		/* scatter-gather and hardware TCP checksumming anabled*/		if (pAC->RlmtNets == 2)			Rc = XmitFrameSG(				pAC,				&pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],				skb);		else			Rc = XmitFrameSG(				pAC,				&pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],				skb);#endif	}	/* Transmitter out of resources? */	if (Rc <= 0) {		netif_stop_queue(dev);	}	/* If not taken, give buffer ownership back to the	 * queueing layer.	 */	if (Rc < 0)		return (1);#if 0	dev->trans_start = jiffies;#endif	return (0);} /* SkGeXmit *//***************************************************************************** * * 	XmitFrame - fill one socket buffer into the transmit ring * * Description: *	This function puts a message into the transmit descriptor ring *	if there is a descriptors left. *	Linux skb's consist of only one continuous buffer. *	The first step locks the ring. It is held locked *	all time to avoid problems with SWITCH_../PORT_RESET. *	Then the descriptoris allocated. *	The second part is linking the buffer to the descriptor. *	At the very last, the Control field of the descriptor *	is made valid for the BMU and a start TX command is given *	if necessary. * * Returns: *	> 0 - on succes: the number of bytes in the message *	= 0 - on resource shortage: this frame sent or dropped, now *		the ring is full ( -> set tbusy) *	< 0 - on failure: other problems ( -> return failure to upper layers) */static int XmitFrame(SK_AC 		*pAC,		/* pointer to adapter context */TX_PORT		*pTxPort,	/* pointer to struct of port to send to */struct sk_buff	*pMessage)	/* pointer to send-message */{TXD		*pTxd;		/* the rxd to fill */unsigned long	Flags;SK_U64		PhysAddr;int		BytesSend;	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,		("X"));	spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);#ifndef USE_TX_COMPLETE	FreeTxDescriptors(pAC, pTxPort);#endif	if (pTxPort->TxdRingFree == 0) {		/* no enough free descriptors in ring at the moment */		FreeTxDescriptors(pAC, pTxPort);		if (pTxPort->TxdRingFree == 0) {			spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);			SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,				SK_DBGCAT_DRV_TX_PROGRESS,				("XmitFrame failed\n"));			/* this message can not be sent now */			/* Because tbusy seems to be set, the message should not be freed here */			/* It will be used by the scheduler of the ethernet handler */			return (-1);		}	}	/* advance head counter behind descriptor needed for this frame */	pTxd = pTxPort->pTxdRingHead;	pTxPort->pTxdRingHead = pTxd->pNextTxd;	pTxPort->TxdRingFree--;	/* the needed descriptor is reserved now */	/*	 * everything allocated ok, so add buffer to descriptor	 */#ifdef SK_DUMP_TX	DumpMsg(pMessage, "XmitFrame");#endif	/* set up descriptor and CONTROL dword */#if 0	PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,		virt_to_page(pMessage->data),		((unsigned long) pMessage->data &		~PAGE_MASK),		pMessage->len,		PCI_DMA_TODEVICE);#else	PhysAddr = (SK_U64) pci_phys_to_mem(pAC->PciDev, (u32) pMessage->data);#endif	pTxd->VDataLow = (SK_U32)  (PhysAddr & 0xffffffff);	pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);	pTxd->pMBuf = pMessage;	pTxd->TBControl = TX_CTRL_OWN_BMU | TX_CTRL_STF |		TX_CTRL_CHECK_DEFAULT | TX_CTRL_SOFTWARE |#ifdef USE_TX_COMPLETE		TX_CTRL_EOF | TX_CTRL_EOF_IRQ | pMessage->len;#else		TX_CTRL_EOF | pMessage->len;#endif	if ((pTxPort->pTxdRingPrev->TBControl & TX_CTRL_OWN_BMU) == 0) {		/* previous descriptor already done, so give tx start cmd */		/* StartTx(pAC, pTxPort->HwAddr); */		SK_OUT8(pTxPort->HwAddr, TX_Q_CTRL, TX_Q_CTRL_START);	}	pTxPort->pTxdRingPrev = pTxd;	BytesSend = pMessage->len;	spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);	/* after releasing the lock, the skb may be immidiately freed */	if (pTxPort->TxdRingFree != 0)		return (BytesSend);	else		return (0);} /* XmitFrame *//***************************************************************************** * * 	XmitFrameSG - fill one socket buffer into the transmit ring *                (use SG and TCP/UDP hardware checksumming) * * Description: *	This function puts a message into the transmit descriptor ring *	if there is a descriptors left. * * Returns: *	> 0 - on succes: the number of bytes in the message *	= 0 - on resource shortage: this frame sent or dropped, now *		the ring is full ( -> set tbusy) *	< 0 - on failure: other problems ( -> return failure to upper layers) */#if 0static int XmitFrameSG(SK_AC 		*pAC,			/* pointer to adapter context */TX_PORT		*pTxPort,		/* pointer to struct of port to send to */struct sk_buff	*pMessage)	/* pointer to send-message */{	int 		i;	int			BytesSend;	int			hlength;	int			protocol;	skb_frag_t		*sk_frag;	TXD			*pTxd;	TXD			*pTxdFst;	TXD			*pTxdLst;	SK_U64		PhysAddr;	unsigned long	Flags;	spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);#ifndef USE_TX_COMPLETE	FreeTxDescriptors(pAC, pTxPort);#endif	if ((skb_shinfo(pMessage)->nr_frags +1) > pTxPort->TxdRingFree) {		FreeTxDescriptors(pAC, pTxPort);		if ((skb_shinfo(pMessage)->nr_frags + 1) > pTxPort->TxdRingFree) {			spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);			SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);			SK_DBG_MSG(NULL, SK_DBGMOD_DRV,				SK_DBGCAT_DRV_TX_PROGRESS,				("XmitFrameSG failed - Ring full\n"));				/* this message can not be sent now */			return(-1);		}	}	pTxd = pTxPort->pTxdRingHead;	pTxdFst = pTxd;	pTxdLst = pTxd;	BytesSend = 0;	protocol = 0;	/* map first fragment (header) */	PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,			virt_to_page(pMessage->data),			((unsigned long) pMessage->data & ~PAGE_MASK),			skb_headlen(pMessage),			PCI_DMA_TODEVICE);	pTxd->VDataLow = (SK_U32)  (PhysAddr & 0xffffffff);	pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);	/* HW checksum? */	if (pMessage->ip_summed == CHECKSUM_HW) {		pTxd->TBControl = TX_CTRL_STF |				  TX_CTRL_ST_FWD |				  skb_headlen(pMessage);		/* We have to use the opcode for tcp here because the opcode for		udp is not working in the hardware yet (revision 2.0)*/		protocol = ((SK_U8)pMessage->data[23] & 0xf);		if ((protocol == 17) && (pAC->GIni.GIChipRev != 0))			pTxd->TBControl |=  BMU_UDP_CHECK;		else			pTxd->TBControl |= BMU_TCP_CHECK ;		hlength = ((SK_U8)pMessage->data[14] & 0xf) * 4;		pTxd->TcpSumOfs = 0; /* PH-Checksum already claculated */		pTxd->TcpSumSt = 14+hlength+16;		pTxd->TcpSumWr = 14+hlength;	} else {		pTxd->TBControl = TX_CTRL_CHECK_DEFAULT |				  TX_CTRL_SOFTWARE |				  TX_CTRL_STF |				  skb_headlen(pMessage);	}	pTxd = pTxd->pNextTxd;	pTxPort->TxdRingFree--;	BytesSend += skb_headlen(pMessage);	/* Map SG fragments */	for (i = 0; i < skb_shinfo(pMessage)->nr_frags; i++) {		sk_frag = &skb_shinfo(pMessage)->frags[i];		/* we already have the proper value in entry */		PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,						 sk_frag->page,						 sk_frag->page_offset,						 sk_frag->size,						 PCI_DMA_TODEVICE);		pTxd->VDataLow = (SK_U32)  (PhysAddr & 0xffffffff);		pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);		pTxd->pMBuf = pMessage;		/* HW checksum */		if (pMessage->ip_summed == CHECKSUM_HW) {			pTxd->TBControl = TX_CTRL_OWN_BMU |					  TX_CTRL_SOFTWARE |					  TX_CTRL_ST_FWD;			/* We have to use the opcode for tcp here because the opcode for			udp is not working in the hardware yet (revision 2.0)*/			if ((protocol == 17) && (pAC->GIni.GIChipRev != 0))				pTxd->TBControl |= BMU_UDP_CHECK ;			else				pTxd->TBControl |= BMU_TCP_CHECK ;		} else {			pTxd->TBControl = TX_CTRL_CHECK_DEFAULT |					  TX_CTRL_SOFTWARE |					  TX_CTRL_OWN_BMU;		}		/* Last fragment  */		if( (i+1) == skb_shinfo(pMessage)->nr_frags )  {#ifdef USE_TX_COMPLETE			pTxd->TBControl |= TX_CTRL_EOF |					   TX_CTRL_EOF_IRQ |					   sk_frag->size;#else			pTxd->TBControl |= TX_CTRL_EOF |					   sk_frag->size;#endif			pTxdFst->TBControl |= TX_CTRL_OWN_BMU |					      TX_CTRL_SOFTWARE;		} else {			pTxd->TBControl |= sk_frag->size;		}		pTxdLst = pTxd;		pTxd = pTxd->pNextTxd;		pTxPort->TxdRingFree--;		BytesSend += sk_frag->size;	}	if ((pTxPort->pTxdRingPrev->TBControl & TX_CTRL_OWN_BMU) == 0) {		/* previous descriptor already done, so give tx start cmd */		/* StartTx(pAC, pTxPort->HwAddr); */		SK_OUT8(pTxPort->HwAddr, TX_Q_CTRL, TX_Q_CTRL_START);	}	pTxPort->pTxdRingPrev = pTxdLst;	pTxPort->pTxdRingHead = pTxd;	spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);	if (pTxPort->TxdRingFree > 0)		return (BytesSend);	else		return (0);}#endifvoid dump_frag( SK_U8 *data, int length){	int i;	printk("Length: %d\n", length);	for( i=0;

⌨️ 快捷键说明

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