bfad_bsg.c (99113B)
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 strlcpy(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 strlcpy(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(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, 2139 &fcomp, &iocmd->stats); 2140 spin_lock_irqsave(&bfad->bfad_lock, flags); 2141 iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); 2142 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2143 if (iocmd->status != BFA_STATUS_OK) { 2144 bfa_trc(bfad, iocmd->status); 2145 goto out; 2146 } 2147 wait_for_completion(&fcomp.comp); 2148 iocmd->status = fcomp.status; 2149out: 2150 return 0; 2151} 2152 2153static int 2154bfad_iocmd_fcport_reset_stats(struct bfad_s *bfad, void *cmd) 2155{ 2156 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 2157 struct bfad_hal_comp fcomp; 2158 unsigned long flags; 2159 struct bfa_cb_pending_q_s cb_qe; 2160 2161 init_completion(&fcomp.comp); 2162 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, &fcomp, NULL); 2163 2164 spin_lock_irqsave(&bfad->bfad_lock, flags); 2165 iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); 2166 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2167 if (iocmd->status != BFA_STATUS_OK) { 2168 bfa_trc(bfad, iocmd->status); 2169 goto out; 2170 } 2171 wait_for_completion(&fcomp.comp); 2172 iocmd->status = fcomp.status; 2173out: 2174 return 0; 2175} 2176 2177static int 2178bfad_iocmd_boot_cfg(struct bfad_s *bfad, void *cmd) 2179{ 2180 struct bfa_bsg_boot_s *iocmd = (struct bfa_bsg_boot_s *)cmd; 2181 struct bfad_hal_comp fcomp; 2182 unsigned long flags; 2183 2184 init_completion(&fcomp.comp); 2185 spin_lock_irqsave(&bfad->bfad_lock, flags); 2186 iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), 2187 BFA_FLASH_PART_BOOT, bfad->bfa.ioc.port_id, 2188 &iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0, 2189 bfad_hcb_comp, &fcomp); 2190 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2191 if (iocmd->status != BFA_STATUS_OK) 2192 goto out; 2193 wait_for_completion(&fcomp.comp); 2194 iocmd->status = fcomp.status; 2195out: 2196 return 0; 2197} 2198 2199static int 2200bfad_iocmd_boot_query(struct bfad_s *bfad, void *cmd) 2201{ 2202 struct bfa_bsg_boot_s *iocmd = (struct bfa_bsg_boot_s *)cmd; 2203 struct bfad_hal_comp fcomp; 2204 unsigned long flags; 2205 2206 init_completion(&fcomp.comp); 2207 spin_lock_irqsave(&bfad->bfad_lock, flags); 2208 iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), 2209 BFA_FLASH_PART_BOOT, bfad->bfa.ioc.port_id, 2210 &iocmd->cfg, sizeof(struct bfa_boot_cfg_s), 0, 2211 bfad_hcb_comp, &fcomp); 2212 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2213 if (iocmd->status != BFA_STATUS_OK) 2214 goto out; 2215 wait_for_completion(&fcomp.comp); 2216 iocmd->status = fcomp.status; 2217out: 2218 return 0; 2219} 2220 2221static int 2222bfad_iocmd_preboot_query(struct bfad_s *bfad, void *cmd) 2223{ 2224 struct bfa_bsg_preboot_s *iocmd = (struct bfa_bsg_preboot_s *)cmd; 2225 struct bfi_iocfc_cfgrsp_s *cfgrsp = bfad->bfa.iocfc.cfgrsp; 2226 struct bfa_boot_pbc_s *pbcfg = &iocmd->cfg; 2227 unsigned long flags; 2228 2229 spin_lock_irqsave(&bfad->bfad_lock, flags); 2230 pbcfg->enable = cfgrsp->pbc_cfg.boot_enabled; 2231 pbcfg->nbluns = cfgrsp->pbc_cfg.nbluns; 2232 pbcfg->speed = cfgrsp->pbc_cfg.port_speed; 2233 memcpy(pbcfg->pblun, cfgrsp->pbc_cfg.blun, sizeof(pbcfg->pblun)); 2234 iocmd->status = BFA_STATUS_OK; 2235 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2236 2237 return 0; 2238} 2239 2240static int 2241bfad_iocmd_ethboot_cfg(struct bfad_s *bfad, void *cmd) 2242{ 2243 struct bfa_bsg_ethboot_s *iocmd = (struct bfa_bsg_ethboot_s *)cmd; 2244 struct bfad_hal_comp fcomp; 2245 unsigned long flags; 2246 2247 init_completion(&fcomp.comp); 2248 spin_lock_irqsave(&bfad->bfad_lock, flags); 2249 iocmd->status = bfa_flash_update_part(BFA_FLASH(&bfad->bfa), 2250 BFA_FLASH_PART_PXECFG, 2251 bfad->bfa.ioc.port_id, &iocmd->cfg, 2252 sizeof(struct bfa_ethboot_cfg_s), 0, 2253 bfad_hcb_comp, &fcomp); 2254 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2255 if (iocmd->status != BFA_STATUS_OK) 2256 goto out; 2257 wait_for_completion(&fcomp.comp); 2258 iocmd->status = fcomp.status; 2259out: 2260 return 0; 2261} 2262 2263static int 2264bfad_iocmd_ethboot_query(struct bfad_s *bfad, void *cmd) 2265{ 2266 struct bfa_bsg_ethboot_s *iocmd = (struct bfa_bsg_ethboot_s *)cmd; 2267 struct bfad_hal_comp fcomp; 2268 unsigned long flags; 2269 2270 init_completion(&fcomp.comp); 2271 spin_lock_irqsave(&bfad->bfad_lock, flags); 2272 iocmd->status = bfa_flash_read_part(BFA_FLASH(&bfad->bfa), 2273 BFA_FLASH_PART_PXECFG, 2274 bfad->bfa.ioc.port_id, &iocmd->cfg, 2275 sizeof(struct bfa_ethboot_cfg_s), 0, 2276 bfad_hcb_comp, &fcomp); 2277 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2278 if (iocmd->status != BFA_STATUS_OK) 2279 goto out; 2280 wait_for_completion(&fcomp.comp); 2281 iocmd->status = fcomp.status; 2282out: 2283 return 0; 2284} 2285 2286static int 2287bfad_iocmd_cfg_trunk(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) 2288{ 2289 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 2290 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2291 struct bfa_fcport_trunk_s *trunk = &fcport->trunk; 2292 unsigned long flags; 2293 2294 spin_lock_irqsave(&bfad->bfad_lock, flags); 2295 2296 if (bfa_fcport_is_dport(&bfad->bfa)) { 2297 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2298 return BFA_STATUS_DPORT_ERR; 2299 } 2300 2301 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || 2302 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2303 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2304 else { 2305 if (v_cmd == IOCMD_TRUNK_ENABLE) { 2306 trunk->attr.state = BFA_TRUNK_OFFLINE; 2307 bfa_fcport_disable(&bfad->bfa); 2308 fcport->cfg.trunked = BFA_TRUE; 2309 } else if (v_cmd == IOCMD_TRUNK_DISABLE) { 2310 trunk->attr.state = BFA_TRUNK_DISABLED; 2311 bfa_fcport_disable(&bfad->bfa); 2312 fcport->cfg.trunked = BFA_FALSE; 2313 } 2314 2315 if (!bfa_fcport_is_disabled(&bfad->bfa)) 2316 bfa_fcport_enable(&bfad->bfa); 2317 2318 iocmd->status = BFA_STATUS_OK; 2319 } 2320 2321 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2322 2323 return 0; 2324} 2325 2326static int 2327bfad_iocmd_trunk_get_attr(struct bfad_s *bfad, void *cmd) 2328{ 2329 struct bfa_bsg_trunk_attr_s *iocmd = (struct bfa_bsg_trunk_attr_s *)cmd; 2330 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2331 struct bfa_fcport_trunk_s *trunk = &fcport->trunk; 2332 unsigned long flags; 2333 2334 spin_lock_irqsave(&bfad->bfad_lock, flags); 2335 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) || 2336 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2337 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2338 else { 2339 memcpy((void *)&iocmd->attr, (void *)&trunk->attr, 2340 sizeof(struct bfa_trunk_attr_s)); 2341 iocmd->attr.port_id = bfa_lps_get_base_pid(&bfad->bfa); 2342 iocmd->status = BFA_STATUS_OK; 2343 } 2344 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2345 2346 return 0; 2347} 2348 2349static int 2350bfad_iocmd_qos(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) 2351{ 2352 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 2353 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2354 unsigned long flags; 2355 2356 spin_lock_irqsave(&bfad->bfad_lock, flags); 2357 if (bfa_ioc_get_type(&bfad->bfa.ioc) == BFA_IOC_TYPE_FC) { 2358 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 2359 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2360 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2361 else { 2362 if (v_cmd == IOCMD_QOS_ENABLE) 2363 fcport->cfg.qos_enabled = BFA_TRUE; 2364 else if (v_cmd == IOCMD_QOS_DISABLE) { 2365 fcport->cfg.qos_enabled = BFA_FALSE; 2366 fcport->cfg.qos_bw.high = BFA_QOS_BW_HIGH; 2367 fcport->cfg.qos_bw.med = BFA_QOS_BW_MED; 2368 fcport->cfg.qos_bw.low = BFA_QOS_BW_LOW; 2369 } 2370 } 2371 } 2372 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2373 2374 return 0; 2375} 2376 2377static int 2378bfad_iocmd_qos_get_attr(struct bfad_s *bfad, void *cmd) 2379{ 2380 struct bfa_bsg_qos_attr_s *iocmd = (struct bfa_bsg_qos_attr_s *)cmd; 2381 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2382 unsigned long flags; 2383 2384 spin_lock_irqsave(&bfad->bfad_lock, flags); 2385 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 2386 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2387 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2388 else { 2389 iocmd->attr.state = fcport->qos_attr.state; 2390 iocmd->attr.total_bb_cr = 2391 be32_to_cpu(fcport->qos_attr.total_bb_cr); 2392 iocmd->attr.qos_bw.high = fcport->cfg.qos_bw.high; 2393 iocmd->attr.qos_bw.med = fcport->cfg.qos_bw.med; 2394 iocmd->attr.qos_bw.low = fcport->cfg.qos_bw.low; 2395 iocmd->attr.qos_bw_op = fcport->qos_attr.qos_bw_op; 2396 iocmd->status = BFA_STATUS_OK; 2397 } 2398 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2399 2400 return 0; 2401} 2402 2403static int 2404bfad_iocmd_qos_get_vc_attr(struct bfad_s *bfad, void *cmd) 2405{ 2406 struct bfa_bsg_qos_vc_attr_s *iocmd = 2407 (struct bfa_bsg_qos_vc_attr_s *)cmd; 2408 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2409 struct bfa_qos_vc_attr_s *bfa_vc_attr = &fcport->qos_vc_attr; 2410 unsigned long flags; 2411 u32 i = 0; 2412 2413 spin_lock_irqsave(&bfad->bfad_lock, flags); 2414 iocmd->attr.total_vc_count = be16_to_cpu(bfa_vc_attr->total_vc_count); 2415 iocmd->attr.shared_credit = be16_to_cpu(bfa_vc_attr->shared_credit); 2416 iocmd->attr.elp_opmode_flags = 2417 be32_to_cpu(bfa_vc_attr->elp_opmode_flags); 2418 2419 /* Individual VC info */ 2420 while (i < iocmd->attr.total_vc_count) { 2421 iocmd->attr.vc_info[i].vc_credit = 2422 bfa_vc_attr->vc_info[i].vc_credit; 2423 iocmd->attr.vc_info[i].borrow_credit = 2424 bfa_vc_attr->vc_info[i].borrow_credit; 2425 iocmd->attr.vc_info[i].priority = 2426 bfa_vc_attr->vc_info[i].priority; 2427 i++; 2428 } 2429 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2430 2431 iocmd->status = BFA_STATUS_OK; 2432 return 0; 2433} 2434 2435static int 2436bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd) 2437{ 2438 struct bfa_bsg_fcport_stats_s *iocmd = 2439 (struct bfa_bsg_fcport_stats_s *)cmd; 2440 struct bfad_hal_comp fcomp; 2441 unsigned long flags; 2442 struct bfa_cb_pending_q_s cb_qe; 2443 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2444 2445 init_completion(&fcomp.comp); 2446 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, 2447 &fcomp, &iocmd->stats); 2448 2449 spin_lock_irqsave(&bfad->bfad_lock, flags); 2450 WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); 2451 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 2452 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2453 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2454 else 2455 iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); 2456 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2457 if (iocmd->status != BFA_STATUS_OK) { 2458 bfa_trc(bfad, iocmd->status); 2459 goto out; 2460 } 2461 wait_for_completion(&fcomp.comp); 2462 iocmd->status = fcomp.status; 2463out: 2464 return 0; 2465} 2466 2467static int 2468bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd) 2469{ 2470 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd; 2471 struct bfad_hal_comp fcomp; 2472 unsigned long flags; 2473 struct bfa_cb_pending_q_s cb_qe; 2474 struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); 2475 2476 init_completion(&fcomp.comp); 2477 bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, 2478 &fcomp, NULL); 2479 2480 spin_lock_irqsave(&bfad->bfad_lock, flags); 2481 WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); 2482 if ((fcport->cfg.topology == BFA_PORT_TOPOLOGY_LOOP) && 2483 (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)) 2484 iocmd->status = BFA_STATUS_TOPOLOGY_LOOP; 2485 else 2486 iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); 2487 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2488 if (iocmd->status != BFA_STATUS_OK) { 2489 bfa_trc(bfad, iocmd->status); 2490 goto out; 2491 } 2492 wait_for_completion(&fcomp.comp); 2493 iocmd->status = fcomp.status; 2494out: 2495 return 0; 2496} 2497 2498static int 2499bfad_iocmd_vf_get_stats(struct bfad_s *bfad, void *cmd) 2500{ 2501 struct bfa_bsg_vf_stats_s *iocmd = 2502 (struct bfa_bsg_vf_stats_s *)cmd; 2503 struct bfa_fcs_fabric_s *fcs_vf; 2504 unsigned long flags; 2505 2506 spin_lock_irqsave(&bfad->bfad_lock, flags); 2507 fcs_vf = bfa_fcs_vf_lookup(&bfad->bfa_fcs, iocmd->vf_id); 2508 if (fcs_vf == NULL) { 2509 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2510 iocmd->status = BFA_STATUS_UNKNOWN_VFID; 2511 goto out; 2512 } 2513 memcpy((void *)&iocmd->stats, (void *)&fcs_vf->stats, 2514 sizeof(struct bfa_vf_stats_s)); 2515 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2516 iocmd->status = BFA_STATUS_OK; 2517out: 2518 return 0; 2519} 2520 2521static int 2522bfad_iocmd_vf_clr_stats(struct bfad_s *bfad, void *cmd) 2523{ 2524 struct bfa_bsg_vf_reset_stats_s *iocmd = 2525 (struct bfa_bsg_vf_reset_stats_s *)cmd; 2526 struct bfa_fcs_fabric_s *fcs_vf; 2527 unsigned long flags; 2528 2529 spin_lock_irqsave(&bfad->bfad_lock, flags); 2530 fcs_vf = bfa_fcs_vf_lookup(&bfad->bfa_fcs, iocmd->vf_id); 2531 if (fcs_vf == NULL) { 2532 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2533 iocmd->status = BFA_STATUS_UNKNOWN_VFID; 2534 goto out; 2535 } 2536 memset((void *)&fcs_vf->stats, 0, sizeof(struct bfa_vf_stats_s)); 2537 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2538 iocmd->status = BFA_STATUS_OK; 2539out: 2540 return 0; 2541} 2542 2543/* Function to reset the LUN SCAN mode */ 2544static void 2545bfad_iocmd_lunmask_reset_lunscan_mode(struct bfad_s *bfad, int lunmask_cfg) 2546{ 2547 struct bfad_im_port_s *pport_im = bfad->pport.im_port; 2548 struct bfad_vport_s *vport = NULL; 2549 2550 /* Set the scsi device LUN SCAN flags for base port */ 2551 bfad_reset_sdev_bflags(pport_im, lunmask_cfg); 2552 2553 /* Set the scsi device LUN SCAN flags for the vports */ 2554 list_for_each_entry(vport, &bfad->vport_list, list_entry) 2555 bfad_reset_sdev_bflags(vport->drv_port.im_port, lunmask_cfg); 2556} 2557 2558static int 2559bfad_iocmd_lunmask(struct bfad_s *bfad, void *pcmd, unsigned int v_cmd) 2560{ 2561 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd; 2562 unsigned long flags; 2563 2564 spin_lock_irqsave(&bfad->bfad_lock, flags); 2565 if (v_cmd == IOCMD_FCPIM_LUNMASK_ENABLE) { 2566 iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_TRUE); 2567 /* Set the LUN Scanning mode to be Sequential scan */ 2568 if (iocmd->status == BFA_STATUS_OK) 2569 bfad_iocmd_lunmask_reset_lunscan_mode(bfad, BFA_TRUE); 2570 } else if (v_cmd == IOCMD_FCPIM_LUNMASK_DISABLE) { 2571 iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_FALSE); 2572 /* Set the LUN Scanning mode to default REPORT_LUNS scan */ 2573 if (iocmd->status == BFA_STATUS_OK) 2574 bfad_iocmd_lunmask_reset_lunscan_mode(bfad, BFA_FALSE); 2575 } else if (v_cmd == IOCMD_FCPIM_LUNMASK_CLEAR) 2576 iocmd->status = bfa_fcpim_lunmask_clear(&bfad->bfa); 2577 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2578 return 0; 2579} 2580 2581static int 2582bfad_iocmd_fcpim_lunmask_query(struct bfad_s *bfad, void *cmd) 2583{ 2584 struct bfa_bsg_fcpim_lunmask_query_s *iocmd = 2585 (struct bfa_bsg_fcpim_lunmask_query_s *)cmd; 2586 struct bfa_lunmask_cfg_s *lun_mask = &iocmd->lun_mask; 2587 unsigned long flags; 2588 2589 spin_lock_irqsave(&bfad->bfad_lock, flags); 2590 iocmd->status = bfa_fcpim_lunmask_query(&bfad->bfa, lun_mask); 2591 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2592 return 0; 2593} 2594 2595static int 2596bfad_iocmd_fcpim_cfg_lunmask(struct bfad_s *bfad, void *cmd, unsigned int v_cmd) 2597{ 2598 struct bfa_bsg_fcpim_lunmask_s *iocmd = 2599 (struct bfa_bsg_fcpim_lunmask_s *)cmd; 2600 unsigned long flags; 2601 2602 spin_lock_irqsave(&bfad->bfad_lock, flags); 2603 if (v_cmd == IOCMD_FCPIM_LUNMASK_ADD) 2604 iocmd->status = bfa_fcpim_lunmask_add(&bfad->bfa, iocmd->vf_id, 2605 &iocmd->pwwn, iocmd->rpwwn, iocmd->lun); 2606 else if (v_cmd == IOCMD_FCPIM_LUNMASK_DELETE) 2607 iocmd->status = bfa_fcpim_lunmask_delete(&bfad->bfa, 2608 iocmd->vf_id, &iocmd->pwwn, 2609 iocmd->rpwwn, iocmd->lun); 2610 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2611 return 0; 2612} 2613 2614static int 2615bfad_iocmd_fcpim_throttle_query(struct bfad_s *bfad, void *cmd) 2616{ 2617 struct bfa_bsg_fcpim_throttle_s *iocmd = 2618 (struct bfa_bsg_fcpim_throttle_s *)cmd; 2619 unsigned long flags; 2620 2621 spin_lock_irqsave(&bfad->bfad_lock, flags); 2622 iocmd->status = bfa_fcpim_throttle_get(&bfad->bfa, 2623 (void *)&iocmd->throttle); 2624 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2625 2626 return 0; 2627} 2628 2629static int 2630bfad_iocmd_fcpim_throttle_set(struct bfad_s *bfad, void *cmd) 2631{ 2632 struct bfa_bsg_fcpim_throttle_s *iocmd = 2633 (struct bfa_bsg_fcpim_throttle_s *)cmd; 2634 unsigned long flags; 2635 2636 spin_lock_irqsave(&bfad->bfad_lock, flags); 2637 iocmd->status = bfa_fcpim_throttle_set(&bfad->bfa, 2638 iocmd->throttle.cfg_value); 2639 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2640 2641 return 0; 2642} 2643 2644static int 2645bfad_iocmd_tfru_read(struct bfad_s *bfad, void *cmd) 2646{ 2647 struct bfa_bsg_tfru_s *iocmd = 2648 (struct bfa_bsg_tfru_s *)cmd; 2649 struct bfad_hal_comp fcomp; 2650 unsigned long flags = 0; 2651 2652 init_completion(&fcomp.comp); 2653 spin_lock_irqsave(&bfad->bfad_lock, flags); 2654 iocmd->status = bfa_tfru_read(BFA_FRU(&bfad->bfa), 2655 &iocmd->data, iocmd->len, iocmd->offset, 2656 bfad_hcb_comp, &fcomp); 2657 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2658 if (iocmd->status == BFA_STATUS_OK) { 2659 wait_for_completion(&fcomp.comp); 2660 iocmd->status = fcomp.status; 2661 } 2662 2663 return 0; 2664} 2665 2666static int 2667bfad_iocmd_tfru_write(struct bfad_s *bfad, void *cmd) 2668{ 2669 struct bfa_bsg_tfru_s *iocmd = 2670 (struct bfa_bsg_tfru_s *)cmd; 2671 struct bfad_hal_comp fcomp; 2672 unsigned long flags = 0; 2673 2674 init_completion(&fcomp.comp); 2675 spin_lock_irqsave(&bfad->bfad_lock, flags); 2676 iocmd->status = bfa_tfru_write(BFA_FRU(&bfad->bfa), 2677 &iocmd->data, iocmd->len, iocmd->offset, 2678 bfad_hcb_comp, &fcomp); 2679 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2680 if (iocmd->status == BFA_STATUS_OK) { 2681 wait_for_completion(&fcomp.comp); 2682 iocmd->status = fcomp.status; 2683 } 2684 2685 return 0; 2686} 2687 2688static int 2689bfad_iocmd_fruvpd_read(struct bfad_s *bfad, void *cmd) 2690{ 2691 struct bfa_bsg_fruvpd_s *iocmd = 2692 (struct bfa_bsg_fruvpd_s *)cmd; 2693 struct bfad_hal_comp fcomp; 2694 unsigned long flags = 0; 2695 2696 init_completion(&fcomp.comp); 2697 spin_lock_irqsave(&bfad->bfad_lock, flags); 2698 iocmd->status = bfa_fruvpd_read(BFA_FRU(&bfad->bfa), 2699 &iocmd->data, iocmd->len, iocmd->offset, 2700 bfad_hcb_comp, &fcomp); 2701 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2702 if (iocmd->status == BFA_STATUS_OK) { 2703 wait_for_completion(&fcomp.comp); 2704 iocmd->status = fcomp.status; 2705 } 2706 2707 return 0; 2708} 2709 2710static int 2711bfad_iocmd_fruvpd_update(struct bfad_s *bfad, void *cmd) 2712{ 2713 struct bfa_bsg_fruvpd_s *iocmd = 2714 (struct bfa_bsg_fruvpd_s *)cmd; 2715 struct bfad_hal_comp fcomp; 2716 unsigned long flags = 0; 2717 2718 init_completion(&fcomp.comp); 2719 spin_lock_irqsave(&bfad->bfad_lock, flags); 2720 iocmd->status = bfa_fruvpd_update(BFA_FRU(&bfad->bfa), 2721 &iocmd->data, iocmd->len, iocmd->offset, 2722 bfad_hcb_comp, &fcomp, iocmd->trfr_cmpl); 2723 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2724 if (iocmd->status == BFA_STATUS_OK) { 2725 wait_for_completion(&fcomp.comp); 2726 iocmd->status = fcomp.status; 2727 } 2728 2729 return 0; 2730} 2731 2732static int 2733bfad_iocmd_fruvpd_get_max_size(struct bfad_s *bfad, void *cmd) 2734{ 2735 struct bfa_bsg_fruvpd_max_size_s *iocmd = 2736 (struct bfa_bsg_fruvpd_max_size_s *)cmd; 2737 unsigned long flags = 0; 2738 2739 spin_lock_irqsave(&bfad->bfad_lock, flags); 2740 iocmd->status = bfa_fruvpd_get_max_size(BFA_FRU(&bfad->bfa), 2741 &iocmd->max_size); 2742 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2743 2744 return 0; 2745} 2746 2747static int 2748bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd, 2749 unsigned int payload_len) 2750{ 2751 int rc = -EINVAL; 2752 2753 switch (cmd) { 2754 case IOCMD_IOC_ENABLE: 2755 rc = bfad_iocmd_ioc_enable(bfad, iocmd); 2756 break; 2757 case IOCMD_IOC_DISABLE: 2758 rc = bfad_iocmd_ioc_disable(bfad, iocmd); 2759 break; 2760 case IOCMD_IOC_GET_INFO: 2761 rc = bfad_iocmd_ioc_get_info(bfad, iocmd); 2762 break; 2763 case IOCMD_IOC_GET_ATTR: 2764 rc = bfad_iocmd_ioc_get_attr(bfad, iocmd); 2765 break; 2766 case IOCMD_IOC_GET_STATS: 2767 rc = bfad_iocmd_ioc_get_stats(bfad, iocmd); 2768 break; 2769 case IOCMD_IOC_GET_FWSTATS: 2770 rc = bfad_iocmd_ioc_get_fwstats(bfad, iocmd, payload_len); 2771 break; 2772 case IOCMD_IOC_RESET_STATS: 2773 case IOCMD_IOC_RESET_FWSTATS: 2774 rc = bfad_iocmd_ioc_reset_stats(bfad, iocmd, cmd); 2775 break; 2776 case IOCMD_IOC_SET_ADAPTER_NAME: 2777 case IOCMD_IOC_SET_PORT_NAME: 2778 rc = bfad_iocmd_ioc_set_name(bfad, iocmd, cmd); 2779 break; 2780 case IOCMD_IOCFC_GET_ATTR: 2781 rc = bfad_iocmd_iocfc_get_attr(bfad, iocmd); 2782 break; 2783 case IOCMD_IOCFC_SET_INTR: 2784 rc = bfad_iocmd_iocfc_set_intr(bfad, iocmd); 2785 break; 2786 case IOCMD_PORT_ENABLE: 2787 rc = bfad_iocmd_port_enable(bfad, iocmd); 2788 break; 2789 case IOCMD_PORT_DISABLE: 2790 rc = bfad_iocmd_port_disable(bfad, iocmd); 2791 break; 2792 case IOCMD_PORT_GET_ATTR: 2793 rc = bfad_iocmd_port_get_attr(bfad, iocmd); 2794 break; 2795 case IOCMD_PORT_GET_STATS: 2796 rc = bfad_iocmd_port_get_stats(bfad, iocmd, payload_len); 2797 break; 2798 case IOCMD_PORT_RESET_STATS: 2799 rc = bfad_iocmd_port_reset_stats(bfad, iocmd); 2800 break; 2801 case IOCMD_PORT_CFG_TOPO: 2802 case IOCMD_PORT_CFG_SPEED: 2803 case IOCMD_PORT_CFG_ALPA: 2804 case IOCMD_PORT_CLR_ALPA: 2805 rc = bfad_iocmd_set_port_cfg(bfad, iocmd, cmd); 2806 break; 2807 case IOCMD_PORT_CFG_MAXFRSZ: 2808 rc = bfad_iocmd_port_cfg_maxfrsize(bfad, iocmd); 2809 break; 2810 case IOCMD_PORT_BBCR_ENABLE: 2811 case IOCMD_PORT_BBCR_DISABLE: 2812 rc = bfad_iocmd_port_cfg_bbcr(bfad, cmd, iocmd); 2813 break; 2814 case IOCMD_PORT_BBCR_GET_ATTR: 2815 rc = bfad_iocmd_port_get_bbcr_attr(bfad, iocmd); 2816 break; 2817 case IOCMD_LPORT_GET_ATTR: 2818 rc = bfad_iocmd_lport_get_attr(bfad, iocmd); 2819 break; 2820 case IOCMD_LPORT_GET_STATS: 2821 rc = bfad_iocmd_lport_get_stats(bfad, iocmd); 2822 break; 2823 case IOCMD_LPORT_RESET_STATS: 2824 rc = bfad_iocmd_lport_reset_stats(bfad, iocmd); 2825 break; 2826 case IOCMD_LPORT_GET_IOSTATS: 2827 rc = bfad_iocmd_lport_get_iostats(bfad, iocmd); 2828 break; 2829 case IOCMD_LPORT_GET_RPORTS: 2830 rc = bfad_iocmd_lport_get_rports(bfad, iocmd, payload_len); 2831 break; 2832 case IOCMD_RPORT_GET_ATTR: 2833 rc = bfad_iocmd_rport_get_attr(bfad, iocmd); 2834 break; 2835 case IOCMD_RPORT_GET_ADDR: 2836 rc = bfad_iocmd_rport_get_addr(bfad, iocmd); 2837 break; 2838 case IOCMD_RPORT_GET_STATS: 2839 rc = bfad_iocmd_rport_get_stats(bfad, iocmd); 2840 break; 2841 case IOCMD_RPORT_RESET_STATS: 2842 rc = bfad_iocmd_rport_clr_stats(bfad, iocmd); 2843 break; 2844 case IOCMD_RPORT_SET_SPEED: 2845 rc = bfad_iocmd_rport_set_speed(bfad, iocmd); 2846 break; 2847 case IOCMD_VPORT_GET_ATTR: 2848 rc = bfad_iocmd_vport_get_attr(bfad, iocmd); 2849 break; 2850 case IOCMD_VPORT_GET_STATS: 2851 rc = bfad_iocmd_vport_get_stats(bfad, iocmd); 2852 break; 2853 case IOCMD_VPORT_RESET_STATS: 2854 rc = bfad_iocmd_vport_clr_stats(bfad, iocmd); 2855 break; 2856 case IOCMD_FABRIC_GET_LPORTS: 2857 rc = bfad_iocmd_fabric_get_lports(bfad, iocmd, payload_len); 2858 break; 2859 case IOCMD_RATELIM_ENABLE: 2860 case IOCMD_RATELIM_DISABLE: 2861 rc = bfad_iocmd_ratelim(bfad, cmd, iocmd); 2862 break; 2863 case IOCMD_RATELIM_DEF_SPEED: 2864 rc = bfad_iocmd_ratelim_speed(bfad, cmd, iocmd); 2865 break; 2866 case IOCMD_FCPIM_FAILOVER: 2867 rc = bfad_iocmd_cfg_fcpim(bfad, iocmd); 2868 break; 2869 case IOCMD_FCPIM_MODSTATS: 2870 rc = bfad_iocmd_fcpim_get_modstats(bfad, iocmd); 2871 break; 2872 case IOCMD_FCPIM_MODSTATSCLR: 2873 rc = bfad_iocmd_fcpim_clr_modstats(bfad, iocmd); 2874 break; 2875 case IOCMD_FCPIM_DEL_ITN_STATS: 2876 rc = bfad_iocmd_fcpim_get_del_itn_stats(bfad, iocmd); 2877 break; 2878 case IOCMD_ITNIM_GET_ATTR: 2879 rc = bfad_iocmd_itnim_get_attr(bfad, iocmd); 2880 break; 2881 case IOCMD_ITNIM_GET_IOSTATS: 2882 rc = bfad_iocmd_itnim_get_iostats(bfad, iocmd); 2883 break; 2884 case IOCMD_ITNIM_RESET_STATS: 2885 rc = bfad_iocmd_itnim_reset_stats(bfad, iocmd); 2886 break; 2887 case IOCMD_ITNIM_GET_ITNSTATS: 2888 rc = bfad_iocmd_itnim_get_itnstats(bfad, iocmd); 2889 break; 2890 case IOCMD_FCPORT_ENABLE: 2891 rc = bfad_iocmd_fcport_enable(bfad, iocmd); 2892 break; 2893 case IOCMD_FCPORT_DISABLE: 2894 rc = bfad_iocmd_fcport_disable(bfad, iocmd); 2895 break; 2896 case IOCMD_IOC_PCIFN_CFG: 2897 rc = bfad_iocmd_ioc_get_pcifn_cfg(bfad, iocmd); 2898 break; 2899 case IOCMD_IOC_FW_SIG_INV: 2900 rc = bfad_iocmd_ioc_fw_sig_inv(bfad, iocmd); 2901 break; 2902 case IOCMD_PCIFN_CREATE: 2903 rc = bfad_iocmd_pcifn_create(bfad, iocmd); 2904 break; 2905 case IOCMD_PCIFN_DELETE: 2906 rc = bfad_iocmd_pcifn_delete(bfad, iocmd); 2907 break; 2908 case IOCMD_PCIFN_BW: 2909 rc = bfad_iocmd_pcifn_bw(bfad, iocmd); 2910 break; 2911 case IOCMD_ADAPTER_CFG_MODE: 2912 rc = bfad_iocmd_adapter_cfg_mode(bfad, iocmd); 2913 break; 2914 case IOCMD_PORT_CFG_MODE: 2915 rc = bfad_iocmd_port_cfg_mode(bfad, iocmd); 2916 break; 2917 case IOCMD_FLASH_ENABLE_OPTROM: 2918 case IOCMD_FLASH_DISABLE_OPTROM: 2919 rc = bfad_iocmd_ablk_optrom(bfad, cmd, iocmd); 2920 break; 2921 case IOCMD_FAA_QUERY: 2922 rc = bfad_iocmd_faa_query(bfad, iocmd); 2923 break; 2924 case IOCMD_CEE_GET_ATTR: 2925 rc = bfad_iocmd_cee_attr(bfad, iocmd, payload_len); 2926 break; 2927 case IOCMD_CEE_GET_STATS: 2928 rc = bfad_iocmd_cee_get_stats(bfad, iocmd, payload_len); 2929 break; 2930 case IOCMD_CEE_RESET_STATS: 2931 rc = bfad_iocmd_cee_reset_stats(bfad, iocmd); 2932 break; 2933 case IOCMD_SFP_MEDIA: 2934 rc = bfad_iocmd_sfp_media(bfad, iocmd); 2935 break; 2936 case IOCMD_SFP_SPEED: 2937 rc = bfad_iocmd_sfp_speed(bfad, iocmd); 2938 break; 2939 case IOCMD_FLASH_GET_ATTR: 2940 rc = bfad_iocmd_flash_get_attr(bfad, iocmd); 2941 break; 2942 case IOCMD_FLASH_ERASE_PART: 2943 rc = bfad_iocmd_flash_erase_part(bfad, iocmd); 2944 break; 2945 case IOCMD_FLASH_UPDATE_PART: 2946 rc = bfad_iocmd_flash_update_part(bfad, iocmd, payload_len); 2947 break; 2948 case IOCMD_FLASH_READ_PART: 2949 rc = bfad_iocmd_flash_read_part(bfad, iocmd, payload_len); 2950 break; 2951 case IOCMD_DIAG_TEMP: 2952 rc = bfad_iocmd_diag_temp(bfad, iocmd); 2953 break; 2954 case IOCMD_DIAG_MEMTEST: 2955 rc = bfad_iocmd_diag_memtest(bfad, iocmd); 2956 break; 2957 case IOCMD_DIAG_LOOPBACK: 2958 rc = bfad_iocmd_diag_loopback(bfad, iocmd); 2959 break; 2960 case IOCMD_DIAG_FWPING: 2961 rc = bfad_iocmd_diag_fwping(bfad, iocmd); 2962 break; 2963 case IOCMD_DIAG_QUEUETEST: 2964 rc = bfad_iocmd_diag_queuetest(bfad, iocmd); 2965 break; 2966 case IOCMD_DIAG_SFP: 2967 rc = bfad_iocmd_diag_sfp(bfad, iocmd); 2968 break; 2969 case IOCMD_DIAG_LED: 2970 rc = bfad_iocmd_diag_led(bfad, iocmd); 2971 break; 2972 case IOCMD_DIAG_BEACON_LPORT: 2973 rc = bfad_iocmd_diag_beacon_lport(bfad, iocmd); 2974 break; 2975 case IOCMD_DIAG_LB_STAT: 2976 rc = bfad_iocmd_diag_lb_stat(bfad, iocmd); 2977 break; 2978 case IOCMD_DIAG_DPORT_ENABLE: 2979 rc = bfad_iocmd_diag_dport_enable(bfad, iocmd); 2980 break; 2981 case IOCMD_DIAG_DPORT_DISABLE: 2982 rc = bfad_iocmd_diag_dport_disable(bfad, iocmd); 2983 break; 2984 case IOCMD_DIAG_DPORT_SHOW: 2985 rc = bfad_iocmd_diag_dport_show(bfad, iocmd); 2986 break; 2987 case IOCMD_DIAG_DPORT_START: 2988 rc = bfad_iocmd_diag_dport_start(bfad, iocmd); 2989 break; 2990 case IOCMD_PHY_GET_ATTR: 2991 rc = bfad_iocmd_phy_get_attr(bfad, iocmd); 2992 break; 2993 case IOCMD_PHY_GET_STATS: 2994 rc = bfad_iocmd_phy_get_stats(bfad, iocmd); 2995 break; 2996 case IOCMD_PHY_UPDATE_FW: 2997 rc = bfad_iocmd_phy_update(bfad, iocmd, payload_len); 2998 break; 2999 case IOCMD_PHY_READ_FW: 3000 rc = bfad_iocmd_phy_read(bfad, iocmd, payload_len); 3001 break; 3002 case IOCMD_VHBA_QUERY: 3003 rc = bfad_iocmd_vhba_query(bfad, iocmd); 3004 break; 3005 case IOCMD_DEBUG_PORTLOG: 3006 rc = bfad_iocmd_porglog_get(bfad, iocmd); 3007 break; 3008 case IOCMD_DEBUG_FW_CORE: 3009 rc = bfad_iocmd_debug_fw_core(bfad, iocmd, payload_len); 3010 break; 3011 case IOCMD_DEBUG_FW_STATE_CLR: 3012 case IOCMD_DEBUG_PORTLOG_CLR: 3013 case IOCMD_DEBUG_START_DTRC: 3014 case IOCMD_DEBUG_STOP_DTRC: 3015 rc = bfad_iocmd_debug_ctl(bfad, iocmd, cmd); 3016 break; 3017 case IOCMD_DEBUG_PORTLOG_CTL: 3018 rc = bfad_iocmd_porglog_ctl(bfad, iocmd); 3019 break; 3020 case IOCMD_FCPIM_PROFILE_ON: 3021 case IOCMD_FCPIM_PROFILE_OFF: 3022 rc = bfad_iocmd_fcpim_cfg_profile(bfad, iocmd, cmd); 3023 break; 3024 case IOCMD_ITNIM_GET_IOPROFILE: 3025 rc = bfad_iocmd_itnim_get_ioprofile(bfad, iocmd); 3026 break; 3027 case IOCMD_FCPORT_GET_STATS: 3028 rc = bfad_iocmd_fcport_get_stats(bfad, iocmd); 3029 break; 3030 case IOCMD_FCPORT_RESET_STATS: 3031 rc = bfad_iocmd_fcport_reset_stats(bfad, iocmd); 3032 break; 3033 case IOCMD_BOOT_CFG: 3034 rc = bfad_iocmd_boot_cfg(bfad, iocmd); 3035 break; 3036 case IOCMD_BOOT_QUERY: 3037 rc = bfad_iocmd_boot_query(bfad, iocmd); 3038 break; 3039 case IOCMD_PREBOOT_QUERY: 3040 rc = bfad_iocmd_preboot_query(bfad, iocmd); 3041 break; 3042 case IOCMD_ETHBOOT_CFG: 3043 rc = bfad_iocmd_ethboot_cfg(bfad, iocmd); 3044 break; 3045 case IOCMD_ETHBOOT_QUERY: 3046 rc = bfad_iocmd_ethboot_query(bfad, iocmd); 3047 break; 3048 case IOCMD_TRUNK_ENABLE: 3049 case IOCMD_TRUNK_DISABLE: 3050 rc = bfad_iocmd_cfg_trunk(bfad, iocmd, cmd); 3051 break; 3052 case IOCMD_TRUNK_GET_ATTR: 3053 rc = bfad_iocmd_trunk_get_attr(bfad, iocmd); 3054 break; 3055 case IOCMD_QOS_ENABLE: 3056 case IOCMD_QOS_DISABLE: 3057 rc = bfad_iocmd_qos(bfad, iocmd, cmd); 3058 break; 3059 case IOCMD_QOS_GET_ATTR: 3060 rc = bfad_iocmd_qos_get_attr(bfad, iocmd); 3061 break; 3062 case IOCMD_QOS_GET_VC_ATTR: 3063 rc = bfad_iocmd_qos_get_vc_attr(bfad, iocmd); 3064 break; 3065 case IOCMD_QOS_GET_STATS: 3066 rc = bfad_iocmd_qos_get_stats(bfad, iocmd); 3067 break; 3068 case IOCMD_QOS_RESET_STATS: 3069 rc = bfad_iocmd_qos_reset_stats(bfad, iocmd); 3070 break; 3071 case IOCMD_QOS_SET_BW: 3072 rc = bfad_iocmd_qos_set_bw(bfad, iocmd); 3073 break; 3074 case IOCMD_VF_GET_STATS: 3075 rc = bfad_iocmd_vf_get_stats(bfad, iocmd); 3076 break; 3077 case IOCMD_VF_RESET_STATS: 3078 rc = bfad_iocmd_vf_clr_stats(bfad, iocmd); 3079 break; 3080 case IOCMD_FCPIM_LUNMASK_ENABLE: 3081 case IOCMD_FCPIM_LUNMASK_DISABLE: 3082 case IOCMD_FCPIM_LUNMASK_CLEAR: 3083 rc = bfad_iocmd_lunmask(bfad, iocmd, cmd); 3084 break; 3085 case IOCMD_FCPIM_LUNMASK_QUERY: 3086 rc = bfad_iocmd_fcpim_lunmask_query(bfad, iocmd); 3087 break; 3088 case IOCMD_FCPIM_LUNMASK_ADD: 3089 case IOCMD_FCPIM_LUNMASK_DELETE: 3090 rc = bfad_iocmd_fcpim_cfg_lunmask(bfad, iocmd, cmd); 3091 break; 3092 case IOCMD_FCPIM_THROTTLE_QUERY: 3093 rc = bfad_iocmd_fcpim_throttle_query(bfad, iocmd); 3094 break; 3095 case IOCMD_FCPIM_THROTTLE_SET: 3096 rc = bfad_iocmd_fcpim_throttle_set(bfad, iocmd); 3097 break; 3098 /* TFRU */ 3099 case IOCMD_TFRU_READ: 3100 rc = bfad_iocmd_tfru_read(bfad, iocmd); 3101 break; 3102 case IOCMD_TFRU_WRITE: 3103 rc = bfad_iocmd_tfru_write(bfad, iocmd); 3104 break; 3105 /* FRU */ 3106 case IOCMD_FRUVPD_READ: 3107 rc = bfad_iocmd_fruvpd_read(bfad, iocmd); 3108 break; 3109 case IOCMD_FRUVPD_UPDATE: 3110 rc = bfad_iocmd_fruvpd_update(bfad, iocmd); 3111 break; 3112 case IOCMD_FRUVPD_GET_MAX_SIZE: 3113 rc = bfad_iocmd_fruvpd_get_max_size(bfad, iocmd); 3114 break; 3115 default: 3116 rc = -EINVAL; 3117 break; 3118 } 3119 return rc; 3120} 3121 3122static int 3123bfad_im_bsg_vendor_request(struct bsg_job *job) 3124{ 3125 struct fc_bsg_request *bsg_request = job->request; 3126 struct fc_bsg_reply *bsg_reply = job->reply; 3127 uint32_t vendor_cmd = bsg_request->rqst_data.h_vendor.vendor_cmd[0]; 3128 struct Scsi_Host *shost = fc_bsg_to_shost(job); 3129 struct bfad_im_port_s *im_port = bfad_get_im_port(shost); 3130 struct bfad_s *bfad = im_port->bfad; 3131 void *payload_kbuf; 3132 int rc = -EINVAL; 3133 3134 /* Allocate a temp buffer to hold the passed in user space command */ 3135 payload_kbuf = kzalloc(job->request_payload.payload_len, GFP_KERNEL); 3136 if (!payload_kbuf) { 3137 rc = -ENOMEM; 3138 goto out; 3139 } 3140 3141 /* Copy the sg_list passed in to a linear buffer: holds the cmnd data */ 3142 sg_copy_to_buffer(job->request_payload.sg_list, 3143 job->request_payload.sg_cnt, payload_kbuf, 3144 job->request_payload.payload_len); 3145 3146 /* Invoke IOCMD handler - to handle all the vendor command requests */ 3147 rc = bfad_iocmd_handler(bfad, vendor_cmd, payload_kbuf, 3148 job->request_payload.payload_len); 3149 if (rc != BFA_STATUS_OK) 3150 goto error; 3151 3152 /* Copy the response data to the job->reply_payload sg_list */ 3153 sg_copy_from_buffer(job->reply_payload.sg_list, 3154 job->reply_payload.sg_cnt, 3155 payload_kbuf, 3156 job->reply_payload.payload_len); 3157 3158 /* free the command buffer */ 3159 kfree(payload_kbuf); 3160 3161 /* Fill the BSG job reply data */ 3162 job->reply_len = job->reply_payload.payload_len; 3163 bsg_reply->reply_payload_rcv_len = job->reply_payload.payload_len; 3164 bsg_reply->result = rc; 3165 3166 bsg_job_done(job, bsg_reply->result, 3167 bsg_reply->reply_payload_rcv_len); 3168 return rc; 3169error: 3170 /* free the command buffer */ 3171 kfree(payload_kbuf); 3172out: 3173 bsg_reply->result = rc; 3174 job->reply_len = sizeof(uint32_t); 3175 bsg_reply->reply_payload_rcv_len = 0; 3176 return rc; 3177} 3178 3179/* FC passthru call backs */ 3180static u64 3181bfad_fcxp_get_req_sgaddr_cb(void *bfad_fcxp, int sgeid) 3182{ 3183 struct bfad_fcxp *drv_fcxp = bfad_fcxp; 3184 struct bfa_sge_s *sge; 3185 u64 addr; 3186 3187 sge = drv_fcxp->req_sge + sgeid; 3188 addr = (u64)(size_t) sge->sg_addr; 3189 return addr; 3190} 3191 3192static u32 3193bfad_fcxp_get_req_sglen_cb(void *bfad_fcxp, int sgeid) 3194{ 3195 struct bfad_fcxp *drv_fcxp = bfad_fcxp; 3196 struct bfa_sge_s *sge; 3197 3198 sge = drv_fcxp->req_sge + sgeid; 3199 return sge->sg_len; 3200} 3201 3202static u64 3203bfad_fcxp_get_rsp_sgaddr_cb(void *bfad_fcxp, int sgeid) 3204{ 3205 struct bfad_fcxp *drv_fcxp = bfad_fcxp; 3206 struct bfa_sge_s *sge; 3207 u64 addr; 3208 3209 sge = drv_fcxp->rsp_sge + sgeid; 3210 addr = (u64)(size_t) sge->sg_addr; 3211 return addr; 3212} 3213 3214static u32 3215bfad_fcxp_get_rsp_sglen_cb(void *bfad_fcxp, int sgeid) 3216{ 3217 struct bfad_fcxp *drv_fcxp = bfad_fcxp; 3218 struct bfa_sge_s *sge; 3219 3220 sge = drv_fcxp->rsp_sge + sgeid; 3221 return sge->sg_len; 3222} 3223 3224static void 3225bfad_send_fcpt_cb(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg, 3226 bfa_status_t req_status, u32 rsp_len, u32 resid_len, 3227 struct fchs_s *rsp_fchs) 3228{ 3229 struct bfad_fcxp *drv_fcxp = bfad_fcxp; 3230 3231 drv_fcxp->req_status = req_status; 3232 drv_fcxp->rsp_len = rsp_len; 3233 3234 /* bfa_fcxp will be automatically freed by BFA */ 3235 drv_fcxp->bfa_fcxp = NULL; 3236 complete(&drv_fcxp->comp); 3237} 3238 3239static struct bfad_buf_info * 3240bfad_fcxp_map_sg(struct bfad_s *bfad, void *payload_kbuf, 3241 uint32_t payload_len, uint32_t *num_sgles) 3242{ 3243 struct bfad_buf_info *buf_base, *buf_info; 3244 struct bfa_sge_s *sg_table; 3245 int sge_num = 1; 3246 3247 buf_base = kcalloc(sizeof(struct bfad_buf_info) + 3248 sizeof(struct bfa_sge_s), 3249 sge_num, GFP_KERNEL); 3250 if (!buf_base) 3251 return NULL; 3252 3253 sg_table = (struct bfa_sge_s *) (((uint8_t *)buf_base) + 3254 (sizeof(struct bfad_buf_info) * sge_num)); 3255 3256 /* Allocate dma coherent memory */ 3257 buf_info = buf_base; 3258 buf_info->size = payload_len; 3259 buf_info->virt = dma_alloc_coherent(&bfad->pcidev->dev, 3260 buf_info->size, &buf_info->phys, 3261 GFP_KERNEL); 3262 if (!buf_info->virt) 3263 goto out_free_mem; 3264 3265 /* copy the linear bsg buffer to buf_info */ 3266 memcpy(buf_info->virt, payload_kbuf, buf_info->size); 3267 3268 /* 3269 * Setup SG table 3270 */ 3271 sg_table->sg_len = buf_info->size; 3272 sg_table->sg_addr = (void *)(size_t) buf_info->phys; 3273 3274 *num_sgles = sge_num; 3275 3276 return buf_base; 3277 3278out_free_mem: 3279 kfree(buf_base); 3280 return NULL; 3281} 3282 3283static void 3284bfad_fcxp_free_mem(struct bfad_s *bfad, struct bfad_buf_info *buf_base, 3285 uint32_t num_sgles) 3286{ 3287 int i; 3288 struct bfad_buf_info *buf_info = buf_base; 3289 3290 if (buf_base) { 3291 for (i = 0; i < num_sgles; buf_info++, i++) { 3292 if (buf_info->virt != NULL) 3293 dma_free_coherent(&bfad->pcidev->dev, 3294 buf_info->size, buf_info->virt, 3295 buf_info->phys); 3296 } 3297 kfree(buf_base); 3298 } 3299} 3300 3301static int 3302bfad_fcxp_bsg_send(struct bsg_job *job, struct bfad_fcxp *drv_fcxp, 3303 bfa_bsg_fcpt_t *bsg_fcpt) 3304{ 3305 struct bfa_fcxp_s *hal_fcxp; 3306 struct bfad_s *bfad = drv_fcxp->port->bfad; 3307 unsigned long flags; 3308 uint8_t lp_tag; 3309 3310 spin_lock_irqsave(&bfad->bfad_lock, flags); 3311 3312 /* Allocate bfa_fcxp structure */ 3313 hal_fcxp = bfa_fcxp_req_rsp_alloc(drv_fcxp, &bfad->bfa, 3314 drv_fcxp->num_req_sgles, 3315 drv_fcxp->num_rsp_sgles, 3316 bfad_fcxp_get_req_sgaddr_cb, 3317 bfad_fcxp_get_req_sglen_cb, 3318 bfad_fcxp_get_rsp_sgaddr_cb, 3319 bfad_fcxp_get_rsp_sglen_cb, BFA_TRUE); 3320 if (!hal_fcxp) { 3321 bfa_trc(bfad, 0); 3322 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 3323 return BFA_STATUS_ENOMEM; 3324 } 3325 3326 drv_fcxp->bfa_fcxp = hal_fcxp; 3327 3328 lp_tag = bfa_lps_get_tag_from_pid(&bfad->bfa, bsg_fcpt->fchs.s_id); 3329 3330 bfa_fcxp_send(hal_fcxp, drv_fcxp->bfa_rport, bsg_fcpt->vf_id, lp_tag, 3331 bsg_fcpt->cts, bsg_fcpt->cos, 3332 job->request_payload.payload_len, 3333 &bsg_fcpt->fchs, bfad_send_fcpt_cb, bfad, 3334 job->reply_payload.payload_len, bsg_fcpt->tsecs); 3335 3336 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 3337 3338 return BFA_STATUS_OK; 3339} 3340 3341static int 3342bfad_im_bsg_els_ct_request(struct bsg_job *job) 3343{ 3344 struct bfa_bsg_data *bsg_data; 3345 struct Scsi_Host *shost = fc_bsg_to_shost(job); 3346 struct bfad_im_port_s *im_port = bfad_get_im_port(shost); 3347 struct bfad_s *bfad = im_port->bfad; 3348 bfa_bsg_fcpt_t *bsg_fcpt; 3349 struct bfad_fcxp *drv_fcxp; 3350 struct bfa_fcs_lport_s *fcs_port; 3351 struct bfa_fcs_rport_s *fcs_rport; 3352 struct fc_bsg_request *bsg_request = job->request; 3353 struct fc_bsg_reply *bsg_reply = job->reply; 3354 uint32_t command_type = bsg_request->msgcode; 3355 unsigned long flags; 3356 struct bfad_buf_info *rsp_buf_info; 3357 void *req_kbuf = NULL, *rsp_kbuf = NULL; 3358 int rc = -EINVAL; 3359 3360 job->reply_len = sizeof(uint32_t); /* Atleast uint32_t reply_len */ 3361 bsg_reply->reply_payload_rcv_len = 0; 3362 3363 /* Get the payload passed in from userspace */ 3364 bsg_data = (struct bfa_bsg_data *) (((char *)bsg_request) + 3365 sizeof(struct fc_bsg_request)); 3366 if (bsg_data == NULL) 3367 goto out; 3368 3369 /* 3370 * Allocate buffer for bsg_fcpt and do a copy_from_user op for payload 3371 * buffer of size bsg_data->payload_len 3372 */ 3373 bsg_fcpt = kzalloc(bsg_data->payload_len, GFP_KERNEL); 3374 if (!bsg_fcpt) { 3375 rc = -ENOMEM; 3376 goto out; 3377 } 3378 3379 if (copy_from_user((uint8_t *)bsg_fcpt, 3380 (void *)(unsigned long)bsg_data->payload, 3381 bsg_data->payload_len)) { 3382 kfree(bsg_fcpt); 3383 rc = -EIO; 3384 goto out; 3385 } 3386 3387 drv_fcxp = kzalloc(sizeof(struct bfad_fcxp), GFP_KERNEL); 3388 if (drv_fcxp == NULL) { 3389 kfree(bsg_fcpt); 3390 rc = -ENOMEM; 3391 goto out; 3392 } 3393 3394 spin_lock_irqsave(&bfad->bfad_lock, flags); 3395 fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs, bsg_fcpt->vf_id, 3396 bsg_fcpt->lpwwn); 3397 if (fcs_port == NULL) { 3398 bsg_fcpt->status = BFA_STATUS_UNKNOWN_LWWN; 3399 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 3400 goto out_free_mem; 3401 } 3402 3403 /* Check if the port is online before sending FC Passthru cmd */ 3404 if (!bfa_fcs_lport_is_online(fcs_port)) { 3405 bsg_fcpt->status = BFA_STATUS_PORT_OFFLINE; 3406 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 3407 goto out_free_mem; 3408 } 3409 3410 drv_fcxp->port = fcs_port->bfad_port; 3411 3412 if (!drv_fcxp->port->bfad) 3413 drv_fcxp->port->bfad = bfad; 3414 3415 /* Fetch the bfa_rport - if nexus needed */ 3416 if (command_type == FC_BSG_HST_ELS_NOLOGIN || 3417 command_type == FC_BSG_HST_CT) { 3418 /* BSG HST commands: no nexus needed */ 3419 drv_fcxp->bfa_rport = NULL; 3420 3421 } else if (command_type == FC_BSG_RPT_ELS || 3422 command_type == FC_BSG_RPT_CT) { 3423 /* BSG RPT commands: nexus needed */ 3424 fcs_rport = bfa_fcs_lport_get_rport_by_pwwn(fcs_port, 3425 bsg_fcpt->dpwwn); 3426 if (fcs_rport == NULL) { 3427 bsg_fcpt->status = BFA_STATUS_UNKNOWN_RWWN; 3428 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 3429 goto out_free_mem; 3430 } 3431 3432 drv_fcxp->bfa_rport = fcs_rport->bfa_rport; 3433 3434 } else { /* Unknown BSG msgcode; return -EINVAL */ 3435 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 3436 goto out_free_mem; 3437 } 3438 3439 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 3440 3441 /* allocate memory for req / rsp buffers */ 3442 req_kbuf = kzalloc(job->request_payload.payload_len, GFP_KERNEL); 3443 if (!req_kbuf) { 3444 printk(KERN_INFO "bfa %s: fcpt request buffer alloc failed\n", 3445 bfad->pci_name); 3446 rc = -ENOMEM; 3447 goto out_free_mem; 3448 } 3449 3450 rsp_kbuf = kzalloc(job->reply_payload.payload_len, GFP_KERNEL); 3451 if (!rsp_kbuf) { 3452 printk(KERN_INFO "bfa %s: fcpt response buffer alloc failed\n", 3453 bfad->pci_name); 3454 rc = -ENOMEM; 3455 goto out_free_mem; 3456 } 3457 3458 /* map req sg - copy the sg_list passed in to the linear buffer */ 3459 sg_copy_to_buffer(job->request_payload.sg_list, 3460 job->request_payload.sg_cnt, req_kbuf, 3461 job->request_payload.payload_len); 3462 3463 drv_fcxp->reqbuf_info = bfad_fcxp_map_sg(bfad, req_kbuf, 3464 job->request_payload.payload_len, 3465 &drv_fcxp->num_req_sgles); 3466 if (!drv_fcxp->reqbuf_info) { 3467 printk(KERN_INFO "bfa %s: fcpt request fcxp_map_sg failed\n", 3468 bfad->pci_name); 3469 rc = -ENOMEM; 3470 goto out_free_mem; 3471 } 3472 3473 drv_fcxp->req_sge = (struct bfa_sge_s *) 3474 (((uint8_t *)drv_fcxp->reqbuf_info) + 3475 (sizeof(struct bfad_buf_info) * 3476 drv_fcxp->num_req_sgles)); 3477 3478 /* map rsp sg */ 3479 drv_fcxp->rspbuf_info = bfad_fcxp_map_sg(bfad, rsp_kbuf, 3480 job->reply_payload.payload_len, 3481 &drv_fcxp->num_rsp_sgles); 3482 if (!drv_fcxp->rspbuf_info) { 3483 printk(KERN_INFO "bfa %s: fcpt response fcxp_map_sg failed\n", 3484 bfad->pci_name); 3485 rc = -ENOMEM; 3486 goto out_free_mem; 3487 } 3488 3489 rsp_buf_info = (struct bfad_buf_info *)drv_fcxp->rspbuf_info; 3490 drv_fcxp->rsp_sge = (struct bfa_sge_s *) 3491 (((uint8_t *)drv_fcxp->rspbuf_info) + 3492 (sizeof(struct bfad_buf_info) * 3493 drv_fcxp->num_rsp_sgles)); 3494 3495 /* fcxp send */ 3496 init_completion(&drv_fcxp->comp); 3497 rc = bfad_fcxp_bsg_send(job, drv_fcxp, bsg_fcpt); 3498 if (rc == BFA_STATUS_OK) { 3499 wait_for_completion(&drv_fcxp->comp); 3500 bsg_fcpt->status = drv_fcxp->req_status; 3501 } else { 3502 bsg_fcpt->status = rc; 3503 goto out_free_mem; 3504 } 3505 3506 /* fill the job->reply data */ 3507 if (drv_fcxp->req_status == BFA_STATUS_OK) { 3508 job->reply_len = drv_fcxp->rsp_len; 3509 bsg_reply->reply_payload_rcv_len = drv_fcxp->rsp_len; 3510 bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK; 3511 } else { 3512 bsg_reply->reply_payload_rcv_len = 3513 sizeof(struct fc_bsg_ctels_reply); 3514 job->reply_len = sizeof(uint32_t); 3515 bsg_reply->reply_data.ctels_reply.status = 3516 FC_CTELS_STATUS_REJECT; 3517 } 3518 3519 /* Copy the response data to the reply_payload sg list */ 3520 sg_copy_from_buffer(job->reply_payload.sg_list, 3521 job->reply_payload.sg_cnt, 3522 (uint8_t *)rsp_buf_info->virt, 3523 job->reply_payload.payload_len); 3524 3525out_free_mem: 3526 bfad_fcxp_free_mem(bfad, drv_fcxp->rspbuf_info, 3527 drv_fcxp->num_rsp_sgles); 3528 bfad_fcxp_free_mem(bfad, drv_fcxp->reqbuf_info, 3529 drv_fcxp->num_req_sgles); 3530 kfree(req_kbuf); 3531 kfree(rsp_kbuf); 3532 3533 /* Need a copy to user op */ 3534 if (copy_to_user((void *)(unsigned long)bsg_data->payload, 3535 (void *)bsg_fcpt, bsg_data->payload_len)) 3536 rc = -EIO; 3537 3538 kfree(bsg_fcpt); 3539 kfree(drv_fcxp); 3540out: 3541 bsg_reply->result = rc; 3542 3543 if (rc == BFA_STATUS_OK) 3544 bsg_job_done(job, bsg_reply->result, 3545 bsg_reply->reply_payload_rcv_len); 3546 3547 return rc; 3548} 3549 3550int 3551bfad_im_bsg_request(struct bsg_job *job) 3552{ 3553 struct fc_bsg_request *bsg_request = job->request; 3554 struct fc_bsg_reply *bsg_reply = job->reply; 3555 uint32_t rc = BFA_STATUS_OK; 3556 3557 switch (bsg_request->msgcode) { 3558 case FC_BSG_HST_VENDOR: 3559 /* Process BSG HST Vendor requests */ 3560 rc = bfad_im_bsg_vendor_request(job); 3561 break; 3562 case FC_BSG_HST_ELS_NOLOGIN: 3563 case FC_BSG_RPT_ELS: 3564 case FC_BSG_HST_CT: 3565 case FC_BSG_RPT_CT: 3566 /* Process BSG ELS/CT commands */ 3567 rc = bfad_im_bsg_els_ct_request(job); 3568 break; 3569 default: 3570 bsg_reply->result = rc = -EINVAL; 3571 bsg_reply->reply_payload_rcv_len = 0; 3572 break; 3573 } 3574 3575 return rc; 3576} 3577 3578int 3579bfad_im_bsg_timeout(struct bsg_job *job) 3580{ 3581 /* Don't complete the BSG job request - return -EAGAIN 3582 * to reset bsg job timeout : for ELS/CT pass thru we 3583 * already have timer to track the request. 3584 */ 3585 return -EAGAIN; 3586}