aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/microblaze/lib
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/microblaze/lib')
-rw-r--r--firmware/microblaze/lib/Makefile.inc1
-rw-r--r--firmware/microblaze/lib/eth_addrs.c119
-rw-r--r--firmware/microblaze/lib/net_common.c16
-rw-r--r--firmware/microblaze/lib/net_common.h2
4 files changed, 138 insertions, 0 deletions
diff --git a/firmware/microblaze/lib/Makefile.inc b/firmware/microblaze/lib/Makefile.inc
index a576d1ccb..2b5685d3f 100644
--- a/firmware/microblaze/lib/Makefile.inc
+++ b/firmware/microblaze/lib/Makefile.inc
@@ -26,6 +26,7 @@ COMMON_SRCS = \
$(top_srcdir)/lib/clocks.c \
$(top_srcdir)/lib/dbsm.c \
$(top_srcdir)/lib/eeprom.c \
+ $(top_srcdir)/lib/eth_addrs.c \
$(top_srcdir)/lib/eth_mac.c \
$(top_srcdir)/lib/_exit.c \
$(top_srcdir)/lib/exit.c \
diff --git a/firmware/microblaze/lib/eth_addrs.c b/firmware/microblaze/lib/eth_addrs.c
new file mode 100644
index 000000000..d7c1e0394
--- /dev/null
+++ b/firmware/microblaze/lib/eth_addrs.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2010 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/>.
+ */
+
+#include "ethernet.h"
+#include "memory_map.h"
+#include "nonstdio.h"
+#include <stdbool.h>
+#include "i2c.h"
+#include "usrp2/fw_common.h"
+
+static bool
+unprogrammed(const void *t, size_t len)
+{
+ int i;
+ uint8_t *p = (uint8_t *)t;
+ bool all_zeros = true;
+ bool all_ones = true;
+ for (i = 0; i < len; i++){
+ all_zeros &= p[i] == 0x00;
+ all_ones &= p[i] == 0xff;
+ }
+ return all_ones | all_zeros;
+}
+
+//////////////////// MAC Addr Stuff ///////////////////////
+
+static int8_t src_mac_addr_initialized = false;
+static eth_mac_addr_t src_mac_addr = {{
+ 0x00, 0x50, 0xC2, 0x85, 0x3f, 0xff
+ }};
+
+const eth_mac_addr_t *
+ethernet_mac_addr(void)
+{
+ if (!src_mac_addr_initialized){ // fetch from eeprom
+ src_mac_addr_initialized = true;
+
+ // if we're simulating, don't read the EEPROM model, it's REALLY slow
+ if (hwconfig_simulation_p())
+ return &src_mac_addr;
+
+ eth_mac_addr_t tmp;
+ bool ok = eeprom_read(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_MAC_ADDR, &tmp, sizeof(tmp));
+ if (!ok || unprogrammed(&tmp, sizeof(tmp))){
+ // use the default
+ }
+ else
+ src_mac_addr = tmp;
+ }
+
+ return &src_mac_addr;
+}
+
+bool
+ethernet_set_mac_addr(const eth_mac_addr_t *t)
+{
+ bool ok = eeprom_write(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_MAC_ADDR, t, sizeof(eth_mac_addr_t));
+ if (ok){
+ src_mac_addr = *t;
+ src_mac_addr_initialized = true;
+ //eth_mac_set_addr(t); //this breaks the link
+ }
+
+ return ok;
+}
+
+//////////////////// IP Addr Stuff ///////////////////////
+
+static int8_t src_ip_addr_initialized = false;
+static struct ip_addr src_ip_addr = {
+ (192 << 24 | 168 << 16 | 10 << 8 | 2 << 0)
+};
+
+
+const struct ip_addr *get_ip_addr(void)
+{
+ if (!src_ip_addr_initialized){ // fetch from eeprom
+ src_ip_addr_initialized = true;
+
+ // if we're simulating, don't read the EEPROM model, it's REALLY slow
+ if (hwconfig_simulation_p())
+ return &src_ip_addr;
+
+ struct ip_addr tmp;
+ bool ok = eeprom_read(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, &tmp, sizeof(tmp));
+ if (!ok || unprogrammed(&tmp, sizeof(tmp))){
+ // use the default
+ }
+ else
+ src_ip_addr = tmp;
+ }
+
+ return &src_ip_addr;
+}
+
+bool set_ip_addr(const struct ip_addr *t){
+ bool ok = eeprom_write(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, t, sizeof(struct ip_addr));
+ if (ok){
+ src_ip_addr = *t;
+ src_ip_addr_initialized = true;
+ }
+
+ return ok;
+}
diff --git a/firmware/microblaze/lib/net_common.c b/firmware/microblaze/lib/net_common.c
index 6c9509c92..beaaa5948 100644
--- a/firmware/microblaze/lib/net_common.c
+++ b/firmware/microblaze/lib/net_common.c
@@ -351,6 +351,22 @@ send_arp_reply(struct arp_eth_ipv4 *req, eth_mac_addr_t our_mac)
send_pkt(t, ETHERTYPE_ARP, &reply, sizeof(reply), 0, 0, 0, 0);
}
+void send_gratuitous_arp(void){
+ struct arp_eth_ipv4 req _AL4;
+ req.ar_hrd = ARPHRD_ETHER;
+ req.ar_pro = ETHERTYPE_IPV4;
+ req.ar_hln = sizeof(eth_mac_addr_t);
+ req.ar_pln = sizeof(struct ip_addr);
+ req.ar_op = ARPOP_REQUEST;
+ memcpy(req.ar_sha, ethernet_mac_addr(), sizeof(eth_mac_addr_t));
+ memcpy(req.ar_sip, get_ip_addr(), sizeof(struct ip_addr));
+ memset(req.ar_tha, 0x00, sizeof(eth_mac_addr_t));
+ memcpy(req.ar_tip, get_ip_addr(), sizeof(struct ip_addr));
+
+ //send the request with a broadcast ethernet mac address
+ eth_mac_addr_t t; memset(&t, 0xff, sizeof(t));
+ send_pkt(t, ETHERTYPE_ARP, &req, sizeof(req), 0, 0, 0, 0);
+}
static void
handle_arp_packet(struct arp_eth_ipv4 *p, size_t size)
diff --git a/firmware/microblaze/lib/net_common.h b/firmware/microblaze/lib/net_common.h
index 112669b46..3040e5ef3 100644
--- a/firmware/microblaze/lib/net_common.h
+++ b/firmware/microblaze/lib/net_common.h
@@ -47,4 +47,6 @@ void send_udp_pkt(int src_port, struct socket_address dst,
void handle_eth_packet(uint32_t *p, size_t nlines);
+void send_gratuitous_arp(void);
+
#endif /* INCLUDED_NET_COMMON_H */