Print this page
MFV: illumos-omnios@aea0472ecb9ee91fa70556d6f6a941c10c989f1d
Add support for Emulex Corporation Lancer Gen6: LPe32000 FC Host Adapter
Author: Andy Fiddaman <omnios@citrus-it.co.uk>
NEX-8705 Drivers for ATTO Celerity FC-162E Gen 5 and Celerity FC-162P Gen 6 16GB FC cards support
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-1878 update emlxs from source provided by Emulex

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli4.c
          +++ new/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli4.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2004-2012 Emulex. All rights reserved.
  24   24   * Use is subject to license terms.
       25 + * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  25   26   */
  26   27  
  27   28  #include <emlxs.h>
  28   29  
  29   30  
  30   31  /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
  31   32  EMLXS_MSG_DEF(EMLXS_SLI4_C);
  32   33  
  33   34  static int              emlxs_sli4_init_extents(emlxs_hba_t *hba,
  34   35                                  MAILBOXQ *mbq);
↓ open down ↓ 79 lines elided ↑ open up ↑
 114  115                                  emlxs_buf_t *sbp, RPIobj_t *rpip,
 115  116                                  uint32_t type);
 116  117  static void             emlxs_sli4_enable_intr(emlxs_hba_t *hba);
 117  118  
 118  119  static void             emlxs_sli4_disable_intr(emlxs_hba_t *hba, uint32_t att);
 119  120  
 120  121  static void             emlxs_sli4_timer(emlxs_hba_t *hba);
 121  122  
 122  123  static void             emlxs_sli4_timer_check_mbox(emlxs_hba_t *hba);
 123  124  
      125 +static void             emlxs_sli4_gpio_timer_start(emlxs_hba_t *hba);
      126 +
      127 +static void             emlxs_sli4_gpio_timer_stop(emlxs_hba_t *hba);
      128 +
      129 +static void             emlxs_sli4_gpio_timer(void *arg);
      130 +
      131 +static void             emlxs_sli4_check_gpio(emlxs_hba_t *hba);
      132 +
      133 +static uint32_t emlxs_sli4_fix_gpio(emlxs_hba_t *hba,
      134 +                                        uint8_t *pin, uint8_t *pinval);
      135 +
      136 +static uint32_t emlxs_sli4_fix_gpio_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq);
      137 +
 124  138  static void             emlxs_sli4_poll_erratt(emlxs_hba_t *hba);
 125  139  
 126      -extern XRIobj_t         *emlxs_sli4_reserve_xri(emlxs_port_t *port,
      140 +extern XRIobj_t         *emlxs_sli4_reserve_xri(emlxs_port_t *port,
 127  141                                  RPIobj_t *rpip, uint32_t type, uint16_t rx_id);
 128  142  static int              emlxs_check_hdw_ready(emlxs_hba_t *);
 129  143  
 130  144  static uint32_t         emlxs_sli4_reg_did(emlxs_port_t *port,
 131  145                                  uint32_t did, SERV_PARM *param,
 132  146                                  emlxs_buf_t *sbp, fc_unsol_buf_t *ubp,
 133  147                                  IOCBQ *iocbq);
 134  148  
 135  149  static uint32_t         emlxs_sli4_unreg_node(emlxs_port_t *port,
 136  150                                  emlxs_node_t *node, emlxs_buf_t *sbp,
↓ open down ↓ 188 lines elided ↑ open up ↑
 325  339          hba->chan_count = hba->intr_count * cfg[CFG_NUM_WQ].current;
 326  340          if (hba->chan_count > MAX_CHANNEL) {
 327  341                  EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
 328  342                      "Max channels exceeded, dropping num-wq from %d to 1",
 329  343                      cfg[CFG_NUM_WQ].current);
 330  344                  cfg[CFG_NUM_WQ].current = 1;
 331  345                  hba->chan_count = hba->intr_count * cfg[CFG_NUM_WQ].current;
 332  346          }
 333  347          hba->channel_fcp = 0; /* First channel */
 334  348  
      349 +        /* Gen6 chips only support P2P topologies */
      350 +        if ((hba->model_info.flags & EMLXS_FC_GEN6) &&
      351 +            cfg[CFG_TOPOLOGY].current != 2) {
      352 +                EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg,
      353 +                    "Loop topologies are not supported by this HBA. "
      354 +                    "Forcing topology to P2P.");
      355 +                cfg[CFG_TOPOLOGY].current = 2;
      356 +        }
      357 +
 335  358          /* Default channel for everything else is the last channel */
 336  359          hba->channel_ip = hba->chan_count - 1;
 337  360          hba->channel_els = hba->chan_count - 1;
 338  361          hba->channel_ct = hba->chan_count - 1;
 339  362  
 340  363          hba->fc_iotag = 1;
 341  364          hba->io_count = 0;
 342  365          hba->channel_tx_count = 0;
 343  366  
      367 +        /* Specific to ATTO G5 boards */
      368 +        if (hba->model_info.flags & EMLXS_GPIO_LEDS) {
      369 +                /* Set hard-coded GPIO pins */
      370 +                if (hba->pci_function_number) {
      371 +                        hba->gpio_pin[EMLXS_GPIO_PIN_LO] = 27;
      372 +                        hba->gpio_pin[EMLXS_GPIO_PIN_HI] = 28;
      373 +                        hba->gpio_pin[EMLXS_GPIO_PIN_ACT] = 29;
      374 +                        hba->gpio_pin[EMLXS_GPIO_PIN_LASER] = 8;
      375 +                } else {
      376 +                        hba->gpio_pin[EMLXS_GPIO_PIN_LO] = 13;
      377 +                        hba->gpio_pin[EMLXS_GPIO_PIN_HI] = 25;
      378 +                        hba->gpio_pin[EMLXS_GPIO_PIN_ACT] = 26;
      379 +                        hba->gpio_pin[EMLXS_GPIO_PIN_LASER] = 12;
      380 +                }
      381 +        }
      382 +
 344  383          /* Initialize the local dump region buffer */
 345  384          bzero(&hba->sli.sli4.dump_region, sizeof (MBUF_INFO));
 346  385          hba->sli.sli4.dump_region.size = EMLXS_DUMP_REGION_SIZE;
 347  386          hba->sli.sli4.dump_region.flags = FC_MBUF_DMA | FC_MBUF_SNGLSG
 348  387              | FC_MBUF_DMA32;
 349  388          hba->sli.sli4.dump_region.align = ddi_ptob(hba->dip, 1L);
 350  389  
 351  390          (void) emlxs_mem_alloc(hba, &hba->sli.sli4.dump_region);
 352  391  
 353  392          if (hba->sli.sli4.dump_region.virt == NULL) {
↓ open down ↓ 968 lines elided ↑ open up ↑
1322 1361                  (void) strncpy(vpd->model, hba->model_info.model,
1323 1362                      (sizeof (vpd->model)-1));
1324 1363          }
1325 1364  
1326 1365          if (vpd->prog_types[0] == 0) {
1327 1366                  emlxs_build_prog_types(hba, vpd);
1328 1367          }
1329 1368  
1330 1369          /* Create the symbolic names */
1331 1370          (void) snprintf(hba->snn, (sizeof (hba->snn)-1),
1332      -            "Emulex %s FV%s DV%s %s",
1333      -            hba->model_info.model, hba->vpd.fw_version, emlxs_version,
     1371 +            "%s %s FV%s DV%s %s",
     1372 +            hba->model_info.manufacturer, hba->model_info.model,
     1373 +            hba->vpd.fw_version, emlxs_version,
1334 1374              (char *)utsname.nodename);
1335 1375  
1336 1376          (void) snprintf(hba->spn, (sizeof (hba->spn)-1),
1337      -            "Emulex PPN-%01x%01x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
     1377 +            "%s PPN-%01x%01x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
     1378 +            hba->model_info.manufacturer,
1338 1379              hba->wwpn.nameType, hba->wwpn.IEEEextMsn, hba->wwpn.IEEEextLsb,
1339 1380              hba->wwpn.IEEE[0], hba->wwpn.IEEE[1], hba->wwpn.IEEE[2],
1340 1381              hba->wwpn.IEEE[3], hba->wwpn.IEEE[4], hba->wwpn.IEEE[5]);
1341 1382  
1342 1383  
1343 1384          EMLXS_STATE_CHANGE(hba, FC_LINK_DOWN);
1344 1385          emlxs_sli4_enable_intr(hba);
1345 1386  
1346 1387          /* Check persist-linkdown */
1347 1388          if (cfg[CFG_PERSIST_LINKDOWN].current) {
↓ open down ↓ 50 lines elided ↑ open up ↑
1398 1439  done:
1399 1440          /*
1400 1441           * The leadville driver will now handle the FLOGI at the driver level
1401 1442           */
1402 1443  
1403 1444          if (mbq) {
1404 1445                  (void) kmem_free((uint8_t *)mbq, sizeof (MAILBOXQ));
1405 1446                  mbq = NULL;
1406 1447                  mb = NULL;
1407 1448          }
     1449 +
     1450 +        if (hba->model_info.flags & EMLXS_GPIO_LEDS)
     1451 +                emlxs_sli4_gpio_timer_start(hba);
     1452 +
1408 1453          return (0);
1409 1454  
1410 1455  failed3:
1411 1456          EMLXS_STATE_CHANGE(hba, FC_ERROR);
1412 1457  
1413 1458          if (mp) {
1414 1459                  emlxs_mem_put(hba, MEM_BUF, (void *)mp);
1415 1460                  mp = NULL;
1416 1461          }
1417 1462  
↓ open down ↓ 25 lines elided ↑ open up ↑
1443 1488          return (rval);
1444 1489  
1445 1490  } /* emlxs_sli4_online() */
1446 1491  
1447 1492  
1448 1493  static void
1449 1494  emlxs_sli4_offline(emlxs_hba_t *hba, uint32_t reset_requested)
1450 1495  {
1451 1496          /* Reverse emlxs_sli4_online */
1452 1497  
     1498 +        if (hba->model_info.flags & EMLXS_GPIO_LEDS)
     1499 +                emlxs_sli4_gpio_timer_stop(hba);
     1500 +
1453 1501          mutex_enter(&EMLXS_PORT_LOCK);
1454 1502          if (hba->flag & FC_INTERLOCKED) {
1455 1503                  mutex_exit(&EMLXS_PORT_LOCK);
1456 1504                  goto killed;
1457 1505          }
1458 1506          mutex_exit(&EMLXS_PORT_LOCK);
1459 1507  
1460 1508          if (reset_requested) {
1461 1509                  (void) emlxs_sli4_hba_reset(hba, 0, 0, 0);
1462 1510          }
↓ open down ↓ 774 lines elided ↑ open up ↑
2237 2285          }
2238 2286  
2239 2287          return (0);
2240 2288  
2241 2289  } /* emlxs_sli4_hba_init() */
2242 2290  
2243 2291  
2244 2292  /*ARGSUSED*/
2245 2293  static uint32_t
2246 2294  emlxs_sli4_hba_reset(emlxs_hba_t *hba, uint32_t restart, uint32_t skip_post,
2247      -                uint32_t quiesce)
     2295 +    uint32_t quiesce)
2248 2296  {
2249 2297          emlxs_port_t *port = &PPORT;
2250 2298          emlxs_port_t *vport;
2251 2299          CHANNEL *cp;
2252 2300          emlxs_config_t *cfg = &CFG;
2253 2301          MAILBOXQ mboxq;
2254 2302          uint32_t value;
2255 2303          uint32_t i;
2256 2304          uint32_t rc;
2257 2305          uint16_t channelno;
↓ open down ↓ 98 lines elided ↑ open up ↑
2356 2404          hba->channel_tx_count = 0;
2357 2405          hba->io_count = 0;
2358 2406          hba->iodone_count = 0;
2359 2407          hba->topology = 0;
2360 2408          hba->linkspeed = 0;
2361 2409          hba->heartbeat_active = 0;
2362 2410          hba->discovery_timer = 0;
2363 2411          hba->linkup_timer = 0;
2364 2412          hba->loopback_tics = 0;
2365 2413  
     2414 +        /* Specific to ATTO G5 boards */
     2415 +        if (hba->model_info.flags & EMLXS_GPIO_LEDS) {
     2416 +                /* Assume the boot driver enabled all LEDs */
     2417 +                hba->gpio_current =
     2418 +                    EMLXS_GPIO_LO | EMLXS_GPIO_HI | EMLXS_GPIO_ACT;
     2419 +                hba->gpio_desired = 0;
     2420 +                hba->gpio_bit = 0;
     2421 +        }
     2422 +
2366 2423          /* Reset the port objects */
2367 2424          for (i = 0; i < MAX_VPORTS; i++) {
2368 2425                  vport = &VPORT(i);
2369 2426  
2370 2427                  vport->flag &= EMLXS_PORT_RESET_MASK;
2371 2428                  vport->did = 0;
2372 2429                  vport->prev_did = 0;
2373 2430                  vport->lip_type = 0;
2374 2431                  bzero(&vport->fabric_sparam, sizeof (SERV_PARM));
2375 2432                  bzero(&vport->prev_fabric_sparam, sizeof (SERV_PARM));
↓ open down ↓ 172 lines elided ↑ open up ↑
2548 2605          ddi_dma_cookie_t *cp_cmd;
2549 2606          ddi_dma_cookie_t *cp_data;
2550 2607          uint64_t sge_addr;
2551 2608          uint32_t cmd_cnt;
2552 2609          uint32_t resp_cnt;
2553 2610  
2554 2611          iocbq = (IOCBQ *) &sbp->iocbq;
2555 2612          wqe = &iocbq->wqe;
2556 2613          pkt = PRIV2PKT(sbp);
2557 2614          xrip = sbp->xrip;
2558      -        sge = xrip->SGList.virt;
     2615 +        sge = xrip->SGList->virt;
2559 2616  
2560 2617  #if (EMLXS_MODREV >= EMLXS_MODREV3)
2561 2618          cp_cmd = pkt->pkt_cmd_cookie;
2562 2619          cp_data = pkt->pkt_data_cookie;
2563 2620  #else
2564 2621          cp_cmd  = &pkt->pkt_cmd_cookie;
2565 2622          cp_data = &pkt->pkt_data_cookie;
2566 2623  #endif  /* >= EMLXS_MODREV3 */
2567 2624  
2568 2625          iocbq = &sbp->iocbq;
↓ open down ↓ 129 lines elided ↑ open up ↑
2698 2755           */
2699 2756          fct_mp = (MATCHMAP *)sbp->fct_buf->db_port_private;
2700 2757  
2701 2758          if (sbp->fct_buf->db_sglist_length != 1) {
2702 2759                  EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
2703 2760                      "fct_bde_setup: Only 1 sglist entry supported: %d",
2704 2761                      sbp->fct_buf->db_sglist_length);
2705 2762                  return (1);
2706 2763          }
2707 2764  
2708      -        sge = xrip->SGList.virt;
     2765 +        sge = xrip->SGList->virt;
2709 2766  
2710 2767          if (iocb->ULPCOMMAND == CMD_FCP_TRECEIVE64_CX) {
2711 2768  
2712 2769                  mp = emlxs_mem_buf_alloc(hba, EMLXS_XFER_RDY_SIZE);
2713 2770                  if (!mp || !mp->virt || !mp->phys) {
2714 2771                          EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
2715 2772                              "fct_bde_setup: Cannot allocate XRDY memory");
2716 2773                          return (1);
2717 2774                  }
2718 2775                  /* Save the MATCHMAP info to free this memory later */
↓ open down ↓ 1262 lines elided ↑ open up ↑
3981 4038  #else
3982 4039                  cp_cmd  = &pkt->pkt_cmd_cookie;
3983 4040  #endif  /* >= EMLXS_MODREV3 */
3984 4041  
3985 4042                  sge_size = pkt->pkt_cmdlen;
3986 4043                  /* Make size a multiple of 4 */
3987 4044                  if (sge_size & 3) {
3988 4045                          sge_size = (sge_size + 3) & 0xfffffffc;
3989 4046                  }
3990 4047                  sge_addr = cp_cmd->dmac_laddress;
3991      -                sge = xrip->SGList.virt;
     4048 +                sge = xrip->SGList->virt;
3992 4049  
3993 4050                  stage_sge.addrHigh = PADDR_HI(sge_addr);
3994 4051                  stage_sge.addrLow = PADDR_LO(sge_addr);
3995 4052                  stage_sge.length = sge_size;
3996 4053                  stage_sge.offset = 0;
3997 4054                  stage_sge.type = 0;
3998 4055                  stage_sge.last = 1;
3999 4056  
4000 4057                  /* Copy staged SGE into SGL */
4001 4058                  BE_SWAP32_BCOPY((uint8_t *)&stage_sge,
↓ open down ↓ 171 lines elided ↑ open up ↑
4173 4230          fc_packet_t *pkt;
4174 4231          CHANNEL *cp;
4175 4232          RPIobj_t *rpip;
4176 4233          XRIobj_t *xrip;
4177 4234          emlxs_wqe_t *wqe;
4178 4235          IOCBQ *iocbq;
4179 4236          IOCB *iocb;
4180 4237          NODELIST *node;
4181 4238          uint16_t iotag;
4182 4239          uint32_t did;
4183      -        off_t offset;
4184 4240  
4185 4241          pkt = PRIV2PKT(sbp);
4186 4242          did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
4187 4243          cp = &hba->chan[channel];
4188 4244  
4189 4245          iocbq = &sbp->iocbq;
4190 4246          iocbq->channel = (void *) cp;
4191 4247          iocbq->port = (void *) port;
4192 4248  
4193 4249          wqe = &iocbq->wqe;
↓ open down ↓ 41 lines elided ↑ open up ↑
4235 4291                  emlxs_sli4_free_xri(port, sbp, xrip, 1);
4236 4292                  EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
4237 4293                      "Adapter Busy. Unable to setup SGE. did=0x%x", did);
4238 4294  
4239 4295                  return (FC_TRAN_BUSY);
4240 4296          }
4241 4297  
4242 4298          /* DEBUG */
4243 4299  #ifdef DEBUG_FCP
4244 4300          EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
4245      -            "FCP: SGLaddr virt %p phys %p size %d", xrip->SGList.virt,
4246      -            xrip->SGList.phys, pkt->pkt_datalen);
4247      -        emlxs_data_dump(port, "FCP: SGL", (uint32_t *)xrip->SGList.virt, 20, 0);
     4301 +            "FCP: SGLaddr virt %p phys %p size %d", xrip->SGList->virt,
     4302 +            xrip->SGList->phys, pkt->pkt_datalen);
     4303 +        emlxs_data_dump(port, "FCP: SGL",
     4304 +            (uint32_t *)xrip->SGList->virt, 20, 0);
4248 4305          EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
4249 4306              "FCP: CMD virt %p len %d:%d:%d",
4250 4307              pkt->pkt_cmd, pkt->pkt_cmdlen, pkt->pkt_rsplen, pkt->pkt_datalen);
4251 4308          emlxs_data_dump(port, "FCP: CMD", (uint32_t *)pkt->pkt_cmd, 10, 0);
4252 4309  #endif /* DEBUG_FCP */
4253 4310  
4254      -        offset = (off_t)((uint64_t)((unsigned long)
4255      -            xrip->SGList.virt) -
4256      -            (uint64_t)((unsigned long)
4257      -            hba->sli.sli4.slim2.virt));
     4311 +        EMLXS_MPDATA_SYNC(xrip->SGList->dma_handle, 0,
     4312 +            xrip->SGList->size, DDI_DMA_SYNC_FORDEV);
4258 4313  
4259      -        EMLXS_MPDATA_SYNC(xrip->SGList.dma_handle, offset,
4260      -            xrip->SGList.size, DDI_DMA_SYNC_FORDEV);
4261      -
4262 4314          /* if device is FCP-2 device, set the following bit */
4263 4315          /* that says to run the FC-TAPE protocol. */
4264 4316          if (node->nlp_fcp_info & NLP_FCP_2_DEVICE) {
4265 4317                  wqe->ERP = 1;
4266 4318          }
4267 4319  
4268 4320          if (pkt->pkt_datalen == 0) {
4269 4321                  iocb->ULPCOMMAND = CMD_FCP_ICMND64_CR;
4270 4322                  wqe->Command = CMD_FCP_ICMND64_CR;
4271 4323                  wqe->CmdType = WQE_TYPE_FCP_DATA_IN;
↓ open down ↓ 63 lines elided ↑ open up ↑
4335 4387          RPIobj_t *rpip = NULL;
4336 4388          XRIobj_t *xrip;
4337 4389          CHANNEL *cp;
4338 4390          uint32_t did;
4339 4391          uint32_t cmd;
4340 4392          ULP_SGE64 stage_sge;
4341 4393          ULP_SGE64 *sge;
4342 4394          ddi_dma_cookie_t *cp_cmd;
4343 4395          ddi_dma_cookie_t *cp_resp;
4344 4396          emlxs_node_t *node;
4345      -        off_t offset;
4346 4397  
4347 4398          pkt = PRIV2PKT(sbp);
4348 4399          did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
4349 4400  
4350 4401          iocbq = &sbp->iocbq;
4351 4402          wqe = &iocbq->wqe;
4352 4403          iocb = &iocbq->iocb;
4353 4404          bzero((void *)wqe, sizeof (emlxs_wqe_t));
4354 4405          bzero((void *)iocb, sizeof (IOCB));
4355 4406          cp = &hba->chan[hba->channel_els];
↓ open down ↓ 73 lines elided ↑ open up ↑
4429 4480                  wqe->un.ElsRsp.Payload.tus.f.bdeSize = pkt->pkt_cmdlen;
4430 4481                  wqe->un.ElsCmd.PayloadLength = pkt->pkt_cmdlen;
4431 4482  
4432 4483                  wqe->un.ElsRsp.RemoteId = did;
4433 4484                  wqe->PU = 0x3;
4434 4485                  wqe->OXId = xrip->rx_id;
4435 4486  
4436 4487                  sge->last = 1;
4437 4488                  /* Now sge is fully staged */
4438 4489  
4439      -                sge = xrip->SGList.virt;
     4490 +                sge = xrip->SGList->virt;
4440 4491                  BE_SWAP32_BCOPY((uint8_t *)&stage_sge, (uint8_t *)sge,
4441 4492                      sizeof (ULP_SGE64));
4442 4493  
4443 4494                  if (rpip->RPI == FABRIC_RPI) {
4444 4495                          wqe->ContextTag = port->vpip->VPI;
4445 4496                          wqe->ContextType = WQE_VPI_CONTEXT;
4446 4497                  } else {
4447 4498                          wqe->ContextTag = rpip->RPI;
4448 4499                          wqe->ContextType = WQE_RPI_CONTEXT;
4449 4500                  }
↓ open down ↓ 44 lines elided ↑ open up ↑
4494 4545  
4495 4546                  wqe->un.ElsCmd.RemoteId = did;
4496 4547                  wqe->Timer = ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout);
4497 4548  
4498 4549                  /* setup for rsp */
4499 4550                  iocb->un.elsreq64.remoteID = (did == BCAST_DID) ? 0 : did;
4500 4551                  iocb->ULPPU = 1;        /* Wd4 is relative offset */
4501 4552  
4502 4553                  sge->last = 0;
4503 4554  
4504      -                sge = xrip->SGList.virt;
     4555 +                sge = xrip->SGList->virt;
4505 4556                  BE_SWAP32_BCOPY((uint8_t *)&stage_sge, (uint8_t *)sge,
4506 4557                      sizeof (ULP_SGE64));
4507 4558  
4508 4559                  wqe->un.ElsCmd.PayloadLength =
4509 4560                      pkt->pkt_cmdlen; /* Byte offset of rsp data */
4510 4561  
4511 4562                  /* RSP payload */
4512 4563                  sge = &stage_sge;
4513 4564                  sge->addrHigh = PADDR_HI(cp_resp->dmac_laddress);
4514 4565                  sge->addrLow = PADDR_LO(cp_resp->dmac_laddress);
4515 4566                  sge->length = pkt->pkt_rsplen;
4516 4567                  sge->offset = 0;
4517 4568                  sge->last = 1;
4518 4569                  /* Now sge is fully staged */
4519 4570  
4520      -                sge = xrip->SGList.virt;
     4571 +                sge = xrip->SGList->virt;
4521 4572                  sge++;
4522 4573                  BE_SWAP32_BCOPY((uint8_t *)&stage_sge, (uint8_t *)sge,
4523 4574                      sizeof (ULP_SGE64));
4524 4575  #ifdef DEBUG_ELS
4525 4576                  EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
4526 4577                      "ELS: SGLaddr virt %p phys %p",
4527      -                    xrip->SGList.virt, xrip->SGList.phys);
     4578 +                    xrip->SGList->virt, xrip->SGList->phys);
4528 4579                  EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
4529 4580                      "ELS: PAYLOAD virt %p phys %p",
4530 4581                      pkt->pkt_cmd, cp_cmd->dmac_laddress);
4531      -                emlxs_data_dump(port, "ELS: SGL", (uint32_t *)xrip->SGList.virt,
4532      -                    12, 0);
     4582 +                emlxs_data_dump(port, "ELS: SGL",
     4583 +                    (uint32_t *)xrip->SGList->virt, 12, 0);
4533 4584  #endif /* DEBUG_ELS */
4534 4585  
4535 4586                  switch (cmd) {
4536 4587                  case ELS_CMD_FLOGI:
4537 4588                          wqe->un.ElsCmd.SP = 1;
4538 4589  
4539 4590                          if ((hba->sli_intf & SLI_INTF_IF_TYPE_MASK) ==
4540 4591                              SLI_INTF_IF_TYPE_0) {
4541 4592                                  wqe->ContextTag = fcfp->FCFI;
4542 4593                                  wqe->ContextType = WQE_FCFI_CONTEXT;
↓ open down ↓ 85 lines elided ↑ open up ↑
4628 4679                  }
4629 4680  
4630 4681                  /* Store the reserved rpi */
4631 4682                  if (wqe->Command == CMD_ELS_REQUEST64_CR) {
4632 4683                          wqe->OXId = reserved_rpip->RPI;
4633 4684                  } else {
4634 4685                          wqe->CmdSpecific = reserved_rpip->RPI;
4635 4686                  }
4636 4687          }
4637 4688  
4638      -        offset = (off_t)((uint64_t)((unsigned long)
4639      -            xrip->SGList.virt) -
4640      -            (uint64_t)((unsigned long)
4641      -            hba->sli.sli4.slim2.virt));
     4689 +        EMLXS_MPDATA_SYNC(xrip->SGList->dma_handle, 0,
     4690 +            xrip->SGList->size, DDI_DMA_SYNC_FORDEV);
4642 4691  
4643      -        EMLXS_MPDATA_SYNC(xrip->SGList.dma_handle, offset,
4644      -            xrip->SGList.size, DDI_DMA_SYNC_FORDEV);
4645      -
4646 4692          if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_CHAINED_SEQ) {
4647 4693                  wqe->CCPE = 1;
4648 4694                  wqe->CCP = pkt->pkt_cmd_fhdr.rsvd;
4649 4695          }
4650 4696  
4651 4697          switch (FC_TRAN_CLASS(pkt->pkt_tran_flags)) {
4652 4698          case FC_TRAN_CLASS2:
4653 4699                  wqe->Class = CLASS2;
4654 4700                  break;
4655 4701          case FC_TRAN_CLASS3:
↓ open down ↓ 17 lines elided ↑ open up ↑
4673 4719          emlxs_hba_t *hba = HBA;
4674 4720          fc_packet_t *pkt;
4675 4721          IOCBQ *iocbq;
4676 4722          IOCB *iocb;
4677 4723          emlxs_wqe_t *wqe;
4678 4724          NODELIST *node = NULL;
4679 4725          CHANNEL *cp;
4680 4726          RPIobj_t *rpip;
4681 4727          XRIobj_t *xrip;
4682 4728          uint32_t did;
4683      -        off_t offset;
4684 4729  
4685 4730          pkt = PRIV2PKT(sbp);
4686 4731          did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
4687 4732  
4688 4733          iocbq = &sbp->iocbq;
4689 4734          wqe = &iocbq->wqe;
4690 4735          iocb = &iocbq->iocb;
4691 4736          bzero((void *)wqe, sizeof (emlxs_wqe_t));
4692 4737          bzero((void *)iocb, sizeof (IOCB));
4693 4738  
↓ open down ↓ 131 lines elided ↑ open up ↑
4825 4870                  iocb->ULPCOMMAND = CMD_GEN_REQUEST64_CR;
4826 4871                  wqe->CmdType = WQE_TYPE_GEN;
4827 4872                  wqe->Command = CMD_GEN_REQUEST64_CR;
4828 4873                  wqe->un.GenReq.la = 1;
4829 4874                  wqe->un.GenReq.DFctl  = pkt->pkt_cmd_fhdr.df_ctl;
4830 4875                  wqe->un.GenReq.Rctl  = pkt->pkt_cmd_fhdr.r_ctl;
4831 4876                  wqe->un.GenReq.Type  = pkt->pkt_cmd_fhdr.type;
4832 4877  
4833 4878  #ifdef DEBUG_CT
4834 4879                  EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
4835      -                    "CT: SGLaddr virt %p phys %p", xrip->SGList.virt,
4836      -                    xrip->SGList.phys);
4837      -                emlxs_data_dump(port, "CT: SGL", (uint32_t *)xrip->SGList.virt,
     4880 +                    "CT: SGLaddr virt %p phys %p", xrip->SGList->virt,
     4881 +                    xrip->SGList->phys);
     4882 +                emlxs_data_dump(port, "CT: SGL", (uint32_t *)xrip->SGList->virt,
4838 4883                      12, 0);
4839 4884                  EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
4840 4885                      "CT: CMD virt %p len %d:%d",
4841 4886                      pkt->pkt_cmd, pkt->pkt_cmdlen, pkt->pkt_rsplen);
4842 4887                  emlxs_data_dump(port, "CT: DATA", (uint32_t *)pkt->pkt_cmd,
4843 4888                      20, 0);
4844 4889  #endif /* DEBUG_CT */
4845 4890  
4846 4891  #ifdef SFCT_SUPPORT
4847 4892                  /* This allows fct to abort the request */
↓ open down ↓ 3 lines elided ↑ open up ↑
4851 4896                  }
4852 4897  #endif /* SFCT_SUPPORT */
4853 4898          }
4854 4899  
4855 4900          /* Setup for rsp */
4856 4901          iocb->un.genreq64.w5.hcsw.Rctl  = pkt->pkt_cmd_fhdr.r_ctl;
4857 4902          iocb->un.genreq64.w5.hcsw.Type  = pkt->pkt_cmd_fhdr.type;
4858 4903          iocb->un.genreq64.w5.hcsw.Dfctl  = pkt->pkt_cmd_fhdr.df_ctl;
4859 4904          iocb->ULPPU = 1;        /* Wd4 is relative offset */
4860 4905  
4861      -        offset = (off_t)((uint64_t)((unsigned long)
4862      -            xrip->SGList.virt) -
4863      -            (uint64_t)((unsigned long)
4864      -            hba->sli.sli4.slim2.virt));
     4906 +        EMLXS_MPDATA_SYNC(xrip->SGList->dma_handle, 0,
     4907 +            xrip->SGList->size, DDI_DMA_SYNC_FORDEV);
4865 4908  
4866      -        EMLXS_MPDATA_SYNC(xrip->SGList.dma_handle, offset,
4867      -            xrip->SGList.size, DDI_DMA_SYNC_FORDEV);
4868      -
4869 4909          wqe->ContextTag = rpip->RPI;
4870 4910          wqe->ContextType = WQE_RPI_CONTEXT;
4871 4911          wqe->XRITag = xrip->XRI;
4872 4912          wqe->Timer = ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout);
4873 4913  
4874 4914          if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_CHAINED_SEQ) {
4875 4915                  wqe->CCPE = 1;
4876 4916                  wqe->CCP = pkt->pkt_cmd_fhdr.rsvd;
4877 4917          }
4878 4918  
↓ open down ↓ 222 lines elided ↑ open up ↑
5101 5141                          break;
5102 5142                  default:
5103 5143                          EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
5104 5144                              "FC Async Event: Unknown event. type=%d event=%x",
5105 5145                              cqe->event_type, HBASTATS.LinkEvent);
5106 5146                  }
5107 5147                  break;
5108 5148          case ASYNC_EVENT_CODE_PORT:
5109 5149                  EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
5110 5150                      "SLI Port Async Event: type=%d", cqe->event_type);
5111      -                if (cqe->event_type == ASYNC_EVENT_MISCONFIG_PORT) {
     5151 +
     5152 +                switch (cqe->event_type) {
     5153 +                case ASYNC_EVENT_PORT_OTEMP:
     5154 +                        EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg,
     5155 +                            "SLI Port Async Event: Temperature limit exceeded");
     5156 +                        cmn_err(CE_WARN,
     5157 +                            "^%s%d: Temperature limit exceeded. Fibre channel "
     5158 +                            "controller temperature %u degrees C",
     5159 +                            DRIVER_NAME, hba->ddiinst,
     5160 +                            BE_SWAP32(*(uint32_t *)cqe->un.port.link_status));
     5161 +                        break;
     5162 +
     5163 +                case ASYNC_EVENT_PORT_NTEMP:
     5164 +                        EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg,
     5165 +                            "SLI Port Async Event: Temperature returned to "
     5166 +                            "normal");
     5167 +                        cmn_err(CE_WARN,
     5168 +                            "^%s%d: Temperature returned to normal",
     5169 +                            DRIVER_NAME, hba->ddiinst);
     5170 +                        break;
     5171 +
     5172 +                case ASYNC_EVENT_MISCONFIG_PORT:
5112 5173                          *((uint32_t *)cqe->un.port.link_status) =
5113 5174                              BE_SWAP32(*((uint32_t *)cqe->un.port.link_status));
5114 5175                          status =
5115 5176                              cqe->un.port.link_status[hba->sli.sli4.link_number];
5116 5177  
5117 5178                          switch (status) {
5118 5179                                  case 0 :
5119 5180                                  break;
5120 5181  
5121 5182                                  case 1 :
↓ open down ↓ 32 lines elided ↑ open up ↑
5154 5215                                  default :
5155 5216                                  EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg,
5156 5217                                      "SLI Port Async Event: Physical media "
5157 5218                                      "error, status=%x", status);
5158 5219                                  cmn_err(CE_WARN,
5159 5220                                      "^%s%d: Misconfigured port: status=0x%x - "
5160 5221                                      "Check optics on card.",
5161 5222                                      DRIVER_NAME, hba->ddiinst, status);
5162 5223                                  break;
5163 5224                          }
     5225 +                        break;
5164 5226                  }
     5227 +
5165 5228                  break;
5166 5229          case ASYNC_EVENT_CODE_VF:
5167 5230                  EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
5168 5231                      "VF Async Event: type=%d",
5169 5232                      cqe->event_type);
5170 5233                  break;
5171 5234          case ASYNC_EVENT_CODE_MR:
5172 5235                  EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
5173 5236                      "MR Async Event: type=%d",
5174 5237                      cqe->event_type);
↓ open down ↓ 1417 lines elided ↑ open up ↑
6592 6655                  iocb->unsli3.ext_rcv.oxid = fchdr.ox_id;
6593 6656  
6594 6657                  if (fchdr.f_ctl & F_CTL_CHAINED_SEQ) {
6595 6658                          iocb->unsli3.ext_rcv.ccpe = 1;
6596 6659                          iocb->unsli3.ext_rcv.ccp = fchdr.rsvd;
6597 6660                  }
6598 6661  
6599 6662                  /* pass xrip to FCT in the iocbq */
6600 6663                  iocbq->sbp = xrip;
6601 6664  
6602      -#define EMLXS_FIX_CISCO_BUG1
6603      -#ifdef EMLXS_FIX_CISCO_BUG1
6604      -{
6605      -uint8_t *ptr;
6606      -ptr = ((uint8_t *)seq_mp->virt);
6607      -if (((*ptr+12) != 0xa0) && (*(ptr+20) == 0x8) && (*(ptr+21) == 0x8)) {
6608      -        EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg,
6609      -            "RQ ENTRY: Bad CDB fixed");
6610      -        *ptr++ = 0;
6611      -        *ptr = 0;
6612      -}
6613      -}
6614      -#endif
6615 6665                  (void) emlxs_fct_handle_unsol_req(port, cp, iocbq,
6616      -                        seq_mp, seq_len);
     6666 +                    seq_mp, seq_len);
6617 6667                  break;
6618 6668  #endif /* SFCT_SUPPORT */
6619 6669  
6620 6670          case 0x20: /* CT */
6621 6671                  if (!(port->vpip->flag & EMLXS_VPI_PORT_ENABLED) &&
6622 6672                      !(hba->flag & FC_LOOPBACK_MODE)) {
6623 6673                          EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
6624 6674                              "RQ ENTRY: %s: Port not yet enabled. "
6625 6675                              "Dropping...",
6626 6676                              label);
↓ open down ↓ 562 lines elided ↑ open up ↑
7189 7239  {
7190 7240          if (att) {
7191 7241                  return;
7192 7242          }
7193 7243  
7194 7244          hba->sli.sli4.flag &= ~EMLXS_SLI4_INTR_ENABLED;
7195 7245  
7196 7246          /* Short of reset, we cannot disable interrupts */
7197 7247  } /* emlxs_sli4_disable_intr() */
7198 7248  
7199      -
7200 7249  static void
7201 7250  emlxs_sli4_resource_free(emlxs_hba_t *hba)
7202 7251  {
7203 7252          emlxs_port_t    *port = &PPORT;
7204 7253          MBUF_INFO       *buf_info;
7205 7254          uint32_t        i;
7206 7255  
7207 7256          buf_info = &hba->sli.sli4.slim2;
7208 7257          if (buf_info->virt == 0) {
7209 7258                  /* Already free */
↓ open down ↓ 1 lines elided ↑ open up ↑
7211 7260          }
7212 7261  
7213 7262          emlxs_fcf_fini(hba);
7214 7263  
7215 7264          buf_info = &hba->sli.sli4.HeaderTmplate;
7216 7265          if (buf_info->virt) {
7217 7266                  bzero(buf_info, sizeof (MBUF_INFO));
7218 7267          }
7219 7268  
7220 7269          if (hba->sli.sli4.XRIp) {
     7270 +                XRIobj_t        *xrip;
     7271 +
7221 7272                  if ((hba->sli.sli4.XRIinuse_f !=
7222 7273                      (XRIobj_t *)&hba->sli.sli4.XRIinuse_f) ||
7223 7274                      (hba->sli.sli4.XRIinuse_b !=
7224 7275                      (XRIobj_t *)&hba->sli.sli4.XRIinuse_f)) {
7225 7276                          EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_debug_msg,
7226 7277                              "XRIs in use during free!: %p %p != %p\n",
7227 7278                              hba->sli.sli4.XRIinuse_f,
7228 7279                              hba->sli.sli4.XRIinuse_b,
7229 7280                              &hba->sli.sli4.XRIinuse_f);
7230 7281                  }
     7282 +
     7283 +                xrip = hba->sli.sli4.XRIp;
     7284 +                for (i = 0; i < hba->sli.sli4.XRICount; i++) {
     7285 +                        xrip->XRI = emlxs_sli4_index_to_xri(hba, i);
     7286 +
     7287 +                        if (xrip->XRI != 0)
     7288 +                                emlxs_mem_put(hba, xrip->SGSeg, xrip->SGList);
     7289 +
     7290 +                        xrip++;
     7291 +                }
     7292 +
7231 7293                  kmem_free(hba->sli.sli4.XRIp,
7232 7294                      (sizeof (XRIobj_t) * hba->sli.sli4.XRICount));
7233 7295                  hba->sli.sli4.XRIp = NULL;
7234 7296  
7235 7297                  hba->sli.sli4.XRIfree_f =
7236 7298                      (XRIobj_t *)&hba->sli.sli4.XRIfree_f;
7237 7299                  hba->sli.sli4.XRIfree_b =
7238 7300                      (XRIobj_t *)&hba->sli.sli4.XRIfree_f;
7239 7301                  hba->sli.sli4.xrif_count = 0;
7240 7302          }
↓ open down ↓ 24 lines elided ↑ open up ↑
7265 7327          /* Free the MQ */
7266 7328          bzero(&hba->sli.sli4.mq, sizeof (MQ_DESC_t));
7267 7329  
7268 7330          buf_info = &hba->sli.sli4.slim2;
7269 7331          if (buf_info->virt) {
7270 7332                  buf_info->flags = FC_MBUF_DMA;
7271 7333                  emlxs_mem_free(hba, buf_info);
7272 7334                  bzero(buf_info, sizeof (MBUF_INFO));
7273 7335          }
7274 7336  
     7337 +        /* GPIO lock */
     7338 +        if (hba->model_info.flags & EMLXS_GPIO_LEDS)
     7339 +                mutex_destroy(&hba->gpio_lock);
     7340 +
7275 7341  } /* emlxs_sli4_resource_free() */
7276 7342  
7277      -
7278 7343  static int
7279 7344  emlxs_sli4_resource_alloc(emlxs_hba_t *hba)
7280 7345  {
7281 7346          emlxs_port_t    *port = &PPORT;
7282 7347          emlxs_config_t  *cfg = &CFG;
7283 7348          MBUF_INFO       *buf_info;
7284 7349          int             num_eq;
7285 7350          int             num_wq;
7286 7351          uint16_t        i;
7287 7352          uint32_t        j;
↓ open down ↓ 57 lines elided ↑ open up ↑
7345 7410          /* MQ */
7346 7411          count +=  EMLXS_MAX_MQS * 4096;
7347 7412  
7348 7413          /* RQ */
7349 7414          count +=  EMLXS_MAX_RQS * 4096;
7350 7415  
7351 7416          /* RQB/E */
7352 7417          count += RQB_COUNT * (RQB_DATA_SIZE + RQB_HEADER_SIZE);
7353 7418          count += (4096 - (count%4096)); /* Ensure 4K alignment */
7354 7419  
7355      -        /* SGL */
7356      -        count += hba->sli.sli4.XRIExtSize * hba->sli.sli4.mem_sgl_size;
7357      -        count += (4096 - (count%4096)); /* Ensure 4K alignment */
7358      -
7359 7420          /* RPI Header Templates */
7360 7421          if (hba->sli.sli4.param.HDRR) {
7361 7422                  /* Bytes per extent */
7362 7423                  j = hba->sli.sli4.RPIExtSize * sizeof (RPIHdrTmplate_t);
7363 7424  
7364 7425                  /* Pages required per extent (page == 4096 bytes) */
7365 7426                  k = (j/4096) + ((j%4096)? 1:0);
7366 7427  
7367 7428                  /* Total size */
7368 7429                  hddr_size = (k * hba->sli.sli4.RPIExtCount * 4096);
7369 7430  
7370 7431                  count += hddr_size;
7371 7432          }
7372 7433  
7373 7434          /* Allocate slim2 for SLI4 */
7374 7435          buf_info = &hba->sli.sli4.slim2;
7375 7436          buf_info->size = count;
7376 7437          buf_info->flags = FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32;
7377 7438          buf_info->align = ddi_ptob(hba->dip, 1L);
7378 7439  
     7440 +        EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
     7441 +            "Allocating memory for slim2: %d", count);
     7442 +
7379 7443          (void) emlxs_mem_alloc(hba, buf_info);
7380 7444  
7381 7445          if (buf_info->virt == NULL) {
7382 7446                  EMLXS_MSGF(EMLXS_CONTEXT,
7383 7447                      &emlxs_init_failed_msg,
7384 7448                      "Unable to allocate internal memory for SLI4: %d",
7385 7449                      count);
7386 7450                  goto failed;
7387 7451          }
7388 7452          bzero(buf_info->virt, buf_info->size);
7389 7453          EMLXS_MPDATA_SYNC(buf_info->dma_handle, 0,
7390 7454              buf_info->size, DDI_DMA_SYNC_FORDEV);
7391 7455  
7392      -        /* Assign memory to SGL, Head Template, EQ, CQ, WQ, RQ and MQ */
     7456 +        /* Assign memory to Head Template, EQ, CQ, WQ, RQ and MQ */
7393 7457          data_handle = buf_info->data_handle;
7394 7458          dma_handle = buf_info->dma_handle;
7395 7459          phys = buf_info->phys;
7396 7460          virt = (char *)buf_info->virt;
7397 7461  
7398 7462          /* Allocate space for queues */
7399 7463  
7400 7464          /* EQ */
7401 7465          size = 4096;
7402 7466          for (i = 0; i < num_eq; i++) {
↓ open down ↓ 169 lines elided ↑ open up ↑
7572 7636                  /* Sync the RQ buffer list */
7573 7637                  EMLXS_MPDATA_SYNC(hba->sli.sli4.rq[i].addr.dma_handle, offset,
7574 7638                      hba->sli.sli4.rq[i].addr.size, DDI_DMA_SYNC_FORDEV);
7575 7639          }
7576 7640  
7577 7641          /* 4K Alignment */
7578 7642          align = (4096 - (phys%4096));
7579 7643          phys += align;
7580 7644          virt += align;
7581 7645  
     7646 +        /* RPI Header Templates */
     7647 +        if (hba->sli.sli4.param.HDRR) {
     7648 +                buf_info = &hba->sli.sli4.HeaderTmplate;
     7649 +                bzero(buf_info, sizeof (MBUF_INFO));
     7650 +                buf_info->size = hddr_size;
     7651 +                buf_info->flags = FC_MBUF_DMA | FC_MBUF_DMA32;
     7652 +                buf_info->align = ddi_ptob(hba->dip, 1L);
     7653 +                buf_info->phys = phys;
     7654 +                buf_info->virt = (void *)virt;
     7655 +                buf_info->data_handle = data_handle;
     7656 +                buf_info->dma_handle = dma_handle;
     7657 +        }
     7658 +
7582 7659          /* SGL */
     7660 +
     7661 +        EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
     7662 +            "Allocating memory for %d SGLs: %d/%d",
     7663 +            hba->sli.sli4.XRICount, sizeof (XRIobj_t), size);
     7664 +
7583 7665          /* Initialize double linked lists */
7584 7666          hba->sli.sli4.XRIinuse_f =
7585 7667              (XRIobj_t *)&hba->sli.sli4.XRIinuse_f;
7586 7668          hba->sli.sli4.XRIinuse_b =
7587 7669              (XRIobj_t *)&hba->sli.sli4.XRIinuse_f;
7588 7670          hba->sli.sli4.xria_count = 0;
7589 7671  
7590 7672          hba->sli.sli4.XRIfree_f =
7591 7673              (XRIobj_t *)&hba->sli.sli4.XRIfree_f;
7592 7674          hba->sli.sli4.XRIfree_b =
7593 7675              (XRIobj_t *)&hba->sli.sli4.XRIfree_f;
7594      -        hba->sli.sli4.xria_count = 0;
     7676 +        hba->sli.sli4.xrif_count = 0;
7595 7677  
     7678 +        uint32_t mseg;
     7679 +
     7680 +        switch (hba->sli.sli4.mem_sgl_size) {
     7681 +        case 1024:
     7682 +                mseg = MEM_SGL1K;
     7683 +                break;
     7684 +        case 2048:
     7685 +                mseg = MEM_SGL2K;
     7686 +                break;
     7687 +        case 4096:
     7688 +                mseg = MEM_SGL4K;
     7689 +                break;
     7690 +        default:
     7691 +                EMLXS_MSGF(EMLXS_CONTEXT,
     7692 +                    &emlxs_init_failed_msg,
     7693 +                    "Unsupported SGL Size: %d", hba->sli.sli4.mem_sgl_size);
     7694 +                goto failed;
     7695 +        }
     7696 +
7596 7697          hba->sli.sli4.XRIp = (XRIobj_t *)kmem_zalloc(
7597 7698              (sizeof (XRIobj_t) * hba->sli.sli4.XRICount), KM_SLEEP);
7598 7699  
7599 7700          xrip = hba->sli.sli4.XRIp;
7600      -        size = hba->sli.sli4.mem_sgl_size;
7601 7701          iotag = 1;
     7702 +
7602 7703          for (i = 0; i < hba->sli.sli4.XRICount; i++) {
7603 7704                  xrip->XRI = emlxs_sli4_index_to_xri(hba, i);
7604 7705  
7605 7706                  /* We don't use XRI==0, since it also represents an */
7606 7707                  /* uninitialized exchange */
7607 7708                  if (xrip->XRI == 0) {
7608 7709                          xrip++;
7609 7710                          continue;
7610 7711                  }
7611 7712  
↓ open down ↓ 2 lines elided ↑ open up ↑
7614 7715                      (hba->sli.sli4.mem_sgl_size / sizeof (ULP_SGE64));
7615 7716  
7616 7717                  /* Add xrip to end of free list */
7617 7718                  xrip->_b = hba->sli.sli4.XRIfree_b;
7618 7719                  hba->sli.sli4.XRIfree_b->_f = xrip;
7619 7720                  xrip->_f = (XRIobj_t *)&hba->sli.sli4.XRIfree_f;
7620 7721                  hba->sli.sli4.XRIfree_b = xrip;
7621 7722                  hba->sli.sli4.xrif_count++;
7622 7723  
7623 7724                  /* Allocate SGL for this xrip */
7624      -                buf_info = &xrip->SGList;
7625      -                buf_info->size = size;
7626      -                buf_info->flags =
7627      -                    FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32;
7628      -                buf_info->align = size;
7629      -                buf_info->phys = phys;
7630      -                buf_info->virt = (void *)virt;
7631      -                buf_info->data_handle = data_handle;
7632      -                buf_info->dma_handle = dma_handle;
     7725 +                xrip->SGSeg = mseg;
     7726 +                xrip->SGList = emlxs_mem_get(hba, xrip->SGSeg);
7633 7727  
7634      -                phys += size;
7635      -                virt += size;
     7728 +                if (xrip->SGList == NULL) {
     7729 +                        EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
     7730 +                            "Unable to allocate memory for SGL %d", i);
     7731 +                        goto failed;
     7732 +                }
7636 7733  
     7734 +                EMLXS_MPDATA_SYNC(xrip->SGList->dma_handle, 0,
     7735 +                    xrip->SGList->size, DDI_DMA_SYNC_FORDEV);
     7736 +
7637 7737                  xrip++;
7638 7738          }
7639 7739  
7640      -        /* 4K Alignment */
7641      -        align = (4096 - (phys%4096));
7642      -        phys += align;
7643      -        virt += align;
     7740 +        /* GPIO lock */
     7741 +        if (hba->model_info.flags & EMLXS_GPIO_LEDS)
     7742 +                mutex_init(&hba->gpio_lock, NULL, MUTEX_DRIVER, NULL);
7644 7743  
7645      -        /* RPI Header Templates */
7646      -        if (hba->sli.sli4.param.HDRR) {
7647      -                buf_info = &hba->sli.sli4.HeaderTmplate;
7648      -                bzero(buf_info, sizeof (MBUF_INFO));
7649      -                buf_info->size = hddr_size;
7650      -                buf_info->flags = FC_MBUF_DMA | FC_MBUF_DMA32;
7651      -                buf_info->align = ddi_ptob(hba->dip, 1L);
7652      -                buf_info->phys = phys;
7653      -                buf_info->virt = (void *)virt;
7654      -                buf_info->data_handle = data_handle;
7655      -                buf_info->dma_handle = dma_handle;
7656      -        }
7657      -
7658 7744  #ifdef FMA_SUPPORT
7659 7745          if (hba->sli.sli4.slim2.dma_handle) {
7660 7746                  if (emlxs_fm_check_dma_handle(hba,
7661 7747                      hba->sli.sli4.slim2.dma_handle)
7662 7748                      != DDI_FM_OK) {
7663 7749                          EMLXS_MSGF(EMLXS_CONTEXT,
7664 7750                              &emlxs_invalid_dma_handle_msg,
7665 7751                              "sli4_resource_alloc: hdl=%p",
7666 7752                              hba->sli.sli4.slim2.dma_handle);
7667 7753                          goto failed;
↓ open down ↓ 505 lines elided ↑ open up ↑
8173 8259  } /* emlxs_sli4_free_xri() */
8174 8260  
8175 8261  
8176 8262  static int
8177 8263  emlxs_sli4_post_sgl_pages(emlxs_hba_t *hba, MAILBOXQ *mbq)
8178 8264  {
8179 8265          MAILBOX4        *mb = (MAILBOX4 *)mbq;
8180 8266          emlxs_port_t    *port = &PPORT;
8181 8267          XRIobj_t        *xrip;
8182 8268          MATCHMAP        *mp;
8183      -        mbox_req_hdr_t  *hdr_req;
     8269 +        mbox_req_hdr_t  *hdr_req;
8184 8270          uint32_t        i;
8185 8271          uint32_t        cnt;
8186 8272          uint32_t        xri_cnt;
8187 8273          uint32_t        j;
8188 8274          uint32_t        size;
8189 8275          IOCTL_FCOE_CFG_POST_SGL_PAGES *post_sgl;
8190 8276  
8191 8277          bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
8192 8278          mbq->bp = NULL;
8193 8279          mbq->mbox_cmpl = NULL;
↓ open down ↓ 50 lines elided ↑ open up ↑
8244 8330                          post_sgl->params.request.xri_start = xrip->XRI;
8245 8331  
8246 8332                          xri_cnt = (size -
8247 8333                              sizeof (IOCTL_FCOE_CFG_POST_SGL_PAGES)) /
8248 8334                              sizeof (FCOE_SGL_PAGES);
8249 8335  
8250 8336                          for (i = 0; (i < xri_cnt) && cnt; i++) {
8251 8337                                  post_sgl->params.request.xri_count++;
8252 8338                                  post_sgl->params.request.pages[i].\
8253 8339                                      sgl_page0.addrLow =
8254      -                                    PADDR_LO(xrip->SGList.phys);
     8340 +                                    PADDR_LO(xrip->SGList->phys);
8255 8341                                  post_sgl->params.request.pages[i].\
8256 8342                                      sgl_page0.addrHigh =
8257      -                                    PADDR_HI(xrip->SGList.phys);
     8343 +                                    PADDR_HI(xrip->SGList->phys);
8258 8344  
8259 8345                                  cnt--;
8260 8346                                  xrip++;
8261 8347                          }
8262 8348  
8263 8349                          if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) !=
8264 8350                              MBX_SUCCESS) {
8265 8351                                  EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
8266 8352                                      "Unable to POST_SGL. Mailbox cmd=%x "
8267 8353                                      "status=%x XRI cnt:%d start:%d",
↓ open down ↓ 12 lines elided ↑ open up ↑
8280 8366          return (0);
8281 8367  
8282 8368  } /* emlxs_sli4_post_sgl_pages() */
8283 8369  
8284 8370  
8285 8371  static int
8286 8372  emlxs_sli4_post_hdr_tmplates(emlxs_hba_t *hba, MAILBOXQ *mbq)
8287 8373  {
8288 8374          MAILBOX4        *mb = (MAILBOX4 *)mbq;
8289 8375          emlxs_port_t    *port = &PPORT;
8290      -        uint32_t        j;
8291      -        uint32_t        k;
     8376 +        uint32_t        j;
     8377 +        uint32_t        k;
8292 8378          uint64_t        addr;
8293 8379          IOCTL_FCOE_POST_HDR_TEMPLATES *post_hdr;
8294 8380          uint16_t        num_pages;
8295 8381  
8296 8382          if (!(hba->sli.sli4.param.HDRR)) {
8297 8383                  return (0);
8298 8384          }
8299 8385  
8300 8386          /* Bytes per extent */
8301 8387          j = hba->sli.sli4.RPIExtSize * sizeof (RPIHdrTmplate_t);
↓ open down ↓ 363 lines elided ↑ open up ↑
8665 8751          /* This will wake any sleeping or polling threads */
8666 8752          emlxs_mb_fini(hba, NULL, MBX_TIMEOUT);
8667 8753  
8668 8754          /* Trigger adapter shutdown */
8669 8755          emlxs_thread_spawn(hba, emlxs_shutdown_thread, 0, 0);
8670 8756  
8671 8757          return;
8672 8758  
8673 8759  } /* emlxs_sli4_timer_check_mbox() */
8674 8760  
     8761 +static void
     8762 +emlxs_sli4_gpio_timer_start(emlxs_hba_t *hba)
     8763 +{
     8764 +        mutex_enter(&hba->gpio_lock);
8675 8765  
     8766 +        if (!hba->gpio_timer) {
     8767 +                hba->gpio_timer = timeout(emlxs_sli4_gpio_timer, (void *)hba,
     8768 +                    drv_usectohz(100000));
     8769 +        }
     8770 +
     8771 +        mutex_exit(&hba->gpio_lock);
     8772 +
     8773 +} /* emlxs_sli4_gpio_timer_start() */
     8774 +
     8775 +static void
     8776 +emlxs_sli4_gpio_timer_stop(emlxs_hba_t *hba)
     8777 +{
     8778 +        mutex_enter(&hba->gpio_lock);
     8779 +
     8780 +        if (hba->gpio_timer) {
     8781 +                (void) untimeout(hba->gpio_timer);
     8782 +                hba->gpio_timer = 0;
     8783 +        }
     8784 +
     8785 +        mutex_exit(&hba->gpio_lock);
     8786 +
     8787 +        delay(drv_usectohz(300000));
     8788 +} /* emlxs_sli4_gpio_timer_stop() */
     8789 +
     8790 +static void
     8791 +emlxs_sli4_gpio_timer(void *arg)
     8792 +{
     8793 +        emlxs_hba_t *hba = (emlxs_hba_t *)arg;
     8794 +
     8795 +        mutex_enter(&hba->gpio_lock);
     8796 +
     8797 +        if (hba->gpio_timer) {
     8798 +                emlxs_sli4_check_gpio(hba);
     8799 +                hba->gpio_timer = timeout(emlxs_sli4_gpio_timer, (void *)hba,
     8800 +                    drv_usectohz(100000));
     8801 +        }
     8802 +
     8803 +        mutex_exit(&hba->gpio_lock);
     8804 +} /* emlxs_sli4_gpio_timer() */
     8805 +
     8806 +static void
     8807 +emlxs_sli4_check_gpio(emlxs_hba_t *hba)
     8808 +{
     8809 +        hba->gpio_desired = 0;
     8810 +
     8811 +        if (hba->flag & FC_GPIO_LINK_UP) {
     8812 +                if (hba->io_active)
     8813 +                        hba->gpio_desired |= EMLXS_GPIO_ACT;
     8814 +
     8815 +                /* This is model specific to ATTO gen5 lancer cards */
     8816 +
     8817 +                switch (hba->linkspeed) {
     8818 +                        case LA_4GHZ_LINK:
     8819 +                                hba->gpio_desired |= EMLXS_GPIO_LO;
     8820 +                                break;
     8821 +
     8822 +                        case LA_8GHZ_LINK:
     8823 +                                hba->gpio_desired |= EMLXS_GPIO_HI;
     8824 +                                break;
     8825 +
     8826 +                        case LA_16GHZ_LINK:
     8827 +                                hba->gpio_desired |=
     8828 +                                    EMLXS_GPIO_LO | EMLXS_GPIO_HI;
     8829 +                                break;
     8830 +                }
     8831 +        }
     8832 +
     8833 +        if (hba->gpio_current != hba->gpio_desired) {
     8834 +                emlxs_port_t *port = &PPORT;
     8835 +                uint8_t pin;
     8836 +                uint8_t pinval;
     8837 +                MAILBOXQ *mbq;
     8838 +                uint32_t rval;
     8839 +
     8840 +                if (!emlxs_sli4_fix_gpio(hba, &pin, &pinval))
     8841 +                        return;
     8842 +
     8843 +                if ((mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX)) == NULL) {
     8844 +                        EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
     8845 +                            "Unable to allocate GPIO mailbox.");
     8846 +
     8847 +                        hba->gpio_bit = 0;
     8848 +                        return;
     8849 +                }
     8850 +
     8851 +                emlxs_mb_gpio_write(hba, mbq, pin, pinval);
     8852 +                mbq->mbox_cmpl = emlxs_sli4_fix_gpio_mbcmpl;
     8853 +
     8854 +                rval = emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_NOWAIT, 0);
     8855 +
     8856 +                if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
     8857 +                        EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
     8858 +                            "Unable to start GPIO mailbox.");
     8859 +
     8860 +                        hba->gpio_bit = 0;
     8861 +                        emlxs_mem_put(hba, MEM_MBOX, mbq);
     8862 +                        return;
     8863 +                }
     8864 +        }
     8865 +} /* emlxs_sli4_check_gpio */
     8866 +
     8867 +static uint32_t
     8868 +emlxs_sli4_fix_gpio(emlxs_hba_t *hba, uint8_t *pin, uint8_t *pinval)
     8869 +{
     8870 +        uint8_t dif = hba->gpio_desired ^ hba->gpio_current;
     8871 +        uint8_t bit;
     8872 +        uint8_t i;
     8873 +
     8874 +        /* Get out if no pins to set a GPIO request is pending */
     8875 +
     8876 +        if (dif == 0 || hba->gpio_bit)
     8877 +                return (0);
     8878 +
     8879 +        /* Fix one pin at a time */
     8880 +
     8881 +        bit = dif & -dif;
     8882 +        hba->gpio_bit = bit;
     8883 +        dif = hba->gpio_current ^ bit;
     8884 +
     8885 +        for (i = EMLXS_GPIO_PIN_LO; bit > 1; ++i) {
     8886 +                dif >>= 1;
     8887 +                bit >>= 1;
     8888 +        }
     8889 +
     8890 +        /* Pins are active low so invert the bit value */
     8891 +
     8892 +        *pin = hba->gpio_pin[i];
     8893 +        *pinval = ~dif & bit;
     8894 +
     8895 +        return (1);
     8896 +} /* emlxs_sli4_fix_gpio */
     8897 +
     8898 +static uint32_t
     8899 +emlxs_sli4_fix_gpio_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
     8900 +{
     8901 +        MAILBOX *mb;
     8902 +        uint8_t pin;
     8903 +        uint8_t pinval;
     8904 +
     8905 +        mb = (MAILBOX *)mbq;
     8906 +
     8907 +        mutex_enter(&hba->gpio_lock);
     8908 +
     8909 +        if (mb->mbxStatus == 0)
     8910 +                hba->gpio_current ^= hba->gpio_bit;
     8911 +
     8912 +        hba->gpio_bit = 0;
     8913 +
     8914 +        if (emlxs_sli4_fix_gpio(hba, &pin, &pinval)) {
     8915 +                emlxs_port_t *port = &PPORT;
     8916 +                MAILBOXQ *mbq;
     8917 +                uint32_t rval;
     8918 +
     8919 +                /*
     8920 +                 * We're not using the mb_retry routine here because for some
     8921 +                 * reason it doesn't preserve the completion routine. Just let
     8922 +                 * this mbox cmd fail to start here and run when the mailbox
     8923 +                 * is no longer busy.
     8924 +                 */
     8925 +
     8926 +                if ((mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX)) == NULL) {
     8927 +                        EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
     8928 +                            "Unable to allocate GPIO mailbox.");
     8929 +
     8930 +                        hba->gpio_bit = 0;
     8931 +                        goto done;
     8932 +                }
     8933 +
     8934 +                emlxs_mb_gpio_write(hba, mbq, pin, pinval);
     8935 +                mbq->mbox_cmpl = emlxs_sli4_fix_gpio_mbcmpl;
     8936 +
     8937 +                rval = emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_NOWAIT, 0);
     8938 +
     8939 +                if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
     8940 +                        EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
     8941 +                            "Unable to start GPIO mailbox.");
     8942 +
     8943 +                        hba->gpio_bit = 0;
     8944 +                        emlxs_mem_put(hba, MEM_MBOX, mbq);
     8945 +                        goto done;
     8946 +                }
     8947 +        }
     8948 +
     8949 +done:
     8950 +        mutex_exit(&hba->gpio_lock);
     8951 +
     8952 +        return (0);
     8953 +}
     8954 +
8676 8955  extern void
8677 8956  emlxs_data_dump(emlxs_port_t *port, char *str, uint32_t *iptr, int cnt, int err)
8678 8957  {
8679 8958          void *msg;
8680 8959  
8681 8960          if (!port || !str || !iptr || !cnt) {
8682 8961                  return;
8683 8962          }
8684 8963  
8685 8964          if (err) {
↓ open down ↓ 279 lines elided ↑ open up ↑
8965 9244          return (rval);
8966 9245  
8967 9246  } /* emlxs_sli4_unreg_node() */
8968 9247  
8969 9248  
8970 9249  extern uint32_t
8971 9250  emlxs_sli4_unreg_all_nodes(emlxs_port_t *port)
8972 9251  {
8973 9252          NODELIST        *nlp;
8974 9253          int             i;
8975      -        uint32_t        found;
     9254 +        uint32_t        found;
8976 9255  
8977 9256          /* Set the node tags */
8978 9257          /* We will process all nodes with this tag */
8979 9258          rw_enter(&port->node_rwlock, RW_READER);
8980 9259          found = 0;
8981 9260          for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
8982 9261                  nlp = port->node_table[i];
8983 9262                  while (nlp != NULL) {
8984 9263                          found = 1;
8985 9264                          nlp->nlp_tag = 1;
↓ open down ↓ 120 lines elided ↑ open up ↑
9106 9385                  break;
9107 9386          case 8:
9108 9387                  hba->linkspeed = LA_8GHZ_LINK;
9109 9388                  break;
9110 9389          case 10:
9111 9390                  hba->linkspeed = LA_10GHZ_LINK;
9112 9391                  break;
9113 9392          case 16:
9114 9393                  hba->linkspeed = LA_16GHZ_LINK;
9115 9394                  break;
     9395 +        case 32:
     9396 +                hba->linkspeed = LA_32GHZ_LINK;
     9397 +                break;
9116 9398          default:
9117 9399                  EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
9118 9400                      "sli4_handle_fc_link_att: Unknown link speed=%x.",
9119 9401                      cqe->un.fc.port_speed);
9120 9402                  hba->linkspeed = 0;
9121 9403                  break;
9122 9404          }
9123 9405  
9124 9406          /* Set qos_linkspeed */
9125 9407          hba->qos_linkspeed = cqe->un.fc.link_speed;
↓ open down ↓ 407 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX