diff options
Diffstat (limited to 'mpm/python/usrp_mpm/periph_manager/base.py')
| -rw-r--r-- | mpm/python/usrp_mpm/periph_manager/base.py | 264 | 
1 files changed, 125 insertions, 139 deletions
| diff --git a/mpm/python/usrp_mpm/periph_manager/base.py b/mpm/python/usrp_mpm/periph_manager/base.py index be7600333..4ae30778a 100644 --- a/mpm/python/usrp_mpm/periph_manager/base.py +++ b/mpm/python/usrp_mpm/periph_manager/base.py @@ -177,7 +177,7 @@ class PeriphManagerBase(object):      ###########################################################################      def __init__(self):          # Note: args is a dictionary. -        assert len(self.pids) > 0 +        assert self.pids          assert self.mboard_eeprom_magic is not None          self.dboards = []          self._default_args = "" @@ -241,14 +241,17 @@ class PeriphManagerBase(object):          If no EEPROM is defined, returns empty values.          """ -        if len(self.mboard_eeprom_addr): +        if self.mboard_eeprom_addr:              self.log.trace("Reading EEPROM from address `{}'..."                             .format(self.mboard_eeprom_addr)) -            if (not get_eeprom_paths(self.mboard_eeprom_addr)): -                raise RuntimeError("No EEPROM found at address `{}'" -                    .format(self.mboard_eeprom_addr)) +            eeprom_paths = get_eeprom_paths(self.mboard_eeprom_addr) +            if not eeprom_paths: +                self.log.error("Could not identify EEPROM paths for %s!", +                               self.mboard_eeprom_addr) +                return {}, b'' +            self.log.trace("Found mboard EEPROM path: %s", eeprom_paths[0])              (eeprom_head, eeprom_rawdata) = eeprom.read_eeprom( -                get_eeprom_paths(self.mboard_eeprom_addr)[0], +                eeprom_paths[0],                  self.mboard_eeprom_offset,                  eeprom.MboardEEPROM.eeprom_header_format,                  eeprom.MboardEEPROM.eeprom_header_keys, @@ -512,6 +515,22 @@ class PeriphManagerBase(object):      ###########################################################################      # Misc device status controls and indicators      ########################################################################### +    def set_device_id(self, device_id): +        """ +        Sets the device ID for this motherboard. +        The device ID is used to identify the RFNoC components associated with +        this motherboard. +        """ +        raise NotImplementedError("set_device_id() not implemented.") + +    def get_device_id(self): +        """ +        Gets the device ID for this motherboard. +        The device ID is used to identify the RFNoC components associated with +        this motherboard. +        """ +        raise NotImplementedError("get_device_id() not implemented.") +      def get_init_status(self):          """          Returns the status of the device after its initialization (that happens @@ -592,6 +611,20 @@ class PeriphManagerBase(object):          """          return [dboard.device_info for dboard in self.dboards] +    @no_claim +    def get_proto_ver(self): +        """ +        Return RFNoC protocol version +        """ +        raise NotImplementedError("get_proto_ver() not implemented.") + +    @no_claim +    def get_chdr_width(self): +        """ +        Return RFNoC CHDR width +        """ +        raise NotImplementedError("get_chdr_width() not implemented.") +      ###########################################################################      # Component updating      ########################################################################### @@ -670,64 +703,10 @@ class PeriphManagerBase(object):              self.log.trace("Component info: {}".format(metadata))              # Convert all values to str              return dict([a, str(x)] for a, x in metadata.items()) -        else: -            self.log.trace("Component not found in updateable components: {}" -                           .format(component_name)) -            return {} - -    ########################################################################### -    # Crossbar control -    ########################################################################### -    @no_claim -    def get_num_xbars(self): -        """ -        Returns the number of crossbars instantiated in the current design -        """ -        return 1 # FIXME - -    @no_claim -    def get_num_blocks(self, xbar_index): -        """ -        Returns the number of blocks connected to crossbar with index -        xbar_index. - -        xbar_index -- The index of the crossbar that's being queried. -        docstring for get_num_blocks""" -        # FIXME udev lookup -        xbar_sysfs_path = '/sys/class/rfnoc_crossbar/crossbar{}/nports'.format( -            xbar_index -        ) -        return int(open(xbar_sysfs_path).read().strip()) - \ -                self.get_base_port(xbar_index) - -    @no_claim -    def get_base_port(self, xbar_index): -        """ -        Returns the index of the first port which is connected to an RFNoC -        block. Example: Assume there are two SFPs connected to the crossbar, and -        one DMA engine for CHDR traffic. The convention would be to connect -        those to ports 0, 1, and 2, respectively. This makes port 3 the first -        block to be connected to an RFNoC block. - -        xbar_index -- The index of the crossbar that's being queried -        """ -        return self.crossbar_base_port - -    def set_xbar_local_addr(self, xbar_index, local_addr): -        """ -        Program crossbar xbar_index to have the local address local_addr. -        """ -        # FIXME udev lookup -        xbar_sysfs_path = '/sys/class/rfnoc_crossbar/crossbar{}/local_addr'.format( -            xbar_index -        ) -        laddr_value = "0x{:X}".format(local_addr) -        self.log.trace("Setting local address for xbar {} to {}.".format( -            xbar_sysfs_path, laddr_value -        )) -        with open(xbar_sysfs_path, "w") as xbar_file: -            xbar_file.write(laddr_value) -        return True +        # else: +        self.log.trace("Component not found in updateable components: {}" +                       .format(component_name)) +        return {}      ##########################################################################      # Mboard Sensors @@ -823,86 +802,44 @@ class PeriphManagerBase(object):      #######################################################################      # Transport API      ####################################################################### -    def request_xport( -            self, -            dst_address, -            suggested_src_address, -            xport_type, -        ): -        """ -        When setting up a CHDR connection, this is the first call to be -        made. This function will return a list of dictionaries, each -        describing a way to open an CHDR connection. The list of dictionaries -        is sorted by preference, meaning that the caller should use the first -        option, if possible. -        All transports requested are bidirectional. - -        The callee must maintain a lock on the available CHDR xports. After -        calling request_xport(), the caller needs to pick one of the -        dictionaries, possibly amend data (e.g., if the connection is an -        Ethernet connection, then we need to know the source port, but more -        details on that in commit_xport()'s documentation). -        One way to implement a lock is to simply lock a mutex here and -        unlock it in commit_xport(), even though there are probably more -        nuanced solutions. +    def get_chdr_link_types(self): +        """ +        Return a list of ways how the UHD session can connect to this device to +        initiate CHDR traffic. -        Arguments: -        dst_sid -- The destination part of the connection, i.e., which -                   RFNoC block are we connecting to. Example: 0x0230 -        suggested_src_sid -- The source part of the connection, i.e., -                             what's the source address of packets going to -                             the destination at dst_sid. This is a -                             suggestion, MPM can override this. Example: -                             0x0001. -        xport_type -- One of the following strings: CTRL, ASYNC_MSG, -                      TX_DATA, RX_DATA. See also xports_type_t in UHD. - -        The return value is a list of dictionaries. Every dictionary has -        the following key/value pairs: -        - type: Type of transport, e.g., "UDP", "liberio". -        - ipv4 (UDP only): IPv4 address to connect to. -        - port (UDP only): IP port to connect to. -        - send_sid: String version of the SID used for this transport. This is -                    the definitive version of the SID, the suggested_src_address -                    can be ignored at this point. -        - allocation: This is an integer value which represents a score of -                      how much bandwidth is used. Note: Currently does not -                      have any unit, is just a counter. Higher numbers mean -                      higher utilization. RX means device to UHD, for -                      example, committing an RX streamer would increase this -                      value. -                      This key is optional, MPM does not have to provide it. -                      If the allocation affects the preference, it will be -                      factored into the order of the results, meaning the -                      caller does not strictly have to check its value even if -                      the transport option with the smallest allocation is -                      preferred. - -        Note: The dictionary may include other keys which should be ignored, -        or at the very least, kept intact. commit_xport() might be requiring -        them. -        """ -        raise NotImplementedError("request_xport() not implemented.") - -    def commit_xport(self, xport_info): -        """ -        When setting up a CHDR connection, this is the second call to be -        made. +        The return value is a list of strings. Every string is a key for a +        transport type. Values include: +        - "udp": Means this device can be reached via UDP +        - "liberio": Means this device can be reached via Liberio (local DMA) -        Arguments: -        xport_info -- A dictionary (string -> string). The dictionary must -                      have been originally created by request_xport(), but -                      additional key/value pairs need to be added. +        The list is filtered based on what the device knows about where the UHD +        session is. For example, on an N310, it will only either return "UDP" +        or "Liberio", depending on if we're remotely launching UHD, or locally. -        All transports need to also provide: -        - rx_mtu: In bytes, the max number of bytes going from device to UHD -        - tx_mtu: In bytes, the max number of bytes going from UHD to device +        In order to get further information about how to connect to the device, +        the keys returned from this function can be used with +        get_chdr_link_options(). +        """ +        raise NotImplementedError("get_chdr_link_types() not implemented.") -        UDP transports need to also provide: -        - src_ipv4: IPv4 address the connection is coming from. -        - src_port: IP port the connection is coming from. +    def get_chdr_link_options(self, xport_type):          """ -        raise NotImplementedError("commit_xport() not implemented.") +        Returns a list of dictionaries. Every dictionary contains information +        about one way to connect to this device in order to initiate CHDR +        traffic. + +        The interpretation of the return value is very highly dependant on the +        transport type (xport_type). +        For UDP, the every entry of the list has the following keys: +        - ipv4 (IP Address) +        - port (UDP port) +        - link_rate (bps of the link, e.g. 10e9 for 10GigE) + +        For Liberio, every entry has the following keys: +        - tx_dev: TX device (/dev/tx-dma*) +        - rx_dev: RX device (/dev/rx-dma*) +        """ +        raise NotImplementedError("get_chdr_link_options() not implemented.")      #######################################################################      # Claimer API @@ -927,3 +864,52 @@ class PeriphManagerBase(object):          """          self.log.debug("Device was unclaimed. No actions defined.") +    ####################################################################### +    # Timekeeper API +    ####################################################################### +    def get_num_timekeepers(self): +        """ +        Return the number of timekeepers +        """ +        raise NotImplementedError("get_num_timekeepers() not implemented.") + +    def get_timekeeper_time(self, tk_idx, last_pps): +        """ +        Get the time in ticks + +        Arguments: +        tk_idx: Index of timekeeper +        next_pps: If True, get time at last PPS. Otherwise, get time now. +        """ +        raise NotImplementedError( +            "get_ticks_now({}, {}) not implemented.".format(tk_idx, last_pps)) + +    def set_timekeeper_time(self, tk_idx, ticks, next_pps): +        """ +        Set the time in ticks + +        Arguments: +        tk_idx: Index of timekeeper +        ticks: Time in ticks +        next_pps: If True, set time at next PPS. Otherwise, set time now. +        """ +        raise NotImplementedError( +            "set_ticks_last_pps({}, {}, {}) not implemented." +            .format(tk_idx, ticks, next_pps)) + +    def set_tick_period(self, tk_idx, period_ns): +        """ +        Set the time per tick in nanoseconds (tick period) + +        Arguments: +        tk_idx: Index of timekeeper +        period_ns: Period in nanoseconds +        """ +        raise NotImplementedError( +            "set_tick_period({}) not implemented.".format(tk_idx, period_ns)) + +    def get_clocks(self): +        """ +        Gets the RFNoC-related clocks present in the FPGA design +        """ +        raise NotImplementedError("get_clocks() not implemented.") | 
