diff options
author | Martin Braun <martin.braun@ettus.com> | 2014-10-07 09:39:25 +0200 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2014-10-07 09:39:25 +0200 |
commit | 5bd58bc309e959537e3e820abfa39ee629b140a5 (patch) | |
tree | 81e3a611134e02d9118f0aa846b7146234849fe8 /firmware/x300/lib | |
parent | 9f6a11173aef5e661100268bd746963d713adb91 (diff) | |
download | uhd-5bd58bc309e959537e3e820abfa39ee629b140a5.tar.gz uhd-5bd58bc309e959537e3e820abfa39ee629b140a5.tar.bz2 uhd-5bd58bc309e959537e3e820abfa39ee629b140a5.zip |
Reorganized firmware/ subdirectory (x300->usrp3, zpu->usrp2)
Diffstat (limited to 'firmware/x300/lib')
-rw-r--r-- | firmware/x300/lib/CMakeLists.txt | 32 | ||||
-rw-r--r-- | firmware/x300/lib/chinch.c | 313 | ||||
-rw-r--r-- | firmware/x300/lib/ethernet.c | 644 | ||||
-rw-r--r-- | firmware/x300/lib/link_state_route_proto.c | 441 | ||||
-rw-r--r-- | firmware/x300/lib/mdelay.c | 36 | ||||
-rw-r--r-- | firmware/x300/lib/print_addrs.c | 64 | ||||
-rw-r--r-- | firmware/x300/lib/printf.c | 287 | ||||
-rw-r--r-- | firmware/x300/lib/u3_net_stack.c | 589 | ||||
-rw-r--r-- | firmware/x300/lib/udp_uart.c | 149 | ||||
-rw-r--r-- | firmware/x300/lib/wb_i2c.c | 137 | ||||
-rw-r--r-- | firmware/x300/lib/wb_pkt_iface64.c | 87 | ||||
-rw-r--r-- | firmware/x300/lib/wb_uart.c | 34 |
12 files changed, 0 insertions, 2813 deletions
diff --git a/firmware/x300/lib/CMakeLists.txt b/firmware/x300/lib/CMakeLists.txt deleted file mode 100644 index ed5a0a7c0..000000000 --- a/firmware/x300/lib/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright 2010-2013 Ettus Research LLC -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# - -######################################################################## - -add_library(usrpfw STATIC - udp_uart.c - wb_uart.c - wb_i2c.c - printf.c - wb_pkt_iface64.c - u3_net_stack.c - ethernet.c - mdelay.c - chinch.c - print_addrs.c - link_state_route_proto.c -) diff --git a/firmware/x300/lib/chinch.c b/firmware/x300/lib/chinch.c deleted file mode 100644 index e33378851..000000000 --- a/firmware/x300/lib/chinch.c +++ /dev/null @@ -1,313 +0,0 @@ -// -// Copyright 2013 Ettus Research LLC -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// - -#include "chinch.h" - -#define PCIE_MSG_REG_BASE 0xFB00 -#define PCIE_MSG_DATA_REG 0 //Write: Data register for outbound requests and responses - //Read: Latched data for inbound requests -#define PCIE_MSG_CTRL_REG 1 //Write: Control register for outbound requests and responses (Initiates xfer) - //Read: Latched control word for inbound requests -#define PCIE_MSG_RESP_REG 2 //Read: Latched response data for outbound requests -#define PCIE_MSG_STATUS_REG 3 //Read: Status register for inbound and outbound transactions - -// Transaction Word Format -// -// -Control- --Data-- -// 63 32 31 0 -// | | | | -// FXXA AAAA DDDD DDDD -// -// where: -// D = Data/Payload -// A = Address -// X = Reserved -// F = Flags: {Read_Response, Write_Request, Read_Request, Half_Word_Cycle} - -#define PCIE_CTRL_REG_READ_RESP (1<<31) -#define PCIE_CTRL_REG_WRITE (1<<30) -#define PCIE_CTRL_REG_READ (1<<29) -#define PCIE_CTRL_REG_HALF_WORD (1<<28) -#define PCIE_CTRL_REG_ADDR_MASK 0x000FFFFF - -#define PCIE_STATUS_REG_READ_PENDING (1<<0) -#define PCIE_STATUS_REG_REQ_PENDING (1<<1) -#define PCIE_STATUS_REG_RESP_PENDING (1<<2) -#define PCIE_STATUS_REG_BUSY (1<<4) - -#define CHINCH_FPGA_CONFIG_REG 0x58 -#define CHINCH_FLASH_WINDOW_REG0 0xC0 -#define CHINCH_FLASH_WINDOW_REG1 0xE0 -#define CHINCH_FLASH_2AAA_REG 0x400 -#define CHINCH_FLASH_5555_REG 0x408 -#define CHINCH_FLASH_WINDOW_BASE 0x60000 -#define CHINCH_FLASH_WINDOW_SIZE 0x20000 -#define CHINCH_FLASH_WINDOW_CONF 0x91 - -//----------------------------------------------------- -// Peek-Poke interface -//----------------------------------------------------- - -bool chinch_poke( - const uint32_t addr, - const uint32_t data, - bool half_word, - uint32_t timeout -) -{ - //Build transaction control word - uint32_t ctrl_word = 0, i; - ctrl_word |= (addr & PCIE_CTRL_REG_ADDR_MASK); - if (half_word) ctrl_word |= PCIE_CTRL_REG_HALF_WORD; - ctrl_word |= PCIE_CTRL_REG_WRITE; - - //Wait for space in the transaction queue or timeout - i = 0; - while ((wb_peek32(SR_ADDR(PCIE_MSG_REG_BASE, PCIE_MSG_STATUS_REG)) & PCIE_STATUS_REG_BUSY) != 0) { - if (++i > timeout) return false; - } - - //Flush transaction control and data registers - wb_poke32(SR_ADDR(PCIE_MSG_REG_BASE, PCIE_MSG_DATA_REG), data); - wb_poke32(SR_ADDR(PCIE_MSG_REG_BASE, PCIE_MSG_CTRL_REG), ctrl_word); - - return true; -} - -bool chinch_peek( - const uint32_t addr, - uint32_t* data, - bool half_word, - uint32_t timeout -) -{ - //Build transaction control word - uint32_t ctrl_word = 0, i; - ctrl_word |= (addr & PCIE_CTRL_REG_ADDR_MASK); - if (half_word) ctrl_word |= PCIE_CTRL_REG_HALF_WORD; - ctrl_word |= PCIE_CTRL_REG_READ; - - //Wait for space in the transaction queue or timeout - i = 0; - while ((wb_peek32(SR_ADDR(PCIE_MSG_REG_BASE, PCIE_MSG_STATUS_REG)) & PCIE_STATUS_REG_BUSY) != 0) { - if (++i > timeout) return false; - } - - //Flush transaction control register - if (data) *data = 0; - wb_poke32(SR_ADDR(PCIE_MSG_REG_BASE, PCIE_MSG_CTRL_REG), ctrl_word); - - //Wait for read completion or timeout - i = 0; - while ((wb_peek32(SR_ADDR(PCIE_MSG_REG_BASE, PCIE_MSG_STATUS_REG)) & PCIE_STATUS_REG_READ_PENDING) != 0) { - if (++i > timeout) return false; - } - //Read transaction data register - if (data) *data = wb_peek32(SR_ADDR(PCIE_MSG_REG_BASE, PCIE_MSG_RESP_REG)); - return true; -} - -//----------------------------------------------------- -// Flash access -//----------------------------------------------------- - -uint32_t g_cached_win_reg0; -uint32_t g_cached_win_reg1; - -bool chinch_flash_init() -{ - chinch_peek32(CHINCH_FLASH_WINDOW_REG0, &g_cached_win_reg0); - chinch_peek32(CHINCH_FLASH_WINDOW_REG1, &g_cached_win_reg1); - - bool status = true, passed = true; - STATUS_MERGE(chinch_poke32(CHINCH_FLASH_WINDOW_REG0, CHINCH_FLASH_WINDOW_BASE | CHINCH_FLASH_WINDOW_CONF), status); - - //Run a loopback test to ensure that we will not corrupt the flash. - STATUS_MERGE(chinch_poke32(0x200, 0xDEADBEEF), status); - STATUS_MERGE(chinch_poke16(0x204, 0x5678), status); - uint32_t reg_val; - STATUS_MERGE(chinch_peek16(0x0, ®_val), status); - STATUS_MERGE(chinch_poke16(0x206, reg_val), status); - STATUS_MERGE(chinch_peek32(0x200, ®_val), status); - passed &= (reg_val == 0xDEADBEEF); - STATUS_MERGE(chinch_peek32(0x204, ®_val), status); - passed &= (reg_val == 0x7AD05678); - - return status && passed; -} - -void chinch_flash_cleanup() -{ - chinch_poke32(CHINCH_FLASH_WINDOW_REG0, g_cached_win_reg0); - chinch_poke32(CHINCH_FLASH_WINDOW_REG1, g_cached_win_reg1); -} - -bool chinch_flash_select_sector(uint32_t sector) -{ - return chinch_poke32(CHINCH_FLASH_WINDOW_REG1, sector * CHINCH_FLASH_WINDOW_SIZE); -} - -bool chinch_flash_erase_sector() -{ - bool status = true; - STATUS_CHAIN(chinch_poke16(CHINCH_FLASH_5555_REG, 0x00AA), status); //Unlock #1 - STATUS_CHAIN(chinch_poke16(CHINCH_FLASH_2AAA_REG, 0x0055), status); //Unlock #2 - STATUS_CHAIN(chinch_poke16(CHINCH_FLASH_5555_REG, 0x0080), status); //Setup - STATUS_CHAIN(chinch_poke16(CHINCH_FLASH_5555_REG, 0x00AA), status); //Unlock #1 - STATUS_CHAIN(chinch_poke16(CHINCH_FLASH_2AAA_REG, 0x0055), status); //Unlock #2 - STATUS_CHAIN(chinch_poke16(CHINCH_FLASH_WINDOW_BASE, 0x0030), status); //Erase - - if (status) { - uint32_t read_data; - while (true) { - status = chinch_peek16(CHINCH_FLASH_WINDOW_BASE, &read_data); //Wait for sector to erase - if (((read_data & 0xFFFF) == 0xFFFF) || !status) break; - } - } - return status; -} - -bool chinch_flash_read_buf(uint32_t offset, uint16_t* buf, uint32_t size) -{ - bool status = true; - uint32_t base_addr = CHINCH_FLASH_WINDOW_BASE | (offset & 0x3FFFF); - for (uint32_t i = 0; (i < size) && status; i++) { - uint32_t word; - STATUS_CHAIN(chinch_peek16(base_addr + (i * 2), &word), status); - buf[i] = (uint16_t)word; - } - return status; -} - -bool chinch_flash_write_buf(uint32_t offset, uint16_t* buf, uint32_t size) -{ - if (size > CHINCH_FLASH_MAX_BUF_WRITES || buf == 0) return false; - bool status = true; - - //Setup buffered write - STATUS_CHAIN(chinch_poke16(CHINCH_FLASH_5555_REG, 0x00AA), status); //Unlock #1 - STATUS_MERGE(chinch_poke16(CHINCH_FLASH_2AAA_REG, 0x0055), status); //Unlock #2 - STATUS_CHAIN(chinch_poke16(CHINCH_FLASH_WINDOW_BASE, 0x0025), status); //Setup write - STATUS_CHAIN(chinch_poke16(CHINCH_FLASH_WINDOW_BASE, size - 1), status); //Num words - - //Write the data - uint32_t base_addr = CHINCH_FLASH_WINDOW_BASE | (offset & 0x3FFFF); - for (uint32_t i = 0; i < size; i++) { - STATUS_CHAIN(chinch_poke16(base_addr + (i * 2), buf[i]), status); - } - - //Commit write - STATUS_CHAIN(chinch_poke16(CHINCH_FLASH_WINDOW_BASE, 0x0029), status); - - //Poll for completion - //Bit 7 of the data at the final address is the status bit. - //It is set to the inverse of bit 7 of the final data to be - //written until the final write is completed. - uint32_t read_data; - do { - STATUS_MERGE(chinch_peek16(base_addr + ((size - 1) * 2), &read_data), status); - } while (status && (((uint16_t)read_data ^ buf[size - 1]) & (1 << 7))); - - return status; -} - -//----------------------------------------------------- -// FPGA Configuration -//----------------------------------------------------- -void chinch_start_config() -{ - chinch_poke32(CHINCH_FPGA_CONFIG_REG, 0x1); -} - -config_status_t chinch_get_config_status() -{ - bool status = true; - uint32_t read_data; - STATUS_MERGE(chinch_peek32(CHINCH_FPGA_CONFIG_REG, &read_data), status); - return status ? (config_status_t)read_data : CHINCH_CONFIG_ERROR; -} - -//----------------------------------------------------- -// Read-back interface for the user initiated -// PCIe register transactions -//----------------------------------------------------- -pcie_register_xact_t g_pcie_reg_xact_info; -uint32_t g_pcie_res_timeout; - -bool _respond_to_pcie_xact_request(uint32_t response, uint32_t timeout) -{ - //Wait for space in the transaction queue or timeout - uint32_t i = 0; - while ((wb_peek32(SR_ADDR(PCIE_MSG_REG_BASE, PCIE_MSG_STATUS_REG)) & PCIE_STATUS_REG_BUSY) != 0) { - if (++i > g_pcie_res_timeout) return false; - } - - //First write data and then the control register to ensure coherency - wb_poke32(SR_ADDR(PCIE_MSG_REG_BASE, PCIE_MSG_DATA_REG), response); - wb_poke32(SR_ADDR(PCIE_MSG_REG_BASE, PCIE_MSG_CTRL_REG), PCIE_CTRL_REG_READ_RESP); - - return true; -} - -bool check_pcie_user_regport(pcie_register_xact_t** xact_info_hdl) -{ - //Check for pending transaction requests - if ((wb_peek32(SR_ADDR(PCIE_MSG_REG_BASE, PCIE_MSG_STATUS_REG)) & PCIE_STATUS_REG_REQ_PENDING) != 0) { - //Attach responder to transaction info - g_pcie_reg_xact_info.respond = _respond_to_pcie_xact_request; - - //First read data and then the control register to ensure coherency - g_pcie_reg_xact_info.data = wb_peek32(SR_ADDR(PCIE_MSG_REG_BASE, PCIE_MSG_DATA_REG)); - uint32_t xact_control = wb_peek32(SR_ADDR(PCIE_MSG_REG_BASE, PCIE_MSG_CTRL_REG)); - - g_pcie_reg_xact_info.addr = xact_control & PCIE_CTRL_REG_ADDR_MASK; - g_pcie_reg_xact_info.size = - (xact_control & PCIE_CTRL_REG_HALF_WORD) == 0 ? PCIE_XACT_32_BIT : PCIE_XACT_16_BIT; - if ((xact_control & PCIE_CTRL_REG_READ) != 0) - g_pcie_reg_xact_info.type = PCIE_XACT_READ; - else if ((xact_control & PCIE_CTRL_REG_WRITE) != 0) - g_pcie_reg_xact_info.type = PCIE_XACT_WRITE; - else - g_pcie_reg_xact_info.type = PCIE_XACT_ERROR; - - *xact_info_hdl = &g_pcie_reg_xact_info; - return true; - } else { - *xact_info_hdl = 0; - return false; - } -} - -bool forward_pcie_user_xact_to_wb() -{ - pcie_register_xact_t* xact_info; - if (check_pcie_user_regport(&xact_info)) { - if (xact_info->size == PCIE_XACT_32_BIT) { - //Only respond to 32-bit transactions because that is all the LVFPGA interface can send - if (xact_info->type == PCIE_XACT_WRITE) { - wb_poke32(xact_info->addr, xact_info->data); - return true; - } else if (xact_info->type == PCIE_XACT_READ) { - return xact_info->respond(wb_peek32(xact_info->addr), CHINCH_DEFAULT_XACT_TIMEOUT); - } - } - } - return false; -} - - - diff --git a/firmware/x300/lib/ethernet.c b/firmware/x300/lib/ethernet.c deleted file mode 100644 index 7a86980c7..000000000 --- a/firmware/x300/lib/ethernet.c +++ /dev/null @@ -1,644 +0,0 @@ -/* - * Copyright 2007,2009 Free Software Foundation, Inc. - * Copyright 2009 Ettus Research LLC - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "../x300/x300_defs.h" -#include "ethernet.h" -#include "mdelay.h" -#include "printf.h" -#include "wb_i2c.h" -#include "wb_utils.h" -//#include "memory_map.h" -//#include "eth_phy.h" -//#include "pic.h" -//#include "hal_io.h" -//#include "nonstdio.h" -#include <stdint.h> -#include <stdbool.h> -#include "xge_phy.h" -#include "xge_mac.h" -#include <u3_net_stack.h> - - - - -#define VERBOSE 0 - -#define NETHS 2 // # of ethernet interfaces - -static bool links_up[NETHS] = {}; - -//////////////////////////////////////////////////////////////////////// -// -// 10 Gig Ethernet MAC. -// -typedef struct { - volatile uint32_t config; // WO - volatile uint32_t int_pending; // Clear-on-read - volatile uint32_t int_status; // RO - volatile uint32_t int_mask; // RW - volatile uint32_t mdio_data; - volatile uint32_t mdio_addr; - volatile uint32_t mdio_op; - volatile uint32_t mdio_control; - volatile uint32_t gpio; -} xge_regs_t; - -#define xge_regs ((xge_regs_t *) base) - -#define SFPP_STATUS_MODABS_CHG (1 << 5) // Has MODABS changed since last read? -#define SFPP_STATUS_TXFAULT_CHG (1 << 4) // Has TXFAULT changed since last read? -#define SFPP_STATUS_RXLOS_CHG (1 << 3) // Has RXLOS changed since last read? -#define SFPP_STATUS_MODABS (1 << 2) // MODABS state -#define SFPP_STATUS_TXFAULT (1 << 1) // TXFAULT state -#define SFPP_STATUS_RXLOS (1 << 0) // RXLOS state - - -int -ethernet_ninterfaces(void) -{ - return NETHS; -} - -//////////////////////////////////////////////////////////////////////// -// -// 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 -xge_read_mdio(const uint32_t base, const uint32_t address, const uint32_t device, const uint32_t port) -{ - // Set register address each iteration - xge_regs->mdio_addr = address; - // Its a clause 45 device. We want to ADDRESS - xge_regs->mdio_op = XGE_MDIO_CLAUSE(CLAUSE45) | XGE_MDIO_OP(MDIO_ADDRESS) | XGE_MDIO_ADDR(port) | XGE_MDIO_MMD(device); - // Start MDIO bus transaction - xge_regs->mdio_control = 1; - // Wait until bus transaction complete - while (xge_regs->mdio_control == 1); - // Its a clause 45 device. We want to READ - xge_regs->mdio_op = XGE_MDIO_CLAUSE(CLAUSE45) | XGE_MDIO_OP(MDIO_READ) | XGE_MDIO_ADDR(port) | XGE_MDIO_MMD(device); - // Start MDIO bus transaction - xge_regs->mdio_control = 1; - // Wait until bus transaction complete - while (xge_regs->mdio_control == 1); - // Read MDIO data - return(xge_regs->mdio_data); -} - -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 - xge_regs->mdio_op = XGE_MDIO_CLAUSE(CLAUSE45) | XGE_MDIO_OP(MDIO_ADDRESS) | XGE_MDIO_ADDR(port) | XGE_MDIO_MMD(device); - // Start MDIO bus transaction - 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 - 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 - while (xge_regs->mdio_control == 1); -} - -//////////////////////////////////////////////////////////////////////// -// -// Clause 22 MDIO used for 1Gig Ethernet has one bus transaction to complete a transfer. -// -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 - xge_regs->mdio_op = XGE_MDIO_CLAUSE(CLAUSE22) | XGE_MDIO_OP(MDIO_C22_READ) | XGE_MDIO_ADDR(port) | address; - // Start MDIO bus transaction - xge_regs->mdio_control = 1; - // Wait until bus transaction complete - while (xge_regs->mdio_control == 1); - // Read MDIO data - return(xge_regs->mdio_data); -} - -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 - 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 - while (xge_regs->mdio_control == 1); -} - -//////////////////////////////////////////////////////////////////////// -// -// Read and write MDIO independent of type -// - -static uint32_t read_mdio(const uint8_t eth, const uint32_t address, const uint32_t device, const uint32_t port) -{ - const uint32_t rb_addr = (eth==0) ? RB_ETH_TYPE0 : RB_ETH_TYPE1; - const uint32_t base = (eth==0) ? XGE0_BASE : XGE1_BASE; - if (wb_peek32(SR_ADDR(RB0_BASE, rb_addr)) != 0) - { - return xge_read_mdio(base, address, device, port); - } - else - { - return ge_read_mdio(base, address, port); - } -} - -static void write_mdio(const uint8_t eth, const uint32_t address, const uint32_t device, const uint32_t port, const uint32_t data) -{ - const uint32_t rb_addr = (eth==0) ? RB_ETH_TYPE0 : RB_ETH_TYPE1; - const uint32_t base = (eth==0) ? XGE0_BASE : XGE1_BASE; - if (wb_peek32(SR_ADDR(RB0_BASE, rb_addr)) != 0) - { - return xge_write_mdio(base, address, device, port, data); - } - else - { - return ge_write_mdio(base, address, port, data); - } -} - -//////////////////////////////////////////////////////////////////////// -// -// Read an 8-bit word from a device attached to the PHY's i2c bus. -// -static int -xge_i2c_rd(const uint32_t base, const uint8_t i2c_dev_addr, const uint8_t i2c_word_addr) -{ - uint8_t buf; - // IJB. CHECK HERE FOR MODET. Bail immediately if no module - - // SFF-8472 defines a hardcoded bus address of 0xA0, an 8bit internal address and a register map. - // Write the random access address to the SPF module - if (wb_i2c_write(base, i2c_dev_addr, &i2c_word_addr, 1) == false) - return(-1); - - // Now read back a byte of data - if (wb_i2c_read(base, i2c_dev_addr, &buf, 1) == false) - return(-1); - - return((int) buf); -} - -//////////////////////////////////////////////////////////////////////// -// -// Read identity of SFP+ module for XGE PHY -// -// (base is i2c controller) -static int -xge_read_sfpp_type(const uint32_t base, const uint32_t delay_ms) -{ - int x; - // Delay read of SFPP - if (delay_ms) - mdelay(delay_ms); - // Read ID code from SFP - x = xge_i2c_rd(base, MODULE_DEV_ADDR, 3); - // I2C Error? - if (x < 0) { - printf("DEBUG: I2C error in SFPP_TYPE.\n"); - return x; - } - // Decode module type. These registers and values are defined in SFF-8472 - if (x & 0x01) // Active 1X Infinband Copper - { - goto twinax; - } - if (x & 0x10) - { - printf("DEBUG: SFFP_TYPE_SR.\n"); - return SFFP_TYPE_SR; - } - if (x & 0x20) - { - printf("DEBUG: SFFP_TYPE_LR.\n"); - return SFFP_TYPE_LR; - } - if (x & 0x40) - { - printf("DEBUG: SFFP_TYPE_LRM.\n"); - return SFFP_TYPE_LRM; - } - // Search for legacy 1000-Base SFP types - x = xge_i2c_rd(base, MODULE_DEV_ADDR, 0x6); - if (x < 0) { - printf("DEBUG: I2C error in SFPP_TYPE.\n"); - return x; - } - if (x & 0x01) { - printf("DEBUG: SFFP_TYPE_1000BASE_SX.\n"); - return SFFP_TYPE_1000BASE_SX; - } - if (x & 0x02) { - printf("DEBUG: SFFP_TYPE_1000BASE_LX.\n"); - return SFFP_TYPE_1000BASE_LX; - } - if (x & 0x08) { - printf("DEBUG: SFFP_TYPE_1000BASE_T.\n"); - return SFFP_TYPE_1000BASE_T; - } - // Not one of the standard optical types..now try to deduce if it's twinax aka 10GSFP+CU - // which is not covered explicitly in SFF-8472 - x = xge_i2c_rd(base, MODULE_DEV_ADDR, 8); - if (x < 0) { - printf("DEBUG: I2C error in SFPP_TYPE.\n"); - return x; - } - if ((x & 4) == 0) // Passive SFP+ cable type - goto unknown; -// x = xge_i2c_rd(MODULE_DEV_ADDR, 6); -// printf("SFP+ reg6 read as %x\n",x); -// if (x < 0) -// return x; -// if (x != 0x04) // Returns 1000Base-CX as Compliance code -// goto unknown; - x = xge_i2c_rd(base, MODULE_DEV_ADDR, 0xA); - if (x < 0) { - printf("DEBUG: I2C error in SFPP_TYPE.\n"); - return x; - } - if (x & 0x80) { - twinax: - // Reports 1200 MBytes/sec fibre channel speed..close enough to 10G ethernet! - x = xge_i2c_rd(base, MODULE_DEV_ADDR, 0x12); - - if (x < 0) { - printf("DEBUG: I2C error in SFPP_TYPE.\n"); - return x; - } - printf("DEBUG: TwinAx.\n"); - // If cable length support is greater than 10M then pick correct type - return x > 10 ? SFFP_TYPE_TWINAX_LONG : SFFP_TYPE_TWINAX; - } -unknown: - printf("DEBUG: Unknown SFP+ type.\n"); - // Not a supported Module type - return SFFP_TYPE_UNKNOWN; -} - - -// Pull reset line low for 100ms then release and wait 100ms -static void -xge_hard_phy_reset(const uint32_t base) -{ - wb_poke32(base, 1); - mdelay(100); - wb_poke32(base, 0); - mdelay(100); - -} - -static void -xge_mac_init(const uint32_t base) -{ - printf("INFO: Begining XGE MAC init sequence.\n"); - xge_regs->config = XGE_TX_ENABLE; -} - -// base is pointer to XGE MAC on Wishbone. -static void -xge_phy_init(const uint8_t eth, const uint32_t mdio_port) -{ - int x; - // Read LASI Ctrl register to capture state. - //y = xge_read_mdio(0x9002,XGE_MDIO_DEVICE_PMA,XGE_MDIO_ADDR_PHY_A); - 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); - 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 )); - - if (x & SFPP_STATUS_RXLOS_CHG) - printf("DEBUG: eth%1d RXLOS changed state: %d\n", eth, x & SFPP_STATUS_RXLOS); - if (x & SFPP_STATUS_TXFAULT_CHG) - printf("DEBUG: eth%1d TXFAULT changed state: %d\n", eth,(x & SFPP_STATUS_TXFAULT) >> 1 ); - if (x & SFPP_STATUS_MODABS_CHG) - 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) - { - 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 - if (x & SFPP_STATUS_MODABS) { - // MODDET is high, module currently removed. - printf("INFO: An SFP+ module has been removed from eth port %d.\n", eth); - } else { - // MODDET is low, module currently inserted. - // Return status. - printf("INFO: A new SFP+ module has been inserted into eth port %d.\n", eth); - xge_read_sfpp_type((eth==0) ? I2C0_BASE : I2C2_BASE,1); - } - } - - //update the link up status - const bool old_link_up = links_up[eth]; - links_up[eth] = ((read_mdio(eth, XGE_MDIO_STATUS1,XGE_MDIO_DEVICE_PMA,MDIO_PORT)) & (1 << 2)) != 0; - //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); - 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, - x & SFPP_STATUS_RXLOS, - (x & SFPP_STATUS_TXFAULT) >> 1, - (x & SFPP_STATUS_MODABS) >> 2); -} - -// -// Debug code to verbosely read XGE MDIO registers below here. -// - - -void decode_reg(uint32_t address, uint32_t device, uint32_t data) -{ - int x; - printf("Device: "); - printf("%x",device); - printf(" "); - switch(address) { - case XGE_MDIO_CONTROL1: - printf("CONTROL1: "); - printf("%x",data); printf(" "); - for (x=15; x >= 0 ; x--) - if ((data & (1 << x)) != 0) - // Bits set. - switch(x) { - case 15: printf("Reset,"); break; - case 14: printf("Loopback,"); break; - 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 - // Bits clear. - //switch (x) { - //case 13: case 6: printf(" None 10Gb/s speed set!"); break; - //} - printf(" \n"); - break; - case XGE_MDIO_STATUS1: - printf("STATUS1: "); - printf("%x",data); printf(" "); - for (x=15; x >= 0 ; x--) - if ((data & (1 << x)) != 0) - // Bits set. - switch(x) { - case 7: printf("Fault Detected,"); break; - case 2: printf("Link is Up,"); break; - case 1: printf("Supports Low Power,"); break; - } else - // Bits Clear - switch(x) { - case 2: printf("Link is Down,"); break; - } - printf(" \n"); - break; - case XGE_MDIO_SPEED: - printf("SPEED ABILITY: "); - printf("%x",data); printf(" "); - for (x=15; x >= 0 ; x--) - if ((data & (1 << x)) != 0) - // Bits set. - switch(x) { - 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 - // Bits clear. - switch(x) { - case 0: printf("Incapable of 10Gb/s,"); break; - } - printf(" \n"); - break; - case XGE_MDIO_DEVICES1: - printf("DEVICES IN PACKAGE: "); - printf("%x",data); printf(" "); - for (x=15; x >= 0 ; x--) - if ((data & (1 << x)) != 0) - // Bits set. - switch(x) { - case 7: printf("Auto-Negotiation,"); break; - case 6: printf("TC,"); break; - case 5: printf("DTE XS,"); break; - case 4: printf("PHY XS,"); break; - case 3: printf("PCS,"); break; - case 2: printf("WIS,"); break; - case 1: printf("PMD/PMA,"); break; - case 0: printf("Clause 22 registers,"); break; - } - printf(" \n"); - break; - case XGE_MDIO_DEVICES2: - printf("DEVICES IN PACKAGE (cont): "); - printf("%x",data); printf(" "); - for (x=15; x >= 0 ; x--) - if ((data & (1 << x)) != 0) - // Bits set. - switch(x) { - case 15: printf("Vendor device 2,"); break; - case 14: printf("Vendor device 1,"); break; - case 13: printf("Clause 22 extension,"); break; - } - printf(" \n"); - break; - case XGE_MDIO_CONTROL2: - printf("CONTROL2: "); - printf("%x",data); printf(" "); - // PMA/PMD - if (device == XGE_MDIO_DEVICE_PMA) - switch((data & 0xf)) { - case 0xF: printf("10BASE-T,"); break; - case 0xE: printf("100BASE-TX,"); break; - case 0xD: printf("1000BASE-KX,"); break; - case 0xC: printf("1000BASE-T,"); break; - case 0xB: printf("10GBASE-KR,"); break; - case 0xA: printf("10GBASE-KX4,"); break; - case 0x9: printf("10GBASE-T,"); break; - case 0x8: printf("10GBASE-LRM,"); break; - case 0x7: printf("10GBASE-SR,"); break; - case 0x6: printf("10GBASE-LR,"); break; - case 0x5: printf("10GBASE-ER,"); break; - case 0x4: printf("10GBASE-LX4,"); break; - // case 0x3: printf("10GBASE-SW,"); break; - // case 0x2: printf("10GBASE-LW,"); break; - // case 0x1: printf("10GBASE-EW,"); break; - case 0x0: printf("10GBASE-CX4,"); break; - } else if (device == XGE_MDIO_DEVICE_PCS) - // PCS - switch((data & 0x3)) { - case 0x3: printf("10GBASE-T PCS,"); break; - case 0x2: printf("10GBASE-W PCS,"); break; - case 0x1: printf("10GBASE-X PCS,"); break; - case 0x0: printf("10GBASE-R PCS,"); break; - } - printf(" \n"); - break; - case XGE_MDIO_STATUS2: - printf("STATUS2: "); - printf("%x",data); printf(" "); - for (x=15; x >= 0 ; x--) - if ((data & (1 << x)) != 0) - // Bits set. - switch(x) { - case 15: if ((data & (1 << 14)) == 0) printf("Device responding,"); break; - case 13: if (device == XGE_MDIO_DEVICE_PMA) printf("Able detect a Tx fault,"); break; - case 12: if (device == XGE_MDIO_DEVICE_PMA) printf("Able detect an Rx fault,"); break; - case 11: printf("Fault on Tx path,"); break; - case 10: printf("Fault on Rx path,"); break; - case 9: if (device == XGE_MDIO_DEVICE_PMA) printf("Extended abilities in Reg1.11,"); break; - case 8: if (device == XGE_MDIO_DEVICE_PMA) printf("Able to disable TX,"); break; - case 7: if (device == XGE_MDIO_DEVICE_PMA) printf("10GBASE-SR,"); break; - case 6: if (device == XGE_MDIO_DEVICE_PMA) printf("10GBASE-LR,"); break; - case 5: if (device == XGE_MDIO_DEVICE_PMA) printf("10GBASE-ER,"); break; - case 4: if (device == XGE_MDIO_DEVICE_PMA) printf("10GBASE-LX4,"); break; - case 3: if (device == XGE_MDIO_DEVICE_PMA) printf("10GBASE-SW,"); break; - case 2: if (device == XGE_MDIO_DEVICE_PMA) printf("10GBASE-LW,"); break; - case 1: if (device == XGE_MDIO_DEVICE_PMA) printf("10GBASE-EW,"); break; - case 0: if (device == XGE_MDIO_DEVICE_PMA) printf("loopback,"); break; - } - printf(" \n"); - break; - case XGE_MDIO_LANESTATUS: - printf("LANE STATUS: "); - printf("%x",data); printf(" "); - for (x=15; x >= 0 ; x--) - if ((data & (1 << x)) != 0) - // Bits set. - switch(x) { - case 12: printf("Lanes aligned,"); break; - case 11: printf("Able to generate test patterns,"); break; - case 3: printf("Lane 3 synced,"); break; - case 2: printf("Lane 2 synced,"); break; - case 1: printf("Lane 1 synced,"); break; - case 0: printf("Lane 0 synced,"); break; - } else - // Bits clear - switch(x) { - case 3: printf("Lane 3 not synced,"); break; - 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: - printf("XILINX CORE VERSION: %x ",data); - printf("Version: %d.%d ",(data&0xf000)>>12,(data&0xf00)>>8); - printf("Patch: %d ",(data&0xE)>>1); - if (data&0x1) printf("Evaluation Version of core"); - printf("\n"); - break; - default: - printf("Register @ address: "); - printf("%x",address); - printf(" has value: "); - printf("%x\n",data); - break; - } -} - -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++) - { - // 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 - x = read_mdio(eth,regs_a[y],XGE_MDIO_DEVICE_PCS,mdio_port); - decode_reg(regs_a[y],XGE_MDIO_DEVICE_PCS,x); - } - - printf("\n"); - - /* for (y = 0; y < 8; y++) */ - /* { */ - /* // Read MDIO data */ - /* x = xge_read_mdio(base,regs_a[y],XGE_MDIO_DEVICE_PHY_XS,mdio_port); */ - /* decode_reg(regs_a[y],XGE_MDIO_DEVICE_PHY_XS,x); */ - /* } */ - - /* for (y = 0; y < 8; y++) */ - /* { */ - /* // Read MDIO data */ - /* x = xge_read_mdio(base,regs_a[y],XGE_MDIO_DEVICE_DTE_XS,mdio_port); */ - /* decode_reg(regs_a[y],XGE_MDIO_DEVICE_DTE_XS,x); */ - /* } */ -} - -bool ethernet_get_link_up(const uint32_t eth) -{ - return links_up[eth]; -} diff --git a/firmware/x300/lib/link_state_route_proto.c b/firmware/x300/lib/link_state_route_proto.c deleted file mode 100644 index 30cfd73cb..000000000 --- a/firmware/x300/lib/link_state_route_proto.c +++ /dev/null @@ -1,441 +0,0 @@ - -// Copyright 2013 Ettus Research LLC - -#include <link_state_route_proto.h> -#include <u3_net_stack.h> -#include <ethernet.h> -#include <string.h> -#include <printf.h> -#include <print_addrs.h> - -#define lengthof(a) (sizeof(a)/sizeof(*(a))) - -/*********************************************************************** - * global constants - **********************************************************************/ -#define LS_PROTO_VERSION 6 - -//shift the proto version into the ID so only matching fw responds -#define LS_ID_DISCOVER (0 | (8 << LS_PROTO_VERSION)) -#define LS_ID_INFORM (1 | (8 << LS_PROTO_VERSION)) - -#define LS_PAYLOAD_MTU 1024 -#define LS_NUM_NBOR_ENTRIES 16 -#define LS_NUM_NODE_ENTRIES 64 -#define LS_NUM_MAP_ENTRIES 128 - -#define NETHS 4 //max eths supported in this file - -/*********************************************************************** - * wire format for table communication - **********************************************************************/ -typedef struct -{ - uint32_t num_nbors; //number of entries in neighbors list - uint32_t num_ports; //first few neighbors are local ports - struct ip_addr node; - struct ip_addr nbors[]; -} ls_data_t; - -static inline size_t sizeof_ls_data(const ls_data_t *ls_data) -{ - return 0 - + sizeof(uint32_t)/*num neighbors*/ - + sizeof(uint32_t)/*num ports*/ - + sizeof(struct ip_addr)/*source node*/ - + sizeof(struct ip_addr)*ls_data->num_nbors; -} - -/*********************************************************************** - * sequence and tick counter monitor - **********************************************************************/ -static uint16_t ticker = 0; - -void link_state_route_proto_tick(void) -{ - ticker++; -} - -static inline bool is_tick_expired(const uint16_t tick) -{ - const uint16_t delta = ticker - tick; - return delta > 2; //have not talked in a while, you are deaf to me -} - -static uint16_t current_seq = 0; - -static inline bool is_seq_newer(const uint16_t seq, const uint16_t entry_seq) -{ - if (seq == entry_seq) return false; //not newer if equal - const uint16_t delta = seq - entry_seq; - return (delta & (1 << 15)) == 0; //newer when subtraction did not overflow -} - -/*********************************************************************** - * node entry api - **********************************************************************/ -typedef struct -{ - uint16_t seq; - uint16_t tick; - uint8_t ethno; - struct ip_addr ip_addr; -} ls_node_entry_t; - -static bool ls_node_entry_valid(const ls_node_entry_t *entry) -{ - return entry->ip_addr.addr != 0 && !is_tick_expired(entry->tick); -} - -static void ls_node_entry_update(ls_node_entry_t *entry, const int8_t ethno, const uint16_t seq, const struct ip_addr *ip_addr) -{ - entry->seq = seq; - entry->tick = ticker; - entry->ethno = ethno; - entry->ip_addr.addr = ip_addr->addr; -} - -static bool ls_node_entries_update( - ls_node_entry_t *entries, const size_t num_entries, - const int8_t ethno, const uint16_t seq, const struct ip_addr *ip_addr -) -{ - for (size_t i = 0; i < num_entries; i++) - { - if (!ls_node_entry_valid(&entries[i])) - { - ls_node_entry_update(entries+i, ethno, seq, ip_addr); - return true; - } - - if (entries[i].ip_addr.addr == ip_addr->addr && entries[i].ethno == ethno) - { - if (is_seq_newer(seq, entries[i].seq)) - { - ls_node_entry_update(entries+i, ethno, seq, ip_addr); - return true; - } - return false; - } - } - - //no space, shift the table down and take entry 0 - memmove(entries+1, entries, (num_entries-1)*sizeof(ls_node_entry_t)); - ls_node_entry_update(entries+0, ethno, seq, ip_addr); - return true; -} - -/*********************************************************************** - * storage for nodes in the network - **********************************************************************/ -static ls_node_entry_t ls_nbors[LS_NUM_NBOR_ENTRIES]; -static ls_node_entry_t ls_nodes[LS_NUM_NODE_ENTRIES]; - -/*********************************************************************** - * node table - **********************************************************************/ -static ls_node_mapping_t ls_node_maps[LS_NUM_MAP_ENTRIES]; - -const ls_node_mapping_t *link_state_route_get_node_mapping(size_t *length) -{ - *length = lengthof(ls_node_maps); - return ls_node_maps; -} - -static void add_node_mapping(const struct ip_addr *node, const struct ip_addr *nbor) -{ - //printf("add_node_mapping: %s -> %s\n", ip_addr_to_str(node), ip_addr_to_str(nbor)); - - //write into the first available slot - for (size_t i = 0; i < lengthof(ls_node_maps); i++) - { - if (ls_node_maps[i].node.addr == 0) - { - ls_node_maps[i].node.addr = node->addr; - ls_node_maps[i].nbor.addr = nbor->addr; - return; - } - } - - //otherwise, shift down the table and take slot0 - memmove(ls_node_maps+1, ls_node_maps, sizeof(ls_node_maps) - sizeof(ls_node_mapping_t)); - ls_node_maps[0].node.addr = node->addr; - ls_node_maps[0].nbor.addr = nbor->addr; -} - -static void remove_node_matches(const struct ip_addr *node) -{ - //printf("remove_node_matches: %s\n", ip_addr_to_str(node)); - - for (size_t j = 0; j < lengthof(ls_node_maps); j++) - { - //if the address is a match, clear the entry - if (ls_node_maps[j].node.addr == node->addr) - { - ls_node_maps[j].node.addr = 0; - ls_node_maps[j].nbor.addr = 0; - } - } -} - -static void update_node_mappings(const ls_data_t *ls_data) -{ - //printf("update_node_mappings: %s\n", ip_addr_to_str(&ls_data->node)); - - //remove any expired entries - for (size_t i = 0; i < lengthof(ls_nodes); i++) - { - if (ls_nodes[i].ip_addr.addr != 0 && is_tick_expired(ls_nodes[i].tick)) - { - remove_node_matches(&ls_nodes[i].ip_addr); - } - } - - //remove any matches for the current node - remove_node_matches(&ls_data->node); - - //is this a local packet? - bool is_local = false; - for (size_t e = 0; e < ethernet_ninterfaces(); e++) - { - if (ls_data->node.addr == u3_net_stack_get_ip_addr(e)->addr) is_local = true; - } - - //load entries from ls data into array - for (size_t i = 0; i < ls_data->num_nbors; i++) - { - if (is_local && i < ls_data->num_ports) continue; //ignore local ports - add_node_mapping(&ls_data->node, &ls_data->nbors[i]); - } -} - -/*********************************************************************** - * forward link state data onto all neighbors on the given port - **********************************************************************/ -static void send_link_state_data_to_all_neighbors( - const uint8_t ethno, const uint16_t seq, const ls_data_t *ls_data -){ - //exit and dont forward if the information is stale - if (!ls_node_entries_update(ls_nodes, lengthof(ls_nodes), ethno, seq, &ls_data->node)) return; - - //update the mappings with new info - update_node_mappings(ls_data); - - //forward to all neighbors - for (size_t i = 0; i < lengthof(ls_nbors); i++) - { - if (ls_nbors[i].ip_addr.addr == ls_data->node.addr) continue; //dont forward to sender - if (ls_node_entry_valid(&ls_nbors[i])) - { - if (ethernet_get_link_up(ls_nbors[i].ethno)) u3_net_stack_send_icmp_pkt( - ls_nbors[i].ethno, ICMP_IRQ, 0, - LS_ID_INFORM, seq, - &(ls_nbors[i].ip_addr), ls_data, sizeof_ls_data(ls_data) - ); - } - } - - //a change may have occured, update the cache - link_state_route_proto_update_cycle_cache(ethno); -} - -/*********************************************************************** - * handler for information reply - **********************************************************************/ -static void handle_icmp_ir( - const uint8_t ethno, - const struct ip_addr *src, const struct ip_addr *dst, - const uint16_t id, const uint16_t seq, - const void *buff, const size_t num_bytes -){ - switch (id) - { - //received a reply directly from the neighbor, add to neighbor list - case LS_ID_DISCOVER: - //printf("GOT LS_ID_DISCOVER REPLY - ID 0x%x - IP%u: %s\n", id, (int)ethno, ip_addr_to_str(u3_net_stack_get_ip_addr(ethno))); - if (ls_node_entries_update(ls_nbors, lengthof(ls_nbors), ethno, seq, src)) link_state_route_proto_flood(ethno); - break; - } -} - -/*********************************************************************** - * handler for information request - **********************************************************************/ -static void handle_icmp_irq( - const uint8_t ethno, - const struct ip_addr *src, const struct ip_addr *dst, - const uint16_t id, const uint16_t seq, - const void *buff, const size_t num_bytes -){ - switch (id) - { - //replies to discovery packets - case LS_ID_DISCOVER: - //printf("GOT LS_ID_DISCOVER REQ - IP%u: %s\n", (int)ethno, ip_addr_to_str(u3_net_stack_get_ip_addr(ethno))); - //printf("SEND LS_ID_DISCOVER REPLY - IP%u: %s\n", (int)ethno, ip_addr_to_str(u3_net_stack_get_ip_addr(ethno))); - u3_net_stack_send_icmp_pkt(ethno, ICMP_IR, 0, id, seq, src, buff, num_bytes); - break; - - //handle and forward information - case LS_ID_INFORM: - //printf("GOT LS_ID_INFORM REQ - IP%u: %s\n", (int)ethno, ip_addr_to_str(u3_net_stack_get_ip_addr(ethno))); - send_link_state_data_to_all_neighbors(ethno, seq, (const ls_data_t *)buff); - break; - }; -} - -/*********************************************************************** - * initiate a periodic update to the table - **********************************************************************/ -void link_state_route_proto_update(const uint8_t ethno) -{ - //send a discovery packet - //printf("SEND LS_ID_DISCOVER REQ - IP%u: %s\n", (int)ethno, ip_addr_to_str(u3_net_stack_get_ip_addr(ethno))); - u3_net_stack_send_icmp_pkt( - ethno, ICMP_IRQ, 0, - LS_ID_DISCOVER, current_seq++, - u3_net_stack_get_bcast(ethno), NULL, 0 - ); -} - -void link_state_route_proto_flood(const uint8_t ethno) -{ - for (size_t e = 0; e < ethernet_ninterfaces(); e++) - { - //fill link state data buffer - uint8_t buff[LS_PAYLOAD_MTU] = {}; - ls_data_t *ls_data = (ls_data_t *)buff; - ls_data->node.addr = u3_net_stack_get_ip_addr(e)->addr; - ls_data->num_nbors = 0; - ls_data->num_ports = 0; - - //first the local port links - for (size_t ej = 0; ej < ethernet_ninterfaces(); ej++) - { - if (e == ej) continue; //dont include our own port - ls_data->nbors[ls_data->num_nbors++].addr = u3_net_stack_get_ip_addr(ej)->addr; - ls_data->num_ports++; - } - - //now list the neighbors - for (size_t i = 0; i < lengthof(ls_nbors); i++) - { - if ((sizeof_ls_data(ls_data) + 4) >= LS_PAYLOAD_MTU) break; - if (ls_node_entry_valid(&ls_nbors[i]) && ls_nbors[i].ethno == e) - { - ls_data->nbors[ls_data->num_nbors++].addr = ls_nbors[i].ip_addr.addr; - } - } - - //send this data to all neighbors - send_link_state_data_to_all_neighbors(ethno, current_seq++, ls_data); - } -} - -/*********************************************************************** - * cycle detection logic - **********************************************************************/ -static void follow_links(const size_t current, struct ip_addr *nodes, bool *visited, const size_t num_nodes) -{ - if (visited[current]) return; //end the recursion - visited[current] = true; - - //follow all links where current node is the source - for (size_t i = 0; i < lengthof(ls_node_maps); i++) - { - if (ls_node_maps[i].node.addr != nodes[current].addr) continue; - - //find the index of the neighbor in the node list to recurse - for (size_t j = 0; j < num_nodes; j++) - { - if (nodes[j].addr != ls_node_maps[i].nbor.addr) continue; - follow_links(j, nodes, visited, num_nodes); - } - } -} - -bool link_state_route_proto_causes_cycle(const struct ip_addr *src, const struct ip_addr *dst) -{ - //printf("is there a cycle? %s -> %s: \n", ip_addr_to_str(src), ip_addr_to_str(dst)); - - //make a set of all nodes - size_t num_nodes = 0; - struct ip_addr nodes[LS_NUM_MAP_ENTRIES]; - for (size_t i = 0; i < lengthof(ls_node_maps); i++) - { - if (ls_node_maps[i].node.addr == 0 || ls_node_maps[i].nbor.addr == 0) continue; - //printf(" Link %s -> %s\n", ip_addr_to_str(&ls_node_maps[i].node), ip_addr_to_str(&ls_node_maps[i].nbor)); - const struct ip_addr *node = &ls_node_maps[i].node; - - //check if we have an entry - for (size_t j = 0; j < num_nodes; j++) - { - if (nodes[j].addr == node->addr) goto skip_add; - } - - //otherwise, we add the node - nodes[num_nodes++].addr = node->addr; - //printf(" Add to node set: %s\n", ip_addr_to_str(node)); - skip_add: continue; - } - - //and stateful tracking info for each node - bool visited[LS_NUM_MAP_ENTRIES]; - for (size_t i = 0; i < num_nodes; i++) visited[i] = false; - - //find our src node in the set and follow - for (size_t i = 0; i < num_nodes; i++) - { - if (nodes[i].addr == src->addr) follow_links(i, nodes, visited, num_nodes); - } - - //did we visit the destination? if so, there is a cycle - for (size_t i = 0; i < num_nodes; i++) - { - if (nodes[i].addr == dst->addr && visited[i]) - { - //printf("CAUSES CYCLE!\n"); - return true; - } - } - - //printf("no cycle found.\n"); - return false; -} - -static bool ls_causes_cycle[NETHS][NETHS]; - -void link_state_route_proto_update_cycle_cache(const uint8_t eth_src) -{ - for (size_t eth_dst = 0; eth_dst < ethernet_ninterfaces(); eth_dst++) - { - if (eth_src == eth_dst) continue; - ls_causes_cycle[eth_src][eth_dst] = link_state_route_proto_causes_cycle( - u3_net_stack_get_ip_addr(eth_src), - u3_net_stack_get_ip_addr(eth_dst) - ); - } -} - -bool link_state_route_proto_causes_cycle_cached(const uint8_t eth_src, const uint8_t eth_dst) -{ - return ls_causes_cycle[eth_src][eth_dst]; -} - -/*********************************************************************** - * init and registration code - **********************************************************************/ -void link_state_route_proto_init(void) -{ - u3_net_stack_register_icmp_handler(ICMP_IRQ, 0, &handle_icmp_irq); - u3_net_stack_register_icmp_handler(ICMP_IR, 0, &handle_icmp_ir); - - //default to causing a cycle, let the algorithm set this correctly - for (size_t i = 0; i < NETHS; i++) - { - for (size_t j = 0; j < NETHS; j++) - { - ls_causes_cycle[i][j] = true; - } - } -} diff --git a/firmware/x300/lib/mdelay.c b/firmware/x300/lib/mdelay.c deleted file mode 100644 index 6d2742206..000000000 --- a/firmware/x300/lib/mdelay.c +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- c -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * Copyright 2009 Ettus Research LLC - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "mdelay.h" -#include "wb_utils.h" -#include "printf.h" -#include <stdint.h> -//IJB FIXME. -#include "../x300/x300_defs.h" - -void mdelay(int ms){ - for(int i = 0; i < ms; i++){ - static const uint32_t num_ticks = CPU_CLOCK/1000; - const uint32_t ticks_begin = wb_peek32(SR_ADDR(RB0_BASE, RB_COUNTER)); - // printf("DEBUG: Counter is %d\n",ticks_begin); - while((wb_peek32(SR_ADDR(RB0_BASE, RB_COUNTER)) - ticks_begin) < num_ticks) { - /*NOP*/ - } - } -} diff --git a/firmware/x300/lib/print_addrs.c b/firmware/x300/lib/print_addrs.c deleted file mode 100644 index 6a710f75c..000000000 --- a/firmware/x300/lib/print_addrs.c +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2013 Ettus Research LLC - -#include <print_addrs.h> -#include <stddef.h> -#include <stdint.h> -#include <printf.h> - -#define MAX_MAC_CHARS 24 -#define MAX_IP_CHARS 16 - -static const char hex[16] = "0123456789ABCDEF"; - -char *mac_addr_to_str_r(const void *addr, char *str) -{ - uint8_t *p = (uint8_t *)addr; - size_t j = 0; - for(size_t i = 0; i < 6; i++) - { - if (i) str[j++] = ':'; - str[j++] = hex[(p[i] >> 4) & 0xf]; - str[j++] = hex[p[i] & 0xf]; - } - str[j++] = '\0'; - return str; -} - -char *ip_addr_to_str_r(const void *addr, char *str) -{ - uint8_t *p = (uint8_t *)addr; - sprintf(str, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); - return str; -} - -char *mac_addr_to_str(const void *addr) -{ - static size_t index = 0; - index = (index + 1) % 4; - static char str[4][MAX_MAC_CHARS]; - return mac_addr_to_str_r(addr, str[index]); -} - -char *ip_addr_to_str(const void *addr) -{ - static size_t index = 0; - index = (index + 1) % 4; - static char str[4][MAX_IP_CHARS]; - return ip_addr_to_str_r(addr, str[index]); -} - -/* -void print_mac_addr(const void *addr) -{ - char str[MAX_MAC_CHARS]; - mac_addr_to_str_r(addr, str); - printf("%s", str); -} - -void print_ip_addr(const void *addr) -{ - char str[MAX_IP_CHARS]; - ip_addr_to_str_r(addr, str); - printf("%s", str); -} -*/ diff --git a/firmware/x300/lib/printf.c b/firmware/x300/lib/printf.c deleted file mode 100644 index 6d6a3e712..000000000 --- a/firmware/x300/lib/printf.c +++ /dev/null @@ -1,287 +0,0 @@ -/* -File: printf.c - -Copyright (C) 2004 Kustaa Nyholm - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ - -#include "printf.h" - -typedef void (*putcf) (void*,char); -static putcf stdout_putf; -static void* stdout_putp; - -#ifdef PRINTF_LONG_LONG_SUPPORT - -static void ulli2a(unsigned long long int num, unsigned int base, int uc,char * bf) - { - int n=0; - unsigned int d=1; - while (num/d >= base) - d*=base; - while (d!=0) { - int dgt = num / d; - num%=d; - d/=base; - if (n || dgt>0|| d==0) { - *bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10); - ++n; - } - } - *bf=0; - } - -static void lli2a (long long num, char * bf) - { - if (num<0) { - num=-num; - *bf++ = '-'; - } - ulli2a(num,10,0,bf); - } - -#endif - -#ifdef PRINTF_LONG_SUPPORT - -static void uli2a(unsigned long int num, unsigned int base, int uc,char * bf) - { - int n=0; - unsigned int d=1; - while (num/d >= base) - d*=base; - while (d!=0) { - int dgt = num / d; - num%=d; - d/=base; - if (n || dgt>0|| d==0) { - *bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10); - ++n; - } - } - *bf=0; - } - -static void li2a (long num, char * bf) - { - if (num<0) { - num=-num; - *bf++ = '-'; - } - uli2a(num,10,0,bf); - } - -#endif - -static void ui2a(unsigned int num, unsigned int base, int uc,char * bf) - { - int n=0; - unsigned int d=1; - while (num/d >= base) - d*=base; - while (d!=0) { - int dgt = num / d; - num%= d; - d/=base; - if (n || dgt>0 || d==0) { - *bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10); - ++n; - } - } - *bf=0; - } - -static void i2a (int num, char * bf) - { - if (num<0) { - num=-num; - *bf++ = '-'; - } - ui2a(num,10,0,bf); - } - -static int a2d(char ch) - { - if (ch>='0' && ch<='9') - return ch-'0'; - else if (ch>='a' && ch<='f') - return ch-'a'+10; - else if (ch>='A' && ch<='F') - return ch-'A'+10; - else return -1; - } - -static char a2i(char ch, char** src,int base,int* nump) - { - char* p= *src; - int num=0; - int digit; - while ((digit=a2d(ch))>=0) { - if (digit>base) break; - num=num*base+digit; - ch=*p++; - } - *src=p; - *nump=num; - return ch; - } - -static void putchw(void* putp,putcf putf,int n, char z, char* bf) - { - char fc=z? '0' : ' '; - char ch; - char* p=bf; - while (*p++ && n > 0) - n--; - while (n-- > 0) - putf(putp,fc); - while ((ch= *bf++)) - putf(putp,ch); - } - -void tfp_format(void* putp,putcf putf,char *fmt, va_list va) - { - char bf[12]; - - char ch; - - - while ((ch=*(fmt++))) { - if (ch!='%') - putf(putp,ch); - else { - char lz=0; -#ifdef PRINTF_LONG_SUPPORT - char lng=0; -#endif -#ifdef PRINTF_LONG_LONG_SUPPORT - char lnglng=0; -#endif - int w=0; - ch=*(fmt++); - if (ch=='0') { - ch=*(fmt++); - lz=1; - } - if (ch>='0' && ch<='9') { - ch=a2i(ch,&fmt,10,&w); - } -#ifdef PRINTF_LONG_SUPPORT - if (ch=='l') { - ch=*(fmt++); - lng=1; - } -#endif -#ifdef PRINTF_LONG_LONG_SUPPORT - if ((ch=='l')&&(lng==1)) { - ch=*(fmt++); - lnglng=1; - } -#endif - switch (ch) { - case 0: - goto abort; - case 'u' : { -#ifdef PRINTF_LONG_LONG_SUPPORT - if (lnglng) - ulli2a(va_arg(va, unsigned long long int),10,0,bf); - else -#endif -#ifdef PRINTF_LONG_SUPPORT - if (lng) - uli2a(va_arg(va, unsigned long int),10,0,bf); - else -#endif - ui2a(va_arg(va, unsigned int),10,0,bf); - putchw(putp,putf,w,lz,bf); - break; - } - case 'd' : { -#ifdef PRINTF_LONG_LONG_SUPPORT - if (lnglng) - lli2a(va_arg(va, long long int),bf); - else -#endif -#ifdef PRINTF_LONG_SUPPORT - if (lng) - li2a(va_arg(va, long int),bf); - else -#endif - i2a(va_arg(va, int),bf); - putchw(putp,putf,w,lz,bf); - break; - } - case 'x': case 'X' : -#ifdef PRINTF_LONG_LONG_SUPPORT - if (lnglng) - ulli2a(va_arg(va, unsigned long long int),16,(ch=='X'),bf); - else -#endif -#ifdef PRINTF_LONG_SUPPORT - if (lng) - uli2a(va_arg(va, unsigned long int),16,(ch=='X'),bf); - else -#endif - ui2a(va_arg(va, unsigned int),16,(ch=='X'),bf); - putchw(putp,putf,w,lz,bf); - break; - case 'c' : - putf(putp,(char)(va_arg(va, int))); - break; - case 's' : - putchw(putp,putf,w,0,va_arg(va, char*)); - break; - case '%' : - putf(putp,ch); - default: - break; - } - } - } - abort:; - } - - -void init_printf(void* putp,void (*putf) (void*,char)) - { - stdout_putf=putf; - stdout_putp=putp; - } - -void tfp_printf(char *fmt, ...) - { - va_list va; - va_start(va,fmt); - tfp_format(stdout_putp,stdout_putf,fmt,va); - va_end(va); - } - -static void putcp(void* p,char c) - { - *(*((char**)p))++ = c; - } - - - -void tfp_sprintf(char* s,char *fmt, ...) - { - va_list va; - va_start(va,fmt); - tfp_format(&s,putcp,fmt,va); - putcp(&s,0); - va_end(va); - } diff --git a/firmware/x300/lib/u3_net_stack.c b/firmware/x300/lib/u3_net_stack.c deleted file mode 100644 index 6b8ef096c..000000000 --- a/firmware/x300/lib/u3_net_stack.c +++ /dev/null @@ -1,589 +0,0 @@ - -// Copyright 2012-2013 Ettus Research LLC - -#include <u3_net_stack.h> -#include <string.h> //memcmp -#include <printf.h> - -#define MAX_NETHS 4 - -typedef struct -{ - padded_eth_hdr_t eth; - struct arp_eth_ipv4 arp; -} padded_arp_t; - -typedef struct -{ - padded_eth_hdr_t eth; - struct ip_hdr ip; - struct icmp_echo_hdr icmp; -} padded_icmp_t; - -typedef struct -{ - padded_eth_hdr_t eth; - struct ip_hdr ip; - struct udp_hdr udp; -} padded_udp_t; - -/*********************************************************************** - * declares for internal handlers - **********************************************************************/ -static void handle_icmp_echo_packet( - const uint8_t ethno, - const struct ip_addr *src, const struct ip_addr *dst, - const uint16_t id, const uint16_t seq, - const void *buff, const size_t num_bytes -){ - u3_net_stack_send_icmp_pkt(ethno, ICMP_ER, 0, id, seq, src, buff, num_bytes); -} - -static void handle_icmp_dur_packet( - const uint8_t ethno, - const struct ip_addr *src, const struct ip_addr *dst, - const uint16_t id, const uint16_t seq, - const void *buff, const size_t num_bytes -); - -/*********************************************************************** - * 16-bit one's complement sum - **********************************************************************/ -static uint32_t chksum_buffer( - uint16_t *buf, size_t nshorts, - uint32_t initial_chksum -){ - uint32_t chksum = initial_chksum; - for (size_t i = 0; i < nshorts; i++) chksum += buf[i]; - - while (chksum >> 16) chksum = (chksum & 0xffff) + (chksum >> 16); - - return chksum; -} - -/*********************************************************************** - * ARP Cache implementation - **********************************************************************/ -#define ARP_CACHE_NENTRIES 32 - -static size_t arp_cache_wr_index; - -static struct ip_addr arp_cache_ips[ARP_CACHE_NENTRIES]; -static eth_mac_addr_t arp_cache_macs[ARP_CACHE_NENTRIES]; -static uint8_t arp_cache_eths[ARP_CACHE_NENTRIES]; - -void u3_net_stack_arp_cache_update(const struct ip_addr *ip_addr, const eth_mac_addr_t *mac_addr, const uint8_t ethno) -{ - for (size_t i = 0; i < ARP_CACHE_NENTRIES; i++) - { - if (memcmp(ip_addr, arp_cache_ips+i, sizeof(struct ip_addr)) == 0) - { - memcpy(arp_cache_macs+i, mac_addr, sizeof(eth_mac_addr_t)); - arp_cache_eths[i] = ethno; - return; - } - } - if (arp_cache_wr_index >= ARP_CACHE_NENTRIES) arp_cache_wr_index = 0; - memcpy(arp_cache_ips+arp_cache_wr_index, ip_addr, sizeof(struct ip_addr)); - memcpy(arp_cache_macs+arp_cache_wr_index, mac_addr, sizeof(eth_mac_addr_t)); - arp_cache_eths[arp_cache_wr_index] = ethno; - arp_cache_wr_index++; -} - -const eth_mac_addr_t *u3_net_stack_arp_cache_lookup(const struct ip_addr *ip_addr) -{ - //do a local look up on our own ports - for (size_t e = 0; e < MAX_NETHS; e++) - { - if (memcmp(ip_addr, u3_net_stack_get_ip_addr(e), sizeof(struct ip_addr)) == 0) - { - return u3_net_stack_get_mac_addr(e); - } - } - //now check the arp cache - for (size_t i = 0; i < ARP_CACHE_NENTRIES; i++) - { - if (memcmp(ip_addr, arp_cache_ips+i, sizeof(struct ip_addr)) == 0) - { - return &arp_cache_macs[i]; - } - } - return NULL; -} - -bool resolve_ip(const struct ip_addr *ip_addr, eth_mac_addr_t *mac_addr) -{ - for (size_t e = 0; e < MAX_NETHS; e++) - { - if (memcmp(u3_net_stack_get_bcast(e), ip_addr, sizeof(struct ip_addr)) == 0) - { - memset(mac_addr, 0xff, sizeof(eth_mac_addr_t)); - return true; - } - } - const eth_mac_addr_t *r = u3_net_stack_arp_cache_lookup(ip_addr); - if (r != NULL) - { - memcpy(mac_addr, r, sizeof(eth_mac_addr_t)); - return true; - } - return false; -} - -/*********************************************************************** - * Net stack config - **********************************************************************/ -static wb_pkt_iface64_config_t *pkt_iface_config = NULL; - -void u3_net_stack_init(wb_pkt_iface64_config_t *config) -{ - pkt_iface_config = config; - u3_net_stack_register_icmp_handler(ICMP_ECHO, 0, &handle_icmp_echo_packet); - u3_net_stack_register_icmp_handler(ICMP_DUR, ICMP_DUR_PORT, &handle_icmp_dur_packet); -} - -static struct ip_addr net_conf_ips[MAX_NETHS]; -static eth_mac_addr_t net_conf_macs[MAX_NETHS]; -static struct ip_addr net_conf_subnets[MAX_NETHS]; -static struct ip_addr net_conf_bcasts[MAX_NETHS]; -static uint32_t net_stat_counts[MAX_NETHS]; - -void u3_net_stack_init_eth( - const uint8_t ethno, - const eth_mac_addr_t *mac, - const struct ip_addr *ip, - const struct ip_addr *subnet -) -{ - memcpy(&net_conf_macs[ethno], mac, sizeof(eth_mac_addr_t)); - memcpy(&net_conf_ips[ethno], ip, sizeof(struct ip_addr)); - memcpy(&net_conf_subnets[ethno], subnet, sizeof(struct ip_addr)); - net_stat_counts[ethno] = 0; -} - -const struct ip_addr *u3_net_stack_get_ip_addr(const uint8_t ethno) -{ - return &net_conf_ips[ethno]; -} - -const struct ip_addr *u3_net_stack_get_subnet(const uint8_t ethno) -{ - return &net_conf_subnets[ethno]; -} - -const struct ip_addr *u3_net_stack_get_bcast(const uint8_t ethno) -{ - const uint32_t ip = u3_net_stack_get_ip_addr(ethno)->addr; - const uint32_t subnet = u3_net_stack_get_subnet(ethno)->addr; - net_conf_bcasts[ethno].addr = ip | (~subnet); - return &net_conf_bcasts[ethno]; -} - -const eth_mac_addr_t *u3_net_stack_get_mac_addr(const uint8_t ethno) -{ - return &net_conf_macs[ethno]; -} - -/*********************************************************************** - * Ethernet activity stats - **********************************************************************/ -uint32_t u3_net_stack_get_stat_counts(const uint8_t ethno) -{ - return net_stat_counts[ethno]; -} - -static void incr_stat_counts(const void *p) -{ - const padded_eth_hdr_t *eth = (const padded_eth_hdr_t *)p; - if (eth->ethno < MAX_NETHS) net_stat_counts[eth->ethno]++; -} - -/*********************************************************************** - * Ethernet handlers - send packet w/ payload - **********************************************************************/ -static void send_eth_pkt( - const void *p0, const size_t l0, - const void *p1, const size_t l1, - const void *p2, const size_t l2 -) -{ - incr_stat_counts(p0); - void *ptr = wb_pkt_iface64_tx_claim(pkt_iface_config); - size_t buff_i = 0; - - uint32_t *buff32 = (uint32_t *)ptr; - for (size_t i = 0; i < (l0+3)/4; i++) - { - buff32[buff_i++] = ((const uint32_t *)p0)[i]; - } - for (size_t i = 0; i < (l1+3)/4; i++) - { - buff32[buff_i++] = ((const uint32_t *)p1)[i]; - } - for (size_t i = 0; i < (l2+3)/4; i++) - { - buff32[buff_i++] = ((const uint32_t *)p2)[i]; - } - - // Fixes issue where we don't write an even number of 32bit words leaving last data stranded in H/W. - if ((buff_i%2) == 1) buff32[buff_i++] = 0; - - wb_pkt_iface64_tx_submit(pkt_iface_config, l0 + l1 + l2); -} - -/*********************************************************************** - * ARP handlers - **********************************************************************/ -static void send_arp_reply( - const uint8_t ethno, - const struct arp_eth_ipv4 *req, - const eth_mac_addr_t *our_mac -){ - padded_arp_t reply; - reply.eth.ethno = ethno; - memcpy(&reply.eth.dst, (eth_mac_addr_t *)req->ar_sha, sizeof(eth_mac_addr_t)); - memcpy(&reply.eth.src, u3_net_stack_get_mac_addr(ethno), sizeof(eth_mac_addr_t)); - reply.eth.ethertype = ETHERTYPE_ARP; - - reply.arp.ar_hrd = req->ar_hrd; - reply.arp.ar_pro = req->ar_pro; - reply.arp.ar_hln = req->ar_hln; - reply.arp.ar_pln = req->ar_pln; - reply.arp.ar_op = ARPOP_REPLY; - memcpy(reply.arp.ar_sha, our_mac, sizeof(eth_mac_addr_t)); - memcpy(reply.arp.ar_sip, req->ar_tip, sizeof(struct ip_addr)); - memcpy(reply.arp.ar_tha, req->ar_sha, sizeof(eth_mac_addr_t)); - memcpy(reply.arp.ar_tip, req->ar_sip, sizeof(struct ip_addr)); - - send_eth_pkt(&reply, sizeof(reply), NULL, 0, NULL, 0); -} - -void u3_net_stack_send_arp_request(const uint8_t ethno, const struct ip_addr *addr) -{ - padded_arp_t req; - req.eth.ethno = ethno; - memset(&req.eth.dst, 0xff, sizeof(eth_mac_addr_t)); //bcast - memcpy(&req.eth.src, u3_net_stack_get_mac_addr(ethno), sizeof(eth_mac_addr_t)); - req.eth.ethertype = ETHERTYPE_ARP; - - req.arp.ar_hrd = ARPHRD_ETHER; - req.arp.ar_pro = ETHERTYPE_IPV4; - req.arp.ar_hln = sizeof(eth_mac_addr_t); - req.arp.ar_pln = sizeof(struct ip_addr); - req.arp.ar_op = ARPOP_REQUEST; - memcpy(req.arp.ar_sha, u3_net_stack_get_mac_addr(ethno), sizeof(eth_mac_addr_t)); - memcpy(req.arp.ar_sip, u3_net_stack_get_ip_addr(ethno), sizeof(struct ip_addr)); - memset(req.arp.ar_tha, 0x00, sizeof(eth_mac_addr_t)); - memcpy(req.arp.ar_tip, addr, sizeof(struct ip_addr)); - - send_eth_pkt(&req, sizeof(req), NULL, 0, NULL, 0); -} - -static void handle_arp_packet(const uint8_t ethno, const struct arp_eth_ipv4 *p) -{ - //printf("handle_arp_packet\n"); - if (p->ar_hrd != ARPHRD_ETHER - || p->ar_pro != ETHERTYPE_IPV4 - || p->ar_hln != sizeof(eth_mac_addr_t) - || p->ar_pln != sizeof(struct ip_addr)) - return; - - //got an arp reply -- injest it into the arp cache - if (p->ar_op == ARPOP_REPLY) - { - //printf("ARPOP_REPLY\n"); - struct ip_addr ip_addr; - memcpy(&ip_addr, p->ar_sip, sizeof(ip_addr)); - eth_mac_addr_t mac_addr; - memcpy(&mac_addr, p->ar_sha, sizeof(mac_addr)); - u3_net_stack_arp_cache_update(&ip_addr, &mac_addr, ethno); - } - - //got an arp request -- reply if its for our address - if (p->ar_op == ARPOP_REQUEST) - { - //printf("ARPOP_REQUEST\n"); - if (memcmp(p->ar_tip, u3_net_stack_get_ip_addr(ethno), sizeof(struct ip_addr)) == 0) - { - send_arp_reply(ethno, p, u3_net_stack_get_mac_addr(ethno)); - } - } -} - -/*********************************************************************** - * UDP handlers - **********************************************************************/ -#define UDP_NHANDLERS 16 - -static uint16_t udp_handler_ports[UDP_NHANDLERS]; -static u3_net_stack_udp_handler_t udp_handlers[UDP_NHANDLERS]; -static size_t udp_handlers_index = 0; - -void u3_net_stack_register_udp_handler( - const uint16_t port, - const u3_net_stack_udp_handler_t handler -) -{ - if (udp_handlers_index < UDP_NHANDLERS) - { - udp_handler_ports[udp_handlers_index] = port; - udp_handlers[udp_handlers_index] = handler; - udp_handlers_index++; - } -} - -void u3_net_stack_send_udp_pkt( - const uint8_t ethno, - const struct ip_addr *dst, - const uint16_t src_port, - const uint16_t dst_port, - const void *buff, - const size_t num_bytes -) -{ - eth_mac_addr_t dst_mac_addr; - if (!resolve_ip(dst, &dst_mac_addr)) - { - printf("u3_net_stack_send_udp_pkt arp_cache_lookup fail\n"); - return; - } - - padded_udp_t pkt; - - pkt.eth.ethno = ethno; - memcpy(&pkt.eth.dst, &dst_mac_addr, sizeof(eth_mac_addr_t)); - memcpy(&pkt.eth.src, u3_net_stack_get_mac_addr(ethno), sizeof(eth_mac_addr_t)); - pkt.eth.ethertype = ETHERTYPE_IPV4; - - IPH_VHLTOS_SET(&pkt.ip, 4, 5, 0); - IPH_LEN_SET(&pkt.ip, IP_HLEN + UDP_HLEN + num_bytes); - IPH_ID_SET(&pkt.ip, 0); - IPH_OFFSET_SET(&pkt.ip, IP_DF); /* don't fragment */ - IPH_TTL_SET(&pkt.ip, 32); - IPH_PROTO_SET(&pkt.ip, IP_PROTO_UDP); - IPH_CHKSUM_SET(&pkt.ip, 0); - memcpy(&pkt.ip.src, u3_net_stack_get_ip_addr(ethno), sizeof(struct ip_addr)); - memcpy(&pkt.ip.dest, dst, sizeof(struct ip_addr)); - - IPH_CHKSUM_SET(&pkt.ip, ~chksum_buffer( - (unsigned short *) &pkt.ip, sizeof(pkt.ip)/sizeof(short), 0 - )); - - pkt.udp.src = src_port; - pkt.udp.dest = dst_port; - pkt.udp.len = UDP_HLEN + num_bytes; - pkt.udp.chksum = 0; - - send_eth_pkt(&pkt, sizeof(pkt), buff, num_bytes, NULL, 0); -} - -static void handle_udp_packet( - const uint8_t ethno, - const struct ip_addr *src, - const struct ip_addr *dst, - const struct udp_hdr *udp, - const size_t num_bytes -){ - for (size_t i = 0; i < udp_handlers_index; i++) - { - if (udp_handler_ports[i] == udp->dest) - { - udp_handlers[i]( - ethno, src, u3_net_stack_get_ip_addr(ethno), udp->src, udp->dest, - ((const uint8_t *)udp) + sizeof(struct udp_hdr), - num_bytes - UDP_HLEN - ); - return; - } - } - printf("Unhandled UDP packet src=%u, dest=%u\n", udp->src, udp->dest); - //TODO send destination unreachable -} - -/*********************************************************************** - * ICMP handlers - **********************************************************************/ -#define ICMP_NHANDLERS 8 - -static uint8_t icmp_handler_types[ICMP_NHANDLERS]; -static uint8_t icmp_handler_codes[ICMP_NHANDLERS]; -static u3_net_stack_icmp_handler_t icmp_handlers[ICMP_NHANDLERS]; -static size_t icmp_handlers_index = 0; - -void u3_net_stack_register_icmp_handler( - const uint8_t type, - const uint8_t code, - const u3_net_stack_icmp_handler_t handler -) -{ - if (icmp_handlers_index < ICMP_NHANDLERS) - { - icmp_handler_types[icmp_handlers_index] = type; - icmp_handler_codes[icmp_handlers_index] = code; - icmp_handlers[icmp_handlers_index] = handler; - icmp_handlers_index++; - } -} - -static void handle_icmp_packet( - const uint8_t ethno, - const struct ip_addr *src, - const struct ip_addr *dst, - const struct icmp_echo_hdr *icmp, - const size_t num_bytes -){ - - for (size_t i = 0; i < icmp_handlers_index; i++) - { - if (icmp_handler_types[i] == icmp->type && icmp_handler_codes[i] == icmp->code) - { - icmp_handlers[i]( - ethno, src, u3_net_stack_get_ip_addr(ethno), icmp->id, icmp->seqno, - ((const uint8_t *)icmp) + sizeof(struct icmp_echo_hdr), - num_bytes - sizeof(struct icmp_echo_hdr) - ); - return; - } - } - printf("Unhandled ICMP packet type=%u\n", icmp->type); -} - -static void handle_icmp_dur_packet( - const uint8_t ethno, - const struct ip_addr *src, const struct ip_addr *dst, - const uint16_t id, const uint16_t seq, - const void *buff, const size_t num_bytes -){ - struct ip_hdr *ip = (struct ip_hdr *)buff; - struct udp_hdr *udp = (struct udp_hdr *)(((char *)ip) + IP_HLEN); - if (IPH_PROTO(ip) != IP_PROTO_UDP) return; - for (size_t i = 0; i < udp_handlers_index; i++) - { - if (udp_handler_ports[i] == udp->src) - { - udp_handlers[i](ethno, - src, u3_net_stack_get_ip_addr(ethno), - udp->src, udp->dest, NULL, 0 - ); - return; - } - } -} - -void u3_net_stack_send_icmp_pkt( - const uint8_t ethno, - const uint8_t type, - const uint8_t code, - const uint16_t id, - const uint16_t seq, - const struct ip_addr *dst, - const void *buff, - const size_t num_bytes -) -{ - eth_mac_addr_t dst_mac_addr; - if (!resolve_ip(dst, &dst_mac_addr)) - { - printf("u3_net_stack_send_echo_request arp_cache_lookup fail\n"); - return; - } - - padded_icmp_t pkt; - - pkt.eth.ethno = ethno; - memcpy(&pkt.eth.dst, &dst_mac_addr, sizeof(eth_mac_addr_t)); - memcpy(&pkt.eth.src, u3_net_stack_get_mac_addr(ethno), sizeof(eth_mac_addr_t)); - pkt.eth.ethertype = ETHERTYPE_IPV4; - - IPH_VHLTOS_SET(&pkt.ip, 4, 5, 0); - IPH_LEN_SET(&pkt.ip, IP_HLEN + sizeof(pkt.icmp) + num_bytes); - IPH_ID_SET(&pkt.ip, 0); - IPH_OFFSET_SET(&pkt.ip, IP_DF); /* don't fragment */ - IPH_TTL_SET(&pkt.ip, 32); - IPH_PROTO_SET(&pkt.ip, IP_PROTO_ICMP); - IPH_CHKSUM_SET(&pkt.ip, 0); - memcpy(&pkt.ip.src, u3_net_stack_get_ip_addr(ethno), sizeof(struct ip_addr)); - memcpy(&pkt.ip.dest, dst, sizeof(struct ip_addr)); - - IPH_CHKSUM_SET(&pkt.ip, ~chksum_buffer( - (unsigned short *) &pkt.ip, sizeof(pkt.ip)/sizeof(short), 0 - )); - - pkt.icmp.type = type; - pkt.icmp.code = code; - pkt.icmp.chksum = 0; - pkt.icmp.id = id; - pkt.icmp.seqno = seq; - pkt.icmp.chksum = ~chksum_buffer( //data checksum - (unsigned short *)buff, - num_bytes/sizeof(short), - chksum_buffer( //header checksum - (unsigned short *)&pkt.icmp, - sizeof(pkt.icmp)/sizeof(short), - 0) - ); - - send_eth_pkt(&pkt, sizeof(pkt), buff, num_bytes, NULL, 0); -} - -/*********************************************************************** - * Ethernet handlers - **********************************************************************/ -static void handle_eth_packet(const void *buff, const size_t num_bytes) -{ - const padded_eth_hdr_t *eth_hdr = (padded_eth_hdr_t *)buff; - const uint8_t *eth_body = ((const uint8_t *)buff) + sizeof(padded_eth_hdr_t); - //printf("handle_eth_packet got ethertype 0x%x\n", (unsigned)eth_hdr->ethertype); - - if (eth_hdr->ethertype == ETHERTYPE_ARP) - { - //printf("eth_hdr->ethertype == ETHERTYPE_ARP\n"); - const struct arp_eth_ipv4 *arp = (const struct arp_eth_ipv4 *)eth_body; - handle_arp_packet(eth_hdr->ethno, arp); - } - else if (eth_hdr->ethertype == ETHERTYPE_IPV4) - { - //printf("eth_hdr->ethertype == ETHERTYPE_IPV4\n"); - const struct ip_hdr *ip = (const struct ip_hdr *)eth_body; - const uint8_t *ip_body = eth_body + IP_HLEN; - - if (IPH_V(ip) != 4 || IPH_HL(ip) != 5) return;// ignore pkts w/ bad version or options - if (IPH_OFFSET(ip) & (IP_MF | IP_OFFMASK)) return;// ignore fragmented packets - - //TODO -- only handle when the mac is bcast or IP is for us - - u3_net_stack_arp_cache_update(&ip->src, ð_hdr->src, eth_hdr->ethno); - - if (IPH_PROTO(ip) == IP_PROTO_UDP) - { - handle_udp_packet( - eth_hdr->ethno, &ip->src, &ip->dest, - (const struct udp_hdr *)ip_body, - IPH_LEN(ip) - IP_HLEN - ); - } - - if (IPH_PROTO(ip) == IP_PROTO_ICMP) - { - handle_icmp_packet( - eth_hdr->ethno, &ip->src, &ip->dest, - (const struct icmp_echo_hdr *)ip_body, - IPH_LEN(ip) - IP_HLEN - ); - } - } - else return; // Not ARP or IPV4, ignore -} - -void u3_net_stack_handle_one(void) -{ - size_t num_bytes = 0; - const void *ptr = wb_pkt_iface64_rx_try_claim(pkt_iface_config, &num_bytes); - if (ptr != NULL) - { - //printf("u3_net_stack_handle_one got %u bytes\n", (unsigned)num_bytes); - incr_stat_counts(ptr); - handle_eth_packet(ptr, num_bytes); - wb_pkt_iface64_rx_release(pkt_iface_config); - } -} diff --git a/firmware/x300/lib/udp_uart.c b/firmware/x300/lib/udp_uart.c deleted file mode 100644 index d078aa2c3..000000000 --- a/firmware/x300/lib/udp_uart.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2011-2013 Ettus Research LLC - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <wb_uart.h> -#include <udp_uart.h> -#include <u3_net_stack.h> - -/*********************************************************************** - * Constants - **********************************************************************/ -#define MAX_NUM_UARTS 4 - -static const size_t num_idle_cyc_b4_flush = 22; - -/*********************************************************************** - * Globals - **********************************************************************/ -typedef struct -{ - uint32_t uart_base; - struct ip_addr host_addr; - int host_ethno; - uint16_t host_port; - uint16_t local_port; - __attribute__ ((aligned (16))) uint8_t buf[256]; - size_t len; //length of buffer - size_t cyc; //idle cycle count -} udp_uart_state_t; - -static udp_uart_state_t _states[MAX_NUM_UARTS]; - -static int udp_uart_lookup(const uint16_t port) -{ - for (size_t i = 0; i < MAX_NUM_UARTS; i++) - { - if (_states[i].local_port == port) return i; - } - return -1; -} - -/*********************************************************************** - * UDP handler for UARTs - **********************************************************************/ -static void handle_uart_data_packet( - const uint8_t ethno, - const struct ip_addr *src, const struct ip_addr *dst, - const uint16_t src_port, const uint16_t dst_port, - const void *buff, const size_t num_bytes -){ - //handle ICMP destination unreachable - if (buff == NULL) - { - const size_t which = udp_uart_lookup(src_port); - if (which == -1) return; - _states[which].host_port = 0; - } - - //handle a regular blocking UART write - else - { - const size_t which = udp_uart_lookup(dst_port); - if (which == -1) return; - _states[which].host_ethno = ethno; - _states[which].host_addr = *src; - _states[which].host_port = src_port; - for (size_t i = 0; i < num_bytes; i++) - { - const char ch = ((const char *)buff)[i]; - if (ch == '\n') wb_uart_putc(_states[which].uart_base, (int)'\r'); - wb_uart_putc(_states[which].uart_base, (int)ch); - udp_uart_poll(); - } - } -} - -/*********************************************************************** - * Public init function - **********************************************************************/ -void udp_uart_init(const uint32_t uart_base, const uint16_t udp_port) -{ - for (size_t i = 0; i < MAX_NUM_UARTS; i++) - { - if (_states[i].uart_base != 0) continue; - _states[i].uart_base = uart_base; - _states[i].local_port = udp_port; - _states[i].host_port = 0; //reset to null port - _states[i].len = 0; - _states[i].cyc = 0; - u3_net_stack_register_udp_handler(udp_port, &handle_uart_data_packet); - return; - } -} - -/*********************************************************************** - * Public poll function - **********************************************************************/ -void udp_uart_poll(void) -{ - for (size_t i = 0; i < MAX_NUM_UARTS; i++) - { - if (_states[i].uart_base == 0) continue; - - bool newline = false; - udp_uart_state_t *state = &_states[i]; - - //read all characters we can without blocking - for (size_t j = state->len; j < sizeof(state->buf); j++) - { - int ret = wb_uart_getc(state->uart_base); - if (ret == -1) break; - char ch = (char) ret; - if (ch == '\n' || ch == '\r') newline = true; - state->buf[j] = ch; - state->len++; - state->cyc = 0; //reset idle cycles - } - - //nothing in buffer, continue to next uart - if (state->len == 0) continue; - - //send out a message if newline or forced flush - if (newline || state->cyc++ > num_idle_cyc_b4_flush) - { - if (state->host_port != 0) u3_net_stack_send_udp_pkt( - state->host_ethno, - &state->host_addr, - state->local_port, - state->host_port, - state->buf, state->len - ); - state->len = 0; - state->cyc = 0; - } - } -} diff --git a/firmware/x300/lib/wb_i2c.c b/firmware/x300/lib/wb_i2c.c deleted file mode 100644 index 611908e18..000000000 --- a/firmware/x300/lib/wb_i2c.c +++ /dev/null @@ -1,137 +0,0 @@ - -// Copyright 2012 Ettus Research LLC -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -// NOTE: this driver left shifts a "7bit" I2C address by one bit and puts a R/W bit as bit 0. -// Some devices may specify there I2C address assuming this R/W bit is already in place. - -#include <wb_i2c.h> - -typedef struct { - volatile uint32_t prescaler_lo; // r/w - volatile uint32_t prescaler_hi; // r/w - volatile uint32_t ctrl; // r/w - volatile uint32_t data; // wr = transmit reg; rd = receive reg - volatile uint32_t cmd_status; // wr = command reg; rd = status reg -} i2c_regs_t; - -#define i2c_regs ((i2c_regs_t *) base) - -#define I2C_CTRL_EN (1 << 7) // core enable -#define I2C_CTRL_IE (1 << 6) // interrupt enable - -// -// STA, STO, RD, WR, and IACK bits are cleared automatically -// -#define I2C_CMD_START (1 << 7) // generate (repeated) start condition -#define I2C_CMD_STOP (1 << 6) // generate stop condition -#define I2C_CMD_RD (1 << 5) // read from slave -#define I2C_CMD_WR (1 << 4) // write to slave -#define I2C_CMD_NACK (1 << 3) // when a rcvr, send ACK (ACK=0) or NACK (ACK=1) -#define I2C_CMD_RSVD_2 (1 << 2) // reserved -#define I2C_CMD_RSVD_1 (1 << 1) // reserved -#define I2C_CMD_IACK (1 << 0) // set to clear pending interrupt - -#define I2C_ST_RXACK (1 << 7) // Received acknowledgement from slave (1 = NAK, 0 = ACK) -#define I2C_ST_BUSY (1 << 6) // 1 after START signal detected; 0 after STOP signal detected -#define I2C_ST_AL (1 << 5) // Arbitration lost. 1 when core lost arbitration -#define I2C_ST_RSVD_4 (1 << 4) // reserved -#define I2C_ST_RSVD_3 (1 << 3) // reserved -#define I2C_ST_RSVD_2 (1 << 2) // reserved -#define I2C_ST_TIP (1 << 1) // Transfer-in-progress -#define I2C_ST_IP (1 << 0) // Interrupt pending - -void wb_i2c_init(const uint32_t base, const size_t clk_rate) -{ - // prescaler divisor values for 100 kHz I2C [uses 5 * SCLK internally] - const uint16_t prescaler = (clk_rate/(5 * 400000)) - 1; - i2c_regs->prescaler_lo = prescaler & 0xff; - i2c_regs->prescaler_hi = (prescaler >> 8) & 0xff; - - i2c_regs->ctrl = I2C_CTRL_EN; //| I2C_CTRL_IE; // enable core -} - -static inline void -wait_for_xfer(const uint32_t base) -{ - while (i2c_regs->cmd_status & I2C_ST_TIP) // wait for xfer to complete - ; -} - -static inline bool -wait_chk_ack(const uint32_t base) -{ - wait_for_xfer(base); - - if ((i2c_regs->cmd_status & I2C_ST_RXACK) != 0){ // target NAK'd - return false; - } - return true; -} - -bool wb_i2c_read(const uint32_t base, const uint8_t i2c_addr, uint8_t *buf, size_t len) -{ - if (len == 0) // reading zero bytes always works - return true; - - while (i2c_regs->cmd_status & I2C_ST_BUSY) - ; - - i2c_regs->data = (i2c_addr << 1) | 1; // 7 bit address and read bit (1) - // generate START and write addr - i2c_regs->cmd_status = I2C_CMD_WR | I2C_CMD_START; - if (!wait_chk_ack(base)) - goto fail; - - for (; len > 0; buf++, len--){ - i2c_regs->cmd_status = I2C_CMD_RD | (len == 1 ? (I2C_CMD_NACK | I2C_CMD_STOP) : 0); - wait_for_xfer(base); - *buf = i2c_regs->data; - } - return true; - - fail: - i2c_regs->cmd_status = I2C_CMD_STOP; // generate STOP - return false; -} - -bool wb_i2c_write(const uint32_t base, const uint8_t i2c_addr, const uint8_t *buf, size_t len) -{ - while (i2c_regs->cmd_status & I2C_ST_BUSY) - ; - - i2c_regs->data = (i2c_addr << 1) | 0; // 7 bit address and write bit (0) - - // generate START and write addr (and maybe STOP) - i2c_regs->cmd_status = I2C_CMD_WR | I2C_CMD_START | (len == 0 ? I2C_CMD_STOP : 0); - if (!wait_chk_ack(base)) - goto fail; - - for (; len > 0; buf++, len--){ - i2c_regs->data = *buf; - i2c_regs->cmd_status = I2C_CMD_WR | (len == 1 ? I2C_CMD_STOP : 0); - if (!wait_chk_ack(base)) - goto fail; - } - return true; - - fail: - i2c_regs->cmd_status = I2C_CMD_STOP; // generate STOP - return false; -} - diff --git a/firmware/x300/lib/wb_pkt_iface64.c b/firmware/x300/lib/wb_pkt_iface64.c deleted file mode 100644 index 3c0774bdd..000000000 --- a/firmware/x300/lib/wb_pkt_iface64.c +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2012 Ettus Research LLC - -#include <wb_pkt_iface64.h> -#include <wb_utils.h> -#include <printf.h> - -#define NUM_BYTES_MASK 0x1fff - -static uint32_t get_status(wb_pkt_iface64_config_t *config) -{ - return wb_peek32(config->config_addr); -} - -static void set_control(wb_pkt_iface64_config_t *config) -{ - wb_poke32(config->config_addr, config->ctrl); -} - -wb_pkt_iface64_config_t wb_pkt_iface64_init(const uint32_t base, const size_t ctrl_offset) -{ - wb_pkt_iface64_config_t config; - config.base = base; - config.ctrl = 0; - config.config_addr = base + ctrl_offset; - set_control(&config); - wb_pkt_iface64_rx_release(&config); //always release, in case left in a filled state - return config; -} - -const void *wb_pkt_iface64_rx_try_claim(wb_pkt_iface64_config_t *config, size_t *num_bytes) -{ - const uint32_t status = get_status(config); - const uint32_t rx_state_flag = (status >> 31) & 0x1; - *num_bytes = (status & NUM_BYTES_MASK); - //if (*num_bytes & 0x7) *num_bytes -= 8; //adjust for tuser - if (rx_state_flag == 0) return NULL; - return (void *)config->base; -} - -void wb_pkt_iface64_rx_release(wb_pkt_iface64_config_t *config) -{ - config->ctrl |= 1ul << 31; //does a release - set_control(config); - while (true) - { - const uint32_t status = get_status(config); - const uint32_t rx_state_flag = (status >> 31) & 0x1; - if (rx_state_flag == 0) - { - config->ctrl &= ~(1ul << 31); //allows for next claim - set_control(config); - return; - } - } -} - -void *wb_pkt_iface64_tx_claim(wb_pkt_iface64_config_t *config) -{ - while (true) - { - const uint32_t status = get_status(config); - const uint32_t tx_state_flag = (status >> 30) & 0x1; - if (tx_state_flag == 1) break; - } - return (void *)config->base; -} - -void wb_pkt_iface64_tx_submit(wb_pkt_iface64_config_t *config, size_t num_bytes) -{ - config->ctrl |= (1ul << 30); //allows for next claim - config->ctrl &= ~(NUM_BYTES_MASK); //clear num bytes - if (num_bytes & 0x7) num_bytes += 8; //adjust for tuser - config->ctrl |= num_bytes & NUM_BYTES_MASK; //set num bytes - set_control(config); - - //wait for state machine to transition - while (true) - { - const uint32_t status = get_status(config); - const uint32_t tx_state_flag = (status >> 30) & 0x1; - if (tx_state_flag == 0) break; - } - - config->ctrl &= ~(1ul << 30); //release - set_control(config); - -} diff --git a/firmware/x300/lib/wb_uart.c b/firmware/x300/lib/wb_uart.c deleted file mode 100644 index 368d0e150..000000000 --- a/firmware/x300/lib/wb_uart.c +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2012 Ettus Research LLC - -#include <wb_uart.h> -#include <wb_utils.h> - -localparam SUART_CLKDIV = 0; -localparam SUART_TXLEVEL = 1; -localparam SUART_RXLEVEL = 2; -localparam SUART_TXCHAR = 3; -localparam SUART_RXCHAR = 4; - -void wb_uart_init(const uint32_t base, const size_t div) -{ - wb_poke32(base + SUART_CLKDIV*4, div); -} - -void wb_uart_putc(const uint32_t base, const int ch) -{ - while (wb_peek32(base + SUART_TXLEVEL*4) == 0); - wb_poke32(base + SUART_TXCHAR*4, ch); -} - -bool wb_uart_try_putc(const uint32_t base, const int ch) -{ - if (wb_peek32(base + SUART_TXLEVEL*4) == 0) return false; - wb_poke32(base + SUART_TXCHAR*4, ch); - return true; -} - -int wb_uart_getc(const uint32_t base) -{ - if (wb_peek32(base + SUART_RXLEVEL*4) == 0) return -1; - return wb_peek32(base + SUART_RXCHAR*4); -} |