nbuf.h

来自「开放源码实时操作系统源码.」· C头文件 代码 · 共 649 行 · 第 1/2 页

H
649
字号
/******************************************************************************
   nbuf_rx_release_pkt() - Release the buffer descriptors of the next packet.

   INPUT:
        pointer to the buffer info.
*/
inline static
void nbuf_rx_release_pkt(buf_info_t* pBuf)
{

     NBUF* pNbuf;

     /* Indicates whether the last buffer descriptor is encountered. */
     cyg_bool_t last = false;

     do
     {
         /* Get the buffer descriptor. */
         pNbuf = nbuf_rx_get_next(pBuf);

         /*   Stop when there is a packet truncated bit is set or it is the */
         /* last buffer descriptor of the packet.                           */

         if ((!(pNbuf->status & RX_BD_E) && pNbuf->status & RX_BD_TR) ||
             pNbuf->status & RX_BD_L)
         {
             last = true;
         }

         /* Release the buffer descriptor. */
         nbuf_rx_release(pNbuf);

     }while(last == false);

}



/******************************************************************************
   nbuf_rx_release_good_pkt() - Release the buffer descriptors for
                                good received packets.
                                Note call this function
                                only when there is valid received
                                buffer descriptors.

   INPUT:
        pBuf - pointer to the buffer info.
*/
inline static
void nbuf_rx_release_good_pkt(buf_info_t* pBuf)
{

     u16_t status;

     do
     {

         /*   Read the status bits.  If the RX_BD_L is set we terminate the */
         /* loop.                                                           */

         status = pBuf->RxNBUF[pBuf->iRxbd].status;

         /*   Release the buffer descriptor so that it could reused.        */

         nbuf_rx_release(&pBuf->RxNBUF[pBuf->iRxbd]);

         /*   Advance the index to the next buffer descriptor.              */

         pBuf->iRxbd = (pBuf->iRxbd + 1) % NUM_RXBDS;


     }while(!(status & RX_BD_L));

}


/******************************************************************************
  nbuf_tx_release() - Set the buffer descriptor ready for use to transmit
                      the next packet.

   INPUT:
        pNbuf - Pointer to the transmit buffer descriptor.
*/
inline static
void
nbuf_tx_release (NBUF* pNbuf)
{

    /*   Clear  the  TX_BD_INUSE  to  indicate   that  we  have  read   the */
    /* transmitted buffer.                                                  */

    pNbuf->status &= ~(TX_BD_INUSE | TX_BD_R | TX_BD_L | TX_BD_TC);

}

/* Return a nozero value  if the buffer is full. Otherwise, it returns a
   zero value.
*/
inline static
int_t nbuf_tx_full(buf_info_t* pBuf)
{
    return (pBuf->TxNBUF[pBuf->iTxbd].status & TX_BD_R);
}


/* Return the pointer to the transmit buffer descriptor. */
inline static
NBUF*
nbuf_tx_get(buf_info_t* pBuf, int_t index)
{
    return(&pBuf->TxNBUF[index]);
}

/******************************************************************************
 nbuf_peek_tx_key() - Peek whether there is any
                      pending packets that are still in transmisison.

 INPUT:
    pBuf - Pointer to the buffer structure.

 OUTPUT:
    index - The index to the oldest pending packet in the queue.

 RETURN:
    Returns the index to the oldest pending packet in the queue. Otherwise,
    it returns -1.

*/
inline static
int_t nbuf_peek_tx_key(buf_info_t* pBuf)
{
    if (pBuf->tq_rear == pBuf->tq_front)
    {
        return -1; /* No pending transmit buffers. */
    }
    return pBuf->tx_keys_queue[pBuf->tq_front].tx_buf_index;
}

/******************************************************************************
 nbuf_peek_bd_ahead() - Returns the pointer of the to the last buffer
                        descriptor of the 2nd. pending transmit frame.

 INPUT:
    pBuf - Pointer to the buffer structure.


 RETURN:
    Returns the pointer of the to the last buffer
    descriptor of the 2nd. pending transmit frame. If there is not 2nd.
    pending frame, it returns NULL.


*/
inline static
NBUF* nbuf_peek_bd_ahead(buf_info_t* pBuf)
{
    uint_t ahead_front = (pBuf->tq_front + 1) % TX_KEY_QUEUE_SIZE;

    if (pBuf->tq_rear == pBuf->tq_front ||
        ahead_front == pBuf->tq_rear)
    {
        return NULL; /* No pending transmit buffers. */
    }

    return &pBuf->TxNBUF[pBuf->tx_keys_queue[ahead_front].tx_buf_index];
}



/******************************************************************************
 nbuf_enq_tx_key() - Enqueue and deuque transmit key queue.
   Enqueue the transmit key. The  buf_index is the index to the transmit buffer deiscriptor
   table of the last buffer descriptor for the frame and the transmit packet
   type.
*/
inline static
void nbuf_enq_tx_key(buf_info_t* pBuf,
                     uint_t buf_index,
                     unsigned long txkey,
                     uint_t start_index,
                     int num_bd,
                     int_t total_len,
                     tx_key_type_t key_type)
{
    tx_keys_t* p_keys = &pBuf->tx_keys_queue[pBuf->tq_rear];
    /*   Assign the transmit packet information to the transmit key queue.  */

    /*   NOTE: We don't check for  the full condition because the  transmit */
    /* key queue size is as big as the number of buffer descriptors.        */

    p_keys->tx_key = txkey;
    p_keys->tx_buf_index  = buf_index;
    p_keys->num_dbufs = num_bd;
    p_keys->pk_len = total_len;
    p_keys->start_index = start_index;
    p_keys->key_type = key_type;

    /*   Advance the transmit queue pointer to the next entry.              */

    pBuf->tq_rear = (pBuf->tq_rear + 1) % TX_KEY_QUEUE_SIZE;

 }


/******************************************************************************
 nbuf_deq_tx_key() - Dequeue the transmit packet from the transmit key queue.
                     Assume that the queue is not empty.


 INPUT:
    pBuf - Pointer to the buffer structure.

 OUTPUT:
    key - The  key the transmit information.
*/
inline static
void nbuf_deq_tx_key(buf_info_t* pBuf, tx_keys_t* key)
{

    CYG_ASSERT(pBuf->tq_rear != pBuf->tq_front, "nbuf_deq_tx_key: empty");
    *key = pBuf->tx_keys_queue[pBuf->tq_front];
    pBuf->tq_front = (pBuf->tq_front + 1) %  TX_KEY_QUEUE_SIZE;

}

/*******************************************************************************
 nbuf_tx_dump() - Dump the transmit buffer information.

 INPUT:
    pBuf - pointer to the buffer info.
*/
inline static
void nbuf_tx_dump(buf_info_t* pBuf)
{

    tx_keys_t key;

    diag_printf("Current index to ring buffer: %d\n", pBuf->iTxbd);
    diag_printf("Address to the BD:            %08X\n",
                &pBuf->TxNBUF[pBuf->iTxbd]);

    diag_printf("BD status:            %04X\n", pBuf->TxNBUF[pBuf->iTxbd].status);
    diag_printf("TX Queue rear index:  %d\n", pBuf->tq_rear);
    diag_printf("TX Queue front index: %d\n", pBuf->tq_front);
    diag_printf("Number of busy BDs:   %d\n", pBuf->num_busy_bd);

    diag_printf("Dump Transmit Queue\n");
    diag_printf("===================\n");

    while(nbuf_peek_tx_key(pBuf) != -1)
    {
        nbuf_deq_tx_key(pBuf, &key);
        diag_printf("Number of BDs: %d\n", key.num_dbufs);
        diag_printf("Frame length:  %d\n", key.pk_len);
        diag_printf("Begin index to ring bufer: %d\n", key.start_index);
        diag_printf("BD address: %08X\n", &pBuf->TxNBUF[key.tx_buf_index]);
        diag_printf("status: %04X\n", pBuf->TxNBUF[key.tx_buf_index].status);

        diag_printf("End index to ring buffer:  %d\n", key.tx_buf_index);
        diag_printf("Key Info: %08X\n", key.tx_key);
        diag_printf("Key type: %d\n", key.key_type);
        diag_printf("\n");

    }
    diag_printf("===================\n");


}


/********************************************************************
 nbuf_tx_allocate() - Alocate transmit buffer descriptor.

 INPUT:
    pBuf - pointer to the buffer info.

 OUTPUT:
    index - index to the buffer descriptor ring buffer that it returns. This
            value is invalid if this funtion returns a NULL.

 RETURN:
    Returns the pointer to the buffer descriptor. If the ring buffer
    descriptor is full, it returns NULL.

 */
inline static
NBUF *
nbuf_tx_allocate (buf_info_t* pBuf)
{
    NBUF* pBd = &pBuf->TxNBUF[pBuf->iTxbd];

    /*   If the ring buffer is full, then return a NULL.                    */

	if (pBd->status & TX_BD_INUSE)
    {
        nbuf_tx_dump(pBuf);
        return NULL;
    }
	
    /*   Make sure that the  buffer descriptor is still  not in use by  the */
    /* FEC .                                                                */

    CYG_ASSERT(!(pBd->status & TX_BD_R),
               "Buffer descriptor allocated still in use");

    /*   Set the buffer  to be  in used  so that  we can  check the  status */
    /* before we resuse it to send another packet.                          */

    pBd->status |= TX_BD_INUSE;


	/* increment the circular index */
	pBuf->iTxbd = ((pBuf->iTxbd + 1) % NUM_TXBDS);

	return pBd;
}




/*****************************************************************************/

#endif 	/* _NBUF_H */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?