Hi, I have succeded in making the scheduler-worker design work for packets that are less than 214 bytes (size includes all the headers including the MAC header size; with UDP, the size of UDP data is 170 bytes). I have avoided reading stale rcv_rdy_lo flag by looping around using the RCV_RDY_CNT register. But when I increase the packet by 215 byte (in UDP datagram, this translates to 171 bytes of UDP data), I see overflow in the MAC registers. Also, the scenario is peculiar and is explained as follows : I use my UDP client which sends 1) a single 22 byte data first (always) [64 byte packet after MAC layers' encapsulation]. No problem with this packet. /* Also, any packet size above this will make it successfully. */ 2) Send packets of data size 171 bytes repeatedly!! The strange this, every other 171 packet makes it across to the destination. The first one does not cause any MAC overflow but the next one does cause a MAC overflow. The third 171 one makes it across the board. The fourth 171 fails. This goes on. (171 + 44 = 215 after MAC encapsulation. 64 *3 = 192; 64*4 = 256; and so the last chunk has ractional data of size 23 bytes) { the same packet sending can be repeated with data size = 172,173, etc. } 3) If I increase to very large packets, eg 234 butes, the first one and subsequent ones never make it across the board. Between packets, I have a getchar() and on key stroke, I send packets. The machines are in a linear configuration, i.e source <==> IXP <==> destn. The destn does not send any packet back. I think there is no overflow of the RCV_REQ_CNT byte in the RCV_RDY_CNT register because just 4 chunks have come. Can anyone suggest why I am getting this problem ? Any pointers will be very helpful. Jagan. PS : To gain more insight, the design looks almost as the transaltion of the following pseudocode. The thread allocation to the port is static and there is only one thread that takes care of receive from one port. The scheduler is working as follows : while(1) { read_reg(rcv_rdy_lo); old = read( RCV_RDY_CNT); /* reads value as X*/ if(rcv_rdy_lo==0) continue; see_which_microengine_has_to be informed(); construct_the_rcv_req(other_uc_TID); // so that the correct // microengine is signalled write_to_rcv_req(); new=read(RCV_RDY_CNT);/*reads value as X if transfer is not over reads value as X+1 if transfer is over. while(old <=new) { new=read(RCV_RDY_CNT); /* if X+1, then quit. */ } The worker thread looks like : while (1) { wait_for_signal(start_receive); read_the register(rcv_cntl); read_the packet_from_fifo(); eop=process_the packet(); if(eop) { peek intocache and tranmit the packet to the outgoing i/f } else { assemble the packet till eop comes. } }