xref: /linux/drivers/scsi/elx/efct/efct_unsol.c (revision 2da68a77)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2021 Broadcom. All Rights Reserved. The term
4  * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
5  */
6 
7 #include "efct_driver.h"
8 #include "efct_unsol.h"
9 
10 #define frame_printf(efct, hdr, fmt, ...) \
11 	do { \
12 		char s_id_text[16]; \
13 		efc_node_fcid_display(ntoh24((hdr)->fh_s_id), \
14 			s_id_text, sizeof(s_id_text)); \
15 		efc_log_debug(efct, "[%06x.%s] %02x/%04x/%04x: " fmt, \
16 			ntoh24((hdr)->fh_d_id), s_id_text, \
17 			(hdr)->fh_r_ctl, be16_to_cpu((hdr)->fh_ox_id), \
18 			be16_to_cpu((hdr)->fh_rx_id), ##__VA_ARGS__); \
19 	} while (0)
20 
21 static struct efct_node *
22 efct_node_find(struct efct *efct, u32 port_id, u32 node_id)
23 {
24 	struct efct_node *node;
25 	u64 id = (u64)port_id << 32 | node_id;
26 
27 	/*
28 	 * During node shutdown, Lookup will be removed first,
29 	 * before announcing to backend. So, no new IOs will be allowed
30 	 */
31 	/* Find a target node, given s_id and d_id */
32 	node = xa_load(&efct->lookup, id);
33 	if (node)
34 		kref_get(&node->ref);
35 
36 	return node;
37 }
38 
39 static int
40 efct_dispatch_frame(struct efct *efct, struct efc_hw_sequence *seq)
41 {
42 	struct efct_node *node;
43 	struct fc_frame_header *hdr;
44 	u32 s_id, d_id;
45 
46 	hdr = seq->header->dma.virt;
47 
48 	/* extract the s_id and d_id */
49 	s_id = ntoh24(hdr->fh_s_id);
50 	d_id = ntoh24(hdr->fh_d_id);
51 
52 	if (!(hdr->fh_type == FC_TYPE_FCP || hdr->fh_type == FC_TYPE_BLS))
53 		return -EIO;
54 
55 	if (hdr->fh_type == FC_TYPE_FCP) {
56 		node = efct_node_find(efct, d_id, s_id);
57 		if (!node) {
58 			efc_log_err(efct,
59 				    "Node not found, drop cmd d_id:%x s_id:%x\n",
60 				    d_id, s_id);
61 			efct_hw_sequence_free(&efct->hw, seq);
62 			return 0;
63 		}
64 
65 		efct_dispatch_fcp_cmd(node, seq);
66 	} else {
67 		node = efct_node_find(efct, d_id, s_id);
68 		if (!node) {
69 			efc_log_err(efct, "ABTS: Node not found, d_id:%x s_id:%x\n",
70 				    d_id, s_id);
71 			return -EIO;
72 		}
73 
74 		efc_log_err(efct, "Received ABTS for Node:%p\n", node);
75 		efct_node_recv_abts_frame(node, seq);
76 	}
77 
78 	kref_put(&node->ref, node->release);
79 	efct_hw_sequence_free(&efct->hw, seq);
80 	return 0;
81 }
82 
83 int
84 efct_unsolicited_cb(void *arg, struct efc_hw_sequence *seq)
85 {
86 	struct efct *efct = arg;
87 
88 	/* Process FCP command */
89 	if (!efct_dispatch_frame(efct, seq))
90 		return 0;
91 
92 	/* Forward frame to discovery lib */
93 	efc_dispatch_frame(efct->efcport, seq);
94 	return 0;
95 }
96 
97 static int
98 efct_fc_tmf_rejected_cb(struct efct_io *io,
99 			enum efct_scsi_io_status scsi_status,
100 			u32 flags, void *arg)
101 {
102 	efct_scsi_io_free(io);
103 	return 0;
104 }
105 
106 static void
107 efct_dispatch_unsol_tmf(struct efct_io *io, u8 tm_flags, u32 lun)
108 {
109 	u32 i;
110 	struct {
111 		u32 mask;
112 		enum efct_scsi_tmf_cmd cmd;
113 	} tmflist[] = {
114 	{FCP_TMF_ABT_TASK_SET, EFCT_SCSI_TMF_ABORT_TASK_SET},
115 	{FCP_TMF_CLR_TASK_SET, EFCT_SCSI_TMF_CLEAR_TASK_SET},
116 	{FCP_TMF_LUN_RESET, EFCT_SCSI_TMF_LOGICAL_UNIT_RESET},
117 	{FCP_TMF_TGT_RESET, EFCT_SCSI_TMF_TARGET_RESET},
118 	{FCP_TMF_CLR_ACA, EFCT_SCSI_TMF_CLEAR_ACA} };
119 
120 	io->exp_xfer_len = 0;
121 
122 	for (i = 0; i < ARRAY_SIZE(tmflist); i++) {
123 		if (tmflist[i].mask & tm_flags) {
124 			io->tmf_cmd = tmflist[i].cmd;
125 			efct_scsi_recv_tmf(io, lun, tmflist[i].cmd, NULL, 0);
126 			break;
127 		}
128 	}
129 	if (i == ARRAY_SIZE(tmflist)) {
130 		/* Not handled */
131 		efc_log_err(io->node->efct, "TMF x%x rejected\n", tm_flags);
132 		efct_scsi_send_tmf_resp(io, EFCT_SCSI_TMF_FUNCTION_REJECTED,
133 					NULL, efct_fc_tmf_rejected_cb, NULL);
134 	}
135 }
136 
137 static int
138 efct_validate_fcp_cmd(struct efct *efct, struct efc_hw_sequence *seq)
139 {
140 	/*
141 	 * If we received less than FCP_CMND_IU bytes, assume that the frame is
142 	 * corrupted in some way and drop it.
143 	 * This was seen when jamming the FCTL
144 	 * fill bytes field.
145 	 */
146 	if (seq->payload->dma.len < sizeof(struct fcp_cmnd)) {
147 		struct fc_frame_header	*fchdr = seq->header->dma.virt;
148 
149 		efc_log_debug(efct,
150 			      "drop ox_id %04x payload (%zd) less than (%zd)\n",
151 			      be16_to_cpu(fchdr->fh_ox_id),
152 			      seq->payload->dma.len, sizeof(struct fcp_cmnd));
153 		return -EIO;
154 	}
155 	return 0;
156 }
157 
158 static void
159 efct_populate_io_fcp_cmd(struct efct_io *io, struct fcp_cmnd *cmnd,
160 			 struct fc_frame_header *fchdr, bool sit)
161 {
162 	io->init_task_tag = be16_to_cpu(fchdr->fh_ox_id);
163 	/* note, tgt_task_tag, hw_tag  set when HW io is allocated */
164 	io->exp_xfer_len = be32_to_cpu(cmnd->fc_dl);
165 	io->transferred = 0;
166 
167 	/* The upper 7 bits of CS_CTL is the frame priority thru the SAN.
168 	 * Our assertion here is, the priority given to a frame containing
169 	 * the FCP cmd should be the priority given to ALL frames contained
170 	 * in that IO. Thus we need to save the incoming CS_CTL here.
171 	 */
172 	if (ntoh24(fchdr->fh_f_ctl) & FC_FC_RES_B17)
173 		io->cs_ctl = fchdr->fh_cs_ctl;
174 	else
175 		io->cs_ctl = 0;
176 
177 	io->seq_init = sit;
178 }
179 
180 static u32
181 efct_get_flags_fcp_cmd(struct fcp_cmnd *cmnd)
182 {
183 	u32 flags = 0;
184 
185 	switch (cmnd->fc_pri_ta & FCP_PTA_MASK) {
186 	case FCP_PTA_SIMPLE:
187 		flags |= EFCT_SCSI_CMD_SIMPLE;
188 		break;
189 	case FCP_PTA_HEADQ:
190 		flags |= EFCT_SCSI_CMD_HEAD_OF_QUEUE;
191 		break;
192 	case FCP_PTA_ORDERED:
193 		flags |= EFCT_SCSI_CMD_ORDERED;
194 		break;
195 	case FCP_PTA_ACA:
196 		flags |= EFCT_SCSI_CMD_ACA;
197 		break;
198 	}
199 	if (cmnd->fc_flags & FCP_CFL_WRDATA)
200 		flags |= EFCT_SCSI_CMD_DIR_IN;
201 	if (cmnd->fc_flags & FCP_CFL_RDDATA)
202 		flags |= EFCT_SCSI_CMD_DIR_OUT;
203 
204 	return flags;
205 }
206 
207 static void
208 efct_sframe_common_send_cb(void *arg, u8 *cqe, int status)
209 {
210 	struct efct_hw_send_frame_context *ctx = arg;
211 	struct efct_hw *hw = ctx->hw;
212 
213 	/* Free WQ completion callback */
214 	efct_hw_reqtag_free(hw, ctx->wqcb);
215 
216 	/* Free sequence */
217 	efct_hw_sequence_free(hw, ctx->seq);
218 }
219 
220 static int
221 efct_sframe_common_send(struct efct_node *node,
222 			struct efc_hw_sequence *seq,
223 			enum fc_rctl r_ctl, u32 f_ctl,
224 			u8 type, void *payload, u32 payload_len)
225 {
226 	struct efct *efct = node->efct;
227 	struct efct_hw *hw = &efct->hw;
228 	int rc = 0;
229 	struct fc_frame_header *req_hdr = seq->header->dma.virt;
230 	struct fc_frame_header hdr;
231 	struct efct_hw_send_frame_context *ctx;
232 
233 	u32 heap_size = seq->payload->dma.size;
234 	uintptr_t heap_phys_base = seq->payload->dma.phys;
235 	u8 *heap_virt_base = seq->payload->dma.virt;
236 	u32 heap_offset = 0;
237 
238 	/* Build the FC header reusing the RQ header DMA buffer */
239 	memset(&hdr, 0, sizeof(hdr));
240 	hdr.fh_r_ctl = r_ctl;
241 	/* send it back to whomever sent it to us */
242 	memcpy(hdr.fh_d_id, req_hdr->fh_s_id, sizeof(hdr.fh_d_id));
243 	memcpy(hdr.fh_s_id, req_hdr->fh_d_id, sizeof(hdr.fh_s_id));
244 	hdr.fh_type = type;
245 	hton24(hdr.fh_f_ctl, f_ctl);
246 	hdr.fh_ox_id = req_hdr->fh_ox_id;
247 	hdr.fh_rx_id = req_hdr->fh_rx_id;
248 	hdr.fh_cs_ctl = 0;
249 	hdr.fh_df_ctl = 0;
250 	hdr.fh_seq_cnt = 0;
251 	hdr.fh_parm_offset = 0;
252 
253 	/*
254 	 * send_frame_seq_id is an atomic, we just let it increment,
255 	 * while storing only the low 8 bits to hdr->seq_id
256 	 */
257 	hdr.fh_seq_id = (u8)atomic_add_return(1, &hw->send_frame_seq_id);
258 	hdr.fh_seq_id--;
259 
260 	/* Allocate and fill in the send frame request context */
261 	ctx = (void *)(heap_virt_base + heap_offset);
262 	heap_offset += sizeof(*ctx);
263 	if (heap_offset > heap_size) {
264 		efc_log_err(efct, "Fill send frame failed offset %d size %d\n",
265 			    heap_offset, heap_size);
266 		return -EIO;
267 	}
268 
269 	memset(ctx, 0, sizeof(*ctx));
270 
271 	/* Save sequence */
272 	ctx->seq = seq;
273 
274 	/* Allocate a response payload DMA buffer from the heap */
275 	ctx->payload.phys = heap_phys_base + heap_offset;
276 	ctx->payload.virt = heap_virt_base + heap_offset;
277 	ctx->payload.size = payload_len;
278 	ctx->payload.len = payload_len;
279 	heap_offset += payload_len;
280 	if (heap_offset > heap_size) {
281 		efc_log_err(efct, "Fill send frame failed offset %d size %d\n",
282 			    heap_offset, heap_size);
283 		return -EIO;
284 	}
285 
286 	/* Copy the payload in */
287 	memcpy(ctx->payload.virt, payload, payload_len);
288 
289 	/* Send */
290 	rc = efct_hw_send_frame(&efct->hw, (void *)&hdr, FC_SOF_N3,
291 				FC_EOF_T, &ctx->payload, ctx,
292 				efct_sframe_common_send_cb, ctx);
293 	if (rc)
294 		efc_log_debug(efct, "efct_hw_send_frame failed: %d\n", rc);
295 
296 	return rc;
297 }
298 
299 static int
300 efct_sframe_send_fcp_rsp(struct efct_node *node, struct efc_hw_sequence *seq,
301 			 void *rsp, u32 rsp_len)
302 {
303 	return efct_sframe_common_send(node, seq, FC_RCTL_DD_CMD_STATUS,
304 				      FC_FC_EX_CTX |
305 				      FC_FC_LAST_SEQ |
306 				      FC_FC_END_SEQ |
307 				      FC_FC_SEQ_INIT,
308 				      FC_TYPE_FCP,
309 				      rsp, rsp_len);
310 }
311 
312 static int
313 efct_sframe_send_task_set_full_or_busy(struct efct_node *node,
314 				       struct efc_hw_sequence *seq)
315 {
316 	struct fcp_resp_with_ext fcprsp;
317 	struct fcp_cmnd *fcpcmd = seq->payload->dma.virt;
318 	int rc = 0;
319 	unsigned long flags = 0;
320 	struct efct *efct = node->efct;
321 
322 	/* construct task set full or busy response */
323 	memset(&fcprsp, 0, sizeof(fcprsp));
324 	spin_lock_irqsave(&node->active_ios_lock, flags);
325 	fcprsp.resp.fr_status = list_empty(&node->active_ios) ?
326 				SAM_STAT_BUSY : SAM_STAT_TASK_SET_FULL;
327 	spin_unlock_irqrestore(&node->active_ios_lock, flags);
328 	*((u32 *)&fcprsp.ext.fr_resid) = be32_to_cpu(fcpcmd->fc_dl);
329 
330 	/* send it using send_frame */
331 	rc = efct_sframe_send_fcp_rsp(node, seq, &fcprsp, sizeof(fcprsp));
332 	if (rc)
333 		efc_log_debug(efct, "efct_sframe_send_fcp_rsp failed %d\n", rc);
334 
335 	return rc;
336 }
337 
338 int
339 efct_dispatch_fcp_cmd(struct efct_node *node, struct efc_hw_sequence *seq)
340 {
341 	struct efct *efct = node->efct;
342 	struct fc_frame_header *fchdr = seq->header->dma.virt;
343 	struct fcp_cmnd	*cmnd = NULL;
344 	struct efct_io *io = NULL;
345 	u32 lun;
346 
347 	if (!seq->payload) {
348 		efc_log_err(efct, "Sequence payload is NULL.\n");
349 		return -EIO;
350 	}
351 
352 	cmnd = seq->payload->dma.virt;
353 
354 	/* perform FCP_CMND validation check(s) */
355 	if (efct_validate_fcp_cmd(efct, seq))
356 		return -EIO;
357 
358 	lun = scsilun_to_int(&cmnd->fc_lun);
359 	if (lun == U32_MAX)
360 		return -EIO;
361 
362 	io = efct_scsi_io_alloc(node);
363 	if (!io) {
364 		int rc;
365 
366 		/* Use SEND_FRAME to send task set full or busy */
367 		rc = efct_sframe_send_task_set_full_or_busy(node, seq);
368 		if (rc)
369 			efc_log_err(efct, "Failed to send busy task: %d\n", rc);
370 
371 		return rc;
372 	}
373 
374 	io->hw_priv = seq->hw_priv;
375 
376 	io->app_id = 0;
377 
378 	/* RQ pair, if we got here, SIT=1 */
379 	efct_populate_io_fcp_cmd(io, cmnd, fchdr, true);
380 
381 	if (cmnd->fc_tm_flags) {
382 		efct_dispatch_unsol_tmf(io, cmnd->fc_tm_flags, lun);
383 	} else {
384 		u32 flags = efct_get_flags_fcp_cmd(cmnd);
385 
386 		if (cmnd->fc_flags & FCP_CFL_LEN_MASK) {
387 			efc_log_err(efct, "Additional CDB not supported\n");
388 			return -EIO;
389 		}
390 		/*
391 		 * Can return failure for things like task set full and UAs,
392 		 * no need to treat as a dropped frame if rc != 0
393 		 */
394 		efct_scsi_recv_cmd(io, lun, cmnd->fc_cdb,
395 				   sizeof(cmnd->fc_cdb), flags);
396 	}
397 
398 	return 0;
399 }
400 
401 static int
402 efct_process_abts(struct efct_io *io, struct fc_frame_header *hdr)
403 {
404 	struct efct_node *node = io->node;
405 	struct efct *efct = io->efct;
406 	u16 ox_id = be16_to_cpu(hdr->fh_ox_id);
407 	u16 rx_id = be16_to_cpu(hdr->fh_rx_id);
408 	struct efct_io *abortio;
409 
410 	/* Find IO and attempt to take a reference on it */
411 	abortio = efct_io_find_tgt_io(efct, node, ox_id, rx_id);
412 
413 	if (abortio) {
414 		/* Got a reference on the IO. Hold it until backend
415 		 * is notified below
416 		 */
417 		efc_log_info(node->efct, "Abort ox_id [%04x] rx_id [%04x]\n",
418 			     ox_id, rx_id);
419 
420 		/*
421 		 * Save the ox_id for the ABTS as the init_task_tag in our
422 		 * manufactured
423 		 * TMF IO object
424 		 */
425 		io->display_name = "abts";
426 		io->init_task_tag = ox_id;
427 		/* don't set tgt_task_tag, don't want to confuse with XRI */
428 
429 		/*
430 		 * Save the rx_id from the ABTS as it is
431 		 * needed for the BLS response,
432 		 * regardless of the IO context's rx_id
433 		 */
434 		io->abort_rx_id = rx_id;
435 
436 		/* Call target server command abort */
437 		io->tmf_cmd = EFCT_SCSI_TMF_ABORT_TASK;
438 		efct_scsi_recv_tmf(io, abortio->tgt_io.lun,
439 				   EFCT_SCSI_TMF_ABORT_TASK, abortio, 0);
440 
441 		/*
442 		 * Backend will have taken an additional
443 		 * reference on the IO if needed;
444 		 * done with current reference.
445 		 */
446 		kref_put(&abortio->ref, abortio->release);
447 	} else {
448 		/*
449 		 * Either IO was not found or it has been
450 		 * freed between finding it
451 		 * and attempting to get the reference,
452 		 */
453 		efc_log_info(node->efct, "Abort: ox_id [%04x], IO not found\n",
454 			     ox_id);
455 
456 		/* Send a BA_RJT */
457 		efct_bls_send_rjt(io, hdr);
458 	}
459 	return 0;
460 }
461 
462 int
463 efct_node_recv_abts_frame(struct efct_node *node, struct efc_hw_sequence *seq)
464 {
465 	struct efct *efct = node->efct;
466 	struct fc_frame_header *hdr = seq->header->dma.virt;
467 	struct efct_io *io = NULL;
468 
469 	node->abort_cnt++;
470 	io = efct_scsi_io_alloc(node);
471 	if (io) {
472 		io->hw_priv = seq->hw_priv;
473 		/* If we got this far, SIT=1 */
474 		io->seq_init = 1;
475 
476 		/* fill out generic fields */
477 		io->efct = efct;
478 		io->node = node;
479 		io->cmd_tgt = true;
480 
481 		efct_process_abts(io, seq->header->dma.virt);
482 	} else {
483 		efc_log_err(efct,
484 			    "SCSI IO allocation failed for ABTS received ");
485 		efc_log_err(efct, "s_id %06x d_id %06x ox_id %04x rx_id %04x\n",
486 			    ntoh24(hdr->fh_s_id), ntoh24(hdr->fh_d_id),
487 			    be16_to_cpu(hdr->fh_ox_id),
488 			    be16_to_cpu(hdr->fh_rx_id));
489 	}
490 
491 	return 0;
492 }
493