-/*
- * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
- * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
- * Copyright (c) 2005 Cisco Systems. All rights reserved.
- * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
- * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
- * Copyright (c) 2006 SilverStorm Technologies, Inc. All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * $Id$
- */
-
-#ifndef MTHCA_DEV_H
-#define MTHCA_DEV_H
-
-#include "hca_driver.h"
-#include "mthca_log.h"
-#include "mthca_provider.h"
-#include "mthca_doorbell.h"
-
-// must be synchronized with MTHCA.INF
-#define DRV_NAME "mthca"
-#define PFX DRV_NAME ": "
-//TODO
-#define DRV_VERSION "1.0.0000.566"
-#define DRV_RELDATE "12/21/2006"
-
-#define HZ 1000000 /* 1 sec in usecs */
-
-enum {
- MTHCA_FLAG_DDR_HIDDEN = 1 << 1,
- MTHCA_FLAG_SRQ = 1 << 2,
- MTHCA_FLAG_MSI = 1 << 3,
- MTHCA_FLAG_MSI_X = 1 << 4,
- MTHCA_FLAG_NO_LAM = 1 << 5,
- MTHCA_FLAG_FMR = 1 << 6,
- MTHCA_FLAG_MEMFREE = 1 << 7,
- MTHCA_FLAG_PCIE = 1 << 8,
- MTHCA_FLAG_SINAI_OPT = 1 << 9,
- MTHCA_FLAG_LIVEFISH = 1 << 10
-};
-
-enum {
- MTHCA_MAX_PORTS = 2
-};
-
-enum {
- MTHCA_BOARD_ID_LEN = 64
-};
-
-enum {
- MTHCA_EQ_CONTEXT_SIZE = 0x40,
- MTHCA_CQ_CONTEXT_SIZE = 0x40,
- MTHCA_QP_CONTEXT_SIZE = 0x200,
- MTHCA_RDB_ENTRY_SIZE = 0x20,
- MTHCA_AV_SIZE = 0x20,
- MTHCA_MGM_ENTRY_SIZE = 0x40,
-
- /* Arbel FW gives us these, but we need them for Tavor */
- MTHCA_MPT_ENTRY_SIZE = 0x40,
- MTHCA_MTT_SEG_SIZE = 0x40,
-
- MTHCA_QP_PER_MGM = 4 * (MTHCA_MGM_ENTRY_SIZE / 16 - 2)
-};
-
-enum {
- MTHCA_EQ_CMD,
- MTHCA_EQ_ASYNC,
- MTHCA_EQ_COMP,
- MTHCA_NUM_EQ
-};
-
-enum {
- MTHCA_BYTES_PER_ATOMIC_COMPL = 8
-};
-
-enum mthca_wr_opcode{
- MTHCA_OPCODE_NOP = 0x00,
- MTHCA_OPCODE_RDMA_WRITE = 0x08,
- MTHCA_OPCODE_RDMA_WRITE_IMM = 0x09,
- MTHCA_OPCODE_SEND = 0x0a,
- MTHCA_OPCODE_SEND_IMM = 0x0b,
- MTHCA_OPCODE_RDMA_READ = 0x10,
- MTHCA_OPCODE_ATOMIC_CS = 0x11,
- MTHCA_OPCODE_ATOMIC_FA = 0x12,
- MTHCA_OPCODE_BIND_MW = 0x18,
- MTHCA_OPCODE_INVALID = 0xff
-};
-
-struct mthca_cmd {
- struct pci_pool *pool;
- int use_events;
- KMUTEX hcr_mutex;
- KSEMAPHORE poll_sem;
- KSEMAPHORE event_sem;
- int max_cmds;
- spinlock_t context_lock;
- int free_head;
- struct mthca_cmd_context *context;
- u16 token_mask;
-};
-
-struct mthca_limits {
- int num_ports;
- int vl_cap;
- int mtu_cap;
- int gid_table_len;
- int pkey_table_len;
- int local_ca_ack_delay;
- int num_uars;
- int max_sg;
- int num_qps;
- int max_wqes;
- int max_desc_sz;
- int max_qp_init_rdma;
- int reserved_qps;
- int num_srqs;
- int max_srq_wqes;
- int max_srq_sge;
- int reserved_srqs;
- int num_eecs;
- int reserved_eecs;
- int num_cqs;
- int max_cqes;
- int reserved_cqs;
- int num_eqs;
- int reserved_eqs;
- int num_mpts;
- int num_mtt_segs;
- int fmr_reserved_mtts;
- int reserved_mtts;
- int reserved_mrws;
- int reserved_uars;
- int num_mgms;
- int num_amgms;
- int reserved_mcgs;
- int num_pds;
- int reserved_pds;
- u32 page_size_cap;
- u32 flags;
- u8 port_width_cap;
- u64 num_avs;
-};
-
-struct mthca_alloc {
- u32 last;
- u32 top;
- u32 max;
- u32 mask;
- spinlock_t lock;
- unsigned long *table;
-};
-
-struct mthca_array {
- struct {
- void **page;
- int used;
- } *page_list;
-};
-
-struct mthca_uar_table {
- struct mthca_alloc alloc;
- u64 uarc_base;
- int uarc_size;
-};
-
-struct mthca_pd_table {
- struct mthca_alloc alloc;
-};
-
-struct mthca_buddy {
- unsigned long **bits;
- int max_order;
- spinlock_t lock;
-};
-
-struct mthca_mr_table {
- struct mthca_alloc mpt_alloc;
- struct mthca_buddy mtt_buddy;
- struct mthca_buddy *fmr_mtt_buddy;
- u64 mtt_base;
- u64 mpt_base;
- struct mthca_icm_table *mtt_table;
- struct mthca_icm_table *mpt_table;
- struct {
- void __iomem *mpt_base;
- SIZE_T mpt_base_size;
- void __iomem *mtt_base;
- SIZE_T mtt_base_size;
- struct mthca_buddy mtt_buddy;
- } tavor_fmr;
-};
-
-struct mthca_eq_table {
- struct mthca_alloc alloc;
- void __iomem *clr_int;
- u32 clr_mask;
- u32 arm_mask;
- struct mthca_eq eq[MTHCA_NUM_EQ];
- u64 icm_virt;
- struct scatterlist sg;
- int have_irq;
- u8 inta_pin;
- KLOCK_QUEUE_HANDLE lockh;
-#if 1//WORKAROUND_POLL_EQ
- KEVENT thread_start_event;
- KEVENT thread_stop_event;
- BOOLEAN bTerminated;
- PVOID threadObject;
-#endif
-};
-
-struct mthca_cq_table {
- struct mthca_alloc alloc;
- spinlock_t lock;
- struct mthca_array cq;
- struct mthca_icm_table *table;
-};
-
-struct mthca_srq_table {
- struct mthca_alloc alloc;
- spinlock_t lock;
- struct mthca_array srq;
- struct mthca_icm_table *table;
-};
-
-struct mthca_qp_table {
- struct mthca_alloc alloc;
- u32 rdb_base;
- int rdb_shift;
- int sqp_start;
- spinlock_t lock;
- struct mthca_array qp;
- struct mthca_icm_table *qp_table;
- struct mthca_icm_table *eqp_table;
- struct mthca_icm_table *rdb_table;
-};
-
-struct mthca_av_table {
- struct pci_pool *pool;
- int num_ddr_avs;
- u64 ddr_av_base;
- void __iomem *av_map;
- SIZE_T av_map_size;
- struct mthca_alloc alloc;
-};
-
-struct mthca_mcg_table {
- KMUTEX mutex;
- struct mthca_alloc alloc;
- struct mthca_icm_table *table;
-};
-
-struct mthca_catas_err {
- u64 addr;
- u32 __iomem *map;
- SIZE_T map_size;
- unsigned long stop;
- u32 size;
- KTIMER timer;
- KDPC timer_dpc;
- LARGE_INTEGER interval;
-};
-
-struct mthca_dev {
- struct ib_device ib_dev;
- hca_dev_ext_t *ext;
- uplink_info_t uplink_info;
- volatile long dpc_lock;
-
- int hca_type;
- unsigned long mthca_flags;
- unsigned long device_cap_flags;
-
- u32 rev_id;
- char board_id[MTHCA_BOARD_ID_LEN];
-
- /* firmware info */
- u64 fw_ver;
- union {
- struct {
- u64 fw_start;
- u64 fw_end;
- } tavor;
- struct {
- u64 clr_int_base;
- u64 eq_arm_base;
- u64 eq_set_ci_base;
- struct mthca_icm *fw_icm;
- struct mthca_icm *aux_icm;
- u16 fw_pages;
- } arbel;
- } fw;
-
- u64 ddr_start;
- u64 ddr_end;
-
- MTHCA_DECLARE_DOORBELL_LOCK(doorbell_lock)
- KMUTEX cap_mask_mutex;
-
- u8 __iomem *hcr;
- SIZE_T hcr_size;
- u8 __iomem *kar;
- SIZE_T kar_size;
- u8 __iomem *clr_base;
- SIZE_T clr_base_size;
- union {
- struct {
- void __iomem *ecr_base;
- SIZE_T ecr_base_size;
- } tavor;
- struct {
- void __iomem *eq_arm;
- SIZE_T eq_arm_size;
- void __iomem *eq_set_ci_base;
- SIZE_T eq_set_ci_base_size;
- } arbel;
- } eq_regs;
-
- struct mthca_cmd cmd;
- struct mthca_limits limits;
-
- struct mthca_uar_table uar_table;
- struct mthca_pd_table pd_table;
- struct mthca_mr_table mr_table;
- struct mthca_eq_table eq_table;
- struct mthca_cq_table cq_table;
- struct mthca_srq_table srq_table;
- struct mthca_qp_table qp_table;
- struct mthca_av_table av_table;
- struct mthca_mcg_table mcg_table;
- struct mthca_catas_err catas_err;
- struct mthca_uar driver_uar;
- struct mthca_db_table *db_tab;
- struct mthca_pd driver_pd;
- struct mthca_mr driver_mr;
-
- struct ib_mad_agent *send_agent[MTHCA_MAX_PORTS][2];
- struct ib_ah *sm_ah[MTHCA_MAX_PORTS];
- spinlock_t sm_lock;
- u32 state;
-};
-
-// mthca_dev states
-enum {
- MTHCA_DEV_UNINITIALIZED,
- MTHCA_DEV_INITIALIZED,
- MTHCA_DEV_FAILED
-};
-
-enum {
- MTHCA_CQ_ENTRY_SIZE = 0x20
-};
-
-
-
-#define MTHCA_GET(dest, source, offset) \
- { \
- void *__p = (char *) (source) + (offset); \
- void *__q = &(dest); \
- switch (sizeof (dest)) { \
- case 1: *(u8 *)__q = *(u8 *) __p; break; \
- case 2: *(u16 *)__q = (u16)cl_ntoh16(*(u16 *)__p); break; \
- case 4: *(u32 *)__q = (u32)cl_ntoh32(*(u32 *)__p); break; \
- case 8: *(u64 *)__q = (u64)cl_ntoh64(*(u64 *)__p); break; \
- default: ASSERT(0); \
- } \
- }
-
-
-#define MTHCA_PUT(dest, source, offset) \
- { \
- void *__d = ((char *) (dest) + (offset)); \
- switch (sizeof(source)) { \
- case 1: *(u8 *) __d = (u8)(source); break; \
- case 2: *(__be16 *) __d = cl_hton16((u16)source); break; \
- case 4: *(__be32 *) __d = cl_hton32((u32)source); break; \
- case 8: *(__be64 *) __d = cl_hton64((u64)source); break; \
- default: ASSERT(0); \
- } \
- }
-
-NTSTATUS mthca_reset(struct mthca_dev *mdev);
-
-u32 mthca_alloc(struct mthca_alloc *alloc);
-void mthca_free(struct mthca_alloc *alloc, u32 obj);
-int mthca_alloc_init(struct mthca_alloc *alloc, u32 num, u32 mask,
- u32 reserved);
-void mthca_alloc_cleanup(struct mthca_alloc *alloc);
-void *mthca_array_get(struct mthca_array *array, int index);
-int mthca_array_set(struct mthca_array *array, int index, void *value);
-void mthca_array_clear(struct mthca_array *array, int index);
-int mthca_array_init(struct mthca_array *array, int nent);
-void mthca_array_cleanup(struct mthca_array *array, int nent);
-int mthca_buf_alloc(struct mthca_dev *dev, int size, int max_direct,
- union mthca_buf *buf, int *is_direct, struct mthca_pd *pd,
- int hca_write, struct mthca_mr *mr);
-void mthca_buf_free(struct mthca_dev *dev, int size, union mthca_buf *buf,
- int is_direct, struct mthca_mr *mr);
-
-int mthca_init_uar_table(struct mthca_dev *dev);
-int mthca_init_pd_table(struct mthca_dev *dev);
-int mthca_init_mr_table(struct mthca_dev *dev);
-int mthca_init_eq_table(struct mthca_dev *dev);
-int mthca_init_cq_table(struct mthca_dev *dev);
-int mthca_init_srq_table(struct mthca_dev *dev);
-int mthca_init_qp_table(struct mthca_dev *dev);
-int mthca_init_av_table(struct mthca_dev *dev);
-int mthca_init_mcg_table(struct mthca_dev *dev);
-
-void mthca_cleanup_uar_table(struct mthca_dev *dev);
-void mthca_cleanup_pd_table(struct mthca_dev *dev);
-void mthca_cleanup_mr_table(struct mthca_dev *dev);
-void mthca_cleanup_eq_table(struct mthca_dev *dev);
-void mthca_cleanup_cq_table(struct mthca_dev *dev);
-void mthca_cleanup_srq_table(struct mthca_dev *dev);
-void mthca_cleanup_qp_table(struct mthca_dev *dev);
-void mthca_cleanup_av_table(struct mthca_dev *dev);
-void mthca_cleanup_mcg_table(struct mthca_dev *dev);
-
-int mthca_register_device(struct mthca_dev *dev);
-void mthca_unregister_device(struct mthca_dev *dev);
-
-void mthca_start_catas_poll(struct mthca_dev *dev);
-void mthca_stop_catas_poll(struct mthca_dev *dev);
-
-int mthca_uar_alloc(struct mthca_dev *dev, struct mthca_uar *uar);
-void mthca_uar_free(struct mthca_dev *dev, struct mthca_uar *uar);
-
-int mthca_pd_alloc(struct mthca_dev *dev, int privileged, struct mthca_pd *pd);
-void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd);
-
-struct mthca_mtt *mthca_alloc_mtt(struct mthca_dev *dev, int size);
-void mthca_free_mtt(struct mthca_dev *dev, struct mthca_mtt *mtt);
-int mthca_write_mtt(struct mthca_dev *dev, struct mthca_mtt *mtt,
- int start_index, u64 *buffer_list, int list_len);
-int mthca_mr_alloc(struct mthca_dev *dev, u32 pd, int buffer_size_shift,
- u64 iova, u64 total_size, mthca_mpt_access_t access, struct mthca_mr *mr);
-int mthca_mr_alloc_notrans(struct mthca_dev *dev, u32 pd,
- mthca_mpt_access_t access, struct mthca_mr *mr);
-int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd,
- u64 *buffer_list, int buffer_size_shift,
- int list_len, u64 iova, u64 total_size,
- mthca_mpt_access_t access, struct mthca_mr *mr);
-void mthca_free_mr(struct mthca_dev *dev, struct mthca_mr *mr);
-
-int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd,
- mthca_mpt_access_t access, struct mthca_fmr *fmr);
-int mthca_tavor_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
- int list_len, u64 iova);
-void mthca_tavor_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr);
-int mthca_arbel_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
- int list_len, u64 iova);
-void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr);
-int mthca_free_fmr(struct mthca_dev *dev, struct mthca_fmr *fmr);
-
-int mthca_map_eq_icm(struct mthca_dev *dev, u64 icm_virt);
-void mthca_unmap_eq_icm(struct mthca_dev *dev);
-
-int mthca_poll_cq(struct ib_cq *ibcq, int num_entries,
- struct _ib_wc *entry);
-int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify);
-int mthca_arbel_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify);
-int mthca_init_cq(struct mthca_dev *dev, int nent,
- struct mthca_ucontext *ctx, u32 pdn,
- struct mthca_cq *cq);
-void mthca_free_cq(struct mthca_dev *dev,
- struct mthca_cq *cq);
-void mthca_cq_completion(struct mthca_dev *dev, u32 cqn);
-void mthca_cq_event(struct mthca_dev *dev, u32 cqn,
- enum ib_event_type event_type);
-void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
- struct mthca_srq *srq);
-
-int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
- ib_srq_attr_t *attr, struct mthca_srq *srq);
-void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq);
-int mthca_modify_srq(struct ib_srq *ibsrq, ib_srq_attr_t *attr,
- ib_srq_attr_mask_t attr_mask);
-void mthca_srq_event(struct mthca_dev *dev, u32 srqn,
- enum ib_event_type event_type, u8 vendor_code);
-void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr);
-int mthca_tavor_post_srq_recv(struct ib_srq *srq, struct _ib_recv_wr *wr,
- struct _ib_recv_wr **bad_wr);
-int mthca_arbel_post_srq_recv(struct ib_srq *srq, struct _ib_recv_wr *wr,
- struct _ib_recv_wr **bad_wr);
-
-void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
- enum ib_event_type event_type, u8 vendor_code);
-int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask);
-int mthca_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask,
- struct ib_qp_init_attr *qp_init_attr);
-int mthca_tavor_post_send(struct ib_qp *ibqp, struct _ib_send_wr *wr,
- struct _ib_send_wr **bad_wr);
-int mthca_tavor_post_recv(struct ib_qp *ibqp, struct _ib_recv_wr *wr,
- struct _ib_recv_wr **bad_wr);
-int mthca_arbel_post_send(struct ib_qp *ibqp, struct _ib_send_wr *wr,
- struct _ib_send_wr **bad_wr);
-int mthca_arbel_post_recv(struct ib_qp *ibqp, struct _ib_recv_wr *wr,
- struct _ib_recv_wr **bad_wr);
-void mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send,
- int index, int *dbd, __be32 *new_wqe);
-int mthca_alloc_qp(struct mthca_dev *dev,
- struct mthca_pd *pd,
- struct mthca_cq *send_cq,
- struct mthca_cq *recv_cq,
- enum ib_qp_type_t type,
- enum ib_sig_type send_policy,
- struct ib_qp_cap *cap,
- struct mthca_qp *qp);
-int mthca_alloc_sqp(struct mthca_dev *dev,
- struct mthca_pd *pd,
- struct mthca_cq *send_cq,
- struct mthca_cq *recv_cq,
- enum ib_sig_type send_policy,
- struct ib_qp_cap *cap,
- int qpn,
- int port,
- struct mthca_sqp *sqp);
-void mthca_free_qp(struct mthca_dev *dev, struct mthca_qp *qp);
-int mthca_create_ah(struct mthca_dev *dev,
- struct mthca_pd *pd,
- struct ib_ah_attr *ah_attr,
- struct mthca_ah *ah);
-int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah);
-int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,
- struct ib_ud_header *header);
-
-int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
-int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);
-
-int mthca_process_mad(struct ib_device *ibdev,
- int mad_flags,
- u8 port_num,
- struct _ib_wc *in_wc,
- struct _ib_grh *in_grh,
- struct ib_mad *in_mad,
- struct ib_mad *out_mad);
-
-static inline struct mthca_dev *to_mdev(struct ib_device *ibdev)
-{
- return container_of(ibdev, struct mthca_dev, ib_dev);
-}
-
-static inline int mthca_is_memfree(struct mthca_dev *dev)
-{
- return dev->mthca_flags & MTHCA_FLAG_MEMFREE;
-}
-
-VOID
-WriteEventLogEntry(
- PVOID pi_pIoObject,
- ULONG pi_ErrorCode,
- ULONG pi_UniqueErrorCode,
- ULONG pi_FinalStatus,
- ULONG pi_nDataItems,
- ...
- );
-
-VOID
-WriteEventLogEntryStr(
- PVOID pi_pIoObject,
- ULONG pi_ErrorCode,
- ULONG pi_UniqueErrorCode,
- ULONG pi_FinalStatus,
- PWCHAR pi_InsertionStr,
- ULONG pi_nDataItems,
- ...
- );
-
-
-static inline int mthca_is_livefish(struct mthca_dev *mdev)
-{
- if(mdev == NULL) {
- return TRUE;
- }
- return mdev->mthca_flags & MTHCA_FLAG_LIVEFISH;
-}
-
-void mthca_get_av_params( struct mthca_ah *ah_p, u8 *port_num, __be16 *dlid, u8 *sr, u8 *path_bits );
-
-void mthca_set_av_params( struct mthca_dev *dev, struct mthca_ah *ah_p, struct ib_ah_attr *ah_attr );
-
-int ib_uverbs_init(void);
-void ib_uverbs_cleanup(void);
-int mthca_ah_grh_present(struct mthca_ah *ah);
-
-int mthca_max_srq_sge(struct mthca_dev *dev);
-
-
-#endif /* MTHCA_DEV_H */
+/*\r
+ * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.\r
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.\r
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.\r
+ * Copyright (c) 2005 Mellanox Technologies. All rights reserved.\r
+ * Copyright (c) 2004 Voltaire, Inc. All rights reserved.\r
+ * Copyright (c) 2006 SilverStorm Technologies, Inc. All rights reserved.\r
+ *\r
+ * This software is available to you under a choice of one of two\r
+ * licenses. You may choose to be licensed under the terms of the GNU\r
+ * General Public License (GPL) Version 2, available from the file\r
+ * COPYING in the main directory of this source tree, or the\r
+ * OpenIB.org BSD license below:\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ * - Redistributions of source code must retain the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer.\r
+ *\r
+ * - Redistributions in binary form must reproduce the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer in the documentation and/or other materials\r
+ * provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id$\r
+ */\r
+\r
+#ifndef MTHCA_DEV_H\r
+#define MTHCA_DEV_H\r
+\r
+#include "hca_driver.h"\r
+#include "mthca_log.h"\r
+#include "mthca_provider.h"\r
+#include "mthca_doorbell.h"\r
+\r
+// must be synchronized with MTHCA.INF\r
+#define DRV_NAME "mthca"\r
+#define PFX DRV_NAME ": "\r
+//TODO\r
+#define DRV_VERSION "1.0.0000.566"\r
+#define DRV_RELDATE "12/21/2006"\r
+\r
+#define HZ 1000000 /* 1 sec in usecs */\r
+\r
+enum {\r
+ MTHCA_FLAG_DDR_HIDDEN = 1 << 1,\r
+ MTHCA_FLAG_SRQ = 1 << 2,\r
+ MTHCA_FLAG_MSI = 1 << 3,\r
+ MTHCA_FLAG_MSI_X = 1 << 4,\r
+ MTHCA_FLAG_NO_LAM = 1 << 5,\r
+ MTHCA_FLAG_FMR = 1 << 6,\r
+ MTHCA_FLAG_MEMFREE = 1 << 7,\r
+ MTHCA_FLAG_PCIE = 1 << 8,\r
+ MTHCA_FLAG_SINAI_OPT = 1 << 9,\r
+};\r
+\r
+enum {\r
+ MTHCA_MAX_PORTS = 2\r
+};\r
+\r
+enum {\r
+ MTHCA_BOARD_ID_LEN = 64\r
+};\r
+\r
+enum {\r
+ MTHCA_EQ_CONTEXT_SIZE = 0x40,\r
+ MTHCA_CQ_CONTEXT_SIZE = 0x40,\r
+ MTHCA_QP_CONTEXT_SIZE = 0x200,\r
+ MTHCA_RDB_ENTRY_SIZE = 0x20,\r
+ MTHCA_AV_SIZE = 0x20,\r
+ MTHCA_MGM_ENTRY_SIZE = 0x40,\r
+\r
+ /* Arbel FW gives us these, but we need them for Tavor */\r
+ MTHCA_MPT_ENTRY_SIZE = 0x40,\r
+ MTHCA_MTT_SEG_SIZE = 0x40,\r
+\r
+ MTHCA_QP_PER_MGM = 4 * (MTHCA_MGM_ENTRY_SIZE / 16 - 2)\r
+};\r
+\r
+enum {\r
+ MTHCA_EQ_CMD,\r
+ MTHCA_EQ_ASYNC,\r
+ MTHCA_EQ_COMP,\r
+ MTHCA_NUM_EQ\r
+};\r
+\r
+enum {\r
+ MTHCA_BYTES_PER_ATOMIC_COMPL = 8\r
+};\r
+\r
+enum mthca_wr_opcode{\r
+ MTHCA_OPCODE_NOP = 0x00,\r
+ MTHCA_OPCODE_RDMA_WRITE = 0x08,\r
+ MTHCA_OPCODE_RDMA_WRITE_IMM = 0x09,\r
+ MTHCA_OPCODE_SEND = 0x0a,\r
+ MTHCA_OPCODE_SEND_IMM = 0x0b,\r
+ MTHCA_OPCODE_RDMA_READ = 0x10,\r
+ MTHCA_OPCODE_ATOMIC_CS = 0x11,\r
+ MTHCA_OPCODE_ATOMIC_FA = 0x12,\r
+ MTHCA_OPCODE_BIND_MW = 0x18,\r
+ MTHCA_OPCODE_INVALID = 0xff\r
+};\r
+\r
+struct mthca_cmd {\r
+ struct pci_pool *pool;\r
+ int use_events;\r
+ KMUTEX hcr_mutex;\r
+ KSEMAPHORE poll_sem;\r
+ KSEMAPHORE event_sem;\r
+ int max_cmds;\r
+ spinlock_t context_lock;\r
+ int free_head;\r
+ struct mthca_cmd_context *context;\r
+ u16 token_mask;\r
+};\r
+\r
+struct mthca_limits {\r
+ int num_ports;\r
+ int vl_cap;\r
+ int mtu_cap;\r
+ int gid_table_len;\r
+ int pkey_table_len;\r
+ int local_ca_ack_delay;\r
+ int num_uars;\r
+ int max_sg;\r
+ int num_qps;\r
+ int max_wqes;\r
+ int max_desc_sz;\r
+ int max_qp_init_rdma;\r
+ int reserved_qps;\r
+ int num_srqs;\r
+ int max_srq_wqes;\r
+ int max_srq_sge;\r
+ int reserved_srqs;\r
+ int num_eecs;\r
+ int reserved_eecs;\r
+ int num_cqs;\r
+ int max_cqes;\r
+ int reserved_cqs;\r
+ int num_eqs;\r
+ int reserved_eqs;\r
+ int num_mpts;\r
+ int num_mtt_segs;\r
+ int fmr_reserved_mtts;\r
+ int reserved_mtts;\r
+ int reserved_mrws;\r
+ int reserved_uars;\r
+ int num_mgms;\r
+ int num_amgms;\r
+ int reserved_mcgs;\r
+ int num_pds;\r
+ int reserved_pds;\r
+ u32 page_size_cap;\r
+ u32 flags;\r
+ u8 port_width_cap;\r
+ u64 num_avs;\r
+};\r
+\r
+struct mthca_alloc {\r
+ u32 last;\r
+ u32 top;\r
+ u32 max;\r
+ u32 mask;\r
+ spinlock_t lock;\r
+ unsigned long *table;\r
+};\r
+\r
+struct mthca_array {\r
+ struct {\r
+ void **page;\r
+ int used;\r
+ } *page_list;\r
+};\r
+\r
+struct mthca_uar_table {\r
+ struct mthca_alloc alloc;\r
+ u64 uarc_base;\r
+ int uarc_size;\r
+};\r
+\r
+struct mthca_pd_table {\r
+ struct mthca_alloc alloc;\r
+};\r
+\r
+struct mthca_buddy {\r
+ unsigned long **bits;\r
+ int max_order;\r
+ spinlock_t lock;\r
+};\r
+\r
+struct mthca_mr_table {\r
+ struct mthca_alloc mpt_alloc;\r
+ struct mthca_buddy mtt_buddy;\r
+ struct mthca_buddy *fmr_mtt_buddy;\r
+ u64 mtt_base;\r
+ u64 mpt_base;\r
+ struct mthca_icm_table *mtt_table;\r
+ struct mthca_icm_table *mpt_table;\r
+ struct {\r
+ void __iomem *mpt_base;\r
+ SIZE_T mpt_base_size;\r
+ void __iomem *mtt_base;\r
+ SIZE_T mtt_base_size;\r
+ struct mthca_buddy mtt_buddy;\r
+ } tavor_fmr;\r
+};\r
+\r
+struct mthca_eq_table {\r
+ struct mthca_alloc alloc;\r
+ void __iomem *clr_int;\r
+ u32 clr_mask;\r
+ u32 arm_mask;\r
+ struct mthca_eq eq[MTHCA_NUM_EQ];\r
+ u64 icm_virt;\r
+ struct scatterlist sg;\r
+ int have_irq;\r
+ u8 inta_pin;\r
+ KLOCK_QUEUE_HANDLE lockh;\r
+#if 1//WORKAROUND_POLL_EQ\r
+ KEVENT thread_start_event;\r
+ KEVENT thread_stop_event;\r
+ BOOLEAN bTerminated;\r
+ PVOID threadObject;\r
+#endif\r
+};\r
+\r
+struct mthca_cq_table {\r
+ struct mthca_alloc alloc;\r
+ spinlock_t lock;\r
+ struct mthca_array cq;\r
+ struct mthca_icm_table *table;\r
+};\r
+\r
+struct mthca_srq_table {\r
+ struct mthca_alloc alloc;\r
+ spinlock_t lock;\r
+ struct mthca_array srq;\r
+ struct mthca_icm_table *table;\r
+};\r
+\r
+struct mthca_qp_table {\r
+ struct mthca_alloc alloc;\r
+ u32 rdb_base;\r
+ int rdb_shift;\r
+ int sqp_start;\r
+ spinlock_t lock;\r
+ struct mthca_array qp;\r
+ struct mthca_icm_table *qp_table;\r
+ struct mthca_icm_table *eqp_table;\r
+ struct mthca_icm_table *rdb_table;\r
+};\r
+\r
+struct mthca_av_table {\r
+ struct pci_pool *pool;\r
+ int num_ddr_avs;\r
+ u64 ddr_av_base;\r
+ void __iomem *av_map;\r
+ SIZE_T av_map_size;\r
+ struct mthca_alloc alloc;\r
+};\r
+\r
+struct mthca_mcg_table {\r
+ KMUTEX mutex;\r
+ struct mthca_alloc alloc;\r
+ struct mthca_icm_table *table;\r
+};\r
+\r
+struct mthca_catas_err {\r
+ u64 addr;\r
+ u32 __iomem *map;\r
+ SIZE_T map_size;\r
+ unsigned long stop;\r
+ u32 size;\r
+ KTIMER timer;\r
+ KDPC timer_dpc;\r
+ LARGE_INTEGER interval;\r
+};\r
+\r
+struct mthca_dev {\r
+ struct ib_device ib_dev;\r
+ hca_dev_ext_t *ext;\r
+ uplink_info_t uplink_info;\r
+ volatile long dpc_lock;\r
+\r
+ int hca_type;\r
+ unsigned long mthca_flags;\r
+ unsigned long device_cap_flags;\r
+\r
+ u32 rev_id;\r
+ char board_id[MTHCA_BOARD_ID_LEN];\r
+\r
+ /* firmware info */\r
+ u64 fw_ver;\r
+ union {\r
+ struct {\r
+ u64 fw_start;\r
+ u64 fw_end;\r
+ } tavor;\r
+ struct {\r
+ u64 clr_int_base;\r
+ u64 eq_arm_base;\r
+ u64 eq_set_ci_base;\r
+ struct mthca_icm *fw_icm;\r
+ struct mthca_icm *aux_icm;\r
+ u16 fw_pages;\r
+ } arbel;\r
+ } fw;\r
+\r
+ u64 ddr_start;\r
+ u64 ddr_end;\r
+\r
+ MTHCA_DECLARE_DOORBELL_LOCK(doorbell_lock)\r
+ KMUTEX cap_mask_mutex;\r
+\r
+ u8 __iomem *hcr;\r
+ SIZE_T hcr_size;\r
+ u8 __iomem *kar;\r
+ SIZE_T kar_size;\r
+ u8 __iomem *clr_base;\r
+ SIZE_T clr_base_size;\r
+ union {\r
+ struct {\r
+ void __iomem *ecr_base;\r
+ SIZE_T ecr_base_size;\r
+ } tavor;\r
+ struct {\r
+ void __iomem *eq_arm;\r
+ SIZE_T eq_arm_size;\r
+ void __iomem *eq_set_ci_base;\r
+ SIZE_T eq_set_ci_base_size;\r
+ } arbel;\r
+ } eq_regs;\r
+\r
+ struct mthca_cmd cmd;\r
+ struct mthca_limits limits;\r
+\r
+ struct mthca_uar_table uar_table;\r
+ struct mthca_pd_table pd_table;\r
+ struct mthca_mr_table mr_table;\r
+ struct mthca_eq_table eq_table;\r
+ struct mthca_cq_table cq_table;\r
+ struct mthca_srq_table srq_table;\r
+ struct mthca_qp_table qp_table;\r
+ struct mthca_av_table av_table;\r
+ struct mthca_mcg_table mcg_table;\r
+ struct mthca_catas_err catas_err;\r
+ struct mthca_uar driver_uar;\r
+ struct mthca_db_table *db_tab;\r
+ struct mthca_pd driver_pd;\r
+ struct mthca_mr driver_mr;\r
+\r
+ struct ib_mad_agent *send_agent[MTHCA_MAX_PORTS][2];\r
+ struct ib_ah *sm_ah[MTHCA_MAX_PORTS];\r
+ spinlock_t sm_lock;\r
+ u32 state;\r
+};\r
+\r
+// mthca_dev states\r
+enum {\r
+ MTHCA_DEV_UNINITIALIZED,\r
+ MTHCA_DEV_INITIALIZED,\r
+ MTHCA_DEV_FAILED\r
+}; \r
+\r
+enum {\r
+ MTHCA_CQ_ENTRY_SIZE = 0x20\r
+};\r
+\r
+ \r
+\r
+#define MTHCA_GET(dest, source, offset) \\r
+ { \\r
+ void *__p = (char *) (source) + (offset); \\r
+ void *__q = &(dest); \\r
+ switch (sizeof (dest)) { \\r
+ case 1: *(u8 *)__q = *(u8 *) __p; break; \\r
+ case 2: *(u16 *)__q = (u16)cl_ntoh16(*(u16 *)__p); break; \\r
+ case 4: *(u32 *)__q = (u32)cl_ntoh32(*(u32 *)__p); break; \\r
+ case 8: *(u64 *)__q = (u64)cl_ntoh64(*(u64 *)__p); break; \\r
+ default: ASSERT(0); \\r
+ } \\r
+ } \r
+\r
+\r
+#define MTHCA_PUT(dest, source, offset) \\r
+ { \\r
+ void *__d = ((char *) (dest) + (offset)); \\r
+ switch (sizeof(source)) { \\r
+ case 1: *(u8 *) __d = (u8)(source); break; \\r
+ case 2: *(__be16 *) __d = cl_hton16((u16)source); break; \\r
+ case 4: *(__be32 *) __d = cl_hton32((u32)source); break; \\r
+ case 8: *(__be64 *) __d = cl_hton64((u64)source); break; \\r
+ default: ASSERT(0); \\r
+ } \\r
+ } \r
+\r
+NTSTATUS mthca_reset(struct mthca_dev *mdev);\r
+\r
+u32 mthca_alloc(struct mthca_alloc *alloc);\r
+void mthca_free(struct mthca_alloc *alloc, u32 obj);\r
+int mthca_alloc_init(struct mthca_alloc *alloc, u32 num, u32 mask,\r
+ u32 reserved);\r
+void mthca_alloc_cleanup(struct mthca_alloc *alloc);\r
+void *mthca_array_get(struct mthca_array *array, int index);\r
+int mthca_array_set(struct mthca_array *array, int index, void *value);\r
+void mthca_array_clear(struct mthca_array *array, int index);\r
+int mthca_array_init(struct mthca_array *array, int nent);\r
+void mthca_array_cleanup(struct mthca_array *array, int nent);\r
+int mthca_buf_alloc(struct mthca_dev *dev, int size, int max_direct,\r
+ union mthca_buf *buf, int *is_direct, struct mthca_pd *pd,\r
+ int hca_write, struct mthca_mr *mr);\r
+void mthca_buf_free(struct mthca_dev *dev, int size, union mthca_buf *buf,\r
+ int is_direct, struct mthca_mr *mr);\r
+\r
+int mthca_init_uar_table(struct mthca_dev *dev);\r
+int mthca_init_pd_table(struct mthca_dev *dev);\r
+int mthca_init_mr_table(struct mthca_dev *dev);\r
+int mthca_init_eq_table(struct mthca_dev *dev);\r
+int mthca_init_cq_table(struct mthca_dev *dev);\r
+int mthca_init_srq_table(struct mthca_dev *dev);\r
+int mthca_init_qp_table(struct mthca_dev *dev);\r
+int mthca_init_av_table(struct mthca_dev *dev);\r
+int mthca_init_mcg_table(struct mthca_dev *dev);\r
+\r
+void mthca_cleanup_uar_table(struct mthca_dev *dev);\r
+void mthca_cleanup_pd_table(struct mthca_dev *dev);\r
+void mthca_cleanup_mr_table(struct mthca_dev *dev);\r
+void mthca_cleanup_eq_table(struct mthca_dev *dev);\r
+void mthca_cleanup_cq_table(struct mthca_dev *dev);\r
+void mthca_cleanup_srq_table(struct mthca_dev *dev);\r
+void mthca_cleanup_qp_table(struct mthca_dev *dev);\r
+void mthca_cleanup_av_table(struct mthca_dev *dev);\r
+void mthca_cleanup_mcg_table(struct mthca_dev *dev);\r
+\r
+int mthca_register_device(struct mthca_dev *dev);\r
+void mthca_unregister_device(struct mthca_dev *dev);\r
+\r
+void mthca_start_catas_poll(struct mthca_dev *dev);\r
+void mthca_stop_catas_poll(struct mthca_dev *dev);\r
+\r
+int mthca_uar_alloc(struct mthca_dev *dev, struct mthca_uar *uar);\r
+void mthca_uar_free(struct mthca_dev *dev, struct mthca_uar *uar);\r
+\r
+int mthca_pd_alloc(struct mthca_dev *dev, int privileged, struct mthca_pd *pd);\r
+void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd);\r
+\r
+struct mthca_mtt *mthca_alloc_mtt(struct mthca_dev *dev, int size);\r
+void mthca_free_mtt(struct mthca_dev *dev, struct mthca_mtt *mtt);\r
+int mthca_write_mtt(struct mthca_dev *dev, struct mthca_mtt *mtt,\r
+ int start_index, u64 *buffer_list, int list_len);\r
+int mthca_mr_alloc(struct mthca_dev *dev, u32 pd, int buffer_size_shift,\r
+ u64 iova, u64 total_size, mthca_mpt_access_t access, struct mthca_mr *mr);\r
+int mthca_mr_alloc_notrans(struct mthca_dev *dev, u32 pd,\r
+ mthca_mpt_access_t access, struct mthca_mr *mr);\r
+int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd,\r
+ u64 *buffer_list, int buffer_size_shift,\r
+ int list_len, u64 iova, u64 total_size,\r
+ mthca_mpt_access_t access, struct mthca_mr *mr);\r
+void mthca_free_mr(struct mthca_dev *dev, struct mthca_mr *mr);\r
+\r
+int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd,\r
+ mthca_mpt_access_t access, struct mthca_fmr *fmr);\r
+int mthca_tavor_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,\r
+ int list_len, u64 iova);\r
+void mthca_tavor_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr);\r
+int mthca_arbel_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,\r
+ int list_len, u64 iova);\r
+void mthca_arbel_fmr_unmap(struct mthca_dev *dev, struct mthca_fmr *fmr);\r
+int mthca_free_fmr(struct mthca_dev *dev, struct mthca_fmr *fmr);\r
+\r
+int mthca_map_eq_icm(struct mthca_dev *dev, u64 icm_virt);\r
+void mthca_unmap_eq_icm(struct mthca_dev *dev);\r
+\r
+int mthca_poll_cq(struct ib_cq *ibcq, int num_entries,\r
+ struct _ib_wc *entry);\r
+int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify);\r
+int mthca_arbel_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify);\r
+int mthca_init_cq(struct mthca_dev *dev, int nent,\r
+ struct mthca_ucontext *ctx, u32 pdn,\r
+ struct mthca_cq *cq);\r
+void mthca_free_cq(struct mthca_dev *dev,\r
+ struct mthca_cq *cq);\r
+void mthca_cq_completion(struct mthca_dev *dev, u32 cqn);\r
+void mthca_cq_event(struct mthca_dev *dev, u32 cqn,\r
+ enum ib_event_type event_type);\r
+void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,\r
+ struct mthca_srq *srq);\r
+\r
+int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,\r
+ ib_srq_attr_t *attr, struct mthca_srq *srq);\r
+void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq);\r
+int mthca_modify_srq(struct ib_srq *ibsrq, ib_srq_attr_t *attr,\r
+ ib_srq_attr_mask_t attr_mask);\r
+void mthca_srq_event(struct mthca_dev *dev, u32 srqn,\r
+ enum ib_event_type event_type, u8 vendor_code);\r
+void mthca_free_srq_wqe(struct mthca_srq *srq, u32 wqe_addr);\r
+int mthca_tavor_post_srq_recv(struct ib_srq *srq, struct _ib_recv_wr *wr,\r
+ struct _ib_recv_wr **bad_wr);\r
+int mthca_arbel_post_srq_recv(struct ib_srq *srq, struct _ib_recv_wr *wr,\r
+ struct _ib_recv_wr **bad_wr);\r
+\r
+void mthca_qp_event(struct mthca_dev *dev, u32 qpn,\r
+ enum ib_event_type event_type, u8 vendor_code);\r
+int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask);\r
+int mthca_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask,\r
+ struct ib_qp_init_attr *qp_init_attr);\r
+int mthca_tavor_post_send(struct ib_qp *ibqp, struct _ib_send_wr *wr,\r
+ struct _ib_send_wr **bad_wr);\r
+int mthca_tavor_post_recv(struct ib_qp *ibqp, struct _ib_recv_wr *wr,\r
+ struct _ib_recv_wr **bad_wr);\r
+int mthca_arbel_post_send(struct ib_qp *ibqp, struct _ib_send_wr *wr,\r
+ struct _ib_send_wr **bad_wr);\r
+int mthca_arbel_post_recv(struct ib_qp *ibqp, struct _ib_recv_wr *wr,\r
+ struct _ib_recv_wr **bad_wr);\r
+void mthca_free_err_wqe(struct mthca_dev *dev, struct mthca_qp *qp, int is_send,\r
+ int index, int *dbd, __be32 *new_wqe);\r
+int mthca_alloc_qp(struct mthca_dev *dev,\r
+ struct mthca_pd *pd,\r
+ struct mthca_cq *send_cq,\r
+ struct mthca_cq *recv_cq,\r
+ enum ib_qp_type_t type,\r
+ enum ib_sig_type send_policy,\r
+ struct ib_qp_cap *cap,\r
+ struct mthca_qp *qp);\r
+int mthca_alloc_sqp(struct mthca_dev *dev,\r
+ struct mthca_pd *pd,\r
+ struct mthca_cq *send_cq,\r
+ struct mthca_cq *recv_cq,\r
+ enum ib_sig_type send_policy,\r
+ struct ib_qp_cap *cap,\r
+ int qpn,\r
+ int port,\r
+ struct mthca_sqp *sqp);\r
+void mthca_free_qp(struct mthca_dev *dev, struct mthca_qp *qp);\r
+int mthca_create_ah(struct mthca_dev *dev,\r
+ struct mthca_pd *pd,\r
+ struct ib_ah_attr *ah_attr,\r
+ struct mthca_ah *ah);\r
+int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah);\r
+int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,\r
+ struct ib_ud_header *header);\r
+\r
+int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);\r
+int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid);\r
+\r
+int mthca_process_mad(struct ib_device *ibdev,\r
+ int mad_flags,\r
+ u8 port_num,\r
+ struct _ib_wc *in_wc,\r
+ struct _ib_grh *in_grh,\r
+ struct ib_mad *in_mad,\r
+ struct ib_mad *out_mad);\r
+\r
+static inline struct mthca_dev *to_mdev(struct ib_device *ibdev)\r
+{\r
+ return container_of(ibdev, struct mthca_dev, ib_dev);\r
+}\r
+\r
+static inline int mthca_is_memfree(struct mthca_dev *dev)\r
+{\r
+ return dev->mthca_flags & MTHCA_FLAG_MEMFREE;\r
+}\r
+\r
+VOID\r
+WriteEventLogEntry(\r
+ PVOID pi_pIoObject,\r
+ ULONG pi_ErrorCode,\r
+ ULONG pi_UniqueErrorCode,\r
+ ULONG pi_FinalStatus,\r
+ ULONG pi_nDataItems,\r
+ ...\r
+ );\r
+\r
+VOID\r
+WriteEventLogEntryStr(\r
+ PVOID pi_pIoObject,\r
+ ULONG pi_ErrorCode,\r
+ ULONG pi_UniqueErrorCode,\r
+ ULONG pi_FinalStatus,\r
+ PWCHAR pi_InsertionStr,\r
+ ULONG pi_nDataItems,\r
+ ...\r
+ );\r
+\r
+void mthca_get_av_params( struct mthca_ah *ah_p, u8 *port_num, __be16 *dlid, u8 *sr, u8 *path_bits );\r
+\r
+void mthca_set_av_params( struct mthca_dev *dev, struct mthca_ah *ah_p, struct ib_ah_attr *ah_attr );\r
+\r
+int ib_uverbs_init(void);\r
+void ib_uverbs_cleanup(void);\r
+int mthca_ah_grh_present(struct mthca_ah *ah);\r
+\r
+int mthca_max_srq_sge(struct mthca_dev *dev);\r
+\r
+\r
+#endif /* MTHCA_DEV_H */\r
-/*
- * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * $Id$
- */
-
-#include "mt_l2w.h"
-#include "mlnx_uvp.h"
-
-#if defined(EVENT_TRACING)
-#include "mlnx_uvp.tmh"
-#endif
-
-#include "mx_abi.h"
-
-size_t g_page_size = 0;
-
-#ifndef PCI_VENDOR_ID_MELLANOX
-#define PCI_VENDOR_ID_MELLANOX 0x15b3
-#endif
-
-#ifndef PCI_DEVICE_ID_MELLANOX_TAVOR
-#define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44
-#endif
-
-#ifndef PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT
-#define PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT 0x6278
-#endif
-
-#ifndef PCI_DEVICE_ID_MELLANOX_ARBEL
-#define PCI_DEVICE_ID_MELLANOX_ARBEL 0x6282
-#endif
-
-#ifndef PCI_DEVICE_ID_MELLANOX_SINAI_OLD
-#define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c
-#endif
-
-#ifndef PCI_DEVICE_ID_MELLANOX_SINAI
-#define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274
-#endif
-
-#ifndef PCI_VENDOR_ID_TOPSPIN
-#define PCI_VENDOR_ID_TOPSPIN 0x1867
-#endif
-
-/* live fishes */
-#ifndef PCI_DEVICE_ID_MELLANOX_TAVOR_BD
-#define PCI_DEVICE_ID_MELLANOX_TAVOR_BD 0x5a45
-#endif
-
-#ifndef PCI_DEVICE_ID_MELLANOX_ARBEL_BD
-#define PCI_DEVICE_ID_MELLANOX_ARBEL_BD 0x6279
-#endif
-
-#ifndef PCI_DEVICE_ID_MELLANOX_SINAI_OLD_BD
-#define PCI_DEVICE_ID_MELLANOX_SINAI_OLD_BD 0x5e8d
-#endif
-
-#ifndef PCI_DEVICE_ID_MELLANOX_SINAI_BD
-#define PCI_DEVICE_ID_MELLANOX_SINAI_BD 0x6275
-#endif
-
-
-#define HCA(v, d, t) \
- { PCI_VENDOR_ID_##v, PCI_DEVICE_ID_MELLANOX_##d, MTHCA_##t }
-
-static struct pci_device_id {
- unsigned vendor;
- unsigned device;
- enum mthca_hca_type type;
-} mthca_pci_table[] = {
- HCA( MELLANOX, TAVOR, TAVOR),
- HCA( MELLANOX, ARBEL_COMPAT, TAVOR),
- HCA( MELLANOX, ARBEL, ARBEL),
- HCA( MELLANOX, SINAI_OLD, ARBEL),
- HCA( MELLANOX, SINAI, ARBEL),
- HCA( TOPSPIN, TAVOR, TAVOR),
- HCA( TOPSPIN, ARBEL_COMPAT, TAVOR),
- HCA( TOPSPIN, ARBEL, ARBEL),
- HCA( TOPSPIN, SINAI_OLD, ARBEL),
- HCA( TOPSPIN, SINAI, ARBEL),
- // live fishes
- HCA(MELLANOX, TAVOR_BD, LIVEFISH),
- HCA(MELLANOX, ARBEL_BD, LIVEFISH),
- HCA(MELLANOX, SINAI_OLD_BD, LIVEFISH),
- HCA(MELLANOX, SINAI_BD, LIVEFISH),
- HCA(TOPSPIN, TAVOR_BD, LIVEFISH),
- HCA(TOPSPIN, ARBEL_BD, LIVEFISH),
- HCA(TOPSPIN, SINAI_OLD_BD, LIVEFISH),
- HCA(TOPSPIN, SINAI_BD, LIVEFISH),
-};
-
-static struct ibv_context_ops mthca_ctx_ops = {
- NULL, // mthca_query_device,
- NULL, // mthca_query_port,
- mthca_alloc_pd,
- mthca_free_pd,
- NULL, // mthca_reg_mr,
- NULL, // mthca_dereg_mr,
- mthca_create_cq_pre,
- mthca_create_cq_post,
- mthca_poll_cq,
- mthca_poll_cq_list,
- NULL, /* req_notify_cq */
- mthca_destroy_cq,
- NULL, // mthca_create_srq,
- NULL, // mthca_modify_srq,
- NULL, // mthca_destroy_srq,
- NULL, /* post_srq_recv */
- mthca_create_qp_pre,
- mthca_create_qp_post,
- mthca_modify_qp,
- NULL,
- NULL, /* post_send */
- NULL, /* post_recv */
- mthca_attach_mcast,
- mthca_detach_mcast
-};
-
-struct ibv_context *mthca_alloc_context(struct ibv_get_context_resp *resp_p)
-{
- struct mthca_context * context;
- struct ibv_alloc_pd_resp pd_resp;
- int i;
-
- /* allocate context */
- context = cl_zalloc(sizeof *context);
- if (!context)
- return NULL;
-
- /* find page size */
- if (!g_page_size) {
- SYSTEM_INFO sys_info;
- GetSystemInfo(&sys_info);
- g_page_size = sys_info.dwPageSize;
- }
-
- /* calculate device type */
- for (i = 0; i < sizeof mthca_pci_table / sizeof mthca_pci_table[0]; ++i)
- if (resp_p->vend_id == mthca_pci_table[i].vendor &&
- resp_p->dev_id == mthca_pci_table[i].device)
- goto found;
- goto err_dev_type;
-
-found:
- context->hca_type = mthca_pci_table[i].type;
- context->uar = (void*)(UINT_PTR)resp_p->uar_addr;
- context->num_qps = resp_p->qp_tab_size;
- context->qp_table_shift = ffs(context->num_qps) - 1 - MTHCA_QP_TABLE_BITS;
- context->qp_table_mask = (1 << context->qp_table_shift) - 1;
-
- if (mthca_is_memfree(&context->ibv_ctx)) {
- context->db_tab = mthca_alloc_db_tab(resp_p->uarc_size);
- if (!context->db_tab)
- goto err_alloc_db_tab;
- } else
- context->db_tab = NULL;
-
- context->qp_table_mutex = CreateMutex( NULL, FALSE, NULL );
- if (!context->qp_table_mutex)
- goto err_mutex;
- for (i = 0; i < MTHCA_QP_TABLE_SIZE; ++i)
- context->qp_table[i].refcnt = 0;
-
- cl_spinlock_construct(&context->uar_lock);
- if (cl_spinlock_init(&context->uar_lock))
- goto err_spinlock;
-
- pd_resp.pd_handle = resp_p->pd_handle;
- pd_resp.pdn = resp_p->pdn;
- context->pd = mthca_alloc_pd(&context->ibv_ctx, &pd_resp);
- if (!context->pd)
- goto err_unmap;
-
- context->ibv_ctx.ops = mthca_ctx_ops;
-
- if (mthca_is_memfree(&context->ibv_ctx)) {
- context->ibv_ctx.ops.req_notify_cq = mthca_arbel_arm_cq;
- context->ibv_ctx.ops.post_send = mthca_arbel_post_send;
- context->ibv_ctx.ops.post_recv = mthca_arbel_post_recv;
- context->ibv_ctx.ops.post_srq_recv = mthca_arbel_post_srq_recv;
- } else {
- context->ibv_ctx.ops.req_notify_cq = mthca_tavor_arm_cq;
- context->ibv_ctx.ops.post_send = mthca_tavor_post_send;
- context->ibv_ctx.ops.post_recv = mthca_tavor_post_recv;
- context->ibv_ctx.ops.post_srq_recv = mthca_tavor_post_srq_recv;
- }
-
- return &context->ibv_ctx;
-
-err_unmap:
-err_spinlock:
-err_mutex:
- mthca_free_db_tab(context->db_tab);
-
-err_alloc_db_tab:
-err_dev_type:
- cl_free(context);
- return NULL;
-}
-
-void mthca_free_context(struct ibv_context *ibctx)
-{
- struct mthca_context *context = to_mctx(ibctx);
-
- cl_spinlock_destroy(&context->uar_lock);
- mthca_free_pd(context->pd);
- mthca_free_db_tab(context->db_tab);
- cl_free(context);
-}
+/*\r
+ * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.\r
+ *\r
+ * This software is available to you under a choice of one of two\r
+ * licenses. You may choose to be licensed under the terms of the GNU\r
+ * General Public License (GPL) Version 2, available from the file\r
+ * COPYING in the main directory of this source tree, or the\r
+ * OpenIB.org BSD license below:\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ * - Redistributions of source code must retain the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer.\r
+ *\r
+ * - Redistributions in binary form must reproduce the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer in the documentation and/or other materials\r
+ * provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id$\r
+ */\r
+\r
+#include "mt_l2w.h"\r
+#include "mlnx_uvp.h"\r
+\r
+#if defined(EVENT_TRACING)\r
+#include "mlnx_uvp.tmh"\r
+#endif\r
+\r
+#include "mx_abi.h"\r
+\r
+size_t g_page_size = 0;\r
+\r
+#ifndef PCI_VENDOR_ID_MELLANOX\r
+#define PCI_VENDOR_ID_MELLANOX 0x15b3\r
+#endif\r
+\r
+#ifndef PCI_DEVICE_ID_MELLANOX_TAVOR\r
+#define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44\r
+#endif\r
+\r
+#ifndef PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT\r
+#define PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT 0x6278\r
+#endif\r
+\r
+#ifndef PCI_DEVICE_ID_MELLANOX_ARBEL\r
+#define PCI_DEVICE_ID_MELLANOX_ARBEL 0x6282\r
+#endif\r
+\r
+#ifndef PCI_DEVICE_ID_MELLANOX_SINAI_OLD\r
+#define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c\r
+#endif\r
+\r
+#ifndef PCI_DEVICE_ID_MELLANOX_SINAI\r
+#define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274\r
+#endif\r
+\r
+#ifndef PCI_VENDOR_ID_TOPSPIN\r
+#define PCI_VENDOR_ID_TOPSPIN 0x1867\r
+#endif\r
+\r
+\r
+#define HCA(v, d, t) \\r
+ { PCI_VENDOR_ID_##v, PCI_DEVICE_ID_MELLANOX_##d, MTHCA_##t }\r
+\r
+static struct pci_device_id {\r
+ unsigned vendor;\r
+ unsigned device;\r
+ enum mthca_hca_type type;\r
+} mthca_pci_table[] = {\r
+ HCA( MELLANOX, TAVOR, TAVOR),\r
+ HCA( MELLANOX, ARBEL_COMPAT, TAVOR),\r
+ HCA( MELLANOX, ARBEL, ARBEL),\r
+ HCA( MELLANOX, SINAI_OLD, ARBEL),\r
+ HCA( MELLANOX, SINAI, ARBEL),\r
+ HCA( TOPSPIN, TAVOR, TAVOR),\r
+ HCA( TOPSPIN, ARBEL_COMPAT, TAVOR),\r
+ HCA( TOPSPIN, ARBEL, ARBEL),\r
+ HCA( TOPSPIN, SINAI_OLD, ARBEL),\r
+ HCA( TOPSPIN, SINAI, ARBEL),\r
+};\r
+\r
+static struct ibv_context_ops mthca_ctx_ops = {\r
+ NULL, // mthca_query_device,\r
+ NULL, // mthca_query_port,\r
+ mthca_alloc_pd,\r
+ mthca_free_pd,\r
+ NULL, // mthca_reg_mr,\r
+ NULL, // mthca_dereg_mr,\r
+ mthca_create_cq_pre,\r
+ mthca_create_cq_post,\r
+ mthca_poll_cq,\r
+ mthca_poll_cq_list,\r
+ NULL, /* req_notify_cq */\r
+ mthca_destroy_cq,\r
+ NULL, // mthca_create_srq,\r
+ NULL, // mthca_modify_srq,\r
+ NULL, // mthca_destroy_srq,\r
+ NULL, /* post_srq_recv */\r
+ mthca_create_qp_pre,\r
+ mthca_create_qp_post,\r
+ mthca_modify_qp,\r
+ NULL,\r
+ NULL, /* post_send */\r
+ NULL, /* post_recv */\r
+ mthca_attach_mcast,\r
+ mthca_detach_mcast\r
+};\r
+\r
+struct ibv_context *mthca_alloc_context(struct ibv_get_context_resp *resp_p)\r
+{\r
+ struct mthca_context * context;\r
+ struct ibv_alloc_pd_resp pd_resp;\r
+ int i;\r
+\r
+ /* allocate context */\r
+ context = cl_zalloc(sizeof *context);\r
+ if (!context)\r
+ return NULL;\r
+\r
+ /* find page size */\r
+ if (!g_page_size) {\r
+ SYSTEM_INFO sys_info;\r
+ GetSystemInfo(&sys_info);\r
+ g_page_size = sys_info.dwPageSize;\r
+ }\r
+\r
+ /* calculate device type */\r
+ for (i = 0; i < sizeof mthca_pci_table / sizeof mthca_pci_table[0]; ++i) \r
+ if (resp_p->vend_id == mthca_pci_table[i].vendor &&\r
+ resp_p->dev_id == mthca_pci_table[i].device) \r
+ goto found;\r
+ goto err_dev_type;\r
+\r
+found:\r
+ context->hca_type = mthca_pci_table[i].type;\r
+ context->uar = (void*)(UINT_PTR)resp_p->uar_addr;\r
+ context->num_qps = resp_p->qp_tab_size;\r
+ context->qp_table_shift = ffs(context->num_qps) - 1 - MTHCA_QP_TABLE_BITS;\r
+ context->qp_table_mask = (1 << context->qp_table_shift) - 1;\r
+\r
+ if (mthca_is_memfree(&context->ibv_ctx)) {\r
+ context->db_tab = mthca_alloc_db_tab(resp_p->uarc_size);\r
+ if (!context->db_tab)\r
+ goto err_alloc_db_tab;\r
+ } else\r
+ context->db_tab = NULL;\r
+\r
+ context->qp_table_mutex = CreateMutex( NULL, FALSE, NULL );\r
+ if (!context->qp_table_mutex)\r
+ goto err_mutex;\r
+ for (i = 0; i < MTHCA_QP_TABLE_SIZE; ++i)\r
+ context->qp_table[i].refcnt = 0;\r
+\r
+ cl_spinlock_construct(&context->uar_lock);\r
+ if (cl_spinlock_init(&context->uar_lock))\r
+ goto err_spinlock;\r
+\r
+ pd_resp.pd_handle = resp_p->pd_handle;\r
+ pd_resp.pdn = resp_p->pdn;\r
+ context->pd = mthca_alloc_pd(&context->ibv_ctx, &pd_resp);\r
+ if (!context->pd)\r
+ goto err_unmap;\r
+\r
+ context->ibv_ctx.ops = mthca_ctx_ops;\r
+\r
+ if (mthca_is_memfree(&context->ibv_ctx)) {\r
+ context->ibv_ctx.ops.req_notify_cq = mthca_arbel_arm_cq;\r
+ context->ibv_ctx.ops.post_send = mthca_arbel_post_send;\r
+ context->ibv_ctx.ops.post_recv = mthca_arbel_post_recv;\r
+ context->ibv_ctx.ops.post_srq_recv = mthca_arbel_post_srq_recv;\r
+ } else {\r
+ context->ibv_ctx.ops.req_notify_cq = mthca_tavor_arm_cq;\r
+ context->ibv_ctx.ops.post_send = mthca_tavor_post_send;\r
+ context->ibv_ctx.ops.post_recv = mthca_tavor_post_recv;\r
+ context->ibv_ctx.ops.post_srq_recv = mthca_tavor_post_srq_recv;\r
+ }\r
+\r
+ return &context->ibv_ctx;\r
+\r
+err_unmap:\r
+err_spinlock:\r
+err_mutex:\r
+ mthca_free_db_tab(context->db_tab);\r
+\r
+err_alloc_db_tab:\r
+err_dev_type:\r
+ cl_free(context);\r
+ return NULL;\r
+}\r
+\r
+void mthca_free_context(struct ibv_context *ibctx)\r
+{\r
+ struct mthca_context *context = to_mctx(ibctx);\r
+\r
+ cl_spinlock_destroy(&context->uar_lock);\r
+ mthca_free_pd(context->pd);\r
+ mthca_free_db_tab(context->db_tab);\r
+ cl_free(context);\r
+}\r