|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
This file is provided under a dual BSD/GPLv2 license. When using or
|
|
Packit |
961e70 |
redistributing this file, you may do so under either license.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
GPL LICENSE SUMMARY
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
Copyright(c) 2015 Intel Corporation.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
This program is free software; you can redistribute it and/or modify
|
|
Packit |
961e70 |
it under the terms of version 2 of the GNU General Public License as
|
|
Packit |
961e70 |
published by the Free Software Foundation.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
This program is distributed in the hope that it will be useful, but
|
|
Packit |
961e70 |
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
961e70 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
961e70 |
General Public License for more details.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
Contact Information:
|
|
Packit |
961e70 |
Intel Corporation, www.intel.com
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
BSD LICENSE
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
Copyright(c) 2015 Intel Corporation.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
Redistribution and use in source and binary forms, with or without
|
|
Packit |
961e70 |
modification, are permitted provided that the following conditions
|
|
Packit |
961e70 |
are met:
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
* Redistributions of source code must retain the above copyright
|
|
Packit |
961e70 |
notice, this list of conditions and the following disclaimer.
|
|
Packit |
961e70 |
* Redistributions in binary form must reproduce the above copyright
|
|
Packit |
961e70 |
notice, this list of conditions and the following disclaimer in
|
|
Packit |
961e70 |
the documentation and/or other materials provided with the
|
|
Packit |
961e70 |
distribution.
|
|
Packit |
961e70 |
* Neither the name of Intel Corporation nor the names of its
|
|
Packit |
961e70 |
contributors may be used to endorse or promote products derived
|
|
Packit |
961e70 |
from this software without specific prior written permission.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
961e70 |
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
961e70 |
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
Packit |
961e70 |
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
Packit |
961e70 |
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
Packit |
961e70 |
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
Packit |
961e70 |
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
Packit |
961e70 |
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
Packit |
961e70 |
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
Packit |
961e70 |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
Packit |
961e70 |
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
#ifndef OPA_USER_GEN1_H
|
|
Packit |
961e70 |
#define OPA_USER_GEN1_H
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* This file contains all of the data structures and routines that are
|
|
Packit |
961e70 |
publicly visible and usable (to low level infrastructure code; it is
|
|
Packit |
961e70 |
not expected that any application, or even normal application-level library,
|
|
Packit |
961e70 |
will ever need to use any of this).
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
Additional entry points and data structures that are used by these routines
|
|
Packit |
961e70 |
may be referenced in this file, but they should not be generally available;
|
|
Packit |
961e70 |
they are visible here only to allow use in inlined functions. Any variable,
|
|
Packit |
961e70 |
data structure, or function that starts with a leading "_" is in this
|
|
Packit |
961e70 |
category.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* Include header files we need that are unlikely to otherwise be needed by */
|
|
Packit |
961e70 |
/* programs. */
|
|
Packit |
961e70 |
#include <stddef.h>
|
|
Packit |
961e70 |
#include <stdarg.h>
|
|
Packit |
961e70 |
#include <unistd.h>
|
|
Packit |
961e70 |
#include <errno.h>
|
|
Packit |
961e70 |
#include <string.h>
|
|
Packit |
961e70 |
#include <sys/stat.h>
|
|
Packit |
961e70 |
#include <sys/mman.h>
|
|
Packit |
961e70 |
#include <sys/user.h>
|
|
Packit |
961e70 |
#include <syslog.h>
|
|
Packit Service |
7ed5cc |
#include <stdbool.h>
|
|
Packit |
961e70 |
#include "opa_intf.h"
|
|
Packit |
961e70 |
#include "opa_common_gen1.h"
|
|
Packit |
961e70 |
#include "opa_byteorder.h"
|
|
Packit |
961e70 |
#include "opa_udebug.h"
|
|
Packit |
961e70 |
#include "opa_service_gen1.h"
|
|
Packit |
961e70 |
#include "opa_user.h"
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
#define HFI_RHF_USE_EGRBFR_MASK 0x1
|
|
Packit |
961e70 |
#define HFI_RHF_USE_EGRBFR_SHIFT 15
|
|
Packit |
961e70 |
#define HFI_RHF_EGRBFR_INDEX_MASK 0x7FF
|
|
Packit |
961e70 |
#define HFI_RHF_EGRBFR_INDEX_SHIFT 16
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
#define HFI_RHF_SEQ_MASK 0xF
|
|
Packit |
961e70 |
#define HFI_RHF_SEQ_SHIFT 28
|
|
Packit |
961e70 |
#define HFI_RHF_EGRBFR_OFFSET_MASK 0xFFF
|
|
Packit |
961e70 |
#define HFI_RHF_EGRBFR_OFFSET_SHIFT 0
|
|
Packit |
961e70 |
#define HFI_RHF_HDRQ_OFFSET_MASK 0x1FF
|
|
Packit |
961e70 |
#define HFI_RHF_HDRQ_OFFSET_SHIFT 12
|
|
Packit |
961e70 |
#define HFI_RHF_TIDERR 0x08000000
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* TidFlow related bits */
|
|
Packit |
961e70 |
#define HFI_TF_SEQNUM_SHIFT 0
|
|
Packit |
961e70 |
#define HFI_TF_SEQNUM_MASK 0x7ff
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
#define HFI_TF_GENVAL_SHIFT 11
|
|
Packit |
961e70 |
#define HFI_TF_GENVAL_MASK 0xfffff
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
#define HFI_TF_FLOWVALID_SHIFT 32
|
|
Packit |
961e70 |
#define HFI_TF_FLOWVALID_MASK 0x1
|
|
Packit |
961e70 |
#define HFI_TF_HDRSUPP_ENABLED_SHIFT 33
|
|
Packit |
961e70 |
#define HFI_TF_HDRSUPP_ENABLED_MASK 0x1
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
#define HFI_TF_KEEP_AFTER_SEQERR_SHIFT 34
|
|
Packit |
961e70 |
#define HFI_TF_KEEP_AFTER_SEQERR_MASK 0x1
|
|
Packit |
961e70 |
#define HFI_TF_KEEP_ON_GENERR_SHIFT 35
|
|
Packit |
961e70 |
#define HFI_TF_KEEP_ON_GENERR_MASK 0x1
|
|
Packit |
961e70 |
#define HFI_TF_KEEP_PAYLOAD_ON_GENERR_SHIFT 36
|
|
Packit |
961e70 |
#define HFI_TF_KEEP_PAYLOAD_ON_GENERR_MASK 0x1
|
|
Packit |
961e70 |
#define HFI_TF_STATUS_SEQMISMATCH_SHIFT 37
|
|
Packit |
961e70 |
#define HFI_TF_STATUS_SEQMISMATCH_MASK 0x1
|
|
Packit |
961e70 |
#define HFI_TF_STATUS_GENMISMATCH_SHIFT 38
|
|
Packit |
961e70 |
#define HFI_TF_STATUS_GENMISMATCH_MASK 0x1
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* PBC bits */
|
|
Packit |
961e70 |
#define HFI_PBC_STATICRCC_SHIFT 0
|
|
Packit |
961e70 |
#define HFI_PBC_STATICRCC_MASK 0xffff
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
#define HFI_PBC_SC4_SHIFT 4
|
|
Packit |
961e70 |
#define HFI_PBC_SC4_MASK 0x1
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
#define HFI_PBC_INTR_SHIFT 31
|
|
Packit |
961e70 |
#define HFI_PBC_DCINFO_SHIFT 30
|
|
Packit |
961e70 |
#define HFI_PBC_TESTEBP_SHIFT 29
|
|
Packit |
961e70 |
#define HFI_PBC_PACKETBYPASS_SHIFT 28
|
|
Packit |
961e70 |
#define HFI_PBC_INSERTHCRC_SHIFT 26
|
|
Packit |
961e70 |
#define HFI_PBC_INSERTHCRC_MASK 0x3
|
|
Packit |
961e70 |
#define HFI_PBC_CREDITRETURN_SHIFT 25
|
|
Packit |
961e70 |
#define HFI_PBC_INSERTBYPASSICRC_SHIFT 24
|
|
Packit |
961e70 |
#define HFI_PBC_TESTBADICRC_SHIFT 23
|
|
Packit |
961e70 |
#define HFI_PBC_FECN_SHIFT 22
|
|
Packit |
961e70 |
#define HFI_PBC_VL_SHIFT 12
|
|
Packit |
961e70 |
#define HFI_PBC_VL_MASK 0xf
|
|
Packit |
961e70 |
#define HFI_PBC_LENGTHDWS_SHIFT 0
|
|
Packit |
961e70 |
#define HFI_PBC_LENGTHDWS_MASK 0xfff
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* this portion only defines what we currently use */
|
|
Packit |
961e70 |
struct hfi_pbc {
|
|
Packit |
961e70 |
__u32 pbc0;
|
|
Packit |
961e70 |
__u16 PbcStaticRateControlCnt;
|
|
Packit |
961e70 |
__u16 fill1;
|
|
Packit |
961e70 |
};
|
|
Packit |
961e70 |
|
|
Packit Service |
7ed5cc |
typedef enum mapsize
|
|
Packit Service |
7ed5cc |
{ SC_CREDITS,
|
|
Packit Service |
7ed5cc |
PIO_BUFBASE_SOP,
|
|
Packit Service |
7ed5cc |
PIO_BUFBASE,
|
|
Packit Service |
7ed5cc |
RCVHDR_BUFBASE,
|
|
Packit Service |
7ed5cc |
RCVEGR_BUFBASE,
|
|
Packit Service |
7ed5cc |
SDMA_COMP_BUFBASE,
|
|
Packit Service |
7ed5cc |
USER_REGBASE,
|
|
Packit Service |
7ed5cc |
RCVHDRTAIL_BASE,
|
|
Packit Service |
7ed5cc |
EVENTS_BUFBASE,
|
|
Packit Service |
7ed5cc |
STATUS_BUFBASE,
|
|
Packit Service |
7ed5cc |
SUBCTXT_UREGBASE,
|
|
Packit Service |
7ed5cc |
SUBCTXT_RCVHDRBUF,
|
|
Packit Service |
7ed5cc |
SUBCTXT_RCVEGRBUF,
|
|
Packit Service |
7ed5cc |
MAPSIZE_MAX
|
|
Packit Service |
7ed5cc |
} mapsize_t;
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
/* TODO: consider casting in the ALIGN() macro */
|
|
Packit Service |
7ed5cc |
#define ALIGN(x, a) (((x)+(a)-1)&~((a)-1))
|
|
Packit Service |
7ed5cc |
#define ALIGNDOWN_PTR(x, a) ((void*)(((uintptr_t)(x))&~((uintptr_t)((a)-1))))
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
/* using the same flags for all the mappings */
|
|
Packit Service |
7ed5cc |
#define HFI_MMAP_FLAGS (MAP_SHARED|MAP_LOCKED)
|
|
Packit Service |
7ed5cc |
#define HFI_MMAP_PGSIZE sysconf(_SC_PAGESIZE)
|
|
Packit Service |
7ed5cc |
/* cast to uintptr_t as opposed to intptr_t which evaluates to a signed type
|
|
Packit Service |
7ed5cc |
* * on which one should not perform bitwise operations (undefined behavior)
|
|
Packit Service |
7ed5cc |
* */
|
|
Packit Service |
7ed5cc |
#define HFI_MMAP_PGMASK (~(uintptr_t)(HFI_MMAP_PGSIZE-1))
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
/* this is only an auxiliary macro for HFI_MMAP_ERRCHECK()
|
|
Packit Service |
7ed5cc |
* @off expected to be unsigned in order to AND with the page mask and avoid undefined behavior
|
|
Packit Service |
7ed5cc |
*/
|
|
Packit Service |
7ed5cc |
#define U64_TO_OFF64_PGMASK(off) ((__off64_t)((off) & HFI_MMAP_PGMASK))
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
#define HFI_MMAP_ALIGNOFF(fd, off, size, prot) hfi_mmap64(0,(size),(prot),HFI_MMAP_FLAGS,(fd),U64_TO_OFF64_PGMASK((off)))
|
|
Packit Service |
7ed5cc |
/* complementary */
|
|
Packit Service |
7ed5cc |
#define HFI_MUNMAP(addr, size) munmap((addr), (size))
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
/* make sure uintmax_t can hold the result of unsigned int multiplication */
|
|
Packit Service |
7ed5cc |
#if UINT_MAX > (UINTMAX_MAX / UINT_MAX)
|
|
Packit Service |
7ed5cc |
#error We cannot safely multiply unsigned integers on this platform
|
|
Packit Service |
7ed5cc |
#endif
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
/* @member assumed to be of type u64 and validated to be so */
|
|
Packit Service |
7ed5cc |
#define HFI_MMAP_ERRCHECK(fd, binfo, member, size, prot) ({ \
|
|
Packit Service |
7ed5cc |
typeof((binfo)->member) *__tptr = (__u64 *)NULL; \
|
|
Packit Service |
7ed5cc |
(void)__tptr; \
|
|
Packit Service |
7ed5cc |
void *__maddr = HFI_MMAP_ALIGNOFF((fd), (binfo)->member, (size), (prot)); \
|
|
Packit Service |
7ed5cc |
do { \
|
|
Packit Service |
7ed5cc |
if (unlikely(__maddr == MAP_FAILED)) { \
|
|
Packit Service |
7ed5cc |
uintmax_t outval = (uintmax_t)((binfo)->member); \
|
|
Packit Service |
7ed5cc |
_HFI_INFO("mmap of " #member " (0x%jx) size %zu failed: %s\n", \
|
|
Packit Service |
7ed5cc |
outval, size, strerror(errno)); \
|
|
Packit Service |
7ed5cc |
goto err_mmap_##member; \
|
|
Packit Service |
7ed5cc |
} \
|
|
Packit Service |
7ed5cc |
(binfo)->member = (__u64)__maddr; \
|
|
Packit Service |
7ed5cc |
_HFI_VDBG(#member "mmap %jx successful\n", (uintmax_t)((binfo)->member)); \
|
|
Packit Service |
7ed5cc |
} while(0); \
|
|
Packit Service |
7ed5cc |
__maddr; \
|
|
Packit Service |
7ed5cc |
})
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
/* assigns 0 to the member after unmapping */
|
|
Packit Service |
7ed5cc |
#define HFI_MUNMAP_ERRCHECK(binfo, member, size) \
|
|
Packit Service |
7ed5cc |
do { typeof((binfo)->member) *__tptr = (__u64 *)NULL; \
|
|
Packit Service |
7ed5cc |
(void)__tptr; \
|
|
Packit Service |
7ed5cc |
void *__addr = ALIGNDOWN_PTR((binfo)->member, HFI_MMAP_PGSIZE); \
|
|
Packit Service |
7ed5cc |
if (unlikely( __addr == NULL || (munmap(__addr, (size)) == -1))) { \
|
|
Packit Service |
7ed5cc |
_HFI_INFO("unmap of " #member " (%p) failed: %s\n", \
|
|
Packit Service |
7ed5cc |
__addr, strerror(errno)); \
|
|
Packit Service |
7ed5cc |
} \
|
|
Packit Service |
7ed5cc |
else { \
|
|
Packit Service |
7ed5cc |
_HFI_VDBG("unmap of " #member "(%p) succeeded\n", __addr); \
|
|
Packit Service |
7ed5cc |
(binfo)->member = 0; \
|
|
Packit Service |
7ed5cc |
} \
|
|
Packit Service |
7ed5cc |
} while(0)
|
|
Packit Service |
7ed5cc |
|
|
Packit |
961e70 |
#define HFI_PCB_SIZE_IN_BYTES 8
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* Usable bytes in header (hdrsize - lrh - bth) */
|
|
Packit |
961e70 |
#define HFI_MESSAGE_HDR_SIZE_HFI (HFI_MESSAGE_HDR_SIZE-20)
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* SDMA includes 8B sdma hdr, 8B PBC, and message header.
|
|
Packit |
961e70 |
* If we are using GPU workloads, we need to set a new
|
|
Packit |
961e70 |
* "flags" member which takes another 2 bytes in the
|
|
Packit |
961e70 |
* sdma hdr. We let the driver know of this 2 extra bytes
|
|
Packit |
961e70 |
* at runtime when we set the length for the iovecs.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
#define HFI_SDMA_HDR_SIZE (8+8+56)
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static inline __u32 hfi_hdrget_seq(const __le32 *rbuf)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
return (__le32_to_cpu(rbuf[0]) >> HFI_RHF_SEQ_SHIFT)
|
|
Packit |
961e70 |
& HFI_RHF_SEQ_MASK;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static inline __u32 hfi_hdrget_hdrq_offset(const __le32 *rbuf)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
return (__le32_to_cpu(rbuf[1]) >> HFI_RHF_HDRQ_OFFSET_SHIFT)
|
|
Packit |
961e70 |
& HFI_RHF_HDRQ_OFFSET_MASK;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
struct _hfi_ctrl {
|
|
Packit |
961e70 |
int32_t fd; /* device file descriptor */
|
|
Packit |
961e70 |
/* tidflow valid */
|
|
Packit |
961e70 |
uint32_t __hfi_tfvalid;
|
|
Packit |
961e70 |
/* unit id */
|
|
Packit |
961e70 |
uint32_t __hfi_unit;
|
|
Packit |
961e70 |
/* port id */
|
|
Packit |
961e70 |
uint32_t __hfi_port;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* number of eager tid entries */
|
|
Packit |
961e70 |
uint32_t __hfi_tidegrcnt;
|
|
Packit |
961e70 |
/* number of expected tid entries */
|
|
Packit |
961e70 |
uint32_t __hfi_tidexpcnt;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* effective mtu size, should be <= base_info.mtu */
|
|
Packit |
961e70 |
uint32_t __hfi_mtusize;
|
|
Packit |
961e70 |
/* max PIO size, should be <= effective mtu size */
|
|
Packit |
961e70 |
uint32_t __hfi_piosize;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* two struct output from driver. */
|
|
Packit |
961e70 |
struct hfi1_ctxt_info ctxt_info;
|
|
Packit |
961e70 |
struct hfi1_base_info base_info;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* some local storages in some condition: */
|
|
Packit Service |
7ed5cc |
/* as storage of __hfi_rcvtidflow in hfi_userinit_internal(). */
|
|
Packit |
961e70 |
__le64 regs[HFI_TF_NFLOWS];
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* location to which OPA writes the rcvhdrtail register whenever
|
|
Packit |
961e70 |
it changes, so that no chip registers are read in the performance
|
|
Packit |
961e70 |
path. */
|
|
Packit |
961e70 |
volatile __le64 *__hfi_rcvtail;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* address where ur_rcvhdrtail is written */
|
|
Packit |
961e70 |
volatile __le64 *__hfi_rcvhdrtail;
|
|
Packit |
961e70 |
/* address where ur_rcvhdrhead is written */
|
|
Packit |
961e70 |
volatile __le64 *__hfi_rcvhdrhead;
|
|
Packit |
961e70 |
/* address where ur_rcvegrindextail is read */
|
|
Packit |
961e70 |
volatile __le64 *__hfi_rcvegrtail;
|
|
Packit |
961e70 |
/* address where ur_rcvegrindexhead is written */
|
|
Packit |
961e70 |
volatile __le64 *__hfi_rcvegrhead;
|
|
Packit |
961e70 |
/* address where ur_rcvegroffsettail is read */
|
|
Packit |
961e70 |
volatile __le64 *__hfi_rcvofftail;
|
|
Packit |
961e70 |
/* address where ur_rcvtidflow is written */
|
|
Packit |
961e70 |
volatile __le64 *__hfi_rcvtidflow;
|
|
Packit |
961e70 |
};
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* After the device is opened, hfi_userinit() is called to give the driver the
|
|
Packit |
961e70 |
parameters the user code wants to use, and to get the implementation values,
|
|
Packit |
961e70 |
etc. back. 0 is returned on success, a positive value is a standard errno,
|
|
Packit |
961e70 |
and a negative value is reserved for future use. The first argument is
|
|
Packit |
961e70 |
the filedescriptor returned by the device open.
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
It is allowed to have multiple devices (and of different types)
|
|
Packit |
961e70 |
simultaneously opened and initialized, although this won't be fully
|
|
Packit |
961e70 |
implemented initially. This routine is used by the low level
|
|
Packit |
961e70 |
hfi protocol code (and any other code that has similar low level
|
|
Packit |
961e70 |
functionality).
|
|
Packit |
961e70 |
This is the only routine that takes a file descriptor, rather than an
|
|
Packit |
961e70 |
struct _hfi_ctrl *. The struct _hfi_ctrl * used for everything
|
|
Packit |
961e70 |
else is returned by this routine.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
struct _hfi_ctrl *hfi_userinit(int32_t, struct hfi1_user_info_dep *);
|
|
Packit |
961e70 |
|
|
Packit Service |
7ed5cc |
/* Internal function extends API, while original remains for backwards
|
|
Packit Service |
7ed5cc |
compatibility with external code
|
|
Packit Service |
7ed5cc |
*/
|
|
Packit Service |
7ed5cc |
struct _hfi_ctrl *hfi_userinit_internal(int32_t, bool, struct hfi1_user_info_dep *);
|
|
Packit Service |
7ed5cc |
|
|
Packit |
961e70 |
/* don't inline these; it's all init code, and not inlining makes the */
|
|
Packit |
961e70 |
/* overall code shorter and easier to debug */
|
|
Packit |
961e70 |
void hfi_touch_mmap(void *, size_t) __attribute__ ((noinline));
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* set the BTH pkey to check for this process. */
|
|
Packit |
961e70 |
/* This is for receive checks, not for sends. It isn't necessary
|
|
Packit |
961e70 |
to set the default key, that's always allowed by the hardware.
|
|
Packit |
961e70 |
If too many pkeys are in use for the hardware to support, this
|
|
Packit |
961e70 |
will return EAGAIN, and the caller should then fail and exit
|
|
Packit |
961e70 |
or use the default key and check the pkey in the received packet
|
|
Packit |
961e70 |
checking. */
|
|
Packit |
961e70 |
/* set send context pkey to verify, error if driver is not configured with */
|
|
Packit |
961e70 |
/* this pkey in its pkey table. */
|
|
Packit |
961e70 |
int hfi_set_pkey(struct _hfi_ctrl *, uint16_t);
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
int hfi_wait_for_packet(struct _hfi_ctrl *);
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* New user event mechanism, using spi_sendbuf_status HFI_EVENT_* bits
|
|
Packit |
961e70 |
obsoletes hfi_disarm_bufs(), and extends it, although old mechanism
|
|
Packit |
961e70 |
remains for binary compatibility. */
|
|
Packit |
961e70 |
int hfi_event_ack(struct _hfi_ctrl *ctrl, __u64 ackbits);
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* set whether we want an interrupt on all packets, or just urgent ones */
|
|
Packit |
961e70 |
int hfi_poll_type(struct _hfi_ctrl *ctrl, uint16_t poll_type);
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* reset halted send context, error if context is not halted. */
|
|
Packit |
961e70 |
int hfi_reset_context(struct _hfi_ctrl *ctrl);
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* Safe version of hfi_[d/q]wordcpy that is guaranteed to only copy each byte once.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
#if defined(__x86_64__)
|
|
Packit |
961e70 |
void hfi_dwordcpy_safe(volatile uint32_t *dest, const uint32_t *src,
|
|
Packit |
961e70 |
uint32_t ndwords);
|
|
Packit |
961e70 |
void hfi_qwordcpy_safe(volatile uint64_t *dest, const uint64_t *src,
|
|
Packit |
961e70 |
uint32_t nqwords);
|
|
Packit |
961e70 |
#else
|
|
Packit |
961e70 |
#define hfi_dwordcpy_safe hfi_dwordcpy
|
|
Packit |
961e70 |
#define hfi_qwordcpy_safe hfi_qwordcpy
|
|
Packit |
961e70 |
#endif
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static __inline__ void hfi_tidflow_set_entry(struct _hfi_ctrl *ctrl,
|
|
Packit |
961e70 |
uint32_t flowid, uint32_t genval,
|
|
Packit |
961e70 |
uint32_t seqnum)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
/* For proper behavior with RSM interception of FECN packets for CCA,
|
|
Packit |
961e70 |
* the tidflow entry needs the KeepAfterSequenceError bit set.
|
|
Packit |
961e70 |
* A packet that is converted from expected to eager by RSM will not
|
|
Packit |
961e70 |
* trigger an update in the tidflow state. This will cause the tidflow
|
|
Packit |
961e70 |
* to incorrectly report a sequence error on any non-FECN packets that
|
|
Packit |
961e70 |
* arrive after the RSM intercepted packets. If the KeepAfterSequenceError
|
|
Packit |
961e70 |
* bit is set, PSM can properly detect this "false SeqErr" condition,
|
|
Packit |
961e70 |
* and recover without dropping packets.
|
|
Packit |
961e70 |
* Note that if CCA/RSM are not important, this change will slightly
|
|
Packit |
961e70 |
* increase the CPU load when packets are dropped. If this is significant,
|
|
Packit |
961e70 |
* consider hiding this change behind a CCA/RSM environment variable.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
ctrl->__hfi_rcvtidflow[flowid] = __cpu_to_le64(
|
|
Packit |
961e70 |
((genval & HFI_TF_GENVAL_MASK) << HFI_TF_GENVAL_SHIFT) |
|
|
Packit |
961e70 |
((seqnum & HFI_TF_SEQNUM_MASK) << HFI_TF_SEQNUM_SHIFT) |
|
|
Packit |
961e70 |
((uint64_t)ctrl->__hfi_tfvalid << HFI_TF_FLOWVALID_SHIFT) |
|
|
Packit |
961e70 |
(1ULL << HFI_TF_HDRSUPP_ENABLED_SHIFT) |
|
|
Packit |
961e70 |
/* KeepAfterSequenceError = 1 -- previously was 0 */
|
|
Packit |
961e70 |
(1ULL << HFI_TF_KEEP_AFTER_SEQERR_SHIFT) |
|
|
Packit |
961e70 |
(1ULL << HFI_TF_KEEP_ON_GENERR_SHIFT) |
|
|
Packit |
961e70 |
/* KeePayloadOnGenErr = 0 */
|
|
Packit |
961e70 |
(1ULL << HFI_TF_STATUS_SEQMISMATCH_SHIFT) |
|
|
Packit |
961e70 |
(1ULL << HFI_TF_STATUS_GENMISMATCH_SHIFT));
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static __inline__ void hfi_tidflow_reset(struct _hfi_ctrl *ctrl,
|
|
Packit |
961e70 |
uint32_t flowid, uint32_t genval,
|
|
Packit |
961e70 |
uint32_t seqnum)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* If a tidflow table entry is set to "Invalid", we want to drop
|
|
Packit |
961e70 |
* header if payload is dropped, we want to get a header if the payload
|
|
Packit |
961e70 |
* is delivered.
|
|
Packit |
961e70 |
*
|
|
Packit |
961e70 |
* We set a tidflow table entry "Invalid" by setting FlowValid=1 and
|
|
Packit |
961e70 |
* GenVal=0x1FFF/0xFFFFF, this is a special generation number and no
|
|
Packit |
961e70 |
* packet will use this value. We don't care SeqNum but we set it to
|
|
Packit |
961e70 |
* 0x7FF. So if GenVal does not match, the payload is dropped because
|
|
Packit |
961e70 |
* KeepPayloadOnGenErr=0; for packet header, KeepOnGenErr=0 make sure
|
|
Packit |
961e70 |
* header is not generated. But if a packet happens to have the special
|
|
Packit |
961e70 |
* generation number, the payload is delivered, HdrSuppEnabled=0 make
|
|
Packit |
961e70 |
* sure header is generated if SeqNUm matches, if SeqNum does not match,
|
|
Packit |
961e70 |
* KeepAfterSeqErr=1 makes sure the header is generated.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
ctrl->__hfi_rcvtidflow[flowid] = __cpu_to_le64(
|
|
Packit |
961e70 |
/* genval = 0x1FFF or 0xFFFFF */
|
|
Packit |
961e70 |
((genval & HFI_TF_GENVAL_MASK) << HFI_TF_GENVAL_SHIFT) |
|
|
Packit |
961e70 |
/* seqnum = 0x7FF */
|
|
Packit |
961e70 |
((seqnum & HFI_TF_SEQNUM_MASK) << HFI_TF_SEQNUM_SHIFT) |
|
|
Packit |
961e70 |
((uint64_t)ctrl->__hfi_tfvalid << HFI_TF_FLOWVALID_SHIFT) |
|
|
Packit |
961e70 |
/* HdrSuppEnabled = 0 */
|
|
Packit |
961e70 |
(1ULL << HFI_TF_KEEP_AFTER_SEQERR_SHIFT) |
|
|
Packit |
961e70 |
/* KeepOnGenErr = 0 */
|
|
Packit |
961e70 |
/* KeepPayloadOnGenErr = 0 */
|
|
Packit |
961e70 |
(1ULL << HFI_TF_STATUS_SEQMISMATCH_SHIFT) |
|
|
Packit |
961e70 |
(1ULL << HFI_TF_STATUS_GENMISMATCH_SHIFT));
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* This should only be used for debugging.
|
|
Packit |
961e70 |
* Normally, we shouldn't read the chip.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
static __inline__ uint64_t hfi_tidflow_get(struct _hfi_ctrl *ctrl,
|
|
Packit |
961e70 |
uint32_t flowid)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
return __le64_to_cpu(ctrl->__hfi_rcvtidflow[flowid]);
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static __inline__ uint32_t hfi_tidflow_get_seqnum(uint64_t val)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
return (val >> HFI_TF_SEQNUM_SHIFT) & HFI_TF_SEQNUM_MASK;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static __inline__ uint32_t hfi_tidflow_get_genval(uint64_t val)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
return (val >> HFI_TF_GENVAL_SHIFT) & HFI_TF_GENVAL_MASK;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static __inline__ uint32_t hfi_tidflow_get_flowvalid(uint64_t val)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
return (val >> HFI_TF_FLOWVALID_SHIFT) & HFI_TF_FLOWVALID_MASK;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static __inline__ uint32_t hfi_tidflow_get_enabled(uint64_t val)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
return (val >> HFI_TF_HDRSUPP_ENABLED_SHIFT) &
|
|
Packit |
961e70 |
HFI_TF_HDRSUPP_ENABLED_MASK;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static __inline__ uint32_t hfi_tidflow_get_keep_after_seqerr(uint64_t val)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
return (val >> HFI_TF_KEEP_AFTER_SEQERR_SHIFT) &
|
|
Packit |
961e70 |
HFI_TF_KEEP_AFTER_SEQERR_MASK;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static __inline__ uint32_t hfi_tidflow_get_keep_on_generr(uint64_t val)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
return (val >> HFI_TF_KEEP_ON_GENERR_SHIFT) &
|
|
Packit |
961e70 |
HFI_TF_KEEP_ON_GENERR_MASK;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static __inline__ uint32_t hfi_tidflow_get_keep_payload_on_generr(uint64_t val)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
return (val >> HFI_TF_KEEP_PAYLOAD_ON_GENERR_SHIFT) &
|
|
Packit |
961e70 |
HFI_TF_KEEP_PAYLOAD_ON_GENERR_MASK;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static __inline__ uint32_t hfi_tidflow_get_seqmismatch(uint64_t val)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
return (val >> HFI_TF_STATUS_SEQMISMATCH_SHIFT) &
|
|
Packit |
961e70 |
HFI_TF_STATUS_SEQMISMATCH_MASK;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static __inline__ uint32_t hfi_tidflow_get_genmismatch(uint64_t val)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
return (val >> HFI_TF_STATUS_GENMISMATCH_SHIFT) &
|
|
Packit |
961e70 |
HFI_TF_STATUS_GENMISMATCH_MASK;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* This should only be used by a process to write the eager index into
|
|
Packit |
961e70 |
* a subcontext's eager header entry.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
static __inline__ void hfi_hdrset_use_egrbfr(__le32 *rbuf, uint32_t val)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
rbuf[0] =
|
|
Packit |
961e70 |
(rbuf[0] &
|
|
Packit |
961e70 |
__cpu_to_le32(~(HFI_RHF_USE_EGRBFR_MASK <<
|
|
Packit |
961e70 |
HFI_RHF_USE_EGRBFR_SHIFT))) |
|
|
Packit |
961e70 |
__cpu_to_le32((val & HFI_RHF_USE_EGRBFR_MASK) <<
|
|
Packit |
961e70 |
HFI_RHF_USE_EGRBFR_SHIFT);
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static __inline__ void hfi_hdrset_egrbfr_index(__le32 *rbuf, uint32_t val)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
rbuf[0] =
|
|
Packit |
961e70 |
(rbuf[0] &
|
|
Packit |
961e70 |
__cpu_to_le32(~(HFI_RHF_EGRBFR_INDEX_MASK <<
|
|
Packit |
961e70 |
HFI_RHF_EGRBFR_INDEX_SHIFT))) |
|
|
Packit |
961e70 |
__cpu_to_le32((val & HFI_RHF_EGRBFR_INDEX_MASK) <<
|
|
Packit |
961e70 |
HFI_RHF_EGRBFR_INDEX_SHIFT);
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static __inline__ void hfi_hdrset_egrbfr_offset(__le32 *rbuf, uint32_t val)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
rbuf[1] =
|
|
Packit |
961e70 |
(rbuf[1] &
|
|
Packit |
961e70 |
__cpu_to_le32(~(HFI_RHF_EGRBFR_OFFSET_MASK <<
|
|
Packit |
961e70 |
HFI_RHF_EGRBFR_OFFSET_SHIFT))) |
|
|
Packit |
961e70 |
__cpu_to_le32((val & HFI_RHF_EGRBFR_OFFSET_MASK) <<
|
|
Packit |
961e70 |
HFI_RHF_EGRBFR_OFFSET_SHIFT);
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* This should only be used by a process to update the receive header
|
|
Packit |
961e70 |
* error flags.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
static __inline__ void hfi_hdrset_err_flags(__le32 *rbuf, uint32_t val)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
rbuf[1] |= __cpu_to_le32(val);
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* This should only be used by a process to write the rhf seq number into
|
|
Packit |
961e70 |
* a subcontext's eager header entry.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
static __inline__ void hfi_hdrset_seq(__le32 *rbuf, uint32_t val)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
rbuf[0] =
|
|
Packit |
961e70 |
(rbuf[0] &
|
|
Packit |
961e70 |
__cpu_to_le32(~(HFI_RHF_SEQ_MASK <<
|
|
Packit |
961e70 |
HFI_RHF_SEQ_SHIFT))) |
|
|
Packit |
961e70 |
__cpu_to_le32((val & HFI_RHF_SEQ_MASK) << HFI_RHF_SEQ_SHIFT);
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* Manage TID entries. It is possible that not all entries
|
|
Packit |
961e70 |
requested may be allocated. A matching hfi_free_tid() must be
|
|
Packit |
961e70 |
done for each hfi_update_tid(), because currently no caching or
|
|
Packit |
961e70 |
reuse of expected tid entries is allowed, to work around malloc/free
|
|
Packit |
961e70 |
and mmap/munmap issues. The driver decides which TID entries to allocate.
|
|
Packit |
961e70 |
If hfi_free_tid is called to free entries in use by a different
|
|
Packit |
961e70 |
send by the same process, data corruption will probably occur,
|
|
Packit |
961e70 |
but only within that process, not for other processes.
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/* update tidcnt expected TID entries from the array pointed to by tidinfo. */
|
|
Packit |
961e70 |
/* Returns 0 on success, else an errno. See full description at declaration */
|
|
Packit |
961e70 |
static __inline__ int32_t hfi_update_tid(struct _hfi_ctrl *ctrl,
|
|
Packit |
961e70 |
uint64_t vaddr, uint32_t *length,
|
|
Packit |
961e70 |
uint64_t tidlist, uint32_t *tidcnt, uint16_t flags)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
struct hfi1_cmd cmd;
|
|
Packit |
961e70 |
struct hfi1_tid_info tidinfo;
|
|
Packit Service |
7ed5cc |
#ifdef PSM_CUDA
|
|
Packit Service |
7ed5cc |
struct hfi1_tid_info_v2 tidinfov2;
|
|
Packit |
961e70 |
#endif
|
|
Packit |
961e70 |
int err;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
tidinfo.vaddr = vaddr; /* base address for this send to map */
|
|
Packit |
961e70 |
tidinfo.length = *length; /* length of vaddr */
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
tidinfo.tidlist = tidlist; /* driver copies tids back directly */
|
|
Packit |
961e70 |
tidinfo.tidcnt = 0; /* clear to zero */
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
cmd.type = PSMI_HFI_CMD_TID_UPDATE;
|
|
Packit |
961e70 |
cmd.len = sizeof(tidinfo);
|
|
Packit |
961e70 |
cmd.addr = (__u64) &tidinfo;
|
|
Packit Service |
7ed5cc |
#ifdef PSM_CUDA
|
|
Packit Service |
7ed5cc |
if (PSMI_IS_DRIVER_GPUDIRECT_ENABLED) {
|
|
Packit Service |
7ed5cc |
/* Copy values to v2 struct */
|
|
Packit Service |
7ed5cc |
tidinfov2.vaddr = tidinfo.vaddr;
|
|
Packit Service |
7ed5cc |
tidinfov2.length = tidinfo.length;
|
|
Packit Service |
7ed5cc |
tidinfov2.tidlist = tidinfo.tidlist;
|
|
Packit Service |
7ed5cc |
tidinfov2.tidcnt = tidinfo.tidcnt;
|
|
Packit Service |
7ed5cc |
tidinfov2.flags = flags;
|
|
Packit Service |
7ed5cc |
|
|
Packit Service |
7ed5cc |
cmd.type = PSMI_HFI_CMD_TID_UPDATE_V2;
|
|
Packit Service |
7ed5cc |
cmd.len = sizeof(tidinfov2);
|
|
Packit Service |
7ed5cc |
cmd.addr = (__u64) &tidinfov2;
|
|
Packit Service |
7ed5cc |
}
|
|
Packit Service |
7ed5cc |
#endif
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
err = hfi_cmd_write(ctrl->fd, &cmd, sizeof(cmd));
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
if (err != -1) {
|
|
Packit Service |
7ed5cc |
struct hfi1_tid_info *rettidinfo =
|
|
Packit Service |
7ed5cc |
(struct hfi1_tid_info *)cmd.addr;
|
|
Packit Service |
7ed5cc |
*length = rettidinfo->length;
|
|
Packit Service |
7ed5cc |
*tidcnt = rettidinfo->tidcnt;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
return err;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static __inline__ int32_t hfi_free_tid(struct _hfi_ctrl *ctrl,
|
|
Packit |
961e70 |
uint64_t tidlist, uint32_t tidcnt)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
struct hfi1_cmd cmd;
|
|
Packit |
961e70 |
struct hfi1_tid_info tidinfo;
|
|
Packit |
961e70 |
int err;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
tidinfo.tidlist = tidlist; /* input to driver */
|
|
Packit |
961e70 |
tidinfo.tidcnt = tidcnt;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
cmd.type = PSMI_HFI_CMD_TID_FREE;
|
|
Packit |
961e70 |
cmd.len = sizeof(tidinfo);
|
|
Packit |
961e70 |
cmd.addr = (__u64) &tidinfo;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
err = hfi_cmd_write(ctrl->fd, &cmd, sizeof(cmd));
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
return err;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
static __inline__ int32_t hfi_get_invalidation(struct _hfi_ctrl *ctrl,
|
|
Packit |
961e70 |
uint64_t tidlist, uint32_t *tidcnt)
|
|
Packit |
961e70 |
{
|
|
Packit |
961e70 |
struct hfi1_cmd cmd;
|
|
Packit |
961e70 |
struct hfi1_tid_info tidinfo;
|
|
Packit |
961e70 |
int err;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
tidinfo.tidlist = tidlist; /* driver copies tids back directly */
|
|
Packit |
961e70 |
tidinfo.tidcnt = 0; /* clear to zero */
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
cmd.type = PSMI_HFI_CMD_TID_INVAL_READ;
|
|
Packit |
961e70 |
cmd.len = sizeof(tidinfo);
|
|
Packit |
961e70 |
cmd.addr = (__u64) &tidinfo;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
err = hfi_cmd_write(ctrl->fd, &cmd, sizeof(cmd));
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
if (err != -1)
|
|
Packit |
961e70 |
*tidcnt = tidinfo.tidcnt;
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
return err;
|
|
Packit |
961e70 |
}
|
|
Packit |
961e70 |
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* Data layout in I2C flash (for GUID, etc.)
|
|
Packit |
961e70 |
* All fields are little-endian binary unless otherwise stated
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
#define HFI_FLASH_VERSION 2
|
|
Packit |
961e70 |
struct hfi_flash {
|
|
Packit |
961e70 |
/* flash layout version (HFI_FLASH_VERSION) */
|
|
Packit |
961e70 |
__u8 if_fversion;
|
|
Packit |
961e70 |
/* checksum protecting if_length bytes */
|
|
Packit |
961e70 |
__u8 if_csum;
|
|
Packit |
961e70 |
/*
|
|
Packit |
961e70 |
* valid length (in use, protected by if_csum), including
|
|
Packit |
961e70 |
* if_fversion and if_csum themselves)
|
|
Packit |
961e70 |
*/
|
|
Packit |
961e70 |
__u8 if_length;
|
|
Packit |
961e70 |
/* the GUID, in network order */
|
|
Packit |
961e70 |
__u8 if_guid[8];
|
|
Packit |
961e70 |
/* number of GUIDs to use, starting from if_guid */
|
|
Packit |
961e70 |
__u8 if_numguid;
|
|
Packit |
961e70 |
/* the (last 10 characters of) board serial number, in ASCII */
|
|
Packit |
961e70 |
char if_serial[12];
|
|
Packit |
961e70 |
/* board mfg date (YYYYMMDD ASCII) */
|
|
Packit |
961e70 |
char if_mfgdate[8];
|
|
Packit |
961e70 |
/* last board rework/test date (YYYYMMDD ASCII) */
|
|
Packit |
961e70 |
char if_testdate[8];
|
|
Packit |
961e70 |
/* logging of error counts, TBD */
|
|
Packit |
961e70 |
__u8 if_errcntp[4];
|
|
Packit |
961e70 |
/* powered on hours, updated at driver unload */
|
|
Packit |
961e70 |
__u8 if_powerhour[2];
|
|
Packit |
961e70 |
/* ASCII free-form comment field */
|
|
Packit |
961e70 |
char if_comment[32];
|
|
Packit |
961e70 |
/* Backwards compatible prefix for longer QLogic Serial Numbers */
|
|
Packit |
961e70 |
char if_sprefix[4];
|
|
Packit |
961e70 |
/* 82 bytes used, min flash size is 128 bytes */
|
|
Packit |
961e70 |
__u8 if_future[46];
|
|
Packit |
961e70 |
};
|
|
Packit |
961e70 |
#endif /* OPA_USER_GEN1_H */
|