diff options
-rw-r--r-- | mpm/python/usrp_mpm/CMakeLists.txt | 2 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/liberiotable.py | 72 |
2 files changed, 74 insertions, 0 deletions
diff --git a/mpm/python/usrp_mpm/CMakeLists.txt b/mpm/python/usrp_mpm/CMakeLists.txt index ba640f7cc..7b6e6b84c 100644 --- a/mpm/python/usrp_mpm/CMakeLists.txt +++ b/mpm/python/usrp_mpm/CMakeLists.txt @@ -26,6 +26,8 @@ SET(USRP_MPM_TOP_FILES ${CMAKE_CURRENT_SOURCE_DIR}/discovery.py ${CMAKE_CURRENT_SOURCE_DIR}/dtoverlay.py ${CMAKE_CURRENT_SOURCE_DIR}/eeprom.py + ${CMAKE_CURRENT_SOURCE_DIR}/ethtable.py + ${CMAKE_CURRENT_SOURCE_DIR}/liberiotable.py ${CMAKE_CURRENT_SOURCE_DIR}/mpmlog.py ${CMAKE_CURRENT_SOURCE_DIR}/mpmtypes.py ${CMAKE_CURRENT_SOURCE_DIR}/mpmutils.py diff --git a/mpm/python/usrp_mpm/liberiotable.py b/mpm/python/usrp_mpm/liberiotable.py new file mode 100644 index 000000000..8f70c5ebe --- /dev/null +++ b/mpm/python/usrp_mpm/liberiotable.py @@ -0,0 +1,72 @@ +# +# Copyright 2017 Ettus Research, National Instruments Company +# +# SPDX-License-Identifier: GPL-3.0 +# +""" +Liberio DMA dispatcher table control +""" + +from builtins import str +from builtins import object +from .mpmlog import get_logger +from .uio import UIO + +class LiberioDispatcherTable(object): + """ + Controls a Liberio DMA dispatcher table. + + label -- A label that can be used by udev to find a UIO device + """ + + MTU_OFFSET = 0x80000 + + def __init__(self, label): + self.log = get_logger(label) + self._regs = UIO(label=label, read_only=False) + self.poke32 = self._regs.poke32 + self.peek32 = self._regs.peek32 + + def set_route(self, sid, dma_channel, mtu): + """ + Sets up routing in the Liberio dispatcher. From sid, only the + destination part is important. After this call, any CHDR packet with the + appropriate destination address will get routed to `dma_channel`. + + sid -- Full SID, but only destination part matters. + dma_channel -- The DMA channel to which these packets should get routed. + mtu -- Max size of bytes per packet. This is important to get right. The + DMA implementation will pad packets smaller than MTU up to the + mtu value, so making MTU extra large is inefficient. Packets + larger than MTU will get chopped up. Even worse. + """ + self.log.debug( + "Routing SID `{sid}' to DMA channel `{chan}', MTU {mtu} bytes.".format( + sid=str(sid), chan=dma_channel, mtu=mtu + ) + ) + def poke_and_trace(addr, data): + " Do a poke32() and log.trace() " + self.log.trace("Writing to address 0x{:04X}: 0x{:04X}".format( + addr, data + )) + self.poke32(addr, data) + + # Poke reg for destination channel + # Poke reg for MTU + try: + poke_and_trace( + 0 + 4 * sid.dst_ep, + dma_channel, + ) + poke_and_trace( + self.MTU_OFFSET + 4 * sid.dst_ep, + int(mtu / 8), + ) + except Exception as ex: + self.log.error( + "Unexpected exception while setting route: %s", + str(ex), + ) + raise + |