aboutsummaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authormichael-west <michael.west@ettus.com>2017-01-04 16:57:53 -0800
committerMartin Braun <martin.braun@ettus.com>2017-01-10 13:51:53 -0800
commit64b4c1f5d7554c272884d67d0bf3d0d3d48c77ba (patch)
treed66fa051ce101e11bf30b5fb6217d195723df1bf /firmware
parent29b0fa17382c3dd9c27c556d1c5aa88f0863cb33 (diff)
downloaduhd-64b4c1f5d7554c272884d67d0bf3d0d3d48c77ba.tar.gz
uhd-64b4c1f5d7554c272884d67d0bf3d0d3d48c77ba.tar.bz2
uhd-64b4c1f5d7554c272884d67d0bf3d0d3d48c77ba.zip
X300: Prevent MB EEPROM Corruption
- Load EEPROM data into firmware memory to access from there instead of driving the I2C bus directly - Fixed firmware performance issues by removing the popcntll() function and reducing frequency of background tasks to once every 10ms - Added x300_mb_eeprom_iface to handle cases of devices with older and newer firmware - Added checks for claim to device before driving the I2C bus
Diffstat (limited to 'firmware')
-rw-r--r--firmware/usrp3/x300/x300_defs.h2
-rw-r--r--firmware/usrp3/x300/x300_init.c44
-rw-r--r--firmware/usrp3/x300/x300_init.h5
-rw-r--r--firmware/usrp3/x300/x300_main.c47
4 files changed, 30 insertions, 68 deletions
diff --git a/firmware/usrp3/x300/x300_defs.h b/firmware/usrp3/x300/x300_defs.h
index e9e9f34fa..ed756d6fd 100644
--- a/firmware/usrp3/x300/x300_defs.h
+++ b/firmware/usrp3/x300/x300_defs.h
@@ -9,7 +9,7 @@
#define PKT_RAM0_BASE 0x8000
#define SFP0_MAC_BASE 0xC000
#define SFP1_MAC_BASE 0xD000
-#define BOOT_LDR_BASE 0xFC00
+#define BOOT_LDR_BASE 0xFA00
#define UART0_BASE 0xfd00
#define UART0_BAUD 115200
#define UART1_BASE 0xf900
diff --git a/firmware/usrp3/x300/x300_init.c b/firmware/usrp3/x300/x300_init.c
index 57c1faa2c..61d4f4190 100644
--- a/firmware/usrp3/x300/x300_init.c
+++ b/firmware/usrp3/x300/x300_init.c
@@ -1,5 +1,4 @@
#include "x300_init.h"
-#include "x300_defs.h"
#include "ethernet.h"
#include "cron.h"
#include <wb_utils.h>
@@ -17,27 +16,7 @@
static wb_pkt_iface64_config_t pkt_config;
-struct x300_eeprom_map
-{
- //indentifying numbers
- unsigned char revision[2];
- unsigned char product[2];
- uint8_t _pad0[4];
-
- //all the mac addrs
- uint8_t mac_addr0[6];
- uint8_t _pad1[2];
- uint8_t mac_addr1[6];
- uint8_t _pad2[2];
-
- //all the IP addrs
- uint32_t gateway;
- uint32_t subnet[4];
- uint32_t ip_addr[4];
- uint8_t _pad3[16];
-};
-
-static struct x300_eeprom_map default_map = {
+static x300_eeprom_map_t default_map = {
.mac_addr0 = X300_DEFAULT_MAC_ADDR_0,
.mac_addr1 = X300_DEFAULT_MAC_ADDR_1,
.gateway = X300_DEFAULT_GATEWAY,
@@ -70,7 +49,7 @@ const void *pick_inited_field(const void *eeprom, const void *def, const size_t
return eeprom;
}
-static void init_network(void)
+static void init_network(x300_eeprom_map_t *eeprom_map)
{
pkt_config = wb_pkt_iface64_init(PKT_RAM0_BASE, 0x1ffc);
u3_net_stack_init(&pkt_config);
@@ -79,21 +58,20 @@ static void init_network(void)
//read everything from eeprom
static const uint8_t eeprom_cmd[2] = {0, 0}; //the command is 16 bits of address offset
- struct x300_eeprom_map eeprom_map = default_map;
wb_i2c_write(I2C1_BASE, MBOARD_EEPROM_ADDR, eeprom_cmd, 2);
- wb_i2c_read(I2C1_BASE, MBOARD_EEPROM_ADDR, (uint8_t *)(&eeprom_map), sizeof(eeprom_map));
+ wb_i2c_read(I2C1_BASE, MBOARD_EEPROM_ADDR, (uint8_t *)(eeprom_map), sizeof(x300_eeprom_map_t));
//determine interface number
const size_t eth0no = wb_peek32(SR_ADDR(RB0_BASE, RB_SFP0_TYPE))? 2 : 0;
const size_t eth1no = wb_peek32(SR_ADDR(RB0_BASE, RB_SFP1_TYPE))? 3 : 1;
//pick the address from eeprom or default
- const eth_mac_addr_t *my_mac0 = (const eth_mac_addr_t *)pick_inited_field(&eeprom_map.mac_addr0, &default_map.mac_addr0, 6);
- const eth_mac_addr_t *my_mac1 = (const eth_mac_addr_t *)pick_inited_field(&eeprom_map.mac_addr1, &default_map.mac_addr1, 6);
- const struct ip_addr *my_ip0 = (const struct ip_addr *)pick_inited_field(&eeprom_map.ip_addr[eth0no], &default_map.ip_addr[eth0no], 4);
- const struct ip_addr *subnet0 = (const struct ip_addr *)pick_inited_field(&eeprom_map.subnet[eth0no], &default_map.subnet[eth0no], 4);
- const struct ip_addr *my_ip1 = (const struct ip_addr *)pick_inited_field(&eeprom_map.ip_addr[eth1no], &default_map.ip_addr[eth1no], 4);
- const struct ip_addr *subnet1 = (const struct ip_addr *)pick_inited_field(&eeprom_map.subnet[eth1no], &default_map.subnet[eth1no], 4);
+ const eth_mac_addr_t *my_mac0 = (const eth_mac_addr_t *)pick_inited_field(&eeprom_map->mac_addr0, &default_map.mac_addr0, 6);
+ const eth_mac_addr_t *my_mac1 = (const eth_mac_addr_t *)pick_inited_field(&eeprom_map->mac_addr1, &default_map.mac_addr1, 6);
+ const struct ip_addr *my_ip0 = (const struct ip_addr *)pick_inited_field(&eeprom_map->ip_addr[eth0no], &default_map.ip_addr[eth0no], 4);
+ const struct ip_addr *subnet0 = (const struct ip_addr *)pick_inited_field(&eeprom_map->subnet[eth0no], &default_map.subnet[eth0no], 4);
+ const struct ip_addr *my_ip1 = (const struct ip_addr *)pick_inited_field(&eeprom_map->ip_addr[eth1no], &default_map.ip_addr[eth1no], 4);
+ const struct ip_addr *subnet1 = (const struct ip_addr *)pick_inited_field(&eeprom_map->subnet[eth1no], &default_map.subnet[eth1no], 4);
//init eth0
u3_net_stack_init_eth(0, my_mac0, my_ip0, subnet0);
@@ -126,7 +104,7 @@ static uint32_t get_counter_val()
return wb_peek32(SR_ADDR(RB0_BASE, RB_COUNTER));
}
-void x300_init(void)
+void x300_init(x300_eeprom_map_t *eeprom_map)
{
//first - uart
wb_uart_init(UART0_BASE, CPU_CLOCK/UART0_BAUD);
@@ -153,7 +131,7 @@ void x300_init(void)
wb_poke32(SR_ADDR(SET0_BASE, SR_SW_RST), SW_RST_PHY);
//setup net stack and eth state machines
- init_network();
+ init_network(eeprom_map);
//phy reset release
wb_poke32(SR_ADDR(SET0_BASE, SR_SW_RST), 0);
diff --git a/firmware/usrp3/x300/x300_init.h b/firmware/usrp3/x300/x300_init.h
index 324033779..2e93340f6 100644
--- a/firmware/usrp3/x300/x300_init.h
+++ b/firmware/usrp3/x300/x300_init.h
@@ -4,7 +4,10 @@
#ifndef INCLUDED_B250_INIT_H
#define INCLUDED_B250_INIT_H
-void x300_init(void);
+#include "x300_defs.h"
+#include "x300_fw_common.h"
+
+void x300_init(x300_eeprom_map_t *eeprom_map);
void x300_serial_loader_run1(void);
diff --git a/firmware/usrp3/x300/x300_main.c b/firmware/usrp3/x300/x300_main.c
index f255fe96c..c5e4fc88a 100644
--- a/firmware/usrp3/x300/x300_main.c
+++ b/firmware/usrp3/x300/x300_main.c
@@ -240,7 +240,7 @@ static void handle_claim(void)
last_time = shmem[X300_FW_SHMEM_CLAIM_TIME];
//the claim has timed out after 2 seconds
- if (timeout > 2000) shmem[X300_FW_SHMEM_CLAIM_STATUS] = 0;
+ if (timeout > 200) shmem[X300_FW_SHMEM_CLAIM_STATUS] = 0;
}
/***********************************************************************
@@ -264,36 +264,17 @@ static uint32_t get_xbar_total(const uint32_t port)
return total;
}
-static size_t popcntll(uint64_t num)
-{
- size_t total = 0;
- for (size_t i = 0; i < sizeof(num)*8; i++)
- {
- total += (num >> i) & 0x1;
- }
- return total;
-}
-
static void update_leds(void)
{
- //update activity status for all ports
- uint64_t activity_shreg[16];
- for (uint32_t i = 0; i < 16; i++)
- {
- static uint32_t last_total[16];
- const uint32_t total = get_xbar_total(i);
- activity_shreg[i] <<= 1;
- activity_shreg[i] |= (total == last_total[i])? 0 : 1;
- last_total[i] = total;
- }
-
- static uint32_t counter = 0;
- counter++;
+ static uint32_t last_total0 = 0;
+ static uint32_t last_total1 = 0;
+ const uint32_t total0 = get_xbar_total(0);
+ const uint32_t total1 = get_xbar_total(1);
+ const bool act0 = (total0 != last_total0);
+ const bool act1 = (total1 != last_total1);
+ last_total0 = total0;
+ last_total1 = total1;
- const size_t cnt0 = popcntll(activity_shreg[0]);
- const size_t cnt1 = popcntll(activity_shreg[1]);
- const bool act0 = cnt0*8 > (counter % 64);
- const bool act1 = cnt1*8 > (counter % 64);
const bool link0 = ethernet_get_link_up(0);
const bool link1 = ethernet_get_link_up(1);
const bool claimed = shmem[X300_FW_SHMEM_CLAIM_STATUS];
@@ -314,7 +295,7 @@ static void update_leds(void)
static void garp(void)
{
static size_t count = 0;
- if (count++ < 60000) return; //60 seconds
+ if (count++ < 3000) return; //30 seconds
count = 0;
for (size_t e = 0; e < ethernet_ninterfaces(); e++)
{
@@ -428,7 +409,7 @@ static void handle_link_state(void)
**********************************************************************/
int main(void)
{
- x300_init();
+ x300_init((x300_eeprom_map_t *)&shmem[X300_FW_SHMEM_IDENT]);
u3_net_stack_register_udp_handler(X300_FW_COMMS_UDP_PORT, &handle_udp_fw_comms);
u3_net_stack_register_udp_handler(X300_VITA_UDP_PORT, &handle_udp_prog_framer);
u3_net_stack_register_udp_handler(X300_FPGA_PROG_UDP_PORT, &handle_udp_fpga_prog);
@@ -438,10 +419,10 @@ int main(void)
while(true)
{
- //jobs that happen once every ms
+ //jobs that happen once every 10ms
const uint32_t ticks_now = wb_peek32(SR_ADDR(RB0_BASE, RB_COUNTER));
const uint32_t ticks_passed = ticks_now - last_cronjob;
- static const uint32_t tick_delta = CPU_CLOCK/1000;
+ static const uint32_t tick_delta = CPU_CLOCK/100;
if (ticks_passed > tick_delta)
{
poll_sfpp_status(0); // Every so often poll XGE Phy to look for SFP+ hotplug events.
@@ -450,7 +431,7 @@ int main(void)
handle_claim(); //deal with the host claim register
update_leds(); //run the link and activity leds
garp(); //send periodic garps
- last_cronjob = wb_peek32(SR_ADDR(RB0_BASE, RB_COUNTER));
+ last_cronjob = ticks_now;
}
//run the network stack - poll and handle