162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright(c) 2020-2023 Cornelis Networks, Inc. 462306a36Sopenharmony_ci * Copyright(c) 2015-2020 Intel Corporation. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifndef _HFI1_KERNEL_H 862306a36Sopenharmony_ci#define _HFI1_KERNEL_H 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/refcount.h> 1162306a36Sopenharmony_ci#include <linux/interrupt.h> 1262306a36Sopenharmony_ci#include <linux/pci.h> 1362306a36Sopenharmony_ci#include <linux/dma-mapping.h> 1462306a36Sopenharmony_ci#include <linux/mutex.h> 1562306a36Sopenharmony_ci#include <linux/list.h> 1662306a36Sopenharmony_ci#include <linux/scatterlist.h> 1762306a36Sopenharmony_ci#include <linux/slab.h> 1862306a36Sopenharmony_ci#include <linux/io.h> 1962306a36Sopenharmony_ci#include <linux/fs.h> 2062306a36Sopenharmony_ci#include <linux/completion.h> 2162306a36Sopenharmony_ci#include <linux/kref.h> 2262306a36Sopenharmony_ci#include <linux/sched.h> 2362306a36Sopenharmony_ci#include <linux/cdev.h> 2462306a36Sopenharmony_ci#include <linux/delay.h> 2562306a36Sopenharmony_ci#include <linux/kthread.h> 2662306a36Sopenharmony_ci#include <linux/i2c.h> 2762306a36Sopenharmony_ci#include <linux/i2c-algo-bit.h> 2862306a36Sopenharmony_ci#include <linux/xarray.h> 2962306a36Sopenharmony_ci#include <rdma/ib_hdrs.h> 3062306a36Sopenharmony_ci#include <rdma/opa_addr.h> 3162306a36Sopenharmony_ci#include <linux/rhashtable.h> 3262306a36Sopenharmony_ci#include <rdma/rdma_vt.h> 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#include "chip_registers.h" 3562306a36Sopenharmony_ci#include "common.h" 3662306a36Sopenharmony_ci#include "opfn.h" 3762306a36Sopenharmony_ci#include "verbs.h" 3862306a36Sopenharmony_ci#include "pio.h" 3962306a36Sopenharmony_ci#include "chip.h" 4062306a36Sopenharmony_ci#include "mad.h" 4162306a36Sopenharmony_ci#include "qsfp.h" 4262306a36Sopenharmony_ci#include "platform.h" 4362306a36Sopenharmony_ci#include "affinity.h" 4462306a36Sopenharmony_ci#include "msix.h" 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci/* bumped 1 from s/w major version of TrueScale */ 4762306a36Sopenharmony_ci#define HFI1_CHIP_VERS_MAJ 3U 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci/* don't care about this except printing */ 5062306a36Sopenharmony_ci#define HFI1_CHIP_VERS_MIN 0U 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/* The Organization Unique Identifier (Mfg code), and its position in GUID */ 5362306a36Sopenharmony_ci#define HFI1_OUI 0x001175 5462306a36Sopenharmony_ci#define HFI1_OUI_LSB 40 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#define DROP_PACKET_OFF 0 5762306a36Sopenharmony_ci#define DROP_PACKET_ON 1 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci#define NEIGHBOR_TYPE_HFI 0 6062306a36Sopenharmony_ci#define NEIGHBOR_TYPE_SWITCH 1 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci#define HFI1_MAX_ACTIVE_WORKQUEUE_ENTRIES 5 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ciextern unsigned long hfi1_cap_mask; 6562306a36Sopenharmony_ci#define HFI1_CAP_KGET_MASK(mask, cap) ((mask) & HFI1_CAP_##cap) 6662306a36Sopenharmony_ci#define HFI1_CAP_UGET_MASK(mask, cap) \ 6762306a36Sopenharmony_ci (((mask) >> HFI1_CAP_USER_SHIFT) & HFI1_CAP_##cap) 6862306a36Sopenharmony_ci#define HFI1_CAP_KGET(cap) (HFI1_CAP_KGET_MASK(hfi1_cap_mask, cap)) 6962306a36Sopenharmony_ci#define HFI1_CAP_UGET(cap) (HFI1_CAP_UGET_MASK(hfi1_cap_mask, cap)) 7062306a36Sopenharmony_ci#define HFI1_CAP_IS_KSET(cap) (!!HFI1_CAP_KGET(cap)) 7162306a36Sopenharmony_ci#define HFI1_CAP_IS_USET(cap) (!!HFI1_CAP_UGET(cap)) 7262306a36Sopenharmony_ci#define HFI1_MISC_GET() ((hfi1_cap_mask >> HFI1_CAP_MISC_SHIFT) & \ 7362306a36Sopenharmony_ci HFI1_CAP_MISC_MASK) 7462306a36Sopenharmony_ci/* Offline Disabled Reason is 4-bits */ 7562306a36Sopenharmony_ci#define HFI1_ODR_MASK(rsn) ((rsn) & OPA_PI_MASK_OFFLINE_REASON) 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci/* 7862306a36Sopenharmony_ci * Control context is always 0 and handles the error packets. 7962306a36Sopenharmony_ci * It also handles the VL15 and multicast packets. 8062306a36Sopenharmony_ci */ 8162306a36Sopenharmony_ci#define HFI1_CTRL_CTXT 0 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci/* 8462306a36Sopenharmony_ci * Driver context will store software counters for each of the events 8562306a36Sopenharmony_ci * associated with these status registers 8662306a36Sopenharmony_ci */ 8762306a36Sopenharmony_ci#define NUM_CCE_ERR_STATUS_COUNTERS 41 8862306a36Sopenharmony_ci#define NUM_RCV_ERR_STATUS_COUNTERS 64 8962306a36Sopenharmony_ci#define NUM_MISC_ERR_STATUS_COUNTERS 13 9062306a36Sopenharmony_ci#define NUM_SEND_PIO_ERR_STATUS_COUNTERS 36 9162306a36Sopenharmony_ci#define NUM_SEND_DMA_ERR_STATUS_COUNTERS 4 9262306a36Sopenharmony_ci#define NUM_SEND_EGRESS_ERR_STATUS_COUNTERS 64 9362306a36Sopenharmony_ci#define NUM_SEND_ERR_STATUS_COUNTERS 3 9462306a36Sopenharmony_ci#define NUM_SEND_CTXT_ERR_STATUS_COUNTERS 5 9562306a36Sopenharmony_ci#define NUM_SEND_DMA_ENG_ERR_STATUS_COUNTERS 24 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci/* 9862306a36Sopenharmony_ci * per driver stats, either not device nor port-specific, or 9962306a36Sopenharmony_ci * summed over all of the devices and ports. 10062306a36Sopenharmony_ci * They are described by name via ipathfs filesystem, so layout 10162306a36Sopenharmony_ci * and number of elements can change without breaking compatibility. 10262306a36Sopenharmony_ci * If members are added or deleted hfi1_statnames[] in debugfs.c must 10362306a36Sopenharmony_ci * change to match. 10462306a36Sopenharmony_ci */ 10562306a36Sopenharmony_cistruct hfi1_ib_stats { 10662306a36Sopenharmony_ci __u64 sps_ints; /* number of interrupts handled */ 10762306a36Sopenharmony_ci __u64 sps_errints; /* number of error interrupts */ 10862306a36Sopenharmony_ci __u64 sps_txerrs; /* tx-related packet errors */ 10962306a36Sopenharmony_ci __u64 sps_rcverrs; /* non-crc rcv packet errors */ 11062306a36Sopenharmony_ci __u64 sps_hwerrs; /* hardware errors reported (parity, etc.) */ 11162306a36Sopenharmony_ci __u64 sps_nopiobufs; /* no pio bufs avail from kernel */ 11262306a36Sopenharmony_ci __u64 sps_ctxts; /* number of contexts currently open */ 11362306a36Sopenharmony_ci __u64 sps_lenerrs; /* number of kernel packets where RHF != LRH len */ 11462306a36Sopenharmony_ci __u64 sps_buffull; 11562306a36Sopenharmony_ci __u64 sps_hdrfull; 11662306a36Sopenharmony_ci}; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ciextern struct hfi1_ib_stats hfi1_stats; 11962306a36Sopenharmony_ciextern const struct pci_error_handlers hfi1_pci_err_handler; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ciextern int num_driver_cntrs; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci/* 12462306a36Sopenharmony_ci * First-cut criterion for "device is active" is 12562306a36Sopenharmony_ci * two thousand dwords combined Tx, Rx traffic per 12662306a36Sopenharmony_ci * 5-second interval. SMA packets are 64 dwords, 12762306a36Sopenharmony_ci * and occur "a few per second", presumably each way. 12862306a36Sopenharmony_ci */ 12962306a36Sopenharmony_ci#define HFI1_TRAFFIC_ACTIVE_THRESHOLD (2000) 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci/* 13262306a36Sopenharmony_ci * Below contains all data related to a single context (formerly called port). 13362306a36Sopenharmony_ci */ 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_cistruct hfi1_opcode_stats_perctx; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_cistruct ctxt_eager_bufs { 13862306a36Sopenharmony_ci struct eager_buffer { 13962306a36Sopenharmony_ci void *addr; 14062306a36Sopenharmony_ci dma_addr_t dma; 14162306a36Sopenharmony_ci ssize_t len; 14262306a36Sopenharmony_ci } *buffers; 14362306a36Sopenharmony_ci struct { 14462306a36Sopenharmony_ci void *addr; 14562306a36Sopenharmony_ci dma_addr_t dma; 14662306a36Sopenharmony_ci } *rcvtids; 14762306a36Sopenharmony_ci u32 size; /* total size of eager buffers */ 14862306a36Sopenharmony_ci u32 rcvtid_size; /* size of each eager rcv tid */ 14962306a36Sopenharmony_ci u16 count; /* size of buffers array */ 15062306a36Sopenharmony_ci u16 numbufs; /* number of buffers allocated */ 15162306a36Sopenharmony_ci u16 alloced; /* number of rcvarray entries used */ 15262306a36Sopenharmony_ci u16 threshold; /* head update threshold */ 15362306a36Sopenharmony_ci}; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_cistruct exp_tid_set { 15662306a36Sopenharmony_ci struct list_head list; 15762306a36Sopenharmony_ci u32 count; 15862306a36Sopenharmony_ci}; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_cistruct hfi1_ctxtdata; 16162306a36Sopenharmony_citypedef int (*intr_handler)(struct hfi1_ctxtdata *rcd, int data); 16262306a36Sopenharmony_citypedef void (*rhf_rcv_function_ptr)(struct hfi1_packet *packet); 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_cistruct tid_queue { 16562306a36Sopenharmony_ci struct list_head queue_head; 16662306a36Sopenharmony_ci /* queue head for QP TID resource waiters */ 16762306a36Sopenharmony_ci u32 enqueue; /* count of tid enqueues */ 16862306a36Sopenharmony_ci u32 dequeue; /* count of tid dequeues */ 16962306a36Sopenharmony_ci}; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_cistruct hfi1_ctxtdata { 17262306a36Sopenharmony_ci /* rcvhdrq base, needs mmap before useful */ 17362306a36Sopenharmony_ci void *rcvhdrq; 17462306a36Sopenharmony_ci /* kernel virtual address where hdrqtail is updated */ 17562306a36Sopenharmony_ci volatile __le64 *rcvhdrtail_kvaddr; 17662306a36Sopenharmony_ci /* so functions that need physical port can get it easily */ 17762306a36Sopenharmony_ci struct hfi1_pportdata *ppd; 17862306a36Sopenharmony_ci /* so file ops can get at unit */ 17962306a36Sopenharmony_ci struct hfi1_devdata *dd; 18062306a36Sopenharmony_ci /* this receive context's assigned PIO ACK send context */ 18162306a36Sopenharmony_ci struct send_context *sc; 18262306a36Sopenharmony_ci /* per context recv functions */ 18362306a36Sopenharmony_ci const rhf_rcv_function_ptr *rhf_rcv_function_map; 18462306a36Sopenharmony_ci /* 18562306a36Sopenharmony_ci * The interrupt handler for a particular receive context can vary 18662306a36Sopenharmony_ci * throughout it's lifetime. This is not a lock protected data member so 18762306a36Sopenharmony_ci * it must be updated atomically and the prev and new value must always 18862306a36Sopenharmony_ci * be valid. Worst case is we process an extra interrupt and up to 64 18962306a36Sopenharmony_ci * packets with the wrong interrupt handler. 19062306a36Sopenharmony_ci */ 19162306a36Sopenharmony_ci intr_handler do_interrupt; 19262306a36Sopenharmony_ci /** fast handler after autoactive */ 19362306a36Sopenharmony_ci intr_handler fast_handler; 19462306a36Sopenharmony_ci /** slow handler */ 19562306a36Sopenharmony_ci intr_handler slow_handler; 19662306a36Sopenharmony_ci /* napi pointer assiociated with netdev */ 19762306a36Sopenharmony_ci struct napi_struct *napi; 19862306a36Sopenharmony_ci /* verbs rx_stats per rcd */ 19962306a36Sopenharmony_ci struct hfi1_opcode_stats_perctx *opstats; 20062306a36Sopenharmony_ci /* clear interrupt mask */ 20162306a36Sopenharmony_ci u64 imask; 20262306a36Sopenharmony_ci /* ctxt rcvhdrq head offset */ 20362306a36Sopenharmony_ci u32 head; 20462306a36Sopenharmony_ci /* number of rcvhdrq entries */ 20562306a36Sopenharmony_ci u16 rcvhdrq_cnt; 20662306a36Sopenharmony_ci u8 ireg; /* clear interrupt register */ 20762306a36Sopenharmony_ci /* receive packet sequence counter */ 20862306a36Sopenharmony_ci u8 seq_cnt; 20962306a36Sopenharmony_ci /* size of each of the rcvhdrq entries */ 21062306a36Sopenharmony_ci u8 rcvhdrqentsize; 21162306a36Sopenharmony_ci /* offset of RHF within receive header entry */ 21262306a36Sopenharmony_ci u8 rhf_offset; 21362306a36Sopenharmony_ci /* dynamic receive available interrupt timeout */ 21462306a36Sopenharmony_ci u8 rcvavail_timeout; 21562306a36Sopenharmony_ci /* Indicates that this is vnic context */ 21662306a36Sopenharmony_ci bool is_vnic; 21762306a36Sopenharmony_ci /* vnic queue index this context is mapped to */ 21862306a36Sopenharmony_ci u8 vnic_q_idx; 21962306a36Sopenharmony_ci /* Is ASPM interrupt supported for this context */ 22062306a36Sopenharmony_ci bool aspm_intr_supported; 22162306a36Sopenharmony_ci /* ASPM state (enabled/disabled) for this context */ 22262306a36Sopenharmony_ci bool aspm_enabled; 22362306a36Sopenharmony_ci /* Is ASPM processing enabled for this context (in intr context) */ 22462306a36Sopenharmony_ci bool aspm_intr_enable; 22562306a36Sopenharmony_ci struct ctxt_eager_bufs egrbufs; 22662306a36Sopenharmony_ci /* QPs waiting for context processing */ 22762306a36Sopenharmony_ci struct list_head qp_wait_list; 22862306a36Sopenharmony_ci /* tid allocation lists */ 22962306a36Sopenharmony_ci struct exp_tid_set tid_group_list; 23062306a36Sopenharmony_ci struct exp_tid_set tid_used_list; 23162306a36Sopenharmony_ci struct exp_tid_set tid_full_list; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci /* Timer for re-enabling ASPM if interrupt activity quiets down */ 23462306a36Sopenharmony_ci struct timer_list aspm_timer; 23562306a36Sopenharmony_ci /* per-context configuration flags */ 23662306a36Sopenharmony_ci unsigned long flags; 23762306a36Sopenharmony_ci /* array of tid_groups */ 23862306a36Sopenharmony_ci struct tid_group *groups; 23962306a36Sopenharmony_ci /* mmap of hdrq, must fit in 44 bits */ 24062306a36Sopenharmony_ci dma_addr_t rcvhdrq_dma; 24162306a36Sopenharmony_ci dma_addr_t rcvhdrqtailaddr_dma; 24262306a36Sopenharmony_ci /* Last interrupt timestamp */ 24362306a36Sopenharmony_ci ktime_t aspm_ts_last_intr; 24462306a36Sopenharmony_ci /* Last timestamp at which we scheduled a timer for this context */ 24562306a36Sopenharmony_ci ktime_t aspm_ts_timer_sched; 24662306a36Sopenharmony_ci /* Lock to serialize between intr, timer intr and user threads */ 24762306a36Sopenharmony_ci spinlock_t aspm_lock; 24862306a36Sopenharmony_ci /* Reference count the base context usage */ 24962306a36Sopenharmony_ci struct kref kref; 25062306a36Sopenharmony_ci /* numa node of this context */ 25162306a36Sopenharmony_ci int numa_id; 25262306a36Sopenharmony_ci /* associated msix interrupt. */ 25362306a36Sopenharmony_ci s16 msix_intr; 25462306a36Sopenharmony_ci /* job key */ 25562306a36Sopenharmony_ci u16 jkey; 25662306a36Sopenharmony_ci /* number of RcvArray groups for this context. */ 25762306a36Sopenharmony_ci u16 rcv_array_groups; 25862306a36Sopenharmony_ci /* index of first eager TID entry. */ 25962306a36Sopenharmony_ci u16 eager_base; 26062306a36Sopenharmony_ci /* number of expected TID entries */ 26162306a36Sopenharmony_ci u16 expected_count; 26262306a36Sopenharmony_ci /* index of first expected TID entry. */ 26362306a36Sopenharmony_ci u16 expected_base; 26462306a36Sopenharmony_ci /* Device context index */ 26562306a36Sopenharmony_ci u8 ctxt; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci /* PSM Specific fields */ 26862306a36Sopenharmony_ci /* lock protecting all Expected TID data */ 26962306a36Sopenharmony_ci struct mutex exp_mutex; 27062306a36Sopenharmony_ci /* lock protecting all Expected TID data of kernel contexts */ 27162306a36Sopenharmony_ci spinlock_t exp_lock; 27262306a36Sopenharmony_ci /* Queue for QP's waiting for HW TID flows */ 27362306a36Sopenharmony_ci struct tid_queue flow_queue; 27462306a36Sopenharmony_ci /* Queue for QP's waiting for HW receive array entries */ 27562306a36Sopenharmony_ci struct tid_queue rarr_queue; 27662306a36Sopenharmony_ci /* when waiting for rcv or pioavail */ 27762306a36Sopenharmony_ci wait_queue_head_t wait; 27862306a36Sopenharmony_ci /* uuid from PSM */ 27962306a36Sopenharmony_ci u8 uuid[16]; 28062306a36Sopenharmony_ci /* same size as task_struct .comm[], command that opened context */ 28162306a36Sopenharmony_ci char comm[TASK_COMM_LEN]; 28262306a36Sopenharmony_ci /* Bitmask of in use context(s) */ 28362306a36Sopenharmony_ci DECLARE_BITMAP(in_use_ctxts, HFI1_MAX_SHARED_CTXTS); 28462306a36Sopenharmony_ci /* per-context event flags for fileops/intr communication */ 28562306a36Sopenharmony_ci unsigned long event_flags; 28662306a36Sopenharmony_ci /* A page of memory for rcvhdrhead, rcvegrhead, rcvegrtail * N */ 28762306a36Sopenharmony_ci void *subctxt_uregbase; 28862306a36Sopenharmony_ci /* An array of pages for the eager receive buffers * N */ 28962306a36Sopenharmony_ci void *subctxt_rcvegrbuf; 29062306a36Sopenharmony_ci /* An array of pages for the eager header queue entries * N */ 29162306a36Sopenharmony_ci void *subctxt_rcvhdr_base; 29262306a36Sopenharmony_ci /* total number of polled urgent packets */ 29362306a36Sopenharmony_ci u32 urgent; 29462306a36Sopenharmony_ci /* saved total number of polled urgent packets for poll edge trigger */ 29562306a36Sopenharmony_ci u32 urgent_poll; 29662306a36Sopenharmony_ci /* Type of packets or conditions we want to poll for */ 29762306a36Sopenharmony_ci u16 poll_type; 29862306a36Sopenharmony_ci /* non-zero if ctxt is being shared. */ 29962306a36Sopenharmony_ci u16 subctxt_id; 30062306a36Sopenharmony_ci /* The version of the library which opened this ctxt */ 30162306a36Sopenharmony_ci u32 userversion; 30262306a36Sopenharmony_ci /* 30362306a36Sopenharmony_ci * non-zero if ctxt can be shared, and defines the maximum number of 30462306a36Sopenharmony_ci * sub-contexts for this device context. 30562306a36Sopenharmony_ci */ 30662306a36Sopenharmony_ci u8 subctxt_cnt; 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci /* Bit mask to track free TID RDMA HW flows */ 30962306a36Sopenharmony_ci unsigned long flow_mask; 31062306a36Sopenharmony_ci struct tid_flow_state flows[RXE_NUM_TID_FLOWS]; 31162306a36Sopenharmony_ci}; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci/** 31462306a36Sopenharmony_ci * rcvhdrq_size - return total size in bytes for header queue 31562306a36Sopenharmony_ci * @rcd: the receive context 31662306a36Sopenharmony_ci * 31762306a36Sopenharmony_ci * rcvhdrqentsize is in DWs, so we have to convert to bytes 31862306a36Sopenharmony_ci * 31962306a36Sopenharmony_ci */ 32062306a36Sopenharmony_cistatic inline u32 rcvhdrq_size(struct hfi1_ctxtdata *rcd) 32162306a36Sopenharmony_ci{ 32262306a36Sopenharmony_ci return PAGE_ALIGN(rcd->rcvhdrq_cnt * 32362306a36Sopenharmony_ci rcd->rcvhdrqentsize * sizeof(u32)); 32462306a36Sopenharmony_ci} 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci/* 32762306a36Sopenharmony_ci * Represents a single packet at a high level. Put commonly computed things in 32862306a36Sopenharmony_ci * here so we do not have to keep doing them over and over. The rule of thumb is 32962306a36Sopenharmony_ci * if something is used one time to derive some value, store that something in 33062306a36Sopenharmony_ci * here. If it is used multiple times, then store the result of that derivation 33162306a36Sopenharmony_ci * in here. 33262306a36Sopenharmony_ci */ 33362306a36Sopenharmony_cistruct hfi1_packet { 33462306a36Sopenharmony_ci void *ebuf; 33562306a36Sopenharmony_ci void *hdr; 33662306a36Sopenharmony_ci void *payload; 33762306a36Sopenharmony_ci struct hfi1_ctxtdata *rcd; 33862306a36Sopenharmony_ci __le32 *rhf_addr; 33962306a36Sopenharmony_ci struct rvt_qp *qp; 34062306a36Sopenharmony_ci struct ib_other_headers *ohdr; 34162306a36Sopenharmony_ci struct ib_grh *grh; 34262306a36Sopenharmony_ci struct opa_16b_mgmt *mgmt; 34362306a36Sopenharmony_ci u64 rhf; 34462306a36Sopenharmony_ci u32 maxcnt; 34562306a36Sopenharmony_ci u32 rhqoff; 34662306a36Sopenharmony_ci u32 dlid; 34762306a36Sopenharmony_ci u32 slid; 34862306a36Sopenharmony_ci int numpkt; 34962306a36Sopenharmony_ci u16 tlen; 35062306a36Sopenharmony_ci s16 etail; 35162306a36Sopenharmony_ci u16 pkey; 35262306a36Sopenharmony_ci u8 hlen; 35362306a36Sopenharmony_ci u8 rsize; 35462306a36Sopenharmony_ci u8 updegr; 35562306a36Sopenharmony_ci u8 etype; 35662306a36Sopenharmony_ci u8 extra_byte; 35762306a36Sopenharmony_ci u8 pad; 35862306a36Sopenharmony_ci u8 sc; 35962306a36Sopenharmony_ci u8 sl; 36062306a36Sopenharmony_ci u8 opcode; 36162306a36Sopenharmony_ci bool migrated; 36262306a36Sopenharmony_ci}; 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci/* Packet types */ 36562306a36Sopenharmony_ci#define HFI1_PKT_TYPE_9B 0 36662306a36Sopenharmony_ci#define HFI1_PKT_TYPE_16B 1 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci/* 36962306a36Sopenharmony_ci * OPA 16B Header 37062306a36Sopenharmony_ci */ 37162306a36Sopenharmony_ci#define OPA_16B_L4_MASK 0xFFull 37262306a36Sopenharmony_ci#define OPA_16B_SC_MASK 0x1F00000ull 37362306a36Sopenharmony_ci#define OPA_16B_SC_SHIFT 20 37462306a36Sopenharmony_ci#define OPA_16B_LID_MASK 0xFFFFFull 37562306a36Sopenharmony_ci#define OPA_16B_DLID_MASK 0xF000ull 37662306a36Sopenharmony_ci#define OPA_16B_DLID_SHIFT 20 37762306a36Sopenharmony_ci#define OPA_16B_DLID_HIGH_SHIFT 12 37862306a36Sopenharmony_ci#define OPA_16B_SLID_MASK 0xF00ull 37962306a36Sopenharmony_ci#define OPA_16B_SLID_SHIFT 20 38062306a36Sopenharmony_ci#define OPA_16B_SLID_HIGH_SHIFT 8 38162306a36Sopenharmony_ci#define OPA_16B_BECN_MASK 0x80000000ull 38262306a36Sopenharmony_ci#define OPA_16B_BECN_SHIFT 31 38362306a36Sopenharmony_ci#define OPA_16B_FECN_MASK 0x10000000ull 38462306a36Sopenharmony_ci#define OPA_16B_FECN_SHIFT 28 38562306a36Sopenharmony_ci#define OPA_16B_L2_MASK 0x60000000ull 38662306a36Sopenharmony_ci#define OPA_16B_L2_SHIFT 29 38762306a36Sopenharmony_ci#define OPA_16B_PKEY_MASK 0xFFFF0000ull 38862306a36Sopenharmony_ci#define OPA_16B_PKEY_SHIFT 16 38962306a36Sopenharmony_ci#define OPA_16B_LEN_MASK 0x7FF00000ull 39062306a36Sopenharmony_ci#define OPA_16B_LEN_SHIFT 20 39162306a36Sopenharmony_ci#define OPA_16B_RC_MASK 0xE000000ull 39262306a36Sopenharmony_ci#define OPA_16B_RC_SHIFT 25 39362306a36Sopenharmony_ci#define OPA_16B_AGE_MASK 0xFF0000ull 39462306a36Sopenharmony_ci#define OPA_16B_AGE_SHIFT 16 39562306a36Sopenharmony_ci#define OPA_16B_ENTROPY_MASK 0xFFFFull 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci/* 39862306a36Sopenharmony_ci * OPA 16B L2/L4 Encodings 39962306a36Sopenharmony_ci */ 40062306a36Sopenharmony_ci#define OPA_16B_L4_9B 0x00 40162306a36Sopenharmony_ci#define OPA_16B_L2_TYPE 0x02 40262306a36Sopenharmony_ci#define OPA_16B_L4_FM 0x08 40362306a36Sopenharmony_ci#define OPA_16B_L4_IB_LOCAL 0x09 40462306a36Sopenharmony_ci#define OPA_16B_L4_IB_GLOBAL 0x0A 40562306a36Sopenharmony_ci#define OPA_16B_L4_ETHR OPA_VNIC_L4_ETHR 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci/* 40862306a36Sopenharmony_ci * OPA 16B Management 40962306a36Sopenharmony_ci */ 41062306a36Sopenharmony_ci#define OPA_16B_L4_FM_PAD 3 /* fixed 3B pad */ 41162306a36Sopenharmony_ci#define OPA_16B_L4_FM_HLEN 24 /* 16B(16) + L4_FM(8) */ 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_cistatic inline u8 hfi1_16B_get_l4(struct hfi1_16b_header *hdr) 41462306a36Sopenharmony_ci{ 41562306a36Sopenharmony_ci return (u8)(hdr->lrh[2] & OPA_16B_L4_MASK); 41662306a36Sopenharmony_ci} 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_cistatic inline u8 hfi1_16B_get_sc(struct hfi1_16b_header *hdr) 41962306a36Sopenharmony_ci{ 42062306a36Sopenharmony_ci return (u8)((hdr->lrh[1] & OPA_16B_SC_MASK) >> OPA_16B_SC_SHIFT); 42162306a36Sopenharmony_ci} 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_cistatic inline u32 hfi1_16B_get_dlid(struct hfi1_16b_header *hdr) 42462306a36Sopenharmony_ci{ 42562306a36Sopenharmony_ci return (u32)((hdr->lrh[1] & OPA_16B_LID_MASK) | 42662306a36Sopenharmony_ci (((hdr->lrh[2] & OPA_16B_DLID_MASK) >> 42762306a36Sopenharmony_ci OPA_16B_DLID_HIGH_SHIFT) << OPA_16B_DLID_SHIFT)); 42862306a36Sopenharmony_ci} 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_cistatic inline u32 hfi1_16B_get_slid(struct hfi1_16b_header *hdr) 43162306a36Sopenharmony_ci{ 43262306a36Sopenharmony_ci return (u32)((hdr->lrh[0] & OPA_16B_LID_MASK) | 43362306a36Sopenharmony_ci (((hdr->lrh[2] & OPA_16B_SLID_MASK) >> 43462306a36Sopenharmony_ci OPA_16B_SLID_HIGH_SHIFT) << OPA_16B_SLID_SHIFT)); 43562306a36Sopenharmony_ci} 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_cistatic inline u8 hfi1_16B_get_becn(struct hfi1_16b_header *hdr) 43862306a36Sopenharmony_ci{ 43962306a36Sopenharmony_ci return (u8)((hdr->lrh[0] & OPA_16B_BECN_MASK) >> OPA_16B_BECN_SHIFT); 44062306a36Sopenharmony_ci} 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_cistatic inline u8 hfi1_16B_get_fecn(struct hfi1_16b_header *hdr) 44362306a36Sopenharmony_ci{ 44462306a36Sopenharmony_ci return (u8)((hdr->lrh[1] & OPA_16B_FECN_MASK) >> OPA_16B_FECN_SHIFT); 44562306a36Sopenharmony_ci} 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_cistatic inline u8 hfi1_16B_get_l2(struct hfi1_16b_header *hdr) 44862306a36Sopenharmony_ci{ 44962306a36Sopenharmony_ci return (u8)((hdr->lrh[1] & OPA_16B_L2_MASK) >> OPA_16B_L2_SHIFT); 45062306a36Sopenharmony_ci} 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_cistatic inline u16 hfi1_16B_get_pkey(struct hfi1_16b_header *hdr) 45362306a36Sopenharmony_ci{ 45462306a36Sopenharmony_ci return (u16)((hdr->lrh[2] & OPA_16B_PKEY_MASK) >> OPA_16B_PKEY_SHIFT); 45562306a36Sopenharmony_ci} 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_cistatic inline u8 hfi1_16B_get_rc(struct hfi1_16b_header *hdr) 45862306a36Sopenharmony_ci{ 45962306a36Sopenharmony_ci return (u8)((hdr->lrh[1] & OPA_16B_RC_MASK) >> OPA_16B_RC_SHIFT); 46062306a36Sopenharmony_ci} 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_cistatic inline u8 hfi1_16B_get_age(struct hfi1_16b_header *hdr) 46362306a36Sopenharmony_ci{ 46462306a36Sopenharmony_ci return (u8)((hdr->lrh[3] & OPA_16B_AGE_MASK) >> OPA_16B_AGE_SHIFT); 46562306a36Sopenharmony_ci} 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_cistatic inline u16 hfi1_16B_get_len(struct hfi1_16b_header *hdr) 46862306a36Sopenharmony_ci{ 46962306a36Sopenharmony_ci return (u16)((hdr->lrh[0] & OPA_16B_LEN_MASK) >> OPA_16B_LEN_SHIFT); 47062306a36Sopenharmony_ci} 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_cistatic inline u16 hfi1_16B_get_entropy(struct hfi1_16b_header *hdr) 47362306a36Sopenharmony_ci{ 47462306a36Sopenharmony_ci return (u16)(hdr->lrh[3] & OPA_16B_ENTROPY_MASK); 47562306a36Sopenharmony_ci} 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci#define OPA_16B_MAKE_QW(low_dw, high_dw) (((u64)(high_dw) << 32) | (low_dw)) 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci/* 48062306a36Sopenharmony_ci * BTH 48162306a36Sopenharmony_ci */ 48262306a36Sopenharmony_ci#define OPA_16B_BTH_PAD_MASK 7 48362306a36Sopenharmony_cistatic inline u8 hfi1_16B_bth_get_pad(struct ib_other_headers *ohdr) 48462306a36Sopenharmony_ci{ 48562306a36Sopenharmony_ci return (u8)((be32_to_cpu(ohdr->bth[0]) >> IB_BTH_PAD_SHIFT) & 48662306a36Sopenharmony_ci OPA_16B_BTH_PAD_MASK); 48762306a36Sopenharmony_ci} 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci/* 49062306a36Sopenharmony_ci * 16B Management 49162306a36Sopenharmony_ci */ 49262306a36Sopenharmony_ci#define OPA_16B_MGMT_QPN_MASK 0xFFFFFF 49362306a36Sopenharmony_cistatic inline u32 hfi1_16B_get_dest_qpn(struct opa_16b_mgmt *mgmt) 49462306a36Sopenharmony_ci{ 49562306a36Sopenharmony_ci return be32_to_cpu(mgmt->dest_qpn) & OPA_16B_MGMT_QPN_MASK; 49662306a36Sopenharmony_ci} 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_cistatic inline u32 hfi1_16B_get_src_qpn(struct opa_16b_mgmt *mgmt) 49962306a36Sopenharmony_ci{ 50062306a36Sopenharmony_ci return be32_to_cpu(mgmt->src_qpn) & OPA_16B_MGMT_QPN_MASK; 50162306a36Sopenharmony_ci} 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_cistatic inline void hfi1_16B_set_qpn(struct opa_16b_mgmt *mgmt, 50462306a36Sopenharmony_ci u32 dest_qp, u32 src_qp) 50562306a36Sopenharmony_ci{ 50662306a36Sopenharmony_ci mgmt->dest_qpn = cpu_to_be32(dest_qp & OPA_16B_MGMT_QPN_MASK); 50762306a36Sopenharmony_ci mgmt->src_qpn = cpu_to_be32(src_qp & OPA_16B_MGMT_QPN_MASK); 50862306a36Sopenharmony_ci} 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci/** 51162306a36Sopenharmony_ci * hfi1_get_rc_ohdr - get extended header 51262306a36Sopenharmony_ci * @opah - the opaheader 51362306a36Sopenharmony_ci */ 51462306a36Sopenharmony_cistatic inline struct ib_other_headers * 51562306a36Sopenharmony_cihfi1_get_rc_ohdr(struct hfi1_opa_header *opah) 51662306a36Sopenharmony_ci{ 51762306a36Sopenharmony_ci struct ib_other_headers *ohdr; 51862306a36Sopenharmony_ci struct ib_header *hdr = NULL; 51962306a36Sopenharmony_ci struct hfi1_16b_header *hdr_16b = NULL; 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci /* Find out where the BTH is */ 52262306a36Sopenharmony_ci if (opah->hdr_type == HFI1_PKT_TYPE_9B) { 52362306a36Sopenharmony_ci hdr = &opah->ibh; 52462306a36Sopenharmony_ci if (ib_get_lnh(hdr) == HFI1_LRH_BTH) 52562306a36Sopenharmony_ci ohdr = &hdr->u.oth; 52662306a36Sopenharmony_ci else 52762306a36Sopenharmony_ci ohdr = &hdr->u.l.oth; 52862306a36Sopenharmony_ci } else { 52962306a36Sopenharmony_ci u8 l4; 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci hdr_16b = &opah->opah; 53262306a36Sopenharmony_ci l4 = hfi1_16B_get_l4(hdr_16b); 53362306a36Sopenharmony_ci if (l4 == OPA_16B_L4_IB_LOCAL) 53462306a36Sopenharmony_ci ohdr = &hdr_16b->u.oth; 53562306a36Sopenharmony_ci else 53662306a36Sopenharmony_ci ohdr = &hdr_16b->u.l.oth; 53762306a36Sopenharmony_ci } 53862306a36Sopenharmony_ci return ohdr; 53962306a36Sopenharmony_ci} 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_cistruct rvt_sge_state; 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_ci/* 54462306a36Sopenharmony_ci * Get/Set IB link-level config parameters for f_get/set_ib_cfg() 54562306a36Sopenharmony_ci * Mostly for MADs that set or query link parameters, also ipath 54662306a36Sopenharmony_ci * config interfaces 54762306a36Sopenharmony_ci */ 54862306a36Sopenharmony_ci#define HFI1_IB_CFG_LIDLMC 0 /* LID (LS16b) and Mask (MS16b) */ 54962306a36Sopenharmony_ci#define HFI1_IB_CFG_LWID_DG_ENB 1 /* allowed Link-width downgrade */ 55062306a36Sopenharmony_ci#define HFI1_IB_CFG_LWID_ENB 2 /* allowed Link-width */ 55162306a36Sopenharmony_ci#define HFI1_IB_CFG_LWID 3 /* currently active Link-width */ 55262306a36Sopenharmony_ci#define HFI1_IB_CFG_SPD_ENB 4 /* allowed Link speeds */ 55362306a36Sopenharmony_ci#define HFI1_IB_CFG_SPD 5 /* current Link spd */ 55462306a36Sopenharmony_ci#define HFI1_IB_CFG_RXPOL_ENB 6 /* Auto-RX-polarity enable */ 55562306a36Sopenharmony_ci#define HFI1_IB_CFG_LREV_ENB 7 /* Auto-Lane-reversal enable */ 55662306a36Sopenharmony_ci#define HFI1_IB_CFG_LINKLATENCY 8 /* Link Latency (IB1.2 only) */ 55762306a36Sopenharmony_ci#define HFI1_IB_CFG_HRTBT 9 /* IB heartbeat off/enable/auto; DDR/QDR only */ 55862306a36Sopenharmony_ci#define HFI1_IB_CFG_OP_VLS 10 /* operational VLs */ 55962306a36Sopenharmony_ci#define HFI1_IB_CFG_VL_HIGH_CAP 11 /* num of VL high priority weights */ 56062306a36Sopenharmony_ci#define HFI1_IB_CFG_VL_LOW_CAP 12 /* num of VL low priority weights */ 56162306a36Sopenharmony_ci#define HFI1_IB_CFG_OVERRUN_THRESH 13 /* IB overrun threshold */ 56262306a36Sopenharmony_ci#define HFI1_IB_CFG_PHYERR_THRESH 14 /* IB PHY error threshold */ 56362306a36Sopenharmony_ci#define HFI1_IB_CFG_LINKDEFAULT 15 /* IB link default (sleep/poll) */ 56462306a36Sopenharmony_ci#define HFI1_IB_CFG_PKEYS 16 /* update partition keys */ 56562306a36Sopenharmony_ci#define HFI1_IB_CFG_MTU 17 /* update MTU in IBC */ 56662306a36Sopenharmony_ci#define HFI1_IB_CFG_VL_HIGH_LIMIT 19 56762306a36Sopenharmony_ci#define HFI1_IB_CFG_PMA_TICKS 20 /* PMA sample tick resolution */ 56862306a36Sopenharmony_ci#define HFI1_IB_CFG_PORT 21 /* switch port we are connected to */ 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_ci/* 57162306a36Sopenharmony_ci * HFI or Host Link States 57262306a36Sopenharmony_ci * 57362306a36Sopenharmony_ci * These describe the states the driver thinks the logical and physical 57462306a36Sopenharmony_ci * states are in. Used as an argument to set_link_state(). Implemented 57562306a36Sopenharmony_ci * as bits for easy multi-state checking. The actual state can only be 57662306a36Sopenharmony_ci * one. 57762306a36Sopenharmony_ci */ 57862306a36Sopenharmony_ci#define __HLS_UP_INIT_BP 0 57962306a36Sopenharmony_ci#define __HLS_UP_ARMED_BP 1 58062306a36Sopenharmony_ci#define __HLS_UP_ACTIVE_BP 2 58162306a36Sopenharmony_ci#define __HLS_DN_DOWNDEF_BP 3 /* link down default */ 58262306a36Sopenharmony_ci#define __HLS_DN_POLL_BP 4 58362306a36Sopenharmony_ci#define __HLS_DN_DISABLE_BP 5 58462306a36Sopenharmony_ci#define __HLS_DN_OFFLINE_BP 6 58562306a36Sopenharmony_ci#define __HLS_VERIFY_CAP_BP 7 58662306a36Sopenharmony_ci#define __HLS_GOING_UP_BP 8 58762306a36Sopenharmony_ci#define __HLS_GOING_OFFLINE_BP 9 58862306a36Sopenharmony_ci#define __HLS_LINK_COOLDOWN_BP 10 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci#define HLS_UP_INIT BIT(__HLS_UP_INIT_BP) 59162306a36Sopenharmony_ci#define HLS_UP_ARMED BIT(__HLS_UP_ARMED_BP) 59262306a36Sopenharmony_ci#define HLS_UP_ACTIVE BIT(__HLS_UP_ACTIVE_BP) 59362306a36Sopenharmony_ci#define HLS_DN_DOWNDEF BIT(__HLS_DN_DOWNDEF_BP) /* link down default */ 59462306a36Sopenharmony_ci#define HLS_DN_POLL BIT(__HLS_DN_POLL_BP) 59562306a36Sopenharmony_ci#define HLS_DN_DISABLE BIT(__HLS_DN_DISABLE_BP) 59662306a36Sopenharmony_ci#define HLS_DN_OFFLINE BIT(__HLS_DN_OFFLINE_BP) 59762306a36Sopenharmony_ci#define HLS_VERIFY_CAP BIT(__HLS_VERIFY_CAP_BP) 59862306a36Sopenharmony_ci#define HLS_GOING_UP BIT(__HLS_GOING_UP_BP) 59962306a36Sopenharmony_ci#define HLS_GOING_OFFLINE BIT(__HLS_GOING_OFFLINE_BP) 60062306a36Sopenharmony_ci#define HLS_LINK_COOLDOWN BIT(__HLS_LINK_COOLDOWN_BP) 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_ci#define HLS_UP (HLS_UP_INIT | HLS_UP_ARMED | HLS_UP_ACTIVE) 60362306a36Sopenharmony_ci#define HLS_DOWN ~(HLS_UP) 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci#define HLS_DEFAULT HLS_DN_POLL 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ci/* use this MTU size if none other is given */ 60862306a36Sopenharmony_ci#define HFI1_DEFAULT_ACTIVE_MTU 10240 60962306a36Sopenharmony_ci/* use this MTU size as the default maximum */ 61062306a36Sopenharmony_ci#define HFI1_DEFAULT_MAX_MTU 10240 61162306a36Sopenharmony_ci/* default partition key */ 61262306a36Sopenharmony_ci#define DEFAULT_PKEY 0xffff 61362306a36Sopenharmony_ci 61462306a36Sopenharmony_ci/* 61562306a36Sopenharmony_ci * Possible fabric manager config parameters for fm_{get,set}_table() 61662306a36Sopenharmony_ci */ 61762306a36Sopenharmony_ci#define FM_TBL_VL_HIGH_ARB 1 /* Get/set VL high prio weights */ 61862306a36Sopenharmony_ci#define FM_TBL_VL_LOW_ARB 2 /* Get/set VL low prio weights */ 61962306a36Sopenharmony_ci#define FM_TBL_BUFFER_CONTROL 3 /* Get/set Buffer Control */ 62062306a36Sopenharmony_ci#define FM_TBL_SC2VLNT 4 /* Get/set SC->VLnt */ 62162306a36Sopenharmony_ci#define FM_TBL_VL_PREEMPT_ELEMS 5 /* Get (no set) VL preempt elems */ 62262306a36Sopenharmony_ci#define FM_TBL_VL_PREEMPT_MATRIX 6 /* Get (no set) VL preempt matrix */ 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ci/* 62562306a36Sopenharmony_ci * Possible "operations" for f_rcvctrl(ppd, op, ctxt) 62662306a36Sopenharmony_ci * these are bits so they can be combined, e.g. 62762306a36Sopenharmony_ci * HFI1_RCVCTRL_INTRAVAIL_ENB | HFI1_RCVCTRL_CTXT_ENB 62862306a36Sopenharmony_ci */ 62962306a36Sopenharmony_ci#define HFI1_RCVCTRL_TAILUPD_ENB 0x01 63062306a36Sopenharmony_ci#define HFI1_RCVCTRL_TAILUPD_DIS 0x02 63162306a36Sopenharmony_ci#define HFI1_RCVCTRL_CTXT_ENB 0x04 63262306a36Sopenharmony_ci#define HFI1_RCVCTRL_CTXT_DIS 0x08 63362306a36Sopenharmony_ci#define HFI1_RCVCTRL_INTRAVAIL_ENB 0x10 63462306a36Sopenharmony_ci#define HFI1_RCVCTRL_INTRAVAIL_DIS 0x20 63562306a36Sopenharmony_ci#define HFI1_RCVCTRL_PKEY_ENB 0x40 /* Note, default is enabled */ 63662306a36Sopenharmony_ci#define HFI1_RCVCTRL_PKEY_DIS 0x80 63762306a36Sopenharmony_ci#define HFI1_RCVCTRL_TIDFLOW_ENB 0x0400 63862306a36Sopenharmony_ci#define HFI1_RCVCTRL_TIDFLOW_DIS 0x0800 63962306a36Sopenharmony_ci#define HFI1_RCVCTRL_ONE_PKT_EGR_ENB 0x1000 64062306a36Sopenharmony_ci#define HFI1_RCVCTRL_ONE_PKT_EGR_DIS 0x2000 64162306a36Sopenharmony_ci#define HFI1_RCVCTRL_NO_RHQ_DROP_ENB 0x4000 64262306a36Sopenharmony_ci#define HFI1_RCVCTRL_NO_RHQ_DROP_DIS 0x8000 64362306a36Sopenharmony_ci#define HFI1_RCVCTRL_NO_EGR_DROP_ENB 0x10000 64462306a36Sopenharmony_ci#define HFI1_RCVCTRL_NO_EGR_DROP_DIS 0x20000 64562306a36Sopenharmony_ci#define HFI1_RCVCTRL_URGENT_ENB 0x40000 64662306a36Sopenharmony_ci#define HFI1_RCVCTRL_URGENT_DIS 0x80000 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci/* partition enforcement flags */ 64962306a36Sopenharmony_ci#define HFI1_PART_ENFORCE_IN 0x1 65062306a36Sopenharmony_ci#define HFI1_PART_ENFORCE_OUT 0x2 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci/* how often we check for synthetic counter wrap around */ 65362306a36Sopenharmony_ci#define SYNTH_CNT_TIME 3 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci/* Counter flags */ 65662306a36Sopenharmony_ci#define CNTR_NORMAL 0x0 /* Normal counters, just read register */ 65762306a36Sopenharmony_ci#define CNTR_SYNTH 0x1 /* Synthetic counters, saturate at all 1s */ 65862306a36Sopenharmony_ci#define CNTR_DISABLED 0x2 /* Disable this counter */ 65962306a36Sopenharmony_ci#define CNTR_32BIT 0x4 /* Simulate 64 bits for this counter */ 66062306a36Sopenharmony_ci#define CNTR_VL 0x8 /* Per VL counter */ 66162306a36Sopenharmony_ci#define CNTR_SDMA 0x10 66262306a36Sopenharmony_ci#define CNTR_INVALID_VL -1 /* Specifies invalid VL */ 66362306a36Sopenharmony_ci#define CNTR_MODE_W 0x0 66462306a36Sopenharmony_ci#define CNTR_MODE_R 0x1 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_ci/* VLs Supported/Operational */ 66762306a36Sopenharmony_ci#define HFI1_MIN_VLS_SUPPORTED 1 66862306a36Sopenharmony_ci#define HFI1_MAX_VLS_SUPPORTED 8 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_ci#define HFI1_GUIDS_PER_PORT 5 67162306a36Sopenharmony_ci#define HFI1_PORT_GUID_INDEX 0 67262306a36Sopenharmony_ci 67362306a36Sopenharmony_cistatic inline void incr_cntr64(u64 *cntr) 67462306a36Sopenharmony_ci{ 67562306a36Sopenharmony_ci if (*cntr < (u64)-1LL) 67662306a36Sopenharmony_ci (*cntr)++; 67762306a36Sopenharmony_ci} 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_ci#define MAX_NAME_SIZE 64 68062306a36Sopenharmony_cistruct hfi1_msix_entry { 68162306a36Sopenharmony_ci enum irq_type type; 68262306a36Sopenharmony_ci int irq; 68362306a36Sopenharmony_ci void *arg; 68462306a36Sopenharmony_ci cpumask_t mask; 68562306a36Sopenharmony_ci struct irq_affinity_notify notify; 68662306a36Sopenharmony_ci}; 68762306a36Sopenharmony_ci 68862306a36Sopenharmony_cistruct hfi1_msix_info { 68962306a36Sopenharmony_ci /* lock to synchronize in_use_msix access */ 69062306a36Sopenharmony_ci spinlock_t msix_lock; 69162306a36Sopenharmony_ci DECLARE_BITMAP(in_use_msix, CCE_NUM_MSIX_VECTORS); 69262306a36Sopenharmony_ci struct hfi1_msix_entry *msix_entries; 69362306a36Sopenharmony_ci u16 max_requested; 69462306a36Sopenharmony_ci}; 69562306a36Sopenharmony_ci 69662306a36Sopenharmony_ci/* per-SL CCA information */ 69762306a36Sopenharmony_cistruct cca_timer { 69862306a36Sopenharmony_ci struct hrtimer hrtimer; 69962306a36Sopenharmony_ci struct hfi1_pportdata *ppd; /* read-only */ 70062306a36Sopenharmony_ci int sl; /* read-only */ 70162306a36Sopenharmony_ci u16 ccti; /* read/write - current value of CCTI */ 70262306a36Sopenharmony_ci}; 70362306a36Sopenharmony_ci 70462306a36Sopenharmony_cistruct link_down_reason { 70562306a36Sopenharmony_ci /* 70662306a36Sopenharmony_ci * SMA-facing value. Should be set from .latest when 70762306a36Sopenharmony_ci * HLS_UP_* -> HLS_DN_* transition actually occurs. 70862306a36Sopenharmony_ci */ 70962306a36Sopenharmony_ci u8 sma; 71062306a36Sopenharmony_ci u8 latest; 71162306a36Sopenharmony_ci}; 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_cienum { 71462306a36Sopenharmony_ci LO_PRIO_TABLE, 71562306a36Sopenharmony_ci HI_PRIO_TABLE, 71662306a36Sopenharmony_ci MAX_PRIO_TABLE 71762306a36Sopenharmony_ci}; 71862306a36Sopenharmony_ci 71962306a36Sopenharmony_cistruct vl_arb_cache { 72062306a36Sopenharmony_ci /* protect vl arb cache */ 72162306a36Sopenharmony_ci spinlock_t lock; 72262306a36Sopenharmony_ci struct ib_vl_weight_elem table[VL_ARB_TABLE_SIZE]; 72362306a36Sopenharmony_ci}; 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci/* 72662306a36Sopenharmony_ci * The structure below encapsulates data relevant to a physical IB Port. 72762306a36Sopenharmony_ci * Current chips support only one such port, but the separation 72862306a36Sopenharmony_ci * clarifies things a bit. Note that to conform to IB conventions, 72962306a36Sopenharmony_ci * port-numbers are one-based. The first or only port is port1. 73062306a36Sopenharmony_ci */ 73162306a36Sopenharmony_cistruct hfi1_pportdata { 73262306a36Sopenharmony_ci struct hfi1_ibport ibport_data; 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_ci struct hfi1_devdata *dd; 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci /* PHY support */ 73762306a36Sopenharmony_ci struct qsfp_data qsfp_info; 73862306a36Sopenharmony_ci /* Values for SI tuning of SerDes */ 73962306a36Sopenharmony_ci u32 port_type; 74062306a36Sopenharmony_ci u32 tx_preset_eq; 74162306a36Sopenharmony_ci u32 tx_preset_noeq; 74262306a36Sopenharmony_ci u32 rx_preset; 74362306a36Sopenharmony_ci u8 local_atten; 74462306a36Sopenharmony_ci u8 remote_atten; 74562306a36Sopenharmony_ci u8 default_atten; 74662306a36Sopenharmony_ci u8 max_power_class; 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_ci /* did we read platform config from scratch registers? */ 74962306a36Sopenharmony_ci bool config_from_scratch; 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_ci /* GUIDs for this interface, in host order, guids[0] is a port guid */ 75262306a36Sopenharmony_ci u64 guids[HFI1_GUIDS_PER_PORT]; 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_ci /* GUID for peer interface, in host order */ 75562306a36Sopenharmony_ci u64 neighbor_guid; 75662306a36Sopenharmony_ci 75762306a36Sopenharmony_ci /* up or down physical link state */ 75862306a36Sopenharmony_ci u32 linkup; 75962306a36Sopenharmony_ci 76062306a36Sopenharmony_ci /* 76162306a36Sopenharmony_ci * this address is mapped read-only into user processes so they can 76262306a36Sopenharmony_ci * get status cheaply, whenever they want. One qword of status per port 76362306a36Sopenharmony_ci */ 76462306a36Sopenharmony_ci u64 *statusp; 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_ci /* SendDMA related entries */ 76762306a36Sopenharmony_ci 76862306a36Sopenharmony_ci struct workqueue_struct *hfi1_wq; 76962306a36Sopenharmony_ci struct workqueue_struct *link_wq; 77062306a36Sopenharmony_ci 77162306a36Sopenharmony_ci /* move out of interrupt context */ 77262306a36Sopenharmony_ci struct work_struct link_vc_work; 77362306a36Sopenharmony_ci struct work_struct link_up_work; 77462306a36Sopenharmony_ci struct work_struct link_down_work; 77562306a36Sopenharmony_ci struct work_struct sma_message_work; 77662306a36Sopenharmony_ci struct work_struct freeze_work; 77762306a36Sopenharmony_ci struct work_struct link_downgrade_work; 77862306a36Sopenharmony_ci struct work_struct link_bounce_work; 77962306a36Sopenharmony_ci struct delayed_work start_link_work; 78062306a36Sopenharmony_ci /* host link state variables */ 78162306a36Sopenharmony_ci struct mutex hls_lock; 78262306a36Sopenharmony_ci u32 host_link_state; 78362306a36Sopenharmony_ci 78462306a36Sopenharmony_ci /* these are the "32 bit" regs */ 78562306a36Sopenharmony_ci 78662306a36Sopenharmony_ci u32 ibmtu; /* The MTU programmed for this unit */ 78762306a36Sopenharmony_ci /* 78862306a36Sopenharmony_ci * Current max size IB packet (in bytes) including IB headers, that 78962306a36Sopenharmony_ci * we can send. Changes when ibmtu changes. 79062306a36Sopenharmony_ci */ 79162306a36Sopenharmony_ci u32 ibmaxlen; 79262306a36Sopenharmony_ci u32 current_egress_rate; /* units [10^6 bits/sec] */ 79362306a36Sopenharmony_ci /* LID programmed for this instance */ 79462306a36Sopenharmony_ci u32 lid; 79562306a36Sopenharmony_ci /* list of pkeys programmed; 0 if not set */ 79662306a36Sopenharmony_ci u16 pkeys[MAX_PKEY_VALUES]; 79762306a36Sopenharmony_ci u16 link_width_supported; 79862306a36Sopenharmony_ci u16 link_width_downgrade_supported; 79962306a36Sopenharmony_ci u16 link_speed_supported; 80062306a36Sopenharmony_ci u16 link_width_enabled; 80162306a36Sopenharmony_ci u16 link_width_downgrade_enabled; 80262306a36Sopenharmony_ci u16 link_speed_enabled; 80362306a36Sopenharmony_ci u16 link_width_active; 80462306a36Sopenharmony_ci u16 link_width_downgrade_tx_active; 80562306a36Sopenharmony_ci u16 link_width_downgrade_rx_active; 80662306a36Sopenharmony_ci u16 link_speed_active; 80762306a36Sopenharmony_ci u8 vls_supported; 80862306a36Sopenharmony_ci u8 vls_operational; 80962306a36Sopenharmony_ci u8 actual_vls_operational; 81062306a36Sopenharmony_ci /* LID mask control */ 81162306a36Sopenharmony_ci u8 lmc; 81262306a36Sopenharmony_ci /* Rx Polarity inversion (compensate for ~tx on partner) */ 81362306a36Sopenharmony_ci u8 rx_pol_inv; 81462306a36Sopenharmony_ci 81562306a36Sopenharmony_ci u8 hw_pidx; /* physical port index */ 81662306a36Sopenharmony_ci u32 port; /* IB port number and index into dd->pports - 1 */ 81762306a36Sopenharmony_ci /* type of neighbor node */ 81862306a36Sopenharmony_ci u8 neighbor_type; 81962306a36Sopenharmony_ci u8 neighbor_normal; 82062306a36Sopenharmony_ci u8 neighbor_fm_security; /* 1 if firmware checking is disabled */ 82162306a36Sopenharmony_ci u8 neighbor_port_number; 82262306a36Sopenharmony_ci u8 is_sm_config_started; 82362306a36Sopenharmony_ci u8 offline_disabled_reason; 82462306a36Sopenharmony_ci u8 is_active_optimize_enabled; 82562306a36Sopenharmony_ci u8 driver_link_ready; /* driver ready for active link */ 82662306a36Sopenharmony_ci u8 link_enabled; /* link enabled? */ 82762306a36Sopenharmony_ci u8 linkinit_reason; 82862306a36Sopenharmony_ci u8 local_tx_rate; /* rate given to 8051 firmware */ 82962306a36Sopenharmony_ci u8 qsfp_retry_count; 83062306a36Sopenharmony_ci 83162306a36Sopenharmony_ci /* placeholders for IB MAD packet settings */ 83262306a36Sopenharmony_ci u8 overrun_threshold; 83362306a36Sopenharmony_ci u8 phy_error_threshold; 83462306a36Sopenharmony_ci unsigned int is_link_down_queued; 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_ci /* Used to override LED behavior for things like maintenance beaconing*/ 83762306a36Sopenharmony_ci /* 83862306a36Sopenharmony_ci * Alternates per phase of blink 83962306a36Sopenharmony_ci * [0] holds LED off duration, [1] holds LED on duration 84062306a36Sopenharmony_ci */ 84162306a36Sopenharmony_ci unsigned long led_override_vals[2]; 84262306a36Sopenharmony_ci u8 led_override_phase; /* LSB picks from vals[] */ 84362306a36Sopenharmony_ci atomic_t led_override_timer_active; 84462306a36Sopenharmony_ci /* Used to flash LEDs in override mode */ 84562306a36Sopenharmony_ci struct timer_list led_override_timer; 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ci u32 sm_trap_qp; 84862306a36Sopenharmony_ci u32 sa_qp; 84962306a36Sopenharmony_ci 85062306a36Sopenharmony_ci /* 85162306a36Sopenharmony_ci * cca_timer_lock protects access to the per-SL cca_timer 85262306a36Sopenharmony_ci * structures (specifically the ccti member). 85362306a36Sopenharmony_ci */ 85462306a36Sopenharmony_ci spinlock_t cca_timer_lock ____cacheline_aligned_in_smp; 85562306a36Sopenharmony_ci struct cca_timer cca_timer[OPA_MAX_SLS]; 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_ci /* List of congestion control table entries */ 85862306a36Sopenharmony_ci struct ib_cc_table_entry_shadow ccti_entries[CC_TABLE_SHADOW_MAX]; 85962306a36Sopenharmony_ci 86062306a36Sopenharmony_ci /* congestion entries, each entry corresponding to a SL */ 86162306a36Sopenharmony_ci struct opa_congestion_setting_entry_shadow 86262306a36Sopenharmony_ci congestion_entries[OPA_MAX_SLS]; 86362306a36Sopenharmony_ci 86462306a36Sopenharmony_ci /* 86562306a36Sopenharmony_ci * cc_state_lock protects (write) access to the per-port 86662306a36Sopenharmony_ci * struct cc_state. 86762306a36Sopenharmony_ci */ 86862306a36Sopenharmony_ci spinlock_t cc_state_lock ____cacheline_aligned_in_smp; 86962306a36Sopenharmony_ci 87062306a36Sopenharmony_ci struct cc_state __rcu *cc_state; 87162306a36Sopenharmony_ci 87262306a36Sopenharmony_ci /* Total number of congestion control table entries */ 87362306a36Sopenharmony_ci u16 total_cct_entry; 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_ci /* Bit map identifying service level */ 87662306a36Sopenharmony_ci u32 cc_sl_control_map; 87762306a36Sopenharmony_ci 87862306a36Sopenharmony_ci /* CA's max number of 64 entry units in the congestion control table */ 87962306a36Sopenharmony_ci u8 cc_max_table_entries; 88062306a36Sopenharmony_ci 88162306a36Sopenharmony_ci /* 88262306a36Sopenharmony_ci * begin congestion log related entries 88362306a36Sopenharmony_ci * cc_log_lock protects all congestion log related data 88462306a36Sopenharmony_ci */ 88562306a36Sopenharmony_ci spinlock_t cc_log_lock ____cacheline_aligned_in_smp; 88662306a36Sopenharmony_ci u8 threshold_cong_event_map[OPA_MAX_SLS / 8]; 88762306a36Sopenharmony_ci u16 threshold_event_counter; 88862306a36Sopenharmony_ci struct opa_hfi1_cong_log_event_internal cc_events[OPA_CONG_LOG_ELEMS]; 88962306a36Sopenharmony_ci int cc_log_idx; /* index for logging events */ 89062306a36Sopenharmony_ci int cc_mad_idx; /* index for reporting events */ 89162306a36Sopenharmony_ci /* end congestion log related entries */ 89262306a36Sopenharmony_ci 89362306a36Sopenharmony_ci struct vl_arb_cache vl_arb_cache[MAX_PRIO_TABLE]; 89462306a36Sopenharmony_ci 89562306a36Sopenharmony_ci /* port relative counter buffer */ 89662306a36Sopenharmony_ci u64 *cntrs; 89762306a36Sopenharmony_ci /* port relative synthetic counter buffer */ 89862306a36Sopenharmony_ci u64 *scntrs; 89962306a36Sopenharmony_ci /* port_xmit_discards are synthesized from different egress errors */ 90062306a36Sopenharmony_ci u64 port_xmit_discards; 90162306a36Sopenharmony_ci u64 port_xmit_discards_vl[C_VL_COUNT]; 90262306a36Sopenharmony_ci u64 port_xmit_constraint_errors; 90362306a36Sopenharmony_ci u64 port_rcv_constraint_errors; 90462306a36Sopenharmony_ci /* count of 'link_err' interrupts from DC */ 90562306a36Sopenharmony_ci u64 link_downed; 90662306a36Sopenharmony_ci /* number of times link retrained successfully */ 90762306a36Sopenharmony_ci u64 link_up; 90862306a36Sopenharmony_ci /* number of times a link unknown frame was reported */ 90962306a36Sopenharmony_ci u64 unknown_frame_count; 91062306a36Sopenharmony_ci /* port_ltp_crc_mode is returned in 'portinfo' MADs */ 91162306a36Sopenharmony_ci u16 port_ltp_crc_mode; 91262306a36Sopenharmony_ci /* port_crc_mode_enabled is the crc we support */ 91362306a36Sopenharmony_ci u8 port_crc_mode_enabled; 91462306a36Sopenharmony_ci /* mgmt_allowed is also returned in 'portinfo' MADs */ 91562306a36Sopenharmony_ci u8 mgmt_allowed; 91662306a36Sopenharmony_ci u8 part_enforce; /* partition enforcement flags */ 91762306a36Sopenharmony_ci struct link_down_reason local_link_down_reason; 91862306a36Sopenharmony_ci struct link_down_reason neigh_link_down_reason; 91962306a36Sopenharmony_ci /* Value to be sent to link peer on LinkDown .*/ 92062306a36Sopenharmony_ci u8 remote_link_down_reason; 92162306a36Sopenharmony_ci /* Error events that will cause a port bounce. */ 92262306a36Sopenharmony_ci u32 port_error_action; 92362306a36Sopenharmony_ci struct work_struct linkstate_active_work; 92462306a36Sopenharmony_ci /* Does this port need to prescan for FECNs */ 92562306a36Sopenharmony_ci bool cc_prescan; 92662306a36Sopenharmony_ci /* 92762306a36Sopenharmony_ci * Sample sendWaitCnt & sendWaitVlCnt during link transition 92862306a36Sopenharmony_ci * and counter request. 92962306a36Sopenharmony_ci */ 93062306a36Sopenharmony_ci u64 port_vl_xmit_wait_last[C_VL_COUNT + 1]; 93162306a36Sopenharmony_ci u16 prev_link_width; 93262306a36Sopenharmony_ci u64 vl_xmit_flit_cnt[C_VL_COUNT + 1]; 93362306a36Sopenharmony_ci}; 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_citypedef void (*opcode_handler)(struct hfi1_packet *packet); 93662306a36Sopenharmony_citypedef void (*hfi1_make_req)(struct rvt_qp *qp, 93762306a36Sopenharmony_ci struct hfi1_pkt_state *ps, 93862306a36Sopenharmony_ci struct rvt_swqe *wqe); 93962306a36Sopenharmony_ciextern const rhf_rcv_function_ptr normal_rhf_rcv_functions[]; 94062306a36Sopenharmony_ciextern const rhf_rcv_function_ptr netdev_rhf_rcv_functions[]; 94162306a36Sopenharmony_ci 94262306a36Sopenharmony_ci/* return values for the RHF receive functions */ 94362306a36Sopenharmony_ci#define RHF_RCV_CONTINUE 0 /* keep going */ 94462306a36Sopenharmony_ci#define RHF_RCV_DONE 1 /* stop, this packet processed */ 94562306a36Sopenharmony_ci#define RHF_RCV_REPROCESS 2 /* stop. retain this packet */ 94662306a36Sopenharmony_ci 94762306a36Sopenharmony_cistruct rcv_array_data { 94862306a36Sopenharmony_ci u16 ngroups; 94962306a36Sopenharmony_ci u16 nctxt_extra; 95062306a36Sopenharmony_ci u8 group_size; 95162306a36Sopenharmony_ci}; 95262306a36Sopenharmony_ci 95362306a36Sopenharmony_cistruct per_vl_data { 95462306a36Sopenharmony_ci u16 mtu; 95562306a36Sopenharmony_ci struct send_context *sc; 95662306a36Sopenharmony_ci}; 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_ci/* 16 to directly index */ 95962306a36Sopenharmony_ci#define PER_VL_SEND_CONTEXTS 16 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_cistruct err_info_rcvport { 96262306a36Sopenharmony_ci u8 status_and_code; 96362306a36Sopenharmony_ci u64 packet_flit1; 96462306a36Sopenharmony_ci u64 packet_flit2; 96562306a36Sopenharmony_ci}; 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_cistruct err_info_constraint { 96862306a36Sopenharmony_ci u8 status; 96962306a36Sopenharmony_ci u16 pkey; 97062306a36Sopenharmony_ci u32 slid; 97162306a36Sopenharmony_ci}; 97262306a36Sopenharmony_ci 97362306a36Sopenharmony_cistruct hfi1_temp { 97462306a36Sopenharmony_ci unsigned int curr; /* current temperature */ 97562306a36Sopenharmony_ci unsigned int lo_lim; /* low temperature limit */ 97662306a36Sopenharmony_ci unsigned int hi_lim; /* high temperature limit */ 97762306a36Sopenharmony_ci unsigned int crit_lim; /* critical temperature limit */ 97862306a36Sopenharmony_ci u8 triggers; /* temperature triggers */ 97962306a36Sopenharmony_ci}; 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_cistruct hfi1_i2c_bus { 98262306a36Sopenharmony_ci struct hfi1_devdata *controlling_dd; /* current controlling device */ 98362306a36Sopenharmony_ci struct i2c_adapter adapter; /* bus details */ 98462306a36Sopenharmony_ci struct i2c_algo_bit_data algo; /* bus algorithm details */ 98562306a36Sopenharmony_ci int num; /* bus number, 0 or 1 */ 98662306a36Sopenharmony_ci}; 98762306a36Sopenharmony_ci 98862306a36Sopenharmony_ci/* common data between shared ASIC HFIs */ 98962306a36Sopenharmony_cistruct hfi1_asic_data { 99062306a36Sopenharmony_ci struct hfi1_devdata *dds[2]; /* back pointers */ 99162306a36Sopenharmony_ci struct mutex asic_resource_mutex; 99262306a36Sopenharmony_ci struct hfi1_i2c_bus *i2c_bus0; 99362306a36Sopenharmony_ci struct hfi1_i2c_bus *i2c_bus1; 99462306a36Sopenharmony_ci}; 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_ci/* sizes for both the QP and RSM map tables */ 99762306a36Sopenharmony_ci#define NUM_MAP_ENTRIES 256 99862306a36Sopenharmony_ci#define NUM_MAP_REGS 32 99962306a36Sopenharmony_ci 100062306a36Sopenharmony_ci/* Virtual NIC information */ 100162306a36Sopenharmony_cistruct hfi1_vnic_data { 100262306a36Sopenharmony_ci struct kmem_cache *txreq_cache; 100362306a36Sopenharmony_ci u8 num_vports; 100462306a36Sopenharmony_ci}; 100562306a36Sopenharmony_ci 100662306a36Sopenharmony_cistruct hfi1_vnic_vport_info; 100762306a36Sopenharmony_ci 100862306a36Sopenharmony_ci/* device data struct now contains only "general per-device" info. 100962306a36Sopenharmony_ci * fields related to a physical IB port are in a hfi1_pportdata struct. 101062306a36Sopenharmony_ci */ 101162306a36Sopenharmony_cistruct sdma_engine; 101262306a36Sopenharmony_cistruct sdma_vl_map; 101362306a36Sopenharmony_ci 101462306a36Sopenharmony_ci#define BOARD_VERS_MAX 96 /* how long the version string can be */ 101562306a36Sopenharmony_ci#define SERIAL_MAX 16 /* length of the serial number */ 101662306a36Sopenharmony_ci 101762306a36Sopenharmony_citypedef int (*send_routine)(struct rvt_qp *, struct hfi1_pkt_state *, u64); 101862306a36Sopenharmony_cistruct hfi1_netdev_rx; 101962306a36Sopenharmony_cistruct hfi1_devdata { 102062306a36Sopenharmony_ci struct hfi1_ibdev verbs_dev; /* must be first */ 102162306a36Sopenharmony_ci /* pointers to related structs for this device */ 102262306a36Sopenharmony_ci /* pci access data structure */ 102362306a36Sopenharmony_ci struct pci_dev *pcidev; 102462306a36Sopenharmony_ci struct cdev user_cdev; 102562306a36Sopenharmony_ci struct cdev diag_cdev; 102662306a36Sopenharmony_ci struct cdev ui_cdev; 102762306a36Sopenharmony_ci struct device *user_device; 102862306a36Sopenharmony_ci struct device *diag_device; 102962306a36Sopenharmony_ci struct device *ui_device; 103062306a36Sopenharmony_ci 103162306a36Sopenharmony_ci /* first mapping up to RcvArray */ 103262306a36Sopenharmony_ci u8 __iomem *kregbase1; 103362306a36Sopenharmony_ci resource_size_t physaddr; 103462306a36Sopenharmony_ci 103562306a36Sopenharmony_ci /* second uncached mapping from RcvArray to pio send buffers */ 103662306a36Sopenharmony_ci u8 __iomem *kregbase2; 103762306a36Sopenharmony_ci /* for detecting offset above kregbase2 address */ 103862306a36Sopenharmony_ci u32 base2_start; 103962306a36Sopenharmony_ci 104062306a36Sopenharmony_ci /* Per VL data. Enough for all VLs but not all elements are set/used. */ 104162306a36Sopenharmony_ci struct per_vl_data vld[PER_VL_SEND_CONTEXTS]; 104262306a36Sopenharmony_ci /* send context data */ 104362306a36Sopenharmony_ci struct send_context_info *send_contexts; 104462306a36Sopenharmony_ci /* map hardware send contexts to software index */ 104562306a36Sopenharmony_ci u8 *hw_to_sw; 104662306a36Sopenharmony_ci /* spinlock for allocating and releasing send context resources */ 104762306a36Sopenharmony_ci spinlock_t sc_lock; 104862306a36Sopenharmony_ci /* lock for pio_map */ 104962306a36Sopenharmony_ci spinlock_t pio_map_lock; 105062306a36Sopenharmony_ci /* Send Context initialization lock. */ 105162306a36Sopenharmony_ci spinlock_t sc_init_lock; 105262306a36Sopenharmony_ci /* lock for sdma_map */ 105362306a36Sopenharmony_ci spinlock_t sde_map_lock; 105462306a36Sopenharmony_ci /* array of kernel send contexts */ 105562306a36Sopenharmony_ci struct send_context **kernel_send_context; 105662306a36Sopenharmony_ci /* array of vl maps */ 105762306a36Sopenharmony_ci struct pio_vl_map __rcu *pio_map; 105862306a36Sopenharmony_ci /* default flags to last descriptor */ 105962306a36Sopenharmony_ci u64 default_desc1; 106062306a36Sopenharmony_ci 106162306a36Sopenharmony_ci /* fields common to all SDMA engines */ 106262306a36Sopenharmony_ci 106362306a36Sopenharmony_ci volatile __le64 *sdma_heads_dma; /* DMA'ed by chip */ 106462306a36Sopenharmony_ci dma_addr_t sdma_heads_phys; 106562306a36Sopenharmony_ci void *sdma_pad_dma; /* DMA'ed by chip */ 106662306a36Sopenharmony_ci dma_addr_t sdma_pad_phys; 106762306a36Sopenharmony_ci /* for deallocation */ 106862306a36Sopenharmony_ci size_t sdma_heads_size; 106962306a36Sopenharmony_ci /* num used */ 107062306a36Sopenharmony_ci u32 num_sdma; 107162306a36Sopenharmony_ci /* array of engines sized by num_sdma */ 107262306a36Sopenharmony_ci struct sdma_engine *per_sdma; 107362306a36Sopenharmony_ci /* array of vl maps */ 107462306a36Sopenharmony_ci struct sdma_vl_map __rcu *sdma_map; 107562306a36Sopenharmony_ci /* SPC freeze waitqueue and variable */ 107662306a36Sopenharmony_ci wait_queue_head_t sdma_unfreeze_wq; 107762306a36Sopenharmony_ci atomic_t sdma_unfreeze_count; 107862306a36Sopenharmony_ci 107962306a36Sopenharmony_ci u32 lcb_access_count; /* count of LCB users */ 108062306a36Sopenharmony_ci 108162306a36Sopenharmony_ci /* common data between shared ASIC HFIs in this OS */ 108262306a36Sopenharmony_ci struct hfi1_asic_data *asic_data; 108362306a36Sopenharmony_ci 108462306a36Sopenharmony_ci /* mem-mapped pointer to base of PIO buffers */ 108562306a36Sopenharmony_ci void __iomem *piobase; 108662306a36Sopenharmony_ci /* 108762306a36Sopenharmony_ci * write-combining mem-mapped pointer to base of RcvArray 108862306a36Sopenharmony_ci * memory. 108962306a36Sopenharmony_ci */ 109062306a36Sopenharmony_ci void __iomem *rcvarray_wc; 109162306a36Sopenharmony_ci /* 109262306a36Sopenharmony_ci * credit return base - a per-NUMA range of DMA address that 109362306a36Sopenharmony_ci * the chip will use to update the per-context free counter 109462306a36Sopenharmony_ci */ 109562306a36Sopenharmony_ci struct credit_return_base *cr_base; 109662306a36Sopenharmony_ci 109762306a36Sopenharmony_ci /* send context numbers and sizes for each type */ 109862306a36Sopenharmony_ci struct sc_config_sizes sc_sizes[SC_MAX]; 109962306a36Sopenharmony_ci 110062306a36Sopenharmony_ci char *boardname; /* human readable board info */ 110162306a36Sopenharmony_ci 110262306a36Sopenharmony_ci u64 ctx0_seq_drop; 110362306a36Sopenharmony_ci 110462306a36Sopenharmony_ci /* reset value */ 110562306a36Sopenharmony_ci u64 z_int_counter; 110662306a36Sopenharmony_ci u64 z_rcv_limit; 110762306a36Sopenharmony_ci u64 z_send_schedule; 110862306a36Sopenharmony_ci 110962306a36Sopenharmony_ci u64 __percpu *send_schedule; 111062306a36Sopenharmony_ci /* number of reserved contexts for netdev usage */ 111162306a36Sopenharmony_ci u16 num_netdev_contexts; 111262306a36Sopenharmony_ci /* number of receive contexts in use by the driver */ 111362306a36Sopenharmony_ci u32 num_rcv_contexts; 111462306a36Sopenharmony_ci /* number of pio send contexts in use by the driver */ 111562306a36Sopenharmony_ci u32 num_send_contexts; 111662306a36Sopenharmony_ci /* 111762306a36Sopenharmony_ci * number of ctxts available for PSM open 111862306a36Sopenharmony_ci */ 111962306a36Sopenharmony_ci u32 freectxts; 112062306a36Sopenharmony_ci /* total number of available user/PSM contexts */ 112162306a36Sopenharmony_ci u32 num_user_contexts; 112262306a36Sopenharmony_ci /* base receive interrupt timeout, in CSR units */ 112362306a36Sopenharmony_ci u32 rcv_intr_timeout_csr; 112462306a36Sopenharmony_ci 112562306a36Sopenharmony_ci spinlock_t sendctrl_lock; /* protect changes to SendCtrl */ 112662306a36Sopenharmony_ci spinlock_t rcvctrl_lock; /* protect changes to RcvCtrl */ 112762306a36Sopenharmony_ci spinlock_t uctxt_lock; /* protect rcd changes */ 112862306a36Sopenharmony_ci struct mutex dc8051_lock; /* exclusive access to 8051 */ 112962306a36Sopenharmony_ci struct workqueue_struct *update_cntr_wq; 113062306a36Sopenharmony_ci struct work_struct update_cntr_work; 113162306a36Sopenharmony_ci /* exclusive access to 8051 memory */ 113262306a36Sopenharmony_ci spinlock_t dc8051_memlock; 113362306a36Sopenharmony_ci int dc8051_timed_out; /* remember if the 8051 timed out */ 113462306a36Sopenharmony_ci /* 113562306a36Sopenharmony_ci * A page that will hold event notification bitmaps for all 113662306a36Sopenharmony_ci * contexts. This page will be mapped into all processes. 113762306a36Sopenharmony_ci */ 113862306a36Sopenharmony_ci unsigned long *events; 113962306a36Sopenharmony_ci /* 114062306a36Sopenharmony_ci * per unit status, see also portdata statusp 114162306a36Sopenharmony_ci * mapped read-only into user processes so they can get unit and 114262306a36Sopenharmony_ci * IB link status cheaply 114362306a36Sopenharmony_ci */ 114462306a36Sopenharmony_ci struct hfi1_status *status; 114562306a36Sopenharmony_ci 114662306a36Sopenharmony_ci /* revision register shadow */ 114762306a36Sopenharmony_ci u64 revision; 114862306a36Sopenharmony_ci /* Base GUID for device (network order) */ 114962306a36Sopenharmony_ci u64 base_guid; 115062306a36Sopenharmony_ci 115162306a36Sopenharmony_ci /* both sides of the PCIe link are gen3 capable */ 115262306a36Sopenharmony_ci u8 link_gen3_capable; 115362306a36Sopenharmony_ci u8 dc_shutdown; 115462306a36Sopenharmony_ci /* localbus width (1, 2,4,8,16,32) from config space */ 115562306a36Sopenharmony_ci u32 lbus_width; 115662306a36Sopenharmony_ci /* localbus speed in MHz */ 115762306a36Sopenharmony_ci u32 lbus_speed; 115862306a36Sopenharmony_ci int unit; /* unit # of this chip */ 115962306a36Sopenharmony_ci int node; /* home node of this chip */ 116062306a36Sopenharmony_ci 116162306a36Sopenharmony_ci /* save these PCI fields to restore after a reset */ 116262306a36Sopenharmony_ci u32 pcibar0; 116362306a36Sopenharmony_ci u32 pcibar1; 116462306a36Sopenharmony_ci u32 pci_rom; 116562306a36Sopenharmony_ci u16 pci_command; 116662306a36Sopenharmony_ci u16 pcie_devctl; 116762306a36Sopenharmony_ci u16 pcie_lnkctl; 116862306a36Sopenharmony_ci u16 pcie_devctl2; 116962306a36Sopenharmony_ci u32 pci_msix0; 117062306a36Sopenharmony_ci u32 pci_tph2; 117162306a36Sopenharmony_ci 117262306a36Sopenharmony_ci /* 117362306a36Sopenharmony_ci * ASCII serial number, from flash, large enough for original 117462306a36Sopenharmony_ci * all digit strings, and longer serial number format 117562306a36Sopenharmony_ci */ 117662306a36Sopenharmony_ci u8 serial[SERIAL_MAX]; 117762306a36Sopenharmony_ci /* human readable board version */ 117862306a36Sopenharmony_ci u8 boardversion[BOARD_VERS_MAX]; 117962306a36Sopenharmony_ci u8 lbus_info[32]; /* human readable localbus info */ 118062306a36Sopenharmony_ci /* chip major rev, from CceRevision */ 118162306a36Sopenharmony_ci u8 majrev; 118262306a36Sopenharmony_ci /* chip minor rev, from CceRevision */ 118362306a36Sopenharmony_ci u8 minrev; 118462306a36Sopenharmony_ci /* hardware ID */ 118562306a36Sopenharmony_ci u8 hfi1_id; 118662306a36Sopenharmony_ci /* implementation code */ 118762306a36Sopenharmony_ci u8 icode; 118862306a36Sopenharmony_ci /* vAU of this device */ 118962306a36Sopenharmony_ci u8 vau; 119062306a36Sopenharmony_ci /* vCU of this device */ 119162306a36Sopenharmony_ci u8 vcu; 119262306a36Sopenharmony_ci /* link credits of this device */ 119362306a36Sopenharmony_ci u16 link_credits; 119462306a36Sopenharmony_ci /* initial vl15 credits to use */ 119562306a36Sopenharmony_ci u16 vl15_init; 119662306a36Sopenharmony_ci 119762306a36Sopenharmony_ci /* 119862306a36Sopenharmony_ci * Cached value for vl15buf, read during verify cap interrupt. VL15 119962306a36Sopenharmony_ci * credits are to be kept at 0 and set when handling the link-up 120062306a36Sopenharmony_ci * interrupt. This removes the possibility of receiving VL15 MAD 120162306a36Sopenharmony_ci * packets before this HFI is ready. 120262306a36Sopenharmony_ci */ 120362306a36Sopenharmony_ci u16 vl15buf_cached; 120462306a36Sopenharmony_ci 120562306a36Sopenharmony_ci /* Misc small ints */ 120662306a36Sopenharmony_ci u8 n_krcv_queues; 120762306a36Sopenharmony_ci u8 qos_shift; 120862306a36Sopenharmony_ci 120962306a36Sopenharmony_ci u16 irev; /* implementation revision */ 121062306a36Sopenharmony_ci u32 dc8051_ver; /* 8051 firmware version */ 121162306a36Sopenharmony_ci 121262306a36Sopenharmony_ci spinlock_t hfi1_diag_trans_lock; /* protect diag observer ops */ 121362306a36Sopenharmony_ci struct platform_config platform_config; 121462306a36Sopenharmony_ci struct platform_config_cache pcfg_cache; 121562306a36Sopenharmony_ci 121662306a36Sopenharmony_ci struct diag_client *diag_client; 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_ci /* general interrupt: mask of handled interrupts */ 121962306a36Sopenharmony_ci u64 gi_mask[CCE_NUM_INT_CSRS]; 122062306a36Sopenharmony_ci 122162306a36Sopenharmony_ci struct rcv_array_data rcv_entries; 122262306a36Sopenharmony_ci 122362306a36Sopenharmony_ci /* cycle length of PS* counters in HW (in picoseconds) */ 122462306a36Sopenharmony_ci u16 psxmitwait_check_rate; 122562306a36Sopenharmony_ci 122662306a36Sopenharmony_ci /* 122762306a36Sopenharmony_ci * 64 bit synthetic counters 122862306a36Sopenharmony_ci */ 122962306a36Sopenharmony_ci struct timer_list synth_stats_timer; 123062306a36Sopenharmony_ci 123162306a36Sopenharmony_ci /* MSI-X information */ 123262306a36Sopenharmony_ci struct hfi1_msix_info msix_info; 123362306a36Sopenharmony_ci 123462306a36Sopenharmony_ci /* 123562306a36Sopenharmony_ci * device counters 123662306a36Sopenharmony_ci */ 123762306a36Sopenharmony_ci char *cntrnames; 123862306a36Sopenharmony_ci size_t cntrnameslen; 123962306a36Sopenharmony_ci size_t ndevcntrs; 124062306a36Sopenharmony_ci u64 *cntrs; 124162306a36Sopenharmony_ci u64 *scntrs; 124262306a36Sopenharmony_ci 124362306a36Sopenharmony_ci /* 124462306a36Sopenharmony_ci * remembered values for synthetic counters 124562306a36Sopenharmony_ci */ 124662306a36Sopenharmony_ci u64 last_tx; 124762306a36Sopenharmony_ci u64 last_rx; 124862306a36Sopenharmony_ci 124962306a36Sopenharmony_ci /* 125062306a36Sopenharmony_ci * per-port counters 125162306a36Sopenharmony_ci */ 125262306a36Sopenharmony_ci size_t nportcntrs; 125362306a36Sopenharmony_ci char *portcntrnames; 125462306a36Sopenharmony_ci size_t portcntrnameslen; 125562306a36Sopenharmony_ci 125662306a36Sopenharmony_ci struct err_info_rcvport err_info_rcvport; 125762306a36Sopenharmony_ci struct err_info_constraint err_info_rcv_constraint; 125862306a36Sopenharmony_ci struct err_info_constraint err_info_xmit_constraint; 125962306a36Sopenharmony_ci 126062306a36Sopenharmony_ci atomic_t drop_packet; 126162306a36Sopenharmony_ci bool do_drop; 126262306a36Sopenharmony_ci u8 err_info_uncorrectable; 126362306a36Sopenharmony_ci u8 err_info_fmconfig; 126462306a36Sopenharmony_ci 126562306a36Sopenharmony_ci /* 126662306a36Sopenharmony_ci * Software counters for the status bits defined by the 126762306a36Sopenharmony_ci * associated error status registers 126862306a36Sopenharmony_ci */ 126962306a36Sopenharmony_ci u64 cce_err_status_cnt[NUM_CCE_ERR_STATUS_COUNTERS]; 127062306a36Sopenharmony_ci u64 rcv_err_status_cnt[NUM_RCV_ERR_STATUS_COUNTERS]; 127162306a36Sopenharmony_ci u64 misc_err_status_cnt[NUM_MISC_ERR_STATUS_COUNTERS]; 127262306a36Sopenharmony_ci u64 send_pio_err_status_cnt[NUM_SEND_PIO_ERR_STATUS_COUNTERS]; 127362306a36Sopenharmony_ci u64 send_dma_err_status_cnt[NUM_SEND_DMA_ERR_STATUS_COUNTERS]; 127462306a36Sopenharmony_ci u64 send_egress_err_status_cnt[NUM_SEND_EGRESS_ERR_STATUS_COUNTERS]; 127562306a36Sopenharmony_ci u64 send_err_status_cnt[NUM_SEND_ERR_STATUS_COUNTERS]; 127662306a36Sopenharmony_ci 127762306a36Sopenharmony_ci /* Software counter that spans all contexts */ 127862306a36Sopenharmony_ci u64 sw_ctxt_err_status_cnt[NUM_SEND_CTXT_ERR_STATUS_COUNTERS]; 127962306a36Sopenharmony_ci /* Software counter that spans all DMA engines */ 128062306a36Sopenharmony_ci u64 sw_send_dma_eng_err_status_cnt[ 128162306a36Sopenharmony_ci NUM_SEND_DMA_ENG_ERR_STATUS_COUNTERS]; 128262306a36Sopenharmony_ci /* Software counter that aggregates all cce_err_status errors */ 128362306a36Sopenharmony_ci u64 sw_cce_err_status_aggregate; 128462306a36Sopenharmony_ci /* Software counter that aggregates all bypass packet rcv errors */ 128562306a36Sopenharmony_ci u64 sw_rcv_bypass_packet_errors; 128662306a36Sopenharmony_ci 128762306a36Sopenharmony_ci /* Save the enabled LCB error bits */ 128862306a36Sopenharmony_ci u64 lcb_err_en; 128962306a36Sopenharmony_ci struct cpu_mask_set *comp_vect; 129062306a36Sopenharmony_ci int *comp_vect_mappings; 129162306a36Sopenharmony_ci u32 comp_vect_possible_cpus; 129262306a36Sopenharmony_ci 129362306a36Sopenharmony_ci /* 129462306a36Sopenharmony_ci * Capability to have different send engines simply by changing a 129562306a36Sopenharmony_ci * pointer value. 129662306a36Sopenharmony_ci */ 129762306a36Sopenharmony_ci send_routine process_pio_send ____cacheline_aligned_in_smp; 129862306a36Sopenharmony_ci send_routine process_dma_send; 129962306a36Sopenharmony_ci void (*pio_inline_send)(struct hfi1_devdata *dd, struct pio_buf *pbuf, 130062306a36Sopenharmony_ci u64 pbc, const void *from, size_t count); 130162306a36Sopenharmony_ci int (*process_vnic_dma_send)(struct hfi1_devdata *dd, u8 q_idx, 130262306a36Sopenharmony_ci struct hfi1_vnic_vport_info *vinfo, 130362306a36Sopenharmony_ci struct sk_buff *skb, u64 pbc, u8 plen); 130462306a36Sopenharmony_ci /* hfi1_pportdata, points to array of (physical) port-specific 130562306a36Sopenharmony_ci * data structs, indexed by pidx (0..n-1) 130662306a36Sopenharmony_ci */ 130762306a36Sopenharmony_ci struct hfi1_pportdata *pport; 130862306a36Sopenharmony_ci /* receive context data */ 130962306a36Sopenharmony_ci struct hfi1_ctxtdata **rcd; 131062306a36Sopenharmony_ci u64 __percpu *int_counter; 131162306a36Sopenharmony_ci /* verbs tx opcode stats */ 131262306a36Sopenharmony_ci struct hfi1_opcode_stats_perctx __percpu *tx_opstats; 131362306a36Sopenharmony_ci /* device (not port) flags, basically device capabilities */ 131462306a36Sopenharmony_ci u16 flags; 131562306a36Sopenharmony_ci /* Number of physical ports available */ 131662306a36Sopenharmony_ci u8 num_pports; 131762306a36Sopenharmony_ci /* Lowest context number which can be used by user processes or VNIC */ 131862306a36Sopenharmony_ci u8 first_dyn_alloc_ctxt; 131962306a36Sopenharmony_ci /* adding a new field here would make it part of this cacheline */ 132062306a36Sopenharmony_ci 132162306a36Sopenharmony_ci /* seqlock for sc2vl */ 132262306a36Sopenharmony_ci seqlock_t sc2vl_lock ____cacheline_aligned_in_smp; 132362306a36Sopenharmony_ci u64 sc2vl[4]; 132462306a36Sopenharmony_ci u64 __percpu *rcv_limit; 132562306a36Sopenharmony_ci /* adding a new field here would make it part of this cacheline */ 132662306a36Sopenharmony_ci 132762306a36Sopenharmony_ci /* OUI comes from the HW. Used everywhere as 3 separate bytes. */ 132862306a36Sopenharmony_ci u8 oui1; 132962306a36Sopenharmony_ci u8 oui2; 133062306a36Sopenharmony_ci u8 oui3; 133162306a36Sopenharmony_ci 133262306a36Sopenharmony_ci /* Timer and counter used to detect RcvBufOvflCnt changes */ 133362306a36Sopenharmony_ci struct timer_list rcverr_timer; 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ci wait_queue_head_t event_queue; 133662306a36Sopenharmony_ci 133762306a36Sopenharmony_ci /* receive context tail dummy address */ 133862306a36Sopenharmony_ci __le64 *rcvhdrtail_dummy_kvaddr; 133962306a36Sopenharmony_ci dma_addr_t rcvhdrtail_dummy_dma; 134062306a36Sopenharmony_ci 134162306a36Sopenharmony_ci u32 rcv_ovfl_cnt; 134262306a36Sopenharmony_ci /* Serialize ASPM enable/disable between multiple verbs contexts */ 134362306a36Sopenharmony_ci spinlock_t aspm_lock; 134462306a36Sopenharmony_ci /* Number of verbs contexts which have disabled ASPM */ 134562306a36Sopenharmony_ci atomic_t aspm_disabled_cnt; 134662306a36Sopenharmony_ci /* Keeps track of user space clients */ 134762306a36Sopenharmony_ci refcount_t user_refcount; 134862306a36Sopenharmony_ci /* Used to wait for outstanding user space clients before dev removal */ 134962306a36Sopenharmony_ci struct completion user_comp; 135062306a36Sopenharmony_ci 135162306a36Sopenharmony_ci bool eprom_available; /* true if EPROM is available for this device */ 135262306a36Sopenharmony_ci bool aspm_supported; /* Does HW support ASPM */ 135362306a36Sopenharmony_ci bool aspm_enabled; /* ASPM state: enabled/disabled */ 135462306a36Sopenharmony_ci struct rhashtable *sdma_rht; 135562306a36Sopenharmony_ci 135662306a36Sopenharmony_ci /* vnic data */ 135762306a36Sopenharmony_ci struct hfi1_vnic_data vnic; 135862306a36Sopenharmony_ci /* Lock to protect IRQ SRC register access */ 135962306a36Sopenharmony_ci spinlock_t irq_src_lock; 136062306a36Sopenharmony_ci int vnic_num_vports; 136162306a36Sopenharmony_ci struct hfi1_netdev_rx *netdev_rx; 136262306a36Sopenharmony_ci struct hfi1_affinity_node *affinity_entry; 136362306a36Sopenharmony_ci 136462306a36Sopenharmony_ci /* Keeps track of IPoIB RSM rule users */ 136562306a36Sopenharmony_ci atomic_t ipoib_rsm_usr_num; 136662306a36Sopenharmony_ci}; 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_ci/* 8051 firmware version helper */ 136962306a36Sopenharmony_ci#define dc8051_ver(a, b, c) ((a) << 16 | (b) << 8 | (c)) 137062306a36Sopenharmony_ci#define dc8051_ver_maj(a) (((a) & 0xff0000) >> 16) 137162306a36Sopenharmony_ci#define dc8051_ver_min(a) (((a) & 0x00ff00) >> 8) 137262306a36Sopenharmony_ci#define dc8051_ver_patch(a) ((a) & 0x0000ff) 137362306a36Sopenharmony_ci 137462306a36Sopenharmony_ci/* f_put_tid types */ 137562306a36Sopenharmony_ci#define PT_EXPECTED 0 137662306a36Sopenharmony_ci#define PT_EAGER 1 137762306a36Sopenharmony_ci#define PT_INVALID_FLUSH 2 137862306a36Sopenharmony_ci#define PT_INVALID 3 137962306a36Sopenharmony_ci 138062306a36Sopenharmony_cistruct tid_rb_node; 138162306a36Sopenharmony_ci 138262306a36Sopenharmony_ci/* Private data for file operations */ 138362306a36Sopenharmony_cistruct hfi1_filedata { 138462306a36Sopenharmony_ci struct srcu_struct pq_srcu; 138562306a36Sopenharmony_ci struct hfi1_devdata *dd; 138662306a36Sopenharmony_ci struct hfi1_ctxtdata *uctxt; 138762306a36Sopenharmony_ci struct hfi1_user_sdma_comp_q *cq; 138862306a36Sopenharmony_ci /* update side lock for SRCU */ 138962306a36Sopenharmony_ci spinlock_t pq_rcu_lock; 139062306a36Sopenharmony_ci struct hfi1_user_sdma_pkt_q __rcu *pq; 139162306a36Sopenharmony_ci u16 subctxt; 139262306a36Sopenharmony_ci /* for cpu affinity; -1 if none */ 139362306a36Sopenharmony_ci int rec_cpu_num; 139462306a36Sopenharmony_ci u32 tid_n_pinned; 139562306a36Sopenharmony_ci bool use_mn; 139662306a36Sopenharmony_ci struct tid_rb_node **entry_to_rb; 139762306a36Sopenharmony_ci spinlock_t tid_lock; /* protect tid_[limit,used] counters */ 139862306a36Sopenharmony_ci u32 tid_limit; 139962306a36Sopenharmony_ci u32 tid_used; 140062306a36Sopenharmony_ci u32 *invalid_tids; 140162306a36Sopenharmony_ci u32 invalid_tid_idx; 140262306a36Sopenharmony_ci /* protect invalid_tids array and invalid_tid_idx */ 140362306a36Sopenharmony_ci spinlock_t invalid_lock; 140462306a36Sopenharmony_ci}; 140562306a36Sopenharmony_ci 140662306a36Sopenharmony_ciextern struct xarray hfi1_dev_table; 140762306a36Sopenharmony_cistruct hfi1_devdata *hfi1_lookup(int unit); 140862306a36Sopenharmony_ci 140962306a36Sopenharmony_cistatic inline unsigned long uctxt_offset(struct hfi1_ctxtdata *uctxt) 141062306a36Sopenharmony_ci{ 141162306a36Sopenharmony_ci return (uctxt->ctxt - uctxt->dd->first_dyn_alloc_ctxt) * 141262306a36Sopenharmony_ci HFI1_MAX_SHARED_CTXTS; 141362306a36Sopenharmony_ci} 141462306a36Sopenharmony_ci 141562306a36Sopenharmony_ciint hfi1_init(struct hfi1_devdata *dd, int reinit); 141662306a36Sopenharmony_ciint hfi1_count_active_units(void); 141762306a36Sopenharmony_ci 141862306a36Sopenharmony_ciint hfi1_diag_add(struct hfi1_devdata *dd); 141962306a36Sopenharmony_civoid hfi1_diag_remove(struct hfi1_devdata *dd); 142062306a36Sopenharmony_civoid handle_linkup_change(struct hfi1_devdata *dd, u32 linkup); 142162306a36Sopenharmony_ci 142262306a36Sopenharmony_civoid handle_user_interrupt(struct hfi1_ctxtdata *rcd); 142362306a36Sopenharmony_ci 142462306a36Sopenharmony_ciint hfi1_create_rcvhdrq(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd); 142562306a36Sopenharmony_ciint hfi1_setup_eagerbufs(struct hfi1_ctxtdata *rcd); 142662306a36Sopenharmony_ciint hfi1_create_kctxts(struct hfi1_devdata *dd); 142762306a36Sopenharmony_ciint hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, int numa, 142862306a36Sopenharmony_ci struct hfi1_ctxtdata **rcd); 142962306a36Sopenharmony_civoid hfi1_free_ctxt(struct hfi1_ctxtdata *rcd); 143062306a36Sopenharmony_civoid hfi1_init_pportdata(struct pci_dev *pdev, struct hfi1_pportdata *ppd, 143162306a36Sopenharmony_ci struct hfi1_devdata *dd, u8 hw_pidx, u32 port); 143262306a36Sopenharmony_civoid hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd); 143362306a36Sopenharmony_ciint hfi1_rcd_put(struct hfi1_ctxtdata *rcd); 143462306a36Sopenharmony_ciint hfi1_rcd_get(struct hfi1_ctxtdata *rcd); 143562306a36Sopenharmony_cistruct hfi1_ctxtdata *hfi1_rcd_get_by_index_safe(struct hfi1_devdata *dd, 143662306a36Sopenharmony_ci u16 ctxt); 143762306a36Sopenharmony_cistruct hfi1_ctxtdata *hfi1_rcd_get_by_index(struct hfi1_devdata *dd, u16 ctxt); 143862306a36Sopenharmony_ciint handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread); 143962306a36Sopenharmony_ciint handle_receive_interrupt_nodma_rtail(struct hfi1_ctxtdata *rcd, int thread); 144062306a36Sopenharmony_ciint handle_receive_interrupt_dma_rtail(struct hfi1_ctxtdata *rcd, int thread); 144162306a36Sopenharmony_ciint handle_receive_interrupt_napi_fp(struct hfi1_ctxtdata *rcd, int budget); 144262306a36Sopenharmony_ciint handle_receive_interrupt_napi_sp(struct hfi1_ctxtdata *rcd, int budget); 144362306a36Sopenharmony_civoid set_all_slowpath(struct hfi1_devdata *dd); 144462306a36Sopenharmony_ci 144562306a36Sopenharmony_ciextern const struct pci_device_id hfi1_pci_tbl[]; 144662306a36Sopenharmony_civoid hfi1_make_ud_req_9B(struct rvt_qp *qp, 144762306a36Sopenharmony_ci struct hfi1_pkt_state *ps, 144862306a36Sopenharmony_ci struct rvt_swqe *wqe); 144962306a36Sopenharmony_ci 145062306a36Sopenharmony_civoid hfi1_make_ud_req_16B(struct rvt_qp *qp, 145162306a36Sopenharmony_ci struct hfi1_pkt_state *ps, 145262306a36Sopenharmony_ci struct rvt_swqe *wqe); 145362306a36Sopenharmony_ci 145462306a36Sopenharmony_ci/* receive packet handler dispositions */ 145562306a36Sopenharmony_ci#define RCV_PKT_OK 0x0 /* keep going */ 145662306a36Sopenharmony_ci#define RCV_PKT_LIMIT 0x1 /* stop, hit limit, start thread */ 145762306a36Sopenharmony_ci#define RCV_PKT_DONE 0x2 /* stop, no more packets detected */ 145862306a36Sopenharmony_ci 145962306a36Sopenharmony_ci/** 146062306a36Sopenharmony_ci * hfi1_rcd_head - add accessor for rcd head 146162306a36Sopenharmony_ci * @rcd: the context 146262306a36Sopenharmony_ci */ 146362306a36Sopenharmony_cistatic inline u32 hfi1_rcd_head(struct hfi1_ctxtdata *rcd) 146462306a36Sopenharmony_ci{ 146562306a36Sopenharmony_ci return rcd->head; 146662306a36Sopenharmony_ci} 146762306a36Sopenharmony_ci 146862306a36Sopenharmony_ci/** 146962306a36Sopenharmony_ci * hfi1_set_rcd_head - add accessor for rcd head 147062306a36Sopenharmony_ci * @rcd: the context 147162306a36Sopenharmony_ci * @head: the new head 147262306a36Sopenharmony_ci */ 147362306a36Sopenharmony_cistatic inline void hfi1_set_rcd_head(struct hfi1_ctxtdata *rcd, u32 head) 147462306a36Sopenharmony_ci{ 147562306a36Sopenharmony_ci rcd->head = head; 147662306a36Sopenharmony_ci} 147762306a36Sopenharmony_ci 147862306a36Sopenharmony_ci/* calculate the current RHF address */ 147962306a36Sopenharmony_cistatic inline __le32 *get_rhf_addr(struct hfi1_ctxtdata *rcd) 148062306a36Sopenharmony_ci{ 148162306a36Sopenharmony_ci return (__le32 *)rcd->rcvhdrq + rcd->head + rcd->rhf_offset; 148262306a36Sopenharmony_ci} 148362306a36Sopenharmony_ci 148462306a36Sopenharmony_ci/* return DMA_RTAIL configuration */ 148562306a36Sopenharmony_cistatic inline bool get_dma_rtail_setting(struct hfi1_ctxtdata *rcd) 148662306a36Sopenharmony_ci{ 148762306a36Sopenharmony_ci return !!HFI1_CAP_KGET_MASK(rcd->flags, DMA_RTAIL); 148862306a36Sopenharmony_ci} 148962306a36Sopenharmony_ci 149062306a36Sopenharmony_ci/** 149162306a36Sopenharmony_ci * hfi1_seq_incr_wrap - wrapping increment for sequence 149262306a36Sopenharmony_ci * @seq: the current sequence number 149362306a36Sopenharmony_ci * 149462306a36Sopenharmony_ci * Returns: the incremented seq 149562306a36Sopenharmony_ci */ 149662306a36Sopenharmony_cistatic inline u8 hfi1_seq_incr_wrap(u8 seq) 149762306a36Sopenharmony_ci{ 149862306a36Sopenharmony_ci if (++seq > RHF_MAX_SEQ) 149962306a36Sopenharmony_ci seq = 1; 150062306a36Sopenharmony_ci return seq; 150162306a36Sopenharmony_ci} 150262306a36Sopenharmony_ci 150362306a36Sopenharmony_ci/** 150462306a36Sopenharmony_ci * hfi1_seq_cnt - return seq_cnt member 150562306a36Sopenharmony_ci * @rcd: the receive context 150662306a36Sopenharmony_ci * 150762306a36Sopenharmony_ci * Return seq_cnt member 150862306a36Sopenharmony_ci */ 150962306a36Sopenharmony_cistatic inline u8 hfi1_seq_cnt(struct hfi1_ctxtdata *rcd) 151062306a36Sopenharmony_ci{ 151162306a36Sopenharmony_ci return rcd->seq_cnt; 151262306a36Sopenharmony_ci} 151362306a36Sopenharmony_ci 151462306a36Sopenharmony_ci/** 151562306a36Sopenharmony_ci * hfi1_set_seq_cnt - return seq_cnt member 151662306a36Sopenharmony_ci * @rcd: the receive context 151762306a36Sopenharmony_ci * 151862306a36Sopenharmony_ci * Return seq_cnt member 151962306a36Sopenharmony_ci */ 152062306a36Sopenharmony_cistatic inline void hfi1_set_seq_cnt(struct hfi1_ctxtdata *rcd, u8 cnt) 152162306a36Sopenharmony_ci{ 152262306a36Sopenharmony_ci rcd->seq_cnt = cnt; 152362306a36Sopenharmony_ci} 152462306a36Sopenharmony_ci 152562306a36Sopenharmony_ci/** 152662306a36Sopenharmony_ci * last_rcv_seq - is last 152762306a36Sopenharmony_ci * @rcd: the receive context 152862306a36Sopenharmony_ci * @seq: sequence 152962306a36Sopenharmony_ci * 153062306a36Sopenharmony_ci * return true if last packet 153162306a36Sopenharmony_ci */ 153262306a36Sopenharmony_cistatic inline bool last_rcv_seq(struct hfi1_ctxtdata *rcd, u32 seq) 153362306a36Sopenharmony_ci{ 153462306a36Sopenharmony_ci return seq != rcd->seq_cnt; 153562306a36Sopenharmony_ci} 153662306a36Sopenharmony_ci 153762306a36Sopenharmony_ci/** 153862306a36Sopenharmony_ci * rcd_seq_incr - increment context sequence number 153962306a36Sopenharmony_ci * @rcd: the receive context 154062306a36Sopenharmony_ci * @seq: the current sequence number 154162306a36Sopenharmony_ci * 154262306a36Sopenharmony_ci * Returns: true if the this was the last packet 154362306a36Sopenharmony_ci */ 154462306a36Sopenharmony_cistatic inline bool hfi1_seq_incr(struct hfi1_ctxtdata *rcd, u32 seq) 154562306a36Sopenharmony_ci{ 154662306a36Sopenharmony_ci rcd->seq_cnt = hfi1_seq_incr_wrap(rcd->seq_cnt); 154762306a36Sopenharmony_ci return last_rcv_seq(rcd, seq); 154862306a36Sopenharmony_ci} 154962306a36Sopenharmony_ci 155062306a36Sopenharmony_ci/** 155162306a36Sopenharmony_ci * get_hdrqentsize - return hdrq entry size 155262306a36Sopenharmony_ci * @rcd: the receive context 155362306a36Sopenharmony_ci */ 155462306a36Sopenharmony_cistatic inline u8 get_hdrqentsize(struct hfi1_ctxtdata *rcd) 155562306a36Sopenharmony_ci{ 155662306a36Sopenharmony_ci return rcd->rcvhdrqentsize; 155762306a36Sopenharmony_ci} 155862306a36Sopenharmony_ci 155962306a36Sopenharmony_ci/** 156062306a36Sopenharmony_ci * get_hdrq_cnt - return hdrq count 156162306a36Sopenharmony_ci * @rcd: the receive context 156262306a36Sopenharmony_ci */ 156362306a36Sopenharmony_cistatic inline u16 get_hdrq_cnt(struct hfi1_ctxtdata *rcd) 156462306a36Sopenharmony_ci{ 156562306a36Sopenharmony_ci return rcd->rcvhdrq_cnt; 156662306a36Sopenharmony_ci} 156762306a36Sopenharmony_ci 156862306a36Sopenharmony_ci/** 156962306a36Sopenharmony_ci * hfi1_is_slowpath - check if this context is slow path 157062306a36Sopenharmony_ci * @rcd: the receive context 157162306a36Sopenharmony_ci */ 157262306a36Sopenharmony_cistatic inline bool hfi1_is_slowpath(struct hfi1_ctxtdata *rcd) 157362306a36Sopenharmony_ci{ 157462306a36Sopenharmony_ci return rcd->do_interrupt == rcd->slow_handler; 157562306a36Sopenharmony_ci} 157662306a36Sopenharmony_ci 157762306a36Sopenharmony_ci/** 157862306a36Sopenharmony_ci * hfi1_is_fastpath - check if this context is fast path 157962306a36Sopenharmony_ci * @rcd: the receive context 158062306a36Sopenharmony_ci */ 158162306a36Sopenharmony_cistatic inline bool hfi1_is_fastpath(struct hfi1_ctxtdata *rcd) 158262306a36Sopenharmony_ci{ 158362306a36Sopenharmony_ci if (rcd->ctxt == HFI1_CTRL_CTXT) 158462306a36Sopenharmony_ci return false; 158562306a36Sopenharmony_ci 158662306a36Sopenharmony_ci return rcd->do_interrupt == rcd->fast_handler; 158762306a36Sopenharmony_ci} 158862306a36Sopenharmony_ci 158962306a36Sopenharmony_ci/** 159062306a36Sopenharmony_ci * hfi1_set_fast - change to the fast handler 159162306a36Sopenharmony_ci * @rcd: the receive context 159262306a36Sopenharmony_ci */ 159362306a36Sopenharmony_cistatic inline void hfi1_set_fast(struct hfi1_ctxtdata *rcd) 159462306a36Sopenharmony_ci{ 159562306a36Sopenharmony_ci if (unlikely(!rcd)) 159662306a36Sopenharmony_ci return; 159762306a36Sopenharmony_ci if (unlikely(!hfi1_is_fastpath(rcd))) 159862306a36Sopenharmony_ci rcd->do_interrupt = rcd->fast_handler; 159962306a36Sopenharmony_ci} 160062306a36Sopenharmony_ci 160162306a36Sopenharmony_ciint hfi1_reset_device(int); 160262306a36Sopenharmony_ci 160362306a36Sopenharmony_civoid receive_interrupt_work(struct work_struct *work); 160462306a36Sopenharmony_ci 160562306a36Sopenharmony_ci/* extract service channel from header and rhf */ 160662306a36Sopenharmony_cistatic inline int hfi1_9B_get_sc5(struct ib_header *hdr, u64 rhf) 160762306a36Sopenharmony_ci{ 160862306a36Sopenharmony_ci return ib_get_sc(hdr) | ((!!(rhf_dc_info(rhf))) << 4); 160962306a36Sopenharmony_ci} 161062306a36Sopenharmony_ci 161162306a36Sopenharmony_ci#define HFI1_JKEY_WIDTH 16 161262306a36Sopenharmony_ci#define HFI1_JKEY_MASK (BIT(16) - 1) 161362306a36Sopenharmony_ci#define HFI1_ADMIN_JKEY_RANGE 32 161462306a36Sopenharmony_ci 161562306a36Sopenharmony_ci/* 161662306a36Sopenharmony_ci * J_KEYs are split and allocated in the following groups: 161762306a36Sopenharmony_ci * 0 - 31 - users with administrator privileges 161862306a36Sopenharmony_ci * 32 - 63 - kernel protocols using KDETH packets 161962306a36Sopenharmony_ci * 64 - 65535 - all other users using KDETH packets 162062306a36Sopenharmony_ci */ 162162306a36Sopenharmony_cistatic inline u16 generate_jkey(kuid_t uid) 162262306a36Sopenharmony_ci{ 162362306a36Sopenharmony_ci u16 jkey = from_kuid(current_user_ns(), uid) & HFI1_JKEY_MASK; 162462306a36Sopenharmony_ci 162562306a36Sopenharmony_ci if (capable(CAP_SYS_ADMIN)) 162662306a36Sopenharmony_ci jkey &= HFI1_ADMIN_JKEY_RANGE - 1; 162762306a36Sopenharmony_ci else if (jkey < 64) 162862306a36Sopenharmony_ci jkey |= BIT(HFI1_JKEY_WIDTH - 1); 162962306a36Sopenharmony_ci 163062306a36Sopenharmony_ci return jkey; 163162306a36Sopenharmony_ci} 163262306a36Sopenharmony_ci 163362306a36Sopenharmony_ci/* 163462306a36Sopenharmony_ci * active_egress_rate 163562306a36Sopenharmony_ci * 163662306a36Sopenharmony_ci * returns the active egress rate in units of [10^6 bits/sec] 163762306a36Sopenharmony_ci */ 163862306a36Sopenharmony_cistatic inline u32 active_egress_rate(struct hfi1_pportdata *ppd) 163962306a36Sopenharmony_ci{ 164062306a36Sopenharmony_ci u16 link_speed = ppd->link_speed_active; 164162306a36Sopenharmony_ci u16 link_width = ppd->link_width_active; 164262306a36Sopenharmony_ci u32 egress_rate; 164362306a36Sopenharmony_ci 164462306a36Sopenharmony_ci if (link_speed == OPA_LINK_SPEED_25G) 164562306a36Sopenharmony_ci egress_rate = 25000; 164662306a36Sopenharmony_ci else /* assume OPA_LINK_SPEED_12_5G */ 164762306a36Sopenharmony_ci egress_rate = 12500; 164862306a36Sopenharmony_ci 164962306a36Sopenharmony_ci switch (link_width) { 165062306a36Sopenharmony_ci case OPA_LINK_WIDTH_4X: 165162306a36Sopenharmony_ci egress_rate *= 4; 165262306a36Sopenharmony_ci break; 165362306a36Sopenharmony_ci case OPA_LINK_WIDTH_3X: 165462306a36Sopenharmony_ci egress_rate *= 3; 165562306a36Sopenharmony_ci break; 165662306a36Sopenharmony_ci case OPA_LINK_WIDTH_2X: 165762306a36Sopenharmony_ci egress_rate *= 2; 165862306a36Sopenharmony_ci break; 165962306a36Sopenharmony_ci default: 166062306a36Sopenharmony_ci /* assume IB_WIDTH_1X */ 166162306a36Sopenharmony_ci break; 166262306a36Sopenharmony_ci } 166362306a36Sopenharmony_ci 166462306a36Sopenharmony_ci return egress_rate; 166562306a36Sopenharmony_ci} 166662306a36Sopenharmony_ci 166762306a36Sopenharmony_ci/* 166862306a36Sopenharmony_ci * egress_cycles 166962306a36Sopenharmony_ci * 167062306a36Sopenharmony_ci * Returns the number of 'fabric clock cycles' to egress a packet 167162306a36Sopenharmony_ci * of length 'len' bytes, at 'rate' Mbit/s. Since the fabric clock 167262306a36Sopenharmony_ci * rate is (approximately) 805 MHz, the units of the returned value 167362306a36Sopenharmony_ci * are (1/805 MHz). 167462306a36Sopenharmony_ci */ 167562306a36Sopenharmony_cistatic inline u32 egress_cycles(u32 len, u32 rate) 167662306a36Sopenharmony_ci{ 167762306a36Sopenharmony_ci u32 cycles; 167862306a36Sopenharmony_ci 167962306a36Sopenharmony_ci /* 168062306a36Sopenharmony_ci * cycles is: 168162306a36Sopenharmony_ci * 168262306a36Sopenharmony_ci * (length) [bits] / (rate) [bits/sec] 168362306a36Sopenharmony_ci * --------------------------------------------------- 168462306a36Sopenharmony_ci * fabric_clock_period == 1 /(805 * 10^6) [cycles/sec] 168562306a36Sopenharmony_ci */ 168662306a36Sopenharmony_ci 168762306a36Sopenharmony_ci cycles = len * 8; /* bits */ 168862306a36Sopenharmony_ci cycles *= 805; 168962306a36Sopenharmony_ci cycles /= rate; 169062306a36Sopenharmony_ci 169162306a36Sopenharmony_ci return cycles; 169262306a36Sopenharmony_ci} 169362306a36Sopenharmony_ci 169462306a36Sopenharmony_civoid set_link_ipg(struct hfi1_pportdata *ppd); 169562306a36Sopenharmony_civoid process_becn(struct hfi1_pportdata *ppd, u8 sl, u32 rlid, u32 lqpn, 169662306a36Sopenharmony_ci u32 rqpn, u8 svc_type); 169762306a36Sopenharmony_civoid return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn, 169862306a36Sopenharmony_ci u16 pkey, u32 slid, u32 dlid, u8 sc5, 169962306a36Sopenharmony_ci const struct ib_grh *old_grh); 170062306a36Sopenharmony_civoid return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp, 170162306a36Sopenharmony_ci u32 remote_qpn, u16 pkey, u32 slid, u32 dlid, 170262306a36Sopenharmony_ci u8 sc5, const struct ib_grh *old_grh); 170362306a36Sopenharmony_citypedef void (*hfi1_handle_cnp)(struct hfi1_ibport *ibp, struct rvt_qp *qp, 170462306a36Sopenharmony_ci u32 remote_qpn, u16 pkey, u32 slid, u32 dlid, 170562306a36Sopenharmony_ci u8 sc5, const struct ib_grh *old_grh); 170662306a36Sopenharmony_ci 170762306a36Sopenharmony_ci#define PKEY_CHECK_INVALID -1 170862306a36Sopenharmony_ciint egress_pkey_check(struct hfi1_pportdata *ppd, u32 slid, u16 pkey, 170962306a36Sopenharmony_ci u8 sc5, int8_t s_pkey_index); 171062306a36Sopenharmony_ci 171162306a36Sopenharmony_ci#define PACKET_EGRESS_TIMEOUT 350 171262306a36Sopenharmony_cistatic inline void pause_for_credit_return(struct hfi1_devdata *dd) 171362306a36Sopenharmony_ci{ 171462306a36Sopenharmony_ci /* Pause at least 1us, to ensure chip returns all credits */ 171562306a36Sopenharmony_ci u32 usec = cclock_to_ns(dd, PACKET_EGRESS_TIMEOUT) / 1000; 171662306a36Sopenharmony_ci 171762306a36Sopenharmony_ci udelay(usec ? usec : 1); 171862306a36Sopenharmony_ci} 171962306a36Sopenharmony_ci 172062306a36Sopenharmony_ci/** 172162306a36Sopenharmony_ci * sc_to_vlt() - reverse lookup sc to vl 172262306a36Sopenharmony_ci * @dd - devdata 172362306a36Sopenharmony_ci * @sc5 - 5 bit sc 172462306a36Sopenharmony_ci */ 172562306a36Sopenharmony_cistatic inline u8 sc_to_vlt(struct hfi1_devdata *dd, u8 sc5) 172662306a36Sopenharmony_ci{ 172762306a36Sopenharmony_ci unsigned seq; 172862306a36Sopenharmony_ci u8 rval; 172962306a36Sopenharmony_ci 173062306a36Sopenharmony_ci if (sc5 >= OPA_MAX_SCS) 173162306a36Sopenharmony_ci return (u8)(0xff); 173262306a36Sopenharmony_ci 173362306a36Sopenharmony_ci do { 173462306a36Sopenharmony_ci seq = read_seqbegin(&dd->sc2vl_lock); 173562306a36Sopenharmony_ci rval = *(((u8 *)dd->sc2vl) + sc5); 173662306a36Sopenharmony_ci } while (read_seqretry(&dd->sc2vl_lock, seq)); 173762306a36Sopenharmony_ci 173862306a36Sopenharmony_ci return rval; 173962306a36Sopenharmony_ci} 174062306a36Sopenharmony_ci 174162306a36Sopenharmony_ci#define PKEY_MEMBER_MASK 0x8000 174262306a36Sopenharmony_ci#define PKEY_LOW_15_MASK 0x7fff 174362306a36Sopenharmony_ci 174462306a36Sopenharmony_ci/* 174562306a36Sopenharmony_ci * ingress_pkey_matches_entry - return 1 if the pkey matches ent (ent 174662306a36Sopenharmony_ci * being an entry from the ingress partition key table), return 0 174762306a36Sopenharmony_ci * otherwise. Use the matching criteria for ingress partition keys 174862306a36Sopenharmony_ci * specified in the OPAv1 spec., section 9.10.14. 174962306a36Sopenharmony_ci */ 175062306a36Sopenharmony_cistatic inline int ingress_pkey_matches_entry(u16 pkey, u16 ent) 175162306a36Sopenharmony_ci{ 175262306a36Sopenharmony_ci u16 mkey = pkey & PKEY_LOW_15_MASK; 175362306a36Sopenharmony_ci u16 ment = ent & PKEY_LOW_15_MASK; 175462306a36Sopenharmony_ci 175562306a36Sopenharmony_ci if (mkey == ment) { 175662306a36Sopenharmony_ci /* 175762306a36Sopenharmony_ci * If pkey[15] is clear (limited partition member), 175862306a36Sopenharmony_ci * is bit 15 in the corresponding table element 175962306a36Sopenharmony_ci * clear (limited member)? 176062306a36Sopenharmony_ci */ 176162306a36Sopenharmony_ci if (!(pkey & PKEY_MEMBER_MASK)) 176262306a36Sopenharmony_ci return !!(ent & PKEY_MEMBER_MASK); 176362306a36Sopenharmony_ci return 1; 176462306a36Sopenharmony_ci } 176562306a36Sopenharmony_ci return 0; 176662306a36Sopenharmony_ci} 176762306a36Sopenharmony_ci 176862306a36Sopenharmony_ci/* 176962306a36Sopenharmony_ci * ingress_pkey_table_search - search the entire pkey table for 177062306a36Sopenharmony_ci * an entry which matches 'pkey'. return 0 if a match is found, 177162306a36Sopenharmony_ci * and 1 otherwise. 177262306a36Sopenharmony_ci */ 177362306a36Sopenharmony_cistatic int ingress_pkey_table_search(struct hfi1_pportdata *ppd, u16 pkey) 177462306a36Sopenharmony_ci{ 177562306a36Sopenharmony_ci int i; 177662306a36Sopenharmony_ci 177762306a36Sopenharmony_ci for (i = 0; i < MAX_PKEY_VALUES; i++) { 177862306a36Sopenharmony_ci if (ingress_pkey_matches_entry(pkey, ppd->pkeys[i])) 177962306a36Sopenharmony_ci return 0; 178062306a36Sopenharmony_ci } 178162306a36Sopenharmony_ci return 1; 178262306a36Sopenharmony_ci} 178362306a36Sopenharmony_ci 178462306a36Sopenharmony_ci/* 178562306a36Sopenharmony_ci * ingress_pkey_table_fail - record a failure of ingress pkey validation, 178662306a36Sopenharmony_ci * i.e., increment port_rcv_constraint_errors for the port, and record 178762306a36Sopenharmony_ci * the 'error info' for this failure. 178862306a36Sopenharmony_ci */ 178962306a36Sopenharmony_cistatic void ingress_pkey_table_fail(struct hfi1_pportdata *ppd, u16 pkey, 179062306a36Sopenharmony_ci u32 slid) 179162306a36Sopenharmony_ci{ 179262306a36Sopenharmony_ci struct hfi1_devdata *dd = ppd->dd; 179362306a36Sopenharmony_ci 179462306a36Sopenharmony_ci incr_cntr64(&ppd->port_rcv_constraint_errors); 179562306a36Sopenharmony_ci if (!(dd->err_info_rcv_constraint.status & OPA_EI_STATUS_SMASK)) { 179662306a36Sopenharmony_ci dd->err_info_rcv_constraint.status |= OPA_EI_STATUS_SMASK; 179762306a36Sopenharmony_ci dd->err_info_rcv_constraint.slid = slid; 179862306a36Sopenharmony_ci dd->err_info_rcv_constraint.pkey = pkey; 179962306a36Sopenharmony_ci } 180062306a36Sopenharmony_ci} 180162306a36Sopenharmony_ci 180262306a36Sopenharmony_ci/* 180362306a36Sopenharmony_ci * ingress_pkey_check - Return 0 if the ingress pkey is valid, return 1 180462306a36Sopenharmony_ci * otherwise. Use the criteria in the OPAv1 spec, section 9.10.14. idx 180562306a36Sopenharmony_ci * is a hint as to the best place in the partition key table to begin 180662306a36Sopenharmony_ci * searching. This function should not be called on the data path because 180762306a36Sopenharmony_ci * of performance reasons. On datapath pkey check is expected to be done 180862306a36Sopenharmony_ci * by HW and rcv_pkey_check function should be called instead. 180962306a36Sopenharmony_ci */ 181062306a36Sopenharmony_cistatic inline int ingress_pkey_check(struct hfi1_pportdata *ppd, u16 pkey, 181162306a36Sopenharmony_ci u8 sc5, u8 idx, u32 slid, bool force) 181262306a36Sopenharmony_ci{ 181362306a36Sopenharmony_ci if (!(force) && !(ppd->part_enforce & HFI1_PART_ENFORCE_IN)) 181462306a36Sopenharmony_ci return 0; 181562306a36Sopenharmony_ci 181662306a36Sopenharmony_ci /* If SC15, pkey[0:14] must be 0x7fff */ 181762306a36Sopenharmony_ci if ((sc5 == 0xf) && ((pkey & PKEY_LOW_15_MASK) != PKEY_LOW_15_MASK)) 181862306a36Sopenharmony_ci goto bad; 181962306a36Sopenharmony_ci 182062306a36Sopenharmony_ci /* Is the pkey = 0x0, or 0x8000? */ 182162306a36Sopenharmony_ci if ((pkey & PKEY_LOW_15_MASK) == 0) 182262306a36Sopenharmony_ci goto bad; 182362306a36Sopenharmony_ci 182462306a36Sopenharmony_ci /* The most likely matching pkey has index 'idx' */ 182562306a36Sopenharmony_ci if (ingress_pkey_matches_entry(pkey, ppd->pkeys[idx])) 182662306a36Sopenharmony_ci return 0; 182762306a36Sopenharmony_ci 182862306a36Sopenharmony_ci /* no match - try the whole table */ 182962306a36Sopenharmony_ci if (!ingress_pkey_table_search(ppd, pkey)) 183062306a36Sopenharmony_ci return 0; 183162306a36Sopenharmony_ci 183262306a36Sopenharmony_cibad: 183362306a36Sopenharmony_ci ingress_pkey_table_fail(ppd, pkey, slid); 183462306a36Sopenharmony_ci return 1; 183562306a36Sopenharmony_ci} 183662306a36Sopenharmony_ci 183762306a36Sopenharmony_ci/* 183862306a36Sopenharmony_ci * rcv_pkey_check - Return 0 if the ingress pkey is valid, return 1 183962306a36Sopenharmony_ci * otherwise. It only ensures pkey is vlid for QP0. This function 184062306a36Sopenharmony_ci * should be called on the data path instead of ingress_pkey_check 184162306a36Sopenharmony_ci * as on data path, pkey check is done by HW (except for QP0). 184262306a36Sopenharmony_ci */ 184362306a36Sopenharmony_cistatic inline int rcv_pkey_check(struct hfi1_pportdata *ppd, u16 pkey, 184462306a36Sopenharmony_ci u8 sc5, u16 slid) 184562306a36Sopenharmony_ci{ 184662306a36Sopenharmony_ci if (!(ppd->part_enforce & HFI1_PART_ENFORCE_IN)) 184762306a36Sopenharmony_ci return 0; 184862306a36Sopenharmony_ci 184962306a36Sopenharmony_ci /* If SC15, pkey[0:14] must be 0x7fff */ 185062306a36Sopenharmony_ci if ((sc5 == 0xf) && ((pkey & PKEY_LOW_15_MASK) != PKEY_LOW_15_MASK)) 185162306a36Sopenharmony_ci goto bad; 185262306a36Sopenharmony_ci 185362306a36Sopenharmony_ci return 0; 185462306a36Sopenharmony_cibad: 185562306a36Sopenharmony_ci ingress_pkey_table_fail(ppd, pkey, slid); 185662306a36Sopenharmony_ci return 1; 185762306a36Sopenharmony_ci} 185862306a36Sopenharmony_ci 185962306a36Sopenharmony_ci/* MTU handling */ 186062306a36Sopenharmony_ci 186162306a36Sopenharmony_ci/* MTU enumeration, 256-4k match IB */ 186262306a36Sopenharmony_ci#define OPA_MTU_0 0 186362306a36Sopenharmony_ci#define OPA_MTU_256 1 186462306a36Sopenharmony_ci#define OPA_MTU_512 2 186562306a36Sopenharmony_ci#define OPA_MTU_1024 3 186662306a36Sopenharmony_ci#define OPA_MTU_2048 4 186762306a36Sopenharmony_ci#define OPA_MTU_4096 5 186862306a36Sopenharmony_ci 186962306a36Sopenharmony_ciu32 lrh_max_header_bytes(struct hfi1_devdata *dd); 187062306a36Sopenharmony_ciint mtu_to_enum(u32 mtu, int default_if_bad); 187162306a36Sopenharmony_ciu16 enum_to_mtu(int mtu); 187262306a36Sopenharmony_cistatic inline int valid_ib_mtu(unsigned int mtu) 187362306a36Sopenharmony_ci{ 187462306a36Sopenharmony_ci return mtu == 256 || mtu == 512 || 187562306a36Sopenharmony_ci mtu == 1024 || mtu == 2048 || 187662306a36Sopenharmony_ci mtu == 4096; 187762306a36Sopenharmony_ci} 187862306a36Sopenharmony_ci 187962306a36Sopenharmony_cistatic inline int valid_opa_max_mtu(unsigned int mtu) 188062306a36Sopenharmony_ci{ 188162306a36Sopenharmony_ci return mtu >= 2048 && 188262306a36Sopenharmony_ci (valid_ib_mtu(mtu) || mtu == 8192 || mtu == 10240); 188362306a36Sopenharmony_ci} 188462306a36Sopenharmony_ci 188562306a36Sopenharmony_ciint set_mtu(struct hfi1_pportdata *ppd); 188662306a36Sopenharmony_ci 188762306a36Sopenharmony_ciint hfi1_set_lid(struct hfi1_pportdata *ppd, u32 lid, u8 lmc); 188862306a36Sopenharmony_civoid hfi1_disable_after_error(struct hfi1_devdata *dd); 188962306a36Sopenharmony_ciint hfi1_set_uevent_bits(struct hfi1_pportdata *ppd, const int evtbit); 189062306a36Sopenharmony_ciint hfi1_rcvbuf_validate(u32 size, u8 type, u16 *encode); 189162306a36Sopenharmony_ci 189262306a36Sopenharmony_ciint fm_get_table(struct hfi1_pportdata *ppd, int which, void *t); 189362306a36Sopenharmony_ciint fm_set_table(struct hfi1_pportdata *ppd, int which, void *t); 189462306a36Sopenharmony_ci 189562306a36Sopenharmony_civoid set_up_vau(struct hfi1_devdata *dd, u8 vau); 189662306a36Sopenharmony_civoid set_up_vl15(struct hfi1_devdata *dd, u16 vl15buf); 189762306a36Sopenharmony_civoid reset_link_credits(struct hfi1_devdata *dd); 189862306a36Sopenharmony_civoid assign_remote_cm_au_table(struct hfi1_devdata *dd, u8 vcu); 189962306a36Sopenharmony_ci 190062306a36Sopenharmony_ciint set_buffer_control(struct hfi1_pportdata *ppd, struct buffer_control *bc); 190162306a36Sopenharmony_ci 190262306a36Sopenharmony_cistatic inline struct hfi1_devdata *dd_from_ppd(struct hfi1_pportdata *ppd) 190362306a36Sopenharmony_ci{ 190462306a36Sopenharmony_ci return ppd->dd; 190562306a36Sopenharmony_ci} 190662306a36Sopenharmony_ci 190762306a36Sopenharmony_cistatic inline struct hfi1_devdata *dd_from_dev(struct hfi1_ibdev *dev) 190862306a36Sopenharmony_ci{ 190962306a36Sopenharmony_ci return container_of(dev, struct hfi1_devdata, verbs_dev); 191062306a36Sopenharmony_ci} 191162306a36Sopenharmony_ci 191262306a36Sopenharmony_cistatic inline struct hfi1_devdata *dd_from_ibdev(struct ib_device *ibdev) 191362306a36Sopenharmony_ci{ 191462306a36Sopenharmony_ci return dd_from_dev(to_idev(ibdev)); 191562306a36Sopenharmony_ci} 191662306a36Sopenharmony_ci 191762306a36Sopenharmony_cistatic inline struct hfi1_pportdata *ppd_from_ibp(struct hfi1_ibport *ibp) 191862306a36Sopenharmony_ci{ 191962306a36Sopenharmony_ci return container_of(ibp, struct hfi1_pportdata, ibport_data); 192062306a36Sopenharmony_ci} 192162306a36Sopenharmony_ci 192262306a36Sopenharmony_cistatic inline struct hfi1_ibdev *dev_from_rdi(struct rvt_dev_info *rdi) 192362306a36Sopenharmony_ci{ 192462306a36Sopenharmony_ci return container_of(rdi, struct hfi1_ibdev, rdi); 192562306a36Sopenharmony_ci} 192662306a36Sopenharmony_ci 192762306a36Sopenharmony_cistatic inline struct hfi1_ibport *to_iport(struct ib_device *ibdev, u32 port) 192862306a36Sopenharmony_ci{ 192962306a36Sopenharmony_ci struct hfi1_devdata *dd = dd_from_ibdev(ibdev); 193062306a36Sopenharmony_ci u32 pidx = port - 1; /* IB number port from 1, hdw from 0 */ 193162306a36Sopenharmony_ci 193262306a36Sopenharmony_ci WARN_ON(pidx >= dd->num_pports); 193362306a36Sopenharmony_ci return &dd->pport[pidx].ibport_data; 193462306a36Sopenharmony_ci} 193562306a36Sopenharmony_ci 193662306a36Sopenharmony_cistatic inline struct hfi1_ibport *rcd_to_iport(struct hfi1_ctxtdata *rcd) 193762306a36Sopenharmony_ci{ 193862306a36Sopenharmony_ci return &rcd->ppd->ibport_data; 193962306a36Sopenharmony_ci} 194062306a36Sopenharmony_ci 194162306a36Sopenharmony_ci/** 194262306a36Sopenharmony_ci * hfi1_may_ecn - Check whether FECN or BECN processing should be done 194362306a36Sopenharmony_ci * @pkt: the packet to be evaluated 194462306a36Sopenharmony_ci * 194562306a36Sopenharmony_ci * Check whether the FECN or BECN bits in the packet's header are 194662306a36Sopenharmony_ci * enabled, depending on packet type. 194762306a36Sopenharmony_ci * 194862306a36Sopenharmony_ci * This function only checks for FECN and BECN bits. Additional checks 194962306a36Sopenharmony_ci * are done in the slowpath (hfi1_process_ecn_slowpath()) in order to 195062306a36Sopenharmony_ci * ensure correct handling. 195162306a36Sopenharmony_ci */ 195262306a36Sopenharmony_cistatic inline bool hfi1_may_ecn(struct hfi1_packet *pkt) 195362306a36Sopenharmony_ci{ 195462306a36Sopenharmony_ci bool fecn, becn; 195562306a36Sopenharmony_ci 195662306a36Sopenharmony_ci if (pkt->etype == RHF_RCV_TYPE_BYPASS) { 195762306a36Sopenharmony_ci fecn = hfi1_16B_get_fecn(pkt->hdr); 195862306a36Sopenharmony_ci becn = hfi1_16B_get_becn(pkt->hdr); 195962306a36Sopenharmony_ci } else { 196062306a36Sopenharmony_ci fecn = ib_bth_get_fecn(pkt->ohdr); 196162306a36Sopenharmony_ci becn = ib_bth_get_becn(pkt->ohdr); 196262306a36Sopenharmony_ci } 196362306a36Sopenharmony_ci return fecn || becn; 196462306a36Sopenharmony_ci} 196562306a36Sopenharmony_ci 196662306a36Sopenharmony_cibool hfi1_process_ecn_slowpath(struct rvt_qp *qp, struct hfi1_packet *pkt, 196762306a36Sopenharmony_ci bool prescan); 196862306a36Sopenharmony_cistatic inline bool process_ecn(struct rvt_qp *qp, struct hfi1_packet *pkt) 196962306a36Sopenharmony_ci{ 197062306a36Sopenharmony_ci bool do_work; 197162306a36Sopenharmony_ci 197262306a36Sopenharmony_ci do_work = hfi1_may_ecn(pkt); 197362306a36Sopenharmony_ci if (unlikely(do_work)) 197462306a36Sopenharmony_ci return hfi1_process_ecn_slowpath(qp, pkt, false); 197562306a36Sopenharmony_ci return false; 197662306a36Sopenharmony_ci} 197762306a36Sopenharmony_ci 197862306a36Sopenharmony_ci/* 197962306a36Sopenharmony_ci * Return the indexed PKEY from the port PKEY table. 198062306a36Sopenharmony_ci */ 198162306a36Sopenharmony_cistatic inline u16 hfi1_get_pkey(struct hfi1_ibport *ibp, unsigned index) 198262306a36Sopenharmony_ci{ 198362306a36Sopenharmony_ci struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); 198462306a36Sopenharmony_ci u16 ret; 198562306a36Sopenharmony_ci 198662306a36Sopenharmony_ci if (index >= ARRAY_SIZE(ppd->pkeys)) 198762306a36Sopenharmony_ci ret = 0; 198862306a36Sopenharmony_ci else 198962306a36Sopenharmony_ci ret = ppd->pkeys[index]; 199062306a36Sopenharmony_ci 199162306a36Sopenharmony_ci return ret; 199262306a36Sopenharmony_ci} 199362306a36Sopenharmony_ci 199462306a36Sopenharmony_ci/* 199562306a36Sopenharmony_ci * Return the indexed GUID from the port GUIDs table. 199662306a36Sopenharmony_ci */ 199762306a36Sopenharmony_cistatic inline __be64 get_sguid(struct hfi1_ibport *ibp, unsigned int index) 199862306a36Sopenharmony_ci{ 199962306a36Sopenharmony_ci struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); 200062306a36Sopenharmony_ci 200162306a36Sopenharmony_ci WARN_ON(index >= HFI1_GUIDS_PER_PORT); 200262306a36Sopenharmony_ci return cpu_to_be64(ppd->guids[index]); 200362306a36Sopenharmony_ci} 200462306a36Sopenharmony_ci 200562306a36Sopenharmony_ci/* 200662306a36Sopenharmony_ci * Called by readers of cc_state only, must call under rcu_read_lock(). 200762306a36Sopenharmony_ci */ 200862306a36Sopenharmony_cistatic inline struct cc_state *get_cc_state(struct hfi1_pportdata *ppd) 200962306a36Sopenharmony_ci{ 201062306a36Sopenharmony_ci return rcu_dereference(ppd->cc_state); 201162306a36Sopenharmony_ci} 201262306a36Sopenharmony_ci 201362306a36Sopenharmony_ci/* 201462306a36Sopenharmony_ci * Called by writers of cc_state only, must call under cc_state_lock. 201562306a36Sopenharmony_ci */ 201662306a36Sopenharmony_cistatic inline 201762306a36Sopenharmony_cistruct cc_state *get_cc_state_protected(struct hfi1_pportdata *ppd) 201862306a36Sopenharmony_ci{ 201962306a36Sopenharmony_ci return rcu_dereference_protected(ppd->cc_state, 202062306a36Sopenharmony_ci lockdep_is_held(&ppd->cc_state_lock)); 202162306a36Sopenharmony_ci} 202262306a36Sopenharmony_ci 202362306a36Sopenharmony_ci/* 202462306a36Sopenharmony_ci * values for dd->flags (_device_ related flags) 202562306a36Sopenharmony_ci */ 202662306a36Sopenharmony_ci#define HFI1_INITTED 0x1 /* chip and driver up and initted */ 202762306a36Sopenharmony_ci#define HFI1_PRESENT 0x2 /* chip accesses can be done */ 202862306a36Sopenharmony_ci#define HFI1_FROZEN 0x4 /* chip in SPC freeze */ 202962306a36Sopenharmony_ci#define HFI1_HAS_SDMA_TIMEOUT 0x8 203062306a36Sopenharmony_ci#define HFI1_HAS_SEND_DMA 0x10 /* Supports Send DMA */ 203162306a36Sopenharmony_ci#define HFI1_FORCED_FREEZE 0x80 /* driver forced freeze mode */ 203262306a36Sopenharmony_ci#define HFI1_SHUTDOWN 0x100 /* device is shutting down */ 203362306a36Sopenharmony_ci 203462306a36Sopenharmony_ci/* IB dword length mask in PBC (lower 11 bits); same for all chips */ 203562306a36Sopenharmony_ci#define HFI1_PBC_LENGTH_MASK ((1 << 11) - 1) 203662306a36Sopenharmony_ci 203762306a36Sopenharmony_ci/* ctxt_flag bit offsets */ 203862306a36Sopenharmony_ci /* base context has not finished initializing */ 203962306a36Sopenharmony_ci#define HFI1_CTXT_BASE_UNINIT 1 204062306a36Sopenharmony_ci /* base context initaliation failed */ 204162306a36Sopenharmony_ci#define HFI1_CTXT_BASE_FAILED 2 204262306a36Sopenharmony_ci /* waiting for a packet to arrive */ 204362306a36Sopenharmony_ci#define HFI1_CTXT_WAITING_RCV 3 204462306a36Sopenharmony_ci /* waiting for an urgent packet to arrive */ 204562306a36Sopenharmony_ci#define HFI1_CTXT_WAITING_URG 4 204662306a36Sopenharmony_ci 204762306a36Sopenharmony_ci/* free up any allocated data at closes */ 204862306a36Sopenharmony_ciint hfi1_init_dd(struct hfi1_devdata *dd); 204962306a36Sopenharmony_civoid hfi1_free_devdata(struct hfi1_devdata *dd); 205062306a36Sopenharmony_ci 205162306a36Sopenharmony_ci/* LED beaconing functions */ 205262306a36Sopenharmony_civoid hfi1_start_led_override(struct hfi1_pportdata *ppd, unsigned int timeon, 205362306a36Sopenharmony_ci unsigned int timeoff); 205462306a36Sopenharmony_civoid shutdown_led_override(struct hfi1_pportdata *ppd); 205562306a36Sopenharmony_ci 205662306a36Sopenharmony_ci#define HFI1_CREDIT_RETURN_RATE (100) 205762306a36Sopenharmony_ci 205862306a36Sopenharmony_ci/* 205962306a36Sopenharmony_ci * The number of words for the KDETH protocol field. If this is 206062306a36Sopenharmony_ci * larger then the actual field used, then part of the payload 206162306a36Sopenharmony_ci * will be in the header. 206262306a36Sopenharmony_ci * 206362306a36Sopenharmony_ci * Optimally, we want this sized so that a typical case will 206462306a36Sopenharmony_ci * use full cache lines. The typical local KDETH header would 206562306a36Sopenharmony_ci * be: 206662306a36Sopenharmony_ci * 206762306a36Sopenharmony_ci * Bytes Field 206862306a36Sopenharmony_ci * 8 LRH 206962306a36Sopenharmony_ci * 12 BHT 207062306a36Sopenharmony_ci * ?? KDETH 207162306a36Sopenharmony_ci * 8 RHF 207262306a36Sopenharmony_ci * --- 207362306a36Sopenharmony_ci * 28 + KDETH 207462306a36Sopenharmony_ci * 207562306a36Sopenharmony_ci * For a 64-byte cache line, KDETH would need to be 36 bytes or 9 DWORDS 207662306a36Sopenharmony_ci */ 207762306a36Sopenharmony_ci#define DEFAULT_RCVHDRSIZE 9 207862306a36Sopenharmony_ci 207962306a36Sopenharmony_ci/* 208062306a36Sopenharmony_ci * Maximal header byte count: 208162306a36Sopenharmony_ci * 208262306a36Sopenharmony_ci * Bytes Field 208362306a36Sopenharmony_ci * 8 LRH 208462306a36Sopenharmony_ci * 40 GRH (optional) 208562306a36Sopenharmony_ci * 12 BTH 208662306a36Sopenharmony_ci * ?? KDETH 208762306a36Sopenharmony_ci * 8 RHF 208862306a36Sopenharmony_ci * --- 208962306a36Sopenharmony_ci * 68 + KDETH 209062306a36Sopenharmony_ci * 209162306a36Sopenharmony_ci * We also want to maintain a cache line alignment to assist DMA'ing 209262306a36Sopenharmony_ci * of the header bytes. Round up to a good size. 209362306a36Sopenharmony_ci */ 209462306a36Sopenharmony_ci#define DEFAULT_RCVHDR_ENTSIZE 32 209562306a36Sopenharmony_ci 209662306a36Sopenharmony_cibool hfi1_can_pin_pages(struct hfi1_devdata *dd, struct mm_struct *mm, 209762306a36Sopenharmony_ci u32 nlocked, u32 npages); 209862306a36Sopenharmony_ciint hfi1_acquire_user_pages(struct mm_struct *mm, unsigned long vaddr, 209962306a36Sopenharmony_ci size_t npages, bool writable, struct page **pages); 210062306a36Sopenharmony_civoid hfi1_release_user_pages(struct mm_struct *mm, struct page **p, 210162306a36Sopenharmony_ci size_t npages, bool dirty); 210262306a36Sopenharmony_ci 210362306a36Sopenharmony_ci/** 210462306a36Sopenharmony_ci * hfi1_rcvhdrtail_kvaddr - return tail kvaddr 210562306a36Sopenharmony_ci * @rcd - the receive context 210662306a36Sopenharmony_ci */ 210762306a36Sopenharmony_cistatic inline __le64 *hfi1_rcvhdrtail_kvaddr(const struct hfi1_ctxtdata *rcd) 210862306a36Sopenharmony_ci{ 210962306a36Sopenharmony_ci return (__le64 *)rcd->rcvhdrtail_kvaddr; 211062306a36Sopenharmony_ci} 211162306a36Sopenharmony_ci 211262306a36Sopenharmony_cistatic inline void clear_rcvhdrtail(const struct hfi1_ctxtdata *rcd) 211362306a36Sopenharmony_ci{ 211462306a36Sopenharmony_ci u64 *kv = (u64 *)hfi1_rcvhdrtail_kvaddr(rcd); 211562306a36Sopenharmony_ci 211662306a36Sopenharmony_ci if (kv) 211762306a36Sopenharmony_ci *kv = 0ULL; 211862306a36Sopenharmony_ci} 211962306a36Sopenharmony_ci 212062306a36Sopenharmony_cistatic inline u32 get_rcvhdrtail(const struct hfi1_ctxtdata *rcd) 212162306a36Sopenharmony_ci{ 212262306a36Sopenharmony_ci /* 212362306a36Sopenharmony_ci * volatile because it's a DMA target from the chip, routine is 212462306a36Sopenharmony_ci * inlined, and don't want register caching or reordering. 212562306a36Sopenharmony_ci */ 212662306a36Sopenharmony_ci return (u32)le64_to_cpu(*hfi1_rcvhdrtail_kvaddr(rcd)); 212762306a36Sopenharmony_ci} 212862306a36Sopenharmony_ci 212962306a36Sopenharmony_cistatic inline bool hfi1_packet_present(struct hfi1_ctxtdata *rcd) 213062306a36Sopenharmony_ci{ 213162306a36Sopenharmony_ci if (likely(!rcd->rcvhdrtail_kvaddr)) { 213262306a36Sopenharmony_ci u32 seq = rhf_rcv_seq(rhf_to_cpu(get_rhf_addr(rcd))); 213362306a36Sopenharmony_ci 213462306a36Sopenharmony_ci return !last_rcv_seq(rcd, seq); 213562306a36Sopenharmony_ci } 213662306a36Sopenharmony_ci return hfi1_rcd_head(rcd) != get_rcvhdrtail(rcd); 213762306a36Sopenharmony_ci} 213862306a36Sopenharmony_ci 213962306a36Sopenharmony_ci/* 214062306a36Sopenharmony_ci * sysfs interface. 214162306a36Sopenharmony_ci */ 214262306a36Sopenharmony_ci 214362306a36Sopenharmony_ciextern const char ib_hfi1_version[]; 214462306a36Sopenharmony_ciextern const struct attribute_group ib_hfi1_attr_group; 214562306a36Sopenharmony_ciextern const struct attribute_group *hfi1_attr_port_groups[]; 214662306a36Sopenharmony_ci 214762306a36Sopenharmony_ciint hfi1_device_create(struct hfi1_devdata *dd); 214862306a36Sopenharmony_civoid hfi1_device_remove(struct hfi1_devdata *dd); 214962306a36Sopenharmony_ci 215062306a36Sopenharmony_ciint hfi1_verbs_register_sysfs(struct hfi1_devdata *dd); 215162306a36Sopenharmony_civoid hfi1_verbs_unregister_sysfs(struct hfi1_devdata *dd); 215262306a36Sopenharmony_ci/* Hook for sysfs read of QSFP */ 215362306a36Sopenharmony_ciint qsfp_dump(struct hfi1_pportdata *ppd, char *buf, int len); 215462306a36Sopenharmony_ci 215562306a36Sopenharmony_ciint hfi1_pcie_init(struct hfi1_devdata *dd); 215662306a36Sopenharmony_civoid hfi1_pcie_cleanup(struct pci_dev *pdev); 215762306a36Sopenharmony_ciint hfi1_pcie_ddinit(struct hfi1_devdata *dd, struct pci_dev *pdev); 215862306a36Sopenharmony_civoid hfi1_pcie_ddcleanup(struct hfi1_devdata *); 215962306a36Sopenharmony_ciint pcie_speeds(struct hfi1_devdata *dd); 216062306a36Sopenharmony_ciint restore_pci_variables(struct hfi1_devdata *dd); 216162306a36Sopenharmony_ciint save_pci_variables(struct hfi1_devdata *dd); 216262306a36Sopenharmony_ciint do_pcie_gen3_transition(struct hfi1_devdata *dd); 216362306a36Sopenharmony_civoid tune_pcie_caps(struct hfi1_devdata *dd); 216462306a36Sopenharmony_ciint parse_platform_config(struct hfi1_devdata *dd); 216562306a36Sopenharmony_ciint get_platform_config_field(struct hfi1_devdata *dd, 216662306a36Sopenharmony_ci enum platform_config_table_type_encoding 216762306a36Sopenharmony_ci table_type, int table_index, int field_index, 216862306a36Sopenharmony_ci u32 *data, u32 len); 216962306a36Sopenharmony_ci 217062306a36Sopenharmony_cistruct pci_dev *get_pci_dev(struct rvt_dev_info *rdi); 217162306a36Sopenharmony_ci 217262306a36Sopenharmony_ci/* 217362306a36Sopenharmony_ci * Flush write combining store buffers (if present) and perform a write 217462306a36Sopenharmony_ci * barrier. 217562306a36Sopenharmony_ci */ 217662306a36Sopenharmony_cistatic inline void flush_wc(void) 217762306a36Sopenharmony_ci{ 217862306a36Sopenharmony_ci asm volatile("sfence" : : : "memory"); 217962306a36Sopenharmony_ci} 218062306a36Sopenharmony_ci 218162306a36Sopenharmony_civoid handle_eflags(struct hfi1_packet *packet); 218262306a36Sopenharmony_civoid seqfile_dump_rcd(struct seq_file *s, struct hfi1_ctxtdata *rcd); 218362306a36Sopenharmony_ci 218462306a36Sopenharmony_ci/* global module parameter variables */ 218562306a36Sopenharmony_ciextern unsigned int hfi1_max_mtu; 218662306a36Sopenharmony_ciextern unsigned int hfi1_cu; 218762306a36Sopenharmony_ciextern unsigned int user_credit_return_threshold; 218862306a36Sopenharmony_ciextern int num_user_contexts; 218962306a36Sopenharmony_ciextern unsigned long n_krcvqs; 219062306a36Sopenharmony_ciextern uint krcvqs[]; 219162306a36Sopenharmony_ciextern int krcvqsset; 219262306a36Sopenharmony_ciextern uint loopback; 219362306a36Sopenharmony_ciextern uint quick_linkup; 219462306a36Sopenharmony_ciextern uint rcv_intr_timeout; 219562306a36Sopenharmony_ciextern uint rcv_intr_count; 219662306a36Sopenharmony_ciextern uint rcv_intr_dynamic; 219762306a36Sopenharmony_ciextern ushort link_crc_mask; 219862306a36Sopenharmony_ci 219962306a36Sopenharmony_ciextern struct mutex hfi1_mutex; 220062306a36Sopenharmony_ci 220162306a36Sopenharmony_ci/* Number of seconds before our card status check... */ 220262306a36Sopenharmony_ci#define STATUS_TIMEOUT 60 220362306a36Sopenharmony_ci 220462306a36Sopenharmony_ci#define DRIVER_NAME "hfi1" 220562306a36Sopenharmony_ci#define HFI1_USER_MINOR_BASE 0 220662306a36Sopenharmony_ci#define HFI1_TRACE_MINOR 127 220762306a36Sopenharmony_ci#define HFI1_NMINORS 255 220862306a36Sopenharmony_ci 220962306a36Sopenharmony_ci#define PCI_VENDOR_ID_INTEL 0x8086 221062306a36Sopenharmony_ci#define PCI_DEVICE_ID_INTEL0 0x24f0 221162306a36Sopenharmony_ci#define PCI_DEVICE_ID_INTEL1 0x24f1 221262306a36Sopenharmony_ci 221362306a36Sopenharmony_ci#define HFI1_PKT_USER_SC_INTEGRITY \ 221462306a36Sopenharmony_ci (SEND_CTXT_CHECK_ENABLE_DISALLOW_NON_KDETH_PACKETS_SMASK \ 221562306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_DISALLOW_KDETH_PACKETS_SMASK \ 221662306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_DISALLOW_BYPASS_SMASK \ 221762306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_DISALLOW_GRH_SMASK) 221862306a36Sopenharmony_ci 221962306a36Sopenharmony_ci#define HFI1_PKT_KERNEL_SC_INTEGRITY \ 222062306a36Sopenharmony_ci (SEND_CTXT_CHECK_ENABLE_DISALLOW_KDETH_PACKETS_SMASK) 222162306a36Sopenharmony_ci 222262306a36Sopenharmony_cistatic inline u64 hfi1_pkt_default_send_ctxt_mask(struct hfi1_devdata *dd, 222362306a36Sopenharmony_ci u16 ctxt_type) 222462306a36Sopenharmony_ci{ 222562306a36Sopenharmony_ci u64 base_sc_integrity; 222662306a36Sopenharmony_ci 222762306a36Sopenharmony_ci /* No integrity checks if HFI1_CAP_NO_INTEGRITY is set */ 222862306a36Sopenharmony_ci if (HFI1_CAP_IS_KSET(NO_INTEGRITY)) 222962306a36Sopenharmony_ci return 0; 223062306a36Sopenharmony_ci 223162306a36Sopenharmony_ci base_sc_integrity = 223262306a36Sopenharmony_ci SEND_CTXT_CHECK_ENABLE_DISALLOW_BYPASS_BAD_PKT_LEN_SMASK 223362306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_DISALLOW_PBC_STATIC_RATE_CONTROL_SMASK 223462306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_DISALLOW_TOO_LONG_BYPASS_PACKETS_SMASK 223562306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_DISALLOW_TOO_LONG_IB_PACKETS_SMASK 223662306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_DISALLOW_BAD_PKT_LEN_SMASK 223762306a36Sopenharmony_ci#ifndef CONFIG_FAULT_INJECTION 223862306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_DISALLOW_PBC_TEST_SMASK 223962306a36Sopenharmony_ci#endif 224062306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_DISALLOW_TOO_SMALL_BYPASS_PACKETS_SMASK 224162306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_DISALLOW_TOO_SMALL_IB_PACKETS_SMASK 224262306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_DISALLOW_RAW_IPV6_SMASK 224362306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_DISALLOW_RAW_SMASK 224462306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_CHECK_BYPASS_VL_MAPPING_SMASK 224562306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_CHECK_VL_MAPPING_SMASK 224662306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_CHECK_OPCODE_SMASK 224762306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_CHECK_SLID_SMASK 224862306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_CHECK_VL_SMASK 224962306a36Sopenharmony_ci | SEND_CTXT_CHECK_ENABLE_CHECK_ENABLE_SMASK; 225062306a36Sopenharmony_ci 225162306a36Sopenharmony_ci if (ctxt_type == SC_USER) 225262306a36Sopenharmony_ci base_sc_integrity |= 225362306a36Sopenharmony_ci#ifndef CONFIG_FAULT_INJECTION 225462306a36Sopenharmony_ci SEND_CTXT_CHECK_ENABLE_DISALLOW_PBC_TEST_SMASK | 225562306a36Sopenharmony_ci#endif 225662306a36Sopenharmony_ci HFI1_PKT_USER_SC_INTEGRITY; 225762306a36Sopenharmony_ci else if (ctxt_type != SC_KERNEL) 225862306a36Sopenharmony_ci base_sc_integrity |= HFI1_PKT_KERNEL_SC_INTEGRITY; 225962306a36Sopenharmony_ci 226062306a36Sopenharmony_ci /* turn on send-side job key checks if !A0 */ 226162306a36Sopenharmony_ci if (!is_ax(dd)) 226262306a36Sopenharmony_ci base_sc_integrity |= SEND_CTXT_CHECK_ENABLE_CHECK_JOB_KEY_SMASK; 226362306a36Sopenharmony_ci 226462306a36Sopenharmony_ci return base_sc_integrity; 226562306a36Sopenharmony_ci} 226662306a36Sopenharmony_ci 226762306a36Sopenharmony_cistatic inline u64 hfi1_pkt_base_sdma_integrity(struct hfi1_devdata *dd) 226862306a36Sopenharmony_ci{ 226962306a36Sopenharmony_ci u64 base_sdma_integrity; 227062306a36Sopenharmony_ci 227162306a36Sopenharmony_ci /* No integrity checks if HFI1_CAP_NO_INTEGRITY is set */ 227262306a36Sopenharmony_ci if (HFI1_CAP_IS_KSET(NO_INTEGRITY)) 227362306a36Sopenharmony_ci return 0; 227462306a36Sopenharmony_ci 227562306a36Sopenharmony_ci base_sdma_integrity = 227662306a36Sopenharmony_ci SEND_DMA_CHECK_ENABLE_DISALLOW_BYPASS_BAD_PKT_LEN_SMASK 227762306a36Sopenharmony_ci | SEND_DMA_CHECK_ENABLE_DISALLOW_TOO_LONG_BYPASS_PACKETS_SMASK 227862306a36Sopenharmony_ci | SEND_DMA_CHECK_ENABLE_DISALLOW_TOO_LONG_IB_PACKETS_SMASK 227962306a36Sopenharmony_ci | SEND_DMA_CHECK_ENABLE_DISALLOW_BAD_PKT_LEN_SMASK 228062306a36Sopenharmony_ci | SEND_DMA_CHECK_ENABLE_DISALLOW_TOO_SMALL_BYPASS_PACKETS_SMASK 228162306a36Sopenharmony_ci | SEND_DMA_CHECK_ENABLE_DISALLOW_TOO_SMALL_IB_PACKETS_SMASK 228262306a36Sopenharmony_ci | SEND_DMA_CHECK_ENABLE_DISALLOW_RAW_IPV6_SMASK 228362306a36Sopenharmony_ci | SEND_DMA_CHECK_ENABLE_DISALLOW_RAW_SMASK 228462306a36Sopenharmony_ci | SEND_DMA_CHECK_ENABLE_CHECK_BYPASS_VL_MAPPING_SMASK 228562306a36Sopenharmony_ci | SEND_DMA_CHECK_ENABLE_CHECK_VL_MAPPING_SMASK 228662306a36Sopenharmony_ci | SEND_DMA_CHECK_ENABLE_CHECK_OPCODE_SMASK 228762306a36Sopenharmony_ci | SEND_DMA_CHECK_ENABLE_CHECK_SLID_SMASK 228862306a36Sopenharmony_ci | SEND_DMA_CHECK_ENABLE_CHECK_VL_SMASK 228962306a36Sopenharmony_ci | SEND_DMA_CHECK_ENABLE_CHECK_ENABLE_SMASK; 229062306a36Sopenharmony_ci 229162306a36Sopenharmony_ci if (!HFI1_CAP_IS_KSET(STATIC_RATE_CTRL)) 229262306a36Sopenharmony_ci base_sdma_integrity |= 229362306a36Sopenharmony_ci SEND_DMA_CHECK_ENABLE_DISALLOW_PBC_STATIC_RATE_CONTROL_SMASK; 229462306a36Sopenharmony_ci 229562306a36Sopenharmony_ci /* turn on send-side job key checks if !A0 */ 229662306a36Sopenharmony_ci if (!is_ax(dd)) 229762306a36Sopenharmony_ci base_sdma_integrity |= 229862306a36Sopenharmony_ci SEND_DMA_CHECK_ENABLE_CHECK_JOB_KEY_SMASK; 229962306a36Sopenharmony_ci 230062306a36Sopenharmony_ci return base_sdma_integrity; 230162306a36Sopenharmony_ci} 230262306a36Sopenharmony_ci 230362306a36Sopenharmony_ci#define dd_dev_emerg(dd, fmt, ...) \ 230462306a36Sopenharmony_ci dev_emerg(&(dd)->pcidev->dev, "%s: " fmt, \ 230562306a36Sopenharmony_ci rvt_get_ibdev_name(&(dd)->verbs_dev.rdi), ##__VA_ARGS__) 230662306a36Sopenharmony_ci 230762306a36Sopenharmony_ci#define dd_dev_err(dd, fmt, ...) \ 230862306a36Sopenharmony_ci dev_err(&(dd)->pcidev->dev, "%s: " fmt, \ 230962306a36Sopenharmony_ci rvt_get_ibdev_name(&(dd)->verbs_dev.rdi), ##__VA_ARGS__) 231062306a36Sopenharmony_ci 231162306a36Sopenharmony_ci#define dd_dev_err_ratelimited(dd, fmt, ...) \ 231262306a36Sopenharmony_ci dev_err_ratelimited(&(dd)->pcidev->dev, "%s: " fmt, \ 231362306a36Sopenharmony_ci rvt_get_ibdev_name(&(dd)->verbs_dev.rdi), \ 231462306a36Sopenharmony_ci ##__VA_ARGS__) 231562306a36Sopenharmony_ci 231662306a36Sopenharmony_ci#define dd_dev_warn(dd, fmt, ...) \ 231762306a36Sopenharmony_ci dev_warn(&(dd)->pcidev->dev, "%s: " fmt, \ 231862306a36Sopenharmony_ci rvt_get_ibdev_name(&(dd)->verbs_dev.rdi), ##__VA_ARGS__) 231962306a36Sopenharmony_ci 232062306a36Sopenharmony_ci#define dd_dev_warn_ratelimited(dd, fmt, ...) \ 232162306a36Sopenharmony_ci dev_warn_ratelimited(&(dd)->pcidev->dev, "%s: " fmt, \ 232262306a36Sopenharmony_ci rvt_get_ibdev_name(&(dd)->verbs_dev.rdi), \ 232362306a36Sopenharmony_ci ##__VA_ARGS__) 232462306a36Sopenharmony_ci 232562306a36Sopenharmony_ci#define dd_dev_info(dd, fmt, ...) \ 232662306a36Sopenharmony_ci dev_info(&(dd)->pcidev->dev, "%s: " fmt, \ 232762306a36Sopenharmony_ci rvt_get_ibdev_name(&(dd)->verbs_dev.rdi), ##__VA_ARGS__) 232862306a36Sopenharmony_ci 232962306a36Sopenharmony_ci#define dd_dev_info_ratelimited(dd, fmt, ...) \ 233062306a36Sopenharmony_ci dev_info_ratelimited(&(dd)->pcidev->dev, "%s: " fmt, \ 233162306a36Sopenharmony_ci rvt_get_ibdev_name(&(dd)->verbs_dev.rdi), \ 233262306a36Sopenharmony_ci ##__VA_ARGS__) 233362306a36Sopenharmony_ci 233462306a36Sopenharmony_ci#define dd_dev_dbg(dd, fmt, ...) \ 233562306a36Sopenharmony_ci dev_dbg(&(dd)->pcidev->dev, "%s: " fmt, \ 233662306a36Sopenharmony_ci rvt_get_ibdev_name(&(dd)->verbs_dev.rdi), ##__VA_ARGS__) 233762306a36Sopenharmony_ci 233862306a36Sopenharmony_ci#define hfi1_dev_porterr(dd, port, fmt, ...) \ 233962306a36Sopenharmony_ci dev_err(&(dd)->pcidev->dev, "%s: port %u: " fmt, \ 234062306a36Sopenharmony_ci rvt_get_ibdev_name(&(dd)->verbs_dev.rdi), (port), ##__VA_ARGS__) 234162306a36Sopenharmony_ci 234262306a36Sopenharmony_ci/* 234362306a36Sopenharmony_ci * this is used for formatting hw error messages... 234462306a36Sopenharmony_ci */ 234562306a36Sopenharmony_cistruct hfi1_hwerror_msgs { 234662306a36Sopenharmony_ci u64 mask; 234762306a36Sopenharmony_ci const char *msg; 234862306a36Sopenharmony_ci size_t sz; 234962306a36Sopenharmony_ci}; 235062306a36Sopenharmony_ci 235162306a36Sopenharmony_ci/* in intr.c... */ 235262306a36Sopenharmony_civoid hfi1_format_hwerrors(u64 hwerrs, 235362306a36Sopenharmony_ci const struct hfi1_hwerror_msgs *hwerrmsgs, 235462306a36Sopenharmony_ci size_t nhwerrmsgs, char *msg, size_t lmsg); 235562306a36Sopenharmony_ci 235662306a36Sopenharmony_ci#define USER_OPCODE_CHECK_VAL 0xC0 235762306a36Sopenharmony_ci#define USER_OPCODE_CHECK_MASK 0xC0 235862306a36Sopenharmony_ci#define OPCODE_CHECK_VAL_DISABLED 0x0 235962306a36Sopenharmony_ci#define OPCODE_CHECK_MASK_DISABLED 0x0 236062306a36Sopenharmony_ci 236162306a36Sopenharmony_cistatic inline void hfi1_reset_cpu_counters(struct hfi1_devdata *dd) 236262306a36Sopenharmony_ci{ 236362306a36Sopenharmony_ci struct hfi1_pportdata *ppd; 236462306a36Sopenharmony_ci int i; 236562306a36Sopenharmony_ci 236662306a36Sopenharmony_ci dd->z_int_counter = get_all_cpu_total(dd->int_counter); 236762306a36Sopenharmony_ci dd->z_rcv_limit = get_all_cpu_total(dd->rcv_limit); 236862306a36Sopenharmony_ci dd->z_send_schedule = get_all_cpu_total(dd->send_schedule); 236962306a36Sopenharmony_ci 237062306a36Sopenharmony_ci ppd = (struct hfi1_pportdata *)(dd + 1); 237162306a36Sopenharmony_ci for (i = 0; i < dd->num_pports; i++, ppd++) { 237262306a36Sopenharmony_ci ppd->ibport_data.rvp.z_rc_acks = 237362306a36Sopenharmony_ci get_all_cpu_total(ppd->ibport_data.rvp.rc_acks); 237462306a36Sopenharmony_ci ppd->ibport_data.rvp.z_rc_qacks = 237562306a36Sopenharmony_ci get_all_cpu_total(ppd->ibport_data.rvp.rc_qacks); 237662306a36Sopenharmony_ci } 237762306a36Sopenharmony_ci} 237862306a36Sopenharmony_ci 237962306a36Sopenharmony_ci/* Control LED state */ 238062306a36Sopenharmony_cistatic inline void setextled(struct hfi1_devdata *dd, u32 on) 238162306a36Sopenharmony_ci{ 238262306a36Sopenharmony_ci if (on) 238362306a36Sopenharmony_ci write_csr(dd, DCC_CFG_LED_CNTRL, 0x1F); 238462306a36Sopenharmony_ci else 238562306a36Sopenharmony_ci write_csr(dd, DCC_CFG_LED_CNTRL, 0x10); 238662306a36Sopenharmony_ci} 238762306a36Sopenharmony_ci 238862306a36Sopenharmony_ci/* return the i2c resource given the target */ 238962306a36Sopenharmony_cistatic inline u32 i2c_target(u32 target) 239062306a36Sopenharmony_ci{ 239162306a36Sopenharmony_ci return target ? CR_I2C2 : CR_I2C1; 239262306a36Sopenharmony_ci} 239362306a36Sopenharmony_ci 239462306a36Sopenharmony_ci/* return the i2c chain chip resource that this HFI uses for QSFP */ 239562306a36Sopenharmony_cistatic inline u32 qsfp_resource(struct hfi1_devdata *dd) 239662306a36Sopenharmony_ci{ 239762306a36Sopenharmony_ci return i2c_target(dd->hfi1_id); 239862306a36Sopenharmony_ci} 239962306a36Sopenharmony_ci 240062306a36Sopenharmony_ci/* Is this device integrated or discrete? */ 240162306a36Sopenharmony_cistatic inline bool is_integrated(struct hfi1_devdata *dd) 240262306a36Sopenharmony_ci{ 240362306a36Sopenharmony_ci return dd->pcidev->device == PCI_DEVICE_ID_INTEL1; 240462306a36Sopenharmony_ci} 240562306a36Sopenharmony_ci 240662306a36Sopenharmony_ci/** 240762306a36Sopenharmony_ci * hfi1_need_drop - detect need for drop 240862306a36Sopenharmony_ci * @dd: - the device 240962306a36Sopenharmony_ci * 241062306a36Sopenharmony_ci * In some cases, the first packet needs to be dropped. 241162306a36Sopenharmony_ci * 241262306a36Sopenharmony_ci * Return true is the current packet needs to be dropped and false otherwise. 241362306a36Sopenharmony_ci */ 241462306a36Sopenharmony_cistatic inline bool hfi1_need_drop(struct hfi1_devdata *dd) 241562306a36Sopenharmony_ci{ 241662306a36Sopenharmony_ci if (unlikely(dd->do_drop && 241762306a36Sopenharmony_ci atomic_xchg(&dd->drop_packet, DROP_PACKET_OFF) == 241862306a36Sopenharmony_ci DROP_PACKET_ON)) { 241962306a36Sopenharmony_ci dd->do_drop = false; 242062306a36Sopenharmony_ci return true; 242162306a36Sopenharmony_ci } 242262306a36Sopenharmony_ci return false; 242362306a36Sopenharmony_ci} 242462306a36Sopenharmony_ci 242562306a36Sopenharmony_ciint hfi1_tempsense_rd(struct hfi1_devdata *dd, struct hfi1_temp *temp); 242662306a36Sopenharmony_ci 242762306a36Sopenharmony_ci#define DD_DEV_ENTRY(dd) __string(dev, dev_name(&(dd)->pcidev->dev)) 242862306a36Sopenharmony_ci#define DD_DEV_ASSIGN(dd) __assign_str(dev, dev_name(&(dd)->pcidev->dev)) 242962306a36Sopenharmony_ci 243062306a36Sopenharmony_cistatic inline void hfi1_update_ah_attr(struct ib_device *ibdev, 243162306a36Sopenharmony_ci struct rdma_ah_attr *attr) 243262306a36Sopenharmony_ci{ 243362306a36Sopenharmony_ci struct hfi1_pportdata *ppd; 243462306a36Sopenharmony_ci struct hfi1_ibport *ibp; 243562306a36Sopenharmony_ci u32 dlid = rdma_ah_get_dlid(attr); 243662306a36Sopenharmony_ci 243762306a36Sopenharmony_ci /* 243862306a36Sopenharmony_ci * Kernel clients may not have setup GRH information 243962306a36Sopenharmony_ci * Set that here. 244062306a36Sopenharmony_ci */ 244162306a36Sopenharmony_ci ibp = to_iport(ibdev, rdma_ah_get_port_num(attr)); 244262306a36Sopenharmony_ci ppd = ppd_from_ibp(ibp); 244362306a36Sopenharmony_ci if ((((dlid >= be16_to_cpu(IB_MULTICAST_LID_BASE)) || 244462306a36Sopenharmony_ci (ppd->lid >= be16_to_cpu(IB_MULTICAST_LID_BASE))) && 244562306a36Sopenharmony_ci (dlid != be32_to_cpu(OPA_LID_PERMISSIVE)) && 244662306a36Sopenharmony_ci (dlid != be16_to_cpu(IB_LID_PERMISSIVE)) && 244762306a36Sopenharmony_ci (!(rdma_ah_get_ah_flags(attr) & IB_AH_GRH))) || 244862306a36Sopenharmony_ci (rdma_ah_get_make_grd(attr))) { 244962306a36Sopenharmony_ci rdma_ah_set_ah_flags(attr, IB_AH_GRH); 245062306a36Sopenharmony_ci rdma_ah_set_interface_id(attr, OPA_MAKE_ID(dlid)); 245162306a36Sopenharmony_ci rdma_ah_set_subnet_prefix(attr, ibp->rvp.gid_prefix); 245262306a36Sopenharmony_ci } 245362306a36Sopenharmony_ci} 245462306a36Sopenharmony_ci 245562306a36Sopenharmony_ci/* 245662306a36Sopenharmony_ci * hfi1_check_mcast- Check if the given lid is 245762306a36Sopenharmony_ci * in the OPA multicast range. 245862306a36Sopenharmony_ci * 245962306a36Sopenharmony_ci * The LID might either reside in ah.dlid or might be 246062306a36Sopenharmony_ci * in the GRH of the address handle as DGID if extended 246162306a36Sopenharmony_ci * addresses are in use. 246262306a36Sopenharmony_ci */ 246362306a36Sopenharmony_cistatic inline bool hfi1_check_mcast(u32 lid) 246462306a36Sopenharmony_ci{ 246562306a36Sopenharmony_ci return ((lid >= opa_get_mcast_base(OPA_MCAST_NR)) && 246662306a36Sopenharmony_ci (lid != be32_to_cpu(OPA_LID_PERMISSIVE))); 246762306a36Sopenharmony_ci} 246862306a36Sopenharmony_ci 246962306a36Sopenharmony_ci#define opa_get_lid(lid, format) \ 247062306a36Sopenharmony_ci __opa_get_lid(lid, OPA_PORT_PACKET_FORMAT_##format) 247162306a36Sopenharmony_ci 247262306a36Sopenharmony_ci/* Convert a lid to a specific lid space */ 247362306a36Sopenharmony_cistatic inline u32 __opa_get_lid(u32 lid, u8 format) 247462306a36Sopenharmony_ci{ 247562306a36Sopenharmony_ci bool is_mcast = hfi1_check_mcast(lid); 247662306a36Sopenharmony_ci 247762306a36Sopenharmony_ci switch (format) { 247862306a36Sopenharmony_ci case OPA_PORT_PACKET_FORMAT_8B: 247962306a36Sopenharmony_ci case OPA_PORT_PACKET_FORMAT_10B: 248062306a36Sopenharmony_ci if (is_mcast) 248162306a36Sopenharmony_ci return (lid - opa_get_mcast_base(OPA_MCAST_NR) + 248262306a36Sopenharmony_ci 0xF0000); 248362306a36Sopenharmony_ci return lid & 0xFFFFF; 248462306a36Sopenharmony_ci case OPA_PORT_PACKET_FORMAT_16B: 248562306a36Sopenharmony_ci if (is_mcast) 248662306a36Sopenharmony_ci return (lid - opa_get_mcast_base(OPA_MCAST_NR) + 248762306a36Sopenharmony_ci 0xF00000); 248862306a36Sopenharmony_ci return lid & 0xFFFFFF; 248962306a36Sopenharmony_ci case OPA_PORT_PACKET_FORMAT_9B: 249062306a36Sopenharmony_ci if (is_mcast) 249162306a36Sopenharmony_ci return (lid - 249262306a36Sopenharmony_ci opa_get_mcast_base(OPA_MCAST_NR) + 249362306a36Sopenharmony_ci be16_to_cpu(IB_MULTICAST_LID_BASE)); 249462306a36Sopenharmony_ci else 249562306a36Sopenharmony_ci return lid & 0xFFFF; 249662306a36Sopenharmony_ci default: 249762306a36Sopenharmony_ci return lid; 249862306a36Sopenharmony_ci } 249962306a36Sopenharmony_ci} 250062306a36Sopenharmony_ci 250162306a36Sopenharmony_ci/* Return true if the given lid is the OPA 16B multicast range */ 250262306a36Sopenharmony_cistatic inline bool hfi1_is_16B_mcast(u32 lid) 250362306a36Sopenharmony_ci{ 250462306a36Sopenharmony_ci return ((lid >= 250562306a36Sopenharmony_ci opa_get_lid(opa_get_mcast_base(OPA_MCAST_NR), 16B)) && 250662306a36Sopenharmony_ci (lid != opa_get_lid(be32_to_cpu(OPA_LID_PERMISSIVE), 16B))); 250762306a36Sopenharmony_ci} 250862306a36Sopenharmony_ci 250962306a36Sopenharmony_cistatic inline void hfi1_make_opa_lid(struct rdma_ah_attr *attr) 251062306a36Sopenharmony_ci{ 251162306a36Sopenharmony_ci const struct ib_global_route *grh = rdma_ah_read_grh(attr); 251262306a36Sopenharmony_ci u32 dlid = rdma_ah_get_dlid(attr); 251362306a36Sopenharmony_ci 251462306a36Sopenharmony_ci /* Modify ah_attr.dlid to be in the 32 bit LID space. 251562306a36Sopenharmony_ci * This is how the address will be laid out: 251662306a36Sopenharmony_ci * Assuming MCAST_NR to be 4, 251762306a36Sopenharmony_ci * 32 bit permissive LID = 0xFFFFFFFF 251862306a36Sopenharmony_ci * Multicast LID range = 0xFFFFFFFE to 0xF0000000 251962306a36Sopenharmony_ci * Unicast LID range = 0xEFFFFFFF to 1 252062306a36Sopenharmony_ci * Invalid LID = 0 252162306a36Sopenharmony_ci */ 252262306a36Sopenharmony_ci if (ib_is_opa_gid(&grh->dgid)) 252362306a36Sopenharmony_ci dlid = opa_get_lid_from_gid(&grh->dgid); 252462306a36Sopenharmony_ci else if ((dlid >= be16_to_cpu(IB_MULTICAST_LID_BASE)) && 252562306a36Sopenharmony_ci (dlid != be16_to_cpu(IB_LID_PERMISSIVE)) && 252662306a36Sopenharmony_ci (dlid != be32_to_cpu(OPA_LID_PERMISSIVE))) 252762306a36Sopenharmony_ci dlid = dlid - be16_to_cpu(IB_MULTICAST_LID_BASE) + 252862306a36Sopenharmony_ci opa_get_mcast_base(OPA_MCAST_NR); 252962306a36Sopenharmony_ci else if (dlid == be16_to_cpu(IB_LID_PERMISSIVE)) 253062306a36Sopenharmony_ci dlid = be32_to_cpu(OPA_LID_PERMISSIVE); 253162306a36Sopenharmony_ci 253262306a36Sopenharmony_ci rdma_ah_set_dlid(attr, dlid); 253362306a36Sopenharmony_ci} 253462306a36Sopenharmony_ci 253562306a36Sopenharmony_cistatic inline u8 hfi1_get_packet_type(u32 lid) 253662306a36Sopenharmony_ci{ 253762306a36Sopenharmony_ci /* 9B if lid > 0xF0000000 */ 253862306a36Sopenharmony_ci if (lid >= opa_get_mcast_base(OPA_MCAST_NR)) 253962306a36Sopenharmony_ci return HFI1_PKT_TYPE_9B; 254062306a36Sopenharmony_ci 254162306a36Sopenharmony_ci /* 16B if lid > 0xC000 */ 254262306a36Sopenharmony_ci if (lid >= opa_get_lid(opa_get_mcast_base(OPA_MCAST_NR), 9B)) 254362306a36Sopenharmony_ci return HFI1_PKT_TYPE_16B; 254462306a36Sopenharmony_ci 254562306a36Sopenharmony_ci return HFI1_PKT_TYPE_9B; 254662306a36Sopenharmony_ci} 254762306a36Sopenharmony_ci 254862306a36Sopenharmony_cistatic inline bool hfi1_get_hdr_type(u32 lid, struct rdma_ah_attr *attr) 254962306a36Sopenharmony_ci{ 255062306a36Sopenharmony_ci /* 255162306a36Sopenharmony_ci * If there was an incoming 16B packet with permissive 255262306a36Sopenharmony_ci * LIDs, OPA GIDs would have been programmed when those 255362306a36Sopenharmony_ci * packets were received. A 16B packet will have to 255462306a36Sopenharmony_ci * be sent in response to that packet. Return a 16B 255562306a36Sopenharmony_ci * header type if that's the case. 255662306a36Sopenharmony_ci */ 255762306a36Sopenharmony_ci if (rdma_ah_get_dlid(attr) == be32_to_cpu(OPA_LID_PERMISSIVE)) 255862306a36Sopenharmony_ci return (ib_is_opa_gid(&rdma_ah_read_grh(attr)->dgid)) ? 255962306a36Sopenharmony_ci HFI1_PKT_TYPE_16B : HFI1_PKT_TYPE_9B; 256062306a36Sopenharmony_ci 256162306a36Sopenharmony_ci /* 256262306a36Sopenharmony_ci * Return a 16B header type if either the destination 256362306a36Sopenharmony_ci * or source lid is extended. 256462306a36Sopenharmony_ci */ 256562306a36Sopenharmony_ci if (hfi1_get_packet_type(rdma_ah_get_dlid(attr)) == HFI1_PKT_TYPE_16B) 256662306a36Sopenharmony_ci return HFI1_PKT_TYPE_16B; 256762306a36Sopenharmony_ci 256862306a36Sopenharmony_ci return hfi1_get_packet_type(lid); 256962306a36Sopenharmony_ci} 257062306a36Sopenharmony_ci 257162306a36Sopenharmony_cistatic inline void hfi1_make_ext_grh(struct hfi1_packet *packet, 257262306a36Sopenharmony_ci struct ib_grh *grh, u32 slid, 257362306a36Sopenharmony_ci u32 dlid) 257462306a36Sopenharmony_ci{ 257562306a36Sopenharmony_ci struct hfi1_ibport *ibp = &packet->rcd->ppd->ibport_data; 257662306a36Sopenharmony_ci struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); 257762306a36Sopenharmony_ci 257862306a36Sopenharmony_ci if (!ibp) 257962306a36Sopenharmony_ci return; 258062306a36Sopenharmony_ci 258162306a36Sopenharmony_ci grh->hop_limit = 1; 258262306a36Sopenharmony_ci grh->sgid.global.subnet_prefix = ibp->rvp.gid_prefix; 258362306a36Sopenharmony_ci if (slid == opa_get_lid(be32_to_cpu(OPA_LID_PERMISSIVE), 16B)) 258462306a36Sopenharmony_ci grh->sgid.global.interface_id = 258562306a36Sopenharmony_ci OPA_MAKE_ID(be32_to_cpu(OPA_LID_PERMISSIVE)); 258662306a36Sopenharmony_ci else 258762306a36Sopenharmony_ci grh->sgid.global.interface_id = OPA_MAKE_ID(slid); 258862306a36Sopenharmony_ci 258962306a36Sopenharmony_ci /* 259062306a36Sopenharmony_ci * Upper layers (like mad) may compare the dgid in the 259162306a36Sopenharmony_ci * wc that is obtained here with the sgid_index in 259262306a36Sopenharmony_ci * the wr. Since sgid_index in wr is always 0 for 259362306a36Sopenharmony_ci * extended lids, set the dgid here to the default 259462306a36Sopenharmony_ci * IB gid. 259562306a36Sopenharmony_ci */ 259662306a36Sopenharmony_ci grh->dgid.global.subnet_prefix = ibp->rvp.gid_prefix; 259762306a36Sopenharmony_ci grh->dgid.global.interface_id = 259862306a36Sopenharmony_ci cpu_to_be64(ppd->guids[HFI1_PORT_GUID_INDEX]); 259962306a36Sopenharmony_ci} 260062306a36Sopenharmony_ci 260162306a36Sopenharmony_cistatic inline int hfi1_get_16b_padding(u32 hdr_size, u32 payload) 260262306a36Sopenharmony_ci{ 260362306a36Sopenharmony_ci return -(hdr_size + payload + (SIZE_OF_CRC << 2) + 260462306a36Sopenharmony_ci SIZE_OF_LT) & 0x7; 260562306a36Sopenharmony_ci} 260662306a36Sopenharmony_ci 260762306a36Sopenharmony_cistatic inline void hfi1_make_ib_hdr(struct ib_header *hdr, 260862306a36Sopenharmony_ci u16 lrh0, u16 len, 260962306a36Sopenharmony_ci u16 dlid, u16 slid) 261062306a36Sopenharmony_ci{ 261162306a36Sopenharmony_ci hdr->lrh[0] = cpu_to_be16(lrh0); 261262306a36Sopenharmony_ci hdr->lrh[1] = cpu_to_be16(dlid); 261362306a36Sopenharmony_ci hdr->lrh[2] = cpu_to_be16(len); 261462306a36Sopenharmony_ci hdr->lrh[3] = cpu_to_be16(slid); 261562306a36Sopenharmony_ci} 261662306a36Sopenharmony_ci 261762306a36Sopenharmony_cistatic inline void hfi1_make_16b_hdr(struct hfi1_16b_header *hdr, 261862306a36Sopenharmony_ci u32 slid, u32 dlid, 261962306a36Sopenharmony_ci u16 len, u16 pkey, 262062306a36Sopenharmony_ci bool becn, bool fecn, u8 l4, 262162306a36Sopenharmony_ci u8 sc) 262262306a36Sopenharmony_ci{ 262362306a36Sopenharmony_ci u32 lrh0 = 0; 262462306a36Sopenharmony_ci u32 lrh1 = 0x40000000; 262562306a36Sopenharmony_ci u32 lrh2 = 0; 262662306a36Sopenharmony_ci u32 lrh3 = 0; 262762306a36Sopenharmony_ci 262862306a36Sopenharmony_ci lrh0 = (lrh0 & ~OPA_16B_BECN_MASK) | (becn << OPA_16B_BECN_SHIFT); 262962306a36Sopenharmony_ci lrh0 = (lrh0 & ~OPA_16B_LEN_MASK) | (len << OPA_16B_LEN_SHIFT); 263062306a36Sopenharmony_ci lrh0 = (lrh0 & ~OPA_16B_LID_MASK) | (slid & OPA_16B_LID_MASK); 263162306a36Sopenharmony_ci lrh1 = (lrh1 & ~OPA_16B_FECN_MASK) | (fecn << OPA_16B_FECN_SHIFT); 263262306a36Sopenharmony_ci lrh1 = (lrh1 & ~OPA_16B_SC_MASK) | (sc << OPA_16B_SC_SHIFT); 263362306a36Sopenharmony_ci lrh1 = (lrh1 & ~OPA_16B_LID_MASK) | (dlid & OPA_16B_LID_MASK); 263462306a36Sopenharmony_ci lrh2 = (lrh2 & ~OPA_16B_SLID_MASK) | 263562306a36Sopenharmony_ci ((slid >> OPA_16B_SLID_SHIFT) << OPA_16B_SLID_HIGH_SHIFT); 263662306a36Sopenharmony_ci lrh2 = (lrh2 & ~OPA_16B_DLID_MASK) | 263762306a36Sopenharmony_ci ((dlid >> OPA_16B_DLID_SHIFT) << OPA_16B_DLID_HIGH_SHIFT); 263862306a36Sopenharmony_ci lrh2 = (lrh2 & ~OPA_16B_PKEY_MASK) | ((u32)pkey << OPA_16B_PKEY_SHIFT); 263962306a36Sopenharmony_ci lrh2 = (lrh2 & ~OPA_16B_L4_MASK) | l4; 264062306a36Sopenharmony_ci 264162306a36Sopenharmony_ci hdr->lrh[0] = lrh0; 264262306a36Sopenharmony_ci hdr->lrh[1] = lrh1; 264362306a36Sopenharmony_ci hdr->lrh[2] = lrh2; 264462306a36Sopenharmony_ci hdr->lrh[3] = lrh3; 264562306a36Sopenharmony_ci} 264662306a36Sopenharmony_ci#endif /* _HFI1_KERNEL_H */ 2647