diff options
author | Andrej Rode <andrej.rode@ettus.com> | 2017-04-11 15:56:25 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2017-12-22 15:03:45 -0800 |
commit | 7f7111198816cbf1e0597f7ecc9f46e4c26e916b (patch) | |
tree | 7a74ecf77569b07364de278822873d7ce1f82185 | |
parent | f27cb2a7711e428a88c59a5af762055c7f1e3e13 (diff) | |
download | uhd-7f7111198816cbf1e0597f7ecc9f46e4c26e916b.tar.gz uhd-7f7111198816cbf1e0597f7ecc9f46e4c26e916b.tar.bz2 uhd-7f7111198816cbf1e0597f7ecc9f46e4c26e916b.zip |
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>
-rw-r--r-- | mpm/python/usrp_mpm/CMakeLists.txt | 1 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/periph_manager/base.py | 12 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/periph_manager/n310.py | 88 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/periph_manager/udev.py | 35 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/rpc_server.py | 12 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/types.py | 51 |
6 files changed, 142 insertions, 57 deletions
diff --git a/mpm/python/usrp_mpm/CMakeLists.txt b/mpm/python/usrp_mpm/CMakeLists.txt index 1ab48de0a..b401ac6c4 100644 --- a/mpm/python/usrp_mpm/CMakeLists.txt +++ b/mpm/python/usrp_mpm/CMakeLists.txt @@ -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) diff --git a/mpm/python/usrp_mpm/periph_manager/base.py b/mpm/python/usrp_mpm/periph_manager/base.py index c84205a76..77414c034 100644 --- a/mpm/python/usrp_mpm/periph_manager/base.py +++ b/mpm/python/usrp_mpm/periph_manager/base.py @@ -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 [] - diff --git a/mpm/python/usrp_mpm/periph_manager/n310.py b/mpm/python/usrp_mpm/periph_manager/n310.py index 1b01ac066..4f193b54b 100644 --- a/mpm/python/usrp_mpm/periph_manager/n310.py +++ b/mpm/python/usrp_mpm/periph_manager/n310.py @@ -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() diff --git a/mpm/python/usrp_mpm/periph_manager/udev.py b/mpm/python/usrp_mpm/periph_manager/udev.py index 014e18ede..a42c95ef5 100644 --- a/mpm/python/usrp_mpm/periph_manager/udev.py +++ b/mpm/python/usrp_mpm/periph_manager/udev.py @@ -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) diff --git a/mpm/python/usrp_mpm/rpc_server.py b/mpm/python/usrp_mpm/rpc_server.py index f712c5c87..df73b1ab0 100644 --- a/mpm/python/usrp_mpm/rpc_server.py +++ b/mpm/python/usrp_mpm/rpc_server.py @@ -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) diff --git a/mpm/python/usrp_mpm/types.py b/mpm/python/usrp_mpm/types.py index cc8fe8b8d..1fbddb934 100644 --- a/mpm/python/usrp_mpm/types.py +++ b/mpm/python/usrp_mpm/types.py @@ -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) |