415 lines
12 KiB
C
415 lines
12 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Huawei Hifc PCI Express Linux driver
|
|
* Copyright(c) 2017 Huawei Technologies Co., Ltd
|
|
*
|
|
*/
|
|
#ifndef __HIFCOE_PARENT_CONTEXT_H__
|
|
#define __HIFCOE_PARENT_CONTEXT_H__
|
|
|
|
enum fc_parent_status_e {
|
|
FCOE_PARENT_STATUS_INVALID = 0,
|
|
FCOE_PARENT_STATUS_NORMAL,
|
|
FCOE_PARENT_STATUS_CLOSING
|
|
};
|
|
|
|
#define HIFCOE_DOUBLE_SGL (1)
|
|
#define HIFCOE_SINGLE_SGL (0)
|
|
|
|
#define HIFCOE_DIX_ALGORITHM_IP (1)
|
|
#define HIFCOE_DIX_ALGORITHM_CRC (0)
|
|
|
|
#define HIFCOE_PARENT_CONTEXT_KEY_ALIGN_SIZE (48)
|
|
|
|
#define HIFCOE_PARENT_CONTEXT_SRQ_QINFO_SIZE (8)
|
|
#define HIFCOE_PARENT_CONTEXT_TIMER_SIZE (32) /* 24+2*N,N=timer count */
|
|
#define HIFCOE_RQ_FILLED_OFFSET \
|
|
((u8)(u32)& \
|
|
(((struct hifcoe_sw_section_s *)0x0)->occupy_by_rqe_filled_flag))
|
|
#define HIFCOE_RW_LOCK_AREA_OFFSET \
|
|
((u8)(u32)&\
|
|
(((struct hifcoe_sw_section_s *)0x0)->occupy_by_rw_lock_area))
|
|
|
|
/* "fqg_level_eventiq_info_s" should be care if MAX_EVENTIQ_LEVEL is larger
|
|
* than 4
|
|
*/
|
|
#define MAX_EVENTIQ_LEVEL 4
|
|
#define MAX_EVENTIQ_LEVEL_SHIFT 2
|
|
|
|
#define SP_FEATRUE_EDTR 0x1
|
|
#define SP_FEATRUE_SEQ_CNT 0x2
|
|
|
|
#define MAX_PKT_SIZE_PER_DISPATCH (FC_PARENT_P->per_xmit_data_size)
|
|
#define MAX_PKT_SIZE_PER_DISPATCH_DIF_4K \
|
|
(MAX_PKT_SIZE_PER_DISPATCH + ((MAX_PKT_SIZE_PER_DISPATCH >> 12) << 3))
|
|
#define MAX_PKT_SIZE_PER_DISPATCH_DIF_512B \
|
|
(MAX_PKT_SIZE_PER_DISPATCH + ((MAX_PKT_SIZE_PER_DISPATCH >> 9) << 3))
|
|
#define MAX_PKT_SIZE_PER_DISPATCH_DIF(shift) \
|
|
(MAX_PKT_SIZE_PER_DISPATCH +\
|
|
((u32)((MAX_PKT_SIZE_PER_DISPATCH >> 9) >> (shift)) << 3))
|
|
|
|
/* immidiate data DIF info definition in parent context */
|
|
struct immi_dif_info_s {
|
|
union {
|
|
u32 value;
|
|
struct {
|
|
#if (__BYTE_ORDER__ == __BIG_ENDIAN__)
|
|
u32 pdu_difx_cnt :8;
|
|
u32 sct_size :1;/* Sector size, 1: 4K; 0: 512 */
|
|
u32 dif_verify_type :2; /* verify type */
|
|
u32 dif_ins_rep_type:2; /* ins&rep type */
|
|
u32 io_1st_pdu :1;
|
|
/* Check blocks whose application tag contains
|
|
* 0xFFFF flag
|
|
*/
|
|
u32 difx_app_esc :1;
|
|
u32 difx_ref_esc :1;
|
|
/*
|
|
* Check blocks whose reference tag contains 0xFFFF flag
|
|
*/
|
|
u32 grd_ctrl :3; /* The DIF/DIX Guard control */
|
|
/* Bit 0: DIF/DIX guard verify algorithm control */
|
|
u32 grd_agm_ctrl :2;
|
|
/*
|
|
* Bit 1: DIF/DIX guard replace or insert algorithm
|
|
* control
|
|
*/
|
|
u32 grd_agm_ini_ctrl :3;
|
|
/* The DIF/DIX Reference tag control */
|
|
u32 ref_tag_ctrl :3;
|
|
/* Bit 0: scenario of the reference tag verify mode */
|
|
u32 ref_tag_mode :2;
|
|
/*
|
|
* Bit 1: scenario of the reference tag insert/replace
|
|
* mode
|
|
*/
|
|
/* 0: fixed; 1: increasement;*/
|
|
u32 app_tag_ctrl :3; /* DIF/DIX APP TAG Control */
|
|
|
|
#else
|
|
u32 app_tag_ctrl :3; /* DIF/DIX APP TAG Control */
|
|
/* Bit 0: scenario of the reference tag verify mode */
|
|
u32 ref_tag_mode :2;
|
|
/*
|
|
* Bit 1: scenario of the reference tag insert/replace
|
|
* mode
|
|
*/
|
|
/* 0: fixed; 1: increasement;*/
|
|
/* The DIF/DIX Reference tag control */
|
|
u32 ref_tag_ctrl :3;
|
|
u32 grd_agm_ini_ctrl :3;
|
|
/* Bit 0: DIF/DIX guard verify algorithm control */
|
|
u32 grd_agm_ctrl :2;
|
|
/*
|
|
* Bit 1: DIF/DIX guard replace or insert algorithm
|
|
* control
|
|
*/
|
|
u32 grd_ctrl :3; /* The DIF/DIX Guard control */
|
|
/*
|
|
* Check blocks whose reference tag contains 0xFFFF flag
|
|
*/
|
|
u32 difx_ref_esc :1;
|
|
/*
|
|
* Check blocks whose application tag contains 0xFFFF
|
|
* flag
|
|
*/
|
|
u32 difx_app_esc :1;
|
|
u32 io_1st_pdu :1;
|
|
u32 dif_ins_rep_type:2; /* ins&rep type */
|
|
u32 dif_verify_type :2; /* verify type */
|
|
u32 sct_size :1; /* Sector size, 1: 4K; 0: 512 */
|
|
u32 pdu_difx_cnt :8;
|
|
|
|
#endif
|
|
} info;
|
|
} dif_dw3;
|
|
|
|
union {
|
|
u32 value;
|
|
struct {
|
|
#if (__BYTE_ORDER__ == __BIG_ENDIAN__)
|
|
u32 difx_len :11; /* DIF/DIFX total length */
|
|
u32 difx_en :1; /* DIF/DIFX enable flag */
|
|
u32 rsv0 :4;
|
|
u32 dif_cnt :16;
|
|
#else
|
|
u32 dif_cnt :16;
|
|
u32 rsv0 :4;
|
|
u32 difx_en :1; /* DIF/DIFX enable flag */
|
|
u32 difx_len :11; /* DIF/DIFX total length */
|
|
#endif
|
|
} info;
|
|
} dif_other;
|
|
|
|
#if (__BYTE_ORDER__ == __BIG_ENDIAN__)
|
|
u32 rep_app_tag :16;
|
|
u32 cmp_app_tag :16;
|
|
#else
|
|
u32 cmp_app_tag :16;
|
|
u32 rep_app_tag :16;
|
|
#endif
|
|
/*
|
|
* The ref tag value for verify compare, do not support replace or
|
|
* insert ref tag
|
|
*/
|
|
u32 cmp_ref_tag;
|
|
|
|
#if (__BYTE_ORDER__ == __BIG_ENDIAN__)
|
|
u32 cmp_app_tag_msk :16;
|
|
u32 rsv1 :16;
|
|
#else
|
|
u32 rsv1 :16;
|
|
u32 cmp_app_tag_msk :16;
|
|
#endif
|
|
};
|
|
|
|
/* parent context SW section definition: SW(80B) */
|
|
struct hifcoe_sw_section_s {
|
|
/* RO fields */
|
|
u32 scq_num_rcv_cmd; /* scq number used for cmd receive */
|
|
|
|
#if (__BYTE_ORDER__ == __BIG_ENDIAN__)
|
|
u32 xid; /* driver init */
|
|
#else
|
|
struct {
|
|
u32 xid :13;
|
|
u32 vport :7;
|
|
u32 csctrl :8;
|
|
u32 rsvd0 :4;
|
|
} sw_ctxt_vport_xid;
|
|
#endif
|
|
u32 cid; /* ucode init */
|
|
|
|
u16 conn_id;
|
|
u16 immi_rq_page_size;
|
|
|
|
u16 immi_taskid_min;
|
|
u16 immi_taskid_max;
|
|
|
|
#if (__BYTE_ORDER__ == __BIG_ENDIAN__)
|
|
u32 vlan_id : 16; /* Vlan ID */
|
|
/* phycial port to receive and transmit packet. */
|
|
u32 port_id : 4;
|
|
/*
|
|
* new srq offset. Ucode use new srq to receive els/gs with big payload.
|
|
*/
|
|
u32 rsvd1 : 5;
|
|
u32 srr_support : 2; /* sequence retransmition support flag */
|
|
u32 srv_type : 5;
|
|
#else
|
|
union {
|
|
u32 pctxt_val0;
|
|
struct {
|
|
u32 srv_type : 5; /* driver init */
|
|
/* sequence retransmition support flag */
|
|
u32 srr_support : 2;
|
|
u32 rsvd1 : 5;
|
|
u32 port_id : 4; /* driver init */
|
|
u32 vlan_id : 16; /* driver init */
|
|
} dw;
|
|
} sw_ctxt_misc;
|
|
#endif
|
|
|
|
u16 oqid_rd;
|
|
u16 oqid_wr;
|
|
u32 per_xmit_data_size;
|
|
|
|
/* RW fields */
|
|
u32 cmd_scq_gpa_h;
|
|
u32 cmd_scq_gpa_l;
|
|
/* E_D_TOV timer value: value should be set on ms by driver */
|
|
u32 e_d_tov_timer_val;
|
|
/*
|
|
* mfs unalined bytes of per 64KB dispatch; equal to
|
|
* "MAX_PKT_SIZE_PER_DISPATCH%info->parent->tx_mfs"
|
|
*/
|
|
u16 mfs_unaligned_bytes;
|
|
u16 tx_mfs; /* remote port max receive fc payload length */
|
|
/* max data len allowed in xfer_rdy dis scenario*/
|
|
u32 xfer_rdy_dis_max_len_remote;
|
|
u32 xfer_rdy_dis_max_len_local;
|
|
|
|
#if (__BYTE_ORDER__ == __BIG_ENDIAN__)
|
|
/* Double or single SGL, 1: double; 0: single */
|
|
u32 sgl_num :1;
|
|
u32 write_xfer_rdy :1; /* WRITE Xfer_Rdy disable or enable */
|
|
u32 rec_support :1; /* REC support flag */
|
|
u32 conf_support :1; /* Response confirm support flag */
|
|
u32 vlan_enable :1; /* Vlan enable flag */
|
|
u32 e_d_tov :1; /* E_D_TOV Resolution, 0: ms, 1: us*/
|
|
/* seq_cnt, 1: increament support, 0: increament not support */
|
|
u32 seq_cnt :1;
|
|
/* 0:Target, 1:Initiator, 2:Target&Initiator */
|
|
u32 work_mode :2;
|
|
/* used for parent context cache Consistency judgment,1: done*/
|
|
u32 flush_done :1;
|
|
u32 oq_cos_cmd :3; /* esch oq cos for cmd/xferrdy/rsp */
|
|
u32 oq_cos_data :3; /* esch oq cos for data */
|
|
u32 cos :3; /* doorbell cos value */
|
|
u32 status :8; /* status of flow*/
|
|
u32 rsvd4 :2;
|
|
u32 priority :3; /* vlan priority */
|
|
#else
|
|
union {
|
|
struct {
|
|
u32 priority : 3; /* vlan priority */
|
|
u32 rsvd4 : 2;
|
|
u32 status : 8; /* status of flow*/
|
|
u32 cos : 3; /* doorbell cos value */
|
|
u32 oq_cos_data : 3; /* esch oq cos for data */
|
|
/* esch oq cos for cmd/xferrdy/rsp */
|
|
u32 oq_cos_cmd : 3;
|
|
/*
|
|
* used for parent context cache Consistency judgment,
|
|
* 1: done
|
|
*/
|
|
u32 flush_done : 1;
|
|
/* 0:Target, 1:Initiator, 2:Target&Initiator */
|
|
u32 work_mode : 2;
|
|
u32 seq_cnt : 1; /* seq_cnt */
|
|
u32 e_d_tov : 1; /* E_D_TOV resolution */
|
|
u32 vlan_enable : 1; /* Vlan enable flag */
|
|
/* Response confirm support flag */
|
|
u32 conf_support : 1;
|
|
u32 rec_support : 1; /* REC support flag */
|
|
/* WRITE Xfer_Rdy disable or enable */
|
|
u32 write_xfer_rdy : 1;
|
|
/* Double or single SGL, 1: double; 0: single */
|
|
u32 sgl_num : 1;
|
|
} dw;
|
|
u32 pctxt_val1;
|
|
} sw_ctxt_config;
|
|
#endif
|
|
/* immidiate data dif control info(20B) */
|
|
struct immi_dif_info_s immi_dif_info;
|
|
};
|
|
|
|
struct hifcoe_hw_rsvd_queue_s {
|
|
/* bitmap[0]:255-192 */
|
|
/* bitmap[1]:191-128 */
|
|
/* bitmap[2]:127-64 */
|
|
/* bitmap[3]:63-0 */
|
|
u64 seq_id_bitmap[4];
|
|
struct {
|
|
u64 last_req_seq_id : 8;
|
|
u64 xid : 20;
|
|
u64 rsvd0 : 36;
|
|
} wd0;
|
|
};
|
|
|
|
struct hifcoe_sq_qinfo_s {
|
|
u64 rsvd_0 : 10;
|
|
/* 0: get pmsn from queue header; 1: get pmsn from ucode */
|
|
u64 pmsn_type : 1;
|
|
u64 rsvd_1 : 4;
|
|
u64 cur_wqe_o : 1; /* should be opposite from loop_o */
|
|
u64 rsvd_2 : 48;
|
|
|
|
u64 cur_sqe_gpa;
|
|
u64 pmsn_gpa; /* sq's queue header gpa */
|
|
|
|
u64 sqe_dmaattr_idx : 6;
|
|
u64 sq_so_ro : 2;
|
|
u64 rsvd_3 : 2;
|
|
u64 ring : 1; /* 0: link; 1: ring */
|
|
u64 loop_o : 1; /* init to be the first round o-bit */
|
|
u64 rsvd_4 : 4;
|
|
u64 zerocopy_dmaattr_idx : 6;
|
|
u64 zerocopy_so_ro : 2;
|
|
u64 parity : 8;
|
|
u64 rsvd_5 : 26;
|
|
u64 pcie_template : 6;
|
|
};
|
|
|
|
struct hifcoe_cq_qinfo_s {
|
|
u64 pcie_template_hi : 3;
|
|
u64 parity_2 : 1;
|
|
u64 cur_cqe_gpa : 60;
|
|
|
|
u64 pi : 15;
|
|
u64 pi_o : 1;
|
|
u64 ci : 15;
|
|
u64 ci_o : 1;
|
|
/* if init_mode = 2, is msi/msi-x; other the low-5-bit means c_eqn */
|
|
u64 c_eqn_msi_x : 10;
|
|
u64 parity_1 : 1;
|
|
/* 0: get ci from queue header; 1: get ci from ucode */
|
|
u64 ci_type : 1;
|
|
u64 cq_depth : 3; /* valid when ring = 1 */
|
|
u64 armq : 1; /* 0: IDLE state; 1: NEXT state */
|
|
u64 cur_cqe_cnt : 8;
|
|
u64 cqe_max_cnt : 8;
|
|
|
|
u64 cqe_dmaattr_idx : 6;
|
|
u64 cq_so_ro : 2;
|
|
u64 init_mode : 2; /* 1: armQ; 2: msi/msi-x; others: rsvd */
|
|
u64 next_o : 1; /* next pate valid o-bit */
|
|
u64 loop_o : 1; /* init to be the first round o-bit */
|
|
u64 next_cq_wqe_page_gpa : 52;
|
|
|
|
u64 pcie_template_lo : 3;
|
|
u64 parity_0 : 1;
|
|
u64 ci_gpa : 60; /* cq's queue header gpa */
|
|
};
|
|
|
|
struct hifcoe_scq_qinfo_s {
|
|
#if (__BYTE_ORDER__ == __BIG_ENDIAN__)
|
|
union {
|
|
struct {
|
|
u64 parity : 6;
|
|
u64 rq_th2_preld_cache_num : 5;
|
|
u64 rq_th1_preld_cache_num : 5;
|
|
u64 rq_th0_preld_cache_num : 5;
|
|
u64 rq_min_preld_cache_num : 4;
|
|
u64 sq_th2_preld_cache_num : 5;
|
|
u64 sq_th1_preld_cache_num : 5;
|
|
u64 sq_th0_preld_cache_num : 5;
|
|
u64 sq_min_preld_cache_num : 4;
|
|
u64 scq_n : 20; /* scq number */
|
|
} info;
|
|
|
|
u64 pctxt_val1;
|
|
} hw_scqc_config;
|
|
#else
|
|
union {
|
|
struct {
|
|
u64 scq_n : 20; /* scq number */
|
|
u64 sq_min_preld_cache_num : 4;
|
|
u64 sq_th0_preld_cache_num : 5;
|
|
u64 sq_th1_preld_cache_num : 5;
|
|
u64 sq_th2_preld_cache_num : 5;
|
|
u64 rq_min_preld_cache_num : 4;
|
|
u64 rq_th0_preld_cache_num : 5;
|
|
u64 rq_th1_preld_cache_num : 5;
|
|
u64 rq_th2_preld_cache_num : 5;
|
|
u64 parity : 6;
|
|
} info;
|
|
|
|
u64 pctxt_val1;
|
|
} hw_scqc_config;
|
|
#endif
|
|
};
|
|
|
|
struct hifcoe_srq_qinfo_s {
|
|
#if (__BYTE_ORDER__ == __BIG_ENDIAN__)
|
|
u64 srqc_gpa : 60;
|
|
u64 parity : 4;
|
|
#else
|
|
u64 parity : 4;
|
|
u64 srqc_gpa : 60;
|
|
#endif
|
|
};
|
|
|
|
/* here is the layout of service type 12/13 */
|
|
struct hifcoe_parent_context_s {
|
|
u8 key[HIFCOE_PARENT_CONTEXT_KEY_ALIGN_SIZE];
|
|
struct hifcoe_scq_qinfo_s resp_scq_qinfo;
|
|
struct hifcoe_srq_qinfo_s imm_srq_info;
|
|
struct hifcoe_sq_qinfo_s sq_qinfo;
|
|
u8 timer_section[HIFCOE_PARENT_CONTEXT_TIMER_SIZE];
|
|
struct hifcoe_hw_rsvd_queue_s hw_rsvdq;
|
|
struct hifcoe_srq_qinfo_s els_srq_info;
|
|
struct hifcoe_sw_section_s sw_section;
|
|
};
|
|
|
|
#endif
|