mpm: comment out functionality to make it work

- add uio udev find routine
 - add debug prints

Signed-off-by: Andrej Rode <andrej.rode@ettus.com>
Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
This commit is contained in:
Andrej Rode 2017-04-11 15:56:25 -07:00 committed by Martin Braun
parent f27cb2a771
commit 7f71111988
6 changed files with 142 additions and 57 deletions

View File

@ -24,6 +24,7 @@ SET(USRP_MPM_TOP_FILES
${CMAKE_CURRENT_SOURCE_DIR}/types.py
${CMAKE_CURRENT_SOURCE_DIR}/discovery.py
${CMAKE_CURRENT_SOURCE_DIR}/rpc_server.py
${CMAKE_CURRENT_SOURCE_DIR}/uio.py
)
LIST(APPEND USRP_MPM_FILES ${USRP_MPM_TOP_FILES})
ADD_SUBDIRECTORY(periph_manager)

View File

@ -21,7 +21,7 @@ Mboard implementation base class
import os
from ..types import EEPROM
from .. import dboard_manager
from .udev import get_eeprom
from .udev import get_eeprom_path
from .udev import get_spidev_nodes
from six import iteritems
@ -44,17 +44,20 @@ class PeriphManagerBase(object):
dboard_eeprom_addrs = {}
dboard_spimaster_addrs = {}
updateable_components = []
sid_endpoints = {}
available_endpoints = range(256)
def __init__(self):
# I know my EEPROM address, lets use it
self.overlays = ""
(self._eeprom_head, self._eeprom_rawdata) = EEPROM().read_eeprom(
get_eeprom(self.mboard_eeprom_addr))
get_eeprom_path(self.mboard_eeprom_addr))
print self._eeprom_head
self._dboard_eeproms = {}
for dboard_slot, eeprom_addr in self.dboard_eeprom_addrs.iteritems():
spi_devices = []
# I know EEPROM adresses for my dboard slots
eeprom_data = EEPROM().read_eeprom(get_eeprom(eeprom_addr))
eeprom_data = EEPROM().read_eeprom(get_eeprom_path(eeprom_addr))
# I know spidev masters on the dboard slots
hw_pid = eeprom_data[0].get("hw_pid", 0)
if hw_pid in dboard_manager.HW_PIDS:
@ -116,7 +119,7 @@ class PeriphManagerBase(object):
# Init dboards
pass
def _probe_interface(self, sender_addr):
def _allocate_sid(self, sender_addr, sid, xbar_src_addr, xbar_src_port):
"""
Overload this method in actual device implementation
"""
@ -127,4 +130,3 @@ class PeriphManagerBase(object):
Overload this method in actual device implementation
"""
return []

View File

@ -23,7 +23,13 @@ from .base import PeriphManagerBase
from .net import get_iface_addrs
from .net import byte_to_mac
from .net import get_mac_addr
from .udev import get_uio_node
from ..types import SID
from ..uio import uio
from .. import libpyusrp_periphs as lib
from logging import getLogger
import netaddr
import socket
LOG = getLogger(__name__)
@ -34,9 +40,9 @@ class n310(PeriphManagerBase):
"""
hw_pids = "1"
mboard_type = "n310"
mboard_eeprom_addr = "e0007000.spi:ec@0:i2c-tunnel"
dboard_eeprom_addrs = {"A": "something", "B": "else"}
dboard_spimaster_addrs = {"A": "something", "B": "else"}
mboard_eeprom_addr = "e0005000.i2c"
# dboard_eeprom_addrs = {"A": "something", "B": "else"}
# dboard_spimaster_addrs = {"A": "something", "B": "else"}
interfaces = {}
def __init__(self, *args, **kwargs):
@ -44,21 +50,22 @@ class n310(PeriphManagerBase):
super(n310, self).__init__(*args, **kwargs)
data = self._read_eeprom_v1(self._eeprom_rawdata)
# mac 0: mgmt port, mac1: sfp0, mac2: sfp1
self.interfaces["mgmt"] = {
"mac_addr": byte_to_mac(data[0]),
"addrs": get_iface_addrs(byte_to_mac(data[0]))
}
self.interfaces["sfp0"] = {
"mac_addr": byte_to_mac(data[1]),
"addrs": get_iface_addrs(byte_to_mac(data[1]))
}
self.interfaces["sfp1"] = {
"mac_addr": byte_to_mac(data[2]),
"addrs": get_iface_addrs(byte_to_mac(data[2]))
}
self.mboard_info["serial"] = data[3] # some format
# self.interfaces["mgmt"] = {
# "mac_addr": byte_to_mac(data[0]),
# "addrs": get_iface_addrs(byte_to_mac(data[0]))
# }
# self.interfaces["sfp0"] = {
# "mac_addr": byte_to_mac(data[1]),
# "addrs": get_iface_addrs(byte_to_mac(data[1]))
# }
# self.interfaces["sfp1"] = {
# "mac_addr": byte_to_mac(data[2]),
# "addrs": get_iface_addrs(byte_to_mac(data[2]))
# }
self.mboard_info["serial"] = data[0] # some format
with open("/sys/class/rfnoc_crossbar/crossbar0/local_addr", "w") as xbar:
xbar.write("0x2")
print(data)
# if header.get("dataversion", 0) == 1:
@ -66,15 +73,17 @@ class n310(PeriphManagerBase):
"""
read eeprom with data version 1
"""
# data_version contains
# data contains
# 24 bytes header -> ignore them here
# 8 bytes serial
# 6 bytes mac_addr0
# 2 bytes pad
# 6 bytes mac_addr1
# 2 bytes pad
# 6 bytes mac_addr2
# 2 bytes pad
# 8 bytes serial
return struct.unpack_from("6s 2x 6s 2x 6s 2x 8s", data)
# 4 bytes CRC
return struct.unpack_from("!28x 8s 6s 2x 6s 2x 6s 2x I", data)
def get_interfaces(self):
"""
@ -89,15 +98,40 @@ class n310(PeriphManagerBase):
"""
return self.interfaces.get(interface, {}).get("addrs", [])
def _probe_interface(self, sender_addr):
def _allocate_sid(self, sender_addr, port, sid, xbar_src_addr, xbar_src_port):
"""
Get the MAC address of the sender and store it in the FPGA ARP table
"""
mac_addr = get_mac_addr(sender_addr)
new_ep = self.available_endpoints.pop(0)
if mac_addr is not None:
# Do something with mac_address
return True
return False
if sender_addr not in self.sid_endpoints:
self.sid_endpoints.update({sender_addr: (new_ep,)})
else:
current_allocation = self.sid_endpoints.get(sender_addr)
new_allocation = current_allocation + (new_ep,)
self.sid_endpoints.update({sender_addr: new_allocation})
sid = SID(sid)
sid.set_src_addr(xbar_src_addr)
sid.set_src_ep(new_ep)
my_xbar = lib.xbar.xbar.make("/dev/crossbar0") # TODO
my_xbar.set_route(xbar_src_addr, 0) # TODO
# uio_path, uio_size = get_uio_node("misc-enet-regs0")
uio_path = "/dev/uio0"
uio_size = 0x2000
LOG.debug("got uio_path and size")
uio_obj = uio(uio_path, uio_size, read_only=False)
LOG.info("got my uio")
LOG.info("ip_addr: %s", sender_addr)
# LOG.info("mac_addr: %s", mac_addr)
ip_addr = int(netaddr.IPAddress(sender_addr))
mac_addr = int(netaddr.EUI(mac_addr))
uio_obj.poke32(0x1000 + 4*new_ep, ip_addr)
print("sid: %x" % (sid.get()))
print("gonna poke: %x %x" % (0x1000+4*new_ep, ip_addr))
uio_obj.poke32(0x1800 + 4*new_ep, mac_addr & 0xFFFFFFFF)
print("gonna poke: %x %x" % (0x1800+4*new_ep, mac_addr))
port = int(port)
uio_obj.poke32(0x1400 + 4*new_ep, ((int(port) << 16) | (mac_addr >> 32)))
print("gonna poke: %x %x" % (0x1400+4*new_ep, ((port << 16) | (mac_addr >> 32))))
return sid.get()

View File

@ -16,19 +16,22 @@
#
import pyudev
import os
from logging import getLogger
LOG = getLogger(__name__)
def get_eeprom(address):
def get_eeprom_path(address):
"""
Return EEPROM device path for a given I2C address
"""
context = pyudev.Context()
parent = pyudev.Device.from_name(context, "platform", address)
paths = [device.dev_node if device.dev_node is not None else device.sys_path
paths = [device.device_node if device.device_node is not None else device.sys_path
for device in context.list_devices(parent=parent, subsystem="nvmem")]
if len(paths) != 1:
raise Exception("{0} paths to EEPROM found!".format(len(paths)))
return paths[0]
return paths[0] + "/nvmem"
def get_spidev_nodes(spi_master):
@ -37,6 +40,30 @@ def get_spidev_nodes(spi_master):
"""
context = pyudev.Context()
parent = pyudev.Device.from_name(context, "platform", spi_master)
paths = [device.dev_node if device.dev_node is not None else device.sys_path
paths = [device.sys_path
for device in context.list_devices(parent=parent, subsystem="spidev")]
return paths
def get_uio_node(uio_name):
"""
Return found uio device path for a give parent name
"""
context = pyudev.Context()
paths = [device.sys_path
for device in context.list_devices(subsystem="uio")]
LOG.debug("get_uio_node")
LOG.debug("got paths: %s", paths)
for path in paths:
with open(os.path.join(path, "maps", "map0", "name"), "r") as uio_file:
name = uio_file.read()
LOG.debug("uio_node name: %s", name.strip())
if name.strip() == uio_name:
with open(os.path.join(path, "maps", "map0", "size"), "r") as uio_file:
size = uio_file.read()
LOG.debug("uio_node size: %s", size.strip())
LOG.debug("uio_node syspath: %s", path)
# device = pyudev.Device.from_sys_path(context, path)
LOG.debug("got udev device")
LOG.debug("device_node: %s size: %s", "/dev/uio0", size.strip())
return ("/dev/uio0", int(size.strip()))
return ("", 0)

View File

@ -185,20 +185,18 @@ class MPMServer(RPCServer):
This is as safe method which can be called without a claim on the device
"""
info = self.periph_manager._get_device_info()
if self.host in ["127.0.0.1", "::1"]:
if self.client_host in ["127.0.0.1", "::1"]:
info["connection"] = "local"
else:
info["connection"] = "remote"
return info
def probe_interface(self, token):
def allocate_sid(self, token, *args):
"""
Forwards the call to periph_manager._probe_interface with the client ip addresss
as argument. Should be used to probe the data interfaces on the device
Forwards the call to periph_manager._allocate_sid with the client ip addresss
as argument. Should be used to setup interfaces
"""
if token[:256] != self._state.claim_token.value:
return False
return self.periph_manager._probe_interface(self.host)
return self.periph_manager._allocate_sid(self.client_host, *args)

View File

@ -45,35 +45,58 @@ class SharedState(object):
lock=self.lock) # String with max length of 256
class SID(object):
def __init__(self, sid=0):
self.src_addr = sid >> 24
self.src_ep = (sid >> 16) & 0xFF
self.dst_addr = (sid >> 8) & 0xFF
self.dst_ep = sid & 0xFF
def set_src_addr(self, new_addr):
self.src_addr = new_addr & 0xFF
def set_dst_addr(self, new_addr):
self.dst_addr = new_addr & 0xFF
def set_src_ep(self, new_addr):
self.src_ep = new_addr & 0xFF
def set_dst_ep(self, new_addr):
self.dst_ep = new_addr & 0xFF
def get(self):
return (self.src_addr << 24) | (self.src_ep << 16) | (self.dst_addr << 8) | self.dst_ep
class EEPROM(object):
"""
Reads out common properties and rawdata out of a nvmem path
"""
# eeprom_header contains:
# 4 bytes magic
# 4 bytes CRC
# 2 bytes data_version
# 4 bytes version
# 4x4 bytes mcu_flags -> throw them away
# 2 bytes hw_pid
# 2 bytes hw_rev
# 2 bytes pad
#
# 16 bytes in total
eeprom_header = struct.Struct("I I H H H 2x")
# 28 bytes in total
eeprom_header = struct.Struct("!I I 16x H H")
def read_eeprom(self, nvmem_path):
"""
Read the EEPROM located at nvmem_path and return a tuple (header, body)
Read the EEPROM located at nvmem_path and return a tuple (header, data)
Header is already parsed in the common header fields
Data contains the full eeprom data structure
"""
with open(nvmem_path, "rb") as nvmem_file:
header = nvmem_file.read(16)
data = nvmem_file.read(240)
header = self.eeprom_header.unpack(header)
data = nvmem_file.read(256)
_header = self.eeprom_header.unpack_from(data)
print hex(_header[0]), hex(_header[1]), hex(_header[2]), hex(_header[3])
header = {
"magic": header[0],
"crc": header[1],
"data_version": header[2],
"hw_pid": header[3],
"hw_rev": header[4],
"magic": _header[0],
"version": _header[1],
"hw_pid": _header[2],
"hw_rev": _header[3],
}
print header
return (header, data)