📄 drivers_net_arm_ep93xx_eth_c_diff.htm
字号:
+ _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 + -