1 /*******************************************************************
 
   2  * This file is part of the Emulex Linux Device Driver for         *
 
   3  * Fibre Channel Host Bus Adapters.                                *
 
   4  * Copyright (C) 2004-2007 Emulex.  All rights reserved.           *
 
   5  * EMULEX and SLI are trademarks of Emulex.                        *
 
   7  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
 
   9  * This program is free software; you can redistribute it and/or   *
 
  10  * modify it under the terms of version 2 of the GNU General       *
 
  11  * Public License as published by the Free Software Foundation.    *
 
  12  * This program is distributed in the hope that it will be useful. *
 
  13  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
 
  14  * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
 
  15  * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
 
  16  * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
 
  17  * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
 
  18  * more details, a copy of which can be found in the file COPYING  *
 
  19  * included with this package.                                     *
 
  20  *******************************************************************/
 
  22 #include <linux/blkdev.h>
 
  23 #include <linux/pci.h>
 
  24 #include <linux/interrupt.h>
 
  26 #include <scsi/scsi_device.h>
 
  27 #include <scsi/scsi_transport_fc.h>
 
  29 #include <scsi/scsi.h>
 
  33 #include "lpfc_disc.h"
 
  34 #include "lpfc_scsi.h"
 
  36 #include "lpfc_logmsg.h"
 
  37 #include "lpfc_crtn.h"
 
  38 #include "lpfc_compat.h"
 
  40 /**********************************************/
 
  43 /**********************************************/
 
  45 lpfc_dump_mem(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint16_t offset)
 
  53         /* Setup to dump VPD region */
 
  54         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
  55         mb->mbxCommand = MBX_DUMP_MEMORY;
 
  57         mb->un.varDmp.type = DMP_NV_PARAMS;
 
  58         mb->un.varDmp.entry_index = offset;
 
  59         mb->un.varDmp.region_id = DMP_REGION_VPD;
 
  60         mb->un.varDmp.word_cnt = (DMP_RSP_SIZE / sizeof (uint32_t));
 
  62         mb->un.varDmp.resp_offset = 0;
 
  64         mb->mbxOwner = OWN_HOST;
 
  68 /**********************************************/
 
  69 /*  lpfc_read_nv  Issue a READ NVPARAM        */
 
  71 /**********************************************/
 
  73 lpfc_read_nv(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
  78         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
  79         mb->mbxCommand = MBX_READ_NV;
 
  80         mb->mbxOwner = OWN_HOST;
 
  84 /**********************************************/
 
  85 /*  lpfc_config_async  Issue a                */
 
  86 /*  MBX_ASYNC_EVT_ENABLE mailbox command      */
 
  87 /**********************************************/
 
  89 lpfc_config_async(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb,
 
  95         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
  96         mb->mbxCommand = MBX_ASYNCEVT_ENABLE;
 
  97         mb->un.varCfgAsyncEvent.ring = ring;
 
  98         mb->mbxOwner = OWN_HOST;
 
 102 /**********************************************/
 
 103 /*  lpfc_heart_beat  Issue a HEART_BEAT       */
 
 104 /*                mailbox command             */
 
 105 /**********************************************/
 
 107 lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 112         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 113         mb->mbxCommand = MBX_HEARTBEAT;
 
 114         mb->mbxOwner = OWN_HOST;
 
 118 /**********************************************/
 
 119 /*  lpfc_read_la  Issue a READ LA             */
 
 120 /*                mailbox command             */
 
 121 /**********************************************/
 
 123 lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp)
 
 126         struct lpfc_sli *psli;
 
 130         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 132         INIT_LIST_HEAD(&mp->list);
 
 133         mb->mbxCommand = MBX_READ_LA64;
 
 134         mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128;
 
 135         mb->un.varReadLA.un.lilpBde64.addrHigh = putPaddrHigh(mp->phys);
 
 136         mb->un.varReadLA.un.lilpBde64.addrLow = putPaddrLow(mp->phys);
 
 138         /* Save address for later completion and set the owner to host so that
 
 139          * the FW knows this mailbox is available for processing.
 
 141         pmb->context1 = (uint8_t *) mp;
 
 142         mb->mbxOwner = OWN_HOST;
 
 146 /**********************************************/
 
 147 /*  lpfc_clear_la  Issue a CLEAR LA           */
 
 148 /*                 mailbox command            */
 
 149 /**********************************************/
 
 151 lpfc_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 156         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 158         mb->un.varClearLA.eventTag = phba->fc_eventTag;
 
 159         mb->mbxCommand = MBX_CLEAR_LA;
 
 160         mb->mbxOwner = OWN_HOST;
 
 164 /**************************************************/
 
 165 /*  lpfc_config_link  Issue a CONFIG LINK         */
 
 166 /*                    mailbox command             */
 
 167 /**************************************************/
 
 169 lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 171         struct lpfc_vport  *vport = phba->pport;
 
 172         MAILBOX_t *mb = &pmb->mb;
 
 173         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 176          * SLI-2, Coalescing Response Feature.
 
 178         if (phba->cfg_cr_delay) {
 
 179                 mb->un.varCfgLnk.cr = 1;
 
 180                 mb->un.varCfgLnk.ci = 1;
 
 181                 mb->un.varCfgLnk.cr_delay = phba->cfg_cr_delay;
 
 182                 mb->un.varCfgLnk.cr_count = phba->cfg_cr_count;
 
 185         mb->un.varCfgLnk.myId = vport->fc_myDID;
 
 186         mb->un.varCfgLnk.edtov = phba->fc_edtov;
 
 187         mb->un.varCfgLnk.arbtov = phba->fc_arbtov;
 
 188         mb->un.varCfgLnk.ratov = phba->fc_ratov;
 
 189         mb->un.varCfgLnk.rttov = phba->fc_rttov;
 
 190         mb->un.varCfgLnk.altov = phba->fc_altov;
 
 191         mb->un.varCfgLnk.crtov = phba->fc_crtov;
 
 192         mb->un.varCfgLnk.citov = phba->fc_citov;
 
 195                 mb->un.varCfgLnk.ack0_enable = 1;
 
 197         mb->mbxCommand = MBX_CONFIG_LINK;
 
 198         mb->mbxOwner = OWN_HOST;
 
 202 /**********************************************/
 
 203 /*  lpfc_init_link  Issue an INIT LINK        */
 
 204 /*                  mailbox command           */
 
 205 /**********************************************/
 
 207 lpfc_init_link(struct lpfc_hba * phba,
 
 208                LPFC_MBOXQ_t * pmb, uint32_t topology, uint32_t linkspeed)
 
 211         struct lpfc_sli *psli;
 
 215         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 219         case FLAGS_TOPOLOGY_MODE_LOOP_PT:
 
 220                 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
 
 221                 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
 
 223         case FLAGS_TOPOLOGY_MODE_PT_PT:
 
 224                 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
 
 226         case FLAGS_TOPOLOGY_MODE_LOOP:
 
 227                 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
 
 229         case FLAGS_TOPOLOGY_MODE_PT_LOOP:
 
 230                 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
 
 231                 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
 
 234                 mb->un.varInitLnk.link_flags = FLAGS_LOCAL_LB;
 
 238         /* Enable asynchronous ABTS responses from firmware */
 
 239         mb->un.varInitLnk.link_flags |= FLAGS_IMED_ABORT;
 
 242          * Setting up the link speed
 
 245         if (vpd->rev.feaLevelHigh >= 0x02){
 
 251                                 mb->un.varInitLnk.link_flags |=
 
 253                                 mb->un.varInitLnk.link_speed = linkspeed;
 
 255                         case LINK_SPEED_AUTO:
 
 257                                 mb->un.varInitLnk.link_speed =
 
 264                 mb->un.varInitLnk.link_speed = LINK_SPEED_AUTO;
 
 266         mb->mbxCommand = (volatile uint8_t)MBX_INIT_LINK;
 
 267         mb->mbxOwner = OWN_HOST;
 
 268         mb->un.varInitLnk.fabric_AL_PA = phba->fc_pref_ALPA;
 
 272 /**********************************************/
 
 273 /*  lpfc_read_sparam  Issue a READ SPARAM     */
 
 274 /*                    mailbox command         */
 
 275 /**********************************************/
 
 277 lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi)
 
 279         struct lpfc_dmabuf *mp;
 
 281         struct lpfc_sli *psli;
 
 285         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 287         mb->mbxOwner = OWN_HOST;
 
 289         /* Get a buffer to hold the HBAs Service Parameters */
 
 291         mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
 
 293                 mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
 
 294         if (!mp || !mp->virt) {
 
 296                 mb->mbxCommand = MBX_READ_SPARM64;
 
 297                 /* READ_SPARAM: no buffers */
 
 298                 lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
 
 299                                 "0301 READ_SPARAM: no buffers\n");
 
 302         INIT_LIST_HEAD(&mp->list);
 
 303         mb->mbxCommand = MBX_READ_SPARM64;
 
 304         mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
 
 305         mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys);
 
 306         mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys);
 
 307         mb->un.varRdSparm.vpi = vpi;
 
 309         /* save address for completion */
 
 315 /********************************************/
 
 316 /*  lpfc_unreg_did  Issue a UNREG_DID       */
 
 317 /*                  mailbox command         */
 
 318 /********************************************/
 
 320 lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did,
 
 326         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 328         mb->un.varUnregDID.did = did;
 
 329         mb->un.varUnregDID.vpi = vpi;
 
 331         mb->mbxCommand = MBX_UNREG_D_ID;
 
 332         mb->mbxOwner = OWN_HOST;
 
 336 /**********************************************/
 
 337 /*  lpfc_read_nv  Issue a READ CONFIG         */
 
 338 /*                mailbox command             */
 
 339 /**********************************************/
 
 341 lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 346         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 348         mb->mbxCommand = MBX_READ_CONFIG;
 
 349         mb->mbxOwner = OWN_HOST;
 
 353 /*************************************************/
 
 354 /*  lpfc_read_lnk_stat  Issue a READ LINK STATUS */
 
 355 /*                mailbox command                */
 
 356 /*************************************************/
 
 358 lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 363         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 365         mb->mbxCommand = MBX_READ_LNK_STAT;
 
 366         mb->mbxOwner = OWN_HOST;
 
 370 /********************************************/
 
 371 /*  lpfc_reg_login  Issue a REG_LOGIN       */
 
 372 /*                  mailbox command         */
 
 373 /********************************************/
 
 375 lpfc_reg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
 
 376                uint8_t *param, LPFC_MBOXQ_t *pmb, uint32_t flag)
 
 378         MAILBOX_t *mb = &pmb->mb;
 
 380         struct lpfc_dmabuf *mp;
 
 382         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 384         mb->un.varRegLogin.rpi = 0;
 
 385         mb->un.varRegLogin.vpi = vpi;
 
 386         mb->un.varRegLogin.did = did;
 
 387         mb->un.varWords[30] = flag;     /* Set flag to issue action on cmpl */
 
 389         mb->mbxOwner = OWN_HOST;
 
 391         /* Get a buffer to hold NPorts Service Parameters */
 
 392         mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
 
 394                 mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
 
 395         if (!mp || !mp->virt) {
 
 397                 mb->mbxCommand = MBX_REG_LOGIN64;
 
 398                 /* REG_LOGIN: no buffers */
 
 399                 lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
 
 400                                 "0302 REG_LOGIN: no buffers, VPI:%d DID:x%x, "
 
 401                                 "flag x%x\n", vpi, did, flag);
 
 404         INIT_LIST_HEAD(&mp->list);
 
 407         /* Copy param's into a new buffer */
 
 408         memcpy(sparam, param, sizeof (struct serv_parm));
 
 410         /* save address for completion */
 
 411         pmb->context1 = (uint8_t *) mp;
 
 413         mb->mbxCommand = MBX_REG_LOGIN64;
 
 414         mb->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
 
 415         mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys);
 
 416         mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys);
 
 421 /**********************************************/
 
 422 /*  lpfc_unreg_login  Issue a UNREG_LOGIN     */
 
 423 /*                    mailbox command         */
 
 424 /**********************************************/
 
 426 lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
 
 432         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 434         mb->un.varUnregLogin.rpi = (uint16_t) rpi;
 
 435         mb->un.varUnregLogin.rsvd1 = 0;
 
 436         mb->un.varUnregLogin.vpi = vpi;
 
 438         mb->mbxCommand = MBX_UNREG_LOGIN;
 
 439         mb->mbxOwner = OWN_HOST;
 
 443 /**************************************************/
 
 444 /*  lpfc_reg_vpi   Issue a REG_VPI                */
 
 445 /*                    mailbox command             */
 
 446 /**************************************************/
 
 448 lpfc_reg_vpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t sid,
 
 451         MAILBOX_t *mb = &pmb->mb;
 
 453         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 455         mb->un.varRegVpi.vpi = vpi;
 
 456         mb->un.varRegVpi.sid = sid;
 
 458         mb->mbxCommand = MBX_REG_VPI;
 
 459         mb->mbxOwner = OWN_HOST;
 
 464 /**************************************************/
 
 465 /*  lpfc_unreg_vpi   Issue a UNREG_VNPI           */
 
 466 /*                    mailbox command             */
 
 467 /**************************************************/
 
 469 lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb)
 
 471         MAILBOX_t *mb = &pmb->mb;
 
 472         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 474         mb->un.varUnregVpi.vpi = vpi;
 
 476         mb->mbxCommand = MBX_UNREG_VPI;
 
 477         mb->mbxOwner = OWN_HOST;
 
 483 lpfc_config_pcb_setup(struct lpfc_hba * phba)
 
 485         struct lpfc_sli *psli = &phba->sli;
 
 486         struct lpfc_sli_ring *pring;
 
 487         PCB_t *pcbp = &phba->slim2p->pcb;
 
 488         dma_addr_t pdma_addr;
 
 490         uint32_t iocbCnt = 0;
 
 493         pcbp->maxRing = (psli->num_rings - 1);
 
 495         for (i = 0; i < psli->num_rings; i++) {
 
 496                 pring = &psli->ring[i];
 
 498                 pring->sizeCiocb = phba->sli_rev == 3 ? SLI3_IOCB_CMD_SIZE:
 
 500                 pring->sizeRiocb = phba->sli_rev == 3 ? SLI3_IOCB_RSP_SIZE:
 
 502                 /* A ring MUST have both cmd and rsp entries defined to be
 
 504                 if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) {
 
 505                         pcbp->rdsc[i].cmdEntries = 0;
 
 506                         pcbp->rdsc[i].rspEntries = 0;
 
 507                         pcbp->rdsc[i].cmdAddrHigh = 0;
 
 508                         pcbp->rdsc[i].rspAddrHigh = 0;
 
 509                         pcbp->rdsc[i].cmdAddrLow = 0;
 
 510                         pcbp->rdsc[i].rspAddrLow = 0;
 
 511                         pring->cmdringaddr = NULL;
 
 512                         pring->rspringaddr = NULL;
 
 515                 /* Command ring setup for ring */
 
 516                 pring->cmdringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt];
 
 517                 pcbp->rdsc[i].cmdEntries = pring->numCiocb;
 
 519                 offset = (uint8_t *) &phba->slim2p->IOCBs[iocbCnt] -
 
 520                          (uint8_t *) phba->slim2p;
 
 521                 pdma_addr = phba->slim2p_mapping + offset;
 
 522                 pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr);
 
 523                 pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr);
 
 524                 iocbCnt += pring->numCiocb;
 
 526                 /* Response ring setup for ring */
 
 527                 pring->rspringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt];
 
 529                 pcbp->rdsc[i].rspEntries = pring->numRiocb;
 
 530                 offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] -
 
 531                          (uint8_t *)phba->slim2p;
 
 532                 pdma_addr = phba->slim2p_mapping + offset;
 
 533                 pcbp->rdsc[i].rspAddrHigh = putPaddrHigh(pdma_addr);
 
 534                 pcbp->rdsc[i].rspAddrLow = putPaddrLow(pdma_addr);
 
 535                 iocbCnt += pring->numRiocb;
 
 540 lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 542         MAILBOX_t *mb = &pmb->mb;
 
 543         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 544         mb->un.varRdRev.cv = 1;
 
 545         mb->un.varRdRev.v3req = 1; /* Request SLI3 info */
 
 546         mb->mbxCommand = MBX_READ_REV;
 
 547         mb->mbxOwner = OWN_HOST;
 
 552 lpfc_build_hbq_profile2(struct config_hbq_var *hbqmb,
 
 553                         struct lpfc_hbq_init  *hbq_desc)
 
 555         hbqmb->profiles.profile2.seqlenbcnt = hbq_desc->seqlenbcnt;
 
 556         hbqmb->profiles.profile2.maxlen     = hbq_desc->maxlen;
 
 557         hbqmb->profiles.profile2.seqlenoff  = hbq_desc->seqlenoff;
 
 561 lpfc_build_hbq_profile3(struct config_hbq_var *hbqmb,
 
 562                         struct lpfc_hbq_init  *hbq_desc)
 
 564         hbqmb->profiles.profile3.seqlenbcnt = hbq_desc->seqlenbcnt;
 
 565         hbqmb->profiles.profile3.maxlen     = hbq_desc->maxlen;
 
 566         hbqmb->profiles.profile3.cmdcodeoff = hbq_desc->cmdcodeoff;
 
 567         hbqmb->profiles.profile3.seqlenoff  = hbq_desc->seqlenoff;
 
 568         memcpy(&hbqmb->profiles.profile3.cmdmatch, hbq_desc->cmdmatch,
 
 569                sizeof(hbqmb->profiles.profile3.cmdmatch));
 
 573 lpfc_build_hbq_profile5(struct config_hbq_var *hbqmb,
 
 574                         struct lpfc_hbq_init  *hbq_desc)
 
 576         hbqmb->profiles.profile5.seqlenbcnt = hbq_desc->seqlenbcnt;
 
 577         hbqmb->profiles.profile5.maxlen     = hbq_desc->maxlen;
 
 578         hbqmb->profiles.profile5.cmdcodeoff = hbq_desc->cmdcodeoff;
 
 579         hbqmb->profiles.profile5.seqlenoff  = hbq_desc->seqlenoff;
 
 580         memcpy(&hbqmb->profiles.profile5.cmdmatch, hbq_desc->cmdmatch,
 
 581                sizeof(hbqmb->profiles.profile5.cmdmatch));
 
 585 lpfc_config_hbq(struct lpfc_hba *phba, uint32_t id,
 
 586                  struct lpfc_hbq_init *hbq_desc,
 
 587                 uint32_t hbq_entry_index, LPFC_MBOXQ_t *pmb)
 
 590         MAILBOX_t *mb = &pmb->mb;
 
 591         struct config_hbq_var *hbqmb = &mb->un.varCfgHbq;
 
 593         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 595         hbqmb->entry_count = hbq_desc->entry_count;   /* # entries in HBQ */
 
 596         hbqmb->recvNotify = hbq_desc->rn;             /* Receive
 
 598         hbqmb->numMask    = hbq_desc->mask_count;     /* # R_CTL/TYPE masks
 
 600         hbqmb->profile    = hbq_desc->profile;        /* Selection profile:
 
 603         hbqmb->ringMask   = hbq_desc->ring_mask;      /* Binds HBQ to a ring
 
 606         hbqmb->headerLen  = hbq_desc->headerLen;      /* 0 if not profile 4
 
 608         hbqmb->logEntry   = hbq_desc->logEntry;       /* Set to 1 if this
 
 612         hbqmb->hbqaddrLow = putPaddrLow(phba->hbqslimp.phys) +
 
 613                 hbq_entry_index * sizeof(struct lpfc_hbq_entry);
 
 614         hbqmb->hbqaddrHigh = putPaddrHigh(phba->hbqslimp.phys);
 
 616         mb->mbxCommand = MBX_CONFIG_HBQ;
 
 617         mb->mbxOwner = OWN_HOST;
 
 619                                 /* Copy info for profiles 2,3,5. Other
 
 620                                  * profiles this area is reserved
 
 622         if (hbq_desc->profile == 2)
 
 623                 lpfc_build_hbq_profile2(hbqmb, hbq_desc);
 
 624         else if (hbq_desc->profile == 3)
 
 625                 lpfc_build_hbq_profile3(hbqmb, hbq_desc);
 
 626         else if (hbq_desc->profile == 5)
 
 627                 lpfc_build_hbq_profile5(hbqmb, hbq_desc);
 
 629         /* Return if no rctl / type masks for this HBQ */
 
 630         if (!hbq_desc->mask_count)
 
 633         /* Otherwise we setup specific rctl / type masks for this HBQ */
 
 634         for (i = 0; i < hbq_desc->mask_count; i++) {
 
 635                 hbqmb->hbqMasks[i].tmatch = hbq_desc->hbqMasks[i].tmatch;
 
 636                 hbqmb->hbqMasks[i].tmask  = hbq_desc->hbqMasks[i].tmask;
 
 637                 hbqmb->hbqMasks[i].rctlmatch = hbq_desc->hbqMasks[i].rctlmatch;
 
 638                 hbqmb->hbqMasks[i].rctlmask  = hbq_desc->hbqMasks[i].rctlmask;
 
 647 lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
 
 650         MAILBOX_t *mb = &pmb->mb;
 
 651         struct lpfc_sli *psli;
 
 652         struct lpfc_sli_ring *pring;
 
 654         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 656         mb->un.varCfgRing.ring = ring;
 
 657         mb->un.varCfgRing.maxOrigXchg = 0;
 
 658         mb->un.varCfgRing.maxRespXchg = 0;
 
 659         mb->un.varCfgRing.recvNotify = 1;
 
 662         pring = &psli->ring[ring];
 
 663         mb->un.varCfgRing.numMask = pring->num_mask;
 
 664         mb->mbxCommand = MBX_CONFIG_RING;
 
 665         mb->mbxOwner = OWN_HOST;
 
 667         /* Is this ring configured for a specific profile */
 
 668         if (pring->prt[0].profile) {
 
 669                 mb->un.varCfgRing.profile = pring->prt[0].profile;
 
 673         /* Otherwise we setup specific rctl / type masks for this ring */
 
 674         for (i = 0; i < pring->num_mask; i++) {
 
 675                 mb->un.varCfgRing.rrRegs[i].rval = pring->prt[i].rctl;
 
 676                 if (mb->un.varCfgRing.rrRegs[i].rval != FC_ELS_REQ)
 
 677                         mb->un.varCfgRing.rrRegs[i].rmask = 0xff;
 
 679                         mb->un.varCfgRing.rrRegs[i].rmask = 0xfe;
 
 680                 mb->un.varCfgRing.rrRegs[i].tval = pring->prt[i].type;
 
 681                 mb->un.varCfgRing.rrRegs[i].tmask = 0xff;
 
 688 lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 
 690         MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr;
 
 691         MAILBOX_t *mb = &pmb->mb;
 
 692         dma_addr_t pdma_addr;
 
 693         uint32_t bar_low, bar_high;
 
 699         memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
 
 700         mb->mbxCommand = MBX_CONFIG_PORT;
 
 701         mb->mbxOwner = OWN_HOST;
 
 703         mb->un.varCfgPort.pcbLen = sizeof(PCB_t);
 
 705         offset = (uint8_t *)&phba->slim2p->pcb - (uint8_t *)phba->slim2p;
 
 706         pdma_addr = phba->slim2p_mapping + offset;
 
 707         mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr);
 
 708         mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr);
 
 710         /* If HBA supports SLI=3 ask for it */
 
 712         if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) {
 
 713                 mb->un.varCfgPort.cerbm = 1; /* Request HBQs */
 
 714                 mb->un.varCfgPort.max_hbq = lpfc_sli_hbq_count();
 
 715                 if (phba->max_vpi && phba->cfg_enable_npiv &&
 
 716                     phba->vpd.sli3Feat.cmv) {
 
 717                         mb->un.varCfgPort.max_vpi = phba->max_vpi;
 
 718                         mb->un.varCfgPort.cmv = 1;
 
 719                         phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED;
 
 721                         mb->un.varCfgPort.max_vpi = phba->max_vpi = 0;
 
 724         mb->un.varCfgPort.sli_mode = phba->sli_rev;
 
 727         phba->slim2p->pcb.type = TYPE_NATIVE_SLI2;
 
 728         phba->slim2p->pcb.feature = FEATURE_INITIAL_SLI2;
 
 730         /* Setup Mailbox pointers */
 
 731         phba->slim2p->pcb.mailBoxSize = offsetof(MAILBOX_t, us) +
 
 732                 sizeof(struct sli2_desc);
 
 733         offset = (uint8_t *)&phba->slim2p->mbx - (uint8_t *)phba->slim2p;
 
 734         pdma_addr = phba->slim2p_mapping + offset;
 
 735         phba->slim2p->pcb.mbAddrHigh = putPaddrHigh(pdma_addr);
 
 736         phba->slim2p->pcb.mbAddrLow = putPaddrLow(pdma_addr);
 
 739          * Setup Host Group ring pointer.
 
 741          * For efficiency reasons, the ring get/put pointers can be
 
 742          * placed in adapter memory (SLIM) rather than in host memory.
 
 743          * This allows firmware to avoid PCI reads/writes when updating
 
 744          * and checking pointers.
 
 746          * The firmware recognizes the use of SLIM memory by comparing
 
 747          * the address of the get/put pointers structure with that of
 
 748          * the SLIM BAR (BAR0).
 
 750          * Caution: be sure to use the PCI config space value of BAR0/BAR1
 
 751          * (the hardware's view of the base address), not the OS's
 
 752          * value of pci_resource_start() as the OS value may be a cookie
 
 757         pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_0, &bar_low);
 
 758         pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_1, &bar_high);
 
 761          * Set up HGP - Port Memory
 
 763          * The port expects the host get/put pointers to reside in memory
 
 764          * following the "non-diagnostic" mode mailbox (32 words, 0x80 bytes)
 
 765          * area of SLIM.  In SLI-2 mode, there's an additional 16 reserved
 
 766          * words (0x40 bytes).  This area is not reserved if HBQs are
 
 767          * configured in SLI-3.
 
 769          * CR0Put    - SLI2(no HBQs) = 0xc0, With HBQs = 0x80
 
 779          *    If HBQs configured:
 
 784          *                         HBQ(M-1)Put Pointer 0xc0+(M-1)*4
 
 788         if (phba->sli_rev == 3) {
 
 789                 phba->host_gp = &mb_slim->us.s3.host[0];
 
 790                 phba->hbq_put = &mb_slim->us.s3.hbq_put[0];
 
 792                 phba->host_gp = &mb_slim->us.s2.host[0];
 
 793                 phba->hbq_put = NULL;
 
 796         /* mask off BAR0's flag bits 0 - 3 */
 
 797         phba->slim2p->pcb.hgpAddrLow = (bar_low & PCI_BASE_ADDRESS_MEM_MASK) +
 
 798                 (void __iomem *) phba->host_gp -
 
 799                 (void __iomem *)phba->MBslimaddr;
 
 800         if (bar_low & PCI_BASE_ADDRESS_MEM_TYPE_64)
 
 801                 phba->slim2p->pcb.hgpAddrHigh = bar_high;
 
 803                 phba->slim2p->pcb.hgpAddrHigh = 0;
 
 804         /* write HGP data to SLIM at the required longword offset */
 
 805         memset(&hgp, 0, sizeof(struct lpfc_hgp));
 
 807         for (i=0; i < phba->sli.num_rings; i++) {
 
 808                 lpfc_memcpy_to_slim(phba->host_gp + i, &hgp,
 
 809                                     sizeof(*phba->host_gp));
 
 812         /* Setup Port Group ring pointer */
 
 813         if (phba->sli_rev == 3)
 
 814                 pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s3_pgp.port -
 
 815                         (uint8_t *)phba->slim2p;
 
 817                 pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port -
 
 818                         (uint8_t *)phba->slim2p;
 
 820         pdma_addr = phba->slim2p_mapping + pgp_offset;
 
 821         phba->slim2p->pcb.pgpAddrHigh = putPaddrHigh(pdma_addr);
 
 822         phba->slim2p->pcb.pgpAddrLow = putPaddrLow(pdma_addr);
 
 823         phba->hbq_get = &phba->slim2p->mbx.us.s3_pgp.hbq_get[0];
 
 825         /* Use callback routine to setp rings in the pcb */
 
 826         lpfc_config_pcb_setup(phba);
 
 828         /* special handling for LC HBAs */
 
 829         if (lpfc_is_LC_HBA(phba->pcidev->device)) {
 
 832                 lpfc_hba_init(phba, hbainit);
 
 834                 memcpy(&mb->un.varCfgPort.hbainit, hbainit, 20);
 
 837         /* Swap PCB if needed */
 
 838         lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb,
 
 843 lpfc_kill_board(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 845         MAILBOX_t *mb = &pmb->mb;
 
 847         memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
 
 848         mb->mbxCommand = MBX_KILL_BOARD;
 
 849         mb->mbxOwner = OWN_HOST;
 
 854 lpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
 
 856         struct lpfc_sli *psli;
 
 860         list_add_tail(&mbq->list, &psli->mboxq);
 
 868 lpfc_mbox_get(struct lpfc_hba * phba)
 
 870         LPFC_MBOXQ_t *mbq = NULL;
 
 871         struct lpfc_sli *psli = &phba->sli;
 
 873         list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, list);
 
 881 lpfc_mbox_cmpl_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
 
 883         /* This function expects to be called from interupt context */
 
 884         spin_lock(&phba->hbalock);
 
 885         list_add_tail(&mbq->list, &phba->sli.mboxq_cmpl);
 
 886         spin_unlock(&phba->hbalock);
 
 891 lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd)
 
 894         case MBX_WRITE_NV:      /* 0x03 */
 
 895         case MBX_UPDATE_CFG:    /* 0x1B */
 
 896         case MBX_DOWN_LOAD:     /* 0x1C */
 
 897         case MBX_DEL_LD_ENTRY:  /* 0x1D */
 
 898         case MBX_LOAD_AREA:     /* 0x81 */
 
 899         case MBX_WRITE_WWN:     /* 0x98 */
 
 900         case MBX_LOAD_EXP_ROM:  /* 0x9C */
 
 901                 return LPFC_MBOX_TMO_FLASH_CMD;
 
 903         return LPFC_MBOX_TMO;