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