1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* QLogic FCoE Offload Driver |
3 | * Copyright (c) 2016-2018 Cavium Inc. |
4 | */ |
5 | #include "drv_fcoe_fw_funcs.h" |
6 | #include "drv_scsi_fw_funcs.h" |
7 | |
8 | #define FCOE_RX_ID (0xFFFFu) |
9 | |
10 | static inline void init_common_sqe(struct fcoe_task_params *task_params, |
11 | enum fcoe_sqe_request_type request_type) |
12 | { |
13 | memset(task_params->sqe, 0, sizeof(*(task_params->sqe))); |
14 | SET_FIELD(task_params->sqe->flags, FCOE_WQE_REQ_TYPE, |
15 | request_type); |
16 | task_params->sqe->task_id = task_params->itid; |
17 | } |
18 | |
19 | int init_initiator_rw_fcoe_task(struct fcoe_task_params *task_params, |
20 | struct scsi_sgl_task_params *sgl_task_params, |
21 | struct regpair sense_data_buffer_phys_addr, |
22 | u32 task_retry_id, |
23 | u8 fcp_cmd_payload[32]) |
24 | { |
25 | struct fcoe_task_context *ctx = task_params->context; |
26 | const u8 val_byte = ctx->ystorm_ag_context.byte0; |
27 | struct ustorm_fcoe_task_ag_ctx *u_ag_ctx; |
28 | struct ystorm_fcoe_task_st_ctx *y_st_ctx; |
29 | struct tstorm_fcoe_task_st_ctx *t_st_ctx; |
30 | struct mstorm_fcoe_task_st_ctx *m_st_ctx; |
31 | u32 io_size, val; |
32 | bool slow_sgl; |
33 | |
34 | memset(ctx, 0, sizeof(*(ctx))); |
35 | ctx->ystorm_ag_context.byte0 = val_byte; |
36 | slow_sgl = scsi_is_slow_sgl(num_sges: sgl_task_params->num_sges, |
37 | small_mid_sge: sgl_task_params->small_mid_sge); |
38 | io_size = (task_params->task_type == FCOE_TASK_TYPE_WRITE_INITIATOR ? |
39 | task_params->tx_io_size : task_params->rx_io_size); |
40 | |
41 | /* Ystorm ctx */ |
42 | y_st_ctx = &ctx->ystorm_st_context; |
43 | y_st_ctx->data_2_trns_rem = cpu_to_le32(io_size); |
44 | y_st_ctx->task_rety_identifier = cpu_to_le32(task_retry_id); |
45 | y_st_ctx->task_type = (u8)task_params->task_type; |
46 | memcpy(&y_st_ctx->tx_info_union.fcp_cmd_payload, |
47 | fcp_cmd_payload, sizeof(struct fcoe_fcp_cmd_payload)); |
48 | |
49 | /* Tstorm ctx */ |
50 | t_st_ctx = &ctx->tstorm_st_context; |
51 | t_st_ctx->read_only.dev_type = (u8)(task_params->is_tape_device == 1 ? |
52 | FCOE_TASK_DEV_TYPE_TAPE : |
53 | FCOE_TASK_DEV_TYPE_DISK); |
54 | t_st_ctx->read_only.cid = cpu_to_le32(task_params->conn_cid); |
55 | val = cpu_to_le32(task_params->cq_rss_number); |
56 | t_st_ctx->read_only.glbl_q_num = val; |
57 | t_st_ctx->read_only.fcp_cmd_trns_size = cpu_to_le32(io_size); |
58 | t_st_ctx->read_only.task_type = (u8)task_params->task_type; |
59 | SET_FIELD(t_st_ctx->read_write.flags, |
60 | FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_EXP_FIRST_FRAME, 1); |
61 | t_st_ctx->read_write.rx_id = cpu_to_le16(FCOE_RX_ID); |
62 | |
63 | /* Ustorm ctx */ |
64 | u_ag_ctx = &ctx->ustorm_ag_context; |
65 | u_ag_ctx->global_cq_num = cpu_to_le32(task_params->cq_rss_number); |
66 | |
67 | /* Mstorm buffer for sense/rsp data placement */ |
68 | m_st_ctx = &ctx->mstorm_st_context; |
69 | val = cpu_to_le32(sense_data_buffer_phys_addr.hi); |
70 | m_st_ctx->rsp_buf_addr.hi = val; |
71 | val = cpu_to_le32(sense_data_buffer_phys_addr.lo); |
72 | m_st_ctx->rsp_buf_addr.lo = val; |
73 | |
74 | if (task_params->task_type == FCOE_TASK_TYPE_WRITE_INITIATOR) { |
75 | /* Ystorm ctx */ |
76 | y_st_ctx->expect_first_xfer = 1; |
77 | |
78 | /* Set the amount of super SGEs. Can be up to 4. */ |
79 | SET_FIELD(y_st_ctx->sgl_mode, |
80 | YSTORM_FCOE_TASK_ST_CTX_TX_SGL_MODE, |
81 | (slow_sgl ? SCSI_TX_SLOW_SGL : SCSI_FAST_SGL)); |
82 | init_scsi_sgl_context(sgl_params: &y_st_ctx->sgl_params, |
83 | ctx_data_desc: &y_st_ctx->data_desc, |
84 | sgl_task_params); |
85 | |
86 | /* Mstorm ctx */ |
87 | SET_FIELD(m_st_ctx->flags, |
88 | MSTORM_FCOE_TASK_ST_CTX_TX_SGL_MODE, |
89 | (slow_sgl ? SCSI_TX_SLOW_SGL : SCSI_FAST_SGL)); |
90 | m_st_ctx->sgl_params.sgl_num_sges = |
91 | cpu_to_le16(sgl_task_params->num_sges); |
92 | } else { |
93 | /* Tstorm ctx */ |
94 | SET_FIELD(t_st_ctx->read_write.flags, |
95 | FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_RX_SGL_MODE, |
96 | (slow_sgl ? SCSI_TX_SLOW_SGL : SCSI_FAST_SGL)); |
97 | |
98 | /* Mstorm ctx */ |
99 | m_st_ctx->data_2_trns_rem = cpu_to_le32(io_size); |
100 | init_scsi_sgl_context(sgl_params: &m_st_ctx->sgl_params, |
101 | ctx_data_desc: &m_st_ctx->data_desc, |
102 | sgl_task_params); |
103 | } |
104 | |
105 | /* Init Sqe */ |
106 | init_common_sqe(task_params, request_type: SEND_FCOE_CMD); |
107 | |
108 | return 0; |
109 | } |
110 | |
111 | int init_initiator_midpath_unsolicited_fcoe_task( |
112 | struct fcoe_task_params *task_params, |
113 | struct fcoe_tx_mid_path_params *, |
114 | struct scsi_sgl_task_params *tx_sgl_task_params, |
115 | struct scsi_sgl_task_params *rx_sgl_task_params, |
116 | u8 ) |
117 | { |
118 | struct fcoe_task_context *ctx = task_params->context; |
119 | const u8 val_byte = ctx->ystorm_ag_context.byte0; |
120 | struct ustorm_fcoe_task_ag_ctx *u_ag_ctx; |
121 | struct ystorm_fcoe_task_st_ctx *y_st_ctx; |
122 | struct tstorm_fcoe_task_st_ctx *t_st_ctx; |
123 | struct mstorm_fcoe_task_st_ctx *m_st_ctx; |
124 | u32 val; |
125 | |
126 | memset(ctx, 0, sizeof(*(ctx))); |
127 | ctx->ystorm_ag_context.byte0 = val_byte; |
128 | |
129 | /* Init Ystorm */ |
130 | y_st_ctx = &ctx->ystorm_st_context; |
131 | init_scsi_sgl_context(sgl_params: &y_st_ctx->sgl_params, |
132 | ctx_data_desc: &y_st_ctx->data_desc, |
133 | sgl_task_params: tx_sgl_task_params); |
134 | SET_FIELD(y_st_ctx->sgl_mode, |
135 | YSTORM_FCOE_TASK_ST_CTX_TX_SGL_MODE, SCSI_FAST_SGL); |
136 | y_st_ctx->data_2_trns_rem = cpu_to_le32(task_params->tx_io_size); |
137 | y_st_ctx->task_type = (u8)task_params->task_type; |
138 | memcpy(&y_st_ctx->tx_info_union.tx_params.mid_path, |
139 | mid_path_fc_header, sizeof(struct fcoe_tx_mid_path_params)); |
140 | |
141 | /* Init Mstorm */ |
142 | m_st_ctx = &ctx->mstorm_st_context; |
143 | init_scsi_sgl_context(sgl_params: &m_st_ctx->sgl_params, |
144 | ctx_data_desc: &m_st_ctx->data_desc, |
145 | sgl_task_params: rx_sgl_task_params); |
146 | SET_FIELD(m_st_ctx->flags, |
147 | MSTORM_FCOE_TASK_ST_CTX_MP_INCLUDE_FC_HEADER, |
148 | fw_to_place_fc_header); |
149 | m_st_ctx->data_2_trns_rem = cpu_to_le32(task_params->rx_io_size); |
150 | |
151 | /* Init Tstorm */ |
152 | t_st_ctx = &ctx->tstorm_st_context; |
153 | t_st_ctx->read_only.cid = cpu_to_le32(task_params->conn_cid); |
154 | val = cpu_to_le32(task_params->cq_rss_number); |
155 | t_st_ctx->read_only.glbl_q_num = val; |
156 | t_st_ctx->read_only.task_type = (u8)task_params->task_type; |
157 | SET_FIELD(t_st_ctx->read_write.flags, |
158 | FCOE_TSTORM_FCOE_TASK_ST_CTX_READ_WRITE_EXP_FIRST_FRAME, 1); |
159 | t_st_ctx->read_write.rx_id = cpu_to_le16(FCOE_RX_ID); |
160 | |
161 | /* Init Ustorm */ |
162 | u_ag_ctx = &ctx->ustorm_ag_context; |
163 | u_ag_ctx->global_cq_num = cpu_to_le32(task_params->cq_rss_number); |
164 | |
165 | /* Init SQE */ |
166 | init_common_sqe(task_params, request_type: SEND_FCOE_MIDPATH); |
167 | task_params->sqe->additional_info_union.burst_length = |
168 | tx_sgl_task_params->total_buffer_size; |
169 | SET_FIELD(task_params->sqe->flags, |
170 | FCOE_WQE_NUM_SGES, tx_sgl_task_params->num_sges); |
171 | SET_FIELD(task_params->sqe->flags, FCOE_WQE_SGL_MODE, |
172 | SCSI_FAST_SGL); |
173 | |
174 | return 0; |
175 | } |
176 | |
177 | int init_initiator_abort_fcoe_task(struct fcoe_task_params *task_params) |
178 | { |
179 | init_common_sqe(task_params, request_type: SEND_FCOE_ABTS_REQUEST); |
180 | return 0; |
181 | } |
182 | |
183 | int init_initiator_cleanup_fcoe_task(struct fcoe_task_params *task_params) |
184 | { |
185 | init_common_sqe(task_params, request_type: FCOE_EXCHANGE_CLEANUP); |
186 | return 0; |
187 | } |
188 | |
189 | int init_initiator_sequence_recovery_fcoe_task( |
190 | struct fcoe_task_params *task_params, u32 desired_offset) |
191 | { |
192 | init_common_sqe(task_params, request_type: FCOE_SEQUENCE_RECOVERY); |
193 | task_params->sqe->additional_info_union.seq_rec_updated_offset = |
194 | desired_offset; |
195 | return 0; |
196 | } |
197 | |