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 /mpm/python/usrp_mpm | |
| 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>
Diffstat (limited to 'mpm/python/usrp_mpm')
| -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)  | 
