summaryrefslogtreecommitdiffstats
path: root/firmware/zpu
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2012-02-24 16:56:31 -0800
committerJosh Blum <josh@joshknows.com>2012-03-23 14:36:21 -0700
commite4d3f63ce0bb04287a61e9547acfa02a50e84326 (patch)
tree7e52abd987a51a50d2f5f0f7707c435104ae08ba /firmware/zpu
parentea19de0ba230b738a102d4ebb089614bd3ca2fa0 (diff)
downloaduhd-e4d3f63ce0bb04287a61e9547acfa02a50e84326.tar.gz
uhd-e4d3f63ce0bb04287a61e9547acfa02a50e84326.tar.bz2
uhd-e4d3f63ce0bb04287a61e9547acfa02a50e84326.zip
usrp2: work on alternative stream destination
Diffstat (limited to 'firmware/zpu')
-rw-r--r--firmware/zpu/apps/txrx_uhd.c35
-rw-r--r--firmware/zpu/lib/eth_addrs.c132
-rw-r--r--firmware/zpu/lib/ethernet.h21
-rw-r--r--firmware/zpu/lib/net_common.c28
-rw-r--r--firmware/zpu/lib/net_common.h5
-rw-r--r--firmware/zpu/usrp2p/u2p_init.c3
6 files changed, 122 insertions, 102 deletions
diff --git a/firmware/zpu/apps/txrx_uhd.c b/firmware/zpu/apps/txrx_uhd.c
index 9daf441e2..a4bfce0ec 100644
--- a/firmware/zpu/apps/txrx_uhd.c
+++ b/firmware/zpu/apps/txrx_uhd.c
@@ -92,8 +92,35 @@ static void handle_udp_data_packet(
default: return;
}
- eth_mac_addr_t eth_mac_host; arp_cache_lookup_mac(&src.addr, &eth_mac_host);
- setup_framer(eth_mac_host, *ethernet_mac_addr(), src, dst, which);
+ //assume the packet destination is the packet source
+ //the arp cache lookup should never fail for this case
+ const struct socket_address src_addr = dst;
+ struct socket_address dst_addr = src;
+ eth_mac_addr_t eth_mac_dst;
+ arp_cache_lookup_mac(&dst_addr.addr, &eth_mac_dst);
+
+ //however, if this control packet has an alternative destination...
+ if (payload_len >= sizeof(usrp2_stream_ctrl_t)){
+
+ //parse the destination ip addr and udp port from the payload
+ const usrp2_stream_ctrl_t *stream_ctrl = (const usrp2_stream_ctrl_t *)payload;
+ dst_addr.addr.addr = stream_ctrl->ip_addr;
+ dst_addr.port = (uint16_t)stream_ctrl->udp_port;
+ struct ip_addr ip_dest = dst_addr.addr;
+
+ //are we in the subnet? if not use the gateway
+ const uint32_t subnet_mask = get_subnet()->addr;
+ const bool in_subnet = ((get_ip_addr()->addr & subnet_mask) == (ip_dest.addr & subnet_mask));
+ if (!in_subnet) ip_dest = *get_gateway();
+
+ //lookup the host ip address with ARP (this may fail)
+ const bool ok = arp_cache_lookup_mac(&ip_dest, &eth_mac_dst);
+ if (!ok) net_common_send_arp_request(&ip_dest);
+ const uint32_t result = (ok)? 0 : ~0;
+ send_udp_pkt(dst.port, src, &result, sizeof(result));
+ }
+
+ setup_framer(eth_mac_dst, *ethernet_mac_addr(), dst_addr, src_addr, which);
}
#define OTW_GPIO_BANK_TO_NUM(bank) \
@@ -279,6 +306,7 @@ int
main(void)
{
u2_init();
+ arp_cache_init();
#ifdef BOOTLOADER
putstr("\nUSRP N210 UDP bootloader\n");
#else
@@ -294,8 +322,7 @@ main(void)
//load the production FPGA image or firmware if appropriate
do_the_bootload_thing();
//if we get here we've fallen through to safe firmware
- set_default_mac_addr();
- set_default_ip_addr();
+ eth_addrs_set_default();
#endif
print_mac_addr(ethernet_mac_addr()); newline();
diff --git a/firmware/zpu/lib/eth_addrs.c b/firmware/zpu/lib/eth_addrs.c
index c45ce7559..6d3347cf3 100644
--- a/firmware/zpu/lib/eth_addrs.c
+++ b/firmware/zpu/lib/eth_addrs.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2011 Ettus Research LLC
+ * Copyright 2010-2012 Ettus Research LLC
* Copyright 2007 Free Software Foundation, Inc.
*
* This program is free software: you can redistribute it and/or modify
@@ -20,6 +20,7 @@
#include "memory_map.h"
#include "nonstdio.h"
#include <stdbool.h>
+#include <string.h>
#include "i2c.h"
#include "usrp2/fw_common.h"
@@ -37,104 +38,69 @@ unprogrammed(const void *t, size_t len)
return all_ones | all_zeros;
}
-//////////////////// MAC Addr Stuff ///////////////////////
+typedef struct{
+ eth_mac_addr_t mac_addr;
+ struct ip_addr ip_addr;
+ struct ip_addr gateway;
+ struct ip_addr subnet;
+} eth_addrs_t;
-static bool src_mac_addr_initialized = false;
+static bool eth_addrs_initialized = false;
-static const eth_mac_addr_t default_mac_addr = {{
- 0x00, 0x50, 0xC2, 0x85, 0x3f, 0xff
- }};
+static const eth_addrs_t default_eth_addrs = {
+ .mac_addr = {{0x00, 0x50, 0xC2, 0x85, 0x3f, 0xff}},
+ .ip_addr = {(192 << 24 | 168 << 16 | 10 << 8 | 2 << 0)},
+ .gateway = {(192 << 24 | 168 << 16 | 10 << 8 | 1 << 0)},
+ .subnet = {(255 << 24 | 255 << 16 | 255 << 8 | 0 << 0)},
+};
-static eth_mac_addr_t src_mac_addr = {{
- 0x00, 0x50, 0xC2, 0x85, 0x3f, 0xff
- }};
-
-void set_default_mac_addr(void)
-{
- src_mac_addr_initialized = true;
- src_mac_addr = default_mac_addr;
-}
+static eth_addrs_t current_eth_addrs;
-const eth_mac_addr_t *
-ethernet_mac_addr(void)
-{
- if (!src_mac_addr_initialized){ // fetch from eeprom
- src_mac_addr_initialized = true;
+static void eth_addrs_init(void){
+ if (eth_addrs_initialized) return;
+ eth_addrs_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
+ #define eth_addrs_init_x(addr, x){ \
+ const bool ok = eeprom_read(USRP2_I2C_ADDR_MBOARD, addr, &current_eth_addrs.x, sizeof(current_eth_addrs.x)); \
+ if (!ok || unprogrammed(&current_eth_addrs.x, sizeof(current_eth_addrs.x))){ \
+ memcpy(&current_eth_addrs.x, &default_eth_addrs.x, sizeof(current_eth_addrs.x)); \
+ } \
}
- else
- src_mac_addr = tmp;
- }
- return &src_mac_addr;
-}
+ eth_addrs_init_x(USRP2_EE_MBOARD_MAC_ADDR, mac_addr);
+ eth_addrs_init_x(USRP2_EE_MBOARD_IP_ADDR, ip_addr);
+ eth_addrs_init_x(USRP2_EE_MBOARD_GATEWAY, gateway);
+ eth_addrs_init_x(USRP2_EE_MBOARD_SUBNET, subnet);
-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 bool src_ip_addr_initialized = false;
-
-static const struct ip_addr default_ip_addr = {
- (192 << 24 | 168 << 16 | 10 << 8 | 2 << 0)
-};
-
-static struct ip_addr src_ip_addr = {
- (192 << 24 | 168 << 16 | 10 << 8 | 2 << 0)
-};
-
-void set_default_ip_addr(void)
-{
- src_ip_addr_initialized = true;
- src_ip_addr = default_ip_addr;
+const eth_mac_addr_t *ethernet_mac_addr(void){
+ eth_addrs_init();
+ return &current_eth_addrs.mac_addr;
}
-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;
+const struct ip_addr *get_ip_addr(void){
+ eth_addrs_init();
+ return &current_eth_addrs.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;
- }
+const struct ip_addr *get_subnet(void){
+ eth_addrs_init();
+ return &current_eth_addrs.subnet;
+}
- return &src_ip_addr;
+const struct ip_addr *get_gateway(void){
+ eth_addrs_init();
+ return &current_eth_addrs.gateway;
}
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;
- }
+ const bool ok = eeprom_write(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, t, sizeof(struct ip_addr));
+ if (ok) current_eth_addrs.ip_addr = *t;
+ return ok;
+}
- return ok;
+void eth_addrs_set_default(void){
+ eth_addrs_initialized = true;
+ memcpy(&current_eth_addrs, &default_eth_addrs, sizeof(default_eth_addrs));
}
diff --git a/firmware/zpu/lib/ethernet.h b/firmware/zpu/lib/ethernet.h
index 52b297349..b5b08cb8c 100644
--- a/firmware/zpu/lib/ethernet.h
+++ b/firmware/zpu/lib/ethernet.h
@@ -1,5 +1,5 @@
-/* -*- c -*- */
/*
+ * Copyright 2010-2012 Ettus Research LLC
* Copyright 2007 Free Software Foundation, Inc.
*
* This program is free software: you can redistribute it and/or modify
@@ -44,27 +44,28 @@ void ethernet_register_link_changed_callback(ethernet_link_changed_callback_t cb
*/
const eth_mac_addr_t *ethernet_mac_addr(void);
-/*!set mac addr to default*/
-void set_default_mac_addr(void);
-
/*!
- * \brief write mac address to eeprom and begin using it
+ * \returns IP address
*/
-bool ethernet_set_mac_addr(const eth_mac_addr_t *t);
+const struct ip_addr *get_ip_addr(void);
/*!
- * \returns IP address
+ * \returns gateway address
*/
-const struct ip_addr *get_ip_addr(void);
+const struct ip_addr *get_gateway(void);
-/*!set ip addr to default*/
-void set_default_ip_addr(void);
+/*!
+ * \returns subnet address
+ */
+const struct ip_addr *get_subnet(void);
/*!
* \brief write ip address to eeprom and begin using it
*/
bool set_ip_addr(const struct ip_addr *t);
+//! Apply default settings to eth addrs
+void eth_addrs_set_default(void);
/*
* \brief read RMON regs and return error mask
diff --git a/firmware/zpu/lib/net_common.c b/firmware/zpu/lib/net_common.c
index 42e365393..9b75006d3 100644
--- a/firmware/zpu/lib/net_common.c
+++ b/firmware/zpu/lib/net_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2011 Ettus Research LLC
+ * Copyright 2009-2012 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
@@ -374,6 +374,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 net_common_send_arp_request(const struct ip_addr *addr){
+ 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, addr, sizeof(struct ip_addr));
+
+ //send the request with a broadcast ethernet mac address
+ send_pkt(BCAST_MAC_ADDR, ETHERTYPE_ARP, &req, sizeof(req), 0, 0, 0, 0);
+}
+
void send_gratuitous_arp(void){
struct arp_eth_ipv4 req _AL4;
req.ar_hrd = ARPHRD_ETHER;
@@ -415,7 +431,15 @@ handle_arp_packet(struct arp_eth_ipv4 *p, size_t size)
|| p->ar_hln != 6
|| p->ar_pln != 4)
return;
-
+
+ if (p->ar_op == ARPOP_REPLY){
+ 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));
+ arp_cache_update(&ip_addr, &mac_addr);
+ }
+
if (p->ar_op != ARPOP_REQUEST)
return;
diff --git a/firmware/zpu/lib/net_common.h b/firmware/zpu/lib/net_common.h
index 3cbc5c514..5e6daf689 100644
--- a/firmware/zpu/lib/net_common.h
+++ b/firmware/zpu/lib/net_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2011 Ettus Research LLC
+ * Copyright 2009-2012 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
@@ -55,4 +55,7 @@ void handle_eth_packet(uint32_t *p, size_t nlines);
void send_gratuitous_arp(void);
+//! Send an ARP request for the given IP address
+void net_common_send_arp_request(const struct ip_addr *addr);
+
#endif /* INCLUDED_NET_COMMON_H */
diff --git a/firmware/zpu/usrp2p/u2p_init.c b/firmware/zpu/usrp2p/u2p_init.c
index 381987ae6..1890dd726 100644
--- a/firmware/zpu/usrp2p/u2p_init.c
+++ b/firmware/zpu/usrp2p/u2p_init.c
@@ -24,7 +24,6 @@ void u2p_init(void){
bool safe_fw = find_safe_booted_flag();
set_safe_booted_flag(0);
if (safe_fw) {
- set_default_ip_addr();
- set_default_mac_addr();
+ eth_addrs_set_default();
}
}