Ejemplo n.º 1
0
void ncpfree(void *ptr)
{
   if(ptr) {
      ptr = alt_remap_cached(ptr, sizeof(ptr));
      npfree(ptr);
   }
}
Ejemplo n.º 2
0
/** This is the asynchronous raw send function. It sets up a transfer
 *  but does not wait for it to conclude. It sets the MAC to interrupt
 *  when the transfer has finished. This is not threadsafe.
 *
 *  @param NET
 *  @param data
 *  @param data_bytes
 *
 *  @return 0 if Successful, negative otherwise
 */
int eth_ocm_low_send(NET net, char *data, unsigned data_bytes){
    int result;
    unsigned len;
    eth_ocm_dev *dev;
    eth_ocm_info *info;
    eth_ocm_regs *regs;
    alt_u8 *buf;

    dev = (eth_ocm_dev *)net->n_local;
    info = dev->info;
    regs = dev->regs;
    len = data_bytes - ETHHDR_BIAS;
    result = SUCCESS;

    //Check to see if someone is nesting send calls (BAD!)
    if(info->sem){
       dprintf("[eth_ocm_low_send] ERROR: Nested low send call\n");
       return ENP_RESOURCE;
    }
    //Grab the semaphore
    info->sem = 1;
    // clear bit-31 before passing it to SGDMA Driver
    buf = (alt_u8 *)alt_remap_cached( (volatile void *)data, 4);
    //advance the pointer beyond the header bias
    buf = (alt_u8 *)((unsigned int)buf + ETHHDR_BIAS);

    //Some error checks first
    if(len < ETH_OCM_MIN_MTU)
        result = -1;        //packet too small
    if(len > ETH_OCM_MAX_MTU)
        result = -EFBIG;    //packet too big
    if(regs->txdescs[info->next_tx_desc].ctrl & ETH_OCM_TXDESC_READY_MSK)
        result = -EBUSY;    //DMA not available

    if(result == SUCCESS){
        //Write pointer to descriptor
        regs->txdescs[info->next_tx_desc].ptr = (unsigned int)buf;
        //Write length and setup transfer
        result = ((len << ETH_OCM_TXDESC_LEN_OFST)  |
                 ETH_OCM_TXDESC_READY_MSK           |
                 ETH_OCM_TXDESC_IRQ_MSK             |
                 ETH_OCM_TXDESC_PAD_MSK             |
                 ETH_OCM_TXDESC_CRC_MSK);
        //See if wrap flag should be set
        if(info->next_tx_desc == (ETH_OCM_TX_DESC_COUNT - 1))
            result |= ETH_OCM_TXDESC_WRAP_MSK;
        //Write descriptor
        regs->txdescs[info->next_tx_desc].ctrl = result;
        #if (ETH_OCM_DBG_LVL >= 5)
            dprintf("[eth_ocm_low_send] Sent packet with descriptor 0x%08x\n", result);
        #endif
        result = SUCCESS;
    }

    info->sem = 0;
    return result;
}
Ejemplo n.º 3
0
/**
 *  Raw send function to initiate a transfer to the mac 
 *
 * @param  net  - NET structure associated with the Opencores MAC instance
 * @param  data - pointer to the data payload
 *
 * @return SUCCESS if success, else a negative value
 */
int eth_ocm_raw_send(NET net, char * data, unsigned data_bytes){
    int result;
    int i;
    unsigned len;
    eth_ocm_dev *dev;
    eth_ocm_info *info;
    eth_ocm_regs *regs;
    alt_u8 *buf;
#ifdef UCOS_II
    int cpu_sr;
#endif

    OS_ENTER_CRITICAL(); //disable interrupts

    dev = (eth_ocm_dev *)net->n_local;
    info = dev->info;
    regs = dev->regs;
    len = data_bytes - ETHHDR_BIAS;
    result = 0;

    //Check to see if someone is nesting send calls (BAD!)
    if(info->sem){
       dprintf("[eth_ocm_raw_send] ERROR: Nested raw send call\n");
       OS_EXIT_CRITICAL();
       return ENP_RESOURCE;
    }

    //Grab the semaphore
    info->sem = 1;
    // clear bit-31 before passing it to SGDMA Driver
    buf = (alt_u8 *)alt_remap_cached( (volatile void *)data, 4);
    //advance the pointer beyond the header bias
    buf = (alt_u8 *)((unsigned int)buf + ETHHDR_BIAS);

    //Some error checks first
    if(len < ETH_OCM_MIN_MTU)
        result = -1;        //packet too small
    if(len > ETH_OCM_MAX_MTU)
        result = -EFBIG;    //packet too big
    if(regs->txdescs[0].ctrl & ETH_OCM_TXDESC_READY_MSK)
        result = -EBUSY;    //DMA not available

    if(!result){
        //Write pointer to descriptor
        regs->txdescs[0].ptr = (unsigned int)buf;
        //Write length and setup transfer
        regs->txdescs[0].ctrl =
                ((len << ETH_OCM_TXDESC_LEN_OFST)    |
                 ETH_OCM_TXDESC_READY_MSK            |
                 ETH_OCM_TXDESC_WRAP_MSK             |
                 ETH_OCM_TXDESC_PAD_MSK              |
                 ETH_OCM_TXDESC_CRC_MSK);
        //Wait for transfer to complete
        i=0;
        do{
            result = regs->txdescs[0].ctrl;
            i++;
        }while((result & ETH_OCM_TXDESC_READY_MSK) && i<ETH_OCM_TRANSMIT_TIMEOUT);
        //Make sure no timeout occurred
        if(i<ETH_OCM_TRANSMIT_TIMEOUT){
            if(result &
                    (ETH_OCM_TXDESC_UR_MSK      |
                    ETH_OCM_TXDESC_RL_MSK       |
                    ETH_OCM_TXDESC_LC_MSK       |
                    ETH_OCM_TXDESC_CS_MSK)){
                #if (ETH_OCM_DBG_LVL >= 2)
                dprintf("[eth_ocm_raw_send] Transmit error 0x%x\n", result);
                #endif // if ETH_OCM_DBG_LVL
                result = -EIO;  //Some error occured
            } 
            else{
                #if (ETH_OCM_DBG_LVL >= 5)
                if(result & ETH_OCM_TXDESC_RTRY_MSK)
                    dprintf("[eth_ocm_raw_send] Transmit retries: %d\n", (result & ETH_OCM_TXDESC_RTRY_MSK)>>ETH_OCM_TXDESC_RTRY_OFST);
                #endif
                result = 0;
            }
        } 
        else{   //Timeout
Ejemplo n.º 4
0
/******************************************************************
 * alt_video_display_setup_frame_descriptors
 * 
 * Populate and prepare a video frame's SGDMA descriptors. 
 * 
 * Arguments:
 *   *display: The video display the frame is being prepared for
 *   *frame: The video frame you're constructing
 *   *buffer: The starting-address of your physical display buffer. 
 *    This must be a single, continuous span of memory large enough 
 *    for each pixel in the frame.
 *   *desc_base: The starting-address of memory allocated for 
 *    SGDMA descriptors. Descriptor memory must be aligned to a 
 *    0x20 boundary.
 ******************************************************************/
void alt_video_display_setup_frame_descriptors(
  alt_video_display *display,
  alt_video_frame *frame,
  alt_u32 *buffer,
  alt_sgdma_descriptor *desc_base)
{
  int i;
  alt_u16 length;
  alt_32 buffer_no_cache_bypass;
  alt_sgdma_descriptor *last_descriptor;
  
  /*
   * We don't want the "uncached" bit set in the buffer address we hand
   * off to the SGDMA, so we mask it out here.
   */
  buffer_no_cache_bypass = 
    (alt_u32) alt_remap_cached( buffer, display->bytes_per_frame );
  
  for(i=0; i<display->descriptors_per_frame; i++){
    /* 
     * Calculate the data length associated with each descriptor, taking
     * into account the edge cases 
     */
    if(i == (display->descriptors_per_frame-1)) {
      length = (display->bytes_per_frame % ALT_VIDEO_DISPLAY_BYTES_PER_DESC);

       /* 
        * The init routine calculated the number of desriptors per frame, 
        * based on frame size (bytes) and bytes per descriptor. Being evenly
        * divisible on this last frame means a full-length sized frame.
        */
       if(length == 0) {
         length = ALT_VIDEO_DISPLAY_BYTES_PER_DESC;
       }
    }
    else {
      length = ALT_VIDEO_DISPLAY_BYTES_PER_DESC;
    }
    
    /* Construct the descriptor */
    alt_avalon_sgdma_construct_mem_to_stream_desc(
      (frame->desc_base + i),                    /* Descriptor */
      ( frame->desc_base + i + 1 ),              /* Next descriptor */
      (alt_u32*)( (alt_u8*)buffer_no_cache_bypass +
         (ALT_VIDEO_DISPLAY_BYTES_PER_DESC*i) ), /* Read Address */
      length,                                    /* Transfer length */
      0,                                         /* Don't read fixed addr */
      i==0?1:0,                                  /* Generate SOP @ first desc */
      i==(display->descriptors_per_frame-1)?1:0, /* Generate EOP @ last desc */
      0                                          /* Streaming channel: N/A */
    );
    
    /* 
     * The last descriptor we created above requires a special modification: 
     * Its "next" pointer should point back to the first descriptor in the 
     * chain to create a loop.
     * 
     * This was not done done in the above SGDMA descriptor creation routine 
     * call because that routine always terminates the 'next' descriptor 
     * pointer to prevent the SGDMA from continuing into unknown memory.
     */
    if( i == ( display->descriptors_per_frame - 1 ) ) {  
      last_descriptor = (alt_sgdma_descriptor *) (frame->desc_base + i);
      
      IOWR_32DIRECT((alt_u32)(&last_descriptor->next), 0, 
        (alt_u32)(frame->desc_base));
    }
  }
}