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