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-2015 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        if (!(vport->fdmi_port_mask & LPFC_FDMI_PORT_ATTR_num_disc))
1514                return;
1515
1516        cnt = lpfc_find_map_node(vport);
1517        if (cnt == vport->fdmi_num_disc)
1518                return;
1519
1520        ndlp = lpfc_findnode_did(vport, FDMI_DID);
1521        if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
1522                return;
1523
1524        if (vport->port_type == LPFC_PHYSICAL_PORT) {
1525                lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA,
1526                              LPFC_FDMI_PORT_ATTR_num_disc);
1527        } else {
1528                lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT,
1529                              LPFC_FDMI_PORT_ATTR_num_disc);
1530        }
1531}
1532
1533/* Routines for all individual HBA attributes */
1534int
1535lpfc_fdmi_hba_attr_wwnn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad)
1536{
1537        struct lpfc_fdmi_attr_entry *ae;
1538        uint32_t size;
1539
1540        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1541        memset(ae, 0, sizeof(struct lpfc_name));
1542
1543        memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName,
1544               sizeof(struct lpfc_name));
1545        size = FOURBYTES + sizeof(struct lpfc_name);
1546        ad->AttrLen = cpu_to_be16(size);
1547        ad->AttrType = cpu_to_be16(RHBA_NODENAME);
1548        return size;
1549}
1550int
1551lpfc_fdmi_hba_attr_manufacturer(struct lpfc_vport *vport,
1552                                struct lpfc_fdmi_attr_def *ad)
1553{
1554        struct lpfc_fdmi_attr_entry *ae;
1555        uint32_t len, size;
1556
1557        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1558        memset(ae, 0, 256);
1559
1560        strncpy(ae->un.AttrString,
1561                "Emulex Corporation",
1562                       sizeof(ae->un.AttrString));
1563        len = strnlen(ae->un.AttrString,
1564                          sizeof(ae->un.AttrString));
1565        len += (len & 3) ? (4 - (len & 3)) : 4;
1566        size = FOURBYTES + len;
1567        ad->AttrLen = cpu_to_be16(size);
1568        ad->AttrType = cpu_to_be16(RHBA_MANUFACTURER);
1569        return size;
1570}
1571
1572int
1573lpfc_fdmi_hba_attr_sn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad)
1574{
1575        struct lpfc_hba *phba = vport->phba;
1576        struct lpfc_fdmi_attr_entry *ae;
1577        uint32_t len, size;
1578
1579        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1580        memset(ae, 0, 256);
1581
1582        strncpy(ae->un.AttrString, phba->SerialNumber,
1583                sizeof(ae->un.AttrString));
1584        len = strnlen(ae->un.AttrString,
1585                          sizeof(ae->un.AttrString));
1586        len += (len & 3) ? (4 - (len & 3)) : 4;
1587        size = FOURBYTES + len;
1588        ad->AttrLen = cpu_to_be16(size);
1589        ad->AttrType = cpu_to_be16(RHBA_SERIAL_NUMBER);
1590        return size;
1591}
1592
1593int
1594lpfc_fdmi_hba_attr_model(struct lpfc_vport *vport,
1595                         struct lpfc_fdmi_attr_def *ad)
1596{
1597        struct lpfc_hba *phba = vport->phba;
1598        struct lpfc_fdmi_attr_entry *ae;
1599        uint32_t len, size;
1600
1601        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1602        memset(ae, 0, 256);
1603
1604        strncpy(ae->un.AttrString, phba->ModelName,
1605                sizeof(ae->un.AttrString));
1606        len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
1607        len += (len & 3) ? (4 - (len & 3)) : 4;
1608        size = FOURBYTES + len;
1609        ad->AttrLen = cpu_to_be16(size);
1610        ad->AttrType = cpu_to_be16(RHBA_MODEL);
1611        return size;
1612}
1613
1614int
1615lpfc_fdmi_hba_attr_description(struct lpfc_vport *vport,
1616                               struct lpfc_fdmi_attr_def *ad)
1617{
1618        struct lpfc_hba *phba = vport->phba;
1619        struct lpfc_fdmi_attr_entry *ae;
1620        uint32_t len, size;
1621
1622        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1623        memset(ae, 0, 256);
1624
1625        strncpy(ae->un.AttrString, phba->ModelDesc,
1626                sizeof(ae->un.AttrString));
1627        len = strnlen(ae->un.AttrString,
1628                                  sizeof(ae->un.AttrString));
1629        len += (len & 3) ? (4 - (len & 3)) : 4;
1630        size = FOURBYTES + len;
1631        ad->AttrLen = cpu_to_be16(size);
1632        ad->AttrType = cpu_to_be16(RHBA_MODEL_DESCRIPTION);
1633        return size;
1634}
1635
1636int
1637lpfc_fdmi_hba_attr_hdw_ver(struct lpfc_vport *vport,
1638                           struct lpfc_fdmi_attr_def *ad)
1639{
1640        struct lpfc_hba *phba = vport->phba;
1641        lpfc_vpd_t *vp = &phba->vpd;
1642        struct lpfc_fdmi_attr_entry *ae;
1643        uint32_t i, j, incr, size;
1644
1645        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1646        memset(ae, 0, 256);
1647
1648        /* Convert JEDEC ID to ascii for hardware version */
1649        incr = vp->rev.biuRev;
1650        for (i = 0; i < 8; i++) {
1651                j = (incr & 0xf);
1652                if (j <= 9)
1653                        ae->un.AttrString[7 - i] =
1654                            (char)((uint8_t) 0x30 +
1655                                   (uint8_t) j);
1656                else
1657                        ae->un.AttrString[7 - i] =
1658                            (char)((uint8_t) 0x61 +
1659                                   (uint8_t) (j - 10));
1660                incr = (incr >> 4);
1661        }
1662        size = FOURBYTES + 8;
1663        ad->AttrLen = cpu_to_be16(size);
1664        ad->AttrType = cpu_to_be16(RHBA_HARDWARE_VERSION);
1665        return size;
1666}
1667
1668int
1669lpfc_fdmi_hba_attr_drvr_ver(struct lpfc_vport *vport,
1670                            struct lpfc_fdmi_attr_def *ad)
1671{
1672        struct lpfc_fdmi_attr_entry *ae;
1673        uint32_t len, size;
1674
1675        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1676        memset(ae, 0, 256);
1677
1678        strncpy(ae->un.AttrString, lpfc_release_version,
1679                sizeof(ae->un.AttrString));
1680        len = strnlen(ae->un.AttrString,
1681                          sizeof(ae->un.AttrString));
1682        len += (len & 3) ? (4 - (len & 3)) : 4;
1683        size = FOURBYTES + len;
1684        ad->AttrLen = cpu_to_be16(size);
1685        ad->AttrType = cpu_to_be16(RHBA_DRIVER_VERSION);
1686        return size;
1687}
1688
1689int
1690lpfc_fdmi_hba_attr_rom_ver(struct lpfc_vport *vport,
1691                           struct lpfc_fdmi_attr_def *ad)
1692{
1693        struct lpfc_hba *phba = vport->phba;
1694        struct lpfc_fdmi_attr_entry *ae;
1695        uint32_t len, size;
1696
1697        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1698        memset(ae, 0, 256);
1699
1700        if (phba->sli_rev == LPFC_SLI_REV4)
1701                lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1);
1702        else
1703                strncpy(ae->un.AttrString, phba->OptionROMVersion,
1704                        sizeof(ae->un.AttrString));
1705        len = strnlen(ae->un.AttrString,
1706                          sizeof(ae->un.AttrString));
1707        len += (len & 3) ? (4 - (len & 3)) : 4;
1708        size = FOURBYTES + len;
1709        ad->AttrLen = cpu_to_be16(size);
1710        ad->AttrType = cpu_to_be16(RHBA_OPTION_ROM_VERSION);
1711        return size;
1712}
1713
1714int
1715lpfc_fdmi_hba_attr_fmw_ver(struct lpfc_vport *vport,
1716                           struct lpfc_fdmi_attr_def *ad)
1717{
1718        struct lpfc_hba *phba = vport->phba;
1719        struct lpfc_fdmi_attr_entry *ae;
1720        uint32_t len, size;
1721
1722        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1723        memset(ae, 0, 256);
1724
1725        lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1);
1726        len = strnlen(ae->un.AttrString,
1727                          sizeof(ae->un.AttrString));
1728        len += (len & 3) ? (4 - (len & 3)) : 4;
1729        size = FOURBYTES + len;
1730        ad->AttrLen = cpu_to_be16(size);
1731        ad->AttrType = cpu_to_be16(RHBA_FIRMWARE_VERSION);
1732        return size;
1733}
1734
1735int
1736lpfc_fdmi_hba_attr_os_ver(struct lpfc_vport *vport,
1737                          struct lpfc_fdmi_attr_def *ad)
1738{
1739        struct lpfc_fdmi_attr_entry *ae;
1740        uint32_t len, size;
1741
1742        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1743        memset(ae, 0, 256);
1744
1745        snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s %s %s",
1746                 init_utsname()->sysname,
1747                 init_utsname()->release,
1748                 init_utsname()->version);
1749
1750        len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
1751        len += (len & 3) ? (4 - (len & 3)) : 4;
1752        size = FOURBYTES + len;
1753        ad->AttrLen = cpu_to_be16(size);
1754        ad->AttrType = cpu_to_be16(RHBA_OS_NAME_VERSION);
1755        return size;
1756}
1757
1758int
1759lpfc_fdmi_hba_attr_ct_len(struct lpfc_vport *vport,
1760                          struct lpfc_fdmi_attr_def *ad)
1761{
1762        struct lpfc_fdmi_attr_entry *ae;
1763        uint32_t size;
1764
1765        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1766
1767        ae->un.AttrInt =  cpu_to_be32(LPFC_MAX_CT_SIZE);
1768        size = FOURBYTES + sizeof(uint32_t);
1769        ad->AttrLen = cpu_to_be16(size);
1770        ad->AttrType = cpu_to_be16(RHBA_MAX_CT_PAYLOAD_LEN);
1771        return size;
1772}
1773
1774int
1775lpfc_fdmi_hba_attr_symbolic_name(struct lpfc_vport *vport,
1776                                 struct lpfc_fdmi_attr_def *ad)
1777{
1778        struct lpfc_fdmi_attr_entry *ae;
1779        uint32_t len, size;
1780
1781        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1782        memset(ae, 0, 256);
1783
1784        len = lpfc_vport_symbolic_node_name(vport,
1785                                ae->un.AttrString, 256);
1786        len += (len & 3) ? (4 - (len & 3)) : 4;
1787        size = FOURBYTES + len;
1788        ad->AttrLen = cpu_to_be16(size);
1789        ad->AttrType = cpu_to_be16(RHBA_SYM_NODENAME);
1790        return size;
1791}
1792
1793int
1794lpfc_fdmi_hba_attr_vendor_info(struct lpfc_vport *vport,
1795                               struct lpfc_fdmi_attr_def *ad)
1796{
1797        struct lpfc_fdmi_attr_entry *ae;
1798        uint32_t size;
1799
1800        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1801
1802        /* Nothing is defined for this currently */
1803        ae->un.AttrInt =  cpu_to_be32(0);
1804        size = FOURBYTES + sizeof(uint32_t);
1805        ad->AttrLen = cpu_to_be16(size);
1806        ad->AttrType = cpu_to_be16(RHBA_VENDOR_INFO);
1807        return size;
1808}
1809
1810int
1811lpfc_fdmi_hba_attr_num_ports(struct lpfc_vport *vport,
1812                             struct lpfc_fdmi_attr_def *ad)
1813{
1814        struct lpfc_fdmi_attr_entry *ae;
1815        uint32_t size;
1816
1817        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1818
1819        /* Each driver instance corresponds to a single port */
1820        ae->un.AttrInt =  cpu_to_be32(1);
1821        size = FOURBYTES + sizeof(uint32_t);
1822        ad->AttrLen = cpu_to_be16(size);
1823        ad->AttrType = cpu_to_be16(RHBA_NUM_PORTS);
1824        return size;
1825}
1826
1827int
1828lpfc_fdmi_hba_attr_fabric_wwnn(struct lpfc_vport *vport,
1829                               struct lpfc_fdmi_attr_def *ad)
1830{
1831        struct lpfc_fdmi_attr_entry *ae;
1832        uint32_t size;
1833
1834        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1835        memset(ae, 0, sizeof(struct lpfc_name));
1836
1837        memcpy(&ae->un.AttrWWN, &vport->fabric_nodename,
1838               sizeof(struct lpfc_name));
1839        size = FOURBYTES + sizeof(struct lpfc_name);
1840        ad->AttrLen = cpu_to_be16(size);
1841        ad->AttrType = cpu_to_be16(RHBA_FABRIC_WWNN);
1842        return size;
1843}
1844
1845int
1846lpfc_fdmi_hba_attr_bios_ver(struct lpfc_vport *vport,
1847                            struct lpfc_fdmi_attr_def *ad)
1848{
1849        struct lpfc_hba *phba = vport->phba;
1850        struct lpfc_fdmi_attr_entry *ae;
1851        uint32_t len, size;
1852
1853        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1854        memset(ae, 0, 256);
1855
1856        lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1);
1857        len = strnlen(ae->un.AttrString,
1858                          sizeof(ae->un.AttrString));
1859        len += (len & 3) ? (4 - (len & 3)) : 4;
1860        size = FOURBYTES + len;
1861        ad->AttrLen = cpu_to_be16(size);
1862        ad->AttrType = cpu_to_be16(RHBA_BIOS_VERSION);
1863        return size;
1864}
1865
1866int
1867lpfc_fdmi_hba_attr_bios_state(struct lpfc_vport *vport,
1868                              struct lpfc_fdmi_attr_def *ad)
1869{
1870        struct lpfc_fdmi_attr_entry *ae;
1871        uint32_t size;
1872
1873        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1874
1875        /* Driver doesn't have access to this information */
1876        ae->un.AttrInt =  cpu_to_be32(0);
1877        size = FOURBYTES + sizeof(uint32_t);
1878        ad->AttrLen = cpu_to_be16(size);
1879        ad->AttrType = cpu_to_be16(RHBA_BIOS_STATE);
1880        return size;
1881}
1882
1883int
1884lpfc_fdmi_hba_attr_vendor_id(struct lpfc_vport *vport,
1885                             struct lpfc_fdmi_attr_def *ad)
1886{
1887        struct lpfc_fdmi_attr_entry *ae;
1888        uint32_t len, size;
1889
1890        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1891        memset(ae, 0, 256);
1892
1893        strncpy(ae->un.AttrString, "EMULEX",
1894                sizeof(ae->un.AttrString));
1895        len = strnlen(ae->un.AttrString,
1896                          sizeof(ae->un.AttrString));
1897        len += (len & 3) ? (4 - (len & 3)) : 4;
1898        size = FOURBYTES + len;
1899        ad->AttrLen = cpu_to_be16(size);
1900        ad->AttrType = cpu_to_be16(RHBA_VENDOR_ID);
1901        return size;
1902}
1903
1904/* Routines for all individual PORT attributes */
1905int
1906lpfc_fdmi_port_attr_fc4type(struct lpfc_vport *vport,
1907                            struct lpfc_fdmi_attr_def *ad)
1908{
1909        struct lpfc_fdmi_attr_entry *ae;
1910        uint32_t size;
1911
1912        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1913        memset(ae, 0, 32);
1914
1915        ae->un.AttrTypes[3] = 0x02; /* Type 1 - ELS */
1916        ae->un.AttrTypes[2] = 0x01; /* Type 8 - FCP */
1917        ae->un.AttrTypes[7] = 0x01; /* Type 32 - CT */
1918        size = FOURBYTES + 32;
1919        ad->AttrLen = cpu_to_be16(size);
1920        ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES);
1921        return size;
1922}
1923
1924int
1925lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport,
1926                                  struct lpfc_fdmi_attr_def *ad)
1927{
1928        struct lpfc_hba   *phba = vport->phba;
1929        struct lpfc_fdmi_attr_entry *ae;
1930        uint32_t size;
1931
1932        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1933
1934        ae->un.AttrInt = 0;
1935        if (!(phba->hba_flag & HBA_FCOE_MODE)) {
1936                if (phba->lmt & LMT_32Gb)
1937                        ae->un.AttrInt |= HBA_PORTSPEED_32GFC;
1938                if (phba->lmt & LMT_16Gb)
1939                        ae->un.AttrInt |= HBA_PORTSPEED_16GFC;
1940                if (phba->lmt & LMT_10Gb)
1941                        ae->un.AttrInt |= HBA_PORTSPEED_10GFC;
1942                if (phba->lmt & LMT_8Gb)
1943                        ae->un.AttrInt |= HBA_PORTSPEED_8GFC;
1944                if (phba->lmt & LMT_4Gb)
1945                        ae->un.AttrInt |= HBA_PORTSPEED_4GFC;
1946                if (phba->lmt & LMT_2Gb)
1947                        ae->un.AttrInt |= HBA_PORTSPEED_2GFC;
1948                if (phba->lmt & LMT_1Gb)
1949                        ae->un.AttrInt |= HBA_PORTSPEED_1GFC;
1950        } else {
1951                /* FCoE links support only one speed */
1952                switch (phba->fc_linkspeed) {
1953                case LPFC_ASYNC_LINK_SPEED_10GBPS:
1954                        ae->un.AttrInt = HBA_PORTSPEED_10GE;
1955                        break;
1956                case LPFC_ASYNC_LINK_SPEED_25GBPS:
1957                        ae->un.AttrInt = HBA_PORTSPEED_25GE;
1958                        break;
1959                case LPFC_ASYNC_LINK_SPEED_40GBPS:
1960                        ae->un.AttrInt = HBA_PORTSPEED_40GE;
1961                        break;
1962                case LPFC_ASYNC_LINK_SPEED_100GBPS:
1963                        ae->un.AttrInt = HBA_PORTSPEED_100GE;
1964                        break;
1965                }
1966        }
1967        ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt);
1968        size = FOURBYTES + sizeof(uint32_t);
1969        ad->AttrLen = cpu_to_be16(size);
1970        ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED);
1971        return size;
1972}
1973
1974int
1975lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport,
1976                          struct lpfc_fdmi_attr_def *ad)
1977{
1978        struct lpfc_hba   *phba = vport->phba;
1979        struct lpfc_fdmi_attr_entry *ae;
1980        uint32_t size;
1981
1982        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
1983
1984        if (!(phba->hba_flag & HBA_FCOE_MODE)) {
1985                switch (phba->fc_linkspeed) {
1986                case LPFC_LINK_SPEED_1GHZ:
1987                        ae->un.AttrInt = HBA_PORTSPEED_1GFC;
1988                        break;
1989                case LPFC_LINK_SPEED_2GHZ:
1990                        ae->un.AttrInt = HBA_PORTSPEED_2GFC;
1991                        break;
1992                case LPFC_LINK_SPEED_4GHZ:
1993                        ae->un.AttrInt = HBA_PORTSPEED_4GFC;
1994                        break;
1995                case LPFC_LINK_SPEED_8GHZ:
1996                        ae->un.AttrInt = HBA_PORTSPEED_8GFC;
1997                        break;
1998                case LPFC_LINK_SPEED_10GHZ:
1999                        ae->un.AttrInt = HBA_PORTSPEED_10GFC;
2000                        break;
2001                case LPFC_LINK_SPEED_16GHZ:
2002                        ae->un.AttrInt = HBA_PORTSPEED_16GFC;
2003                        break;
2004                case LPFC_LINK_SPEED_32GHZ:
2005                        ae->un.AttrInt = HBA_PORTSPEED_32GFC;
2006                        break;
2007                default:
2008                        ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN;
2009                        break;
2010                }
2011        } else {
2012                switch (phba->fc_linkspeed) {
2013                case LPFC_ASYNC_LINK_SPEED_10GBPS:
2014                        ae->un.AttrInt = HBA_PORTSPEED_10GE;
2015                        break;
2016                case LPFC_ASYNC_LINK_SPEED_25GBPS:
2017                        ae->un.AttrInt = HBA_PORTSPEED_25GE;
2018                        break;
2019                case LPFC_ASYNC_LINK_SPEED_40GBPS:
2020                        ae->un.AttrInt = HBA_PORTSPEED_40GE;
2021                        break;
2022                case LPFC_ASYNC_LINK_SPEED_100GBPS:
2023                        ae->un.AttrInt = HBA_PORTSPEED_100GE;
2024                        break;
2025                default:
2026                        ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN;
2027                        break;
2028                }
2029        }
2030
2031        ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt);
2032        size = FOURBYTES + sizeof(uint32_t);
2033        ad->AttrLen = cpu_to_be16(size);
2034        ad->AttrType = cpu_to_be16(RPRT_PORT_SPEED);
2035        return size;
2036}
2037
2038int
2039lpfc_fdmi_port_attr_max_frame(struct lpfc_vport *vport,
2040                              struct lpfc_fdmi_attr_def *ad)
2041{
2042        struct serv_parm *hsp;
2043        struct lpfc_fdmi_attr_entry *ae;
2044        uint32_t size;
2045
2046        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2047
2048        hsp = (struct serv_parm *)&vport->fc_sparam;
2049        ae->un.AttrInt = (((uint32_t) hsp->cmn.bbRcvSizeMsb) << 8) |
2050                          (uint32_t) hsp->cmn.bbRcvSizeLsb;
2051        ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt);
2052        size = FOURBYTES + sizeof(uint32_t);
2053        ad->AttrLen = cpu_to_be16(size);
2054        ad->AttrType = cpu_to_be16(RPRT_MAX_FRAME_SIZE);
2055        return size;
2056}
2057
2058int
2059lpfc_fdmi_port_attr_os_devname(struct lpfc_vport *vport,
2060                               struct lpfc_fdmi_attr_def *ad)
2061{
2062        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2063        struct lpfc_fdmi_attr_entry *ae;
2064        uint32_t len, size;
2065
2066        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2067        memset(ae, 0, 256);
2068
2069        snprintf(ae->un.AttrString, sizeof(ae->un.AttrString),
2070                 "/sys/class/scsi_host/host%d", shost->host_no);
2071        len = strnlen((char *)ae->un.AttrString,
2072                          sizeof(ae->un.AttrString));
2073        len += (len & 3) ? (4 - (len & 3)) : 4;
2074        size = FOURBYTES + len;
2075        ad->AttrLen = cpu_to_be16(size);
2076        ad->AttrType = cpu_to_be16(RPRT_OS_DEVICE_NAME);
2077        return size;
2078}
2079
2080int
2081lpfc_fdmi_port_attr_host_name(struct lpfc_vport *vport,
2082                              struct lpfc_fdmi_attr_def *ad)
2083{
2084        struct lpfc_fdmi_attr_entry *ae;
2085        uint32_t len, size;
2086
2087        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2088        memset(ae, 0, 256);
2089
2090        snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s",
2091                 init_utsname()->nodename);
2092
2093        len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
2094        len += (len & 3) ? (4 - (len & 3)) : 4;
2095        size = FOURBYTES + len;
2096        ad->AttrLen = cpu_to_be16(size);
2097        ad->AttrType = cpu_to_be16(RPRT_HOST_NAME);
2098        return size;
2099}
2100
2101int
2102lpfc_fdmi_port_attr_wwnn(struct lpfc_vport *vport,
2103                         struct lpfc_fdmi_attr_def *ad)
2104{
2105        struct lpfc_fdmi_attr_entry *ae;
2106        uint32_t size;
2107
2108        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2109        memset(ae, 0,  sizeof(struct lpfc_name));
2110
2111        memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName,
2112               sizeof(struct lpfc_name));
2113        size = FOURBYTES + sizeof(struct lpfc_name);
2114        ad->AttrLen = cpu_to_be16(size);
2115        ad->AttrType = cpu_to_be16(RPRT_NODENAME);
2116        return size;
2117}
2118
2119int
2120lpfc_fdmi_port_attr_wwpn(struct lpfc_vport *vport,
2121                         struct lpfc_fdmi_attr_def *ad)
2122{
2123        struct lpfc_fdmi_attr_entry *ae;
2124        uint32_t size;
2125
2126        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2127        memset(ae, 0,  sizeof(struct lpfc_name));
2128
2129        memcpy(&ae->un.AttrWWN, &vport->fc_sparam.portName,
2130               sizeof(struct lpfc_name));
2131        size = FOURBYTES + sizeof(struct lpfc_name);
2132        ad->AttrLen = cpu_to_be16(size);
2133        ad->AttrType = cpu_to_be16(RPRT_PORTNAME);
2134        return size;
2135}
2136
2137int
2138lpfc_fdmi_port_attr_symbolic_name(struct lpfc_vport *vport,
2139                                  struct lpfc_fdmi_attr_def *ad)
2140{
2141        struct lpfc_fdmi_attr_entry *ae;
2142        uint32_t len, size;
2143
2144        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2145        memset(ae, 0, 256);
2146
2147        len = lpfc_vport_symbolic_port_name(vport, ae->un.AttrString, 256);
2148        len += (len & 3) ? (4 - (len & 3)) : 4;
2149        size = FOURBYTES + len;
2150        ad->AttrLen = cpu_to_be16(size);
2151        ad->AttrType = cpu_to_be16(RPRT_SYM_PORTNAME);
2152        return size;
2153}
2154
2155int
2156lpfc_fdmi_port_attr_port_type(struct lpfc_vport *vport,
2157                              struct lpfc_fdmi_attr_def *ad)
2158{
2159        struct lpfc_hba *phba = vport->phba;
2160        struct lpfc_fdmi_attr_entry *ae;
2161        uint32_t size;
2162
2163        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2164        if (phba->fc_topology == LPFC_TOPOLOGY_LOOP)
2165                ae->un.AttrInt =  cpu_to_be32(LPFC_FDMI_PORTTYPE_NLPORT);
2166        else
2167                ae->un.AttrInt =  cpu_to_be32(LPFC_FDMI_PORTTYPE_NPORT);
2168        size = FOURBYTES + sizeof(uint32_t);
2169        ad->AttrLen = cpu_to_be16(size);
2170        ad->AttrType = cpu_to_be16(RPRT_PORT_TYPE);
2171        return size;
2172}
2173
2174int
2175lpfc_fdmi_port_attr_class(struct lpfc_vport *vport,
2176                          struct lpfc_fdmi_attr_def *ad)
2177{
2178        struct lpfc_fdmi_attr_entry *ae;
2179        uint32_t size;
2180
2181        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2182        ae->un.AttrInt = cpu_to_be32(FC_COS_CLASS2 | FC_COS_CLASS3);
2183        size = FOURBYTES + sizeof(uint32_t);
2184        ad->AttrLen = cpu_to_be16(size);
2185        ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_CLASS);
2186        return size;
2187}
2188
2189int
2190lpfc_fdmi_port_attr_fabric_wwpn(struct lpfc_vport *vport,
2191                                struct lpfc_fdmi_attr_def *ad)
2192{
2193        struct lpfc_fdmi_attr_entry *ae;
2194        uint32_t size;
2195
2196        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2197        memset(ae, 0,  sizeof(struct lpfc_name));
2198
2199        memcpy(&ae->un.AttrWWN, &vport->fabric_portname,
2200               sizeof(struct lpfc_name));
2201        size = FOURBYTES + sizeof(struct lpfc_name);
2202        ad->AttrLen = cpu_to_be16(size);
2203        ad->AttrType = cpu_to_be16(RPRT_FABRICNAME);
2204        return size;
2205}
2206
2207int
2208lpfc_fdmi_port_attr_active_fc4type(struct lpfc_vport *vport,
2209                                   struct lpfc_fdmi_attr_def *ad)
2210{
2211        struct lpfc_fdmi_attr_entry *ae;
2212        uint32_t size;
2213
2214        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2215        memset(ae, 0, 32);
2216
2217        ae->un.AttrTypes[3] = 0x02; /* Type 1 - ELS */
2218        ae->un.AttrTypes[2] = 0x01; /* Type 8 - FCP */
2219        ae->un.AttrTypes[7] = 0x01; /* Type 32 - CT */
2220        size = FOURBYTES + 32;
2221        ad->AttrLen = cpu_to_be16(size);
2222        ad->AttrType = cpu_to_be16(RPRT_ACTIVE_FC4_TYPES);
2223        return size;
2224}
2225
2226int
2227lpfc_fdmi_port_attr_port_state(struct lpfc_vport *vport,
2228                               struct lpfc_fdmi_attr_def *ad)
2229{
2230        struct lpfc_fdmi_attr_entry *ae;
2231        uint32_t size;
2232
2233        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2234        /* Link Up - operational */
2235        ae->un.AttrInt =  cpu_to_be32(LPFC_FDMI_PORTSTATE_ONLINE);
2236        size = FOURBYTES + sizeof(uint32_t);
2237        ad->AttrLen = cpu_to_be16(size);
2238        ad->AttrType = cpu_to_be16(RPRT_PORT_STATE);
2239        return size;
2240}
2241
2242int
2243lpfc_fdmi_port_attr_num_disc(struct lpfc_vport *vport,
2244                             struct lpfc_fdmi_attr_def *ad)
2245{
2246        struct lpfc_fdmi_attr_entry *ae;
2247        uint32_t size;
2248
2249        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2250        vport->fdmi_num_disc = lpfc_find_map_node(vport);
2251        ae->un.AttrInt = cpu_to_be32(vport->fdmi_num_disc);
2252        size = FOURBYTES + sizeof(uint32_t);
2253        ad->AttrLen = cpu_to_be16(size);
2254        ad->AttrType = cpu_to_be16(RPRT_DISC_PORT);
2255        return size;
2256}
2257
2258int
2259lpfc_fdmi_port_attr_nportid(struct lpfc_vport *vport,
2260                            struct lpfc_fdmi_attr_def *ad)
2261{
2262        struct lpfc_fdmi_attr_entry *ae;
2263        uint32_t size;
2264
2265        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2266        ae->un.AttrInt =  cpu_to_be32(vport->fc_myDID);
2267        size = FOURBYTES + sizeof(uint32_t);
2268        ad->AttrLen = cpu_to_be16(size);
2269        ad->AttrType = cpu_to_be16(RPRT_PORT_ID);
2270        return size;
2271}
2272
2273int
2274lpfc_fdmi_smart_attr_service(struct lpfc_vport *vport,
2275                             struct lpfc_fdmi_attr_def *ad)
2276{
2277        struct lpfc_fdmi_attr_entry *ae;
2278        uint32_t len, size;
2279
2280        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2281        memset(ae, 0, 256);
2282
2283        strncpy(ae->un.AttrString, "Smart SAN Initiator",
2284                sizeof(ae->un.AttrString));
2285        len = strnlen(ae->un.AttrString,
2286                          sizeof(ae->un.AttrString));
2287        len += (len & 3) ? (4 - (len & 3)) : 4;
2288        size = FOURBYTES + len;
2289        ad->AttrLen = cpu_to_be16(size);
2290        ad->AttrType = cpu_to_be16(RPRT_SMART_SERVICE);
2291        return size;
2292}
2293
2294int
2295lpfc_fdmi_smart_attr_guid(struct lpfc_vport *vport,
2296                          struct lpfc_fdmi_attr_def *ad)
2297{
2298        struct lpfc_fdmi_attr_entry *ae;
2299        uint32_t size;
2300
2301        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2302        memset(ae, 0, 256);
2303
2304        memcpy(&ae->un.AttrString, &vport->fc_sparam.nodeName,
2305               sizeof(struct lpfc_name));
2306        memcpy((((uint8_t *)&ae->un.AttrString) +
2307                sizeof(struct lpfc_name)),
2308                &vport->fc_sparam.portName, sizeof(struct lpfc_name));
2309        size = FOURBYTES + (2 * sizeof(struct lpfc_name));
2310        ad->AttrLen =  cpu_to_be16(size);
2311        ad->AttrType = cpu_to_be16(RPRT_SMART_GUID);
2312        return size;
2313}
2314
2315int
2316lpfc_fdmi_smart_attr_version(struct lpfc_vport *vport,
2317                             struct lpfc_fdmi_attr_def *ad)
2318{
2319        struct lpfc_fdmi_attr_entry *ae;
2320        uint32_t len, size;
2321
2322        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2323        memset(ae, 0, 256);
2324
2325        strncpy(ae->un.AttrString, "Smart SAN Version 1.0",
2326                sizeof(ae->un.AttrString));
2327        len = strnlen(ae->un.AttrString,
2328                          sizeof(ae->un.AttrString));
2329        len += (len & 3) ? (4 - (len & 3)) : 4;
2330        size = FOURBYTES + len;
2331        ad->AttrLen =  cpu_to_be16(size);
2332        ad->AttrType = cpu_to_be16(RPRT_SMART_VERSION);
2333        return size;
2334}
2335
2336int
2337lpfc_fdmi_smart_attr_model(struct lpfc_vport *vport,
2338                           struct lpfc_fdmi_attr_def *ad)
2339{
2340        struct lpfc_hba *phba = vport->phba;
2341        struct lpfc_fdmi_attr_entry *ae;
2342        uint32_t len, size;
2343
2344        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2345        memset(ae, 0, 256);
2346
2347        strncpy(ae->un.AttrString, phba->ModelName,
2348                sizeof(ae->un.AttrString));
2349        len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString));
2350        len += (len & 3) ? (4 - (len & 3)) : 4;
2351        size = FOURBYTES + len;
2352        ad->AttrLen = cpu_to_be16(size);
2353        ad->AttrType = cpu_to_be16(RPRT_SMART_MODEL);
2354        return size;
2355}
2356
2357int
2358lpfc_fdmi_smart_attr_port_info(struct lpfc_vport *vport,
2359                               struct lpfc_fdmi_attr_def *ad)
2360{
2361        struct lpfc_fdmi_attr_entry *ae;
2362        uint32_t size;
2363
2364        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2365
2366        /* SRIOV (type 3) is not supported */
2367        if (vport->vpi)
2368                ae->un.AttrInt =  cpu_to_be32(2);  /* NPIV */
2369        else
2370                ae->un.AttrInt =  cpu_to_be32(1);  /* Physical */
2371        size = FOURBYTES + sizeof(uint32_t);
2372        ad->AttrLen = cpu_to_be16(size);
2373        ad->AttrType = cpu_to_be16(RPRT_SMART_PORT_INFO);
2374        return size;
2375}
2376
2377int
2378lpfc_fdmi_smart_attr_qos(struct lpfc_vport *vport,
2379                         struct lpfc_fdmi_attr_def *ad)
2380{
2381        struct lpfc_fdmi_attr_entry *ae;
2382        uint32_t size;
2383
2384        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2385        ae->un.AttrInt =  cpu_to_be32(0);
2386        size = FOURBYTES + sizeof(uint32_t);
2387        ad->AttrLen = cpu_to_be16(size);
2388        ad->AttrType = cpu_to_be16(RPRT_SMART_QOS);
2389        return size;
2390}
2391
2392int
2393lpfc_fdmi_smart_attr_security(struct lpfc_vport *vport,
2394                              struct lpfc_fdmi_attr_def *ad)
2395{
2396        struct lpfc_fdmi_attr_entry *ae;
2397        uint32_t size;
2398
2399        ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
2400        ae->un.AttrInt =  cpu_to_be32(0);
2401        size = FOURBYTES + sizeof(uint32_t);
2402        ad->AttrLen = cpu_to_be16(size);
2403        ad->AttrType = cpu_to_be16(RPRT_SMART_SECURITY);
2404        return size;
2405}
2406
2407/* RHBA attribute jump table */
2408int (*lpfc_fdmi_hba_action[])
2409        (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = {
2410        /* Action routine                 Mask bit     Attribute type */
2411        lpfc_fdmi_hba_attr_wwnn,          /* bit0     RHBA_NODENAME           */
2412        lpfc_fdmi_hba_attr_manufacturer,  /* bit1     RHBA_MANUFACTURER       */
2413        lpfc_fdmi_hba_attr_sn,            /* bit2     RHBA_SERIAL_NUMBER      */
2414        lpfc_fdmi_hba_attr_model,         /* bit3     RHBA_MODEL              */
2415        lpfc_fdmi_hba_attr_description,   /* bit4     RHBA_MODEL_DESCRIPTION  */
2416        lpfc_fdmi_hba_attr_hdw_ver,       /* bit5     RHBA_HARDWARE_VERSION   */
2417        lpfc_fdmi_hba_attr_drvr_ver,      /* bit6     RHBA_DRIVER_VERSION     */
2418        lpfc_fdmi_hba_attr_rom_ver,       /* bit7     RHBA_OPTION_ROM_VERSION */
2419        lpfc_fdmi_hba_attr_fmw_ver,       /* bit8     RHBA_FIRMWARE_VERSION   */
2420        lpfc_fdmi_hba_attr_os_ver,        /* bit9     RHBA_OS_NAME_VERSION    */
2421        lpfc_fdmi_hba_attr_ct_len,        /* bit10    RHBA_MAX_CT_PAYLOAD_LEN */
2422        lpfc_fdmi_hba_attr_symbolic_name, /* bit11    RHBA_SYM_NODENAME       */
2423        lpfc_fdmi_hba_attr_vendor_info,   /* bit12    RHBA_VENDOR_INFO        */
2424        lpfc_fdmi_hba_attr_num_ports,     /* bit13    RHBA_NUM_PORTS          */
2425        lpfc_fdmi_hba_attr_fabric_wwnn,   /* bit14    RHBA_FABRIC_WWNN        */
2426        lpfc_fdmi_hba_attr_bios_ver,      /* bit15    RHBA_BIOS_VERSION       */
2427        lpfc_fdmi_hba_attr_bios_state,    /* bit16    RHBA_BIOS_STATE         */
2428        lpfc_fdmi_hba_attr_vendor_id,     /* bit17    RHBA_VENDOR_ID          */
2429};
2430
2431/* RPA / RPRT attribute jump table */
2432int (*lpfc_fdmi_port_action[])
2433        (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = {
2434        /* Action routine                   Mask bit   Attribute type */
2435        lpfc_fdmi_port_attr_fc4type,        /* bit0   RPRT_SUPPORT_FC4_TYPES  */
2436        lpfc_fdmi_port_attr_support_speed,  /* bit1   RPRT_SUPPORTED_SPEED    */
2437        lpfc_fdmi_port_attr_speed,          /* bit2   RPRT_PORT_SPEED         */
2438        lpfc_fdmi_port_attr_max_frame,      /* bit3   RPRT_MAX_FRAME_SIZE     */
2439        lpfc_fdmi_port_attr_os_devname,     /* bit4   RPRT_OS_DEVICE_NAME     */
2440        lpfc_fdmi_port_attr_host_name,      /* bit5   RPRT_HOST_NAME          */
2441        lpfc_fdmi_port_attr_wwnn,           /* bit6   RPRT_NODENAME           */
2442        lpfc_fdmi_port_attr_wwpn,           /* bit7   RPRT_PORTNAME           */
2443        lpfc_fdmi_port_attr_symbolic_name,  /* bit8   RPRT_SYM_PORTNAME       */
2444        lpfc_fdmi_port_attr_port_type,      /* bit9   RPRT_PORT_TYPE          */
2445        lpfc_fdmi_port_attr_class,          /* bit10  RPRT_SUPPORTED_CLASS    */
2446        lpfc_fdmi_port_attr_fabric_wwpn,    /* bit11  RPRT_FABRICNAME         */
2447        lpfc_fdmi_port_attr_active_fc4type, /* bit12  RPRT_ACTIVE_FC4_TYPES   */
2448        lpfc_fdmi_port_attr_port_state,     /* bit13  RPRT_PORT_STATE         */
2449        lpfc_fdmi_port_attr_num_disc,       /* bit14  RPRT_DISC_PORT          */
2450        lpfc_fdmi_port_attr_nportid,        /* bit15  RPRT_PORT_ID            */
2451        lpfc_fdmi_smart_attr_service,       /* bit16  RPRT_SMART_SERVICE      */
2452        lpfc_fdmi_smart_attr_guid,          /* bit17  RPRT_SMART_GUID         */
2453        lpfc_fdmi_smart_attr_version,       /* bit18  RPRT_SMART_VERSION      */
2454        lpfc_fdmi_smart_attr_model,         /* bit19  RPRT_SMART_MODEL        */
2455        lpfc_fdmi_smart_attr_port_info,     /* bit20  RPRT_SMART_PORT_INFO    */
2456        lpfc_fdmi_smart_attr_qos,           /* bit21  RPRT_SMART_QOS          */
2457        lpfc_fdmi_smart_attr_security,      /* bit22  RPRT_SMART_SECURITY     */
2458};
2459
2460/**
2461 * lpfc_fdmi_cmd - Build and send a FDMI cmd to the specified NPort
2462 * @vport: pointer to a host virtual N_Port data structure.
2463 * @ndlp: ndlp to send FDMI cmd to (if NULL use FDMI_DID)
2464 * cmdcode: FDMI command to send
2465 * mask: Mask of HBA or PORT Attributes to send
2466 *
2467 * Builds and sends a FDMI command using the CT subsystem.
2468 */
2469int
2470lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2471              int cmdcode, uint32_t new_mask)
2472{
2473        struct lpfc_hba *phba = vport->phba;
2474        struct lpfc_dmabuf *mp, *bmp;
2475        struct lpfc_sli_ct_request *CtReq;
2476        struct ulp_bde64 *bpl;
2477        uint32_t bit_pos;
2478        uint32_t size;
2479        uint32_t rsp_size;
2480        uint32_t mask;
2481        struct lpfc_fdmi_reg_hba *rh;
2482        struct lpfc_fdmi_port_entry *pe;
2483        struct lpfc_fdmi_reg_portattr *pab = NULL;
2484        struct lpfc_fdmi_attr_block *ab = NULL;
2485        int  (*func)(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad);
2486        void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *,
2487                     struct lpfc_iocbq *);
2488
2489        if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
2490                return 0;
2491
2492        cmpl = lpfc_cmpl_ct_disc_fdmi; /* called from discovery */
2493
2494        /* fill in BDEs for command */
2495        /* Allocate buffer for command payload */
2496        mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
2497        if (!mp)
2498                goto fdmi_cmd_exit;
2499
2500        mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys));
2501        if (!mp->virt)
2502                goto fdmi_cmd_free_mp;
2503
2504        /* Allocate buffer for Buffer ptr list */
2505        bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
2506        if (!bmp)
2507                goto fdmi_cmd_free_mpvirt;
2508
2509        bmp->virt = lpfc_mbuf_alloc(phba, 0, &(bmp->phys));
2510        if (!bmp->virt)
2511                goto fdmi_cmd_free_bmp;
2512
2513        INIT_LIST_HEAD(&mp->list);
2514        INIT_LIST_HEAD(&bmp->list);
2515
2516        /* FDMI request */
2517        lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
2518                         "0218 FDMI Request Data: x%x x%x x%x\n",
2519                         vport->fc_flag, vport->port_state, cmdcode);
2520        CtReq = (struct lpfc_sli_ct_request *)mp->virt;
2521
2522        /* First populate the CT_IU preamble */
2523        memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request));
2524        CtReq->RevisionId.bits.Revision = SLI_CT_REVISION;
2525        CtReq->RevisionId.bits.InId = 0;
2526
2527        CtReq->FsType = SLI_CT_MANAGEMENT_SERVICE;
2528        CtReq->FsSubType = SLI_CT_FDMI_Subtypes;
2529
2530        CtReq->CommandResponse.bits.CmdRsp = cpu_to_be16(cmdcode);
2531        rsp_size = LPFC_BPL_SIZE;
2532        size = 0;
2533
2534        /* Next fill in the specific FDMI cmd information */
2535        switch (cmdcode) {
2536        case SLI_MGMT_RHAT:
2537        case SLI_MGMT_RHBA:
2538                rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un.PortID;
2539                /* HBA Identifier */
2540                memcpy(&rh->hi.PortName, &phba->pport->fc_sparam.portName,
2541                       sizeof(struct lpfc_name));
2542
2543                if (cmdcode == SLI_MGMT_RHBA) {
2544                        /* Registered Port List */
2545                        /* One entry (port) per adapter */
2546                        rh->rpl.EntryCnt = cpu_to_be32(1);
2547                        memcpy(&rh->rpl.pe, &phba->pport->fc_sparam.portName,
2548                               sizeof(struct lpfc_name));
2549
2550                        /* point to the HBA attribute block */
2551                        size = 2 * sizeof(struct lpfc_name) +
2552                                FOURBYTES;
2553                } else {
2554                        size = sizeof(struct lpfc_name);
2555                }
2556                ab = (struct lpfc_fdmi_attr_block *)((uint8_t *)rh + size);
2557                ab->EntryCnt = 0;
2558                size += FOURBYTES;
2559                bit_pos = 0;
2560                if (new_mask)
2561                        mask = new_mask;
2562                else
2563                        mask = vport->fdmi_hba_mask;
2564
2565                /* Mask will dictate what attributes to build in the request */
2566                while (mask) {
2567                        if (mask & 0x1) {
2568                                func = lpfc_fdmi_hba_action[bit_pos];
2569                                size += func(vport,
2570                                             (struct lpfc_fdmi_attr_def *)
2571                                             ((uint8_t *)rh + size));
2572                                ab->EntryCnt++;
2573                                if ((size + 256) >
2574                                    (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
2575                                        goto hba_out;
2576                        }
2577                        mask = mask >> 1;
2578                        bit_pos++;
2579                }
2580hba_out:
2581                ab->EntryCnt = cpu_to_be32(ab->EntryCnt);
2582                /* Total size */
2583                size = GID_REQUEST_SZ - 4 + size;
2584                break;
2585
2586        case SLI_MGMT_RPRT:
2587        case SLI_MGMT_RPA:
2588                pab = (struct lpfc_fdmi_reg_portattr *)&CtReq->un.PortID;
2589                if (cmdcode == SLI_MGMT_RPRT) {
2590                        rh = (struct lpfc_fdmi_reg_hba *)pab;
2591                        /* HBA Identifier */
2592                        memcpy(&rh->hi.PortName,
2593                               &phba->pport->fc_sparam.portName,
2594                               sizeof(struct lpfc_name));
2595                        pab = (struct lpfc_fdmi_reg_portattr *)
2596                                ((uint8_t *)pab +  sizeof(struct lpfc_name));
2597                }
2598
2599                memcpy((uint8_t *)&pab->PortName,
2600                       (uint8_t *)&vport->fc_sparam.portName,
2601                       sizeof(struct lpfc_name));
2602                size += sizeof(struct lpfc_name) + FOURBYTES;
2603                pab->ab.EntryCnt = 0;
2604                bit_pos = 0;
2605                if (new_mask)
2606                        mask = new_mask;
2607                else
2608                        mask = vport->fdmi_port_mask;
2609
2610                /* Mask will dictate what attributes to build in the request */
2611                while (mask) {
2612                        if (mask & 0x1) {
2613                                func = lpfc_fdmi_port_action[bit_pos];
2614                                size += func(vport,
2615                                             (struct lpfc_fdmi_attr_def *)
2616                                             ((uint8_t *)pab + size));
2617                                pab->ab.EntryCnt++;
2618                                if ((size + 256) >
2619                                    (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))
2620                                        goto port_out;
2621                        }
2622                        mask = mask >> 1;
2623                        bit_pos++;
2624                }
2625port_out:
2626                pab->ab.EntryCnt = cpu_to_be32(pab->ab.EntryCnt);
2627                /* Total size */
2628                if (cmdcode == SLI_MGMT_RPRT)
2629                        size += sizeof(struct lpfc_name);
2630                size = GID_REQUEST_SZ - 4 + size;
2631                break;
2632
2633        case SLI_MGMT_GHAT:
2634        case SLI_MGMT_GRPL:
2635                rsp_size = FC_MAX_NS_RSP;
2636        case SLI_MGMT_DHBA:
2637        case SLI_MGMT_DHAT:
2638                pe = (struct lpfc_fdmi_port_entry *)&CtReq->un.PortID;
2639                memcpy((uint8_t *)&pe->PortName,
2640                       (uint8_t *)&vport->fc_sparam.portName,
2641                       sizeof(struct lpfc_name));
2642                size = GID_REQUEST_SZ - 4 + sizeof(struct lpfc_name);
2643                break;
2644
2645        case SLI_MGMT_GPAT:
2646        case SLI_MGMT_GPAS:
2647                rsp_size = FC_MAX_NS_RSP;
2648        case SLI_MGMT_DPRT:
2649        case SLI_MGMT_DPA:
2650                pe = (struct lpfc_fdmi_port_entry *)&CtReq->un.PortID;
2651                memcpy((uint8_t *)&pe->PortName,
2652                       (uint8_t *)&vport->fc_sparam.portName,
2653                       sizeof(struct lpfc_name));
2654                size = GID_REQUEST_SZ - 4 + sizeof(struct lpfc_name);
2655                break;
2656        case SLI_MGMT_GRHL:
2657                size = GID_REQUEST_SZ - 4;
2658                break;
2659        default:
2660                lpfc_printf_vlog(vport, KERN_WARNING, LOG_DISCOVERY,
2661                                 "0298 FDMI cmdcode x%x not supported\n",
2662                                 cmdcode);
2663                goto fdmi_cmd_free_bmpvirt;
2664        }
2665        CtReq->CommandResponse.bits.Size = cpu_to_be16(rsp_size);
2666
2667        bpl = (struct ulp_bde64 *)bmp->virt;
2668        bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys));
2669        bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys));
2670        bpl->tus.f.bdeFlags = 0;
2671        bpl->tus.f.bdeSize = size;
2672
2673        /*
2674         * The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count
2675         * to hold ndlp reference for the corresponding callback function.
2676         */
2677        if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, 0))
2678                return 0;
2679
2680        /*
2681         * Decrement ndlp reference count to release ndlp reference held
2682         * for the failed command's callback function.
2683         */
2684        lpfc_nlp_put(ndlp);
2685
2686fdmi_cmd_free_bmpvirt:
2687        lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
2688fdmi_cmd_free_bmp:
2689        kfree(bmp);
2690fdmi_cmd_free_mpvirt:
2691        lpfc_mbuf_free(phba, mp->virt, mp->phys);
2692fdmi_cmd_free_mp:
2693        kfree(mp);
2694fdmi_cmd_exit:
2695        /* Issue FDMI request failed */
2696        lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
2697                         "0244 Issue FDMI request failed Data: x%x\n",
2698                         cmdcode);
2699        return 1;
2700}
2701
2702/**
2703 * lpfc_delayed_disc_tmo - Timeout handler for delayed discovery timer.
2704 * @ptr - Context object of the timer.
2705 *
2706 * This function set the WORKER_DELAYED_DISC_TMO flag and wake up
2707 * the worker thread.
2708 **/
2709void
2710lpfc_delayed_disc_tmo(unsigned long ptr)
2711{
2712        struct lpfc_vport *vport = (struct lpfc_vport *)ptr;
2713        struct lpfc_hba   *phba = vport->phba;
2714        uint32_t tmo_posted;
2715        unsigned long iflag;
2716
2717        spin_lock_irqsave(&vport->work_port_lock, iflag);
2718        tmo_posted = vport->work_port_events & WORKER_DELAYED_DISC_TMO;
2719        if (!tmo_posted)
2720                vport->work_port_events |= WORKER_DELAYED_DISC_TMO;
2721        spin_unlock_irqrestore(&vport->work_port_lock, iflag);
2722
2723        if (!tmo_posted)
2724                lpfc_worker_wake_up(phba);
2725        return;
2726}
2727
2728/**
2729 * lpfc_delayed_disc_timeout_handler - Function called by worker thread to
2730 *      handle delayed discovery.
2731 * @vport: pointer to a host virtual N_Port data structure.
2732 *
2733 * This function start nport discovery of the vport.
2734 **/
2735void
2736lpfc_delayed_disc_timeout_handler(struct lpfc_vport *vport)
2737{
2738        struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2739
2740        spin_lock_irq(shost->host_lock);
2741        if (!(vport->fc_flag & FC_DISC_DELAYED)) {
2742                spin_unlock_irq(shost->host_lock);
2743                return;
2744        }
2745        vport->fc_flag &= ~FC_DISC_DELAYED;
2746        spin_unlock_irq(shost->host_lock);
2747
2748        lpfc_do_scr_ns_plogi(vport->phba, vport);
2749}
2750
2751void
2752lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)
2753{
2754        struct lpfc_sli *psli = &phba->sli;
2755        lpfc_vpd_t *vp = &phba->vpd;
2756        uint32_t b1, b2, b3, b4, i, rev;
2757        char c;
2758        uint32_t *ptr, str[4];
2759        uint8_t *fwname;
2760
2761        if (phba->sli_rev == LPFC_SLI_REV4)
2762                snprintf(fwrevision, FW_REV_STR_SIZE, "%s", vp->rev.opFwName);
2763        else if (vp->rev.rBit) {
2764                if (psli->sli_flag & LPFC_SLI_ACTIVE)
2765                        rev = vp->rev.sli2FwRev;
2766                else
2767                        rev = vp->rev.sli1FwRev;
2768
2769                b1 = (rev & 0x0000f000) >> 12;
2770                b2 = (rev & 0x00000f00) >> 8;
2771                b3 = (rev & 0x000000c0) >> 6;
2772                b4 = (rev & 0x00000030) >> 4;
2773
2774                switch (b4) {
2775                case 0:
2776                        c = 'N';
2777                        break;
2778                case 1:
2779                        c = 'A';
2780                        break;
2781                case 2:
2782                        c = 'B';
2783                        break;
2784                case 3:
2785                        c = 'X';
2786                        break;
2787                default:
2788                        c = 0;
2789                        break;
2790                }
2791                b4 = (rev & 0x0000000f);
2792
2793                if (psli->sli_flag & LPFC_SLI_ACTIVE)
2794                        fwname = vp->rev.sli2FwName;
2795                else
2796                        fwname = vp->rev.sli1FwName;
2797
2798                for (i = 0; i < 16; i++)
2799                        if (fwname[i] == 0x20)
2800                                fwname[i] = 0;
2801
2802                ptr = (uint32_t*)fwname;
2803
2804                for (i = 0; i < 3; i++)
2805                        str[i] = be32_to_cpu(*ptr++);
2806
2807                if (c == 0) {
2808                        if (flag)
2809                                sprintf(fwrevision, "%d.%d%d (%s)",
2810                                        b1, b2, b3, (char *)str);
2811                        else
2812                                sprintf(fwrevision, "%d.%d%d", b1,
2813                                        b2, b3);
2814                } else {
2815                        if (flag)
2816                                sprintf(fwrevision, "%d.%d%d%c%d (%s)",
2817                                        b1, b2, b3, c,
2818                                        b4, (char *)str);
2819                        else
2820                                sprintf(fwrevision, "%d.%d%d%c%d",
2821                                        b1, b2, b3, c, b4);
2822                }
2823        } else {
2824                rev = vp->rev.smFwRev;
2825
2826                b1 = (rev & 0xff000000) >> 24;
2827                b2 = (rev & 0x00f00000) >> 20;
2828                b3 = (rev & 0x000f0000) >> 16;
2829                c  = (rev & 0x0000ff00) >> 8;
2830                b4 = (rev & 0x000000ff);
2831
2832                sprintf(fwrevision, "%d.%d%d%c%d", b1, b2, b3, c, b4);
2833        }
2834        return;
2835}
2836