Здравствуйте. Помогите, пожалуйста, разобраться с проблемой.
Собственно, стоит задача отправить ethernet фрейм, используя TSE. В наличии стенд Altera DE2-115 (Циклон4, Marvel 88E1111). Аппаратную часть взял от Simple Socket Server, программную(драйвер) использую от ув. Vadimuzzz'a.
MAC_init:Цитата
int MAC_init() {
alt_u32 tse_cmd_cfg = 0;
tse_cmd_cfg = IORD_ALTERA_TSEMAC_CMD_CONFIG(TSE_MAC_BASE);
printf("MAC_init(): tse_cmd_cfg= %x\n", tse_cmd_cfg);
alt_u32 /*t,*1=0,*/t2 = 0;
int status = 0;
p_counter = 0;
alt_u16 phyid1, phyid2;
/* PHY инициализация */
IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TSE_MAC_BASE,PHY);
phyid1 = IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE, 0, 2);
phyid2 = IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE, 0, 3);
printf ("PHY=%X phy found:id1 %x, id2 %x\n",PHY, phyid1, phyid2);
do {
Delay(0xFFFFF);
t2=IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,ALTERA_TSEMAC_PHY_ADDR_STATUS);
printf("t2=%d\n", t2);
}
while ((t2 & 0x04) == 0);//wait link-up
printf("t2=%d\n", t2);
/* ПОлучаем адреса Rx и Tx SGDMA */
sgdma_tx_dev = alt_avalon_sgdma_open(SGDMA_TX_NAME);
sgdma_rx_dev = alt_avalon_sgdma_open(SGDMA_RX_NAME);
if((!sgdma_tx_dev)||(!sgdma_rx_dev)) {
printf("[triple_speed_ethernet_init] Error opening TX or RX SGDMA\n");
}
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_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) {
}
/* Инициализация мак регистров */
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);
IOWR_ALTERA_TSEMAC_TX_SECTION_FULL(TSE_MAC_BASE, 16);
IOWR_ALTERA_TSEMAC_RX_SECTION_EMPTY(TSE_MAC_BASE, TSE_MAC_RECEIVE_FIFO_DEPTH - 16);
IOWR_ALTERA_TSEMAC_RX_SECTION_FULL(TSE_MAC_BASE, 16);
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));
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;
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_SGDMA_RX_DESC_OFST], // descriptor I want to work with
(alt_sgdma_descriptor *) &desc[ALTERA_TSE_SECOND_SGDMA_RX_DESC_OFST], // 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_SGDMA_RX_DESC_OFST]);
tse_cmd_cfg = IORD_ALTERA_TSEMAC_CMD_CONFIG(TSE_MAC_BASE);
printf("MAC_init(): tse_cmd_cfg= %x\n", tse_cmd_cfg);
sem = 0;
printf("controlPHY = %x\n",IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE, 0, 0));
printf("statusPHY = %x\n",IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE, 0, 1));
return status;
}
tse_mac_raw_send:Цитата
int tse_mac_raw_send(char * data, unsigned data_bytes) {
alt_u32 *uncached_packet_payload;
alt_32 timeout;
alt_u16 actualBytesTransferred=0;
int result;
if (sem != 0) /* Tx занят*/
{
alt_printf("Tx is busy\n");
return -22;
}
sem = 1;
// clear bit-31 before passing it to SGDMA Driver
uncached_packet_payload = (alt_u32*) alt_remap_cached(
(volatile void*) data, 4);
if (data_bytes > ALTERA_TSE_MIN_MTU_SIZE) {
alt_avalon_sgdma_construct_mem_to_stream_desc(
(alt_sgdma_descriptor *) &desc[ALTERA_TSE_FIRST_SGDMA_TX_DESC_OFST], // descriptor I want to work with
(alt_sgdma_descriptor *) &desc[ALTERA_TSE_SECOND_SGDMA_TX_DESC_OFST],// 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;
// Проверяем не занят ли TX и SGDMA
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
}
}
// Начинаем передачу
IOWR_ALTERA_AVALON_SGDMA_CONTROL (SGDMA_TX_BASE, 0);
IOWR_ALTERA_AVALON_SGDMA_STATUS (SGDMA_TX_BASE, 0xFF);
result = alt_avalon_sgdma_do_sync_transfer(
sgdma_tx_dev,
(alt_sgdma_descriptor *) &desc[ALTERA_TSE_FIRST_SGDMA_TX_DESC_OFST]);
//printf("tse_sgdmaRx_isr() result = %d\n", result);
} else {
result = -3;
}
if (result < 0) /* SGDMA не доступен */
{
alt_printf("raw_send() SGDMA not available\n");
sem = 0;
return -22;
} else /* Всё ОК*/
{
sem = 0;
actualBytesTransferred=0;
actualBytesTransferred = IORD_ALTERA_TSE_SGDMA_DESC_ACTUAL_BYTES_TRANSFERRED(&desc[ALTERA_TSE_FIRST_SGDMA_TX_DESC_OFST]);
//printf("actualBytesTransferred = %d\n", actualBytesTransferred);
return 0; /*ОК */
}
}
отправка пакетов из MainЦитата
while (1){
a=IORD_ALTERA_AVALON_PIO_DATA(SW_BASE);
if (a==0x01){
while (a==0x1)
{
res_init = tse_mac_raw_send(data_ptr, 200);
res_init = tse_mac_raw_send(data_test1, 200);
res_init = tse_mac_raw_send(data_test2, 200);
res_init = tse_mac_raw_send(data_test3, 200);
a=IORD_ALTERA_AVALON_PIO_DATA(SW_BASE);
}
StatisticsCounters_Report();
}
}
В итоге, внешне вроде как всё работает: Светодиоды TX, RX на Marverl моргают, запускается на скорости 1гбит/c full duplex (судя по светодиодам). В консоль получаю вывод:
Цитата
------------------------------------------------------Hello from NIOS
MAC_init(): tse_cmd_cfg= 4000223
PHY=10 phy found:id1 141, id2 cc2
t2=31081
t2=31085
t2=31085
MAC_init(): tse_cmd_cfg= 4000223
controlPHY = 1140
controlPHY = 796d
MAC init err: 0
------------------------------------------------------------------
The MAC address 1: F0AB0700
The MAC address 2: BA0D
The number of frames that are successfully transmitted including the pause frames: 168067
The number of receive frames with CRC error: 0
The number of data and padding octets that are successfully transmitted: 31260462
The number of data and padding octets that are successfully received: 0
The number of pause frames transmitted: 0
The number received pause frames received: 0
The number of errored frames received: 0
The number of transmit frames with one the following errors(see TSE guide 5-10): 13
The number of valid unicast frames received: 0
The number of valid multicast frames received(without pause frames): 0
The number of valid broadcast frames received: 0
The number of valid unicast frames transmitted: 126049
The number of valid multicast frames transmitted, excluding pause frames: 42020
The number of valid broadcast frames transmitted: 0
The number of frames that are dropped due to MAC internal errors when FIFO buffer overflow persists: 0
The total number of octets received: 0
The total number of frames received: 0
The number of frames received with length less than 64 bytes: 0
The number of frames received that are longer than the value configured in the frm_length register: 0
The number of 64-byte good and err frames received: 0
The number of received good and errored frames between the length of 65 and 127 bytes: 0
The number of received good and errored frames between the length of 128 and 255 bytes: 0
The number of received good and errored frames between the length of 256 and 511 bytes: 0
The number of received good and errored frames between the length of 512 and 1023 bytes: 0
The number of received good and errored frames between the length of 1024 and 1518 bytes: 0
The number of received good and errored frames between the length of 1519 and the maximum frame length configured in the frm_length register: 0
Too long frames with CRC error: 0
Too short frames with CRC error: 0
------------------------------------------------------------------tse_sgdmaRx_isr(): Im here
Packet counter:1
ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_CRC_MSK
RX descriptor reported error. Packet dropped
tse_sgdmaRx_isr(): Im here
Packet counter:2
ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_CRC_MSK
RX descriptor reported error. Packet dropped
tse_sgdmaRx_isr(): Im here
Packet counter:3
ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_CRC_MSK
RX descriptor reported error. Packet dropped
Т.е. судя по Statistics Counters и светодиодам всё успешно отправляется. Но на WireShark (ОС win7) тишина.. В чем может быть проблема??
Да и почему SGDMA рапортует об ошибках входящих пакетов?
P.S. До этого успешно отправлял пакеты с помощью демонстрационного примера Simple Socket Server.
P.S.S. Заранее извиняюсь за глупые ошибки) До этого с FPGA не работал.)