efct_unsol.c (12700B)
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 21static struct efct_node * 22efct_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 39static int 40efct_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 83int 84efct_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 97static int 98efct_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 106static void 107efct_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 137static int 138efct_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 158static void 159efct_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 180static u32 181efct_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 207static void 208efct_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 220static int 221efct_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 299static int 300efct_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 312static int 313efct_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 338int 339efct_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 401static int 402efct_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 462int 463efct_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}