aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/x300/lib/ethernet.c
diff options
context:
space:
mode:
authormichael-west <michael.west@ettus.com>2014-03-03 12:23:23 -0800
committermichael-west <michael.west@ettus.com>2014-03-03 12:23:23 -0800
commitd2baf9d612e1a35645079eb582ad5a6c5881377e (patch)
tree376ea596566a4dfc66e4a18b8bc504e15dce0725 /firmware/x300/lib/ethernet.c
parent573d39c8b33b2f16ba6bd8d007423e5df315ad02 (diff)
downloaduhd-d2baf9d612e1a35645079eb582ad5a6c5881377e.tar.gz
uhd-d2baf9d612e1a35645079eb582ad5a6c5881377e.tar.bz2
uhd-d2baf9d612e1a35645079eb582ad5a6c5881377e.zip
BUG #371: X300: Dies and left in bad state
- Disabled packet forwarding and link state cycle detection in firmware. - Fixed the link state algorithm so the updating runs the first time and the forwading update only happens when necessary. - Added check for 10GbE before calling MDIO functions.
Diffstat (limited to 'firmware/x300/lib/ethernet.c')
-rw-r--r--firmware/x300/lib/ethernet.c90
1 files changed, 48 insertions, 42 deletions
diff --git a/firmware/x300/lib/ethernet.c b/firmware/x300/lib/ethernet.c
index fdde9e41b..7a86980c7 100644
--- a/firmware/x300/lib/ethernet.c
+++ b/firmware/x300/lib/ethernet.c
@@ -82,7 +82,7 @@ ethernet_ninterfaces(void)
// Clause 45 MDIO used for 10Gig Ethernet has two bus transactions to complete a transfer.
// An initial transaction sets up the address, and a subsequent one transfers the read or write data.
//
-static uint32_t
+static uint32_t
xge_read_mdio(const uint32_t base, const uint32_t address, const uint32_t device, const uint32_t port)
{
// Set register address each iteration
@@ -103,9 +103,9 @@ xge_read_mdio(const uint32_t base, const uint32_t address, const uint32_t device
return(xge_regs->mdio_data);
}
-static void
+static void
xge_write_mdio(const uint32_t base, const uint32_t address, const uint32_t device, const uint32_t port, const uint32_t data)
-{
+{
// Set register address each iteration
xge_regs->mdio_addr = address;
// Its a clause 45 device. We want to ADDRESS
@@ -114,13 +114,13 @@ xge_write_mdio(const uint32_t base, const uint32_t address, const uint32_t devic
xge_regs->mdio_control = 1;
// Wait until bus transaction complete
while (xge_regs->mdio_control == 1);
- // Write new value to mdio_write_data reg.
- xge_regs->mdio_data = data;
- // Its a clause 45 device. We want to WRITE
+ // Write new value to mdio_write_data reg.
+ xge_regs->mdio_data = data;
+ // Its a clause 45 device. We want to WRITE
xge_regs->mdio_op = XGE_MDIO_CLAUSE(CLAUSE45) | XGE_MDIO_OP(MDIO_WRITE) | XGE_MDIO_ADDR(port) | XGE_MDIO_MMD(device);
- // Start MDIO bus transaction
- xge_regs->mdio_control = 1;
- // Wait until bus transaction complete
+ // Start MDIO bus transaction
+ xge_regs->mdio_control = 1;
+ // Wait until bus transaction complete
while (xge_regs->mdio_control == 1);
}
@@ -128,7 +128,7 @@ xge_write_mdio(const uint32_t base, const uint32_t address, const uint32_t devic
//
// Clause 22 MDIO used for 1Gig Ethernet has one bus transaction to complete a transfer.
//
-static uint32_t
+static uint32_t
ge_read_mdio(const uint32_t base, const uint32_t address, const uint32_t port)
{
// Its a clause 22 device. We want to READ
@@ -141,16 +141,16 @@ ge_read_mdio(const uint32_t base, const uint32_t address, const uint32_t port)
return(xge_regs->mdio_data);
}
-static void
+static void
ge_write_mdio(const uint32_t base, const uint32_t address, const uint32_t port, const uint32_t data)
{
- // Write new value to mdio_write_data reg.
- xge_regs->mdio_data = data;
- // Its a clause 22 device. We want to WRITE
+ // Write new value to mdio_write_data reg.
+ xge_regs->mdio_data = data;
+ // Its a clause 22 device. We want to WRITE
xge_regs->mdio_op = XGE_MDIO_CLAUSE(CLAUSE22) | XGE_MDIO_OP(MDIO_C22_WRITE) | XGE_MDIO_ADDR(port) | address;
- // Start MDIO bus transaction
- xge_regs->mdio_control = 1;
- // Wait until bus transaction complete
+ // Start MDIO bus transaction
+ xge_regs->mdio_control = 1;
+ // Wait until bus transaction complete
while (xge_regs->mdio_control == 1);
}
@@ -205,7 +205,7 @@ xge_i2c_rd(const uint32_t base, const uint8_t i2c_dev_addr, const uint8_t i2c_wo
// Now read back a byte of data
if (wb_i2c_read(base, i2c_dev_addr, &buf, 1) == false)
return(-1);
-
+
return((int) buf);
}
@@ -334,15 +334,15 @@ xge_phy_init(const uint8_t eth, const uint32_t mdio_port)
printf("INFO: Begining XGE PHY init sequence.\n");
// Software reset
x = read_mdio(eth, 0x0, XGE_MDIO_DEVICE_PMA,mdio_port);
- x = x | (1 << 15);
- write_mdio(eth, 0x0,XGE_MDIO_DEVICE_PMA,mdio_port,x);
+ x = x | (1 << 15);
+ write_mdio(eth, 0x0,XGE_MDIO_DEVICE_PMA,mdio_port,x);
while(x&(1<<15))
x = read_mdio(eth, 0x0,XGE_MDIO_DEVICE_PMA,mdio_port);
}
void
xge_poll_sfpp_status(const uint32_t eth)
-{
+{
uint32_t x;
// Has MODDET/MODAbS changed since we last looked?
x = wb_peek32(SR_ADDR(RB0_BASE, (eth==0) ? RB_SFPP_STATUS0 : RB_SFPP_STATUS1 ));
@@ -355,14 +355,20 @@ xge_poll_sfpp_status(const uint32_t eth)
printf("DEBUG: eth%1d MODABS changed state: %d\n", eth, (x & SFPP_STATUS_MODABS) >> 2);
if (x & (SFPP_STATUS_RXLOS_CHG|SFPP_STATUS_TXFAULT_CHG|SFPP_STATUS_MODABS_CHG))
- if (( x & (SFPP_STATUS_RXLOS|SFPP_STATUS_TXFAULT|SFPP_STATUS_MODABS)) == 0) {
- xge_ethernet_init(eth);
- dump_mdio_regs((eth==0) ? XGE0_BASE : XGE1_BASE,MDIO_PORT);
- mdelay(100);
- dump_mdio_regs((eth==0) ? XGE0_BASE : XGE1_BASE,MDIO_PORT);
- mdelay(100);
- dump_mdio_regs((eth==0) ? XGE0_BASE : XGE1_BASE,MDIO_PORT);
+ {
+ if (( x & (SFPP_STATUS_RXLOS|SFPP_STATUS_TXFAULT|SFPP_STATUS_MODABS)) == 0)
+ {
+ if (wb_peek32(SR_ADDR(RB0_BASE, eth == 0 ? RB_ETH_TYPE0 : RB_ETH_TYPE1)) == 1)
+ {
+ xge_ethernet_init(eth);
+ dump_mdio_regs((eth==0) ? XGE0_BASE : XGE1_BASE,MDIO_PORT);
+ mdelay(100);
+ dump_mdio_regs((eth==0) ? XGE0_BASE : XGE1_BASE,MDIO_PORT);
+ mdelay(100);
+ dump_mdio_regs((eth==0) ? XGE0_BASE : XGE1_BASE,MDIO_PORT);
}
+ }
+ }
if (x & SFPP_STATUS_MODABS_CHG) {
// MODDET has changed state since last checked
@@ -383,14 +389,14 @@ xge_poll_sfpp_status(const uint32_t eth)
//The link became up, send a GARP so everyone knows our mac/ip association
if (!old_link_up && links_up[eth]) u3_net_stack_send_arp_request(eth, u3_net_stack_get_ip_addr(eth));
}
-
+
void
xge_ethernet_init(const uint32_t eth)
-{
- xge_mac_init((eth==0) ? XGE0_BASE : XGE1_BASE);
- //xge_hard_phy_reset();
- xge_phy_init(eth ,MDIO_PORT);
+{
+ xge_mac_init((eth==0) ? XGE0_BASE : XGE1_BASE);
+ //xge_hard_phy_reset();
+ xge_phy_init(eth ,MDIO_PORT);
uint32_t x = wb_peek32(SR_ADDR(RB0_BASE, (eth==0) ? RB_SFPP_STATUS0 : RB_SFPP_STATUS1 ));
printf(" eth%1d SFP initial state: RXLOS: %d TXFAULT: %d MODABS: %d\n",
eth,
@@ -411,7 +417,7 @@ void decode_reg(uint32_t address, uint32_t device, uint32_t data)
printf("%x",device);
printf(" ");
switch(address) {
- case XGE_MDIO_CONTROL1:
+ case XGE_MDIO_CONTROL1:
printf("CONTROL1: ");
printf("%x",data); printf(" ");
for (x=15; x >= 0 ; x--)
@@ -423,7 +429,7 @@ void decode_reg(uint32_t address, uint32_t device, uint32_t data)
case 11: printf("Low Power Mode,"); break;
case 5:case 4:case 3:case 2: printf("RESERVED speed value,"); break;
case 0: printf("PMA loopback,"); break;
- } //else
+ } //else
// Bits clear.
//switch (x) {
//case 13: case 6: printf(" None 10Gb/s speed set!"); break;
@@ -440,7 +446,7 @@ void decode_reg(uint32_t address, uint32_t device, uint32_t data)
case 7: printf("Fault Detected,"); break;
case 2: printf("Link is Up,"); break;
case 1: printf("Supports Low Power,"); break;
- } else
+ } else
// Bits Clear
switch(x) {
case 2: printf("Link is Down,"); break;
@@ -457,7 +463,7 @@ void decode_reg(uint32_t address, uint32_t device, uint32_t data)
case 15:case 14:case 13:case 12:case 11:case 10:case 9:
case 8:case 7:case 6:case 5:case 4:case 3:case 2:case 1: printf("RESERVED bits set!,"); break;
case 0: printf("Capable of 10Gb/s,");
- } else
+ } else
// Bits clear.
switch(x) {
case 0: printf("Incapable of 10Gb/s,"); break;
@@ -572,7 +578,7 @@ void decode_reg(uint32_t address, uint32_t device, uint32_t data)
case 2: printf("Lane 2 not synced,"); break;
case 1: printf("Lane 1 not synced,"); break;
case 0: printf("Lane 0 not synced,"); break;
- }
+ }
printf(" \n");
break;
case XILINX_CORE_VERSION:
@@ -591,23 +597,23 @@ void decode_reg(uint32_t address, uint32_t device, uint32_t data)
}
}
-void
+void
dump_mdio_regs(const uint8_t eth, uint32_t mdio_port)
{
volatile unsigned int x;
int y;
unsigned int regs_a[9] = {0,1,4,5,6,7,8,32,33};
unsigned int regs_b[10] = {0,1,4,5,6,7,8,10,11,65535};
-
+
printf("\n");
- for (y = 0; y < 10; y++)
+ for (y = 0; y < 10; y++)
{
// Read MDIO data
x = read_mdio(eth,regs_b[y],XGE_MDIO_DEVICE_PMA,mdio_port);
decode_reg(regs_b[y],XGE_MDIO_DEVICE_PMA,x);
}
-
+
for (y = 0; y < 9; y++)
{
// Read MDIO data