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