int32 des8651bSwThroughput(uint32 round, uint32 startMode, uint32 endMode, uint32 pktLen) { uint32 testRound, modeIdx, i, bps; uint32 sTime, eTime; cryptOrg = (int8 *) UNCACHED_MALLOC(4352); cryptEncrypt = (int8 *) UNCACHED_MALLOC(4352); cryptKey = (int8 *) UNCACHED_MALLOC(24); cryptIv = (int8 *) UNCACHED_MALLOC(8); for(i=0; i<24; i++) cryptKey[i] = 0x01; for(i=0; i<8; i++) cryptIv[i] = 0x01; for(i=0; i<pktLen; i++)//8-byte for IV and 4-byte for DMA_addr (0-3) byte offset test cryptOrg[i] = 0xff;//(int8)taurand(256); rtlglue_printf("Evaluate software simulation throughput\n"); for(modeIdx=startMode;modeIdx<=endMode;modeIdx++) { rtlglue_getmstime(&sTime); for(testRound=0; testRound<=round; testRound++) { if ( desSim_des(modeIdx, cryptOrg, cryptEncrypt, pktLen, cryptKey, cryptIv) != SUCCESS ) { rtlglue_printf("testRound=%d, desSim_des(modeIdx=%d) failed...\n", testRound, modeIdx ); return FAILED; } } rtlglue_getmstime(&eTime); if ( eTime - sTime == 0 ) { rtlglue_printf("round is too small to measure throughput, try larger round number!\n"); return FAILED; } else { bps = pktLen*8*1000/((uint32)(eTime - sTime))*round; if(bps>1000000) rtlglue_printf("%s round %u len %u time %u throughput %u.%02u mbps\n", desModeString[modeIdx], round, pktLen, (uint32)(eTime - sTime), bps/1000000, (bps%1000000)/10000); else if(bps>1000) rtlglue_printf("%s round %u len %u time %u throughput %u.%02u kbps\n", desModeString[modeIdx], round, pktLen, (uint32)(eTime - sTime), bps/1000, (bps%1000)/10); else rtlglue_printf("%s round %u len %u time %u throughput %u bps\n", desModeString[modeIdx], round, pktLen, (uint32)(eTime - sTime), bps); } } UNCACHED_FREE(cryptAsic); UNCACHED_FREE(cryptKey); UNCACHED_FREE(cryptIv); return SUCCESS; }
int32 runDes8651bGeneralApiRandTest(uint32 seed, uint32 round) { uint32 roundIdx, modeIdx, pktLen, i, offset, errCount; uint32 doneCounter, allDoneCounter; int32 ret = SUCCESS; cryptGenAsic = (int8 *) UNCACHED_MALLOC(4352); tauset(58, (int32)seed); errCount = 0; for(roundIdx = 0; roundIdx<round; roundIdx++) { for(i=0; i<24; i++) cryptGenKey[i] = taurand(256)&0xFF; for(i=0; i<8; i++) cryptGenIv[i] = taurand(256)&0xFF; modeIdx = taurand(4)&0x3; pktLen = (taurand(4080)&0xFF8) + 8; offset = taurand(4)&0x3; for(i=0; i<pktLen; i++)//8-byte for IV and 4-byte for DMA_addr (0-3) byte offset test cryptGenAsic[i+offset] = taurand(256)&0xFF; rtl8651b_cryptoEngineGetIntCounter(&doneCounter, &allDoneCounter); rtlglue_printf("\r[%05u, %03u]Mode: %s Packet length %04u Offset %u (%u, %u)", roundIdx, errCount, desOpModeString[modeIdx&0x3], pktLen, offset, doneCounter, allDoneCounter); if(des8651bGeneralApiTestItem(modeIdx&0x3, &cryptGenAsic[offset], pktLen, cryptGenKey, cryptGenIv) == FAILED) errCount++; } UNCACHED_FREE(cryptGenAsic); rtlglue_printf("\nGeneral API Test Finished\n"); return ret; }
int32 runAuth8651bGeneralApiTest(uint32 round, uint32 funStart, uint32 funEnd, uint32 lenStart, uint32 lenEnd, uint32 keyLenStart, uint32 keyLenEnd, uint32 offsetStart, uint32 offsetEnd) { uint32 i, j, pktLen, keyLen, roundIdx, errCount, offset; uint32 doneCounter, allDoneCounter; asicTestData = (uint8 *)UNCACHED_MALLOC(4352*sizeof(uint32)); keyLen = 8; for(i=0; i<keyLen; i++) asicTestKey[i] = 0x01;//(uint8)taurand(256); errCount=0; for(roundIdx=0; roundIdx<round; roundIdx++) for(i=funStart; i<=funEnd; i++) for(pktLen=lenStart; pktLen<=lenEnd; pktLen+=8) for(offset=offsetStart; offset<=offsetEnd; offset++) { for(j=0; j<pktLen; j++) asicTestData[j+offset] = (j&0xFF);//(uint8)taurand(256); rtl8651b_authEngineGetIntCounter(&doneCounter, &allDoneCounter); rtlglue_printf("\r[%05u, %03u]Mode: %s Packet length %04u Offset %u (%u, %u)", roundIdx, errCount, authModeString[i], pktLen, offset, doneCounter, allDoneCounter); if(auth8651bGeneralApiTestItem(i, &asicTestData[offset], pktLen, asicTestKey, keyLen) == FAILED) { errCount++; break; } } UNCACHED_FREE(asicTestData); return SUCCESS; }
int32 auth8651bAsicThroughput(uint32 round, uint32 startMode, uint32 endMode, uint32 pktLen) { uint32 testRound, modeIdx, i, keyLen, bps; uint32 sTime, eTime; if(endMode> 3) endMode = 3; if(startMode>3) startMode = 3; asicTestData = (uint8 *)UNCACHED_MALLOC(4352*sizeof(uint32)); keyLen = 8; for(i=0; i<pktLen; i++) asicTestData[i] = 0xFF;//(uint8)taurand(256); for(i=0; i<keyLen; i++) asicTestKey[i] = 0x01;//(uint8)taurand(256); rtlglue_printf("Evaluate 8651b throughput\n"); for(modeIdx=startMode;modeIdx<=endMode;modeIdx++) { rtlglue_getmstime(&sTime); for(testRound=0; testRound<=round; testRound++) { if ( rtl8651b_authEngine(modeIdx, asicTestData, pktLen, asicTestKey, keyLen, asicDigest) != SUCCESS ) { rtlglue_printf("testRound=%d, rtl8651b_authEngine(modeIdx=%d) failed...\n", testRound, modeIdx ); return FAILED; } } rtlglue_getmstime(&eTime); if ( eTime - sTime == 0 ) { rtlglue_printf("round is too small to measure throughput, try larger round number!\n"); return FAILED; } else { bps = pktLen*8*1000/((uint32)(eTime - sTime))*round; if(bps>1000000) rtlglue_printf("%s round %u len %u time %u throughput %u.%02u mbps\n", authModeString[modeIdx], round, pktLen, (uint32)(eTime - sTime), bps/1000000, (bps%1000000)/10000); else if(bps>1000) rtlglue_printf("%s round %u len %u time %u throughput %u.%02u kbps\n", authModeString[modeIdx], round, pktLen, (uint32)(eTime - sTime), bps/1000, (bps%1000)/10); else rtlglue_printf("%s round %u len %u time %u throughput %u bps\n", authModeString[modeIdx], round, pktLen, (uint32)(eTime - sTime), bps); } } UNCACHED_FREE(asicTestData); return SUCCESS; }
int32 des8651bTest(uint32 round, uint32 funStart, uint32 funEnd, uint32 lenStart, uint32 lenEnd, uint32 offsetStart, uint32 offsetEnd) { uint32 i, pktLen, offset, funIdx, dupRound; tauset(58, 19); cryptOrg = (int8 *) UNCACHED_MALLOC(4352); cryptAsic = (int8 *) UNCACHED_MALLOC(4352); cryptEncrypt = (int8 *) UNCACHED_MALLOC(4352); cryptDecrypt = (int8 *) UNCACHED_MALLOC(4352); cryptKey = (int8 *) UNCACHED_MALLOC(24); cryptIv = (int8 *) UNCACHED_MALLOC(8); for(i=0; i<24; i++) cryptKey[i] = 0x01;//(int8)taurand(256); for(i=0; i<8; i++) cryptIv[i] = 0x01;//(int8)taurand(256); for(i=0; i<2064; i++)//8-byte for IV and 4-byte for DMA_addr (0-3) byte offset test cryptOrg[i] = 0xff;//(int8)taurand(256); REG32(0xbd01200c) &= 0x0fffffff; REG32(0xbd012010) |= 0xf0000000; REG32(0xbd012014) &= 0x0fffffff; for(dupRound=0; dupRound<=round; dupRound++) { for(funIdx=funStart; funIdx<=funEnd; funIdx++) { for(pktLen = (lenStart&0xFFFFFFF8); pktLen <= (lenEnd&0xFFFFFFF8); pktLen+=8) { for(offset = offsetStart; offset<=offsetEnd; offset++) { rtlglue_printf("\rRound %4d %s Offset %2d PktLen %4d", dupRound, testDesItem[funIdx].funcTitle, offset, pktLen); if(testDesItem[funIdx].func(offset, pktLen)==FAILED) { rtlglue_printf("\nOffset %2d PktLen %4d %s Failed\n", offset, pktLen, testDesItem[funIdx].funcTitle); REG32(0xbd012014) |= 0xf0000000; goto FINISHED; } } } } } FINISHED: UNCACHED_FREE(cryptOrg); UNCACHED_FREE(cryptAsic); UNCACHED_FREE(cryptEncrypt); UNCACHED_FREE(cryptDecrypt); UNCACHED_FREE(cryptKey); UNCACHED_FREE(cryptIv); return SUCCESS; }
int32 runDes8651bGeneralApiTest(uint32 round, uint32 funStart, uint32 funEnd, uint32 lenStart, uint32 lenEnd, uint32 offsetStart, uint32 offsetEnd) { uint32 roundIdx, modeIdx, pktLen, i, offset, errCount; uint32 doneCounter, allDoneCounter; int32 ret = SUCCESS; cryptGenAsic = (int8 *) UNCACHED_MALLOC(4352); for(i=0; i<24; i++) cryptGenKey[i] = 0x01; for(i=0; i<8; i++) cryptGenIv[i] = 0x01; errCount = 0; #if 0 for(roundIdx = 0; roundIdx<round; roundIdx++) for(modeIdx=funStart; modeIdx<=funEnd; modeIdx++) for(pktLen=lenStart; pktLen<=lenEnd; pktLen+=8) for(offset=offsetStart; offset<=offsetEnd; offset++) { for(i=0; i<pktLen; i++)//8-byte for IV and 4-byte for DMA_addr (0-3) byte offset test cryptGenAsic[i+offset] = 0xff;//(int8)taurand(256); rtlglue_printf("\r[%05u, %03u]Mode: %s Packet length %04u Offset %u[%08X]", roundIdx, errCount, desModeString[modeIdx], pktLen, offset, &cryptGenAsic[offset]); if(des8651bGeneralApiTestItem(modeIdx, &cryptGenAsic[offset], pktLen, cryptGenKey, cryptGenIv) == FAILED) errCount++; } #endif for(roundIdx = 0; roundIdx<round; roundIdx++) for(modeIdx=funStart; modeIdx<=funEnd; modeIdx++) for(pktLen=lenStart; pktLen<=lenEnd; pktLen+=8) for(offset=offsetStart; offset<=offsetEnd; offset++) { for(i=0; i<pktLen; i++)//8-byte for IV and 4-byte for DMA_addr (0-3) byte offset test cryptGenAsic[i+offset] = (i&0xFF);//(int8)taurand(256); rtl8651b_cryptoEngineGetIntCounter(&doneCounter, &allDoneCounter); rtlglue_printf("\r[%05u, %03u]Mode: %s Packet length %04u Offset %u (%u, %u)", roundIdx, errCount, desOpModeString[modeIdx&0x3], pktLen, offset, doneCounter, allDoneCounter); if(des8651bGeneralApiTestItem(modeIdx&0x3, &cryptGenAsic[offset], pktLen, cryptGenKey, cryptGenIv) == FAILED) errCount++; } UNCACHED_FREE(cryptGenAsic); rtlglue_printf("\nGeneral API Test Finished\n"); return ret; }
int32 runAuth8651bGeneralApiRandTest(uint32 seed, uint32 round) { uint32 i, pktLen, keyLen, roundIdx, modeIdx, errCount, offset; uint32 doneCounter, allDoneCounter; tauset(58, (int32)seed); asicTestData = (uint8 *)UNCACHED_MALLOC(4352*sizeof(uint32)); errCount = 0; for(roundIdx=0; roundIdx<round; roundIdx++) { keyLen = taurand(1024)&0x3FF; for(i=0; i<keyLen; i++) asicTestKey[i] = taurand(256)&0xFF; modeIdx = taurand(4)&0x3; pktLen = taurand(4024); offset = taurand(4); for(i=0; i<pktLen; i++) asicTestData[i+offset] = taurand(256)&0xFF; rtl8651b_authEngineGetIntCounter(&doneCounter, &allDoneCounter); rtlglue_printf("\r[%05u, %03u]Mode: %s Packet length %04u Offset %u (%u, %u)", roundIdx, errCount, authModeString[modeIdx], pktLen, offset, doneCounter, allDoneCounter); if(auth8651bGeneralApiTestItem(modeIdx, &asicTestData[offset], pktLen, asicTestKey, keyLen) == FAILED) errCount++; } UNCACHED_FREE(asicTestData); return SUCCESS; }
int32 swNic_init(uint32 userNeedRxPkthdrRingCnt[RTL865X_SWNIC_RXRING_HW_PKTDESC], uint32 userNeedRxMbufRingCnt, uint32 userNeedTxPkthdrRingCnt[RTL865X_SWNIC_TXRING_HW_PKTDESC], uint32 clusterSize) { uint32 i, j, k; static uint32 totalRxPkthdrRingCnt = 0, totalTxPkthdrRingCnt = 0; static struct rtl_pktHdr *pPkthdrList_start; static struct rtl_mBuf *pMbufList_start; struct rtl_pktHdr *pPkthdrList; struct rtl_mBuf *pMbufList; struct rtl_pktHdr * pPkthdr; struct rtl_mBuf * pMbuf; unsigned long flags=0; int ret; #if defined(CONFIG_RTL_8198C) && defined(_PKTHDR_CACHEABLE) int cpu_dcache_line = cpu_dcache_line_size(); // in \arch\mips\include\asm\cpu-features.h #endif /* init const array for rx pre-process */ extPortMaskToPortNum[0] = 5; extPortMaskToPortNum[1] = 6; extPortMaskToPortNum[2] = 7; extPortMaskToPortNum[3] = 5; extPortMaskToPortNum[4] = 8; extPortMaskToPortNum[5] = 5; extPortMaskToPortNum[6] = 5; extPortMaskToPortNum[7] = 5; #if defined(DELAY_REFILL_ETH_RX_BUF) rxPkthdrRefillThreshold[0] = ETH_REFILL_THRESHOLD; rxPkthdrRefillThreshold[1] = ETH_REFILL_THRESHOLD1; rxPkthdrRefillThreshold[2] = ETH_REFILL_THRESHOLD2; rxPkthdrRefillThreshold[3] = ETH_REFILL_THRESHOLD3; rxPkthdrRefillThreshold[4] = ETH_REFILL_THRESHOLD4; rxPkthdrRefillThreshold[5] = ETH_REFILL_THRESHOLD5; #endif #if defined(CONFIG_RTL8196C_REVISION_B) rtl_chip_version = REG32(REVR); #endif ret = SUCCESS; SMP_LOCK_ETH_RECV(flags); if (rxMbufRing == NULL) { size_of_cluster = clusterSize; /* Allocate Rx descriptors of rings */ for (i = 0; i < RTL865X_SWNIC_RXRING_HW_PKTDESC; i++) { rxPkthdrRingCnt[i] = userNeedRxPkthdrRingCnt[i]; if (rxPkthdrRingCnt[i] == 0) { rxPkthdrRing[i] = NULL; continue; } rxPkthdrRing[i] = (uint32 *) UNCACHED_MALLOC(rxPkthdrRingCnt[i] * sizeof(uint32*)); ASSERT_CSP( (uint32) rxPkthdrRing[i] & 0x0fffffff ); totalRxPkthdrRingCnt += rxPkthdrRingCnt[i]; } if (totalRxPkthdrRingCnt == 0) { ret = EINVAL; goto out; } /* Allocate Tx descriptors of rings */ for (i = 0; i < RTL865X_SWNIC_TXRING_HW_PKTDESC; i++) { txPkthdrRingCnt[i] = userNeedTxPkthdrRingCnt[i]; if (txPkthdrRingCnt[i] == 0) { txPkthdrRing[i] = NULL; continue; } txPkthdrRing[i] = (uint32 *) UNCACHED_MALLOC(txPkthdrRingCnt[i] * sizeof(uint32*)); #ifdef CONFIG_RTL8196C_REVISION_B if (rtl_chip_version == RTL8196C_REVISION_A) txPkthdrRing_backup[i]=(uint32 *) UNCACHED_MALLOC(txPkthdrRingCnt[i] * sizeof(uint32)); #endif ASSERT_CSP( (uint32) txPkthdrRing[i] & 0x0fffffff ); totalTxPkthdrRingCnt += txPkthdrRingCnt[i]; } if (totalTxPkthdrRingCnt == 0) { ret = EINVAL; goto out; } /* Allocate MBuf descriptors of rings */ rxMbufRingCnt = userNeedRxMbufRingCnt; if (userNeedRxMbufRingCnt == 0) { ret = EINVAL; goto out; } rxMbufRing = (uint32 *) UNCACHED_MALLOC((rxMbufRingCnt+RESERVERD_MBUF_RING_NUM) * sizeof(uint32*)); ASSERT_CSP( (uint32) rxMbufRing & 0x0fffffff ); /* Allocate pkthdr */ #ifdef _PKTHDR_CACHEABLE #if 0 //defined(CONFIG_RTL_8198C) pPkthdrList_start = (struct rtl_pktHdr *) kmalloc( (totalRxPkthdrRingCnt + totalTxPkthdrRingCnt) * sizeof(struct rtl_pktHdr), GFP_ATOMIC); ASSERT_CSP( (uint32) pPkthdrList_start & 0x0fffffff ); /* Allocate mbufs */ pMbufList_start = (struct rtl_mBuf *) kmalloc( (rxMbufRingCnt+RESERVERD_MBUF_RING_NUM+ totalTxPkthdrRingCnt) * sizeof(struct rtl_mBuf), GFP_ATOMIC); ASSERT_CSP( (uint32) pMbufList_start & 0x0fffffff ); #else pPkthdrList_start = (struct rtl_pktHdr *) kmalloc( (totalRxPkthdrRingCnt+totalTxPkthdrRingCnt+1) * sizeof(struct rtl_pktHdr), GFP_ATOMIC); ASSERT_CSP( (uint32) pPkthdrList_start & 0x0fffffff ); pPkthdrList_start = (struct rtl_pktHdr *)(((uint32) pPkthdrList_start + (cpu_dcache_line - 1))& ~(cpu_dcache_line - 1)); /* Allocate mbufs */ pMbufList_start = (struct rtl_mBuf *) kmalloc( (rxMbufRingCnt+RESERVERD_MBUF_RING_NUM+totalTxPkthdrRingCnt+1) * sizeof(struct rtl_mBuf), GFP_ATOMIC); ASSERT_CSP( (uint32) pMbufList_start & 0x0fffffff ); pMbufList_start = (struct rtl_mBuf *)(((uint32) pMbufList_start + (cpu_dcache_line - 1))& ~(cpu_dcache_line - 1)); #endif #else pPkthdrList_start = (struct rtl_pktHdr *) UNCACHED_MALLOC( (totalRxPkthdrRingCnt + totalTxPkthdrRingCnt) * sizeof(struct rtl_pktHdr)); ASSERT_CSP( (uint32) pPkthdrList_start & 0x0fffffff ); /* Allocate mbufs */ pMbufList_start = (struct rtl_mBuf *) UNCACHED_MALLOC( (rxMbufRingCnt+RESERVERD_MBUF_RING_NUM+ totalTxPkthdrRingCnt) * sizeof(struct rtl_mBuf)); ASSERT_CSP( (uint32) pMbufList_start & 0x0fffffff ); #endif } /* Initialize interrupt statistics counter */ //rxPktCounter = txPktCounter = 0; /* Initialize index of Tx pkthdr descriptor */ for (i=0;i<RTL865X_SWNIC_TXRING_HW_PKTDESC;i++) { currTxPkthdrDescIndex[i] = 0; txPktDoneDescIndex[i]=0; } pPkthdrList = pPkthdrList_start; pMbufList = pMbufList_start; /* Initialize Tx packet header descriptors */ for (i = 0; i < RTL865X_SWNIC_TXRING_HW_PKTDESC; i++) { for (j = 0; j < txPkthdrRingCnt[i]; j++) { /* Dequeue pkthdr and mbuf */ pPkthdr = pPkthdrList++; pMbuf = pMbufList++; bzero((void *) pPkthdr, sizeof(struct rtl_pktHdr)); bzero((void *) pMbuf, sizeof(struct rtl_mBuf)); pPkthdr->ph_mbuf = pMbuf; pPkthdr->ph_len = 0; pPkthdr->ph_flags = PKTHDR_USED | PKT_OUTGOING; pPkthdr->ph_type = PKTHDR_ETHERNET; pPkthdr->ph_portlist = 0; pMbuf->m_next = NULL; pMbuf->m_pkthdr = pPkthdr; pMbuf->m_flags = MBUF_USED | MBUF_EXT | MBUF_PKTHDR | MBUF_EOR; pMbuf->m_data = NULL; pMbuf->m_extbuf = NULL; pMbuf->m_extsize = 0; txPkthdrRing[i][j] = (int32) pPkthdr | DESC_RISC_OWNED; #ifdef CONFIG_RTL8196C_REVISION_B if (rtl_chip_version == RTL8196C_REVISION_A) txPkthdrRing_backup[i][j]=(int32) pPkthdr | DESC_RISC_OWNED; #endif } #ifdef CONFIG_RTL_ENHANCE_RELIABILITY txPkthdrRing_base[i] = txPkthdrRing[i][0]; #endif if(txPkthdrRingCnt[i] > 0) { /* Set wrap bit of the last descriptor */ txPkthdrRing[i][txPkthdrRingCnt[i] - 1] |= DESC_WRAP; #ifdef CONFIG_RTL8196C_REVISION_B if (rtl_chip_version == RTL8196C_REVISION_A) txPkthdrRing_backup[i][txPkthdrRingCnt[i] - 1] |= DESC_WRAP; #endif } } /* Fill Tx packet header FDP */ REG32(CPUTPDCR0) = (uint32) txPkthdrRing[0]; REG32(CPUTPDCR1) = (uint32) txPkthdrRing[1]; #if defined(CONFIG_RTL_819XD) || defined(CONFIG_RTL_8196E) || defined(CONFIG_RTL_8198C) REG32(CPUTPDCR2) = (uint32) txPkthdrRing[2]; REG32(CPUTPDCR3) = (uint32) txPkthdrRing[3]; #endif /* Initialize Rx packet header descriptors */ k = 0; for (i = 0; i < RTL865X_SWNIC_RXRING_HW_PKTDESC; i++) { for (j = 0; j < rxPkthdrRingCnt[i]; j++) { /* Dequeue pkthdr and mbuf */ pPkthdr = pPkthdrList++; pMbuf = pMbufList++; bzero((void *) pPkthdr, sizeof(struct rtl_pktHdr)); bzero((void *) pMbuf, sizeof(struct rtl_mBuf)); /* Setup pkthdr and mbuf */ pPkthdr->ph_mbuf = pMbuf; pPkthdr->ph_len = 0; pPkthdr->ph_flags = PKTHDR_USED | PKT_INCOMING; pPkthdr->ph_type = PKTHDR_ETHERNET; pPkthdr->ph_portlist = 0; pMbuf->m_next = NULL; pMbuf->m_pkthdr = pPkthdr; pMbuf->m_len = 0; pMbuf->m_flags = MBUF_USED | MBUF_EXT | MBUF_PKTHDR | MBUF_EOR; pMbuf->m_extsize = size_of_cluster; pMbuf->m_data = pMbuf->m_extbuf = alloc_rx_buf(&pPkthdr->ph_mbuf->skb, size_of_cluster); /* Setup descriptors */ rxPkthdrRing[i][j] = (int32) pPkthdr | DESC_SWCORE_OWNED; rxMbufRing[k++] = (int32) pMbuf | DESC_SWCORE_OWNED; } #ifdef CONFIG_RTL_ENHANCE_RELIABILITY rxPkthdrRing_base[i] = rxPkthdrRing[i][0] & ~DESC_OWNED_BIT; #endif /* Initialize index of current Rx pkthdr descriptor */ currRxPkthdrDescIndex[i] = 0; /* Initialize index of current Rx Mbuf descriptor */ currRxMbufDescIndex = 0; /* Set wrap bit of the last descriptor */ if(rxPkthdrRingCnt[i] > 0) rxPkthdrRing[i][rxPkthdrRingCnt[i] - 1] |= DESC_WRAP; #if defined(DELAY_REFILL_ETH_RX_BUF) rxDescReadyForHwIndex[i] = 0; rxDescCrossBoundFlag[i] = 0; #endif } #if defined(CONFIG_RTL_ENHANCE_RELIABILITY) && defined(CONFIG_RTL_8198C) rxMbufRing_base = rxMbufRing[0] & ~DESC_OWNED_BIT; #endif rxMbufRing[rxMbufRingCnt - 1] |= DESC_WRAP; /* Fill Rx packet header FDP */ REG32(CPURPDCR0) = (uint32) rxPkthdrRing[0]; REG32(CPURPDCR1) = (uint32) rxPkthdrRing[1]; REG32(CPURPDCR2) = (uint32) rxPkthdrRing[2]; REG32(CPURPDCR3) = (uint32) rxPkthdrRing[3]; REG32(CPURPDCR4) = (uint32) rxPkthdrRing[4]; REG32(CPURPDCR5) = (uint32) rxPkthdrRing[5]; REG32(CPURMDCR0) = (uint32) rxMbufRing; out: //SMP_UNLOCK_ETH_RECV(flags); #ifdef _PKTHDR_CACHEABLE _dma_cache_wback_inv((unsigned long)pPkthdrList_start, (totalRxPkthdrRingCnt + totalTxPkthdrRingCnt) * sizeof(struct rtl_pktHdr)); _dma_cache_wback_inv((unsigned long)pMbufList_start, (rxMbufRingCnt+RESERVERD_MBUF_RING_NUM+ totalTxPkthdrRingCnt) * sizeof(struct rtl_mBuf)); #endif SMP_UNLOCK_ETH_RECV(flags); return ret; }
int32 swNic_init(uint32 userNeedRxPkthdrRingCnt[RTL865X_SWNIC_RXRING_MAX_PKTDESC], uint32 userNeedRxMbufRingCnt, uint32 userNeedTxPkthdrRingCnt[RTL865X_SWNIC_TXRING_MAX_PKTDESC], uint32 clusterSize) { uint32 i, j, k; uint32 totalRxPkthdrRingCnt = 0, totalTxPkthdrRingCnt = 0; struct pktHdr *pPkthdrList; struct mBuf *pMbufList; uint8 * pClusterList; struct pktHdr * pPkthdr; struct mBuf * pMbuf; /* Cluster size is always 2048 */ size_of_cluster = 2048; /* Allocate Rx descriptors of rings */ for (i = 0; i < RTL865X_SWNIC_RXRING_MAX_PKTDESC; i++) { rxPkthdrRingCnt[i] = userNeedRxPkthdrRingCnt[i]; if (rxPkthdrRingCnt[i] == 0) continue; rxPkthdrRing[i] = (uint32 *) UNCACHED_MALLOC(rxPkthdrRingCnt[i] * sizeof(uint32)); ASSERT_CSP( (uint32) rxPkthdrRing[i] & 0x0fffffff ); memset(rxPkthdrRing[i],0,rxPkthdrRingCnt[i] * sizeof(uint32)); totalRxPkthdrRingCnt += rxPkthdrRingCnt[i]; } if (totalRxPkthdrRingCnt == 0) return EINVAL; /* Allocate Tx descriptors of rings */ for (i = 0; i < RTL865X_SWNIC_TXRING_MAX_PKTDESC; i++) { txPkthdrRingCnt[i] = userNeedTxPkthdrRingCnt[i]; if (txPkthdrRingCnt[i] == 0) continue; txPkthdrRing[i] = (uint32 *) UNCACHED_MALLOC(txPkthdrRingCnt[i] * sizeof(uint32)); #ifdef CONFIG_RTL8196C_SWITCH_PATCH #ifdef CONFIG_AUTO_IDENTIFY if (REG32(REVR) == RTL8196C_REVISION_A) txPkthdrRing_BAK[i] = (uint32 *) UNCACHED_MALLOC(txPkthdrRingCnt[i] * sizeof(uint32)); #endif #endif ASSERT_CSP( (uint32) txPkthdrRing[i] & 0x0fffffff ); memset(txPkthdrRing[i],0,(txPkthdrRingCnt[i] * sizeof(uint32))); totalTxPkthdrRingCnt += txPkthdrRingCnt[i]; } if (totalTxPkthdrRingCnt == 0) return EINVAL; /* Allocate MBuf descriptors of rings */ rxMbufRingCnt = userNeedRxMbufRingCnt; if (userNeedRxMbufRingCnt == 0) return EINVAL; rxMbufRing = (uint32 *) UNCACHED_MALLOC(userNeedRxMbufRingCnt * sizeof(uint32)); ASSERT_CSP( (uint32) rxMbufRing & 0x0fffffff ); memset(rxMbufRing,0,userNeedRxMbufRingCnt * sizeof(uint32)); /* Allocate pkthdr */ pPkthdrList = (struct pktHdr *) UNCACHED_MALLOC( (totalRxPkthdrRingCnt + totalTxPkthdrRingCnt) * sizeof(struct pktHdr)); ASSERT_CSP( (uint32) pPkthdrList & 0x0fffffff ); memset(pPkthdrList,0, (totalRxPkthdrRingCnt + totalTxPkthdrRingCnt) * sizeof(struct pktHdr)); /* Allocate mbufs */ pMbufList = (struct mBuf *) UNCACHED_MALLOC( (rxMbufRingCnt + totalTxPkthdrRingCnt) * sizeof(struct mBuf)); ASSERT_CSP( (uint32) pMbufList & 0x0fffffff ); memset(pMbufList,0,((rxMbufRingCnt + totalTxPkthdrRingCnt) * sizeof(struct mBuf))); /* Allocate clusters */ pClusterList = (uint8 *) UNCACHED_MALLOC(rxMbufRingCnt * size_of_cluster + 8 - 1+2*rxMbufRingCnt); ASSERT_CSP( (uint32) pClusterList & 0x0fffffff ); memset(pClusterList,0,(rxMbufRingCnt * size_of_cluster + 8 - 1+2*rxMbufRingCnt)); pClusterList = (uint8*)(((uint32) pClusterList + 8 - 1) & ~(8 - 1)); /* Initialize interrupt statistics counter */ rxPktCounter = txPktCounter = 0; /* Initialize index of Tx pkthdr descriptor */ currTxPkthdrDescIndex = 0; txPktDoneDescIndex=0; /* Initialize Tx packet header descriptors */ for (i = 0; i < RTL865X_SWNIC_TXRING_MAX_PKTDESC; i++) { for (j = 0; j < txPkthdrRingCnt[i]; j++) { /* Dequeue pkthdr and mbuf */ pPkthdr = pPkthdrList++; pMbuf = pMbufList++; bzero((void *) pPkthdr, sizeof(struct pktHdr)); bzero((void *) pMbuf, sizeof(struct mBuf)); pPkthdr->ph_mbuf = pMbuf; pPkthdr->ph_len = 0; pPkthdr->ph_flags = PKTHDR_USED | PKT_OUTGOING; pPkthdr->ph_type = PKTHDR_ETHERNET; pPkthdr->ph_portlist = 0; pMbuf->m_next = NULL; pMbuf->m_pkthdr = pPkthdr; pMbuf->m_flags = MBUF_USED | MBUF_EXT | MBUF_PKTHDR | MBUF_EOR; pMbuf->m_data = NULL; pMbuf->m_extbuf = NULL; pMbuf->m_extsize = 0; txPkthdrRing[i][j] = (int32) pPkthdr | DESC_RISC_OWNED; #ifdef CONFIG_RTL8196C_SWITCH_PATCH #ifdef CONFIG_AUTO_IDENTIFY if (REG32(REVR) == RTL8196C_REVISION_A) txPkthdrRing_BAK[i][j]=(int32) pPkthdr | DESC_RISC_OWNED; #endif #endif } /* Set wrap bit of the last descriptor */ if (txPkthdrRingCnt[i] != 0) { txPkthdrRing[i][txPkthdrRingCnt[i] - 1] |= DESC_WRAP; #ifdef CONFIG_RTL8196C_SWITCH_PATCH #ifdef CONFIG_AUTO_IDENTIFY if (REG32(REVR) == RTL8196C_REVISION_A) txPkthdrRing_BAK[i][txPkthdrRingCnt[i] - 1] |= DESC_WRAP; #endif #endif } } /* Fill Tx packet header FDP */ REG32(CPUTPDCR0) = (uint32) txPkthdrRing[0]; REG32(CPUTPDCR1) = (uint32) txPkthdrRing[1]; /* Initialize index of current Rx pkthdr descriptor */ currRxPkthdrDescIndex = 0; /* Initialize index of current Rx Mbuf descriptor */ currRxMbufDescIndex = 0; /* Initialize Rx packet header descriptors */ k = 0; for (i = 0; i < RTL865X_SWNIC_RXRING_MAX_PKTDESC; i++) { for (j = 0; j < rxPkthdrRingCnt[i]; j++) { /* Dequeue pkthdr and mbuf */ pPkthdr = pPkthdrList++; pMbuf = pMbufList++; bzero((void *) pPkthdr, sizeof(struct pktHdr)); bzero((void *) pMbuf, sizeof(struct mBuf)); /* Setup pkthdr and mbuf */ pPkthdr->ph_mbuf = pMbuf; pPkthdr->ph_len = 0; pPkthdr->ph_flags = PKTHDR_USED | PKT_INCOMING; pPkthdr->ph_type = PKTHDR_ETHERNET; pPkthdr->ph_portlist = 0; pMbuf->m_next = NULL; pMbuf->m_pkthdr = pPkthdr; pMbuf->m_len = 0; pMbuf->m_flags = MBUF_USED | MBUF_EXT | MBUF_PKTHDR | MBUF_EOR; pMbuf->m_data = NULL; pMbuf->m_extsize = size_of_cluster; /*offset 2 bytes for 4 bytes align of ip packet*/ pMbuf->m_data = pMbuf->m_extbuf = (pClusterList+2); pClusterList += size_of_cluster; /* Setup descriptors */ rxPkthdrRing[i][j] = (int32) pPkthdr | DESC_SWCORE_OWNED; rxMbufRing[k++] = (int32) pMbuf | DESC_SWCORE_OWNED; } /* Set wrap bit of the last descriptor */ if (rxPkthdrRingCnt[i] != 0) rxPkthdrRing[i][rxPkthdrRingCnt[i] - 1] |= DESC_WRAP; } rxMbufRing[rxMbufRingCnt - 1] |= DESC_WRAP; /* Fill Rx packet header FDP */ REG32(CPURPDCR0) = (uint32) rxPkthdrRing[0]; REG32(CPURPDCR1) = (uint32) rxPkthdrRing[1]; REG32(CPURPDCR2) = (uint32) rxPkthdrRing[2]; REG32(CPURPDCR3) = (uint32) rxPkthdrRing[3]; REG32(CPURPDCR4) = (uint32) rxPkthdrRing[4]; REG32(CPURPDCR5) = (uint32) rxPkthdrRing[5]; REG32(CPURMDCR0) = (uint32) rxMbufRing; // for debug #if 0 /* Initialize ARP table */ bzero((void *) arptab, ARPTAB_SIZ * sizeof(struct arptab_s)); arptab_next_available = 0; #endif //dprintf("addr=%x, val=%x\r\n",(CPUIIMR),REG32(CPUIIMR)); /* Enable runout interrupts */ //REG32(CPUIIMR) |= RX_ERR_IE_ALL | TX_ERR_IE_ALL | PKTHDR_DESC_RUNOUT_IE_ALL; //8651c //REG32(CPUIIMR) = 0xffffffff; //RX_DONE_IE_ALL; // 0xffffffff; //wei test irq //*(volatile unsigned int*)(0xb8010028)=0xffffffff; //dprintf("eth0 CPUIIMR status=%x\r\n", *(volatile unsigned int*)(0xb8010028)); //ISR /* Enable Rx & Tx. Config bus burst size and mbuf size. */ //REG32(CPUICR) = TXCMD | RXCMD | BUSBURST_256WORDS | icr_mbufsize; //REG32(CPUICR) = TXCMD | RXCMD | BUSBURST_32WORDS | MBUF_2048BYTES; //8651c REG32(CPUICR) = TXCMD | RXCMD | BUSBURST_32WORDS | MBUF_2048BYTES; //wei test irq #ifdef CONFIG_RTL8196C_ETH_IOT REG32(CPUIIMR) = RX_DONE_IE_ALL | TX_DONE_IE_ALL | LINK_CHANGE_IE; #else REG32(CPUIIMR) = RX_DONE_IE_ALL | TX_DONE_IE_ALL; #endif REG32(MDCIOCR)=0x96181441; // enable Giga port 8211B LED //dprintf("eth0 CPUIIMR status=%x\r\n", *(volatile unsigned int*)(0xb8010028)); //ISR return SUCCESS; }