1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. 4 * Copyright (c) 2014- QLogic Corporation. 5 * All rights reserved 6 * www.qlogic.com 7 * 8 * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. 9 */ 10 11 #include <linux/uaccess.h> 12 #include "bfad_drv.h" 13 #include "bfad_im.h" 14 #include "bfad_bsg.h" 15 16 BFA_TRC_FILE(LDRV, BSG); 17 18 static int 19 bfad_iocmd_ioc_enable(struct bfad_s *bfad, void *cmd) 20 { 21 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 22 unsigned long flags; 23 24 spin_lock_irqsave(&bfad->bfad_lock, flags); 25 /* If IOC is not in disabled state - return */ 26 if (!bfa_ioc_is_disabled(&bfad->bfa.ioc)) { 27 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 28 iocmd->status = BFA_STATUS_OK; 29 return 0; 30 } 31 32 init_completion(&bfad->enable_comp); 33 bfa_iocfc_enable(&bfad->bfa); 34 iocmd->status = BFA_STATUS_OK; 35 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 36 wait_for_completion(&bfad->enable_comp); 37 38 return 0; 39 } 40 41 static int 42 bfad_iocmd_ioc_disable(struct bfad_s *bfad, void *cmd) 43 { 44 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 45 unsigned long flags; 46 47 spin_lock_irqsave(&bfad->bfad_lock, flags); 48 if (bfa_ioc_is_disabled(&bfad->bfa.ioc)) { 49 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 50 iocmd->status = BFA_STATUS_OK; 51 return 0; 52 } 53 54 if (bfad->disable_active) { 55 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 56 return -EBUSY; 57 } 58 59 bfad->disable_active = BFA_TRUE; 60 init_completion(&bfad->disable_comp); 61 bfa_iocfc_disable(&bfad->bfa); 62 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 63 64 wait_for_completion(&bfad->disable_comp); 65 bfad->disable_active = BFA_FALSE; 66 iocmd->status = BFA_STATUS_OK; 67 68 return 0; 69 } 70 71 static int 72 bfad_iocmd_ioc_get_info(struct bfad_s *bfad, void *cmd) 73 { 74 int i; 75 struct bfa_bsg_ioc_info_s *iocmd = (struct bfa_bsg_ioc_info_s *)cmd; 76 struct bfad_im_port_s *im_port; 77 struct bfa_port_attr_s pattr; 78 unsigned long flags; 79 80 spin_lock_irqsave(&bfad->bfad_lock, flags); 81 bfa_fcport_get_attr(&bfad->bfa, &pattr); 82 iocmd->nwwn = pattr.nwwn; 83 iocmd->pwwn = pattr.pwwn; 84 iocmd->ioc_type = bfa_get_type(&bfad->bfa); 85 iocmd->mac = bfa_get_mac(&bfad->bfa); 86 iocmd->factory_mac = bfa_get_mfg_mac(&bfad->bfa); 87 bfa_get_adapter_serial_num(&bfad->bfa, iocmd->serialnum); 88 iocmd->factorynwwn = pattr.factorynwwn; 89 iocmd->factorypwwn = pattr.factorypwwn; 90 iocmd->bfad_num = bfad->inst_no; 91 im_port = bfad->pport.im_port; 92 iocmd->host = im_port->shost->host_no; 93 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 94 95 strcpy(iocmd->name, bfad->adapter_name); 96 strcpy(iocmd->port_name, bfad->port_name); 97 strcpy(iocmd->hwpath, bfad->pci_name); 98 99 /* set adapter hw path */ 100 strcpy(iocmd->adapter_hwpath, bfad->pci_name); 101 for (i = 0; iocmd->adapter_hwpath[i] != ':' && i < BFA_STRING_32; i++) 102 ; 103 for (; iocmd->adapter_hwpath[++i] != ':' && i < BFA_STRING_32; ) 104 ; 105 iocmd->adapter_hwpath[i] = '\0'; 106 iocmd->status = BFA_STATUS_OK; 107 return 0; 108 } 109 110 static int 111 bfad_iocmd_ioc_get_attr(struct bfad_s *bfad, void *cmd) 112 { 113 struct bfa_bsg_ioc_attr_s *iocmd = (struct bfa_bsg_ioc_attr_s *)cmd; 114 unsigned long flags; 115 116 spin_lock_irqsave(&bfad->bfad_lock, flags); 117 bfa_ioc_get_attr(&bfad->bfa.ioc, &iocmd->ioc_attr); 118 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 119 120 /* fill in driver attr info */ 121 strcpy(iocmd->ioc_attr.driver_attr.driver, BFAD_DRIVER_NAME); 122 strscpy(iocmd->ioc_attr.driver_attr.driver_ver, 123 BFAD_DRIVER_VERSION, BFA_VERSION_LEN); 124 strcpy(iocmd->ioc_attr.driver_attr.fw_ver, 125 iocmd->ioc_attr.adapter_attr.fw_ver); 126 strcpy(iocmd->ioc_attr.driver_attr.bios_ver, 127 iocmd->ioc_attr.adapter_attr.optrom_ver); 128 129 /* copy chip rev info first otherwise it will be overwritten */ 130 memcpy(bfad->pci_attr.chip_rev, iocmd->ioc_attr.pci_attr.chip_rev, 131 sizeof(bfad->pci_attr.chip_rev)); 132 memcpy(&iocmd->ioc_attr.pci_attr, &bfad->pci_attr, 133 sizeof(struct bfa_ioc_pci_attr_s)); 134 135 iocmd->status = BFA_STATUS_OK; 136 return 0; 137 } 138 139 static int 140 bfad_iocmd_ioc_get_stats(struct bfad_s *bfad, void *cmd) 141 { 142 struct bfa_bsg_ioc_stats_s *iocmd = (struct bfa_bsg_ioc_stats_s *)cmd; 143 144 bfa_ioc_get_stats(&bfad->bfa, &iocmd->ioc_stats); 145 iocmd->status = BFA_STATUS_OK; 146 return 0; 147 } 148 149 static int 150 bfad_iocmd_ioc_get_fwstats(struct bfad_s *bfad, void *cmd, 151 unsigned int payload_len) 152 { 153 struct bfa_bsg_ioc_fwstats_s *iocmd = 154 (struct bfa_bsg_ioc_fwstats_s *)cmd; 155 void *iocmd_bufptr; 156 unsigned long flags; 157 158 if (bfad_chk_iocmd_sz(payload_len, 159 sizeof(struct bfa_bsg_ioc_fwstats_s), 160 sizeof(struct bfa_fw_stats_s)) != BFA_STATUS_OK) { 161 iocmd->status = BFA_STATUS_VERSION_FAIL; 162 goto out; 163 } 164 165 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_ioc_fwstats_s); 166 spin_lock_irqsave(&bfad->bfad_lock, flags); 167 iocmd->status = bfa_ioc_fw_stats_get(&bfad->bfa.ioc, iocmd_bufptr); 168 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 169 170 if (iocmd->status != BFA_STATUS_OK) { 171 bfa_trc(bfad, iocmd->status); 172 goto out; 173 } 174 out: 175 bfa_trc(bfad, 0x6666); 176 return 0; 177 } 178 179 static int 180 bfad_iocmd_ioc_reset_stats(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) 181 { 182 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 183 unsigned long flags; 184 185 if (v_cmd == IOCMD_IOC_RESET_STATS) { 186 bfa_ioc_clear_stats(&bfad->bfa); 187 iocmd->status = BFA_STATUS_OK; 188 } else if (v_cmd == IOCMD_IOC_RESET_FWSTATS) { 189 spin_lock_irqsave(&bfad->bfad_lock, flags); 190 iocmd->status = bfa_ioc_fw_stats_clear(&bfad->bfa.ioc); 191 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 192 } 193 194 return 0; 195 } 196 197 static int 198 bfad_iocmd_ioc_set_name(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) 199 { 200 struct bfa_bsg_ioc_name_s *iocmd = (struct bfa_bsg_ioc_name_s *) cmd; 201 202 if (v_cmd == IOCMD_IOC_SET_ADAPTER_NAME) 203 strcpy(bfad->adapter_name, iocmd->name); 204 else if (v_cmd == IOCMD_IOC_SET_PORT_NAME) 205 strcpy(bfad->port_name, iocmd->name); 206 207 iocmd->status = BFA_STATUS_OK; 208 return 0; 209 } 210 211 static int 212 bfad_iocmd_iocfc_get_attr(struct bfad_s *bfad, void *cmd) 213 { 214 struct bfa_bsg_iocfc_attr_s *iocmd = (struct bfa_bsg_iocfc_attr_s *)cmd; 215 216 iocmd->status = BFA_STATUS_OK; 217 bfa_iocfc_get_attr(&bfad->bfa, &iocmd->iocfc_attr); 218 219 return 0; 220 } 221 222 static int 223 bfad_iocmd_ioc_fw_sig_inv(struct bfad_s *bfad, void *cmd) 224 { 225 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 226 unsigned long flags; 227 228 spin_lock_irqsave(&bfad->bfad_lock, flags); 229 iocmd->status = bfa_ioc_fwsig_invalidate(&bfad->bfa.ioc); 230 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 231 return 0; 232 } 233 234 static int 235 bfad_iocmd_iocfc_set_intr(struct bfad_s *bfad, void *cmd) 236 { 237 struct bfa_bsg_iocfc_intr_s *iocmd = (struct bfa_bsg_iocfc_intr_s *)cmd; 238 unsigned long flags; 239 240 spin_lock_irqsave(&bfad->bfad_lock, flags); 241 iocmd->status = bfa_iocfc_israttr_set(&bfad->bfa, &iocmd->attr); 242 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 243 244 return 0; 245 } 246 247 static int 248 bfad_iocmd_port_enable(struct bfad_s *bfad, void *cmd) 249 { 250 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 251 struct bfad_hal_comp fcomp; 252 unsigned long flags; 253 254 init_completion(&fcomp.comp); 255 spin_lock_irqsave(&bfad->bfad_lock, flags); 256 iocmd->status = bfa_port_enable(&bfad->bfa.modules.port, 257 bfad_hcb_comp, &fcomp); 258 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 259 if (iocmd->status != BFA_STATUS_OK) { 260 bfa_trc(bfad, iocmd->status); 261 return 0; 262 } 263 wait_for_completion(&fcomp.comp); 264 iocmd->status = fcomp.status; 265 return 0; 266 } 267 268 static int 269 bfad_iocmd_port_disable(struct bfad_s *bfad, void *cmd) 270 { 271 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 272 struct bfad_hal_comp fcomp; 273 unsigned long flags; 274 275 init_completion(&fcomp.comp); 276 spin_lock_irqsave(&bfad->bfad_lock, flags); 277 iocmd->status = bfa_port_disable(&bfad->bfa.modules.port, 278 bfad_hcb_comp, &fcomp); 279 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 280 281 if (iocmd->status != BFA_STATUS_OK) { 282 bfa_trc(bfad, iocmd->status); 283 return 0; 284 } 285 wait_for_completion(&fcomp.comp); 286 iocmd->status = fcomp.status; 287 return 0; 288 } 289 290 static int 291 bfad_iocmd_port_get_attr(struct bfad_s *bfad, void *cmd) 292 { 293 struct bfa_bsg_port_attr_s *iocmd = (struct bfa_bsg_port_attr_s *)cmd; 294 struct bfa_lport_attr_s port_attr; 295 unsigned long flags; 296 297 spin_lock_irqsave(&bfad->bfad_lock, flags); 298 bfa_fcport_get_attr(&bfad->bfa, &iocmd->attr); 299 bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr); 300 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 301 302 if (iocmd->attr.topology != BFA_PORT_TOPOLOGY_NONE) 303 iocmd->attr.pid = port_attr.pid; 304 else 305 iocmd->attr.pid = 0; 306 307 iocmd->attr.port_type = port_attr.port_type; 308 iocmd->attr.loopback = port_attr.loopback; 309 iocmd->attr.authfail = port_attr.authfail; 310 strscpy(iocmd->attr.port_symname.symname, 311 port_attr.port_cfg.sym_name.symname, 312 sizeof(iocmd->attr.port_symname.symname)); 313 314 iocmd->status = BFA_STATUS_OK; 315 return 0; 316 } 317 318 static int 319 bfad_iocmd_port_get_stats(struct bfad_s *bfad, void *cmd, 320 unsigned int payload_len) 321 { 322 struct bfa_bsg_port_stats_s *iocmd = (struct bfa_bsg_port_stats_s *)cmd; 323 struct bfad_hal_comp fcomp; 324 void *iocmd_bufptr; 325 unsigned long flags; 326 327 if (bfad_chk_iocmd_sz(payload_len, 328 sizeof(struct bfa_bsg_port_stats_s), 329 sizeof(union bfa_port_stats_u)) != BFA_STATUS_OK) { 330 iocmd->status = BFA_STATUS_VERSION_FAIL; 331 return 0; 332 } 333 334 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_port_stats_s); 335 336 init_completion(&fcomp.comp); 337 spin_lock_irqsave(&bfad->bfad_lock, flags); 338 iocmd->status = bfa_port_get_stats(&bfad->bfa.modules.port, 339 iocmd_bufptr, bfad_hcb_comp, &fcomp); 340 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 341 if (iocmd->status != BFA_STATUS_OK) { 342 bfa_trc(bfad, iocmd->status); 343 goto out; 344 } 345 346 wait_for_completion(&fcomp.comp); 347 iocmd->status = fcomp.status; 348 out: 349 return 0; 350 } 351 352 static int 353 bfad_iocmd_port_reset_stats(struct bfad_s *bfad, void *cmd) 354 { 355 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 356 struct bfad_hal_comp fcomp; 357 unsigned long flags; 358 359 init_completion(&fcomp.comp); 360 spin_lock_irqsave(&bfad->bfad_lock, flags); 361 iocmd->status = bfa_port_clear_stats(&bfad->bfa.modules.port, 362 bfad_hcb_comp, &fcomp); 363 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 364 if (iocmd->status != BFA_STATUS_OK) { 365 bfa_trc(bfad, iocmd->status); 366 return 0; 367 } 368 wait_for_completion(&fcomp.comp); 369 iocmd->status = fcomp.status; 370 return 0; 371 } 372 373 static int 374 bfad_iocmd_set_port_cfg(struct bfad_s *bfad, void *iocmd, unsigned int v_cmd) 375 { 376 struct bfa_bsg_port_cfg_s *cmd = (struct bfa_bsg_port_cfg_s *)iocmd; 377 unsigned long flags; 378 379 spin_lock_irqsave(&bfad->bfad_lock, flags); 380 if (v_cmd == IOCMD_PORT_CFG_TOPO) 381 cmd->status = bfa_fcport_cfg_topology(&bfad->bfa, cmd->param); 382 else if (v_cmd == IOCMD_PORT_CFG_SPEED) 383 cmd->status = bfa_fcport_cfg_speed(&bfad->bfa, cmd->param); 384 else if (v_cmd == IOCMD_PORT_CFG_ALPA) 385 cmd->status = bfa_fcport_cfg_hardalpa(&bfad->bfa, cmd->param); 386 else if (v_cmd == IOCMD_PORT_CLR_ALPA) 387 cmd->status = bfa_fcport_clr_hardalpa(&bfad->bfa); 388 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 389 390 return 0; 391 } 392 393 static int 394 bfad_iocmd_port_cfg_maxfrsize(struct bfad_s *bfad, void *cmd) 395 { 396 struct bfa_bsg_port_cfg_maxfrsize_s *iocmd = 397 (struct bfa_bsg_port_cfg_maxfrsize_s *)cmd; 398 unsigned long flags; 399 400 spin_lock_irqsave(&bfad->bfad_lock, flags); 401 iocmd->status = bfa_fcport_cfg_maxfrsize(&bfad->bfa, iocmd->maxfrsize); 402 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 403 404 return 0; 405 } 406 407 static int 408 bfad_iocmd_port_cfg_bbcr(struct bfad_s *bfad, unsigned int cmd, void *pcmd) 409 { 410 struct bfa_bsg_bbcr_enable_s *iocmd = 411 (struct bfa_bsg_bbcr_enable_s *)pcmd; 412 unsigned long flags; 413 int rc; 414 415 spin_lock_irqsave(&bfad->bfad_lock, flags); 416 if (cmd == IOCMD_PORT_BBCR_ENABLE) 417 rc = bfa_fcport_cfg_bbcr(&bfad->bfa, BFA_TRUE, iocmd->bb_scn); 418 else if (cmd == IOCMD_PORT_BBCR_DISABLE) 419 rc = bfa_fcport_cfg_bbcr(&bfad->bfa, BFA_FALSE, 0); 420 else { 421 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 422 return -EINVAL; 423 } 424 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 425 426 iocmd->status = rc; 427 return 0; 428 } 429 430 static int 431 bfad_iocmd_port_get_bbcr_attr(struct bfad_s *bfad, void *pcmd) 432 { 433 struct bfa_bsg_bbcr_attr_s *iocmd = (struct bfa_bsg_bbcr_attr_s *) pcmd; 434 unsigned long flags; 435 436 spin_lock_irqsave(&bfad->bfad_lock, flags); 437 iocmd->status = 438 bfa_fcport_get_bbcr_attr(&bfad->bfa, &iocmd->attr); 439 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 440 441 return 0; 442 } 443 444 445 static int 446 bfad_iocmd_lport_get_attr(struct bfad_s *bfad, void *cmd) 447 { 448 struct bfa_fcs_lport_s *fcs_port; 449 struct bfa_bsg_lport_attr_s *iocmd = (struct bfa_bsg_lport_attr_s *)cmd; 450 unsigned long flags; 451 452 spin_lock_irqsave(&bfad->bfad_lock, flags); 453 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, 454 iocmd->vf_id, iocmd->pwwn); 455 if (fcs_port == NULL) { 456 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 457 iocmd->status = BFA_STATUS_UNKNOWN_LWWN; 458 goto out; 459 } 460 461 bfa_fcs_lport_get_attr(fcs_port, &iocmd->port_attr); 462 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 463 iocmd->status = BFA_STATUS_OK; 464 out: 465 return 0; 466 } 467 468 static int 469 bfad_iocmd_lport_get_stats(struct bfad_s *bfad, void *cmd) 470 { 471 struct bfa_fcs_lport_s *fcs_port; 472 struct bfa_bsg_lport_stats_s *iocmd = 473 (struct bfa_bsg_lport_stats_s *)cmd; 474 unsigned long flags; 475 476 spin_lock_irqsave(&bfad->bfad_lock, flags); 477 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, 478 iocmd->vf_id, iocmd->pwwn); 479 if (fcs_port == NULL) { 480 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 481 iocmd->status = BFA_STATUS_UNKNOWN_LWWN; 482 goto out; 483 } 484 485 bfa_fcs_lport_get_stats(fcs_port, &iocmd->port_stats); 486 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 487 iocmd->status = BFA_STATUS_OK; 488 out: 489 return 0; 490 } 491 492 static int 493 bfad_iocmd_lport_reset_stats(struct bfad_s *bfad, void *cmd) 494 { 495 struct bfa_fcs_lport_s *fcs_port; 496 struct bfa_bsg_reset_stats_s *iocmd = 497 (struct bfa_bsg_reset_stats_s *)cmd; 498 struct bfa_fcpim_s *fcpim = BFA_FCPIM(&bfad->bfa); 499 struct list_head *qe, *qen; 500 struct bfa_itnim_s *itnim; 501 unsigned long flags; 502 503 spin_lock_irqsave(&bfad->bfad_lock, flags); 504 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, 505 iocmd->vf_id, iocmd->vpwwn); 506 if (fcs_port == NULL) { 507 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 508 iocmd->status = BFA_STATUS_UNKNOWN_LWWN; 509 goto out; 510 } 511 512 bfa_fcs_lport_clear_stats(fcs_port); 513 /* clear IO stats from all active itnims */ 514 list_for_each_safe(qe, qen, &fcpim->itnim_q) { 515 itnim = (struct bfa_itnim_s *) qe; 516 if (itnim->rport->rport_info.lp_tag != fcs_port->lp_tag) 517 continue; 518 bfa_itnim_clear_stats(itnim); 519 } 520 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 521 iocmd->status = BFA_STATUS_OK; 522 out: 523 return 0; 524 } 525 526 static int 527 bfad_iocmd_lport_get_iostats(struct bfad_s *bfad, void *cmd) 528 { 529 struct bfa_fcs_lport_s *fcs_port; 530 struct bfa_bsg_lport_iostats_s *iocmd = 531 (struct bfa_bsg_lport_iostats_s *)cmd; 532 unsigned long flags; 533 534 spin_lock_irqsave(&bfad->bfad_lock, flags); 535 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, 536 iocmd->vf_id, iocmd->pwwn); 537 if (fcs_port == NULL) { 538 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 539 iocmd->status = BFA_STATUS_UNKNOWN_LWWN; 540 goto out; 541 } 542 543 bfa_fcpim_port_iostats(&bfad->bfa, &iocmd->iostats, 544 fcs_port->lp_tag); 545 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 546 iocmd->status = BFA_STATUS_OK; 547 out: 548 return 0; 549 } 550 551 static int 552 bfad_iocmd_lport_get_rports(struct bfad_s *bfad, void *cmd, 553 unsigned int payload_len) 554 { 555 struct bfa_bsg_lport_get_rports_s *iocmd = 556 (struct bfa_bsg_lport_get_rports_s *)cmd; 557 struct bfa_fcs_lport_s *fcs_port; 558 unsigned long flags; 559 void *iocmd_bufptr; 560 561 if (iocmd->nrports == 0) 562 return -EINVAL; 563 564 if (bfad_chk_iocmd_sz(payload_len, 565 sizeof(struct bfa_bsg_lport_get_rports_s), 566 sizeof(struct bfa_rport_qualifier_s) * iocmd->nrports) 567 != BFA_STATUS_OK) { 568 iocmd->status = BFA_STATUS_VERSION_FAIL; 569 return 0; 570 } 571 572 iocmd_bufptr = (char *)iocmd + 573 sizeof(struct bfa_bsg_lport_get_rports_s); 574 spin_lock_irqsave(&bfad->bfad_lock, flags); 575 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, 576 iocmd->vf_id, iocmd->pwwn); 577 if (fcs_port == NULL) { 578 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 579 bfa_trc(bfad, 0); 580 iocmd->status = BFA_STATUS_UNKNOWN_LWWN; 581 goto out; 582 } 583 584 bfa_fcs_lport_get_rport_quals(fcs_port, 585 (struct bfa_rport_qualifier_s *)iocmd_bufptr, 586 &iocmd->nrports); 587 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 588 iocmd->status = BFA_STATUS_OK; 589 out: 590 return 0; 591 } 592 593 static int 594 bfad_iocmd_rport_get_attr(struct bfad_s *bfad, void *cmd) 595 { 596 struct bfa_bsg_rport_attr_s *iocmd = (struct bfa_bsg_rport_attr_s *)cmd; 597 struct bfa_fcs_lport_s *fcs_port; 598 struct bfa_fcs_rport_s *fcs_rport; 599 unsigned long flags; 600 601 spin_lock_irqsave(&bfad->bfad_lock, flags); 602 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, 603 iocmd->vf_id, iocmd->pwwn); 604 if (fcs_port == NULL) { 605 bfa_trc(bfad, 0); 606 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 607 iocmd->status = BFA_STATUS_UNKNOWN_LWWN; 608 goto out; 609 } 610 611 if (iocmd->pid) 612 fcs_rport = bfa_fcs_lport_get_rport_by_qualifier(fcs_port, 613 iocmd->rpwwn, iocmd->pid); 614 else 615 fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn); 616 if (fcs_rport == NULL) { 617 bfa_trc(bfad, 0); 618 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 619 iocmd->status = BFA_STATUS_UNKNOWN_RWWN; 620 goto out; 621 } 622 623 bfa_fcs_rport_get_attr(fcs_rport, &iocmd->attr); 624 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 625 iocmd->status = BFA_STATUS_OK; 626 out: 627 return 0; 628 } 629 630 static int 631 bfad_iocmd_rport_get_addr(struct bfad_s *bfad, void *cmd) 632 { 633 struct bfa_bsg_rport_scsi_addr_s *iocmd = 634 (struct bfa_bsg_rport_scsi_addr_s *)cmd; 635 struct bfa_fcs_lport_s *fcs_port; 636 struct bfa_fcs_itnim_s *fcs_itnim; 637 struct bfad_itnim_s *drv_itnim; 638 unsigned long flags; 639 640 spin_lock_irqsave(&bfad->bfad_lock, flags); 641 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, 642 iocmd->vf_id, iocmd->pwwn); 643 if (fcs_port == NULL) { 644 bfa_trc(bfad, 0); 645 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 646 iocmd->status = BFA_STATUS_UNKNOWN_LWWN; 647 goto out; 648 } 649 650 fcs_itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn); 651 if (fcs_itnim == NULL) { 652 bfa_trc(bfad, 0); 653 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 654 iocmd->status = BFA_STATUS_UNKNOWN_RWWN; 655 goto out; 656 } 657 658 drv_itnim = fcs_itnim->itnim_drv; 659 660 if (drv_itnim && drv_itnim->im_port) 661 iocmd->host = drv_itnim->im_port->shost->host_no; 662 else { 663 bfa_trc(bfad, 0); 664 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 665 iocmd->status = BFA_STATUS_UNKNOWN_RWWN; 666 goto out; 667 } 668 669 iocmd->target = drv_itnim->scsi_tgt_id; 670 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 671 672 iocmd->bus = 0; 673 iocmd->lun = 0; 674 iocmd->status = BFA_STATUS_OK; 675 out: 676 return 0; 677 } 678 679 static int 680 bfad_iocmd_rport_get_stats(struct bfad_s *bfad, void *cmd) 681 { 682 struct bfa_bsg_rport_stats_s *iocmd = 683 (struct bfa_bsg_rport_stats_s *)cmd; 684 struct bfa_fcs_lport_s *fcs_port; 685 struct bfa_fcs_rport_s *fcs_rport; 686 unsigned long flags; 687 688 spin_lock_irqsave(&bfad->bfad_lock, flags); 689 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, 690 iocmd->vf_id, iocmd->pwwn); 691 if (fcs_port == NULL) { 692 bfa_trc(bfad, 0); 693 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 694 iocmd->status = BFA_STATUS_UNKNOWN_LWWN; 695 goto out; 696 } 697 698 fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn); 699 if (fcs_rport == NULL) { 700 bfa_trc(bfad, 0); 701 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 702 iocmd->status = BFA_STATUS_UNKNOWN_RWWN; 703 goto out; 704 } 705 706 memcpy((void *)&iocmd->stats, (void *)&fcs_rport->stats, 707 sizeof(struct bfa_rport_stats_s)); 708 if (bfa_fcs_rport_get_halrport(fcs_rport)) { 709 memcpy((void *)&iocmd->stats.hal_stats, 710 (void *)&(bfa_fcs_rport_get_halrport(fcs_rport)->stats), 711 sizeof(struct bfa_rport_hal_stats_s)); 712 } 713 714 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 715 iocmd->status = BFA_STATUS_OK; 716 out: 717 return 0; 718 } 719 720 static int 721 bfad_iocmd_rport_clr_stats(struct bfad_s *bfad, void *cmd) 722 { 723 struct bfa_bsg_rport_reset_stats_s *iocmd = 724 (struct bfa_bsg_rport_reset_stats_s *)cmd; 725 struct bfa_fcs_lport_s *fcs_port; 726 struct bfa_fcs_rport_s *fcs_rport; 727 struct bfa_rport_s *rport; 728 unsigned long flags; 729 730 spin_lock_irqsave(&bfad->bfad_lock, flags); 731 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, 732 iocmd->vf_id, iocmd->pwwn); 733 if (fcs_port == NULL) { 734 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 735 iocmd->status = BFA_STATUS_UNKNOWN_LWWN; 736 goto out; 737 } 738 739 fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn); 740 if (fcs_rport == NULL) { 741 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 742 iocmd->status = BFA_STATUS_UNKNOWN_RWWN; 743 goto out; 744 } 745 746 memset((char *)&fcs_rport->stats, 0, sizeof(struct bfa_rport_stats_s)); 747 rport = bfa_fcs_rport_get_halrport(fcs_rport); 748 if (rport) 749 memset(&rport->stats, 0, sizeof(rport->stats)); 750 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 751 iocmd->status = BFA_STATUS_OK; 752 out: 753 return 0; 754 } 755 756 static int 757 bfad_iocmd_rport_set_speed(struct bfad_s *bfad, void *cmd) 758 { 759 struct bfa_bsg_rport_set_speed_s *iocmd = 760 (struct bfa_bsg_rport_set_speed_s *)cmd; 761 struct bfa_fcs_lport_s *fcs_port; 762 struct bfa_fcs_rport_s *fcs_rport; 763 unsigned long flags; 764 765 spin_lock_irqsave(&bfad->bfad_lock, flags); 766 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, 767 iocmd->vf_id, iocmd->pwwn); 768 if (fcs_port == NULL) { 769 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 770 iocmd->status = BFA_STATUS_UNKNOWN_LWWN; 771 goto out; 772 } 773 774 fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn); 775 if (fcs_rport == NULL) { 776 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 777 iocmd->status = BFA_STATUS_UNKNOWN_RWWN; 778 goto out; 779 } 780 781 fcs_rport->rpf.assigned_speed = iocmd->speed; 782 /* Set this speed in f/w only if the RPSC speed is not available */ 783 if (fcs_rport->rpf.rpsc_speed == BFA_PORT_SPEED_UNKNOWN) 784 if (fcs_rport->bfa_rport) 785 bfa_rport_speed(fcs_rport->bfa_rport, iocmd->speed); 786 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 787 iocmd->status = BFA_STATUS_OK; 788 out: 789 return 0; 790 } 791 792 static int 793 bfad_iocmd_vport_get_attr(struct bfad_s *bfad, void *cmd) 794 { 795 struct bfa_fcs_vport_s *fcs_vport; 796 struct bfa_bsg_vport_attr_s *iocmd = (struct bfa_bsg_vport_attr_s *)cmd; 797 unsigned long flags; 798 799 spin_lock_irqsave(&bfad->bfad_lock, flags); 800 fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 801 iocmd->vf_id, iocmd->vpwwn); 802 if (fcs_vport == NULL) { 803 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 804 iocmd->status = BFA_STATUS_UNKNOWN_VWWN; 805 goto out; 806 } 807 808 bfa_fcs_vport_get_attr(fcs_vport, &iocmd->vport_attr); 809 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 810 iocmd->status = BFA_STATUS_OK; 811 out: 812 return 0; 813 } 814 815 static int 816 bfad_iocmd_vport_get_stats(struct bfad_s *bfad, void *cmd) 817 { 818 struct bfa_fcs_vport_s *fcs_vport; 819 struct bfa_bsg_vport_stats_s *iocmd = 820 (struct bfa_bsg_vport_stats_s *)cmd; 821 unsigned long flags; 822 823 spin_lock_irqsave(&bfad->bfad_lock, flags); 824 fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 825 iocmd->vf_id, iocmd->vpwwn); 826 if (fcs_vport == NULL) { 827 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 828 iocmd->status = BFA_STATUS_UNKNOWN_VWWN; 829 goto out; 830 } 831 832 memcpy((void *)&iocmd->vport_stats, (void *)&fcs_vport->vport_stats, 833 sizeof(struct bfa_vport_stats_s)); 834 memcpy((void *)&iocmd->vport_stats.port_stats, 835 (void *)&fcs_vport->lport.stats, 836 sizeof(struct bfa_lport_stats_s)); 837 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 838 iocmd->status = BFA_STATUS_OK; 839 out: 840 return 0; 841 } 842 843 static int 844 bfad_iocmd_vport_clr_stats(struct bfad_s *bfad, void *cmd) 845 { 846 struct bfa_fcs_vport_s *fcs_vport; 847 struct bfa_bsg_reset_stats_s *iocmd = 848 (struct bfa_bsg_reset_stats_s *)cmd; 849 unsigned long flags; 850 851 spin_lock_irqsave(&bfad->bfad_lock, flags); 852 fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 853 iocmd->vf_id, iocmd->vpwwn); 854 if (fcs_vport == NULL) { 855 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 856 iocmd->status = BFA_STATUS_UNKNOWN_VWWN; 857 goto out; 858 } 859 860 memset(&fcs_vport->vport_stats, 0, sizeof(struct bfa_vport_stats_s)); 861 memset(&fcs_vport->lport.stats, 0, sizeof(struct bfa_lport_stats_s)); 862 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 863 iocmd->status = BFA_STATUS_OK; 864 out: 865 return 0; 866 } 867 868 static int 869 bfad_iocmd_fabric_get_lports(struct bfad_s *bfad, void *cmd, 870 unsigned int payload_len) 871 { 872 struct bfa_bsg_fabric_get_lports_s *iocmd = 873 (struct bfa_bsg_fabric_get_lports_s *)cmd; 874 bfa_fcs_vf_t *fcs_vf; 875 uint32_t nports = iocmd->nports; 876 unsigned long flags; 877 void *iocmd_bufptr; 878 879 if (nports == 0) { 880 iocmd->status = BFA_STATUS_EINVAL; 881 goto out; 882 } 883 884 if (bfad_chk_iocmd_sz(payload_len, 885 sizeof(struct bfa_bsg_fabric_get_lports_s), 886 sizeof(wwn_t) * iocmd->nports) != BFA_STATUS_OK) { 887 iocmd->status = BFA_STATUS_VERSION_FAIL; 888 goto out; 889 } 890 891 iocmd_bufptr = (char *)iocmd + 892 sizeof(struct bfa_bsg_fabric_get_lports_s); 893 894 spin_lock_irqsave(&bfad->bfad_lock, flags); 895 fcs_vf = bfa_fcs_vf_lookup(&bfad->bfa_fcs, iocmd->vf_id); 896 if (fcs_vf == NULL) { 897 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 898 iocmd->status = BFA_STATUS_UNKNOWN_VFID; 899 goto out; 900 } 901 bfa_fcs_vf_get_ports(fcs_vf, (wwn_t *)iocmd_bufptr, &nports); 902 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 903 904 iocmd->nports = nports; 905 iocmd->status = BFA_STATUS_OK; 906 out: 907 return 0; 908 } 909 910 static int 911 bfad_iocmd_qos_set_bw(struct bfad_s *bfad, void *pcmd) 912 { 913 struct bfa_bsg_qos_bw_s *iocmd = (struct bfa_bsg_qos_bw_s *)pcmd; 914 unsigned long flags; 915 916 spin_lock_irqsave(&bfad->bfad_lock, flags); 917 iocmd->status = bfa_fcport_set_qos_bw(&bfad->bfa, &iocmd->qos_bw); 918 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 919 920 return 0; 921 } 922 923 static int 924 bfad_iocmd_ratelim(struct bfad_s *bfad, unsigned int cmd, void *pcmd) 925 { 926 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; 927 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 928 unsigned long flags; 929 930 spin_lock_irqsave(&bfad->bfad_lock, flags); 931 932 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 933 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 934 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 935 else { 936 if (cmd == IOCMD_RATELIM_ENABLE) 937 fcport->cfg.ratelimit = BFA_TRUE; 938 else if (cmd == IOCMD_RATELIM_DISABLE) 939 fcport->cfg.ratelimit = BFA_FALSE; 940 941 if (fcport->cfg.trl_def_speed == BFA_PORT_SPEED_UNKNOWN) 942 fcport->cfg.trl_def_speed = BFA_PORT_SPEED_1GBPS; 943 944 iocmd->status = BFA_STATUS_OK; 945 } 946 947 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 948 949 return 0; 950 } 951 952 static int 953 bfad_iocmd_ratelim_speed(struct bfad_s *bfad, unsigned int cmd, void *pcmd) 954 { 955 struct bfa_bsg_trl_speed_s *iocmd = (struct bfa_bsg_trl_speed_s *)pcmd; 956 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 957 unsigned long flags; 958 959 spin_lock_irqsave(&bfad->bfad_lock, flags); 960 961 /* Auto and speeds greater than the supported speed, are invalid */ 962 if ((iocmd->speed == BFA_PORT_SPEED_AUTO) || 963 (iocmd->speed > fcport->speed_sup)) { 964 iocmd->status = BFA_STATUS_UNSUPP_SPEED; 965 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 966 return 0; 967 } 968 969 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 970 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 971 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 972 else { 973 fcport->cfg.trl_def_speed = iocmd->speed; 974 iocmd->status = BFA_STATUS_OK; 975 } 976 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 977 978 return 0; 979 } 980 981 static int 982 bfad_iocmd_cfg_fcpim(struct bfad_s *bfad, void *cmd) 983 { 984 struct bfa_bsg_fcpim_s *iocmd = (struct bfa_bsg_fcpim_s *)cmd; 985 unsigned long flags; 986 987 spin_lock_irqsave(&bfad->bfad_lock, flags); 988 bfa_fcpim_path_tov_set(&bfad->bfa, iocmd->param); 989 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 990 iocmd->status = BFA_STATUS_OK; 991 return 0; 992 } 993 994 static int 995 bfad_iocmd_fcpim_get_modstats(struct bfad_s *bfad, void *cmd) 996 { 997 struct bfa_bsg_fcpim_modstats_s *iocmd = 998 (struct bfa_bsg_fcpim_modstats_s *)cmd; 999 struct bfa_fcpim_s *fcpim = BFA_FCPIM(&bfad->bfa); 1000 struct list_head *qe, *qen; 1001 struct bfa_itnim_s *itnim; 1002 unsigned long flags; 1003 1004 spin_lock_irqsave(&bfad->bfad_lock, flags); 1005 /* accumulate IO stats from itnim */ 1006 memset((void *)&iocmd->modstats, 0, sizeof(struct bfa_itnim_iostats_s)); 1007 list_for_each_safe(qe, qen, &fcpim->itnim_q) { 1008 itnim = (struct bfa_itnim_s *) qe; 1009 bfa_fcpim_add_stats(&iocmd->modstats, &(itnim->stats)); 1010 } 1011 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1012 iocmd->status = BFA_STATUS_OK; 1013 return 0; 1014 } 1015 1016 static int 1017 bfad_iocmd_fcpim_clr_modstats(struct bfad_s *bfad, void *cmd) 1018 { 1019 struct bfa_bsg_fcpim_modstatsclr_s *iocmd = 1020 (struct bfa_bsg_fcpim_modstatsclr_s *)cmd; 1021 struct bfa_fcpim_s *fcpim = BFA_FCPIM(&bfad->bfa); 1022 struct list_head *qe, *qen; 1023 struct bfa_itnim_s *itnim; 1024 unsigned long flags; 1025 1026 spin_lock_irqsave(&bfad->bfad_lock, flags); 1027 list_for_each_safe(qe, qen, &fcpim->itnim_q) { 1028 itnim = (struct bfa_itnim_s *) qe; 1029 bfa_itnim_clear_stats(itnim); 1030 } 1031 memset(&fcpim->del_itn_stats, 0, 1032 sizeof(struct bfa_fcpim_del_itn_stats_s)); 1033 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1034 iocmd->status = BFA_STATUS_OK; 1035 return 0; 1036 } 1037 1038 static int 1039 bfad_iocmd_fcpim_get_del_itn_stats(struct bfad_s *bfad, void *cmd) 1040 { 1041 struct bfa_bsg_fcpim_del_itn_stats_s *iocmd = 1042 (struct bfa_bsg_fcpim_del_itn_stats_s *)cmd; 1043 struct bfa_fcpim_s *fcpim = BFA_FCPIM(&bfad->bfa); 1044 unsigned long flags; 1045 1046 spin_lock_irqsave(&bfad->bfad_lock, flags); 1047 memcpy((void *)&iocmd->modstats, (void *)&fcpim->del_itn_stats, 1048 sizeof(struct bfa_fcpim_del_itn_stats_s)); 1049 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1050 1051 iocmd->status = BFA_STATUS_OK; 1052 return 0; 1053 } 1054 1055 static int 1056 bfad_iocmd_itnim_get_attr(struct bfad_s *bfad, void *cmd) 1057 { 1058 struct bfa_bsg_itnim_attr_s *iocmd = (struct bfa_bsg_itnim_attr_s *)cmd; 1059 struct bfa_fcs_lport_s *fcs_port; 1060 unsigned long flags; 1061 1062 spin_lock_irqsave(&bfad->bfad_lock, flags); 1063 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, 1064 iocmd->vf_id, iocmd->lpwwn); 1065 if (!fcs_port) 1066 iocmd->status = BFA_STATUS_UNKNOWN_LWWN; 1067 else 1068 iocmd->status = bfa_fcs_itnim_attr_get(fcs_port, 1069 iocmd->rpwwn, &iocmd->attr); 1070 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1071 return 0; 1072 } 1073 1074 static int 1075 bfad_iocmd_itnim_get_iostats(struct bfad_s *bfad, void *cmd) 1076 { 1077 struct bfa_bsg_itnim_iostats_s *iocmd = 1078 (struct bfa_bsg_itnim_iostats_s *)cmd; 1079 struct bfa_fcs_lport_s *fcs_port; 1080 struct bfa_fcs_itnim_s *itnim; 1081 unsigned long flags; 1082 1083 spin_lock_irqsave(&bfad->bfad_lock, flags); 1084 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, 1085 iocmd->vf_id, iocmd->lpwwn); 1086 if (!fcs_port) { 1087 iocmd->status = BFA_STATUS_UNKNOWN_LWWN; 1088 bfa_trc(bfad, 0); 1089 } else { 1090 itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn); 1091 if (itnim == NULL) 1092 iocmd->status = BFA_STATUS_UNKNOWN_RWWN; 1093 else { 1094 iocmd->status = BFA_STATUS_OK; 1095 if (bfa_fcs_itnim_get_halitn(itnim)) 1096 memcpy((void *)&iocmd->iostats, (void *) 1097 &(bfa_fcs_itnim_get_halitn(itnim)->stats), 1098 sizeof(struct bfa_itnim_iostats_s)); 1099 } 1100 } 1101 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1102 return 0; 1103 } 1104 1105 static int 1106 bfad_iocmd_itnim_reset_stats(struct bfad_s *bfad, void *cmd) 1107 { 1108 struct bfa_bsg_rport_reset_stats_s *iocmd = 1109 (struct bfa_bsg_rport_reset_stats_s *)cmd; 1110 struct bfa_fcs_lport_s *fcs_port; 1111 struct bfa_fcs_itnim_s *itnim; 1112 unsigned long flags; 1113 1114 spin_lock_irqsave(&bfad->bfad_lock, flags); 1115 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, 1116 iocmd->vf_id, iocmd->pwwn); 1117 if (!fcs_port) 1118 iocmd->status = BFA_STATUS_UNKNOWN_LWWN; 1119 else { 1120 itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn); 1121 if (itnim == NULL) 1122 iocmd->status = BFA_STATUS_UNKNOWN_RWWN; 1123 else { 1124 iocmd->status = BFA_STATUS_OK; 1125 bfa_fcs_itnim_stats_clear(fcs_port, iocmd->rpwwn); 1126 bfa_itnim_clear_stats(bfa_fcs_itnim_get_halitn(itnim)); 1127 } 1128 } 1129 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1130 1131 return 0; 1132 } 1133 1134 static int 1135 bfad_iocmd_itnim_get_itnstats(struct bfad_s *bfad, void *cmd) 1136 { 1137 struct bfa_bsg_itnim_itnstats_s *iocmd = 1138 (struct bfa_bsg_itnim_itnstats_s *)cmd; 1139 struct bfa_fcs_lport_s *fcs_port; 1140 struct bfa_fcs_itnim_s *itnim; 1141 unsigned long flags; 1142 1143 spin_lock_irqsave(&bfad->bfad_lock, flags); 1144 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, 1145 iocmd->vf_id, iocmd->lpwwn); 1146 if (!fcs_port) { 1147 iocmd->status = BFA_STATUS_UNKNOWN_LWWN; 1148 bfa_trc(bfad, 0); 1149 } else { 1150 itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn); 1151 if (itnim == NULL) 1152 iocmd->status = BFA_STATUS_UNKNOWN_RWWN; 1153 else { 1154 iocmd->status = BFA_STATUS_OK; 1155 bfa_fcs_itnim_stats_get(fcs_port, iocmd->rpwwn, 1156 &iocmd->itnstats); 1157 } 1158 } 1159 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1160 return 0; 1161 } 1162 1163 static int 1164 bfad_iocmd_fcport_enable(struct bfad_s *bfad, void *cmd) 1165 { 1166 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 1167 unsigned long flags; 1168 1169 spin_lock_irqsave(&bfad->bfad_lock, flags); 1170 iocmd->status = bfa_fcport_enable(&bfad->bfa); 1171 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1172 1173 return 0; 1174 } 1175 1176 static int 1177 bfad_iocmd_fcport_disable(struct bfad_s *bfad, void *cmd) 1178 { 1179 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 1180 unsigned long flags; 1181 1182 spin_lock_irqsave(&bfad->bfad_lock, flags); 1183 iocmd->status = bfa_fcport_disable(&bfad->bfa); 1184 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1185 1186 return 0; 1187 } 1188 1189 static int 1190 bfad_iocmd_ioc_get_pcifn_cfg(struct bfad_s *bfad, void *cmd) 1191 { 1192 struct bfa_bsg_pcifn_cfg_s *iocmd = (struct bfa_bsg_pcifn_cfg_s *)cmd; 1193 struct bfad_hal_comp fcomp; 1194 unsigned long flags; 1195 1196 init_completion(&fcomp.comp); 1197 spin_lock_irqsave(&bfad->bfad_lock, flags); 1198 iocmd->status = bfa_ablk_query(&bfad->bfa.modules.ablk, 1199 &iocmd->pcifn_cfg, 1200 bfad_hcb_comp, &fcomp); 1201 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1202 if (iocmd->status != BFA_STATUS_OK) 1203 goto out; 1204 1205 wait_for_completion(&fcomp.comp); 1206 iocmd->status = fcomp.status; 1207 out: 1208 return 0; 1209 } 1210 1211 static int 1212 bfad_iocmd_pcifn_create(struct bfad_s *bfad, void *cmd) 1213 { 1214 struct bfa_bsg_pcifn_s *iocmd = (struct bfa_bsg_pcifn_s *)cmd; 1215 struct bfad_hal_comp fcomp; 1216 unsigned long flags; 1217 1218 init_completion(&fcomp.comp); 1219 spin_lock_irqsave(&bfad->bfad_lock, flags); 1220 iocmd->status = bfa_ablk_pf_create(&bfad->bfa.modules.ablk, 1221 &iocmd->pcifn_id, iocmd->port, 1222 iocmd->pcifn_class, iocmd->bw_min, 1223 iocmd->bw_max, bfad_hcb_comp, &fcomp); 1224 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1225 if (iocmd->status != BFA_STATUS_OK) 1226 goto out; 1227 1228 wait_for_completion(&fcomp.comp); 1229 iocmd->status = fcomp.status; 1230 out: 1231 return 0; 1232 } 1233 1234 static int 1235 bfad_iocmd_pcifn_delete(struct bfad_s *bfad, void *cmd) 1236 { 1237 struct bfa_bsg_pcifn_s *iocmd = (struct bfa_bsg_pcifn_s *)cmd; 1238 struct bfad_hal_comp fcomp; 1239 unsigned long flags; 1240 1241 init_completion(&fcomp.comp); 1242 spin_lock_irqsave(&bfad->bfad_lock, flags); 1243 iocmd->status = bfa_ablk_pf_delete(&bfad->bfa.modules.ablk, 1244 iocmd->pcifn_id, 1245 bfad_hcb_comp, &fcomp); 1246 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1247 if (iocmd->status != BFA_STATUS_OK) 1248 goto out; 1249 1250 wait_for_completion(&fcomp.comp); 1251 iocmd->status = fcomp.status; 1252 out: 1253 return 0; 1254 } 1255 1256 static int 1257 bfad_iocmd_pcifn_bw(struct bfad_s *bfad, void *cmd) 1258 { 1259 struct bfa_bsg_pcifn_s *iocmd = (struct bfa_bsg_pcifn_s *)cmd; 1260 struct bfad_hal_comp fcomp; 1261 unsigned long flags; 1262 1263 init_completion(&fcomp.comp); 1264 spin_lock_irqsave(&bfad->bfad_lock, flags); 1265 iocmd->status = bfa_ablk_pf_update(&bfad->bfa.modules.ablk, 1266 iocmd->pcifn_id, iocmd->bw_min, 1267 iocmd->bw_max, bfad_hcb_comp, &fcomp); 1268 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1269 bfa_trc(bfad, iocmd->status); 1270 if (iocmd->status != BFA_STATUS_OK) 1271 goto out; 1272 1273 wait_for_completion(&fcomp.comp); 1274 iocmd->status = fcomp.status; 1275 bfa_trc(bfad, iocmd->status); 1276 out: 1277 return 0; 1278 } 1279 1280 static int 1281 bfad_iocmd_adapter_cfg_mode(struct bfad_s *bfad, void *cmd) 1282 { 1283 struct bfa_bsg_adapter_cfg_mode_s *iocmd = 1284 (struct bfa_bsg_adapter_cfg_mode_s *)cmd; 1285 struct bfad_hal_comp fcomp; 1286 unsigned long flags = 0; 1287 1288 init_completion(&fcomp.comp); 1289 spin_lock_irqsave(&bfad->bfad_lock, flags); 1290 iocmd->status = bfa_ablk_adapter_config(&bfad->bfa.modules.ablk, 1291 iocmd->cfg.mode, iocmd->cfg.max_pf, 1292 iocmd->cfg.max_vf, bfad_hcb_comp, &fcomp); 1293 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1294 if (iocmd->status != BFA_STATUS_OK) 1295 goto out; 1296 1297 wait_for_completion(&fcomp.comp); 1298 iocmd->status = fcomp.status; 1299 out: 1300 return 0; 1301 } 1302 1303 static int 1304 bfad_iocmd_port_cfg_mode(struct bfad_s *bfad, void *cmd) 1305 { 1306 struct bfa_bsg_port_cfg_mode_s *iocmd = 1307 (struct bfa_bsg_port_cfg_mode_s *)cmd; 1308 struct bfad_hal_comp fcomp; 1309 unsigned long flags = 0; 1310 1311 init_completion(&fcomp.comp); 1312 spin_lock_irqsave(&bfad->bfad_lock, flags); 1313 iocmd->status = bfa_ablk_port_config(&bfad->bfa.modules.ablk, 1314 iocmd->instance, iocmd->cfg.mode, 1315 iocmd->cfg.max_pf, iocmd->cfg.max_vf, 1316 bfad_hcb_comp, &fcomp); 1317 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1318 if (iocmd->status != BFA_STATUS_OK) 1319 goto out; 1320 1321 wait_for_completion(&fcomp.comp); 1322 iocmd->status = fcomp.status; 1323 out: 1324 return 0; 1325 } 1326 1327 static int 1328 bfad_iocmd_ablk_optrom(struct bfad_s *bfad, unsigned int cmd, void *pcmd) 1329 { 1330 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; 1331 struct bfad_hal_comp fcomp; 1332 unsigned long flags; 1333 1334 init_completion(&fcomp.comp); 1335 spin_lock_irqsave(&bfad->bfad_lock, flags); 1336 if (cmd == IOCMD_FLASH_ENABLE_OPTROM) 1337 iocmd->status = bfa_ablk_optrom_en(&bfad->bfa.modules.ablk, 1338 bfad_hcb_comp, &fcomp); 1339 else 1340 iocmd->status = bfa_ablk_optrom_dis(&bfad->bfa.modules.ablk, 1341 bfad_hcb_comp, &fcomp); 1342 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1343 1344 if (iocmd->status != BFA_STATUS_OK) 1345 goto out; 1346 1347 wait_for_completion(&fcomp.comp); 1348 iocmd->status = fcomp.status; 1349 out: 1350 return 0; 1351 } 1352 1353 static int 1354 bfad_iocmd_faa_query(struct bfad_s *bfad, void *cmd) 1355 { 1356 struct bfa_bsg_faa_attr_s *iocmd = (struct bfa_bsg_faa_attr_s *)cmd; 1357 struct bfad_hal_comp fcomp; 1358 unsigned long flags; 1359 1360 init_completion(&fcomp.comp); 1361 iocmd->status = BFA_STATUS_OK; 1362 spin_lock_irqsave(&bfad->bfad_lock, flags); 1363 iocmd->status = bfa_faa_query(&bfad->bfa, &iocmd->faa_attr, 1364 bfad_hcb_comp, &fcomp); 1365 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1366 1367 if (iocmd->status != BFA_STATUS_OK) 1368 goto out; 1369 1370 wait_for_completion(&fcomp.comp); 1371 iocmd->status = fcomp.status; 1372 out: 1373 return 0; 1374 } 1375 1376 static int 1377 bfad_iocmd_cee_attr(struct bfad_s *bfad, void *cmd, unsigned int payload_len) 1378 { 1379 struct bfa_bsg_cee_attr_s *iocmd = 1380 (struct bfa_bsg_cee_attr_s *)cmd; 1381 void *iocmd_bufptr; 1382 struct bfad_hal_comp cee_comp; 1383 unsigned long flags; 1384 1385 if (bfad_chk_iocmd_sz(payload_len, 1386 sizeof(struct bfa_bsg_cee_attr_s), 1387 sizeof(struct bfa_cee_attr_s)) != BFA_STATUS_OK) { 1388 iocmd->status = BFA_STATUS_VERSION_FAIL; 1389 return 0; 1390 } 1391 1392 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_cee_attr_s); 1393 1394 cee_comp.status = 0; 1395 init_completion(&cee_comp.comp); 1396 mutex_lock(&bfad_mutex); 1397 spin_lock_irqsave(&bfad->bfad_lock, flags); 1398 iocmd->status = bfa_cee_get_attr(&bfad->bfa.modules.cee, iocmd_bufptr, 1399 bfad_hcb_comp, &cee_comp); 1400 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1401 if (iocmd->status != BFA_STATUS_OK) { 1402 mutex_unlock(&bfad_mutex); 1403 bfa_trc(bfad, 0x5555); 1404 goto out; 1405 } 1406 wait_for_completion(&cee_comp.comp); 1407 mutex_unlock(&bfad_mutex); 1408 out: 1409 return 0; 1410 } 1411 1412 static int 1413 bfad_iocmd_cee_get_stats(struct bfad_s *bfad, void *cmd, 1414 unsigned int payload_len) 1415 { 1416 struct bfa_bsg_cee_stats_s *iocmd = 1417 (struct bfa_bsg_cee_stats_s *)cmd; 1418 void *iocmd_bufptr; 1419 struct bfad_hal_comp cee_comp; 1420 unsigned long flags; 1421 1422 if (bfad_chk_iocmd_sz(payload_len, 1423 sizeof(struct bfa_bsg_cee_stats_s), 1424 sizeof(struct bfa_cee_stats_s)) != BFA_STATUS_OK) { 1425 iocmd->status = BFA_STATUS_VERSION_FAIL; 1426 return 0; 1427 } 1428 1429 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_cee_stats_s); 1430 1431 cee_comp.status = 0; 1432 init_completion(&cee_comp.comp); 1433 mutex_lock(&bfad_mutex); 1434 spin_lock_irqsave(&bfad->bfad_lock, flags); 1435 iocmd->status = bfa_cee_get_stats(&bfad->bfa.modules.cee, iocmd_bufptr, 1436 bfad_hcb_comp, &cee_comp); 1437 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1438 if (iocmd->status != BFA_STATUS_OK) { 1439 mutex_unlock(&bfad_mutex); 1440 bfa_trc(bfad, 0x5555); 1441 goto out; 1442 } 1443 wait_for_completion(&cee_comp.comp); 1444 mutex_unlock(&bfad_mutex); 1445 out: 1446 return 0; 1447 } 1448 1449 static int 1450 bfad_iocmd_cee_reset_stats(struct bfad_s *bfad, void *cmd) 1451 { 1452 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 1453 unsigned long flags; 1454 1455 spin_lock_irqsave(&bfad->bfad_lock, flags); 1456 iocmd->status = bfa_cee_reset_stats(&bfad->bfa.modules.cee, NULL, NULL); 1457 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1458 if (iocmd->status != BFA_STATUS_OK) 1459 bfa_trc(bfad, 0x5555); 1460 return 0; 1461 } 1462 1463 static int 1464 bfad_iocmd_sfp_media(struct bfad_s *bfad, void *cmd) 1465 { 1466 struct bfa_bsg_sfp_media_s *iocmd = (struct bfa_bsg_sfp_media_s *)cmd; 1467 struct bfad_hal_comp fcomp; 1468 unsigned long flags; 1469 1470 init_completion(&fcomp.comp); 1471 spin_lock_irqsave(&bfad->bfad_lock, flags); 1472 iocmd->status = bfa_sfp_media(BFA_SFP_MOD(&bfad->bfa), &iocmd->media, 1473 bfad_hcb_comp, &fcomp); 1474 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1475 bfa_trc(bfad, iocmd->status); 1476 if (iocmd->status != BFA_STATUS_SFP_NOT_READY) 1477 goto out; 1478 1479 wait_for_completion(&fcomp.comp); 1480 iocmd->status = fcomp.status; 1481 out: 1482 return 0; 1483 } 1484 1485 static int 1486 bfad_iocmd_sfp_speed(struct bfad_s *bfad, void *cmd) 1487 { 1488 struct bfa_bsg_sfp_speed_s *iocmd = (struct bfa_bsg_sfp_speed_s *)cmd; 1489 struct bfad_hal_comp fcomp; 1490 unsigned long flags; 1491 1492 init_completion(&fcomp.comp); 1493 spin_lock_irqsave(&bfad->bfad_lock, flags); 1494 iocmd->status = bfa_sfp_speed(BFA_SFP_MOD(&bfad->bfa), iocmd->speed, 1495 bfad_hcb_comp, &fcomp); 1496 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1497 bfa_trc(bfad, iocmd->status); 1498 if (iocmd->status != BFA_STATUS_SFP_NOT_READY) 1499 goto out; 1500 wait_for_completion(&fcomp.comp); 1501 iocmd->status = fcomp.status; 1502 out: 1503 return 0; 1504 } 1505 1506 static int 1507 bfad_iocmd_flash_get_attr(struct bfad_s *bfad, void *cmd) 1508 { 1509 struct bfa_bsg_flash_attr_s *iocmd = 1510 (struct bfa_bsg_flash_attr_s *)cmd; 1511 struct bfad_hal_comp fcomp; 1512 unsigned long flags; 1513 1514 init_completion(&fcomp.comp); 1515 spin_lock_irqsave(&bfad->bfad_lock, flags); 1516 iocmd->status = bfa_flash_get_attr(BFA_FLASH(&bfad->bfa), &iocmd->attr, 1517 bfad_hcb_comp, &fcomp); 1518 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1519 if (iocmd->status != BFA_STATUS_OK) 1520 goto out; 1521 wait_for_completion(&fcomp.comp); 1522 iocmd->status = fcomp.status; 1523 out: 1524 return 0; 1525 } 1526 1527 static int 1528 bfad_iocmd_flash_erase_part(struct bfad_s *bfad, void *cmd) 1529 { 1530 struct bfa_bsg_flash_s *iocmd = (struct bfa_bsg_flash_s *)cmd; 1531 struct bfad_hal_comp fcomp; 1532 unsigned long flags; 1533 1534 init_completion(&fcomp.comp); 1535 spin_lock_irqsave(&bfad->bfad_lock, flags); 1536 iocmd->status = bfa_flash_erase_part(BFA_FLASH(&bfad->bfa), iocmd->type, 1537 iocmd->instance, bfad_hcb_comp, &fcomp); 1538 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1539 if (iocmd->status != BFA_STATUS_OK) 1540 goto out; 1541 wait_for_completion(&fcomp.comp); 1542 iocmd->status = fcomp.status; 1543 out: 1544 return 0; 1545 } 1546 1547 static int 1548 bfad_iocmd_flash_update_part(struct bfad_s *bfad, void *cmd, 1549 unsigned int payload_len) 1550 { 1551 struct bfa_bsg_flash_s *iocmd = (struct bfa_bsg_flash_s *)cmd; 1552 void *iocmd_bufptr; 1553 struct bfad_hal_comp fcomp; 1554 unsigned long flags; 1555 1556 if (bfad_chk_iocmd_sz(payload_len, 1557 sizeof(struct bfa_bsg_flash_s), 1558 iocmd->bufsz) != BFA_STATUS_OK) { 1559 iocmd->status = BFA_STATUS_VERSION_FAIL; 1560 return 0; 1561 } 1562 1563 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_flash_s); 1564 1565 init_completion(&fcomp.comp); 1566 spin_lock_irqsave(&bfad->bfad_lock, flags); 1567 iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), 1568 iocmd->type, iocmd->instance, iocmd_bufptr, 1569 iocmd->bufsz, 0, bfad_hcb_comp, &fcomp); 1570 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1571 if (iocmd->status != BFA_STATUS_OK) 1572 goto out; 1573 wait_for_completion(&fcomp.comp); 1574 iocmd->status = fcomp.status; 1575 out: 1576 return 0; 1577 } 1578 1579 static int 1580 bfad_iocmd_flash_read_part(struct bfad_s *bfad, void *cmd, 1581 unsigned int payload_len) 1582 { 1583 struct bfa_bsg_flash_s *iocmd = (struct bfa_bsg_flash_s *)cmd; 1584 struct bfad_hal_comp fcomp; 1585 void *iocmd_bufptr; 1586 unsigned long flags; 1587 1588 if (bfad_chk_iocmd_sz(payload_len, 1589 sizeof(struct bfa_bsg_flash_s), 1590 iocmd->bufsz) != BFA_STATUS_OK) { 1591 iocmd->status = BFA_STATUS_VERSION_FAIL; 1592 return 0; 1593 } 1594 1595 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_flash_s); 1596 1597 init_completion(&fcomp.comp); 1598 spin_lock_irqsave(&bfad->bfad_lock, flags); 1599 iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), iocmd->type, 1600 iocmd->instance, iocmd_bufptr, iocmd->bufsz, 0, 1601 bfad_hcb_comp, &fcomp); 1602 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1603 if (iocmd->status != BFA_STATUS_OK) 1604 goto out; 1605 wait_for_completion(&fcomp.comp); 1606 iocmd->status = fcomp.status; 1607 out: 1608 return 0; 1609 } 1610 1611 static int 1612 bfad_iocmd_diag_temp(struct bfad_s *bfad, void *cmd) 1613 { 1614 struct bfa_bsg_diag_get_temp_s *iocmd = 1615 (struct bfa_bsg_diag_get_temp_s *)cmd; 1616 struct bfad_hal_comp fcomp; 1617 unsigned long flags; 1618 1619 init_completion(&fcomp.comp); 1620 spin_lock_irqsave(&bfad->bfad_lock, flags); 1621 iocmd->status = bfa_diag_tsensor_query(BFA_DIAG_MOD(&bfad->bfa), 1622 &iocmd->result, bfad_hcb_comp, &fcomp); 1623 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1624 bfa_trc(bfad, iocmd->status); 1625 if (iocmd->status != BFA_STATUS_OK) 1626 goto out; 1627 wait_for_completion(&fcomp.comp); 1628 iocmd->status = fcomp.status; 1629 out: 1630 return 0; 1631 } 1632 1633 static int 1634 bfad_iocmd_diag_memtest(struct bfad_s *bfad, void *cmd) 1635 { 1636 struct bfa_bsg_diag_memtest_s *iocmd = 1637 (struct bfa_bsg_diag_memtest_s *)cmd; 1638 struct bfad_hal_comp fcomp; 1639 unsigned long flags; 1640 1641 init_completion(&fcomp.comp); 1642 spin_lock_irqsave(&bfad->bfad_lock, flags); 1643 iocmd->status = bfa_diag_memtest(BFA_DIAG_MOD(&bfad->bfa), 1644 &iocmd->memtest, iocmd->pat, 1645 &iocmd->result, bfad_hcb_comp, &fcomp); 1646 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1647 bfa_trc(bfad, iocmd->status); 1648 if (iocmd->status != BFA_STATUS_OK) 1649 goto out; 1650 wait_for_completion(&fcomp.comp); 1651 iocmd->status = fcomp.status; 1652 out: 1653 return 0; 1654 } 1655 1656 static int 1657 bfad_iocmd_diag_loopback(struct bfad_s *bfad, void *cmd) 1658 { 1659 struct bfa_bsg_diag_loopback_s *iocmd = 1660 (struct bfa_bsg_diag_loopback_s *)cmd; 1661 struct bfad_hal_comp fcomp; 1662 unsigned long flags; 1663 1664 init_completion(&fcomp.comp); 1665 spin_lock_irqsave(&bfad->bfad_lock, flags); 1666 iocmd->status = bfa_fcdiag_loopback(&bfad->bfa, iocmd->opmode, 1667 iocmd->speed, iocmd->lpcnt, iocmd->pat, 1668 &iocmd->result, bfad_hcb_comp, &fcomp); 1669 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1670 bfa_trc(bfad, iocmd->status); 1671 if (iocmd->status != BFA_STATUS_OK) 1672 goto out; 1673 wait_for_completion(&fcomp.comp); 1674 iocmd->status = fcomp.status; 1675 out: 1676 return 0; 1677 } 1678 1679 static int 1680 bfad_iocmd_diag_fwping(struct bfad_s *bfad, void *cmd) 1681 { 1682 struct bfa_bsg_diag_fwping_s *iocmd = 1683 (struct bfa_bsg_diag_fwping_s *)cmd; 1684 struct bfad_hal_comp fcomp; 1685 unsigned long flags; 1686 1687 init_completion(&fcomp.comp); 1688 spin_lock_irqsave(&bfad->bfad_lock, flags); 1689 iocmd->status = bfa_diag_fwping(BFA_DIAG_MOD(&bfad->bfa), iocmd->cnt, 1690 iocmd->pattern, &iocmd->result, 1691 bfad_hcb_comp, &fcomp); 1692 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1693 bfa_trc(bfad, iocmd->status); 1694 if (iocmd->status != BFA_STATUS_OK) 1695 goto out; 1696 bfa_trc(bfad, 0x77771); 1697 wait_for_completion(&fcomp.comp); 1698 iocmd->status = fcomp.status; 1699 out: 1700 return 0; 1701 } 1702 1703 static int 1704 bfad_iocmd_diag_queuetest(struct bfad_s *bfad, void *cmd) 1705 { 1706 struct bfa_bsg_diag_qtest_s *iocmd = (struct bfa_bsg_diag_qtest_s *)cmd; 1707 struct bfad_hal_comp fcomp; 1708 unsigned long flags; 1709 1710 init_completion(&fcomp.comp); 1711 spin_lock_irqsave(&bfad->bfad_lock, flags); 1712 iocmd->status = bfa_fcdiag_queuetest(&bfad->bfa, iocmd->force, 1713 iocmd->queue, &iocmd->result, 1714 bfad_hcb_comp, &fcomp); 1715 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1716 if (iocmd->status != BFA_STATUS_OK) 1717 goto out; 1718 wait_for_completion(&fcomp.comp); 1719 iocmd->status = fcomp.status; 1720 out: 1721 return 0; 1722 } 1723 1724 static int 1725 bfad_iocmd_diag_sfp(struct bfad_s *bfad, void *cmd) 1726 { 1727 struct bfa_bsg_sfp_show_s *iocmd = 1728 (struct bfa_bsg_sfp_show_s *)cmd; 1729 struct bfad_hal_comp fcomp; 1730 unsigned long flags; 1731 1732 init_completion(&fcomp.comp); 1733 spin_lock_irqsave(&bfad->bfad_lock, flags); 1734 iocmd->status = bfa_sfp_show(BFA_SFP_MOD(&bfad->bfa), &iocmd->sfp, 1735 bfad_hcb_comp, &fcomp); 1736 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1737 bfa_trc(bfad, iocmd->status); 1738 if (iocmd->status != BFA_STATUS_OK) 1739 goto out; 1740 wait_for_completion(&fcomp.comp); 1741 iocmd->status = fcomp.status; 1742 bfa_trc(bfad, iocmd->status); 1743 out: 1744 return 0; 1745 } 1746 1747 static int 1748 bfad_iocmd_diag_led(struct bfad_s *bfad, void *cmd) 1749 { 1750 struct bfa_bsg_diag_led_s *iocmd = (struct bfa_bsg_diag_led_s *)cmd; 1751 unsigned long flags; 1752 1753 spin_lock_irqsave(&bfad->bfad_lock, flags); 1754 iocmd->status = bfa_diag_ledtest(BFA_DIAG_MOD(&bfad->bfa), 1755 &iocmd->ledtest); 1756 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1757 return 0; 1758 } 1759 1760 static int 1761 bfad_iocmd_diag_beacon_lport(struct bfad_s *bfad, void *cmd) 1762 { 1763 struct bfa_bsg_diag_beacon_s *iocmd = 1764 (struct bfa_bsg_diag_beacon_s *)cmd; 1765 unsigned long flags; 1766 1767 spin_lock_irqsave(&bfad->bfad_lock, flags); 1768 iocmd->status = bfa_diag_beacon_port(BFA_DIAG_MOD(&bfad->bfa), 1769 iocmd->beacon, iocmd->link_e2e_beacon, 1770 iocmd->second); 1771 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1772 return 0; 1773 } 1774 1775 static int 1776 bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd) 1777 { 1778 struct bfa_bsg_diag_lb_stat_s *iocmd = 1779 (struct bfa_bsg_diag_lb_stat_s *)cmd; 1780 unsigned long flags; 1781 1782 spin_lock_irqsave(&bfad->bfad_lock, flags); 1783 iocmd->status = bfa_fcdiag_lb_is_running(&bfad->bfa); 1784 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1785 bfa_trc(bfad, iocmd->status); 1786 1787 return 0; 1788 } 1789 1790 static int 1791 bfad_iocmd_diag_dport_enable(struct bfad_s *bfad, void *pcmd) 1792 { 1793 struct bfa_bsg_dport_enable_s *iocmd = 1794 (struct bfa_bsg_dport_enable_s *)pcmd; 1795 unsigned long flags; 1796 struct bfad_hal_comp fcomp; 1797 1798 init_completion(&fcomp.comp); 1799 spin_lock_irqsave(&bfad->bfad_lock, flags); 1800 iocmd->status = bfa_dport_enable(&bfad->bfa, iocmd->lpcnt, 1801 iocmd->pat, bfad_hcb_comp, &fcomp); 1802 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1803 if (iocmd->status != BFA_STATUS_OK) 1804 bfa_trc(bfad, iocmd->status); 1805 else { 1806 wait_for_completion(&fcomp.comp); 1807 iocmd->status = fcomp.status; 1808 } 1809 return 0; 1810 } 1811 1812 static int 1813 bfad_iocmd_diag_dport_disable(struct bfad_s *bfad, void *pcmd) 1814 { 1815 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; 1816 unsigned long flags; 1817 struct bfad_hal_comp fcomp; 1818 1819 init_completion(&fcomp.comp); 1820 spin_lock_irqsave(&bfad->bfad_lock, flags); 1821 iocmd->status = bfa_dport_disable(&bfad->bfa, bfad_hcb_comp, &fcomp); 1822 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1823 if (iocmd->status != BFA_STATUS_OK) 1824 bfa_trc(bfad, iocmd->status); 1825 else { 1826 wait_for_completion(&fcomp.comp); 1827 iocmd->status = fcomp.status; 1828 } 1829 return 0; 1830 } 1831 1832 static int 1833 bfad_iocmd_diag_dport_start(struct bfad_s *bfad, void *pcmd) 1834 { 1835 struct bfa_bsg_dport_enable_s *iocmd = 1836 (struct bfa_bsg_dport_enable_s *)pcmd; 1837 unsigned long flags; 1838 struct bfad_hal_comp fcomp; 1839 1840 init_completion(&fcomp.comp); 1841 spin_lock_irqsave(&bfad->bfad_lock, flags); 1842 iocmd->status = bfa_dport_start(&bfad->bfa, iocmd->lpcnt, 1843 iocmd->pat, bfad_hcb_comp, 1844 &fcomp); 1845 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1846 1847 if (iocmd->status != BFA_STATUS_OK) { 1848 bfa_trc(bfad, iocmd->status); 1849 } else { 1850 wait_for_completion(&fcomp.comp); 1851 iocmd->status = fcomp.status; 1852 } 1853 1854 return 0; 1855 } 1856 1857 static int 1858 bfad_iocmd_diag_dport_show(struct bfad_s *bfad, void *pcmd) 1859 { 1860 struct bfa_bsg_diag_dport_show_s *iocmd = 1861 (struct bfa_bsg_diag_dport_show_s *)pcmd; 1862 unsigned long flags; 1863 1864 spin_lock_irqsave(&bfad->bfad_lock, flags); 1865 iocmd->status = bfa_dport_show(&bfad->bfa, &iocmd->result); 1866 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1867 1868 return 0; 1869 } 1870 1871 1872 static int 1873 bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd) 1874 { 1875 struct bfa_bsg_phy_attr_s *iocmd = 1876 (struct bfa_bsg_phy_attr_s *)cmd; 1877 struct bfad_hal_comp fcomp; 1878 unsigned long flags; 1879 1880 init_completion(&fcomp.comp); 1881 spin_lock_irqsave(&bfad->bfad_lock, flags); 1882 iocmd->status = bfa_phy_get_attr(BFA_PHY(&bfad->bfa), iocmd->instance, 1883 &iocmd->attr, bfad_hcb_comp, &fcomp); 1884 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1885 if (iocmd->status != BFA_STATUS_OK) 1886 goto out; 1887 wait_for_completion(&fcomp.comp); 1888 iocmd->status = fcomp.status; 1889 out: 1890 return 0; 1891 } 1892 1893 static int 1894 bfad_iocmd_phy_get_stats(struct bfad_s *bfad, void *cmd) 1895 { 1896 struct bfa_bsg_phy_stats_s *iocmd = 1897 (struct bfa_bsg_phy_stats_s *)cmd; 1898 struct bfad_hal_comp fcomp; 1899 unsigned long flags; 1900 1901 init_completion(&fcomp.comp); 1902 spin_lock_irqsave(&bfad->bfad_lock, flags); 1903 iocmd->status = bfa_phy_get_stats(BFA_PHY(&bfad->bfa), iocmd->instance, 1904 &iocmd->stats, bfad_hcb_comp, &fcomp); 1905 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1906 if (iocmd->status != BFA_STATUS_OK) 1907 goto out; 1908 wait_for_completion(&fcomp.comp); 1909 iocmd->status = fcomp.status; 1910 out: 1911 return 0; 1912 } 1913 1914 static int 1915 bfad_iocmd_phy_read(struct bfad_s *bfad, void *cmd, unsigned int payload_len) 1916 { 1917 struct bfa_bsg_phy_s *iocmd = (struct bfa_bsg_phy_s *)cmd; 1918 struct bfad_hal_comp fcomp; 1919 void *iocmd_bufptr; 1920 unsigned long flags; 1921 1922 if (bfad_chk_iocmd_sz(payload_len, 1923 sizeof(struct bfa_bsg_phy_s), 1924 iocmd->bufsz) != BFA_STATUS_OK) { 1925 iocmd->status = BFA_STATUS_VERSION_FAIL; 1926 return 0; 1927 } 1928 1929 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_phy_s); 1930 init_completion(&fcomp.comp); 1931 spin_lock_irqsave(&bfad->bfad_lock, flags); 1932 iocmd->status = bfa_phy_read(BFA_PHY(&bfad->bfa), 1933 iocmd->instance, iocmd_bufptr, iocmd->bufsz, 1934 0, bfad_hcb_comp, &fcomp); 1935 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1936 if (iocmd->status != BFA_STATUS_OK) 1937 goto out; 1938 wait_for_completion(&fcomp.comp); 1939 iocmd->status = fcomp.status; 1940 if (iocmd->status != BFA_STATUS_OK) 1941 goto out; 1942 out: 1943 return 0; 1944 } 1945 1946 static int 1947 bfad_iocmd_vhba_query(struct bfad_s *bfad, void *cmd) 1948 { 1949 struct bfa_bsg_vhba_attr_s *iocmd = 1950 (struct bfa_bsg_vhba_attr_s *)cmd; 1951 struct bfa_vhba_attr_s *attr = &iocmd->attr; 1952 unsigned long flags; 1953 1954 spin_lock_irqsave(&bfad->bfad_lock, flags); 1955 attr->pwwn = bfad->bfa.ioc.attr->pwwn; 1956 attr->nwwn = bfad->bfa.ioc.attr->nwwn; 1957 attr->plog_enabled = (bfa_boolean_t)bfad->bfa.plog->plog_enabled; 1958 attr->io_profile = bfa_fcpim_get_io_profile(&bfad->bfa); 1959 attr->path_tov = bfa_fcpim_path_tov_get(&bfad->bfa); 1960 iocmd->status = BFA_STATUS_OK; 1961 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1962 return 0; 1963 } 1964 1965 static int 1966 bfad_iocmd_phy_update(struct bfad_s *bfad, void *cmd, unsigned int payload_len) 1967 { 1968 struct bfa_bsg_phy_s *iocmd = (struct bfa_bsg_phy_s *)cmd; 1969 void *iocmd_bufptr; 1970 struct bfad_hal_comp fcomp; 1971 unsigned long flags; 1972 1973 if (bfad_chk_iocmd_sz(payload_len, 1974 sizeof(struct bfa_bsg_phy_s), 1975 iocmd->bufsz) != BFA_STATUS_OK) { 1976 iocmd->status = BFA_STATUS_VERSION_FAIL; 1977 return 0; 1978 } 1979 1980 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_phy_s); 1981 init_completion(&fcomp.comp); 1982 spin_lock_irqsave(&bfad->bfad_lock, flags); 1983 iocmd->status = bfa_phy_update(BFA_PHY(&bfad->bfa), 1984 iocmd->instance, iocmd_bufptr, iocmd->bufsz, 1985 0, bfad_hcb_comp, &fcomp); 1986 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1987 if (iocmd->status != BFA_STATUS_OK) 1988 goto out; 1989 wait_for_completion(&fcomp.comp); 1990 iocmd->status = fcomp.status; 1991 out: 1992 return 0; 1993 } 1994 1995 static int 1996 bfad_iocmd_porglog_get(struct bfad_s *bfad, void *cmd) 1997 { 1998 struct bfa_bsg_debug_s *iocmd = (struct bfa_bsg_debug_s *)cmd; 1999 void *iocmd_bufptr; 2000 2001 if (iocmd->bufsz < sizeof(struct bfa_plog_s)) { 2002 bfa_trc(bfad, sizeof(struct bfa_plog_s)); 2003 iocmd->status = BFA_STATUS_EINVAL; 2004 goto out; 2005 } 2006 2007 iocmd->status = BFA_STATUS_OK; 2008 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_debug_s); 2009 memcpy(iocmd_bufptr, (u8 *) &bfad->plog_buf, sizeof(struct bfa_plog_s)); 2010 out: 2011 return 0; 2012 } 2013 2014 #define BFA_DEBUG_FW_CORE_CHUNK_SZ 0x4000U /* 16K chunks for FW dump */ 2015 static int 2016 bfad_iocmd_debug_fw_core(struct bfad_s *bfad, void *cmd, 2017 unsigned int payload_len) 2018 { 2019 struct bfa_bsg_debug_s *iocmd = (struct bfa_bsg_debug_s *)cmd; 2020 void *iocmd_bufptr; 2021 unsigned long flags; 2022 u32 offset; 2023 2024 if (bfad_chk_iocmd_sz(payload_len, sizeof(struct bfa_bsg_debug_s), 2025 BFA_DEBUG_FW_CORE_CHUNK_SZ) != BFA_STATUS_OK) { 2026 iocmd->status = BFA_STATUS_VERSION_FAIL; 2027 return 0; 2028 } 2029 2030 if (iocmd->bufsz < BFA_DEBUG_FW_CORE_CHUNK_SZ || 2031 !IS_ALIGNED(iocmd->bufsz, sizeof(u16)) || 2032 !IS_ALIGNED(iocmd->offset, sizeof(u32))) { 2033 bfa_trc(bfad, BFA_DEBUG_FW_CORE_CHUNK_SZ); 2034 iocmd->status = BFA_STATUS_EINVAL; 2035 goto out; 2036 } 2037 2038 iocmd_bufptr = (char *)iocmd + sizeof(struct bfa_bsg_debug_s); 2039 spin_lock_irqsave(&bfad->bfad_lock, flags); 2040 offset = iocmd->offset; 2041 iocmd->status = bfa_ioc_debug_fwcore(&bfad->bfa.ioc, iocmd_bufptr, 2042 &offset, &iocmd->bufsz); 2043 iocmd->offset = offset; 2044 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2045 out: 2046 return 0; 2047 } 2048 2049 static int 2050 bfad_iocmd_debug_ctl(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) 2051 { 2052 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 2053 unsigned long flags; 2054 2055 if (v_cmd == IOCMD_DEBUG_FW_STATE_CLR) { 2056 spin_lock_irqsave(&bfad->bfad_lock, flags); 2057 bfad->bfa.ioc.dbg_fwsave_once = BFA_TRUE; 2058 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2059 } else if (v_cmd == IOCMD_DEBUG_PORTLOG_CLR) 2060 bfad->plog_buf.head = bfad->plog_buf.tail = 0; 2061 else if (v_cmd == IOCMD_DEBUG_START_DTRC) 2062 bfa_trc_init(bfad->trcmod); 2063 else if (v_cmd == IOCMD_DEBUG_STOP_DTRC) 2064 bfa_trc_stop(bfad->trcmod); 2065 2066 iocmd->status = BFA_STATUS_OK; 2067 return 0; 2068 } 2069 2070 static int 2071 bfad_iocmd_porglog_ctl(struct bfad_s *bfad, void *cmd) 2072 { 2073 struct bfa_bsg_portlogctl_s *iocmd = (struct bfa_bsg_portlogctl_s *)cmd; 2074 2075 if (iocmd->ctl == BFA_TRUE) 2076 bfad->plog_buf.plog_enabled = 1; 2077 else 2078 bfad->plog_buf.plog_enabled = 0; 2079 2080 iocmd->status = BFA_STATUS_OK; 2081 return 0; 2082 } 2083 2084 static int 2085 bfad_iocmd_fcpim_cfg_profile(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) 2086 { 2087 struct bfa_bsg_fcpim_profile_s *iocmd = 2088 (struct bfa_bsg_fcpim_profile_s *)cmd; 2089 unsigned long flags; 2090 2091 spin_lock_irqsave(&bfad->bfad_lock, flags); 2092 if (v_cmd == IOCMD_FCPIM_PROFILE_ON) 2093 iocmd->status = bfa_fcpim_profile_on(&bfad->bfa, ktime_get_real_seconds()); 2094 else if (v_cmd == IOCMD_FCPIM_PROFILE_OFF) 2095 iocmd->status = bfa_fcpim_profile_off(&bfad->bfa); 2096 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2097 2098 return 0; 2099 } 2100 2101 static int 2102 bfad_iocmd_itnim_get_ioprofile(struct bfad_s *bfad, void *cmd) 2103 { 2104 struct bfa_bsg_itnim_ioprofile_s *iocmd = 2105 (struct bfa_bsg_itnim_ioprofile_s *)cmd; 2106 struct bfa_fcs_lport_s *fcs_port; 2107 struct bfa_fcs_itnim_s *itnim; 2108 unsigned long flags; 2109 2110 spin_lock_irqsave(&bfad->bfad_lock, flags); 2111 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, 2112 iocmd->vf_id, iocmd->lpwwn); 2113 if (!fcs_port) 2114 iocmd->status = BFA_STATUS_UNKNOWN_LWWN; 2115 else { 2116 itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn); 2117 if (itnim == NULL) 2118 iocmd->status = BFA_STATUS_UNKNOWN_RWWN; 2119 else 2120 iocmd->status = bfa_itnim_get_ioprofile( 2121 bfa_fcs_itnim_get_halitn(itnim), 2122 &iocmd->ioprofile); 2123 } 2124 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2125 return 0; 2126 } 2127 2128 static int 2129 bfad_iocmd_fcport_get_stats(struct bfad_s *bfad, void *cmd) 2130 { 2131 struct bfa_bsg_fcport_stats_s *iocmd = 2132 (struct bfa_bsg_fcport_stats_s *)cmd; 2133 struct bfad_hal_comp fcomp; 2134 unsigned long flags; 2135 struct bfa_cb_pending_q_s cb_qe; 2136 2137 init_completion(&fcomp.comp); 2138 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, 2139 &fcomp, &iocmd->stats); 2140 spin_lock_irqsave(&bfad->bfad_lock, flags); 2141 iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); 2142 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2143 if (iocmd->status != BFA_STATUS_OK) { 2144 bfa_trc(bfad, iocmd->status); 2145 goto out; 2146 } 2147 wait_for_completion(&fcomp.comp); 2148 iocmd->status = fcomp.status; 2149 out: 2150 return 0; 2151 } 2152 2153 static int 2154 bfad_iocmd_fcport_reset_stats(struct bfad_s *bfad, void *cmd) 2155 { 2156 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 2157 struct bfad_hal_comp fcomp; 2158 unsigned long flags; 2159 struct bfa_cb_pending_q_s cb_qe; 2160 2161 init_completion(&fcomp.comp); 2162 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, &fcomp, NULL); 2163 2164 spin_lock_irqsave(&bfad->bfad_lock, flags); 2165 iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); 2166 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2167 if (iocmd->status != BFA_STATUS_OK) { 2168 bfa_trc(bfad, iocmd->status); 2169 goto out; 2170 } 2171 wait_for_completion(&fcomp.comp); 2172 iocmd->status = fcomp.status; 2173 out: 2174 return 0; 2175 } 2176 2177 static int 2178 bfad_iocmd_boot_cfg(struct bfad_s *bfad, void *cmd) 2179 { 2180 struct bfa_bsg_boot_s *iocmd = (struct bfa_bsg_boot_s *)cmd; 2181 struct bfad_hal_comp fcomp; 2182 unsigned long flags; 2183 2184 init_completion(&fcomp.comp); 2185 spin_lock_irqsave(&bfad->bfad_lock, flags); 2186 iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), 2187 BFA_FLASH_PART_BOOT, bfad->bfa.ioc.port_id, 2188 &iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0, 2189 bfad_hcb_comp, &fcomp); 2190 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2191 if (iocmd->status != BFA_STATUS_OK) 2192 goto out; 2193 wait_for_completion(&fcomp.comp); 2194 iocmd->status = fcomp.status; 2195 out: 2196 return 0; 2197 } 2198 2199 static int 2200 bfad_iocmd_boot_query(struct bfad_s *bfad, void *cmd) 2201 { 2202 struct bfa_bsg_boot_s *iocmd = (struct bfa_bsg_boot_s *)cmd; 2203 struct bfad_hal_comp fcomp; 2204 unsigned long flags; 2205 2206 init_completion(&fcomp.comp); 2207 spin_lock_irqsave(&bfad->bfad_lock, flags); 2208 iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), 2209 BFA_FLASH_PART_BOOT, bfad->bfa.ioc.port_id, 2210 &iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0, 2211 bfad_hcb_comp, &fcomp); 2212 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2213 if (iocmd->status != BFA_STATUS_OK) 2214 goto out; 2215 wait_for_completion(&fcomp.comp); 2216 iocmd->status = fcomp.status; 2217 out: 2218 return 0; 2219 } 2220 2221 static int 2222 bfad_iocmd_preboot_query(struct bfad_s *bfad, void *cmd) 2223 { 2224 struct bfa_bsg_preboot_s *iocmd = (struct bfa_bsg_preboot_s *)cmd; 2225 struct bfi_iocfc_cfgrsp_s *cfgrsp = bfad->bfa.iocfc.cfgrsp; 2226 struct bfa_boot_pbc_s *pbcfg = &iocmd->cfg; 2227 unsigned long flags; 2228 2229 spin_lock_irqsave(&bfad->bfad_lock, flags); 2230 pbcfg->enable = cfgrsp->pbc_cfg.boot_enabled; 2231 pbcfg->nbluns = cfgrsp->pbc_cfg.nbluns; 2232 pbcfg->speed = cfgrsp->pbc_cfg.port_speed; 2233 memcpy(pbcfg->pblun, cfgrsp->pbc_cfg.blun, sizeof(pbcfg->pblun)); 2234 iocmd->status = BFA_STATUS_OK; 2235 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2236 2237 return 0; 2238 } 2239 2240 static int 2241 bfad_iocmd_ethboot_cfg(struct bfad_s *bfad, void *cmd) 2242 { 2243 struct bfa_bsg_ethboot_s *iocmd = (struct bfa_bsg_ethboot_s *)cmd; 2244 struct bfad_hal_comp fcomp; 2245 unsigned long flags; 2246 2247 init_completion(&fcomp.comp); 2248 spin_lock_irqsave(&bfad->bfad_lock, flags); 2249 iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), 2250 BFA_FLASH_PART_PXECFG, 2251 bfad->bfa.ioc.port_id, &iocmd->cfg, 2252 sizeof(struct bfa_ethboot_cfg_s), 0, 2253 bfad_hcb_comp, &fcomp); 2254 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2255 if (iocmd->status != BFA_STATUS_OK) 2256 goto out; 2257 wait_for_completion(&fcomp.comp); 2258 iocmd->status = fcomp.status; 2259 out: 2260 return 0; 2261 } 2262 2263 static int 2264 bfad_iocmd_ethboot_query(struct bfad_s *bfad, void *cmd) 2265 { 2266 struct bfa_bsg_ethboot_s *iocmd = (struct bfa_bsg_ethboot_s *)cmd; 2267 struct bfad_hal_comp fcomp; 2268 unsigned long flags; 2269 2270 init_completion(&fcomp.comp); 2271 spin_lock_irqsave(&bfad->bfad_lock, flags); 2272 iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), 2273 BFA_FLASH_PART_PXECFG, 2274 bfad->bfa.ioc.port_id, &iocmd->cfg, 2275 sizeof(struct bfa_ethboot_cfg_s), 0, 2276 bfad_hcb_comp, &fcomp); 2277 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2278 if (iocmd->status != BFA_STATUS_OK) 2279 goto out; 2280 wait_for_completion(&fcomp.comp); 2281 iocmd->status = fcomp.status; 2282 out: 2283 return 0; 2284 } 2285 2286 static int 2287 bfad_iocmd_cfg_trunk(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) 2288 { 2289 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 2290 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2291 struct bfa_fcport_trunk_s *trunk = &fcport->trunk; 2292 unsigned long flags; 2293 2294 spin_lock_irqsave(&bfad->bfad_lock, flags); 2295 2296 if (bfa_fcport_is_dport(&bfad->bfa)) { 2297 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2298 return BFA_STATUS_DPORT_ERR; 2299 } 2300 2301 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || 2302 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2303 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2304 else { 2305 if (v_cmd == IOCMD_TRUNK_ENABLE) { 2306 trunk->attr.state = BFA_TRUNK_OFFLINE; 2307 bfa_fcport_disable(&bfad->bfa); 2308 fcport->cfg.trunked = BFA_TRUE; 2309 } else if (v_cmd == IOCMD_TRUNK_DISABLE) { 2310 trunk->attr.state = BFA_TRUNK_DISABLED; 2311 bfa_fcport_disable(&bfad->bfa); 2312 fcport->cfg.trunked = BFA_FALSE; 2313 } 2314 2315 if (!bfa_fcport_is_disabled(&bfad->bfa)) 2316 bfa_fcport_enable(&bfad->bfa); 2317 2318 iocmd->status = BFA_STATUS_OK; 2319 } 2320 2321 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2322 2323 return 0; 2324 } 2325 2326 static int 2327 bfad_iocmd_trunk_get_attr(struct bfad_s *bfad, void *cmd) 2328 { 2329 struct bfa_bsg_trunk_attr_s *iocmd = (struct bfa_bsg_trunk_attr_s *)cmd; 2330 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2331 struct bfa_fcport_trunk_s *trunk = &fcport->trunk; 2332 unsigned long flags; 2333 2334 spin_lock_irqsave(&bfad->bfad_lock, flags); 2335 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || 2336 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2337 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2338 else { 2339 memcpy((void *)&iocmd->attr, (void *)&trunk->attr, 2340 sizeof(struct bfa_trunk_attr_s)); 2341 iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa); 2342 iocmd->status = BFA_STATUS_OK; 2343 } 2344 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2345 2346 return 0; 2347 } 2348 2349 static int 2350 bfad_iocmd_qos(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) 2351 { 2352 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 2353 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2354 unsigned long flags; 2355 2356 spin_lock_irqsave(&bfad->bfad_lock, flags); 2357 if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) { 2358 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 2359 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2360 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2361 else { 2362 if (v_cmd == IOCMD_QOS_ENABLE) 2363 fcport->cfg.qos_enabled = BFA_TRUE; 2364 else if (v_cmd == IOCMD_QOS_DISABLE) { 2365 fcport->cfg.qos_enabled = BFA_FALSE; 2366 fcport->cfg.qos_bw.high = BFA_QOS_BW_HIGH; 2367 fcport->cfg.qos_bw.med = BFA_QOS_BW_MED; 2368 fcport->cfg.qos_bw.low = BFA_QOS_BW_LOW; 2369 } 2370 } 2371 } 2372 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2373 2374 return 0; 2375 } 2376 2377 static int 2378 bfad_iocmd_qos_get_attr(struct bfad_s *bfad, void *cmd) 2379 { 2380 struct bfa_bsg_qos_attr_s *iocmd = (struct bfa_bsg_qos_attr_s *)cmd; 2381 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2382 unsigned long flags; 2383 2384 spin_lock_irqsave(&bfad->bfad_lock, flags); 2385 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 2386 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2387 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2388 else { 2389 iocmd->attr.state = fcport->qos_attr.state; 2390 iocmd->attr.total_bb_cr = 2391 be32_to_cpu(fcport->qos_attr.total_bb_cr); 2392 iocmd->attr.qos_bw.high = fcport->cfg.qos_bw.high; 2393 iocmd->attr.qos_bw.med = fcport->cfg.qos_bw.med; 2394 iocmd->attr.qos_bw.low = fcport->cfg.qos_bw.low; 2395 iocmd->attr.qos_bw_op = fcport->qos_attr.qos_bw_op; 2396 iocmd->status = BFA_STATUS_OK; 2397 } 2398 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2399 2400 return 0; 2401 } 2402 2403 static int 2404 bfad_iocmd_qos_get_vc_attr(struct bfad_s *bfad, void *cmd) 2405 { 2406 struct bfa_bsg_qos_vc_attr_s *iocmd = 2407 (struct bfa_bsg_qos_vc_attr_s *)cmd; 2408 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2409 struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr; 2410 unsigned long flags; 2411 u32 i = 0; 2412 2413 spin_lock_irqsave(&bfad->bfad_lock, flags); 2414 iocmd->attr.total_vc_count = be16_to_cpu(bfa_vc_attr->total_vc_count); 2415 iocmd->attr.shared_credit = be16_to_cpu(bfa_vc_attr->shared_credit); 2416 iocmd->attr.elp_opmode_flags = 2417 be32_to_cpu(bfa_vc_attr->elp_opmode_flags); 2418 2419 /* Individual VC info */ 2420 while (i < iocmd->attr.total_vc_count) { 2421 iocmd->attr.vc_info[i].vc_credit = 2422 bfa_vc_attr->vc_info[i].vc_credit; 2423 iocmd->attr.vc_info[i].borrow_credit = 2424 bfa_vc_attr->vc_info[i].borrow_credit; 2425 iocmd->attr.vc_info[i].priority = 2426 bfa_vc_attr->vc_info[i].priority; 2427 i++; 2428 } 2429 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2430 2431 iocmd->status = BFA_STATUS_OK; 2432 return 0; 2433 } 2434 2435 static int 2436 bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd) 2437 { 2438 struct bfa_bsg_fcport_stats_s *iocmd = 2439 (struct bfa_bsg_fcport_stats_s *)cmd; 2440 struct bfad_hal_comp fcomp; 2441 unsigned long flags; 2442 struct bfa_cb_pending_q_s cb_qe; 2443 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2444 2445 init_completion(&fcomp.comp); 2446 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, 2447 &fcomp, &iocmd->stats); 2448 2449 spin_lock_irqsave(&bfad->bfad_lock, flags); 2450 WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); 2451 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 2452 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2453 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2454 else 2455 iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); 2456 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2457 if (iocmd->status != BFA_STATUS_OK) { 2458 bfa_trc(bfad, iocmd->status); 2459 goto out; 2460 } 2461 wait_for_completion(&fcomp.comp); 2462 iocmd->status = fcomp.status; 2463 out: 2464 return 0; 2465 } 2466 2467 static int 2468 bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd) 2469 { 2470 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 2471 struct bfad_hal_comp fcomp; 2472 unsigned long flags; 2473 struct bfa_cb_pending_q_s cb_qe; 2474 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2475 2476 init_completion(&fcomp.comp); 2477 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, 2478 &fcomp, NULL); 2479 2480 spin_lock_irqsave(&bfad->bfad_lock, flags); 2481 WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); 2482 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 2483 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2484 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2485 else 2486 iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); 2487 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2488 if (iocmd->status != BFA_STATUS_OK) { 2489 bfa_trc(bfad, iocmd->status); 2490 goto out; 2491 } 2492 wait_for_completion(&fcomp.comp); 2493 iocmd->status = fcomp.status; 2494 out: 2495 return 0; 2496 } 2497 2498 static int 2499 bfad_iocmd_vf_get_stats(struct bfad_s *bfad, void *cmd) 2500 { 2501 struct bfa_bsg_vf_stats_s *iocmd = 2502 (struct bfa_bsg_vf_stats_s *)cmd; 2503 struct bfa_fcs_fabric_s *fcs_vf; 2504 unsigned long flags; 2505 2506 spin_lock_irqsave(&bfad->bfad_lock, flags); 2507 fcs_vf = bfa_fcs_vf_lookup(&bfad->bfa_fcs, iocmd->vf_id); 2508 if (fcs_vf == NULL) { 2509 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2510 iocmd->status = BFA_STATUS_UNKNOWN_VFID; 2511 goto out; 2512 } 2513 memcpy((void *)&iocmd->stats, (void *)&fcs_vf->stats, 2514 sizeof(struct bfa_vf_stats_s)); 2515 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2516 iocmd->status = BFA_STATUS_OK; 2517 out: 2518 return 0; 2519 } 2520 2521 static int 2522 bfad_iocmd_vf_clr_stats(struct bfad_s *bfad, void *cmd) 2523 { 2524 struct bfa_bsg_vf_reset_stats_s *iocmd = 2525 (struct bfa_bsg_vf_reset_stats_s *)cmd; 2526 struct bfa_fcs_fabric_s *fcs_vf; 2527 unsigned long flags; 2528 2529 spin_lock_irqsave(&bfad->bfad_lock, flags); 2530 fcs_vf = bfa_fcs_vf_lookup(&bfad->bfa_fcs, iocmd->vf_id); 2531 if (fcs_vf == NULL) { 2532 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2533 iocmd->status = BFA_STATUS_UNKNOWN_VFID; 2534 goto out; 2535 } 2536 memset((void *)&fcs_vf->stats, 0, sizeof(struct bfa_vf_stats_s)); 2537 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2538 iocmd->status = BFA_STATUS_OK; 2539 out: 2540 return 0; 2541 } 2542 2543 /* 2544 * Set the SCSI device sdev_bflags - sdev_bflags are used by the 2545 * SCSI mid-layer to choose LUN Scanning mode REPORT_LUNS vs. Sequential Scan 2546 * 2547 * Internally iterates over all the ITNIM's part of the im_port & sets the 2548 * sdev_bflags for the scsi_device associated with LUN #0. 2549 */ 2550 static void bfad_reset_sdev_bflags(struct bfad_im_port_s *im_port, 2551 int lunmask_cfg) 2552 { 2553 const blist_flags_t scan_flags = BLIST_NOREPORTLUN | BLIST_SPARSELUN; 2554 struct bfad_itnim_s *itnim; 2555 struct scsi_device *sdev; 2556 unsigned long flags; 2557 2558 spin_lock_irqsave(im_port->shost->host_lock, flags); 2559 list_for_each_entry(itnim, &im_port->itnim_mapped_list, list_entry) { 2560 sdev = __scsi_device_lookup(im_port->shost, itnim->channel, 2561 itnim->scsi_tgt_id, 0); 2562 if (sdev) { 2563 if (lunmask_cfg == BFA_TRUE) 2564 sdev->sdev_bflags |= scan_flags; 2565 else 2566 sdev->sdev_bflags &= ~scan_flags; 2567 } 2568 } 2569 spin_unlock_irqrestore(im_port->shost->host_lock, flags); 2570 } 2571 2572 /* Function to reset the LUN SCAN mode */ 2573 static void 2574 bfad_iocmd_lunmask_reset_lunscan_mode(struct bfad_s *bfad, int lunmask_cfg) 2575 { 2576 struct bfad_im_port_s *pport_im = bfad->pport.im_port; 2577 struct bfad_vport_s *vport = NULL; 2578 2579 /* Set the scsi device LUN SCAN flags for base port */ 2580 bfad_reset_sdev_bflags(pport_im, lunmask_cfg); 2581 2582 /* Set the scsi device LUN SCAN flags for the vports */ 2583 list_for_each_entry(vport, &bfad->vport_list, list_entry) 2584 bfad_reset_sdev_bflags(vport->drv_port.im_port, lunmask_cfg); 2585 } 2586 2587 static int 2588 bfad_iocmd_lunmask(struct bfad_s *bfad, void *pcmd, unsigned int v_cmd) 2589 { 2590 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; 2591 unsigned long flags; 2592 2593 spin_lock_irqsave(&bfad->bfad_lock, flags); 2594 if (v_cmd == IOCMD_FCPIM_LUNMASK_ENABLE) { 2595 iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_TRUE); 2596 /* Set the LUN Scanning mode to be Sequential scan */ 2597 if (iocmd->status == BFA_STATUS_OK) 2598 bfad_iocmd_lunmask_reset_lunscan_mode(bfad, BFA_TRUE); 2599 } else if (v_cmd == IOCMD_FCPIM_LUNMASK_DISABLE) { 2600 iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_FALSE); 2601 /* Set the LUN Scanning mode to default REPORT_LUNS scan */ 2602 if (iocmd->status == BFA_STATUS_OK) 2603 bfad_iocmd_lunmask_reset_lunscan_mode(bfad, BFA_FALSE); 2604 } else if (v_cmd == IOCMD_FCPIM_LUNMASK_CLEAR) 2605 iocmd->status = bfa_fcpim_lunmask_clear(&bfad->bfa); 2606 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2607 return 0; 2608 } 2609 2610 static int 2611 bfad_iocmd_fcpim_lunmask_query(struct bfad_s *bfad, void *cmd) 2612 { 2613 struct bfa_bsg_fcpim_lunmask_query_s *iocmd = 2614 (struct bfa_bsg_fcpim_lunmask_query_s *)cmd; 2615 struct bfa_lunmask_cfg_s *lun_mask = &iocmd->lun_mask; 2616 unsigned long flags; 2617 2618 spin_lock_irqsave(&bfad->bfad_lock, flags); 2619 iocmd->status = bfa_fcpim_lunmask_query(&bfad->bfa, lun_mask); 2620 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2621 return 0; 2622 } 2623 2624 static int 2625 bfad_iocmd_fcpim_cfg_lunmask(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) 2626 { 2627 struct bfa_bsg_fcpim_lunmask_s *iocmd = 2628 (struct bfa_bsg_fcpim_lunmask_s *)cmd; 2629 unsigned long flags; 2630 2631 spin_lock_irqsave(&bfad->bfad_lock, flags); 2632 if (v_cmd == IOCMD_FCPIM_LUNMASK_ADD) 2633 iocmd->status = bfa_fcpim_lunmask_add(&bfad->bfa, iocmd->vf_id, 2634 &iocmd->pwwn, iocmd->rpwwn, iocmd->lun); 2635 else if (v_cmd == IOCMD_FCPIM_LUNMASK_DELETE) 2636 iocmd->status = bfa_fcpim_lunmask_delete(&bfad->bfa, 2637 iocmd->vf_id, &iocmd->pwwn, 2638 iocmd->rpwwn, iocmd->lun); 2639 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2640 return 0; 2641 } 2642 2643 static int 2644 bfad_iocmd_fcpim_throttle_query(struct bfad_s *bfad, void *cmd) 2645 { 2646 struct bfa_bsg_fcpim_throttle_s *iocmd = 2647 (struct bfa_bsg_fcpim_throttle_s *)cmd; 2648 unsigned long flags; 2649 2650 spin_lock_irqsave(&bfad->bfad_lock, flags); 2651 iocmd->status = bfa_fcpim_throttle_get(&bfad->bfa, 2652 (void *)&iocmd->throttle); 2653 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2654 2655 return 0; 2656 } 2657 2658 static int 2659 bfad_iocmd_fcpim_throttle_set(struct bfad_s *bfad, void *cmd) 2660 { 2661 struct bfa_bsg_fcpim_throttle_s *iocmd = 2662 (struct bfa_bsg_fcpim_throttle_s *)cmd; 2663 unsigned long flags; 2664 2665 spin_lock_irqsave(&bfad->bfad_lock, flags); 2666 iocmd->status = bfa_fcpim_throttle_set(&bfad->bfa, 2667 iocmd->throttle.cfg_value); 2668 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2669 2670 return 0; 2671 } 2672 2673 static int 2674 bfad_iocmd_tfru_read(struct bfad_s *bfad, void *cmd) 2675 { 2676 struct bfa_bsg_tfru_s *iocmd = 2677 (struct bfa_bsg_tfru_s *)cmd; 2678 struct bfad_hal_comp fcomp; 2679 unsigned long flags = 0; 2680 2681 init_completion(&fcomp.comp); 2682 spin_lock_irqsave(&bfad->bfad_lock, flags); 2683 iocmd->status = bfa_tfru_read(BFA_FRU(&bfad->bfa), 2684 &iocmd->data, iocmd->len, iocmd->offset, 2685 bfad_hcb_comp, &fcomp); 2686 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2687 if (iocmd->status == BFA_STATUS_OK) { 2688 wait_for_completion(&fcomp.comp); 2689 iocmd->status = fcomp.status; 2690 } 2691 2692 return 0; 2693 } 2694 2695 static int 2696 bfad_iocmd_tfru_write(struct bfad_s *bfad, void *cmd) 2697 { 2698 struct bfa_bsg_tfru_s *iocmd = 2699 (struct bfa_bsg_tfru_s *)cmd; 2700 struct bfad_hal_comp fcomp; 2701 unsigned long flags = 0; 2702 2703 init_completion(&fcomp.comp); 2704 spin_lock_irqsave(&bfad->bfad_lock, flags); 2705 iocmd->status = bfa_tfru_write(BFA_FRU(&bfad->bfa), 2706 &iocmd->data, iocmd->len, iocmd->offset, 2707 bfad_hcb_comp, &fcomp); 2708 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2709 if (iocmd->status == BFA_STATUS_OK) { 2710 wait_for_completion(&fcomp.comp); 2711 iocmd->status = fcomp.status; 2712 } 2713 2714 return 0; 2715 } 2716 2717 static int 2718 bfad_iocmd_fruvpd_read(struct bfad_s *bfad, void *cmd) 2719 { 2720 struct bfa_bsg_fruvpd_s *iocmd = 2721 (struct bfa_bsg_fruvpd_s *)cmd; 2722 struct bfad_hal_comp fcomp; 2723 unsigned long flags = 0; 2724 2725 init_completion(&fcomp.comp); 2726 spin_lock_irqsave(&bfad->bfad_lock, flags); 2727 iocmd->status = bfa_fruvpd_read(BFA_FRU(&bfad->bfa), 2728 &iocmd->data, iocmd->len, iocmd->offset, 2729 bfad_hcb_comp, &fcomp); 2730 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2731 if (iocmd->status == BFA_STATUS_OK) { 2732 wait_for_completion(&fcomp.comp); 2733 iocmd->status = fcomp.status; 2734 } 2735 2736 return 0; 2737 } 2738 2739 static int 2740 bfad_iocmd_fruvpd_update(struct bfad_s *bfad, void *cmd) 2741 { 2742 struct bfa_bsg_fruvpd_s *iocmd = 2743 (struct bfa_bsg_fruvpd_s *)cmd; 2744 struct bfad_hal_comp fcomp; 2745 unsigned long flags = 0; 2746 2747 init_completion(&fcomp.comp); 2748 spin_lock_irqsave(&bfad->bfad_lock, flags); 2749 iocmd->status = bfa_fruvpd_update(BFA_FRU(&bfad->bfa), 2750 &iocmd->data, iocmd->len, iocmd->offset, 2751 bfad_hcb_comp, &fcomp, iocmd->trfr_cmpl); 2752 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2753 if (iocmd->status == BFA_STATUS_OK) { 2754 wait_for_completion(&fcomp.comp); 2755 iocmd->status = fcomp.status; 2756 } 2757 2758 return 0; 2759 } 2760 2761 static int 2762 bfad_iocmd_fruvpd_get_max_size(struct bfad_s *bfad, void *cmd) 2763 { 2764 struct bfa_bsg_fruvpd_max_size_s *iocmd = 2765 (struct bfa_bsg_fruvpd_max_size_s *)cmd; 2766 unsigned long flags = 0; 2767 2768 spin_lock_irqsave(&bfad->bfad_lock, flags); 2769 iocmd->status = bfa_fruvpd_get_max_size(BFA_FRU(&bfad->bfa), 2770 &iocmd->max_size); 2771 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2772 2773 return 0; 2774 } 2775 2776 static int 2777 bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, 2778 unsigned int payload_len) 2779 { 2780 int rc = -EINVAL; 2781 2782 switch (cmd) { 2783 case IOCMD_IOC_ENABLE: 2784 rc = bfad_iocmd_ioc_enable(bfad, iocmd); 2785 break; 2786 case IOCMD_IOC_DISABLE: 2787 rc = bfad_iocmd_ioc_disable(bfad, iocmd); 2788 break; 2789 case IOCMD_IOC_GET_INFO: 2790 rc = bfad_iocmd_ioc_get_info(bfad, iocmd); 2791 break; 2792 case IOCMD_IOC_GET_ATTR: 2793 rc = bfad_iocmd_ioc_get_attr(bfad, iocmd); 2794 break; 2795 case IOCMD_IOC_GET_STATS: 2796 rc = bfad_iocmd_ioc_get_stats(bfad, iocmd); 2797 break; 2798 case IOCMD_IOC_GET_FWSTATS: 2799 rc = bfad_iocmd_ioc_get_fwstats(bfad, iocmd, payload_len); 2800 break; 2801 case IOCMD_IOC_RESET_STATS: 2802 case IOCMD_IOC_RESET_FWSTATS: 2803 rc = bfad_iocmd_ioc_reset_stats(bfad, iocmd, cmd); 2804 break; 2805 case IOCMD_IOC_SET_ADAPTER_NAME: 2806 case IOCMD_IOC_SET_PORT_NAME: 2807 rc = bfad_iocmd_ioc_set_name(bfad, iocmd, cmd); 2808 break; 2809 case IOCMD_IOCFC_GET_ATTR: 2810 rc = bfad_iocmd_iocfc_get_attr(bfad, iocmd); 2811 break; 2812 case IOCMD_IOCFC_SET_INTR: 2813 rc = bfad_iocmd_iocfc_set_intr(bfad, iocmd); 2814 break; 2815 case IOCMD_PORT_ENABLE: 2816 rc = bfad_iocmd_port_enable(bfad, iocmd); 2817 break; 2818 case IOCMD_PORT_DISABLE: 2819 rc = bfad_iocmd_port_disable(bfad, iocmd); 2820 break; 2821 case IOCMD_PORT_GET_ATTR: 2822 rc = bfad_iocmd_port_get_attr(bfad, iocmd); 2823 break; 2824 case IOCMD_PORT_GET_STATS: 2825 rc = bfad_iocmd_port_get_stats(bfad, iocmd, payload_len); 2826 break; 2827 case IOCMD_PORT_RESET_STATS: 2828 rc = bfad_iocmd_port_reset_stats(bfad, iocmd); 2829 break; 2830 case IOCMD_PORT_CFG_TOPO: 2831 case IOCMD_PORT_CFG_SPEED: 2832 case IOCMD_PORT_CFG_ALPA: 2833 case IOCMD_PORT_CLR_ALPA: 2834 rc = bfad_iocmd_set_port_cfg(bfad, iocmd, cmd); 2835 break; 2836 case IOCMD_PORT_CFG_MAXFRSZ: 2837 rc = bfad_iocmd_port_cfg_maxfrsize(bfad, iocmd); 2838 break; 2839 case IOCMD_PORT_BBCR_ENABLE: 2840 case IOCMD_PORT_BBCR_DISABLE: 2841 rc = bfad_iocmd_port_cfg_bbcr(bfad, cmd, iocmd); 2842 break; 2843 case IOCMD_PORT_BBCR_GET_ATTR: 2844 rc = bfad_iocmd_port_get_bbcr_attr(bfad, iocmd); 2845 break; 2846 case IOCMD_LPORT_GET_ATTR: 2847 rc = bfad_iocmd_lport_get_attr(bfad, iocmd); 2848 break; 2849 case IOCMD_LPORT_GET_STATS: 2850 rc = bfad_iocmd_lport_get_stats(bfad, iocmd); 2851 break; 2852 case IOCMD_LPORT_RESET_STATS: 2853 rc = bfad_iocmd_lport_reset_stats(bfad, iocmd); 2854 break; 2855 case IOCMD_LPORT_GET_IOSTATS: 2856 rc = bfad_iocmd_lport_get_iostats(bfad, iocmd); 2857 break; 2858 case IOCMD_LPORT_GET_RPORTS: 2859 rc = bfad_iocmd_lport_get_rports(bfad, iocmd, payload_len); 2860 break; 2861 case IOCMD_RPORT_GET_ATTR: 2862 rc = bfad_iocmd_rport_get_attr(bfad, iocmd); 2863 break; 2864 case IOCMD_RPORT_GET_ADDR: 2865 rc = bfad_iocmd_rport_get_addr(bfad, iocmd); 2866 break; 2867 case IOCMD_RPORT_GET_STATS: 2868 rc = bfad_iocmd_rport_get_stats(bfad, iocmd); 2869 break; 2870 case IOCMD_RPORT_RESET_STATS: 2871 rc = bfad_iocmd_rport_clr_stats(bfad, iocmd); 2872 break; 2873 case IOCMD_RPORT_SET_SPEED: 2874 rc = bfad_iocmd_rport_set_speed(bfad, iocmd); 2875 break; 2876 case IOCMD_VPORT_GET_ATTR: 2877 rc = bfad_iocmd_vport_get_attr(bfad, iocmd); 2878 break; 2879 case IOCMD_VPORT_GET_STATS: 2880 rc = bfad_iocmd_vport_get_stats(bfad, iocmd); 2881 break; 2882 case IOCMD_VPORT_RESET_STATS: 2883 rc = bfad_iocmd_vport_clr_stats(bfad, iocmd); 2884 break; 2885 case IOCMD_FABRIC_GET_LPORTS: 2886 rc = bfad_iocmd_fabric_get_lports(bfad, iocmd, payload_len); 2887 break; 2888 case IOCMD_RATELIM_ENABLE: 2889 case IOCMD_RATELIM_DISABLE: 2890 rc = bfad_iocmd_ratelim(bfad, cmd, iocmd); 2891 break; 2892 case IOCMD_RATELIM_DEF_SPEED: 2893 rc = bfad_iocmd_ratelim_speed(bfad, cmd, iocmd); 2894 break; 2895 case IOCMD_FCPIM_FAILOVER: 2896 rc = bfad_iocmd_cfg_fcpim(bfad, iocmd); 2897 break; 2898 case IOCMD_FCPIM_MODSTATS: 2899 rc = bfad_iocmd_fcpim_get_modstats(bfad, iocmd); 2900 break; 2901 case IOCMD_FCPIM_MODSTATSCLR: 2902 rc = bfad_iocmd_fcpim_clr_modstats(bfad, iocmd); 2903 break; 2904 case IOCMD_FCPIM_DEL_ITN_STATS: 2905 rc = bfad_iocmd_fcpim_get_del_itn_stats(bfad, iocmd); 2906 break; 2907 case IOCMD_ITNIM_GET_ATTR: 2908 rc = bfad_iocmd_itnim_get_attr(bfad, iocmd); 2909 break; 2910 case IOCMD_ITNIM_GET_IOSTATS: 2911 rc = bfad_iocmd_itnim_get_iostats(bfad, iocmd); 2912 break; 2913 case IOCMD_ITNIM_RESET_STATS: 2914 rc = bfad_iocmd_itnim_reset_stats(bfad, iocmd); 2915 break; 2916 case IOCMD_ITNIM_GET_ITNSTATS: 2917 rc = bfad_iocmd_itnim_get_itnstats(bfad, iocmd); 2918 break; 2919 case IOCMD_FCPORT_ENABLE: 2920 rc = bfad_iocmd_fcport_enable(bfad, iocmd); 2921 break; 2922 case IOCMD_FCPORT_DISABLE: 2923 rc = bfad_iocmd_fcport_disable(bfad, iocmd); 2924 break; 2925 case IOCMD_IOC_PCIFN_CFG: 2926 rc = bfad_iocmd_ioc_get_pcifn_cfg(bfad, iocmd); 2927 break; 2928 case IOCMD_IOC_FW_SIG_INV: 2929 rc = bfad_iocmd_ioc_fw_sig_inv(bfad, iocmd); 2930 break; 2931 case IOCMD_PCIFN_CREATE: 2932 rc = bfad_iocmd_pcifn_create(bfad, iocmd); 2933 break; 2934 case IOCMD_PCIFN_DELETE: 2935 rc = bfad_iocmd_pcifn_delete(bfad, iocmd); 2936 break; 2937 case IOCMD_PCIFN_BW: 2938 rc = bfad_iocmd_pcifn_bw(bfad, iocmd); 2939 break; 2940 case IOCMD_ADAPTER_CFG_MODE: 2941 rc = bfad_iocmd_adapter_cfg_mode(bfad, iocmd); 2942 break; 2943 case IOCMD_PORT_CFG_MODE: 2944 rc = bfad_iocmd_port_cfg_mode(bfad, iocmd); 2945 break; 2946 case IOCMD_FLASH_ENABLE_OPTROM: 2947 case IOCMD_FLASH_DISABLE_OPTROM: 2948 rc = bfad_iocmd_ablk_optrom(bfad, cmd, iocmd); 2949 break; 2950 case IOCMD_FAA_QUERY: 2951 rc = bfad_iocmd_faa_query(bfad, iocmd); 2952 break; 2953 case IOCMD_CEE_GET_ATTR: 2954 rc = bfad_iocmd_cee_attr(bfad, iocmd, payload_len); 2955 break; 2956 case IOCMD_CEE_GET_STATS: 2957 rc = bfad_iocmd_cee_get_stats(bfad, iocmd, payload_len); 2958 break; 2959 case IOCMD_CEE_RESET_STATS: 2960 rc = bfad_iocmd_cee_reset_stats(bfad, iocmd); 2961 break; 2962 case IOCMD_SFP_MEDIA: 2963 rc = bfad_iocmd_sfp_media(bfad, iocmd); 2964 break; 2965 case IOCMD_SFP_SPEED: 2966 rc = bfad_iocmd_sfp_speed(bfad, iocmd); 2967 break; 2968 case IOCMD_FLASH_GET_ATTR: 2969 rc = bfad_iocmd_flash_get_attr(bfad, iocmd); 2970 break; 2971 case IOCMD_FLASH_ERASE_PART: 2972 rc = bfad_iocmd_flash_erase_part(bfad, iocmd); 2973 break; 2974 case IOCMD_FLASH_UPDATE_PART: 2975 rc = bfad_iocmd_flash_update_part(bfad, iocmd, payload_len); 2976 break; 2977 case IOCMD_FLASH_READ_PART: 2978 rc = bfad_iocmd_flash_read_part(bfad, iocmd, payload_len); 2979 break; 2980 case IOCMD_DIAG_TEMP: 2981 rc = bfad_iocmd_diag_temp(bfad, iocmd); 2982 break; 2983 case IOCMD_DIAG_MEMTEST: 2984 rc = bfad_iocmd_diag_memtest(bfad, iocmd); 2985 break; 2986 case IOCMD_DIAG_LOOPBACK: 2987 rc = bfad_iocmd_diag_loopback(bfad, iocmd); 2988 break; 2989 case IOCMD_DIAG_FWPING: 2990 rc = bfad_iocmd_diag_fwping(bfad, iocmd); 2991 break; 2992 case IOCMD_DIAG_QUEUETEST: 2993 rc = bfad_iocmd_diag_queuetest(bfad, iocmd); 2994 break; 2995 case IOCMD_DIAG_SFP: 2996 rc = bfad_iocmd_diag_sfp(bfad, iocmd); 2997 break; 2998 case IOCMD_DIAG_LED: 2999 rc = bfad_iocmd_diag_led(bfad, iocmd); 3000 break; 3001 case IOCMD_DIAG_BEACON_LPORT: 3002 rc = bfad_iocmd_diag_beacon_lport(bfad, iocmd); 3003 break; 3004 case IOCMD_DIAG_LB_STAT: 3005 rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); 3006 break; 3007 case IOCMD_DIAG_DPORT_ENABLE: 3008 rc = bfad_iocmd_diag_dport_enable(bfad, iocmd); 3009 break; 3010 case IOCMD_DIAG_DPORT_DISABLE: 3011 rc = bfad_iocmd_diag_dport_disable(bfad, iocmd); 3012 break; 3013 case IOCMD_DIAG_DPORT_SHOW: 3014 rc = bfad_iocmd_diag_dport_show(bfad, iocmd); 3015 break; 3016 case IOCMD_DIAG_DPORT_START: 3017 rc = bfad_iocmd_diag_dport_start(bfad, iocmd); 3018 break; 3019 case IOCMD_PHY_GET_ATTR: 3020 rc = bfad_iocmd_phy_get_attr(bfad, iocmd); 3021 break; 3022 case IOCMD_PHY_GET_STATS: 3023 rc = bfad_iocmd_phy_get_stats(bfad, iocmd); 3024 break; 3025 case IOCMD_PHY_UPDATE_FW: 3026 rc = bfad_iocmd_phy_update(bfad, iocmd, payload_len); 3027 break; 3028 case IOCMD_PHY_READ_FW: 3029 rc = bfad_iocmd_phy_read(bfad, iocmd, payload_len); 3030 break; 3031 case IOCMD_VHBA_QUERY: 3032 rc = bfad_iocmd_vhba_query(bfad, iocmd); 3033 break; 3034 case IOCMD_DEBUG_PORTLOG: 3035 rc = bfad_iocmd_porglog_get(bfad, iocmd); 3036 break; 3037 case IOCMD_DEBUG_FW_CORE: 3038 rc = bfad_iocmd_debug_fw_core(bfad, iocmd, payload_len); 3039 break; 3040 case IOCMD_DEBUG_FW_STATE_CLR: 3041 case IOCMD_DEBUG_PORTLOG_CLR: 3042 case IOCMD_DEBUG_START_DTRC: 3043 case IOCMD_DEBUG_STOP_DTRC: 3044 rc = bfad_iocmd_debug_ctl(bfad, iocmd, cmd); 3045 break; 3046 case IOCMD_DEBUG_PORTLOG_CTL: 3047 rc = bfad_iocmd_porglog_ctl(bfad, iocmd); 3048 break; 3049 case IOCMD_FCPIM_PROFILE_ON: 3050 case IOCMD_FCPIM_PROFILE_OFF: 3051 rc = bfad_iocmd_fcpim_cfg_profile(bfad, iocmd, cmd); 3052 break; 3053 case IOCMD_ITNIM_GET_IOPROFILE: 3054 rc = bfad_iocmd_itnim_get_ioprofile(bfad, iocmd); 3055 break; 3056 case IOCMD_FCPORT_GET_STATS: 3057 rc = bfad_iocmd_fcport_get_stats(bfad, iocmd); 3058 break; 3059 case IOCMD_FCPORT_RESET_STATS: 3060 rc = bfad_iocmd_fcport_reset_stats(bfad, iocmd); 3061 break; 3062 case IOCMD_BOOT_CFG: 3063 rc = bfad_iocmd_boot_cfg(bfad, iocmd); 3064 break; 3065 case IOCMD_BOOT_QUERY: 3066 rc = bfad_iocmd_boot_query(bfad, iocmd); 3067 break; 3068 case IOCMD_PREBOOT_QUERY: 3069 rc = bfad_iocmd_preboot_query(bfad, iocmd); 3070 break; 3071 case IOCMD_ETHBOOT_CFG: 3072 rc = bfad_iocmd_ethboot_cfg(bfad, iocmd); 3073 break; 3074 case IOCMD_ETHBOOT_QUERY: 3075 rc = bfad_iocmd_ethboot_query(bfad, iocmd); 3076 break; 3077 case IOCMD_TRUNK_ENABLE: 3078 case IOCMD_TRUNK_DISABLE: 3079 rc = bfad_iocmd_cfg_trunk(bfad, iocmd, cmd); 3080 break; 3081 case IOCMD_TRUNK_GET_ATTR: 3082 rc = bfad_iocmd_trunk_get_attr(bfad, iocmd); 3083 break; 3084 case IOCMD_QOS_ENABLE: 3085 case IOCMD_QOS_DISABLE: 3086 rc = bfad_iocmd_qos(bfad, iocmd, cmd); 3087 break; 3088 case IOCMD_QOS_GET_ATTR: 3089 rc = bfad_iocmd_qos_get_attr(bfad, iocmd); 3090 break; 3091 case IOCMD_QOS_GET_VC_ATTR: 3092 rc = bfad_iocmd_qos_get_vc_attr(bfad, iocmd); 3093 break; 3094 case IOCMD_QOS_GET_STATS: 3095 rc = bfad_iocmd_qos_get_stats(bfad, iocmd); 3096 break; 3097 case IOCMD_QOS_RESET_STATS: 3098 rc = bfad_iocmd_qos_reset_stats(bfad, iocmd); 3099 break; 3100 case IOCMD_QOS_SET_BW: 3101 rc = bfad_iocmd_qos_set_bw(bfad, iocmd); 3102 break; 3103 case IOCMD_VF_GET_STATS: 3104 rc = bfad_iocmd_vf_get_stats(bfad, iocmd); 3105 break; 3106 case IOCMD_VF_RESET_STATS: 3107 rc = bfad_iocmd_vf_clr_stats(bfad, iocmd); 3108 break; 3109 case IOCMD_FCPIM_LUNMASK_ENABLE: 3110 case IOCMD_FCPIM_LUNMASK_DISABLE: 3111 case IOCMD_FCPIM_LUNMASK_CLEAR: 3112 rc = bfad_iocmd_lunmask(bfad, iocmd, cmd); 3113 break; 3114 case IOCMD_FCPIM_LUNMASK_QUERY: 3115 rc = bfad_iocmd_fcpim_lunmask_query(bfad, iocmd); 3116 break; 3117 case IOCMD_FCPIM_LUNMASK_ADD: 3118 case IOCMD_FCPIM_LUNMASK_DELETE: 3119 rc = bfad_iocmd_fcpim_cfg_lunmask(bfad, iocmd, cmd); 3120 break; 3121 case IOCMD_FCPIM_THROTTLE_QUERY: 3122 rc = bfad_iocmd_fcpim_throttle_query(bfad, iocmd); 3123 break; 3124 case IOCMD_FCPIM_THROTTLE_SET: 3125 rc = bfad_iocmd_fcpim_throttle_set(bfad, iocmd); 3126 break; 3127 /* TFRU */ 3128 case IOCMD_TFRU_READ: 3129 rc = bfad_iocmd_tfru_read(bfad, iocmd); 3130 break; 3131 case IOCMD_TFRU_WRITE: 3132 rc = bfad_iocmd_tfru_write(bfad, iocmd); 3133 break; 3134 /* FRU */ 3135 case IOCMD_FRUVPD_READ: 3136 rc = bfad_iocmd_fruvpd_read(bfad, iocmd); 3137 break; 3138 case IOCMD_FRUVPD_UPDATE: 3139 rc = bfad_iocmd_fruvpd_update(bfad, iocmd); 3140 break; 3141 case IOCMD_FRUVPD_GET_MAX_SIZE: 3142 rc = bfad_iocmd_fruvpd_get_max_size(bfad, iocmd); 3143 break; 3144 default: 3145 rc = -EINVAL; 3146 break; 3147 } 3148 return rc; 3149 } 3150 3151 static int 3152 bfad_im_bsg_vendor_request(struct bsg_job *job) 3153 { 3154 struct fc_bsg_request *bsg_request = job->request; 3155 struct fc_bsg_reply *bsg_reply = job->reply; 3156 uint32_t vendor_cmd = bsg_request->rqst_data.h_vendor.vendor_cmd[0]; 3157 struct Scsi_Host *shost = fc_bsg_to_shost(job); 3158 struct bfad_im_port_s *im_port = bfad_get_im_port(shost); 3159 struct bfad_s *bfad = im_port->bfad; 3160 void *payload_kbuf; 3161 int rc = -EINVAL; 3162 3163 /* Allocate a temp buffer to hold the passed in user space command */ 3164 payload_kbuf = kzalloc(job->request_payload.payload_len, GFP_KERNEL); 3165 if (!payload_kbuf) { 3166 rc = -ENOMEM; 3167 goto out; 3168 } 3169 3170 /* Copy the sg_list passed in to a linear buffer: holds the cmnd data */ 3171 sg_copy_to_buffer(job->request_payload.sg_list, 3172 job->request_payload.sg_cnt, payload_kbuf, 3173 job->request_payload.payload_len); 3174 3175 /* Invoke IOCMD handler - to handle all the vendor command requests */ 3176 rc = bfad_iocmd_handler(bfad, vendor_cmd, payload_kbuf, 3177 job->request_payload.payload_len); 3178 if (rc != BFA_STATUS_OK) 3179 goto error; 3180 3181 /* Copy the response data to the job->reply_payload sg_list */ 3182 sg_copy_from_buffer(job->reply_payload.sg_list, 3183 job->reply_payload.sg_cnt, 3184 payload_kbuf, 3185 job->reply_payload.payload_len); 3186 3187 /* free the command buffer */ 3188 kfree(payload_kbuf); 3189 3190 /* Fill the BSG job reply data */ 3191 job->reply_len = job->reply_payload.payload_len; 3192 bsg_reply->reply_payload_rcv_len = job->reply_payload.payload_len; 3193 bsg_reply->result = rc; 3194 3195 bsg_job_done(job, bsg_reply->result, 3196 bsg_reply->reply_payload_rcv_len); 3197 return rc; 3198 error: 3199 /* free the command buffer */ 3200 kfree(payload_kbuf); 3201 out: 3202 bsg_reply->result = rc; 3203 job->reply_len = sizeof(uint32_t); 3204 bsg_reply->reply_payload_rcv_len = 0; 3205 return rc; 3206 } 3207 3208 /* FC passthru call backs */ 3209 static u64 3210 bfad_fcxp_get_req_sgaddr_cb(void *bfad_fcxp, int sgeid) 3211 { 3212 struct bfad_fcxp *drv_fcxp = bfad_fcxp; 3213 struct bfa_sge_s *sge; 3214 u64 addr; 3215 3216 sge = drv_fcxp->req_sge + sgeid; 3217 addr = (u64)(size_t) sge->sg_addr; 3218 return addr; 3219 } 3220 3221 static u32 3222 bfad_fcxp_get_req_sglen_cb(void *bfad_fcxp, int sgeid) 3223 { 3224 struct bfad_fcxp *drv_fcxp = bfad_fcxp; 3225 struct bfa_sge_s *sge; 3226 3227 sge = drv_fcxp->req_sge + sgeid; 3228 return sge->sg_len; 3229 } 3230 3231 static u64 3232 bfad_fcxp_get_rsp_sgaddr_cb(void *bfad_fcxp, int sgeid) 3233 { 3234 struct bfad_fcxp *drv_fcxp = bfad_fcxp; 3235 struct bfa_sge_s *sge; 3236 u64 addr; 3237 3238 sge = drv_fcxp->rsp_sge + sgeid; 3239 addr = (u64)(size_t) sge->sg_addr; 3240 return addr; 3241 } 3242 3243 static u32 3244 bfad_fcxp_get_rsp_sglen_cb(void *bfad_fcxp, int sgeid) 3245 { 3246 struct bfad_fcxp *drv_fcxp = bfad_fcxp; 3247 struct bfa_sge_s *sge; 3248 3249 sge = drv_fcxp->rsp_sge + sgeid; 3250 return sge->sg_len; 3251 } 3252 3253 static void 3254 bfad_send_fcpt_cb(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg, 3255 bfa_status_t req_status, u32 rsp_len, u32 resid_len, 3256 struct fchs_s *rsp_fchs) 3257 { 3258 struct bfad_fcxp *drv_fcxp = bfad_fcxp; 3259 3260 drv_fcxp->req_status = req_status; 3261 drv_fcxp->rsp_len = rsp_len; 3262 3263 /* bfa_fcxp will be automatically freed by BFA */ 3264 drv_fcxp->bfa_fcxp = NULL; 3265 complete(&drv_fcxp->comp); 3266 } 3267 3268 static struct bfad_buf_info * 3269 bfad_fcxp_map_sg(struct bfad_s *bfad, void *payload_kbuf, 3270 uint32_t payload_len, uint32_t *num_sgles) 3271 { 3272 struct bfad_buf_info *buf_base, *buf_info; 3273 struct bfa_sge_s *sg_table; 3274 int sge_num = 1; 3275 3276 buf_base = kcalloc(sizeof(struct bfad_buf_info) + 3277 sizeof(struct bfa_sge_s), 3278 sge_num, GFP_KERNEL); 3279 if (!buf_base) 3280 return NULL; 3281 3282 sg_table = (struct bfa_sge_s *) (((uint8_t *)buf_base) + 3283 (sizeof(struct bfad_buf_info) * sge_num)); 3284 3285 /* Allocate dma coherent memory */ 3286 buf_info = buf_base; 3287 buf_info->size = payload_len; 3288 buf_info->virt = dma_alloc_coherent(&bfad->pcidev->dev, 3289 buf_info->size, &buf_info->phys, 3290 GFP_KERNEL); 3291 if (!buf_info->virt) 3292 goto out_free_mem; 3293 3294 /* copy the linear bsg buffer to buf_info */ 3295 memcpy(buf_info->virt, payload_kbuf, buf_info->size); 3296 3297 /* 3298 * Setup SG table 3299 */ 3300 sg_table->sg_len = buf_info->size; 3301 sg_table->sg_addr = (void *)(size_t) buf_info->phys; 3302 3303 *num_sgles = sge_num; 3304 3305 return buf_base; 3306 3307 out_free_mem: 3308 kfree(buf_base); 3309 return NULL; 3310 } 3311 3312 static void 3313 bfad_fcxp_free_mem(struct bfad_s *bfad, struct bfad_buf_info *buf_base, 3314 uint32_t num_sgles) 3315 { 3316 int i; 3317 struct bfad_buf_info *buf_info = buf_base; 3318 3319 if (buf_base) { 3320 for (i = 0; i < num_sgles; buf_info++, i++) { 3321 if (buf_info->virt != NULL) 3322 dma_free_coherent(&bfad->pcidev->dev, 3323 buf_info->size, buf_info->virt, 3324 buf_info->phys); 3325 } 3326 kfree(buf_base); 3327 } 3328 } 3329 3330 static int 3331 bfad_fcxp_bsg_send(struct bsg_job *job, struct bfad_fcxp *drv_fcxp, 3332 bfa_bsg_fcpt_t *bsg_fcpt) 3333 { 3334 struct bfa_fcxp_s *hal_fcxp; 3335 struct bfad_s *bfad = drv_fcxp->port->bfad; 3336 unsigned long flags; 3337 uint8_t lp_tag; 3338 3339 spin_lock_irqsave(&bfad->bfad_lock, flags); 3340 3341 /* Allocate bfa_fcxp structure */ 3342 hal_fcxp = bfa_fcxp_req_rsp_alloc(drv_fcxp, &bfad->bfa, 3343 drv_fcxp->num_req_sgles, 3344 drv_fcxp->num_rsp_sgles, 3345 bfad_fcxp_get_req_sgaddr_cb, 3346 bfad_fcxp_get_req_sglen_cb, 3347 bfad_fcxp_get_rsp_sgaddr_cb, 3348 bfad_fcxp_get_rsp_sglen_cb, BFA_TRUE); 3349 if (!hal_fcxp) { 3350 bfa_trc(bfad, 0); 3351 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 3352 return BFA_STATUS_ENOMEM; 3353 } 3354 3355 drv_fcxp->bfa_fcxp = hal_fcxp; 3356 3357 lp_tag = bfa_lps_get_tag_from_pid(&bfad->bfa, bsg_fcpt->fchs.s_id); 3358 3359 bfa_fcxp_send(hal_fcxp, drv_fcxp->bfa_rport, bsg_fcpt->vf_id, lp_tag, 3360 bsg_fcpt->cts, bsg_fcpt->cos, 3361 job->request_payload.payload_len, 3362 &bsg_fcpt->fchs, bfad_send_fcpt_cb, bfad, 3363 job->reply_payload.payload_len, bsg_fcpt->tsecs); 3364 3365 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 3366 3367 return BFA_STATUS_OK; 3368 } 3369 3370 static int 3371 bfad_im_bsg_els_ct_request(struct bsg_job *job) 3372 { 3373 struct bfa_bsg_data *bsg_data; 3374 struct Scsi_Host *shost = fc_bsg_to_shost(job); 3375 struct bfad_im_port_s *im_port = bfad_get_im_port(shost); 3376 struct bfad_s *bfad = im_port->bfad; 3377 bfa_bsg_fcpt_t *bsg_fcpt; 3378 struct bfad_fcxp *drv_fcxp; 3379 struct bfa_fcs_lport_s *fcs_port; 3380 struct bfa_fcs_rport_s *fcs_rport; 3381 struct fc_bsg_request *bsg_request = job->request; 3382 struct fc_bsg_reply *bsg_reply = job->reply; 3383 uint32_t command_type = bsg_request->msgcode; 3384 unsigned long flags; 3385 struct bfad_buf_info *rsp_buf_info; 3386 void *req_kbuf = NULL, *rsp_kbuf = NULL; 3387 int rc = -EINVAL; 3388 3389 job->reply_len = sizeof(uint32_t); /* Atleast uint32_t reply_len */ 3390 bsg_reply->reply_payload_rcv_len = 0; 3391 3392 /* Get the payload passed in from userspace */ 3393 bsg_data = (struct bfa_bsg_data *) (((char *)bsg_request) + 3394 sizeof(struct fc_bsg_request)); 3395 if (bsg_data == NULL) 3396 goto out; 3397 3398 /* 3399 * Allocate buffer for bsg_fcpt and do a copy_from_user op for payload 3400 * buffer of size bsg_data->payload_len 3401 */ 3402 bsg_fcpt = kzalloc(bsg_data->payload_len, GFP_KERNEL); 3403 if (!bsg_fcpt) { 3404 rc = -ENOMEM; 3405 goto out; 3406 } 3407 3408 if (copy_from_user((uint8_t *)bsg_fcpt, 3409 (void *)(unsigned long)bsg_data->payload, 3410 bsg_data->payload_len)) { 3411 kfree(bsg_fcpt); 3412 rc = -EIO; 3413 goto out; 3414 } 3415 3416 drv_fcxp = kzalloc(sizeof(struct bfad_fcxp), GFP_KERNEL); 3417 if (drv_fcxp == NULL) { 3418 kfree(bsg_fcpt); 3419 rc = -ENOMEM; 3420 goto out; 3421 } 3422 3423 spin_lock_irqsave(&bfad->bfad_lock, flags); 3424 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, bsg_fcpt->vf_id, 3425 bsg_fcpt->lpwwn); 3426 if (fcs_port == NULL) { 3427 bsg_fcpt->status = BFA_STATUS_UNKNOWN_LWWN; 3428 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 3429 goto out_free_mem; 3430 } 3431 3432 /* Check if the port is online before sending FC Passthru cmd */ 3433 if (!bfa_fcs_lport_is_online(fcs_port)) { 3434 bsg_fcpt->status = BFA_STATUS_PORT_OFFLINE; 3435 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 3436 goto out_free_mem; 3437 } 3438 3439 drv_fcxp->port = fcs_port->bfad_port; 3440 3441 if (!drv_fcxp->port->bfad) 3442 drv_fcxp->port->bfad = bfad; 3443 3444 /* Fetch the bfa_rport - if nexus needed */ 3445 if (command_type == FC_BSG_HST_ELS_NOLOGIN || 3446 command_type == FC_BSG_HST_CT) { 3447 /* BSG HST commands: no nexus needed */ 3448 drv_fcxp->bfa_rport = NULL; 3449 3450 } else if (command_type == FC_BSG_RPT_ELS || 3451 command_type == FC_BSG_RPT_CT) { 3452 /* BSG RPT commands: nexus needed */ 3453 fcs_rport = bfa_fcs_lport_get_rport_by_pwwn(fcs_port, 3454 bsg_fcpt->dpwwn); 3455 if (fcs_rport == NULL) { 3456 bsg_fcpt->status = BFA_STATUS_UNKNOWN_RWWN; 3457 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 3458 goto out_free_mem; 3459 } 3460 3461 drv_fcxp->bfa_rport = fcs_rport->bfa_rport; 3462 3463 } else { /* Unknown BSG msgcode; return -EINVAL */ 3464 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 3465 goto out_free_mem; 3466 } 3467 3468 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 3469 3470 /* allocate memory for req / rsp buffers */ 3471 req_kbuf = kzalloc(job->request_payload.payload_len, GFP_KERNEL); 3472 if (!req_kbuf) { 3473 printk(KERN_INFO "bfa %s: fcpt request buffer alloc failed\n", 3474 bfad->pci_name); 3475 rc = -ENOMEM; 3476 goto out_free_mem; 3477 } 3478 3479 rsp_kbuf = kzalloc(job->reply_payload.payload_len, GFP_KERNEL); 3480 if (!rsp_kbuf) { 3481 printk(KERN_INFO "bfa %s: fcpt response buffer alloc failed\n", 3482 bfad->pci_name); 3483 rc = -ENOMEM; 3484 goto out_free_mem; 3485 } 3486 3487 /* map req sg - copy the sg_list passed in to the linear buffer */ 3488 sg_copy_to_buffer(job->request_payload.sg_list, 3489 job->request_payload.sg_cnt, req_kbuf, 3490 job->request_payload.payload_len); 3491 3492 drv_fcxp->reqbuf_info = bfad_fcxp_map_sg(bfad, req_kbuf, 3493 job->request_payload.payload_len, 3494 &drv_fcxp->num_req_sgles); 3495 if (!drv_fcxp->reqbuf_info) { 3496 printk(KERN_INFO "bfa %s: fcpt request fcxp_map_sg failed\n", 3497 bfad->pci_name); 3498 rc = -ENOMEM; 3499 goto out_free_mem; 3500 } 3501 3502 drv_fcxp->req_sge = (struct bfa_sge_s *) 3503 (((uint8_t *)drv_fcxp->reqbuf_info) + 3504 (sizeof(struct bfad_buf_info) * 3505 drv_fcxp->num_req_sgles)); 3506 3507 /* map rsp sg */ 3508 drv_fcxp->rspbuf_info = bfad_fcxp_map_sg(bfad, rsp_kbuf, 3509 job->reply_payload.payload_len, 3510 &drv_fcxp->num_rsp_sgles); 3511 if (!drv_fcxp->rspbuf_info) { 3512 printk(KERN_INFO "bfa %s: fcpt response fcxp_map_sg failed\n", 3513 bfad->pci_name); 3514 rc = -ENOMEM; 3515 goto out_free_mem; 3516 } 3517 3518 rsp_buf_info = (struct bfad_buf_info *)drv_fcxp->rspbuf_info; 3519 drv_fcxp->rsp_sge = (struct bfa_sge_s *) 3520 (((uint8_t *)drv_fcxp->rspbuf_info) + 3521 (sizeof(struct bfad_buf_info) * 3522 drv_fcxp->num_rsp_sgles)); 3523 3524 /* fcxp send */ 3525 init_completion(&drv_fcxp->comp); 3526 rc = bfad_fcxp_bsg_send(job, drv_fcxp, bsg_fcpt); 3527 if (rc == BFA_STATUS_OK) { 3528 wait_for_completion(&drv_fcxp->comp); 3529 bsg_fcpt->status = drv_fcxp->req_status; 3530 } else { 3531 bsg_fcpt->status = rc; 3532 goto out_free_mem; 3533 } 3534 3535 /* fill the job->reply data */ 3536 if (drv_fcxp->req_status == BFA_STATUS_OK) { 3537 job->reply_len = drv_fcxp->rsp_len; 3538 bsg_reply->reply_payload_rcv_len = drv_fcxp->rsp_len; 3539 bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK; 3540 } else { 3541 bsg_reply->reply_payload_rcv_len = 3542 sizeof(struct fc_bsg_ctels_reply); 3543 job->reply_len = sizeof(uint32_t); 3544 bsg_reply->reply_data.ctels_reply.status = 3545 FC_CTELS_STATUS_REJECT; 3546 } 3547 3548 /* Copy the response data to the reply_payload sg list */ 3549 sg_copy_from_buffer(job->reply_payload.sg_list, 3550 job->reply_payload.sg_cnt, 3551 (uint8_t *)rsp_buf_info->virt, 3552 job->reply_payload.payload_len); 3553 3554 out_free_mem: 3555 bfad_fcxp_free_mem(bfad, drv_fcxp->rspbuf_info, 3556 drv_fcxp->num_rsp_sgles); 3557 bfad_fcxp_free_mem(bfad, drv_fcxp->reqbuf_info, 3558 drv_fcxp->num_req_sgles); 3559 kfree(req_kbuf); 3560 kfree(rsp_kbuf); 3561 3562 /* Need a copy to user op */ 3563 if (copy_to_user((void *)(unsigned long)bsg_data->payload, 3564 (void *)bsg_fcpt, bsg_data->payload_len)) 3565 rc = -EIO; 3566 3567 kfree(bsg_fcpt); 3568 kfree(drv_fcxp); 3569 out: 3570 bsg_reply->result = rc; 3571 3572 if (rc == BFA_STATUS_OK) 3573 bsg_job_done(job, bsg_reply->result, 3574 bsg_reply->reply_payload_rcv_len); 3575 3576 return rc; 3577 } 3578 3579 int 3580 bfad_im_bsg_request(struct bsg_job *job) 3581 { 3582 struct fc_bsg_request *bsg_request = job->request; 3583 struct fc_bsg_reply *bsg_reply = job->reply; 3584 uint32_t rc = BFA_STATUS_OK; 3585 3586 switch (bsg_request->msgcode) { 3587 case FC_BSG_HST_VENDOR: 3588 /* Process BSG HST Vendor requests */ 3589 rc = bfad_im_bsg_vendor_request(job); 3590 break; 3591 case FC_BSG_HST_ELS_NOLOGIN: 3592 case FC_BSG_RPT_ELS: 3593 case FC_BSG_HST_CT: 3594 case FC_BSG_RPT_CT: 3595 /* Process BSG ELS/CT commands */ 3596 rc = bfad_im_bsg_els_ct_request(job); 3597 break; 3598 default: 3599 bsg_reply->result = rc = -EINVAL; 3600 bsg_reply->reply_payload_rcv_len = 0; 3601 break; 3602 } 3603 3604 return rc; 3605 } 3606 3607 int 3608 bfad_im_bsg_timeout(struct bsg_job *job) 3609 { 3610 /* Don't complete the BSG job request - return -EAGAIN 3611 * to reset bsg job timeout : for ELS/CT pass thru we 3612 * already have timer to track the request. 3613 */ 3614 return -EAGAIN; 3615 } 3616