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_heart_beat  Issue a HEART_BEAT       */
 
  87 /**********************************************/
 
  89 lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
  94         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
  95         mb->mbxCommand = MBX_HEARTBEAT;
 
  96         mb->mbxOwner = OWN_HOST;
 
 100 /**********************************************/
 
 101 /*  lpfc_read_la  Issue a READ LA             */
 
 102 /*                mailbox command             */
 
 103 /**********************************************/
 
 105 lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp)
 
 108         struct lpfc_sli *psli;
 
 112         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 114         INIT_LIST_HEAD(&mp->list);
 
 115         mb->mbxCommand = MBX_READ_LA64;
 
 116         mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128;
 
 117         mb->un.varReadLA.un.lilpBde64.addrHigh = putPaddrHigh(mp->phys);
 
 118         mb->un.varReadLA.un.lilpBde64.addrLow = putPaddrLow(mp->phys);
 
 120         /* Save address for later completion and set the owner to host so that
 
 121          * the FW knows this mailbox is available for processing.
 
 123         pmb->context1 = (uint8_t *) mp;
 
 124         mb->mbxOwner = OWN_HOST;
 
 128 /**********************************************/
 
 129 /*  lpfc_clear_la  Issue a CLEAR LA           */
 
 130 /*                 mailbox command            */
 
 131 /**********************************************/
 
 133 lpfc_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 138         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 140         mb->un.varClearLA.eventTag = phba->fc_eventTag;
 
 141         mb->mbxCommand = MBX_CLEAR_LA;
 
 142         mb->mbxOwner = OWN_HOST;
 
 146 /**************************************************/
 
 147 /*  lpfc_config_link  Issue a CONFIG LINK         */
 
 148 /*                    mailbox command             */
 
 149 /**************************************************/
 
 151 lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 153         struct lpfc_vport  *vport = phba->pport;
 
 154         MAILBOX_t *mb = &pmb->mb;
 
 155         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 158          * SLI-2, Coalescing Response Feature.
 
 160         if (phba->cfg_cr_delay) {
 
 161                 mb->un.varCfgLnk.cr = 1;
 
 162                 mb->un.varCfgLnk.ci = 1;
 
 163                 mb->un.varCfgLnk.cr_delay = phba->cfg_cr_delay;
 
 164                 mb->un.varCfgLnk.cr_count = phba->cfg_cr_count;
 
 167         mb->un.varCfgLnk.myId = vport->fc_myDID;
 
 168         mb->un.varCfgLnk.edtov = phba->fc_edtov;
 
 169         mb->un.varCfgLnk.arbtov = phba->fc_arbtov;
 
 170         mb->un.varCfgLnk.ratov = phba->fc_ratov;
 
 171         mb->un.varCfgLnk.rttov = phba->fc_rttov;
 
 172         mb->un.varCfgLnk.altov = phba->fc_altov;
 
 173         mb->un.varCfgLnk.crtov = phba->fc_crtov;
 
 174         mb->un.varCfgLnk.citov = phba->fc_citov;
 
 177                 mb->un.varCfgLnk.ack0_enable = 1;
 
 179         mb->mbxCommand = MBX_CONFIG_LINK;
 
 180         mb->mbxOwner = OWN_HOST;
 
 184 /**********************************************/
 
 185 /*  lpfc_init_link  Issue an INIT LINK        */
 
 186 /*                  mailbox command           */
 
 187 /**********************************************/
 
 189 lpfc_init_link(struct lpfc_hba * phba,
 
 190                LPFC_MBOXQ_t * pmb, uint32_t topology, uint32_t linkspeed)
 
 193         struct lpfc_sli *psli;
 
 197         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 201         case FLAGS_TOPOLOGY_MODE_LOOP_PT:
 
 202                 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
 
 203                 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
 
 205         case FLAGS_TOPOLOGY_MODE_PT_PT:
 
 206                 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
 
 208         case FLAGS_TOPOLOGY_MODE_LOOP:
 
 209                 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
 
 211         case FLAGS_TOPOLOGY_MODE_PT_LOOP:
 
 212                 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
 
 213                 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
 
 216                 mb->un.varInitLnk.link_flags = FLAGS_LOCAL_LB;
 
 220         /* Enable asynchronous ABTS responses from firmware */
 
 221         mb->un.varInitLnk.link_flags |= FLAGS_IMED_ABORT;
 
 224          * Setting up the link speed
 
 227         if (vpd->rev.feaLevelHigh >= 0x02){
 
 233                                 mb->un.varInitLnk.link_flags |=
 
 235                                 mb->un.varInitLnk.link_speed = linkspeed;
 
 237                         case LINK_SPEED_AUTO:
 
 239                                 mb->un.varInitLnk.link_speed =
 
 246                 mb->un.varInitLnk.link_speed = LINK_SPEED_AUTO;
 
 248         mb->mbxCommand = (volatile uint8_t)MBX_INIT_LINK;
 
 249         mb->mbxOwner = OWN_HOST;
 
 250         mb->un.varInitLnk.fabric_AL_PA = phba->fc_pref_ALPA;
 
 254 /**********************************************/
 
 255 /*  lpfc_read_sparam  Issue a READ SPARAM     */
 
 256 /*                    mailbox command         */
 
 257 /**********************************************/
 
 259 lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi)
 
 261         struct lpfc_dmabuf *mp;
 
 263         struct lpfc_sli *psli;
 
 267         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 269         mb->mbxOwner = OWN_HOST;
 
 271         /* Get a buffer to hold the HBAs Service Parameters */
 
 273         if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == 0) ||
 
 274             ((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) {
 
 276                 mb->mbxCommand = MBX_READ_SPARM64;
 
 277                 /* READ_SPARAM: no buffers */
 
 278                 lpfc_printf_log(phba,
 
 281                                 "%d:0301 READ_SPARAM: no buffers\n",
 
 285         INIT_LIST_HEAD(&mp->list);
 
 286         mb->mbxCommand = MBX_READ_SPARM64;
 
 287         mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
 
 288         mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys);
 
 289         mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys);
 
 290         mb->un.varRdSparm.vpi = vpi;
 
 292         /* save address for completion */
 
 298 /********************************************/
 
 299 /*  lpfc_unreg_did  Issue a UNREG_DID       */
 
 300 /*                  mailbox command         */
 
 301 /********************************************/
 
 303 lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did,
 
 309         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 311         mb->un.varUnregDID.did = did;
 
 312         mb->un.varUnregDID.vpi = vpi;
 
 314         mb->mbxCommand = MBX_UNREG_D_ID;
 
 315         mb->mbxOwner = OWN_HOST;
 
 319 /**********************************************/
 
 320 /*  lpfc_read_nv  Issue a READ CONFIG         */
 
 321 /*                mailbox command             */
 
 322 /**********************************************/
 
 324 lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 329         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 331         mb->mbxCommand = MBX_READ_CONFIG;
 
 332         mb->mbxOwner = OWN_HOST;
 
 336 /*************************************************/
 
 337 /*  lpfc_read_lnk_stat  Issue a READ LINK STATUS */
 
 338 /*                mailbox command                */
 
 339 /*************************************************/
 
 341 lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 346         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 348         mb->mbxCommand = MBX_READ_LNK_STAT;
 
 349         mb->mbxOwner = OWN_HOST;
 
 353 /********************************************/
 
 354 /*  lpfc_reg_login  Issue a REG_LOGIN       */
 
 355 /*                  mailbox command         */
 
 356 /********************************************/
 
 358 lpfc_reg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
 
 359                uint8_t *param, LPFC_MBOXQ_t *pmb, uint32_t flag)
 
 361         MAILBOX_t *mb = &pmb->mb;
 
 363         struct lpfc_dmabuf *mp;
 
 365         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 367         mb->un.varRegLogin.rpi = 0;
 
 368         mb->un.varRegLogin.vpi = vpi;
 
 369         mb->un.varRegLogin.did = did;
 
 370         mb->un.varWords[30] = flag;     /* Set flag to issue action on cmpl */
 
 372         mb->mbxOwner = OWN_HOST;
 
 374         /* Get a buffer to hold NPorts Service Parameters */
 
 375         if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == NULL) ||
 
 376             ((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) {
 
 378                 mb->mbxCommand = MBX_REG_LOGIN64;
 
 379                 /* REG_LOGIN: no buffers */
 
 380                 lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
 
 381                                 "%d (%d):0302 REG_LOGIN: no buffers, DID x%x, "
 
 383                                 phba->brd_no, vpi, did, flag);
 
 386         INIT_LIST_HEAD(&mp->list);
 
 389         /* Copy param's into a new buffer */
 
 390         memcpy(sparam, param, sizeof (struct serv_parm));
 
 392         /* save address for completion */
 
 393         pmb->context1 = (uint8_t *) mp;
 
 395         mb->mbxCommand = MBX_REG_LOGIN64;
 
 396         mb->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
 
 397         mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys);
 
 398         mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys);
 
 403 /**********************************************/
 
 404 /*  lpfc_unreg_login  Issue a UNREG_LOGIN     */
 
 405 /*                    mailbox command         */
 
 406 /**********************************************/
 
 408 lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
 
 414         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 416         mb->un.varUnregLogin.rpi = (uint16_t) rpi;
 
 417         mb->un.varUnregLogin.rsvd1 = 0;
 
 418         mb->un.varUnregLogin.vpi = vpi;
 
 420         mb->mbxCommand = MBX_UNREG_LOGIN;
 
 421         mb->mbxOwner = OWN_HOST;
 
 425 /**************************************************/
 
 426 /*  lpfc_reg_vpi   Issue a REG_VPI                */
 
 427 /*                    mailbox command             */
 
 428 /**************************************************/
 
 430 lpfc_reg_vpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t sid,
 
 433         MAILBOX_t *mb = &pmb->mb;
 
 435         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 437         mb->un.varRegVpi.vpi = vpi;
 
 438         mb->un.varRegVpi.sid = sid;
 
 440         mb->mbxCommand = MBX_REG_VPI;
 
 441         mb->mbxOwner = OWN_HOST;
 
 446 /**************************************************/
 
 447 /*  lpfc_unreg_vpi   Issue a UNREG_VNPI           */
 
 448 /*                    mailbox command             */
 
 449 /**************************************************/
 
 451 lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb)
 
 453         MAILBOX_t *mb = &pmb->mb;
 
 454         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 456         mb->un.varUnregVpi.vpi = vpi;
 
 458         mb->mbxCommand = MBX_UNREG_VPI;
 
 459         mb->mbxOwner = OWN_HOST;
 
 465 lpfc_config_pcb_setup(struct lpfc_hba * phba)
 
 467         struct lpfc_sli *psli = &phba->sli;
 
 468         struct lpfc_sli_ring *pring;
 
 469         PCB_t *pcbp = &phba->slim2p->pcb;
 
 470         dma_addr_t pdma_addr;
 
 472         uint32_t iocbCnt = 0;
 
 475         pcbp->maxRing = (psli->num_rings - 1);
 
 477         for (i = 0; i < psli->num_rings; i++) {
 
 478                 pring = &psli->ring[i];
 
 480                 pring->sizeCiocb = phba->sli_rev == 3 ? SLI3_IOCB_CMD_SIZE:
 
 482                 pring->sizeRiocb = phba->sli_rev == 3 ? SLI3_IOCB_RSP_SIZE:
 
 484                 /* A ring MUST have both cmd and rsp entries defined to be
 
 486                 if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) {
 
 487                         pcbp->rdsc[i].cmdEntries = 0;
 
 488                         pcbp->rdsc[i].rspEntries = 0;
 
 489                         pcbp->rdsc[i].cmdAddrHigh = 0;
 
 490                         pcbp->rdsc[i].rspAddrHigh = 0;
 
 491                         pcbp->rdsc[i].cmdAddrLow = 0;
 
 492                         pcbp->rdsc[i].rspAddrLow = 0;
 
 493                         pring->cmdringaddr = NULL;
 
 494                         pring->rspringaddr = NULL;
 
 497                 /* Command ring setup for ring */
 
 498                 pring->cmdringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt];
 
 499                 pcbp->rdsc[i].cmdEntries = pring->numCiocb;
 
 501                 offset = (uint8_t *) &phba->slim2p->IOCBs[iocbCnt] -
 
 502                          (uint8_t *) phba->slim2p;
 
 503                 pdma_addr = phba->slim2p_mapping + offset;
 
 504                 pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr);
 
 505                 pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr);
 
 506                 iocbCnt += pring->numCiocb;
 
 508                 /* Response ring setup for ring */
 
 509                 pring->rspringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt];
 
 511                 pcbp->rdsc[i].rspEntries = pring->numRiocb;
 
 512                 offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] -
 
 513                          (uint8_t *)phba->slim2p;
 
 514                 pdma_addr = phba->slim2p_mapping + offset;
 
 515                 pcbp->rdsc[i].rspAddrHigh = putPaddrHigh(pdma_addr);
 
 516                 pcbp->rdsc[i].rspAddrLow = putPaddrLow(pdma_addr);
 
 517                 iocbCnt += pring->numRiocb;
 
 522 lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 524         MAILBOX_t *mb = &pmb->mb;
 
 525         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 526         mb->un.varRdRev.cv = 1;
 
 527         mb->un.varRdRev.v3req = 1; /* Request SLI3 info */
 
 528         mb->mbxCommand = MBX_READ_REV;
 
 529         mb->mbxOwner = OWN_HOST;
 
 534 lpfc_build_hbq_profile2(struct config_hbq_var *hbqmb,
 
 535                         struct lpfc_hbq_init  *hbq_desc)
 
 537         hbqmb->profiles.profile2.seqlenbcnt = hbq_desc->seqlenbcnt;
 
 538         hbqmb->profiles.profile2.maxlen     = hbq_desc->maxlen;
 
 539         hbqmb->profiles.profile2.seqlenoff  = hbq_desc->seqlenoff;
 
 543 lpfc_build_hbq_profile3(struct config_hbq_var *hbqmb,
 
 544                         struct lpfc_hbq_init  *hbq_desc)
 
 546         hbqmb->profiles.profile3.seqlenbcnt = hbq_desc->seqlenbcnt;
 
 547         hbqmb->profiles.profile3.maxlen     = hbq_desc->maxlen;
 
 548         hbqmb->profiles.profile3.cmdcodeoff = hbq_desc->cmdcodeoff;
 
 549         hbqmb->profiles.profile3.seqlenoff  = hbq_desc->seqlenoff;
 
 550         memcpy(&hbqmb->profiles.profile3.cmdmatch, hbq_desc->cmdmatch,
 
 551                sizeof(hbqmb->profiles.profile3.cmdmatch));
 
 555 lpfc_build_hbq_profile5(struct config_hbq_var *hbqmb,
 
 556                         struct lpfc_hbq_init  *hbq_desc)
 
 558         hbqmb->profiles.profile5.seqlenbcnt = hbq_desc->seqlenbcnt;
 
 559         hbqmb->profiles.profile5.maxlen     = hbq_desc->maxlen;
 
 560         hbqmb->profiles.profile5.cmdcodeoff = hbq_desc->cmdcodeoff;
 
 561         hbqmb->profiles.profile5.seqlenoff  = hbq_desc->seqlenoff;
 
 562         memcpy(&hbqmb->profiles.profile5.cmdmatch, hbq_desc->cmdmatch,
 
 563                sizeof(hbqmb->profiles.profile5.cmdmatch));
 
 567 lpfc_config_hbq(struct lpfc_hba *phba, struct lpfc_hbq_init *hbq_desc,
 
 568                 uint32_t hbq_entry_index, LPFC_MBOXQ_t *pmb)
 
 571         MAILBOX_t *mb = &pmb->mb;
 
 572         struct config_hbq_var *hbqmb = &mb->un.varCfgHbq;
 
 574         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 575         hbqmb->entry_count = hbq_desc->entry_count;   /* # entries in HBQ */
 
 576         hbqmb->recvNotify = hbq_desc->rn;             /* Receive
 
 578         hbqmb->numMask    = hbq_desc->mask_count;     /* # R_CTL/TYPE masks
 
 580         hbqmb->profile    = hbq_desc->profile;        /* Selection profile:
 
 583         hbqmb->ringMask   = hbq_desc->ring_mask;      /* Binds HBQ to a ring
 
 586         hbqmb->headerLen  = hbq_desc->headerLen;      /* 0 if not profile 4
 
 588         hbqmb->logEntry   = hbq_desc->logEntry;       /* Set to 1 if this
 
 592         hbqmb->hbqaddrLow = putPaddrLow(phba->hbqslimp.phys) +
 
 593                 hbq_entry_index * sizeof(struct lpfc_hbq_entry);
 
 594         hbqmb->hbqaddrHigh = putPaddrHigh(phba->hbqslimp.phys);
 
 596         mb->mbxCommand = MBX_CONFIG_HBQ;
 
 597         mb->mbxOwner = OWN_HOST;
 
 599                                 /* Copy info for profiles 2,3,5. Other
 
 600                                  * profiles this area is reserved
 
 602         if (hbq_desc->profile == 2)
 
 603                 lpfc_build_hbq_profile2(hbqmb, hbq_desc);
 
 604         else if (hbq_desc->profile == 3)
 
 605                 lpfc_build_hbq_profile3(hbqmb, hbq_desc);
 
 606         else if (hbq_desc->profile == 5)
 
 607                 lpfc_build_hbq_profile5(hbqmb, hbq_desc);
 
 609         /* Return if no rctl / type masks for this HBQ */
 
 610         if (!hbq_desc->mask_count)
 
 613         /* Otherwise we setup specific rctl / type masks for this HBQ */
 
 614         for (i = 0; i < hbq_desc->mask_count; i++) {
 
 615                 hbqmb->hbqMasks[i].tmatch = hbq_desc->hbqMasks[i].tmatch;
 
 616                 hbqmb->hbqMasks[i].tmask  = hbq_desc->hbqMasks[i].tmask;
 
 617                 hbqmb->hbqMasks[i].rctlmatch = hbq_desc->hbqMasks[i].rctlmatch;
 
 618                 hbqmb->hbqMasks[i].rctlmask  = hbq_desc->hbqMasks[i].rctlmask;
 
 627 lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
 
 630         MAILBOX_t *mb = &pmb->mb;
 
 631         struct lpfc_sli *psli;
 
 632         struct lpfc_sli_ring *pring;
 
 634         memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 636         mb->un.varCfgRing.ring = ring;
 
 637         mb->un.varCfgRing.maxOrigXchg = 0;
 
 638         mb->un.varCfgRing.maxRespXchg = 0;
 
 639         mb->un.varCfgRing.recvNotify = 1;
 
 642         pring = &psli->ring[ring];
 
 643         mb->un.varCfgRing.numMask = pring->num_mask;
 
 644         mb->mbxCommand = MBX_CONFIG_RING;
 
 645         mb->mbxOwner = OWN_HOST;
 
 647         /* Is this ring configured for a specific profile */
 
 648         if (pring->prt[0].profile) {
 
 649                 mb->un.varCfgRing.profile = pring->prt[0].profile;
 
 653         /* Otherwise we setup specific rctl / type masks for this ring */
 
 654         for (i = 0; i < pring->num_mask; i++) {
 
 655                 mb->un.varCfgRing.rrRegs[i].rval = pring->prt[i].rctl;
 
 656                 if (mb->un.varCfgRing.rrRegs[i].rval != FC_ELS_REQ)
 
 657                         mb->un.varCfgRing.rrRegs[i].rmask = 0xff;
 
 659                         mb->un.varCfgRing.rrRegs[i].rmask = 0xfe;
 
 660                 mb->un.varCfgRing.rrRegs[i].tval = pring->prt[i].type;
 
 661                 mb->un.varCfgRing.rrRegs[i].tmask = 0xff;
 
 668 lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 
 670         MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr;
 
 671         MAILBOX_t *mb = &pmb->mb;
 
 672         dma_addr_t pdma_addr;
 
 673         uint32_t bar_low, bar_high;
 
 679         memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
 
 680         mb->mbxCommand = MBX_CONFIG_PORT;
 
 681         mb->mbxOwner = OWN_HOST;
 
 683         mb->un.varCfgPort.pcbLen = sizeof(PCB_t);
 
 685         offset = (uint8_t *)&phba->slim2p->pcb - (uint8_t *)phba->slim2p;
 
 686         pdma_addr = phba->slim2p_mapping + offset;
 
 687         mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr);
 
 688         mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr);
 
 690         /* If HBA supports SLI=3 ask for it */
 
 692         if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) {
 
 693                 mb->un.varCfgPort.cerbm = 1; /* Request HBQs */
 
 694                 mb->un.varCfgPort.max_hbq = 1; /* Requesting 2 HBQs */
 
 695                 if (phba->max_vpi && phba->cfg_npiv_enable &&
 
 696                     phba->vpd.sli3Feat.cmv) {
 
 697                         mb->un.varCfgPort.max_vpi = phba->max_vpi;
 
 698                         mb->un.varCfgPort.cmv = 1;
 
 699                         phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED;
 
 701                         mb->un.varCfgPort.max_vpi = phba->max_vpi = 0;
 
 704         mb->un.varCfgPort.sli_mode = phba->sli_rev;
 
 707         phba->slim2p->pcb.type = TYPE_NATIVE_SLI2;
 
 708         phba->slim2p->pcb.feature = FEATURE_INITIAL_SLI2;
 
 710         /* Setup Mailbox pointers */
 
 711         phba->slim2p->pcb.mailBoxSize = offsetof(MAILBOX_t, us) +
 
 712                 sizeof(struct sli2_desc);
 
 713         offset = (uint8_t *)&phba->slim2p->mbx - (uint8_t *)phba->slim2p;
 
 714         pdma_addr = phba->slim2p_mapping + offset;
 
 715         phba->slim2p->pcb.mbAddrHigh = putPaddrHigh(pdma_addr);
 
 716         phba->slim2p->pcb.mbAddrLow = putPaddrLow(pdma_addr);
 
 719          * Setup Host Group ring pointer.
 
 721          * For efficiency reasons, the ring get/put pointers can be
 
 722          * placed in adapter memory (SLIM) rather than in host memory.
 
 723          * This allows firmware to avoid PCI reads/writes when updating
 
 724          * and checking pointers.
 
 726          * The firmware recognizes the use of SLIM memory by comparing
 
 727          * the address of the get/put pointers structure with that of
 
 728          * the SLIM BAR (BAR0).
 
 730          * Caution: be sure to use the PCI config space value of BAR0/BAR1
 
 731          * (the hardware's view of the base address), not the OS's
 
 732          * value of pci_resource_start() as the OS value may be a cookie
 
 737         pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_0, &bar_low);
 
 738         pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_1, &bar_high);
 
 741          * Set up HGP - Port Memory
 
 743          * The port expects the host get/put pointers to reside in memory
 
 744          * following the "non-diagnostic" mode mailbox (32 words, 0x80 bytes)
 
 745          * area of SLIM.  In SLI-2 mode, there's an additional 16 reserved
 
 746          * words (0x40 bytes).  This area is not reserved if HBQs are
 
 747          * configured in SLI-3.
 
 749          * CR0Put    - SLI2(no HBQs) = 0xc0, With HBQs = 0x80
 
 759          *    If HBQs configured:
 
 764          *                         HBQ(M-1)Put Pointer 0xc0+(M-1)*4
 
 768         if (phba->sli_rev == 3) {
 
 769                 phba->host_gp = &mb_slim->us.s3.host[0];
 
 770                 phba->hbq_put = &mb_slim->us.s3.hbq_put[0];
 
 772                 phba->host_gp = &mb_slim->us.s2.host[0];
 
 773                 phba->hbq_put = NULL;
 
 776         /* mask off BAR0's flag bits 0 - 3 */
 
 777         phba->slim2p->pcb.hgpAddrLow = (bar_low & PCI_BASE_ADDRESS_MEM_MASK) +
 
 778                 (void __iomem *) phba->host_gp -
 
 779                 (void __iomem *)phba->MBslimaddr;
 
 780         if (bar_low & PCI_BASE_ADDRESS_MEM_TYPE_64)
 
 781                 phba->slim2p->pcb.hgpAddrHigh = bar_high;
 
 783                 phba->slim2p->pcb.hgpAddrHigh = 0;
 
 784         /* write HGP data to SLIM at the required longword offset */
 
 785         memset(&hgp, 0, sizeof(struct lpfc_hgp));
 
 787         for (i=0; i < phba->sli.num_rings; i++) {
 
 788                 lpfc_memcpy_to_slim(phba->host_gp + i, &hgp,
 
 789                                     sizeof(*phba->host_gp));
 
 792         /* Setup Port Group ring pointer */
 
 793         if (phba->sli_rev == 3)
 
 794                 pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s3_pgp.port -
 
 795                         (uint8_t *)phba->slim2p;
 
 797                 pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port -
 
 798                         (uint8_t *)phba->slim2p;
 
 800         pdma_addr = phba->slim2p_mapping + pgp_offset;
 
 801         phba->slim2p->pcb.pgpAddrHigh = putPaddrHigh(pdma_addr);
 
 802         phba->slim2p->pcb.pgpAddrLow = putPaddrLow(pdma_addr);
 
 803         phba->hbq_get = &phba->slim2p->mbx.us.s3_pgp.hbq_get[0];
 
 805         /* Use callback routine to setp rings in the pcb */
 
 806         lpfc_config_pcb_setup(phba);
 
 808         /* special handling for LC HBAs */
 
 809         if (lpfc_is_LC_HBA(phba->pcidev->device)) {
 
 812                 lpfc_hba_init(phba, hbainit);
 
 814                 memcpy(&mb->un.varCfgPort.hbainit, hbainit, 20);
 
 817         /* Swap PCB if needed */
 
 818         lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb,
 
 823 lpfc_kill_board(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
 825         MAILBOX_t *mb = &pmb->mb;
 
 827         memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
 
 828         mb->mbxCommand = MBX_KILL_BOARD;
 
 829         mb->mbxOwner = OWN_HOST;
 
 834 lpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
 
 836         struct lpfc_sli *psli;
 
 840         list_add_tail(&mbq->list, &psli->mboxq);
 
 848 lpfc_mbox_get(struct lpfc_hba * phba)
 
 850         LPFC_MBOXQ_t *mbq = NULL;
 
 851         struct lpfc_sli *psli = &phba->sli;
 
 853         list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, list);
 
 861 lpfc_mbox_cmpl_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
 
 863         /* This function expects to be called from interupt context */
 
 864         spin_lock(&phba->hbalock);
 
 865         list_add_tail(&mbq->list, &phba->sli.mboxq_cmpl);
 
 866         spin_unlock(&phba->hbalock);
 
 871 lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd)
 
 874         case MBX_WRITE_NV:      /* 0x03 */
 
 875         case MBX_UPDATE_CFG:    /* 0x1B */
 
 876         case MBX_DOWN_LOAD:     /* 0x1C */
 
 877         case MBX_DEL_LD_ENTRY:  /* 0x1D */
 
 878         case MBX_LOAD_AREA:     /* 0x81 */
 
 879         case MBX_FLASH_WR_ULA:  /* 0x98 */
 
 880         case MBX_LOAD_EXP_ROM:  /* 0x9C */
 
 881                 return LPFC_MBOX_TMO_FLASH_CMD;
 
 883         return LPFC_MBOX_TMO;