Emulex Logo
OneCoreā„¢ Storage SDK Release 11.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sli4.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2018, Emulex
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  * may be used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 /**
34  * @defgroup sli SLI-4 Base APIs
35  */
36 
37 /**
38  * @file
39  * All common (i.e. transport-independent) SLI-4 functions are implemented
40  * in this file.
41  */
42 
43 #include "sli4.h"
44 
45 #include "sli4_fc.h"
46 
47 #include "ocs.h"
48 #if defined(OCS_INCLUDE_DEBUG)
49 #include "ocs_debug.h"
50 #endif
51 
52 #define SLI4_BMBX_DELAY_US 1000 /* 1 ms */
53 #define SLI4_INIT_PORT_DELAY_US 10000 /* 10 ms */
54 
55 static int32_t sli_fw_init(sli4_t *);
56 static int32_t sli_fw_term(sli4_t *);
57 static int32_t sli_sliport_control(sli4_t *sli4, uint32_t endian);
58 static int32_t sli_cmd_fw_deinitialize(sli4_t *, void *, size_t);
59 static int32_t sli_cmd_fw_initialize(sli4_t *, void *, size_t);
60 static int32_t sli_queue_doorbell(sli4_t *, sli4_queue_t *);
61 static uint8_t sli_queue_entry_is_valid(sli4_queue_t *, uint8_t *, uint8_t);
62 
63 const uint8_t sli4_fw_initialize[] = {
64  0xff, 0x12, 0x34, 0xff,
65  0xff, 0x56, 0x78, 0xff,
66 };
67 
68 const uint8_t sli4_fw_deinitialize[] = {
69  0xff, 0xaa, 0xbb, 0xff,
70  0xff, 0xcc, 0xdd, 0xff,
71 };
72 
73 typedef struct {
74  uint32_t rev_id;
75  uint32_t family; /* generation */
79 
84  { 0x00, 4, SLI4_ASIC_TYPE_SKYHAWK, SLI4_ASIC_REV_A0}, // not documented
97 
99 };
100 
101 /*
102  * @brief Convert queue type enum (SLI_QTYPE_*) into a string.
103  */
104 const char *SLI_QNAME[] = {
105  "Event Queue",
106  "Completion Queue",
107  "Mailbox Queue",
108  "Work Queue",
109  "Receive Queue",
110  "Undefined"
111 };
112 
113 /**
114  * @brief Define the mapping of registers to their BAR and offset.
115  *
116  * @par Description
117  * Although SLI-4 specification defines a common set of registers, their locations
118  * (both BAR and offset) depend on the interface type. This array maps a register
119  * enum to an array of BAR/offset pairs indexed by the interface type. For
120  * example, to access the bootstrap mailbox register on an interface type 0
121  * device, code can refer to the offset using regmap[SLI4_REG_BMBX][0].offset.
122  *
123  * @b Note: A value of UINT32_MAX for either the register set (rset) or offset (off)
124  * indicates an invalid mapping.
125  */
127  // SLI4_REG_BMBX
128  {
129  { 2, SLI4_BMBX_REG }, { 0, SLI4_BMBX_REG }, { 0, SLI4_BMBX_REG }, { 0, SLI4_BMBX_REG },
130  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX } , { 0, SLI4_BMBX_REG },
131  },
132  // SLI4_REG_EQ_DOORBELL
133  {
136  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX },
138  },
139  // SLI4_REG_CQ_DOORBELL
140  {
143  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX },
145  },
146  // SLI4_REG_FCOE_RQ_DOORBELL
147  {
149  { 0, SLI4_RQ_DOORBELL_REG }, { UINT32_MAX, UINT32_MAX },
150  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX },
152  },
153  // SLI4_REG_IO_WQ_DOORBELL
154  {
156  { 0, SLI4_IO_WQ_DOORBELL_REG }, { UINT32_MAX, UINT32_MAX },
157  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX },
159  },
160  // SLI4_REG_MQ_DOORBELL
161  {
164  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX },
166  },
167  // SLI4_REG_PHYSDEV_CONTROL
168  {
169  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { 0, SLI4_PHSDEV_CONTROL_REG_236 }, { 0, SLI4_PHSDEV_CONTROL_REG_236 },
170  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { 0, SLI4_PHSDEV_CONTROL_REG_236 },
171  },
172  // SLI4_REG_SLIPORT_CONTROL
173  {
174  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { 0, SLI4_SLIPORT_CONTROL_REG }, { UINT32_MAX, UINT32_MAX },
175  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { 0, SLI4_SLIPORT_CONTROL_REG },
176  },
177  // SLI4_REG_SLIPORT_ERROR1
178  {
179  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { 0, SLI4_SLIPORT_ERROR1 }, { UINT32_MAX, UINT32_MAX },
180  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { 0, SLI4_SLIPORT_ERROR1 },
181  },
182  // SLI4_REG_SLIPORT_ERROR2
183  {
184  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { 0, SLI4_SLIPORT_ERROR2 }, { UINT32_MAX, UINT32_MAX },
185  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { 0, SLI4_SLIPORT_ERROR2 },
186  },
187  // SLI4_REG_SLIPORT_SEMAPHORE
188  {
191  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX },
193  },
194  // SLI4_REG_SLIPORT_STATUS
195  {
196  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { 0, SLI4_PORT_STATUS_REG_236 }, { 0, SLI4_PORT_STATUS_REG_236 },
197  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { 0, SLI4_PORT_STATUS_REG_236 },
198  },
199  // SLI4_REG_UERR_MASK_HI
200  {
201  { 0, SLI4_UERR_MASK_HIGH_REG }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX },
202  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }
203  },
204  // SLI4_REG_UERR_MASK_LO
205  {
206  { 0, SLI4_UERR_MASK_LOW_REG }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX },
207  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }
208  },
209  // SLI4_REG_UERR_STATUS_HI
210  {
211  { 0, SLI4_UERR_STATUS_HIGH_REG }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX },
212  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }
213  },
214  // SLI4_REG_UERR_STATUS_LO
215  {
216  { 0, SLI4_UERR_STATUS_LOW_REG }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX },
217  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }
218  },
219  // SLI4_REG_SW_UE_CSR1
220  {
221  { 1, SLI4_SW_UE_CSR1}, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX },
222  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }
223  },
224  // SLI4_REG_SW_UE_CSR2
225  {
226  { 1, SLI4_SW_UE_CSR2}, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX },
227  { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }, { UINT32_MAX, UINT32_MAX }
228  },
229 };
230 
231 /**
232  * @brief Read the given SLI register.
233  *
234  * @param sli Pointer to the SLI context.
235  * @param reg Register name enum.
236  *
237  * @return Returns the register value.
238  */
239 uint32_t
241 {
242  const sli4_reg_t *r = &(regmap[reg][sli->if_type]);
243 
244  // sanity check
245  if ((UINT32_MAX == r->rset) || (UINT32_MAX == r->off)) {
246  ocs_log_err(sli->os, "regname %d not defined for if_type %d\n", reg, sli->if_type);
247  return UINT32_MAX;
248  }
249 
250  return ocs_reg_read32(sli->os, r->rset, r->off);
251 }
252 
253 /**
254  * @brief Write the value to the given SLI register.
255  *
256  * @param sli Pointer to the SLI context.
257  * @param reg Register name enum.
258  * @param val Value to write.
259  *
260  * @return None.
261  */
262 void
263 sli_reg_write(sli4_t *sli, sli4_regname_e reg, uint32_t val)
264 {
265  const sli4_reg_t *r = &(regmap[reg][sli->if_type]);
266 
267  // sanity check
268  if ((UINT32_MAX == r->rset) || (UINT32_MAX == r->off)) {
269  ocs_log_err(sli->os, "regname %d not defined for if_type %d\n", reg, sli->if_type);
270  return;
271  }
272 
273  ocs_reg_write32(sli->os, r->rset, r->off, val);
274 }
275 
276 /**
277  * @brief Check if the SLI_INTF register is valid.
278  *
279  * @param val 32-bit SLI_INTF register value.
280  *
281  * @return Returns 0 on success, or a non-zero value on failure.
282  */
283 static uint8_t
284 sli_intf_valid_check(uint32_t val)
285 {
287 }
288 
289 /**
290  * @brief Retrieve the SLI revision level.
291  *
292  * @param val 32-bit SLI_INTF register value.
293  *
294  * @return Returns the SLI revision level.
295  */
296 static uint8_t
298 {
300 }
301 
302 static uint8_t
303 sli_intf_sli_family(uint32_t val)
304 {
306 }
307 
308 /**
309  * @brief Retrieve the SLI interface type.
310  *
311  * @param val 32-bit SLI_INTF register value.
312  *
313  * @return Returns the SLI interface type.
314  */
315 static uint8_t
316 sli_intf_if_type(uint32_t val)
317 {
319 }
320 
321 /**
322  * @brief Retrieve PCI revision ID.
323  *
324  * @param val 32-bit PCI CLASS_REVISION register value.
325  *
326  * @return Returns the PCI revision ID.
327  */
328 static uint8_t
329 sli_pci_rev_id(uint32_t val)
330 {
331  return ((val >> SLI4_PCI_REV_ID_SHIFT) & SLI4_PCI_REV_ID_MASK);
332 }
333 
334 /**
335  * @brief retrieve SLI ASIC generation
336  *
337  * @param val 32-bit SLI_ASIC_ID register value
338  *
339  * @return SLI ASIC generation
340  */
341 static uint8_t
342 sli_asic_gen(uint32_t val)
343 {
344  return ((val >> SLI4_ASIC_GEN_SHIFT) & SLI4_ASIC_GEN_MASK);
345 }
346 
347 /**
348  * @brief Wait for the bootstrap mailbox to report "ready".
349  *
350  * @param sli4 SLI context pointer.
351  * @param msec Number of milliseconds to wait.
352  *
353  * @return Returns 0 if BMBX is ready, or non-zero otherwise (i.e. time out occurred).
354  */
355 static int32_t
356 sli_bmbx_wait(sli4_t *sli4, uint32_t msec)
357 {
358  uint32_t val = 0;
359 
360  do {
361  ocs_delay_usec(SLI4_BMBX_DELAY_US); // 1 ms
362  val = sli_reg_read(sli4, SLI4_REG_BMBX);
363  msec--;
364  } while(msec && !(val & SLI4_BMBX_RDY));
365 
366  return(!(val & SLI4_BMBX_RDY));
367 }
368 
369 /**
370  * @brief Write bootstrap mailbox.
371  *
372  * @param sli4 SLI context pointer.
373  *
374  * @return Returns 0 if command succeeded, or non-zero otherwise.
375  */
376 static int32_t
378 {
379  uint32_t val = 0;
380 
381  // write buffer location to bootstrap mailbox register
382  ocs_dma_sync(&sli4->bmbx, OCS_DMASYNC_PREWRITE);
383  val = SLI4_BMBX_WRITE_HI(sli4->bmbx.phys);
384  sli_reg_write(sli4, SLI4_REG_BMBX, val);
385 
386  if (sli_bmbx_wait(sli4, SLI4_BMBX_DELAY_US)) {
387  ocs_log_crit(sli4->os, "BMBX WRITE_HI failed\n");
388  return -1;
389  }
390  val = SLI4_BMBX_WRITE_LO(sli4->bmbx.phys);
391  sli_reg_write(sli4, SLI4_REG_BMBX, val);
392 
393  // wait for SLI Port to set ready bit
394  return sli_bmbx_wait(sli4, SLI4_BMBX_TIMEOUT_MSEC/*XXX*/);
395 }
396 
397 #if defined(OCS_INCLUDE_DEBUG)
398 /**
399  * @ingroup sli
400  * @brief Dump BMBX mailbox command.
401  *
402  * @par Description
403  * Convenience function for dumping BMBX mailbox commands. Takes
404  * into account which mailbox command is given since SLI_CONFIG
405  * commands are special.
406  *
407  * @b Note: This function takes advantage of
408  * the one-command-at-a-time nature of the BMBX to be able to
409  * display non-embedded SLI_CONFIG commands. This will not work
410  * for mailbox commands on the MQ. Luckily, all current non-emb
411  * mailbox commands go through the BMBX.
412  *
413  * @param sli4 SLI context pointer.
414  * @param mbx Pointer to mailbox command to dump.
415  * @param prefix Prefix for dump label.
416  *
417  * @return None.
418  */
419 static void
420 sli_dump_bmbx_command(sli4_t *sli4, void *mbx, const char *prefix)
421 {
422  uint32_t size = 0;
423  char label[64];
424  uint32_t i;
425  // Mailbox diagnostic logging
427 
429  return;
430  }
431 
433  sli4_cmd_sli_config_t *sli_config = (sli4_cmd_sli_config_t *)hdr;
434  sli4_req_hdr_t *sli_config_hdr;
435  if (sli_config->emb) {
436  ocs_snprintf(label, sizeof(label), "%s (emb)", prefix);
437 
438  /* if embedded, dump entire command */
439  sli_config_hdr = (sli4_req_hdr_t *)sli_config->payload.embed;
440  size = sizeof(*sli_config) - sizeof(sli_config->payload) +
441  sli_config_hdr->request_length + (4*sizeof(uint32_t));
442  ocs_dump32(OCS_DEBUG_ENABLE_MQ_DUMP, sli4->os, label,
443  (uint8_t *)sli4->bmbx.virt, size);
444  } else {
446  ocs_snprintf(label, sizeof(label), "%s (non-emb hdr)", prefix);
447 
448  /* if non-embedded, break up into two parts: SLI_CONFIG hdr
449  and the payload(s) */
450  size = sizeof(*sli_config) - sizeof(sli_config->payload) + (12 * sli_config->pmd_count);
451  ocs_dump32(OCS_DEBUG_ENABLE_MQ_DUMP, sli4->os, label,
452  (uint8_t *)sli4->bmbx.virt, size);
453 
454  /* as sanity check, make sure first PMD matches what was saved */
455  pmd = &sli_config->payload.mem;
456  if ((pmd->address_high == ocs_addr32_hi(sli4->bmbx_non_emb_pmd->phys)) &&
457  (pmd->address_low == ocs_addr32_lo(sli4->bmbx_non_emb_pmd->phys))) {
458  for (i = 0; i < sli_config->pmd_count; i++, pmd++) {
459  sli_config_hdr = sli4->bmbx_non_emb_pmd->virt;
460  ocs_snprintf(label, sizeof(label), "%s (non-emb pay[%d])",
461  prefix, i);
462  ocs_dump32(OCS_DEBUG_ENABLE_MQ_DUMP, sli4->os, label,
463  (uint8_t *)sli4->bmbx_non_emb_pmd->virt,
464  sli_config_hdr->request_length + (4*sizeof(uint32_t)));
465  }
466  } else {
467  ocs_log_debug(sli4->os, "pmd addr does not match pmd:%x %x (%x %x)\n",
468  pmd->address_high, pmd->address_low,
469  ocs_addr32_hi(sli4->bmbx_non_emb_pmd->phys),
470  ocs_addr32_lo(sli4->bmbx_non_emb_pmd->phys));
471  }
472 
473  }
474  } else {
475  /* not an SLI_CONFIG command, just display first 64 bytes, like we do
476  for MQEs */
477  size = 64;
478  ocs_dump32(OCS_DEBUG_ENABLE_MQ_DUMP, sli4->os, prefix,
479  (uint8_t *)mbx, size);
480  }
481 }
482 #endif
483 
484 /**
485  * @ingroup sli
486  * @brief Submit a command to the bootstrap mailbox and check the status.
487  *
488  * @param sli4 SLI context pointer.
489  *
490  * @return Returns 0 on success, or a non-zero value on failure.
491  */
492 int32_t
494 {
495  void *cqe = (uint8_t *)sli4->bmbx.virt + SLI4_BMBX_SIZE;
496 
497 #if defined(OCS_INCLUDE_DEBUG)
498  sli_dump_bmbx_command(sli4, sli4->bmbx.virt, "bmbx cmd");
499 #endif
500 
501  if (sli_fw_error_status(sli4) > 0) {
502  ocs_log_crit(sli4->os, "Chip is in an error state - Mailbox "
503  "command rejected status=%#x error1=%#x error2=%#x\n",
507  return -1;
508  }
509 
510  if (sli_bmbx_write(sli4)) {
511  ocs_log_crit(sli4->os, "bootstrap mailbox write fail phys=%p reg=%#x\n",
512  (void*)sli4->bmbx.phys,
513  sli_reg_read(sli4, SLI4_REG_BMBX));
514  return -1;
515  }
516 
517  // check completion queue entry status
518  ocs_dma_sync(&sli4->bmbx, OCS_DMASYNC_POSTREAD);
519  if (((sli4_mcqe_t *)cqe)->val) {
520 #if defined(OCS_INCLUDE_DEBUG)
521  sli_dump_bmbx_command(sli4, sli4->bmbx.virt, "bmbx cmpl");
522  ocs_dump32(OCS_DEBUG_ENABLE_CQ_DUMP, sli4->os, "bmbx cqe", cqe, sizeof(sli4_mcqe_t));
523 #endif
524  return sli_cqe_mq(cqe);
525  } else {
526  ocs_log_err(sli4->os, "invalid or wrong type\n");
527  return -1;
528  }
529 }
530 
531 /****************************************************************************
532  * Messages
533  */
534 
535 /**
536  * @ingroup sli
537  * @brief Write a CONFIG_LINK command to the provided buffer.
538  *
539  * @param sli4 SLI context pointer.
540  * @param buf Virtual pointer to the destination buffer.
541  * @param size Buffer size, in bytes.
542  *
543  * @return Returns the number of bytes written.
544  */
545 int32_t
546 sli_cmd_config_link(sli4_t *sli4, void *buf, size_t size)
547 {
548  sli4_cmd_config_link_t *config_link = buf;
549 
550  ocs_memset(buf, 0, size);
551 
553 
554  if (ocs_bbcr_enabled(sli4->os)) {
555  config_link->cscn = 1;
556  config_link->bbscn = sli4->config.bbscn_def;
557  }
558 
559  ocs_log_debug(sli4->os, "config_link->bbscn: %d\n", config_link->bbscn);
560 
561  /* Port interprets zero in a field as "use default value" */
562 
563  return sizeof(sli4_cmd_config_link_t);
564 }
565 
566 /**
567  * @ingroup sli
568  * @brief Write a DOWN_LINK command to the provided buffer.
569  *
570  * @param sli4 SLI context pointer.
571  * @param buf Virtual pointer to the destination buffer.
572  * @param size Buffer size, in bytes.
573  *
574  * @return Returns the number of bytes written.
575  */
576 int32_t
577 sli_cmd_down_link(sli4_t *sli4, void *buf, size_t size)
578 {
579  sli4_mbox_command_header_t *hdr = buf;
580 
581  ocs_memset(buf, 0, size);
582 
584 
585  /* Port interprets zero in a field as "use default value" */
586 
587  return sizeof(sli4_mbox_command_header_t);
588 }
589 
590 /**
591  * @ingroup sli
592  * @brief Write a DUMP Type 4 command to the provided buffer.
593  *
594  * @param sli4 SLI context pointer.
595  * @param buf Virtual pointer to the destination buffer.
596  * @param size Buffer size, in bytes.
597  * @param wki The well known item ID.
598  *
599  * @return Returns the number of bytes written.
600  */
601 int32_t
602 sli_cmd_dump_type4(sli4_t *sli4, void *buf, size_t size, uint16_t wki)
603 {
604  sli4_cmd_dump4_t *cmd = buf;
605 
606  ocs_memset(buf, 0, size);
607 
609  cmd->type = 4;
610  cmd->wki_selection = wki;
611  return sizeof(sli4_cmd_dump4_t);
612 }
613 
614 /**
615  * @ingroup sli
616  * @brief Write a COMMON_READ_TRANSCEIVER_DATA command.
617  *
618  * @param sli4 SLI context.
619  * @param buf Destination buffer for the command.
620  * @param size Buffer size, in bytes.
621  * @param page_num The page of SFP data to retrieve (0xa0 or 0xa2).
622  * @param dma DMA structure from which the data will be copied.
623  *
624  * @note This creates a Version 0 message.
625  *
626  * @return Returns the number of bytes written.
627  */
628 int32_t
629 sli_cmd_common_read_transceiver_data(sli4_t *sli4, void *buf, size_t size, uint32_t page_num,
630  ocs_dma_t *dma)
631 {
633  uint32_t sli_config_off = 0;
634  uint32_t payload_size;
635 
636  if (dma == NULL) {
637  /* Payload length must accomodate both request and response */
638  payload_size = max(sizeof(sli4_req_common_read_transceiver_data_t),
640  } else {
641  payload_size = dma->size;
642  }
643 
644  if (sli4->port_type == SLI4_PORT_TYPE_FC) {
645  sli_config_off = sli_cmd_sli_config(sli4, buf, size, payload_size, dma);
646  }
647 
648  if (dma == NULL) {
649  req = (sli4_req_common_read_transceiver_data_t *)((uint8_t *)buf + sli_config_off);
650  } else {
651  req = (sli4_req_common_read_transceiver_data_t *)dma->virt;
652  ocs_memset(req, 0, dma->size);
653  }
654 
657  req->hdr.request_length = payload_size - sizeof(sli4_req_hdr_t);
658 
659  req->page_number = page_num;
660  req->port = sli4->physical_port;
661 
662  return(sli_config_off + sizeof(sli4_req_common_read_transceiver_data_t));
663 }
664 
665 /**
666  * @ingroup sli
667  * @brief Write a READ_LINK_STAT command to the provided buffer.
668  *
669  * @param sli4 SLI context pointer.
670  * @param buf Virtual pointer to the destination buffer.
671  * @param size Buffer size, in bytes.
672  * @param req_ext_counters If TRUE, then the extended counters will be requested.
673  * @param clear_overflow_flags If TRUE, then overflow flags will be cleared.
674  * @param clear_all_counters If TRUE, the counters will be cleared.
675  *
676  * @return Returns the number of bytes written.
677  */
678 int32_t
679 sli_cmd_read_link_stats(sli4_t *sli4, void *buf, size_t size,
680  uint8_t req_ext_counters,
681  uint8_t clear_overflow_flags,
682  uint8_t clear_all_counters)
683 {
684  sli4_cmd_read_link_stats_t *cmd = buf;
685 
686  ocs_memset(buf, 0, size);
687 
689  cmd->rec = req_ext_counters;
690  cmd->clrc = clear_all_counters;
691  cmd->clof = clear_overflow_flags;
692  return sizeof(sli4_cmd_read_link_stats_t);
693 }
694 
695 /**
696  * @ingroup sli
697  * @brief Write a READ_STATUS command to the provided buffer.
698  *
699  * @param sli4 SLI context pointer.
700  * @param buf Virtual pointer to the destination buffer.
701  * @param size Buffer size, in bytes.
702  * @param clear_counters If TRUE, the counters will be cleared.
703  *
704  * @return Returns the number of bytes written.
705  */
706 int32_t
707 sli_cmd_read_status(sli4_t *sli4, void *buf, size_t size,
708  uint8_t clear_counters)
709 {
710  sli4_cmd_read_status_t *cmd = buf;
711 
712  ocs_memset(buf, 0, size);
713 
715  cmd->cc = clear_counters;
716  return sizeof(sli4_cmd_read_status_t);
717 }
718 
719 /**
720  * @brief Write a FW_DEINITIALIZE command to the provided buffer.
721  *
722  * @param sli4 SLI context pointer.
723  * @param buf Virtual pointer to the destination buffer.
724  * @param size Buffer size, in bytes.
725  *
726  * @return Returns the number of bytes written.
727  */
728 static int32_t
729 sli_cmd_fw_deinitialize(sli4_t *sli4, void *buf, size_t size)
730 {
731 
732  // TODO assert sizeof(sli4_fw_initialize) <= size
733  ocs_memset(buf, 0, size);
734  ocs_memcpy(buf, sli4_fw_deinitialize, sizeof(sli4_fw_deinitialize));
735 
736  return sizeof(sli4_fw_deinitialize);
737 }
738 
739 /**
740  * @brief Write a FW_INITIALIZE command to the provided buffer.
741  *
742  * @param sli4 SLI context pointer.
743  * @param buf Virtual pointer to the destination buffer.
744  * @param size Buffer size, in bytes.
745  *
746  * @return Returns the number of bytes written.
747  */
748 static int32_t
749 sli_cmd_fw_initialize(sli4_t *sli4, void *buf, size_t size)
750 {
751 
752  // TODO assert sizeof(sli4_fw_initialize) <= size
753  ocs_memset(buf, 0, size);
754  ocs_memcpy(buf, sli4_fw_initialize, sizeof(sli4_fw_initialize));
755 
756  return sizeof(sli4_fw_initialize);
757 }
758 
759 /**
760  * @ingroup sli
761  * @brief Write an INIT_LINK command to the provided buffer.
762  *
763  * @param sli4 SLI context pointer.
764  * @param buf Virtual pointer to the destination buffer.
765  * @param size Buffer size, in bytes.
766  * @param speed Link speed.
767  * @param reset_alpa For native FC, this is the selective reset AL_PA
768  *
769  * @return Returns the number of bytes written.
770  */
771 int32_t
772 sli_cmd_init_link(sli4_t *sli4, void *buf, size_t size, uint32_t speed, uint8_t reset_alpa)
773 {
774  sli4_cmd_init_link_t *init_link = buf;
775 
776  ocs_memset(buf, 0, size);
777 
779 
780  /* Most fields only have meaning for FC links */
781  if (sli4->config.topology != SLI4_READ_CFG_TOPO_FCOE) {
782  init_link->selective_reset_al_pa = reset_alpa;
783  init_link->link_flags.loopback = FALSE;
784 
785  init_link->link_speed_selection_code = speed;
786  switch (speed) {
787  case FC_LINK_SPEED_1G:
788  case FC_LINK_SPEED_2G:
789  case FC_LINK_SPEED_4G:
790  case FC_LINK_SPEED_8G:
791  case FC_LINK_SPEED_16G:
792  case FC_LINK_SPEED_32G:
793  init_link->link_flags.fixed_speed = TRUE;
794  break;
795  case FC_LINK_SPEED_10G:
796  ocs_log_test(sli4->os, "unsupported FC speed %d\n", speed);
797  return 0;
798  }
799 
800  switch (sli4->config.topology) {
802  // Attempt P2P but failover to FC-AL
803  init_link->link_flags.enable_topology_failover = TRUE;
805  break;
808  if ((init_link->link_speed_selection_code == FC_LINK_SPEED_16G) ||
810  ocs_log_test(sli4->os, "unsupported FC-AL speed %d\n", speed);
811  return 0;
812  }
813  break;
815  init_link->link_flags.topology = FC_TOPOLOGY_P2P;
816  break;
817  default:
818  ocs_log_test(sli4->os, "unsupported topology %#x\n", sli4->config.topology);
819  return 0;
820  }
821 
822  init_link->link_flags.unfair = FALSE;
823  init_link->link_flags.skip_lirp_lilp = FALSE;
824  init_link->link_flags.gen_loop_validity_check = FALSE;
825  init_link->link_flags.skip_lisa = FALSE;
826  init_link->link_flags.select_hightest_al_pa = FALSE;
827  }
828 
829  return sizeof(sli4_cmd_init_link_t);
830 }
831 
832 /**
833  * @ingroup sli
834  * @brief Write an INIT_VFI command to the provided buffer.
835  *
836  * @param sli4 SLI context pointer.
837  * @param buf Virtual pointer to the destination buffer.
838  * @param size Buffer size, in bytes.
839  * @param vfi VFI
840  * @param fcfi FCFI
841  * @param vpi VPI (Set to -1 if unused.)
842  *
843  * @return Returns the number of bytes written.
844  */
845 int32_t
846 sli_cmd_init_vfi(sli4_t *sli4, void *buf, size_t size, uint16_t vfi,
847  uint16_t fcfi, uint16_t vpi)
848 {
849  sli4_cmd_init_vfi_t *init_vfi = buf;
850 
851  ocs_memset(buf, 0, size);
852 
854 
855  init_vfi->vfi = vfi;
856  init_vfi->fcfi = fcfi;
857 
858  /*
859  * If the VPI is valid, initialize it at the same time as
860  * the VFI
861  */
862  if (0xffff != vpi) {
863  init_vfi->vp = TRUE;
864  init_vfi->vpi = vpi;
865  }
866 
867  return sizeof(sli4_cmd_init_vfi_t);
868 }
869 
870 /**
871  * @ingroup sli
872  * @brief Write an INIT_VPI command to the provided buffer.
873  *
874  * @param sli4 SLI context pointer.
875  * @param buf Virtual pointer to the destination buffer.
876  * @param size Buffer size, in bytes.
877  * @param vpi VPI allocated.
878  * @param vfi VFI associated with this VPI.
879  *
880  * @return Returns the number of bytes written.
881  */
882 int32_t
883 sli_cmd_init_vpi(sli4_t *sli4, void *buf, size_t size, uint16_t vpi, uint16_t vfi)
884 {
885  sli4_cmd_init_vpi_t *init_vpi = buf;
886 
887  ocs_memset(buf, 0, size);
888 
890  init_vpi->vpi = vpi;
891  init_vpi->vfi = vfi;
892 
893  return sizeof(sli4_cmd_init_vpi_t);
894 }
895 
896 /**
897  * @ingroup sli
898  * @brief Write a POST_XRI command to the provided buffer.
899  *
900  * @param sli4 SLI context pointer.
901  * @param buf Virtual pointer to the destination buffer.
902  * @param size Buffer size, in bytes.
903  * @param xri_base Starting XRI value for range of XRI given to SLI Port.
904  * @param xri_count Number of XRIs provided to the SLI Port.
905  *
906  * @return Returns the number of bytes written.
907  */
908 int32_t
909 sli_cmd_post_xri(sli4_t *sli4, void *buf, size_t size, uint16_t xri_base, uint16_t xri_count)
910 {
911  sli4_cmd_post_xri_t *post_xri = buf;
912 
913  ocs_memset(buf, 0, size);
914 
916  post_xri->xri_base = xri_base;
917  post_xri->xri_count = xri_count;
918 
919  if ((!sli_get_auto_xfer_rdy_capable(sli4)) && (!sli_get_tow_capable(sli4))) {
920  post_xri->enx = TRUE;
921  post_xri->val = TRUE;
922  }
923 
924  return sizeof(sli4_cmd_post_xri_t);
925 }
926 
927 /**
928  * @ingroup sli
929  * @brief Write a RELEASE_XRI command to the provided buffer.
930  *
931  * @param sli4 SLI context pointer.
932  * @param buf Virtual pointer to the destination buffer.
933  * @param size Buffer size, in bytes.
934  * @param num_xri The number of XRIs to be released.
935  *
936  * @return Returns the number of bytes written.
937  */
938 int32_t
939 sli_cmd_release_xri(sli4_t *sli4, void *buf, size_t size, uint8_t num_xri)
940 {
941  sli4_cmd_release_xri_t *release_xri = buf;
942 
943  ocs_memset(buf, 0, size);
944 
946  release_xri->xri_count = num_xri;
947 
948  return sizeof(sli4_cmd_release_xri_t);
949 }
950 
951 /**
952  * @brief Write a READ_CONFIG command to the provided buffer.
953  *
954  * @param sli4 SLI context pointer.
955  * @param buf Virtual pointer to the destination buffer.
956  * @param size Buffer size, in bytes
957  *
958  * @return Returns the number of bytes written.
959  */
960 int32_t
961 sli_cmd_read_config(sli4_t *sli4, void *buf, size_t size)
962 {
963  sli4_cmd_read_config_t *read_config = buf;
964 
965  ocs_memset(buf, 0, size);
966 
968 
969  return sizeof(sli4_cmd_read_config_t);
970 }
971 
972 /**
973  * @brief Write a READ_NVPARMS command to the provided buffer.
974  *
975  * @param sli4 SLI context pointer.
976  * @param buf Virtual pointer to the destination buffer.
977  * @param size Buffer size, in bytes.
978  *
979  * @return Returns the number of bytes written.
980  */
981 int32_t
982 sli_cmd_read_nvparms(sli4_t *sli4, void *buf, size_t size)
983 {
984  sli4_cmd_read_nvparms_t *read_nvparms = buf;
985 
986  ocs_memset(buf, 0, size);
987 
989 
990  return sizeof(sli4_cmd_read_nvparms_t);
991 }
992 
993 /**
994  * @brief Write a WRITE_NVPARMS command to the provided buffer.
995  *
996  * @param sli4 SLI context pointer.
997  * @param buf Virtual pointer to the destination buffer.
998  * @param size Buffer size, in bytes.
999  * @param wwpn WWPN to write - pointer to array of 8 uint8_t.
1000  * @param wwnn WWNN to write - pointer to array of 8 uint8_t.
1001  * @param hard_alpa Hard ALPA to write.
1002  * @param preferred_d_id Preferred D_ID to write.
1003  *
1004  * @return Returns the number of bytes written.
1005  */
1006 int32_t
1007 sli_cmd_write_nvparms(sli4_t *sli4, void *buf, size_t size, uint8_t *wwpn, uint8_t *wwnn, uint8_t hard_alpa,
1008  uint32_t preferred_d_id)
1009 {
1010  sli4_cmd_write_nvparms_t *write_nvparms = buf;
1011 
1012  ocs_memset(buf, 0, size);
1013 
1014  write_nvparms->hdr.command = SLI4_MBOX_COMMAND_WRITE_NVPARMS;
1015  ocs_memcpy(write_nvparms->wwpn, wwpn, 8);
1016  ocs_memcpy(write_nvparms->wwnn, wwnn, 8);
1017  write_nvparms->hard_alpa = hard_alpa;
1018  write_nvparms->preferred_d_id = preferred_d_id;
1019 
1020  return sizeof(sli4_cmd_write_nvparms_t);
1021 }
1022 
1023 /**
1024  * @brief Write a READ_REV command to the provided buffer.
1025  *
1026  * @param sli4 SLI context pointer.
1027  * @param buf Virtual pointer to the destination buffer.
1028  * @param size Buffer size, in bytes.
1029  * @param vpd Pointer to the buffer.
1030  *
1031  * @return Returns the number of bytes written.
1032  */
1033 static int32_t
1034 sli_cmd_read_rev(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *vpd)
1035 {
1036  sli4_cmd_read_rev_t *read_rev = buf;
1037 
1038  ocs_memset(buf, 0, size);
1039 
1041 
1042  if (vpd && vpd->size) {
1043  read_rev->vpd = TRUE;
1044 
1045  read_rev->available_length = vpd->size;
1046 
1047  read_rev->physical_address_low = ocs_addr32_lo(vpd->phys);
1048  read_rev->physical_address_high = ocs_addr32_hi(vpd->phys);
1049  }
1050 
1051  return sizeof(sli4_cmd_read_rev_t);
1052 }
1053 
1054 /**
1055  * @ingroup sli
1056  * @brief Write a READ_SPARM64 command to the provided buffer.
1057  *
1058  * @param sli4 SLI context pointer.
1059  * @param buf Virtual pointer to the destination buffer.
1060  * @param size Buffer size, in bytes.
1061  * @param dma DMA buffer for the service parameters.
1062  * @param vpi VPI used to determine the WWN.
1063  *
1064  * @return Returns the number of bytes written.
1065  */
1066 int32_t
1067 sli_cmd_read_sparm64(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma,
1068  uint16_t vpi)
1069 {
1070  sli4_cmd_read_sparm64_t *read_sparm64 = buf;
1071 
1072  ocs_memset(buf, 0, size);
1073 
1074  if (SLI4_READ_SPARM64_VPI_SPECIAL == vpi) {
1075  ocs_log_test(sli4->os, "special VPI not supported!!!\n");
1076  return -1;
1077  }
1078 
1079  if (!dma || !dma->phys) {
1080  ocs_log_test(sli4->os, "bad DMA buffer\n");
1081  return -1;
1082  }
1083 
1084  read_sparm64->hdr.command = SLI4_MBOX_COMMAND_READ_SPARM64;
1085 
1086  read_sparm64->bde_64.bde_type = SLI4_BDE_TYPE_BDE_64;
1087  read_sparm64->bde_64.buffer_length = dma->size;
1088  read_sparm64->bde_64.u.data.buffer_address_low = ocs_addr32_lo(dma->phys);
1089  read_sparm64->bde_64.u.data.buffer_address_high = ocs_addr32_hi(dma->phys);
1090 
1091  read_sparm64->vpi = vpi;
1092 
1093  return sizeof(sli4_cmd_read_sparm64_t);
1094 }
1095 
1096 /**
1097  * @ingroup sli
1098  * @brief Write a READ_TOPOLOGY command to the provided buffer.
1099  *
1100  * @param sli4 SLI context pointer.
1101  * @param buf Virtual pointer to the destination buffer.
1102  * @param size Buffer size, in bytes.
1103  * @param dma DMA buffer for loop map (optional).
1104  *
1105  * @return Returns the number of bytes written.
1106  */
1107 int32_t
1108 sli_cmd_read_topology(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma)
1109 {
1110  sli4_cmd_read_topology_t *read_topo = buf;
1111 
1112  ocs_memset(buf, 0, size);
1113 
1115 
1116  if (dma && dma->size) {
1117  if (dma->size < SLI4_MIN_LOOP_MAP_BYTES) {
1118  ocs_log_test(sli4->os, "loop map buffer too small %jd\n",
1119  dma->size);
1120  return 0;
1121  }
1122 
1123  ocs_memset(dma->virt, 0, dma->size);
1124 
1126  read_topo->bde_loop_map.buffer_length = dma->size;
1127  read_topo->bde_loop_map.u.data.buffer_address_low = ocs_addr32_lo(dma->phys);
1128  read_topo->bde_loop_map.u.data.buffer_address_high = ocs_addr32_hi(dma->phys);
1129  }
1130 
1131  return sizeof(sli4_cmd_read_topology_t);
1132 }
1133 
1134 /**
1135  * @ingroup sli
1136  * @brief Write a REG_FCFI command to the provided buffer.
1137  *
1138  * @param sli4 SLI context pointer.
1139  * @param buf Virtual pointer to the destination buffer.
1140  * @param size Buffer size, in bytes.
1141  * @param index FCF index returned by READ_FCF_TABLE.
1142  * @param rq_cfg RQ_ID/R_CTL/TYPE routing information
1143  * @param vlan_id VLAN ID tag.
1144  *
1145  * @return Returns the number of bytes written.
1146  */
1147 int32_t
1148 sli_cmd_reg_fcfi(sli4_t *sli4, void *buf, size_t size, uint16_t index, sli4_cmd_rq_cfg_t rq_cfg[SLI4_CMD_REG_FCFI_NUM_RQ_CFG], uint16_t vlan_id)
1149 {
1150  sli4_cmd_reg_fcfi_t *reg_fcfi = buf;
1151  uint32_t i;
1152 
1153  ocs_memset(buf, 0, size);
1154 
1156 
1157  reg_fcfi->fcf_index = index;
1158 
1159  for (i = 0; i < SLI4_CMD_REG_FCFI_NUM_RQ_CFG; i++) {
1160  switch(i) {
1161  case 0: reg_fcfi->rq_id_0 = rq_cfg[0].rq_id; break;
1162  case 1: reg_fcfi->rq_id_1 = rq_cfg[1].rq_id; break;
1163  case 2: reg_fcfi->rq_id_2 = rq_cfg[2].rq_id; break;
1164  case 3: reg_fcfi->rq_id_3 = rq_cfg[3].rq_id; break;
1165  }
1166  reg_fcfi->rq_cfg[i].r_ctl_mask = rq_cfg[i].r_ctl_mask;
1167  reg_fcfi->rq_cfg[i].r_ctl_match = rq_cfg[i].r_ctl_match;
1168  reg_fcfi->rq_cfg[i].type_mask = rq_cfg[i].type_mask;
1169  reg_fcfi->rq_cfg[i].type_match = rq_cfg[i].type_match;
1170  }
1171 
1172  if (vlan_id) {
1173  reg_fcfi->vv = TRUE;
1174  reg_fcfi->vlan_tag = vlan_id;
1175  }
1176 
1177  return sizeof(sli4_cmd_reg_fcfi_t);
1178 }
1179 
1180 /**
1181  * @brief Write REG_FCFI_MRQ to provided command buffer
1182  *
1183  * @param sli4 SLI context pointer.
1184  * @param buf Virtual pointer to the destination buffer.
1185  * @param size Buffer size, in bytes.
1186  * @param fcf_index FCF index returned by READ_FCF_TABLE.
1187  * @param vlan_id VLAN ID tag.
1188  * @param rq_cfg RQ_ID/R_CTL/TYPE routing information
1189  *
1190  * @return returns 0 for success, a negative error code value for failure.
1191  */
1192 int32_t
1193 sli_cmd_reg_fcfi_mrq(sli4_t *sli4, void *buf, size_t size, uint8_t mode,
1194  uint16_t fcf_index, uint16_t vlan_id,
1196 {
1197  sli4_cmd_reg_fcfi_mrq_t *reg_fcfi_mrq = buf;
1198  uint32_t i;
1199  bool filter_ext_used = FALSE;
1200 
1201  ocs_memset(buf, 0, size);
1202 
1203  reg_fcfi_mrq->hdr.command = SLI4_MBOX_COMMAND_REG_FCFI_MRQ;
1204  reg_fcfi_mrq->mode = mode;
1205  if (mode == SLI4_CMD_REG_FCFI_SET_FCFI_MODE) {
1206  reg_fcfi_mrq->fcf_index = fcf_index;
1207  if (vlan_id) {
1208  reg_fcfi_mrq->vv = TRUE;
1209  reg_fcfi_mrq->vlan_tag = vlan_id;
1210  }
1211  goto done;
1212  }
1213 
1214  for (i = 0; i < SLI4_CMD_REG_FCFI_NUM_RQ_CFG; i++) {
1215 
1216  switch (i) {
1217  case 7: reg_fcfi_mrq->rq_id_7 = rq_cfg[i].rq_id; break;
1218  case 6: reg_fcfi_mrq->rq_id_6 = rq_cfg[i].rq_id; break;
1219  case 5: reg_fcfi_mrq->rq_id_5 = rq_cfg[i].rq_id; break;
1220  case 4: reg_fcfi_mrq->rq_id_4 = rq_cfg[i].rq_id; break;
1221  case 3: reg_fcfi_mrq->rq_id_3 = rq_cfg[i].rq_id; break;
1222  case 2: reg_fcfi_mrq->rq_id_2 = rq_cfg[i].rq_id; break;
1223  case 1: reg_fcfi_mrq->rq_id_1 = rq_cfg[i].rq_id; break;
1224  case 0: reg_fcfi_mrq->rq_id_0 = rq_cfg[i].rq_id; break;
1225  }
1226 
1227  if (rq_cfg[i].rq_id == 0xffff) { // Not valid
1228  continue;
1229  }
1230 
1231  if (i < 4) {
1232  // First set of filters
1233  reg_fcfi_mrq->rq_cfg_1[i].r_ctl_mask = rq_cfg[i].r_ctl_mask;
1234  reg_fcfi_mrq->rq_cfg_1[i].r_ctl_match = rq_cfg[i].r_ctl_match;
1235  reg_fcfi_mrq->rq_cfg_1[i].type_mask = rq_cfg[i].type_mask;
1236  reg_fcfi_mrq->rq_cfg_1[i].type_match = rq_cfg[i].type_match;
1237  } else {
1238  filter_ext_used = TRUE;
1239 
1240  reg_fcfi_mrq->rq_cfg_2[i - 4].r_ctl_mask = rq_cfg[i].r_ctl_mask;
1241  reg_fcfi_mrq->rq_cfg_2[i - 4].r_ctl_match = rq_cfg[i].r_ctl_match;
1242  reg_fcfi_mrq->rq_cfg_2[i - 4].type_mask = rq_cfg[i].type_mask;
1243  reg_fcfi_mrq->rq_cfg_2[i - 4].type_match = rq_cfg[i].type_match;
1244  }
1245 
1246 
1247  /* Check if protocol need be set */
1248  if (rq_cfg[i].protocol_valid) {
1249  reg_fcfi_mrq->ptc |= (1 << i);
1250  reg_fcfi_mrq->pt |= ((rq_cfg[i].protocol & 0x1) << i);
1251  }
1252 
1253  /* Check if this filter points to MRQ */
1254  if (rq_cfg[i].is_mrq) {
1255  if (rq_cfg[i].mrq_set_num == 0) { // set 0
1256  reg_fcfi_mrq->num_mrq_pairs_1 =
1257  rq_cfg[i].mrq_set_count;
1258 
1259  if (rq_cfg[i].filtermask & 0xf0) { // extended filter
1260  reg_fcfi_mrq->alt_mrq_filter_bit_mask_1 =
1261  rq_cfg[i].filtermask;
1262  } else {
1263  reg_fcfi_mrq->mrq_filter_bitmask_1 =
1264  rq_cfg[i].filtermask;
1265  }
1266 
1267  reg_fcfi_mrq->rq_selection_policy_1 =
1268  rq_cfg[i].mrq_policy;
1269 
1270  } else if (rq_cfg[i].mrq_set_num == 1) { // set 1
1271  reg_fcfi_mrq->num_mrq_pairs_2 =
1272  rq_cfg[i].mrq_set_count;
1273 
1274  if (rq_cfg[i].filtermask & 0xf0) {
1275  reg_fcfi_mrq->alt_mrq_filter_bit_mask_2 =
1276  rq_cfg[i].filtermask;
1277  } else {
1278  reg_fcfi_mrq->mrq_filter_bitmask_2 =
1279  rq_cfg[i].filtermask;
1280  }
1281 
1282  reg_fcfi_mrq->rq_selection_policy_2 =
1283  rq_cfg[i].mrq_policy;
1284  } else {
1285  return 0;
1286  }
1287  }
1288  }
1289 
1290  if (filter_ext_used) {
1291  reg_fcfi_mrq->xmv = TRUE;
1292  }
1293 done:
1294  return sizeof(sli4_cmd_reg_fcfi_mrq_t);
1295 }
1296 
1297 /**
1298  * @ingroup sli
1299  * @brief Write a REG_RPI command to the provided buffer.
1300  *
1301  * @param sli4 SLI context pointer.
1302  * @param buf Virtual pointer to the destination buffer.
1303  * @param size Buffer size, in bytes.
1304  * @param nport_id Remote F/N_Port_ID.
1305  * @param rpi Previously-allocated Remote Port Indicator.
1306  * @param vpi Previously-allocated Virtual Port Indicator.
1307  * @param dma DMA buffer that contains the remote port's service parameters.
1308  * @param update Boolean indicating an update to an existing RPI (TRUE)
1309  * or a new registration (FALSE).
1310  * @param hlm Indicating an RPI being used for HLM RPI
1311  *
1312  * @return Returns the number of bytes written.
1313  */
1314 int32_t
1315 sli_cmd_reg_rpi(sli4_t *sli4, void *buf, size_t size, uint32_t nport_id, uint16_t rpi,
1316  uint16_t vpi, ocs_dma_t *dma, uint8_t update,
1317  uint8_t enable_t10_pi, uint8_t hlm)
1318 {
1319  sli4_cmd_reg_rpi_t *reg_rpi = buf;
1320 
1321  ocs_memset(buf, 0, size);
1322 
1324 
1325  reg_rpi->rpi = rpi;
1326  reg_rpi->remote_n_port_id = nport_id;
1327  reg_rpi->upd = update;
1328  reg_rpi->etow = enable_t10_pi;
1329  reg_rpi->hlm = hlm;
1330 
1333  reg_rpi->bde_64.u.data.buffer_address_low = ocs_addr32_lo(dma->phys);
1334  reg_rpi->bde_64.u.data.buffer_address_high = ocs_addr32_hi(dma->phys);
1335 
1336  reg_rpi->vpi = vpi;
1337 
1338  return sizeof(sli4_cmd_reg_rpi_t);
1339 }
1340 
1341 /**
1342  * @ingroup sli
1343  * @brief Write a REG_VFI command to the provided buffer.
1344  *
1345  * @param sli4 SLI context pointer.
1346  * @param buf Virtual pointer to the destination buffer.
1347  * @param size Buffer size, in bytes.
1348  * @param domain Pointer to the domain object.
1349  *
1350  * @return Returns the number of bytes written.
1351  */
1352 int32_t
1353 sli_cmd_reg_vfi(sli4_t *sli4, void *buf, size_t size, ocs_domain_t *domain)
1354 {
1355  sli4_cmd_reg_vfi_t *reg_vfi = buf;
1356  fc_plogi_payload_t *flogi_rsp_sparams = NULL;
1357  uint8_t bbscn_fabric = 0;
1358 
1359  if (!sli4 || !buf || !domain) {
1360  return 0;
1361  }
1362 
1363  ocs_memset(buf, 0, size);
1364 
1366 
1367  reg_vfi->vfi = domain->indicator;
1368 
1369  reg_vfi->fcfi = domain->fcf_indicator;
1370 
1371  // TODO contents of domain->dma only valid if topo == FABRIC
1372  reg_vfi->sparm.bde_type = SLI4_BDE_TYPE_BDE_64;
1373  reg_vfi->sparm.buffer_length = 0x70;
1374  reg_vfi->sparm.u.data.buffer_address_low = ocs_addr32_lo(domain->dma.phys);
1375  reg_vfi->sparm.u.data.buffer_address_high = ocs_addr32_hi(domain->dma.phys);
1376 
1377  reg_vfi->e_d_tov = sli4->config.e_d_tov;
1378  reg_vfi->r_a_tov = sli4->config.r_a_tov;
1379 
1380  reg_vfi->vp = TRUE;
1381  reg_vfi->vpi = domain->sport->indicator;
1382  ocs_memcpy(reg_vfi->wwpn, &domain->sport->sli_wwpn, sizeof(reg_vfi->wwpn));
1383  reg_vfi->local_n_port_id = domain->sport->fc_id;
1384 
1385  flogi_rsp_sparams = (fc_plogi_payload_t *)domain->flogi_service_params;
1386  bbscn_fabric = (ocs_be32toh(flogi_rsp_sparams->common_service_parameters[1]) >> 12) & 0xF;
1387  ocs_log_debug(sli4->os, "bbscn_fabric: %d\n", bbscn_fabric);
1388 
1389  /**
1390  * If our advertised service parameter BB_SC_N is 0 or
1391  * accept BB_SC_N is 0, send REG_VFI with BBCR set to 0
1392  */
1393  if (ocs_bbcr_enabled(sli4->os) && bbscn_fabric) {
1394  /**
1395  * If the accept BB_SC_N value is greater than our maximum supported value
1396  * (BBSCN_MAX from READ_CONFIG), then BBCR should not be enabled
1397  */
1398  if (bbscn_fabric <= sli4->config.bbscn_max) {
1399  /* BB_SC_N value should be set to max of (advertised value, accept value) */
1400  reg_vfi->bbscn = OCS_MAX(sli4->config.bbscn_def, bbscn_fabric);
1401  reg_vfi->bbcr = 1;
1402  ocs_log_info(sli4->os, "Enabling BBCR with BB_SC_N: %d\n", reg_vfi->bbscn);
1403  }
1404  }
1405 
1406  return sizeof(sli4_cmd_reg_vfi_t);
1407 }
1408 
1409 /**
1410  * @ingroup sli
1411  * @brief Write a REG_VPI command to the provided buffer.
1412  *
1413  * @param sli4 SLI context pointer.
1414  * @param buf Virtual pointer to the destination buffer.
1415  * @param size Buffer size, in bytes.
1416  * @param sport Point to SLI Port object.
1417  * @param update Boolean indicating whether to update the existing VPI (true)
1418  * or create a new VPI (false).
1419  *
1420  * @return Returns the number of bytes written.
1421  */
1422 int32_t
1423 sli_cmd_reg_vpi(sli4_t *sli4, void *buf, size_t size, ocs_sli_port_t *sport, uint8_t update)
1424 {
1425  sli4_cmd_reg_vpi_t *reg_vpi = buf;
1426 
1427  if (!sli4 || !buf || !sport) {
1428  return 0;
1429  }
1430 
1431  ocs_memset(buf, 0, size);
1432 
1434 
1435  reg_vpi->local_n_port_id = sport->fc_id;
1436  reg_vpi->upd = update != 0;
1437  ocs_memcpy(reg_vpi->wwpn, &sport->sli_wwpn, sizeof(reg_vpi->wwpn));
1438  reg_vpi->vpi = sport->indicator;
1439  reg_vpi->vfi = sport->domain->indicator;
1440 
1441  return sizeof(sli4_cmd_reg_vpi_t);
1442 }
1443 
1444 /**
1445  * @brief Write a REQUEST_FEATURES command to the provided buffer.
1446  *
1447  * @param sli4 SLI context pointer.
1448  * @param buf Virtual pointer to the destination buffer.
1449  * @param size Buffer size, in bytes.
1450  * @param mask Features to request.
1451  * @param query Use feature query mode (does not change FW).
1452  *
1453  * @return Returns the number of bytes written.
1454  */
1455 static int32_t
1456 sli_cmd_request_features(sli4_t *sli4, void *buf, size_t size, sli4_features_t mask, uint8_t query)
1457 {
1458  sli4_cmd_request_features_t *features = buf;
1459 
1460  ocs_memset(buf, 0, size);
1461 
1463 
1464  if (query) {
1465  features->qry = TRUE;
1466  }
1467  features->command.dword = mask.dword;
1468 
1469  return sizeof(sli4_cmd_request_features_t);
1470 }
1471 
1472 /**
1473  * @ingroup sli
1474  * @brief Write a SLI_CONFIG command to the provided buffer.
1475  *
1476  * @param sli4 SLI context pointer.
1477  * @param buf Virtual pointer to the destination buffer.
1478  * @param size Buffer size, in bytes.
1479  * @param length Length in bytes of attached command.
1480  * @param dma DMA buffer for non-embedded commands.
1481  *
1482  * @return Returns the number of bytes written.
1483  */
1484 int32_t
1485 sli_cmd_sli_config(sli4_t *sli4, void *buf, size_t size, uint32_t length, ocs_dma_t *dma)
1486 {
1487  sli4_cmd_sli_config_t *sli_config = NULL;
1488 
1489  if ((length > sizeof(sli_config->payload.embed)) && (dma == NULL)) {
1490  ocs_log_test(sli4->os, "length(%d) > payload(%ld)\n",
1491  length, sizeof(sli_config->payload.embed));
1492  return -1;
1493  }
1494 
1495  sli_config = buf;
1496 
1497  ocs_memset(buf, 0, size);
1498 
1500  if (NULL == dma) {
1501  sli_config->emb = TRUE;
1502  sli_config->payload_length = length;
1503  } else {
1504  sli_config->emb = FALSE;
1505 
1506  sli_config->pmd_count = 1;
1507 
1508  sli_config->payload.mem.address_low = ocs_addr32_lo(dma->phys);
1509  sli_config->payload.mem.address_high = ocs_addr32_hi(dma->phys);
1510  sli_config->payload.mem.length = dma->size;
1511  sli_config->payload_length = dma->size;
1512 #if defined(OCS_INCLUDE_DEBUG)
1513  /* save pointer to DMA for BMBX dumping purposes */
1514  sli4->bmbx_non_emb_pmd = dma;
1515 #endif
1516 
1517  }
1518 
1519  return offsetof(sli4_cmd_sli_config_t, payload.embed);
1520 }
1521 
1522 /**
1523  * @brief Initialize SLI Port control register.
1524  *
1525  * @param sli4 SLI context pointer.
1526  * @param endian Endian value to write.
1527  *
1528  * @return Returns 0 on success, or a negative error code value on failure.
1529  */
1530 
1531 static int32_t
1532 sli_sliport_control(sli4_t *sli4, uint32_t endian)
1533 {
1534  uint32_t iter;
1535  int32_t rc;
1536 
1537  rc = -1;
1538 
1539  /* Initialize port, endian */
1541 
1542  for (iter = 0; iter < 3000; iter ++) {
1543  ocs_delay_usec(SLI4_INIT_PORT_DELAY_US); // 10 ms
1544  /* Wait for FW to become ready & error to be cleared */
1545  if ((sli_fw_ready(sli4) == 1) && !sli_fw_error_status(sli4)) {
1546  rc = 0;
1547  break;
1548  }
1549  }
1550 
1551  if (rc != 0) {
1552  ocs_log_crit(sli4->os, "port failed to become ready after initialization\n");
1553  }
1554 
1555  return rc;
1556 }
1557 
1558 /**
1559  * @ingroup sli
1560  * @brief Write a UNREG_FCFI command to the provided buffer.
1561  *
1562  * @param sli4 SLI context pointer.
1563  * @param buf Virtual pointer to the destination buffer.
1564  * @param size Buffer size, in bytes.
1565  * @param indicator Indicator value.
1566  *
1567  * @return Returns the number of bytes written.
1568  */
1569 int32_t
1570 sli_cmd_unreg_fcfi(sli4_t *sli4, void *buf, size_t size, uint16_t indicator)
1571 {
1572  sli4_cmd_unreg_fcfi_t *unreg_fcfi = buf;
1573 
1574  if (!sli4 || !buf) {
1575  return 0;
1576  }
1577 
1578  ocs_memset(buf, 0, size);
1579 
1581 
1582  unreg_fcfi->fcfi = indicator;
1583 
1584  return sizeof(sli4_cmd_unreg_fcfi_t);
1585 }
1586 
1587 /**
1588  * @ingroup sli
1589  * @brief Write an UNREG_RPI command to the provided buffer.
1590  *
1591  * @param sli4 SLI context pointer.
1592  * @param buf Virtual pointer to the destination buffer.
1593  * @param size Buffer size, in bytes.
1594  * @param indicator Indicator value.
1595  * @param which Type of unregister, such as node, port, domain, or FCF.
1596  * @param fc_id FC address.
1597  *
1598  * @return Returns the number of bytes written.
1599  */
1600 int32_t
1601 sli_cmd_unreg_rpi(sli4_t *sli4, void *buf, size_t size, uint16_t indicator, sli4_resource_e which,
1602  uint32_t fc_id)
1603 {
1604  sli4_cmd_unreg_rpi_t *unreg_rpi = buf;
1605  uint8_t index_indicator = 0;
1606 
1607  if (!sli4 || !buf) {
1608  return 0;
1609  }
1610 
1611  ocs_memset(buf, 0, size);
1612 
1614 
1615  switch (which) {
1616  case SLI_RSRC_FCOE_RPI:
1617  index_indicator = SLI4_UNREG_RPI_II_RPI;
1618  if (fc_id != UINT32_MAX) {
1619  unreg_rpi->dp = TRUE;
1620  unreg_rpi->destination_n_port_id = fc_id & 0x00ffffff;
1621  }
1622  break;
1623  case SLI_RSRC_FCOE_VPI:
1624  index_indicator = SLI4_UNREG_RPI_II_VPI;
1625  break;
1626  case SLI_RSRC_FCOE_VFI:
1627  index_indicator = SLI4_UNREG_RPI_II_VFI;
1628  break;
1629  case SLI_RSRC_FCOE_FCFI:
1630  index_indicator = SLI4_UNREG_RPI_II_FCFI;
1631  break;
1632  default:
1633  ocs_log_test(sli4->os, "unknown type %#x\n", which);
1634  return 0;
1635  }
1636 
1637  unreg_rpi->ii = index_indicator;
1638  unreg_rpi->index = indicator;
1639 
1640  return sizeof(sli4_cmd_unreg_rpi_t);
1641 }
1642 
1643 /**
1644  * @ingroup sli
1645  * @brief Write an UNREG_VFI command to the provided buffer.
1646  *
1647  * @param sli4 SLI context pointer.
1648  * @param buf Virtual pointer to the destination buffer.
1649  * @param size Buffer size, in bytes.
1650  * @param domain Pointer to the domain object
1651  * @param which Type of unregister, such as domain, FCFI, or everything.
1652  *
1653  * @return Returns the number of bytes written.
1654  */
1655 int32_t
1656 sli_cmd_unreg_vfi(sli4_t *sli4, void *buf, size_t size, ocs_domain_t *domain, uint32_t which)
1657 {
1658  sli4_cmd_unreg_vfi_t *unreg_vfi = buf;
1659 
1660  if (!sli4 || !buf || !domain) {
1661  return 0;
1662  }
1663 
1664  ocs_memset(buf, 0, size);
1665 
1667  switch (which) {
1669  unreg_vfi->index = domain->indicator;
1670  break;
1671  case SLI4_UNREG_TYPE_FCF:
1672  unreg_vfi->index = domain->fcf_indicator;
1673  break;
1674  case SLI4_UNREG_TYPE_ALL:
1675  unreg_vfi->index = UINT16_MAX;
1676  break;
1677  default:
1678  return 0;
1679  }
1680 
1681  if (SLI4_UNREG_TYPE_DOMAIN != which) {
1682  unreg_vfi->ii = SLI4_UNREG_VFI_II_FCFI;
1683  }
1684 
1685  return sizeof(sli4_cmd_unreg_vfi_t);
1686 }
1687 
1688 /**
1689  * @ingroup sli
1690  * @brief Write an UNREG_VPI command to the provided buffer.
1691  *
1692  * @param sli4 SLI context pointer.
1693  * @param buf Virtual pointer to the destination buffer.
1694  * @param size Buffer size, in bytes.
1695  * @param indicator Indicator value.
1696  * @param which Type of unregister: port, domain, FCFI, everything
1697  *
1698  * @return Returns the number of bytes written.
1699  */
1700 int32_t
1701 sli_cmd_unreg_vpi(sli4_t *sli4, void *buf, size_t size, uint16_t indicator, uint32_t which)
1702 {
1703  sli4_cmd_unreg_vpi_t *unreg_vpi = buf;
1704 
1705  if (!sli4 || !buf) {
1706  return 0;
1707  }
1708 
1709  ocs_memset(buf, 0, size);
1710 
1712  unreg_vpi->index = indicator;
1713  switch (which) {
1714  case SLI4_UNREG_TYPE_PORT:
1715  unreg_vpi->ii = SLI4_UNREG_VPI_II_VPI;
1716  break;
1718  unreg_vpi->ii = SLI4_UNREG_VPI_II_VFI;
1719  break;
1720  case SLI4_UNREG_TYPE_FCF:
1721  unreg_vpi->ii = SLI4_UNREG_VPI_II_FCFI;
1722  break;
1723  case SLI4_UNREG_TYPE_ALL:
1724  unreg_vpi->index = UINT16_MAX; /* override indicator */
1725  unreg_vpi->ii = SLI4_UNREG_VPI_II_FCFI;
1726  break;
1727  default:
1728  return 0;
1729  }
1730 
1731  return sizeof(sli4_cmd_unreg_vpi_t);
1732 }
1733 
1734 /**
1735  * @ingroup sli
1736  * @brief Write an CONFIG_AUTO_XFER_RDY command to the provided buffer.
1737  * Command to enable AXR in G5.
1738  *
1739  * @param sli4 SLI context pointer.
1740  * @param buf Virtual pointer to the destination buffer.
1741  * @param size Buffer size, in bytes.
1742  * @param max_burst_len if the write FCP_DL is less than this size,
1743  * then the SLI port will generate the auto XFER_RDY.
1744  *
1745  * @return Returns the number of bytes written.
1746  */
1747 int32_t
1748 sli_cmd_config_auto_xfer_rdy(sli4_t *sli4, void *buf, size_t size, uint32_t max_burst_len)
1749 {
1751 
1752  if (!sli4 || !buf) {
1753  return 0;
1754  }
1755 
1756  ocs_memset(buf, 0, size);
1757 
1759  req->max_burst_len = max_burst_len;
1760 
1761  return sizeof(sli4_cmd_config_auto_xfer_rdy_t);
1762 }
1763 
1764 /**
1765  * @ingroup sli
1766  * @brief Write an CONFIG_AUTO_XFER_RDY_HP command to the provided buffer.
1767  *
1768  * @param sli4 SLI context pointer.
1769  * @param buf Virtual pointer to the destination buffer.
1770  * @param size Buffer size, in bytes.
1771  * @param max_burst_len if the write FCP_DL is less than this size,
1772  * @param esoc enable start offset computation,
1773  * @param block_size block size,
1774  * then the SLI port will generate the auto XFER_RDY.
1775  *
1776  * @return Returns the number of bytes written.
1777  */
1778 int32_t sli_cmd_config_auto_xfer_rdy_hp(sli4_t *sli4, void *buf, size_t size,
1779  uint32_t max_burst_len, uint32_t block_size)
1780 {
1782 
1783  if (!sli4 || !buf) {
1784  return 0;
1785  }
1786 
1787  ocs_memset(buf, 0, size);
1788 
1790  req->max_burst_len = max_burst_len;
1791  req->esoc = 1;
1792  req->block_size = block_size;
1793  return sizeof(sli4_cmd_config_auto_xfer_rdy_hp_t);
1794 }
1795 
1796 /**
1797  * @ingroup sli
1798  * @brief Write an CONFIG_OPTIMIZED_WRITE command to the provided buffer.
1799  *
1800  * @param sli4 SLI context pointer.
1801  * @param buf Virtual pointer to the destination buffer.
1802  * @param size Buffer size, in bytes.
1803  * @param max_burst_len if the write FCP_DL is less than this size,
1804  * @param xri_cnt Total XRIs that will be posted,
1805  * then the SLI port will generate the auto XFER_RDY.
1806  *
1807  * @return Returns the number of bytes written.
1808  */
1809 int32_t
1810 sli_cmd_config_optimized_write(sli4_t *sli4, void *buf, size_t size,
1811  uint32_t max_burst_len, uint32_t xri_cnt,
1812  uint32_t tow_feature)
1813 {
1814  sli4_cmd_config_tow_t *req = buf;
1815 
1816  if (!sli4 || !buf) {
1817  return 0;
1818  }
1819 
1820  ocs_memset(buf, 0, size);
1821 
1823  if (tow_feature & OCS_TOW_FEATURE_AXR)
1824  req->axs = 1;
1825  if (tow_feature & OCS_TOW_FEATURE_TFB)
1826  req->fbs = 1;
1827  req->xpns = 0;
1828  req->scsi_max_data_len = max_burst_len;
1829  req->version = 1;
1830  req->pool0_xri_cnt = xri_cnt;
1831 
1832  return sizeof(sli4_cmd_config_tow_t);
1833 }
1834 
1835 /**
1836  * @ingroup sli
1837  * @brief Write an CONFIG_OPTIMIZED_WRITE_HP command to the provided buffer.
1838  *
1839  * @param sli4 SLI context pointer.
1840  * @param buf Virtual pointer to the destination buffer.
1841  * @param size Buffer size, in bytes.
1842  * @param max_burst_len if the write FCP_DL is less than this size,
1843  * @param xri_cnt Total XRIs that will be posted,
1844  * @param block_size block size,
1845  * then the SLI port will generate the auto XFER_RDY.
1846  *
1847  * @return Returns the number of bytes written.
1848  */
1850  size_t size, uint32_t max_burst_len,
1851  uint32_t xri_cnt, uint32_t block_size,
1852  uint32_t tow_feature)
1853 {
1854  sli4_cmd_config_tow_hp_t *req = buf;
1855 
1856  if (!sli4 || !buf) {
1857  return 0;
1858  }
1859 
1860  ocs_memset(buf, 0, size);
1861 
1863  if (tow_feature & OCS_TOW_FEATURE_AXR)
1864  req->axs = 1;
1865  if (tow_feature & OCS_TOW_FEATURE_TFB)
1866  req->fbs = 1;
1867 
1868  req->xpns = 0;
1869  req->scsi_max_data_len = max_burst_len;
1870  req->esoc = 1;
1871  req->scsi_block_size = block_size;
1872  req->pool0_xri_cnt = xri_cnt;
1873  return sizeof(sli4_cmd_config_tow_hp_t);
1874 }
1875 
1876 /**
1877  * @brief Write a COMMON_FUNCTION_RESET command.
1878  *
1879  * @param sli4 SLI context.
1880  * @param buf Destination buffer for the command.
1881  * @param size Buffer size, in bytes.
1882  *
1883  * @return Returns the number of bytes written.
1884  */
1885 static int32_t
1886 sli_cmd_common_function_reset(sli4_t *sli4, void *buf, size_t size)
1887 {
1888  sli4_req_common_function_reset_t *reset = NULL;
1889  uint32_t sli_config_off = 0;
1890 
1891  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
1892  uint32_t payload_size;
1893 
1894  /* Payload length must accomodate both request and response */
1895  payload_size = max(sizeof(sli4_req_common_function_reset_t),
1897 
1898  sli_config_off = sli_cmd_sli_config(sli4, buf, size, payload_size,
1899  NULL);
1900  }
1901  reset = (sli4_req_common_function_reset_t *)((uint8_t *)buf + sli_config_off);
1902 
1905 
1906  return(sli_config_off + sizeof(sli4_req_common_function_reset_t));
1907 }
1908 
1909 /**
1910  * @brief Write a COMMON_CREATE_CQ command.
1911  *
1912  * @param sli4 SLI context.
1913  * @param buf Destination buffer for the command.
1914  * @param size Buffer size, in bytes.
1915  * @param qmem DMA memory for the queue.
1916  * @param eq_id Associated EQ_ID
1917  * @param ignored This parameter carries the ULP which is only used for WQ and RQs
1918  *
1919  * @note This creates a Version 0 message.
1920  *
1921  * @return Returns the number of bytes written.
1922  */
1923 static int32_t
1924 sli_cmd_common_create_cq(sli4_t *sli4, void *buf, size_t size,
1925  ocs_dma_t *qmem, uint16_t eq_id, uint16_t ignored)
1926 {
1927  sli4_req_common_create_cq_v0_t *cqv0 = NULL;
1928  sli4_req_common_create_cq_v2_t *cqv2 = NULL;
1929  uint32_t sli_config_off = 0;
1930  uint32_t p;
1931  uintptr_t addr;
1932  uint32_t if_type = sli4->if_type;
1933  uint32_t page_bytes = 0;
1934  uint32_t num_pages = 0;
1935  uint32_t cmd_size = 0;
1936  uint32_t page_size = 0;
1937  uint32_t n_cqe = 0;
1938 
1939  /* First calculate number of pages and the mailbox cmd length */
1940  switch (if_type)
1941  {
1943  page_bytes = SLI_PAGE_SIZE;
1944  num_pages = sli_page_count(qmem->size, page_bytes);
1945  cmd_size = sizeof(sli4_req_common_create_cq_v0_t) + (8 * num_pages);
1946  break;
1949  n_cqe = qmem->size / SLI4_CQE_BYTES;
1950  switch (n_cqe) {
1951  case 256:
1952  case 512:
1953  case 1024:
1954  case 2048:
1955  page_size = 1;
1956  break;
1957  case 4096:
1958  page_size = 2;
1959  break;
1960  default:
1961  return 0;
1962  }
1963  page_bytes = page_size * SLI_PAGE_SIZE;
1964  num_pages = sli_page_count(qmem->size, page_bytes);
1965  cmd_size = sizeof(sli4_req_common_create_cq_v2_t) + (8 * num_pages);
1966  break;
1967  default:
1968  ocs_log_test(sli4->os, "unsupported IF_TYPE %d\n", if_type);
1969  return -1;
1970  }
1971 
1972 
1973  /* now that we have the mailbox command size, we can set SLI_CONFIG fields */
1974  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
1975  uint32_t payload_size;
1976 
1977  /* Payload length must accomodate both request and response */
1978  payload_size = max((size_t)cmd_size, sizeof(sli4_res_common_create_queue_t));
1979 
1980  sli_config_off = sli_cmd_sli_config(sli4, buf, size, payload_size,
1981  NULL);
1982  }
1983 
1984  switch (if_type)
1985  {
1987  cqv0 = (sli4_req_common_create_cq_v0_t *)((uint8_t *)buf + sli_config_off);
1990  cqv0->hdr.version = 0;
1991  cqv0->hdr.request_length = cmd_size - sizeof(sli4_req_hdr_t);
1992 
1993  /* valid values for number of pages: 1, 2, 4 (sec 4.4.3) */
1994  cqv0->num_pages = num_pages;
1995  switch (cqv0->num_pages) {
1996  case 1:
1997  cqv0->cqecnt = SLI4_CQ_CNT_256;
1998  break;
1999  case 2:
2000  cqv0->cqecnt = SLI4_CQ_CNT_512;
2001  break;
2002  case 4:
2003  cqv0->cqecnt = SLI4_CQ_CNT_1024;
2004  break;
2005  default:
2006  ocs_log_test(sli4->os, "num_pages %d not valid\n", cqv0->num_pages);
2007  return -1;
2008  }
2009  cqv0->evt = TRUE;
2010  cqv0->valid = TRUE;
2011  /* TODO cq->nodelay = ???; */
2012  /* TODO cq->clswm = ???; */
2013  cqv0->arm = FALSE;
2014  cqv0->eq_id = eq_id;
2015 
2016  for (p = 0, addr = qmem->phys;
2017  p < cqv0->num_pages;
2018  p++, addr += page_bytes) {
2019  cqv0->page_physical_address[p].low = ocs_addr32_lo(addr);
2020  cqv0->page_physical_address[p].high = ocs_addr32_hi(addr);
2021  }
2022 
2023  break;
2026  {
2027  cqv2 = (sli4_req_common_create_cq_v2_t *)((uint8_t *)buf + sli_config_off);
2030  cqv2->hdr.version = 2;
2031  cqv2->hdr.request_length = cmd_size - sizeof(sli4_req_hdr_t);
2032 
2033  if (if_type == SLI4_IF_TYPE_LANCER_G7)
2034  cqv2->autovalid = TRUE;
2035 
2036  cqv2->page_size = page_size;
2037 
2038  /* valid values for number of pages: 1, 2, 4, 8 (sec 4.4.3) */
2039  cqv2->num_pages = num_pages;
2040  if (!cqv2->num_pages || (cqv2->num_pages > SLI4_COMMON_CREATE_CQ_V2_MAX_PAGES)) {
2041  return 0;
2042  }
2043 
2044  switch (cqv2->num_pages) {
2045  case 1:
2046  cqv2->cqecnt = SLI4_CQ_CNT_256;
2047  break;
2048  case 2:
2049  cqv2->cqecnt = SLI4_CQ_CNT_512;
2050  break;
2051  case 4:
2052  cqv2->cqecnt = SLI4_CQ_CNT_1024;
2053  break;
2054  case 8:
2055  cqv2->cqecnt = SLI4_CQ_CNT_LARGE;
2056  cqv2->cqe_count = n_cqe;
2057  break;
2058  default:
2059  ocs_log_test(sli4->os, "num_pages %d not valid\n", cqv2->num_pages);
2060  return -1;
2061  }
2062 
2063  cqv2->evt = TRUE;
2064  cqv2->valid = TRUE;
2065  /* TODO cq->nodelay = ???; */
2066  /* TODO cq->clswm = ???; */
2067  cqv2->arm = FALSE;
2068  cqv2->eq_id = eq_id;
2069 
2070  for (p = 0, addr = qmem->phys;
2071  p < cqv2->num_pages;
2072  p++, addr += page_bytes) {
2073  cqv2->page_physical_address[p].low = ocs_addr32_lo(addr);
2074  cqv2->page_physical_address[p].high = ocs_addr32_hi(addr);
2075  }
2076  }
2077  break;
2078  default:
2079  ocs_log_test(sli4->os, "unsupported IF_TYPE %d\n", if_type);
2080  return -1;
2081  }
2082 
2083  return (sli_config_off + cmd_size);
2084 }
2085 
2086 /**
2087  * @brief Write a COMMON_DESTROY_CQ command.
2088  *
2089  * @param sli4 SLI context.
2090  * @param buf Destination buffer for the command.
2091  * @param size Buffer size, in bytes.
2092  * @param cq_id CQ ID
2093  *
2094  * @note This creates a Version 0 message.
2095  *
2096  * @return Returns the number of bytes written.
2097  */
2098 static int32_t
2099 sli_cmd_common_destroy_cq(sli4_t *sli4, void *buf, size_t size, uint16_t cq_id)
2100 {
2101  sli4_req_common_destroy_cq_t *cq = NULL;
2102  uint32_t sli_config_off = 0;
2103 
2104  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2105  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2106  /* Payload length must accomodate both request and response */
2107  max(sizeof(sli4_req_common_destroy_cq_t),
2108  sizeof(sli4_res_hdr_t)),
2109  NULL);
2110  }
2111  cq = (sli4_req_common_destroy_cq_t *)((uint8_t *)buf + sli_config_off);
2112 
2116  sizeof(sli4_req_hdr_t);
2117  cq->cq_id = cq_id;
2118 
2119  return(sli_config_off + sizeof(sli4_req_common_destroy_cq_t));
2120 }
2121 
2122 /**
2123  * @brief Write a COMMON_MODIFY_EQ_DELAY command.
2124  *
2125  * @param sli4 SLI context.
2126  * @param buf Destination buffer for the command.
2127  * @param size Buffer size, in bytes.
2128  * @param q Queue object array.
2129  * @param num_q Queue object array count.
2130  * @param shift Phase shift for staggering interrupts.
2131  * @param delay_mult Delay multiplier for limiting interrupt frequency.
2132  *
2133  * @return Returns the number of bytes written.
2134  */
2135 static int32_t
2136 sli_cmd_common_modify_eq_delay(sli4_t *sli4, void *buf, size_t size, sli4_queue_t *q, int num_q, uint32_t shift,
2137  uint32_t delay_mult)
2138 {
2139  sli4_req_common_modify_eq_delay_t *modify_delay = NULL;
2140  uint32_t sli_config_off = 0;
2141  int i;
2142 
2143  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2144  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2145  /* Payload length must accomodate both request and response */
2146  max(sizeof(sli4_req_common_modify_eq_delay_t), sizeof(sli4_res_hdr_t)),
2147  NULL);
2148  }
2149 
2150  modify_delay = (sli4_req_common_modify_eq_delay_t *)((uint8_t *)buf + sli_config_off);
2151 
2152  modify_delay->hdr.opcode = SLI4_OPC_COMMON_MODIFY_EQ_DELAY;
2153  modify_delay->hdr.subsystem = SLI4_SUBSYSTEM_COMMON;
2154  modify_delay->hdr.request_length = sizeof(sli4_req_common_modify_eq_delay_t) -
2155  sizeof(sli4_req_hdr_t);
2156 
2157  modify_delay->num_eq = num_q;
2158 
2159  for (i = 0; i<num_q; i++) {
2160  modify_delay->eq_delay_record[i].eq_id = q[i].id;
2161  modify_delay->eq_delay_record[i].phase = shift;
2162  modify_delay->eq_delay_record[i].delay_multiplier = delay_mult;
2163  }
2164 
2165  return(sli_config_off + sizeof(sli4_req_common_modify_eq_delay_t));
2166 }
2167 
2168 /**
2169  * @brief Write a COMMON_CREATE_EQ command.
2170  *
2171  * @param sli4 SLI context.
2172  * @param buf Destination buffer for the command.
2173  * @param size Buffer size, in bytes.
2174  * @param qmem DMA memory for the queue.
2175  * @param ignored1 Ignored (used for consistency among queue creation functions).
2176  * @param ignored2 Ignored (used for consistency among queue creation functions).
2177  *
2178  * @note Other queue creation routines use the last parameter to pass in
2179  * the associated Q_ID and ULP. EQ doesn't have an associated queue or ULP,
2180  * so these parameters are ignored
2181  *
2182  * @note This creates a Version 0 message
2183  *
2184  * @return Returns the number of bytes written.
2185  */
2186 static int32_t
2187 sli_cmd_common_create_eq(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *qmem,
2188  uint16_t ignored1, uint16_t ignored2)
2189 {
2190  sli4_req_common_create_eq_t *eq = NULL;
2191  uint32_t sli_config_off = 0;
2192  uint32_t p;
2193  uintptr_t addr;
2194 
2195  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2196  uint32_t payload_size;
2197 
2198  /* Payload length must accomodate both request and response */
2199  payload_size = max(sizeof(sli4_req_common_create_eq_t),
2201 
2202  sli_config_off = sli_cmd_sli_config(sli4, buf, size, payload_size,
2203  NULL);
2204  }
2205  eq = (sli4_req_common_create_eq_t *)((uint8_t *)buf + sli_config_off);
2206 
2209  if (sli4->if_type == SLI4_IF_TYPE_LANCER_G7)
2210  eq->hdr.version = 2;
2211 
2213  sizeof(sli4_req_hdr_t);
2214  /* valid values for number of pages: 1, 2, 4 (sec 4.4.3) */
2215  eq->num_pages = qmem->size / SLI_PAGE_SIZE;
2216  switch (eq->num_pages) {
2217  case 1:
2218  eq->eqesz = SLI4_EQE_SIZE_4;
2219  eq->count = SLI4_EQ_CNT_1024;
2220  break;
2221  case 2:
2222  eq->eqesz = SLI4_EQE_SIZE_4;
2223  eq->count = SLI4_EQ_CNT_2048;
2224  break;
2225  case 4:
2226  eq->eqesz = SLI4_EQE_SIZE_4;
2227  eq->count = SLI4_EQ_CNT_4096;
2228  break;
2229  default:
2230  ocs_log_test(sli4->os, "num_pages %d not valid\n", eq->num_pages);
2231  return -1;
2232  }
2233 
2234  if (sli4->if_type == SLI4_IF_TYPE_LANCER_G7)
2235  eq->autovalid = TRUE;
2236 
2237  eq->valid = TRUE;
2238  eq->arm = FALSE;
2239  eq->delay_multiplier = 32;
2240 
2241  for (p = 0, addr = qmem->phys;
2242  p < eq->num_pages;
2243  p++, addr += SLI_PAGE_SIZE) {
2244  eq->page_address[p].low = ocs_addr32_lo(addr);
2245  eq->page_address[p].high = ocs_addr32_hi(addr);
2246  }
2247 
2248  return(sli_config_off + sizeof(sli4_req_common_create_eq_t));
2249 }
2250 
2251 
2252 /**
2253  * @brief Write a COMMON_DESTROY_EQ command.
2254  *
2255  * @param sli4 SLI context.
2256  * @param buf Destination buffer for the command.
2257  * @param size Buffer size, in bytes.
2258  * @param eq_id Queue ID to destroy.
2259  *
2260  * @note Other queue creation routines use the last parameter to pass in
2261  * the associated Q_ID. EQ doesn't have an associated queue so this
2262  * parameter is ignored.
2263  *
2264  * @note This creates a Version 0 message.
2265  *
2266  * @return Returns the number of bytes written.
2267  */
2268 static int32_t
2269 sli_cmd_common_destroy_eq(sli4_t *sli4, void *buf, size_t size, uint16_t eq_id)
2270 {
2271  sli4_req_common_destroy_eq_t *eq = NULL;
2272  uint32_t sli_config_off = 0;
2273 
2274  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2275  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2276  /* Payload length must accomodate both request and response */
2277  max(sizeof(sli4_req_common_destroy_eq_t),
2278  sizeof(sli4_res_hdr_t)),
2279  NULL);
2280  }
2281  eq = (sli4_req_common_destroy_eq_t *)((uint8_t *)buf + sli_config_off);
2282 
2286  sizeof(sli4_req_hdr_t);
2287 
2288  eq->eq_id = eq_id;
2289 
2290  return(sli_config_off + sizeof(sli4_req_common_destroy_eq_t));
2291 }
2292 
2293 /**
2294  * @brief Write a LOWLEVEL_SET_WATCHDOG command.
2295  *
2296  * @param sli4 SLI context.
2297  * @param buf Destination buffer for the command.
2298  * @param size Buffer size, in bytes.
2299  * @param timeout watchdog timer timeout in seconds
2300  *
2301  * @return void
2302  */
2303 void
2304 sli4_cmd_lowlevel_set_watchdog(sli4_t *sli4, void *buf, size_t size, uint16_t timeout)
2305 {
2306 
2308  uint32_t sli_config_off = 0;
2309 
2310  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2311  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2312  /* Payload length must accomodate both request and response */
2315  NULL);
2316  }
2317  req = (sli4_req_lowlevel_set_watchdog_t *)((uint8_t *)buf + sli_config_off);
2318 
2322  req->watchdog_timeout = timeout;
2323 
2324  return;
2325 }
2326 
2327 
2328 /**
2329  * @brief Write a LOWLEVEL_SET_DIAG_LOG_OPTIONS command.
2330  *
2331  * @param sli4 SLI context.
2332  * @param buf Destination buffer for the command.
2333  * @param size Buffer size, in bytes.
2334  * @param timeout watchdog timer timeout in seconds
2335  *
2336  * @return void
2337  */
2338 void
2339 sli4_cmd_lowlevel_enable_ras(sli4_t *sli4, void *buf, size_t size, int log_level,
2340  uint32_t unit_size, int32_t buf_count, uint32_t *phys_addr,
2341  uintptr_t lwpd_phys_addr)
2342 {
2343  int32_t i;
2344  uint32_t sli_config_off = 0;
2346 
2347  ocs_memset(buf, 0x00, sizeof(sli4_req_lowlevel_set_diag_log_options_t) + sizeof(sli4_req_hdr_t));
2348 
2349  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2350  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2351  /* Payload length must accomodate both request and response */
2354  NULL);
2355  }
2356  req = (sli4_req_lowlevel_set_diag_log_options_t *)((uint8_t *)buf + sli_config_off);
2357 
2361  sizeof(sli4_req_hdr_t) + sizeof(uint32_t) * 2 * buf_count;
2362  req->enable = 1;
2363  req->reset_action = 0;
2364  req->log_level = log_level;
2365  req->buffer_size = (uint8_t)(unit_size / 4096);
2366  req->buffer_cnt = (uint8_t)buf_count;
2367  req->acqe_interval = 0; // Disabled
2368  req->cq_id = 0;
2369  req->lwpd_addr_lo = (uint32_t)(lwpd_phys_addr & 0xFFFFFFFF);
2370  req->lwpd_addr_hi = (uint32_t)(lwpd_phys_addr >> 32);
2371  for (i = 0; i < buf_count; i++) {
2372  req->buffer_desc[i].addr_lo = phys_addr[i * 2];
2373  req->buffer_desc[i].addr_hi = phys_addr[i * 2 + 1];
2374  }
2375 }
2376 
2377 
2378 /**
2379  * @brief Write a LOWLEVEL_SET_DIAG_LOG_OPTIONS command.
2380  *
2381  * @param sli4 SLI context.
2382  * @param buf Destination buffer for the command.
2383  * @param size Buffer size, in bytes.
2384  * @param timeout watchdog timer timeout in seconds
2385  *
2386  * @return void
2387  */
2388 void
2389 sli4_cmd_lowlevel_disable_ras(sli4_t *sli4, void *buf, size_t size)
2390 {
2391  uint32_t sli_config_off = 0;
2393 
2394  ocs_memset(buf, 0x00, sizeof(sli4_req_lowlevel_set_diag_log_options_t) + sizeof(sli4_req_hdr_t));
2395 
2396  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2397  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2398  /* Payload length must accomodate both request and response */
2401  NULL);
2402  }
2403  req = (sli4_req_lowlevel_set_diag_log_options_t *)((uint8_t *)buf + sli_config_off);
2404 
2408  req->enable = 0;
2409 }
2410 
2411 void
2412 sli4_cmd_lowlevel_get_itcm_parity_stats(sli4_t *sli4, void *buf, size_t size, bool clear_stats)
2413 {
2415  uint32_t sli_config_off = 0;
2416 
2417  if (SLI4_PORT_TYPE_FC == sli4->port_type)
2418  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2419  /* Payload length must accomodate both request and response */
2420  max(sizeof(*req), sizeof(sli4_res_lowlevel_get_itcm_parity_stats_t)),
2421  NULL);
2422 
2426  req->hdr.request_length = (sizeof(*req) - sizeof(sli4_req_hdr_t));
2427  if (clear_stats) {
2428  ocs_log_info(sli4->os, "Clearing the ITCM parity stats\n");
2429  req->clr_pbec = 1;
2430  req->clr_tpec = 1;
2431  }
2432 }
2433 
2434 static int32_t
2435 sli_cmd_common_get_cntl_attributes(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma)
2436 {
2437  sli4_req_hdr_t *hdr = NULL;
2438  uint32_t sli_config_off = 0;
2439 
2440  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2441  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2442  sizeof(sli4_req_hdr_t),
2443  dma);
2444  }
2445 
2446  if (dma == NULL) {
2447  return 0;
2448  }
2449 
2450  ocs_memset(dma->virt, 0, dma->size);
2451 
2452  hdr = dma->virt;
2453 
2456  hdr->request_length = dma->size;
2457 
2458  return(sli_config_off + sizeof(sli4_req_hdr_t));
2459 }
2460 
2461 /**
2462  * @brief Write a COMMON_GET_CNTL_ADDL_ATTRIBUTES command.
2463  *
2464  * @param sli4 SLI context.
2465  * @param buf Destination buffer for the command.
2466  * @param size Buffer size, in bytes.
2467  * @param dma DMA structure from which the data will be copied.
2468  *
2469  * @note This creates a Version 0 message.
2470  *
2471  * @return Returns the number of bytes written.
2472  */
2473 static int32_t
2474 sli_cmd_common_get_cntl_addl_attributes(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma)
2475 {
2476  sli4_req_hdr_t *hdr = NULL;
2477  uint32_t sli_config_off = 0;
2478 
2479  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2480  sli_config_off = sli_cmd_sli_config(sli4, buf, size, sizeof(sli4_req_hdr_t), dma);
2481  }
2482 
2483  if (dma == NULL) {
2484  return 0;
2485  }
2486 
2487  ocs_memset(dma->virt, 0, dma->size);
2488 
2489  hdr = dma->virt;
2490 
2493  hdr->request_length = dma->size;
2494 
2495  return(sli_config_off + sizeof(sli4_req_hdr_t));
2496 }
2497 
2498 /**
2499  * @brief Write a COMMON_CREATE_MQ_EXT command.
2500  *
2501  * @param sli4 SLI context.
2502  * @param buf Destination buffer for the command.
2503  * @param size Buffer size, in bytes.
2504  * @param qmem DMA memory for the queue.
2505  * @param cq_id Associated CQ_ID.
2506  * @param ignored This parameter carries the ULP which is only used for WQ and RQs
2507  *
2508  * @note This creates a Version 0 message.
2509  *
2510  * @return Returns the number of bytes written.
2511  */
2512 static int32_t
2513 sli_cmd_common_create_mq_ext(sli4_t *sli4, void *buf, size_t size,
2514  ocs_dma_t *qmem, uint16_t cq_id, uint16_t ignored)
2515 {
2517  uint32_t sli_config_off = 0;
2518  uint32_t p;
2519  uintptr_t addr;
2520 
2521  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2522  uint32_t payload_size;
2523 
2524  /* Payload length must accomodate both request and response */
2525  payload_size = max(sizeof(sli4_req_common_create_mq_ext_t),
2527 
2528  sli_config_off = sli_cmd_sli_config(sli4, buf, size, payload_size,
2529  NULL);
2530  }
2531  mq = (sli4_req_common_create_mq_ext_t *)((uint8_t *)buf + sli_config_off);
2532 
2536  sizeof(sli4_req_hdr_t);
2537  /* valid values for number of pages: 1, 2, 4, 8 (sec 4.4.12) */
2538  mq->num_pages = qmem->size / SLI_PAGE_SIZE;
2539  switch (mq->num_pages) {
2540  case 1:
2542  break;
2543  case 2:
2545  break;
2546  case 4:
2548  break;
2549  case 8:
2551  break;
2552  default:
2553  ocs_log_test(sli4->os, "num_pages %d not valid\n", mq->num_pages);
2554  return -1;
2555  }
2556 
2557  /* TODO break this down by sli4->config.topology */
2559 
2560  if (sli4->config.mq_create_version) {
2561  mq->cq_id_v1 = cq_id;
2562  mq->hdr.version = 1;
2563  }
2564  else {
2565  mq->cq_id_v0 = cq_id;
2566  }
2567  mq->val = TRUE;
2568 
2569  for (p = 0, addr = qmem->phys;
2570  p < mq->num_pages;
2571  p++, addr += SLI_PAGE_SIZE) {
2572  mq->page_physical_address[p].low = ocs_addr32_lo(addr);
2573  mq->page_physical_address[p].high = ocs_addr32_hi(addr);
2574  }
2575 
2576  return(sli_config_off + sizeof(sli4_req_common_create_mq_ext_t));
2577 }
2578 
2579 /**
2580  * @brief Write a COMMON_DESTROY_MQ command.
2581  *
2582  * @param sli4 SLI context.
2583  * @param buf Destination buffer for the command.
2584  * @param size Buffer size, in bytes.
2585  * @param mq_id MQ ID
2586  *
2587  * @note This creates a Version 0 message.
2588  *
2589  * @return Returns the number of bytes written.
2590  */
2591 static int32_t
2592 sli_cmd_common_destroy_mq(sli4_t *sli4, void *buf, size_t size, uint16_t mq_id)
2593 {
2594  sli4_req_common_destroy_mq_t *mq = NULL;
2595  uint32_t sli_config_off = 0;
2596 
2597  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2598  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2599  /* Payload length must accomodate both request and response */
2600  max(sizeof(sli4_req_common_destroy_mq_t),
2601  sizeof(sli4_res_hdr_t)),
2602  NULL);
2603  }
2604  mq = (sli4_req_common_destroy_mq_t *)((uint8_t *)buf + sli_config_off);
2605 
2609  sizeof(sli4_req_hdr_t);
2610 
2611  mq->mq_id = mq_id;
2612 
2613  return(sli_config_off + sizeof(sli4_req_common_destroy_mq_t));
2614 }
2615 
2616 /**
2617  * @ingroup sli
2618  * @brief Write a COMMON_NOP command
2619  *
2620  * @param sli4 SLI context.
2621  * @param buf Destination buffer for the command.
2622  * @param size Buffer size, in bytes.
2623  * @param context NOP context value (passed to response, except on FC/FCoE).
2624  *
2625  * @return Returns the number of bytes written.
2626  */
2627 int32_t
2628 sli_cmd_common_nop(sli4_t *sli4, void *buf, size_t size, uint64_t context)
2629 {
2630  sli4_req_common_nop_t *nop = NULL;
2631  uint32_t sli_config_off = 0;
2632 
2633  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2634  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2635  /* Payload length must accomodate both request and response */
2636  max(sizeof(sli4_req_common_nop_t), sizeof(sli4_res_common_nop_t)),
2637  NULL);
2638  }
2639 
2640  nop = (sli4_req_common_nop_t *)((uint8_t *)buf + sli_config_off);
2641 
2644  nop->hdr.request_length = 8;
2645 
2646  ocs_memcpy(&nop->context, &context, sizeof(context));
2647 
2648  return(sli_config_off + sizeof(sli4_req_common_nop_t));
2649 }
2650 
2651 /**
2652  * @ingroup sli
2653  * @brief Write a COMMON_GET_RESOURCE_EXTENT_INFO command.
2654  *
2655  * @param sli4 SLI context.
2656  * @param buf Destination buffer for the command.
2657  * @param size Buffer size, in bytes.
2658  * @param rtype Resource type (for example, XRI, VFI, VPI, and RPI).
2659  *
2660  * @return Returns the number of bytes written.
2661  */
2662 int32_t
2663 sli_cmd_common_get_resource_extent_info(sli4_t *sli4, void *buf, size_t size, uint16_t rtype)
2664 {
2666  uint32_t sli_config_off = 0;
2667 
2668  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2669  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2671  NULL);
2672  }
2673 
2674  extent = (sli4_req_common_get_resource_extent_info_t *)((uint8_t *)buf + sli_config_off);
2675 
2678  extent->hdr.request_length = 4;
2679 
2680  extent->resource_type = rtype;
2681 
2682  return(sli_config_off + sizeof(sli4_req_common_get_resource_extent_info_t));
2683 }
2684 
2685 /**
2686  * @ingroup sli
2687  * @brief Write a COMMON_GET_SLI4_PARAMETERS command.
2688  *
2689  * @param sli4 SLI context.
2690  * @param buf Destination buffer for the command.
2691  * @param size Buffer size, in bytes.
2692  *
2693  * @return Returns the number of bytes written.
2694  */
2695 int32_t
2696 sli_cmd_common_get_sli4_parameters(sli4_t *sli4, void *buf, size_t size)
2697 {
2698  sli4_req_hdr_t *hdr = NULL;
2699  uint32_t sli_config_off = 0;
2700 
2701  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2702  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2704  NULL);
2705  }
2706 
2707  hdr = (sli4_req_hdr_t *)((uint8_t *)buf + sli_config_off);
2708 
2711  hdr->request_length = 0x50;
2712 
2713  return(sli_config_off + sizeof(sli4_req_hdr_t));
2714 }
2715 
2716 /**
2717  * @brief Write a COMMON_QUERY_FW_CONFIG command to the provided buffer.
2718  *
2719  * @param sli4 SLI context pointer.
2720  * @param buf Virtual pointer to destination buffer.
2721  * @param size Buffer size in bytes.
2722  *
2723  * @return Returns the number of bytes written
2724  */
2725 static int32_t
2726 sli_cmd_common_query_fw_config(sli4_t *sli4, void *buf, size_t size)
2727 {
2729  uint32_t sli_config_off = 0;
2730  uint32_t payload_size;
2731 
2732  /* Payload length must accomodate both request and response */
2733  payload_size = max(sizeof(sli4_req_common_query_fw_config_t),
2735 
2736  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2737  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2738  payload_size,
2739  NULL);
2740  }
2741 
2742  fw_config = (sli4_req_common_query_fw_config_t*)((uint8_t*)buf + sli_config_off);
2744  fw_config->hdr.subsystem = SLI4_SUBSYSTEM_COMMON;
2745  fw_config->hdr.request_length = payload_size - sizeof(sli4_req_hdr_t);
2746  return sli_config_off + sizeof(sli4_req_common_query_fw_config_t);
2747 }
2748 
2749 /**
2750  * @brief Write a COMMON_GET_PORT_NAME command to the provided buffer.
2751  *
2752  * @param sli4 SLI context pointer.
2753  * @param buf Virtual pointer to destination buffer.
2754  * @param size Buffer size in bytes.
2755  *
2756  * @note Function supports both version 0 and 1 forms of this command via
2757  * the IF_TYPE.
2758  *
2759  * @return Returns the number of bytes written.
2760  */
2761 static int32_t
2762 sli_cmd_common_get_port_name(sli4_t *sli4, void *buf, size_t size)
2763 {
2765  uint32_t sli_config_off = 0;
2766  uint32_t payload_size;
2767  uint8_t version = 0;
2768  uint8_t pt = 0;
2769 
2770  /* Select command version according to IF_TYPE */
2771  switch (sli4->if_type) {
2774  version = 0;
2775  break;
2779  version = 1;
2780  break;
2781  default:
2782  ocs_log_test(sli4->os, "unsupported IF_TYPE %d\n", sli4->if_type);
2783  return 0;
2784  }
2785 
2786  /* Payload length must accomodate both request and response */
2787  payload_size = max(sizeof(sli4_req_common_get_port_name_t),
2789 
2790  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2791  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2792  payload_size,
2793  NULL);
2794 
2795  pt = 1;
2796  }
2797 
2798  port_name = (sli4_req_common_get_port_name_t *)((uint8_t *)buf + sli_config_off);
2799 
2801  port_name->hdr.subsystem = SLI4_SUBSYSTEM_COMMON;
2802  port_name->hdr.request_length = sizeof(sli4_req_hdr_t) + (version * sizeof(uint32_t));
2803  port_name->hdr.version = version;
2804 
2805  /* Set the port type value (ethernet=0, FC=1) for V1 commands */
2806  if (version == 1) {
2807  port_name->pt = pt;
2808  }
2809 
2810  return sli_config_off + port_name->hdr.request_length;
2811 }
2812 
2813 
2814 /**
2815  * @ingroup sli
2816  * @brief Write a COMMON_WRITE_OBJECT command.
2817  *
2818  * @param sli4 SLI context.
2819  * @param buf Destination buffer for the command.
2820  * @param size Buffer size, in bytes.
2821  * @param noc True if the object should be written but not committed to flash.
2822  * @param eof True if this is the last write for this object.
2823  * @param desired_write_length Number of bytes of data to write to the object.
2824  * @param offset Offset, in bytes, from the start of the object.
2825  * @param object_name Name of the object to write.
2826  * @param dma DMA structure from which the data will be copied.
2827  *
2828  * @return Returns the number of bytes written.
2829  */
2830 int32_t
2831 sli_cmd_common_write_object(sli4_t *sli4, void *buf, size_t size,
2832  uint16_t noc, uint16_t eof, uint32_t desired_write_length,
2833  uint32_t offset,
2834  char *object_name,
2835  ocs_dma_t *dma)
2836 {
2837  sli4_req_common_write_object_t *wr_obj = NULL;
2838  uint32_t sli_config_off = 0;
2839  sli4_bde_t *host_buffer;
2840 
2841  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2842  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2843  sizeof (sli4_req_common_write_object_t) + sizeof (sli4_bde_t),
2844  NULL);
2845  }
2846 
2847  wr_obj = (sli4_req_common_write_object_t *)((uint8_t *)buf + sli_config_off);
2848 
2851  wr_obj->hdr.request_length = sizeof(*wr_obj) - 4*sizeof(uint32_t) + sizeof(sli4_bde_t);
2852  wr_obj->hdr.timeout = 0;
2853  wr_obj->hdr.version = 0;
2854 
2855  wr_obj->noc = noc;
2856  wr_obj->eof = eof;
2857  wr_obj->desired_write_length = desired_write_length;
2858  wr_obj->write_offset = offset;
2859  ocs_strncpy(wr_obj->object_name, object_name, sizeof(wr_obj->object_name));
2860  wr_obj->host_buffer_descriptor_count = 1;
2861 
2862  host_buffer = (sli4_bde_t *)wr_obj->host_buffer_descriptor;
2863 
2864  // Setup to transfer xfer_size bytes to device
2865  host_buffer->bde_type = SLI4_BDE_TYPE_BDE_64;
2866  host_buffer->buffer_length = desired_write_length;
2867  host_buffer->u.data.buffer_address_low = ocs_addr32_lo(dma->phys);
2868  host_buffer->u.data.buffer_address_high = ocs_addr32_hi(dma->phys);
2869 
2870 
2871  return(sli_config_off + sizeof(sli4_req_common_write_object_t) + sizeof (sli4_bde_t));
2872 }
2873 
2874 
2875 /**
2876  * @ingroup sli
2877  * @brief Write a COMMON_DELETE_OBJECT command.
2878  *
2879  * @param sli4 SLI context.
2880  * @param buf Destination buffer for the command.
2881  * @param size Buffer size, in bytes.
2882  * @param object_name Name of the object to write.
2883  *
2884  * @return Returns the number of bytes written.
2885  */
2886 int32_t
2887 sli_cmd_common_delete_object(sli4_t *sli4, void *buf, size_t size,
2888  char *object_name)
2889 {
2890  sli4_req_common_delete_object_t *del_obj = NULL;
2891  uint32_t sli_config_off = 0;
2892 
2893  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2894  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2896  NULL);
2897  }
2898 
2899  del_obj = (sli4_req_common_delete_object_t *)((uint8_t *)buf + sli_config_off);
2900 
2902  del_obj->hdr.subsystem = SLI4_SUBSYSTEM_COMMON;
2903  del_obj->hdr.request_length = sizeof(*del_obj);
2904  del_obj->hdr.timeout = 0;
2905  del_obj->hdr.version = 0;
2906 
2907  ocs_strncpy(del_obj->object_name, object_name, sizeof(del_obj->object_name));
2908  return(sli_config_off + sizeof(sli4_req_common_delete_object_t));
2909 }
2910 
2911 /**
2912  * @ingroup sli
2913  * @brief Write a COMMON_READ_OBJECT command.
2914  *
2915  * @param sli4 SLI context.
2916  * @param buf Destination buffer for the command.
2917  * @param size Buffer size, in bytes.
2918  * @param desired_read_length Number of bytes of data to read from the object.
2919  * @param offset Offset, in bytes, from the start of the object.
2920  * @param object_name Name of the object to read.
2921  * @param dma DMA structure from which the data will be copied.
2922  *
2923  * @return Returns the number of bytes written.
2924  */
2925 int32_t
2926 sli_cmd_common_read_object(sli4_t *sli4, void *buf, size_t size,
2927  uint32_t desired_read_length,
2928  uint32_t offset,
2929  char *object_name,
2930  ocs_dma_t *dma)
2931 {
2932  sli4_req_common_read_object_t *rd_obj = NULL;
2933  uint32_t sli_config_off = 0;
2934  sli4_bde_t *host_buffer;
2935 
2936  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2937  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2938  sizeof (sli4_req_common_read_object_t) + sizeof (sli4_bde_t),
2939  NULL);
2940  }
2941 
2942  rd_obj = (sli4_req_common_read_object_t *)((uint8_t *)buf + sli_config_off);
2943 
2946  rd_obj->hdr.request_length = sizeof(*rd_obj) - 4*sizeof(uint32_t) + sizeof(sli4_bde_t);
2947  rd_obj->hdr.timeout = 0;
2948  rd_obj->hdr.version = 0;
2949 
2950  rd_obj->desired_read_length = desired_read_length;
2951  rd_obj->read_offset = offset;
2952  ocs_strncpy(rd_obj->object_name, object_name, sizeof(rd_obj->object_name));
2953  rd_obj->host_buffer_descriptor_count = 1;
2954 
2955  host_buffer = (sli4_bde_t *)rd_obj->host_buffer_descriptor;
2956 
2957  // Setup to transfer xfer_size bytes to device
2958  host_buffer->bde_type = SLI4_BDE_TYPE_BDE_64;
2959  host_buffer->buffer_length = desired_read_length;
2960  if (dma != NULL) {
2961  host_buffer->u.data.buffer_address_low = ocs_addr32_lo(dma->phys);
2962  host_buffer->u.data.buffer_address_high = ocs_addr32_hi(dma->phys);
2963  } else {
2964  host_buffer->u.data.buffer_address_low = 0;
2965  host_buffer->u.data.buffer_address_high = 0;
2966  }
2967 
2968 
2969  return(sli_config_off + sizeof(sli4_req_common_read_object_t) + sizeof (sli4_bde_t));
2970 }
2971 
2972 /**
2973  * @ingroup sli
2974  * @brief Write a DMTF_EXEC_CLP_CMD command.
2975  *
2976  * @param sli4 SLI context.
2977  * @param buf Destination buffer for the command.
2978  * @param size Buffer size, in bytes.
2979  * @param cmd DMA structure that describes the buffer for the command.
2980  * @param resp DMA structure that describes the buffer for the response.
2981  *
2982  * @return Returns the number of bytes written.
2983  */
2984 int32_t
2985 sli_cmd_dmtf_exec_clp_cmd(sli4_t *sli4, void *buf, size_t size,
2986  ocs_dma_t *cmd,
2987  ocs_dma_t *resp)
2988 {
2989  sli4_req_dmtf_exec_clp_cmd_t *clp_cmd = NULL;
2990  uint32_t sli_config_off = 0;
2991 
2992  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
2993  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
2995  NULL);
2996  }
2997 
2998  clp_cmd = (sli4_req_dmtf_exec_clp_cmd_t*)((uint8_t *)buf + sli_config_off);
2999 
3001  clp_cmd->hdr.subsystem = SLI4_SUBSYSTEM_DMTF;
3002  clp_cmd->hdr.request_length = sizeof(sli4_req_dmtf_exec_clp_cmd_t) -
3003  sizeof(sli4_req_hdr_t);
3004  clp_cmd->hdr.timeout = 0;
3005  clp_cmd->hdr.version = 0;
3006  clp_cmd->cmd_buf_length = cmd->size;
3007  clp_cmd->cmd_buf_addr_low = ocs_addr32_lo(cmd->phys);
3008  clp_cmd->cmd_buf_addr_high = ocs_addr32_hi(cmd->phys);
3009  clp_cmd->resp_buf_length = resp->size;
3010  clp_cmd->resp_buf_addr_low = ocs_addr32_lo(resp->phys);
3011  clp_cmd->resp_buf_addr_high = ocs_addr32_hi(resp->phys);
3012 
3013  return(sli_config_off + sizeof(sli4_req_dmtf_exec_clp_cmd_t));
3014 }
3015 
3016 /**
3017  * @ingroup sli
3018  * @brief Write a COMMON_SET_DUMP_LOCATION command.
3019  *
3020  * @param sli4 SLI context.
3021  * @param buf Destination buffer for the command.
3022  * @param size Buffer size, in bytes.
3023  * @param query Zero to set dump location, non-zero to query dump size
3024  * @param is_buffer_list Set to one if the buffer is a set of buffer descriptors or
3025  * set to 0 if the buffer is a contiguous dump area.
3026  * @param buffer DMA structure to which the dump will be copied.
3027  *
3028  * @return Returns the number of bytes written.
3029  */
3030 int32_t
3031 sli_cmd_common_set_dump_location(sli4_t *sli4, void *buf, size_t size,
3032  uint8_t query, uint8_t is_buffer_list,
3033  ocs_dma_t *buffer, uint8_t fdb)
3034 {
3035  sli4_req_common_set_dump_location_t *set_dump_loc = NULL;
3036  uint32_t sli_config_off = 0;
3037 
3038  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
3039  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
3041  NULL);
3042  }
3043 
3044  set_dump_loc = (sli4_req_common_set_dump_location_t *)((uint8_t *)buf + sli_config_off);
3045 
3047  set_dump_loc->hdr.subsystem = SLI4_SUBSYSTEM_COMMON;
3048  set_dump_loc->hdr.request_length = sizeof(sli4_req_common_set_dump_location_t) - sizeof(sli4_req_hdr_t);
3049  set_dump_loc->hdr.timeout = 0;
3050  set_dump_loc->hdr.version = 0;
3051 
3052  set_dump_loc->blp = is_buffer_list;
3053  set_dump_loc->qry = query;
3054  set_dump_loc->fdb = fdb;
3055 
3056  if (buffer) {
3057  set_dump_loc->buf_addr_low = ocs_addr32_lo(buffer->phys);
3058  set_dump_loc->buf_addr_high = ocs_addr32_hi(buffer->phys);
3059  set_dump_loc->buffer_length = buffer->len;
3060  } else {
3061  set_dump_loc->buf_addr_low = 0;
3062  set_dump_loc->buf_addr_high = 0;
3063  set_dump_loc->buffer_length = 0;
3064  }
3065 
3066  return(sli_config_off + sizeof(sli4_req_common_set_dump_location_t));
3067 }
3068 
3069 /**
3070  * @ingroup sli
3071  * @brief Write a RUN_BIU_DIAG command.
3072  *
3073  * @param sli4 SLI context.
3074  * @param buf Destination buffer for the command.
3075  * @param size Buffer size, in bytes.
3076  * @param TX DMA buffer structure
3077  * @param TX DMA buffer size
3078  * @param RX DMA buffer structure
3079  * @param RX DMA buffer size
3080  *
3081  * @return Returns the number of bytes written.
3082  */
3083 int32_t
3084 sli_cmd_config_run_biu_diag(sli4_t *sli4, void *buf, size_t size,
3085  ocs_dma_t *tx_buffer, size_t tx_buf_len,
3086  ocs_dma_t *rx_buffer, size_t rx_buf_len)
3087 {
3088  sli4_cmd_config_run_biu_diag_t *req = buf;
3089 
3090  if (!sli4 || !buf) {
3091  ocs_log_err(NULL, "Invalid parameters\n");
3092  return 0;
3093  }
3094 
3095  if (!tx_buffer || !rx_buffer) {
3096  ocs_log_err(sli4->os, "Invalid Tx/Rx buffers\n");
3097  return 0;
3098  }
3099  ocs_memset(buf, 0, size);
3100 
3102 
3103  req->tx_phy_addr_low = ocs_addr32_lo(tx_buffer->phys);
3104  req->tx_phy_addr_high = ocs_addr32_hi(tx_buffer->phys);
3105  req->tx_buf_len = tx_buf_len;
3106 
3107  req->rx_phy_addr_low = ocs_addr32_lo(rx_buffer->phys);
3108  req->rx_phy_addr_high = ocs_addr32_hi(rx_buffer->phys);
3109  req->rx_buf_len = rx_buf_len;
3110 
3111  return(sizeof(sli4_cmd_config_run_biu_diag_t));
3112 }
3113 /**
3114  * @ingroup sli
3115  * @brief Write a SLI4_OPC_FCOE_SET_LINK_DIAG_LOOPBACK command.
3116  *
3117  * @param sli4 SLI context.
3118  * @param buf Destination buffer for the command.
3119  * @param size Buffer size, in bytes.
3120  * @param type Loopback type.
3121  *
3122  * @return Returns the number of bytes written.
3123  */
3124 
3125 int32_t
3126 sli_cmd_fcoe_set_loopback_mode(sli4_t *sli4, void *buf, size_t size, int type)
3127 {
3128  sli4_req_common_set_loopback_mode_t *set_loopback_mode = NULL;
3129  uint32_t sli_config_off = 0;
3130 
3131  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
3132  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
3134  NULL);
3135  }
3136 
3137  set_loopback_mode = (sli4_req_common_set_loopback_mode_t *)((uint8_t *)buf + sli_config_off);
3138 
3139  set_loopback_mode->hdr.opcode = SLI4_OPC_FCOE_SET_LINK_DIAG_LOOPBACK;
3140  set_loopback_mode->hdr.subsystem = SLI4_SUBSYSTEM_FCFCOE;
3141  set_loopback_mode->hdr.request_length = sizeof(sli4_req_common_set_loopback_mode_t) - sizeof(sli4_req_hdr_t);
3142  set_loopback_mode->hdr.timeout = 0;
3143  set_loopback_mode->hdr.version = 0;
3144 
3145  set_loopback_mode->typ = type; /* Loopback type */
3146  set_loopback_mode->link_number = sli4->config.port_number; /* Link number */
3147  set_loopback_mode->link_type = 0x1; /* FC Link */
3148 
3149  return(sli_config_off + sizeof(sli4_req_common_set_loopback_mode_t));
3150 }
3151 
3152 /**
3153  * @ingroup sli
3154  * @brief Write a SLI4_OPC_FC_SET_TRUNK_MODE command.
3155  *
3156  * @param sli4 SLI context.
3157  * @param buf Destination buffer for the command.
3158  * @param size Buffer size, in bytes.
3159  * @param trunk_mode Trunk mode.
3160  *
3161  * @return Returns the number of bytes written or '-1' if an invalid trunk mode is requested.
3162  */
3163 
3164 int32_t
3165 sli_cmd_fc_set_trunk_mode(sli4_t *sli4, void *buf, size_t size, uint32_t trunk_mode)
3166 {
3167  sli4_req_set_trunk_mode_t *req = NULL;
3168  uint32_t sli_config_off = 0;
3169 
3170  if (trunk_mode > SLI4_TRUNK_MODE_4_LINKS_PER_TRUNK)
3171  return -1;
3172 
3173  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
3174  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
3175  /* Payload length must accomodate both request and response */
3176  max(sizeof(sli4_req_set_trunk_mode_t),
3177  sizeof(sli4_res_set_trunk_mode_t)),
3178  NULL);
3179  }
3180  req = (sli4_req_set_trunk_mode_t *)((uint8_t *)buf + sli_config_off);
3184  req->trunk_mode = trunk_mode;
3185  return (sli_config_off + sizeof(sli4_req_set_trunk_mode_t));
3186 }
3187 
3188 /**
3189  * @ingroup sli
3190  * @brief Write a COMMON_SET_FEATURES command.
3191  *
3192  * @param sli4 SLI context.
3193  * @param buf Destination buffer for the command.
3194  * @param size Buffer size, in bytes.
3195  * @param feature Feature to set.
3196  * @param param_len Length of the parameter (must be a multiple of 4 bytes).
3197  * @param parameter Pointer to the parameter value.
3198  *
3199  * @return Returns the number of bytes written.
3200  */
3201 int32_t
3202 sli_cmd_common_set_features(sli4_t *sli4, void *buf, size_t size,
3203  uint32_t feature,
3204  uint32_t param_len,
3205  void* parameter)
3206 {
3207  sli4_req_common_set_features_t *cmd = NULL;
3208  uint32_t sli_config_off = 0;
3209 
3210  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
3211  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
3213  NULL);
3214  }
3215 
3216  cmd = (sli4_req_common_set_features_t *)((uint8_t *)buf + sli_config_off);
3217 
3221  cmd->hdr.timeout = 0;
3222  cmd->hdr.version = 0;
3223 
3224  cmd->feature = feature;
3225  cmd->param_len = param_len;
3226  ocs_memcpy(cmd->params, parameter, param_len);
3227 
3228  return(sli_config_off + sizeof(sli4_req_common_set_features_t));
3229 }
3230 
3231 /**
3232  * @ingroup sli
3233  * @brief Write a COMMON_COMMON_GET_PROFILE_CONFIG command.
3234  *
3235  * @param sli4 SLI context.
3236  * @param buf Destination buffer for the command.
3237  * @param size Buffer size in bytes.
3238  * @param dma DMA capable memory used to retrieve profile.
3239  *
3240  * @return Returns the number of bytes written.
3241  */
3242 int32_t
3243 sli_cmd_common_get_profile_config(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma)
3244 {
3246  uint32_t sli_config_off = 0;
3247  uint32_t payload_size;
3248 
3249  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
3250  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
3252  dma);
3253  }
3254 
3255  if (dma != NULL) {
3256  req = dma->virt;
3257  ocs_memset(req, 0, dma->size);
3258  payload_size = dma->size;
3259  } else {
3260  req = (sli4_req_common_get_profile_config_t *)((uint8_t *)buf + sli_config_off);
3261  payload_size = sizeof(sli4_req_common_get_profile_config_t);
3262  }
3263 
3266  req->hdr.request_length = payload_size - sizeof(sli4_req_hdr_t);
3267  req->hdr.version = 1;
3268 
3269  return(sli_config_off + sizeof(sli4_req_common_get_profile_config_t));
3270 }
3271 
3272 /**
3273  * @ingroup sli
3274  * @brief Write a COMMON_COMMON_SET_PROFILE_CONFIG command.
3275  *
3276  * @param sli4 SLI context.
3277  * @param buf Destination buffer for the command.
3278  * @param size Buffer size, in bytes.
3279  * @param dma DMA capable memory containing profile.
3280  * @param profile_id Profile ID to configure.
3281  * @param descriptor_count Number of descriptors in DMA buffer.
3282  * @param isap Implicit Set Active Profile value to use.
3283  *
3284  * @return Returns the number of bytes written.
3285  */
3286 int32_t
3287 sli_cmd_common_set_profile_config(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma,
3288  uint8_t profile_id, uint32_t descriptor_count, uint8_t isap)
3289 {
3291  uint32_t cmd_off = 0;
3292  uint32_t payload_size;
3293 
3294  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
3295  cmd_off = sli_cmd_sli_config(sli4, buf, size,
3297  dma);
3298  }
3299 
3300  if (dma != NULL) {
3301  req = dma->virt;
3302  ocs_memset(req, 0, dma->size);
3303  payload_size = dma->size;
3304  } else {
3305  req = (sli4_req_common_set_profile_config_t *)((uint8_t *)buf + cmd_off);
3306  payload_size = sizeof(sli4_req_common_set_profile_config_t);
3307  }
3308 
3311  req->hdr.request_length = payload_size - sizeof(sli4_req_hdr_t);
3312  req->hdr.version = 1;
3313  req->profile_id = profile_id;
3314  req->desc_count = descriptor_count;
3315  req->isap = isap;
3316 
3317  return(cmd_off + sizeof(sli4_req_common_set_profile_config_t));
3318 }
3319 
3320 /**
3321  * @ingroup sli
3322  * @brief Write a COMMON_COMMON_GET_PROFILE_LIST command.
3323  *
3324  * @param sli4 SLI context.
3325  * @param buf Destination buffer for the command.
3326  * @param size Buffer size in bytes.
3327  * @param start_profile_index First profile index to return.
3328  * @param dma Buffer into which the list will be written.
3329  *
3330  * @return Returns the number of bytes written.
3331  */
3332 int32_t
3333 sli_cmd_common_get_profile_list(sli4_t *sli4, void *buf, size_t size,
3334  uint32_t start_profile_index, ocs_dma_t *dma)
3335 {
3337  uint32_t cmd_off = 0;
3338  uint32_t payload_size;
3339 
3340  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
3341  cmd_off = sli_cmd_sli_config(sli4, buf, size,
3343  dma);
3344  }
3345 
3346  if (dma != NULL) {
3347  req = dma->virt;
3348  ocs_memset(req, 0, dma->size);
3349  payload_size = dma->size;
3350  } else {
3351  req = (sli4_req_common_get_profile_list_t *)((uint8_t *)buf + cmd_off);
3352  payload_size = sizeof(sli4_req_common_get_profile_list_t);
3353  }
3354 
3357  req->hdr.request_length = payload_size - sizeof(sli4_req_hdr_t);
3358  req->hdr.version = 0;
3359 
3360  req->start_profile_index = start_profile_index;
3361 
3362  return(cmd_off + sizeof(sli4_req_common_get_profile_list_t));
3363 }
3364 
3365 /**
3366  * @ingroup sli
3367  * @brief Write a COMMON_COMMON_GET_ACTIVE_PROFILE command.
3368  *
3369  * @param sli4 SLI context.
3370  * @param buf Destination buffer for the command.
3371  * @param size Buffer size in bytes.
3372  *
3373  * @return Returns the number of bytes written.
3374  */
3375 int32_t
3376 sli_cmd_common_get_active_profile(sli4_t *sli4, void *buf, size_t size)
3377 {
3379  uint32_t cmd_off = 0;
3380  uint32_t payload_size;
3381 
3382  /* Payload length must accomodate both request and response */
3383  payload_size = max(sizeof(sli4_req_common_get_active_profile_t),
3385 
3386  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
3387  cmd_off = sli_cmd_sli_config(sli4, buf, size,
3388  payload_size,
3389  NULL);
3390  }
3391 
3393  ((uint8_t*)buf + cmd_off);
3394 
3397  req->hdr.request_length = payload_size - sizeof(sli4_req_hdr_t);
3398  req->hdr.version = 0;
3399 
3400  return(cmd_off + sizeof(sli4_req_common_get_active_profile_t));
3401 }
3402 
3403 /**
3404  * @ingroup sli
3405  * @brief Write a COMMON_COMMON_SET_ACTIVE_PROFILE command.
3406  *
3407  * @param sli4 SLI context.
3408  * @param buf Destination buffer for the command.
3409  * @param size Buffer size in bytes.
3410  * @param fd If non-zero, set profile to factory default.
3411  * @param active_profile_id ID of new active profile.
3412  *
3413  * @return Returns the number of bytes written.
3414  */
3415 int32_t
3416 sli_cmd_common_set_active_profile(sli4_t *sli4, void *buf, size_t size,
3417  uint32_t fd, uint32_t active_profile_id)
3418 {
3420  uint32_t cmd_off = 0;
3421  uint32_t payload_size;
3422 
3423  /* Payload length must accomodate both request and response */
3424  payload_size = max(sizeof(sli4_req_common_set_active_profile_t),
3426 
3427  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
3428  cmd_off = sli_cmd_sli_config(sli4, buf, size,
3429  payload_size,
3430  NULL);
3431  }
3432 
3434  ((uint8_t*)buf + cmd_off);
3435 
3438  req->hdr.request_length = payload_size - sizeof(sli4_req_hdr_t);
3439  req->hdr.version = 0;
3440  req->fd = fd;
3441  req->active_profile_id = active_profile_id;
3442 
3443  return(cmd_off + sizeof(sli4_req_common_set_active_profile_t));
3444 }
3445 
3446 /**
3447  * @ingroup sli
3448  * @brief Write a COMMON_GET_RECONFIG_LINK_INFO command.
3449  *
3450  * @param sli4 SLI context.
3451  * @param buf Destination buffer for the command.
3452  * @param size Buffer size in bytes.
3453  * @param dma Buffer to store the supported link configuration modes from the physical device.
3454  *
3455  * @return Returns the number of bytes written.
3456  */
3457 int32_t
3458 sli_cmd_common_get_reconfig_link_info(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma)
3459 {
3461  uint32_t cmd_off = 0;
3462  uint32_t payload_size;
3463 
3464  /* Payload length must accomodate both request and response */
3465  payload_size = max(sizeof(sli4_req_common_get_reconfig_link_info_t),
3467 
3468  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
3469  cmd_off = sli_cmd_sli_config(sli4, buf, size,
3470  payload_size,
3471  dma);
3472  }
3473 
3474  if (dma != NULL) {
3475  req = dma->virt;
3476  ocs_memset(req, 0, dma->size);
3477  payload_size = dma->size;
3478  } else {
3479  req = (sli4_req_common_get_reconfig_link_info_t *)((uint8_t *)buf + cmd_off);
3480  payload_size = sizeof(sli4_req_common_get_reconfig_link_info_t);
3481  }
3482 
3485  req->hdr.request_length = payload_size - sizeof(sli4_req_hdr_t);
3486  req->hdr.version = 0;
3487 
3488  return(cmd_off + sizeof(sli4_req_common_get_reconfig_link_info_t));
3489 }
3490 
3491 /**
3492  * @ingroup sli
3493  * @brief Write a COMMON_SET_RECONFIG_LINK_ID command.
3494  *
3495  * @param sli4 SLI context.
3496  * @param buf destination buffer for the command.
3497  * @param size buffer size in bytes.
3498  * @param fd If non-zero, set link config to factory default.
3499  * @param active_link_config_id ID of new active profile.
3500  * @param dma Buffer to assign the link configuration mode that is to become active from the physical device.
3501  *
3502  * @return Returns the number of bytes written.
3503  */
3504 int32_t
3505 sli_cmd_common_set_reconfig_link_id(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma,
3506  uint32_t fd, uint32_t active_link_config_id)
3507 {
3509  uint32_t cmd_off = 0;
3510  uint32_t payload_size;
3511 
3512  /* Payload length must accomodate both request and response */
3513  payload_size = max(sizeof(sli4_req_common_set_reconfig_link_id_t),
3515 
3516  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
3517  cmd_off = sli_cmd_sli_config(sli4, buf, size,
3518  payload_size,
3519  NULL);
3520  }
3521 
3522  if (dma != NULL) {
3523  req = dma->virt;
3524  ocs_memset(req, 0, dma->size);
3525  payload_size = dma->size;
3526  } else {
3527  req = (sli4_req_common_set_reconfig_link_id_t *)((uint8_t *)buf + cmd_off);
3528  payload_size = sizeof(sli4_req_common_set_reconfig_link_id_t);
3529  }
3530 
3533  req->hdr.request_length = payload_size - sizeof(sli4_req_hdr_t);
3534  req->hdr.version = 0;
3535  req->fd = fd;
3536  req->next_link_config_id = active_link_config_id;
3537 
3538  return(cmd_off + sizeof(sli4_req_common_set_reconfig_link_id_t));
3539 }
3540 
3541 
3542 /**
3543  * @ingroup sli
3544  * @brief Check the mailbox/queue completion entry.
3545  *
3546  * @param buf Pointer to the MCQE.
3547  *
3548  * @return Returns 0 on success, or a non-zero value on failure.
3549  */
3550 int32_t
3551 sli_cqe_mq(void *buf)
3552 {
3553  sli4_mcqe_t *mcqe = buf;
3554 
3555  /*
3556  * Firmware can split mbx completions into two MCQEs: first with only
3557  * the "consumed" bit set and a second with the "complete" bit set.
3558  * Thus, ignore MCQE unless "complete" is set.
3559  */
3560  if (!mcqe->cmp) {
3561  ocs_log_warn(NULL, "Ignoring MCQE, completion bit not set\n");
3562  return -2;
3563  }
3564 
3565  if (mcqe->completion_status) {
3566  ocs_log_err(NULL, "MCQE: bad status (cmpl=%#x ext=%#x con=%d cmp=%d ae=%d val=%d)\n",
3567  mcqe->completion_status, mcqe->extended_status,
3568  mcqe->con, mcqe->cmp, mcqe->ae, mcqe->val);
3569  ocs_log_err(NULL, " %08X %08X %08X %08X\n", ((uint32_t *)buf)[0],
3570  ((uint32_t *)buf)[1], ((uint32_t *)buf)[2], ((uint32_t *)buf)[3]);
3571  }
3572 
3573  return mcqe->completion_status;
3574 }
3575 
3576 /**
3577  * @ingroup sli
3578  * @brief Check the asynchronous event completion entry.
3579  *
3580  * @param sli4 SLI context.
3581  * @param buf Pointer to the ACQE.
3582  *
3583  * @return Returns 0 on success, or a non-zero value on failure.
3584  */
3585 int32_t
3586 sli_cqe_async(sli4_t *sli4, void *buf)
3587 {
3588  sli4_acqe_t *acqe = buf;
3589  int32_t rc = -1;
3590 
3591  if (!sli4 || !buf) {
3592  ocs_log_err(NULL, "bad parameter sli4=%p buf=%p\n", sli4, buf);
3593  return -1;
3594  }
3595 
3596  switch (acqe->event_code) {
3598  rc = sli_fc_process_link_state(sli4, buf);
3599  break;
3601  rc = sli_fc_process_fcoe(sli4, buf);
3602  break;
3604  /*TODO*/ocs_log_debug(sli4->os, "ACQE GRP5\n");
3605  break;
3607  ocs_log_debug(sli4->os,"ACQE SLI Port, type=0x%x, data1,2=0x%08x,0x%08x\n",
3608  acqe->event_type, acqe->event_data[0], acqe->event_data[1]);
3609 #if defined(OCS_INCLUDE_DEBUG)
3610  ocs_dump32(OCS_DEBUG_ALWAYS, sli4->os, "acq", acqe, sizeof(*acqe));
3611 #endif
3612  rc = sli_fc_process_sli_port_event(sli4, buf);
3613  break;
3614 
3616  rc = sli_fc_process_link_attention(sli4, buf);
3617  break;
3618  default:
3619  /*TODO*/ocs_log_test(sli4->os, "ACQE unknown=%#x\n", acqe->event_code);
3620  }
3621 
3622  return rc;
3623 }
3624 
3625 /**
3626  * @brief Check the SLI_CONFIG response.
3627  *
3628  * @par Description
3629  * Function checks the SLI_CONFIG response and the payload status.
3630  *
3631  * @param buf Pointer to SLI_CONFIG response.
3632  *
3633  * @return Returns 0 on success, or a non-zero value on failure.
3634  */
3635 static int32_t
3637 {
3638  sli4_cmd_sli_config_t *sli_config = buf;
3639 
3640  // sanity check
3641  if (!buf || (SLI4_MBOX_COMMAND_SLI_CONFIG != sli_config->hdr.command)) {
3642  ocs_log_err(NULL, "bad parameter buf=%p cmd=%#x\n", buf,
3643  buf ? sli_config->hdr.command : -1);
3644  return -1;
3645  }
3646 
3647  if (sli_config->hdr.status) {
3648  return sli_config->hdr.status;
3649  }
3650 
3651  if (sli_config->emb) {
3652  return sli_config->payload.embed[4];
3653  } else {
3654  ocs_log_test(NULL, "external buffers not supported\n");
3655  return -1;
3656  }
3657 }
3658 
3659 /**
3660  * @brief Issue a COMMON_FUNCTION_RESET command.
3661  *
3662  * @param sli4 SLI context.
3663  *
3664  * @return Returns 0 on success, or a non-zero value on failure.
3665  */
3666 static int32_t
3668 {
3669 
3670  if (sli_cmd_common_function_reset(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE)) {
3671  if (sli_bmbx_command(sli4)) {
3672  ocs_log_crit(sli4->os, "bootstrap mailbox write fail (COM_FUNC_RESET)\n");
3673  return -1;
3674  }
3675  if (sli_res_sli_config(sli4->bmbx.virt)) {
3676  ocs_log_err(sli4->os, "bad status COM_FUNC_RESET\n");
3677  return -1;
3678  }
3679  } else {
3680  ocs_log_err(sli4->os, "bad COM_FUNC_RESET write\n");
3681  return -1;
3682  }
3683 
3684  return 0;
3685 }
3686 
3687 
3688 /**
3689  * @brief check to see if the FW is ready.
3690  *
3691  * @par Description
3692  * Based on <i>SLI-4 Architecture Specification, Revision 4.x0-13 (2012).</i>.
3693  *
3694  * @param sli4 SLI context.
3695  * @param timeout_ms Time, in milliseconds, to wait for the port to be ready
3696  * before failing.
3697  *
3698  * @return Returns TRUE for ready, or FALSE otherwise.
3699  */
3700 static int32_t
3701 sli_wait_for_fw_ready(sli4_t *sli4, uint32_t timeout_ms)
3702 {
3703  uint32_t iter = timeout_ms / (SLI4_INIT_PORT_DELAY_US / 1000);
3704  uint32_t ready = FALSE;
3705 
3706  do {
3707  iter--;
3708  ocs_delay_usec(SLI4_INIT_PORT_DELAY_US); // 10 ms
3709  if (sli_fw_ready(sli4) == 1) {
3710  ready = TRUE;
3711  }
3712  } while (!ready && (iter > 0));
3713 
3714  return ready;
3715 }
3716 
3717 /**
3718  * @brief Initialize the firmware.
3719  *
3720  * @par Description
3721  * Based on <i>SLI-4 Architecture Specification, Revision 4.x0-13 (2012).</i>.
3722  *
3723  * @param sli4 SLI context.
3724  *
3725  * @return Returns 0 on success, or a non-zero value on failure.
3726  */
3727 static int32_t
3729 {
3730  uint32_t ready;
3731  uint32_t endian;
3732 
3733  /*
3734  * Is firmware ready for operation?
3735  */
3737  if (!ready) {
3738  ocs_log_crit(sli4->os, "FW status is NOT ready\n");
3739  return -1;
3740  }
3741 
3742  /*
3743  * Reset port to a known state
3744  */
3745  switch (sli4->if_type) {
3748  /* No SLIPORT_CONTROL register so use command sequence instead */
3749  if (sli_bmbx_wait(sli4, SLI4_BMBX_DELAY_US)) {
3750  ocs_log_crit(sli4->os, "bootstrap mailbox not ready\n");
3751  return -1;
3752  }
3753 
3754  if (sli_cmd_fw_initialize(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE)) {
3755  if (sli_bmbx_command(sli4)) {
3756  ocs_log_crit(sli4->os, "bootstrap mailbox write fail (FW_INIT)\n");
3757  return -1;
3758  }
3759  } else {
3760  ocs_log_crit(sli4->os, "bad FW_INIT write\n");
3761  return -1;
3762  }
3763 
3764  if (sli_common_function_reset(sli4)) {
3765  ocs_log_err(sli4->os, "bad COM_FUNC_RESET write\n");
3766  return -1;
3767  }
3768  break;
3771 #if BYTE_ORDER == LITTLE_ENDIAN
3773 #else
3775 #endif
3776 
3777  if (sli_sliport_control(sli4, endian))
3778  return -1;
3779  break;
3780  default:
3781  ocs_log_test(sli4->os, "if_type %d not supported\n", sli4->if_type);
3782  return -1;
3783  }
3784 
3785  return 0;
3786 }
3787 
3788 /**
3789  * @brief Terminate the firmware.
3790  *
3791  * @param sli4 SLI context.
3792  *
3793  * @return Returns 0 on success, or a non-zero value on failure.
3794  */
3795 static int32_t
3797 {
3798  uint32_t endian;
3799 
3800  if (sli4->if_type == SLI4_IF_TYPE_BE3_SKH_PF ||
3801  sli4->if_type == SLI4_IF_TYPE_BE3_SKH_VF) {
3802  /* No SLIPORT_CONTROL register so use command sequence instead */
3803  if (sli_bmbx_wait(sli4, SLI4_BMBX_DELAY_US)) {
3804  ocs_log_crit(sli4->os, "bootstrap mailbox not ready\n");
3805  return -1;
3806  }
3807 
3808  if (sli_common_function_reset(sli4)) {
3809  ocs_log_err(sli4->os, "bad COM_FUNC_RESET write\n");
3810  return -1;
3811  }
3812 
3813  if (sli_cmd_fw_deinitialize(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE)) {
3814  if (sli_bmbx_command(sli4)) {
3815  ocs_log_crit(sli4->os, "bootstrap mailbox write fail (FW_DEINIT)\n");
3816  return -1;
3817  }
3818  } else {
3819  ocs_log_test(sli4->os, "bad FW_DEINIT write\n");
3820  return -1;
3821  }
3822  } else {
3823 #if BYTE_ORDER == LITTLE_ENDIAN
3825 #else
3827 #endif
3828  // type 2 etc. use SLIPORT_CONTROL to initialize port
3829  sli_sliport_control(sli4, endian);
3830  }
3831  return 0;
3832 }
3833 
3834 /**
3835  * @brief Write the doorbell register associated with the queue object.
3836  *
3837  * @param sli4 SLI context.
3838  * @param q Queue object.
3839  *
3840  * @return Returns 0 on success, or a non-zero value on failure.
3841  */
3842 static int32_t
3844 {
3845  uint32_t val = 0;
3846 
3847  switch (q->type) {
3848  case SLI_QTYPE_EQ:
3849  if (sli4->if_type == SLI4_IF_TYPE_LANCER_G7)
3850  val = sli_iftype6_eq_doorbell(q->n_posted, q->id, FALSE);
3851  else
3852  val = sli_eq_doorbell(q->n_posted, q->id, FALSE);
3853  ocs_reg_write32(sli4->os, q->doorbell_rset, q->doorbell_offset, val);
3854  break;
3855  case SLI_QTYPE_CQ:
3856  if (sli4->if_type == SLI4_IF_TYPE_LANCER_G7)
3857  val = sli_iftype6_cq_doorbell(q->n_posted, q->id, FALSE);
3858  else
3859  val = sli_cq_doorbell(q->n_posted, q->id, FALSE);
3860  ocs_reg_write32(sli4->os, q->doorbell_rset, q->doorbell_offset, val);
3861  break;
3862  case SLI_QTYPE_MQ:
3863  val = SLI4_MQ_DOORBELL(q->n_posted, q->id);
3864  ocs_reg_write32(sli4->os, q->doorbell_rset, q->doorbell_offset, val);
3865  break;
3866  case SLI_QTYPE_RQ:
3867  {
3868  uint32_t n_posted = q->n_posted;
3869  /*
3870  * FC/FCoE has different rules for Receive Queues. The host
3871  * should only update the doorbell of the RQ-pair containing
3872  * the headers since the header / payload RQs are treated
3873  * as a matched unit.
3874  */
3875  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
3876  /*
3877  * In RQ-pair, an RQ either contains the FC header
3878  * (i.e. is_hdr == TRUE) or the payload.
3879  *
3880  * Don't ring doorbell for payload RQ
3881  */
3882  if (!q->u.flag.is_hdr) {
3883  break;
3884  }
3885  /*
3886  * Some RQ cannot be incremented one entry at a time. Instead,
3887  * the driver collects a number of entries and updates the
3888  * RQ in batches.
3889  */
3890  if (q->u.flag.rq_batch) {
3891  if (((q->index + q->n_posted) % SLI4_QUEUE_RQ_BATCH)) {
3892  break;
3893  }
3894  n_posted = SLI4_QUEUE_RQ_BATCH;
3895  }
3896  }
3897 
3898  val = SLI4_RQ_DOORBELL(n_posted, q->id);
3899  ocs_reg_write32(sli4->os, q->doorbell_rset, q->doorbell_offset, val);
3900  break;
3901  }
3902  case SLI_QTYPE_WQ:
3903  if (sli4->if_type == SLI4_IF_TYPE_LANCER_G7) {
3904  if (q->u.dpp.enabled) {
3905  /* Ring the doorbell with dpp bit set + dpp id + q id*/
3906  val = SLI4_DPP_WQ_DOORBELL(q->n_posted, q->u.dpp.id, q->id);
3907  } else {
3908  /* non-dpp write for iftype = 6 */
3909  val = SLI4_WQ_DOORBELL(q->n_posted, 0, q->id); ;
3910  }
3911  } else {
3912  /* For iftype = 2 and 3, q->index value is ignored */
3913  val = SLI4_WQ_DOORBELL(q->n_posted, q->index, q->id);
3914  }
3915  ocs_reg_write32(sli4->os, q->doorbell_rset, q->doorbell_offset, val);
3916  break;
3917  default:
3918  ocs_log_test(sli4->os, "bad queue type %d\n", q->type);
3919  return -1;
3920  }
3921 
3922  return 0;
3923 }
3924 
3925 static int32_t
3926 sli_request_features(sli4_t *sli4, sli4_features_t *features, uint8_t query)
3927 {
3928 
3929  if (sli_cmd_request_features(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE,
3930  *features, query)) {
3931  sli4_cmd_request_features_t *req_features = sli4->bmbx.virt;
3932 
3933  if (sli_bmbx_command(sli4)) {
3934  ocs_log_crit(sli4->os, "bootstrap mailbox write fail (REQUEST_FEATURES)\n");
3935  return -1;
3936  }
3937  if (req_features->hdr.status) {
3938  ocs_log_err(sli4->os, "REQUEST_FEATURES bad status %#x\n",
3939  req_features->hdr.status);
3940  return -1;
3941  }
3942  features->dword = req_features->response.dword;
3943  } else {
3944  ocs_log_err(sli4->os, "bad REQUEST_FEATURES write\n");
3945  return -1;
3946  }
3947 
3948  return 0;
3949 }
3950 
3951 /**
3952  * @brief Calculate max queue entries.
3953  *
3954  * @param sli4 SLI context.
3955  *
3956  * @return Returns 0 on success, or a non-zero value on failure.
3957  */
3958 void
3960 {
3961  sli4_qtype_e q;
3962  uint32_t alloc_size, qentries, qentry_size;
3963 
3964  for (q = SLI_QTYPE_EQ; q < SLI_QTYPE_MAX; q++) {
3966  sli4->config.count_mask[q]);
3967  }
3968 
3969  /* single, continguous DMA allocations will be called for each queue
3970  * of size (max_qentries * queue entry size); since these can be large,
3971  * check against the OS max DMA allocation size
3972  */
3973  for (q = SLI_QTYPE_EQ; q < SLI_QTYPE_MAX; q++) {
3974  qentries = sli4->config.max_qentries[q];
3975  qentry_size = sli_get_queue_entry_size(sli4, q);
3976  alloc_size = qentries * qentry_size;
3977  if (alloc_size > ocs_max_dma_alloc(sli4->os, SLI_PAGE_SIZE)) {
3978  while (alloc_size > ocs_max_dma_alloc(sli4->os, SLI_PAGE_SIZE)) {
3979  /* cut the qentries in half until alloc_size <= max DMA alloc size */
3980  qentries >>= 1;
3981  alloc_size = qentries * qentry_size;
3982  }
3983  ocs_log_debug(sli4->os, "[%s]: max_qentries from %d to %d (max dma %d)\n",
3984  SLI_QNAME[q], sli4->config.max_qentries[q],
3985  qentries, ocs_max_dma_alloc(sli4->os, SLI_PAGE_SIZE));
3986  sli4->config.max_qentries[q] = qentries;
3987  }
3988  }
3989 }
3990 
3991 /**
3992  * @brief Issue a FW_CONFIG mailbox command and store the results.
3993  *
3994  * @param sli4 SLI context.
3995  *
3996  * @return Returns 0 on success, or a non-zero value on failure.
3997  */
3998 static int32_t
4000 {
4001  /*
4002  * Read the device configuration
4003  *
4004  * Note: Only ulp0 fields contain values
4005  */
4006  if (sli_cmd_common_query_fw_config(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE)) {
4009  (((uint8_t *)sli4->bmbx.virt) + offsetof(sli4_cmd_sli_config_t, payload.embed));
4010 
4011  if (sli_bmbx_command(sli4)) {
4012  ocs_log_crit(sli4->os, "bootstrap mailbox write fail (QUERY_FW_CONFIG)\n");
4013  return -1;
4014  }
4015  if (fw_config->hdr.status) {
4016  ocs_log_err(sli4->os, "COMMON_QUERY_FW_CONFIG bad status %#x\n",
4017  fw_config->hdr.status);
4018  return -1;
4019  }
4020 
4021  sli4->physical_port = fw_config->physical_port;
4022  sli4->config.dual_ulp_capable = ((fw_config->function_mode & SLI4_FUNCTION_MODE_DUA_MODE) == 0 ? 0 : 1);
4023  sli4->config.is_ulp_fc[0] = ((fw_config->ulp0_mode &
4025  SLI4_ULP_MODE_FCOE_TGT)) == 0 ? 0 : 1);
4026  sli4->config.is_ulp_fc[1] = ((fw_config->ulp1_mode &
4028  SLI4_ULP_MODE_FCOE_TGT)) == 0 ? 0 : 1);
4029 
4030  if (sli4->config.dual_ulp_capable) {
4031  /*
4032  * Lancer will not support this, so we use the values
4033  * from the READ_CONFIG.
4034  */
4035  if (sli4->config.is_ulp_fc[0] &&
4036  sli4->config.is_ulp_fc[1]) {
4037  sli4->config.max_qcount[SLI_QTYPE_WQ] = fw_config->ulp0_toe_wq_total + fw_config->ulp1_toe_wq_total;
4038  sli4->config.max_qcount[SLI_QTYPE_RQ] = fw_config->ulp0_toe_defrq_total + fw_config->ulp1_toe_defrq_total;
4039  } else if (sli4->config.is_ulp_fc[0]) {
4040  sli4->config.max_qcount[SLI_QTYPE_WQ] = fw_config->ulp0_toe_wq_total;
4041  sli4->config.max_qcount[SLI_QTYPE_RQ] = fw_config->ulp0_toe_defrq_total;
4042  } else {
4043  sli4->config.max_qcount[SLI_QTYPE_WQ] = fw_config->ulp1_toe_wq_total;
4044  sli4->config.max_qcount[SLI_QTYPE_RQ] = fw_config->ulp1_toe_defrq_total;
4045  }
4046  }
4047  } else {
4048  ocs_log_err(sli4->os, "bad QUERY_FW_CONFIG write\n");
4049  return -1;
4050  }
4051  return 0;
4052 }
4053 
4054 
4055 static int32_t
4057 {
4058  ocs_dma_t get_cntl_addl_data;
4059 
4060  /*
4061  * Read the device configuration
4062  */
4063  if (sli_cmd_read_config(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE)) {
4064  sli4_res_read_config_t *read_config = sli4->bmbx.virt;
4065  uint32_t i;
4066  uint32_t total;
4067 
4068  if (sli_bmbx_command(sli4)) {
4069  ocs_log_crit(sli4->os, "bootstrap mailbox write fail (READ_CONFIG)\n");
4070  return -1;
4071  }
4072  if (read_config->hdr.status) {
4073  ocs_log_err(sli4->os, "READ_CONFIG bad status %#x\n",
4074  read_config->hdr.status);
4075  return -1;
4076  }
4077 
4078  sli4->config.has_extents = read_config->ext;
4079  if (FALSE == sli4->config.has_extents) {
4080  uint32_t i = 0;
4081  uint32_t *base = sli4->config.extent[0].base;
4082 
4083  if (!base) {
4084  if (NULL == (base = ocs_malloc(sli4->os, SLI_RSRC_MAX * sizeof(uint32_t),
4085  OCS_M_ZERO | OCS_M_NOWAIT))) {
4086  ocs_log_err(sli4->os, "memory allocation failed for sli4_resource_t\n");
4087  return -1;
4088  }
4089  }
4090 
4091  for (i = 0; i < SLI_RSRC_MAX; i++) {
4092  sli4->config.extent[i].number = 1;
4093  sli4->config.extent[i].n_alloc = 0;
4094  sli4->config.extent[i].base = &base[i];
4095  }
4096 
4097  sli4->config.extent[SLI_RSRC_FCOE_VFI].base[0] = read_config->vfi_base;
4098  sli4->config.extent[SLI_RSRC_FCOE_VFI].size = read_config->vfi_count;
4099 
4100  sli4->config.extent[SLI_RSRC_FCOE_VPI].base[0] = read_config->vpi_base;
4101  sli4->config.extent[SLI_RSRC_FCOE_VPI].size = read_config->vpi_count;
4102 
4103  sli4->config.extent[SLI_RSRC_FCOE_RPI].base[0] = read_config->rpi_base;
4104  sli4->config.extent[SLI_RSRC_FCOE_RPI].size = read_config->rpi_count;
4105 
4106 #if defined(OCS_USPACE_SPDK)
4107  sli4->config.extent[SLI_RSRC_FCOE_XRI].base[0] = read_config->xri_base;
4108  sli4->config.extent[SLI_RSRC_FCOE_XRI].size = read_config->xri_count / 2;
4109  ocs_log_info(sli4->os, "SLI4 Xri base = %d cnt = %d\n",
4110  read_config->xri_base, read_config->xri_count);
4111 #else
4112  sli4->config.extent[SLI_RSRC_FCOE_XRI].base[0] = read_config->xri_base;
4113  sli4->config.extent[SLI_RSRC_FCOE_XRI].size = read_config->xri_count;
4114 #endif
4115 
4116  sli4->config.extent[SLI_RSRC_FCOE_FCFI].base[0] = 0;
4117  sli4->config.extent[SLI_RSRC_FCOE_FCFI].size = read_config->fcfi_count;
4118  } else {
4119  // TODO extents
4120  ;
4121  }
4122 
4123  for (i = 0; i < SLI_RSRC_MAX; i++) {
4124  total = sli4->config.extent[i].number * sli4->config.extent[i].size;
4125  sli4->config.extent[i].use_map = ocs_bitmap_alloc(total);
4126  if (NULL == sli4->config.extent[i].use_map) {
4127  ocs_log_err(sli4->os, "bitmap memory allocation failed "
4128  "resource %d\n", i);
4129  return -1;
4130  }
4131  sli4->config.extent[i].map_size = total;
4132  ocs_lock_init(sli4->os, &sli4->config.extent[i].lock,
4133  "rsrc_lock-%d", i);
4134  }
4135 
4136  sli4->config.topology = read_config->topology;
4137  switch (sli4->config.topology) {
4139  ocs_log_debug(sli4->os, "FCoE\n");
4140  break;
4141  case SLI4_READ_CFG_TOPO_FC:
4142  ocs_log_debug(sli4->os, "FC (unknown)\n");
4143  break;
4145  ocs_log_debug(sli4->os, "FC (direct attach)\n");
4146  break;
4148  ocs_log_debug(sli4->os, "FC (arbitrated loop)\n");
4149  break;
4150  default:
4151  ocs_log_test(sli4->os, "bad topology %#x\n", sli4->config.topology);
4152  }
4153 
4154  sli4->config.e_d_tov = read_config->e_d_tov;
4155  sli4->config.r_a_tov = read_config->r_a_tov;
4156 
4157  if (read_config->bbscn_def) {
4158  sli4->config.enable_bbcr = TRUE;
4159  sli4->config.bbscn_max = read_config->bbscn_max;
4160  sli4->config.bbscn_def = read_config->bbscn_def;
4161  }
4162 
4163  ocs_log_debug(sli4->os, "bbscn_max: %d, bbscn_def: %d\n",
4164  read_config->bbscn_max, read_config->bbscn_def);
4165 
4166  sli4->config.link_module_type = read_config->lmt;
4167 
4168  sli4->config.max_qcount[SLI_QTYPE_EQ] = read_config->eq_count;
4169  sli4->config.max_qcount[SLI_QTYPE_CQ] = read_config->cq_count;
4170  sli4->config.max_qcount[SLI_QTYPE_WQ] = read_config->wq_count;
4171  sli4->config.max_qcount[SLI_QTYPE_RQ] = read_config->rq_count;
4172 
4173  /*
4174  * READ_CONFIG doesn't give the max number of MQ. Applications
4175  * will typically want 1, but we may need another at some future
4176  * date. Dummy up a "max" MQ count here.
4177  */
4179  } else {
4180  ocs_log_err(sli4->os, "bad READ_CONFIG write\n");
4181  return -1;
4182  }
4183 
4184  if (sli_cmd_common_get_sli4_parameters(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE)) {
4186  (((uint8_t *)sli4->bmbx.virt) + offsetof(sli4_cmd_sli_config_t, payload.embed));
4187 
4188  if (sli_bmbx_command(sli4)) {
4189  ocs_log_crit(sli4->os, "bootstrap mailbox write fail (COMMON_GET_SLI4_PARAMETERS)\n");
4190  return -1;
4191  } else if (parms->hdr.status) {
4192  ocs_log_err(sli4->os, "COMMON_GET_SLI4_PARAMETERS bad status %#x att'l %#x\n",
4193  parms->hdr.status, parms->hdr.additional_status);
4194  return -1;
4195  }
4196 
4197  sli4->config.auto_reg = parms->areg;
4198  sli4->config.auto_xfer_rdy = parms->agxf;
4199  sli4->config.tow = parms->tow;
4200  sli4->config.max_tow_xris = parms->dw20w0;
4201 
4202  sli4->config.hdr_template_req = parms->hdrr;
4203  sli4->config.t10_dif_inline_capable = parms->timm;
4204  sli4->config.t10_dif_separate_capable = parms->tsmm;
4205  sli4->config.fdd_present = parms->fdb;
4206 
4207  sli4->config.xib_capable = parms->xib;
4208  sli4->config.suppress_rsp_not_supported = parms->sriuns;
4209 
4210  sli4->config.mq_create_version = parms->mqv;
4211  sli4->config.cq_create_version = parms->cqv;
4212  sli4->config.rq_min_buf_size = parms->min_rq_buffer_size;
4213  sli4->config.rq_max_buf_size = parms->max_rq_buffer_size;
4214 
4215  sli4->config.qpage_count[SLI_QTYPE_EQ] = parms->eq_page_cnt;
4216  sli4->config.qpage_count[SLI_QTYPE_CQ] = parms->cq_page_cnt;
4217  sli4->config.qpage_count[SLI_QTYPE_MQ] = parms->mq_page_cnt;
4218  sli4->config.qpage_count[SLI_QTYPE_WQ] = parms->wq_page_cnt;
4219  sli4->config.qpage_count[SLI_QTYPE_RQ] = parms->rq_page_cnt;
4220 
4221  /* save count methods and masks for each queue type */
4222  sli4->config.count_mask[SLI_QTYPE_EQ] = parms->eqe_count_mask;
4224  sli4->config.count_mask[SLI_QTYPE_CQ] = parms->cqe_count_mask;
4226  sli4->config.count_mask[SLI_QTYPE_MQ] = parms->mqe_count_mask;
4228  sli4->config.count_mask[SLI_QTYPE_WQ] = parms->wqe_count_mask;
4230  sli4->config.count_mask[SLI_QTYPE_RQ] = parms->rqe_count_mask;
4232 
4233  /* now calculate max queue entries */
4234  sli_calc_max_qentries(sli4);
4235 
4236  sli4->config.max_sgl_pages = parms->sgl_page_cnt; // max # of pages
4237  sli4->config.sgl_page_sizes = parms->sgl_page_sizes; // bit map of available sizes
4238  // ignore HLM here. Use value from REQUEST_FEATURES
4240  sli4->config.sgl_pre_registration_required = parms->sglr;
4241  // default to using pre-registered SGL's
4242  sli4->config.sgl_pre_registered = TRUE;
4243 
4244  sli4->config.perf_hint = parms->phon;
4245  sli4->config.perf_wq_id_association = parms->phwq;
4246 
4247  sli4->config.rq_batch = parms->rq_db_window;
4248 
4249  /* save the fields for skyhawk SGL chaining */
4251  (parms->sglc == 1);
4254  (1ull << parms->dw20w1) - 1;
4256  parms->sgl_index_field_offset;
4258  (1ull << parms->sgl_index_field_size) - 1;
4263 
4264  /* Use the highest available WQE size. */
4265  if (parms->wqe_sizes & SLI4_128BYTE_WQE_SUPPORT) {
4267  } else {
4268  sli4->config.wqe_size = SLI4_WQE_BYTES;
4269  }
4270  }
4271 
4272  if (sli_query_fw_config(sli4)) {
4273  ocs_log_err(sli4->os, "Error sending QUERY_FW_CONFIG\n");
4274  return -1;
4275  }
4276 
4277  sli4->config.port_number = 0;
4278 
4279  /*
4280  * Issue COMMON_GET_CNTL_ATTRIBUTES to get port_number. Temporarily
4281  * uses VPD DMA buffer as the response won't fit in the embedded
4282  * buffer.
4283  */
4284  if (sli_cmd_common_get_cntl_attributes(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE, &sli4->vpd.data)) {
4285  sli4_res_common_get_cntl_attributes_t *attr = sli4->vpd.data.virt;
4286 
4287  if (sli_bmbx_command(sli4)) {
4288  ocs_log_crit(sli4->os, "bootstrap mailbox write fail (COMMON_GET_CNTL_ATTRIBUTES)\n");
4289  return -1;
4290  } else if (attr->hdr.status) {
4291  ocs_log_err(sli4->os, "COMMON_GET_CNTL_ATTRIBUTES bad status %#x att'l %#x\n",
4292  attr->hdr.status, attr->hdr.additional_status);
4293  return -1;
4294  }
4295 
4296  sli4->config.port_number = attr->port_number;
4297 
4298  ocs_memcpy(sli4->config.modeldesc, attr->description, sizeof(sli4->config.modeldesc));
4299  ocs_memcpy(sli4->config.bios_version_string, attr->bios_version_string,
4300  sizeof(sli4->config.bios_version_string));
4301  } else {
4302  ocs_log_err(sli4->os, "bad COMMON_GET_CNTL_ATTRIBUTES write\n");
4303  return -1;
4304  }
4305 
4306  if (ocs_dma_alloc(sli4->os, &get_cntl_addl_data, sizeof(sli4_res_common_get_cntl_addl_attributes_t),
4307  OCS_MIN_DMA_ALIGNMENT)) {
4308  ocs_log_err(sli4->os, "Failed to allocate memory for GET_CNTL_ADDL_ATTR data\n");
4309  } else {
4311  &get_cntl_addl_data)) {
4312  sli4_res_common_get_cntl_addl_attributes_t *attr = get_cntl_addl_data.virt;
4313 
4314  if (sli_bmbx_command(sli4)) {
4315  ocs_log_crit(sli4->os,
4316  "bootstrap mailbox write fail (COMMON_GET_CNTL_ADDL_ATTRIBUTES)\n");
4317  ocs_dma_free(sli4->os, &get_cntl_addl_data);
4318  return -1;
4319  }
4320  if (attr->hdr.status) {
4321  ocs_log_err(sli4->os, "COMMON_GET_CNTL_ADDL_ATTRIBUTES bad status %#x\n",
4322  attr->hdr.status);
4323  ocs_dma_free(sli4->os, &get_cntl_addl_data);
4324  return -1;
4325  }
4326 
4327  ocs_memcpy(sli4->config.ipl_name, attr->ipl_file_name, sizeof(sli4->config.ipl_name));
4328 
4329  ocs_log_debug(sli4->os, "IPL:%s \n", (char*)sli4->config.ipl_name);
4330  } else {
4331  ocs_log_err(sli4->os, "bad COMMON_GET_CNTL_ADDL_ATTRIBUTES write\n");
4332  ocs_dma_free(sli4->os, &get_cntl_addl_data);
4333  return -1;
4334  }
4335 
4336  ocs_dma_free(sli4->os, &get_cntl_addl_data);
4337  }
4338 
4339  if (sli_cmd_common_get_port_name(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE)) {
4340  sli4_res_common_get_port_name_t *port_name = (sli4_res_common_get_port_name_t *)(((uint8_t *)sli4->bmbx.virt) +
4341  offsetof(sli4_cmd_sli_config_t, payload.embed));
4342 
4343  if (sli_bmbx_command(sli4)) {
4344  ocs_log_crit(sli4->os, "bootstrap mailbox write fail (COMMON_GET_PORT_NAME)\n");
4345  return -1;
4346  }
4347 
4348  sli4->config.port_name[0] = port_name->port_name[sli4->config.port_number];
4349  }
4350  sli4->config.port_name[1] = '\0';
4351 
4352  if (sli_cmd_read_rev(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE, &sli4->vpd.data)) {
4353  sli4_cmd_read_rev_t *read_rev = sli4->bmbx.virt;
4354 
4355  if (sli_bmbx_command(sli4)) {
4356  ocs_log_crit(sli4->os, "bootstrap mailbox write fail (READ_REV)\n");
4357  return -1;
4358  }
4359  if (read_rev->hdr.status) {
4360  ocs_log_err(sli4->os, "READ_REV bad status %#x\n",
4361  read_rev->hdr.status);
4362  return -1;
4363  }
4364 
4365  sli4->config.fw_rev[0] = read_rev->first_fw_id;
4366  ocs_memcpy(sli4->config.fw_name[0],read_rev->first_fw_name, sizeof(sli4->config.fw_name[0]));
4367 
4368  sli4->config.fw_rev[1] = read_rev->second_fw_id;
4369  ocs_memcpy(sli4->config.fw_name[1],read_rev->second_fw_name, sizeof(sli4->config.fw_name[1]));
4370 
4371  sli4->config.hw_rev[0] = read_rev->first_hw_revision;
4372  sli4->config.hw_rev[1] = read_rev->second_hw_revision;
4373  sli4->config.hw_rev[2] = read_rev->third_hw_revision;
4374 
4375  ocs_log_info(sli4->os, "FW1:%s (%08x) / FW2:%s (%08x)\n",
4376  read_rev->first_fw_name, read_rev->first_fw_id,
4377  read_rev->second_fw_name, read_rev->second_fw_id);
4378 
4379  ocs_log_info(sli4->os, "HW1: %08x / HW2: %08x\n", read_rev->first_hw_revision,
4380  read_rev->second_hw_revision);
4381 
4382  /* Check that all VPD data was returned */
4383  if (read_rev->returned_vpd_length != read_rev->actual_vpd_length) {
4384  ocs_log_test(sli4->os, "VPD length: available=%d returned=%d actual=%d\n",
4385  read_rev->available_length,
4386  read_rev->returned_vpd_length,
4387  read_rev->actual_vpd_length);
4388  }
4389  sli4->vpd.length = read_rev->returned_vpd_length;
4390  } else {
4391  ocs_log_err(sli4->os, "bad READ_REV write\n");
4392  return -1;
4393  }
4394 
4395  if (sli_cmd_read_nvparms(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE)) {
4396  sli4_cmd_read_nvparms_t *read_nvparms = sli4->bmbx.virt;
4397 
4398  if (sli_bmbx_command(sli4)) {
4399  ocs_log_crit(sli4->os, "bootstrap mailbox write fail (READ_NVPARMS)\n");
4400  return -1;
4401  }
4402  if (read_nvparms->hdr.status) {
4403  ocs_log_err(sli4->os, "READ_NVPARMS bad status %#x\n",
4404  read_nvparms->hdr.status);
4405  return -1;
4406  }
4407 
4408  ocs_memcpy(sli4->config.wwpn, read_nvparms->wwpn, sizeof(sli4->config.wwpn));
4409  ocs_memcpy(sli4->config.wwnn, read_nvparms->wwnn, sizeof(sli4->config.wwnn));
4410 
4411  ocs_log_debug(sli4->os, "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
4412  sli4->config.wwpn[0],
4413  sli4->config.wwpn[1],
4414  sli4->config.wwpn[2],
4415  sli4->config.wwpn[3],
4416  sli4->config.wwpn[4],
4417  sli4->config.wwpn[5],
4418  sli4->config.wwpn[6],
4419  sli4->config.wwpn[7]);
4420  ocs_log_debug(sli4->os, "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
4421  sli4->config.wwnn[0],
4422  sli4->config.wwnn[1],
4423  sli4->config.wwnn[2],
4424  sli4->config.wwnn[3],
4425  sli4->config.wwnn[4],
4426  sli4->config.wwnn[5],
4427  sli4->config.wwnn[6],
4428  sli4->config.wwnn[7]);
4429  } else {
4430  ocs_log_err(sli4->os, "bad READ_NVPARMS write\n");
4431  return -1;
4432  }
4433 
4434  return 0;
4435 }
4436 
4437 /****************************************************************************
4438  * Public functions
4439  */
4440 
4441 /**
4442  * @ingroup sli
4443  * @brief Set up the SLI context.
4444  *
4445  * @param sli4 SLI context.
4446  * @param os Device abstraction.
4447  * @param port_type Protocol type of port (for example, FC and NIC).
4448  *
4449  * @return Returns 0 on success, or a non-zero value on failure.
4450  */
4451 int32_t
4452 sli_setup(sli4_t *sli4, ocs_os_handle_t os, sli4_port_type_e port_type)
4453 {
4454  uint32_t sli_intf = UINT32_MAX;
4455  uint32_t pci_class_rev = 0;
4456  uint32_t rev_id = 0;
4457  uint32_t family = 0;
4458  uint32_t i;
4459  sli4_asic_entry_t *asic;
4460 
4461  ocs_memset(sli4, 0, sizeof(sli4_t));
4462 
4463  sli4->os = os;
4464  sli4->port_type = port_type;
4465 
4466  /*
4467  * Read the SLI_INTF register to discover the register layout
4468  * and other capability information
4469  */
4470  sli_intf = ocs_config_read32(os, SLI4_INTF_REG);
4471 
4472  if (sli_intf_valid_check(sli_intf)) {
4473  ocs_log_err(os, "SLI_INTF is not valid\n");
4474  return -1;
4475  }
4476 
4477  /* driver only support SLI-4 */
4478  sli4->sli_rev = sli_intf_sli_revision(sli_intf);
4479  if (4 != sli4->sli_rev) {
4480  ocs_log_err(os, "Unsupported SLI revision (intf=%#x)\n",
4481  sli_intf);
4482  return -1;
4483  }
4484 
4485  sli4->sli_family = sli_intf_sli_family(sli_intf);
4486 
4487  sli4->if_type = sli_intf_if_type(sli_intf);
4488 
4489  /*
4490  * set the ASIC type and revision
4491  */
4492  pci_class_rev = ocs_config_read32(os, SLI4_PCI_CLASS_REVISION);
4493  rev_id = sli_pci_rev_id(pci_class_rev);
4494  family = sli4->sli_family;
4495  if (family == SLI4_FAMILY_CHECK_ASIC_TYPE) {
4496  uint32_t asic_id = ocs_config_read32(os, SLI4_ASIC_ID_REG);
4497  family = sli_asic_gen(asic_id);
4498  }
4499 
4500  for (i = 0, asic = sli4_asic_table; i < ARRAY_SIZE(sli4_asic_table); i++, asic++) {
4501  if ((rev_id == asic->rev_id) && (family == asic->family)) {
4502  sli4->asic_type = asic->type;
4503  sli4->asic_rev = asic->rev;
4504  break;
4505  }
4506  }
4507  /* Fail if no matching asic type/rev was found */
4508  if( (sli4->asic_type == 0) || (sli4->asic_rev == 0)) {
4509  ocs_log_err(os, "no matching asic family/rev found: %02x/%02x\n", family, rev_id);
4510  return -1;
4511  }
4512 
4513  /*
4514  * The bootstrap mailbox is equivalent to a MQ with a single 256 byte
4515  * entry, a CQ with a single 16 byte entry, and no event queue.
4516  * Alignment must be 16 bytes as the low order address bits in the
4517  * address register are also control / status.
4518  */
4519  if (ocs_dma_alloc(sli4->os, &sli4->bmbx, SLI4_BMBX_SIZE +
4520  sizeof(sli4_mcqe_t), 16)) {
4521  ocs_log_err(os, "bootstrap mailbox allocation failed\n");
4522  return -1;
4523  }
4524 
4525  if (sli4->bmbx.phys & SLI4_BMBX_MASK_LO) {
4526  ocs_log_err(os, "bad alignment for bootstrap mailbox\n");
4527  return -1;
4528  }
4529 
4530  ocs_log_debug(os, "bmbx v=%p p=0x%x %08x s=%zd\n", sli4->bmbx.virt,
4531  ocs_addr32_hi(sli4->bmbx.phys),
4532  ocs_addr32_lo(sli4->bmbx.phys),
4533  sli4->bmbx.size);
4534 
4535  // TODO 4096 is arbitrary. What should this value actually be?
4536  if (ocs_dma_alloc(sli4->os, &sli4->vpd.data, 4096/*TODO*/, 4096)) {
4537  /* Note that failure isn't fatal in this specific case */
4538  sli4->vpd.data.size = 0;
4539  ocs_log_test(os, "VPD buffer allocation failed\n");
4540  }
4541 
4542  if (sli_fw_init(sli4)) {
4543  ocs_log_err(sli4->os, "FW initialization failed\n");
4544  return -1;
4545  }
4546 
4547  if ( (SLI4_IF_TYPE_LANCER_FC_ETH == sli4->if_type) ||
4548  (SLI4_IF_TYPE_LANCER_G7 == sli4->if_type)) {
4549  ocs_log_debug(os, "status=%#x error1=%#x error2=%#x\n",
4553  }
4554 
4555 
4556  /*
4557  * Set one of fcpi(initiator), fcpt(target), fcpc(combined) to true
4558  * in addition to any other desired features
4559  */
4560  sli4->config.features.flag.iaab = TRUE;
4561  sli4->config.features.flag.npiv = TRUE;
4562  sli4->config.features.flag.dif = TRUE;
4563  sli4->config.features.flag.vf = TRUE;
4564  sli4->config.features.flag.fcpc = TRUE;
4565  sli4->config.features.flag.iaar = TRUE;
4566  sli4->config.features.flag.hlm = TRUE;
4567  sli4->config.features.flag.perfh = TRUE;
4568  sli4->config.features.flag.rxseq = TRUE;
4569  sli4->config.features.flag.rxri = TRUE;
4570  sli4->config.features.flag.mrqp = TRUE;
4571  sli4->config.features.flag.ashdr = TRUE;
4572 
4573  // use performance hints if available
4574  if (sli4->config.perf_hint) {
4575  sli4->config.features.flag.perfh = TRUE;
4576  }
4577 
4578  if (sli_request_features(sli4, &sli4->config.features, TRUE)) {
4579  return -1;
4580  }
4581 
4582  if (sli_get_config(sli4)) {
4583  return -1;
4584  }
4585 
4586  return 0;
4587 }
4588 
4589 int32_t
4591 {
4592 
4593  if (sli4->config.has_extents) {
4594  /* TODO COMMON_ALLOC_RESOURCE_EXTENTS */;
4595  ocs_log_test(sli4->os, "XXX need to implement extent allocation\n");
4596  return -1;
4597  }
4598 
4599  sli4->config.features.flag.hlm = sli4->config.high_login_mode;
4600  sli4->config.features.flag.rxseq = FALSE;
4601  sli4->config.features.flag.rxri = FALSE;
4602 
4603  if (sli_request_features(sli4, &sli4->config.features, FALSE)) {
4604  return -1;
4605  }
4606 
4607  return 0;
4608 }
4609 
4610 int32_t
4612 {
4613  uint32_t i;
4614 
4615  if (sli_fw_init(sli4)) {
4616  ocs_log_crit(sli4->os, "FW initialization failed\n");
4617  return -1;
4618  }
4619 
4620  if (sli4->config.extent[0].base) {
4621  ocs_free(sli4->os, sli4->config.extent[0].base, SLI_RSRC_MAX * sizeof(uint32_t));
4622  sli4->config.extent[0].base = NULL;
4623  }
4624 
4625  for (i = 0; i < SLI_RSRC_MAX; i++) {
4626  if (sli4->config.extent[i].use_map) {
4627  ocs_bitmap_free(sli4->config.extent[i].use_map);
4628  sli4->config.extent[i].use_map = NULL;
4629  }
4630  sli4->config.extent[i].base = NULL;
4631  ocs_lock_free(&sli4->config.extent[i].lock);
4632  }
4633 
4634  if (sli_get_config(sli4)) {
4635  return -1;
4636  }
4637 
4638  return 0;
4639 }
4640 
4641 /**
4642  * @ingroup sli
4643  * @brief Issue a Firmware Reset.
4644  *
4645  * @par Description
4646  * Issues a Firmware Reset to the chip. This reset affects the entire chip,
4647  * so all PCI function on the same PCI bus and device are affected.
4648  * @n @n This type of reset can be used to activate newly downloaded firmware.
4649  * @n @n The driver should be considered to be in an unknown state after this
4650  * reset and should be reloaded.
4651  *
4652  * @param sli4 SLI context.
4653  *
4654  * @return Returns 0 on success, or -1 otherwise.
4655  */
4656 
4657 int32_t
4659 {
4660  uint32_t val;
4661  uint32_t ready;
4662 
4663  /*
4664  * Firmware must be ready before issuing the reset.
4665  */
4667  if (!ready) {
4668  ocs_log_crit(sli4->os, "FW status is NOT ready\n");
4669  return -1;
4670  }
4671  switch(sli4->if_type) {
4673  /* BE3 / Skyhawk use PCICFG_SOFT_RESET_CSR */
4674  val = ocs_config_read32(sli4->os, SLI4_PCI_SOFT_RESET_CSR);
4675  val |= SLI4_PCI_SOFT_RESET_MASK;
4676  ocs_config_write32(sli4->os, SLI4_PCI_SOFT_RESET_CSR, val);
4677  break;
4680  /* Lancer uses PHYDEV_CONTROL */
4681 
4684  break;
4685  default:
4686  ocs_log_test(sli4->os, "Unexpected iftype %d\n", sli4->if_type);
4687  return -1;
4688  break;
4689  }
4690 
4691  /* wait for the FW to become ready after the reset */
4693  if (!ready) {
4694  ocs_log_crit(sli4->os, "Failed to become ready after firmware reset\n");
4695  return -1;
4696  }
4697  return 0;
4698 }
4699 
4700 int32_t
4702 {
4703  uint32_t ready;
4704  uint32_t val;
4705 
4706  /*
4707  * Firmware must be ready before setting port migration.
4708  */
4710  if (!ready) {
4711  ocs_log_crit(sli4->os, "FW status is NOT ready\n");
4712  return -1;
4713  }
4714 
4715  switch (sli4->if_type) {
4717  val = BIT(SLI4_PORT_MIGRATION_BIT + sli4->physical_port);
4718  ocs_log_debug(sli4->os, "PM: Setting SLI4_REG_PHYSDEV_CONTROL to val: 0x%x\n", val);
4720  break;
4721  default:
4722  ocs_log_test(sli4->os, "Unexpected iftype %d\n", sli4->if_type);
4723  return -1;
4724  }
4725 
4726  /* wait for the FW to become ready after the reset */
4728  if (!ready) {
4729  ocs_log_crit(sli4->os, "Failed to become ready after firmware reset\n");
4730  }
4731 
4732  return 0;
4733 }
4734 /**
4735  * @ingroup sli
4736  * @brief Tear down a SLI context.
4737  *
4738  * @param sli4 SLI context.
4739  *
4740  * @return Returns 0 on success, or non-zero otherwise.
4741  */
4742 int32_t
4744 {
4745  uint32_t i;
4746 
4747  if (sli4->config.extent[0].base) {
4748  ocs_free(sli4->os, sli4->config.extent[0].base, SLI_RSRC_MAX * sizeof(uint32_t));
4749  sli4->config.extent[0].base = NULL;
4750  }
4751 
4752  for (i = 0; i < SLI_RSRC_MAX; i++) {
4753  if (sli4->config.has_extents) {
4754  /* TODO COMMON_DEALLOC_RESOURCE_EXTENTS */;
4755  }
4756 
4757  sli4->config.extent[i].base = NULL;
4758 
4759  ocs_bitmap_free(sli4->config.extent[i].use_map);
4760  sli4->config.extent[i].use_map = NULL;
4761  ocs_lock_free(&sli4->config.extent[i].lock);
4762  }
4763 
4764  if (sli_fw_term(sli4)) {
4765  ocs_log_err(sli4->os, "FW deinitialization failed\n");
4766  }
4767 
4768  ocs_dma_free(sli4->os, &sli4->vpd.data);
4769  ocs_dma_free(sli4->os, &sli4->bmbx);
4770 
4771  return 0;
4772 }
4773 
4774 /**
4775  * @ingroup sli
4776  * @brief Register a callback for the given event.
4777  *
4778  * @param sli4 SLI context.
4779  * @param which Event of interest.
4780  * @param func Function to call when the event occurs.
4781  * @param arg Argument passed to the callback function.
4782  *
4783  * @return Returns 0 on success, or non-zero otherwise.
4784  */
4785 int32_t
4786 sli_callback(sli4_t *sli4, sli4_callback_e which, void *func, void *arg)
4787 {
4788 
4789  if (!sli4 || !func || (which >= SLI4_CB_MAX)) {
4790  ocs_log_err(NULL, "bad parameter sli4=%p which=%#x func=%p\n",
4791  sli4, which, func);
4792  return -1;
4793  }
4794 
4795  switch (which) {
4796  case SLI4_CB_LINK:
4797  sli4->link = func;
4798  sli4->link_arg = arg;
4799  break;
4800  case SLI4_CB_FIP:
4801  sli4->fip = func;
4802  sli4->fip_arg = arg;
4803  break;
4804  default:
4805  ocs_log_test(sli4->os, "unknown callback %#x\n", which);
4806  return -1;
4807  }
4808 
4809  return 0;
4810 }
4811 
4812 /**
4813  * @ingroup sli
4814  * @brief Initialize a queue object.
4815  *
4816  * @par Description
4817  * This initializes the sli4_queue_t object members, including the underlying
4818  * DMA memory.
4819  *
4820  * @param sli4 SLI context.
4821  * @param q Pointer to queue object.
4822  * @param qtype Type of queue to create.
4823  * @param size Size of each entry.
4824  * @param n_entries Number of entries to allocate.
4825  * @param align Starting memory address alignment.
4826  *
4827  * @note Checks if using the existing DMA memory (if any) is possible. If not,
4828  * it frees the existing memory and re-allocates.
4829  *
4830  * @return Returns 0 on success, or non-zero otherwise.
4831  */
4832 int32_t
4833 __sli_queue_init(sli4_t *sli4, sli4_queue_t *q, uint32_t qtype,
4834  size_t size, uint32_t n_entries, uint32_t align)
4835 {
4836  /* According to SLI, Q DMA size should be a power of 2 */
4837  ocs_hal_assert(ocs_power_of_2(size * n_entries));
4838 
4839  if ((q->dma.virt == NULL) || (size != q->size) || (n_entries != q->length)) {
4840  if (q->dma.size) {
4841  ocs_dma_free(sli4->os, &q->dma);
4842  }
4843 
4844  ocs_memset(q, 0, sizeof(sli4_queue_t));
4845 
4846  if (ocs_dma_alloc(sli4->os, &q->dma, size * n_entries, align)) {
4847  ocs_log_err(sli4->os, "%s allocation failed\n", SLI_QNAME[qtype]);
4848  return -1;
4849  }
4850 
4851  ocs_memset(q->dma.virt, 0, size * n_entries);
4852 
4853  ocs_lock_init(sli4->os, &q->lock, "%s lock[%d]", SLI_QNAME[qtype], ocs_instance(sli4->os));
4854 
4855  q->type = qtype;
4856  q->size = size;
4857  q->length = n_entries;
4858 
4859  if ((q->type == SLI_QTYPE_EQ) || (q->type == SLI_QTYPE_CQ)) {
4860  /* For prism, phase will be flipped after a sweep through eq and cq */
4861  q->phase = 1;
4862  }
4863 
4864  switch(q->type) {
4865  case SLI_QTYPE_EQ:
4866  q->posted_limit = q->length / 2;
4867  break;
4868  default:
4869  if ((sli4->if_type == SLI4_IF_TYPE_BE3_SKH_PF) ||
4870  (sli4->if_type == SLI4_IF_TYPE_BE3_SKH_VF)) {
4871  /* For Skyhawk, ring the doorbell more often */
4872  q->posted_limit = 8;
4873  } else {
4874  q->posted_limit = 64;
4875  }
4876  break;
4877  }
4878  }
4879 
4880  return 0;
4881 }
4882 
4883 /**
4884  * @ingroup sli
4885  * @brief Issue the command to create a queue.
4886  *
4887  * @param sli4 SLI context.
4888  * @param q Pointer to queue object.
4889  *
4890  * @return Returns 0 on success, or non-zero otherwise.
4891  */
4892 int32_t
4894 {
4895  sli4_res_common_create_queue_t *res_q = NULL;
4896  sli4_res_create_dpp_wq_t *dpp_res_q = NULL;
4897 
4898  if (sli_bmbx_command(sli4)){
4899  ocs_log_crit(sli4->os, "bootstrap mailbox write fail %s\n",
4900  SLI_QNAME[q->type]);
4901  ocs_dma_free(sli4->os, &q->dma);
4902  return -1;
4903  }
4904  if (sli_res_sli_config(sli4->bmbx.virt)) {
4905  ocs_log_err(sli4->os, "bad status create %s\n", SLI_QNAME[q->type]);
4906  ocs_dma_free(sli4->os, &q->dma);
4907  return -1;
4908  }
4909  res_q = (void *)((uint8_t *)sli4->bmbx.virt +
4910  offsetof(sli4_cmd_sli_config_t, payload));
4911 
4912  if (res_q->hdr.status) {
4913  ocs_log_err(sli4->os, "bad create %s status=%#x addl=%#x\n",
4914  SLI_QNAME[q->type],
4915  res_q->hdr.status, res_q->hdr.additional_status);
4916  ocs_dma_free(sli4->os, &q->dma);
4917  return -1;
4918  } else {
4919  q->id = res_q->q_id;
4920 
4921  switch (q->type) {
4922  case SLI_QTYPE_EQ:
4923  /* No doorbell information in response for EQs */
4924  q->doorbell_offset = regmap[SLI4_REG_EQ_DOORBELL][sli4->if_type].off;
4925  q->doorbell_rset = regmap[SLI4_REG_EQ_DOORBELL][sli4->if_type].rset;
4926  break;
4927  case SLI_QTYPE_CQ:
4928  /* No doorbell information in response for CQs */
4929  q->doorbell_offset = regmap[SLI4_REG_CQ_DOORBELL][sli4->if_type].off;
4930  q->doorbell_rset = regmap[SLI4_REG_CQ_DOORBELL][sli4->if_type].rset;
4931  break;
4932  case SLI_QTYPE_MQ:
4933  /* No doorbell information in response for MQs */
4934  q->doorbell_offset = regmap[SLI4_REG_MQ_DOORBELL][sli4->if_type].off;
4935  q->doorbell_rset = regmap[SLI4_REG_MQ_DOORBELL][sli4->if_type].rset;
4936  break;
4937  case SLI_QTYPE_RQ:
4938  if (!sli4->config.dual_ulp_capable) {
4939  /* set the doorbell for non-skyhawks */
4942  } else {
4943  q->doorbell_offset = res_q->db_offset;
4944  q->doorbell_rset = res_q->db_rs;
4945  }
4946  break;
4947  case SLI_QTYPE_WQ:
4948  if (sli4->config.dpp) {
4949  dpp_res_q = (sli4_res_create_dpp_wq_t *) res_q;
4950  q->u.dpp.enabled = dpp_res_q->dpp;
4951  /* Check if dpp is enabled */
4952  if (dpp_res_q->dpp) {
4953  q->doorbell_rset = dpp_res_q->wq_reg_set;
4954  q->doorbell_offset = dpp_res_q->wq_db_offset;
4955  q->u.dpp.id = dpp_res_q->dpp_id;
4956  q->u.dpp.db_offset = dpp_res_q->dpp_offset;
4957  q->u.dpp.db_rset = dpp_res_q->dpp_reg_set;
4958  ocs_log_info(sli4->os, "DPP WQ Create success dpp_id = %d \n",
4959  dpp_res_q->dpp_id);
4960  break;
4961  }
4962  }
4963  /* DPP Not enabled. Set the regualr wq doorbell register and offset */
4964  if (!sli4->config.dual_ulp_capable) {
4965  /* set the doorbell for non-skyhawks */
4966  q->doorbell_offset = regmap[SLI4_REG_IO_WQ_DOORBELL][sli4->if_type].off;
4967  q->doorbell_rset = regmap[SLI4_REG_IO_WQ_DOORBELL][sli4->if_type].rset;
4968  } else {
4969  q->doorbell_offset = res_q->db_offset;
4970  q->doorbell_rset = res_q->db_rs;
4971  }
4972  break;
4973  default:
4974  break;
4975  }
4976  }
4977 
4978  return 0;
4979 }
4980 
4981 /**
4982  * @ingroup sli
4983  * @brief Get queue entry size.
4984  *
4985  * Get queue entry size given queue type.
4986  *
4987  * @param sli4 SLI context
4988  * @param qtype Type for which the entry size is returned.
4989  *
4990  * @return Returns > 0 on success (queue entry size), or a negative value on failure.
4991  */
4992 int32_t
4993 sli_get_queue_entry_size(sli4_t *sli4, uint32_t qtype)
4994 {
4995  uint32_t size = 0;
4996 
4997  if (!sli4) {
4998  ocs_log_err(NULL, "bad parameter sli4=%p\n", sli4);
4999  return -1;
5000  }
5001 
5002  switch (qtype) {
5003  case SLI_QTYPE_EQ:
5004  size = SLI4_EQE_BYTES;
5005  break;
5006  case SLI_QTYPE_CQ:
5007  size = SLI4_CQE_BYTES;
5008  break;
5009  case SLI_QTYPE_MQ:
5010  size = SLI4_MQE_BYTES;
5011  break;
5012  case SLI_QTYPE_WQ:
5013  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
5014  size = sli4->config.wqe_size;
5015  } else {
5016  // TODO
5017  ocs_log_test(sli4->os, "unsupported queue entry size\n");
5018  return -1;
5019  }
5020  break;
5021  case SLI_QTYPE_RQ:
5022  size = SLI4_FCOE_RQE_SIZE;
5023  break;
5024  default:
5025  ocs_log_test(sli4->os, "unknown queue type %d\n", qtype);
5026  return -1;
5027  }
5028  return size;
5029 }
5030 
5031 /**
5032  * @ingroup sli
5033  * @brief Modify the delay timer for all the EQs
5034  *
5035  * @param sli4 SLI context.
5036  * @param eq Array of EQs.
5037  * @param num_eq Count of EQs.
5038  * @param shift Phase shift for staggering interrupts.
5039  * @param delay_mult Delay multiplier for limiting interrupt frequency.
5040  *
5041  * @return Returns 0 on success, or -1 otherwise.
5042  */
5043 int32_t
5044 sli_eq_modify_delay(sli4_t *sli4, sli4_queue_t *eq, uint32_t num_eq, uint32_t shift, uint32_t delay_mult)
5045 {
5046 
5047  sli_cmd_common_modify_eq_delay(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE, eq, num_eq, shift, delay_mult);
5048 
5049  if (sli_bmbx_command(sli4)) {
5050  ocs_log_crit(sli4->os, "bootstrap mailbox write fail (MODIFY EQ DELAY)\n");
5051  return -1;
5052  }
5053  if (sli_res_sli_config(sli4->bmbx.virt)) {
5054  ocs_log_err(sli4->os, "bad status MODIFY EQ DELAY\n");
5055  return -1;
5056  }
5057 
5058  return 0;
5059 }
5060 
5061 /**
5062  * @ingroup sli
5063  * @brief Allocate a queue.
5064  *
5065  * @par Description
5066  * Allocates DMA memory and configures the requested queue type.
5067  *
5068  * @param sli4 SLI context.
5069  * @param qtype Type of queue to create.
5070  * @param q Pointer to the queue object.
5071  * @param n_entries Number of entries to allocate.
5072  * @param assoc Associated queue (that is, the EQ for a CQ, the CQ for a MQ, and so on).
5073  * @param ulp The ULP to bind, which is only used for WQ and RQs
5074  *
5075  * @return Returns 0 on success, or -1 otherwise.
5076  */
5077 int32_t
5078 sli_queue_alloc(sli4_t *sli4, uint32_t qtype, sli4_queue_t *q, uint32_t n_entries,
5079  sli4_queue_t *assoc, uint16_t ulp)
5080 {
5081  int32_t size;
5082  uint32_t align = 0;
5083  sli4_create_q_fn_t create = NULL;
5084 
5085 
5086  if (!sli4 || !q) {
5087  ocs_log_err(NULL, "bad parameter sli4=%p q=%p\n", sli4, q);
5088  return -1;
5089  }
5090 
5091  /* get queue size */
5092  size = sli_get_queue_entry_size(sli4, qtype);
5093  if (size < 0)
5094  return -1;
5095  align = SLI_PAGE_SIZE;
5096 
5097  switch (qtype) {
5098  case SLI_QTYPE_EQ:
5099  create = sli_cmd_common_create_eq;
5100  break;
5101  case SLI_QTYPE_CQ:
5102  create = sli_cmd_common_create_cq;
5103  break;
5104  case SLI_QTYPE_MQ:
5105  /* Validate the number of entries */
5106  switch (n_entries) {
5107  case 16:
5108  case 32:
5109  case 64:
5110  case 128:
5111  break;
5112  default:
5113  ocs_log_test(sli4->os, "illegal n_entries value %d for MQ\n", n_entries);
5114  return -1;
5115  }
5116  assoc->u.flag.is_mq = TRUE;
5118  break;
5119  case SLI_QTYPE_WQ:
5120  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
5121  if (sli4->if_type == SLI4_IF_TYPE_BE3_SKH_PF) {
5122  create = sli_cmd_fcoe_wq_create;
5123  } else {
5124  create = sli_cmd_fcoe_wq_create_v1;
5125  }
5126  } else {
5127  // TODO
5128  ocs_log_test(sli4->os, "unsupported WQ create\n");
5129  return -1;
5130  }
5131  break;
5132  default:
5133  ocs_log_test(sli4->os, "unknown queue type %d\n", qtype);
5134  return -1;
5135  }
5136 
5137 
5138  if (__sli_queue_init(sli4, q, qtype, size, n_entries, align)) {
5139  ocs_log_err(sli4->os, "%s allocation failed\n", SLI_QNAME[qtype]);
5140  return -1;
5141  }
5142 
5143  if (create(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE, &q->dma, assoc ? assoc->id : 0, ulp)) {
5144 
5145  if (__sli_create_queue(sli4, q)) {
5146  ocs_log_err(sli4->os, "create %s failed\n", SLI_QNAME[qtype]);
5147  return -1;
5148  }
5149  q->ulp = ulp;
5150  } else {
5151  ocs_log_err(sli4->os, "cannot create %s\n", SLI_QNAME[qtype]);
5152  return -1;
5153  }
5154 
5155  return 0;
5156 }
5157 
5158 
5159 /**
5160  * @ingroup sli
5161  * @brief Allocate a c queue set.
5162  *
5163  * @param sli4 SLI context.
5164  * @param num_cqs to create
5165  * @param qs Pointers to the queue objects.
5166  * @param n_entries Number of entries to allocate per CQ.
5167  * @param eqs Associated event queues
5168  *
5169  * @return Returns 0 on success, or -1 otherwise.
5170  */
5171 int32_t
5172 sli_cq_alloc_set(sli4_t *sli4, sli4_queue_t *qs[], uint32_t num_cqs,
5173  uint32_t n_entries, sli4_queue_t *eqs[])
5174 {
5175  uint32_t i, offset = 0, page_bytes = 0, payload_size, cmd_size = 0;
5176  uint32_t p = 0, page_size = 0, n_cqe = 0, num_pages_cq;
5177  uintptr_t addr;
5178  ocs_dma_t dma;
5181 
5182  if (!sli4) {
5183  ocs_log_err(NULL, "bad parameter sli4=%p\n", sli4);
5184  return -1;
5185  }
5186 
5187  memset(&dma, 0, sizeof(dma));
5188 
5189  /* Align the queue DMA memory */
5190  for (i = 0; i < num_cqs; i++) {
5191  if (__sli_queue_init(sli4, qs[i], SLI_QTYPE_CQ, SLI4_CQE_BYTES,
5192  n_entries, SLI_PAGE_SIZE)) {
5193  ocs_log_err(sli4->os, "Queue init failed.\n");
5194  goto error;
5195  }
5196  }
5197 
5198  n_cqe = qs[0]->dma.size / SLI4_CQE_BYTES;
5199  switch (n_cqe) {
5200  case 256:
5201  case 512:
5202  case 1024:
5203  case 2048:
5204  page_size = 1;
5205  break;
5206  case 4096:
5207  page_size = 2;
5208  break;
5209  default:
5210  return -1;
5211  }
5212 
5213  page_bytes = page_size * SLI_PAGE_SIZE;
5214  num_pages_cq = sli_page_count(qs[0]->dma.size, page_bytes);
5215  cmd_size = sizeof(sli4_req_common_create_cq_set_v0_t) + (8 * num_pages_cq * num_cqs);
5216  payload_size = max((size_t)cmd_size, sizeof(sli4_res_common_create_queue_set_t));
5217 
5218  if (ocs_dma_alloc(sli4->os, &dma, payload_size, SLI_PAGE_SIZE)) {
5219  ocs_log_err(sli4->os, "DMA allocation failed\n");
5220  goto error;
5221  }
5222  ocs_memset(dma.virt, 0, payload_size);
5223 
5224  if (sli_cmd_sli_config(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE,
5225  payload_size, &dma) == -1) {
5226  goto error;
5227  }
5228 
5229  /* Fill the request structure */
5230 
5231  req = (sli4_req_common_create_cq_set_v0_t *)((uint8_t *)dma.virt);
5234  req->hdr.version = 0;
5235  req->hdr.request_length = cmd_size - sizeof(sli4_req_hdr_t);
5236  req->page_size = page_size;
5237 
5238  req->num_pages = num_pages_cq;
5239  switch (req->num_pages) {
5240  case 1:
5241  req->cqecnt = SLI4_CQ_CNT_256;
5242  break;
5243  case 2:
5244  req->cqecnt = SLI4_CQ_CNT_512;
5245  break;
5246  case 4:
5247  req->cqecnt = SLI4_CQ_CNT_1024;
5248  break;
5249  case 8:
5250  req->cqecnt = SLI4_CQ_CNT_LARGE;
5251  req->cqe_count = n_cqe;
5252  break;
5253  default:
5254  ocs_log_test(sli4->os, "num_pages %d not valid\n", req->num_pages);
5255  goto error;
5256  }
5257 
5258  req->evt = TRUE;
5259  req->valid = TRUE;
5260  req->arm = FALSE;
5261  req->num_cq_req = num_cqs;
5262  if (sli4->if_type == SLI4_IF_TYPE_LANCER_G7)
5263  req->autovalid = TRUE;
5264 
5265  /* Fill page addresses of all the CQs. */
5266  for (i = 0; i < num_cqs; i++) {
5267  req->eq_id[i] = eqs[i]->id;
5268  for (p = 0, addr = qs[i]->dma.phys; p < req->num_pages; p++, addr += page_bytes) {
5269  req->page_physical_address[offset].low = ocs_addr32_lo(addr);
5270  req->page_physical_address[offset].high = ocs_addr32_hi(addr);
5271  offset++;
5272  }
5273  }
5274 
5275  if (sli_bmbx_command(sli4)) {
5276  ocs_log_crit(sli4->os, "bootstrap mailbox write fail CQSet\n");
5277  goto error;
5278  }
5279 
5280  res = (void *)((uint8_t *)dma.virt);
5281  if (res->hdr.status) {
5282  ocs_log_err(sli4->os, "bad create CQSet status=%#x addl=%#x\n",
5283  res->hdr.status, res->hdr.additional_status);
5284  goto error;
5285  } else {
5286  /* Check if we got all requested CQs. */
5287  if (res->num_q_allocated != num_cqs) {
5288  ocs_log_crit(sli4->os, "Requested count CQs doesnt match.\n");
5289  goto error;
5290  }
5291 
5292  /* Fill the resp cq ids. */
5293  for (i = 0; i < num_cqs; i++) {
5294  qs[i]->id = res->q_id + i;
5295  qs[i]->doorbell_offset = regmap[SLI4_REG_CQ_DOORBELL][sli4->if_type].off;
5296  qs[i]->doorbell_rset = regmap[SLI4_REG_CQ_DOORBELL][sli4->if_type].rset;
5297  }
5298  }
5299 
5300  ocs_dma_free(sli4->os, &dma);
5301 
5302  return 0;
5303 
5304 error:
5305  for (i = 0; i < num_cqs; i++) {
5306  if (qs[i]->dma.size) {
5307  ocs_dma_free(sli4->os, &qs[i]->dma);
5308  }
5309  }
5310 
5311  if (dma.size) {
5312  ocs_dma_free(sli4->os, &dma);
5313  }
5314 
5315  return -1;
5316 }
5317 
5318 
5319 
5320 /**
5321  * @ingroup sli
5322  * @brief Free a queue.
5323  *
5324  * @par Description
5325  * Frees DMA memory and de-registers the requested queue.
5326  *
5327  * @param sli4 SLI context.
5328  * @param q Pointer to the queue object.
5329  * @param destroy_queues Non-zero if the mailbox commands should be sent to destroy the queues.
5330  * @param free_memory Non-zero if the DMA memory associated with the queue should be freed.
5331  *
5332  * @return Returns 0 on success, or -1 otherwise.
5333  */
5334 int32_t
5335 sli_queue_free(sli4_t *sli4, sli4_queue_t *q, uint32_t destroy_queues, uint32_t free_memory)
5336 {
5337  sli4_destroy_q_fn_t destroy = NULL;
5338  int32_t rc = -1;
5339 
5340  if (!sli4 || !q) {
5341  ocs_log_err(NULL, "bad parameter sli4=%p q=%p\n", sli4, q);
5342  return -1;
5343  }
5344 
5345  if (destroy_queues) {
5346  switch (q->type) {
5347  case SLI_QTYPE_EQ:
5348  destroy = sli_cmd_common_destroy_eq;
5349  break;
5350  case SLI_QTYPE_CQ:
5351  destroy = sli_cmd_common_destroy_cq;
5352  break;
5353  case SLI_QTYPE_MQ:
5354  destroy = sli_cmd_common_destroy_mq;
5355  break;
5356  case SLI_QTYPE_WQ:
5357  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
5358  destroy = sli_cmd_fcoe_wq_destroy;
5359  } else {
5360  // TODO
5361  ocs_log_test(sli4->os, "unsupported WQ destroy\n");
5362  return -1;
5363  }
5364  break;
5365  case SLI_QTYPE_RQ:
5366  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
5367  destroy = sli_cmd_fcoe_rq_destroy;
5368  } else {
5369  // TODO
5370  ocs_log_test(sli4->os, "unsupported RQ destroy\n");
5371  return -1;
5372  }
5373  break;
5374  default:
5375  ocs_log_test(sli4->os, "bad queue type %d\n",
5376  q->type);
5377  return -1;
5378  }
5379 
5380  /*
5381  * Destroying queues makes BE3 sad (version 0 interface type). Rely
5382  * on COMMON_FUNCTION_RESET to free host allocated queue resources
5383  * inside the SLI Port.
5384  */
5385  if (SLI4_IF_TYPE_BE3_SKH_PF == sli4->if_type) {
5386  destroy = NULL;
5387  }
5388 
5389  // Destroy the queue if the operation is defined
5390  if (destroy && destroy(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE, q->id)) {
5391  sli4_res_hdr_t *res = NULL;
5392 
5393  if (sli_bmbx_command(sli4)){
5394  ocs_log_crit(sli4->os, "bootstrap mailbox write fail destroy %s\n",
5395  SLI_QNAME[q->type]);
5396  } else if (sli_res_sli_config(sli4->bmbx.virt)) {
5397  ocs_log_err(sli4->os, "bad status destroy %s\n", SLI_QNAME[q->type]);
5398  } else {
5399  res = (void *)((uint8_t *)sli4->bmbx.virt +
5400  offsetof(sli4_cmd_sli_config_t, payload));
5401 
5402  if (res->status) {
5403  ocs_log_err(sli4->os, "bad destroy %s status=%#x addl=%#x\n",
5404  SLI_QNAME[q->type],
5405  res->status, res->additional_status);
5406  } else {
5407  rc = 0;
5408  }
5409  }
5410  }
5411  }
5412 
5413  sli_queue_reset(sli4, q);
5414 
5415  if (free_memory) {
5416  ocs_lock_free(&q->lock);
5417 
5418  if (ocs_dma_free(sli4->os, &q->dma)) {
5419  ocs_log_err(sli4->os, "%s queue ID %d free failed\n",
5420  SLI_QNAME[q->type], q->id);
5421  rc = -1;
5422  }
5423  }
5424 
5425  return rc;
5426 }
5427 
5428 int32_t
5430 {
5431 
5432  ocs_lock(&q->lock);
5433 
5434  q->index = 0;
5435  q->n_posted = 0;
5436 
5437  if (SLI_QTYPE_MQ == q->type) {
5438  q->u.r_idx = 0;
5439  }
5440 
5441  if (q->dma.virt != NULL) {
5442  ocs_memset(q->dma.virt, 0, (q->size * (uint64_t)q->length));
5443  }
5444 
5445  ocs_unlock(&q->lock);
5446 
5447  return 0;
5448 }
5449 
5450 /**
5451  * @ingroup sli
5452  * @brief Check if the given queue is empty.
5453  *
5454  * @par Description
5455  * If the valid bit of the current entry is unset, the queue is empty.
5456  *
5457  * @param sli4 SLI context.
5458  * @param q Pointer to the queue object.
5459  *
5460  * @return Returns TRUE if empty, or FALSE otherwise.
5461  */
5462 int32_t
5464 {
5465  int32_t rc = TRUE;
5466  uint8_t *qe = q->dma.virt;
5467 
5468  ocs_lock(&q->lock);
5469 
5470  ocs_dma_sync(&q->dma, OCS_DMASYNC_POSTREAD);
5471 
5472  qe += q->index * q->size;
5473 
5474  rc = !sli_queue_entry_is_valid(q, qe, FALSE);
5475 
5476  ocs_unlock(&q->lock);
5477 
5478  return rc;
5479 }
5480 
5481 /**
5482  * @ingroup sli
5483  * @brief Arm an EQ.
5484  *
5485  * @param sli4 SLI context.
5486  * @param q Pointer to queue object.
5487  * @param arm If TRUE, arm the EQ.
5488  *
5489  * @return Returns 0 on success, or non-zero otherwise.
5490  */
5491 int32_t
5492 sli_queue_eq_arm(sli4_t *sli4, sli4_queue_t *q, uint8_t arm)
5493 {
5494  uint32_t val = 0;
5495 
5496  ocs_lock(&q->lock);
5497  if (sli4->if_type == SLI4_IF_TYPE_LANCER_G7)
5498  val = sli_iftype6_eq_doorbell(q->n_posted, q->id, arm);
5499  else
5500  val = sli_eq_doorbell(q->n_posted, q->id, arm);
5501  ocs_reg_write32(sli4->os, q->doorbell_rset, q->doorbell_offset, val);
5502  q->n_posted = 0;
5503  ocs_unlock(&q->lock);
5504 
5505  return 0;
5506 }
5507 
5508 /**
5509  * @ingroup sli
5510  * @brief Arm a queue.
5511  *
5512  * @param sli4 SLI context.
5513  * @param q Pointer to queue object.
5514  * @param arm If TRUE, arm the queue.
5515  *
5516  * @return Returns 0 on success, or non-zero otherwise.
5517  */
5518 int32_t
5519 sli_queue_arm(sli4_t *sli4, sli4_queue_t *q, uint8_t arm)
5520 {
5521  uint32_t val = 0;
5522 
5523  ocs_lock(&q->lock);
5524 
5525  switch (q->type) {
5526  case SLI_QTYPE_EQ:
5527  if (sli4->if_type == SLI4_IF_TYPE_LANCER_G7)
5528  val = sli_iftype6_eq_doorbell(q->n_posted, q->id, arm);
5529  else
5530  val = sli_eq_doorbell(q->n_posted, q->id, arm);
5531  ocs_reg_write32(sli4->os, q->doorbell_rset, q->doorbell_offset, val);
5532  q->n_posted = 0;
5533  break;
5534  case SLI_QTYPE_CQ:
5535  if (sli4->if_type == SLI4_IF_TYPE_LANCER_G7)
5536  val = sli_iftype6_cq_doorbell(q->n_posted, q->id, arm);
5537  else
5538  val = sli_cq_doorbell(q->n_posted, q->id, arm);
5539  ocs_reg_write32(sli4->os, q->doorbell_rset, q->doorbell_offset, val);
5540  q->n_posted = 0;
5541  break;
5542  default:
5543  ocs_log_test(sli4->os, "should only be used for EQ/CQ, not %s\n",
5544  SLI_QNAME[q->type]);
5545  }
5546 
5547  ocs_unlock(&q->lock);
5548 
5549  return 0;
5550 }
5551 
5552 /**
5553  * @ingroup sli
5554  * @brief Write an entry to the queue object.
5555  *
5556  * Note: Assumes the q->lock will be locked and released by the caller.
5557  *
5558  * @param sli4 SLI context.
5559  * @param q Pointer to the queue object.
5560  * @param entry Pointer to the entry contents.
5561  *
5562  * @return Returns queue index on success, or negative error value otherwise.
5563  */
5564 int32_t
5565 _sli_queue_write(sli4_t *sli4, sli4_queue_t *q, uint8_t *entry)
5566 {
5567  int32_t rc = 0;
5568  uint8_t *qe = q->dma.virt;
5569  uint32_t qindex;
5570  uint8_t dpp = FALSE;
5571  uint32_t i = 0;
5572  uint8_t *tmp;
5573 
5574  qindex = q->index;
5575  qe += q->index * q->size;
5576 
5577  if (entry) {
5578  if (SLI_QTYPE_WQ == q->type) {
5579  if (sli4->config.perf_wq_id_association)
5580  sli_set_wq_id_association(entry, q->id);
5581 
5582  if (q->u.dpp.enabled)
5583  dpp = TRUE;
5584  }
5585 #if defined(OCS_INCLUDE_DEBUG)
5586  switch (q->type) {
5587  case SLI_QTYPE_WQ: {
5588  ocs_dump32(OCS_DEBUG_ENABLE_WQ_DUMP, sli4->os, "wqe", entry, q->size);
5589  break;
5590 
5591  }
5592  case SLI_QTYPE_MQ:
5593  // Note: we don't really need to dump the whole 256 bytes, just do 64
5594  ocs_dump32(OCS_DEBUG_ENABLE_MQ_DUMP, sli4->os, "mqe outbound", entry, 64);
5595  break;
5596 
5597  default:
5598  break;
5599  }
5600 #endif
5601  ocs_memcpy(qe, entry, q->size);
5602  if (dpp) {
5603  tmp = (uint8_t *)entry;
5604  for (i = 0; i < q->size; i += sizeof(uint32_t)) {
5605  ocs_reg_write32(sli4->os,
5606  q->u.dpp.db_rset,
5607  q->u.dpp.db_offset + i,
5608  *((uint32_t *)(tmp + i)));
5609  }
5610  }
5611  q->n_posted = 1;
5612  }
5613 
5614  ocs_dma_sync(&q->dma, OCS_DMASYNC_PREWRITE);
5615 
5616  rc = sli_queue_doorbell(sli4, q);
5617 
5618  q->index = (q->index + q->n_posted) & (q->length - 1);
5619  q->n_posted = 0;
5620 
5621  if (rc < 0) {
5622  /* failure */
5623  return rc;
5624  } else if (rc > 0) {
5625  /* failure, but we need to return a negative value on failure */
5626  return -rc;
5627  } else {
5628  return qindex;
5629  }
5630 }
5631 
5632 /**
5633  * @ingroup sli
5634  * @brief Write an entry to the queue object.
5635  *
5636  * Note: Assumes the q->lock will be locked and released by the caller.
5637  *
5638  * @param sli4 SLI context.
5639  * @param q Pointer to the queue object.
5640  * @param entry Pointer to the entry contents.
5641  *
5642  * @return Returns queue index on success, or negative error value otherwise.
5643  */
5644 int32_t
5645 sli_queue_write(sli4_t *sli4, sli4_queue_t *q, uint8_t *entry)
5646 {
5647  int32_t rc;
5648 
5649  ocs_lock(&q->lock);
5650  rc = _sli_queue_write(sli4, q, entry);
5651  ocs_unlock(&q->lock);
5652 
5653  return rc;
5654 }
5655 
5656 /**
5657  * @brief Check if the current queue entry is valid.
5658  *
5659  * @param q Pointer to the queue object.
5660  * @param qe Pointer to the queue entry.
5661  * @param clear Boolean to clear valid bit.
5662  *
5663  * @return Returns TRUE if the entry is valid, or FALSE otherwise.
5664  */
5665 static uint8_t
5666 sli_queue_entry_is_valid(sli4_queue_t *q, uint8_t *qe, uint8_t clear)
5667 {
5668  uint8_t valid = FALSE;
5669  uint8_t valid_bit_set = 0;
5670 
5671  switch (q->type) {
5672  case SLI_QTYPE_EQ:
5673  valid = (((sli4_eqe_t *)qe)->vld == q->phase) ? 1 : 0;
5674  if (valid && clear) {
5675  ((sli4_eqe_t *)qe)->vld = 0;
5676  }
5677  break;
5678  case SLI_QTYPE_CQ:
5679  /*
5680  * For both MCQE and WCQE/RCQE, the valid bit
5681  * is bit 31 of dword 3 (0 based)
5682  */
5683  valid_bit_set = (qe[15] & 0x80) != 0;
5684  if (valid_bit_set == q->phase)
5685  valid = 1;
5686 
5687  if (valid & clear) {
5688  qe[15] &= ~0x80;
5689  }
5690  break;
5691  case SLI_QTYPE_MQ:
5692  valid = q->index != q->u.r_idx;
5693  break;
5694  case SLI_QTYPE_RQ:
5695  valid = TRUE;
5696  clear = FALSE;
5697  break;
5698  default:
5699  ocs_log_test(NULL, "doesn't handle type=%#x\n", q->type);
5700  }
5701 
5702  if (clear) {
5703  ocs_dma_sync(&q->dma, OCS_DMASYNC_PREWRITE);
5704  }
5705 
5706  return valid;
5707 }
5708 
5709 /**
5710  * @ingroup sli
5711  * @brief Read an entry from the queue object.
5712  *
5713  * @param sli4 SLI context.
5714  * @param q Pointer to the queue object.
5715  * @param entry Destination pointer for the queue entry contents.
5716  *
5717  * @return Returns 0 on success, or non-zero otherwise.
5718  */
5719 int32_t
5720 sli_queue_read(sli4_t *sli4, sli4_queue_t *q, uint8_t *entry)
5721 {
5722  int32_t rc = 0;
5723  uint8_t *qe = q->dma.virt;
5724  uint32_t *qindex = NULL;
5725  uint8_t clear = (SLI4_IF_TYPE_LANCER_G7 == sli_get_if_type(sli4)) ? FALSE : TRUE;
5726 
5727  if (SLI_QTYPE_MQ == q->type) {
5728  qindex = &q->u.r_idx;
5729  } else {
5730  qindex = &q->index;
5731  }
5732 
5733  ocs_lock(&q->lock);
5734 
5735  ocs_dma_sync(&q->dma, OCS_DMASYNC_POSTREAD);
5736 
5737  qe += *qindex * q->size;
5738 
5739  if (!sli_queue_entry_is_valid(q, qe, clear)) {
5740  ocs_unlock(&q->lock);
5741  return -1;
5742  }
5743 
5744  if (entry) {
5745  ocs_memcpy(entry, qe, q->size);
5746 #if defined(OCS_INCLUDE_DEBUG)
5747  switch(q->type) {
5748  case SLI_QTYPE_CQ:
5749  ocs_dump32(OCS_DEBUG_ENABLE_CQ_DUMP, sli4->os, "cq", entry, q->size);
5750  break;
5751  case SLI_QTYPE_MQ:
5752  ocs_dump32(OCS_DEBUG_ENABLE_MQ_DUMP, sli4->os, "mq Compl", entry, 64);
5753  break;
5754  case SLI_QTYPE_EQ:
5755  ocs_dump32(OCS_DEBUG_ENABLE_EQ_DUMP, sli4->os, "eq Compl", entry, q->size);
5756  break;
5757  default:
5758  break;
5759  }
5760 #endif
5761  }
5762 
5763  switch (q->type) {
5764  case SLI_QTYPE_EQ:
5765  case SLI_QTYPE_CQ:
5766  case SLI_QTYPE_MQ:
5767  *qindex = (*qindex + 1) & (q->length - 1);
5768  if (SLI_QTYPE_MQ != q->type) {
5769  q->n_posted++;
5770  /*
5771  * For prism, the phase value will be used to check the validity of eq/cq entries.
5772  * The value toggles after a complete sweep through the queue.
5773  */
5774  if ((SLI4_IF_TYPE_LANCER_G7 == sli_get_if_type(sli4)) && (*qindex == 0)) {
5775  q->phase ^= (uint16_t) 0x1;
5776  }
5777  }
5778  break;
5779  default:
5780  /* reads don't update the index */
5781  break;
5782  }
5783 
5784  ocs_unlock(&q->lock);
5785 
5786  return rc;
5787 }
5788 
5789 int32_t
5791 {
5792 
5793  if (q) {
5794  return q->index;
5795  } else {
5796  return -1;
5797  }
5798 }
5799 
5800 int32_t
5801 sli_queue_poke(sli4_t *sli4, sli4_queue_t *q, uint32_t index, uint8_t *entry)
5802 {
5803  int32_t rc;
5804 
5805  ocs_lock(&q->lock);
5806  rc = _sli_queue_poke(sli4, q, index, entry);
5807  ocs_unlock(&q->lock);
5808 
5809  return rc;
5810 }
5811 
5812 int32_t
5813 _sli_queue_poke(sli4_t *sli4, sli4_queue_t *q, uint32_t index, uint8_t *entry)
5814 {
5815  int32_t rc = 0;
5816  uint8_t *qe = q->dma.virt;
5817 
5818  if (index >= q->length) {
5819  return -1;
5820  }
5821 
5822  qe += index * q->size;
5823 
5824  if (entry) {
5825  ocs_memcpy(qe, entry, q->size);
5826  }
5827 
5828  ocs_dma_sync(&q->dma, OCS_DMASYNC_PREWRITE);
5829 
5830  return rc;
5831 }
5832 
5833 /**
5834  * @ingroup sli
5835  * @brief Allocate SLI Port resources.
5836  *
5837  * @par Description
5838  * Allocate port-related resources, such as VFI, RPI, XRI, and so on.
5839  * Resources are modeled using extents, regardless of whether the underlying
5840  * device implements resource extents. If the device does not implement
5841  * extents, the SLI layer models this as a single (albeit large) extent.
5842  *
5843  * @param sli4 SLI context.
5844  * @param rtype Resource type (for example, RPI or XRI)
5845  * @param rid Allocated resource ID.
5846  * @param index Index into the bitmap.
5847  *
5848  * @return Returns 0 on success, or a non-zero value on failure.
5849  */
5850 int32_t
5851 sli_resource_alloc(sli4_t *sli4, sli4_resource_e rtype, uint32_t *rid, uint32_t *index)
5852 {
5853  int32_t rc = 0;
5854  uint32_t size;
5855  uint32_t extent_idx;
5856  uint32_t item_idx;
5857  int status;
5858 
5859  switch (rtype) {
5860  case SLI_RSRC_FCOE_VFI:
5861  case SLI_RSRC_FCOE_VPI:
5862  case SLI_RSRC_FCOE_RPI:
5863  case SLI_RSRC_FCOE_XRI:
5864  ocs_lock(&sli4->config.extent[rtype].lock);
5865 
5866  *rid = UINT32_MAX;
5867  *index = UINT32_MAX;
5868  status = ocs_bitmap_find(sli4->config.extent[rtype].use_map,
5869  sli4->config.extent[rtype].map_size);
5870  if (status < 0) {
5871  ocs_log_err(sli4->os, "out of resource %d (alloc=%d, status=%d, map_size=%d)\n",
5872  rtype, sli4->config.extent[rtype].n_alloc,
5873  status, sli4->config.extent[rtype].map_size);
5874  rc = -1;
5875  ocs_unlock(&sli4->config.extent[rtype].lock);
5876  break;
5877  } else {
5878  *index = status;
5879  }
5880 
5881  size = sli4->config.extent[rtype].size;
5882 
5883  extent_idx = *index / size;
5884  item_idx = *index % size;
5885 
5886  *rid = sli4->config.extent[rtype].base[extent_idx] + item_idx;
5887 
5888  sli4->config.extent[rtype].n_alloc++;
5889  ocs_unlock(&sli4->config.extent[rtype].lock);
5890  break;
5891  default:
5892  rc = -1;
5893  }
5894 
5895  return rc;
5896 }
5897 
5898 /**
5899  * @ingroup sli
5900  * @brief Free the SLI Port resources.
5901  *
5902  * @par Description
5903  * Free port-related resources, such as VFI, RPI, XRI, and so. See discussion of
5904  * "extent" usage in sli_resource_alloc.
5905  *
5906  * @param sli4 SLI context.
5907  * @param rtype Resource type (for example, RPI or XRI).
5908  * @param rid Allocated resource ID.
5909  *
5910  * @return Returns 0 on success, or a non-zero value on failure.
5911  */
5912 int32_t
5913 sli_resource_free(sli4_t *sli4, sli4_resource_e rtype, uint32_t rid)
5914 {
5915  int32_t rc = -1;
5916  uint32_t x;
5917  uint32_t size, *base;
5918 
5919  switch (rtype) {
5920  case SLI_RSRC_FCOE_VFI:
5921  case SLI_RSRC_FCOE_VPI:
5922  case SLI_RSRC_FCOE_RPI:
5923  case SLI_RSRC_FCOE_XRI:
5924  ocs_lock(&sli4->config.extent[rtype].lock);
5925  /*
5926  * Figure out which extent contains the resource ID. I.e. find
5927  * the extent such that
5928  * extent->base <= resource ID < extent->base + extent->size
5929  */
5930  base = sli4->config.extent[rtype].base;
5931  size = sli4->config.extent[rtype].size;
5932 
5933  /*
5934  * In the case of FW reset, this may be cleared but the force_free path will
5935  * still attempt to free the resource. Prevent a NULL pointer access.
5936  */
5937  if (base != NULL) {
5938  for (x = 0; x < sli4->config.extent[rtype].number; x++) {
5939  if ((rid >= base[x]) && (rid < (base[x] + size))) {
5940  rid -= base[x];
5941  ocs_bitmap_clear(sli4->config.extent[rtype].use_map,
5942  (x * size) + rid);
5943  sli4->config.extent[rtype].n_alloc--;
5944  rc = 0;
5945  break;
5946  }
5947  }
5948  }
5949 
5950  ocs_unlock(&sli4->config.extent[rtype].lock);
5951  break;
5952  default:
5953  ;
5954  }
5955 
5956  return rc;
5957 }
5958 
5959 int32_t
5961 {
5962  int32_t rc = -1;
5963  uint32_t i;
5964 
5965  switch (rtype) {
5966  case SLI_RSRC_FCOE_VFI:
5967  case SLI_RSRC_FCOE_VPI:
5968  case SLI_RSRC_FCOE_RPI:
5969  case SLI_RSRC_FCOE_XRI:
5970  ocs_lock(&sli4->config.extent[rtype].lock);
5971 
5972  for (i = 0; i < sli4->config.extent[rtype].map_size; i++) {
5973  ocs_bitmap_clear(sli4->config.extent[rtype].use_map, i);
5974  }
5975 
5976  ocs_unlock(&sli4->config.extent[rtype].lock);
5977  rc = 0;
5978  break;
5979  default:
5980  ;
5981  }
5982 
5983  return rc;
5984 }
5985 
5986 /**
5987  * @ingroup sli
5988  * @brief Parse an EQ entry to retrieve the CQ_ID for this event.
5989  *
5990  * @param sli4 SLI context.
5991  * @param buf Pointer to the EQ entry.
5992  * @param cq_id CQ_ID for this entry (only valid on success).
5993  *
5994  * @return
5995  * - 0 if success.
5996  * - < 0 if error.
5997  * - > 0 if firmware detects EQ overflow.
5998  */
5999 int32_t
6000 sli_eq_parse(sli4_t *sli4, uint8_t *buf, uint16_t *cq_id)
6001 {
6002  sli4_eqe_t *eqe = (void *)buf;
6003  int32_t rc = 0;
6004 
6005  if (!sli4 || !buf || !cq_id) {
6006  ocs_log_err(NULL, "bad parameters sli4=%p buf=%p cq_id=%p\n",
6007  sli4, buf, cq_id);
6008  return -1;
6009 
6010  }
6011 
6012  switch (eqe->major_code) {
6014  *cq_id = eqe->resource_id;
6015  break;
6017  ocs_log_debug(sli4->os, "sentinel EQE\n");
6018  rc = 1;
6019  break;
6020  default:
6021  ocs_log_test(sli4->os, "Unsupported EQE: major %x minor %x\n",
6022  eqe->major_code, eqe->minor_code);
6023  rc = -1;
6024  }
6025 
6026  return rc;
6027 }
6028 
6029 /**
6030  * @ingroup sli
6031  * @brief Parse a CQ entry to retrieve the event type and the associated queue.
6032  *
6033  * @param sli4 SLI context.
6034  * @param cq CQ to process.
6035  * @param cqe Pointer to the CQ entry.
6036  * @param etype CQ event type.
6037  * @param q_id Queue ID associated with this completion message
6038  * (that is, MQ_ID, RQ_ID, and so on).
6039  *
6040  * @return
6041  * - 0 if call completed correctly and CQE status is SUCCESS.
6042  * - -1 if call failed (no CQE status).
6043  * - Other value if call completed correctly and return value is a CQE status value.
6044  */
6045 int32_t
6046 sli_cq_parse(sli4_t *sli4, sli4_queue_t *cq, uint8_t *cqe, sli4_qentry_e *etype,
6047  uint16_t *q_id)
6048 {
6049  int32_t rc = 0;
6050 
6051  if (!sli4 || !cq || !cqe || !etype) {
6052  ocs_log_err(NULL, "bad parameters sli4=%p cq=%p cqe=%p etype=%p q_id=%p\n",
6053  sli4, cq, cqe, etype, q_id);
6054  return -1;
6055  }
6056 
6057  if (cq->u.flag.is_mq) {
6058  sli4_mcqe_t *mcqe = (void *)cqe;
6059 
6060  if (mcqe->ae) {
6061  *etype = SLI_QENTRY_ASYNC;
6062  } else {
6063  *etype = SLI_QENTRY_MQ;
6064  rc = sli_cqe_mq(mcqe);
6065  }
6066  *q_id = -1;
6067  } else if (SLI4_PORT_TYPE_FC == sli4->port_type) {
6068  rc = sli_fc_cqe_parse(sli4, cq, cqe, etype, q_id);
6069  } else {
6070  ocs_log_test(sli4->os, "implement CQE parsing type = %#x\n",
6071  sli4->port_type);
6072  rc = -1;
6073  }
6074 
6075  return rc;
6076 }
6077 
6078 /**
6079  * @ingroup sli
6080  * @brief Cause chip to enter an unrecoverable error state.
6081  *
6082  * @par Description
6083  * Cause chip to enter an unrecoverable error state. This is
6084  * used when detecting unexpected FW behavior so FW can be
6085  * halted from the driver as soon as error is detected.
6086  *
6087  * @param sli4 SLI context.
6088  * @param dump Generate dump as part of reset.
6089  *
6090  * @return Returns 0 if call completed correctly, or -1 if call failed (unsupported chip).
6091  */
6092 int32_t sli_raise_ue(sli4_t *sli4, uint8_t dump)
6093 {
6095  switch(sli_get_asic_type(sli4)) {
6096  case SLI4_ASIC_TYPE_BE3: {
6097  sli_reg_write(sli4, SLI4_REG_SW_UE_CSR1, 0xffffffff);
6099  break;
6100  }
6101  case SLI4_ASIC_TYPE_SKYHAWK: {
6102  uint32_t value;
6103  value = ocs_config_read32(sli4->os, SLI4_SW_UE_REG);
6104  ocs_config_write32(sli4->os, SLI4_SW_UE_REG, (value | (1U << 24)));
6105  break;
6106  }
6107  default:
6108  ocs_log_test(sli4->os, "invalid asic type %d\n", sli_get_asic_type(sli4));
6109  return -1;
6110  }
6111  } else if ((SLI4_IF_TYPE_LANCER_FC_ETH == sli_get_if_type(sli4)) ||
6113  if (FW_FUNC_DESC_DUMP == dump) {
6115  } else {
6116  uint32_t value = SLI4_PHYDEV_CONTROL_FRST;
6117  if (FW_CHIP_LEVEL_DUMP == dump) {
6118  value |= SLI4_PHYDEV_CONTROL_DD;
6119  }
6121  }
6122  } else {
6123  ocs_log_test(sli4->os, "invalid iftype=%d\n", sli_get_if_type(sli4));
6124  return -1;
6125  }
6126  return 0;
6127 }
6128 
6129 /**
6130  * @ingroup sli
6131  * @brief Read the SLIPORT_STATUS register to to check if a dump is present.
6132  *
6133  * @param sli4 SLI context.
6134  *
6135  * @return
6136  * - 0 if the chip is not ready.
6137  * - 1 if dd is present.
6138  * - 2 if fdp is present.
6139  * - 3 if dump won't be generated.
6140  * - -1 if call failed (unsupported chip).
6141  */
6143 {
6144  int32_t rc = FW_DUMP_READY_STATUS_NOT_READY;
6145  uint32_t port_val;
6146  uint32_t bmbx_val;
6147  uint32_t uerr_lo;
6148  uint32_t uerr_hi;
6149  uint32_t uerr_mask_lo;
6150  uint32_t uerr_mask_hi;
6151 
6153  /* for iftype=0, dump ready when UE is encountered */
6154  uerr_lo = sli_reg_read(sli4, SLI4_REG_UERR_STATUS_LO);
6155  uerr_hi = sli_reg_read(sli4, SLI4_REG_UERR_STATUS_HI);
6156  uerr_mask_lo = sli_reg_read(sli4, SLI4_REG_UERR_MASK_LO);
6157  uerr_mask_hi = sli_reg_read(sli4, SLI4_REG_UERR_MASK_HI);
6158  if ((uerr_lo & ~uerr_mask_lo) || (uerr_hi & ~uerr_mask_hi)) {
6160  }
6161 
6162  } else if ((SLI4_IF_TYPE_LANCER_FC_ETH == sli_get_if_type(sli4)) ||
6164  /*
6165  * Ensure that the port is ready AND the mailbox is
6166  * ready before signaling that the dump is ready to go.
6167  */
6168  port_val = sli_reg_read(sli4, SLI4_REG_SLIPORT_STATUS);
6169  bmbx_val = sli_reg_read(sli4, SLI4_REG_BMBX);
6170 
6171  if ((bmbx_val & SLI4_BMBX_RDY) && SLI4_PORT_STATUS_READY(port_val)) {
6172  if (SLI4_PORT_STATUS_DUMP_PRESENT(port_val)) {
6174  } else if (SLI4_PORT_STATUS_FDP_PRESENT(port_val)) {
6176  } else {
6177  /* Chip is in ready state but no dump was generated by the FW */
6179  }
6180  } else if (SLI4_PORT_STATUS_SPP & port_val) {
6181  uint32_t skip_dump = FALSE;
6182  uint32_t flags = SLI4_PHYDEV_CONTROL_CFP;
6183 
6184  /*
6185  * If SLI is in a paused state set CFP bit to resume, and
6186  * skip dump based on pause errors list.
6187  */
6188  sli_validate_pause_errors(sli4, &skip_dump);
6189  if (skip_dump) {
6191  } else {
6192  flags |= SLI4_PHYDEV_CONTROL_DD;
6193  }
6194 
6196  }
6197  } else {
6198  ocs_log_test(sli4->os, "invalid iftype=%d\n", sli_get_if_type(sli4));
6200  }
6201 
6202  return rc;
6203 }
6204 
6205 /**
6206  * @ingroup sli
6207  * @brief Read the SLIPORT_STATUS register to check if a dump is present.
6208  *
6209  * @param sli4 SLI context.
6210  *
6211  * @return
6212  * - 0 if call completed correctly and no dump is present.
6213  * - 1 if call completed and dump is present.
6214  * - -1 if call failed (unsupported chip).
6215  */
6217 {
6218  uint32_t val;
6219  uint32_t ready;
6220 
6223  ocs_log_test(sli4->os, "Function only supported for I/F type 2/6");
6224  return -1;
6225  }
6226 
6227  /* If the chip is not ready, then there cannot be a dump */
6229  if (!ready) {
6230  return 0;
6231  }
6232 
6234  if (UINT32_MAX == val) {
6235  ocs_log_err(sli4->os, "error reading SLIPORT_STATUS\n");
6236  return -1;
6237  } else {
6238  return ((val & SLI4_PORT_STATUS_DIP) ? 1 : 0);
6239  }
6240 }
6241 
6242 /**
6243  * @ingroup sli
6244  * @brief Read the SLIPORT_STATUS register to check if the reset required is set.
6245  *
6246  * @param sli4 SLI context.
6247  *
6248  * @return
6249  * - 0 if call completed correctly and reset is not required.
6250  * - 1 if call completed and reset is required.
6251  * - -1 if call failed.
6252  */
6254 {
6255  uint32_t val;
6256 
6258  ocs_log_test(sli4->os, "reset required N/A for iftype 0\n");
6259  return 0;
6260  }
6261 
6263  if (UINT32_MAX == val) {
6264  ocs_log_err(sli4->os, "error reading SLIPORT_STATUS\n");
6265  return -1;
6266  } else {
6267  return ((val & SLI4_PORT_STATUS_RN) ? 1 : 0);
6268  }
6269 }
6270 
6271 /**
6272  * @ingroup sli
6273  * @brief Read the SLIPORT_SEMAPHORE and SLIPORT_STATUS registers to check if
6274  * the port status indicates that a FW error has occurred.
6275  *
6276  * @param sli4 SLI context.
6277  *
6278  * @return
6279  * - 0 if call completed correctly and no FW error occurred.
6280  * - > 0 which indicates that a FW error has occurred.
6281  * - -1 if call failed.
6282  */
6284 {
6285  uint32_t sliport_semaphore;
6286  int32_t rc = 0;
6287 
6288  sliport_semaphore = sli_reg_read(sli4, SLI4_REG_SLIPORT_SEMAPHORE);
6289  if (UINT32_MAX == sliport_semaphore) {
6290  ocs_log_err(sli4->os, "error reading SLIPORT_SEMAPHORE register\n");
6291  return -1;
6292  }
6293  rc = (SLI4_PORT_SEMAPHORE_IN_ERR(sliport_semaphore) ? 1 : 0);
6294 
6295  if (rc == 0) {
6296  if (SLI4_IF_TYPE_BE3_SKH_PF == sli4->if_type ||
6297  (SLI4_IF_TYPE_BE3_SKH_VF == sli4->if_type)) {
6298  uint32_t uerr_mask_lo, uerr_mask_hi;
6299  uint32_t uerr_status_lo, uerr_status_hi;
6300 
6301  uerr_mask_lo = sli_reg_read(sli4, SLI4_REG_UERR_MASK_LO);
6302  uerr_mask_hi = sli_reg_read(sli4, SLI4_REG_UERR_MASK_HI);
6303  uerr_status_lo = sli_reg_read(sli4, SLI4_REG_UERR_STATUS_LO);
6304  uerr_status_hi = sli_reg_read(sli4, SLI4_REG_UERR_STATUS_HI);
6305  if ((uerr_mask_lo & uerr_status_lo) != 0 ||
6306  (uerr_mask_hi & uerr_status_hi) != 0) {
6307  rc = 1;
6308  }
6309  } else if ((SLI4_IF_TYPE_LANCER_FC_ETH == sli4->if_type) ||
6310  (SLI4_IF_TYPE_LANCER_G7 == sli4->if_type)) {
6311  uint32_t sliport_status;
6312 
6313  sliport_status = sli_reg_read(sli4, SLI4_REG_SLIPORT_STATUS);
6314  rc = (SLI4_PORT_STATUS_ERROR(sliport_status) ? 1 : 0);
6315  }
6316  }
6317  return rc;
6318 }
6319 
6320 /**
6321  * @ingroup sli
6322  * @brief Determine if the chip FW is in a ready state
6323  *
6324  * @param sli4 SLI context.
6325  *
6326  * @return
6327  * - 0 if call completed correctly and FW is not ready.
6328  * - 1 if call completed correctly and FW is ready.
6329  * - -1 if call failed.
6330  */
6331 int32_t
6333 {
6334  uint32_t val;
6335  int32_t rc = -1;
6336 
6337  /*
6338  * Is firmware ready for operation? Check needed depends on IF_TYPE
6339  */
6340  if (SLI4_IF_TYPE_BE3_SKH_PF == sli4->if_type ||
6341  SLI4_IF_TYPE_BE3_SKH_VF == sli4->if_type) {
6344  SLI4_PORT_SEMAPHORE_PORT(val)) &&
6345  (!SLI4_PORT_SEMAPHORE_IN_ERR(val)) ? 1 : 0);
6346  } else if ((SLI4_IF_TYPE_LANCER_FC_ETH == sli4->if_type) ||
6347  (SLI4_IF_TYPE_LANCER_G7 == sli4->if_type)) {
6349  rc = (SLI4_PORT_STATUS_READY(val) ? 1 : 0);
6350  }
6351  return rc;
6352 }
6353 
6354 /**
6355  * @ingroup sli
6356  * @brief Determine if the link can be configured
6357  *
6358  * @param sli4 SLI context.
6359  *
6360  * @return
6361  * - 0 if link is not configurable.
6362  * - 1 if link is configurable.
6363  */
6365 {
6366  int32_t rc = 0;
6367  /*
6368  * Link config works on: Skyhawk and Lancer
6369  * Link config does not work on: LancerG6
6370  */
6371 
6372  switch (sli_get_asic_type(sli)) {
6374  case SLI4_ASIC_TYPE_LANCER:
6376  rc = 1;
6377  break;
6380  case SLI4_ASIC_TYPE_BE3:
6381  default:
6382  rc = 0;
6383  break;
6384  }
6385 
6386  return rc;
6387 
6388 }
6389 
6390 int32_t sli_is_paused(sli4_t *sli4)
6391 {
6392  int32_t rc = FALSE;
6393 
6395  rc = TRUE;
6396 
6397  return rc;
6398 }
6399 
6400 void sli_validate_pause_errors(sli4_t *sli4, uint32_t *skip_dump)
6401 {
6402  int32_t i;
6403  uint32_t err1 = sli_reg_read(sli4, SLI4_REG_SLIPORT_ERROR1);
6404  uint32_t err2 = sli_reg_read(sli4, SLI4_REG_SLIPORT_ERROR2);
6405 
6406  ocs_log_debug(sli4->os, "error1: 0x%x\n", err1);
6407  ocs_log_debug(sli4->os, "error2: 0x%x\n", err2);
6408 
6409  for (i = 0; i < SLI4_PAUSE_ERRX_PAIR_CNT; i++) {
6410  if ((err1 == sli4->pause_errx_pair[i].err1) &&
6411  ((0xFFFFFFFF == sli4->pause_errx_pair[i].err2) ||
6412  (err2 == sli4->pause_errx_pair[i].err2))) {
6413  *skip_dump = TRUE;
6414  break;
6415  }
6416  }
6417 
6418  if (*skip_dump) {
6419  ocs_log_crit(sli4->os, "Skipping diagnostic dump for (error1, error2) = (%#x, %#x)\n", err1, err2);
6420  }
6421 }
uint32_t r_ctl_mask
Definition: sli4.h:1052
uint32_t sgl_page_sizes
Definition: sli4.h:3674
uint32_t preferred_d_id
Definition: sli4.h:891
int32_t sli_cmd_fcoe_wq_create_v1(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *qmem, uint16_t cq_id, uint16_t ignored)
Write an FCOE_WQ_CREATE_V1 command.
Definition: sli4_fc.c:131
sli4_mbox_command_header_t hdr
Definition: sli4.h:980
uint32_t chain_sge_initial_value_hi
Definition: sli4.h:3556
READ_STATUS - read tx/rx status of a particular port.
Definition: sli4.h:1278
uint32_t r_ctl_match
Definition: sli4.h:1052
Mailbox Completion Queue Entry.
Definition: sli4.h:3324
int32_t(* link)(void *, void *)
Definition: sli4.h:3687
uint32_t uint8_t wwpn[8]
Definition: sli4.h:1181
uint32_t vfi
Definition: sli4.h:1186
int32_t sli_cmd_read_link_stats(sli4_t *sli4, void *buf, size_t size, uint8_t req_ext_counters, uint8_t clear_overflow_flags, uint8_t clear_all_counters)
Write a READ_LINK_STAT command to the provided buffer.
Definition: sli4.c:679
uint32_t tow
Definition: sli4.h:3654
#define SLI4_OPC_COMMON_GET_ACTIVE_PROFILE
Definition: sli4.h:1640
int32_t sli_cmd_down_link(sli4_t *sli4, void *buf, size_t size)
Write a DOWN_LINK command to the provided buffer.
Definition: sli4.c:577
ocs_os_handle_t os
Definition: sli4.h:3602
#define SLI4_FAMILY_CHECK_ASIC_TYPE
Definition: sli4.h:111
char ipl_name[16]
Definition: sli4.h:3630
COMMON_DELETE_OBJECT.
Definition: sli4.h:2659
uint32_t index
Definition: sli4.h:1415
uint32_t uint32_t sge_supported_length
Definition: sli4.h:3654
#define FC_LINK_SPEED_2G
Definition: sli4.h:705
uint32_t ocs_instance(void *os)
Return instance index of an opaque ocs structure.
int32_t sli_cmd_read_status(sli4_t *sli4, void *buf, size_t size, uint8_t clear_counters)
Write a READ_STATUS command to the provided buffer.
Definition: sli4.c:707
int32_t sli_cmd_common_nop(sli4_t *sli4, void *buf, size_t size, uint64_t context)
Write a COMMON_NOP command.
Definition: sli4.c:2628
uint32_t physical_port
Definition: sli4.h:3611
#define SLI4_MBOX_COMMAND_UNREG_VPI
Definition: sli4.h:454
uint32_t uint32_t wq_db_offset
Definition: sli4.h:1851
union sli4_cmd_sli_config_t::@36 payload
#define SLI4_ACQE_EVENT_CODE_FC_LINK_EVENT
Definition: sli4.h:3385
sli4_port_type_e port_type
Definition: sli4.h:3603
int32_t sli_cmd_write_nvparms(sli4_t *sli4, void *buf, size_t size, uint8_t *wwpn, uint8_t *wwnn, uint8_t hard_alpa, uint32_t preferred_d_id)
Write a WRITE_NVPARMS command to the provided buffer.
Definition: sli4.c:1007
uint32_t ae
Definition: sli4.h:3330
#define SLI4_OPC_COMMON_GET_RESOURCE_EXTENT_INFO
Definition: sli4.h:1621
uint32_t type_mask
Definition: sli4.h:1052
#define SLI4_MBOX_COMMAND_REG_VPI
Definition: sli4.h:448
UNREG_RPI - unregister one or more RPI.
Definition: sli4.h:1412
uint32_t bbscn_def
Definition: sli4.h:827
#define SLI4_UNREG_RPI_II_RPI
Definition: sli4.h:1426
uint32_t rq_selection_policy_1
Definition: sli4.h:1095
#define OCS_TOW_FEATURE_TFB
Definition: ocs_hal.h:149
char bios_version_string[32]
Definition: sli4.h:3635
#define SLI4_PCI_REV_ID_SHIFT
Definition: sli4.h:86
void * fip_arg
Definition: sli4.h:3690
#define SLI4_IO_WQ_DOORBELL_REG
WQ_DOORBELL - WQ Doorbell Register.
Definition: sli4.h:338
uint32_t con
Definition: sli4.h:3330
#define SLI4_INTF_VALID
Definition: sli4.h:104
uint32_t pmd_count
Definition: sli4.h:1256
union sli4_bde_t::@27 u
Generic Common Create EQ/CQ/MQ/WQ/RQ Queue completion.
Definition: sli4.h:1831
static int32_t sli_cmd_fw_initialize(sli4_t *, void *, size_t)
Write a FW_INITIALIZE command to the provided buffer.
Definition: sli4.c:749
uint32_t iaab
Definition: sli4.h:1199
int32_t sli_fc_process_sli_port_event(sli4_t *sli4, void *acqe)
Process an asynchronous sli port event.
Definition: sli4_fc.c:2295
uint32_t length
Definition: sli4.h:3701
uint16_t count_mask[SLI_QTYPE_MAX]
Definition: sli4.h:3618
int32_t sli_cmd_common_read_transceiver_data(sli4_t *sli4, void *buf, size_t size, uint32_t page_num, ocs_dma_t *dma)
Write a COMMON_READ_TRANSCEIVER_DATA command.
Definition: sli4.c:629
#define SLI4_PHSDEV_CONTROL_REG_236
Definition: sli4.h:404
REG_RPI - register a Remote Port Indicator.
Definition: sli4.h:1125
uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t cqe_count_mask
Definition: sli4.h:2204
#define FC_LINK_SPEED_8G
Definition: sli4.h:711
uint32_t uint32_t scsi_max_data_len
Definition: sli4.h:1509
#define SLI4_ACQE_EVENT_CODE_LINK_STATE
Definition: sli4.h:3380
sli4_qtype_e
Definition: sli4.h:3423
uint32_t fcfi_count
Definition: sli4.h:843
static uint32_t sli_eq_doorbell(uint16_t n_popped, uint16_t id, uint8_t arm)
Definition: sli4.h:214
uint16_t e_d_tov
Definition: sli4.h:3614
int32_t sli_fw_error_status(sli4_t *sli4)
Read the SLIPORT_SEMAPHORE and SLIPORT_STATUS registers to check if the port status indicates that a ...
Definition: sli4.c:6283
uint32_t uint32_t rq_selection_policy_2
Definition: sli4.h:1095
uint32_t cq_create_version
Definition: sli4.h:3654
int32_t sli_queue_poke(sli4_t *sli4, sli4_queue_t *q, uint32_t index, uint8_t *entry)
Definition: sli4.c:5801
uint32_t uint32_t timeout
Definition: sli4.h:1668
uint16_t link_module_type
Definition: sli4.h:3621
sli4_mbox_command_header_t hdr
Definition: sli4.h:883
#define SLI4_PCI_SOFT_RESET_MASK
Definition: sli4.h:92
#define SLI4_MIN_LOOP_MAP_BYTES
Definition: sli4.h:1019
#define SLI4_MBOX_COMMAND_REG_FCFI_MRQ
Definition: sli4.h:444
#define SLI4_IF6_EQ_DOORBELL_REG
Definition: sli4.h:170
#define SLI4_QUEUE_RQ_BATCH
Definition: sli4.h:3502
uint8_t wwpn[8]
Definition: sli4.h:889
uint32_t family
Definition: sli4.c:75
uint32_t vlan_tag
Definition: sli4.h:1057
uint32_t second_fw_id
Definition: sli4.h:922
int32_t sli_cmd_common_set_dump_location(sli4_t *sli4, void *buf, size_t size, uint8_t query, uint8_t is_buffer_list, ocs_dma_t *buffer, uint8_t fdb)
Write a COMMON_SET_DUMP_LOCATION command.
Definition: sli4.c:3031
uint32_t index
Definition: sli4.h:1463
#define SLI4_OPC_COMMON_DESTROY_EQ
Definition: sli4.h:1616
uint32_t npiv
Definition: sli4.h:1199
#define SLI4_OPC_LOWLEVEL_GET_ITCM_PARITY_STATS
Definition: sli4.h:1605
uint16_t size
Definition: sli4.h:3453
sli4_mbox_command_header_t hdr
Definition: sli4.h:864
#define SLI4_PHYDEV_CONTROL_CFP
Definition: sli4.h:412
#define SLI4_READ_SPARM64_VPI_SPECIAL
Definition: sli4.h:957
sli4_mbox_command_header_t hdr
Definition: sli4.h:902
uint32_t vfi_count
Definition: sli4.h:841
INIT_VFI - initialize the VFI resource.
Definition: sli4.h:733
uint32_t uint32_t wki_selection
Definition: sli4.h:634
int32_t sli_cq_parse(sli4_t *sli4, sli4_queue_t *cq, uint8_t *cqe, sli4_qentry_e *etype, uint16_t *q_id)
Parse a CQ entry to retrieve the event type and the associated queue.
Definition: sli4.c:6046
#define SLI4_SLIPORT_CONTROL_BIG_ENDIAN
Definition: sli4.h:179
uint32_t sli_family
Definition: sli4.h:3606
uint32_t pool0_xri_cnt
Definition: sli4.h:1554
int32_t sli_dump_is_ready(sli4_t *sli4)
Read the SLIPORT_STATUS register to to check if a dump is present.
Definition: sli4.c:6142
#define SLI4_FW_READY_TIMEOUT_MSEC
Definition: sli4.h:49
uint16_t sgl_index_field_offset
Definition: sli4.h:3552
#define OCS_DEBUG_ENABLE_MQ_DUMP
Definition: ocs_debug.h:168
#define SLI4_UNREG_RPI_II_FCFI
Definition: sli4.h:1429
uint32_t perfh
Definition: sli4.h:1199
uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t rq_db_window
Definition: sli4.h:2204
uint32_t err2
Definition: sli4.h:3706
COMMON_CREATE_MQ_EXT.
Definition: sli4.h:1969
#define SLI4_PAUSE_ERRX_PAIR_CNT
Definition: sli4.h:3498
uint32_t max_qentries[SLI_QTYPE_MAX]
Definition: sli4.h:3617
struct sli4_features_t::@35 flag
#define SLI4_MBOX_COMMAND_UNREG_VFI
Definition: sli4.h:453
uint32_t extended_status
Definition: sli4.h:3326
#define SLI4_IF6_RQ_DOORBELL_REG
Definition: sli4.h:328
#define SLI4_FCOE_RQE_SIZE
Definition: sli4_fc.h:277
#define FC_LINK_SPEED_32G
Definition: sli4.h:722
uint32_t uint32_t additional_status
Definition: sli4.h:1685
#define SLI4_UERR_MASK_HIGH_REG
Definition: sli4.h:201
uint32_t suppress_rsp_not_supported
Definition: sli4.h:3654
void sli_validate_pause_errors(sli4_t *sli4, uint32_t *skip_dump)
Definition: sli4.c:6400
static int32_t sli_bmbx_write(sli4_t *sli4)
Write bootstrap mailbox.
Definition: sli4.c:377
uint32_t uint32_t scsi_block_size
Definition: sli4.h:1547
#define SLI4_SW_UE_CSR2
Definition: sli4.h:207
#define SLI4_OPC_COMMON_QUERY_FW_CONFIG
Definition: sli4.h:1623
#define SLI4_PORT_SEMAPHORE_REG_0
SLIPORT_SEMAPHORE - SLI Port Host and Port Status Register.
Definition: sli4.h:363
uint32_t uint32_t uint32_t eqe_count_method
Definition: sli4.h:2204
int32_t sli_cmd_init_link(sli4_t *sli4, void *buf, size_t size, uint32_t speed, uint8_t reset_alpa)
Write an INIT_LINK command to the provided buffer.
Definition: sli4.c:772
int32_t sli_eq_modify_delay(sli4_t *sli4, sli4_queue_t *eq, uint32_t num_eq, uint32_t shift, uint32_t delay_mult)
Modify the delay timer for all the EQs.
Definition: sli4.c:5044
sli4_bde_t bde_64
Definition: sli4.h:944
static bool ocs_power_of_2(size_t len)
uint32_t buffer_length
Definition: sli4.h:469
Event Queue Entry.
Definition: sli4.h:3305
uint32_t uint32_t upd
Definition: sli4.h:1128
sli4_qentry_e
Definition: sli4.h:3436
COMMON_QUERY_FW_CONFIG.
Definition: sli4.h:2333
int32_t sli_cmd_common_set_features(sli4_t *sli4, void *buf, size_t size, uint32_t feature, uint32_t param_len, void *parameter)
Write a COMMON_SET_FEATURES command.
Definition: sli4.c:3202
#define SLI4_READ_CFG_TOPO_FC_DA
Definition: sli4.h:857
#define SLI4_ACQE_EVENT_CODE_GRP_5
Definition: sli4.h:3384
#define SLI4_EQ_CNT_2048
Definition: sli4.h:1943
sli4_sli_config_pmd_t mem
Definition: sli4.h:1266
#define SLI4_READ_CFG_TOPO_FCOE
Definition: sli4.h:855
uint32_t hw_rev[3]
Definition: sli4.h:3631
#define SLI4_MQE_SIZE_16
Definition: sli4.h:1994
int32_t sli_cmd_fcoe_rq_destroy(sli4_t *sli4, void *buf, size_t size, uint16_t rq_id)
Write an FCOE_RQ_DESTROY command.
Definition: sli4_fc.c:504
uint32_t vpd
Definition: sli4.h:904
uint32_t cmp
Definition: sli4.h:3330
uint8_t dual_ulp_capable
Definition: sli4.h:3636
int32_t sli_setup(sli4_t *sli4, ocs_os_handle_t os, sli4_port_type_e port_type)
Set up the SLI context.
Definition: sli4.c:4452
#define SLI4_PHYDEV_CONTROL_DD
Definition: sli4.h:407
static uint32_t sli_iftype6_eq_doorbell(uint16_t n_popped, uint16_t id, uint8_t arm)
Definition: sli4.h:268
#define SLI4_OPC_COMMON_GET_PROFILE_LIST
Definition: sli4.h:1639
#define SLI4_MQ_DOORBELL_REG
MQ_DOORBELL - MQ Doorbell Register.
Definition: sli4.h:316
uint32_t uint32_t mrq_filter_bitmask_2
Definition: sli4.h:1095
#define SLI4_CMD_REG_FCFI_NUM_RQ_CFG
REG_FCFI - activate a FC Forwarder.
Definition: sli4.h:1041
sli4_mbox_command_header_t hdr
Definition: sli4.h:1178
int32_t sli_cmd_config_optimized_write_hp(sli4_t *sli4, void *buf, size_t size, uint32_t max_burst_len, uint32_t xri_cnt, uint32_t block_size, uint32_t tow_feature)
Write an CONFIG_OPTIMIZED_WRITE_HP command to the provided buffer.
Definition: sli4.c:1849
static uint8_t sli_pci_rev_id(uint32_t val)
Retrieve PCI revision ID.
Definition: sli4.c:329
uint32_t sgl_pre_registered
Definition: sli4.h:3654
#define SLI4_MBOX_COMMAND_CONFIG_TOW
Definition: sli4.h:456
sli4_mbox_command_header_t hdr
Definition: sli4.h:1565
UNREG_VFI - unregister one or more VFI.
Definition: sli4.h:1434
COMMON_NOP.
Definition: sli4.h:2149
uint32_t uint32_t uint32_t eq_page_cnt
Definition: sli4.h:2204
#define SLI4_MBOX_COMMAND_DOWN_LINK
Definition: sli4.h:430
static uint8_t sli_intf_sli_family(uint32_t val)
Definition: sli4.c:303
void sli4_cmd_lowlevel_get_itcm_parity_stats(sli4_t *sli4, void *buf, size_t size, bool clear_stats)
Definition: sli4.c:2412
INIT_VPI - initialize the VPI resource.
Definition: sli4.h:757
int32_t sli_queue_write(sli4_t *sli4, sli4_queue_t *q, uint8_t *entry)
Write an entry to the queue object.
Definition: sli4.c:5645
static uint32_t sli_iftype6_cq_doorbell(uint16_t n_popped, uint16_t id, uint8_t arm)
Definition: sli4.h:291
uint32_t rset
Definition: sli4.h:3419
sli4_sgl_chaining_params_t sgl_chaining_params
Definition: sli4.h:3677
#define FW_DUMP_READY_STATUS_DD_PRESENT
Definition: ocs_gendump.h:69
uint32_t posted_limit
Definition: sli4.h:3461
#define SLI_PAGE_SIZE
Definition: sli4.h:43
#define SLI4_MBOX_COMMAND_DUMP
Definition: sli4.h:429
#define SLI4_OPC_COMMON_GET_RECONFIG_LINK_INFO
Definition: sli4.h:1648
sli4_req_hdr_t hdr
Definition: sli4.h:3248
void sli4_cmd_lowlevel_set_watchdog(sli4_t *sli4, void *buf, size_t size, uint16_t timeout)
Write a LOWLEVEL_SET_WATCHDOG command.
Definition: sli4.c:2304
Common Destroy CQ.
Definition: sli4.h:1879
uint32_t hdr_template_req
Definition: sli4.h:3654
static uint8_t sli_intf_sli_revision(uint32_t val)
Retrieve the SLI revision level.
Definition: sli4.c:297
ocs_dma_t data
Definition: sli4.h:3700
uint32_t r_ctl_match
Definition: sli4.h:1081
#define SLI4_FUNCTION_MODE_DUA_MODE
Definition: sli4.h:2340
uint32_t type
Definition: sli4.h:634
#define SLI4_DPP_WQ_DOORBELL(n, x, i)
Definition: sli4.h:355
uint32_t vv
Definition: sli4.h:1057
uint8_t wwpn[8]
Definition: sli4.h:3626
static uint32_t sli_get_tow_capable(sli4_t *sli4)
Definition: sli4.h:3864
uint32_t local_n_port_id
Definition: sli4.h:1181
#define SLI4_OPC_COMMON_GET_CNTL_ADDL_ATTRIBUTES
Definition: sli4.h:1629
#define SLI4_OPC_COMMON_SET_RECONFIG_LINK_ID
Definition: sli4.h:1649
#define SLI4_MBOX_COMMAND_READ_SPARM64
Definition: sli4.h:441
struct sli4_bde_t::@27::@28 data
int32_t sli_queue_free(sli4_t *sli4, sli4_queue_t *q, uint32_t destroy_queues, uint32_t free_memory)
Free a queue.
Definition: sli4.c:5335
#define SLI4_OPC_COMMON_SET_ACTIVE_PROFILE
Definition: sli4.h:1641
uint32_t type_match
Definition: sli4.h:1081
uint32_t uint32_t etow
Definition: sli4.h:1128
#define SLI4_BMBX_TIMEOUT_MSEC
Definition: sli4.h:48
char port_name[2]
Definition: sli4.h:3633
uint32_t uint32_t hlm
Definition: sli4.h:1128
uint32_t uint32_t scsi_max_data_len
Definition: sli4.h:1535
uint32_t index
Definition: sli4.h:3452
#define SLI4_INTF_SLI_FAMILY_SHIFT
Definition: sli4.h:107
int32_t sli_fw_ready(sli4_t *sli4)
Determine if the chip FW is in a ready state.
Definition: sli4.c:6332
sli4_bde_t host_buffer_descriptor[0]
Definition: sli4.h:2609
sli4_features_t response
Definition: sli4.h:1234
int32_t sli_queue_reset(sli4_t *sli4, sli4_queue_t *q)
Definition: sli4.c:5429
sli4_resource_e
Definition: sli4.h:3564
static uint8_t sli_asic_gen(uint32_t val)
retrieve SLI ASIC generation
Definition: sli4.c:342
static uint32_t sli_convert_mask_to_count(uint32_t method, uint32_t mask)
Definition: sli4.h:4046
uint16_t count_method[SLI_QTYPE_MAX]
Definition: sli4.h:3619
#define SLI4_MBOX_COMMAND_INIT_VPI
Definition: sli4.h:433
#define SLI4_OPC_COMMON_GET_PROFILE_CONFIG
Definition: sli4.h:1637
DMTF_EXEC_CLP_CMD.
Definition: sli4.h:2887
sli4_asic_entry_t sli4_asic_table[]
Definition: sli4.c:80
#define SLI4_INTF_IF_TYPE_MASK
Definition: sli4.h:106
int32_t sli_resource_alloc(sli4_t *sli4, sli4_resource_e rtype, uint32_t *rid, uint32_t *index)
Allocate SLI Port resources.
Definition: sli4.c:5851
#define SLI4_BMBX_WRITE_HI(r)
Definition: sli4.h:145
uint32_t ashdr
Definition: sli4.h:1199
READ_SPARM64 - read the Port service parameters.
Definition: sli4.h:939
int32_t sli_cmd_unreg_rpi(sli4_t *sli4, void *buf, size_t size, uint16_t indicator, sli4_resource_e which, uint32_t fc_id)
Write an UNREG_RPI command to the provided buffer.
Definition: sli4.c:1601
int32_t sli_cmd_post_xri(sli4_t *sli4, void *buf, size_t size, uint16_t xri_base, uint16_t xri_count)
Write a POST_XRI command to the provided buffer.
Definition: sli4.c:909
int32_t sli_queue_is_empty(sli4_t *sli4, sli4_queue_t *q)
Check if the given queue is empty.
Definition: sli4.c:5463
sli4_mbox_command_header_t hdr
Definition: sli4.h:791
int32_t sli_cmd_fc_set_trunk_mode(sli4_t *sli4, void *buf, size_t size, uint32_t trunk_mode)
Write a SLI4_OPC_FC_SET_TRUNK_MODE command.
Definition: sli4.c:3165
static int32_t sli_query_fw_config(sli4_t *sli4)
Issue a FW_CONFIG mailbox command and store the results.
Definition: sli4.c:3999
#define SLI4_SLIPORT_ERROR2
SLI4_SLIPORT_ERROR2 - SLI Port Error Register.
Definition: sli4.h:193
#define SLI4_OPC_COMMON_DESTROY_MQ
Definition: sli4.h:1618
#define SLI4_MQE_SIZE_64
Definition: sli4.h:1996
static int32_t sli_cmd_common_modify_eq_delay(sli4_t *sli4, void *buf, size_t size, sli4_queue_t *q, int num_q, uint32_t shift, uint32_t delay_mult)
Write a COMMON_MODIFY_EQ_DELAY command.
Definition: sli4.c:2136
uint32_t uint32_t read_offset
Definition: sli4.h:2604
uint32_t uint32_t uint32_t rq_id_4
Definition: sli4.h:1095
void sli_reg_write(sli4_t *sli, sli4_regname_e reg, uint32_t val)
Write the value to the given SLI register.
Definition: sli4.c:263
uint32_t rxseq
Definition: sli4.h:1199
#define SLI_USER_MQ_COUNT
Definition: sli4.h:3432
#define SLI4_PCI_SOFT_RESET_CSR
Definition: sli4.h:91
int32_t sli_fc_cqe_parse(sli4_t *sli4, sli4_queue_t *cq, uint8_t *cqe, sli4_qentry_e *etype, uint16_t *r_id)
Parse an FC/FCoE work queue CQ entry.
Definition: sli4_fc.c:2551
uint32_t sli4_features_t command
Definition: sli4.h:1228
uint32_t mq_create_version
Definition: sli4.h:3654
#define SLI4_MBOX_COMMAND_RELEASE_XRI
Definition: sli4.h:435
#define SLI4_IF_TYPE_BE3_SKH_VF
Definition: sli4.h:114
uint32_t e_d_tov
Definition: sli4.h:1163
int32_t sli_cmd_reg_fcfi(sli4_t *sli4, void *buf, size_t size, uint16_t index, sli4_cmd_rq_cfg_t rq_cfg[SLI4_CMD_REG_FCFI_NUM_RQ_CFG], uint16_t vlan_id)
Write a REG_FCFI command to the provided buffer.
Definition: sli4.c:1148
#define FW_DUMP_READY_STATUS_SKIP_DUMP
Definition: ocs_gendump.h:71
sli4_req_hdr_t hdr
Definition: sli4.h:1880
uint32_t uint32_t fcfi
Definition: sli4.h:1154
static int32_t sli_get_config(sli4_t *sli4)
Definition: sli4.c:4056
#define FW_DUMP_READY_STATUS_FAILED
Definition: ocs_gendump.h:72
int32_t sli_resource_reset(sli4_t *sli4, sli4_resource_e rtype)
Definition: sli4.c:5960
int32_t sli_cqe_mq(void *buf)
Check the mailbox/queue completion entry.
Definition: sli4.c:3551
uint32_t type_match
Definition: sli4.h:1052
sli4_req_hdr_t hdr
Definition: sli4.h:1955
Common Destroy MQ.
Definition: sli4.h:2032
uint16_t r_a_tov
Definition: sli4.h:3615
uint8_t bbscn_max
Definition: sli4.h:3680
#define SLI4_IF6_MQ_DOORBELL_REG
Definition: sli4.h:317
sli4_mbox_command_header_t hdr
Definition: sli4.h:758
#define SLI4_SLIPORT_ERROR1
SLI4_SLIPORT_ERROR1 - SLI Port Error Register.
Definition: sli4.h:187
static int32_t sli_request_features(sli4_t *sli4, sli4_features_t *features, uint8_t query)
Definition: sli4.c:3926
#define SLI4_WQE_BYTES
Definition: sli4_fc.h:433
uint32_t resource_id
Definition: sli4.h:3307
sli4_mbox_command_header_t hdr
Definition: sli4.h:734
static int32_t sli_cmd_common_get_cntl_attributes(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma)
Definition: sli4.c:2435
int32_t sli_cmd_config_optimized_write(sli4_t *sli4, void *buf, size_t size, uint32_t max_burst_len, uint32_t xri_cnt, uint32_t tow_feature)
Write an CONFIG_OPTIMIZED_WRITE command to the provided buffer.
Definition: sli4.c:1810
uint32_t uint32_t first_hw_revision
Definition: sli4.h:904
uint32_t topology
Definition: sli4.h:818
#define SLI4_PORT_MIGRATION_BIT
Definition: sli4.h:152
int32_t sli_queue_read(sli4_t *sli4, sli4_queue_t *q, uint8_t *entry)
Read an entry from the queue object.
Definition: sli4.c:5720
uint32_t uint32_t physical_address_low
Definition: sli4.h:925
#define SLI4_INTF_IF_TYPE_SHIFT
Definition: sli4.h:105
uint32_t returned_vpd_length
Definition: sli4.h:929
#define SLI4_READ_CFG_TOPO_FC
Definition: sli4.h:856
static int32_t sli_cmd_request_features(sli4_t *sli4, void *buf, size_t size, sli4_features_t mask, uint8_t query)
Write a REQUEST_FEATURES command to the provided buffer.
Definition: sli4.c:1456
uint32_t uint32_t payload_length
Definition: sli4.h:1256
struct sli4_req_lowlevel_set_diag_log_options_t::@43 buffer_desc[0]
int32_t sli_teardown(sli4_t *sli4)
Tear down a SLI context.
Definition: sli4.c:4743
#define SLI4_MBOX_COMMAND_SLI_CONFIG
Definition: sli4.h:450
#define SLI4_UNREG_VPI_II_VPI
Definition: sli4.h:1471
#define SLI4_OPC_COMMON_FUNCTION_RESET
Definition: sli4.h:1610
#define SLI4_MQE_BYTES
Definition: sli4.h:1999
uint32_t context[2]
Definition: sli4.h:2152
sli4_req_hdr_t hdr
Definition: sli4.h:2033
int32_t sli_cmd_reg_fcfi_mrq(sli4_t *sli4, void *buf, size_t size, uint8_t mode, uint16_t fcf_index, uint16_t vlan_id, sli4_cmd_rq_cfg_t rq_cfg[SLI4_CMD_REG_FCFI_NUM_RQ_CFG])
Write REG_FCFI_MRQ to provided command buffer.
Definition: sli4.c:1193
#define SLI4_PCI_REV_ID_MASK
Definition: sli4.h:87
int32_t sli_cmd_common_write_object(sli4_t *sli4, void *buf, size_t size, uint16_t noc, uint16_t eof, uint32_t desired_write_length, uint32_t offset, char *object_name, ocs_dma_t *dma)
Write a COMMON_WRITE_OBJECT command.
Definition: sli4.c:2831
uint32_t enx
Definition: sli4.h:773
uint32_t length
Definition: sli4.h:1249
sli4_asic_type_e type
Definition: sli4.c:76
uint32_t local_n_port_id
Definition: sli4.h:1165
#define SLI4_CQ_CNT_LARGE
Definition: sli4.h:1822
#define OCS_DEBUG_ALWAYS
Definition: ocs_debug.h:167
#define SLI4_ULP_MODE_FCOE_TGT
Definition: sli4.h:2343
#define SLI4_MQ_DOORBELL(n, i)
Definition: sli4.h:321
#define SLI4_ASIC_ID_REG
ASIC_ID - SLI ASIC Type and Revision Register.
Definition: sli4.h:123
sli4_asic_type_e
Definition: sli4.h:3580
uint8_t wwnn[8]
Definition: sli4.h:871
READ_NVPARMS - read SLI port configuration parameters.
Definition: sli4.h:863
#define SLI4_WQE_EXT_BYTES
Definition: sli4_fc.h:434
sli4_mbox_command_header_t hdr
Definition: sli4.h:632
#define SLI4_CQ_CNT_512
Definition: sli4.h:1820
#define SLI4_MBOX_COMMAND_REG_VFI
Definition: sli4.h:447
#define SLI4_SLIPORT_CONTROL_FDD
Definition: sli4.h:182
uint32_t sli_rev
Definition: sli4.h:3605
uint8_t wwnn[8]
Definition: sli4.h:890
COMMON_READ_OBJECT.
Definition: sli4.h:2601
uint32_t third_hw_revision
Definition: sli4.h:914
uint32_t vfi
Definition: sli4.h:1154
void sli_calc_max_qentries(sli4_t *sli4)
Calculate max queue entries.
Definition: sli4.c:3959
#define SLI4_ASYNC_EVT_FC_FCOE
Definition: sli4.h:2022
uint32_t type_mask
Definition: sli4.h:1081
#define SLI4_MBOX_COMMAND_WRITE_NVPARMS
Definition: sli4.h:455
uint32_t completion_status
Definition: sli4.h:3326
COMMON_MODIFY_EQ_DELAY.
Definition: sli4.h:1894
static int32_t sli_cmd_common_create_eq(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *qmem, uint16_t ignored1, uint16_t ignored2)
Write a COMMON_CREATE_EQ command.
Definition: sli4.c:2187
#define SLI4_MBOX_COMMAND_READ_STATUS
Definition: sli4.h:437
int32_t sli_link_is_configurable(sli4_t *sli)
Determine if the link can be configured.
Definition: sli4.c:6364
uint16_t ulp
Definition: sli4.h:3457
uint32_t event_type
Definition: sli4.h:3350
Common Destroy EQ.
Definition: sli4.h:1954
uint8_t wwpn[8]
Definition: sli4.h:1161
sli4_mbox_command_header_t hdr
Definition: sli4.h:940
struct sli4_t::@47 config
#define SLI4_OPC_COMMON_SET_DUMP_LOCATION
Definition: sli4.h:1646
#define SLI4_INTF_VALID_MASK
Definition: sli4.h:103
uint32_t val
Definition: sli4.h:3330
uint32_t dpp_reg_set
Definition: sli4.h:1854
uint32_t doorbell_offset
Definition: sli4.h:3458
int32_t sli_resource_free(sli4_t *sli4, sli4_resource_e rtype, uint32_t rid)
Free the SLI Port resources.
Definition: sli4.c:5913
#define SLI4_UNREG_RPI_II_VFI
Definition: sli4.h:1428
#define SLI4_MBOX_COMMAND_READ_NVPARMS
Definition: sli4.h:438
uint32_t opcode
Definition: sli4.h:1668
uint8_t dpp
Definition: sli4.h:3679
static int32_t sli_cmd_common_function_reset(sli4_t *sli4, void *buf, size_t size)
Write a COMMON_FUNCTION_RESET command.
Definition: sli4.c:1886
uint32_t uint32_t uint32_t uint32_t uint32_t cq_page_cnt
Definition: sli4.h:2204
uint8_t object_name[104]
Definition: sli4.h:2637
int32_t sli_cqe_async(sli4_t *sli4, void *buf)
Check the asynchronous event completion entry.
Definition: sli4.c:3586
int32_t sli_cmd_config_auto_xfer_rdy(sli4_t *sli4, void *buf, size_t size, uint32_t max_burst_len)
Write an CONFIG_AUTO_XFER_RDY command to the provided buffer. Command to enable AXR in G5...
Definition: sli4.c:1748
uint32_t xri_count
Definition: sli4.h:773
sli4_regname_e
Register name enums.
Definition: sli4.h:3396
uint32_t auto_reg
Definition: sli4.h:3654
uint32_t rpi
Definition: sli4.h:1128
Definition: sli4.h:3601
size_t wqe_size
Definition: sli4.h:3678
COMMON_SET_DUMP_LOCATION.
Definition: sli4.h:2690
static uint8_t sli_queue_entry_is_valid(sli4_queue_t *, uint8_t *, uint8_t)
Check if the current queue entry is valid.
Definition: sli4.c:5666
sli4_mbox_command_header_t hdr
Definition: sli4.h:1533
int32_t sli_cmd_read_sparm64(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma, uint16_t vpi)
Write a READ_SPARM64 command to the provided buffer.
Definition: sli4.c:1067
#define SLI4_BMBX_SIZE
Definition: sli4.h:150
sli4_req_hdr_t hdr
Definition: sli4.h:2602
ocs_lock_t lock
Definition: sli4.h:3451
int32_t sli_cmd_common_set_reconfig_link_id(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma, uint32_t fd, uint32_t active_link_config_id)
Write a COMMON_SET_RECONFIG_LINK_ID command.
Definition: sli4.c:3505
static int32_t sli_common_function_reset(sli4_t *sli4)
Issue a COMMON_FUNCTION_RESET command.
Definition: sli4.c:3667
#define SLI4_OPC_COMMON_MODIFY_EQ_DELAY
Definition: sli4.h:1614
uint8_t bbscn_def
Definition: sli4.h:3680
uint32_t vpi
Definition: sli4.h:1186
#define SLI4_BMBX_REG
BMBX - Bootstrap Mailbox Register.
Definition: sli4.h:140
int32_t sli_port_migration(sli4_t *sli4)
Definition: sli4.c:4701
Definition: sli4.c:73
sli4_features_t features
Definition: sli4.h:3653
#define SLI4_MBOX_COMMAND_REG_FCFI
Definition: sli4.h:443
uint32_t uint32_t lmt
Definition: sli4.h:827
uint32_t uint32_t min_rq_buffer_size
Definition: sli4.h:2292
uint32_t upd
Definition: sli4.h:1181
uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t wqe_sizes
Definition: sli4.h:2204
uint32_t host_buffer_descriptor_count
Definition: sli4.h:2638
#define SLI4_SUBSYSTEM_COMMON
Definition: sli4.h:1598
uint32_t event_code
Definition: sli4.h:3350
#define SLI4_INTF_SLI_FAMILY_MASK
Definition: sli4.h:108
#define SLI4_CQ_CNT_256
Definition: sli4.h:1819
sli4_mbox_command_header_t hdr
Definition: sli4.h:1435
#define SLI4_RQ_DOORBELL_REG
RQ_DOORBELL - RQ Doorbell Register.
Definition: sli4.h:327
#define SLI4_MBOX_COMMAND_INIT_VFI
Definition: sli4.h:432
void ocs_dump32(uint32_t mask, ocs_os_handle_t os, const char *label, void *buf, uint32_t buf_length)
Dump 32 bit hex/ascii data.
Definition: ocs_dump32.c:72
int32_t sli_queue_eq_arm(sli4_t *sli4, sli4_queue_t *q, uint8_t arm)
Arm an EQ.
Definition: sli4.c:5492
uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t mq_page_cnt
Definition: sli4.h:2204
uint32_t uint32_t uint32_t uint32_t eqe_count_mask
Definition: sli4.h:2204
uint32_t mrqp
Definition: sli4.h:1199
AUTO_XFER_RDY - Configure the auto-generate XFER-RDY feature.
Definition: sli4.h:1479
int32_t sli_raise_ue(sli4_t *sli4, uint8_t dump)
Cause chip to enter an unrecoverable error state.
Definition: sli4.c:6092
sli4_req_hdr_t hdr
Definition: sli4.h:2888
Buffer Descriptor Entry (BDE)
Definition: sli4.h:467
#define SLI4_MBOX_COMMAND_REQUEST_FEATURES
Definition: sli4.h:449
uint32_t xib_capable
Definition: sli4.h:3654
#define SLI4_OPC_COMMON_WRITE_OBJECT
Definition: sli4.h:1643
uint32_t rxri
Definition: sli4.h:1199
COMMON_FUNCTION_RESET.
Definition: sli4.h:1705
char second_fw_name[16]
Definition: sli4.h:923
uint32_t t10_dif_inline_capable
Definition: sli4.h:3654
uint32_t address_low
Definition: sli4.h:1247
#define SLI4_ASIC_GEN_SHIFT
Definition: sli4.h:128
#define SLI4_OPC_COMMON_NOP
Definition: sli4.h:1620
uint32_t vfi
Definition: sli4.h:736
#define SLI4_MBOX_COMMAND_UNREG_RPI
Definition: sli4.h:452
#define SLI4_OPC_DMTF_EXEC_CLP_CMD
Definition: sli4.h:1661
uint32_t xri_base
Definition: sli4.h:773
uint32_t cq_count
Definition: sli4.h:847
#define SLI4_MAX_IF_TYPES
Definition: sli4.h:118
static void sli_set_wq_id_association(void *entry, uint16_t q_id)
Format a WQE with WQ_ID Association performance hint.
Definition: sli4.h:1379
sli4_mbox_command_header_t hdr
Definition: sli4.h:1490
COMMON_GET_PORT_NAME.
Definition: sli4.h:2391
uint32_t rq_max_buf_size
Definition: sli4.h:3624
COMMON_SET_PROFILE_CONFIG.
Definition: sli4.h:3029
void * link_arg
Definition: sli4.h:3688
static int32_t sli_cmd_common_get_cntl_addl_attributes(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma)
Write a COMMON_GET_CNTL_ADDL_ATTRIBUTES command.
Definition: sli4.c:2474
int32_t sli_get_queue_entry_size(sli4_t *sli4, uint32_t qtype)
Get queue entry size.
Definition: sli4.c:4993
int32_t sli_cmd_reg_vpi(sli4_t *sli4, void *buf, size_t size, ocs_sli_port_t *sport, uint8_t update)
Write a REG_VPI command to the provided buffer.
Definition: sli4.c:1423
sli4_req_hdr_t hdr
Definition: sli4.h:1914
#define SLI4_PHYDEV_CONTROL_FRST
Definition: sli4.h:406
COMMON_GET_SLI4_PARAMETERS.
Definition: sli4.h:2201
static int32_t sli_cmd_common_get_port_name(sli4_t *sli4, void *buf, size_t size)
Write a COMMON_GET_PORT_NAME command to the provided buffer.
Definition: sli4.c:2762
sli4_mbox_command_header_t hdr
Definition: sli4.h:1043
uint32_t dword
Definition: sli4.h:1219
const uint8_t sli4_fw_initialize[]
FW_INITIALIZE - initialize a SLI port.
Definition: sli4.c:63
int32_t sli_eq_parse(sli4_t *sli4, uint8_t *buf, uint16_t *cq_id)
Parse an EQ entry to retrieve the CQ_ID for this event.
Definition: sli4.c:6000
uint32_t vfi
Definition: sli4.h:760
sli4_mbox_command_header_t hdr
Definition: sli4.h:771
uint32_t uint32_t block_size
Definition: sli4.h:1494
uint16_t phase
Definition: sli4.h:3465
#define SLI4_GET_SLI_CONFIG_OFFSET(buf, offset)
SLI_CONFIG - submit a configuration command to Port.
Definition: sli4.h:1244
struct sli4_t::@47::@50 extent[SLI_RSRC_MAX]
Asynchronous Completion Queue Entry.
Definition: sli4.h:3347
uint32_t rq_id_0
Definition: sli4.h:1047
#define SLI4_UNREG_VPI_II_FCFI
Definition: sli4.h:1473
uint8_t type
Definition: sli4.h:3460
#define SLI4_UNREG_RPI_II_VPI
Definition: sli4.h:1427
uint32_t t10_dif_separate_capable
Definition: sli4.h:3654
int32_t sli_cmd_common_get_resource_extent_info(sli4_t *sli4, void *buf, size_t size, uint16_t rtype)
Write a COMMON_GET_RESOURCE_EXTENT_INFO command.
Definition: sli4.c:2663
POST_XRI - post XRI resources to the SLI Port.
Definition: sli4.h:770
#define SLI4_INIT_PORT_DELAY_US
Definition: sli4.c:53
uint32_t first_fw_id
Definition: sli4.h:920
sli4_mbox_command_header_t hdr
Definition: sli4.h:1254
#define SLI4_READ_CFG_TOPO_FC_AL
Definition: sli4.h:858
#define SLI4_EQ_CNT_4096
Definition: sli4.h:1944
static int32_t sli_cmd_common_query_fw_config(sli4_t *sli4, void *buf, size_t size)
Write a COMMON_QUERY_FW_CONFIG command to the provided buffer.
Definition: sli4.c:2726
uint32_t physical_address_high
Definition: sli4.h:928
uint32_t wq_count
Definition: sli4.h:847
sli4_bde_t sparm
Definition: sli4.h:1162
#define SLI4_EQE_BYTES
Definition: sli4.h:1949
uint32_t vpi
Definition: sli4.h:760
COMMON_READ_TRANSCEIVER_DATA.
Definition: sli4.h:2576
uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t mqe_count_mask
Definition: sli4.h:2204
struct sli4_queue_t::@44::@45 flag
uint32_t bbscn_max
Definition: sli4.h:827
uint32_t rq_id_1
Definition: sli4.h:1047
#define SLI4_PORT_STATUS_READY(r)
Definition: sli4.h:398
sli4_mbox_command_header_t hdr
Definition: sli4.h:810
sli4_asic_type_e asic_type
Definition: sli4.h:3609
#define SLI4_SW_UE_REG
Registers for generating software UE (Skyhawk)
Definition: sli4.h:212
uint32_t bbscn
Definition: sli4.h:1165
int32_t sli_cmd_read_nvparms(sli4_t *sli4, void *buf, size_t size)
Write a READ_NVPARMS command to the provided buffer.
Definition: sli4.c:982
uint32_t high_login_mode
Definition: sli4.h:3654
uint32_t uint32_t alt_mrq_filter_bit_mask_2
Definition: sli4.h:1095
int32_t sli_dump_is_present(sli4_t *sli4)
Read the SLIPORT_STATUS register to check if a dump is present.
Definition: sli4.c:6216
const char * SLI_QNAME[]
Definition: sli4.c:104
#define SLI4_SW_UE_CSR1
Registers for generating software UE (BE3)
Definition: sli4.h:206
#define SLI4_TRUNK_MODE_4_LINKS_PER_TRUNK
Definition: sli4.h:3245
#define OCS_DEBUG_ENABLE_CQ_DUMP
Definition: ocs_debug.h:169
struct sli4_t::@48 vpd
static uint8_t sli_intf_valid_check(uint32_t val)
Check if the SLI_INTF register is valid.
Definition: sli4.c:284
uint32_t r_a_tov
Definition: sli4.h:1164
uint16_t rq_min_buf_size
Definition: sli4.h:3623
#define SLI4_OPC_LOWLEVEL_SET_DIAG_LOG_OPTIONS
Definition: sli4.h:1604
#define FW_DUMP_READY_STATUS_FDB_PRESENT
Definition: ocs_gendump.h:70
uint32_t version
Definition: sli4.h:1673
#define SLI4_PORT_STATUS_REG_236
SLIPORT_STATUS - SLI Port Status Register.
Definition: sli4.h:389
uint32_t uint32_t num_mrq_pairs_2
Definition: sli4.h:1095
#define SLI4_UERR_STATUS_HIGH_REG
Definition: sli4.h:199
#define SLI4_COMMON_CREATE_CQ_V2_MAX_PAGES
Definition: sli4.h:1826
sli4_asic_rev_e rev
Definition: sli4.c:77
int32_t sli_cmd_sli_config(sli4_t *sli4, void *buf, size_t size, uint32_t length, ocs_dma_t *dma)
Write a SLI_CONFIG command to the provided buffer.
Definition: sli4.c:1485
uint16_t length
Definition: sli4.h:3454
uint32_t rpi_base
Definition: sli4.h:837
#define SLI4_OPC_COMMON_DESTROY_CQ
Definition: sli4.h:1613
COMMON_GET_PROFILE_CONFIG.
Definition: sli4.h:3009
uint32_t if_type
Definition: sli4.h:3607
uint16_t id
Definition: sli4.h:3456
#define SLI4_PORT_STATUS_SPP
Definition: sli4.h:394
uint32_t uint32_t uint32_t uint32_t uint32_t cqv
Definition: sli4.h:2204
uint32_t perf_hint
Definition: sli4.h:3654
static int32_t sli_queue_doorbell(sli4_t *, sli4_queue_t *)
Write the doorbell register associated with the queue object.
Definition: sli4.c:3843
uint32_t pool0_xri_cnt
Definition: sli4.h:1525
uint32_t e_d_tov
Definition: sli4.h:821
#define SLI4_UNREG_VPI_II_VFI
Definition: sli4.h:1472
REQUEST_FEATURES - request / query SLI features.
Definition: sli4.h:1196
int32_t(* sli4_create_q_fn_t)(sli4_t *, void *, size_t, ocs_dma_t *, uint16_t, uint16_t)
Common Create Queue function prototype.
Definition: sli4.h:4063
int32_t sli_cmd_fcoe_set_loopback_mode(sli4_t *sli4, void *buf, size_t size, int type)
Write a SLI4_OPC_FCOE_SET_LINK_DIAG_LOOPBACK command.
Definition: sli4.c:3126
int32_t sli_cmd_common_get_profile_list(sli4_t *sli4, void *buf, size_t size, uint32_t start_profile_index, ocs_dma_t *dma)
Write a COMMON_COMMON_GET_PROFILE_LIST command.
Definition: sli4.c:3333
AUTO_XFER_RDY - Configure the Target Optimized Write Feature.
Definition: sli4.h:1506
int32_t sli_cmd_common_read_object(sli4_t *sli4, void *buf, size_t size, uint32_t desired_read_length, uint32_t offset, char *object_name, ocs_dma_t *dma)
Write a COMMON_READ_OBJECT command.
Definition: sli4.c:2926
#define SLI4_PORT_SEMAPHORE_REG_236
Definition: sli4.h:365
#define SLI4_MBOX_COMMAND_READ_TOPOLOGY
Definition: sli4.h:442
uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t mqv
Definition: sli4.h:2204
int32_t sli_fc_process_fcoe(sli4_t *sli4, void *acqe)
Process an asynchronous FCoE event entry.
Definition: sli4_fc.c:2880
sli4_bde_t host_buffer_descriptor[0]
Definition: sli4.h:2639
#define SLI4_BMBX_RDY
Definition: sli4.h:143
#define SLI4_INIT_LINK_F_FCAL_ONLY
Definition: sli4.h:692
#define SLI4_BMBX_DELAY_US
Definition: sli4.c:52
struct sli4_cmd_reg_fcfi_mrq_t::@34 rq_cfg_2[4]
WRITE_NVPARMS - write SLI port configuration parameters.
Definition: sli4.h:882
uint32_t subsystem
Definition: sli4.h:1668
#define SLI4_ULP_MODE_FCOE_INI
Definition: sli4.h:2342
#define FC_LINK_SPEED_16G
Definition: sli4.h:719
int32_t sli_queue_arm(sli4_t *sli4, sli4_queue_t *q, uint8_t arm)
Arm a queue.
Definition: sli4.c:5519
uint16_t n_posted
Definition: sli4.h:3455
#define SLI4_OPC_COMMON_CREATE_EQ
Definition: sli4.h:1615
uint32_t r_a_tov
Definition: sli4.h:824
int32_t sli_reset(sli4_t *sli4)
Definition: sli4.c:4611
sli4_callback_e
Definition: sli4.h:3504
int32_t sli_cmd_dmtf_exec_clp_cmd(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *cmd, ocs_dma_t *resp)
Write a DMTF_EXEC_CLP_CMD command.
Definition: sli4.c:2985
static int32_t sli_cmd_common_create_cq(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *qmem, uint16_t eq_id, uint16_t ignored)
Write a COMMON_CREATE_CQ command.
Definition: sli4.c:1924
uint8_t wwpn[8]
Definition: sli4.h:870
uint8_t object_name[104]
Definition: sli4.h:2607
RELEASE_XRI - Release XRI resources from the SLI Port.
Definition: sli4.h:790
uint16_t doorbell_rset
Definition: sli4.h:3459
uint32_t fcpc
Definition: sli4.h:1199
uint32_t uint32_t uint32_t uint32_t uint32_t cqe_count_method
Definition: sli4.h:2204
#define FW_FUNC_DESC_DUMP
Definition: ocs_gendump.h:56
#define SLI4_BMBX_WRITE_LO(r)
Definition: sli4.h:147
#define FC_TOPOLOGY_P2P
Definition: sli4.h:669
uint32_t rq_id_3
Definition: sli4.h:1049
int32_t sli_cq_alloc_set(sli4_t *sli4, sli4_queue_t *qs[], uint32_t num_cqs, uint32_t n_entries, sli4_queue_t *eqs[])
Allocate a c queue set.
Definition: sli4.c:5172
#define SLI4_EQ_CNT_1024
Definition: sli4.h:1942
struct sli4_cmd_reg_fcfi_mrq_t::@33 rq_cfg_1[4]
#define SLI4_PORT_STATUS_FDP_PRESENT(r)
Definition: sli4.h:401
uint32_t max_tow_xris
Definition: sli4.h:3676
COMMON_GET_RESOURCE_EXTENT_INFO.
Definition: sli4.h:2170
uint32_t sgl_pre_registration_required
Definition: sli4.h:3654
#define SLI4_PORT_SEMAPHORE_PORT(r)
Definition: sli4.h:367
static int32_t sli_fw_init(sli4_t *)
Initialize the firmware.
Definition: sli4.c:3728
uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t rqe_count_mask
Definition: sli4.h:2204
uint32_t fdd_present
Definition: sli4.h:3654
COMMON_CREATE_CQ_SET_V0.
Definition: sli4.h:1788
#define SLI4_OPC_COMMON_RUN_BIU_DIAG
Definition: sli4.h:1635
#define SLI4_MQE_SIZE_128
Definition: sli4.h:1997
uint32_t bbcr
Definition: sli4.h:1165
uint32_t uint32_t remote_n_port_id
Definition: sli4.h:1128
sli4_mbox_command_header_t hdr
Definition: sli4.h:1226
uint32_t iaar
Definition: sli4.h:1199
uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t wq_page_cnt
Definition: sli4.h:2204
sli4_bde_t bde_64
Definition: sli4.h:1138
uint32_t fcfi
Definition: sli4.h:742
#define SLI4_OPC_COMMON_SET_FEATURES
Definition: sli4.h:1647
#define SLI4_OPC_COMMON_CREATE_CQ
Definition: sli4.h:1611
#define SLI4_SUBSYSTEM_LOWLEVEL
Definition: sli4.h:1599
COMMON_GET_PROFILE_LIST.
Definition: sli4.h:3070
uint32_t eq_count
Definition: sli4.h:845
int32_t sli_cmd_common_get_profile_config(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma)
Write a COMMON_COMMON_GET_PROFILE_CONFIG command.
Definition: sli4.c:3243
COMMON_SET_LOOPBACK_MODE.
Definition: sli4.h:2717
#define SLI4_OPC_COMMON_READ_OBJECT
Definition: sli4.h:1642
#define SLI4_CQE_BYTES
Definition: sli4.h:1824
uint32_t vpi
Definition: sli4.h:742
sli4_bde_t bde_loop_map
Definition: sli4.h:994
sli4_mbox_command_header_t hdr
Definition: sli4.h:1069
COMMON_GET_ACTIVE_PROFILE.
Definition: sli4.h:3093
#define SLI4_PORT_SEMAPHORE_IN_ERR(r)
Definition: sli4.h:382
#define FW_CHIP_LEVEL_DUMP
Definition: ocs_gendump.h:55
uint32_t vpi_base
Definition: sli4.h:839
UNREG_FCFI - unregister a FCFI.
Definition: sli4.h:1398
#define SLI4_RQ_DOORBELL(n, i)
Definition: sli4.h:332
#define SLI4_UNREG_VFI_II_FCFI
Definition: sli4.h:1447
#define SLI4_SLIPORT_CONTROL_REG
SLIPORT_CONTROL - SLI Port Control Register.
Definition: sli4.h:176
uint32_t enable_bbcr
Definition: sli4.h:3654
uint32_t address_high
Definition: sli4.h:1248
uint32_t err1
Definition: sli4.h:3705
static uint32_t sli_page_count(size_t bytes, uint32_t page_size)
Definition: sli4.h:53
uint32_t r_idx
Definition: sli4.h:3471
uint32_t rq_count
Definition: sli4.h:845
static int32_t sli_bmbx_wait(sli4_t *sli4, uint32_t msec)
Wait for the bootstrap mailbox to report &quot;ready&quot;.
Definition: sli4.c:356
#define SLI4_MBOX_COMMAND_READ_LNK_STAT
Definition: sli4.h:440
static sli4_asic_type_e sli_get_asic_type(sli4_t *sli4)
Definition: sli4.h:3996
int32_t sli_cmd_config_auto_xfer_rdy_hp(sli4_t *sli4, void *buf, size_t size, uint32_t max_burst_len, uint32_t block_size)
Write an CONFIG_AUTO_XFER_RDY_HP command to the provided buffer.
Definition: sli4.c:1778
uint32_t xri_count
Definition: sli4.h:835
#define SLI4_OPC_FC_SET_TRUNK_MODE
Definition: sli4.h:1655
uint32_t has_extents
Definition: sli4.h:3654
int32_t sli_reset_required(sli4_t *sli4)
Read the SLIPORT_STATUS register to check if the reset required is set.
Definition: sli4.c:6253
uint8_t fw_name[2][16]
Definition: sli4.h:3629
#define SLI4_MAJOR_CODE_SENTINEL
Definition: sli4.h:3317
uint32_t sli_reg_read(sli4_t *sli, sli4_regname_e reg)
Read the given SLI register.
Definition: sli4.c:240
uint32_t alt_mrq_filter_bit_mask_1
Definition: sli4.h:1095
struct sli4_req_common_modify_eq_delay_t::@40 eq_delay_record[8]
int32_t sli_cmd_common_delete_object(sli4_t *sli4, void *buf, size_t size, char *object_name)
Write a COMMON_DELETE_OBJECT command.
Definition: sli4.c:2887
#define SLI4_MBOX_COMMAND_POST_XRI
Definition: sli4.h:434
#define SLI4_INTF_REG
SLI_INTF - SLI Interface Definition Register.
Definition: sli4.h:101
#define SLI4_IF_TYPE_LANCER_G7
Definition: sli4.h:117
int32_t sli_fc_process_link_attention(sli4_t *sli4, void *acqe)
Process an asynchronous Link Attention event entry.
Definition: sli4_fc.c:2485
uint32_t actual_vpd_length
Definition: sli4.h:930
#define SLI4_PCI_CLASS_REVISION
Definition: sli4.h:85
READ_TOPOLOGY - read the link event information.
Definition: sli4.h:979
uint32_t major_code
Definition: sli4.h:3307
#define SLI4_ACQE_EVENT_CODE_SLI_PORT_EVENT
Definition: sli4.h:3386
#define FC_LINK_SPEED_10G
Definition: sli4.h:718
uint32_t available_length
Definition: sli4.h:925
#define SLI4_OPC_COMMON_CREATE_CQ_SET
Definition: sli4.h:1612
int32_t __sli_create_queue(sli4_t *sli4, sli4_queue_t *q)
Issue the command to create a queue.
Definition: sli4.c:4893
uint32_t xri_count
Definition: sli4.h:793
#define SLI4_INTF_SLI_REVISION_SHIFT
Definition: sli4.h:109
uint8_t rq_batch
Definition: sli4.h:3622
uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t mqe_count_method
Definition: sli4.h:2204
static bool ocs_bbcr_enabled(ocs_t *ocs)
Definition: ocs_drv_fc.h:244
int32_t sli_cmd_fcoe_wq_destroy(sli4_t *sli4, void *buf, size_t size, uint16_t wq_id)
Write an FCOE_WQ_DESTROY command.
Definition: sli4_fc.c:231
void sli4_cmd_lowlevel_disable_ras(sli4_t *sli4, void *buf, size_t size)
Write a LOWLEVEL_SET_DIAG_LOG_OPTIONS command.
Definition: sli4.c:2389
#define SLI4_PORT_STATUS_ERROR(r)
Definition: sli4.h:399
sli4_mbox_command_header_t hdr
Definition: sli4.h:1507
int32_t __sli_queue_init(sli4_t *sli4, sli4_queue_t *q, uint32_t qtype, size_t size, uint32_t n_entries, uint32_t align)
Initialize a queue object.
Definition: sli4.c:4833
int32_t sli_fw_reset(sli4_t *sli4)
Issue a Firmware Reset.
Definition: sli4.c:4658
int32_t sli_cmd_reg_vfi(sli4_t *sli4, void *buf, size_t size, ocs_domain_t *domain)
Write a REG_VFI command to the provided buffer.
Definition: sli4.c:1353
uint32_t rev_id
Definition: sli4.c:74
int32_t _sli_queue_poke(sli4_t *sli4, sli4_queue_t *q, uint32_t index, uint8_t *entry)
Definition: sli4.c:5813
ocs_dma_t bmbx
Definition: sli4.h:3692
#define FC_LINK_SPEED_1G
Definition: sli4.h:704
struct sli4_cmd_reg_fcfi_t::@32 rq_cfg[SLI4_CMD_REG_FCFI_NUM_RQ_CFG]
#define SLI4_CMD_REG_FCFI_SET_FCFI_MODE
Definition: sli4.h:1065
int32_t sli_cmd_common_get_reconfig_link_info(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma)
Write a COMMON_GET_RECONFIG_LINK_INFO command.
Definition: sli4.c:3458
COMMON_CREATE_CQ_V2.
Definition: sli4.h:1751
#define SLI4_MBOX_COMMAND_READ_REV
Definition: sli4.h:439
#define SLI4_OPC_COMMON_CREATE_MQ_EXT
Definition: sli4.h:1617
int32_t sli_cmd_unreg_vpi(sli4_t *sli4, void *buf, size_t size, uint16_t indicator, uint32_t which)
Write an UNREG_VPI command to the provided buffer.
Definition: sli4.c:1701
uint32_t fcf_index
Definition: sli4.h:1045
sli4_mbox_command_header_t hdr
Definition: sli4.h:1152
int32_t sli_cmd_common_set_active_profile(sli4_t *sli4, void *buf, size_t size, uint32_t fd, uint32_t active_profile_id)
Write a COMMON_COMMON_SET_ACTIVE_PROFILE command.
Definition: sli4.c:3416
uint8_t is_ulp_fc[2]
Definition: sli4.h:3637
#define ocs_hal_assert(cond)
Definition: ocs_hal.h:82
uint32_t mrq_filter_bitmask_1
Definition: sli4.h:1095
int32_t sli_cmd_common_get_active_profile(sli4_t *sli4, void *buf, size_t size)
Write a COMMON_COMMON_GET_ACTIVE_PROFILE command.
Definition: sli4.c:3376
#define SLI4_IF_TYPE_BE3_SKH_PF
Definition: sli4.h:113
uint32_t index
Definition: sli4.h:1438
static int32_t sli_cmd_common_create_mq_ext(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *qmem, uint16_t cq_id, uint16_t ignored)
Write a COMMON_CREATE_MQ_EXT command.
Definition: sli4.c:2513
sli4_mbox_command_header_t hdr
Definition: sli4.h:1399
#define SLI4_IF_TYPE_LANCER_RDMA
Definition: sli4.h:116
char first_fw_name[16]
Definition: sli4.h:921
#define SLI4_OPC_COMMON_GET_SLI4_PARAMETERS
Definition: sli4.h:1622
#define SLI4_UERR_STATUS_LOW_REG
User error registers.
Definition: sli4.h:198
int32_t sli_cmd_release_xri(sli4_t *sli4, void *buf, size_t size, uint8_t num_xri)
Write a RELEASE_XRI command to the provided buffer.
Definition: sli4.c:939
uint32_t fcf_index
Definition: sli4.h:1071
#define SLI4_EQCQ_DOORBELL_REG
EQCQ_DOORBELL - EQ and CQ Doorbell Register.
Definition: sli4.h:157
#define SLI4_PORT_SEMAPHORE_STATUS_POST_READY
Definition: sli4.h:379
#define SLI4_MQE_SIZE_32
Definition: sli4.h:1995
static int32_t sli_res_sli_config(void *buf)
Check the SLI_CONFIG response.
Definition: sli4.c:3636
uint32_t uint32_t status
Definition: sli4.h:1685
int32_t sli_cmd_read_config(sli4_t *sli4, void *buf, size_t size)
Write a READ_CONFIG command to the provided buffer.
Definition: sli4.c:961
uint8_t port_number
Definition: sli4.h:3632
uint32_t chain_sge_initial_value_lo
Definition: sli4.h:3555
#define SLI4_ASIC_GEN_MASK
Definition: sli4.h:129
#define SLI4_PORT_STATUS_DUMP_PRESENT(r)
Definition: sli4.h:400
uint32_t destination_n_port_id
Definition: sli4.h:1419
sli4_mbox_command_header_t hdr
Definition: sli4.h:1480
COMMON_WRITE_OBJECT.
Definition: sli4.h:2629
uint32_t xri_base
Definition: sli4.h:835
int32_t sli_is_paused(sli4_t *sli4)
Definition: sli4.c:6390
COMMON_GET_CNTL_ATTRIBUTES.
Definition: sli4.h:2047
int ocs_debug_is_enabled(uint32_t mask)
return true if debug bits are enabled
Definition: ocs_debug.c:106
char modeldesc[64]
Definition: sli4.h:3634
uint32_t uint32_t uint32_t rq_id_5
Definition: sli4.h:1095
#define SLI4_SUBSYSTEM_DMTF
Definition: sli4.h:1601
#define SLI4_OPC_COMMON_SET_PROFILE_CONFIG
Definition: sli4.h:1638
#define SLI4_PORT_SEMAPHORE_REG_1
Definition: sli4.h:364
int32_t sli_queue_alloc(sli4_t *sli4, uint32_t qtype, sli4_queue_t *q, uint32_t n_entries, sli4_queue_t *assoc, uint16_t ulp)
Allocate a queue.
Definition: sli4.c:5078
#define SLI4_ACQE_EVENT_CODE_FCOE_FIP
Definition: sli4.h:3381
sli4_mbox_command_header_t hdr
Definition: sli4.h:1460
#define SLI4_SUBSYSTEM_FCFCOE
Definition: sli4.h:1600
uint32_t uint32_t uint32_t max_rq_buffer_size
Definition: sli4.h:2292
uint32_t vfi_base
Definition: sli4.h:841
static int32_t sli_cmd_common_destroy_cq(sli4_t *sli4, void *buf, size_t size, uint16_t cq_id)
Write a COMMON_DESTROY_CQ command.
Definition: sli4.c:2099
COMMON_CREATE_CQ_V0.
Definition: sli4.h:1719
static int32_t sli_wait_for_fw_ready(sli4_t *sli4, uint32_t timeout_ms)
check to see if the FW is ready.
Definition: sli4.c:3701
UNREG_VPI - unregister one or more VPI.
Definition: sli4.h:1459
int32_t sli_bmbx_command(sli4_t *sli4)
Submit a command to the bootstrap mailbox and check the status.
Definition: sli4.c:493
uint32_t max_sgl_pages
Definition: sli4.h:3675
static uint8_t sli_intf_if_type(uint32_t val)
Retrieve the SLI interface type.
Definition: sli4.c:316
struct sli4_req_common_create_eq_t::@41 page_address[8]
int32_t sli_fc_process_link_state(sli4_t *sli4, void *acqe)
Process an asynchronous Link State event entry.
Definition: sli4_fc.c:2145
int32_t sli_cmd_unreg_vfi(sli4_t *sli4, void *buf, size_t size, ocs_domain_t *domain, uint32_t which)
Write an UNREG_VFI command to the provided buffer.
Definition: sli4.c:1656
uint32_t auto_xfer_rdy
Definition: sli4.h:3654
#define SLI4_MBOX_COMMAND_REG_RPI
Definition: sli4.h:445
#define SLI4_OPC_COMMON_GET_CNTL_ATTRIBUTES
Definition: sli4.h:1619
#define SLI4_MBOX_COMMAND_INIT_LINK
Definition: sli4.h:431
int32_t sli_cmd_dump_type4(sli4_t *sli4, void *buf, size_t size, uint16_t wki)
Write a DUMP Type 4 command to the provided buffer.
Definition: sli4.c:602
static int32_t sli_cmd_common_destroy_mq(sli4_t *sli4, void *buf, size_t size, uint16_t mq_id)
Write a COMMON_DESTROY_MQ command.
Definition: sli4.c:2592
struct sli4_queue_t::@44::@46 dpp
int32_t sli_cmd_init_vpi(sli4_t *sli4, void *buf, size_t size, uint16_t vpi, uint16_t vfi)
Write an INIT_VPI command to the provided buffer.
Definition: sli4.c:883
#define SLI4_EQE_SIZE_4
Definition: sli4.h:1946
int32_t sli_callback(sli4_t *sli4, sli4_callback_e which, void *func, void *arg)
Register a callback for the given event.
Definition: sli4.c:4786
static int32_t sli_cmd_fw_deinitialize(sli4_t *, void *, size_t)
Write a FW_DEINITIALIZE command to the provided buffer.
Definition: sli4.c:729
#define OCS_TOW_FEATURE_AXR
Definition: ocs_hal.h:148
static int32_t sli_fw_term(sli4_t *)
Terminate the firmware.
Definition: sli4.c:3796
static int32_t sli_cmd_read_rev(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *vpd)
Write a READ_REV command to the provided buffer.
Definition: sli4.c:1034
#define SLI4_OPC_COMMON_GET_PORT_NAME
Definition: sli4.h:1624
uint32_t minor_code
Definition: sli4.h:3307
uint8_t embed[58 *sizeof(uint32_t)]
Definition: sli4.h:1265
static int32_t sli_sliport_control(sli4_t *sli4, uint32_t endian)
Initialize SLI Port control register.
Definition: sli4.c:1532
READ_CONFIG - read SLI port configuration parameters.
Definition: sli4.h:809
uint32_t off
Definition: sli4.h:3420
void sli4_cmd_lowlevel_enable_ras(sli4_t *sli4, void *buf, size_t size, int log_level, uint32_t unit_size, int32_t buf_count, uint32_t *phys_addr, uintptr_t lwpd_phys_addr)
Write a LOWLEVEL_SET_DIAG_LOG_OPTIONS command.
Definition: sli4.c:2339
static int32_t sli_cmd_common_destroy_eq(sli4_t *sli4, void *buf, size_t size, uint16_t eq_id)
Write a COMMON_DESTROY_EQ command.
Definition: sli4.c:2269
int32_t sli_cmd_common_set_profile_config(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma, uint8_t profile_id, uint32_t descriptor_count, uint8_t isap)
Write a COMMON_COMMON_SET_PROFILE_CONFIG command.
Definition: sli4.c:3287
REG_VFI - register a Virtual Fabric Indicator.
Definition: sli4.h:1151
int32_t sli_cmd_common_get_sli4_parameters(sli4_t *sli4, void *buf, size_t size)
Write a COMMON_GET_SLI4_PARAMETERS command.
Definition: sli4.c:2696
#define SLI4_MBOX_COMMAND_CONFIG_LINK
Definition: sli4.h:428
uint16_t max_qcount[SLI_QTYPE_MAX]
Definition: sli4.h:3616
uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t rq_page_cnt
Definition: sli4.h:2204
REG_VPI - register a Virtual Port Indicator.
Definition: sli4.h:1177
uint32_t event_data[3]
Definition: sli4.h:3349
int32_t sli_cmd_config_run_biu_diag(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *tx_buffer, size_t tx_buf_len, ocs_dma_t *rx_buffer, size_t rx_buf_len)
Write a RUN_BIU_DIAG command.
Definition: sli4.c:3084
static uint32_t sli_get_if_type(sli4_t *sli4)
Definition: sli4.h:3804
uint32_t fw_rev[2]
Definition: sli4.h:3628
uint32_t uint32_t vpi
Definition: sli4.h:1154
int32_t sli_cmd_init_vfi(sli4_t *sli4, void *buf, size_t size, uint16_t vfi, uint16_t fcfi, uint16_t vpi)
Write an INIT_VFI command to the provided buffer.
Definition: sli4.c:846
uint32_t bde_type
Definition: sli4.h:469
uint64_t sgl_index_field_mask
Definition: sli4.h:3554
uint8_t topology
Definition: sli4.h:3625
struct sli4_req_common_create_cq_v0_t::@37 page_physical_address[0]
#define FC_LINK_SPEED_4G
Definition: sli4.h:707
uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t wqe_count_mask
Definition: sli4.h:2204
uint32_t val
Definition: sli4.h:773
sli4_mbox_command_header_t hdr
Definition: sli4.h:814
#define SLI4_MBOX_COMMAND_UNREG_FCFI
Definition: sli4.h:451
#define SLI4_BDE_TYPE_BDE_64
Definition: sli4.h:490
#define SLI4_UERR_MASK_LOW_REG
Definition: sli4.h:200
uint32_t perf_wq_id_association
Definition: sli4.h:3654
struct sli4_req_common_create_cq_v2_t::@38 page_physical_address[0]
uint32_t request_length
Definition: sli4.h:1672
uint16_t frag_num_field_offset
Definition: sli4.h:3551
int32_t sli_cmd_unreg_fcfi(sli4_t *sli4, void *buf, size_t size, uint16_t indicator)
Write a UNREG_FCFI command to the provided buffer.
Definition: sli4.c:1570
int32_t sli_cmd_config_link(sli4_t *sli4, void *buf, size_t size)
Write a CONFIG_LINK command to the provided buffer.
Definition: sli4.c:546
#define SLI4_INTF_SLI_REVISION_MASK
Definition: sli4.h:110
#define SLI4_MAJOR_CODE_STANDARD
Definition: sli4.h:3316
sli4_mbox_command_header_t hdr
Definition: sli4.h:1126
uint64_t frag_num_field_mask
Definition: sli4.h:3553
Generic Command Request header.
Definition: sli4.h:1666
#define FW_DUMP_READY_STATUS_NOT_READY
Definition: ocs_gendump.h:68
struct sli4_req_common_create_mq_ext_t::@42 page_physical_address[8]
uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t rqe_count_method
Definition: sli4.h:2204
uint32_t qpage_count[SLI_QTYPE_MAX]
Definition: sli4.h:3620
sli4_mbox_command_header_t hdr
Definition: sli4.h:1279
sli4_mbox_command_header_t hdr
Definition: sli4.h:1413
Generic Command Response header.
Definition: sli4.h:1683
uint32_t hlm
Definition: sli4.h:1199
COMMON_SET_ACTIVE_PROFILE.
Definition: sli4.h:3112
#define SLI4_PORT_STATUS_RN
Definition: sli4.h:392
#define SLI4_REG_RPI_BUF_LEN
Definition: sli4.h:1145
#define SLI4_OPC_FCOE_SET_LINK_DIAG_LOOPBACK
Definition: sli4.h:1652
uint32_t vp
Definition: sli4.h:736
sli4_req_hdr_t hdr
Definition: sli4.h:2150
#define SLI4_INTF_VALID_SHIFT
Definition: sli4.h:102
const uint8_t sli4_fw_deinitialize[]
FW_DEINITIALIZE - deinitialize a SLI port.
Definition: sli4.c:68
uint32_t uint32_t dpp_offset
Definition: sli4.h:1854
int32_t(* fip)(void *, void *)
Definition: sli4.h:3689
struct sli4_req_common_create_cq_set_v0_t::@39 page_physical_address[0]
uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t uint32_t wqe_count_method
Definition: sli4.h:2204
uint32_t r_ctl_mask
Definition: sli4.h:1081
uint32_t second_hw_revision
Definition: sli4.h:912
READ_REV - read the Port revision levels.
Definition: sli4.h:901
uint32_t vp
Definition: sli4.h:1154
#define SLI4_IF6_WQ_DOORBELL_REG
Definition: sli4.h:339
#define SLI4_BMBX_MASK_LO
Definition: sli4.h:142
COMMON_CREATE_EQ.
Definition: sli4.h:1913
int32_t sli_cmd_read_topology(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma)
Write a READ_TOPOLOGY command to the provided buffer.
Definition: sli4.c:1108
sli4_asic_rev_e
Definition: sli4.h:3589
#define OCS_DEBUG_ENABLE_EQ_DUMP
Definition: ocs_debug.h:171
uint32_t num_mrq_pairs_1
Definition: sli4.h:1095
#define SLI4_INIT_LINK_F_P2P_FAIL_OVER
Definition: sli4.h:695
int32_t sli_queue_index(sli4_t *sli4, sli4_queue_t *q)
Definition: sli4.c:5790
uint32_t rq_id_2
Definition: sli4.h:1049
int32_t _sli_queue_write(sli4_t *sli4, sli4_queue_t *q, uint8_t *entry)
Write an entry to the queue object.
Definition: sli4.c:5565
#define SLI4_PORT_STATUS_DIP
Definition: sli4.h:393
uint32_t vf
Definition: sli4.h:1199
int32_t sli_init(sli4_t *sli4)
Definition: sli4.c:4590
sli4_asic_rev_e asic_rev
Definition: sli4.h:3610
uint32_t rpi_count
Definition: sli4.h:837
#define SLI4_SLIPORT_CONTROL_LITTLE_ENDIAN
Definition: sli4.h:178
#define SLI4_OPC_COMMON_DELETE_OBJECT
Definition: sli4.h:1644
#define SLI4_OPC_LOWLEVEL_SET_WATCHDOG
Definition: sli4.h:1603
uint32_t hard_alpa
Definition: sli4.h:891
#define SLI4_MBOX_COMMAND_CONFIG_TOW_HP
Definition: sli4.h:457
int32_t sli_cmd_reg_rpi(sli4_t *sli4, void *buf, size_t size, uint32_t nport_id, uint16_t rpi, uint16_t vpi, ocs_dma_t *dma, uint8_t update, uint8_t enable_t10_pi, uint8_t hlm)
Write a REG_RPI command to the provided buffer.
Definition: sli4.c:1315
#define SLI4_128BYTE_WQE_SUPPORT
Definition: sli4.h:2197
#define SLI4_MBOX_COMMAND_READ_CONFIG
Definition: sli4.h:436
#define SLI4_WQ_DOORBELL(n, x, i)
Definition: sli4.h:345
static uint32_t sli_cq_doorbell(uint16_t n_popped, uint16_t id, uint8_t arm)
Definition: sli4.h:242
struct sli4_t::@49 pause_errx_pair[SLI4_PAUSE_ERRX_PAIR_CNT]
union sli4_queue_t::@44 u
uint32_t vpi
Definition: sli4.h:1139
sli4_port_type_e
Definition: sli4.h:3574
uint32_t vpi_count
Definition: sli4.h:839
static uint32_t sli_get_auto_xfer_rdy_capable(sli4_t *sli4)
Definition: sli4.h:3858
#define SLI4_CQ_CNT_1024
Definition: sli4.h:1821
uint32_t version
Definition: sli4.h:1521
uint32_t common_service_parameters[4]
Definition: ocs_fcp.h:323
#define SLI4_OPC_COMMON_READ_TRANSCEIVER_DATA
Definition: sli4.h:1628
ocs_dma_t dma
Definition: sli4.h:3450
#define SLI4_IF_TYPE_LANCER_FC_ETH
Definition: sli4.h:115
int32_t(* sli4_destroy_q_fn_t)(sli4_t *, void *, size_t, uint16_t)
Common Destroy Queue function prototype.
Definition: sli4.h:4068
int32_t sli_cmd_fcoe_wq_create(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *qmem, uint16_t cq_id, uint16_t ulp)
Write an FCOE_WQ_CREATE command.
Definition: sli4_fc.c:68
#define OCS_DEBUG_ENABLE_WQ_DUMP
Definition: ocs_debug.h:170
#define SLI4_SLIPORT_CONTROL_IP
Definition: sli4.h:180
uint8_t wwnn[8]
Definition: sli4.h:3627
uint32_t dif
Definition: sli4.h:1199
#define SLI4_IF6_CQ_DOORBELL_REG
Definition: sli4.h:171
const sli4_reg_t regmap[SLI4_REG_MAX][SLI4_MAX_IF_TYPES]
Define the mapping of registers to their BAR and offset.
Definition: sli4.c:126
uint32_t host_buffer_descriptor_count
Definition: sli4.h:2608