2012-03-21 04:09:06 +05:30
/*******************************************************************
* 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"
2014-02-04 11:57:00 +05:30
# define OCRDMA_ROCE_DRV_VERSION "10.2.145.0u"
# define OCRDMA_ROCE_DRV_DESC "Emulex OneConnect RoCE Driver"
2012-03-21 04:09:06 +05:30
# define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA"
2014-02-04 11:57:07 +05:30
# define OC_NAME_SH OCRDMA_NODE_DESC "(Skyhawk)"
# define OC_NAME_UNKNOWN OCRDMA_NODE_DESC "(Unknown)"
# define OC_SKH_DEVICE_PF 0x720
# define OC_SKH_DEVICE_VF 0x728
2012-03-21 04:09:06 +05:30
# define OCRDMA_MAX_AH 512
# define OCRDMA_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME)
2014-02-04 11:57:07 +05:30
# define convert_to_64bit(lo, hi) ((u64)hi << 32 | (u64)lo)
2012-03-21 04:09:06 +05:30
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 ;
2013-08-26 15:27:39 +05:30
u16 max_srq ;
2012-03-21 04:09:06 +05:30
u32 max_inline_data ;
int max_send_sge ;
int max_recv_sge ;
2012-06-08 21:26:11 +05:30
int max_srq_sge ;
2013-08-07 12:52:37 +05:30
int max_rdma_sge ;
2012-03-21 04:09:06 +05:30
int max_mr ;
u64 max_mr_size ;
u32 max_num_mr_pbl ;
2014-02-04 11:57:04 +05:30
int max_mw ;
2012-03-21 04:09:06 +05:30
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 ;
} ;
2014-02-04 11:57:07 +05:30
struct ocrdma_dma_mem {
void * va ;
dma_addr_t pa ;
u32 size ;
} ;
2012-03-21 04:09:06 +05:30
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 ;
} ;
2013-09-06 15:02:47 +05:30
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 ;
} ;
2014-02-04 11:57:07 +05:30
struct ocrdma_stats {
u8 type ;
struct ocrdma_dev * dev ;
} ;
struct stats_mem {
struct ocrdma_mqe mqe ;
void * va ;
dma_addr_t pa ;
u32 size ;
char * debugfs_mem ;
} ;
struct phy_info {
u16 auto_speeds_supported ;
u16 fixed_speeds_supported ;
u16 phy_type ;
u16 interface_type ;
} ;
2012-03-21 04:09:06 +05:30
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 ;
2013-08-26 15:27:41 +05:30
struct ocrdma_eq * eq_tbl ;
2012-03-21 04:09:06 +05:30
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 ;
2014-02-04 11:57:07 +05:30
struct phy_info phy ;
char model_number [ 32 ] ;
u32 hba_port_num ;
2012-03-21 04:09:06 +05:30
struct list_head entry ;
2012-04-28 07:40:01 +02:00
struct rcu_head rcu ;
2012-03-21 04:09:06 +05:30
int id ;
2013-09-06 15:02:47 +05:30
struct ocrdma_mr * stag_arr [ OCRDMA_MAX_STAG ] ;
2013-08-26 15:27:50 +05:30
u16 pvid ;
2014-02-04 11:56:56 +05:30
u32 asic_id ;
2014-02-04 11:57:07 +05:30
ulong last_stats_time ;
struct mutex stats_lock ; /* provide synch for debugfs operations */
struct stats_mem stats_mem ;
struct ocrdma_stats rsrc_stats ;
struct ocrdma_stats rx_stats ;
struct ocrdma_stats wqe_stats ;
struct ocrdma_stats tx_stats ;
struct ocrdma_stats db_err_stats ;
struct ocrdma_stats tx_qp_err_stats ;
struct ocrdma_stats rx_qp_err_stats ;
struct ocrdma_stats tx_dbg_stats ;
struct ocrdma_stats rx_dbg_stats ;
struct dentry * dir ;
2012-03-21 04:09:06 +05:30
} ;
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 ;
2014-02-04 11:56:54 +05:30
bool deferred_arm , deferred_sol ;
bool first_arm ;
2012-03-21 04:09:06 +05:30
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 ;
2014-02-04 11:56:54 +05:30
u32 cqe_cnt ;
2012-03-21 04:09:06 +05:30
/* 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 ;
2013-06-10 04:42:42 +00:00
struct ocrdma_qp_hwq_info rq ;
u64 * rqe_wr_id_tbl ;
u32 * idx_bit_fields ;
u32 bit_fields_len ;
2012-03-21 04:09:06 +05:30
/* 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 ;
2013-06-10 04:42:42 +00:00
/* provide synchronization to multiple context(s) posting wqe, rqe */
spinlock_t q_lock ____cacheline_aligned ;
2012-03-21 04:09:06 +05:30
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 ;
2013-08-26 15:27:43 +05:30
bool signaled ;
2013-08-07 12:52:37 +05:30
u16 db_cache ;
2012-03-21 04:09:06 +05:30
} ;
struct ocrdma_ucontext {
struct ib_ucontext ibucontext ;
struct list_head mm_head ;
struct mutex mm_list_lock ; /* protects list entries of mm type */
2013-08-26 15:27:44 +05:30
struct ocrdma_pd * cntxt_pd ;
int pd_in_use ;
2012-03-21 04:09:06 +05:30
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 ) ;
}
2013-06-10 04:42:41 +00:00
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 ;
2013-08-07 12:52:32 +05:30
return ( cqe_valid = = cq - > phase ) ;
2013-06-10 04:42:41 +00:00
}
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 ;
}
2013-12-12 18:03:15 +02:00
static inline int ocrdma_resolve_dmac ( struct ocrdma_dev * dev ,
struct ib_ah_attr * ah_attr , u8 * mac_addr )
{
struct in6_addr in6 ;
memcpy ( & in6 , ah_attr - > grh . dgid . raw , sizeof ( in6 ) ) ;
if ( rdma_is_multicast_addr ( & in6 ) )
rdma_get_mcast_mac ( & in6 , mac_addr ) ;
else
memcpy ( mac_addr , ah_attr - > dmac , ETH_ALEN ) ;
return 0 ;
}
2013-06-10 04:42:41 +00:00
2014-02-04 11:57:07 +05:30
static inline char * hca_name ( struct ocrdma_dev * dev )
{
switch ( dev - > nic_info . pdev - > device ) {
case OC_SKH_DEVICE_PF :
case OC_SKH_DEVICE_VF :
return OC_NAME_SH ;
default :
return OC_NAME_UNKNOWN ;
}
}
2014-02-04 11:56:54 +05:30
static inline int ocrdma_get_eq_table_index ( struct ocrdma_dev * dev ,
int eqid )
{
int indx ;
for ( indx = 0 ; indx < dev - > eq_cnt ; indx + + ) {
if ( dev - > eq_tbl [ indx ] . q . id = = eqid )
return indx ;
}
return - EINVAL ;
}
2014-02-04 11:56:56 +05:30
static inline u8 ocrdma_get_asic_type ( struct ocrdma_dev * dev )
{
if ( dev - > nic_info . dev_family = = 0xF & & ! dev - > asic_id ) {
pci_read_config_dword (
dev - > nic_info . pdev ,
OCRDMA_SLI_ASIC_ID_OFFSET , & dev - > asic_id ) ;
}
return ( dev - > asic_id & OCRDMA_SLI_ASIC_GEN_NUM_MASK ) > >
OCRDMA_SLI_ASIC_GEN_NUM_SHIFT ;
}
2012-03-21 04:09:06 +05:30
# endif