From 64b4c1f5d7554c272884d67d0bf3d0d3d48c77ba Mon Sep 17 00:00:00 2001 From: michael-west Date: Wed, 4 Jan 2017 16:57:53 -0800 Subject: 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 --- firmware/usrp3/x300/x300_defs.h | 2 +- firmware/usrp3/x300/x300_init.c | 44 ++++++++++---------------------------- firmware/usrp3/x300/x300_init.h | 5 ++++- firmware/usrp3/x300/x300_main.c | 47 ++++++++++++----------------------------- 4 files changed, 30 insertions(+), 68 deletions(-) (limited to 'firmware') 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 @@ -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 -- cgit v1.2.3