Question regarding END_RCV_RTN_CALL - VxWorks

This is a discussion on Question regarding END_RCV_RTN_CALL - VxWorks ; I have written an Ethernet driver (integrated with VxWorks) on ARM926 EJ_S. There are following problems that I am facing: a) VxWorks Network Stack Alignment problem: This is a standard problem with VxWorks Network Stack. The stack crashes if the ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: Question regarding END_RCV_RTN_CALL

  1. Question regarding END_RCV_RTN_CALL

    I have written an Ethernet driver (integrated with VxWorks) on ARM926
    EJ_S.

    There are following problems that I am facing:

    a) VxWorks Network Stack Alignment problem: This is a standard problem
    with VxWorks Network Stack. The stack crashes if the payload is not
    word aligned. To circumvent this problem I am currently coyping the
    incoming ethernet packet from one buffer to another with a 2-byte
    offset. Is there any other solution to this?

    b) The END_RCV_RTN_CALL that is being used in the Receive function of
    the driver is taking hell lot of time. I instrumented the receive call
    with WindView Graphs and found out that most of the time is being spent
    in this call. The entire receive function takes on average 220 us and
    the contribution of this function is approx 193 us. The amount of time
    being taken by the receive function is very high and is unacceptable.

    I need to reduce the time being taken by the receive function
    drastically, anybody who can tell me an alternative to
    END_RCV_RTN_CALL!!!!!!!!

    Thanks in advance.

    P.S. END_RCV_RTN_CALL is used to pass the incoming packet to the upper
    layers(protocol).

    END_RCV_RTN_CALL(pEnd,pMblk)

    Where pEnd is END_OBJ * and pMblk is M_BLK_ID.


  2. Re: Question regarding END_RCV_RTN_CALL

    a) I deal with this issue on MIPS. Rather than copying, adjust the
    offset when you get a packet buffer. That way when you copy the data in
    it is already aligned and you can avoid the redundant copy for
    alignment.

    b) You did say that you wrote the end driver, right? The MACRO just
    calls the receiveRtn() function of your end driver.

    >From endlib.h:


    #define END_RCV_RTN_CALL(pEnd,pMblk) \
    if ((pEnd)->receiveRtn) \
    { \
    (pEnd)->receiveRtn ((pEnd), pMblk,NULL,NULL,NULL,NULL); \
    }


  3. Re: Question regarding END_RCV_RTN_CALL

    >> a) I deal with this issue on MIPS. Rather than copying, adjust the
    >> offset when you get a packet buffer. That way when you copy the data in
    >> it is already aligned and you can avoid the redundant copy for
    >> alignment.


    You can do this by asking the MAC to receive at
    pBuf+VXW_RCV_BUF_OFFSET. I assume VXW_RCV_BUF_OFFSET would be 2 for
    MIPS. So your actual data (pData) will start at pBuf+VXW_RCV_BUF_OFFSET
    netClBlkJoin(pClBlk, pData - VXW_RCV_BUF_OFFSET, MAX_FRAME_SIZE);
    netMblkClJoin(pMblk, pClBlk);
    pMblk->mBlkHdr.mFlags |= M_PKTHDR;
    pMblk->mBlkHdr.mLen = len;
    pMblk->mBlkHdr.mData = pData ;
    pMblk->mBlkPktHdr.len = len;
    END_RCV_RTN_CALL (&endObj, pMblk);

    I just repeated what ifdef said with code.

    >> b) You did say that you wrote the end driver, right? The MACRO just
    >> calls the receiveRtn() function of your end driver.
    >> >From endlib.h:

    >>
    >> #define END_RCV_RTN_CALL(pEnd,pMblk) \
    >> if ((pEnd)->receiveRtn) \
    >> { \
    >> (pEnd)->receiveRtn ((pEnd), pMblk,NULL,NULL,NULL,NULL); \
    >> }


    I think most drivers do not write this routine themselves - but use
    muxTkReceive( ) as pEnd->receiveRtn. From the Network Protocol Toolkit
    Programmer's guide appendix A:

    A) Explanation of END_OBJ's receiveRtn:

    A function pointer that references a receive routine in the MUX. The
    MUX supplies this pointer when the driver is loaded. Any time after the
    completion of the muxDevLoad( ) call, the driver can use this
    receiveRtn( ) to pass data up to the protocol layer. The prototype for
    this receive routine is:


    STATUS receiveRtn
    (
    void * pCookie, /* The cookie passed in to endLoad() */
    M_BLK_ID pMblk /* The packet, as an mblk chain */
    )

    B). Explanation of muxTkReceive( ):
    Typically, a driver includes an interrupt handling routine to process
    received packets. It should keep processing to a minimum during
    interrupt context and then arrange for processing of the received
    packet itself within task context.

    Once the frame has been validated, it should be passed to the MUX with
    muxTkReceive( ).***1 The muxTkReceive( ) function forwards the data to
    the network service sublayer by calling the stackRcvRtn( ) registered
    for that sublayer.

    The footnote ***1 is:
    1: This function is registered by the MUX as the receiveRtn in the
    END_OBJ data structure for the device. The driver should make a call to
    this reference rather than calling muxTkReceive( ) directly.


  4. Re: Question regarding END_RCV_RTN_CALL

    I haven't written receiveRtn() function and as Abhijit also says
    pEnd->receiveRtn calls muxTkReceive. Does it mean that whatever
    function I have written for receiving a packet is actually the
    pEnd->receiveRtn. I am not very clear on this point. Can anybody
    illustrate it?

    Thanks in advance.


  5. Re: Question regarding END_RCV_RTN_CALL

    No pEnd->receiveRtn is not your driver receive routine but it is set to
    muxTkReceive when muxDevLoad is called for the driver:

    Read:
    http://www.eelab.usyd.edu.au/tornado...DLDrivers.html

    Section 10.1.3:
    10.1.3 The Datalink-to-MUX Interface
    To add an END or NPT device to the MUX, call muxDevLoad( ) for each
    driver you want to add. This is done for you automatically in the
    standard network initialization code if you name the driver's load
    function in the endDevTbl[ ]. The stack initialization code uses this
    function name as input to a muxDevLoad( ) call.

    Internally, the driver's load function must allocate and partially
    populate an END_OBJ structure and a NET_FUNCS structure. The END_OBJ
    structure provides the MUX with a description of the device, and the
    NET_FUNCS structure provides the MUX with pointers to the driver's
    standard MUX interface functions, xStart( ), xStop( ), xReceive( ),
    xIoctl( ), and so on.

    After a driver is loaded in to the MUX and has been bound to a
    protocol, it can pass received packets up to the MUX by calling
    muxReceive( ), if it is an END, or muxTkReceive( ), in NPT
    drivers.1****

    =====================================
    The footnote 1**** (bottom of the page) is:

    1: The mux[Tk]Receive( ) calls in the shipped ENDs and the template
    END are hard to identify as such when casually reading the code. When
    passing a packet up to the MUX, each of these drivers uses the function
    pointer referenced in the receiveRtn member of its END_OBJ. An earlier
    call to muxDevLoad( ) set the receiveRtn member to muxReceive( ) or
    muxTkReceive( ), whichever was appropriate.
    ========================

    Also read:

    Section 10.2.2.


  6. Re: Question regarding END_RCV_RTN_CALL

    Can I somehow see the code for pEnd->receiveRtn, can I change it some
    how?????

    Thanks in advance.


+ Reply to Thread