예제 #1
0
void    MACPut(int8 val)
{
    NICPut(RBCR0, 1);
    NICPut(RBCR1, 0);
    NICPut(CMDR, 0x12);
    NICPut(NIC_DATAPORT, val);
}
예제 #2
0
int8    MACGet(void)
{
    NICPut(RBCR0, 1);
    NICPut(RBCR1, 0);
    NICPut(CMDR, 0x0a);
    return NICGet(NIC_DATAPORT);
}
예제 #3
0
void NICSetAddr(int16 addr)
{
    WORD_VAL t;

    t.Val = addr;
    NICPut(ISR, 0x40);
    NICPut(RSAR0, t.v[0]);
    NICPut(RSAR1, t.v[1]);
}
예제 #4
0
void MACDiscardRx(void)
{
    int8 newBoundary;

    newBoundary = NICReadPtr - 1;
    if ( newBoundary < RXSTART )
        newBoundary = RXSTOP - 1;
    NICPut(CMDR, 0x20);     // Select PAGE 0
    NICPut(BNRY, newBoundary);
}
예제 #5
0
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]);
}
예제 #6
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));
}
예제 #7
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);
}
예제 #8
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]);
}
예제 #9
0
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]);

}
예제 #10
0
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;
        }
    }
}
예제 #11
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;
}
예제 #12
0
/**
 * 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);
}
예제 #13
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;
}
예제 #14
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;
}
예제 #15
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--;
}
예제 #16
0
/**
 * 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;
        }
    }
}
예제 #17
0
/**
 * 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;
}
예제 #18
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);

    }

}
예제 #19
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;

}
예제 #20
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
}
예제 #21
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;

}