Merge git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6
[linux-2.6] / drivers / scsi / fnic / cq_exch_desc.h
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_ */