int32 swNic_rxRunoutTxPending(struct rtl_pktHdr *pPkthdr){ //exception handling struct rtl_pktHdr *freePkthdrListHead, *freePkthdrListTail; struct rtl_mBuf *freeMbufListHead, *freeMbufListTail; uint32 wrap=0; rtlglue_printf("Desc %d (ph: %08x): Rx runout by pending Tx\n", rxPhdrIndex,(uint32)pPkthdr ); pPkthdr->ph_rxdesc = totalRxPkthdr; if (rxPhdrIndex==totalRxPkthdr-1) wrap=0x2; if ((mBuf_driverGetPkthdr(1, &freePkthdrListHead, &freePkthdrListTail))!=1){ rtlglue_printf("No more pkthdr. runout NOT solved!!\n"); return FAILED; } if(1!=mBuf_driverGet(1, &freeMbufListHead, &freeMbufListTail)){ rtlglue_printf("No more mbuf. runout NOT solved!!\n"); mBuf_driverFreePkthdr(freePkthdrListHead, 1, 0); return FAILED; } #ifndef CONFIG_RTL865X_CACHED_NETWORK_IO freeMbufListHead->m_extbuf=(uint8 *)UNCACHE(freeMbufListHead->m_extbuf); freeMbufListHead->m_data=(uint8 *)UNCACHE(freeMbufListHead->m_data); #endif #if defined(CONFIG_RTL865X_MBUF_HEADROOM)&&defined(CONFIG_RTL865X_MULTILAYER_BSP) if(mBuf_reserve(freeMbufListHead, CONFIG_RTL865X_MBUF_HEADROOM)) rtlglue_printf("Failed when init Rx %d\n", rxPhdrIndex); #endif freePkthdrListHead->ph_flags&=~PKTHDR_DRIVERHOLD; RxMbufRing[rxPhdrIndex] = (uint32) freeMbufListHead | DESC_SWCORE_OWNED|wrap; RxPkthdrRing[rxPhdrIndex] = (uint32) freePkthdrListHead | DESC_SWCORE_OWNED | wrap; return SUCCESS; }
void dma_nand_set_wait(void *tar,unsigned char src,unsigned int size) { unsigned int setdata[16]; unsigned int *ptemp; ptemp = (unsigned int *)UNCACHE(((unsigned int)(&setdata)+ 31)& (~31)); *ptemp = (unsigned int) ((src << 24) | (src << 16) | (src << 8) | src); if(((unsigned int)tar < 0xa0000000) && size) dma_cache_wback_inv((unsigned long)tar, size); CLRREG32(A_DMA_DCS(DMA_NAND_COPY_CHANNEL), DCS_CTE); OUTREG32(A_DMA_DSA(DMA_NAND_COPY_CHANNEL), PHYSADDR((unsigned long)ptemp)); OUTREG32(A_DMA_DTA(DMA_NAND_COPY_CHANNEL), PHYSADDR((unsigned long)tar)); OUTREG32(A_DMA_DTC(DMA_NAND_COPY_CHANNEL), size / 32); OUTREG32(A_DMA_DRT(DMA_NAND_COPY_CHANNEL), DRT_AUTO); OUTREG32(A_DMA_DCM(DMA_NAND_COPY_CHANNEL),(DCM_DAI | DCM_SP_32BIT | DCM_DP_32BIT| DCM_TSZ_32BYTE)); CLRREG32(A_DMA_DCS(DMA_NAND_COPY_CHANNEL),(DCS_TT)); SETREG32(A_DMA_DCS(DMA_NAND_COPY_CHANNEL), DCS_CTE | DCS_NDES); while (!(INREG32(A_DMA_DCS(DMA_NAND_COPY_CHANNEL)) & DCS_TT)); }
void jz_nand_hardware_test_speed (void) { nand_page_info_t *info; unsigned char *pucinfo; unsigned int page,blockid; unsigned char *data_ptr; unsigned char *dataread_ptr; unsigned int *mybuffer; unsigned int *mybufferread; unsigned char *mask; unsigned int k,i, j; unsigned long ulTimeStart = 0,ulTimeEnd = 0,ulTime =0,ulSpeed =0; jz_nand_init(); //data_ptr = (unsigned char *)alloc(BLOCK_SIZE); data_ptr = (unsigned char *)UNCACHE(data_buf); dataread_ptr = (unsigned char *)alloc(BLOCK_SIZE); mask = (unsigned char *)alloc(CONFIG_SSFDC_NAND_PAGE_PER_BLOCK); pucinfo = (unsigned char *)alloc(CONFIG_SSFDC_NAND_PAGE_PER_BLOCK * 128); mybuffer = (unsigned int *)data_ptr; mybufferread = (unsigned int *)dataread_ptr; info = (nand_page_info_t *)pucinfo; page = blockid * CONFIG_SSFDC_NAND_PAGE_PER_BLOCK; memset(pucinfo, 0x0, 128 * CONFIG_SSFDC_NAND_PAGE_PER_BLOCK); for(k = 0;k < BLOCK_SIZE/4;k++) mybuffer[k] =k+1; //jz_nand_speed_mode(1); /////////////////////test speed and time//////////////////////////// #if 1 for (j =0 ; j<20; j++) { blockid = 512; for(k = 0;k< 10; k++) { jz_nand_erase_block(0,(blockid + k)); } memset(pucinfo, 0x0, 128 * CONFIG_SSFDC_NAND_PAGE_PER_BLOCK); page = blockid * CONFIG_SSFDC_NAND_PAGE_PER_BLOCK; memset(mask, 0xF, CONFIG_SSFDC_NAND_PAGE_PER_BLOCK); #if 1 Init_PerformanceCounter(); ulTimeEnd = Get_PerformanceCounter(); ulTimeStart = ulTimeEnd; #endif for(k = 0;k< 10; k++) { jz_nand_multiwrite(0, page, CONFIG_SSFDC_NAND_PAGE_PER_BLOCK, mask, data_ptr, info); page += CONFIG_SSFDC_NAND_PAGE_PER_BLOCK; } #if 1 ulTimeEnd = Get_PerformanceCounter(); ulTime = (ulTimeEnd - ulTimeStart)/ 6000; ulSpeed = (BLOCK_SIZE*10) / ulTime;// KB/S printf("%d %d\n", ulSpeed,ulTime); #endif } printf("write over!\n"); #endif #if 1 for (j =0 ; j<20; j++) { blockid = 512; page = blockid * CONFIG_SSFDC_NAND_PAGE_PER_BLOCK; memset(pucinfo, 0x0, 128 * CONFIG_SSFDC_NAND_PAGE_PER_BLOCK); memset(mask, 0x0, CONFIG_SSFDC_NAND_PAGE_PER_BLOCK); #if 1 Init_PerformanceCounter(); ulTimeEnd = Get_PerformanceCounter(); ulTimeStart = ulTimeEnd; #endif for(k = 0;k<10; k++) { jz_nand_multiread(0, page, CONFIG_SSFDC_NAND_PAGE_PER_BLOCK, mask, dataread_ptr, info); page += CONFIG_SSFDC_NAND_PAGE_PER_BLOCK; memset(mask, 0x0, CONFIG_SSFDC_NAND_PAGE_PER_BLOCK); } #if 1 ulTimeEnd = Get_PerformanceCounter(); ulTime = (ulTimeEnd - ulTimeStart)/ 6000; ulSpeed = (BLOCK_SIZE*10) / ulTime;// KB/S printf(" %d %d\n", ulSpeed,ulTime); #endif } #endif unsigned char *tempbuf = dataread_ptr;//pucinfo; for(k = 0;k < 512/8; k++) printf("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",*tempbuf++,*tempbuf++,*tempbuf++,*tempbuf++,*tempbuf++,*tempbuf++,*tempbuf++,*tempbuf++); printf("\r\nTest OK!jlv\r\n"); while (1); /*for(k = 0;k < BLOCK_SIZE / 8; k++) { if (k != mybufferread[k] )//*data_ptr++ != *dataread_ptr++ ) { printf("read sector data error, k = %d,data_ptr[0x%x],dataread_ptr[0x%x]\r\n",k,*(--data_ptr),*(--dataread_ptr)); while (1); } } */ }
int32 swNic_setup(uint32 pkthdrs, uint32 mbufs, uint32 txpkthdrs) { struct rtl_pktHdr *freePkthdrListHead,*freePkthdrListTail; struct rtl_mBuf *freeMbufListHead, *freeMbufListTail; int i; /* Disable Rx & Tx ,bus burst size, etc */ swNic_txRxSwitch(0,0); #ifdef SWNIC_EARLYSTOP nicRxEarlyStop=0; #endif /* Initialize index of Tx pkthdr descriptor */ txDoneIndex = 0; txFreeIndex = 0; /* Allocate rx pkthdrs */ if(pkthdrs!=mBuf_driverGetPkthdr(pkthdrs, &freePkthdrListHead, &freePkthdrListTail)){ rtlglue_printf("Can't allocate all pkthdrs\n"); return EINVAL; } assert(freePkthdrListHead); assert(freePkthdrListTail); /* Allocate rx mbufs and clusters */ if(mbufs!=mBuf_driverGet(mbufs, &freeMbufListHead, &freeMbufListTail)){ rtlglue_printf("Can't allocate all mbuf/clusters\n"); return EINVAL; } assert(freeMbufListHead); assert(freeMbufListTail); ///////////////////////////////////////////////// /* Initialize Tx packet header descriptors */ for (i=0; i<txpkthdrs; i++) TxPkthdrRing[i] = DESC_RISC_OWNED; /* Set wrap bit of the last descriptor */ TxPkthdrRing[txpkthdrs - 1] |= DESC_WRAP; /* Fill Tx packet header FDP */ REG32(CPUTPDCR) = (uint32) TxPkthdrRing; ///////////////////////////////////////////////// /* Initialize index of current Rx pkthdr descriptor */ rxPhdrIndex = 0; /* Initialize Rx packet header descriptors */ for (i=0; i<pkthdrs; i++) { assert( freePkthdrListHead ); RxPkthdrRing[i] = (uint32) freePkthdrListHead | DESC_SWCORE_OWNED; if ( (freePkthdrListHead = freePkthdrListHead->ph_nextHdr) == NULL ) freePkthdrListTail = NULL; } /* Set wrap bit of the last descriptor */ RxPkthdrRing[pkthdrs - 1] |= DESC_WRAP; /* Fill Rx packet header FDP */ REG32(CPURPDCR) = (uint32) RxPkthdrRing; ///////////////////////////////////////////////// /* Initialize index of current Rx pkthdr descriptor */ rxMbufIndex = 0; /* Initialize Rx mbuf descriptors */ for (i=0; i<mbufs; i++) { assert( freeMbufListHead ); RxMbufRing[i] = (uint32) freeMbufListHead | DESC_SWCORE_OWNED; #ifndef CONFIG_RTL865X_CACHED_NETWORK_IO freeMbufListHead->m_extbuf=(uint8 *)UNCACHE(freeMbufListHead->m_extbuf); freeMbufListHead->m_data=(uint8 *)UNCACHE(freeMbufListHead->m_data); #endif #if defined(CONFIG_RTL865X_MBUF_HEADROOM)&&defined(CONFIG_RTL865X_MULTILAYER_BSP) if(mBuf_reserve(freeMbufListHead, CONFIG_RTL865X_MBUF_HEADROOM)) rtlglue_printf("Failed when init Rx %d\n", i); #endif if ( (freeMbufListHead = freeMbufListHead->m_next) == NULL ) freeMbufListTail = NULL; } /* Set wrap bit of the last descriptor */ RxMbufRing[mbufs - 1] |= DESC_WRAP; /* Fill Rx mbuf FDP */ REG32(CPURMDCR) = (uint32) RxMbufRing; REG32(CPUICR) =0; #ifdef CONFIG_RTL865XB { char chipVersion[16]; uint32 align=0; REG32(CPUICR)|=EXCLUDE_CRC; GetChipVersion(chipVersion, sizeof(chipVersion), NULL); if(chipVersion[strlen(chipVersion)-1]=='B') { //865xB chips support free Rx align from 0~256 bytes #ifdef SWNIC_RX_ALIGNED_IPHDR align+=2; #endif REG32(CPUICR)|=align; rtlglue_printf("Rx shift=%x\n",REG32(CPUICR)); } } #endif /* Enable Rx & Tx. Config bus burst size and mbuf size. */ REG32(CPUICR) |= BUSBURST_32WORDS | MBUF_2048BYTES; REG32(CPUIIMR) |= LINK_CHANG_IE; swNic_txRxSwitch(1,1); return SUCCESS; }
__IRAM static int32 _swNic_recvLoop(int32 last){ volatile struct rtl_pktHdr * pPkthdr; //don't optimize volatile struct rtl_mBuf * pMbuf; //don't optimize int32 count=0; do{ #ifdef CONFIG_RTL865X_ROMEPERF rtl8651_romeperfEnterPoint(ROMEPERF_INDEX_RECVLOOP); #endif /* Increment counter */ if((RxPkthdrRing[rxPhdrIndex]&DESC_OWNED_BIT)==1){ goto out; } #ifdef SWNIC_EARLYSTOP if(nicRxEarlyStop && ((count & nicRxEarlyStop)==nicRxEarlyStop)){//check global interrupt status uint32 gisrNow = REG32(GISR); if(gisrNow & 0x65000000){ //Bit 30: USB, Bit 29:PCMCIA, Bit 26: PCI, Bit 24:GPIO nicRxAbort=1; goto out; } } #endif #ifdef CONFIG_RTL865X_CACHED_NETWORK_IO #if 0 /*Invalidate D-Cache*/ lx4180_writeCacheCtrl(0); lx4180_writeCacheCtrl(1); lx4180_writeCacheCtrl(0); pPkthdr = (struct rtl_pktHdr *) (RxPkthdrRing[rxPhdrIndex] & ~(DESC_OWNED_BIT | DESC_WRAP)); pMbuf = pPkthdr->ph_mbuf; #else pPkthdr = (struct rtl_pktHdr *) (RxPkthdrRing[rxPhdrIndex] & ~(DESC_OWNED_BIT | DESC_WRAP)); pMbuf = pPkthdr->ph_mbuf; //force update d-cache if hit. src32=(uint32 *)UNCACHE(pPkthdr); dst32=(uint32 *)CACHED(pPkthdr); dst32[0]=src32[0]; dst32[1]=src32[1]; dst32[2]=src32[2]; dst32[3]=src32[3]; src32=(uint32 *)UNCACHE(pMbuf); dst32=(uint32 *)CACHED(pMbuf); dst32[0]=src32[0]; dst32[1]=src32[1]; dst32[2]=src32[2]; dst32[3]=src32[3]; //pkt from ASIC, convert to uncached data pointer for used in //fwd engine pMbuf->m_data=UNCACHE(pMbuf->m_data); pMbuf->m_extbuf=UNCACHE(pMbuf->m_extbuf); #endif #else pPkthdr = (struct rtl_pktHdr *) (RxPkthdrRing[rxPhdrIndex] & ~(DESC_OWNED_BIT | DESC_WRAP)); pMbuf = pPkthdr->ph_mbuf; #endif //CONFIG_RTL865X_CACHED_NETWORK_IO #ifdef CONFIG_RTL865XB_EXP_PERFORMANCE_EVALUATION if(_pernicStart == TRUE){ static uint32 start, end; if(!_pernicPktCount){ startCOP3Counters(_pernicInst); start = jiffies; } else if(_pernicPktCount == _pernicPktLimit){ end = jiffies; stopCOP3Counters(); printk("%d pkts. Total %d bytes, %d ms. %u KBps\n", _pernicPktCount, _pernicByteCount, (uint32)((end-start)*10), (uint32)(_pernicByteCount/((end-start)*10))); _pernicStart = FALSE; } _pernicPktCount++; _pernicByteCount += pPkthdr->ph_len + 4; swNic_isrReclaim(rxPhdrIndex, pPkthdr, pMbuf); /* Increment index */ if ( ++rxPhdrIndex == totalRxPkthdr ) rxPhdrIndex = 0; if ( ++rxMbufIndex == totalRxMbuf ) rxMbufIndex = 0; continue; } #endif assert(pPkthdr->ph_len>0); if((pPkthdr->ph_flags&PKTHDR_DRIVERHOLD)==0){ //exception handling swNic_rxRunoutTxPending((struct rtl_pktHdr *)pPkthdr); goto out; } count++; //SETBITS(pPkthdr->ph_flags, PKT_INCOMING); //packet from physical port pPkthdr->ph_rxdesc=rxPhdrIndex; pPkthdr->ph_flags&=~PKTHDR_DRIVERHOLD; //Transform extension port numbers to continuous number for fwd engine. #ifdef CONFIG_RTL865X_MULTILAYER_BSP //Default run this except L2 BSP. //must call this API after rxPhdrIndex is assigned... if(rtl8651_rxPktPreprocess(pPkthdr)){ rtlglue_printf("Drop rxDesc=%d\n",rxPhdrIndex ); //memDump(pPkthdr->ph_mbuf->m_data, pPkthdr->ph_len,"Loopback Pkt"); swNic_isrReclaim(rxPhdrIndex, pPkthdr, pMbuf); }else #endif { #ifdef CONFIG_RTL865X_ROMEREAL rtl8651_romerealRecord( pPkthdr, 0x00000001 ); #endif/*CONFIG_RTL865X_ROMEREAL*/ /* Invoked installed function pointer to handle packet */ (*installedProcessInputPacket)((struct rtl_pktHdr*)pPkthdr); } #ifdef SWNIC_DEBUG assert(rxPhdrIndex==rxMbufIndex); #endif /* Increment index */ if ( ++rxPhdrIndex == totalRxPkthdr ) rxPhdrIndex = 0; if ( ++rxMbufIndex == totalRxMbuf ) rxMbufIndex = 0; }while(last>=0&&rxPhdrIndex!=last); out: return count; }