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