Я так понимаю что нужно alt_dcache_flush() , но праильно ли я делаю не уверен (вернее совсем не правильно делаю скорее всего). Вот исходник вашего eth_driver.c
CODE
#include "control.h"
#include "system.h"
#include "defines.h"
#include "sys/alt_irq.h"
#include "triple_speed_ethernet_regs.h"
#include "altera_avalon_sgdma.h"
#include "altera_avalon_sgdma_descriptor.h"
#include "altera_avalon_sgdma_regs.h"
#include "sys/alt_cache.h"
#include "sys/alt_stdio.h"
#include "eth_driver.h"
#include "network.h"
#include <errno.h>
#include "altera_avalon_tse.h"
//---------------------------------------------------------------------------------------------
//alt_sgdma_descriptor *desc = (alt_sgdma_descriptor *) DESCRIPTOR_MEMORY_BASE;
alt_sgdma_descriptor *desc = (alt_sgdma_descriptor *) 0x4000000;
alt_sgdma_descriptor *currdescriptor_ptr;
alt_sgdma_descriptor *nextdescriptor_ptr;
alt_sgdma_descriptor *desc_pointer;
alt_sgdma_dev *sgdma_tx_dev;
alt_sgdma_dev *sgdma_rx_dev;
volatile char pkt[1562] __attribute__ ((aligned (4)));
volatile char pkt_copy[1562] __attribute__ ((aligned (4)));
int sem;
alt_u32 p_counter;
//---------------------------------------------------------------------------------------------
int MAC_init()
{
alt_u32 t2=0;
alt_u32 t5 =0;
int status=0;
p_counter=0;
// /* PHY and other board peripherial initialization */
IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TSE_MAC_BASE,PHY); //
IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x00,0x3100);
IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x04,0x1E1);
// IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x09,0x1C0);// nnn
// IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x10,0x68); //nnn
IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x14,0xC53);
// IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x14,0xC51);//delay to RX/TX
// IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x14,0xCD1);//delay to RX/TX
IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,0x00,0xB100); //peregrujaem MAC SOFT Reset
do
{
Delay(0xFFFF);
t2=IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,MDIO_SPACE0,ALTERA_TSEMAC_PHY_ADDR_STATU
S);
}
while((t2&0x04)==0);//wait for link-up
// printf("t2 %x\n",t2);
alt_u32 desc_mem_clear_count=0;
for(desc_mem_clear_count=0;desc_mem_clear_count<256;++desc_mem_clear_count)
{
IOWR(DESCRIPTOR_MEMORY_BASE,desc_mem_clear_count,0);
}
currdescriptor_ptr = &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST];
nextdescriptor_ptr = (alt_sgdma_descriptor *) IORD_ALTERA_TSE_SGDMA_DESC_NEXT(currdescriptor_ptr);
desc_pointer = currdescriptor_ptr;
desc_pointer->status&=~ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK;
desc_pointer = currdescriptor_ptr;
/* Get the Rx and Tx SGDMA addresses */
sgdma_tx_dev = alt_avalon_sgdma_open("/dev/sgdma_tx");
sgdma_rx_dev = alt_avalon_sgdma_open("/dev/sgdma_rx");
IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_RX_BASE,ALTERA_AVALON_SGDMA_CONTROL_SOFTW
ARERESET_MSK);
IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_RX_BASE, 0x0);
IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_TX_BASE,ALTERA_AVALON_SGDMA_CONTROL_SOFTW
ARERESET_MSK); //-
IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_TX_BASE, 0x0);//-
// printf("SGDMA TX %x, SGDMA RX %x\n",sgdma_tx_dev, sgdma_rx_dev);
/* reset the mac */
IOWR_ALTERA_TSEMAC_CMD_CONFIG(TSE_MAC_BASE , ALTERA_TSEMAC_CMD_SW_RESET_MSK | ALTERA_TSEMAC_CMD_TX_ENA_MSK | ALTERA_TSEMAC_CMD_RX_ENA_MSK);
while(IORD_ALTERA_TSEMAC_CMD_CONFIG(TSE_MAC_BASE) & ALTERA_TSEMAC_CMD_SW_RESET_MSK)
{
}
/* Initialize MAC registers */
IOWR_ALTERA_TSEMAC_FRM_LENGTH(TSE_MAC_BASE, ALTERA_TSE_MAC_MAX_FRAME_LENGTH);
IOWR_ALTERA_TSEMAC_RX_ALMOST_EMPTY(TSE_MAC_BASE, 8);
IOWR_ALTERA_TSEMAC_RX_ALMOST_FULL(TSE_MAC_BASE, 8);
IOWR_ALTERA_TSEMAC_TX_ALMOST_EMPTY(TSE_MAC_BASE, 8);
IOWR_ALTERA_TSEMAC_TX_ALMOST_FULL(TSE_MAC_BASE, 3);
IOWR_ALTERA_TSEMAC_TX_SECTION_EMPTY(TSE_MAC_BASE, TSE_MAC_TRANSMIT_FIFO_DEPTH - 16); //1024/4;
IOWR_ALTERA_TSEMAC_TX_SECTION_FULL(TSE_MAC_BASE, 0); //16/32/4; // start transmit when there are 48 bytes
IOWR_ALTERA_TSEMAC_RX_SECTION_EMPTY(TSE_MAC_BASE, TSE_MAC_RECEIVE_FIFO_DEPTH - 16); //4000/4);
IOWR_ALTERA_TSEMAC_RX_SECTION_FULL(TSE_MAC_BASE, 0);//16
IOWR_ALTERA_TSEMAC_TX_CMD_STAT(TSE_MAC_BASE,ALTERA_TSEMAC_TX_CMD_STAT_TXSHIFT16_
MSK);
IOWR_ALTERA_TSEMAC_TX_CMD_STAT(TSE_MAC_BASE,0);
IOWR_ALTERA_TSEMAC_RX_CMD_STAT(TSE_MAC_BASE,ALTERA_TSEMAC_RX_CMD_STAT_RXSHIFT16_
MSK);
IOWR_ALTERA_TSEMAC_RX_CMD_STAT(TSE_MAC_BASE,0);
IOWR_ALTERA_TSEMAC_CMD_CONFIG(TSE_MAC_BASE, ALTERA_TSEMAC_CMD_TX_ENA_MSK | ALTERA_TSEMAC_CMD_RX_ENA_MSK | ALTERA_TSEMAC_CMD_TX_ADDR_INS_MSK | ALTERA_TSEMAC_CMD_RX_ERR_DISC_MSK | ALTERA_TSEMAC_CMD_PAD_EN_MSK);
IOWR_ALTERA_TSEMAC_MAC_0(TSE_MAC_BASE,((int)(0x00) | (int)(0x07 << 8) | (int)(0xAB << 16) | (int)(0xF0 << 24)));
IOWR_ALTERA_TSEMAC_MAC_1(TSE_MAC_BASE,(((int)(0x0D) | (int)(0xBA << 8)) & 0xFFFF));
int tse_mac00;
int tse_mac01;
tse_mac00 = IORD_ALTERA_TSEMAC_MAC_0(TSE_MAC_BASE);
tse_mac01 = IORD_ALTERA_TSEMAC_MAC_1(TSE_MAC_BASE);
/*вывожу в терминал сообщение о МАК адресе и установленном IP адресе*/
printf("MAC addr setted! %X%X:%X%X:%X:%X:%X%X:%X\n",(tse_mac00&0x000000F0),(tse_mac00&0x0000000F),((tse_mac00&0x0000F000)>>8),((tse_mac00&0x00000F00)>>8),((tse_mac00&0x00FF0000)>>16),
((tse_mac00&0xFF000000)>>24),(tse_mac01&0x00F0),(tse_mac01&0x000F),((tse_mac01&0xFF00)>>8));
alt_avalon_sgdma_register_callback(sgdma_rx_dev,(alt_avalon_sgdma_callback)&tse_sgdmaRx_isr,(alt_u16)ALTERA_TSE_SGDMA_INTR_MASK,sgdma_rx_dev);
alt_u32 *uncached_packet_payload;
alt_dcache_flush(pkt, 4);
uncached_packet_payload = (void *)alt_remap_cached ((volatile void*) pkt, 4);
alt_dcache_flush(uncached_packet_payload, 4);
alt_avalon_sgdma_construct_stream_to_mem_desc(
(alt_sgdma_descriptor *) &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST], // descriptor I want to work with
(alt_sgdma_descriptor *) &desc[ALTERA_TSE_SECOND_RX_SGDMA_DESC_OFST], // pointer to "next"
uncached_packet_payload, // starting write_address
0, // read until EOP
0);
// alt_avalon_sgdma_construct_stream_to_mem_desc(
// currdescriptor_ptr, // descriptor I want to work with
// nextdescriptor_ptr, // pointer to "next"
// uncached_packet_payload, // starting write_address
// 0, // read until EOP
// 0);
while ((IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_RX_BASE) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK));
t2=alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST]);
sem=0;
return status;
}
//---------------------------------------------------------------------------------------------
int tse_sgdmaRx_isr(void * context, alt_u32 irqnum)
{
alt_u32 t2=0;
static int p_counter;
alt_u32 *uncached_packet_payload;
t2=IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_RX_BASE);
if (t2 & (ALTERA_AVALON_SGDMA_STATUS_CHAIN_COMPLETED_MSK |
ALTERA_AVALON_SGDMA_STATUS_DESC_COMPLETED_MSK))
{
p_counter++;
IOWR_ALTERA_AVALON_SGDMA_STATUS(SGDMA_RX_BASE,ALTERA_AVALON_SGDMA_STATUS_CHAIN_C
OMPLETED_MSK);
t2=IORD_ALTERA_TSE_SGDMA_DESC_STATUS(&desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST]);
/*check status and handle packet*/
if( (t2 &
(ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_CRC_MSK |
ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_PARITY_MSK |
ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_OVERFLOW_MSK |
ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_SYNC_MSK |
ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_UEOP_MSK |
ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_MEOP_MSK |
ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_MSOP_MSK ) ) == 0)
{
t2=IORD_16DIRECT(&desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST].actual_bytes_transferred, 0)-2;
alt_printf("Packet counter: 0x%x len bytes: 0x%x\n",p_counter, t2);
alt_printf("data: |%x|%x|%x|%x|%x|%x|%x|%x| |%x|%x|%x|%x|%x|%x|%x|%x|\n",
pkt[0]&0xFF,pkt[1]&0xFF,pkt[2]&0xFF,pkt[3]&0xFF,pkt[4]&0xFF,pkt[5]&0xFF,pkt[6]&0xFF,pkt[7]&0xFF,
pkt[8]&0xFF,pkt[9]&0xFF,pkt[10]&0xFF,pkt[11]&0xFF,pkt[12]&0xFF,pkt[13]&0xFF,pkt[14]&0xFF,pkt[15]&0xFF);
alt_printf(" |%x|%x|%x|%x|%x|%x|%x|%x| |%x|%x|%x|%x|%x|%x|%x|%x|\n",
pkt[16]&0xFF,pkt[17]&0xFF,pkt[18]&0xFF,pkt[19]&0xFF,pkt[20]&0xFF,pkt[21]&0xFF,pkt[22]&0xFF,pkt[23]&0xFF,
pkt[24]&0xFF,pkt[25]&0xFF,pkt[26]&0xFF,pkt[27]&0xFF,pkt[28]&0xFF,pkt[29]&0xFF,pkt[30]&0xFF,pkt[31]&0xFF);
CheckPacket(pkt,t2);
}
else
{
alt_printf("RX descriptor reported error. Packet dropped\n");
}
uncached_packet_payload = (void *)alt_remap_cached ((volatile void*) pkt, 4);
alt_avalon_sgdma_construct_stream_to_mem_desc(
(alt_sgdma_descriptor *) &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST], // descriptor I want to work with
(alt_sgdma_descriptor *) &desc[ALTERA_TSE_SECOND_RX_SGDMA_DESC_OFST], // pointer to "next"
uncached_packet_payload, // starting write_address
0, // read until EOP
0); // don't write to constant address
// t2=alt_avalon_sgdma_do_sync_transfer(sgdma_rx_dev, &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST]);
t2=alt_avalon_sgdma_do_async_transfer(
sgdma_rx_dev,
&desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST]);
}
return 0;
}
//--------------------------------Ethernet Message Send-----------------------------
int tse_mac_raw_send(char * data, unsigned data_bytes)
{
alt_u32 *uncached_packet_payload;
alt_32 timeout;
int result;
if(sem!=0) /* Tx is busy*/
{
alt_printf("Tx is busy\n");
return -22;
}
sem = 1;
alt_dcache_flush(data, data_bytes);
// clear bit-31 before passing it to SGDMA Driver
// uncached_packet_payload = (alt_u32*)alt_remap_cached ((volatile void*) data, 4);
uncached_packet_payload = (alt_u32*)alt_remap_cached ((volatile void*) data, data_bytes);
/* Write data to Tx FIFO using the DMA */
// alt_dcache_flush(uncached_packet_payload, data_bytes);
if( data_bytes > ALTERA_TSE_MIN_MTU_SIZE )
{
alt_printf("TX Starting read adrr %x - bytes %x\n",uncached_packet_payload, data_bytes);
/* make sure there is room in the FIFO. */
alt_avalon_sgdma_construct_mem_to_stream_desc(
currdescriptor_ptr, // descriptor I want to work with
nextdescriptor_ptr,// pointer to "next"
uncached_packet_payload, // starting read address
data_bytes, // # bytes
0, // don't read from constant address
1, // generate sop
1, // generate endofpacket signal
0); // atlantic channel (don't know/don't care: set to 0)
result = 0;
// Make sure DMA controller is not busy from a former command
// and TX is able to accept data
timeout = 0;
while ( (IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_TX_BASE) &
ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK) )
{
if(timeout++ == ALTERA_TSE_SGDMA_BUSY_TIME_OUT_CNT)
{
alt_printf("WARNING : TX SGDMA Timeout\n");
return -22; // avoid being stuck here
}
}
// Set up the SGDMA
// Clear the status and control bits of the SGDMA descriptor
IOWR_ALTERA_AVALON_SGDMA_CONTROL (SGDMA_TX_BASE, 0);
IOWR_ALTERA_AVALON_SGDMA_STATUS (SGDMA_TX_BASE, 0xFF);
// Start SGDMA (blocking call)
result = alt_avalon_sgdma_do_async_transfer(
sgdma_tx_dev,
(alt_sgdma_descriptor *) &desc[ALTERA_TSE_FIRST_TX_SGDMA_DESC_OFST]);
}
else
{
result = -3;
}
// printf("transfer %x\n", result);
if(result < 0) /* SGDMA not available */
{
alt_printf("raw_send() SGDMA not available\n");
sem = 0;
return -22; /* ENP_RESOURCE and SEND_DROPPED have the same value! */
}
else /* = 0, success */
{
sem = 0;
return 0; /*success */
}
}
//---------------------------------------------------------------------------------------------