# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB)
# Copyright (c) 2018, Mellanox Technologies. All rights reserved. See COPYING file

"""
Device module introduces the Context and DeviceAttr class.
It allows user to open an IB device (using Context(name=<name>) and query it,
which returns a DeviceAttr object.
"""
import weakref

from .pyverbs_error import PyverbsRDMAError, PyverbsError
from pyverbs.cq cimport CQEX, CQ, CompChannel
from .pyverbs_error import PyverbsUserError
from pyverbs.base import PyverbsRDMAErrno
from pyverbs.base cimport close_weakrefs
from pyverbs.wq cimport WQ, RwqIndTable
cimport pyverbs.libibverbs_enums as e
cimport pyverbs.libibverbs as v
cimport pyverbs.librdmacm as cm
from pyverbs.cmid cimport CMID
from pyverbs.xrcd cimport XRCD
from pyverbs.addr cimport GID
from pyverbs.mr import DMMR, DMAHandle
from pyverbs.pd cimport PD
from pyverbs.qp cimport QP
from libc.stdlib cimport free, malloc
from libc.string cimport memset
from libc.stdint cimport uint64_t
from libc.stdint cimport uint16_t
from libc.stdint cimport uint32_t
from libc.stdint cimport uintptr_t
from pyverbs.utils import gid_str

cdef extern from 'endian.h':
    unsigned long be64toh(unsigned long host_64bits);


class Device(PyverbsObject):
    """
    Device class represents the C ibv_device. It stores device's properties.
    It is not a part of objects creation order - there's no need for the user
    to create it for such purposes.
    """
    def __init__(self, name, guid, node_type, transport_type, index):
        self._node_type = node_type
        self._transport_type = transport_type
        self._name = name
        self._guid = guid
        self._index = index

    @property
    def name(self):
        return self._name

    @property
    def node_type(self):
        return self._node_type

    @property
    def transport_type(self):
        return self._transport_type

    @property
    def guid(self):
        return self._guid

    @property
    def index(self):
        return self._index

    def __str__(self):
        return 'Device {dev}, node type {ntype}, transport type {ttype},' \
               ' guid {guid}, index {index}'.format(dev=self.name.decode(),
                ntype=translate_node_type(self.node_type),
                ttype=translate_transport_type(self.transport_type),
                guid=guid_to_hex(self.guid), index=self._index)


cdef class Context(PyverbsCM):
    """
    Context class represents the C ibv_context.
    """
    def __init__(self, **kwargs):
        """
        Initializes a Context object. The function searches the IB devices list
        for a device with the name provided by the user. If such a device is
        found, it is opened (unless provider attributes were given).
        In case of cmid argument, CMID object already holds an ibv_context
        initiated pointer, hence all we have to do is assign this pointer to
        Context's object pointer.
        :param kwargs: Arguments:
            * *name*
              The device's name
            * *attr*
              Provider-specific attributes. If not None, it means that the
              device will be opened by the provider and __init__ will return
              after locating the requested device.
            * *cmid*
              A CMID object. If not None, it means that the device was already
              opened by a CMID class, and only a pointer assignment is missing.
            * *cmd_fd*
              A command FD. If passed, the device will be imported from the
              given cmd_fd using ibv_import_device.
        :return: None
        """
        cdef int count
        cdef v.ibv_device **dev_list
        cdef CMID cmid

        super().__init__()
        self.pds = weakref.WeakSet()
        self.dms = weakref.WeakSet()
        self.ccs = weakref.WeakSet()
        self.cqs = weakref.WeakSet()
        self.qps = weakref.WeakSet()
        self.xrcds = weakref.WeakSet()
        self.vars = weakref.WeakSet()
        self.uars = weakref.WeakSet()
        self.pps = weakref.WeakSet()
        self.sched_nodes = weakref.WeakSet()
        self.sched_leafs = weakref.WeakSet()
        self.dr_domains = weakref.WeakSet()
        self.wqs = weakref.WeakSet()
        self.rwq_ind_tbls = weakref.WeakSet()
        self.crypto_logins = weakref.WeakSet()
        self.event_channels = weakref.WeakSet()
        self.dmahs = weakref.WeakSet()
        self.devx_umems = weakref.WeakSet()
        self.devx_objs = weakref.WeakSet()

        self.name = kwargs.get('name')
        provider_attr = kwargs.get('attr')
        cmid = kwargs.get('cmid')
        cmd_fd = kwargs.get('cmd_fd')
        if cmid is not None:
            self.context = cmid.id.verbs
            self.name = str(v.ibv_get_device_name(self.context.device).decode('utf-8'))
            cmid.ctx = self
            return
        if cmd_fd is not None:
            self.context = v.ibv_import_device(cmd_fd)
            if self.context == NULL:
                raise PyverbsRDMAErrno('Failed to import device')
            self.name = str(v.ibv_get_device_name(self.context.device).decode('utf-8'))
            return

        if self.name is None:
            raise PyverbsUserError('Device name must be provided')
        dev_list = v.ibv_get_device_list(&count)
        if dev_list == NULL:
            raise PyverbsRDMAError('Failed to get devices list')
        try:
            for i in range(count):
                if dev_list[i].name.decode() == self.name:
                    if provider_attr is not None:
                        # A provider opens its own context, we're just
                        # setting its IB device
                        self.device = dev_list[i]
                        return
                    self.context = v.ibv_open_device(dev_list[i])
                    if self.context == NULL:
                        raise PyverbsRDMAErrno('Failed to open device {dev}'.
                                               format(dev=self.name))
                    self.logger.debug('Context: opened device {dev}'.
                                      format(dev=self.name))
                    break
            else:
                raise PyverbsRDMAError('Failed to find device {dev}'.
                                       format(dev=self.name))
        finally:
            v.ibv_free_device_list(dev_list)

    def __dealloc__(self):
        """
        Closes the inner IB device.
        :return: None
        """
        self.close()

    cpdef close(self):
        if self.context != NULL:
            if self.logger:
                self.logger.debug('Closing Context')
            close_weakrefs([self.devx_objs, self.devx_umems, self.qps,
                            self.crypto_logins, self.rwq_ind_tbls, self.wqs,
                            self.ccs, self.cqs, self.dms, self.pds, self.xrcds,
                            self.vars, self.sched_leafs, self.sched_nodes,
                            self.dr_domains, self.event_channels, self.dmahs])
            rc = v.ibv_close_device(self.context)
            if rc != 0:
                raise PyverbsRDMAErrno(f'Failed to close device {self.name}')
            self.context = NULL

    @property
    def context(self):
        return <uintptr_t>self.context

    @property
    def num_comp_vectors(self):
        return self.context.num_comp_vectors

    def query_device(self):
        """
        Queries the device's attributes.
        :return: A DeviceAttr object which holds the device's attributes as
                 reported by the hardware.
        """
        dev_attr = DeviceAttr()
        rc = v.ibv_query_device(self.context, &dev_attr.dev_attr)
        if rc != 0:
            raise PyverbsRDMAError('Failed to query device {name}'.
                                   format(name=self.name), rc)
        return dev_attr

    def query_device_ex(self, QueryDeviceExInput ex_input = None):
        """
        Queries the device's extended attributes.
        :param ex_input: An extensible input struct for possible future
                         extensions
        :return: DeviceAttrEx object
        """
        dev_attr_ex = DeviceAttrEx()
        rc = v.ibv_query_device_ex(self.context,
                                   &ex_input.input if ex_input is not None else NULL,
                                   &dev_attr_ex.dev_attr)
        if rc != 0:
            raise PyverbsRDMAError('Failed to query EX device {name}'.
                                   format(name=self.name), rc)
        return dev_attr_ex

    def query_pkey(self, unsigned int port_num, int index):
        cdef uint16_t pkey
        rc = v.ibv_query_pkey(self.context, port_num, index, &pkey)
        if rc != 0:
            raise PyverbsRDMAError(f'Failed to query pkey {index} of port {port_num}')
        return pkey

    def get_pkey_index(self, unsigned int port_num, int pkey):
        idx = v.ibv_get_pkey_index(self.context, port_num, pkey)
        if idx == -1:
            raise PyverbsRDMAError(f'Failed to get pkey index of pkey = {pkey} of port {port_num}')
        return idx

    def query_gid(self, unsigned int port_num, int index):
        gid = GID()
        rc = v.ibv_query_gid(self.context, port_num, index, &gid.gid)
        if rc != 0:
            raise PyverbsRDMAError('Failed to query gid {idx} of port {port}'.
                                                                   format(idx=index, port=port_num))
        return gid

    def query_gid_type(self, unsigned int port_num, unsigned int index):
        cdef v.ibv_gid_type_sysfs gid_type
        rc = v.ibv_query_gid_type(self.context, port_num, index, &gid_type)
        if rc != 0:
            raise PyverbsRDMAErrno('Failed to query gid type of port {p} and gid index {g}'
                                   .format(p=port_num, g=index))
        return gid_type

    def query_port(self, unsigned int port_num):
        """
        Query port <port_num> of the device and returns its attributes.
        :param port_num: Port number to query
        :return: PortAttr object on success
        """
        port_attrs = PortAttr()
        rc = v.ibv_query_port(self.context, port_num, &port_attrs.attr)
        if rc != 0:
            raise PyverbsRDMAError('Failed to query port {p}'.
                                   format(p=port_num), rc)
        return port_attrs

    def query_port_speed(self, unsigned int port_num):
        """
        Query port <port_num> speed in 100 Mb/s granularity.
        :param port_num: Port number to query
        :return: Port speed
        """
        cdef uint64_t port_speed
        rc = v.ibv_query_port_speed(self.context, port_num, &port_speed)
        if rc != 0:
            raise PyverbsRDMAError(f'Failed to query port speed for port {port_num}', rc)
        return port_speed

    def query_gid_table(self, size_t max_entries, uint32_t flags=0):
        """
        Queries the GID tables of the device for at most <max_entries> entries
        and returns them.
        :param max_entries: Maximum number of GID entries to retrieve
        :param flags: Specifies new extra members of struct ibv_gid_entry to
                      query
        :return: List of GIDEntry objects on success
        """
        cdef v.ibv_gid_entry *entries
        cdef v.ibv_gid_entry entry

        entries = <v.ibv_gid_entry *>malloc(max_entries *
                                            sizeof(v.ibv_gid_entry))
        rc = v.ibv_query_gid_table(self.context, entries, max_entries, flags)
        if rc < 0:
            raise PyverbsRDMAError('Failed to query gid tables of the device',
                                   rc)
        gid_entries = []
        for i in range(rc):
            entry = entries[i]
            gid_entries.append(GIDEntry(entry.gid._global.subnet_prefix,
                               entry.gid._global.interface_id, entry.gid_index,
                               entry.port_num, entry.gid_type,
                               entry.ndev_ifindex))
        free(entries)
        return gid_entries

    def query_gid_ex(self, uint32_t port_num, uint32_t gid_index,
                     uint32_t flags=0):
        """
        Queries the GID table of port <port_num> in index <gid_index>, and
        returns the GID entry.
        :param port_num: The port number to query
        :param gid_index: The index in the GID table to query
        :param flags: Specifies new extra members of struct ibv_gid_entry to
                      query
        :return: GIDEntry object on success
        """
        entry = GIDEntry()
        rc = v.ibv_query_gid_ex(self.context, port_num, gid_index,
                                &entry.entry, flags)
        if rc != 0:
            raise PyverbsRDMAError(f'Failed to query gid table of port '\
                                   f'{port_num} in index {gid_index}', rc)
        return entry

    def query_rt_values_ex(self, comp_mask=v.IBV_VALUES_MASK_RAW_CLOCK):
        """
        Query an RDMA device for some real time values.
        :return: A tuple of the real time values according to comp_mask (sec, nsec)
        """
        cdef v.ibv_values_ex *val
        val = <v.ibv_values_ex *>malloc(sizeof(v.ibv_values_ex))
        val.comp_mask = comp_mask
        rc = v.ibv_query_rt_values_ex(self.context, val)
        if rc != 0:
            raise PyverbsRDMAError(f'Failed to query real time values', rc)
        if val.comp_mask != comp_mask:
            raise PyverbsRDMAError(f'Failed to query real time values with requested comp_mask')
        nsec = (<v.ibv_values_ex *>val).raw_clock.tv_nsec
        sec = (<v.ibv_values_ex *>val).raw_clock.tv_sec
        free(val)
        return sec, nsec

    cdef add_ref(self, obj):
        if isinstance(obj, PD):
            self.pds.add(obj)
        elif isinstance(obj, DM):
            self.dms.add(obj)
        elif isinstance(obj, CompChannel):
            self.ccs.add(obj)
        elif isinstance(obj, CQ) or isinstance(obj, CQEX):
            self.cqs.add(obj)
        elif isinstance(obj, QP):
            self.qps.add(obj)
        elif isinstance(obj, XRCD):
            self.xrcds.add(obj)
        elif isinstance(obj, WQ):
            self.wqs.add(obj)
        elif isinstance(obj, RwqIndTable):
            self.rwq_ind_tbls.add(obj)
        elif isinstance(obj, DMAHandle):
            self.dmahs.add(obj)
        else:
            raise PyverbsError('Unrecognized object type')

    def get_async_event(self):
        event = AsyncEvent()
        rc = v.ibv_get_async_event(self.context, &event.event)
        if rc != 0:
            raise PyverbsRDMAError(f'Failed to get async event', rc)
        return event

    @property
    def cmd_fd(self):
        return self.context.cmd_fd

    @property
    def name(self):
        return self.name


cdef class DeviceAttr(PyverbsObject):
    """
    DeviceAttr represents ibv_device_attr C class. It exposes the same
    properties (read only) and also provides an __str__() function for
    readability.
    """
    @property
    def fw_version(self):
        return self.dev_attr.fw_ver.decode()
    @property
    def node_guid(self):
        return self.dev_attr.node_guid
    @property
    def sys_image_guid(self):
        return self.dev_attr.sys_image_guid
    @property
    def max_mr_size(self):
        return self.dev_attr.max_mr_size
    @property
    def page_size_cap(self):
        return self.dev_attr.page_size_cap
    @property
    def vendor_id(self):
        return self.dev_attr.vendor_id
    @property
    def vendor_part_id(self):
        return self.dev_attr.vendor_part_id
    @property
    def hw_ver(self):
        return self.dev_attr.hw_ver
    @property
    def max_qp(self):
        return self.dev_attr.max_qp
    @property
    def max_qp_wr(self):
        return self.dev_attr.max_qp_wr
    @property
    def device_cap_flags(self):
        return self.dev_attr.device_cap_flags
    @property
    def max_sge(self):
        return self.dev_attr.max_sge
    @property
    def max_sge_rd(self):
        return self.dev_attr.max_sge_rd
    @property
    def max_cq(self):
        return self.dev_attr.max_cq
    @property
    def max_cqe(self):
        return self.dev_attr.max_cqe
    @property
    def max_mr(self):
        return self.dev_attr.max_mr
    @property
    def max_pd(self):
        return self.dev_attr.max_pd
    @property
    def max_qp_rd_atom(self):
        return self.dev_attr.max_qp_rd_atom
    @property
    def max_ee_rd_atom(self):
        return self.dev_attr.max_ee_rd_atom
    @property
    def max_res_rd_atom(self):
        return self.dev_attr.max_res_rd_atom
    @property
    def max_qp_init_rd_atom(self):
        return self.dev_attr.max_qp_init_rd_atom
    @property
    def max_ee_init_rd_atom(self):
        return self.dev_attr.max_ee_init_rd_atom
    @property
    def atomic_caps(self):
        return self.dev_attr.atomic_cap
    @property
    def max_ee(self):
        return self.dev_attr.max_ee
    @property
    def max_rdd(self):
        return self.dev_attr.max_rdd
    @property
    def max_mw(self):
        return self.dev_attr.max_mw
    @property
    def max_raw_ipv6_qps(self):
        return self.dev_attr.max_raw_ipv6_qp
    @property
    def max_raw_ethy_qp(self):
        return self.dev_attr.max_raw_ethy_qp
    @property
    def max_mcast_grp(self):
        return self.dev_attr.max_mcast_grp
    @property
    def max_mcast_qp_attach(self):
        return self.dev_attr.max_mcast_qp_attach
    @property
    def max_ah(self):
        return self.dev_attr.max_ah
    @property
    def max_fmr(self):
        return self.dev_attr.max_fmr
    @property
    def max_map_per_fmr(self):
        return self.dev_attr.max_map_per_fmr
    @property
    def max_srq(self):
        return self.dev_attr.max_srq
    @property
    def max_srq_wr(self):
        return self.dev_attr.max_srq_wr
    @property
    def max_srq_sge(self):
        return self.dev_attr.max_srq_sge
    @property
    def max_pkeys(self):
        return self.dev_attr.max_pkeys
    @property
    def local_ca_ack_delay(self):
        return self.dev_attr.local_ca_ack_delay
    @property
    def phys_port_cnt(self):
        return self.dev_attr.phys_port_cnt

    def __str__(self):
        print_format = '{:<22}: {:<20}\n'
        return print_format.format('FW version', self.fw_version) +\
            print_format.format('Node guid', guid_format(self.node_guid)) +\
            print_format.format('Sys image GUID', guid_format(self.sys_image_guid)) +\
            print_format.format('Max MR size', hex(self.max_mr_size).replace('L', '')) +\
            print_format.format('Page size cap', hex(self.page_size_cap).replace('L', '')) +\
            print_format.format('Vendor ID', hex(self.vendor_id)) +\
            print_format.format('Vendor part ID', self.vendor_part_id) +\
            print_format.format('HW version', self.hw_ver) +\
            print_format.format('Max QP', self.max_qp) +\
            print_format.format('Max QP WR', self.max_qp_wr) +\
            print_format.format('Device cap flags',
                                translate_device_caps(self.device_cap_flags)) +\
            print_format.format('Max SGE', self.max_sge) +\
            print_format.format('Max SGE RD', self.max_sge_rd) +\
            print_format.format('MAX CQ', self.max_cq) +\
            print_format.format('Max CQE', self.max_cqe) +\
            print_format.format('Max MR', self.max_mr) +\
            print_format.format('Max PD', self.max_pd) +\
            print_format.format('Max QP RD atom', self.max_qp_rd_atom) +\
            print_format.format('Max EE RD atom', self.max_ee_rd_atom) +\
            print_format.format('Max res RD atom', self.max_res_rd_atom) +\
            print_format.format('Max QP init RD atom', self.max_qp_init_rd_atom) +\
            print_format.format('Max EE init RD atom', self.max_ee_init_rd_atom) +\
            print_format.format('Atomic caps', self.atomic_caps) +\
            print_format.format('Max EE', self.max_ee) +\
            print_format.format('Max RDD', self.max_rdd) +\
            print_format.format('Max MW', self.max_mw) +\
            print_format.format('Max raw IPv6 QPs', self.max_raw_ipv6_qps) +\
            print_format.format('Max raw ethy QP', self.max_raw_ethy_qp) +\
            print_format.format('Max mcast group', self.max_mcast_grp) +\
            print_format.format('Max mcast QP attach', self.max_mcast_qp_attach) +\
            print_format.format('Max AH', self.max_ah) +\
            print_format.format('Max FMR', self.max_fmr) +\
            print_format.format('Max map per FMR', self.max_map_per_fmr) +\
            print_format.format('Max SRQ', self.max_srq) +\
            print_format.format('Max SRQ WR', self.max_srq_wr) +\
            print_format.format('Max SRQ SGE', self.max_srq_sge) +\
            print_format.format('Max PKeys', self.max_pkeys) +\
            print_format.format('local CA ack delay', self.local_ca_ack_delay) +\
            print_format.format('Phys port count', self.phys_port_cnt)


cdef class QueryDeviceExInput(PyverbsObject):
    def __init__(self, comp_mask):
        super().__init__()
        self.ex_input.comp_mask = comp_mask


cdef class ODPCaps(PyverbsObject):
    @property
    def general_caps(self):
        return self.odp_caps.general_caps
    @property
    def rc_odp_caps(self):
        return self.odp_caps.per_transport_caps.rc_odp_caps
    @property
    def uc_odp_caps(self):
        return self.odp_caps.per_transport_caps.uc_odp_caps
    @property
    def ud_odp_caps(self):
        return self.odp_caps.per_transport_caps.ud_odp_caps
    @property
    def xrc_odp_caps(self):
        return self.xrc_odp_caps
    @xrc_odp_caps.setter
    def xrc_odp_caps(self, val):
       self.xrc_odp_caps = val

    def __str__(self):
        general_caps = {e.IBV_ODP_SUPPORT: 'IBV_ODP_SUPPORT',
              e.IBV_ODP_SUPPORT_IMPLICIT: 'IBV_ODP_SUPPORT_IMPLICIT'}

        l = {e.IBV_ODP_SUPPORT_SEND: 'IBV_ODP_SUPPORT_SEND',
             e.IBV_ODP_SUPPORT_RECV: 'IBV_ODP_SUPPORT_RECV',
             e.IBV_ODP_SUPPORT_WRITE: 'IBV_ODP_SUPPORT_WRITE',
             e.IBV_ODP_SUPPORT_READ: 'IBV_ODP_SUPPORT_READ',
             e.IBV_ODP_SUPPORT_ATOMIC: 'IBV_ODP_SUPPORT_ATOMIC',
             e.IBV_ODP_SUPPORT_SRQ_RECV: 'IBV_ODP_SUPPORT_SRQ_RECV',
             e.IBV_ODP_SUPPORT_FLUSH: 'IBV_ODP_SUPPORT_FLUSH',
             e.IBV_ODP_SUPPORT_ATOMIC_WRITE: 'IBV_ODP_SUPPORT_ATOMIC_WRITE'}

        print_format = '{}: {}\n'
        return print_format.format('ODP General caps', str_from_flags(self.general_caps, general_caps)) +\
            print_format.format('RC ODP caps', str_from_flags(self.rc_odp_caps, l)) +\
            print_format.format('UD ODP caps', str_from_flags(self.ud_odp_caps, l)) +\
            print_format.format('UC ODP caps', str_from_flags(self.uc_odp_caps, l)) +\
            print_format.format('XRC ODP caps', str_from_flags(self.xrc_odp_caps, l))


cdef class PCIAtomicCaps(PyverbsObject):
    @property
    def fetch_add(self):
        return self.caps.fetch_add
    @property
    def swap(self):
        return self.caps.swap
    @property
    def compare_swap(self):
        return self.caps.compare_swap


cdef class TSOCaps(PyverbsObject):
    @property
    def max_tso(self):
        return self.tso_caps.max_tso
    @property
    def supported_qpts(self):
        return self.tso_caps.supported_qpts


cdef class RSSCaps(PyverbsObject):
    @property
    def supported_qpts(self):
        return self.rss_caps.supported_qpts
    @property
    def max_rwq_indirection_tables(self):
        return self.rss_caps.max_rwq_indirection_tables
    @property
    def rx_hash_fields_mask(self):
        return self.rss_caps.rx_hash_fields_mask
    @property
    def rx_hash_function(self):
        return self.rss_caps.rx_hash_function
    @property
    def max_rwq_indirection_table_size(self):
        return self.rss_caps.max_rwq_indirection_table_size


cdef class PacketPacingCaps(PyverbsObject):
    @property
    def qp_rate_limit_min(self):
        return self.packet_pacing_caps.qp_rate_limit_min
    @property
    def qp_rate_limit_max(self):
        return self.packet_pacing_caps.qp_rate_limit_max
    @property
    def supported_qpts(self):
        return self.packet_pacing_caps.supported_qpts


cdef class TMCaps(PyverbsObject):
    @property
    def max_rndv_hdr_size(self):
        return self.tm_caps.max_rndv_hdr_size
    @property
    def max_num_tags(self):
        return self.tm_caps.max_num_tags
    @property
    def flags(self):
        return self.tm_caps.flags
    @property
    def max_ops(self):
        return self.tm_caps.max_ops
    @property
    def max_sge(self):
        return self.tm_caps.max_sge


cdef class CQModerationCaps(PyverbsObject):
    @property
    def max_cq_count(self):
        return self.cq_mod_caps.max_cq_count
    @property
    def max_cq_period(self):
        return self.cq_mod_caps.max_cq_period


cdef class DeviceAttrEx(PyverbsObject):
    @property
    def orig_attr(self):
        attr = DeviceAttr()
        attr.dev_attr = self.dev_attr.orig_attr
        return attr
    @property
    def comp_mask(self):
        return self.dev_attr.comp_mask
    @comp_mask.setter
    def comp_mask(self, val):
        self.dev_attr.comp_mask = val
    @property
    def odp_caps(self):
        caps = ODPCaps()
        caps.odp_caps = self.dev_attr.odp_caps
        caps.xrc_odp_caps = self.dev_attr.xrc_odp_caps
        return caps
    @property
    def completion_timestamp_mask(self):
        return self.dev_attr.completion_timestamp_mask
    @property
    def hca_core_clock(self):
        return self.dev_attr.hca_core_clock
    @property
    def device_cap_flags_ex(self):
        return self.dev_attr.device_cap_flags_ex
    @property
    def tso_caps(self):
        caps = TSOCaps()
        caps.tso_caps = self.dev_attr.tso_caps
        return caps
    @property
    def pci_atomic_caps(self):
        caps = PCIAtomicCaps()
        caps.caps = self.dev_attr.pci_atomic_caps
        return caps
    @property
    def rss_caps(self):
        caps = RSSCaps()
        caps.rss_caps = self.dev_attr.rss_caps
        return caps
    @property
    def max_wq_type_rq(self):
        return self.dev_attr.max_wq_type_rq
    @property
    def packet_pacing_caps(self):
        caps = PacketPacingCaps()
        caps.packet_pacing_caps = self.dev_attr.packet_pacing_caps
        return caps
    @property
    def raw_packet_caps(self):
        return self.dev_attr.raw_packet_caps
    @property
    def tm_caps(self):
        caps = TMCaps()
        caps.tm_caps = self.dev_attr.tm_caps
        return caps
    @property
    def cq_mod_caps(self):
        caps = CQModerationCaps()
        caps.cq_mod_caps = self.dev_attr.cq_mod_caps
        return caps
    @property
    def max_dm_size(self):
        return self.dev_attr.max_dm_size
    @property
    def phys_port_cnt_ex(self):
        return self.dev_attr.phys_port_cnt_ex


cdef class AllocDmAttr(PyverbsObject):
    def __init__(self, length, log_align_req = 0, comp_mask = 0):
        """
        Creates an AllocDmAttr object with the given parameters. This object
        can than be used to create a DM object.
        :param length: Length of the future device memory
        :param log_align_req: log2 of address alignment requirement
        :param comp_mask: compatibility mask
        :return: An AllocDmAttr object
        """
        super().__init__()
        self.alloc_dm_attr.length = length
        self.alloc_dm_attr.log_align_req = log_align_req
        self.alloc_dm_attr.comp_mask = comp_mask

    @property
    def length(self):
        return self.alloc_dm_attr.length

    @length.setter
    def length(self, val):
        self.alloc_dm_attr.length = val

    @property
    def log_align_req(self):
        return self.alloc_dm_attr.log_align_req

    @log_align_req.setter
    def log_align_req(self, val):
        self.alloc_dm_attr.log_align_req = val

    @property
    def comp_mask(self):
        return self.alloc_dm_attr.comp_mask

    @comp_mask.setter
    def comp_mask(self, val):
        self.alloc_dm_attr.comp_mask = val


cdef class DM(PyverbsCM):
    def __init__(self, Context context, AllocDmAttr dm_attr=None, **kwargs):
        """
        Allocate a device (direct) memory.
        :param context: The context of the device on which to allocate memory
        :param dm_attr: Attributes that define the DM
        :param kwargs: Arguments:
            * *handle*
                A valid kernel handle for a DM object in the given context.
                If passed, the DM will be imported and associated with the
                given context using ibv_import_dm.
        :return: A DM object on success
        """
        super().__init__()
        self.dm_mrs = weakref.WeakSet()

        dm_handle = kwargs.get('handle')
        if dm_handle is not None:
            self.dm = v.ibv_import_dm(context.context, dm_handle)
            if self.dm == NULL:
                raise PyverbsRDMAErrno('Failed to import DM')
            self._is_imported = True
        else:
            device_attr = context.query_device_ex()
            if device_attr.max_dm_size <= 0:
                raise PyverbsUserError('Device doesn\'t support dm allocation')
            self.dm = v.ibv_alloc_dm(<v.ibv_context*>context.context,
                                     &dm_attr.alloc_dm_attr)
            if self.dm == NULL:
                raise PyverbsRDMAErrno('Failed to allocate device memory of size '
                                       '{size}. Max available size {max}.'
                                       .format(size=dm_attr.length,
                                               max=device_attr.max_dm_size))
        self.context = context
        context.add_ref(self)

    def unimport(self):
        v.ibv_unimport_dm(self.dm)
        self.close()

    def __dealloc__(self):
        self.close()

    cpdef close(self):
        """
        Closes the underlying C object of the DM.
        In case of an imported DM, the DM won't be freed, and it's kept for the
        original DM object, in order to prevent double free by Python GC.
        """
        if self.dm != NULL:
            if self.logger:
                self.logger.debug('Closing DM')
            close_weakrefs([self.dm_mrs])
            if not self._is_imported:
                rc = v.ibv_free_dm(self.dm)
                if rc != 0:
                    raise PyverbsRDMAError('Failed to free dm', rc)
            self.dm = NULL
            self.context = None

    cdef add_ref(self, obj):
        if isinstance(obj, DMMR):
            self.dm_mrs.add(obj)

    def copy_to_dm(self, dm_offset, data, length):
        rc = v.ibv_memcpy_to_dm(<v.ibv_dm *>self.dm, <uint64_t>dm_offset,
                                <char *>data, <size_t>length)
        if rc != 0:
            raise PyverbsRDMAError('Failed to copy to dm', rc)

    def copy_from_dm(self, dm_offset, length):
        cdef char *data =<char*>malloc(length)
        memset(data, 0, length)
        rc = v.ibv_memcpy_from_dm(<void *>data, <v.ibv_dm *>self.dm,
                                  <uint64_t>dm_offset, <size_t>length)
        if rc != 0:
            raise PyverbsRDMAError('Failed to copy from dm', rc)
        res = data[:length]
        free(data)
        return res

    def export_dmabuf_fd(self):
        """
        Export a dmabuf FD for this DM object.
        :return: A file descriptor (int) for the dmabuf FD
        """
        fd = v.ibv_dm_export_dmabuf_fd(self.dm)
        if fd < 0:
            raise PyverbsRDMAErrno('Failed to export dmabuf FD for DM')
        return fd

    @property
    def handle(self):
        return self.dm.handle


cdef class PortAttr(PyverbsObject):
    @property
    def state(self):
        return self.attr.state
    @property
    def max_mtu(self):
        return self.attr.max_mtu
    @property
    def active_mtu(self):
        return self.attr.active_mtu
    @property
    def gid_tbl_len(self):
        return self.attr.gid_tbl_len
    @property
    def port_cap_flags(self):
        return self.attr.port_cap_flags
    @property
    def max_msg_sz(self):
        return self.attr.max_msg_sz
    @property
    def bad_pkey_cntr(self):
        return self.attr.bad_pkey_cntr
    @property
    def qkey_viol_cntr(self):
        return self.attr.qkey_viol_cntr
    @property
    def pkey_tbl_len(self):
        return self.attr.pkey_tbl_len
    @property
    def lid(self):
        return self.attr.lid
    @property
    def sm_lid(self):
        return self.attr.sm_lid
    @property
    def lmc(self):
        return self.attr.lmc
    @property
    def max_vl_num(self):
        return self.attr.max_vl_num
    @property
    def sm_sl(self):
        return self.attr.sm_sl
    @property
    def subnet_timeout(self):
        return self.attr.subnet_timeout
    @property
    def init_type_reply(self):
        return self.attr.init_type_reply
    @property
    def active_width(self):
        return self.attr.active_width
    @property
    def active_speed(self):
        return self.attr.active_speed
    @property
    def phys_state(self):
        return self.attr.phys_state
    @property
    def link_layer(self):
        return self.attr.link_layer
    @property
    def flags(self):
        return self.attr.flags
    @property
    def port_cap_flags2(self):
        return self.attr.port_cap_flags2
    @property
    def active_speed_ex(self):
        return self.attr.active_speed_ex

    def __str__(self):
        print_format = '{:<24}: {:<20}\n'
        return print_format.format('Port state', port_state_to_str(self.attr.state)) +\
            print_format.format('Max MTU', translate_mtu(self.attr.max_mtu)) +\
            print_format.format('Active MTU', translate_mtu(self.attr.active_mtu)) +\
            print_format.format('SM lid', self.attr.sm_lid) +\
            print_format.format('Port lid', self.attr.lid) +\
            print_format.format('lmc', hex(self.attr.lmc)) +\
            print_format.format('Link layer', translate_link_layer(self.attr.link_layer)) +\
            print_format.format('Max message size', hex(self.attr.max_msg_sz)) +\
            print_format.format('Port cap flags', translate_port_cap_flags(self.attr.port_cap_flags)) +\
            print_format.format('Port cap flags 2', translate_port_cap_flags2(self.attr.port_cap_flags2)) +\
            print_format.format('max VL num', self.attr.max_vl_num) +\
            print_format.format('Bad Pkey counter', self.attr.bad_pkey_cntr) +\
            print_format.format('Qkey violations counter', self.attr.qkey_viol_cntr) +\
            print_format.format('GID table len', self.attr.gid_tbl_len) +\
            print_format.format('Pkey table len', self.attr.pkey_tbl_len) +\
            print_format.format('SM sl', self.attr.sm_sl) +\
            print_format.format('Subnet timeout', self.attr.subnet_timeout) +\
            print_format.format('Init type reply', self.attr.init_type_reply) +\
            print_format.format('Active width', width_to_str(self.attr.active_width)) +\
            print_format.format('Active speed', speed_to_str(self.attr.active_speed, self.attr.active_speed_ex)) +\
            print_format.format('Phys state', phys_state_to_str(self.attr.phys_state)) +\
            print_format.format('Flags', self.attr.flags)


cdef class GIDEntry(PyverbsObject):
    def __init__(self, subnet_prefix=0, interface_id=0, gid_index=0,
                 port_num=0, gid_type=0, ndev_ifindex=0):
        super().__init__()
        self.entry.gid._global.subnet_prefix = subnet_prefix
        self.entry.gid._global.interface_id = interface_id
        self.entry.gid_index = gid_index
        self.entry.port_num = port_num
        self.entry.gid_type = gid_type
        self.entry.ndev_ifindex = ndev_ifindex

    @property
    def gid_subnet_prefix(self):
        return self.entry.gid._global.subnet_prefix

    @property
    def gid_interface_id(self):
        return self.entry.gid._global.interface_id

    @property
    def gid_index(self):
        return self.entry.gid_index

    @property
    def port_num(self):
        return self.entry.port_num

    @property
    def gid_type(self):
        return self.entry.gid_type

    @property
    def ndev_ifindex(self):
        return self.entry.ndev_ifindex

    def gid_str(self):
        return gid_str(self.gid_subnet_prefix, self.gid_interface_id)

    def __str__(self):
        print_format = '{:<24}: {:<20}\n'
        return print_format.format('GID', self.gid_str()) +\
            print_format.format('GID Index', self.gid_index) +\
            print_format.format('Port number', self.port_num) +\
            print_format.format('GID type', translate_gid_type(
                                self.gid_type)) +\
            print_format.format('Ndev ifindex', self.ndev_ifindex)


cdef class AsyncEvent(PyverbsObject):
    def __init__(self, event_type=0):
        super().__init__()
        self.event.event_type = event_type

    def ack(self):
        v.ibv_ack_async_event(&self.event)

    @property
    def event_type(self):
        return self.event.event_type

    def __str__(self):
        print_format = '{:<24}: {:<20}\n'
        return print_format.format('Event Type', translate_event_type(
                                   self.event.event_type))


def translate_gid_type(gid_type):
    types = {e.IBV_GID_TYPE_IB: 'IB', e.IBV_GID_TYPE_ROCE_V1: 'RoCEv1',
             e.IBV_GID_TYPE_ROCE_V2: 'RoCEv2'}
    try:
        return types[gid_type]
    except KeyError:
        return f'Unknown gid_type ({gid_type})'


def guid_format(num):
    """
    Get GUID representation of the given number, including change of endianness.
    :param num: Number to change to GUID format.
    :return: GUID-formatted string.
    """
    num = be64toh(num)
    hex_str = "%016x" % (num)
    hex_array = [hex_str[i:i+2] for i in range(0, len(hex_str), 2)]
    hex_array = [''.join(x) for x in zip(hex_array[0::2], hex_array[1::2])]
    return ':'.join(hex_array)


def translate_transport_type(transport_type):
    l = {0: 'IB', 1: 'IWARP', 2: 'USNIC', 3: 'USNIC UDP'}
    try:
        return l[transport_type]
    except KeyError:
        return 'Unknown'


def translate_node_type(node_type):
    l = {1: 'CA', 2: 'Switch', 3: 'Router', 4: 'RNIC', 5: 'USNIC',
         6: 'USNIC UDP'}
    try:
        return l[node_type]
    except KeyError:
        return 'Unknown'


def guid_to_hex(node_guid):
    return hex(node_guid).replace('L', '').replace('0x', '')


def port_state_to_str(port_state):
    l = {0: 'NOP', 1: 'Down', 2: 'Init', 3: 'Armed', 4: 'Active', 5: 'Defer'}
    try:
        return '{s} ({n})'.format(s=l[port_state], n=port_state)
    except KeyError:
        return 'Invalid state ({s})'.format(s=port_state)


def translate_mtu(mtu):
    l = {1: 256, 2: 512, 3: 1024, 4: 2048, 5: 4096}
    try:
        return '{s} ({n})'.format(s=l[mtu], n=mtu)
    except KeyError:
        return 'Invalid MTU ({m})'.format(m=mtu)


def translate_link_layer(ll):
    l = {0: 'Unspecified', 1:'InfiniBand', 2:'Ethernet'}
    try:
        return l[ll]
    except KeyError:
        return 'Invalid link layer ({ll})'.format(ll=ll)


def translate_port_cap_flags(flags):
    l = {e.IBV_PORT_SM: 'IBV_PORT_SM',
         e.IBV_PORT_NOTICE_SUP: 'IBV_PORT_NOTICE_SUP',
         e.IBV_PORT_TRAP_SUP: 'IBV_PORT_TRAP_SUP',
         e.IBV_PORT_OPT_IPD_SUP: 'IBV_PORT_OPT_IPD_SUP',
         e.IBV_PORT_AUTO_MIGR_SUP: 'IBV_PORT_AUTO_MIGR_SUP',
         e.IBV_PORT_SL_MAP_SUP: 'IBV_PORT_SL_MAP_SUP',
         e.IBV_PORT_MKEY_NVRAM: 'IBV_PORT_MKEY_NVRAM',
         e.IBV_PORT_PKEY_NVRAM: 'IBV_PORT_PKEY_NVRAM',
         e.IBV_PORT_LED_INFO_SUP: 'IBV_PORT_LED_INFO_SUP',
         e.IBV_PORT_SYS_IMAGE_GUID_SUP: 'IBV_PORT_SYS_IMAGE_GUID_SUP',
         e.IBV_PORT_PKEY_SW_EXT_PORT_TRAP_SUP: 'IBV_PORT_PKEY_SW_EXT_PORT_TRAP_SUP',
         e.IBV_PORT_EXTENDED_SPEEDS_SUP: 'IBV_PORT_EXTENDED_SPEEDS_SUP',
         e.IBV_PORT_CAP_MASK2_SUP: 'IBV_PORT_CAP_MASK2_SUP',
         e.IBV_PORT_CM_SUP: 'IBV_PORT_CM_SUP',
         e.IBV_PORT_SNMP_TUNNEL_SUP: 'IBV_PORT_SNMP_TUNNEL_SUP',
         e.IBV_PORT_REINIT_SUP: 'IBV_PORT_REINIT_SUP',
         e.IBV_PORT_DEVICE_MGMT_SUP: 'IBV_PORT_DEVICE_MGMT_SUP',
         e.IBV_PORT_VENDOR_CLASS_SUP: 'IBV_PORT_VENDOR_CLASS_SUP',
         e.IBV_PORT_DR_NOTICE_SUP: 'IBV_PORT_DR_NOTICE_SUP',
         e.IBV_PORT_CAP_MASK_NOTICE_SUP: 'IBV_PORT_CAP_MASK_NOTICE_SUP',
         e.IBV_PORT_BOOT_MGMT_SUP: 'IBV_PORT_BOOT_MGMT_SUP',
         e.IBV_PORT_LINK_LATENCY_SUP: 'IBV_PORT_LINK_LATENCY_SUP',
         e.IBV_PORT_CLIENT_REG_SUP: 'IBV_PORT_CLIENT_REG_SUP',
         e.IBV_PORT_IP_BASED_GIDS: 'IBV_PORT_IP_BASED_GIDS'}
    return str_from_flags(flags, l)


def translate_port_cap_flags2(flags):
    l = {e.IBV_PORT_SET_NODE_DESC_SUP: 'IBV_PORT_SET_NODE_DESC_SUP',
         e.IBV_PORT_INFO_EXT_SUP: 'IBV_PORT_INFO_EXT_SUP',
         e.IBV_PORT_VIRT_SUP: 'IBV_PORT_VIRT_SUP',
         e.IBV_PORT_SWITCH_PORT_STATE_TABLE_SUP: 'IBV_PORT_SWITCH_PORT_STATE_TABLE_SUP',
         e.IBV_PORT_LINK_WIDTH_2X_SUP: 'IBV_PORT_LINK_WIDTH_2X_SUP',
         e.IBV_PORT_LINK_SPEED_HDR_SUP: 'IBV_PORT_LINK_SPEED_HDR_SUP',
         e.IBV_PORT_LINK_SPEED_NDR_SUP: 'IBV_PORT_LINK_SPEED_NDR_SUP'}
    return str_from_flags(flags, l)


def translate_device_caps(flags):
    l = {e.IBV_DEVICE_RESIZE_MAX_WR: 'IBV_DEVICE_RESIZE_MAX_WR',
         e.IBV_DEVICE_BAD_PKEY_CNTR: 'IBV_DEVICE_BAD_PKEY_CNTR',
         e.IBV_DEVICE_BAD_QKEY_CNTR: 'IBV_DEVICE_BAD_QKEY_CNTR',
         e.IBV_DEVICE_RAW_MULTI: 'IBV_DEVICE_RAW_MULTI',
         e.IBV_DEVICE_AUTO_PATH_MIG: 'IBV_DEVICE_AUTO_PATH_MIG',
         e.IBV_DEVICE_CHANGE_PHY_PORT: 'IBV_DEVICE_CHANGE_PHY_PORT',
         e.IBV_DEVICE_UD_AV_PORT_ENFORCE: 'IBV_DEVICE_UD_AV_PORT_ENFORCE',
         e.IBV_DEVICE_CURR_QP_STATE_MOD: 'IBV_DEVICE_CURR_QP_STATE_MOD',
         e.IBV_DEVICE_SHUTDOWN_PORT: 'IBV_DEVICE_SHUTDOWN_PORT',
         e.IBV_DEVICE_INIT_TYPE: 'IBV_DEVICE_INIT_TYPE',
         e.IBV_DEVICE_PORT_ACTIVE_EVENT: 'IBV_DEVICE_PORT_ACTIVE_EVENT',
         e.IBV_DEVICE_SYS_IMAGE_GUID: 'IBV_DEVICE_SYS_IMAGE_GUID',
         e.IBV_DEVICE_RC_RNR_NAK_GEN: 'IBV_DEVICE_RC_RNR_NAK_GEN',
         e.IBV_DEVICE_SRQ_RESIZE: 'IBV_DEVICE_SRQ_RESIZE',
         e.IBV_DEVICE_N_NOTIFY_CQ: 'IBV_DEVICE_N_NOTIFY_CQ',
         e.IBV_DEVICE_MEM_WINDOW: 'IBV_DEVICE_MEM_WINDOW',
         e.IBV_DEVICE_UD_IP_CSUM: 'IBV_DEVICE_UD_IP_CSUM',
         e.IBV_DEVICE_XRC: 'IBV_DEVICE_XRC',
         e.IBV_DEVICE_MEM_MGT_EXTENSIONS: 'IBV_DEVICE_MEM_MGT_EXTENSIONS',
         e.IBV_DEVICE_MEM_WINDOW_TYPE_2A: 'IBV_DEVICE_MEM_WINDOW_TYPE_2A',
         e.IBV_DEVICE_MEM_WINDOW_TYPE_2B: 'IBV_DEVICE_MEM_WINDOW_TYPE_2B',
         e.IBV_DEVICE_RC_IP_CSUM: 'IBV_DEVICE_RC_IP_CSUM',
         e.IBV_DEVICE_RAW_IP_CSUM: 'IBV_DEVICE_RAW_IP_CSUM',
         e.IBV_DEVICE_MANAGED_FLOW_STEERING: 'IBV_DEVICE_MANAGED_FLOW_STEERING'}
    return str_from_flags(flags, l)


def str_from_flags(flags, dictionary):
    str_flags = "\n  "
    for bit in dictionary:
        if flags & bit:
            str_flags += dictionary[bit]
            str_flags += '\n  '
    return str_flags


def phys_state_to_str(phys):
    l =  {1: 'Sleep', 2: 'Polling', 3: 'Disabled',
          4: 'Port configuration training', 5: 'Link up',
          6: 'Link error recovery', 7: 'Phy test'}
    try:
        return '{s} ({n})'.format(s=l[phys], n=phys)
    except KeyError:
        return 'Invalid physical state'


def width_to_str(width):
    l = {1: '1X', 2: '4X', 4: '8X', 8: '12X', 16: '2X'}
    try:
        return '{s} ({n})'.format(s=l[width], n=width)
    except KeyError:
        return 'Invalid width'


def speed_to_str(active_speed, active_speed_ex):
    real_speed = active_speed if not active_speed_ex else active_speed_ex
    l = {0: '0.0 Gbps', 1: '2.5 Gbps', 2: '5.0 Gbps', 4: '5.0 Gbps',
         8: '10.0 Gbps', 16: '14.0 Gbps', 32: '25.0 Gbps', 64: '50.0 Gbps',
         128: '100.0 Gbps', 256: '200.0 Gbps'}
    try:
        return '{s} ({n})'.format(s=l[real_speed], n=real_speed)
    except KeyError:
        return 'Invalid speed'


def get_device_list():
    """
    :return: list of IB_devices on current node
             each list element contains a Device with:
                 device name
                 device node type
                 device transport type
                 device guid
                 device index
    """
    cdef int count = 0;
    cdef v.ibv_device **dev_list;
    dev_list = v.ibv_get_device_list(&count)
    if dev_list == NULL:
            raise PyverbsRDMAError('Failed to get devices list')
    devices = []
    try:
        for i in range(count):
            name = dev_list[i].name
            node = dev_list[i].node_type
            transport = dev_list[i].transport_type
            guid = be64toh(v.ibv_get_device_guid(dev_list[i]))
            index = v.ibv_get_device_index(dev_list[i])
            devices.append(Device(name, guid, node, transport, index))
    finally:
        v.ibv_free_device_list(dev_list)
    return devices


def rdma_get_devices():
    """
    Get the RDMA devices.
    :return: list of Device objects.
    """
    cdef int count
    cdef v.ibv_context **ctx_list
    ctx_list = cm.rdma_get_devices(&count)
    if ctx_list == NULL:
        raise PyverbsRDMAErrno('Failed to get device list')
    devices = []
    for i in range(count):
        name = ctx_list[i].device.name
        node = ctx_list[i].device.node_type
        transport = ctx_list[i].device.transport_type
        guid = be64toh(v.ibv_get_device_guid(ctx_list[i].device))
        index = v.ibv_get_device_index(ctx_list[i].device)
        devices.append(Device(name, guid, node, transport, index))
    cm.rdma_free_devices(ctx_list)
    return devices


def translate_event_type(event_type):
    types = {
        e.IBV_EVENT_CQ_ERR: 'IBV_EVENT_CQ_ERR',
        e.IBV_EVENT_QP_FATAL: 'IBV_EVENT_QP_FATAL',
        e.IBV_EVENT_QP_REQ_ERR: 'IBV_EVENT_QP_REQ_ERR',
        e.IBV_EVENT_QP_ACCESS_ERR: 'IBV_EVENT_QP_ACCESS_ERR',
        e.IBV_EVENT_COMM_EST: 'IBV_EVENT_COMM_EST',
        e.IBV_EVENT_SQ_DRAINED: 'IBV_EVENT_SQ_DRAINED',
        e.IBV_EVENT_PATH_MIG: 'IBV_EVENT_PATH_MIG',
        e.IBV_EVENT_PATH_MIG_ERR: 'IBV_EVENT_PATH_MIG_ERR',
        e.IBV_EVENT_DEVICE_FATAL: 'IBV_EVENT_DEVICE_FATAL',
        e.IBV_EVENT_PORT_ACTIVE: 'IBV_EVENT_PORT_ACTIVE',
        e.IBV_EVENT_PORT_ERR: 'IBV_EVENT_PORT_ERR',
        e.IBV_EVENT_LID_CHANGE: 'IBV_EVENT_LID_CHANGE',
        e.IBV_EVENT_PKEY_CHANGE: 'IBV_EVENT_PKEY_CHANGE',
        e.IBV_EVENT_SM_CHANGE: 'IBV_EVENT_SM_CHANGE',
        e.IBV_EVENT_SRQ_ERR: 'IBV_EVENT_SRQ_ERR',
        e.IBV_EVENT_SRQ_LIMIT_REACHED: 'IBV_EVENT_SRQ_LIMIT_REACHED',
        e.IBV_EVENT_QP_LAST_WQE_REACHED: '.IBV_EVENT_QP_LAST_WQE_REACHED',
        e.IBV_EVENT_CLIENT_REREGISTER: 'IBV_EVENT_CLIENT_REREGISTER',
        e.IBV_EVENT_GID_CHANGE: 'IBV_EVENT_GID_CHANGE',
        e.IBV_EVENT_WQ_FATAL: 'IBV_EVENT_WQ_FATAL',
        e.IBV_EVENT_DEVICE_SPEED_CHANGE: 'IBV_EVENT_DEVICE_SPEED_CHANGE'
    }
    try:
        return types[event_type]
    except KeyError:
        return f'Unknown event_type ({event_type})'


cdef class FdArr(PyverbsObject):
    """
    Represent ibv_fd_arr struct. This class is used a pointer to the file descriptor array
    """
    def __init__(self, arr=[], count=0):
        super().__init__()
        cdef int *dst
        self.attr.arr = <int*>malloc(count * sizeof(int))
        if self.attr.arr == NULL:
            raise PyverbsRDMAErrno('Failed to malloc FD list')
        dst = self.attr.arr
        for i in range(count):
            dst[i]= arr[i]
        self.attr.count = count

    def __dealloc__(self):
        self.close()

    cpdef close(self):
        free(self.attr.arr)

    def __str__(self):
        print_format = '{:20}: {:<20}\n'
        return print_format.format('Number of fd in arr', self.attr.count) +\
               print_format.format('FDs in arr', [self.attr.arr[i] for i in range(self.attr.count)])

    @property
    def arr(self):
        return [self.attr.arr[i] for i in range(self.attr.count)]

    @property
    def count(self):
        return self.attr.count
