Esempio n. 1
0
/**
 * Function for performing MAC related tasks
 *
 * @preCondition    Must be called every couple of ms
 */
void MACTask(void)
{
    #if (DEBUG_MAC >= LOG_WARN)
    BYTE tmpSum;
    char buf[5];
    #endif

    #if defined(MAC_CNTR1_3)
    cntr0.Val += NICGet(CNTR0);
    cntr1.Val += NICGet(CNTR1);
    cntr2.Val += NICGet(CNTR2);
    #endif

    #if (DEBUG_MAC >= LOG_WARN)
    tmpSum = LSB(cntr0) + MSB(cntr0) + LSB(cntr1) + MSB(cntr1) + LSB(cntr2) + MSB(cntr2);
    //If any of the error counter have changed, print them out!
    if (cntrSum != tmpSum) {
        debugPutMsg(1);     //@mxd:1:Frame Alignment=%s, CRC=%s, Missed Packets=%s

        itoa(cntr0.Val, buf);
        debugPutString(buf);
        itoa(cntr1.Val, buf);
        debugPutString(buf);
        itoa(cntr2.Val, buf);
        debugPutString(buf);

        cntrSum = tmpSum;
    }
    #endif
}
Esempio n. 2
0
int16 MACGetOffset(void)
{
    WORD_VAL t;

    t.v[1] = NICGet(RSAR1);
    t.v[0] = NICGet(RSAR0);

    return t.Val;
}
Esempio n. 3
0
/**
 * Get the current Remote DMA address. This is the address set by the NICSetAddr register.
 * It will however be incremented after each Remote DMA read.
 * The MACRxbufGet() function for example does a remote DMA read.
 *
 * @return The current Remote DMA address.
 */ 
WORD MACGetNICAddr(void)
{
    WORD_VAL t;

    t.v[1] = NICGet(RSAR1);
    t.v[0] = NICGet(RSAR0);

    return t.Val;
}
Esempio n. 4
0
int8    MACGet(void)
{
    NICPut(RBCR0, 1);
    NICPut(RBCR1, 0);
    NICPut(CMDR, 0x0a);
    return NICGet(NIC_DATAPORT);
}
Esempio n. 5
0
int1    MACIsTxReady(void)
{

    // NICCurrentTxBuffer always points to free buffer, if there is any.
    // If there is none, NICCurrentTxBuffer will be a in 'Use' state.
    //return TxBuffers[NICCurrentTxBuffer].bFree;
       return !(NICGet(CMDR) & 0x04);
}
Esempio n. 6
0
/**
 * Check if ready for next transmission.
 *
 * @return      TRUE if transmit buffer is empty <br>
 *              FALSE if transmit buffer is not empty
 *
 */
BOOL    MACIsTxReady(void)
{
    // MACCurrTxbuf always points to free buffer, if there is any.
    // If there is none, MACCurrTxbuf will be a in 'Use' state.
    //return TxBuffers[MACCurrTxbuf].bFree;
    // Check to see if previous transmission was successful or not.
    return !(NICGet(CMDR) & 0x04);
}
Esempio n. 7
0
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));
}
Esempio n. 8
0
/**
 * 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);
}
Esempio n. 9
0
/**
 * Reads a single byte via Remote DMA from the current MAC Receive buffer.
 * If the last byte of the RX Buffer was read, this function automatically
 * updates the Remote DMA read address to the first page of the RX Buffer.
 * See PreConditions for more info.
 *
 * @preCondition:    Remote DMA address has to be set up prior to calling this function.
 *                  The Remote DMA registers are NOT configured by this function,
 *                  and simply continue reading from the current "Remote DMA Address". A function
 *                  like MACRxbufGetHdr() can be called prior to this function to configure Remote
 *                  DMA to read the next packet in RX Buffer (situated in Remote DMA RAM)
 *
 * @return      Read byte
 */
BYTE    MACRxbufGet(void)
{
#if defined(__18CXX)
    overlay
#endif
    BYTE b;

    //Configure RBCR (Remote Byte Count Register) for bytes to be read via DMA
    FirstFastNICPut(RBCR0, 1);
    FastNICPut(RBCR1, 0);

    //Last byte of MAC RX Buffer is read wronge by RTL8019AS - Address has to be set again!
    if ((DMAAddr.v[0] == 0xff) && (DMAAddr.v[1] == (RXSTOP-1))) {
        //Set NIC Remote DMA read again - this fixes the RTL8019AS bug!!!!
        NICSetAddr((RXSTOP << 8) - 1);

        //Remote DMA Read command. This causes given (RBCR0 & 1) number of bytes, starting at given
        //address (RSAR0 & 1) set by NICSetAddr() to be read with each I/O read cycle.
        FastNICPut(CMDR, 0x0a); 

        b = NICGet(NIC_DATAPORT);   //Read I/O port

        //Reset to first byte of MAC RX Buffer - this function also updates DMAAddr
        //This fixes the RTL8019AS bug where the address point is not updated to first byte of Receive Buffer
        NICSetAddr(RXSTART << 8);
    }
    else {
        //Remote DMA Read command. This causes given (RBCR0 & 1) number of bytes, starting at given
        //address (RSAR0 & 1) set by NICSetAddr() to be read with each I/O read cycle.
        FastNICPut(CMDR, 0x0a); 

        //Read a byte from the I/O port
        TRISD = 0xff;   //Input
        WRITE_NIC_ADDR(NIC_DATAPORT);
        BEGIN_IO_CYCLE();
        NIC_IOR_IO = 0;
        WAIT_FOR_IOCHRDY();
        b = NIC_DATA_IO;
        NIC_IOR_IO = 1;
        LEAVE_IO_CYCLE();

        //The above I/O port operation updated the Remote DMA address
        DMAAddr.Val++;
    }

    return (b);
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
/**
 * 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;
}
Esempio n. 13
0
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--;
}
Esempio n. 14
0
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;

}
Esempio n. 15
0
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);

    }

}
Esempio n. 16
0
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
}
Esempio n. 17
0
/**
 * 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;

}