linux/drivers/scsi/lpfc/lpfc_ct.c
<<
>>
Prefs
   1/*******************************************************************
   2 * This file is part of the Emulex Linux Device Driver for         *
   3 * Fibre Channel Host Bus Adapters.                                *
   4 * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *
   5 * EMULEX and SLI are trademarks of Emulex.                        *
   6 * www.emulex.com                                                  *
   7 *                                                                 *
   8 * This program is free software; you can redistribute it and/or   *
   9 * modify it under the terms of version 2 of the GNU General       *
  10 * Public License as published by the Free Software Foundation.    *
  11 * This program is distributed in the hope that it will be useful. *
  12 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
  13 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
  14 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
  15 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
  16 * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
  17 * more details, a copy of which can be found in the file COPYING  *
  18 * included with this package.                                     *
  19 *******************************************************************/
  20
  21/*
  22 * Fibre Channel SCSI LAN Device Driver CT support: FC Generic Services FC-GS
  23 */
  24
  25#include <linux/blkdev.h>
  26#include <linux/pci.h>
  27#include <linux/interrupt.h>
  28#include <linux/slab.h>
  29#include <linux/utsname.h>
  30
  31#include <scsi/scsi.h>
  32#include <scsi/scsi_device.h>
  33#include <scsi/scsi_host.h>
  34#include <scsi/scsi_transport_fc.h>
  35#include <scsi/fc/fc_fs.h>
  36
  37#include "lpfc_hw4.h"
  38#include "lpfc_hw.h"
  39#include "lpfc_sli.h"
  40#include "lpfc_sli4.h"
  41#include "lpfc_nl.h"
  42#include "lpfc_disc.h"
  43#include "lpfc_scsi.h"
  44#include "lpfc.h"
  45#include "lpfc_logmsg.h"
  46#include "lpfc_crtn.h"
  47#include "lpfc_version.h"
  48#include "lpfc_vport.h"
  49#include "lpfc_debugfs.h"
  50
  51/* FDMI Port Speed definitions - FC-GS-7 */
  52#define HBA_PORTSPEED_1GFC              0x00000001      /* 1G FC */
  53#define HBA_PORTSPEED_2GFC              0x00000002      /* 2G FC */
  54#define HBA_PORTSPEED_4GFC              0x00000008      /* 4G FC */
  55#define HBA_PORTSPEED_10GFC             0x00000004      /* 10G FC */
  56#define HBA_PORTSPEED_8GFC              0x00000010      /* 8G FC */
  57#define HBA_PORTSPEED_16GFC             0x00000020      /* 16G FC */
  58#define HBA_PORTSPEED_32GFC             0x00000040      /* 32G FC */
  59#define HBA_PORTSPEED_20GFC             0x00000080      /* 20G FC */
  60#define HBA_PORTSPEED_40GFC             0x00000100      /* 40G FC */
  61#define HBA_PORTSPEED_128GFC            0x00000200      /* 128G FC */
  62#define HBA_PORTSPEED_64GFC             0x00000400      /* 64G FC */
  63#define HBA_PORTSPEED_256GFC            0x00000800      /* 256G FC */
  64#define HBA_PORTSPEED_UNKNOWN           0x00008000      /* Unknown */
  65#define HBA_PORTSPEED_10GE              0x00010000      /* 10G E */
  66#define HBA_PORTSPEED_40GE              0x00020000      /* 40G E */
  67#define HBA_PORTSPEED_100GE             0x00040000      /* 100G E */
  68#define HBA_PORTSPEED_25GE              0x00080000      /* 25G E */
  69#define HBA_PORTSPEED_50GE              0x00100000      /* 50G E */
  70#define HBA_PORTSPEED_400GE             0x00200000      /* 400G E */
  71
  72#define FOURBYTES       4
  73
  74
  75static char *lpfc_release_version = LPFC_DRIVER_VERSION;
  76
  77static void
  78lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
  79                          struct lpfc_dmabuf *mp, uint32_t size)
  80{
  81        if (!mp) {
  82                lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
  83                                "0146 Ignoring unsolicited CT No HBQ "
  84                                "status = x%x\n",
  85                                piocbq->iocb.ulpStatus);
  86        }
  87        lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
  88                        "0145 Ignoring unsolicted CT HBQ Size:%d "
  89                        "status = x%x\n",
  90                        size, piocbq->iocb.ulpStatus);
  91}
  92
  93static void
  94lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
  95                     struct lpfc_dmabuf *mp, uint32_t size)
  96{
  97        lpfc_ct_ignore_hbq_buffer(phba, piocbq, mp, size);
  98}
  99
 100void
 101lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 102                    struct lpfc_iocbq *piocbq)
 103{
 104        struct lpfc_dmabuf *mp = NULL;
 105        IOCB_t *icmd = &piocbq->iocb;
 106        int i;
 107        struct lpfc_iocbq *iocbq;
 108        dma_addr_t paddr;
 109        uint32_t size;
 110        struct list_head head;
 111        struct lpfc_dmabuf *bdeBuf;
 112
 113        if (lpfc_bsg_ct_unsol_event(phba, pring, piocbq) == 0)
 114                return;
 115
 116        if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) {
 117                lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
 118        } else if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
 119                   ((icmd->un.ulpWord[4] & IOERR_PARAM_MASK) ==
 120                   IOERR_RCV_BUFFER_WAITING)) {
 121                /* Not enough posted buffers; Try posting more buffers */
 122                phba->fc_stat.NoRcvBuf++;
 123                if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
 124                        lpfc_post_buffer(phba, pring, 2);
 125                return;
 126        }
 127
 128        /* If there are no BDEs associated with this IOCB,
 129         * there is nothing to do.
 130         */
 131        if (icmd->ulpBdeCount == 0)
 132                return;
 133
 134        if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
 135                INIT_LIST_HEAD(&head);
 136                list_add_tail(&head, &piocbq->list);
 137                list_for_each_entry(iocbq, &head, list) {
 138                        icmd = &iocbq->iocb;
 139                        if (icmd->ulpBdeCount == 0)
 140                                continue;
 141                        bdeBuf = iocbq->context2;
 142                        iocbq->context2 = NULL;
 143                        size  = icmd->un.cont64[0].tus.f.bdeSize;
 144                        lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, size);
 145                        lpfc_in_buf_free(phba, bdeBuf);
 146                        if (icmd->ulpBdeCount == 2) {
 147                                bdeBuf = iocbq->context3;
 148                                iocbq->context3 = NULL;
 149                                size  = icmd->unsli3.rcvsli3.bde2.tus.f.bdeSize;
 150                                lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf,
 151                                                     size);
 152                                lpfc_in_buf_free(phba, bdeBuf);
 153                        }
 154                }
 155                list_del(&head);
 156        } else {
 157                INIT_LIST_HEAD(&head);
 158                list_add_tail(&head, &piocbq->list);
 159                list_for_each_entry(iocbq, &head, list) {
 160                        icmd = &iocbq->iocb;
 161                        if (icmd->ulpBdeCount == 0)
 162                                lpfc_ct_unsol_buffer(phba, iocbq, NULL, 0);
 163                        for (i = 0; i < icmd->ulpBdeCount; i++) {
 164                                paddr = getPaddr(icmd->un.cont64[i].addrHigh,
 165                                                 icmd->un.cont64[i].addrLow);
 166                                mp = lpfc_sli_ringpostbuf_get(phba, pring,
 167                                                              paddr);
 168                                size = icmd->un.cont64[i].tus.f.bdeSize;
 169                                lpfc_ct_unsol_buffer(phba, iocbq, mp, size);
 170                                lpfc_in_buf_free(phba, mp);
 171                        }
 172                        lpfc_post_buffer(phba, pring, i);
 173                }
 174                list_del(&head);
 175        }
 176}
 177
 178/**
 179 * lpfc_ct_handle_unsol_abort - ct upper level protocol abort handler
 180 * @phba: Pointer to HBA context object.
 181 * @dmabuf: pointer to a dmabuf that describes the FC sequence
 182 *
 183 * This function serves as the upper level protocol abort handler for CT
 184 * protocol.
 185 *
 186 * Return 1 if abort has been handled, 0 otherwise.
 187 **/
 188int
 189lpfc_ct_handle_unsol_abort(struct lpfc_hba *phba, struct hbq_dmabuf *dmabuf)
 190{
 191        int handled;
 192
 193        /* CT upper level goes through BSG */
 194        handled = lpfc_bsg_ct_unsol_abort(phba, dmabuf);
 195
 196        return handled;
 197}
 198
 199static void
 200lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist)
 201{
 202        struct lpfc_dmabuf *mlast, *next_mlast;
 203
 204        list_for_each_entry_safe(mlast, next_mlast, &mlist->list, list) {
 205                lpfc_mbuf_free(phba, mlast->virt, mlast->phys);
 206                list_del(&mlast->list);
 207                kfree(mlast);
 208        }
 209        lpfc_mbuf_free(phba, mlist->virt, mlist->phys);
 210        kfree(mlist);
 211        return;
 212}
 213
 214static struct lpfc_dmabuf *
 215lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl,
 216                  uint32_t size, int *entries)
 217{
 218        struct lpfc_dmabuf *mlist = NULL;
 219        struct lpfc_dmabuf *mp;
 220        int cnt, i = 0;
 221
 222        /* We get chunks of FCELSSIZE */
 223        cnt = size > FCELSSIZE ? FCELSSIZE: size;
 224
 225        while (size) {
 226                /* Allocate buffer for rsp payload */
 227                mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
 228                if (!mp) {
 229                        if (mlist)
 230                                lpfc_free_ct_rsp(phba, mlist);
 231                        return NULL;
 232                }
 233
 234                INIT_LIST_HEAD(&mp->list);
 235
 236                if (cmdcode == be16_to_cpu(SLI_CTNS_GID_FT) ||
 237                    cmdcode == be16_to_cpu(SLI_CTNS_GFF_ID))
 238                        mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys));
 239                else
 240                        mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys));
 241
 242                if (!mp->virt) {
 243                        kfree(mp);
 244                        if (mlist)
 245                                lpfc_free_ct_rsp(phba, mlist);
 246                        return NULL;
 247                }
 248
 249                /* Queue it to a linked list */
 250                if (!mlist)
 251                        mlist = mp;
 252                else
 253                        list_add_tail(&mp->list, &mlist->list);
 254
 255                bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;
 256                /* build buffer ptr list for IOCB */
 257                bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) );
 258                bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) );
 259                bpl->tus.f.bdeSize = (uint16_t) cnt;
 260                bpl->tus.w = le32_to_cpu(bpl->tus.w);
 261                bpl++;
 262
 263                i++;
 264                size -= cnt;
 265        }
 266
 267        *entries = i;
 268        return mlist;
 269}
 270
 271int
 272lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocb)
 273{
 274        struct lpfc_dmabuf *buf_ptr;
 275
 276        if (ctiocb->context_un.ndlp) {
 277                lpfc_nlp_put(ctiocb->context_un.ndlp);
 278                ctiocb->context_un.ndlp = NULL;
 279        }
 280        if (ctiocb->context1) {
 281                buf_ptr = (struct lpfc_dmabuf *) ctiocb->context1;
 282                lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
 283                kfree(buf_ptr);
 284                ctiocb->context1 = NULL;
 285        }
 286        if (ctiocb->context2) {
 287                lpfc_free_ct_rsp(phba, (struct lpfc_dmabuf *) ctiocb->context2);
 288                ctiocb->context2 = NULL;
 289        }
 290
 291        if (ctiocb->context3) {
 292                buf_ptr = (struct lpfc_dmabuf *) ctiocb->context3;
 293                lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
 294                kfree(buf_ptr);
 295                ctiocb->context3 = NULL;
 296        }
 297        lpfc_sli_release_iocbq(phba, ctiocb);
 298        return 0;
 299}
 300
 301/**
 302 * lpfc_gen_req - Build and issue a GEN_REQUEST command  to the SLI Layer
 303 * @vport: pointer to a host virtual N_Port data structure.
 304 * @bmp: Pointer to BPL for SLI command
 305 * @inp: Pointer to data buffer for response data.
 306 * @outp: Pointer to data buffer that hold the CT command.
 307 * @cmpl: completion routine to call when command completes
 308 * @ndlp: Destination NPort nodelist entry
 309 *
 310 * This function as the final part for issuing a CT command.
 311 */
 312static int
 313lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
 314             struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp,
 315             void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
 316                     struct lpfc_iocbq *),
 317             struct lpfc_nodelist *ndlp, uint32_t usr_flg, uint32_t num_entry,
 318             uint32_t tmo, uint8_t retry)
 319{
 320        struct lpfc_hba  *phba = vport->phba;
 321        IOCB_t *icmd;
 322        struct lpfc_iocbq *geniocb;
 323        int rc;
 324
 325        /* Allocate buffer for  command iocb */
 326        geniocb = lpfc_sli_get_iocbq(phba);
 327
 328        if (geniocb == NULL)
 329                return 1;
 330
 331        icmd = &geniocb->iocb;
 332        icmd->un.genreq64.bdl.ulpIoTag32 = 0;
 333        icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
 334        icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
 335        icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
 336        icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof(struct ulp_bde64));
 337
 338        if (usr_flg)
 339                geniocb->context3 = NULL;
 340        else
 341                geniocb->context3 = (uint8_t *) bmp;
 342
 343        /* Save for completion so we can release these resources */
 344        geniocb->context1 = (uint8_t *) inp;
 345        geniocb->context2 = (uint8_t *) outp;
 346        geniocb->context_un.ndlp = lpfc_nlp_get(ndlp);
 347
 348        /* Fill in payload, bp points to frame payload */
 349        icmd->ulpCommand = CMD_GEN_REQUEST64_CR;
 350
 351        /* Fill in rest of iocb */
 352        icmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
 353        icmd->un.genreq64.w5.hcsw.Dfctl = 0;
 354        icmd->un.genreq64.w5.hcsw.Rctl = FC_RCTL_DD_UNSOL_CTL;
 355        icmd->un.genreq64.w5.hcsw.Type = FC_TYPE_CT;
 356
 357        if (!tmo) {
 358                 /* FC spec states we need 3 * ratov for CT requests */
 359                tmo = (3 * phba->fc_ratov);
 360        }
 361        icmd->ulpTimeout = tmo;
 362        icmd->ulpBdeCount = 1;
 363        icmd->ulpLe = 1;
 364        icmd->ulpClass = CLASS3;
 365        icmd->ulpContext = ndlp->nlp_rpi;
 366        if (phba->sli_rev == LPFC_SLI_REV4)
 367                icmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
 368
 369        if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
 370                /* For GEN_REQUEST64_CR, use the RPI */
 371                icmd->ulpCt_h = 0;
 372                icmd->ulpCt_l = 0;
 373        }
 374
 375        /* Issue GEN REQ IOCB for NPORT <did> */
 376        lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
 377                         "0119 Issue GEN REQ IOCB to NPORT x%x "
 378                         "Data: x%x x%x\n",
 379                         ndlp->nlp_DID, icmd->ulpIoTag,
 380                         vport->port_state);
 381        geniocb->iocb_cmpl = cmpl;
 382        geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT;
 383        geniocb->vport = vport;
 384        geniocb->retry = retry;
 385        rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, geniocb, 0);
 386
 387        if (rc == IOCB_ERROR) {
 388                lpfc_sli_release_iocbq(phba, geniocb);
 389                return 1;
 390        }
 391
 392        return 0;
 393}
 394
 395/**
 396 * lpfc_ct_cmd - Build and issue a CT command
 397 * @vport: pointer to a host virtual N_Port data structure.
 398 * @inmp: Pointer to data buffer for response data.
 399 * @bmp: Pointer to BPL for SLI command
 400 * @ndlp: Destination NPort nodelist entry
 401 * @cmpl: completion routine to call when command completes
 402 *
 403 * This function is called for issuing a CT command.
 404 */
 405static int
 406lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp,
 407            struct lpfc_dmabuf *bmp, struct lpfc_nodelist *ndlp,
 408            void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
 409                          struct lpfc_iocbq *),
 410            uint32_t rsp_size, uint8_t retry)
 411{
 412        struct lpfc_hba  *phba = vport->phba;
 413        struct ulp_bde64 *bpl = (struct ulp_bde64 *) bmp->virt;
 414        struct lpfc_dmabuf *outmp;
 415        int cnt = 0, status;
 416        int cmdcode = ((struct lpfc_sli_ct_request *) inmp->virt)->
 417                CommandResponse.bits.CmdRsp;
 418
 419        bpl++;                  /* Skip past ct request */
 420
 421        /* Put buffer(s) for ct rsp in bpl */
 422        outmp = lpfc_alloc_ct_rsp(phba, cmdcode, bpl, rsp_size, &cnt);
 423        if (!outmp)
 424                return -ENOMEM;
 425        /*
 426         * Form the CT IOCB.  The total number of BDEs in this IOCB
 427         * is the single command plus response count from
 428         * lpfc_alloc_ct_rsp.
 429         */
 430        cnt += 1;
 431        status = lpfc_gen_req(vport, bmp, inmp, outmp, cmpl, ndlp, 0,
 432                              cnt, 0, retry);
 433        if (status) {
 434                lpfc_free_ct_rsp(phba, outmp);
 435                return -ENOMEM;
 436        }
 437        return 0;
 438}
 439
 440struct lpfc_vport *
 441lpfc_find_vport_by_did(struct lpfc_hba *phba, uint32_t did) {
 442        struct lpfc_vport *vport_curr;
 443        unsigned long flags;
 444
 445        spin_lock_irqsave(&phba->hbalock, flags);
 446        list_for_each_entry(vport_curr, &phba->port_list, listentry) {
 447                if ((vport_curr->fc_myDID) && (vport_curr->fc_myDID == did)) {
 448                        spin_unlock_irqrestore(&phba->hbalock, flags);
 449                        return vport_curr;
 450                }
 451        }
 452        spin_unlock_irqrestore(&phba->hbalock, flags);
 453        return NULL;
 454}
 455
 456static int
 457lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
 458{
 459        struct lpfc_hba  *phba = vport->phba;
 460        struct lpfc_sli_ct_request *Response =
 461                (struct lpfc_sli_ct_request *) mp->virt;
 462        struct lpfc_nodelist *ndlp = NULL;
 463        struct lpfc_dmabuf *mlast, *next_mp;
 464        uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType;
 465        uint32_t Did, CTentry;
 466        int Cnt;
 467        struct list_head head;
 468
 469        lpfc_set_disctmo(vport);
 470        vport->num_disc_nodes = 0;
 471        vport->fc_ns_retry = 0;
 472
 473
 474        list_add_tail(&head, &mp->list);
 475        list_for_each_entry_safe(mp, next_mp, &head, list) {
 476                mlast = mp;
 477
 478                Cnt = Size  > FCELSSIZE ? FCELSSIZE : Size;
 479
 480                Size -= Cnt;
 481
 482                if (!ctptr) {
 483                        ctptr = (uint32_t *) mlast->virt;
 484                } else
 485                        Cnt -= 16;      /* subtract length of CT header */
 486
 487                /* Loop through entire NameServer list of DIDs */
 488                while (Cnt >= sizeof(uint32_t)) {
 489                        /* Get next DID from NameServer List */
 490                        CTentry = *ctptr++;
 491                        Did = ((be32_to_cpu(CTentry)) & Mask_DID);
 492
 493                        ndlp = NULL;
 494
 495                        /*
 496                         * Check for rscn processing or not
 497                         * To conserve rpi's, filter out addresses for other
 498                         * vports on the same physical HBAs.
 499                         */
 500                        if ((Did != vport->fc_myDID) &&
 501                            ((lpfc_find_vport_by_did(phba, Did) == NULL) ||
 502                             vport->cfg_peer_port_login)) {
 503                                if ((vport->port_type != LPFC_NPIV_PORT) ||
 504                                    (!(vport->ct_flags & FC_CT_RFF_ID)) ||
 505                                    (!vport->cfg_restrict_login)) {
 506                                        ndlp = lpfc_setup_disc_node(vport, Did);
 507                                        if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
 508                                                lpfc_debugfs_disc_trc(vport,
 509                                                LPFC_DISC_TRC_CT,
 510                                                "Parse GID_FTrsp: "
 511                                                "did:x%x flg:x%x x%x",
 512                                                Did, ndlp->nlp_flag,
 513                                                vport->fc_flag);
 514
 515                                                lpfc_printf_vlog(vport,
 516                                                        KERN_INFO,
 517                                                        LOG_DISCOVERY,
 518                                                        "0238 Process "
 519                                                        "x%x NameServer Rsp"
 520                                                        "Data: x%x x%x x%x\n",
 521                                                        Did, ndlp->nlp_flag,
 522                                                        vport->fc_flag,
 523                                                        vport->fc_rscn_id_cnt);
 524                                        } else {
 525                                                lpfc_debugfs_disc_trc(vport,
 526                                                LPFC_DISC_TRC_CT,
 527                                                "Skip1 GID_FTrsp: "
 528                                                "did:x%x flg:x%x cnt:%d",
 529                                                Did, vport->fc_flag,
 530                                                vport->fc_rscn_id_cnt);
 531
 532                                                lpfc_printf_vlog(vport,
 533                                                        KERN_INFO,
 534                                                        LOG_DISCOVERY,
 535                                                        "0239 Skip x%x "
 536                                                        "NameServer Rsp Data: "
 537                                                        "x%x x%x\n",
 538                                                        Did, vport->fc_flag,
 539                                                        vport->fc_rscn_id_cnt);
 540                                        }
 541
 542                                } else {
 543                                        if (!(vport->fc_flag & FC_RSCN_MODE) ||
 544                                        (lpfc_rscn_payload_check(vport, Did))) {
 545                                                lpfc_debugfs_disc_trc(vport,
 546                                                LPFC_DISC_TRC_CT,
 547                                                "Query GID_FTrsp: "
 548                                                "did:x%x flg:x%x cnt:%d",
 549                                                Did, vport->fc_flag,
 550                                                vport->fc_rscn_id_cnt);
 551
 552                                                /* This NPortID was previously
 553                                                 * a FCP target, * Don't even
 554                                                 * bother to send GFF_ID.
 555                                                 */
 556                                                ndlp = lpfc_findnode_did(vport,
 557                                                        Did);
 558                                                if (ndlp &&
 559                                                    NLP_CHK_NODE_ACT(ndlp)
 560                                                    && (ndlp->nlp_type &
 561                                                     NLP_FCP_TARGET))
 562                                                        lpfc_setup_disc_node
 563                                                                (vport, Did);
 564                                                else if (lpfc_ns_cmd(vport,
 565                                                        SLI_CTNS_GFF_ID,
 566                                                        0, Did) == 0)
 567                                                        vport->num_disc_nodes++;
 568                                                else
 569                                                        lpfc_setup_disc_node
 570                                                                (vport, Did);
 571                                        }
 572                                        else {
 573                                                lpfc_debugfs_disc_trc(vport,
 574                                                LPFC_DISC_TRC_CT,
 575                                                "Skip2 GID_FTrsp: "
 576                                                "did:x%x flg:x%x cnt:%d",
 577                                                Did, vport->fc_flag,
 578                                                vport->fc_rscn_id_cnt);
 579
 580                                                lpfc_printf_vlog(vport,
 581                                                        KERN_INFO,
 582                                                        LOG_DISCOVERY,
 583                                                        "0245 Skip x%x "
 584                                                        "NameServer Rsp Data: "
 585                                                        "x%x x%x\n",
 586                                                        Did, vport->fc_flag,
 587                                                        vport->fc_rscn_id_cnt);
 588                                        }
 589                                }
 590                        }
 591                        if (CTentry & (cpu_to_be32(SLI_CT_LAST_ENTRY)))
 592                                goto nsout1;
 593                        Cnt -= sizeof(uint32_t);
 594                }
 595                ctptr = NULL;
 596
 597        }
 598
 599nsout1:
 600        list_del(&head);
 601        return 0;
 602}
 603
 604static void
 605lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 606                        struct lpfc_iocbq *rspiocb)
 607{
 608        struct lpfc_vport *vport = cmdiocb->vport;
 609        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 610        IOCB_t *irsp;
 611        struct lpfc_dmabuf *outp;
 612        struct lpfc_sli_ct_request *CTrsp;
 613        struct lpfc_nodelist *ndlp;
 614        int rc;
 615
 616        /* First save ndlp, before we overwrite it */
 617        ndlp = cmdiocb->context_un.ndlp;
 618
 619        /* we pass cmdiocb to state machine which needs rspiocb as well */
 620        cmdiocb->context_un.rsp_iocb = rspiocb;
 621
 622        outp = (struct lpfc_dmabuf *) cmdiocb->context2;
 623        irsp = &rspiocb->iocb;
 624
 625        lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
 626                 "GID_FT cmpl:     status:x%x/x%x rtry:%d",
 627                irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_ns_retry);
 628
 629        /* Don't bother processing response if vport is being torn down. */
 630        if (vport->load_flag & FC_UNLOADING) {
 631                if (vport->fc_flag & FC_RSCN_MODE)
 632                        lpfc_els_flush_rscn(vport);
 633                goto out;
 634        }
 635
 636        if (lpfc_els_chk_latt(vport)) {
 637                lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
 638                                 "0216 Link event during NS query\n");
 639                if (vport->fc_flag & FC_RSCN_MODE)
 640                        lpfc_els_flush_rscn(vport);
 641                lpfc_vport_set_state(vport, FC_VPORT_FAILED);
 642                goto out;
 643        }
 644        if (lpfc_error_lost_link(irsp)) {
 645                lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
 646                                 "0226 NS query failed due to link event\n");
 647                if (vport->fc_flag & FC_RSCN_MODE)
 648                        lpfc_els_flush_rscn(vport);
 649                goto out;
 650        }
 651        if (irsp->ulpStatus) {
 652                /* Check for retry */
 653                if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
 654                        if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT ||
 655                            (irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
 656                            IOERR_NO_RESOURCES)
 657                                vport->fc_ns_retry++;
 658
 659                        /* CT command is being retried */
 660                        rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
 661                                         vport->fc_ns_retry, 0);
 662                        if (rc == 0)
 663                                goto out;
 664                }
 665                if (vport->fc_flag & FC_RSCN_MODE)
 666                        lpfc_els_flush_rscn(vport);
 667                lpfc_vport_set_state(vport, FC_VPORT_FAILED);
 668                lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
 669                                 "0257 GID_FT Query error: 0x%x 0x%x\n",
 670                                 irsp->ulpStatus, vport->fc_ns_retry);
 671        } else {
 672                /* Good status, continue checking */
 673                CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
 674                if (CTrsp->CommandResponse.bits.CmdRsp ==
 675                    cpu_to_be16(SLI_CT_RESPONSE_FS_ACC)) {
 676                        lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
 677                                         "0208 NameServer Rsp Data: x%x\n",
 678                                         vport->fc_flag);
 679                        lpfc_ns_rsp(vport, outp,
 680                                    (uint32_t) (irsp->un.genreq64.bdl.bdeSize));
 681                } else if (CTrsp->CommandResponse.bits.CmdRsp ==
 682                           be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) {
 683                        /* NameServer Rsp Error */
 684                        if ((CTrsp->ReasonCode == SLI_CT_UNABLE_TO_PERFORM_REQ)
 685                            && (CTrsp->Explanation == SLI_CT_NO_FC4_TYPES)) {
 686                                lpfc_printf_vlog(vport, KERN_INFO,
 687                                        LOG_DISCOVERY,
 688                                        "0269 No NameServer Entries "
 689                                        "Data: x%x x%x x%x x%x\n",
 690                                        CTrsp->CommandResponse.bits.CmdRsp,
 691                                        (uint32_t) CTrsp->ReasonCode,
 692                                        (uint32_t) CTrsp->Explanation,
 693                                        vport->fc_flag);
 694
 695                                lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
 696                                "GID_FT no entry  cmd:x%x rsn:x%x exp:x%x",
 697                                (uint32_t)CTrsp->CommandResponse.bits.CmdRsp,
 698                                (uint32_t) CTrsp->ReasonCode,
 699                                (uint32_t) CTrsp->Explanation);
 700                        } else {
 701                                lpfc_printf_vlog(vport, KERN_INFO,
 702                                        LOG_DISCOVERY,
 703                                        "0240 NameServer Rsp Error "
 704                                        "Data: x%x x%x x%x x%x\n",
 705                                        CTrsp->CommandResponse.bits.CmdRsp,
 706                                        (uint32_t) CTrsp->ReasonCode,
 707                                        (uint32_t) CTrsp->Explanation,
 708                                        vport->fc_flag);
 709
 710                                lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
 711                                "GID_FT rsp err1  cmd:x%x rsn:x%x exp:x%x",
 712                                (uint32_t)CTrsp->CommandResponse.bits.CmdRsp,
 713                                (uint32_t) CTrsp->ReasonCode,
 714                                (uint32_t) CTrsp->Explanation);
 715                        }
 716
 717
 718                } else {
 719                        /* NameServer Rsp Error */
 720                        lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
 721                                        "0241 NameServer Rsp Error "
 722                                        "Data: x%x x%x x%x x%x\n",
 723                                        CTrsp->CommandResponse.bits.CmdRsp,
 724                                        (uint32_t) CTrsp->ReasonCode,
 725                                        (uint32_t) CTrsp->Explanation,
 726                                        vport->fc_flag);
 727
 728                        lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
 729                                "GID_FT rsp err2  cmd:x%x rsn:x%x exp:x%x",
 730                                (uint32_t)CTrsp->CommandResponse.bits.CmdRsp,
 731                                (uint32_t) CTrsp->ReasonCode,
 732                                (uint32_t) CTrsp->Explanation);
 733                }
 734        }
 735        /* Link up / RSCN discovery */
 736        if (vport->num_disc_nodes == 0) {
 737                /*
 738                 * The driver has cycled through all Nports in the RSCN payload.
 739                 * Complete the handling by cleaning up and marking the
 740                 * current driver state.
 741                 */
 742                if (vport->port_state >= LPFC_DISC_AUTH) {
 743                        if (vport->fc_flag & FC_RSCN_MODE) {
 744                                lpfc_els_flush_rscn(vport);
 745                                spin_lock_irq(shost->host_lock);
 746                                vport->fc_flag |= FC_RSCN_MODE; /* RSCN still */
 747                                spin_unlock_irq(shost->host_lock);
 748                        }
 749                        else
 750                                lpfc_els_flush_rscn(vport);
 751                }
 752
 753                lpfc_disc_start(vport);
 754        }
 755out:
 756        cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */
 757        lpfc_ct_free_iocb(phba, cmdiocb);
 758        return;
 759}
 760
 761static void
 762lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 763                        struct lpfc_iocbq *rspiocb)
 764{
 765        struct lpfc_vport *vport = cmdiocb->vport;
 766        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 767        IOCB_t *irsp = &rspiocb->iocb;
 768        struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *) cmdiocb->context1;
 769        struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2;
 770        struct lpfc_sli_ct_request *CTrsp;
 771        int did, rc, retry;
 772        uint8_t fbits;
 773        struct lpfc_nodelist *ndlp;
 774
 775        did = ((struct lpfc_sli_ct_request *) inp->virt)->un.gff.PortId;
 776        did = be32_to_cpu(did);
 777
 778        lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
 779                "GFF_ID cmpl:     status:x%x/x%x did:x%x",
 780                irsp->ulpStatus, irsp->un.ulpWord[4], did);
 781
 782        if (irsp->ulpStatus == IOSTAT_SUCCESS) {
 783                /* Good status, continue checking */
 784                CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
 785                fbits = CTrsp->un.gff_acc.fbits[FCP_TYPE_FEATURE_OFFSET];
 786
 787                if (CTrsp->CommandResponse.bits.CmdRsp ==
 788                    be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) {
 789                        if ((fbits & FC4_FEATURE_INIT) &&
 790                            !(fbits & FC4_FEATURE_TARGET)) {
 791                                lpfc_printf_vlog(vport, KERN_INFO,
 792                                                 LOG_DISCOVERY,
 793                                                 "0270 Skip x%x GFF "
 794                                                 "NameServer Rsp Data: (init) "
 795                                                 "x%x x%x\n", did, fbits,
 796                                                 vport->fc_rscn_id_cnt);
 797                                goto out;
 798                        }
 799                }
 800        }
 801        else {
 802                /* Check for retry */
 803                if (cmdiocb->retry < LPFC_MAX_NS_RETRY) {
 804                        retry = 1;
 805                        if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
 806                                switch ((irsp->un.ulpWord[4] &
 807                                        IOERR_PARAM_MASK)) {
 808
 809                                case IOERR_NO_RESOURCES:
 810                                        /* We don't increment the retry
 811                                         * count for this case.
 812                                         */
 813                                        break;
 814                                case IOERR_LINK_DOWN:
 815                                case IOERR_SLI_ABORTED:
 816                                case IOERR_SLI_DOWN:
 817                                        retry = 0;
 818                                        break;
 819                                default:
 820                                        cmdiocb->retry++;
 821                                }
 822                        }
 823                        else
 824                                cmdiocb->retry++;
 825
 826                        if (retry) {
 827                                /* CT command is being retried */
 828                                rc = lpfc_ns_cmd(vport, SLI_CTNS_GFF_ID,
 829                                         cmdiocb->retry, did);
 830                                if (rc == 0) {
 831                                        /* success */
 832                                        lpfc_ct_free_iocb(phba, cmdiocb);
 833                                        return;
 834                                }
 835                        }
 836                }
 837                lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
 838                                 "0267 NameServer GFF Rsp "
 839                                 "x%x Error (%d %d) Data: x%x x%x\n",
 840                                 did, irsp->ulpStatus, irsp->un.ulpWord[4],
 841                                 vport->fc_flag, vport->fc_rscn_id_cnt);
 842        }
 843
 844        /* This is a target port, unregistered port, or the GFF_ID failed */
 845        ndlp = lpfc_setup_disc_node(vport, did);
 846        if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
 847                lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
 848                                 "0242 Process x%x GFF "
 849                                 "NameServer Rsp Data: x%x x%x x%x\n",
 850                                 did, ndlp->nlp_flag, vport->fc_flag,
 851                                 vport->fc_rscn_id_cnt);
 852        } else {
 853                lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
 854                                 "0243 Skip x%x GFF "
 855                                 "NameServer Rsp Data: x%x x%x\n", did,
 856                                 vport->fc_flag, vport->fc_rscn_id_cnt);
 857        }
 858out:
 859        /* Link up / RSCN discovery */
 860        if (vport->num_disc_nodes)
 861                vport->num_disc_nodes--;
 862        if (vport->num_disc_nodes == 0) {
 863                /*
 864                 * The driver has cycled through all Nports in the RSCN payload.
 865                 * Complete the handling by cleaning up and marking the
 866                 * current driver state.
 867                 */
 868                if (vport->port_state >= LPFC_DISC_AUTH) {
 869                        if (vport->fc_flag & FC_RSCN_MODE) {
 870                                lpfc_els_flush_rscn(vport);
 871                                spin_lock_irq(shost->host_lock);
 872                                vport->fc_flag |= FC_RSCN_MODE; /* RSCN still */
 873                                spin_unlock_irq(shost->host_lock);
 874                        }
 875                        else
 876                                lpfc_els_flush_rscn(vport);
 877                }
 878                lpfc_disc_start(vport);
 879        }
 880        lpfc_ct_free_iocb(phba, cmdiocb);
 881        return;
 882}
 883
 884
 885static void
 886lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 887             struct lpfc_iocbq *rspiocb)
 888{
 889        struct lpfc_vport *vport = cmdiocb->vport;
 890        struct lpfc_dmabuf *inp;
 891        struct lpfc_dmabuf *outp;
 892        IOCB_t *irsp;
 893        struct lpfc_sli_ct_request *CTrsp;
 894        struct lpfc_nodelist *ndlp;
 895        int cmdcode, rc;
 896        uint8_t retry;
 897        uint32_t latt;
 898
 899        /* First save ndlp, before we overwrite it */
 900        ndlp = cmdiocb->context_un.ndlp;
 901
 902        /* we pass cmdiocb to state machine which needs rspiocb as well */
 903        cmdiocb->context_un.rsp_iocb = rspiocb;
 904
 905        inp = (struct lpfc_dmabuf *) cmdiocb->context1;
 906        outp = (struct lpfc_dmabuf *) cmdiocb->context2;
 907        irsp = &rspiocb->iocb;
 908
 909        cmdcode = be16_to_cpu(((struct lpfc_sli_ct_request *) inp->virt)->
 910                                        CommandResponse.bits.CmdRsp);
 911        CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
 912
 913        latt = lpfc_els_chk_latt(vport);
 914
 915        /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */
 916        lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
 917                         "0209 CT Request completes, latt %d, "
 918                         "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n",
 919                         latt, irsp->ulpStatus,
 920                         CTrsp->CommandResponse.bits.CmdRsp,
 921                         cmdiocb->iocb.ulpContext, cmdiocb->iocb.ulpIoTag);
 922
 923        lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
 924                "CT cmd cmpl:     status:x%x/x%x cmd:x%x",
 925                irsp->ulpStatus, irsp->un.ulpWord[4], cmdcode);
 926
 927        if (irsp->ulpStatus) {
 928                lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
 929                                 "0268 NS cmd x%x Error (x%x x%x)\n",
 930                                 cmdcode, irsp->ulpStatus, irsp->un.ulpWord[4]);
 931
 932                if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
 933                        (((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
 934                          IOERR_SLI_DOWN) ||
 935                         ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
 936                          IOERR_SLI_ABORTED)))
 937                        goto out;
 938
 939                retry = cmdiocb->retry;
 940                if (retry >= LPFC_MAX_NS_RETRY)
 941                        goto out;
 942
 943                retry++;
 944                lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
 945                                 "0250 Retrying NS cmd %x\n", cmdcode);
 946                rc = lpfc_ns_cmd(vport, cmdcode, retry, 0);
 947                if (rc == 0)
 948                        goto out;
 949        }
 950
 951out:
 952        cmdiocb->context_un.ndlp = ndlp; /* Now restore ndlp for free */
 953        lpfc_ct_free_iocb(phba, cmdiocb);
 954        return;
 955}
 956
 957static void
 958lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 959                        struct lpfc_iocbq *rspiocb)
 960{
 961        IOCB_t *irsp = &rspiocb->iocb;
 962        struct lpfc_vport *vport = cmdiocb->vport;
 963
 964        if (irsp->ulpStatus == IOSTAT_SUCCESS) {
 965                struct lpfc_dmabuf *outp;
 966                struct lpfc_sli_ct_request *CTrsp;
 967
 968                outp = (struct lpfc_dmabuf *) cmdiocb->context2;
 969                CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
 970                if (CTrsp->CommandResponse.bits.CmdRsp ==
 971                    be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
 972                        vport->ct_flags |= FC_CT_RFT_ID;
 973        }
 974        lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
 975        return;
 976}
 977
 978static void
 979lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 980                        struct lpfc_iocbq *rspiocb)
 981{
 982        IOCB_t *irsp = &rspiocb->iocb;
 983        struct lpfc_vport *vport = cmdiocb->vport;
 984
 985        if (irsp->ulpStatus == IOSTAT_SUCCESS) {
 986                struct lpfc_dmabuf *outp;
 987                struct lpfc_sli_ct_request *CTrsp;
 988
 989                outp = (struct lpfc_dmabuf *) cmdiocb->context2;
 990                CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
 991                if (CTrsp->CommandResponse.bits.CmdRsp ==
 992                    be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
 993                        vport->ct_flags |= FC_CT_RNN_ID;
 994        }
 995        lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
 996        return;
 997}
 998
 999static void
1000lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1001                         struct lpfc_iocbq *rspiocb)
1002{
1003        IOCB_t *irsp = &rspiocb->iocb;
1004        struct lpfc_vport *vport = cmdiocb->vport;
1005
1006        if (irsp->ulpStatus == IOSTAT_SUCCESS) {
1007                struct lpfc_dmabuf *outp;
1008                struct lpfc_sli_ct_request *CTrsp;
1009
1010                outp = (struct lpfc_dmabuf *) cmdiocb->context2;
1011                CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
1012                if (CTrsp->CommandResponse.bits.CmdRsp ==
1013                    be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
1014                        vport->ct_flags |= FC_CT_RSPN_ID;
1015        }
1016        lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
1017        return;
1018}
1019
1020static void
1021lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1022                         struct lpfc_iocbq *rspiocb)
1023{
1024        IOCB_t *irsp = &rspiocb->iocb;
1025        struct lpfc_vport *vport = cmdiocb->vport;
1026
1027        if (irsp->ulpStatus == IOSTAT_SUCCESS) {
1028                struct lpfc_dmabuf *outp;
1029                struct lpfc_sli_ct_request *CTrsp;
1030
1031                outp = (struct lpfc_dmabuf *) cmdiocb->context2;
1032                CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
1033                if (CTrsp->CommandResponse.bits.CmdRsp ==
1034                    be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
1035                        vport->ct_flags |= FC_CT_RSNN_NN;
1036        }
1037        lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
1038        return;
1039}
1040
1041static void
1042lpfc_cmpl_ct_cmd_da_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1043 struct lpfc_iocbq *rspiocb)
1044{
1045        struct lpfc_vport *vport = cmdiocb->vport;
1046
1047        /* even if it fails we will act as though it succeeded. */
1048        vport->ct_flags = 0;
1049        lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
1050        return;
1051}
1052
1053static void
1054lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1055                        struct lpfc_iocbq *rspiocb)
1056{
1057        IOCB_t *irsp = &rspiocb->iocb;
1058        struct lpfc_vport *vport = cmdiocb->vport;
1059
1060        if (irsp->ulpStatus == IOSTAT_SUCCESS) {
1061                struct lpfc_dmabuf *outp;
1062                struct lpfc_sli_ct_request *CTrsp;
1063
1064                outp = (struct lpfc_dmabuf *) cmdiocb->context2;
1065                CTrsp = (struct lpfc_sli_ct_request *) outp->virt;
1066                if (CTrsp->CommandResponse.bits.CmdRsp ==
1067                    be16_to_cpu(SLI_CT_RESPONSE_FS_ACC))
1068                        vport->ct_flags |= FC_CT_RFF_ID;
1069        }
1070        lpfc_cmpl_ct(phba, cmdiocb, rspiocb);
1071        return;
1072}
1073
1074int
1075lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol,
1076        size_t size)
1077{
1078        int n;
1079        uint8_t *wwn = vport->phba->wwpn;
1080
1081        n = snprintf(symbol, size,
1082                     "Emulex PPN-%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1083                     wwn[0], wwn[1], wwn[2], wwn[3],
1084                     wwn[4], wwn[5], wwn[6], wwn[7]);
1085
1086        if (vport->port_type == LPFC_PHYSICAL_PORT)
1087                return n;
1088
1089        if (n < size)
1090                n += snprintf(symbol + n, size - n, " VPort-%d", vport->vpi);
1091
1092        if (n < size &&
1093            strlen(vport->fc_vport->symbolic_name))
1094                n += snprintf(symbol + n, size - n, " VName-%s",
1095                              vport->fc_vport->symbolic_name);
1096        return n;
1097}
1098
1099int
1100lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol,
1101        size_t size)
1102{
1103        char fwrev[FW_REV_STR_SIZE];
1104        int n;
1105
1106        lpfc_decode_firmware_rev(vport->phba, fwrev, 0);
1107
1108        n = snprintf(symbol, size, "Emulex %s", vport->phba->ModelName);
1109
1110        if (size < n)
1111                return n;
1112        n += snprintf(symbol + n, size - n, " FV%s", fwrev);
1113
1114        if (size < n)
1115                return n;
1116        n += snprintf(symbol + n, size - n, " DV%s", lpfc_release_version);
1117
1118        if (size < n)
1119                return n;
1120        n += snprintf(symbol + n, size - n, " HN:%s", init_utsname()->nodename);
1121
1122        /* Note :- OS name is "Linux" */
1123        if (size < n)
1124                return n;
1125        n += snprintf(symbol + n, size - n, " OS:%s", init_utsname()->sysname);
1126
1127        return n;
1128}
1129
1130static uint32_t
1131lpfc_find_map_node(struct lpfc_vport *vport)
1132{
1133        struct lpfc_nodelist *ndlp, *next_ndlp;
1134        struct Scsi_Host  *shost;
1135        uint32_t cnt = 0;
1136
1137        shost = lpfc_shost_from_vport(vport);
1138        spin_lock_irq(shost->host_lock);
1139        list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
1140                if (ndlp->nlp_type & NLP_FABRIC)
1141                        continue;
1142                if ((ndlp->nlp_state == NLP_STE_MAPPED_NODE) ||
1143                    (ndlp->nlp_state == NLP_STE_UNMAPPED_NODE))
1144                        cnt++;
1145        }
1146        spin_unlock_irq(shost->host_lock);
1147        return cnt;
1148}
1149
1150/*
1151 * lpfc_ns_cmd
1152 * Description:
1153 *    Issue Cmd to NameServer
1154 *       SLI_CTNS_GID_FT
1155 *       LI_CTNS_RFT_ID
1156 */
1157int
1158lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
1159            uint8_t retry, uint32_t context)
1160{
1161        struct lpfc_nodelist * ndlp;
1162        struct lpfc_hba *phba = vport->phba;
1163        struct lpfc_dmabuf *mp, *bmp;
1164        struct lpfc_sli_ct_request *CtReq;
1165        struct ulp_bde64 *bpl;
1166        void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,
1167                      struct lpfc_iocbq *) = NULL;
1168        uint32_t rsp_size = 1024;
1169        size_t   size;
1170        int rc = 0;
1171
1172        ndlp = lpfc_findnode_did(vport, NameServer_DID);
1173        if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)
1174            || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) {
1175                rc=1;
1176                goto ns_cmd_exit;
1177        }
1178
1179        /* fill in BDEs for command */
1180        /* Allocate buffer for command payload */
1181        mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
1182        if (!mp) {
1183                rc=2;
1184                goto ns_cmd_exit;
1185        }
1186
1187        INIT_LIST_HEAD(&mp->list);
1188        mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys));
1189        if (!mp->virt) {
1190                rc=3;
1191                goto ns_cmd_free_mp;
1192        }
1193
1194        /* Allocate buffer for Buffer ptr list */
1195        bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
1196        if (!bmp) {
1197                rc=4;
1198                goto ns_cmd_free_mpvirt;
1199        }
1200
1201        INIT_LIST_HEAD(&bmp->list);
1202        bmp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(bmp->phys));
1203        if (!bmp->virt) {
1204                rc=5;
1205                goto ns_cmd_free_bmp;
1206        }
1207
1208        /* NameServer Req */
1209        lpfc_printf_vlog(vport, KERN_INFO ,LOG_DISCOVERY,
1210                         "0236 NameServer Req Data: x%x x%x x%x\n",
1211                         cmdcode, vport->fc_flag, vport->fc_rscn_id_cnt);
1212
1213        bpl = (struct ulp_bde64 *) bmp->virt;
1214        memset(bpl, 0, sizeof(struct ulp_bde64));
1215        bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) );
1216        bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) );
1217        bpl->tus.f.bdeFlags = 0;
1218        if (cmdcode == SLI_CTNS_GID_FT)
1219                bpl->tus.f.bdeSize = GID_REQUEST_SZ;
1220        else if (cmdcode == SLI_CTNS_GFF_ID)
1221                bpl->tus.f.bdeSize = GFF_REQUEST_SZ;
1222        else if (cmdcode == SLI_CTNS_RFT_ID)
1223                bpl->tus.f.bdeSize = RFT_REQUEST_SZ;
1224        else if (cmdcode == SLI_CTNS_RNN_ID)
1225                bpl->tus.f.bdeSize = RNN_REQUEST_SZ;
1226        else if (cmdcode == SLI_CTNS_RSPN_ID)
1227                bpl->tus.f.bdeSize = RSPN_REQUEST_SZ;
1228        else if (cmdcode == SLI_CTNS_RSNN_NN)
1229                bpl->tus.f.bdeSize = RSNN_REQUEST_SZ;
1230        else if (cmdcode == SLI_CTNS_DA_ID)
1231                bpl->tus.f.bdeSize = DA_ID_REQUEST_SZ;
1232        else if (cmdcode == SLI_CTNS_RFF_ID)
1233                bpl->tus.f.bdeSize = RFF_REQUEST_SZ;
1234        else
1235                bpl->tus.f.bdeSize = 0;
1236        bpl->tus.w = le32_to_cpu(bpl->tus.w);
1237
1238        CtReq = (struct lpfc_sli_ct_request *) mp->virt;
1239        memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request));
1240        CtReq->RevisionId.bits.Revision = SLI_CT_REVISION;
1241        CtReq->RevisionId.bits.InId = 0;
1242        CtReq->FsType = SLI_CT_DIRECTORY_SERVICE;
1243        CtReq->FsSubType = SLI_CT_DIRECTORY_NAME_SERVER;
1244        CtReq->CommandResponse.bits.Size = 0;
1245        switch (cmdcode) {
1246        case SLI_CTNS_GID_FT:
1247                CtReq->CommandResponse.bits.CmdRsp =
1248                    cpu_to_be16(SLI_CTNS_GID_FT);
1249                CtReq->un.gid.Fc4Type = SLI_CTPT_FCP;
1250                if (vport->port_state < LPFC_NS_QRY)
1251                        vport->port_state = LPFC_NS_QRY;
1252                lpfc_set_disctmo(vport);
1253                cmpl = lpfc_cmpl_ct_cmd_gid_ft;
1254                rsp_size = FC_MAX_NS_RSP;
1255                break;
1256
1257        case SLI_CTNS_GFF_ID:
1258                CtReq->CommandResponse.bits.CmdRsp =
1259                        cpu_to_be16(SLI_CTNS_GFF_ID);
1260                CtReq->un.gff.PortId = cpu_to_be32(context);
1261                cmpl = lpfc_cmpl_ct_cmd_gff_id;
1262                break;
1263
1264        case SLI_CTNS_RFT_ID:
1265                vport->ct_flags &= ~FC_CT_RFT_ID;
1266                CtReq->CommandResponse.bits.CmdRsp =
1267                    cpu_to_be16(SLI_CTNS_RFT_ID);
1268                CtReq->un.rft.PortId = cpu_to_be32(vport->fc_myDID);
1269                CtReq->un.rft.fcpReg = 1;
1270                cmpl = lpfc_cmpl_ct_cmd_rft_id;
1271                break;
1272
1273        case SLI_CTNS_RNN_ID:
1274                vport->ct_flags &= ~FC_CT_RNN_ID;
1275                CtReq->CommandResponse.bits.CmdRsp =
1276                    cpu_to_be16(SLI_CTNS_RNN_ID);
1277                CtReq->un.rnn.PortId = cpu_to_be32(vport->fc_myDID);
1278                memcpy(CtReq->un.rnn.wwnn,  &vport->fc_nodename,
1279                       sizeof(struct lpfc_name));
1280                cmpl = lpfc_cmpl_ct_cmd_rnn_id;
1281                break;
1282
1283        case SLI_CTNS_RSPN_ID:
1284                vport->ct_flags &= ~FC_CT_RSPN_ID;
1285                CtReq->CommandResponse.bits.CmdRsp =
1286                    cpu_to_be16(SLI_CTNS_RSPN_ID);
1287                CtReq->un.rspn.PortId = cpu_to_be32(vport->fc_myDID);
1288                size = sizeof(CtReq->un.rspn.symbname);
1289                CtReq->un.rspn.len =
1290                        lpfc_vport_symbolic_port_name(vport,
1291                        CtReq->un.rspn.symbname, size);
1292                cmpl = lpfc_cmpl_ct_cmd_rspn_id;
1293                break;
1294        case SLI_CTNS_RSNN_NN:
1295                vport->ct_flags &= ~FC_CT_RSNN_NN;
1296                CtReq->CommandResponse.bits.CmdRsp =
1297                    cpu_to_be16(SLI_CTNS_RSNN_NN);
1298                memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename,
1299                       sizeof(struct lpfc_name));
1300                size = sizeof(CtReq->un.rsnn.symbname);
1301                CtReq->un.rsnn.len =
1302                        lpfc_vport_symbolic_node_name(vport,
1303                        CtReq->un.rsnn.symbname, size);
1304                cmpl = lpfc_cmpl_ct_cmd_rsnn_nn;
1305                break;
1306        case SLI_CTNS_DA_ID:
1307                /* Implement DA_ID Nameserver request */
1308                CtReq->CommandResponse.bits.CmdRsp =
1309                        cpu_to_be16(SLI_CTNS_DA_ID);
1310                CtReq->un.da_id.port_id = cpu_to_be32(vport->fc_myDID);
1311                cmpl = lpfc_cmpl_ct_cmd_da_id;
1312                break;
1313        case SLI_CTNS_RFF_ID:
1314                vport->ct_flags &= ~FC_CT_RFF_ID;
1315                CtReq->CommandResponse.bits.CmdRsp =
1316                    cpu_to_be16(SLI_CTNS_RFF_ID);
1317                CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID);
1318                CtReq->un.rff.fbits = FC4_FEATURE_INIT;
1319                CtReq->un.rff.type_code = FC_TYPE_FCP;
1320                cmpl = lpfc_cmpl_ct_cmd_rff_id;
1321                break;
1322        }
1323        /* The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count
1324         * to hold ndlp reference for the corresponding callback function.
1325         */
1326        if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry)) {
1327                /* On success, The cmpl function will free the buffers */
1328                lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
1329                        "Issue CT cmd:    cmd:x%x did:x%x",
1330                        cmdcode, ndlp->nlp_DID, 0);
1331                return 0;
1332        }
1333        rc=6;
1334
1335        /* Decrement ndlp reference count to release ndlp reference held
1336         * for the failed command's callback function.
1337         */
1338        lpfc_nlp_put(ndlp);
1339
1340        lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
1341ns_cmd_free_bmp:
1342        kfree(bmp);
1343ns_cmd_free_mpvirt:
1344        lpfc_mbuf_free(phba, mp->virt, mp->phys);
1345ns_cmd_free_mp:
1346        kfree(mp);
1347ns_cmd_exit:
1348        lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
1349                         "0266 Issue NameServer Req x%x err %d Data: x%x x%x\n",
1350                         cmdcode, rc, vport->fc_flag, vport->fc_rscn_id_cnt);
1351        return 1;
1352}
1353
1354/**
1355 * lpfc_cmpl_ct_disc_fdmi - Handle a discovery FDMI completion
1356 * @phba: Pointer to HBA context object.
1357 * @cmdiocb: Pointer to the command IOCBQ.
1358 * @rspiocb: Pointer to the response IOCBQ.
1359 *
1360 * This function to handle the completion of a driver initiated FDMI
1361 * CT command issued during discovery.
1362 */
1363static void
1364lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1365                       struct lpfc_iocbq *rspiocb)
1366{
1367        struct lpfc_vport *vport = cmdiocb->vport;
1368        struct lpfc_dmabuf *inp = cmdiocb->context1;
1369        struct lpfc_dmabuf *outp = cmdiocb->context2;
1370        struct lpfc_sli_ct_request *CTcmd = inp->virt;
1371        struct lpfc_sli_ct_request *CTrsp = outp->virt;
1372        uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp;
1373        uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp;
1374        IOCB_t *irsp = &rspiocb->iocb;
1375        struct lpfc_nodelist *ndlp;
1376        uint32_t latt, cmd, err;
1377
1378        latt = lpfc_els_chk_latt(vport);
1379        lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,
1380                "FDMI cmpl:       status:x%x/x%x latt:%d",
1381                irsp->ulpStatus, irsp->un.ulpWord[4], latt);
1382
1383        if (latt || irsp->ulpStatus) {
1384
1385                /* Look for a retryable error */
1386                if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
1387                        switch ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK)) {
1388                        case IOERR_SLI_ABORTED:
1389                        case IOERR_ABORT_IN_PROGRESS:
1390                        case IOERR_SEQUENCE_TIMEOUT:
1391                        case IOERR_ILLEGAL_FRAME:
1392                        case IOERR_NO_RESOURCES:
1393                        case IOERR_ILLEGAL_COMMAND:
1394                                cmdiocb->retry++;
1395                                if (cmdiocb->retry >= LPFC_FDMI_MAX_RETRY)
1396                                        break;
1397
1398                                /* Retry the same FDMI command */
1399                                err = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING,
1400                                                          cmdiocb, 0);
1401                                if (err == IOCB_ERROR)
1402                                        break;
1403                                return;
1404                        default:
1405                                break;
1406                        }
1407                }
1408
1409                lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1410                                 "0229 FDMI cmd %04x failed, latt = %d "
1411                                 "ulpStatus: x%x, rid x%x\n",
1412                                 be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus,
1413                                 irsp->un.ulpWord[4]);
1414        }
1415        lpfc_ct_free_iocb(phba, cmdiocb);
1416
1417        ndlp = lpfc_findnode_did(vport, FDMI_DID);
1418        if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
1419                return;
1420
1421        /* Check for a CT LS_RJT response */
1422        cmd =  be16_to_cpu(fdmi_cmd);
1423        if (fdmi_rsp == cpu_to_be16(SLI_CT_RESPONSE_FS_RJT)) {
1424                /* FDMI rsp failed */
1425                lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1426                                 "0220 FDMI cmd failed FS_RJT Data: x%x", cmd);
1427
1428                /* Should we fallback to FDMI-2 / FDMI-1 ? */
1429                switch (cmd) {
1430                case SLI_MGMT_RHBA:
1431                        if (vport->fdmi_hba_mask == LPFC_FDMI2_HBA_ATTR) {
1432                                /* Fallback to FDMI-1 */
1433                                vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR;
1434                                vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR;
1435                                /* Start over */
1436                                lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0);
1437                        }
1438                        return;
1439
1440                case SLI_MGMT_RPRT:
1441                        if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) {
1442                                /* Fallback to FDMI-1 */
1443                                vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR;
1444                                /* Start over */
1445                                lpfc_fdmi_cmd(vport, ndlp, cmd, 0);
1446                        }
1447                        if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) {
1448                                vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
1449                                /* Retry the same command */
1450                                lpfc_fdmi_cmd(vport, ndlp, cmd, 0);
1451                        }
1452                        return;
1453
1454                case SLI_MGMT_RPA:
1455                        if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) {
1456                                /* Fallback to FDMI-1 */
1457                                vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR;
1458                                vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR;
1459                                /* Start over */
1460                                lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0);
1461                        }
1462                        if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) {
1463                                vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
1464                                /* Retry the same command */
1465                                lpfc_fdmi_cmd(vport, ndlp, cmd, 0);
1466                        }
1467                        return;
1468                }
1469        }
1470
1471        /*
1472         * On success, need to cycle thru FDMI registration for discovery
1473         * DHBA -> DPRT -> RHBA -> RPA  (physical port)
1474         * DPRT -> RPRT (vports)
1475         */
1476        switch (cmd) {
1477        case SLI_MGMT_RHBA:
1478                lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA, 0);
1479                break;
1480
1481        case SLI_MGMT_DHBA:
1482                lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0);
1483                break;
1484
1485        case SLI_MGMT_DPRT:
1486                if (vport->port_type == LPFC_PHYSICAL_PORT)
1487                        lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA, 0);
1488                else
1489                        lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, 0);
1490                break;
1491        }
1492        return;
1493}
1494
1495
1496/**
1497 * lpfc_fdmi_num_disc_check - Check how many mapped NPorts we are connected to
1498 * @vport: pointer to a host virtual N_Port data structure.
1499 *
1500 * Called from hbeat timeout routine to check if the number of discovered
1501 * ports has changed. If so, re-register thar port Attribute.
1502 */
1503void
1504lpfc_fdmi_num_disc_check(struct lpfc_vport *vport)
1505{
1506        struct lpfc_hba *phba = vport->phba;
1507        struct lpfc_nodelist *ndlp;
1508        uint16_t cnt;
1509
1510        if (!lpfc_is_link_up(phba))
1511                return;
1512
1513        /* Must be connected to a Fabric */
1514        if (!(vport->fc_flag & FC_FABRIC))
1515                return;
1516
1517        if (!(vport->fdmi_port_mask & LPFC_FDMI_PORT_ATTR_num_disc))
1518                return;
1519
1520        cnt = lpfc_find_map_node(vport);
1521        if (cnt == vport->fdmi_num_disc)
1522                return;
1523
1524        ndlp = lpfc_findnode_did(vport, FDMI_DID);
1525        if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
1526                return;
1527
1528        if (vport->port_type == LPFC_PHYSICAL_PORT) {
1529                lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA,
1530                              LPFC_FDMI_PORT_ATTR_num_disc);
1531        } else {
1532                lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT,
1533                              LPFC_FDMI_PORT_ATTR_num_disc);
1534        }
1535}
1536
1537/* Routines for all individual HBA attributes */
1538static int
1539lpfc_fdmi_hba_attr_wwnn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad)
1540{
1541        struct lpfc_fdmi_attr_entry *ae;
1542        uint32_t size;
1543
1544        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1545        memset(ae, 0, sizeof(struct lpfc_name));
1546
1547        memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName,
1548               sizeof(struct lpfc_name));
1549        size = FOURBYTES + sizeof(struct lpfc_name);
1550        ad->AttrLen = cpu_to_be16(size);
1551        ad->AttrType = cpu_to_be16(RHBA_NODENAME);
1552        return size;
1553}
1554static int
1555lpfc_fdmi_hba_attr_manufacturer(struct lpfc_vport *vport,
1556                                struct lpfc_fdmi_attr_def *ad)
1557{
1558        struct lpfc_fdmi_attr_entry *ae;
1559        uint32_t len, size;
1560
1561        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1562        memset(ae, 0, 256);
1563
1564        strncpy(ae->un.AttrString,
1565                "Emulex Corporation",
1566                       sizeof(ae->un.AttrString));
1567        len = strnlen(ae->un.AttrString,
1568                          sizeof(ae->un.AttrString));
1569        len += (len & 3) ? (4 - (len & 3)) : 4;
1570        size = FOURBYTES + len;
1571        ad->AttrLen = cpu_to_be16(size);
1572        ad->AttrType = cpu_to_be16(RHBA_MANUFACTURER);
1573        return size;
1574}
1575
1576static int
1577lpfc_fdmi_hba_attr_sn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad)
1578{
1579        struct lpfc_hba *phba = vport->phba;
1580        struct lpfc_fdmi_attr_entry *ae;
1581        uint32_t len, size;
1582
1583        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1584        memset(ae, 0, 256);
1585
1586        strncpy(ae->un.AttrString, phba->SerialNumber,
1587                sizeof(ae->un.AttrString));
1588        len = strnlen(ae->un.AttrString,
1589                          sizeof(ae->un.AttrString));
1590        len += (len & 3) ? (4 - (len & 3)) : 4;
1591        size = FOURBYTES + len;
1592        ad->AttrLen = cpu_to_be16(size);
1593        ad->AttrType = cpu_to_be16(RHBA_SERIAL_NUMBER);
1594        return size;
1595}
1596
1597static int
1598lpfc_fdmi_hba_attr_model(struct lpfc_vport *vport,
1599                         struct lpfc_fdmi_attr_def *ad)
1600{
1601        struct lpfc_hba *phba = vport->phba;
1602        struct lpfc_fdmi_attr_entry *ae;
1603        uint32_t len, size;
1604
1605        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1606        memset(ae, 0, 256);
1607
1608        strncpy(ae->un.AttrString, phba->ModelName,
1609                sizeof(ae->un.AttrString));
1610        len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
1611        len += (len & 3) ? (4 - (len & 3)) : 4;
1612        size = FOURBYTES + len;
1613        ad->AttrLen = cpu_to_be16(size);
1614        ad->AttrType = cpu_to_be16(RHBA_MODEL);
1615        return size;
1616}
1617
1618static int
1619lpfc_fdmi_hba_attr_description(struct lpfc_vport *vport,
1620                               struct lpfc_fdmi_attr_def *ad)
1621{
1622        struct lpfc_hba *phba = vport->phba;
1623        struct lpfc_fdmi_attr_entry *ae;
1624        uint32_t len, size;
1625
1626        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1627        memset(ae, 0, 256);
1628
1629        strncpy(ae->un.AttrString, phba->ModelDesc,
1630                sizeof(ae->un.AttrString));
1631        len = strnlen(ae->un.AttrString,
1632                                  sizeof(ae->un.AttrString));
1633        len += (len & 3) ? (4 - (len & 3)) : 4;
1634        size = FOURBYTES + len;
1635        ad->AttrLen = cpu_to_be16(size);
1636        ad->AttrType = cpu_to_be16(RHBA_MODEL_DESCRIPTION);
1637        return size;
1638}
1639
1640static int
1641lpfc_fdmi_hba_attr_hdw_ver(struct lpfc_vport *vport,
1642                           struct lpfc_fdmi_attr_def *ad)
1643{
1644        struct lpfc_hba *phba = vport->phba;
1645        lpfc_vpd_t *vp = &phba->vpd;
1646        struct lpfc_fdmi_attr_entry *ae;
1647        uint32_t i, j, incr, size;
1648
1649        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1650        memset(ae, 0, 256);
1651
1652        /* Convert JEDEC ID to ascii for hardware version */
1653        incr = vp->rev.biuRev;
1654        for (i = 0; i < 8; i++) {
1655                j = (incr & 0xf);
1656                if (j <= 9)
1657                        ae->un.AttrString[7 - i] =
1658                            (char)((uint8_t) 0x30 +
1659                                   (uint8_t) j);
1660                else
1661                        ae->un.AttrString[7 - i] =
1662                            (char)((uint8_t) 0x61 +
1663                                   (uint8_t) (j - 10));
1664                incr = (incr >> 4);
1665        }
1666        size = FOURBYTES + 8;
1667        ad->AttrLen = cpu_to_be16(size);
1668        ad->AttrType = cpu_to_be16(RHBA_HARDWARE_VERSION);
1669        return size;
1670}
1671
1672static int
1673lpfc_fdmi_hba_attr_drvr_ver(struct lpfc_vport *vport,
1674                            struct lpfc_fdmi_attr_def *ad)
1675{
1676        struct lpfc_fdmi_attr_entry *ae;
1677        uint32_t len, size;
1678
1679        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1680        memset(ae, 0, 256);
1681
1682        strncpy(ae->un.AttrString, lpfc_release_version,
1683                sizeof(ae->un.AttrString));
1684        len = strnlen(ae->un.AttrString,
1685                          sizeof(ae->un.AttrString));
1686        len += (len & 3) ? (4 - (len & 3)) : 4;
1687        size = FOURBYTES + len;
1688        ad->AttrLen = cpu_to_be16(size);
1689        ad->AttrType = cpu_to_be16(RHBA_DRIVER_VERSION);
1690        return size;
1691}
1692
1693static int
1694lpfc_fdmi_hba_attr_rom_ver(struct lpfc_vport *vport,
1695                           struct lpfc_fdmi_attr_def *ad)
1696{
1697        struct lpfc_hba *phba = vport->phba;
1698        struct lpfc_fdmi_attr_entry *ae;
1699        uint32_t len, size;
1700
1701        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1702        memset(ae, 0, 256);
1703
1704        if (phba->sli_rev == LPFC_SLI_REV4)
1705                lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1);
1706        else
1707                strncpy(ae->un.AttrString, phba->OptionROMVersion,
1708                        sizeof(ae->un.AttrString));
1709        len = strnlen(ae->un.AttrString,
1710                          sizeof(ae->un.AttrString));
1711        len += (len & 3) ? (4 - (len & 3)) : 4;
1712        size = FOURBYTES + len;
1713        ad->AttrLen = cpu_to_be16(size);
1714        ad->AttrType = cpu_to_be16(RHBA_OPTION_ROM_VERSION);
1715        return size;
1716}
1717
1718static int
1719lpfc_fdmi_hba_attr_fmw_ver(struct lpfc_vport *vport,
1720                           struct lpfc_fdmi_attr_def *ad)
1721{
1722        struct lpfc_hba *phba = vport->phba;
1723        struct lpfc_fdmi_attr_entry *ae;
1724        uint32_t len, size;
1725
1726        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1727        memset(ae, 0, 256);
1728
1729        lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1);
1730        len = strnlen(ae->un.AttrString,
1731                          sizeof(ae->un.AttrString));
1732        len += (len & 3) ? (4 - (len & 3)) : 4;
1733        size = FOURBYTES + len;
1734        ad->AttrLen = cpu_to_be16(size);
1735        ad->AttrType = cpu_to_be16(RHBA_FIRMWARE_VERSION);
1736        return size;
1737}
1738
1739static int
1740lpfc_fdmi_hba_attr_os_ver(struct lpfc_vport *vport,
1741                          struct lpfc_fdmi_attr_def *ad)
1742{
1743        struct lpfc_fdmi_attr_entry *ae;
1744        uint32_t len, size;
1745
1746        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1747        memset(ae, 0, 256);
1748
1749        snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s %s %s",
1750                 init_utsname()->sysname,
1751                 init_utsname()->release,
1752                 init_utsname()->version);
1753
1754        len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
1755        len += (len & 3) ? (4 - (len & 3)) : 4;
1756        size = FOURBYTES + len;
1757        ad->AttrLen = cpu_to_be16(size);
1758        ad->AttrType = cpu_to_be16(RHBA_OS_NAME_VERSION);
1759        return size;
1760}
1761
1762static int
1763lpfc_fdmi_hba_attr_ct_len(struct lpfc_vport *vport,
1764                          struct lpfc_fdmi_attr_def *ad)
1765{
1766        struct lpfc_fdmi_attr_entry *ae;
1767        uint32_t size;
1768
1769        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1770
1771        ae->un.AttrInt =  cpu_to_be32(LPFC_MAX_CT_SIZE);
1772        size = FOURBYTES + sizeof(uint32_t);
1773        ad->AttrLen = cpu_to_be16(size);
1774        ad->AttrType = cpu_to_be16(RHBA_MAX_CT_PAYLOAD_LEN);
1775        return size;
1776}
1777
1778static int
1779lpfc_fdmi_hba_attr_symbolic_name(struct lpfc_vport *vport,
1780                                 struct lpfc_fdmi_attr_def *ad)
1781{
1782        struct lpfc_fdmi_attr_entry *ae;
1783        uint32_t len, size;
1784
1785        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1786        memset(ae, 0, 256);
1787
1788        len = lpfc_vport_symbolic_node_name(vport,
1789                                ae->un.AttrString, 256);
1790        len += (len & 3) ? (4 - (len & 3)) : 4;
1791        size = FOURBYTES + len;
1792        ad->AttrLen = cpu_to_be16(size);
1793        ad->AttrType = cpu_to_be16(RHBA_SYM_NODENAME);
1794        return size;
1795}
1796
1797static int
1798lpfc_fdmi_hba_attr_vendor_info(struct lpfc_vport *vport,
1799                               struct lpfc_fdmi_attr_def *ad)
1800{
1801        struct lpfc_fdmi_attr_entry *ae;
1802        uint32_t size;
1803
1804        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1805
1806        /* Nothing is defined for this currently */
1807        ae->un.AttrInt =  cpu_to_be32(0);
1808        size = FOURBYTES + sizeof(uint32_t);
1809        ad->AttrLen = cpu_to_be16(size);
1810        ad->AttrType = cpu_to_be16(RHBA_VENDOR_INFO);
1811        return size;
1812}
1813
1814static int
1815lpfc_fdmi_hba_attr_num_ports(struct lpfc_vport *vport,
1816                             struct lpfc_fdmi_attr_def *ad)
1817{
1818        struct lpfc_fdmi_attr_entry *ae;
1819        uint32_t size;
1820
1821        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1822
1823        /* Each driver instance corresponds to a single port */
1824        ae->un.AttrInt =  cpu_to_be32(1);
1825        size = FOURBYTES + sizeof(uint32_t);
1826        ad->AttrLen = cpu_to_be16(size);
1827        ad->AttrType = cpu_to_be16(RHBA_NUM_PORTS);
1828        return size;
1829}
1830
1831static int
1832lpfc_fdmi_hba_attr_fabric_wwnn(struct lpfc_vport *vport,
1833                               struct lpfc_fdmi_attr_def *ad)
1834{
1835        struct lpfc_fdmi_attr_entry *ae;
1836        uint32_t size;
1837
1838        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1839        memset(ae, 0, sizeof(struct lpfc_name));
1840
1841        memcpy(&ae->un.AttrWWN, &vport->fabric_nodename,
1842               sizeof(struct lpfc_name));
1843        size = FOURBYTES + sizeof(struct lpfc_name);
1844        ad->AttrLen = cpu_to_be16(size);
1845        ad->AttrType = cpu_to_be16(RHBA_FABRIC_WWNN);
1846        return size;
1847}
1848
1849static int
1850lpfc_fdmi_hba_attr_bios_ver(struct lpfc_vport *vport,
1851                            struct lpfc_fdmi_attr_def *ad)
1852{
1853        struct lpfc_hba *phba = vport->phba;
1854        struct lpfc_fdmi_attr_entry *ae;
1855        uint32_t len, size;
1856
1857        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1858        memset(ae, 0, 256);
1859
1860        lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1);
1861        len = strnlen(ae->un.AttrString,
1862                          sizeof(ae->un.AttrString));
1863        len += (len & 3) ? (4 - (len & 3)) : 4;
1864        size = FOURBYTES + len;
1865        ad->AttrLen = cpu_to_be16(size);
1866        ad->AttrType = cpu_to_be16(RHBA_BIOS_VERSION);
1867        return size;
1868}
1869
1870static int
1871lpfc_fdmi_hba_attr_bios_state(struct lpfc_vport *vport,
1872                              struct lpfc_fdmi_attr_def *ad)
1873{
1874        struct lpfc_fdmi_attr_entry *ae;
1875        uint32_t size;
1876
1877        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1878
1879        /* Driver doesn't have access to this information */
1880        ae->un.AttrInt =  cpu_to_be32(0);
1881        size = FOURBYTES + sizeof(uint32_t);
1882        ad->AttrLen = cpu_to_be16(size);
1883        ad->AttrType = cpu_to_be16(RHBA_BIOS_STATE);
1884        return size;
1885}
1886
1887static int
1888lpfc_fdmi_hba_attr_vendor_id(struct lpfc_vport *vport,
1889                             struct lpfc_fdmi_attr_def *ad)
1890{
1891        struct lpfc_fdmi_attr_entry *ae;
1892        uint32_t len, size;
1893
1894        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1895        memset(ae, 0, 256);
1896
1897        strncpy(ae->un.AttrString, "EMULEX",
1898                sizeof(ae->un.AttrString));
1899        len = strnlen(ae->un.AttrString,
1900                          sizeof(ae->un.AttrString));
1901        len += (len & 3) ? (4 - (len & 3)) : 4;
1902        size = FOURBYTES + len;
1903        ad->AttrLen = cpu_to_be16(size);
1904        ad->AttrType = cpu_to_be16(RHBA_VENDOR_ID);
1905        return size;
1906}
1907
1908/* Routines for all individual PORT attributes */
1909static int
1910lpfc_fdmi_port_attr_fc4type(struct lpfc_vport *vport,
1911                            struct lpfc_fdmi_attr_def *ad)
1912{
1913        struct lpfc_fdmi_attr_entry *ae;
1914        uint32_t size;
1915
1916        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1917        memset(ae, 0, 32);
1918
1919        ae->un.AttrTypes[3] = 0x02; /* Type 1 - ELS */
1920        ae->un.AttrTypes[2] = 0x01; /* Type 8 - FCP */
1921        ae->un.AttrTypes[7] = 0x01; /* Type 32 - CT */
1922        size = FOURBYTES + 32;
1923        ad->AttrLen = cpu_to_be16(size);
1924        ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES);
1925        return size;
1926}
1927
1928static int
1929lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport,
1930                                  struct lpfc_fdmi_attr_def *ad)
1931{
1932        struct lpfc_hba   *phba = vport->phba;
1933        struct lpfc_fdmi_attr_entry *ae;
1934        uint32_t size;
1935
1936        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1937
1938        ae->un.AttrInt = 0;
1939        if (!(phba->hba_flag & HBA_FCOE_MODE)) {
1940                if (phba->lmt & LMT_32Gb)
1941                        ae->un.AttrInt |= HBA_PORTSPEED_32GFC;
1942                if (phba->lmt & LMT_16Gb)
1943                        ae->un.AttrInt |= HBA_PORTSPEED_16GFC;
1944                if (phba->lmt & LMT_10Gb)
1945                        ae->un.AttrInt |= HBA_PORTSPEED_10GFC;
1946                if (phba->lmt & LMT_8Gb)
1947                        ae->un.AttrInt |= HBA_PORTSPEED_8GFC;
1948                if (phba->lmt & LMT_4Gb)
1949                        ae->un.AttrInt |= HBA_PORTSPEED_4GFC;
1950                if (phba->lmt & LMT_2Gb)
1951                        ae->un.AttrInt |= HBA_PORTSPEED_2GFC;
1952                if (phba->lmt & LMT_1Gb)
1953                        ae->un.AttrInt |= HBA_PORTSPEED_1GFC;
1954        } else {
1955                /* FCoE links support only one speed */
1956                switch (phba->fc_linkspeed) {
1957                case LPFC_ASYNC_LINK_SPEED_10GBPS:
1958                        ae->un.AttrInt = HBA_PORTSPEED_10GE;
1959                        break;
1960                case LPFC_ASYNC_LINK_SPEED_25GBPS:
1961                        ae->un.AttrInt = HBA_PORTSPEED_25GE;
1962                        break;
1963                case LPFC_ASYNC_LINK_SPEED_40GBPS:
1964                        ae->un.AttrInt = HBA_PORTSPEED_40GE;
1965                        break;
1966                case LPFC_ASYNC_LINK_SPEED_100GBPS:
1967                        ae->un.AttrInt = HBA_PORTSPEED_100GE;
1968                        break;
1969                }
1970        }
1971        ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt);
1972        size = FOURBYTES + sizeof(uint32_t);
1973        ad->AttrLen = cpu_to_be16(size);
1974        ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED);
1975        return size;
1976}
1977
1978static int
1979lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport,
1980                          struct lpfc_fdmi_attr_def *ad)
1981{
1982        struct lpfc_hba   *phba = vport->phba;
1983        struct lpfc_fdmi_attr_entry *ae;
1984        uint32_t size;
1985
1986        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1987
1988        if (!(phba->hba_flag & HBA_FCOE_MODE)) {
1989                switch (phba->fc_linkspeed) {
1990                case LPFC_LINK_SPEED_1GHZ:
1991                        ae->un.AttrInt = HBA_PORTSPEED_1GFC;
1992                        break;
1993                case LPFC_LINK_SPEED_2GHZ:
1994                        ae->un.AttrInt = HBA_PORTSPEED_2GFC;
1995                        break;
1996                case LPFC_LINK_SPEED_4GHZ:
1997                        ae->un.AttrInt = HBA_PORTSPEED_4GFC;
1998                        break;
1999                case LPFC_LINK_SPEED_8GHZ:
2000                        ae->un.AttrInt = HBA_PORTSPEED_8GFC;
2001                        break;
2002                case LPFC_LINK_SPEED_10GHZ:
2003                        ae->un.AttrInt = HBA_PORTSPEED_10GFC;
2004                        break;
2005                case LPFC_LINK_SPEED_16GHZ:
2006                        ae->un.AttrInt = HBA_PORTSPEED_16GFC;
2007                        break;
2008                case LPFC_LINK_SPEED_32GHZ:
2009                        ae->un.AttrInt = HBA_PORTSPEED_32GFC;
2010                        break;
2011                default:
2012                        ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN;
2013                        break;
2014                }
2015        } else {
2016                switch (phba->fc_linkspeed) {
2017                case LPFC_ASYNC_LINK_SPEED_10GBPS:
2018                        ae->un.AttrInt = HBA_PORTSPEED_10GE;
2019                        break;
2020                case LPFC_ASYNC_LINK_SPEED_25GBPS:
2021                        ae->un.AttrInt = HBA_PORTSPEED_25GE;
2022                        break;
2023                case LPFC_ASYNC_LINK_SPEED_40GBPS:
2024                        ae->un.AttrInt = HBA_PORTSPEED_40GE;
2025                        break;
2026                case LPFC_ASYNC_LINK_SPEED_100GBPS:
2027                        ae->un.AttrInt = HBA_PORTSPEED_100GE;
2028                        break;
2029                default:
2030                        ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN;
2031                        break;
2032                }
2033        }
2034
2035        ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt);
2036        size = FOURBYTES + sizeof(uint32_t);
2037        ad->AttrLen = cpu_to_be16(size);
2038        ad->AttrType = cpu_to_be16(RPRT_PORT_SPEED);
2039        return size;
2040}
2041
2042static int
2043lpfc_fdmi_port_attr_max_frame(struct lpfc_vport *vport,
2044                              struct lpfc_fdmi_attr_def *ad)
2045{
2046        struct serv_parm *hsp;
2047        struct lpfc_fdmi_attr_entry *ae;
2048        uint32_t size;
2049
2050        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2051
2052        hsp = (struct serv_parm *)&vport->fc_sparam;
2053        ae->un.AttrInt = (((uint32_t) hsp->cmn.bbRcvSizeMsb) << 8) |
2054                          (uint32_t) hsp->cmn.bbRcvSizeLsb;
2055        ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt);
2056        size = FOURBYTES + sizeof(uint32_t);
2057        ad->AttrLen = cpu_to_be16(size);
2058        ad->AttrType = cpu_to_be16(RPRT_MAX_FRAME_SIZE);
2059        return size;
2060}
2061
2062static int
2063lpfc_fdmi_port_attr_os_devname(struct lpfc_vport *vport,
2064                               struct lpfc_fdmi_attr_def *ad)
2065{
2066        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2067        struct lpfc_fdmi_attr_entry *ae;
2068        uint32_t len, size;
2069
2070        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2071        memset(ae, 0, 256);
2072
2073        snprintf(ae->un.AttrString, sizeof(ae->un.AttrString),
2074                 "/sys/class/scsi_host/host%d", shost->host_no);
2075        len = strnlen((char *)ae->un.AttrString,
2076                          sizeof(ae->un.AttrString));
2077        len += (len & 3) ? (4 - (len & 3)) : 4;
2078        size = FOURBYTES + len;
2079        ad->AttrLen = cpu_to_be16(size);
2080        ad->AttrType = cpu_to_be16(RPRT_OS_DEVICE_NAME);
2081        return size;
2082}
2083
2084static int
2085lpfc_fdmi_port_attr_host_name(struct lpfc_vport *vport,
2086                              struct lpfc_fdmi_attr_def *ad)
2087{
2088        struct lpfc_fdmi_attr_entry *ae;
2089        uint32_t len, size;
2090
2091        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2092        memset(ae, 0, 256);
2093
2094        snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s",
2095                 init_utsname()->nodename);
2096
2097        len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
2098        len += (len & 3) ? (4 - (len & 3)) : 4;
2099        size = FOURBYTES + len;
2100        ad->AttrLen = cpu_to_be16(size);
2101        ad->AttrType = cpu_to_be16(RPRT_HOST_NAME);
2102        return size;
2103}
2104
2105static int
2106lpfc_fdmi_port_attr_wwnn(struct lpfc_vport *vport,
2107                         struct lpfc_fdmi_attr_def *ad)
2108{
2109        struct lpfc_fdmi_attr_entry *ae;
2110        uint32_t size;
2111
2112        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2113        memset(ae, 0,  sizeof(struct lpfc_name));
2114
2115        memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName,
2116               sizeof(struct lpfc_name));
2117        size = FOURBYTES + sizeof(struct lpfc_name);
2118        ad->AttrLen = cpu_to_be16(size);
2119        ad->AttrType = cpu_to_be16(RPRT_NODENAME);
2120        return size;
2121}
2122
2123static int
2124lpfc_fdmi_port_attr_wwpn(struct lpfc_vport *vport,
2125                         struct lpfc_fdmi_attr_def *ad)
2126{
2127        struct lpfc_fdmi_attr_entry *ae;
2128        uint32_t size;
2129
2130        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2131        memset(ae, 0,  sizeof(struct lpfc_name));
2132
2133        memcpy(&ae->un.AttrWWN, &vport->fc_sparam.portName,
2134               sizeof(struct lpfc_name));
2135        size = FOURBYTES + sizeof(struct lpfc_name);
2136        ad->AttrLen = cpu_to_be16(size);
2137        ad->AttrType = cpu_to_be16(RPRT_PORTNAME);
2138        return size;
2139}
2140
2141static int
2142lpfc_fdmi_port_attr_symbolic_name(struct lpfc_vport *vport,
2143                                  struct lpfc_fdmi_attr_def *ad)
2144{
2145        struct lpfc_fdmi_attr_entry *ae;
2146        uint32_t len, size;
2147
2148        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2149        memset(ae, 0, 256);
2150
2151        len = lpfc_vport_symbolic_port_name(vport, ae->un.AttrString, 256);
2152        len += (len & 3) ? (4 - (len & 3)) : 4;
2153        size = FOURBYTES + len;
2154        ad->AttrLen = cpu_to_be16(size);
2155        ad->AttrType = cpu_to_be16(RPRT_SYM_PORTNAME);
2156        return size;
2157}
2158
2159static int
2160lpfc_fdmi_port_attr_port_type(struct lpfc_vport *vport,
2161                              struct lpfc_fdmi_attr_def *ad)
2162{
2163        struct lpfc_hba *phba = vport->phba;
2164        struct lpfc_fdmi_attr_entry *ae;
2165        uint32_t size;
2166
2167        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2168        if (phba->fc_topology == LPFC_TOPOLOGY_LOOP)
2169                ae->un.AttrInt =  cpu_to_be32(LPFC_FDMI_PORTTYPE_NLPORT);
2170        else
2171                ae->un.AttrInt =  cpu_to_be32(LPFC_FDMI_PORTTYPE_NPORT);
2172        size = FOURBYTES + sizeof(uint32_t);
2173        ad->AttrLen = cpu_to_be16(size);
2174        ad->AttrType = cpu_to_be16(RPRT_PORT_TYPE);
2175        return size;
2176}
2177
2178static int
2179lpfc_fdmi_port_attr_class(struct lpfc_vport *vport,
2180                          struct lpfc_fdmi_attr_def *ad)
2181{
2182        struct lpfc_fdmi_attr_entry *ae;
2183        uint32_t size;
2184
2185        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2186        ae->un.AttrInt = cpu_to_be32(FC_COS_CLASS2 | FC_COS_CLASS3);
2187        size = FOURBYTES + sizeof(uint32_t);
2188        ad->AttrLen = cpu_to_be16(size);
2189        ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_CLASS);
2190        return size;
2191}
2192
2193static int
2194lpfc_fdmi_port_attr_fabric_wwpn(struct lpfc_vport *vport,
2195                                struct lpfc_fdmi_attr_def *ad)
2196{
2197        struct lpfc_fdmi_attr_entry *ae;
2198        uint32_t size;
2199
2200        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2201        memset(ae, 0,  sizeof(struct lpfc_name));
2202
2203        memcpy(&ae->un.AttrWWN, &vport->fabric_portname,
2204               sizeof(struct lpfc_name));
2205        size = FOURBYTES + sizeof(struct lpfc_name);
2206        ad->AttrLen = cpu_to_be16(size);
2207        ad->AttrType = cpu_to_be16(RPRT_FABRICNAME);
2208        return size;
2209}
2210
2211static int
2212lpfc_fdmi_port_attr_active_fc4type(struct lpfc_vport *vport,
2213                                   struct lpfc_fdmi_attr_def *ad)
2214{
2215        struct lpfc_fdmi_attr_entry *ae;
2216        uint32_t size;
2217
2218        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2219        memset(ae, 0, 32);
2220
2221        ae->un.AttrTypes[3] = 0x02; /* Type 1 - ELS */
2222        ae->un.AttrTypes[2] = 0x01; /* Type 8 - FCP */
2223        ae->un.AttrTypes[7] = 0x01; /* Type 32 - CT */
2224        size = FOURBYTES + 32;
2225        ad->AttrLen = cpu_to_be16(size);
2226        ad->AttrType = cpu_to_be16(RPRT_ACTIVE_FC4_TYPES);
2227        return size;
2228}
2229
2230static int
2231lpfc_fdmi_port_attr_port_state(struct lpfc_vport *vport,
2232                               struct lpfc_fdmi_attr_def *ad)
2233{
2234        struct lpfc_fdmi_attr_entry *ae;
2235        uint32_t size;
2236
2237        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2238        /* Link Up - operational */
2239        ae->un.AttrInt =  cpu_to_be32(LPFC_FDMI_PORTSTATE_ONLINE);
2240        size = FOURBYTES + sizeof(uint32_t);
2241        ad->AttrLen = cpu_to_be16(size);
2242        ad->AttrType = cpu_to_be16(RPRT_PORT_STATE);
2243        return size;
2244}
2245
2246static int
2247lpfc_fdmi_port_attr_num_disc(struct lpfc_vport *vport,
2248                             struct lpfc_fdmi_attr_def *ad)
2249{
2250        struct lpfc_fdmi_attr_entry *ae;
2251        uint32_t size;
2252
2253        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2254        vport->fdmi_num_disc = lpfc_find_map_node(vport);
2255        ae->un.AttrInt = cpu_to_be32(vport->fdmi_num_disc);
2256        size = FOURBYTES + sizeof(uint32_t);
2257        ad->AttrLen = cpu_to_be16(size);
2258        ad->AttrType = cpu_to_be16(RPRT_DISC_PORT);
2259        return size;
2260}
2261
2262static int
2263lpfc_fdmi_port_attr_nportid(struct lpfc_vport *vport,
2264                            struct lpfc_fdmi_attr_def *ad)
2265{
2266        struct lpfc_fdmi_attr_entry *ae;
2267        uint32_t size;
2268
2269        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2270        ae->un.AttrInt =  cpu_to_be32(vport->fc_myDID);
2271        size = FOURBYTES + sizeof(uint32_t);
2272        ad->AttrLen = cpu_to_be16(size);
2273        ad->AttrType = cpu_to_be16(RPRT_PORT_ID);
2274        return size;
2275}
2276
2277static int
2278lpfc_fdmi_smart_attr_service(struct lpfc_vport *vport,
2279                             struct lpfc_fdmi_attr_def *ad)
2280{
2281        struct lpfc_fdmi_attr_entry *ae;
2282        uint32_t len, size;
2283
2284        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2285        memset(ae, 0, 256);
2286
2287        strncpy(ae->un.AttrString, "Smart SAN Initiator",
2288                sizeof(ae->un.AttrString));
2289        len = strnlen(ae->un.AttrString,
2290                          sizeof(ae->un.AttrString));
2291        len += (len & 3) ? (4 - (len & 3)) : 4;
2292        size = FOURBYTES + len;
2293        ad->AttrLen = cpu_to_be16(size);
2294        ad->AttrType = cpu_to_be16(RPRT_SMART_SERVICE);
2295        return size;
2296}
2297
2298static int
2299lpfc_fdmi_smart_attr_guid(struct lpfc_vport *vport,
2300                          struct lpfc_fdmi_attr_def *ad)
2301{
2302        struct lpfc_fdmi_attr_entry *ae;
2303        uint32_t size;
2304
2305        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2306        memset(ae, 0, 256);
2307
2308        memcpy(&ae->un.AttrString, &vport->fc_sparam.nodeName,
2309               sizeof(struct lpfc_name));
2310        memcpy((((uint8_t *)&ae->un.AttrString) +
2311                sizeof(struct lpfc_name)),
2312                &vport->fc_sparam.portName, sizeof(struct lpfc_name));
2313        size = FOURBYTES + (2 * sizeof(struct lpfc_name));
2314        ad->AttrLen =  cpu_to_be16(size);
2315        ad->AttrType = cpu_to_be16(RPRT_SMART_GUID);
2316        return size;
2317}
2318
2319static int
2320lpfc_fdmi_smart_attr_version(struct lpfc_vport *vport,
2321                             struct lpfc_fdmi_attr_def *ad)
2322{
2323        struct lpfc_fdmi_attr_entry *ae;
2324        uint32_t len, size;
2325
2326        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2327        memset(ae, 0, 256);
2328
2329        strncpy(ae->un.AttrString, "Smart SAN Version 2.0",
2330                sizeof(ae->un.AttrString));
2331        len = strnlen(ae->un.AttrString,
2332                          sizeof(ae->un.AttrString));
2333        len += (len & 3) ? (4 - (len & 3)) : 4;
2334        size = FOURBYTES + len;
2335        ad->AttrLen =  cpu_to_be16(size);
2336        ad->AttrType = cpu_to_be16(RPRT_SMART_VERSION);
2337        return size;
2338}
2339
2340static int
2341lpfc_fdmi_smart_attr_model(struct lpfc_vport *vport,
2342                           struct lpfc_fdmi_attr_def *ad)
2343{
2344        struct lpfc_hba *phba = vport->phba;
2345        struct lpfc_fdmi_attr_entry *ae;
2346        uint32_t len, size;
2347
2348        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2349        memset(ae, 0, 256);
2350
2351        strncpy(ae->un.AttrString, phba->ModelName,
2352                sizeof(ae->un.AttrString));
2353        len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
2354        len += (len & 3) ? (4 - (len & 3)) : 4;
2355        size = FOURBYTES + len;
2356        ad->AttrLen = cpu_to_be16(size);
2357        ad->AttrType = cpu_to_be16(RPRT_SMART_MODEL);
2358        return size;
2359}
2360
2361static int
2362lpfc_fdmi_smart_attr_port_info(struct lpfc_vport *vport,
2363                               struct lpfc_fdmi_attr_def *ad)
2364{
2365        struct lpfc_fdmi_attr_entry *ae;
2366        uint32_t size;
2367
2368        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2369
2370        /* SRIOV (type 3) is not supported */
2371        if (vport->vpi)
2372                ae->un.AttrInt =  cpu_to_be32(2);  /* NPIV */
2373        else
2374                ae->un.AttrInt =  cpu_to_be32(1);  /* Physical */
2375        size = FOURBYTES + sizeof(uint32_t);
2376        ad->AttrLen = cpu_to_be16(size);
2377        ad->AttrType = cpu_to_be16(RPRT_SMART_PORT_INFO);
2378        return size;
2379}
2380
2381static int
2382lpfc_fdmi_smart_attr_qos(struct lpfc_vport *vport,
2383                         struct lpfc_fdmi_attr_def *ad)
2384{
2385        struct lpfc_fdmi_attr_entry *ae;
2386        uint32_t size;
2387
2388        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2389        ae->un.AttrInt =  cpu_to_be32(0);
2390        size = FOURBYTES + sizeof(uint32_t);
2391        ad->AttrLen = cpu_to_be16(size);
2392        ad->AttrType = cpu_to_be16(RPRT_SMART_QOS);
2393        return size;
2394}
2395
2396static int
2397lpfc_fdmi_smart_attr_security(struct lpfc_vport *vport,
2398                              struct lpfc_fdmi_attr_def *ad)
2399{
2400        struct lpfc_fdmi_attr_entry *ae;
2401        uint32_t size;
2402
2403        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2404        ae->un.AttrInt =  cpu_to_be32(1);
2405        size = FOURBYTES + sizeof(uint32_t);
2406        ad->AttrLen = cpu_to_be16(size);
2407        ad->AttrType = cpu_to_be16(RPRT_SMART_SECURITY);
2408        return size;
2409}
2410
2411/* RHBA attribute jump table */
2412int (*lpfc_fdmi_hba_action[])
2413        (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = {
2414        /* Action routine                 Mask bit     Attribute type */
2415        lpfc_fdmi_hba_attr_wwnn,          /* bit0     RHBA_NODENAME           */
2416        lpfc_fdmi_hba_attr_manufacturer,  /* bit1     RHBA_MANUFACTURER       */
2417        lpfc_fdmi_hba_attr_sn,            /* bit2     RHBA_SERIAL_NUMBER      */
2418        lpfc_fdmi_hba_attr_model,         /* bit3     RHBA_MODEL              */
2419        lpfc_fdmi_hba_attr_description,   /* bit4     RHBA_MODEL_DESCRIPTION  */
2420        lpfc_fdmi_hba_attr_hdw_ver,       /* bit5     RHBA_HARDWARE_VERSION   */
2421        lpfc_fdmi_hba_attr_drvr_ver,      /* bit6     RHBA_DRIVER_VERSION     */
2422        lpfc_fdmi_hba_attr_rom_ver,       /* bit7     RHBA_OPTION_ROM_VERSION */
2423        lpfc_fdmi_hba_attr_fmw_ver,       /* bit8     RHBA_FIRMWARE_VERSION   */
2424        lpfc_fdmi_hba_attr_os_ver,        /* bit9     RHBA_OS_NAME_VERSION    */
2425        lpfc_fdmi_hba_attr_ct_len,        /* bit10    RHBA_MAX_CT_PAYLOAD_LEN */
2426        lpfc_fdmi_hba_attr_symbolic_name, /* bit11    RHBA_SYM_NODENAME       */
2427        lpfc_fdmi_hba_attr_vendor_info,   /* bit12    RHBA_VENDOR_INFO        */
2428        lpfc_fdmi_hba_attr_num_ports,     /* bit13    RHBA_NUM_PORTS          */
2429        lpfc_fdmi_hba_attr_fabric_wwnn,   /* bit14    RHBA_FABRIC_WWNN        */
2430        lpfc_fdmi_hba_attr_bios_ver,      /* bit15    RHBA_BIOS_VERSION       */
2431        lpfc_fdmi_hba_attr_bios_state,    /* bit16    RHBA_BIOS_STATE         */
2432        lpfc_fdmi_hba_attr_vendor_id,     /* bit17    RHBA_VENDOR_ID          */
2433};
2434
2435/* RPA / RPRT attribute jump table */
2436int (*lpfc_fdmi_port_action[])
2437        (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = {
2438        /* Action routine                   Mask bit   Attribute type */
2439        lpfc_fdmi_port_attr_fc4type,        /* bit0   RPRT_SUPPORT_FC4_TYPES  */
2440        lpfc_fdmi_port_attr_support_speed,  /* bit1   RPRT_SUPPORTED_SPEED    */
2441        lpfc_fdmi_port_attr_speed,          /* bit2   RPRT_PORT_SPEED         */
2442        lpfc_fdmi_port_attr_max_frame,      /* bit3   RPRT_MAX_FRAME_SIZE     */
2443        lpfc_fdmi_port_attr_os_devname,     /* bit4   RPRT_OS_DEVICE_NAME     */
2444        lpfc_fdmi_port_attr_host_name,      /* bit5   RPRT_HOST_NAME          */
2445        lpfc_fdmi_port_attr_wwnn,           /* bit6   RPRT_NODENAME           */
2446        lpfc_fdmi_port_attr_wwpn,           /* bit7   RPRT_PORTNAME           */
2447        lpfc_fdmi_port_attr_symbolic_name,  /* bit8   RPRT_SYM_PORTNAME       */
2448        lpfc_fdmi_port_attr_port_type,      /* bit9   RPRT_PORT_TYPE          */
2449        lpfc_fdmi_port_attr_class,          /* bit10  RPRT_SUPPORTED_CLASS    */
2450        lpfc_fdmi_port_attr_fabric_wwpn,    /* bit11  RPRT_FABRICNAME         */
2451        lpfc_fdmi_port_attr_active_fc4type, /* bit12  RPRT_ACTIVE_FC4_TYPES   */
2452        lpfc_fdmi_port_attr_port_state,     /* bit13  RPRT_PORT_STATE         */
2453        lpfc_fdmi_port_attr_num_disc,       /* bit14  RPRT_DISC_PORT          */
2454        lpfc_fdmi_port_attr_nportid,        /* bit15  RPRT_PORT_ID            */
2455        lpfc_fdmi_smart_attr_service,       /* bit16  RPRT_SMART_SERVICE      */
2456        lpfc_fdmi_smart_attr_guid,          /* bit17  RPRT_SMART_GUID         */
2457        lpfc_fdmi_smart_attr_version,       /* bit18  RPRT_SMART_VERSION      */
2458        lpfc_fdmi_smart_attr_model,         /* bit19  RPRT_SMART_MODEL        */
2459        lpfc_fdmi_smart_attr_port_info,     /* bit20  RPRT_SMART_PORT_INFO    */
2460        lpfc_fdmi_smart_attr_qos,           /* bit21  RPRT_SMART_QOS          */
2461        lpfc_fdmi_smart_attr_security,      /* bit22  RPRT_SMART_SECURITY     */
2462};
2463
2464/**
2465 * lpfc_fdmi_cmd - Build and send a FDMI cmd to the specified NPort
2466 * @vport: pointer to a host virtual N_Port data structure.
2467 * @ndlp: ndlp to send FDMI cmd to (if NULL use FDMI_DID)
2468 * cmdcode: FDMI command to send
2469 * mask: Mask of HBA or PORT Attributes to send
2470 *
2471 * Builds and sends a FDMI command using the CT subsystem.
2472 */
2473int
2474lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2475              int cmdcode, uint32_t new_mask)
2476{
2477        struct lpfc_hba *phba = vport->phba;
2478        struct lpfc_dmabuf *mp, *bmp;
2479        struct lpfc_sli_ct_request *CtReq;
2480        struct ulp_bde64 *bpl;
2481        uint32_t bit_pos;
2482        uint32_t size;
2483        uint32_t rsp_size;
2484        uint32_t mask;
2485        struct lpfc_fdmi_reg_hba *rh;
2486        struct lpfc_fdmi_port_entry *pe;
2487        struct lpfc_fdmi_reg_portattr *pab = NULL;
2488        struct lpfc_fdmi_attr_block *ab = NULL;
2489        int  (*func)(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad);
2490        void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *,
2491                     struct lpfc_iocbq *);
2492
2493        if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
2494                return 0;
2495
2496        cmpl = lpfc_cmpl_ct_disc_fdmi; /* called from discovery */
2497
2498        /* fill in BDEs for command */
2499        /* Allocate buffer for command payload */
2500        mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
2501        if (!mp)
2502                goto fdmi_cmd_exit;
2503
2504        mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys));
2505        if (!mp->virt)
2506                goto fdmi_cmd_free_mp;
2507
2508        /* Allocate buffer for Buffer ptr list */
2509        bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
2510        if (!bmp)
2511                goto fdmi_cmd_free_mpvirt;
2512
2513        bmp->virt = lpfc_mbuf_alloc(phba, 0, &(bmp->phys));
2514        if (!bmp->virt)
2515                goto fdmi_cmd_free_bmp;
2516
2517        INIT_LIST_HEAD(&mp->list);
2518        INIT_LIST_HEAD(&bmp->list);
2519
2520        /* FDMI request */
2521        lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
2522                         "0218 FDMI Request Data: x%x x%x x%x\n",
2523                         vport->fc_flag, vport->port_state, cmdcode);
2524        CtReq = (struct lpfc_sli_ct_request *)mp->virt;
2525
2526        /* First populate the CT_IU preamble */
2527        memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request));
2528        CtReq->RevisionId.bits.Revision = SLI_CT_REVISION;
2529        CtReq->RevisionId.bits.InId = 0;
2530
2531        CtReq->FsType = SLI_CT_MANAGEMENT_SERVICE;
2532        CtReq->FsSubType = SLI_CT_FDMI_Subtypes;
2533
2534        CtReq->CommandResponse.bits.CmdRsp = cpu_to_be16(cmdcode);
2535        rsp_size = LPFC_BPL_SIZE;
2536        size = 0;
2537
2538        /* Next fill in the specific FDMI cmd information */
2539        switch (cmdcode) {
2540        case SLI_MGMT_RHAT:
2541        case SLI_MGMT_RHBA:
2542                rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un.PortID;
2543                /* HBA Identifier */
2544                memcpy(&rh->hi.PortName, &phba->pport->fc_sparam.portName,
2545                       sizeof(struct lpfc_name));
2546
2547                if (cmdcode == SLI_MGMT_RHBA) {
2548                        /* Registered Port List */
2549                        /* One entry (port) per adapter */
2550                        rh->rpl.EntryCnt = cpu_to_be32(1);
2551                        memcpy(&rh->rpl.pe, &phba->pport->fc_sparam.portName,
2552                               sizeof(struct lpfc_name));
2553
2554                        /* point to the HBA attribute block */
2555                        size = 2 * sizeof(struct lpfc_name) +
2556                                FOURBYTES;
2557                } else {
2558                        size = sizeof(struct lpfc_name);
2559                }
2560                ab = (struct lpfc_fdmi_attr_block *)((uint8_t *)rh + size);
2561                ab->EntryCnt = 0;
2562                size += FOURBYTES;
2563                bit_pos = 0;
2564                if (new_mask)
2565                        mask = new_mask;
2566                else
2567                        mask = vport->fdmi_hba_mask;
2568
2569                /* Mask will dictate what attributes to build in the request */
2570                while (mask) {
2571                        if (mask & 0x1) {
2572                                func = lpfc_fdmi_hba_action[bit_pos];
2573                                size += func(vport,
2574                                             (struct lpfc_fdmi_attr_def *)
2575                                             ((uint8_t *)rh + size));
2576                                ab->EntryCnt++;
2577                                if ((size + 256) >
2578                                    (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
2579                                        goto hba_out;
2580                        }
2581                        mask = mask >> 1;
2582                        bit_pos++;
2583                }
2584hba_out:
2585                ab->EntryCnt = cpu_to_be32(ab->EntryCnt);
2586                /* Total size */
2587                size = GID_REQUEST_SZ - 4 + size;
2588                break;
2589
2590        case SLI_MGMT_RPRT:
2591        case SLI_MGMT_RPA:
2592                pab = (struct lpfc_fdmi_reg_portattr *)&CtReq->un.PortID;
2593                if (cmdcode == SLI_MGMT_RPRT) {
2594                        rh = (struct lpfc_fdmi_reg_hba *)pab;
2595                        /* HBA Identifier */
2596                        memcpy(&rh->hi.PortName,
2597                               &phba->pport->fc_sparam.portName,
2598                               sizeof(struct lpfc_name));
2599                        pab = (struct lpfc_fdmi_reg_portattr *)
2600                                ((uint8_t *)pab +  sizeof(struct lpfc_name));
2601                }
2602
2603                memcpy((uint8_t *)&pab->PortName,
2604                       (uint8_t *)&vport->fc_sparam.portName,
2605                       sizeof(struct lpfc_name));
2606                size += sizeof(struct lpfc_name) + FOURBYTES;
2607                pab->ab.EntryCnt = 0;
2608                bit_pos = 0;
2609                if (new_mask)
2610                        mask = new_mask;
2611                else
2612                        mask = vport->fdmi_port_mask;
2613
2614                /* Mask will dictate what attributes to build in the request */
2615                while (mask) {
2616                        if (mask & 0x1) {
2617                                func = lpfc_fdmi_port_action[bit_pos];
2618                                size += func(vport,
2619                                             (struct lpfc_fdmi_attr_def *)
2620                                             ((uint8_t *)pab + size));
2621                                pab->ab.EntryCnt++;
2622                                if ((size + 256) >
2623                                    (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
2624                                        goto port_out;
2625                        }
2626                        mask = mask >> 1;
2627                        bit_pos++;
2628                }
2629port_out:
2630                pab->ab.EntryCnt = cpu_to_be32(pab->ab.EntryCnt);
2631                /* Total size */
2632                if (cmdcode == SLI_MGMT_RPRT)
2633                        size += sizeof(struct lpfc_name);
2634                size = GID_REQUEST_SZ - 4 + size;
2635                break;
2636
2637        case SLI_MGMT_GHAT:
2638        case SLI_MGMT_GRPL:
2639                rsp_size = FC_MAX_NS_RSP;
2640        case SLI_MGMT_DHBA:
2641        case SLI_MGMT_DHAT:
2642                pe = (struct lpfc_fdmi_port_entry *)&CtReq->un.PortID;
2643                memcpy((uint8_t *)&pe->PortName,
2644                       (uint8_t *)&vport->fc_sparam.portName,
2645                       sizeof(struct lpfc_name));
2646                size = GID_REQUEST_SZ - 4 + sizeof(struct lpfc_name);
2647                break;
2648
2649        case SLI_MGMT_GPAT:
2650        case SLI_MGMT_GPAS:
2651                rsp_size = FC_MAX_NS_RSP;
2652        case SLI_MGMT_DPRT:
2653        case SLI_MGMT_DPA:
2654                pe = (struct lpfc_fdmi_port_entry *)&CtReq->un.PortID;
2655                memcpy((uint8_t *)&pe->PortName,
2656                       (uint8_t *)&vport->fc_sparam.portName,
2657                       sizeof(struct lpfc_name));
2658                size = GID_REQUEST_SZ - 4 + sizeof(struct lpfc_name);
2659                break;
2660        case SLI_MGMT_GRHL:
2661                size = GID_REQUEST_SZ - 4;
2662                break;
2663        default:
2664                lpfc_printf_vlog(vport, KERN_WARNING, LOG_DISCOVERY,
2665                                 "0298 FDMI cmdcode x%x not supported\n",
2666                                 cmdcode);
2667                goto fdmi_cmd_free_bmpvirt;
2668        }
2669        CtReq->CommandResponse.bits.Size = cpu_to_be16(rsp_size);
2670
2671        bpl = (struct ulp_bde64 *)bmp->virt;
2672        bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys));
2673        bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys));
2674        bpl->tus.f.bdeFlags = 0;
2675        bpl->tus.f.bdeSize = size;
2676
2677        /*
2678         * The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count
2679         * to hold ndlp reference for the corresponding callback function.
2680         */
2681        if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, 0))
2682                return 0;
2683
2684        /*
2685         * Decrement ndlp reference count to release ndlp reference held
2686         * for the failed command's callback function.
2687         */
2688        lpfc_nlp_put(ndlp);
2689
2690fdmi_cmd_free_bmpvirt:
2691        lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
2692fdmi_cmd_free_bmp:
2693        kfree(bmp);
2694fdmi_cmd_free_mpvirt:
2695        lpfc_mbuf_free(phba, mp->virt, mp->phys);
2696fdmi_cmd_free_mp:
2697        kfree(mp);
2698fdmi_cmd_exit:
2699        /* Issue FDMI request failed */
2700        lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
2701                         "0244 Issue FDMI request failed Data: x%x\n",
2702                         cmdcode);
2703        return 1;
2704}
2705
2706/**
2707 * lpfc_delayed_disc_tmo - Timeout handler for delayed discovery timer.
2708 * @ptr - Context object of the timer.
2709 *
2710 * This function set the WORKER_DELAYED_DISC_TMO flag and wake up
2711 * the worker thread.
2712 **/
2713void
2714lpfc_delayed_disc_tmo(unsigned long ptr)
2715{
2716        struct lpfc_vport *vport = (struct lpfc_vport *)ptr;
2717        struct lpfc_hba   *phba = vport->phba;
2718        uint32_t tmo_posted;
2719        unsigned long iflag;
2720
2721        spin_lock_irqsave(&vport->work_port_lock, iflag);
2722        tmo_posted = vport->work_port_events & WORKER_DELAYED_DISC_TMO;
2723        if (!tmo_posted)
2724                vport->work_port_events |= WORKER_DELAYED_DISC_TMO;
2725        spin_unlock_irqrestore(&vport->work_port_lock, iflag);
2726
2727        if (!tmo_posted)
2728                lpfc_worker_wake_up(phba);
2729        return;
2730}
2731
2732/**
2733 * lpfc_delayed_disc_timeout_handler - Function called by worker thread to
2734 *      handle delayed discovery.
2735 * @vport: pointer to a host virtual N_Port data structure.
2736 *
2737 * This function start nport discovery of the vport.
2738 **/
2739void
2740lpfc_delayed_disc_timeout_handler(struct lpfc_vport *vport)
2741{
2742        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2743
2744        spin_lock_irq(shost->host_lock);
2745        if (!(vport->fc_flag & FC_DISC_DELAYED)) {
2746                spin_unlock_irq(shost->host_lock);
2747                return;
2748        }
2749        vport->fc_flag &= ~FC_DISC_DELAYED;
2750        spin_unlock_irq(shost->host_lock);
2751
2752        lpfc_do_scr_ns_plogi(vport->phba, vport);
2753}
2754
2755void
2756lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)
2757{
2758        struct lpfc_sli *psli = &phba->sli;
2759        lpfc_vpd_t *vp = &phba->vpd;
2760        uint32_t b1, b2, b3, b4, i, rev;
2761        char c;
2762        uint32_t *ptr, str[4];
2763        uint8_t *fwname;
2764
2765        if (phba->sli_rev == LPFC_SLI_REV4)
2766                snprintf(fwrevision, FW_REV_STR_SIZE, "%s", vp->rev.opFwName);
2767        else if (vp->rev.rBit) {
2768                if (psli->sli_flag & LPFC_SLI_ACTIVE)
2769                        rev = vp->rev.sli2FwRev;
2770                else
2771                        rev = vp->rev.sli1FwRev;
2772
2773                b1 = (rev & 0x0000f000) >> 12;
2774                b2 = (rev & 0x00000f00) >> 8;
2775                b3 = (rev & 0x000000c0) >> 6;
2776                b4 = (rev & 0x00000030) >> 4;
2777
2778                switch (b4) {
2779                case 0:
2780                        c = 'N';
2781                        break;
2782                case 1:
2783                        c = 'A';
2784                        break;
2785                case 2:
2786                        c = 'B';
2787                        break;
2788                case 3:
2789                        c = 'X';
2790                        break;
2791                default:
2792                        c = 0;
2793                        break;
2794                }
2795                b4 = (rev & 0x0000000f);
2796
2797                if (psli->sli_flag & LPFC_SLI_ACTIVE)
2798                        fwname = vp->rev.sli2FwName;
2799                else
2800                        fwname = vp->rev.sli1FwName;
2801
2802                for (i = 0; i < 16; i++)
2803                        if (fwname[i] == 0x20)
2804                                fwname[i] = 0;
2805
2806                ptr = (uint32_t*)fwname;
2807
2808                for (i = 0; i < 3; i++)
2809                        str[i] = be32_to_cpu(*ptr++);
2810
2811                if (c == 0) {
2812                        if (flag)
2813                                sprintf(fwrevision, "%d.%d%d (%s)",
2814                                        b1, b2, b3, (char *)str);
2815                        else
2816                                sprintf(fwrevision, "%d.%d%d", b1,
2817                                        b2, b3);
2818                } else {
2819                        if (flag)
2820                                sprintf(fwrevision, "%d.%d%d%c%d (%s)",
2821                                        b1, b2, b3, c,
2822                                        b4, (char *)str);
2823                        else
2824                                sprintf(fwrevision, "%d.%d%d%c%d",
2825                                        b1, b2, b3, c, b4);
2826                }
2827        } else {
2828                rev = vp->rev.smFwRev;
2829
2830                b1 = (rev & 0xff000000) >> 24;
2831                b2 = (rev & 0x00f00000) >> 20;
2832                b3 = (rev & 0x000f0000) >> 16;
2833                c  = (rev & 0x0000ff00) >> 8;
2834                b4 = (rev & 0x000000ff);
2835
2836                sprintf(fwrevision, "%d.%d%d%c%d", b1, b2, b3, c, b4);
2837        }
2838        return;
2839}
2840