xref: /linux/drivers/scsi/fnic/cq_exch_desc.h (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
1 /*
2  * Copyright 2008 Cisco Systems, Inc.  All rights reserved.
3  * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
4  *
5  * This program is free software; you may redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; version 2 of the License.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16  * SOFTWARE.
17  */
18 #ifndef _CQ_EXCH_DESC_H_
19 #define _CQ_EXCH_DESC_H_
20 
21 #include "cq_desc.h"
22 
23 /* Exchange completion queue descriptor: 16B */
24 struct cq_exch_wq_desc {
25 	u16 completed_index;
26 	u16 q_number;
27 	u16 exchange_id;
28 	u8  tmpl;
29 	u8  reserved0;
30 	u32 reserved1;
31 	u8  exch_status;
32 	u8  reserved2[2];
33 	u8  type_color;
34 };
35 
36 #define CQ_EXCH_WQ_STATUS_BITS      2
37 #define CQ_EXCH_WQ_STATUS_MASK      ((1 << CQ_EXCH_WQ_STATUS_BITS) - 1)
38 
39 enum cq_exch_status_types {
40 	CQ_EXCH_WQ_STATUS_TYPE_COMPLETE = 0,
41 	CQ_EXCH_WQ_STATUS_TYPE_ABORT = 1,
42 	CQ_EXCH_WQ_STATUS_TYPE_SGL_EOF = 2,
43 	CQ_EXCH_WQ_STATUS_TYPE_TMPL_ERR = 3,
44 };
45 
46 static inline void cq_exch_wq_desc_dec(struct cq_exch_wq_desc *desc_ptr,
47 				       u8  *type,
48 				       u8  *color,
49 				       u16 *q_number,
50 				       u16 *completed_index,
51 				       u8  *exch_status)
52 {
53 	cq_desc_dec((struct cq_desc *)desc_ptr, type,
54 		    color, q_number, completed_index);
55 	*exch_status = desc_ptr->exch_status & CQ_EXCH_WQ_STATUS_MASK;
56 }
57 
58 struct cq_fcp_rq_desc {
59 	u16 completed_index_eop_sop_prt;
60 	u16 q_number;
61 	u16 exchange_id;
62 	u16 tmpl;
63 	u16 bytes_written;
64 	u16 vlan;
65 	u8  sof;
66 	u8  eof;
67 	u8  fcs_fer_fck;
68 	u8  type_color;
69 };
70 
71 #define CQ_FCP_RQ_DESC_FLAGS_SOP		(1 << 15)
72 #define CQ_FCP_RQ_DESC_FLAGS_EOP		(1 << 14)
73 #define CQ_FCP_RQ_DESC_FLAGS_PRT		(1 << 12)
74 #define CQ_FCP_RQ_DESC_TMPL_MASK		0x1f
75 #define CQ_FCP_RQ_DESC_BYTES_WRITTEN_MASK	0x3fff
76 #define CQ_FCP_RQ_DESC_PACKET_ERR_SHIFT		14
77 #define CQ_FCP_RQ_DESC_PACKET_ERR_MASK (1 << CQ_FCP_RQ_DESC_PACKET_ERR_SHIFT)
78 #define CQ_FCP_RQ_DESC_VS_STRIPPED_SHIFT	15
79 #define CQ_FCP_RQ_DESC_VS_STRIPPED_MASK (1 << CQ_FCP_RQ_DESC_VS_STRIPPED_SHIFT)
80 #define CQ_FCP_RQ_DESC_FC_CRC_OK_MASK		0x1
81 #define CQ_FCP_RQ_DESC_FCOE_ERR_SHIFT		1
82 #define CQ_FCP_RQ_DESC_FCOE_ERR_MASK (1 << CQ_FCP_RQ_DESC_FCOE_ERR_SHIFT)
83 #define CQ_FCP_RQ_DESC_FCS_OK_SHIFT		7
84 #define CQ_FCP_RQ_DESC_FCS_OK_MASK (1 << CQ_FCP_RQ_DESC_FCS_OK_SHIFT)
85 
86 static inline void cq_fcp_rq_desc_dec(struct cq_fcp_rq_desc *desc_ptr,
87 				      u8  *type,
88 				      u8  *color,
89 				      u16 *q_number,
90 				      u16 *completed_index,
91 				      u8  *eop,
92 				      u8  *sop,
93 				      u8  *fck,
94 				      u16 *exchange_id,
95 				      u16 *tmpl,
96 				      u32 *bytes_written,
97 				      u8  *sof,
98 				      u8  *eof,
99 				      u8  *ingress_port,
100 				      u8  *packet_err,
101 				      u8  *fcoe_err,
102 				      u8  *fcs_ok,
103 				      u8  *vlan_stripped,
104 				      u16 *vlan)
105 {
106 	cq_desc_dec((struct cq_desc *)desc_ptr, type,
107 		    color, q_number, completed_index);
108 	*eop = (desc_ptr->completed_index_eop_sop_prt &
109 		CQ_FCP_RQ_DESC_FLAGS_EOP) ? 1 : 0;
110 	*sop = (desc_ptr->completed_index_eop_sop_prt &
111 		CQ_FCP_RQ_DESC_FLAGS_SOP) ? 1 : 0;
112 	*ingress_port =
113 		(desc_ptr->completed_index_eop_sop_prt &
114 		 CQ_FCP_RQ_DESC_FLAGS_PRT) ? 1 : 0;
115 	*exchange_id = desc_ptr->exchange_id;
116 	*tmpl = desc_ptr->tmpl & CQ_FCP_RQ_DESC_TMPL_MASK;
117 	*bytes_written =
118 		desc_ptr->bytes_written & CQ_FCP_RQ_DESC_BYTES_WRITTEN_MASK;
119 	*packet_err =
120 		(desc_ptr->bytes_written & CQ_FCP_RQ_DESC_PACKET_ERR_MASK) >>
121 		CQ_FCP_RQ_DESC_PACKET_ERR_SHIFT;
122 	*vlan_stripped =
123 		(desc_ptr->bytes_written & CQ_FCP_RQ_DESC_VS_STRIPPED_MASK) >>
124 		CQ_FCP_RQ_DESC_VS_STRIPPED_SHIFT;
125 	*vlan = desc_ptr->vlan;
126 	*sof = desc_ptr->sof;
127 	*fck = desc_ptr->fcs_fer_fck & CQ_FCP_RQ_DESC_FC_CRC_OK_MASK;
128 	*fcoe_err = (desc_ptr->fcs_fer_fck & CQ_FCP_RQ_DESC_FCOE_ERR_MASK) >>
129 		CQ_FCP_RQ_DESC_FCOE_ERR_SHIFT;
130 	*eof = desc_ptr->eof;
131 	*fcs_ok =
132 		(desc_ptr->fcs_fer_fck & CQ_FCP_RQ_DESC_FCS_OK_MASK) >>
133 		CQ_FCP_RQ_DESC_FCS_OK_SHIFT;
134 }
135 
136 struct cq_sgl_desc {
137 	u16 exchange_id;
138 	u16 q_number;
139 	u32 active_burst_offset;
140 	u32 tot_data_bytes;
141 	u16 tmpl;
142 	u8  sgl_err;
143 	u8  type_color;
144 };
145 
146 enum cq_sgl_err_types {
147 	CQ_SGL_ERR_NO_ERROR = 0,
148 	CQ_SGL_ERR_OVERFLOW,         /* data ran beyond end of SGL */
149 	CQ_SGL_ERR_SGL_LCL_ADDR_ERR, /* sgl access to local vnic addr illegal*/
150 	CQ_SGL_ERR_ADDR_RSP_ERR,     /* sgl address error */
151 	CQ_SGL_ERR_DATA_RSP_ERR,     /* sgl data rsp error */
152 	CQ_SGL_ERR_CNT_ZERO_ERR,     /* SGL count is 0 */
153 	CQ_SGL_ERR_CNT_MAX_ERR,      /* SGL count is larger than supported */
154 	CQ_SGL_ERR_ORDER_ERR,        /* frames recv on both ports, order err */
155 	CQ_SGL_ERR_DATA_LCL_ADDR_ERR,/* sgl data buf to local vnic addr ill */
156 	CQ_SGL_ERR_HOST_CQ_ERR,      /* host cq entry to local vnic addr ill */
157 };
158 
159 #define CQ_SGL_SGL_ERR_MASK             0x1f
160 #define CQ_SGL_TMPL_MASK                0x1f
161 
162 static inline void cq_sgl_desc_dec(struct cq_sgl_desc *desc_ptr,
163 				   u8  *type,
164 				   u8  *color,
165 				   u16 *q_number,
166 				   u16 *exchange_id,
167 				   u32 *active_burst_offset,
168 				   u32 *tot_data_bytes,
169 				   u16 *tmpl,
170 				   u8  *sgl_err)
171 {
172 	/* Cheat a little by assuming exchange_id is the same as completed
173 	   index */
174 	cq_desc_dec((struct cq_desc *)desc_ptr, type, color, q_number,
175 		    exchange_id);
176 	*active_burst_offset = desc_ptr->active_burst_offset;
177 	*tot_data_bytes = desc_ptr->tot_data_bytes;
178 	*tmpl = desc_ptr->tmpl & CQ_SGL_TMPL_MASK;
179 	*sgl_err = desc_ptr->sgl_err & CQ_SGL_SGL_ERR_MASK;
180 }
181 
182 #endif /* _CQ_EXCH_DESC_H_ */
183