WARP Project Forums - Wireless Open-Access Research Platform

You are not logged in.

#1 2010-Jun-23 13:15:33

jitin.bajaj
Member
Registered: 2009-May-01
Posts: 17

Destination IP Address checking in WARPMAC

Hi,
I want to check destination IP address for the data I am sending. I made certain changes in the pollDataSource Function in warpmac:

warpmac_pollDataSource() {
   
    unsigned int dIPAddr, dhostAddr;
    unsigned short int temp;
       
    if(XIo_In32(EMAC_FIFO_BaseAddr+XLLF_RDFO_OFFSET) > 0)
    {
        // 30 is the offset for destination IP Address in the RXFIFO_DATA

        dIPAddr = XIo_In32(EMAC_FIFO_BaseAddr+XLLF_RDFD_OFFSET+30);
        dhostAddr = dIPAddr & 0x000000FF;
       
        xil_printf("host addr %d", dhostAddr);

        //Clear the LLFIFO status bits
        XIo_Out32(EMAC_FIFO_BaseAddr+XLLF_ISR_OFFSET, 0x0FFFFFFF);
       
        //Call the ethernet packet handler
        emacRx_handler();
         }
}

But this always gives the dhostAddr as 0...Is there anything wrong with reading data offset before reading rx length and then doing DMA from fifo to buffer in emacrx_handler() ??

Please suggest how can this be done in case of temac & FIFO....we have done this successfully with reference design 12.1 which used emaclite..

Offline

 

#2 2010-Jun-24 02:25:33

murphpo
Administrator
From: Mango Communications
Registered: 2006-Jul-03
Posts: 5159

Re: Destination IP Address checking in WARPMAC

The xps_ll_fifo does not have a memory mapped packet buffer. It operates as FIFO, moving packet payloads one 32-bit word per access, always from the same address. I suggest moving your IP address checking to the top-level dataFromNetwork callback, where a pointer to the full Ethernet payload is provided. (This works by using DMA to move Ethernet packets from the ll_fifo into one of the PHY packet buffers, which are memory mapped).

Offline

 

#3 2010-Jul-09 03:16:16

jitin.bajaj
Member
Registered: 2009-May-01
Posts: 17

Re: Destination IP Address checking in WARPMAC

Hi,

As suggested we moved the IP address checking operation to higher level i.e after the DMA transfer of the payload is done. We made some more changes to the code shown below:

#define ETHER_TYPE_OFFSET 12
#define ETHER_PROTO_TYPE_IP        0x0800  /**< IP Protocol */
#define ETHER_PROTO_TYPE_ARP    0x0806  /**< ARP Protocol */
#define HEADER_IP_LENGTH_OFFSET    16        /**< IP Length Offset */
#define HEADER_IP_DESTIP_OFFSET 30        /** Destination IP address offset */
#define ARP_PACKET_TPA_OFFSET 38  /** TARGET PROTOCOL ADDRESS (IP ADDRESS OF DESTINATION) OFFSET 24 + 14 FOR ETHERNET*/


inline void warpmac_pollDataSource() {
       
    if( controlStruct.enableEth == 0)
        return;
    warpmac_setDebugGPIO(0x1);
   
    if(XIo_In32(EMAC_FIFO_BaseAddr+XLLF_RDFO_OFFSET) > 0)
    {
        XIo_Out32(EMAC_FIFO_BaseAddr+XLLF_ISR_OFFSET, 0x0FFFFFFF);
        warpmac_setDebugGPIO(0x3);
        emacRx_handler();
    }
    warpmac_setDebugGPIO(0x0);
    return;
}



void emacRx_handler() {
    unsigned int dIPAddr;
    unsigned short RxPktLength=0;
    void* pktBufPtr = NULL;
   
   
          pktBufPtr = (void *)warpphy_getBuffAddr(1)+NUM_HEADER_BYTES;
    
       //Wait for the DMA to be idle
      warpmac_waitForDMA();

     //Set DMA to non-increment source, increment dest addresses
    XDmaCentral_SetControl(&DmaCentralInst, XDMC_DMACR_DEST_INCR_MASK);

    //Read the Rx packet length; the packet must be read from the FIFO immediately after this read
    RxPktLength = XIo_In32(EMAC_FIFO_BaseAddr+XLLF_RLF_OFFSET);

    warpmac_setDebugGPIO(0x7);
    //Transfer the Ethernet frame from the FIFO to the PHY buffer
    XDmaCentral_Transfer(&DmaCentralInst,
                        (u8 *)(EMAC_FIFO_BaseAddr+XLLF_RDFD_OFFSET),
                        (u8 *)pktBufPtr,
                        RxPktLength);
                           
    ethType = XIo_In32((unsigned int )warpphy_getBuffAddr(1)+NUM_HEADER_BYTES+ETHER_TYPE_OFFSET);
       
    ethType = (ethType >> 16) & 0x0000FFFF;
    
    if (ethType == ETHER_PROTO_TYPE_ARP) {
       
        dIPAddr = XIo_In32((unsigned int )warpphy_getBuffAddr(1)+NUM_HEADER_BYTES+ARP_PACKET_TPA_OFFSET);
        dhostIPAddr = (dIPAddr & 0x000000FF);
        xil_printf("IP %d\r\n", dhostIPAddr);
           
        if(dhostIPAddr==2 || dhostIPAddr==3)
            //some operation
       
    }
    else if (ethType == ETHER_PROTO_TYPE_IP) {
        dIPAddr = XIo_In32((unsigned int )warpphy_getBuffAddr(empty.start->index)+NUM_HEADER_BYTES+HEADER_IP_DESTIP_OFFSET);
        dhostIPAddr = (dIPAddr & 0x000000FF);
           
        //xil_printf("IP %d\r\n", dhostIPAddr);
           
        if(dhostIPAddr==2 || dhostIPAddr==3)
            //some operation   
       
    }
       
    warpmac_setDebugGPIO(0xF);
    usr_dataFromNetworkLayer(RxPktLength, pktBufPtr);
    return;
}

The changes were made keeping the suggestions of one previous post also in mind..
http://warp.rice.edu/forums/viewtopic.php?id=706

Now it is printing the IP values we are sending data to, but it is also printing lot of random values also besides those even when we are not sending any data....why is it so?? Please help..!!

Offline

 

#4 2010-Jul-09 11:26:37

murphpo
Administrator
From: Mango Communications
Registered: 2006-Jul-03
Posts: 5159

Re: Destination IP Address checking in WARPMAC

Two things:
-In your two access to the packet buffer, you used "warpphy_getBuffAddr(empty.start->index)", while the code above actually copied the packet to "warpphy_getBuffAddr(1)". Maybe they're accessing different packets?

-The DMA is fast, but does take time to copy the full packet. Your code jumps directly from initiating the DMA transfer (XDmaCentral_Transfer) to accessing the destination of the transfer. It's entirely possible the DMA hasn't actually copied enough bytes yet. You can call warpmac_waitForDMA() to wait for the DMA to finish. It might also be possible to poll the DMA to monitor how many bytes have been transferred; you'd have to refer to its datasheet/driver for details.

Also, I would strongly recommend reverting warpmac.c and putting your custom packet-handling code in the top level dataFromNetworkLayer callback. This way your function will be called with a pointer to the just-received packet, wherever the framework copied it. It will also facilitate migrating your code to newer reference designs in the future.

Offline

 

Board footer