ocrdma.h 8.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
/*******************************************************************
 * This file is part of the Emulex RoCE Device Driver for          *
 * RoCE (RDMA over Converged Ethernet) adapters.                   *
 * Copyright (C) 2008-2012 Emulex. All rights reserved.            *
 * EMULEX and SLI are trademarks of Emulex.                        *
 * www.emulex.com                                                  *
 *                                                                 *
 * This program is free software; you can redistribute it and/or   *
 * modify it under the terms of version 2 of the GNU General       *
 * Public License as published by the Free Software Foundation.    *
 * This program is distributed in the hope that it will be useful. *
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
 * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
 * more details, a copy of which can be found in the file COPYING  *
 * included with this package.                                     *
 *
 * Contact Information:
 * linux-drivers@emulex.com
 *
 * Emulex
 * 3333 Susan Street
 * Costa Mesa, CA 92626
 *******************************************************************/

#ifndef __OCRDMA_H__
#define __OCRDMA_H__

#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/pci.h>

#include <rdma/ib_verbs.h>
#include <rdma/ib_user_verbs.h>

#include <be_roce.h>
#include "ocrdma_sli.h"

#define OCRDMA_ROCE_DEV_VERSION "1.0.0"
#define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA"

#define OCRDMA_MAX_AH 512

#define OCRDMA_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME)

struct ocrdma_dev_attr {
	u8 fw_ver[32];
	u32 vendor_id;
	u32 device_id;
	u16 max_pd;
	u16 max_cq;
	u16 max_cqe;
	u16 max_qp;
	u16 max_wqe;
	u16 max_rqe;
59
	u16 max_srq;
60 61 62
	u32 max_inline_data;
	int max_send_sge;
	int max_recv_sge;
63
	int max_srq_sge;
64
	int max_rdma_sge;
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
	int max_mr;
	u64 max_mr_size;
	u32 max_num_mr_pbl;
	int max_fmr;
	int max_map_per_fmr;
	int max_pages_per_frmr;
	u16 max_ord_per_qp;
	u16 max_ird_per_qp;

	int device_cap_flags;
	u8 cq_overflow_detect;
	u8 srq_supported;

	u32 wqe_size;
	u32 rqe_size;
	u32 ird_page_size;
	u8 local_ca_ack_delay;
	u8 ird;
	u8 num_ird_pages;
};

struct ocrdma_pbl {
	void *va;
	dma_addr_t pa;
};

struct ocrdma_queue_info {
	void *va;
	dma_addr_t dma;
	u32 size;
	u16 len;
	u16 entry_size;		/* Size of an element in the queue */
	u16 id;			/* qid, where to ring the doorbell. */
	u16 head, tail;
	bool created;
};

struct ocrdma_eq {
	struct ocrdma_queue_info q;
	u32 vector;
	int cq_cnt;
	struct ocrdma_dev *dev;
	char irq_name[32];
};

struct ocrdma_mq {
	struct ocrdma_queue_info sq;
	struct ocrdma_queue_info cq;
	bool rearm_cq;
};

struct mqe_ctx {
	struct mutex lock; /* for serializing mailbox commands on MQ */
	wait_queue_head_t cmd_wait;
	u32 tag;
	u16 cqe_status;
	u16 ext_status;
	bool cmd_done;
};

struct ocrdma_dev {
	struct ib_device ibdev;
	struct ocrdma_dev_attr attr;

	struct mutex dev_lock; /* provides syncronise access to device data */
	spinlock_t flush_q_lock ____cacheline_aligned;

	struct ocrdma_cq **cq_tbl;
	struct ocrdma_qp **qp_tbl;

135
	struct ocrdma_eq *eq_tbl;
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
	int eq_cnt;
	u16 base_eqid;
	u16 max_eq;

	union ib_gid *sgid_tbl;
	/* provided synchronization to sgid table for
	 * updating gid entries triggered by notifier.
	 */
	spinlock_t sgid_lock;

	int gsi_qp_created;
	struct ocrdma_cq *gsi_sqcq;
	struct ocrdma_cq *gsi_rqcq;

	struct {
		struct ocrdma_av *va;
		dma_addr_t pa;
		u32 size;
		u32 num_ah;
		/* provide synchronization for av
		 * entry allocations.
		 */
		spinlock_t lock;
		u32 ahid;
		struct ocrdma_pbl pbl;
	} av_tbl;

	void *mbx_cmd;
	struct ocrdma_mq mq;
	struct mqe_ctx mqe_ctx;

	struct be_dev_info nic_info;

	struct list_head entry;
170
	struct rcu_head rcu;
171
	int id;
172
	u64 stag_arr[OCRDMA_MAX_STAG];
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
};

struct ocrdma_cq {
	struct ib_cq ibcq;
	struct ocrdma_cqe *va;
	u32 phase;
	u32 getp;	/* pointer to pending wrs to
			 * return to stack, wrap arounds
			 * at max_hw_cqe
			 */
	u32 max_hw_cqe;
	bool phase_change;
	bool armed, solicited;
	bool arm_needed;

	spinlock_t cq_lock ____cacheline_aligned; /* provide synchronization
						   * to cq polling
						   */
	/* syncronizes cq completion handler invoked from multiple context */
	spinlock_t comp_handler_lock ____cacheline_aligned;
	u16 id;
	u16 eqn;

	struct ocrdma_ucontext *ucontext;
	dma_addr_t pa;
	u32 len;

	/* head of all qp's sq and rq for which cqes need to be flushed
	 * by the software.
	 */
	struct list_head sq_head, rq_head;
};

struct ocrdma_pd {
	struct ib_pd ibpd;
	struct ocrdma_dev *dev;
	struct ocrdma_ucontext *uctx;
	u32 id;
	int num_dpp_qp;
	u32 dpp_page;
	bool dpp_enabled;
};

struct ocrdma_ah {
	struct ib_ah ibah;
	struct ocrdma_av *av;
	u16 sgid_index;
	u32 id;
};

struct ocrdma_qp_hwq_info {
	u8 *va;			/* virtual address */
	u32 max_sges;
	u32 head, tail;
	u32 entry_size;
	u32 max_cnt;
	u32 max_wqe_idx;
	u16 dbid;		/* qid, where to ring the doorbell. */
	u32 len;
	dma_addr_t pa;
};

struct ocrdma_srq {
	struct ib_srq ibsrq;
	u8 __iomem *db;
238 239 240 241 242
	struct ocrdma_qp_hwq_info rq;
	u64 *rqe_wr_id_tbl;
	u32 *idx_bit_fields;
	u32 bit_fields_len;

243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
	/* provide synchronization to multiple context(s) posting rqe */
	spinlock_t q_lock ____cacheline_aligned;

	struct ocrdma_pd *pd;
	u32 id;
};

struct ocrdma_qp {
	struct ib_qp ibqp;
	struct ocrdma_dev *dev;

	u8 __iomem *sq_db;
	struct ocrdma_qp_hwq_info sq;
	struct {
		uint64_t wrid;
		uint16_t dpp_wqe_idx;
		uint16_t dpp_wqe;
		uint8_t  signaled;
		uint8_t  rsvd[3];
	} *wqe_wr_id_tbl;
	u32 max_inline_data;
264 265 266

	/* provide synchronization to multiple context(s) posting wqe, rqe */
	spinlock_t q_lock ____cacheline_aligned;
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
	struct ocrdma_cq *sq_cq;
	/* list maintained per CQ to flush SQ errors */
	struct list_head sq_entry;

	u8 __iomem *rq_db;
	struct ocrdma_qp_hwq_info rq;
	u64 *rqe_wr_id_tbl;
	struct ocrdma_cq *rq_cq;
	struct ocrdma_srq *srq;
	/* list maintained per CQ to flush RQ errors */
	struct list_head rq_entry;

	enum ocrdma_qp_state state;	/*  QP state */
	int cap_flags;
	u32 max_ord, max_ird;

	u32 id;
	struct ocrdma_pd *pd;

	enum ib_qp_type qp_type;

	int sgid_idx;
	u32 qkey;
	bool dpp_enabled;
	u8 *ird_q_va;
292
	u16 db_cache;
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
};

struct ocrdma_hw_mr {
	u32 lkey;
	u8 fr_mr;
	u8 remote_atomic;
	u8 remote_rd;
	u8 remote_wr;
	u8 local_rd;
	u8 local_wr;
	u8 mw_bind;
	u8 rsvd;
	u64 len;
	struct ocrdma_pbl *pbl_table;
	u32 num_pbls;
	u32 num_pbes;
	u32 pbl_size;
	u32 pbe_size;
	u64 fbo;
	u64 va;
};

struct ocrdma_mr {
	struct ib_mr ibmr;
	struct ib_umem *umem;
	struct ocrdma_hw_mr hwmr;
};

struct ocrdma_ucontext {
	struct ib_ucontext ibucontext;

	struct list_head mm_head;
	struct mutex mm_list_lock; /* protects list entries of mm type */
	struct {
		u32 *va;
		dma_addr_t pa;
		u32 len;
	} ah_tbl;
};

struct ocrdma_mm {
	struct {
		u64 phy_addr;
		unsigned long len;
	} key;
	struct list_head entry;
};

static inline struct ocrdma_dev *get_ocrdma_dev(struct ib_device *ibdev)
{
	return container_of(ibdev, struct ocrdma_dev, ibdev);
}

static inline struct ocrdma_ucontext *get_ocrdma_ucontext(struct ib_ucontext
							  *ibucontext)
{
	return container_of(ibucontext, struct ocrdma_ucontext, ibucontext);
}

static inline struct ocrdma_pd *get_ocrdma_pd(struct ib_pd *ibpd)
{
	return container_of(ibpd, struct ocrdma_pd, ibpd);
}

static inline struct ocrdma_cq *get_ocrdma_cq(struct ib_cq *ibcq)
{
	return container_of(ibcq, struct ocrdma_cq, ibcq);
}

static inline struct ocrdma_qp *get_ocrdma_qp(struct ib_qp *ibqp)
{
	return container_of(ibqp, struct ocrdma_qp, ibqp);
}

static inline struct ocrdma_mr *get_ocrdma_mr(struct ib_mr *ibmr)
{
	return container_of(ibmr, struct ocrdma_mr, ibmr);
}

static inline struct ocrdma_ah *get_ocrdma_ah(struct ib_ah *ibah)
{
	return container_of(ibah, struct ocrdma_ah, ibah);
}

static inline struct ocrdma_srq *get_ocrdma_srq(struct ib_srq *ibsrq)
{
	return container_of(ibsrq, struct ocrdma_srq, ibsrq);
}

382 383 384 385

static inline int ocrdma_get_num_posted_shift(struct ocrdma_qp *qp)
{
	return ((qp->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY &&
386
		 qp->id < 128) ? 24 : 16);
387 388 389 390 391 392
}

static inline int is_cqe_valid(struct ocrdma_cq *cq, struct ocrdma_cqe *cqe)
{
	int cqe_valid;
	cqe_valid = le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_VALID;
393
	return (cqe_valid == cq->phase);
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420
}

static inline int is_cqe_for_sq(struct ocrdma_cqe *cqe)
{
	return (le32_to_cpu(cqe->flags_status_srcqpn) &
		OCRDMA_CQE_QTYPE) ? 0 : 1;
}

static inline int is_cqe_invalidated(struct ocrdma_cqe *cqe)
{
	return (le32_to_cpu(cqe->flags_status_srcqpn) &
		OCRDMA_CQE_INVALIDATE) ? 1 : 0;
}

static inline int is_cqe_imm(struct ocrdma_cqe *cqe)
{
	return (le32_to_cpu(cqe->flags_status_srcqpn) &
		OCRDMA_CQE_IMM) ? 1 : 0;
}

static inline int is_cqe_wr_imm(struct ocrdma_cqe *cqe)
{
	return (le32_to_cpu(cqe->flags_status_srcqpn) &
		OCRDMA_CQE_WRITE_IMM) ? 1 : 0;
}


421
#endif