void ncpfree(void *ptr) { if(ptr) { ptr = alt_remap_cached(ptr, sizeof(ptr)); npfree(ptr); } }
/** 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; }
/** * 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
/****************************************************************** * 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)); } } }