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

📄 drivers_net_arm_ep93xx_eth_c_diff.htm

📁 linux2.6.11.6drivers_net_arm_ep93xx_eth_c
💻 HTM
📖 第 1 页 / 共 5 页
字号:
+	_PRTK_INFO(("devQue_init(): Rx Descriptor Queue at 0x%p(Phy0x%x), %d entries\n", pP->s.pQueRxDesc, (unsigned int)pP->s.phyQueRxDesc, LEN_QueRxDesc));
+	_PRTK_INFO(("devQue_init(): Rx Status Queue at 0x%p(Phy0x%x), %d entries\n", pP->s.pQueRxSts, (unsigned int)pP->s.phyQueRxSts, LEN_QueRxSts));
+	_PRTK_INFO(("devQue_init(): Tx Descriptor Queue at 0x%p(Phy0x%x), %d entries\n", pP->s.pQueTxDesc, (unsigned int)pP->s.phyQueTxDesc, LEN_QueTxDesc));
+	_PRTK_INFO(("devQue_init(): Tx Status Queue at 0x%p(Phy0x%x), %d entries\n", pP->s.pQueTxSts, (unsigned int)pP->s.phyQueTxSts, LEN_QueTxSts));
+
+	/*
+	   init queue entries
+	 */
+	memset(pP->s.pQueRxDesc, 0,
+	       sizeof(union receiveDescriptor) * LEN_QueRxDesc);
+	memset(pP->s.pQueRxSts, 0, sizeof(union receiveStatus) * LEN_QueRxSts);
+	memset(pP->s.pQueTxDesc, 0,
+	       sizeof(union transmitDescriptor) * LEN_QueTxDesc);
+	memset(pP->s.pQueTxSts, 0, sizeof(union transmitStatus) * LEN_QueTxSts);
+
+	/*Allocate Rx Buffer
+	   (We might need to copy from Rx buf to skbuff in whatever case,
+	   because device bus master requires 32bit aligned Rx buffer address 
+	   but Linux network stack requires odd 16bit aligned Rx buf address) */
+	pP->s.pRxBuf =
+	    MALLOC_DMA(((LEN_RxBuf + 3) & ~0x03) * LEN_QueRxDesc,
+		       &pP->s.phyRxBuf);
+	if (!pP->s.pRxBuf) {
+		/*@ */
+		pP->s.pRxBuf = NULL;
+		_PRTK_SYSFAIL(("devQue_init(): fail to allocate memory for RxBuf\n"));
+		return -1;
+	}
+
+	/*if */
+	/*
+	   allocate kernel memory for buffer descriptors
+	 */
+	size =
+	    sizeof(struct bufferDescriptor) * (LEN_QueRxDesc + LEN_QueTxDesc);
+	pBuf = kmalloc(size, GFP_KERNEL);
+	if (!pBuf) {
+		_PRTK_SYSFAIL(("devQue_initAll(): fail to allocate memory for buf desc\n"));
+		return -1;
+	}			/*if */
+	memset(pBuf, 0x0, size);	/*clear with 0 */
+	pP->s.pRxBufDesc = pBuf;
+	pP->s.pTxBufDesc =
+	    pBuf + sizeof(struct bufferDescriptor) * LEN_QueRxDesc;
+
+	return 0;
+}				/*devQue_init() */
+
+#ifndef _PRTK_DUMP
+# define _dbg_ep9312eth_dumpReg(pD)
+#else
+/*****************************************************************************
+* _dbg_ep9312eth_dumpReg()
+*****************************************************************************/
+static void _dbg_ep9312eth_dumpReg(struct net_device *pD)
+{
+
+	_PRTK_DUMP(("Dumping registers of Ethernet Module Embedded within EP9312\n"));
+	_PRTK_DUMP((" pD:0x%p, Base Address:0x%x\n", pD,
+		    (unsigned int)pD->base_addr));
+
+	_PRTK_DUMP((" RxCTL:0x%08x  TxCTL:0x%08x  TestCTL:0x%08x\n",
+		    (unsigned int)RegRd32(REG_RxCTL),
+		    (unsigned int)RegRd32(REG_TxCTL),
+		    (unsigned int)RegRd32(REG_TestCTL)));
+	_PRTK_DUMP((" SelfCTL:0x%08x  IntEn:0x%08x  IntStsP:0x%08x\n",
+		    (unsigned int)RegRd32(REG_SelfCTL),
+		    (unsigned int)RegRd32(REG_IntEn),
+		    (unsigned int)RegRd32(REG_IntStsP)));
+	_PRTK_DUMP((" GT:0x%08x  FCT:0x%08x  FCF:0x%08x\n",
+		    (unsigned int)RegRd32(REG_GT),
+		    (unsigned int)RegRd32(REG_FCT),
+		    (unsigned int)RegRd32(REG_FCF)));
+	_PRTK_DUMP((" AFP:0x%08x\n", (unsigned int)RegRd32(REG_AFP)));
+	_PRTK_DUMP((" TxCollCnt:0x%08x  RxMissCnt:0x%08x  RxRntCnt:0x%08x\n",
+		    (unsigned int)RegRd32(REG_TxCollCnt),
+		    (unsigned int)RegRd32(REG_RxMissCnt),
+		    (unsigned int)RegRd32(REG_RxRntCnt)));
+	_PRTK_DUMP((" BMCtl:0x%08x  BMSts:0x%08x\n",
+		    (unsigned int)RegRd32(REG_BMCtl),
+		    (unsigned int)RegRd32(REG_BMSts)));
+	_PRTK_DUMP((" RBCA:0x%08x  TBCA:0x%08x\n",
+		    (unsigned int)RegRd32(REG_RBCA),
+		    (unsigned int)RegRd32(REG_TBCA)));
+	_PRTK_DUMP((" RxDBA:0x%08x  RxDBL/CL:0x%08x  RxDCA:0x%08x\n",
+		    (unsigned int)RegRd32(REG_RxDBA),
+		    (unsigned int)RegRd32(REG_RxDBL),
+		    (unsigned int)RegRd32(REG_RxDCA)));
+	_PRTK_DUMP((" RxSBA:0x%08x  RxSBL/CL:0x%08x  RxSCA:0x%08x\n",
+		    (unsigned int)RegRd32(REG_RxSBA),
+		    (unsigned int)RegRd32(REG_RxSBL),
+		    (unsigned int)RegRd32(REG_RxSCA)));
+	_PRTK_DUMP((" RxDEQ:0x%08x  RxSEQ:0x%08x\n",
+		    (unsigned int)RegRd32(REG_RxDEQ),
+		    (unsigned int)RegRd32(REG_RxSEQ)));
+	_PRTK_DUMP((" TxDBA:0x%08x  TxDBL/CL:0x%08x  TxDCA:0x%08x\n",
+		    (unsigned int)RegRd32(REG_TxDBA),
+		    (unsigned int)RegRd32(REG_TxDBL),
+		    (unsigned int)RegRd32(REG_TxDCA)));
+	_PRTK_DUMP((" TxSBA:0x%08x  TxSBL/CL:0x%08x  TxSCA:0x%08x\n",
+		    (unsigned int)RegRd32(REG_TxSBA),
+		    (unsigned int)RegRd32(REG_TxSBL),
+		    (unsigned int)RegRd32(REG_TxSCA)));
+	_PRTK_DUMP((" TxDEQ:0x%08x\n", (unsigned int)RegRd32(REG_TxDEQ)));
+	_PRTK_DUMP((" RxBTH:0x%08x  TxBTH:0x%08x  RxSTH:0x%08x\n",
+		    (unsigned int)RegRd32(REG_RxBTH),
+		    (unsigned int)RegRd32(REG_TxBTH),
+		    (unsigned int)RegRd32(REG_RxSTH)));
+	_PRTK_DUMP((" TxSTH:0x%08x  RxDTH:0x%08x  TxDTH:0x%08x\n",
+		    (unsigned int)RegRd32(REG_TxSTH),
+		    (unsigned int)RegRd32(REG_RxDTH),
+		    (unsigned int)RegRd32(REG_TxDTH)));
+	_PRTK_DUMP((" MaxFL:0x%08x  RxHL:0x%08x\n",
+		    (unsigned int)RegRd32(REG_MaxFL),
+		    (unsigned int)RegRd32(REG_RxHL)));
+	_PRTK_DUMP((" MACCFG0-3:0x%08x 0x%08x 0x%08x 0x%08x\n",
+		    (unsigned int)RegRd32(REG_MACCFG0),
+		    (unsigned int)RegRd32(REG_MACCFG1),
+		    (unsigned int)RegRd32(REG_MACCFG2),
+		    (unsigned int)RegRd32(REG_MACCFG3)));
+/*
+    _PRTK_DUMP((" ---INT Controller Reg---\n"));
+    _PRTK_DUMP((" RawIrqSts :0x%08x 0x%08x\n",_RegRd(u32,0x80800004),_RegRd(u32,0x80800018)));
+    _PRTK_DUMP((" IrqMask   :0x%08x 0x%08x\n",_RegRd(u32,0x80800008),_RegRd(u32,0x8080001c)));
+    _PRTK_DUMP((" MaskIrqSts:0x%08x 0x%08x\n",_RegRd(u32,0x80800000),_RegRd(u32,0x80800014)));
+*/
+
+	_PRTK_DUMP(("Dumping private data:\n"));
+	_PRTK_DUMP((" d.txStopped:%d  d.idxQueTxSts:%d  d.idxQueTxDescHead:%d  d.idxQueTxDescTail:%d\n", pP->d.txStopped, pP->d.idxQueTxSts, pP->d.idxQueTxDescHead, pP->d.idxQueTxDescTail));
+	_PRTK_DUMP((" d.idxQueRxDesc:%d  d.idxQueRxSts:%d\n",
+		    pP->d.idxQueRxDesc, pP->d.idxQueRxSts));
+}/*_dbg_ep9312eth_dumpReg()*/
+#endif				/*ifndef _PRTK_DUMP else */
+
+#define CRC_PRIME 0xFFFFFFFF
+#define CRC_POLYNOMIAL 0x04C11DB6
+/*****************************************************************************
+* calculate_hash_index()
+*****************************************************************************/
+static unsigned char calculate_hash_index(char *pMulticastAddr)
+{
+	unsigned long CRC;
+	unsigned char HashIndex;
+	unsigned char AddrByte;
+	unsigned char *pC;
+	unsigned long HighBit;
+	int Byte;
+	int Bit;
+
+	/* Prime the CRC */
+	CRC = CRC_PRIME;
+	pC = pMulticastAddr;
+
+	/* For each of the six bytes of the multicast address */
+	for (Byte = 0; Byte < 6; Byte++) {
+		AddrByte = *pC;
+		pC++;
+		/* For each bit of the byte */
+		for (Bit = 8; Bit > 0; Bit--) {
+			HighBit = CRC >> 31;
+			CRC <<= 1;
+
+			if (HighBit ^ (AddrByte & 1)) {
+				CRC ^= CRC_POLYNOMIAL;
+				CRC |= 1;
+			}
+
+			AddrByte >>= 1;
+		}
+	}
+
+	/* Take the least significant six bits of the CRC and copy them */
+	/* to the HashIndex in reverse order.                           */
+	for (Bit = 0, HashIndex = 0; Bit < 6; Bit++) {
+		HashIndex <<= 1;
+		HashIndex |= (unsigned char)(CRC & 1);
+		CRC >>= 1;
+	}
+
+	return HashIndex;
+}				/*calculate_hash_index() */
+
+/*****************************************************************************
+* eth_setMulticastTbl()
+*****************************************************************************/
+static void eth_setMulticastTbl(struct net_device *pD, u8 * pBuf)
+{
+	int i;
+	unsigned char position;
+	struct dev_mc_list *cur_addr;
+
+	memset(pBuf, 0x00, 8);
+
+	cur_addr = pD->mc_list;
+	for (i = 0; i < pD->mc_count; i++, cur_addr = cur_addr->next) {
+
+		if (!cur_addr)
+			break;
+		if (!(*cur_addr->dmi_addr & 1))
+			continue;	/*make sure multicast addr */
+		position = calculate_hash_index(cur_addr->dmi_addr);
+		pBuf[position >> 3] |= 1 << (position & 0x07);
+
+	}			/*for */
+}				/*eth_setMulticastTbl() */
+
+/*****************************************************************************
+* eth_indAddrWr()
+*****************************************************************************/
+static int eth_indAddrWr(struct net_device *pD, int afp, char *pBuf)
+{
+	u32 rxctl;
+	int i, len;
+
+	_PRTK_ENTRY(("eth_indAddrWr(pD:0x%x,afp:0x%x,pBuf:0x%x)\n",
+		     (unsigned int)pD, afp, (unsigned int)pBuf));
+
+	afp &= 0x07;
+	if (4 == afp || 5 == afp) {
+		_PRTK_SWERR(("eth_indAddrWr(): invalid afp value\n"));
+		return -1;
+	}			/*if */
+	len = (AFP_AFP_HASH == afp) ? 8 : 6;
+
+	_PRTK_INFO(("eth_indAddrWr(): %02x:%02x:%02x:%02x:%02x:%02x%s",
+		    pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5],
+		    (6 == len) ? "\n" : ":"));
+	if (6 != len)
+		_PRTK_INFO(("%02x:%02x\n", pBuf[6], pBuf[7]));
+
+	/*if */
+	rxctl = RegRd32(REG_RxCTL);	/*turn Rx off */
+	RegWr32(REG_RxCTL, ~RxCTL_SRxON & rxctl);
+	RegWr32(REG_AFP, afp);	/*load new address pattern */
+	for (i = 0; i < len; i++)
+		RegWr8(REG_IndAD + i, pBuf[i]);
+	RegWr32(REG_RxCTL, rxctl);	/*turn Rx back */
+
+	return 0;
+}				/*eth_indAddrWr() */
+
+/*****************************************************************************
+* eth_indAddrRd()
+*****************************************************************************/
+#if 0
+static int eth_indAddrRd(struct net_device *pD, int afp, char *pBuf)
+{
+	int i, len;
+
+	_PRTK_ENTRY(("eth_indAddrRd(pD:0x%x,afp:0x%x,pBuf:0x%x)\n",
+		     (unsigned int)pD, afp, (unsigned int)pBuf));
+
+	afp &= 0x07;
+	if (4 == afp || 5 == afp) {
+		_PRTK_SWERR(("eth_indAddrRd(): invalid afp value\n"));
+		return -1;
+	}
+	/*if */
+	RegWr32(REG_AFP, afp);
+	len = (AFP_AFP_HASH == afp) ? 8 : 6;
+	for (i = 0; i < len; i++)
+		pBuf[i] = RegRd8(REG_IndAD + i);
+
+	return 0;
+}				/*eth_indAddrRd() */
+#endif
+
+/*****************************************************************************
+* eth_rxCtl()
+*****************************************************************************/
+static int eth_rxCtl(struct net_device *pD, int sw)
+{
+
+	_PRTK_ENTRY(("eth_rxCtl(pD:0x%p,sw:%d)\n", pD, sw));
+
+/* Workaround for MAC lost 60-byte-long frames:  must enable Runt_CRC_Accept bit */
+	RegWr32(REG_RxCTL, sw ? RegRd32(REG_RxCTL) | RxCTL_SRxON | RxCTL_RCRCA :
+		RegRd32(REG_RxCTL) & ~RxCTL_SRxON);
+
+	return 0;
+}				/*eth_rxCtl() */
+
+/*****************************************************************************
+* eth_chkTxLvl()
+*****************************************************************************/
+static void eth_chkTxLvl(struct net_device *pD)
+{
+	struct ep93xxEth_info *pP = netdev_priv(pD);
+	int idxQTxDescHd;
+	int filled;
+
+	_PRTK_ENTRY_ISR(("eth_chkTxLvl(pD:0x%x)\n", (unsigned int)pD));
+
+	idxQTxDescHd = pP->d.idxQueTxDescHead;
+
+	/*check Tx Descriptor Queue fill-up level */
+	filled = idxQTxDescHd - pP->d.idxQueTxDescTail;
+	if (filled < 0)
+		filled += LEN_QueTxDesc;
+
+	if (pP->d.txStopped && filled <= (LVL_TxResume + 1)) {
+		pP->d.txStopped = 0;
+		pD->trans_start = jiffies;
+		netif_wake_queue(pD);
+		_PRTK_INFO_ISR(("eth_chkTxLvl(): Tx Resumed, filled:%d\n",
+				filled));
+	}			/*if */
+}				/*eth_chkTxLvl() */
+
+/*****************************************************************************
+* eth_cleanUpTx()
+*****************************************************************************/
+static int eth_cleanUpTx(struct net_device *pD)
+{
+	struct ep93xxEth_info *pP = netdev_priv(pD);
+	union transmitStatus *pQTxSts;
+	int idxSts, bi;
+
+	_PRTK_ENTRY(("eth_cleanUpTx(pD:0x%x)\n", (unsigned int)pD));
+
+	/*process Tx Status Queue (no need to limit processing of TxStatus Queue because
+	   each queue entry consist of 1 dword) */
+	while (pP->s.pQueTxSts[pP->d.idxQueTxSts].f.txfp) {
+
+		idxSts = pP->d.idxQueTxSts;
+
+		/*ahead Tx Status Queue index */
+		pP->d.idxQueTxSts = IdxNext(pP->d.idxQueTxSts, LEN_QueTxSts);
+		pQTxSts = &pP->s.pQueTxSts[idxSts];
+		_PRTK_INFO(("eth_cleanUpTx(): QTxSts[%d]:0x%x\n", idxSts,
+			    (unsigned int)pQTxSts->w.e0));
+		if (!pQTxSts->f.txfp) {	/*empty? */
+			_PRTK_HWFAIL(("eth_cleanUpTx(): QueTxSts[%d]:x%08x is empty\n", idxSts, (int)pQTxSts->w.e0));
+			/*@ do recover */
+			return -1;
+		}		/*if */
+		pQTxSts->f.txfp = 0;	/*mark processed */
+
+		bi = pQTxSts->f.bi;	/*buffer index */
+#if 0
+		if (pP->d.idxQueTxDescTail != bi) {	/*verify BI */
+			_PRTK_HWFAIL(("eth_cleanUpTx(): unmatching QTxSts[%d].BI:%d idxQTxDTail:%d\n", idxSts, bi, pP->d.idxQueTxDescTail));
+			/*@ recover */
+		}		/*if */
+#endif
+
+		/*free Tx buffer */
+		if (pP->s.pTxBufDesc[bi].pFreeRtn) {
+			(*pP->s.pTxBufDesc[bi].pFreeRtn) (pP->s.pTxBufDesc[bi].
+							  vaddr);
+			pP->s.pTxBufDesc[bi].pFreeRtn = NULL;
+		}
+
+		/*if */
+		/*statistics collection */
+		if (pQTxSts->f.txwe) {	/*Sent without error */
+			pP->d.stats.tx_packets++;
+		} else {	/*Tx failed due to error */
+			_PRTK_INFO(("eth_cleanUpTx(): Tx failed due to error QTxSts[%d]:0x%x\n", idxSts, (unsigned int)pQTxSts->w.e0));

⌨️ 快捷键说明

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