static void _ISR_HandlerRX(void * context, u_long intnum) { aCounter++; //testcounter a // Interrupt clearen und Run-Bit zurücksetzen IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_RX_BASE, ALTERA_AVALON_SGDMA_CONTROL_CLEAR_INTERRUPT_MSK & ~ALTERA_AVALON_SGDMA_CONTROL_RUN_MSK); // inform TCP/IP stack about new packet IP_OnRx(); bCounter++; //testcounter b } static int _ReadPacket(unsigned Unit, U8 *pDest, unsigned NumBytes) { volatile UInt32 ulPacketLengthFromSgdmaRX = 0x00, i = 0x00; volatile UChar8 * pRxBuff = NULL; cCounter++; //testcounter c ulPacketLengthFromSgdmaRX = pSgdmaDescriptor[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST].actual_bytes_transferred; if(IORD_ALTERA_TSEMAC_RX_CMD_STAT(TSE_MAC_BASE) & ALTERA_TSEMAC_RX_CMD_STAT_RXSHIFT16_MSK && ulRxPacketSize > 0) ulPacketLengthFromSgdmaRX -= 2; // when the shift option is used, the length read from the status word is 2 bytes larger than the real frame size, adjust counter! if(NumBytes == ulPacketLengthFromSgdmaRX) { /* test for errors */ if (((pSgdmaDescriptor[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST].status) & ( ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_CRC_MSK | // crc error ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_PARITY_MSK | // parity error ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_OVERFLOW_MSK | // overflow error ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_SYNC_MSK | // sync error ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_UEOP_MSK | // end of package error ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_MEOP_MSK | // end of package error ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_MSOP_MSK )) // start of package error == 0) { pRxBuff = pUncachedPtrRx + 2; // pointer to the first field, where the data begins while(NumBytes) // copy all data { pDest[i] = *pRxBuff++; i++; NumBytes--; } } } dCounter++; //testcounter d _ResetRx(); return 0; } static int _ResetRx(void) { volatile alt_u32 timeout=0, ulSgdmaCtrl = 0x00; eCounter++; //testcounter e /*SGDMA RX Softwarereset*/ IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_RX_BASE,ALTERA_AVALON_SGDMA_CONTROL_SOFTWARERESET_MSK); IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_RX_BASE,0); memset((void*) cRxBufferTmp, 0x00, BUFF_SIZE); memset((void*) &pSgdmaDescriptor [ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST], 0x00, sizeof(alt_sgdma_descriptor)); //pUncachedPtrRx = alt_remap_uncached((void*)cRxBufferTmp, BUFF_SIZE); /* rx-sgdma descriptor konstruieren */ alt_avalon_sgdma_construct_stream_to_mem_desc ((alt_sgdma_descriptor *) &pSgdmaDescriptor [ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST], // descriptor I want to work with (alt_sgdma_descriptor *) &pSgdmaDescriptor [ALTERA_TSE_SECOND_RX_SGDMA_DESC_OFST], // pointer to "next" (UInt32 *)pUncachedPtrRx, // starting write_address 0, // read until EOP 0); // don't write to constant address /* register callback for rx-sgdma */ alt_avalon_sgdma_register_callback ((alt_sgdma_dev *) pRxSgdmaDev, (alt_avalon_sgdma_callback) &_ISR_HandlerRX, /* callbackfunction for the interrupt */ (ALTERA_AVALON_SGDMA_CONTROL_IE_GLOBAL_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK), /* interrupt if chain completed */ NULL); /* Make sure SGDMA controller is not busy from a former command */ while ((IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_RX_BASE) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK)) { if(timeout++ == ALTERA_TSE_SGDMA_BUSY_TIME_OUT_CNT) return ENP_RESOURCE; // avoid being stuck here } IOWR_ALTERA_AVALON_SGDMA_STATUS(SGDMA_RX_BASE, 0xff); //clear status register (look at documentation of sgdma status reg) /* SGDMA operation invoked for RX (non-blocking call) */ if(alt_avalon_sgdma_do_async_transfer((alt_sgdma_dev *) pRxSgdmaDev, (alt_sgdma_descriptor *) &pSgdmaDescriptor [ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST]) != 0) return -1; ulSgdmaCtrl = IORD_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_RX_BASE); // read SGDMA Ctrl Register IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_RX_BASE, ulSgdmaCtrl | ALTERA_TSE_SGDMA_INTR_MASK); //write SGDMA Ctrl Regs fCounter++; //testcounter f return 0; }