605 lines
17 KiB
C
605 lines
17 KiB
C
//#include <gmac_defines.h>
|
|
//#include <prototypes.h>
|
|
|
|
#include <config.h>
|
|
#include <common.h>
|
|
#include <malloc.h>
|
|
#include <net.h>
|
|
#include <command.h>
|
|
#include <asm/io.h>
|
|
#include <asm/addrspace.h>
|
|
#include <asm/types.h>
|
|
|
|
#include <atheros.h>
|
|
#include "qca-eth-955x.h"
|
|
#include "qca-eth-955x_phy.h"
|
|
|
|
#ifdef ATH_RGMII_CAL
|
|
|
|
#define NUM_DESCRIPTORS 10 //Number of packets to be looped back
|
|
#define node_tx_buf_len 100 // No of bytes per packet to be looped back
|
|
|
|
#define DEBUG 0
|
|
#define DEBUG_1 0
|
|
|
|
#define GE0_PEMSTAT_RBYT (0x9c + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_RPKT (0xA0 + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_RFCS (0xA4 + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_RMCA (0xA8 + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_RBCA (0xAC + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_RXCF (0xB0 + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_RXPF (0xB4 + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_RXUO (0xB8 + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_RALN (0xBC + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_RFLR (0xC0 + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_RCDE (0xC4 + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_RCSE (0xC8 + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_RUND (0xCC + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_ROVR (0xD0 + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_RFRG (0xD4 + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_RJBR (0xD8 + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_RDRP (0xDC + ATH_GE0_BASE)
|
|
#define GE0_PEMSTAT_TPKT (0xE0 + ATH_GE0_BASE)
|
|
|
|
#define NUM_DESCS 10
|
|
|
|
void init_s17_lpbk(void);
|
|
uint32_t athrs17_reg_read(uint32_t reg_addr);
|
|
void athrs17_reg_write(uint32_t reg_addr, uint32_t reg_val);
|
|
|
|
int results[5] = { 0, 1, 1, 1, 0 };
|
|
|
|
int find;
|
|
|
|
void big_del(void)
|
|
{
|
|
int i;
|
|
for (i = 0; i < 10000; i++) ;
|
|
}
|
|
|
|
// This should tell us what the best of the 4 values is. It should also tell us what the longest sequence is.
|
|
// Since only four bits are used the best of 4 values can be easily arrived at by a truth table.
|
|
// Presently we have an algorithm though.
|
|
int find_value(void)
|
|
{
|
|
int i;
|
|
int start_ok = 9;
|
|
int end_ok = 9;
|
|
int longest_start_ok = 0;
|
|
int longest_end_ok = 0;
|
|
int longest_ok_cnt = -1;
|
|
int first = 0;
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
#if DEBUG
|
|
printf("results [%d]: %d\n", i, results[i]);
|
|
#endif
|
|
if (results[i] == 1) {
|
|
if (start_ok == 9) {
|
|
start_ok = i;
|
|
if (first == 0) {
|
|
longest_start_ok = i;
|
|
longest_end_ok = i;
|
|
first = 1;
|
|
}
|
|
}
|
|
}
|
|
if (results[i] == 0) {
|
|
if (end_ok == 9) {
|
|
end_ok = i - 1;
|
|
}
|
|
if ((end_ok - start_ok) > longest_ok_cnt) {
|
|
longest_start_ok = start_ok;
|
|
longest_end_ok = end_ok;
|
|
longest_ok_cnt = (end_ok - start_ok);
|
|
}
|
|
start_ok = 9;
|
|
end_ok = 9;
|
|
}
|
|
}
|
|
|
|
#if DEBUG
|
|
printf("FINAL VALUE - ");
|
|
#endif
|
|
find = (longest_end_ok + longest_start_ok) / 2;
|
|
#if DEBUG
|
|
printf("find - %d\n", find);
|
|
printf("FINAL OK COUNT - %d\n", longest_ok_cnt + 1);
|
|
#endif
|
|
return (longest_ok_cnt + 1);
|
|
}
|
|
|
|
int pkt_compare_data(void)
|
|
{
|
|
unsigned int i, j;
|
|
//unsigned int k,rddata;
|
|
unsigned int node_rx_buf_len;
|
|
//unsigned int * node_tx_desc_ptr = (unsigned int *) 0xa0280000;
|
|
unsigned int *node_rx_desc_ptr = (unsigned int *)0xa0380000;
|
|
unsigned int *node_tx_buf_addr = (unsigned int *)0xa0680000;
|
|
unsigned int *node_rx_buf_addr = (unsigned int *)0xa0580000;
|
|
unsigned int error = 0;
|
|
unsigned pkt_err[NUM_DESCS];
|
|
|
|
node_rx_buf_len = (*(node_rx_desc_ptr + 0x1) & 0xfff) - 0x4;
|
|
// node_tx_buf_len = *(node_tx_desc_ptr + (NUM_DESCS-1)*0x3+0x1) & 0xfff;
|
|
|
|
for (j = 0; j < NUM_DESCS; j++) {
|
|
node_rx_buf_len = (*(node_rx_desc_ptr + (NUM_DESCS - 1) * 0x3 + 0x1) & 0xfff) - 0x4;
|
|
pkt_err[j] = 0;
|
|
for (i = 0; i < (node_rx_buf_len / 4); i++) {
|
|
if (((*(node_rx_buf_addr + i + (j * 0x100))) != *(node_tx_buf_addr + i))) {
|
|
error = error + 0x1;
|
|
pkt_err[j] = 1;
|
|
}
|
|
}
|
|
//node_rx_buf_addr = node_rx_buf_addr + 0x100;
|
|
}
|
|
if (error == 0) {
|
|
return 0;
|
|
} else {
|
|
for (j = 0; j < NUM_DESCS; j++) {
|
|
node_rx_buf_len = (*(node_rx_desc_ptr + (NUM_DESCS - 1) * 0x3 + 0x1) & 0xfff) - 0x4;
|
|
if (pkt_err[j] == 1) {
|
|
#if DEBUG
|
|
printf("PKT %d\n", j);
|
|
printf("---------------------------------\n");
|
|
|
|
for (i = 0; i < (node_rx_buf_len / 4); i++) {
|
|
//if(((*(node_rx_buf_addr + i )) != *(node_tx_buf_addr + i)))
|
|
if (((*(node_rx_buf_addr + i + (j * 0x100))) != *(node_tx_buf_addr + i))) {
|
|
printf("->");
|
|
} else {
|
|
printf(" ");
|
|
}
|
|
printf("%x", (*(node_rx_buf_addr + i + (j * 0x100))));
|
|
printf(" ");
|
|
printf("%x\n", (*(node_tx_buf_addr + i)));
|
|
}
|
|
printf("---------------------------------\n");
|
|
#endif
|
|
}
|
|
//node_rx_buf_addr = node_rx_buf_addr + 0x100;
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
void rgmii_calib(ath_gmac_mac_t * mac)
|
|
{
|
|
|
|
unsigned int i;
|
|
unsigned int j;
|
|
unsigned int k, l, m;
|
|
unsigned int rddata, error = 0;
|
|
volatile unsigned int * rd_register;
|
|
unsigned int node_rx_buf_len = 1600;
|
|
unsigned int node_rx_buf_len1;
|
|
unsigned int *node_tx_desc_ptr = (unsigned int *)0xa0280000;
|
|
unsigned int *node_rx_desc_ptr = (unsigned int *)0xa0380000;
|
|
unsigned int *node_rx_buf_addr = (unsigned int *)0xa0580000;
|
|
unsigned int *node_tx_buf_addr = (unsigned int *)0xa0680000;
|
|
unsigned int *node_comp_result = (unsigned int *)0xa0200000;
|
|
unsigned int s17_tx_pkt = 0;
|
|
unsigned int s17_rx_pkt = 0;
|
|
unsigned int to;
|
|
unsigned int pass = 1;
|
|
unsigned int fail = 0;
|
|
int lgst = 0;
|
|
int old_lgst = 0;
|
|
unsigned int xmii[16];
|
|
unsigned int eth_cfg[16];
|
|
unsigned int xmii_val = 0;
|
|
unsigned int eth_cfg_val = 1;
|
|
unsigned int tx_fix = 0;
|
|
|
|
|
|
// GIGE Enable
|
|
ath_reg_wr(ETH_XMII_ADDRESS, ETH_XMII_TX_INVERT_SET(0x1) |
|
|
ETH_XMII_RX_DELAY_SET(0x2) |
|
|
ETH_XMII_TX_DELAY_SET(0x1) |
|
|
ETH_XMII_GIGE_SET(0x1));
|
|
|
|
while ((ath_reg_rd(SGMII_SERDES_ADDRESS) & SGMII_SERDES_LOCK_DETECT_STATUS_SET(1)) == 0) {
|
|
printf("TEST: WAIT FOR LOCK\n");
|
|
}
|
|
|
|
big_del();
|
|
|
|
// MAC INITS
|
|
// RGMII Enable on GE0
|
|
//eth_init();
|
|
init_s17_lpbk();
|
|
athrs17_reg_write(0x30, 1);
|
|
|
|
ath_reg_wr(ETH_CFG_ADDRESS, ETH_CFG_ETH_RXDV_DELAY_SET(0x3) |
|
|
ETH_CFG_ETH_RXD_DELAY_SET(0x3) |
|
|
ETH_CFG_RGMII_GE0_SET(0x1));
|
|
|
|
ath_reg_rmw_clear(RST_RESET_ADDRESS, RST_RESET_GE0_MAC_RESET_MASK); // Bringing GE0 out of RESET
|
|
ath_gmac_reg_wr(mac, ATH_MAC_CFG2, 0x7235); //for 1000mbps
|
|
//ath_reg_wr(GE0_MAC_CONFIG_2,0x7135); //for 100mbps
|
|
ath_gmac_reg_wr(mac, ATH_MAC_IFCTL, 0x00000);
|
|
ath_gmac_reg_wr(mac, ATH_MAC_CFG1, 0x005);
|
|
//ath_reg_wr(GE0_MAC_CONFIG_1,0x105); // For MAC Loopback
|
|
ath_gmac_reg_wr(mac, ATH_DMA_INTR_MASK, 0); // Disable interrupt mask
|
|
ath_gmac_reg_wr(mac, ATH_GE_MAC_ADDR1, 0x003fffff); //ethernet mac address
|
|
ath_gmac_reg_wr(mac, ATH_GE_MAC_ADDR2, 0xfffe0000); //ethernet mac address
|
|
ath_gmac_reg_wr(mac, ATH_MAC_MII_MGMT_CFG, 0x6); //clock/20= 2MHz
|
|
ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_0, 0x1f00); // Enable the FIFO modules
|
|
ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_1, 0x10ffff);
|
|
ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_3, 0x1f00140);
|
|
ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_4, 0x1000);
|
|
//ath_reg_wr(GE0_FIFO_CFG_REG_5, 0xbefff); //enable drop
|
|
ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_5, 0xfffff); //for 1000Mbps
|
|
//ath_reg_wr(GE0_FIFO_CFG_REG_5, 0x7ffff);//for 100Mbps
|
|
|
|
//************
|
|
// PACKETS
|
|
//***********
|
|
|
|
// Initialise Data in Memory for TX and RX
|
|
for (i = 0; i < node_tx_buf_len; i++)
|
|
*(node_tx_buf_addr + i) = i | (i + 1) << 8 | (i + 2) << 16 | (i + 3) << 24;
|
|
|
|
#if DEBUG
|
|
printf("TEST: Inits Done\n");
|
|
#endif
|
|
// Set Up Transmit Descriptor Table
|
|
|
|
for (i = 0; i < NUM_DESCRIPTORS; i++) {
|
|
*(node_tx_desc_ptr + (i * 0x3)) = ((unsigned int)node_tx_buf_addr & 0x0fffffff);
|
|
*(node_tx_desc_ptr + (i * 0x3) + 0x1) = (node_tx_buf_len & 0x7fffffff);
|
|
|
|
if (i == (NUM_DESCRIPTORS - 1))
|
|
*(node_tx_desc_ptr + (i * 0x3) + 0x2) = ((unsigned int)node_tx_desc_ptr & 0x0fffffff);
|
|
else
|
|
*(node_tx_desc_ptr + (i * 0x3) + 0x2) = ((unsigned int)node_tx_desc_ptr & 0x0fffffff) + (i * 0xc) + 0xc;
|
|
}
|
|
|
|
ath_gmac_reg_wr(mac, ATH_DMA_TX_DESC, ((unsigned int)node_tx_desc_ptr & 0x0fffffff));
|
|
ath_gmac_reg_wr(mac, ATH_DMA_TX_STATUS, 0xfffffff); // clear dma status
|
|
|
|
for (i = 0; i < NUM_DESCRIPTORS; i++) {
|
|
*(node_rx_desc_ptr + (i * 0x3)) = ((unsigned int)node_rx_buf_addr & 0x0fffffff);
|
|
*(node_rx_desc_ptr + (i * 0x3) + 0x1) = (node_rx_buf_len & 0xfff) | (1 << 31);
|
|
if (i == (NUM_DESCRIPTORS - 1))
|
|
*(node_rx_desc_ptr + (i * 0x3) + 0x2) = ((unsigned int)node_rx_desc_ptr & 0x0fffffff);
|
|
else
|
|
*(node_rx_desc_ptr + (i * 0x3) + 0x2) = ((unsigned int)node_rx_desc_ptr & 0x0fffffff) + (i * 0xc) + 0xc;
|
|
node_rx_buf_addr = node_rx_buf_addr + 0x100;
|
|
|
|
}
|
|
|
|
ath_gmac_reg_wr(mac, ATH_DMA_RX_DESC, ((unsigned int)node_rx_desc_ptr & 0x0fffffff));
|
|
ath_gmac_reg_wr(mac, ATH_DMA_RX_STATUS, 0xfffffff); // clear dma status
|
|
|
|
k = 0;
|
|
|
|
// Enable TX and RX MAC
|
|
ath_gmac_reg_wr(mac, ATH_MAC_CFG1, 0x005);
|
|
|
|
// This routine will go through 16 combinations to find the best value for TX_DELAY, GIGE_QUAD, TX_INVERT
|
|
for (l = 0; l < 16; l++) {
|
|
// initialize pass. this will be made zero if there is a failure in packet reception compare
|
|
pass = 1;
|
|
// fail due to checks in rx etc. this is not the same as !pass
|
|
fail = 0;
|
|
|
|
// GIGE_QUAD - 0
|
|
// TX_INVERT - 0
|
|
// TX_DELAY - 0,1,2,3
|
|
if (l < 4) {
|
|
// GIGE Enable and TX_DELAY
|
|
rddata = ETH_XMII_GIGE_SET(0x1) |
|
|
ETH_XMII_TX_DELAY_SET(l);
|
|
ath_reg_wr(ETH_XMII_ADDRESS, rddata);
|
|
rddata = ath_reg_rd(ETH_XMII_ADDRESS);
|
|
#if DEBUG
|
|
printf("TEST: ETH_XMII - 0x%08x\n", rddata);
|
|
#endif
|
|
}
|
|
// GIGE_QUAD - 1
|
|
// TX_INVERT - 0
|
|
// TX_DELAY - 0,1,2,3
|
|
if ((l < 8) && (l > 3)) {
|
|
// GIGE Enable and TX_DELAY & GIGE_QUAD
|
|
rddata = ETH_XMII_GIGE_QUAD_SET(0x1) |
|
|
ETH_XMII_GIGE_SET(0x1) |
|
|
ETH_XMII_TX_DELAY_SET(l);
|
|
ath_reg_wr(ETH_XMII_ADDRESS, rddata);
|
|
rddata = ath_reg_rd(ETH_XMII_ADDRESS);
|
|
#if DEBUG
|
|
printf("TEST: ETH_XMII - 0x%08x\n", rddata);
|
|
#endif
|
|
}
|
|
// GIGE_QUAD - 0
|
|
// TX_INVERT - 1
|
|
// TX_DELAY - 0,1,2,3
|
|
if ((l < 12) && (l > 7)) {
|
|
// GIGE Enable and TX_DELAY and TX_INVERT
|
|
rddata = ETH_XMII_TX_INVERT_SET(0x1) |
|
|
ETH_XMII_GIGE_SET(0x1) |
|
|
ETH_XMII_TX_DELAY_SET(l);
|
|
ath_reg_wr(ETH_XMII_ADDRESS, rddata);
|
|
rddata = ath_reg_rd(ETH_XMII_ADDRESS);
|
|
#if DEBUG
|
|
printf("TEST: ETH_XMII - 0x%08x\n", rddata);
|
|
#endif
|
|
}
|
|
// GIGE_QUAD - 0
|
|
// TX_INVERT - 1
|
|
// TX_DELAY - 0,1,2,3
|
|
if ((l < 16) && (l > 11)) {
|
|
// GIGE Enable and TX_DELAY and TX_INVERT and GIGE_QUAD
|
|
rddata = ETH_XMII_TX_INVERT_SET(0x1) |
|
|
ETH_XMII_GIGE_QUAD_SET(0x1) |
|
|
ETH_XMII_GIGE_SET(0x1) |
|
|
ETH_XMII_TX_DELAY_SET(l);
|
|
ath_reg_wr(ETH_XMII_ADDRESS, rddata);
|
|
rddata = ath_reg_rd(ETH_XMII_ADDRESS);
|
|
#if DEBUG
|
|
printf("TEST: ETH_XMII - 0x%08x\n", rddata);
|
|
#endif
|
|
}
|
|
xmii[l] = rddata;
|
|
|
|
// counts when to print out counter stats
|
|
k++;
|
|
// Set Up Receive Descriptor Table
|
|
node_rx_buf_len = 0x0;
|
|
ath_gmac_reg_wr(mac, ATH_DMA_RX_CTRL, 0x1); // enable dma rx
|
|
ath_gmac_reg_wr(mac, ATH_DMA_TX_CTRL, 0x1); // enable dma tx
|
|
|
|
rd_register = node_tx_desc_ptr + (NUM_DESCRIPTORS - 1) * 0x3 + 0x1;
|
|
rddata = (*(rd_register) & (1 << 31));
|
|
while (rddata != (1 << 31))
|
|
rddata = (*(rd_register) & (1 << 31));
|
|
#if DEBUG
|
|
printf("TEST: Tx Done \n");
|
|
#endif
|
|
|
|
to = 0;
|
|
rd_register = node_rx_desc_ptr + (NUM_DESCS - 1) * 0x3 + 0x1;
|
|
rddata = (*(rd_register) & (1 << 31));
|
|
while (rddata != 0x0) {
|
|
rddata = (*(rd_register) & (1 << 31));
|
|
to++;
|
|
if (to > 100000) {
|
|
#if DEBUG
|
|
printf("TEST: ERROR!! Atleast 1 packet in GE0 not seen.\n");
|
|
#endif
|
|
fail = 1;
|
|
break;
|
|
}
|
|
}
|
|
#if DEBUG
|
|
printf("TEST: Rx Done \n");
|
|
#endif
|
|
|
|
if (k % 1 == 0) {
|
|
for (j = GE0_PEMSTAT_RBYT; j <= GE0_PEMSTAT_RDRP; j = j + 4) {
|
|
rddata = ath_reg_rd(j);
|
|
switch (j) {
|
|
#if DEBUG
|
|
case GE0_PEMSTAT_RPKT:
|
|
printf("TEST: RPKT - 0x%08x\n", rddata);
|
|
break;
|
|
case GE0_PEMSTAT_TPKT:
|
|
printf("TEST: TPKT - 0x%08x\n", rddata);
|
|
break;
|
|
#endif
|
|
}
|
|
}
|
|
#ifdef ATH_S17_MAC0_SGMII
|
|
s17_rx_pkt = athrs17_reg_read(0x163c) + (athrs17_reg_read(0x1640) << 16);
|
|
#else
|
|
s17_rx_pkt = athrs17_reg_read(0x103c) + (athrs17_reg_read(0x1040) << 16);
|
|
#endif
|
|
#if DEBUG
|
|
printf("TEST: RPKT in S17 0x%08x\n", s17_rx_pkt);
|
|
#endif
|
|
#ifdef ATH_S17_MAC0_SGMII
|
|
s17_tx_pkt = athrs17_reg_read(0x1684) + (athrs17_reg_read(0x1688) << 16);
|
|
#else
|
|
s17_tx_pkt = athrs17_reg_read(0x1084) + (athrs17_reg_read(0x1088) << 16);
|
|
#endif
|
|
#if DEBUG
|
|
printf("TEST: TPKT in S17 0x%08x\n", s17_tx_pkt);
|
|
#endif
|
|
// Compare BYTES in TX
|
|
if (s17_tx_pkt != 0x410) {
|
|
#if DEBUG
|
|
printf("TEST: PKTS @ S17 - 0x%08x\n", rddata);
|
|
#endif
|
|
pass = 0;
|
|
fail = 1;
|
|
}
|
|
|
|
}
|
|
if (fail == 0) {
|
|
error = pkt_compare_data();
|
|
}
|
|
if (error == 0) {
|
|
#if DEBUG
|
|
printf("TEST: PACKET COMPARISON PASS\n");
|
|
#endif
|
|
} else {
|
|
#if DEBUG
|
|
printf("TEST: ERROR!! PACKET COMPARISON FAIL\n");
|
|
#endif
|
|
fail = 1;
|
|
}
|
|
|
|
for (i = 0; i < NUM_DESCRIPTORS; i++) {
|
|
*(node_tx_desc_ptr + (i * 0x3) + 0x1) = (node_tx_buf_len & 0x7fffffff);
|
|
*(node_rx_desc_ptr + (i * 0x3) + 0x1) = (node_rx_buf_len & 0xfff) | (1 << 31);
|
|
}
|
|
|
|
// populate results and find the optimum value of programming
|
|
results[(l % 4)] = pass;
|
|
if (((l % 4) == 3)) {
|
|
lgst = find_value();
|
|
if (lgst > old_lgst) {
|
|
old_lgst = lgst;
|
|
xmii_val = xmii[(l - 3) + find];
|
|
}
|
|
}
|
|
}
|
|
#if DEBUG_1
|
|
printf("TEST: FINAL REG VAL after TX Calibration - 0x%08x\n", xmii_val);
|
|
#endif
|
|
tx_fix = xmii_val;
|
|
|
|
old_lgst = 0;
|
|
|
|
// Using the previously arrived at value of TX Calib we calibrate RX DELAYS. For this we use RX DAT and EN Delays
|
|
for (l = 0; l < 16; l++) {
|
|
// initialize pass. this will be made zero if there is a failure in packet reception compare
|
|
pass = 1;
|
|
// fail due to checks in rx etc. this is not the same as !pass
|
|
fail = 0;
|
|
rddata = ath_reg_rd(ETH_CFG_ADDRESS);
|
|
#if DEBUG
|
|
printf("TEST: Initial ETH_CFG - 0x%08x\n", rddata);
|
|
#endif
|
|
|
|
// RXD_DELAY - l / 4 -> 0, 1, 2, 3
|
|
// RXEN_DELAY - l / 4 -> 0, 1, 2, 3
|
|
// RX_DELAY - l & 3 -> 0, 1, 2, 3
|
|
ath_reg_rmw_clear(ETH_CFG_ADDRESS,
|
|
ETH_CFG_ETH_RXDV_DELAY_MASK |
|
|
ETH_CFG_ETH_RXD_DELAY_MASK);
|
|
ath_reg_rmw_set(ETH_CFG_ADDRESS,
|
|
ETH_CFG_ETH_RXDV_DELAY_SET(l / 4) |
|
|
ETH_CFG_ETH_RXD_DELAY_SET(l / 4));
|
|
rddata = ath_reg_rd(ETH_CFG_ADDRESS);
|
|
#if DEBUG
|
|
printf("TEST: ETH_CFG - 0x%08x\n", rddata);
|
|
#endif
|
|
eth_cfg[l] = rddata;
|
|
rddata = tx_fix | ETH_XMII_RX_DELAY_SET(l);
|
|
ath_reg_wr(ETH_XMII_ADDRESS, rddata);
|
|
|
|
xmii[l] = rddata;
|
|
|
|
// counts when to print out counter stats
|
|
k++;
|
|
// Set Up Receive Descriptor Table
|
|
node_rx_buf_len = 0x0;
|
|
ath_gmac_reg_wr(mac, ATH_DMA_RX_CTRL, 0x1); // enable dma rx
|
|
ath_gmac_reg_wr(mac, ATH_DMA_TX_CTRL, 0x1); // enable dma tx
|
|
rd_register = node_tx_desc_ptr + (NUM_DESCRIPTORS - 1) * 0x3 + 0x1;
|
|
rddata = (*(rd_register) & (1 << 31));
|
|
while (rddata != (1 << 31))
|
|
rddata = (*(rd_register) & (1 << 31));
|
|
#if DEBUG
|
|
printf("TEST: Tx Done \n");
|
|
#endif
|
|
|
|
to = 0;
|
|
rd_register = node_rx_desc_ptr + (NUM_DESCS - 1) * 0x3 + 0x1;
|
|
rddata = (*(rd_register) & (1 << 31));
|
|
while (rddata != 0x0) {
|
|
rddata = (*(rd_register) & (1 << 31));
|
|
to++;
|
|
if (to > 100000) {
|
|
#if DEBUG
|
|
printf("TEST: ERROR!! Atleast 1 packet in GE0 not seen.\n");
|
|
#endif
|
|
// This check for RX.
|
|
pass = 0;
|
|
fail = 1;
|
|
break;
|
|
}
|
|
}
|
|
#if DEBUG
|
|
printf("TEST: Rx Done \n");
|
|
#endif
|
|
|
|
if (k % 1 == 0) {
|
|
for (j = GE0_PEMSTAT_RBYT; j <= GE0_PEMSTAT_RDRP; j = j + 4) {
|
|
rddata = ath_reg_rd(j);
|
|
switch (j) {
|
|
#if DEBUG
|
|
case GE0_PEMSTAT_RPKT:
|
|
printf("TEST: RPKT 0x%08x\n", rddata);
|
|
break;
|
|
case GE0_PEMSTAT_TPKT:
|
|
printf("TEST: TPKT 0x%08x\n", rddata);
|
|
break;
|
|
#endif
|
|
}
|
|
}
|
|
#ifdef ATH_S17_MAC0_SGMII
|
|
s17_rx_pkt = athrs17_reg_read(0x163c) + (athrs17_reg_read(0x1640) << 16);
|
|
#else
|
|
s17_rx_pkt = athrs17_reg_read(0x103c) + (athrs17_reg_read(0x1040) << 16);
|
|
#endif
|
|
#if DEBUG
|
|
printf("TEST: RPKT in S17 0x%08x\n", s17_rx_pkt);
|
|
#endif
|
|
#ifdef ATH_S17_MAC0_SGMII
|
|
s17_tx_pkt = athrs17_reg_read(0x1684) + (athrs17_reg_read(0x1688) << 16);
|
|
#else
|
|
s17_tx_pkt = athrs17_reg_read(0x1084) + (athrs17_reg_read(0x1088) << 16);
|
|
#endif
|
|
#if DEBUG
|
|
printf("TEST: TPKT in S17 0x%08x\n", s17_tx_pkt);
|
|
#endif
|
|
// Compare BYTES in TX
|
|
if (s17_tx_pkt != 0x410) {
|
|
#if DEBUG
|
|
printf("TEST: PKTS @ S17 - 0x%08x\n", rddata);
|
|
#endif
|
|
pass = 0;
|
|
fail = 1;
|
|
}
|
|
|
|
}
|
|
if (fail == 0) {
|
|
error = pkt_compare_data();
|
|
}
|
|
if (error == 0) {
|
|
//printf("TEST: PACKET COMPARISON PASS\n");
|
|
} else {
|
|
#if DEBUG
|
|
printf("TEST: ERROR!! PACKET COMPARISON FAIL\n");
|
|
#endif
|
|
fail = 1;
|
|
// Different from TX. This ensures packets are received back properly for a valid config.
|
|
pass = 0;
|
|
}
|
|
|
|
for (i = 0; i < NUM_DESCRIPTORS; i++) {
|
|
*(node_tx_desc_ptr + (i * 0x3) + 0x1) = (node_tx_buf_len & 0x7fffffff);
|
|
*(node_rx_desc_ptr + (i * 0x3) + 0x1) = (node_rx_buf_len & 0xfff) | (1 << 31);
|
|
}
|
|
|
|
// populate results and find the optimum value of programming
|
|
// For every set of 4 configurations find longest valid configs and number.
|
|
results[(l % 4)] = pass;
|
|
if (((l % 4) == 3)) {
|
|
lgst = find_value();
|
|
if (lgst > old_lgst) {
|
|
old_lgst = lgst;
|
|
xmii_val = xmii[(l - 3) + find];
|
|
eth_cfg_val = eth_cfg[(l - 3) + find];
|
|
}
|
|
}
|
|
}
|
|
// And write to these registers.
|
|
#if DEBUG_1
|
|
printf("TEST: FINAL XMII VAL after RX Calibration - 0x%08x\n", xmii_val);
|
|
#endif
|
|
ath_reg_wr(ETH_XMII_ADDRESS, xmii_val);
|
|
#if DEBUG_1
|
|
printf("TEST: FINAL ETH_CFG VAL after RX Calibration - 0x%08x\n", eth_cfg_val);
|
|
#endif
|
|
ath_reg_wr(ETH_CFG_ADDRESS, eth_cfg_val);
|
|
ath_gmac_reg_wr(mac,ATH_MAC_CFG1,1<<31);
|
|
|
|
}
|
|
|
|
#endif /* #ifdef RGMII_CAL */
|