📄 ins_eth_ocm.old
字号:
);
//Wait for transfer to complete
i=0;
do{
result = IORD_ETH_OCM_DESC_CTRL(dev->base, ETH_OCM_FIRST_TX_DESC);
i++;
}while((result & ETH_OCM_TXDESC_READY_MSK) && i<ETH_OCM_TRANSMIT_TIMEOUT);
//Make sure no timeout occurred
if(i<ETH_OCM_TRANSMIT_TIMEOUT){
//TODO Add case for retry
if(result &
(ETH_OCM_TXDESC_UR_MSK |
ETH_OCM_TXDESC_RL_MSK |
ETH_OCM_TXDESC_LC_MSK |
ETH_OCM_TXDESC_CS_MSK)){
dprintf("[eth_ocm_raw_send] Transmit error 0x%x\n", result);
result = -EIO; //Some error occured
}
else
result = 0;
}
else{ //Timeout
result = -ETIMEDOUT;
}
} //End of if(!result) Transmit branch
//Check final result
if(!result){ //Successfull transfer
net->n_mib->ifOutOctets += data_bytes; //Increment TX data counter
// we dont know whether it was unicast or not, we count both in <ifOutUcastPkts>
net->n_mib->ifOutUcastPkts++;
result = SUCCESS;
}
else{ //Failed transfer
dprintf("[eth_ocm_raw_send] Transmit failed, "
"ret=%d, len=%d\n",
result,
len);
net->n_mib->ifOutDiscards++; //increment TX discard counter
result = SEND_DROPPED; // ENP_RESOURCE and SEND_DROPPED have the same value!
}
info->sem = 0; //release semaphore
OS_EXIT_CRITICAL(); //reenable interrupts
return result; //success
}
//End of function eth_ocm_raw_send
/**
* Receive ISR (interrupt service routine)
*
* @param context - context of the Opencores MAC instance
* @param id - IRQ number
*/
void eth_ocm_rx_isr(void *context, alt_u32 id){
eth_ocm_dev *dev;
int result;
dev = (eth_ocm_dev *)context;
//Check to see whether the interrupt was a successfull transfer or not
result = IORD_ETH_OCM_INT_SOURCE(dev->base);
IOWR_ETH_OCM_INT_SOURCE(dev->base, 0x7F); //clear interrupts
//Call the receive function. This will set up a new transfer
eth_ocm_rcv(dev);
//Check to see if there is something in the stack's received queue
if ((rcvdq.q_len) > 0){
SignalPktDemux();
}
}
/**
* Set up the first receive transfer
*/
static int eth_ocm_read_init(eth_ocm_dev *dev){
eth_ocm_info *info;
alt_u8 *uncached_packet_payload;
PACKET *pkt_array;
int result;
int i;
info = dev->info;
pkt_array = info->pkt_array;
pkt_array[0] = pk_alloc(ETH_OCM_BUF_ALLOC_SIZE);
result = 0;
if (!pkt_array[0]){ // couldn't get a free buffer for rx
dprintf("[eth_ocm_read_init] Fatal error: No free packet buffers for RX\n");
return ENP_NOBUFFER;
}
// ensure bit-31 of pkt_array[i]->nb_buff is clear before passing
uncached_packet_payload = (alt_u8*)alt_remap_cached ((volatile void*) pkt_array[0]->nb_buff, 4);
uncached_packet_payload = (alt_u8*)(((unsigned int)uncached_packet_payload) + ETHHDR_BIAS);
if(!(IORD_ETH_OCM_DESC_CTRL(dev->base, ETH_OCM_FIRST_RX_DESC) & ETH_OCM_RXDESC_EMPTY_MSK)){
//Write pointer
IOWR_ETH_OCM_DESC_PTR(dev->base,
ETH_OCM_FIRST_RX_DESC,
uncached_packet_payload);
//Write the control register to start the transfer
IOWR_ETH_OCM_DESC_CTRL(dev->base, ETH_OCM_FIRST_RX_DESC,
(ETH_OCM_RXDESC_EMPTY_MSK |
ETH_OCM_RXDESC_IRQ_MSK |
ETH_OCM_RXDESC_WRAP_MSK)
);
}
else
result = -EBUSY;
if(!result)
result = SUCCESS;
else
dprintf("[eth_ocm_read_init] Fatal error: Unable to set up initial RX\n");
return result;
}
//End of function eth_ocm_read_init
/**
* Receive operation. Checks the status of the received frame.
* Attempt to obtain a new buffer from the InterNiche stack.
* Schedules another RX transfer
*
* @return SUCCESS on success
*/
static int eth_ocm_rcv(eth_ocm_dev *dev)
{
eth_ocm_info *info;
struct ethhdr *eth;
int pklen;
int stat;
int i;
PACKET pkt;
PACKET *pkt_array;
alt_u8 *uncached_packet_payload;
info = dev->info;
pkt_array = info->pkt_array;
stat = IORD_ETH_OCM_DESC_CTRL(dev->base, ETH_OCM_FIRST_RX_DESC);
pklen = stat & ETH_OCM_RXDESC_LEN_MSK;
pklen = pklen >> ETH_OCM_RXDESC_LEN_OFST;
//Increment received byte count
info->netp->n_mib->ifInOctets += (u_long)pklen;
pkt_array[0]->nb_prot = pkt_array[0]->nb_buff + ETHHDR_SIZE;
pkt_array[0]->nb_plen = pklen - (14 + 4); //Packet length minus (header + CRC)
//TODO See if MAC appends CRC
pkt_array[0]->nb_tstamp = cticks;
pkt_array[0]->net = info->netp;
// set packet type for demux routine
eth = (struct ethhdr *)(pkt_array[0]->nb_buff + ETHHDR_BIAS);
pkt_array[0]->type = eth->e_type;
if (!(stat & ETH_OCM_RXDESC_ERROR_MSK)){
pkt = pk_alloc(ETH_OCM_BUF_ALLOC_SIZE);
if (!pkt){ // couldn't get a free buffer for rx
dprintf("No free buffers for rx\n");
info->netp->n_mib->ifInDiscards++;
}
else{
putq(&rcvdq, pkt_array[0]);
pkt_array[0] = pkt;
}
}
else{
dprintf("[eth_ocm_rcv] Frame discarded due to errors!\n");
info->netp->n_mib->ifInDiscards++;
}
// ensure bit-31 of pkt_array[]->nb_buff is clear before passing
// to DMA Driver
uncached_packet_payload = (alt_u8*)alt_remap_cached ((volatile void*) pkt_array[0]->nb_buff, 4);
uncached_packet_payload = (alt_u8*)((unsigned int)uncached_packet_payload + ETHHDR_BIAS);
if(!(IORD_ETH_OCM_DESC_CTRL(dev->base, ETH_OCM_FIRST_RX_DESC) & ETH_OCM_RXDESC_EMPTY_MSK)){
//Write pointer
IOWR_ETH_OCM_DESC_PTR(dev->base,
ETH_OCM_FIRST_RX_DESC,
(unsigned int)uncached_packet_payload);
//Write the control register to start the transfer
IOWR_ETH_OCM_DESC_CTRL(dev->base, ETH_OCM_FIRST_RX_DESC,
(ETH_OCM_RXDESC_EMPTY_MSK |
ETH_OCM_RXDESC_IRQ_MSK |
ETH_OCM_RXDESC_WRAP_MSK)
);
}
else
stat = -EBUSY;
return SUCCESS;
}
void eth_ocm_stats(void *pio, int iface) {
NET ifp;
eth_ocm_dev *dev;
//get the ifp first
ifp = nets[iface];
dev = (eth_ocm_dev *)ifp->n_local;
ns_printf(pio, "eth_ocm_stats(), stats will be added later!\n");
}
/**
* Closes the opencores mac interface
*
* @param iface index of the NET interface associated with the Opencores MAC.
* @return SUCCESS
*/
int eth_ocm_close(int iface)
{
int err;
NET ifp;
eth_ocm_dev *dev;
/* status = down */
ifp = nets[iface];
dev = (eth_ocm_dev *)ifp->n_local;
ifp->n_mib->ifAdminStatus = ETH_OCM_STATUS_DOWN;
/* disable the interrupt in the OS*/
err = alt_irq_register (dev->irq, 0, NULL);
if (err){
dprintf("[eth_ocm_close]Could not unregister interrupt, error = %d\n",err);
return err;
}
// Shut down the MAC
IOWR_ETH_OCM_MODER(dev->base, 0);
/* status = down */
ifp->n_mib->ifOperStatus = ETH_OCM_STATUS_DOWN;
//deallocate memory for the eth_ocm_info struct allocated in eth_ocm_prep
free(dev->info);
return SUCCESS;
}
//End of file ins_eth_ocm.h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -