void MACPut(int8 val) { NICPut(RBCR0, 1); NICPut(RBCR1, 0); NICPut(CMDR, 0x12); NICPut(NIC_DATAPORT, val); }
int8 MACGet(void) { NICPut(RBCR0, 1); NICPut(RBCR1, 0); NICPut(CMDR, 0x0a); return NICGet(NIC_DATAPORT); }
void NICSetAddr(int16 addr) { WORD_VAL t; t.Val = addr; NICPut(ISR, 0x40); NICPut(RSAR0, t.v[0]); NICPut(RSAR1, t.v[1]); }
void MACDiscardRx(void) { int8 newBoundary; newBoundary = NICReadPtr - 1; if ( newBoundary < RXSTART ) newBoundary = RXSTOP - 1; NICPut(CMDR, 0x20); // Select PAGE 0 NICPut(BNRY, newBoundary); }
void NICSetAddr(WORD addr) { WORD_VAL t; //The DMAAddr variable keeps track of the Remote DMA current address. Reads or writes to the //Remote DMA will access this address, and increment it when done. DMAAddr.Val = addr; //Set the RSAR (Remote start address) registers to point to given address. This is the address //of the RAM that will be accessed with subsequent read/write operations. t.Val = addr; //NICPut(ISR, 0x40); //ISR bit 6 is set when Remote DMA has completed - why is it set here??? NICPut(RSAR0, t.v[0]); NICPut(RSAR1, t.v[1]); }
int1 MACIsLinked(void) { int8 temp; // Select Page 3 NICPut(CMDR, 0xe0); // Read CONFIG0. temp = NICGet(0x03); // Reset to page 0. NICPut(CMDR, 0x20); // Bit 2 "BNC" will be '0' if LINK is established. return (!bit_test(temp,2)); }
/** * Check if the MAC is linked * * @return TRUE if linked, else FALSE */ BOOL MACIsLinked(void) { BYTE_VAL temp; // Select Page 3 NICPut(CMDR, 0xe0); // Read CONFIG0. temp.Val = NICGet(0x03); // Reset to page 0. NICPut(CMDR, 0x20); // Bit 2 "BNC" will be '0' if LINK is established. return (temp.bits.b2 == 0); }
/** * This function writes the MAC header (Ethernet header) part of a packet that * has to be transmitted to the current TX buffer (page in NIC RAM). * After this function, the data must still be written to the TX buffer. * After both header and data has been written, bits are set to instruct * NIC to transmit transmit buffer. This function does the following: <ul> * <li> Reset the NIC Remote DMA write pointer to the first byte of the current TX Buffer </li> * <li> Write the given header to the current TX Buffer </li> * <li> Set the NIC Remote DMA byte count to the given len. This configures the * Remote DMA to receive the given number of bytes. </li></ul> * * @param[out] remote Pointer to a MAC_ADDR structure. This function will write the MAC address of the * node who sent this packet to this structure * @param type Type of header. Can be ETHER_IP, ETHER_ARP or MAC_UNKNOWN * @param dataLen Size of the Data of this Ethernet packet. A Ethernet packet consists of: <br> * - 6 Bytes = Desitination MAC address <br> * - 6 Bytes = Source MAC address <br> * - 2 Bytes = Type field, currently only IP or ARP <br> * - n Bytes = Data. Minimum length of 46 bytes <br><br> * The data will be written to the TX buffer following this command. * * @return True if header was read, False if not */ void MACPutHeader(MAC_ADDR *remote, BYTE type, WORD dataLen) { WORD_VAL mytemp; BYTE etherType; NICPut(ISR, 0x0a); //Set the address of the current Remote DMA. This is the address that all future MACPut() //functions will write data to in the current TX Buffer. This address is set to the start //address of the current MAC TX Buffer. The current TX Buffer will thus point to the first //byte in the packet that will be transmitted = first byte of Ethernet header mytemp.v[1] = TxBuffers[MACCurrTxbuf].Index; mytemp.v[0] = 0; NICSetAddr(mytemp.Val); ///////////////////////////////////////////////// //Write Ethernet header part (MAC header) = Dest MAC Adrr, Source MAC Adr, Type MACPutArray((BYTE*)remote, sizeof(*remote)); MACPut(MY_MAC_BYTE1); MACPut(MY_MAC_BYTE2); MACPut(MY_MAC_BYTE3); MACPut(MY_MAC_BYTE4); MACPut(MY_MAC_BYTE5); MACPut(MY_MAC_BYTE6); if ( type == MAC_IP ) etherType = ETHER_IP; else etherType = ETHER_ARP; MACPut(0x08); MACPut(etherType); dataLen += (WORD)sizeof(ETHER_HEADER); //If datalength smaller than minimum Ethernet packet (not including CRC), pad till minimum size if ( dataLen < MINFRAME ) dataLen = MINFRAME; mytemp.Val = dataLen; NICPut(TBCR0, mytemp.v[0]); NICPut(TBCR1, mytemp.v[1]); }
void MACPutHeader(MAC_ADDR *remote, int8 type, int16 dataLen) { WORD_VAL mytemp; int8 etherType; NICPut(ISR, 0x0a); mytemp.v[1] = TxBuffers[NICCurrentTxBuffer].Index; mytemp.v[0] = 0; NICSetAddr(mytemp.Val); // MACPutArray((int8*)remote, sizeof(*remote)); MACPutArray(remote, sizeof(MAC_ADDR)); debug(debug_putc,"\r\n\r\nMACPUTHEADER: DA:%X.%X.%X.%X.%X.%X T=%X L=%LX", remote->v[0],remote->v[1],remote->v[2],remote->v[3],remote->v[4],remote->v[5],type,datalen); MACPut(MY_MAC_BYTE1); MACPut(MY_MAC_BYTE2); MACPut(MY_MAC_BYTE3); MACPut(MY_MAC_BYTE4); MACPut(MY_MAC_BYTE5); MACPut(MY_MAC_BYTE6); if ( type == MAC_IP ) etherType = ETHER_IP; else etherType = ETHER_ARP; MACPut(0x08); MACPut(etherType); dataLen += (int16)sizeof(ETHER_HEADER); if ( dataLen < MINFRAME ) // 64 ) // NKR 4/23/02 dataLen = 64; // MINFRAME; mytemp.Val = dataLen; NICPut(TBCR0, mytemp.v[0]); NICPut(TBCR1, mytemp.v[1]); }
void MACFlush(void) { int8 i; NICPut(TPSR, TxBuffers[NICCurrentTxBuffer].Index); NICPut(CMDR, 0x24); // After every transmission, adjust transmit pointer to // next free transmit buffer. for ( i = 0; i < MAX_DATA_BUFFERS; i++ ) { if ( TxBuffers[i].bFree ) { NICCurrentTxBuffer = i; return; } } }
int16 MACGetFreeRxSize(void) { int8 NICWritePtr; int8 temp; WORD_VAL tempVal; NICPut(CMDR, 0x60); NICWritePtr = NICGet(CURRP); NICPut(CMDR, 0x20); if ( NICWritePtr < NICCurrentRdPtr ) temp = (RXSTOP - NICCurrentRdPtr) + NICWritePtr; else temp = NICWritePtr - NICCurrentRdPtr; temp = RXPAGES - temp; tempVal.v[1] = temp; tempVal.v[0] = 0; return tempVal.Val; }
/** * Initializes registers that should have been initialized with the contents * of the EEPROM * * @preCondition Must be called after chip is initialized * */ void MACInitEepromRegs(void) { // Select Page 3 NICPut(CMDR, 0xe0); //Because the EEPROM read pin is floating on some boards, the registers initialized by the //EEPROM will all contain non defined values. Write them with correct values NICPut(RTL9346CR, 0xc0); //Config register write enable NICPut(RTLCONF1, 0x00); //Interrupt disable NICPut(RTL9346CR, 0xc0); //Config register write enable NICPut(RTLCONF2, 0x00); //TP/CX link test enabled (10BaseT link test is enabled) NICPut(RTL9346CR, 0xc0); //Config register write enable NICPut(RTLCONF3, 0x00); //Not sleep mode, Not powerdown mode NICPut(RTL9346CR, 0x00); //Normal operating mode //Reset to default = Page 0 NICPut(CMDR, 0x20); }
int16 MACGetArray(int8 *val, int16 len) { WORD_VAL t; t.Val = len; NICPut(ISR, 0x40); NICPut(RBCR0, t.v[0]); NICPut(RBCR1, t.v[1]); NICPut(CMDR, 0x0a); debug("\r\nMACGETARRAY: "); while( len-- > 0 ) { *val++ = NICGet(NIC_DATAPORT); debug("%X ",*(val-1)); } return t.Val; }
/** * This function returns total receive buffer size available for future data packets. */ WORD MACGetFreeRxSize(void) { BYTE NICWritePtr; //CURR register - RX buffer's PUT pointer BYTE temp; WORD_VAL tempVal; //Read current page pointer - Curr is the RX Buffer's PUT pointer NICPut(CMDR, 0x60); //Set page 1 NICWritePtr = NICGet(CURRP); //Curr is the RX Buffer's PUT pointer NICPut(CMDR, 0x20); //Reset to page 0 if ( NICWritePtr < MACCurrRxbuf ) temp = (RXSTOP - MACCurrRxbuf) + NICWritePtr; else temp = NICWritePtr - MACCurrRxbuf; temp = RXPAGES - temp; tempVal.v[1] = temp; tempVal.v[0] = 0; return tempVal.Val; }
void MACPutArray(int8 *val, int16 len) { WORD_VAL t; t.Val = len + (len & 1); debug("\r\nMACPUTARRAY %LX: ",len); NICPut(ISR, 0x40); NICPut(RBCR0, t.v[0]); NICPut(RBCR1, t.v[1]); NICPut(CMDR, 0x12); // index bug corrected RJS 8/3/04 while ( t.val-- > 0 ) { NICPut(NIC_DATAPORT, *val++); debug("%X ",*(val-1)); } // Make sure that DMA is complete. len = 255; while( len && (NICGet(ISR) & 0x40) == 0 ) len--; }
/** * Flush the MAC - transmit the current TX buffer */ void MACFlush(void) { BYTE i; //Configure to send a packet. To configure the NIC to send a packet, 3 registers have to //be set: // - TPSR: This gives the NIC RAM page of the packet to send // - TBCR0 & 1: These two resisters give the size of the packet to transmit NICPut(TPSR, TxBuffers[MACCurrTxbuf].Index); NICPut(CMDR, 0x24); // After every transmission, adjust transmit pointer to // next free transmit buffer. for ( i = 0; i < MAX_DATA_BUFFERS; i++ ) { if ( TxBuffers[i].bFree ) { MACCurrTxbuf = i; return; } } }
/** * Discard the contents of the current RX buffer. */ void MACRxbufDiscard(void) { BYTE newBoundary; WORD_VAL t; //Read the "Next Packet Pointer" from current MAC RX buffer. The first 4 bytes of the current //buffer contains the status, next packet pointer and length bytes. //Set t.v[1] = MACCurrRxbuf; //Page poiner to current MAC Rx Buffer t.v[0] = 1; //"Next packet pointer" is second byte of packet NICSetAddr(t.Val); newBoundary = MACRxbufGet(); //Update BNRY pointer with new value - this will remove current MAC RX Buffer from ring! //NICPut(CMDR, 0x20); // Select PAGE 0, Abort remote DMA NICPut(BNRY, newBoundary); //BNRY is the receive buffer's GET pointer return; }
void MACInit(void) { int8 i; // On Init, all transmit buffers are free. for ( i = 0; i < MAX_DATA_BUFFERS; i++ ) { TxBuffers[i].Index = TXSTART + (i * (MAC_TX_BUFFER_SIZE/NIC_PAGE_SIZE)); TxBuffers[i].bFree = TRUE; } NICCurrentTxBuffer = 0; NICReset(); delay_ms(2); NICPut(NIC_RESET, NICGet(NIC_RESET)); delay_ms(2); // mimimum Delay of 1.6 ms // Continue only if reset state is entered. if ( (NICGet(ISR) & 0x80) != 0 ) { // Select Page 0 NICPut(CMDR, 0x21); delay_ms(2); // Initialize Data Configuration Register NICPut(DCR, DCRVAL); // Clear Remote Byte Count Registers NICPut(RBCR0, 0); NICPut(RBCR1, 0); // Initialize Receive Configuration Register NICPut(RCR, 0x04); // Place NIC in LOOPBACK mode 1 NICPut(TCR, 0x02); // Initialize Transmit buffer queue NICPut(TPSR, TxBuffers[NICCurrentTxBuffer].Index); // Initialize Receive Buffer Ring NICPut(PSTART, RXSTART); NICPut(PSTOP, RXSTOP); NICPut(BNRY, (BYTE)(RXSTOP-1)); // Initialize Interrupt Mask Register // Clear all status bits NICPut(ISR, 0xff); // No interrupt enabled. NICPut(IMR, 0x00); // Select Page 1 NICPut(CMDR, 0x61); // Initialize Physical Address Registers NICPut(PAR0, MY_MAC_BYTE1); NICPut(PAR0+1, MY_MAC_BYTE2); NICPut(PAR0+2, MY_MAC_BYTE3); NICPut(PAR0+3, MY_MAC_BYTE4); NICPut(PAR0+4, MY_MAC_BYTE5); NICPut(PAR0+5, MY_MAC_BYTE6); // Initialize Multicast registers for ( i = 0; i < 8; i++ ) NICPut(MAR0+i, 0xff); // Initialize CURRent pointer NICPut(CURRP, RXSTART); // Remember current receive page NICReadPtr = RXSTART; // Page 0, Abort Remote DMA and Activate the transmitter. NICPut(CMDR, 0x22); // Set Normal Mode NICPut(TCR, 0x00); } }
int1 MACGetHeader(MAC_ADDR *remote, int8* type) { NE_PREAMBLE header; int8 NICWritePtr; WORD_VAL temp; *type = MAC_UNKNOWN; // Reset NIC if overrun has occured. if ( NICGet(ISR) & 0x10 ) { #if 1 NICPut(CMDR, 0x21); Delay(0xff); NICPut(RBCR0, 0); NICPut(RBCR1, 0); NICPut(TCR, 0x02); NICPut(CMDR, 0x20); MACDiscardRx(); NICPut(ISR, 0xff); NICPut(TCR, 0x00); return FALSE; #else MACInit(); return FALSE; #endif } NICPut(CMDR, 0x60); NICWritePtr = NICGet(CURRP); NICPut(CMDR, 0x20); if ( NICWritePtr != NICReadPtr ) { temp.v[1] = NICReadPtr; temp.v[0] = 0; NICSetAddr(temp.Val); //MACGetArray((int8*)&header, sizeof(header)); debug("\r\n***************************************\r\n"); MACGetArray(&header, sizeof(NE_PREAMBLE)); debug(debug_putc,"\r\n\r\nGOT HDR = ST:%X NPP:%X LEN:%LU", (int8)header.Status,header.NextPacketPointer,header.ReceivedBytes); debug(debug_putc,"\r\n DEST: %X.%X.%X.%X.%X.%X SRC: %X.%X.%X.%X.%X.%X TYPE:%LX", header.DestMACAddr.v[0],header.DestMACAddr.v[1],header.DestMACAddr.v[2], header.DestMACAddr.v[3],header.DestMACAddr.v[4],header.DestMACAddr.v[5], header.SourceMACAddr.v[0],header.SourceMACAddr.v[1],header.SourceMACAddr.v[2], header.SourceMACAddr.v[3],header.SourceMACAddr.v[4],header.SourceMACAddr.v[5], header.Type.Val); // Validate packet length and status. if ( header.Status.PRX && (header.ReceivedBytes >= MINFRAMEC) && (header.ReceivedBytes <= MAXFRAMEC) ) { debug(debug_putc," VALID"); header.Type.Val = swaps(header.Type.Val); //memcpy((char*)remote->v, (char*)header.SourceMACAddr.v, sizeof(*remote)); memcpy(&remote->v[0], &header.SourceMACAddr.v[0], sizeof(MAC_ADDR)); if ( (header.Type.v[1] == 0x08) && ((header.Type.v[0] == ETHER_IP) || (header.Type.v[0] == ETHER_ARP)) ) *type = header.Type.v[0]; } NICCurrentRdPtr = NICReadPtr; NICReadPtr = header.NextPacketPointer; return TRUE; } return FALSE; }
void MACInit(void) { BYTE i; /* SBC45EC - use port B*/ #if defined(BRD_SBC44EC) TRISB = 0xe0; //RB0-4 are outputs //NIC_DISABLE_IOCHRDY can be defined if the MAC should NOT use the IOCHRDY signal on the RTL8019AS chip. // - For SBC44EC PIC port pin B5 will be available for user IO. Solder jumper SJ5 must be opened! #if !defined(NIC_DISABLE_IOCHRDY) NIC_IOCHRDY_TRIS = 1; //IOCHRDY is an input #endif /* SBC45EC - use port A*/ #elif defined(BRD_SBC45EC) TRISA = 0xd0; //RA0-3 and RA5 are outputs //NIC_DISABLE_IOCHRDY can be defined if the MAC should NOT use the IOCHRDY signal on the RTL8019AS chip. // - For SBC45EC PIC port pin A4 will be available for user IO. Solder jumper SJ5 must be opened! #if !defined(NIC_DISABLE_IOCHRDY) NIC_IOCHRDY_TRIS = 1; //IOCHRDY is an input #endif /* SBC65EC - use port E*/ #elif defined(BRD_SBC65EC) TRISE = 0x00; //RE0-7 are outputs //NIC_DISABLE_IOCHRDY can be defined if the MAC should NOT use the IOCHRDY signal on the RTL8019AS chip. // - For SBC65EC and SBC68EC this frees up PIC pin RG4. This pin is currently however not routed to an connectors //#if !defined(NIC_DISABLE_IOCHRDY) NIC_IOCHRDY = 1; NIC_IOCHRDY_TRIS = 1; //IOCHRDY is an input //#endif #endif //Reset all error counters #ifdef MAC_CNTR1_3 cntr0.Val = 0; cntr1.Val = 0; cntr2.Val = 0; #endif #if (DEBUG_MAC >= LOG_WARN) cntrSum = 0; #endif // On Init, all transmit buffers are free. for ( i = 0; i < MAX_DATA_BUFFERS; i++ ) { //Set to NIC SRAM page TxBuffers[i].Index = TXSTART + (i * (MAC_TX_BUFFER_SIZE/NIC_PAGE_SIZE)); TxBuffers[i].bFree = TRUE; } MACCurrTxbuf = 0; NICReset(); DelayMs(5); // Give RTL8019AS time to load EEPROM values - takes about 2ms NICPut(NIC_RESET, NICGet(NIC_RESET)); //Writing to NIC_RESET register caused NIC to reset // mimimum Delay of 1.6 ms DelayMs(5); // Give RTL8019AS time to load EEPROM values - takes about 2ms //Some documentation states that reset bit is unreliable - only check it for 100ms //if ( (NICGet(ISR) & 0x80) != 0 ) { #if defined(BRD_SBC44EC) || defined(BRD_SBC45EC) //Because the EEPROM read pin is floating on some boards, the registers initialized by the //EEPROM will all contain non defined values. Write them with correct values //MACInitEepromRegs(); // TEST TEST #endif // Select Page 0 AND issue STOP Command NICPut(CMDR, 0x21); DelayMs(5); // Initialize Data Configuration Register NICPut(DCR, DCRVAL); // Clear Remote Byte Count Registers NICPut(RBCR0, 0); NICPut(RBCR1, 0); // Initialize Receive Configuration Register NICPut(RCR, 0x04); // Place NIC in LOOPBACK mode 1 NICPut(TCR, 0x02); // Initialize Transmit buffer queue NICPut(TPSR, TxBuffers[MACCurrTxbuf].Index); // Initialize Receive Buffer Ring NICPut(PSTART, RXSTART); NICPut(PSTOP, RXSTOP); NICPut(BNRY, RXSTART); //Receive buffer GET pointer // Initialize Interrupt Mask Register // Clear all status bits NICPut(ISR, 0xff); // No interrupt enabled. NICPut(IMR, 0x00); // Select Page 1 NICPut(CMDR, 0x61); // Initialize Physical Address Registers NICPut(PAR0, MY_MAC_BYTE1); NICPut(PAR0+1, MY_MAC_BYTE2); NICPut(PAR0+2, MY_MAC_BYTE3); NICPut(PAR0+3, MY_MAC_BYTE4); NICPut(PAR0+4, MY_MAC_BYTE5); NICPut(PAR0+5, MY_MAC_BYTE6); // Initialize Multicast registers for ( i = 0; i < 8; i++ ) NICPut(MAR0+i, 0xff); // Initialize CURRent pointer - this is the RX Buffer PUT pointer NICPut(CURRP, RXSTART); // TCP layer uses this value to calculate window size. Without init the // first window size value sent would be wrong if no packet has been received before. MACCurrRxbuf = RXSTART; // Page 0, Abort Remote DMA and Activate the transmitter. NICPut(CMDR, 0x22); // Set Normal Mode NICPut(TCR, 0x00); } #if defined(BRD_SBC44EC) || defined(BRD_SBC45EC) //Because the EEPROM read pin is floating on some boards, the registers initialized by the //EEPROM will all contain non defined values. Write them with correct values //MACInitEepromRegs(); // TEST TEST #endif //Disable RTL8019AS interrupts. All INT lines go tri-state, and PIC pin is available to user. The //PIC port pin that becomes available is: // - For SBC44EC this has no affect - no PIC pins are connected to the interrupt pins // - For SBC45EC this has no affect - no PIC pins are connected to the interrupt pins // - For SBC65EC and SBC68EC this frees up PIC pin RB0. #if (defined(BRD_SBC65EC) || defined(BRD_SBC68EC)) && defined(NIC_DISABLE_INT0) NICPut(CMDR, 0xe0); //Select page 3 NICPut(RTL9346CR, 0xc0); //Config register write enable NICPut(RTLCONF1, 0); //Interrupt disable - will cause INT0 to be high impedance. NICPut(RTL9346CR, 0x00); //Normal operating mode NICPut(CMDR, 0x20); //Reset to default = Page 0 #endif }
/** * Check if the MAC Receive Buffer has any received packets. * Reads the following data from the next available packet in the RX buffer: <ul> * <li> The MAC 4 bytes RX packet header (status, nex receive packet, length) </li> * <li> The 14 byte Ethernet header </li></ul> * Once a data packet is fetched by calling MACRxbufGetHdr, the complete data * packet must be fetched (using MACRxbufGet) and discarded (using MACRxbufDiscard). * Users cannot call MACRxbufGetHdr multiple times to receive multiple packets * and fetch data later on. * * @param[out] remote Pointer to a MAC_ADDR structure. This function will write the MAC address of the * node who sent this packet to this structure * @param[out] type Pointer to byte. This function will write the type of header to this variable. * Can be ETHER_IP, ETHER_ARP or MAC_UNKNOWN * * @return True if RX Buffer contained a packet and it's header was read, False if not * */ BOOL MACRxbufGetHdr(MAC_ADDR *remote, BYTE* type) { NE_PREAMBLE header; BYTE NICWritePtr; BYTE NICReadPtr; WORD_VAL temp; *type = MAC_UNKNOWN; //Read CURR and BNDY registers = RX Buffer's GET and PUT pointers NICPut(CMDR, 0x60); //Set page 1 NICWritePtr = NICGet(CURRP); //Curr is the RX Buffer's PUT pointer NICPut(CMDR, 0x20); //Reset to page 0 NICReadPtr = NICGet(BNRY); //Get BNRY pointer // Reset NIC if overrun has occured. if ( NICGet(ISR) & 0x10 ) { BYTE resend; #if (DEBUG_MAC >= LOG_ERROR) debugPutMsg(3); //@mxd:3:Overrun error! Reseting MAC! #endif // Save TXP bit resend = NICGet(CMDR) & 0x04; //Issue STOP command to NIC and delay 2ms NICPut(CMDR, 0x21); DelayMs(2); //Clear Remote Byte count registers NICPut(RBCR0, 0); NICPut(RBCR1, 0); // TXP bit set? if (resend) // No re-send if Packet Transmitted or Transmit Error bit is set resend = !(NICGet(ISR) & 0x0A); //Put NIC in loopback mode and issue start command NICPut(TCR, 0x02); NICPut(CMDR, 0x22); // HM: Modified, changed to 22 to re-start NIC // Empty ring buffer completely MACCurrRxbuf = NICWritePtr; MACRxbufDiscard(); //Reset ISR by writing FF to it NICPut(ISR, 0xff); //Take NIC out of loopback mode NICPut(TCR, 0x00); //Resend the packet if(resend) NICPut(CMDR, 0x26); return FALSE; } //Is there something in the buffer if ( NICWritePtr != NICReadPtr ) { temp.v[1] = NICReadPtr; //Pointer to RAM page, is MSB of address temp.v[0] = 0; //LSB is 0 NICSetAddr(temp.Val); //Read the following from the current MAC RX Buffer: // - The MAC 4 bytes RX packet header (status, nex receive packet, length) // - The 14 byte Ethernet header MACRxbufGetArray((BYTE*)&header, sizeof(header)); // Validate packet length and status as. if ( header.Status.PRX && (header.ReceivedBytes >= MINFRAMEC) && (header.ReceivedBytes <= MAXFRAMEC) && (header.NextPacketPointer < RXSTOP) && (header.NextPacketPointer >= RXSTART) ) { header.Type.Val = swaps(header.Type.Val); memcpy((void*)remote->v, (void*)header.SourceMACAddr.v, sizeof(*remote)); if ( (header.Type.v[1] == 0x08) && ((header.Type.v[0] == ETHER_IP) || (header.Type.v[0] == ETHER_ARP)) ) *type = header.Type.v[0]; MACCurrRxbuf = NICReadPtr; //Set MACCurrRxbuf with page address of current RX Buffer return TRUE; } //ERROR!!! Invalid packet received! #if (DEBUG_MAC >= LOG_ERROR) debugPutMsg(4); //@mxd:4:Invalid Packet Error! #endif //Ring now contains garbage MACCurrRxbuf = NICWritePtr; // Empty ring buffer completely MACRxbufDiscard(); } return FALSE; }