Emulex Logo
OneCoreā„¢ Storage SDK Release 11.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sli4_fc.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2015, 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_fc SLI-4 FC/FCoE APIs
35  */
36 
37 /**
38  * @file
39  * Implementation of Fibre Channel SLI-4 functions.
40  */
41 
42 #include "ocs_os.h"
43 #include "sli4_fc.h"
44 
45 #if defined(OCS_INCLUDE_DEBUG)
46 #include "ocs_debug.h"
47 #endif
48 
49 extern const char *SLI_QNAME[];
51 
52 /**
53  * @ingroup sli_fc
54  * @brief Write an FCOE_WQ_CREATE command.
55  *
56  * @param sli4 SLI context.
57  * @param buf Destination buffer for the command.
58  * @param size Buffer size, in bytes.
59  * @param qmem DMA memory for the queue.
60  * @param cq_id Associated CQ_ID.
61  * @param ulp The ULP to bind
62  *
63  * @note This creates a Version 0 message.
64  *
65  * @return Returns the number of bytes written.
66  */
67 int32_t
68 sli_cmd_fcoe_wq_create(sli4_t *sli4, void *buf, size_t size,
69  ocs_dma_t *qmem, uint16_t cq_id, uint16_t ulp)
70 {
71  sli4_req_fcoe_wq_create_t *wq = NULL;
72  uint32_t sli_config_off = 0;
73  uint32_t p;
74  uintptr_t addr;
75 
76  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
77  uint32_t payload_size;
78 
79  /* Payload length must accomodate both request and response */
80  payload_size = max(sizeof(sli4_req_fcoe_wq_create_t),
82 
83  sli_config_off = sli_cmd_sli_config(sli4, buf, size, payload_size,
84  NULL);
85  }
86  wq = (sli4_req_fcoe_wq_create_t *)((uint8_t *)buf + sli_config_off);
87 
91  sizeof(sli4_req_hdr_t);
92  /* valid values for number of pages: 1-4 (sec 4.5.1) */
93  wq->num_pages = sli_page_count(qmem->size, SLI_PAGE_SIZE);
95  return 0;
96  }
97 
98  wq->cq_id = cq_id;
99 
100  if (sli4->config.dual_ulp_capable) {
101  wq->dua = 1;
102  wq->bqu = 1;
103  wq->ulp = ulp;
104  }
105 
106  for (p = 0, addr = qmem->phys;
107  p < wq->num_pages;
108  p++, addr += SLI_PAGE_SIZE) {
109  wq->page_physical_address[p].low = ocs_addr32_lo(addr);
110  wq->page_physical_address[p].high = ocs_addr32_hi(addr);
111  }
112 
113  return(sli_config_off + sizeof(sli4_req_fcoe_wq_create_t));
114 }
115 
116 /**
117  * @ingroup sli_fc
118  * @brief Write an FCOE_WQ_CREATE_V1 command.
119  *
120  * @param sli4 SLI context.
121  * @param buf Destination buffer for the command.
122  * @param size Buffer size, in bytes.
123  * @param qmem DMA memory for the queue.
124  * @param cq_id Associated CQ_ID.
125  * @param ignored This parameter carries the ULP for WQ (ignored for V1)
126 
127  *
128  * @return Returns the number of bytes written.
129  */
130 int32_t
131 sli_cmd_fcoe_wq_create_v1(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *qmem,
132  uint16_t cq_id, uint16_t ignored)
133 {
134  sli4_req_fcoe_wq_create_v1_t *wq = NULL;
135  uint32_t sli_config_off = 0;
136  uint32_t p;
137  uintptr_t addr;
138  uint32_t page_size = 0;
139  uint32_t page_bytes = 0;
140  uint32_t n_wqe = 0;
141 
142  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
143  uint32_t payload_size;
144 
145  /* Payload length must accomodate both request and response */
146  payload_size = max(sizeof(sli4_req_fcoe_wq_create_v1_t),
148 
149  sli_config_off = sli_cmd_sli_config(sli4, buf, size, payload_size,
150  NULL);
151  }
152  wq = (sli4_req_fcoe_wq_create_v1_t *)((uint8_t *)buf + sli_config_off);
153 
157  sizeof(sli4_req_hdr_t);
158  wq->hdr.version = 1;
159 
160  n_wqe = qmem->size / sli4->config.wqe_size;
161 
162  // This heuristic to determine the page size is simplistic but could be made more
163  // sophisticated
164  switch (qmem->size) {
165  case 4096:
166  case 8192:
167  case 16384:
168  case 32768:
169  page_size = 1;
170  break;
171  case 65536:
172  page_size = 2;
173  break;
174  case 131072:
175  page_size = 4;
176  break;
177  case 262144:
178  page_size = 8;
179  break;
180  case 524288:
181  page_size = 10;
182  break;
183  default:
184  return 0;
185  }
186  page_bytes = page_size * SLI_PAGE_SIZE;
187 
188  /* valid values for number of pages: 1-8 */
189  wq->num_pages = sli_page_count(qmem->size, page_bytes);
191  return 0;
192  }
193 
194  wq->cq_id = cq_id;
195 
196  wq->page_size = page_size;
197 
198  if (sli4->config.wqe_size == SLI4_WQE_EXT_BYTES) {
200  } else {
201  wq->wqe_size = SLI4_WQE_SIZE;
202  }
203 
204  if (sli4->config.dpp)
205  wq->dpp = 1;
206 
207  wq->wqe_count = n_wqe;
208 
209  for (p = 0, addr = qmem->phys;
210  p < wq->num_pages;
211  p++, addr += page_bytes) {
212  wq->page_physical_address[p].low = ocs_addr32_lo(addr);
213  wq->page_physical_address[p].high = ocs_addr32_hi(addr);
214  }
215 
216  return(sli_config_off + sizeof(sli4_req_fcoe_wq_create_v1_t));
217 }
218 
219 /**
220  * @ingroup sli_fc
221  * @brief Write an FCOE_WQ_DESTROY command.
222  *
223  * @param sli4 SLI context.
224  * @param buf Destination buffer for the command.
225  * @param size Buffer size, in bytes.
226  * @param wq_id WQ_ID.
227  *
228  * @return Returns the number of bytes written.
229  */
230 int32_t
231 sli_cmd_fcoe_wq_destroy(sli4_t *sli4, void *buf, size_t size, uint16_t wq_id)
232 {
233  sli4_req_fcoe_wq_destroy_t *wq = NULL;
234  uint32_t sli_config_off = 0;
235 
236  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
237  uint32_t payload_size;
238 
239  /* Payload length must accomodate both request and response */
240  payload_size = max(sizeof(sli4_req_fcoe_wq_destroy_t),
241  sizeof(sli4_res_hdr_t));
242 
243  sli_config_off = sli_cmd_sli_config(sli4, buf, size, payload_size,
244  NULL);
245  }
246  wq = (sli4_req_fcoe_wq_destroy_t *)((uint8_t *)buf + sli_config_off);
247 
251  sizeof(sli4_req_hdr_t);
252 
253  wq->wq_id = wq_id;
254 
255  return(sli_config_off + sizeof(sli4_req_fcoe_wq_destroy_t));
256 }
257 
258 /**
259  * @ingroup sli_fc
260  * @brief Write an FCOE_POST_SGL_PAGES command.
261  *
262  * @param sli4 SLI context.
263  * @param buf Destination buffer for the command.
264  * @param size Buffer size, in bytes.
265  * @param xri starting XRI
266  * @param xri_count XRI
267  * @param page0 First SGL memory page.
268  * @param page1 Second SGL memory page (optional).
269  * @param dma DMA buffer for non-embedded mailbox command (options)
270  *
271  * if non-embedded mbx command is used, dma buffer must be at least (32 + xri_count*16) in length
272  *
273  * @return Returns the number of bytes written.
274  */
275 int32_t
276 sli_cmd_fcoe_post_sgl_pages(sli4_t *sli4, void *buf, size_t size,
277  uint16_t xri, uint32_t xri_count, ocs_dma_t *page0[], ocs_dma_t *page1[], ocs_dma_t *dma)
278 {
279  sli4_req_fcoe_post_sgl_pages_t *post = NULL;
280  uint32_t sli_config_off = 0;
281  uint32_t i;
282 
283  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
284  uint32_t payload_size;
285 
286  /* Payload length must accomodate both request and response */
287  payload_size = max(sizeof(sli4_req_fcoe_post_sgl_pages_t) +
288  xri_count*sizeof(sli4_fcoe_post_sgl_page_desc_t),
289  sizeof(sli4_res_hdr_t));
290 
291  sli_config_off = sli_cmd_sli_config(sli4, buf, size, payload_size,
292  dma);
293  }
294  if (dma) {
295  post = dma->virt;
296  ocs_memset(post, 0, dma->size);
297  } else {
298  post = (sli4_req_fcoe_post_sgl_pages_t *)((uint8_t *)buf + sli_config_off);
299  }
300 
303  // payload size calculation
304  // 4 = xri_start + xri_count
305  // xri_count = # of XRI's registered
306  // sizeof(uint64_t) = physical address size
307  // 2 = # of physical addresses per page set
308  post->hdr.request_length = 4 + (xri_count * (sizeof(uint64_t) * 2));
309 
310  post->xri_start = xri;
311  post->xri_count = xri_count;
312 
313  for (i = 0; i < xri_count; i++) {
314  post->page_desc[i].page0_low = ocs_addr32_lo(page0[i]->phys);
315  post->page_desc[i].page0_high = ocs_addr32_hi(page0[i]->phys);
316  }
317 
318  if (page1) {
319  for (i = 0; i < xri_count; i++) {
320  post->page_desc[i].page1_low = ocs_addr32_lo(page1[i]->phys);
321  post->page_desc[i].page1_high = ocs_addr32_hi(page1[i]->phys);
322  }
323  }
324 
325  return dma ? sli_config_off : (sli_config_off + sizeof(sli4_req_fcoe_post_sgl_pages_t));
326 }
327 
328 /**
329  * @ingroup sli_fc
330  * @brief Write an FCOE_RQ_CREATE command.
331  *
332  * @param sli4 SLI context.
333  * @param buf Destination buffer for the command.
334  * @param size Buffer size, in bytes.
335  * @param qmem DMA memory for the queue.
336  * @param cq_id Associated CQ_ID.
337  * @param ulp This parameter carries the ULP for the RQ
338  * @param buffer_size Buffer size pointed to by each RQE.
339  *
340  * @note This creates a Version 0 message.
341  *
342  * @return Returns the number of bytes written.
343  */
344 int32_t
345 sli_cmd_fcoe_rq_create(sli4_t *sli4, void *buf, size_t size,
346  ocs_dma_t *qmem, uint16_t cq_id, uint16_t ulp, uint16_t buffer_size)
347 {
348  sli4_req_fcoe_rq_create_t *rq = NULL;
349  uint32_t sli_config_off = 0;
350  uint32_t p;
351  uintptr_t addr;
352 
353  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
354  uint32_t payload_size;
355 
356  /* Payload length must accomodate both request and response */
357  payload_size = max(sizeof(sli4_req_fcoe_rq_create_t),
359 
360  sli_config_off = sli_cmd_sli_config(sli4, buf, size, payload_size,
361  NULL);
362  }
363  rq = (sli4_req_fcoe_rq_create_t *)((uint8_t *)buf + sli_config_off);
364 
368  sizeof(sli4_req_hdr_t);
369  /* valid values for number of pages: 1-8 (sec 4.5.6) */
370  rq->num_pages = sli_page_count(qmem->size, SLI_PAGE_SIZE);
372  ocs_log_test(sli4->os, "num_pages %d not valid\n", rq->num_pages);
373  return 0;
374  }
375 
376  /*
377  * RQE count is the log base 2 of the total number of entries
378  */
379  rq->rqe_count = ocs_lg2(qmem->size / SLI4_FCOE_RQE_SIZE);
380 
381  if ((buffer_size < SLI4_FCOE_RQ_CREATE_V0_MIN_BUF_SIZE) ||
382  (buffer_size > SLI4_FCOE_RQ_CREATE_V0_MAX_BUF_SIZE)) {
383  ocs_log_err(sli4->os, "buffer_size %d out of range (%d-%d)\n",
384  buffer_size,
387  return -1;
388  }
389  rq->buffer_size = buffer_size;
390 
391  rq->cq_id = cq_id;
392 
393  if (sli4->config.dual_ulp_capable) {
394  rq->dua = 1;
395  rq->bqu = 1;
396  rq->ulp = ulp;
397  }
398 
399  for (p = 0, addr = qmem->phys;
400  p < rq->num_pages;
401  p++, addr += SLI_PAGE_SIZE) {
402  rq->page_physical_address[p].low = ocs_addr32_lo(addr);
403  rq->page_physical_address[p].high = ocs_addr32_hi(addr);
404  }
405 
406  return(sli_config_off + sizeof(sli4_req_fcoe_rq_create_t));
407 }
408 
409 /**
410  * @ingroup sli_fc
411  * @brief Write an FCOE_RQ_CREATE_V1 command.
412  *
413  * @param sli4 SLI context.
414  * @param buf Destination buffer for the command.
415  * @param size Buffer size, in bytes.
416  * @param qmem DMA memory for the queue.
417  * @param cq_id Associated CQ_ID.
418  * @param ulp This parameter carries the ULP for RQ (ignored for V1)
419  * @param buffer_size Buffer size pointed to by each RQE.
420  *
421  * @note This creates a Version 0 message
422  *
423  * @return Returns the number of bytes written.
424  */
425 int32_t
426 sli_cmd_fcoe_rq_create_v1(sli4_t *sli4, void *buf, size_t size,
427  ocs_dma_t *qmem, uint16_t cq_id, uint16_t ulp,
428  uint16_t buffer_size)
429 {
430  sli4_req_fcoe_rq_create_v1_t *rq = NULL;
431  uint32_t sli_config_off = 0;
432  uint32_t p;
433  uintptr_t addr;
434 
435  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
436  uint32_t payload_size;
437 
438  /* Payload length must accomodate both request and response */
439  payload_size = max(sizeof(sli4_req_fcoe_rq_create_v1_t),
441 
442  sli_config_off = sli_cmd_sli_config(sli4, buf, size, payload_size,
443  NULL);
444  }
445  rq = (sli4_req_fcoe_rq_create_v1_t *)((uint8_t *)buf + sli_config_off);
446 
450  sizeof(sli4_req_hdr_t);
451  rq->hdr.version = 1;
452 
453  /* valid values for number of pages: 1-8 (sec 4.5.6) */
454  rq->num_pages = sli_page_count(qmem->size, SLI_PAGE_SIZE);
456  ocs_log_test(sli4->os, "num_pages %d not valid, max %d\n",
458  return 0;
459  }
460 
461  /*
462  * RQE count is the total number of entries (note not lg2(# entries))
463  */
464  rq->rqe_count = qmem->size / SLI4_FCOE_RQE_SIZE;
465 
467 
469 
470  if ((buffer_size < sli4->config.rq_min_buf_size) ||
471  (buffer_size > sli4->config.rq_max_buf_size)) {
472  ocs_log_err(sli4->os, "buffer_size %d out of range (%d-%d)\n",
473  buffer_size,
474  sli4->config.rq_min_buf_size,
475  sli4->config.rq_max_buf_size);
476  return -1;
477  }
478  rq->buffer_size = buffer_size;
479 
480  rq->cq_id = cq_id;
481 
482  for (p = 0, addr = qmem->phys;
483  p < rq->num_pages;
484  p++, addr += SLI_PAGE_SIZE) {
485  rq->page_physical_address[p].low = ocs_addr32_lo(addr);
486  rq->page_physical_address[p].high = ocs_addr32_hi(addr);
487  }
488 
489  return(sli_config_off + sizeof(sli4_req_fcoe_rq_create_v1_t));
490 }
491 
492 /**
493  * @ingroup sli_fc
494  * @brief Write an FCOE_RQ_DESTROY command.
495  *
496  * @param sli4 SLI context.
497  * @param buf Destination buffer for the command.
498  * @param size Buffer size, in bytes.
499  * @param rq_id RQ_ID.
500  *
501  * @return Returns the number of bytes written.
502  */
503 int32_t
504 sli_cmd_fcoe_rq_destroy(sli4_t *sli4, void *buf, size_t size, uint16_t rq_id)
505 {
506  sli4_req_fcoe_rq_destroy_t *rq = NULL;
507  uint32_t sli_config_off = 0;
508 
509  if (SLI4_PORT_TYPE_FC == sli4->port_type) {
510  uint32_t payload_size;
511 
512  /* Payload length must accomodate both request and response */
513  payload_size = max(sizeof(sli4_req_fcoe_rq_destroy_t),
514  sizeof(sli4_res_hdr_t));
515 
516  sli_config_off = sli_cmd_sli_config(sli4, buf, size, payload_size,
517  NULL);
518  }
519  rq = (sli4_req_fcoe_rq_destroy_t *)((uint8_t *)buf + sli_config_off);
520 
524  sizeof(sli4_req_hdr_t);
525 
526  rq->rq_id = rq_id;
527 
528  return(sli_config_off + sizeof(sli4_req_fcoe_rq_destroy_t));
529 }
530 
531 /**
532  * @ingroup sli_fc
533  * @brief Write an FCOE_READ_FCF_TABLE command.
534  *
535  * @note
536  * The response of this command exceeds the size of an embedded
537  * command and requires an external buffer with DMA capability to hold the results.
538  * The caller should allocate the ocs_dma_t structure / memory.
539  *
540  * @param sli4 SLI context.
541  * @param buf Destination buffer for the command.
542  * @param size Buffer size, in bytes.
543  * @param dma Pointer to DMA memory structure. This is allocated by the caller.
544  * @param index FCF table index to retrieve.
545  *
546  * @return Returns the number of bytes written.
547  */
548 int32_t
549 sli_cmd_fcoe_read_fcf_table(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma, uint16_t index)
550 {
551  sli4_req_fcoe_read_fcf_table_t *read_fcf = NULL;
552 
553  if (SLI4_PORT_TYPE_FC != sli4->port_type) {
554  ocs_log_test(sli4->os, "FCOE_READ_FCF_TABLE only supported on FC\n");
555  return -1;
556  }
557 
558  read_fcf = dma->virt;
559 
560  ocs_memset(read_fcf, 0, sizeof(sli4_req_fcoe_read_fcf_table_t));
561 
563  read_fcf->hdr.subsystem = SLI4_SUBSYSTEM_FCFCOE;
564  read_fcf->hdr.request_length = dma->size -
566  read_fcf->fcf_index = index;
567 
568  return sli_cmd_sli_config(sli4, buf, size, 0, dma);
569 }
570 
571 /**
572  * @ingroup sli_fc
573  * @brief Write an FCOE_POST_HDR_TEMPLATES command.
574  *
575  * @param sli4 SLI context.
576  * @param buf Destination buffer for the command.
577  * @param size Buffer size, in bytes.
578  * @param dma Pointer to DMA memory structure. This is allocated by the caller.
579  * @param rpi Starting RPI index for the header templates.
580  * @param payload_dma Pointer to DMA memory used to hold larger descriptor counts.
581  *
582  * @return Returns the number of bytes written.
583  */
584 int32_t
585 sli_cmd_fcoe_post_hdr_templates(sli4_t *sli4, void *buf, size_t size,
586  ocs_dma_t *dma, uint16_t rpi, ocs_dma_t *payload_dma)
587 {
588  sli4_req_fcoe_post_hdr_templates_t *template = NULL;
589  uint32_t sli_config_off = 0;
590  uintptr_t phys = 0;
591  uint32_t i = 0;
592  uint32_t page_count;
593  uint32_t payload_size;
594 
595  page_count = sli_page_count(dma->size, SLI_PAGE_SIZE);
596 
597  payload_size = sizeof(sli4_req_fcoe_post_hdr_templates_t) +
598  page_count * sizeof(sli4_physical_page_descriptor_t);
599 
600  if (page_count > 16) {
601  /* We can't fit more than 16 descriptors into an embedded mailbox
602  command, it has to be non-embedded */
603  if (ocs_dma_alloc(sli4->os, payload_dma, payload_size, 4)) {
604  ocs_log_err(sli4->os, "mailbox payload memory allocation fail\n");
605  return 0;
606  }
607  sli_config_off = sli_cmd_sli_config(sli4, buf, size, payload_size, payload_dma);
608  template = (sli4_req_fcoe_post_hdr_templates_t *)payload_dma->virt;
609  } else {
610  sli_config_off = sli_cmd_sli_config(sli4, buf, size, payload_size, NULL);
611  template = (sli4_req_fcoe_post_hdr_templates_t *)((uint8_t *)buf + sli_config_off);
612  }
613 
614  if (UINT16_MAX == rpi) {
615  rpi = sli4->config.extent[SLI_RSRC_FCOE_RPI].base[0];
616  }
617 
618  template->hdr.opcode = SLI4_OPC_FCOE_POST_HDR_TEMPLATES;
619  template->hdr.subsystem = SLI4_SUBSYSTEM_FCFCOE;
620  template->hdr.request_length = sizeof(sli4_req_fcoe_post_hdr_templates_t) -
621  sizeof(sli4_req_hdr_t);
622 
623  template->rpi_offset = rpi;
624  template->page_count = page_count;
625  phys = dma->phys;
626  for (i = 0; i < template->page_count; i++) {
627  template->page_descriptor[i].low = ocs_addr32_lo(phys);
628  template->page_descriptor[i].high = ocs_addr32_hi(phys);
629 
630  phys += SLI_PAGE_SIZE;
631  }
632 
633  return(sli_config_off + payload_size);
634 }
635 
636 int32_t
637 sli_cmd_fcoe_rediscover_fcf(sli4_t *sli4, void *buf, size_t size, uint16_t index)
638 {
639  sli4_req_fcoe_rediscover_fcf_t *redisc = NULL;
640  uint32_t sli_config_off = 0;
641 
642  sli_config_off = sli_cmd_sli_config(sli4, buf, size,
644  NULL);
645 
646  redisc = (sli4_req_fcoe_rediscover_fcf_t *)((uint8_t *)buf + sli_config_off);
647 
651  sizeof(sli4_req_hdr_t);
652 
653  if (index == UINT16_MAX) {
654  redisc->fcf_count = 0;
655  } else {
656  redisc->fcf_count = 1;
657  redisc->fcf_index[0] = index;
658  }
659 
660  return(sli_config_off + sizeof(sli4_req_fcoe_rediscover_fcf_t));
661 }
662 
663 /**
664  * @ingroup sli_fc
665  * @brief Write an ABORT_WQE work queue entry.
666  *
667  * @param sli4 SLI context.
668  * @param buf Destination buffer for the WQE.
669  * @param size Buffer size, in bytes.
670  * @param type Abort type, such as XRI, abort tag, and request tag.
671  * @param send_abts Boolean to cause the hardware to automatically generate an ABTS.
672  * @param ids ID of IOs to abort.
673  * @param mask Mask applied to the ID values to abort.
674  * @param tag Tag value associated with this abort.
675  * @param cq_id The id of the completion queue where the WQE response is sent.
676  * @param dnrx When set to 1, this field indicates that the SLI Port must not return the associated XRI to the SLI
677  * Port's optimized write XRI pool.
678  *
679  * @return Returns 0 on success, or a non-zero value on failure.
680  */
681 int32_t
682 sli_abort_wqe(sli4_t *sli4, void *buf, size_t size, sli4_abort_type_e type, uint32_t send_abts,
683  uint32_t ids, uint32_t mask, uint16_t tag, uint16_t cq_id)
684 {
685  sli4_abort_wqe_t *abort = buf;
686 
687  ocs_memset(buf, 0, size);
688 
689  switch (type) {
690  case SLI_ABORT_XRI:
692  if (mask) {
693  ocs_log_warn(sli4->os, "warning non-zero mask %#x when aborting XRI %#x\n", mask, ids);
694  mask = 0;
695  }
696  break;
697  case SLI_ABORT_ABORT_ID:
699  break;
702  break;
703  default:
704  ocs_log_test(sli4->os, "unsupported type %#x\n", type);
705  return -1;
706  }
707 
708  abort->ia = send_abts ? 0 : 1;
709 
710  /* Supress ABTS retries */
711  abort->ir = 1;
712 
713  abort->t_mask = mask;
714  abort->t_tag = ids;
715  abort->command = SLI4_WQE_ABORT;
716  abort->request_tag = tag;
717  abort->qosd = TRUE;
718  abort->cq_id = cq_id;
719  abort->cmd_type = SLI4_CMD_ABORT_WQE;
720 
721  return 0;
722 }
723 
724 /**
725  * @ingroup sli_fc
726  * @brief Write an ELS_REQUEST64_WQE work queue entry.
727  *
728  * @param sli4 SLI context.
729  * @param buf Destination buffer for the WQE.
730  * @param size Buffer size, in bytes.
731  * @param sgl DMA memory for the ELS request.
732  * @param req_type ELS request type.
733  * @param req_len Length of ELS request in bytes.
734  * @param max_rsp_len Max length of ELS response in bytes.
735  * @param timeout Time, in seconds, before an IO times out. Zero means 2 * R_A_TOV.
736  * @param xri XRI for this exchange.
737  * @param tag IO tag value.
738  * @param cq_id The id of the completion queue where the WQE response is sent.
739  * @param rnode Destination of ELS request (that is, the remote node).
740  *
741  * @return Returns 0 on success, or a non-zero value on failure.
742  */
743 int32_t
744 sli_els_request64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint8_t req_type,
745  uint32_t req_len, uint32_t max_rsp_len, uint8_t timeout,
746  uint16_t xri, uint16_t tag, uint16_t cq_id, ocs_remote_node_t *rnode)
747 {
748  sli4_els_request64_wqe_t *els = buf;
749  sli4_sge_t *sge = sgl->virt;
750  uint8_t is_fabric = FALSE;
751 
752  ocs_memset(buf, 0, size);
753 
754  if (sli4->config.sgl_pre_registered) {
755  els->xbl = FALSE;
756 
757  els->dbde = TRUE;
759 
760  els->els_request_payload.buffer_length = req_len;
761  els->els_request_payload.u.data.buffer_address_low = sge[0].buffer_address_low;
762  els->els_request_payload.u.data.buffer_address_high = sge[0].buffer_address_high;
763  } else {
764  els->xbl = TRUE;
765 
767 
768  els->els_request_payload.buffer_length = 2 * sizeof(sli4_sge_t);
769  els->els_request_payload.u.blp.sgl_segment_address_low = ocs_addr32_lo(sgl->phys);
770  els->els_request_payload.u.blp.sgl_segment_address_high = ocs_addr32_hi(sgl->phys);
771  }
772 
773  els->els_request_payload_length = req_len;
774  els->max_response_payload_length = max_rsp_len;
775 
776  els->xri_tag = xri;
777  els->timer = timeout;
779 
781 
782  els->request_tag = tag;
783 
784  if (rnode->node_group) {
785  els->hlm = TRUE;
786  els->remote_id = rnode->fc_id & 0x00ffffff;
787  }
788 
790 
791  els->qosd = TRUE;
792 
793  // figure out the ELS_ID value from the request buffer
794 
795  switch (req_type) {
796  case FC_ELS_CMD_LOGO:
798  if (rnode->attached) {
800  els->context_tag = rnode->indicator;
801  } else {
803  els->context_tag = rnode->sport->indicator;
804  }
805  if (FC_ADDR_FABRIC == rnode->fc_id) {
806  is_fabric = TRUE;
807  }
808  break;
809  case FC_ELS_CMD_FDISC:
810  if (FC_ADDR_FABRIC == rnode->fc_id) {
811  is_fabric = TRUE;
812  }
813  if (0 == rnode->sport->fc_id) {
815  is_fabric = TRUE;
816  } else {
818  }
820  els->context_tag = rnode->sport->indicator;
821  els->sp = TRUE;
822  break;
823  case FC_ELS_CMD_FLOGI:
825  is_fabric = TRUE;
826  if (SLI4_IF_TYPE_BE3_SKH_PF == sli4->if_type) {
827  if (!rnode->sport->domain) {
828  ocs_log_test(sli4->os, "invalid domain handle\n");
829  return -1;
830  }
831  /*
832  * IF_TYPE 0 skips INIT_VFI/INIT_VPI and therefore must use the
833  * FCFI here
834  */
836  els->context_tag = rnode->sport->domain->fcf_indicator;
837  els->sp = TRUE;
838  } else {
840  els->context_tag = rnode->sport->indicator;
841 
842  /*
843  * Set SP here ... we haven't done a REG_VPI yet
844  * TODO: need to maybe not set this when we have
845  * completed VFI/VPI registrations ...
846  *
847  * Use the FC_ID of the SPORT if it has been allocated, otherwise
848  * use an S_ID of zero.
849  */
850  els->sp = TRUE;
851  if (rnode->sport->fc_id != UINT32_MAX) {
852  els->sid = rnode->sport->fc_id;
853  }
854  }
855  break;
856  case FC_ELS_CMD_PLOGI:
859  els->context_tag = rnode->sport->indicator;
860  break;
861  case FC_ELS_CMD_SCR:
864  els->context_tag = rnode->sport->indicator;
865  break;
866  default:
868  if (rnode->attached) {
870  els->context_tag = rnode->indicator;
871  } else {
873  els->context_tag = rnode->sport->indicator;
874  }
875  break;
876  }
877 
878  if (is_fabric) {
880  } else {
882  }
883 
884  els->cq_id = cq_id;
885 
886  if (SLI4_ELS_REQUEST64_CONTEXT_RPI != els->ct) {
887  els->remote_id = rnode->fc_id;
888  }
889  if (SLI4_ELS_REQUEST64_CONTEXT_VPI == els->ct) {
890  els->temporary_rpi = rnode->indicator;
891  }
892 
893  return 0;
894 }
895 
896 
897 /**
898  * @ingroup sli_fc
899  * @brief Write an FCP_ICMND64_WQE work queue entry.
900  *
901  * @param sli4 SLI context.
902  * @param buf Destination buffer for the WQE.
903  * @param size Buffer size, in bytes.
904  * @param sgl DMA memory for the scatter gather list.
905  * @param xri XRI for this exchange.
906  * @param tag IO tag value.
907  * @param cq_id The id of the completion queue where the WQE response is sent.
908  * @param rpi remote node indicator (RPI)
909  * @param rnode Destination request (that is, the remote node).
910  * @param timeout Time, in seconds, before an IO times out. Zero means no timeout.
911  *
912  * @return Returns 0 on success, or a non-zero value on failure.
913  */
914 int32_t
915 sli_fcp_icmnd64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl,
916  uint16_t xri, uint16_t tag, uint16_t cq_id,
917  uint32_t rpi, ocs_remote_node_t *rnode, uint8_t timeout)
918 {
919  sli4_fcp_icmnd64_wqe_t *icmnd = buf;
920  sli4_sge_t *sge = NULL;
921 
922  ocs_memset(buf, 0, size);
923 
924  if (!sgl || !sgl->virt) {
925  ocs_log_err(sli4->os, "bad parameter sgl=%p virt=%p\n",
926  sgl, sgl ? sgl->virt : NULL);
927  return -1;
928  }
929  sge = sgl->virt;
930 
931  if (sli4->config.sgl_pre_registered) {
932  icmnd->xbl = FALSE;
933 
934  icmnd->dbde = TRUE;
936 
937  icmnd->bde.buffer_length = sge[0].buffer_length;
938  icmnd->bde.u.data.buffer_address_low = sge[0].buffer_address_low;
939  icmnd->bde.u.data.buffer_address_high = sge[0].buffer_address_high;
940  } else {
941  icmnd->xbl = TRUE;
942 
943  icmnd->bde.bde_type = SLI4_BDE_TYPE_BLP;
944 
945  icmnd->bde.buffer_length = sgl->size;
946  icmnd->bde.u.blp.sgl_segment_address_low = ocs_addr32_lo(sgl->phys);
947  icmnd->bde.u.blp.sgl_segment_address_high = ocs_addr32_hi(sgl->phys);
948  }
949 
950  icmnd->payload_offset_length = sge[0].buffer_length + sge[1].buffer_length;
951  icmnd->xri_tag = xri;
952  icmnd->context_tag = rpi;
953  icmnd->timer = timeout;
954 
955  icmnd->pu = 2; // WQE word 4 contains read transfer length
957  icmnd->command = SLI4_WQE_FCP_ICMND64;
959 
960  icmnd->abort_tag = xri;
961 
962  icmnd->request_tag = tag;
963  icmnd->len_loc = 3;
964  if (rnode->node_group) {
965  icmnd->hlm = TRUE;
966  icmnd->remote_n_port_id = rnode->fc_id & 0x00ffffff;
967  }
969  icmnd->cq_id = cq_id;
970 
971  return 0;
972 }
973 
974 /**
975  * @ingroup sli_fc
976  * @brief Write an FCP_IREAD64_WQE work queue entry.
977  *
978  * @param sli4 SLI context.
979  * @param buf Destination buffer for the WQE.
980  * @param size Buffer size, in bytes.
981  * @param sgl DMA memory for the scatter gather list.
982  * @param first_data_sge Index of first data sge (used if perf hints are enabled)
983  * @param xfer_len Data transfer length.
984  * @param xri XRI for this exchange.
985  * @param tag IO tag value.
986  * @param cq_id The id of the completion queue where the WQE response is sent.
987  * @param rpi remote node indicator (RPI)
988  * @param rnode Destination request (i.e. remote node).
989  * @param dif T10 DIF operation, or 0 to disable.
990  * @param bs T10 DIF block size, or 0 if DIF is disabled.
991  * @param timeout Time, in seconds, before an IO times out. Zero means no timeout.
992  *
993  * @return Returns 0 on success, or a non-zero value on failure.
994  */
995 int32_t
996 sli_fcp_iread64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint32_t first_data_sge,
997  uint32_t xfer_len, uint16_t xri, uint16_t tag, uint16_t cq_id,
998  uint32_t rpi, ocs_remote_node_t *rnode,
999  uint8_t dif, uint8_t bs, uint8_t timeout)
1000 {
1001  sli4_fcp_iread64_wqe_t *iread = buf;
1002  sli4_sge_t *sge = NULL;
1003 
1004  ocs_memset(buf, 0, size);
1005 
1006  if (!sgl || !sgl->virt) {
1007  ocs_log_err(sli4->os, "bad parameter sgl=%p virt=%p\n",
1008  sgl, sgl ? sgl->virt : NULL);
1009  return -1;
1010  }
1011  sge = sgl->virt;
1012 
1013  if (sli4->config.sgl_pre_registered) {
1014  iread->xbl = FALSE;
1015 
1016  iread->dbde = TRUE;
1018 
1019  iread->bde.buffer_length = sge[0].buffer_length;
1020  iread->bde.u.data.buffer_address_low = sge[0].buffer_address_low;
1021  iread->bde.u.data.buffer_address_high = sge[0].buffer_address_high;
1022  } else {
1023  iread->xbl = TRUE;
1024 
1025  iread->bde.bde_type = SLI4_BDE_TYPE_BLP;
1026 
1027  iread->bde.buffer_length = sgl->size;
1028  iread->bde.u.blp.sgl_segment_address_low = ocs_addr32_lo(sgl->phys);
1029  iread->bde.u.blp.sgl_segment_address_high = ocs_addr32_hi(sgl->phys);
1030 
1031  /* fill out fcp_cmnd buffer len and change resp buffer to be of type
1032  * "skip" (note: response will still be written to sge[1] if necessary) */
1033  iread->fcp_cmd_buffer_length = sge[0].buffer_length;
1034  sge[1].sge_type = SLI4_SGE_TYPE_SKIP;
1035  }
1036 
1037  iread->payload_offset_length = sge[0].buffer_length + sge[1].buffer_length;
1038  iread->total_transfer_length = xfer_len;
1039 
1040  iread->xri_tag = xri;
1041  iread->context_tag = rpi;
1042 
1043  iread->timer = timeout;
1044 
1045  iread->pu = 2; // WQE word 4 contains read transfer length
1047  iread->command = SLI4_WQE_FCP_IREAD64;
1049  iread->dif = dif;
1050  iread->bs = bs;
1051 
1052  iread->abort_tag = xri;
1053 
1054  iread->request_tag = tag;
1055  iread->len_loc = 3;
1056  if (rnode->node_group) {
1057  iread->hlm = TRUE;
1058  iread->remote_n_port_id = rnode->fc_id & 0x00ffffff;
1059  }
1060  iread->iod = 1;
1062  iread->cq_id = cq_id;
1063 
1064  if (sli4->config.perf_hint) {
1066  iread->first_data_bde.buffer_length = sge[first_data_sge].buffer_length;
1067  iread->first_data_bde.u.data.buffer_address_low = sge[first_data_sge].buffer_address_low;
1068  iread->first_data_bde.u.data.buffer_address_high = sge[first_data_sge].buffer_address_high;
1069  }
1070 
1071  return 0;
1072 }
1073 
1074 
1075 /**
1076  * @ingroup sli_fc
1077  * @brief Write an FCP_IWRITE64_WQE work queue entry.
1078  *
1079  * @param sli4 SLI context.
1080  * @param buf Destination buffer for the WQE.
1081  * @param size Buffer size, in bytes.
1082  * @param sgl DMA memory for the scatter gather list.
1083  * @param first_data_sge Index of first data sge (used if perf hints are enabled)
1084  * @param xfer_len Data transfer length.
1085  * @param first_burst The number of first burst bytes
1086  * @param xri XRI for this exchange.
1087  * @param tag IO tag value.
1088  * @param cq_id The id of the completion queue where the WQE response is sent.
1089  * @param rpi remote node indicator (RPI)
1090  * @param rnode Destination request (i.e. remote node)
1091  * @param dif T10 DIF operation, or 0 to disable
1092  * @param bs T10 DIF block size, or 0 if DIF is disabled
1093  * @param timeout Time, in seconds, before an IO times out. Zero means no timeout.
1094  *
1095  * @return Returns 0 on success, or a non-zero value on failure.
1096  */
1097 int32_t
1098 sli_fcp_iwrite64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint32_t first_data_sge,
1099  uint32_t xfer_len, uint32_t first_burst, uint16_t xri, uint16_t tag, uint16_t cq_id,
1100  uint32_t rpi, ocs_remote_node_t *rnode,
1101  uint8_t dif, uint8_t bs, uint8_t timeout)
1102 {
1103  sli4_fcp_iwrite64_wqe_t *iwrite = buf;
1104  sli4_sge_t *sge = NULL;
1105 
1106  ocs_memset(buf, 0, size);
1107 
1108  if (!sgl || !sgl->virt) {
1109  ocs_log_err(sli4->os, "bad parameter sgl=%p virt=%p\n",
1110  sgl, sgl ? sgl->virt : NULL);
1111  return -1;
1112  }
1113  sge = sgl->virt;
1114 
1115  if (sli4->config.sgl_pre_registered) {
1116  iwrite->xbl = FALSE;
1117 
1118  iwrite->dbde = TRUE;
1119  iwrite->bde.bde_type = SLI4_BDE_TYPE_BDE_64;
1120 
1121  iwrite->bde.buffer_length = sge[0].buffer_length;
1122  iwrite->bde.u.data.buffer_address_low = sge[0].buffer_address_low;
1123  iwrite->bde.u.data.buffer_address_high = sge[0].buffer_address_high;
1124  } else {
1125  iwrite->xbl = TRUE;
1126 
1127  iwrite->bde.bde_type = SLI4_BDE_TYPE_BLP;
1128 
1129  iwrite->bde.buffer_length = sgl->size;
1130  iwrite->bde.u.blp.sgl_segment_address_low = ocs_addr32_lo(sgl->phys);
1131  iwrite->bde.u.blp.sgl_segment_address_high = ocs_addr32_hi(sgl->phys);
1132 
1133  /* fill out fcp_cmnd buffer len and change resp buffer to be of type
1134  * "skip" (note: response will still be written to sge[1] if necessary) */
1135  iwrite->fcp_cmd_buffer_length = sge[0].buffer_length;
1136  sge[1].sge_type = SLI4_SGE_TYPE_SKIP;
1137  }
1138 
1139  iwrite->payload_offset_length = sge[0].buffer_length + sge[1].buffer_length;
1140  iwrite->total_transfer_length = xfer_len;
1141  iwrite->initial_transfer_length = MIN(xfer_len, first_burst);
1142 
1143  iwrite->xri_tag = xri;
1144  iwrite->context_tag = rpi;
1145 
1146  iwrite->timer = timeout;
1147 
1148  iwrite->pu = 2; // WQE word 4 contains read transfer length
1150  iwrite->command = SLI4_WQE_FCP_IWRITE64;
1152  iwrite->dif = dif;
1153  iwrite->bs = bs;
1154 
1155  iwrite->abort_tag = xri;
1156 
1157  iwrite->request_tag = tag;
1158  iwrite->len_loc = 3;
1159  if (rnode->node_group) {
1160  iwrite->hlm = TRUE;
1161  iwrite->remote_n_port_id = rnode->fc_id & 0x00ffffff;
1162  }
1164  iwrite->cq_id = cq_id;
1165 
1166  if (sli4->config.perf_hint) {
1168  iwrite->first_data_bde.buffer_length = sge[first_data_sge].buffer_length;
1169  iwrite->first_data_bde.u.data.buffer_address_low = sge[first_data_sge].buffer_address_low;
1170  iwrite->first_data_bde.u.data.buffer_address_high = sge[first_data_sge].buffer_address_high;
1171  }
1172 
1173  return 0;
1174 }
1175 
1176 /**
1177  * @ingroup sli_fc
1178  * @brief Write an FCP_TRECEIVE64_WQE work queue entry.
1179  *
1180  * @param sli4 SLI context.
1181  * @param buf Destination buffer for the WQE.
1182  * @param size Buffer size, in bytes.
1183  * @param sgl DMA memory for the Scatter-Gather List.
1184  * @param first_data_sge Index of first data sge (used if perf hints are enabled)
1185  * @param relative_off Relative offset of the IO (if any).
1186  * @param xfer_len Data transfer length.
1187  * @param xri XRI for this exchange.
1188  * @param tag IO tag value.
1189  * @param xid OX_ID for the exchange.
1190  * @param cq_id The id of the completion queue where the WQE response is sent.
1191  * @param rpi remote node indicator (RPI)
1192  * @param rnode Destination request (i.e. remote node).
1193  * @param flags Optional attributes, including:
1194  * - ACTIVE - IO is already active.
1195  * - AUTO RSP - Automatically generate a good FCP_RSP.
1196  * @param dif T10 DIF operation, or 0 to disable.
1197  * @param bs T10 DIF block size, or 0 if DIF is disabled.
1198  * @param csctl value of csctl field.
1199  * @param app_id value for VM application header.
1200  *
1201  * @return Returns 0 on success, or a non-zero value on failure.
1202  */
1203 int32_t
1204 sli_fcp_treceive64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint32_t first_data_sge,
1205  uint32_t relative_off, uint32_t xfer_len, uint16_t xri, uint16_t tag, uint16_t cq_id,
1206  uint16_t xid, uint32_t rpi, ocs_remote_node_t *rnode, uint32_t flags, uint8_t dif, uint8_t bs,
1207  uint8_t csctl, uint32_t app_id, uint8_t timer)
1208 {
1209  sli4_fcp_treceive64_wqe_t *trecv = buf;
1210  sli4_fcp_128byte_wqe_t *trecv_128 = buf;
1211  sli4_sge_t *sge = NULL;
1212  bool iftype_g7 = (SLI4_IF_TYPE_LANCER_G7 == sli4->if_type) ? true : false;
1213  /* BZ 217434 - Disable pbde use till proper fix to work around prism asic issue */
1214  bool disable_pbde = true;
1215 
1216  ocs_memset(buf, 0, size);
1217 
1218  if (!sgl || !sgl->virt) {
1219  ocs_log_err(sli4->os, "bad parameter sgl=%p virt=%p\n",
1220  sgl, sgl ? sgl->virt : NULL);
1221  return -1;
1222  }
1223  sge = sgl->virt;
1224 
1225  if (sli4->config.sgl_pre_registered) {
1226  trecv->xbl = FALSE;
1227 
1228  if (!dif && !disable_pbde && iftype_g7 && (xfer_len <= sge[2].buffer_length) && (!relative_off)) {
1229 
1230  /* For single bde, use the pbde optimization. This is expected to give latency
1231  benefit with G7 */
1232  trecv->pbde = true;
1234  trecv->first_data_bde.buffer_length = sge[2].buffer_length;
1235  trecv->first_data_bde.u.data.buffer_address_low = sge[2].buffer_address_low;
1236  trecv->first_data_bde.u.data.buffer_address_high = sge[2].buffer_address_high;
1237  } else {
1238  trecv->dbde = TRUE;
1240 
1241  trecv->bde.buffer_length = sge[0].buffer_length;
1242  trecv->bde.u.data.buffer_address_low = sge[0].buffer_address_low;
1243  trecv->bde.u.data.buffer_address_high = sge[0].buffer_address_high;
1244 
1245  trecv->payload_offset_length = sge[0].buffer_length;
1246  }
1247  } else {
1248  trecv->xbl = TRUE;
1249 
1250  // if data is a single physical address, use a BDE
1251  if (!dif && (xfer_len <= sge[2].buffer_length)) {
1252  trecv->dbde = TRUE;
1254 
1255  trecv->bde.buffer_length = sge[2].buffer_length;
1256  trecv->bde.u.data.buffer_address_low = sge[2].buffer_address_low;
1257  trecv->bde.u.data.buffer_address_high = sge[2].buffer_address_high;
1258  } else {
1259  trecv->bde.bde_type = SLI4_BDE_TYPE_BLP;
1260  trecv->bde.buffer_length = sgl->size;
1261  trecv->bde.u.blp.sgl_segment_address_low = ocs_addr32_lo(sgl->phys);
1262  trecv->bde.u.blp.sgl_segment_address_high = ocs_addr32_hi(sgl->phys);
1263  }
1264  }
1265 
1266  trecv->relative_offset = relative_off;
1267 
1268  if (flags & SLI4_IO_CONTINUATION) {
1269  trecv->xc = TRUE;
1270  }
1271  trecv->xri_tag = xri;
1272 
1273  trecv->context_tag = rpi;
1274 
1275  trecv->pu = TRUE; // WQE uses relative offset
1276 
1277  if (flags & SLI4_IO_AUTO_GOOD_RESPONSE) {
1278  trecv->ar = TRUE;
1279  }
1280 
1284  trecv->dif = dif;
1285  trecv->bs = bs;
1286  trecv->timer = timer;
1287 
1288  trecv->remote_xid = xid;
1289 
1290  trecv->request_tag = tag;
1291 
1292  trecv->iod = 1;
1293 
1294  trecv->len_loc = 0x2;
1295 
1296  if (rnode->node_group) {
1297  trecv->hlm = TRUE;
1298  trecv->dword5.dword = rnode->fc_id & 0x00ffffff;
1299  }
1300 
1302 
1303  trecv->cq_id = cq_id;
1304 
1305  trecv->fcp_data_receive_length = xfer_len;
1306 
1307  if (sli4->config.perf_hint) {
1309  trecv->first_data_bde.buffer_length = sge[first_data_sge].buffer_length;
1310  trecv->first_data_bde.u.data.buffer_address_low = sge[first_data_sge].buffer_address_low;
1311  trecv->first_data_bde.u.data.buffer_address_high = sge[first_data_sge].buffer_address_high;
1312  }
1313 
1314  /* The upper 7 bits of csctl is the priority */
1315  if (csctl & SLI4_MASK_CCP) {
1316  trecv->ccpe = 1;
1317  trecv->ccp = (csctl & SLI4_MASK_CCP);
1318  }
1319 
1320  if (app_id && (sli4->config.wqe_size == SLI4_WQE_EXT_BYTES) && !trecv->eat) {
1321  trecv->app_id_valid = 1;
1322  trecv->wqes = 1;
1323  trecv_128->dw[31] = app_id;
1324  }
1325  return 0;
1326 }
1327 
1328 /**
1329  * @ingroup sli_fc
1330  * @brief Write an FCP_CONT_TRECEIVE64_WQE work queue entry.
1331  *
1332  * @param sli4 SLI context.
1333  * @param buf Destination buffer for the WQE.
1334  * @param size Buffer size, in bytes.
1335  * @param sgl DMA memory for the Scatter-Gather List.
1336  * @param first_data_sge Index of first data sge (used if perf hints are enabled)
1337  * @param relative_off Relative offset of the IO (if any).
1338  * @param xfer_len Data transfer length.
1339  * @param xri XRI for this exchange.
1340  * @param sec_xri Secondary XRI for this exchange. (BZ 161832 workaround)
1341  * @param tag IO tag value.
1342  * @param xid OX_ID for the exchange.
1343  * @param cq_id The id of the completion queue where the WQE response is sent.
1344  * @param rpi remote node indicator (RPI)
1345  * @param rnode Destination request (i.e. remote node).
1346  * @param flags Optional attributes, including:
1347  * - ACTIVE - IO is already active.
1348  * - AUTO RSP - Automatically generate a good FCP_RSP.
1349  * @param dif T10 DIF operation, or 0 to disable.
1350  * @param bs T10 DIF block size, or 0 if DIF is disabled.
1351  * @param csctl value of csctl field.
1352  * @param app_id value for VM application header.
1353  *
1354  * @return Returns 0 on success, or a non-zero value on failure.
1355  */
1356 int32_t
1357 sli_fcp_cont_treceive64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint32_t first_data_sge,
1358  uint32_t relative_off, uint32_t xfer_len, uint16_t xri, uint16_t sec_xri, uint16_t tag,
1359  uint16_t cq_id, uint16_t xid, uint32_t rpi, ocs_remote_node_t *rnode, uint32_t flags,
1360  uint8_t dif, uint8_t bs, uint8_t csctl, uint32_t app_id, uint8_t timer)
1361 {
1362  int32_t rc;
1363 
1364  rc = sli_fcp_treceive64_wqe(sli4, buf, size, sgl, first_data_sge, relative_off, xfer_len, xri, tag,
1365  cq_id, xid, rpi, rnode, flags, dif, bs, csctl, app_id, timer);
1366  if (rc == 0) {
1367  sli4_fcp_treceive64_wqe_t *trecv = buf;
1368 
1370  trecv->dword5.sec_xri_tag = sec_xri;
1371  }
1372  return rc;
1373 }
1374 
1375 /**
1376  * @ingroup sli_fc
1377  * @brief Write an FCP_TRSP64_WQE work queue entry.
1378  *
1379  * @param sli4 SLI context.
1380  * @param buf Destination buffer for the WQE.
1381  * @param size Buffer size, in bytes.
1382  * @param sgl DMA memory for the Scatter-Gather List.
1383  * @param rsp_len Response data length.
1384  * @param xri XRI for this exchange.
1385  * @param tag IO tag value.
1386  * @param cq_id The id of the completion queue where the WQE response is sent.
1387  * @param xid OX_ID for the exchange.
1388  * @param rpi remote node indicator (RPI)
1389  * @param rnode Destination request (i.e. remote node).
1390  * @param flags Optional attributes, including:
1391  * - ACTIVE - IO is already active
1392  * - AUTO RSP - Automatically generate a good FCP_RSP.
1393  * @param csctl value of csctl field.
1394  * @param port_owned 0/1 to indicate if the XRI is port owned (used to set XBL=0)
1395  * @param app_id value for VM application header.
1396  *
1397  * @return Returns 0 on success, or a non-zero value on failure.
1398  */
1399 int32_t
1400 sli_fcp_trsp64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint32_t rsp_len,
1401  uint16_t xri, uint16_t tag, uint16_t cq_id, uint16_t xid, uint32_t rpi, ocs_remote_node_t *rnode,
1402  uint32_t flags, uint8_t csctl, uint8_t port_owned, uint32_t app_id)
1403 {
1404  sli4_fcp_trsp64_wqe_t *trsp = buf;
1405  sli4_fcp_128byte_wqe_t *trsp_128 = buf;
1406 
1407  ocs_memset(buf, 0, size);
1408 
1409  if (flags & SLI4_IO_AUTO_GOOD_RESPONSE) {
1410  trsp->ag = TRUE;
1411  /*
1412  * The SLI-4 documentation states that the BDE is ignored when
1413  * using auto-good response, but, at least for IF_TYPE 0 devices,
1414  * this does not appear to be true.
1415  */
1416  if (SLI4_IF_TYPE_BE3_SKH_PF == sli4->if_type) {
1417  trsp->bde.buffer_length = 12; // byte size of RSP
1418  }
1419  } else {
1420  sli4_sge_t *sge = sgl->virt;
1421 
1422  if (sli4->config.sgl_pre_registered || port_owned) {
1423  trsp->dbde = TRUE;
1424  } else {
1425  trsp->xbl = TRUE;
1426  }
1427 
1429  trsp->bde.buffer_length = sge[0].buffer_length;
1430  trsp->bde.u.data.buffer_address_low = sge[0].buffer_address_low;
1431  trsp->bde.u.data.buffer_address_high = sge[0].buffer_address_high;
1432 
1433  trsp->fcp_response_length = rsp_len;
1434  }
1435 
1436  if (flags & SLI4_IO_CONTINUATION) {
1437  trsp->xc = TRUE;
1438  }
1439 
1440  if (rnode->node_group) {
1441  trsp->hlm = TRUE;
1442  trsp->dword5 = rnode->fc_id & 0x00ffffff;
1443  }
1444 
1445  trsp->xri_tag = xri;
1446  trsp->rpi = rpi;
1447 
1448  trsp->command = SLI4_WQE_FCP_TRSP64;
1450 
1451  trsp->remote_xid = xid;
1452  trsp->request_tag = tag;
1453  trsp->dnrx = ((flags & SLI4_IO_DNRX) == 0 ? 0 : 1);
1454  trsp->len_loc = 0x1;
1455  trsp->cq_id = cq_id;
1457 
1458  /* The upper 7 bits of csctl is the priority */
1459  if (csctl & SLI4_MASK_CCP) {
1460  trsp->ccpe = 1;
1461  trsp->ccp = (csctl & SLI4_MASK_CCP);
1462  }
1463 
1464  if (app_id && (sli4->config.wqe_size == SLI4_WQE_EXT_BYTES) && !trsp->eat) {
1465  trsp->app_id_valid = 1;
1466  trsp->wqes = 1;
1467  trsp_128->dw[31] = app_id;
1468  }
1469  return 0;
1470 }
1471 
1472 /**
1473  * @ingroup sli_fc
1474  * @brief Write an FCP_TSEND64_WQE work queue entry.
1475  *
1476  * @param sli4 SLI context.
1477  * @param buf Destination buffer for the WQE.
1478  * @param size Buffer size, in bytes.
1479  * @param sgl DMA memory for the scatter gather list.
1480  * @param first_data_sge Index of first data sge (used if perf hints are enabled)
1481  * @param relative_off Relative offset of the IO (if any).
1482  * @param xfer_len Data transfer length.
1483  * @param xri XRI for this exchange.
1484  * @param tag IO tag value.
1485  * @param cq_id The id of the completion queue where the WQE response is sent.
1486  * @param xid OX_ID for the exchange.
1487  * @param rpi remote node indicator (RPI)
1488  * @param rnode Destination request (i.e. remote node).
1489  * @param flags Optional attributes, including:
1490  * - ACTIVE - IO is already active.
1491  * - AUTO RSP - Automatically generate a good FCP_RSP.
1492  * @param dif T10 DIF operation, or 0 to disable.
1493  * @param bs T10 DIF block size, or 0 if DIF is disabled.
1494  * @param csctl value of csctl field.
1495  * @param app_id value for VM application header.
1496  *
1497  * @return Returns 0 on success, or a non-zero value on failure.
1498  */
1499 int32_t
1500 sli_fcp_tsend64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint32_t first_data_sge,
1501  uint32_t relative_off, uint32_t xfer_len,
1502  uint16_t xri, uint16_t tag, uint16_t cq_id, uint16_t xid, uint32_t rpi, ocs_remote_node_t *rnode,
1503  uint32_t flags, uint8_t dif, uint8_t bs, uint8_t csctl, uint32_t app_id)
1504 {
1505  sli4_fcp_tsend64_wqe_t *tsend = buf;
1506  sli4_fcp_128byte_wqe_t *tsend_128 = buf;
1507  sli4_sge_t *sge = NULL;
1508 
1509  ocs_memset(buf, 0, size);
1510 
1511  if (!sgl || !sgl->virt) {
1512  ocs_log_err(sli4->os, "bad parameter sgl=%p virt=%p\n",
1513  sgl, sgl ? sgl->virt : NULL);
1514  return -1;
1515  }
1516  sge = sgl->virt;
1517 
1518  if (sli4->config.sgl_pre_registered) {
1519  tsend->xbl = FALSE;
1520 
1521  tsend->dbde = TRUE;
1523 
1524  // TSEND64_WQE specifies first two SGE are skipped (i.e. 3rd is valid)
1525  tsend->bde.buffer_length = sge[2].buffer_length;
1526  tsend->bde.u.data.buffer_address_low = sge[2].buffer_address_low;
1527  tsend->bde.u.data.buffer_address_high = sge[2].buffer_address_high;
1528  } else {
1529  tsend->xbl = TRUE;
1530 
1531  // if data is a single physical address, use a BDE
1532  if (!dif && (xfer_len <= sge[2].buffer_length)) {
1533  tsend->dbde = TRUE;
1535  // TSEND64_WQE specifies first two SGE are skipped (i.e. 3rd is valid)
1536  tsend->bde.buffer_length = sge[2].buffer_length;
1537  tsend->bde.u.data.buffer_address_low = sge[2].buffer_address_low;
1538  tsend->bde.u.data.buffer_address_high = sge[2].buffer_address_high;
1539  } else {
1540  tsend->bde.bde_type = SLI4_BDE_TYPE_BLP;
1541  tsend->bde.buffer_length = sgl->size;
1542  tsend->bde.u.blp.sgl_segment_address_low = ocs_addr32_lo(sgl->phys);
1543  tsend->bde.u.blp.sgl_segment_address_high = ocs_addr32_hi(sgl->phys);
1544  }
1545  }
1546 
1547  tsend->relative_offset = relative_off;
1548 
1549  if (flags & SLI4_IO_CONTINUATION) {
1550  tsend->xc = TRUE;
1551  }
1552  tsend->xri_tag = xri;
1553 
1554  tsend->rpi = rpi;
1555 
1556  tsend->pu = TRUE; // WQE uses relative offset
1557 
1558  if (flags & SLI4_IO_AUTO_GOOD_RESPONSE) {
1559  tsend->ar = TRUE;
1560  if (flags & SLI4_IO_SUPPRESS_RESPONSE) {
1561  tsend->suppress_rsp = TRUE;
1562  }
1563  }
1564 
1565  tsend->command = SLI4_WQE_FCP_TSEND64;
1568  tsend->dif = dif;
1569  tsend->bs = bs;
1570 
1571  tsend->remote_xid = xid;
1572 
1573  tsend->request_tag = tag;
1574 
1575  tsend->len_loc = 0x2;
1576 
1577  if (rnode->node_group) {
1578  tsend->hlm = TRUE;
1579  tsend->dword5 = rnode->fc_id & 0x00ffffff;
1580  }
1581 
1582  tsend->cq_id = cq_id;
1583 
1585 
1586  tsend->fcp_data_transmit_length = xfer_len;
1587 
1588  if (sli4->config.perf_hint) {
1590  tsend->first_data_bde.buffer_length = sge[first_data_sge].buffer_length;
1591  tsend->first_data_bde.u.data.buffer_address_low = sge[first_data_sge].buffer_address_low;
1592  tsend->first_data_bde.u.data.buffer_address_high = sge[first_data_sge].buffer_address_high;
1593  }
1594 
1595  /* The upper 7 bits of csctl is the priority */
1596  if (csctl & SLI4_MASK_CCP) {
1597  tsend->ccpe = 1;
1598  tsend->ccp = (csctl & SLI4_MASK_CCP);
1599  }
1600 
1601  if (app_id && (sli4->config.wqe_size == SLI4_WQE_EXT_BYTES) && !tsend->eat) {
1602  tsend->app_id_valid = 1;
1603  tsend->wqes = 1;
1604  tsend_128->dw[31] = app_id;
1605  }
1606  return 0;
1607 }
1608 
1609 /**
1610  * @ingroup sli_fc
1611  * @brief Write a GEN_REQUEST64 work queue entry.
1612  *
1613  * @note This WQE is only used to send FC-CT commands.
1614  *
1615  * @param sli4 SLI context.
1616  * @param buf Destination buffer for the WQE.
1617  * @param size Buffer size, in bytes.
1618  * @param sgl DMA memory for the request.
1619  * @param req_len Length of request.
1620  * @param max_rsp_len Max length of response.
1621  * @param timeout Time, in seconds, before an IO times out. Zero means infinite.
1622  * @param xri XRI for this exchange.
1623  * @param tag IO tag value.
1624  * @param cq_id The id of the completion queue where the WQE response is sent.
1625  * @param rnode Destination of request (that is, the remote node).
1626  * @param r_ctl R_CTL value for sequence.
1627  * @param type TYPE value for sequence.
1628  * @param df_ctl DF_CTL value for sequence.
1629  *
1630  * @return Returns 0 on success, or a non-zero value on failure.
1631  */
1632 int32_t
1633 sli_gen_request64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl,
1634  uint32_t req_len, uint32_t max_rsp_len, uint8_t timeout,
1635  uint16_t xri, uint16_t tag, uint16_t cq_id, ocs_remote_node_t *rnode,
1636  uint8_t r_ctl, uint8_t type, uint8_t df_ctl)
1637 {
1638  sli4_gen_request64_wqe_t *gen = buf;
1639  sli4_sge_t *sge = NULL;
1640 
1641  ocs_memset(buf, 0, size);
1642 
1643  if (!sgl || !sgl->virt) {
1644  ocs_log_err(sli4->os, "bad parameter sgl=%p virt=%p\n",
1645  sgl, sgl ? sgl->virt : NULL);
1646  return -1;
1647  }
1648  sge = sgl->virt;
1649 
1650  if (sli4->config.sgl_pre_registered) {
1651  gen->xbl = FALSE;
1652 
1653  gen->dbde = TRUE;
1655 
1656  gen->bde.buffer_length = req_len;
1657  gen->bde.u.data.buffer_address_low = sge[0].buffer_address_low;
1658  gen->bde.u.data.buffer_address_high = sge[0].buffer_address_high;
1659  } else {
1660  gen->xbl = TRUE;
1661 
1663 
1664  gen->bde.buffer_length = 2 * sizeof(sli4_sge_t);
1665  gen->bde.u.blp.sgl_segment_address_low = ocs_addr32_lo(sgl->phys);
1666  gen->bde.u.blp.sgl_segment_address_high = ocs_addr32_hi(sgl->phys);
1667  }
1668 
1669  gen->request_payload_length = req_len;
1670  gen->max_response_payload_length = max_rsp_len;
1671 
1672  gen->df_ctl = df_ctl;
1673  gen->type = type;
1674  gen->r_ctl = r_ctl;
1675 
1676  gen->xri_tag = xri;
1677 
1679  gen->context_tag = rnode->indicator;
1680 
1682 
1684 
1685  gen->timer = timeout;
1686 
1687  gen->request_tag = tag;
1688 
1690 
1691  gen->qosd = TRUE;
1692 
1693  if (rnode->node_group) {
1694  gen->hlm = TRUE;
1695  gen->remote_n_port_id = rnode->fc_id & 0x00ffffff;
1696  }
1697 
1699 
1700  gen->cq_id = cq_id;
1701 
1702  return 0;
1703 }
1704 
1705 /**
1706  * @ingroup sli_fc
1707  * @brief Write a SEND_FRAME work queue entry
1708  *
1709  * @param sli4 SLI context.
1710  * @param buf Destination buffer for the WQE.
1711  * @param size Buffer size, in bytes.
1712  * @param sof Start of frame value
1713  * @param eof End of frame value
1714  * @param hdr Pointer to FC header data
1715  * @param payload DMA memory for the payload.
1716  * @param req_len Length of payload.
1717  * @param timeout Time, in seconds, before an IO times out. Zero means infinite.
1718  * @param xri XRI for this exchange.
1719  * @param req_tag IO tag value.
1720  *
1721  * @return Returns 0 on success, or a non-zero value on failure.
1722  */
1723 int32_t
1724 sli_send_frame_wqe(sli4_t *sli4, void *buf, size_t size, uint8_t sof, uint8_t eof, uint32_t *hdr,
1725  ocs_dma_t *payload, uint32_t req_len, uint8_t timeout,
1726  uint16_t xri, uint16_t req_tag)
1727 {
1728  sli4_send_frame_wqe_t *sf = buf;
1729 
1730  ocs_memset(buf, 0, size);
1731 
1732  sf->dbde = TRUE;
1733  sf->bde.buffer_length = req_len;
1734  sf->bde.u.data.buffer_address_low = ocs_addr32_lo(payload->phys);
1735  sf->bde.u.data.buffer_address_high = ocs_addr32_hi(payload->phys);
1736 
1737  /* Copy FC header */
1738  sf->fc_header_0_1[0] = hdr[0];
1739  sf->fc_header_0_1[1] = hdr[1];
1740  sf->fc_header_2_5[0] = hdr[2];
1741  sf->fc_header_2_5[1] = hdr[3];
1742  sf->fc_header_2_5[2] = hdr[4];
1743  sf->fc_header_2_5[3] = hdr[5];
1744 
1745  sf->frame_length = req_len;
1746 
1747  sf->xri_tag = xri;
1748  sf->pu = 0;
1749  sf->context_tag = 0;
1750 
1751 
1752  sf->ct = 0;
1755  sf->timer = timeout;
1756 
1757  sf->request_tag = req_tag;
1758  sf->eof = eof;
1759  sf->sof = sof;
1760 
1761  sf->qosd = 0;
1762  sf->lenloc = 1;
1763  sf->xc = 0;
1764 
1765  sf->xbl = 1;
1766 
1768  sf->cq_id = 0xffff;
1769 
1770  return 0;
1771 }
1772 
1773 /**
1774  * @ingroup sli_fc
1775  * @brief Write a XMIT_SEQUENCE64 work queue entry.
1776  *
1777  * This WQE is used to send FC-CT response frames.
1778  *
1779  * @note This API implements a restricted use for this WQE, a TODO: would
1780  * include passing in sequence initiative, and full SGL's
1781  *
1782  * @param sli4 SLI context.
1783  * @param buf Destination buffer for the WQE.
1784  * @param size Buffer size, in bytes.
1785  * @param payload DMA memory for the request.
1786  * @param payload_len Length of request.
1787  * @param timeout Time, in seconds, before an IO times out. Zero means infinite.
1788  * @param ox_id originator exchange ID
1789  * @param xri XRI for this exchange.
1790  * @param tag IO tag value.
1791  * @param rnode Destination of request (that is, the remote node).
1792  * @param r_ctl R_CTL value for sequence.
1793  * @param type TYPE value for sequence.
1794  * @param df_ctl DF_CTL value for sequence.
1795  *
1796  * @return Returns 0 on success, or a non-zero value on failure.
1797  */
1798 int32_t
1799 sli_xmit_sequence64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *payload,
1800  uint32_t payload_len, uint8_t timeout, uint16_t ox_id,
1801  uint16_t xri, uint16_t tag, ocs_remote_node_t *rnode,
1802  uint8_t r_ctl, uint8_t type, uint8_t df_ctl)
1803 {
1804  sli4_xmit_sequence64_wqe_t *xmit = buf;
1805 
1806  ocs_memset(buf, 0, size);
1807 
1808  if ((payload == NULL) || (payload->virt == NULL)) {
1809  ocs_log_err(sli4->os, "bad parameter sgl=%p virt=%p\n",
1810  payload, payload ? payload->virt : NULL);
1811  return -1;
1812  }
1813 
1814  if (sli4->config.sgl_pre_registered) {
1815  xmit->dbde = TRUE;
1816  } else {
1817  xmit->xbl = TRUE;
1818  }
1819 
1821  xmit->bde.buffer_length = payload_len;
1822  xmit->bde.u.data.buffer_address_low = ocs_addr32_lo(payload->phys);
1823  xmit->bde.u.data.buffer_address_high = ocs_addr32_hi(payload->phys);
1824  xmit->sequence_payload_len = payload_len;
1825 
1826  xmit->remote_n_port_id = rnode->fc_id & 0x00ffffff;
1827 
1828  xmit->relative_offset = 0;
1829 
1830  xmit->si = 0; /* sequence initiative - this matches what is seen from
1831  * FC switches in response to FCGS commands */
1832  xmit->ft = 0; /* force transmit */
1833  xmit->xo = 0; /* exchange responder */
1834  xmit->ls = 1; /* last in seqence */
1835  xmit->df_ctl = df_ctl;
1836  xmit->type = type;
1837  xmit->r_ctl = r_ctl;
1838 
1839  xmit->xri_tag = xri;
1840  xmit->context_tag = rnode->indicator;
1841 
1842  xmit->dif = 0;
1844  xmit->bs = 0;
1845 
1848  xmit->pu = 0;
1849  xmit->timer = timeout;
1850 
1851  xmit->abort_tag = 0;
1852  xmit->request_tag = tag;
1853  xmit->remote_xid = ox_id;
1854 
1856 
1857  if (rnode->node_group) {
1858  xmit->hlm = TRUE;
1859  xmit->remote_n_port_id = rnode->fc_id & 0x00ffffff;
1860  }
1861 
1863 
1864  xmit->len_loc = 2;
1865 
1866  xmit->cq_id = 0xFFFF;
1867 
1868  return 0;
1869 }
1870 
1871 /**
1872  * @ingroup sli_fc
1873  * @brief Write a REQUEUE_XRI_WQE work queue entry.
1874  *
1875  * @param sli4 SLI context.
1876  * @param buf Destination buffer for the WQE.
1877  * @param size Buffer size, in bytes.
1878  * @param xri XRI for this exchange.
1879  * @param tag IO tag value.
1880  * @param cq_id The id of the completion queue where the WQE response is sent.
1881  *
1882  * @return Returns 0 on success, or a non-zero value on failure.
1883  */
1884 int32_t
1885 sli_requeue_xri_wqe(sli4_t *sli4, void *buf, size_t size, uint16_t xri, uint16_t tag, uint16_t cq_id)
1886 {
1887  sli4_requeue_xri_wqe_t *requeue = buf;
1888 
1889  ocs_memset(buf, 0, size);
1890 
1891  requeue->command = SLI4_WQE_REQUEUE_XRI;
1892  requeue->xri_tag = xri;
1893  requeue->request_tag = tag;
1894  requeue->xc = 1;
1895  requeue->qosd = 1;
1896  requeue->cq_id = cq_id;
1897  requeue->disable_cqe = 1; // Disable Completion CQE
1899  return 0;
1900 }
1901 
1902 int32_t
1903 sli_xmit_bcast64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *payload,
1904  uint32_t payload_len, uint8_t timeout, uint16_t xri, uint16_t tag,
1905  uint16_t cq_id, ocs_remote_node_t *rnode,
1906  uint8_t r_ctl, uint8_t type, uint8_t df_ctl)
1907 {
1908  sli4_xmit_bcast64_wqe_t *bcast = buf;
1909 
1910  /* Command requires a temporary RPI (i.e. unused remote node) */
1911  if (rnode->attached) {
1912  ocs_log_test(sli4->os, "remote node %d in use\n", rnode->indicator);
1913  return -1;
1914  }
1915 
1916  ocs_memset(buf, 0, size);
1917 
1918  bcast->dbde = TRUE;
1920  bcast->sequence_payload.buffer_length = payload_len;
1921  bcast->sequence_payload.u.data.buffer_address_low = ocs_addr32_lo(payload->phys);
1922  bcast->sequence_payload.u.data.buffer_address_high = ocs_addr32_hi(payload->phys);
1923 
1924  bcast->sequence_payload_length = payload_len;
1925 
1926  bcast->df_ctl = df_ctl;
1927  bcast->type = type;
1928  bcast->r_ctl = r_ctl;
1929 
1930  bcast->xri_tag = xri;
1931 
1933  bcast->context_tag = rnode->sport->indicator;
1934 
1936 
1937  bcast->command = SLI4_WQE_XMIT_BCAST64;
1938 
1939  bcast->timer = timeout;
1940 
1941  bcast->request_tag = tag;
1942 
1943  bcast->temporary_rpi = rnode->indicator;
1944 
1945  bcast->len_loc = 0x1;
1946 
1948 
1950 
1951  bcast->cq_id = cq_id;
1952 
1953  return 0;
1954 }
1955 
1956 /**
1957  * @ingroup sli_fc
1958  * @brief Write an XMIT_BLS_RSP64_WQE work queue entry.
1959  *
1960  * @param sli4 SLI context.
1961  * @param buf Destination buffer for the WQE.
1962  * @param size Buffer size, in bytes.
1963  * @param payload Contents of the BLS payload to be sent.
1964  * @param xri XRI for this exchange.
1965  * @param tag IO tag value.
1966  * @param cq_id The id of the completion queue where the WQE response is sent.
1967  * @param rnode Destination of request (that is, the remote node).
1968  * @param s_id Source ID to use in the response. If UINT32_MAX, use SLI Port's ID.
1969  *
1970  * @return Returns 0 on success, or a non-zero value on failure.
1971  */
1972 int32_t
1973 sli_xmit_bls_rsp64_wqe(sli4_t *sli4, void *buf, size_t size, sli_bls_payload_t *payload,
1974  uint16_t xri, uint16_t tag, uint16_t cq_id, ocs_remote_node_t *rnode, uint32_t s_id)
1975 {
1976  sli4_xmit_bls_rsp_wqe_t *bls = buf;
1977 
1978  /*
1979  * Callers can either specify RPI or S_ID, but not both
1980  */
1981  if (rnode->attached && (s_id != UINT32_MAX)) {
1982  ocs_log_test(sli4->os, "S_ID specified for attached remote node %d\n",
1983  rnode->indicator);
1984  return -1;
1985  }
1986 
1987  ocs_memset(buf, 0, size);
1988 
1989  if (SLI_BLS_ACC == payload->type) {
1990  bls->payload_word0 = (payload->u.acc.seq_id_last << 16) |
1991  (payload->u.acc.seq_id_validity << 24);
1992  bls->high_seq_cnt = payload->u.acc.high_seq_cnt;
1993  bls->low_seq_cnt = payload->u.acc.low_seq_cnt;
1994  } else if (SLI_BLS_RJT == payload->type) {
1995  bls->payload_word0 = *((uint32_t *)&payload->u.rjt);
1996  bls->ar = TRUE;
1997  } else {
1998  ocs_log_test(sli4->os, "bad BLS type %#x\n",
1999  payload->type);
2000  return -1;
2001  }
2002 
2003  bls->ox_id = payload->ox_id;
2004  bls->rx_id = payload->rx_id;
2005 
2006  if (rnode->attached) {
2008  bls->context_tag = rnode->indicator;
2009  } else {
2011  bls->context_tag = rnode->sport->indicator;
2012 
2013  if (UINT32_MAX != s_id) {
2014  bls->local_n_port_id = s_id & 0x00ffffff;
2015  } else {
2016  bls->local_n_port_id = rnode->sport->fc_id & 0x00ffffff;
2017  }
2018  bls->remote_id = rnode->fc_id & 0x00ffffff;
2019 
2020  bls->temporary_rpi = rnode->indicator;
2021  }
2022 
2023  bls->xri_tag = xri;
2024 
2026 
2028 
2029  bls->request_tag = tag;
2030 
2031  bls->qosd = TRUE;
2032 
2033  if (rnode->node_group) {
2034  bls->hlm = TRUE;
2035  bls->remote_id = rnode->fc_id & 0x00ffffff;
2036  }
2037 
2038  bls->cq_id = cq_id;
2039 
2041 
2042  return 0;
2043 }
2044 
2045 /**
2046  * @ingroup sli_fc
2047  * @brief Write a XMIT_ELS_RSP64_WQE work queue entry.
2048  *
2049  * @param sli4 SLI context.
2050  * @param buf Destination buffer for the WQE.
2051  * @param size Buffer size, in bytes.
2052  * @param rsp DMA memory for the ELS response.
2053  * @param rsp_len Length of ELS response, in bytes.
2054  * @param xri XRI for this exchange.
2055  * @param tag IO tag value.
2056  * @param cq_id The id of the completion queue where the WQE response is sent.
2057  * @param ox_id OX_ID of the exchange containing the request.
2058  * @param rnode Destination of the ELS response (that is, the remote node).
2059  * @param flags Optional attributes, including:
2060  * - SLI4_IO_CONTINUATION - IO is already active.
2061  * @param s_id S_ID used for special responses.
2062  *
2063  * @return Returns 0 on success, or a non-zero value on failure.
2064  */
2065 int32_t
2066 sli_xmit_els_rsp64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *rsp,
2067  uint32_t rsp_len, uint16_t xri, uint16_t tag, uint16_t cq_id,
2068  uint16_t ox_id, ocs_remote_node_t *rnode, uint32_t flags, uint32_t s_id)
2069 {
2070  sli4_xmit_els_rsp64_wqe_t *els = buf;
2071 
2072  ocs_memset(buf, 0, size);
2073 
2074  if (sli4->config.sgl_pre_registered) {
2075  els->dbde = TRUE;
2076  } else {
2077  els->xbl = TRUE;
2078  }
2079 
2081  els->els_response_payload.buffer_length = rsp_len;
2082  els->els_response_payload.u.data.buffer_address_low = ocs_addr32_lo(rsp->phys);
2083  els->els_response_payload.u.data.buffer_address_high = ocs_addr32_hi(rsp->phys);
2084 
2085  els->els_response_payload_length = rsp_len;
2086 
2087  els->xri_tag = xri;
2088 
2090 
2091  els->command = SLI4_WQE_ELS_RSP64;
2092 
2093  els->request_tag = tag;
2094 
2095  els->ox_id = ox_id;
2096 
2098 
2099  els->qosd = TRUE;
2100 
2101  if (flags & SLI4_IO_CONTINUATION) {
2102  els->xc = TRUE;
2103  }
2104 
2105  if (rnode->attached) {
2107  els->context_tag = rnode->indicator;
2108  } else {
2110  els->context_tag = rnode->sport->indicator;
2111  els->remote_id = rnode->fc_id & 0x00ffffff;
2112  els->temporary_rpi = rnode->indicator;
2113  if (UINT32_MAX != s_id) {
2114  els->sp = TRUE;
2115  els->s_id = s_id & 0x00ffffff;
2116  }
2117  }
2118 
2119  if (rnode->node_group) {
2120  els->hlm = TRUE;
2121  els->remote_id = rnode->fc_id & 0x00ffffff;
2122  }
2123 
2125 
2126  els->cq_id = cq_id;
2127 
2128  return 0;
2129 }
2130 
2131 /**
2132  * @ingroup sli_fc
2133  * @brief Process an asynchronous Link State event entry.
2134  *
2135  * @par Description
2136  * Parses Asynchronous Completion Queue Entry (ACQE),
2137  * creates an abstracted event, and calls registered callback functions.
2138  *
2139  * @param sli4 SLI context.
2140  * @param acqe Pointer to the ACQE.
2141  *
2142  * @return Returns 0 on success, or a non-zero value on failure.
2143  */
2144 int32_t
2146 {
2147  sli4_link_state_t *link_state = acqe;
2148  sli4_link_event_t event = { 0 };
2149  int32_t rc = 0;
2150 
2151  if (!sli4->link) {
2152  // bail if there is no callback
2153  return 0;
2154  }
2155 
2156  if (SLI4_LINK_TYPE_ETHERNET == link_state->link_type) {
2157  event.topology = SLI_LINK_TOPO_NPORT;
2159  } else {
2160  // TODO is this supported for anything other than FCoE?
2161  ocs_log_test(sli4->os, "unsupported link type %#x\n",
2162  link_state->link_type);
2163  event.topology = SLI_LINK_TOPO_MAX;
2164  event.medium = SLI_LINK_MEDIUM_MAX;
2165  rc = -1;
2166  }
2167 
2168  switch (link_state->port_link_status) {
2171  event.status = SLI_LINK_STATUS_DOWN;
2172  break;
2175  event.status = SLI_LINK_STATUS_UP;
2176  break;
2177  default:
2178  ocs_log_test(sli4->os, "unsupported link status %#x\n",
2179  link_state->port_link_status);
2180  event.status = SLI_LINK_STATUS_MAX;
2181  rc = -1;
2182  }
2183 
2184  switch (link_state->port_speed) {
2185  case 0:
2186  event.speed = 0;
2187  break;
2188  case 1:
2189  event.speed = 10;
2190  break;
2191  case 2:
2192  event.speed = 100;
2193  break;
2194  case 3:
2195  event.speed = 1000;
2196  break;
2197  case 4:
2198  event.speed = 10000;
2199  break;
2200  case 5:
2201  event.speed = 20000;
2202  break;
2203  case 6:
2204  event.speed = 25000;
2205  break;
2206  case 7:
2207  event.speed = 40000;
2208  break;
2209  case 8:
2210  event.speed = 100000;
2211  break;
2212  default:
2213  ocs_log_test(sli4->os, "unsupported port_speed %#x\n",
2214  link_state->port_speed);
2215  rc = -1;
2216  }
2217 
2218  sli4->link(sli4->link_arg, (void *)&event);
2219 
2220  return rc;
2221 }
2222 
2223 typedef struct sli4_tcm_parity_event_s {
2225  uint32_t tcm_address:24,
2226  ulp_id:8;
2227  uint32_t pbec:16,
2228  tpec:16;
2229  uint32_t :8,
2230  event_code:8,
2231  event_type:8,
2232  :6,
2233  async_event:1,
2234  valid:1;
2236 
2237 static void
2238 sli_fc_log_link_state(sli4_t *sli4, uint8_t state)
2239 {
2240  switch (state) {
2241  case 0:
2242  ocs_log_info(sli4->os, "Link is valid\n");
2243  break;
2244  case 1:
2245  ocs_log_info(sli4->os, "Link not present\n");
2246  break;
2247  case 2:
2248  ocs_log_info(sli4->os, "Link is present but incompatible physical media type\n");
2249  break;
2250  case 3:
2251  ocs_log_info(sli4->os, "Present, Unsupported PHY\n");
2252  break;
2253  default:
2254  ocs_log_err(sli4->os, "Unknown link state %d\n", state);
2255  break;
2256  }
2257 }
2258 
2259 static void
2261 {
2262  switch (sli4->config.port_number) {
2263  case 0:
2264  sli_fc_log_link_state(sli4, pe_acqe->p0_linkstate);
2265  break;
2266  case 1:
2267  sli_fc_log_link_state(sli4, pe_acqe->p1_linkstate);
2268  break;
2269  case 2:
2270  sli_fc_log_link_state(sli4, pe_acqe->p2_linkstate);
2271  break;
2272  case 3:
2273  sli_fc_log_link_state(sli4, pe_acqe->p3_linkstate);
2274  break;
2275  default:
2276  ocs_log_err(sli4->os, "Invalid port number %d\n", sli4->config.port_number);
2277  break;
2278  }
2279 }
2280 
2281 /**
2282  * @ingroup sli_fc
2283  * @brief Process an asynchronous sli port event.
2284  *
2285  * @par Description
2286  * Parses Asynchronous Completion Queue Entry (ACQE)
2287  * and logs driver debug messages for correct SFP link status
2288  *
2289  * @param sli4 SLI context.
2290  * @param acqe Pointer to the ACQE.
2291  *
2292  * @return Returns 0 on success, or a non-zero value on failure.
2293  */
2294 int32_t
2296 {
2297  sli4_port_event_acqe_t *pe_acqe = acqe;
2298  sli4_link_event_t event = { 0 };
2299 
2300  if (!sli4->link)
2301  return 0;
2302 
2303  switch (pe_acqe->event_type) {
2305  sli4_tcm_parity_event_t *evt = acqe;
2306 
2307  ocs_log_warn(sli4->os, "ITCM parity event detected; ULP id = %d, "\
2308  "parity_bit_error_count = %d, total_parity_error_count = %d\n",
2309  evt->ulp_id, evt->pbec, evt->tpec);
2310  break;
2311  }
2313  sli_fc_report_link_state(sli4, pe_acqe);
2314  break;
2315  default:
2316  ocs_log_err(sli4->os, "Unhandled async event type %d\n", pe_acqe->event_type);
2317  break;
2318  }
2319 
2321  sli4->link(sli4->link_arg, (void *)&event);
2322  return 0;
2323 }
2324 
2325 static uint32_t
2326 sli_fc_decode_port_speed(uint32_t speed_code)
2327 {
2328  uint32_t speed_gbps = 0;
2329 
2330  // Speed in Gbps
2331  switch (speed_code) {
2332  case SLI4_LINK_ATTN_8G:
2333  case SLI4_LINK_ATTN_10G:
2334  case SLI4_LINK_ATTN_16G:
2335  case SLI4_LINK_ATTN_32G:
2336  speed_gbps = speed_code;
2337  break;
2338  case SLI4_LINK_ATTN_64G:
2339  speed_gbps = 0x40;
2340  break;
2341  case SLI4_LINK_ATTN_128G:
2342  speed_gbps = 0x80;
2343  break;
2344  case SLI4_LINK_ATTN_256G:
2345  speed_gbps = 0x100;
2346  break;
2347  default:
2348  speed_gbps = speed_code;
2349  }
2350 
2351  // Return Mbps value
2352  return speed_gbps * 1000;
2353 }
2354 
2355 static int32_t
2357 {
2358  int32_t rc = 0;
2359 
2360  switch (link_attn->attn_type) {
2362  event->status = SLI_LINK_STATUS_UP;
2363  break;
2365  event->status = SLI_LINK_STATUS_DOWN;
2366  break;
2368  ocs_log_debug(sli4->os, "attn_type: no hard alpa\n");
2370  break;
2371  default:
2372  ocs_log_test(sli4->os, "attn_type: unknown\n");
2373  return -1;
2374  }
2375 
2376  switch (link_attn->topology) {
2377  case SLI4_LINK_ATTN_P2P:
2378  event->topology = SLI_LINK_TOPO_NPORT;
2379  break;
2380  case SLI4_LINK_ATTN_FC_AL:
2381  event->topology = SLI_LINK_TOPO_LOOP;
2382  break;
2384  ocs_log_debug(sli4->os, "topology Internal loopback\n");
2386  break;
2388  ocs_log_debug(sli4->os, "topology serdes loopback\n");
2390  break;
2391  default:
2392  ocs_log_test(sli4->os, "topology: unknown\n");
2393  rc = -1;
2394  break;
2395  }
2396 
2397  event->speed = sli_fc_decode_port_speed(link_attn->port_speed);
2398  return rc;
2399 }
2400 
2401 static void
2402 sli_fc_report_trunk_links(sli4_t *sli4, uint8_t ports_active, char *active_ports_str, size_t max_str_len)
2403 {
2404  char tmp[8];
2405  char *ptr = active_ports_str;
2406  int i;
2407 
2408  memset(active_ports_str, 0x0, max_str_len);
2409  for (i = 0; i < 4; i++) {
2410  if (!(ports_active & (1 << i)))
2411  continue;
2412  if (!ocs_strlen(active_ports_str)) {
2413  ocs_snprintf(tmp, sizeof(tmp), "%d", i);
2414  } else {
2415  ocs_snprintf(tmp, sizeof(tmp), ",%d", i);
2416  }
2417  if (ocs_strlen(active_ports_str) + ocs_strlen(tmp) > max_str_len)
2418  break;
2419  ocs_strcpy(ptr, tmp);
2420  ptr += ocs_strlen(tmp);
2421  }
2422  if (!ocs_strlen(active_ports_str)) {
2423  ocs_strcpy(active_ports_str, "None");
2424  }
2425 }
2426 
2427 static void
2429 {
2430  uint8_t ports_active;
2431  uint32_t potential_agg_speed;
2432  uint32_t current_trunk_speed;
2433  char active_ports_str[16];
2434 
2435  potential_agg_speed = sli_fc_decode_port_speed(link_attn->port_speed);
2436  current_trunk_speed = link_attn->logical_link_speed * 10; // is in units of 10 Mbps
2437 
2438  ports_active = link_attn->topology & SLI4_FC_TRUNK_LINK_STATE_MASK;
2439 
2440  switch (link_attn->topology & SLI4_FC_TRUNK_CONFIG_MASK) {
2442  // 2 port trunk, member ports 0/1
2443  sli_fc_report_trunk_links(sli4, ports_active, active_ports_str, sizeof(active_ports_str));
2444  ocs_log_debug(sli4->os,
2445  "[ Trunk ] Links=2, Ports={ Member={0,1}, Active={%s} }, Speed={max=%dMbps, current=%dMbps}\n",
2446  active_ports_str, potential_agg_speed, current_trunk_speed);
2447  break;
2449  // 2 port trunk, member ports 2/3
2450  sli_fc_report_trunk_links(sli4, ports_active, active_ports_str, sizeof(active_ports_str));
2451  ocs_log_debug(sli4->os,
2452  "[ Trunk ] Links=2, Ports={ Member={2,3}, Active={%s} }, Speed={max=%dMbps, current=%dMbps}\n",
2453  active_ports_str, potential_agg_speed, current_trunk_speed);
2454  break;
2456  // All 4 ports are members of the same trunk
2457  sli_fc_report_trunk_links(sli4, ports_active, active_ports_str, sizeof(active_ports_str));
2458  ocs_log_debug(sli4->os,
2459  "[ Trunk ] Links=4, Ports={ Member={0,1,2,3}, Active={%s} }, Speed={max=%dMbps, current=%dMbps}\n",
2460  active_ports_str, potential_agg_speed, current_trunk_speed);
2461  break;
2462  default:
2463  ocs_log_debug(sli4->os,
2464  "[ Trunk ] Invalid config: topology=%#x, reported max speed=%d Mbps, current speed=%d Mbps\n",
2465  link_attn->topology, potential_agg_speed, current_trunk_speed);
2466  }
2467 }
2468 
2469 /**
2470  * @ingroup sli_fc
2471  * @brief Process an asynchronous Link Attention event entry.
2472  *
2473  * @par Description
2474  * Parses Asynchronous Completion Queue Entry (ACQE),
2475  * creates an abstracted event, and calls the registered callback functions.
2476  *
2477  * @param sli4 SLI context.
2478  * @param acqe Pointer to the ACQE.
2479  *
2480  * @todo XXX all events return LINK_UP.
2481  *
2482  * @return Returns 0 on success, or a non-zero value on failure.
2483  */
2484 int32_t
2486 {
2487  sli4_link_attention_t *link_attn = acqe;
2488  sli4_link_event_t event = { 0 };
2489  int32_t rc = 0;
2490 
2491  ocs_log_debug(sli4->os, "link_number=%d attn_type=%#x topology=%#x port_speed=%#x "
2492  "port_fault=%#x shared_link_status=%#x logical_link_speed=%#x "
2493  "event_tag=%#x\n", link_attn->link_number, link_attn->attn_type,
2494  link_attn->topology, link_attn->port_speed, link_attn->port_fault,
2495  link_attn->shared_link_status, link_attn->logical_link_speed,
2496  link_attn->event_tag);
2497 
2498  if (!sli4->link) {
2499  return 0;
2500  }
2501 
2502  switch (link_attn->event_type) {
2504  ocs_log_debug(sli4->os, "event_type: SLI4_FC_EVENT_LINK_ATTENTION \n");
2505  break;
2507  ocs_log_debug(sli4->os, "event_type: FC shared link event \n");
2508  break;
2509  default:
2510  ocs_log_test(sli4->os, "event_type: unknown, %d\n", link_attn->event_type);
2511  break;
2512  }
2513 
2514  event.medium = SLI_LINK_MEDIUM_FC;
2515 
2516  switch (link_attn->attn_type) {
2520  rc = sli_fc_process_fc_link_attention(sli4, link_attn, &event);
2521  sli4->link(sli4->link_arg, (void *)&event);
2522  break;
2524  sli_fc_process_trunk_link_attention(sli4, link_attn);
2526  event.logical_link_speed = link_attn->logical_link_speed * 10; // is in units of 10 Mbps
2528  sli4->link(sli4->link_arg, (void *)&event);
2529  break;
2530  default:
2531  ocs_log_test(sli4->os, "attn_type: unknown\n");
2532  rc = -1;
2533  break;
2534  }
2535  return rc;
2536 }
2537 
2538 /**
2539  * @ingroup sli_fc
2540  * @brief Parse an FC/FCoE work queue CQ entry.
2541  *
2542  * @param sli4 SLI context.
2543  * @param cq CQ to process.
2544  * @param cqe Pointer to the CQ entry.
2545  * @param etype CQ event type.
2546  * @param r_id Resource ID associated with this completion message (such as the IO tag).
2547  *
2548  * @return Returns 0 on success, or a non-zero value on failure.
2549  */
2550 int32_t
2551 sli_fc_cqe_parse(sli4_t *sli4, sli4_queue_t *cq, uint8_t *cqe, sli4_qentry_e *etype,
2552  uint16_t *r_id)
2553 {
2554  uint8_t code = cqe[SLI4_CQE_CODE_OFFSET];
2555  int32_t rc = -1;
2556 
2557  switch (code) {
2559  {
2560  sli4_fc_wcqe_t *wcqe = (void *)cqe;
2561 
2562  *etype = SLI_QENTRY_WQ;
2563  *r_id = wcqe->request_tag;
2564  rc = wcqe->status;
2565 
2566  // Flag errors except for FCP_RSP_FAILURE
2567  if (rc && (rc != SLI4_FC_WCQE_STATUS_FCP_RSP_FAILURE)) {
2568  ocs_log_err(sli4->os, "WCQE: status=%#x hw_status=%#x tag=%#x w1=%#x w2=%#x xb=%d\n",
2569  wcqe->status, wcqe->hw_status, wcqe->request_tag,
2570  wcqe->wqe_specific_1, wcqe->wqe_specific_2, wcqe->xb);
2571  ocs_log_err(sli4->os, " %08X %08X %08X %08X\n", ((uint32_t *)cqe)[0],
2572  ((uint32_t *)cqe)[1], ((uint32_t *)cqe)[2], ((uint32_t *)cqe)[3]);
2573  }
2574 
2575 //TODO: need to pass additional status back out of here as well as status (could overload rc as status/addlstatus
2576 // are only 8 bits each)
2577  break;
2578  }
2580  {
2581  sli4_fc_async_rcqe_t *rcqe = (void *)cqe;
2582 
2583  *etype = SLI_QENTRY_RQ;
2584  *r_id = rcqe->rq_id;
2585  rc = rcqe->status;
2586  break;
2587  }
2589  {
2590  sli4_fc_async_rcqe_v1_t *rcqe = (void *)cqe;
2591 
2592  *etype = SLI_QENTRY_RQ;
2593  *r_id = rcqe->rq_id;
2594  rc = rcqe->status;
2595  break;
2596  }
2598  {
2599  sli4_fc_optimized_write_cmd_cqe_t *optcqe = (void *)cqe;
2600 
2601  *etype = SLI_QENTRY_OPT_WRITE_CMD;
2602  *r_id = optcqe->rq_id;
2603  rc = optcqe->status;
2604  break;
2605  }
2607  {
2608  sli4_fc_optimized_write_data_cqe_t *dcqe = (void *)cqe;
2609 
2610  *etype = SLI_QENTRY_OPT_WRITE_DATA;
2611  *r_id = dcqe->xri;
2612  rc = dcqe->status;
2613 
2614  // Flag errors
2615  if (rc != SLI4_FC_WCQE_STATUS_SUCCESS) {
2616  ocs_log_err(sli4->os, "Optimized DATA CQE: status=%#x ext_status=%#x hw_status=%#x xri=%#x dpl=%#x w3=%#x xb=%d\n",
2617  dcqe->status, ((uint32_t*) cqe)[2], dcqe->hw_status,
2618  dcqe->xri, dcqe->total_data_placed,
2619  ((uint32_t*) cqe)[3], dcqe->xb);
2620  }
2621  break;
2622  }
2624  {
2625  sli4_fc_coalescing_rcqe_t *rcqe = (void *)cqe;
2626 
2627  *etype = SLI_QENTRY_RQ;
2628  *r_id = rcqe->rq_id;
2629  rc = rcqe->status;
2630  break;
2631  }
2633  {
2634  sli4_fc_xri_aborted_cqe_t *xa = (void *)cqe;
2635 
2636  *etype = SLI_QENTRY_XABT;
2637  *r_id = xa->xri;
2638  rc = 0;
2639  break;
2640  }
2642  sli4_fc_wqec_t *wqec = (void*) cqe;
2643 
2644  *etype = SLI_QENTRY_WQ_RELEASE;
2645  *r_id = wqec->wq_id;
2646  rc = 0;
2647  break;
2648  }
2649  case SLI4_CQE_CODE_MARKER: {
2650  sli4_fc_marker_rcqe_t *marker_cqe = (void *)cqe;
2651 
2652  *etype = SLI_QENTRY_RQ;
2653  *r_id = marker_cqe->rq_id;
2654  rc = marker_cqe->status;
2655  break;
2656  }
2657  default:
2658  ocs_log_test(sli4->os, "CQE completion code %d not handled\n", code);
2659  *etype = SLI_QENTRY_MAX;
2660  *r_id = UINT16_MAX;
2661  }
2662 
2663  return rc;
2664 }
2665 
2666 /**
2667  * @ingroup sli_fc
2668  * @brief Return the ELS/CT response length.
2669  *
2670  * @param sli4 SLI context.
2671  * @param cqe Pointer to the CQ entry.
2672  *
2673  * @return Returns the length, in bytes.
2674  */
2675 uint32_t
2676 sli_fc_response_length(sli4_t *sli4, uint8_t *cqe)
2677 {
2678  sli4_fc_wcqe_t *wcqe = (void *)cqe;
2679 
2680  return wcqe->wqe_specific_1;
2681 }
2682 
2683 /**
2684  * @ingroup sli_fc
2685  * @brief Return the FCP IO length.
2686  *
2687  * @param sli4 SLI context.
2688  * @param cqe Pointer to the CQ entry.
2689  *
2690  * @return Returns the length, in bytes.
2691  */
2692 uint32_t
2693 sli_fc_io_length(sli4_t *sli4, uint8_t *cqe)
2694 {
2695  sli4_fc_wcqe_t *wcqe = (void *)cqe;
2696 
2697  return wcqe->wqe_specific_1;
2698 }
2699 
2700 /**
2701  * @ingroup sli_fc
2702  * @brief Retrieve the D_ID from the completion.
2703  *
2704  * @param sli4 SLI context.
2705  * @param cqe Pointer to the CQ entry.
2706  * @param d_id Pointer where the D_ID is written.
2707  *
2708  * @return Returns 0 on success, or a non-zero value on failure.
2709  */
2710 int32_t
2711 sli_fc_els_did(sli4_t *sli4, uint8_t *cqe, uint32_t *d_id)
2712 {
2713  sli4_fc_wcqe_t *wcqe = (void *)cqe;
2714 
2715  *d_id = 0;
2716 
2717  if (wcqe->status) {
2718  return -1;
2719  } else {
2720  *d_id = wcqe->wqe_specific_2 & 0x00ffffff;
2721  return 0;
2722  }
2723 }
2724 
2725 uint32_t
2726 sli_fc_ext_status(sli4_t *sli4, uint8_t *cqe)
2727 {
2728  sli4_fc_wcqe_t *wcqe = (void *)cqe;
2729  uint32_t mask;
2730 
2731  switch (wcqe->status) {
2733  mask = UINT32_MAX;
2734  break;
2737  mask = 0xff;
2738  break;
2744  mask = UINT32_MAX;
2745  break;
2747  mask = UINT32_MAX;
2748  break;
2749  default:
2750  mask = 0;
2751  }
2752 
2753  return wcqe->wqe_specific_2 & mask;
2754 }
2755 
2756 /**
2757  * @ingroup sli_fc
2758  * @brief Retrieve the RQ index from the completion.
2759  *
2760  * @param sli4 SLI context.
2761  * @param cqe Pointer to the CQ entry.
2762  * @param rq_id Pointer where the rq_id is written.
2763  * @param index Pointer where the index is written.
2764  *
2765  * @return Returns 0 on success, or a non-zero value on failure.
2766  */
2767 int32_t
2768 sli_fc_rqe_rqid_and_index(sli4_t *sli4, uint8_t *cqe, uint16_t *rq_id, uint32_t *index)
2769 {
2770  sli4_fc_async_rcqe_t *rcqe = (void *)cqe;
2771  sli4_fc_async_rcqe_v1_t *rcqe_v1 = (void *)cqe;
2772  int32_t rc = -1;
2773  uint8_t code = 0;
2774 
2775  *rq_id = 0;
2776  *index = UINT32_MAX;
2777 
2778  code = cqe[SLI4_CQE_CODE_OFFSET];
2779 
2780  if (code == SLI4_CQE_CODE_RQ_ASYNC) {
2781  *rq_id = rcqe->rq_id;
2782  if (SLI4_FC_ASYNC_RQ_SUCCESS == rcqe->status) {
2783  *index = rcqe->rq_element_index;
2784  rc = 0;
2785  } else {
2786  *index = rcqe->rq_element_index;
2787  rc = rcqe->status;
2788  ocs_log_err(sli4->os, "RCQE: status=%02x (%s) rq_id=%d, index=%x pdpl=%x sof=%02x eof=%02x hdpl=%x\n",
2789  rcqe->status, sli_fc_get_status_string(rcqe->status), rcqe->rq_id,
2791  rcqe->eof_byte, rcqe->header_data_placement_length);
2792  ocs_log_err(sli4->os, " %08X %08X %08X %08X\n", ((uint32_t *)cqe)[0],
2793  ((uint32_t *)cqe)[1], ((uint32_t *)cqe)[2], ((uint32_t *)cqe)[3]);
2794  }
2795  } else if (code == SLI4_CQE_CODE_RQ_ASYNC_V1) {
2796  *rq_id = rcqe_v1->rq_id;
2797  if (SLI4_FC_ASYNC_RQ_SUCCESS == rcqe_v1->status) {
2798  *index = rcqe_v1->rq_element_index;
2799  rc = 0;
2800  } else {
2801  *index = rcqe_v1->rq_element_index;
2802  rc = rcqe_v1->status;
2803  ocs_log_err(sli4->os, "RCQE: status=%02x (%s) rq_id=%d, index=%x pdpl=%x sof=%02x eof=%02x hdpl=%x\n",
2804  rcqe_v1->status, sli_fc_get_status_string(rcqe_v1->status), rcqe_v1->rq_id,
2805  rcqe_v1->rq_element_index, rcqe_v1->payload_data_placement_length, rcqe_v1->sof_byte,
2806  rcqe_v1->eof_byte, rcqe_v1->header_data_placement_length);
2807  ocs_log_err(sli4->os, " %08X %08X %08X %08X\n", ((uint32_t *)cqe)[0],
2808  ((uint32_t *)cqe)[1], ((uint32_t *)cqe)[2], ((uint32_t *)cqe)[3]);
2809  }
2810  } else if (code == SLI4_CQE_CODE_OPTIMIZED_WRITE_CMD) {
2811  sli4_fc_optimized_write_cmd_cqe_t *optcqe = (void *)cqe;
2812 
2813  *rq_id = optcqe->rq_id;
2814  if (SLI4_FC_ASYNC_RQ_SUCCESS == optcqe->status) {
2815  *index = optcqe->rq_element_index;
2816  rc = 0;
2817  } else {
2818  *index = optcqe->rq_element_index;
2819  rc = optcqe->status;
2820  ocs_log_test(sli4->os, "status=%02x (%s) rq_id=%d, index=%x pdpl=%x hdpl=%x oox=%d agxr=%d xri=0x%x rpi=0x%x\n",
2821  optcqe->status, sli_fc_get_status_string(optcqe->status), optcqe->rq_id,
2823  optcqe->header_data_placement_length, optcqe->oox, optcqe->tow, optcqe->xri,
2824  optcqe->rpi);
2825  }
2826  } else if (code == SLI4_CQE_CODE_RQ_COALESCING) {
2827  sli4_fc_coalescing_rcqe_t *rcqe = (void *)cqe;
2828 
2829  *rq_id = rcqe->rq_id;
2830  if (SLI4_FC_COALESCE_RQ_SUCCESS == rcqe->status) {
2831  *index = rcqe->rq_element_index;
2832  rc = 0;
2833  } else {
2834  *index = UINT32_MAX;
2835  rc = rcqe->status;
2836 
2837  ocs_log_test(sli4->os, "status=%02x (%s) rq_id=%d, index=%x rq_id=%#x sdpl=%x\n",
2838  rcqe->status, sli_fc_get_status_string(rcqe->status), rcqe->rq_id,
2840  }
2841  } else if (code == SLI4_CQE_CODE_MARKER) {
2842  sli4_fc_marker_rcqe_t *rcqe = (void *)cqe;
2843  *rq_id = rcqe->rq_id;
2844 
2845  if (SLI4_FC_ASYNC_RQ_SUCCESS == rcqe->status) {
2846  *index = rcqe->rq_element_index;
2847  rc = 0;
2848  } else {
2849  *index = UINT32_MAX;
2850  rc = rcqe->status;
2851  ocs_log_test(sli4->os, "marker rcqe failed. status=%d\n", rc);
2852  }
2853  } else {
2854  *index = UINT32_MAX;
2855 
2856  rc = rcqe->status;
2857 
2858  ocs_log_debug(sli4->os, "status=%02x rq_id=%d, index=%x pdpl=%x sof=%02x eof=%02x hdpl=%x\n",
2859  rcqe->status, rcqe->rq_id, rcqe->rq_element_index, rcqe->payload_data_placement_length,
2860  rcqe->sof_byte, rcqe->eof_byte, rcqe->header_data_placement_length);
2861  }
2862 
2863  return rc;
2864 }
2865 
2866 /**
2867  * @ingroup sli_fc
2868  * @brief Process an asynchronous FCoE event entry.
2869  *
2870  * @par Description
2871  * Parses Asynchronous Completion Queue Entry (ACQE),
2872  * creates an abstracted event, and calls the registered callback functions.
2873  *
2874  * @param sli4 SLI context.
2875  * @param acqe Pointer to the ACQE.
2876  *
2877  * @return Returns 0 on success, or a non-zero value on failure.
2878  */
2879 int32_t
2880 sli_fc_process_fcoe(sli4_t *sli4, void *acqe)
2881 {
2882  sli4_fcoe_fip_t *fcoe = acqe;
2883  sli4_fip_event_t event = { 0 };
2884  uint32_t mask = UINT32_MAX;
2885 
2886  ocs_log_debug(sli4->os, "ACQE FCoE FIP type=%02x count=%d tag=%#x\n",
2887  fcoe->event_type,
2888  fcoe->fcf_count,
2889  fcoe->event_tag);
2890 
2891  if (!sli4->fip) {
2892  return 0;
2893  }
2894 
2895  event.type = fcoe->event_type;
2896  event.index = UINT32_MAX;
2897 
2898  switch (fcoe->event_type) {
2900  ocs_log_debug(sli4->os, "FCF Discovered index=%d\n", fcoe->event_information);
2901  break;
2903  ocs_log_debug(sli4->os, "FCF Table Full\n");
2904  mask = 0;
2905  break;
2907  ocs_log_debug(sli4->os, "FCF Dead/Gone index=%d\n", fcoe->event_information);
2908  break;
2910  mask = UINT16_MAX;
2911  ocs_log_debug(sli4->os, "Clear VLINK Received VPI=%#x\n", fcoe->event_information & mask);
2912  break;
2914  ocs_log_debug(sli4->os, "FCF Modified\n");
2915  break;
2916  default:
2917  ocs_log_test(sli4->os, "bad FCoE type %#x", fcoe->event_type);
2918  mask = 0;
2919  }
2920 
2921  if (mask != 0) {
2922  event.index = fcoe->event_information & mask;
2923  }
2924 
2925  sli4->fip(sli4->fip_arg, &event);
2926 
2927  return 0;
2928 }
2929 
2930 /**
2931  * @ingroup sli_fc
2932  * @brief Allocate a receive queue.
2933  *
2934  * @par Description
2935  * Allocates DMA memory and configures the requested queue type.
2936  *
2937  * @param sli4 SLI context.
2938  * @param q Pointer to the queue object for the header.
2939  * @param n_entries Number of entries to allocate.
2940  * @param buffer_size buffer size for the queue.
2941  * @param cq Associated CQ.
2942  * @param ulp The ULP to bind
2943  * @param is_hdr Used to validate the rq_id and set the type of queue
2944  *
2945  * @return Returns 0 on success, or -1 on failure.
2946  */
2947 int32_t
2949  uint32_t n_entries, uint32_t buffer_size,
2950  sli4_queue_t *cq, uint16_t ulp, uint8_t is_hdr)
2951 {
2952  int32_t (*rq_create)(sli4_t *, void *, size_t, ocs_dma_t *, uint16_t, uint16_t, uint16_t);
2953 
2954  if ((sli4 == NULL) || (q == NULL)) {
2955  void *os = sli4 != NULL ? sli4->os : NULL;
2956 
2957  ocs_log_err(os, "bad parameter sli4=%p q=%p\n", sli4, q);
2958  return -1;
2959  }
2960 
2962  n_entries, SLI_PAGE_SIZE)) {
2963  return -1;
2964  }
2965 
2966  if (sli4->if_type == SLI4_IF_TYPE_BE3_SKH_PF) {
2967  rq_create = sli_cmd_fcoe_rq_create;
2968  } else {
2969  rq_create = sli_cmd_fcoe_rq_create_v1;
2970  }
2971 
2972  if (rq_create(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE, &q->dma,
2973  cq->id, ulp, buffer_size)) {
2974  if (__sli_create_queue(sli4, q)) {
2975  ocs_dma_free(sli4->os, &q->dma);
2976  return -1;
2977  }
2978  if (is_hdr && q->id & 1) {
2979  ocs_log_test(sli4->os, "bad header RQ_ID %d\n", q->id);
2980  ocs_dma_free(sli4->os, &q->dma);
2981  return -1;
2982  } else if (!is_hdr && (q->id & 1) == 0) {
2983  ocs_log_test(sli4->os, "bad data RQ_ID %d\n", q->id);
2984  ocs_dma_free(sli4->os, &q->dma);
2985  return -1;
2986  }
2987  } else {
2988  return -1;
2989  }
2990  q->u.flag.is_hdr = is_hdr;
2991  if (SLI4_IF_TYPE_BE3_SKH_PF == sli4->if_type) {
2992  q->u.flag.rq_batch = TRUE;
2993  }
2994  return 0;
2995 }
2996 
2997 
2998 /**
2999  * @ingroup sli_fc
3000  * @brief Allocate a receive queue set.
3001  *
3002  * @param sli4 SLI context.
3003  * @param num_rq_pairs to create
3004  * @param qs Pointers to the queue objects for both header and data.
3005  * Length of this arrays should be 2 * num_rq_pairs
3006  * @param base_cq_id. Assumes base_cq_id : (base_cq_id + num_rq_pairs) cqs as allotted.
3007  * @param n_entries number of entries in each RQ queue.
3008  * @param header_buffer_size
3009  * @param payload_buffer_size
3010  * @param ulp The ULP to bind
3011  *
3012  * @return Returns 0 on success, or -1 on failure.
3013  */
3014 int32_t
3015 sli_fc_rq_set_alloc(sli4_t *sli4, uint32_t num_rq_pairs,
3016  sli4_queue_t *qs[], uint32_t base_cq_id,
3017  uint32_t n_entries, uint32_t header_buffer_size,
3018  uint32_t payload_buffer_size, uint16_t ulp)
3019 {
3020  uint32_t i, p, offset = 0;
3021  uint32_t payload_size, total_page_count = 0;
3022  uintptr_t addr;
3023  ocs_dma_t dma;
3025  sli4_req_fcoe_rq_create_v2_t *req = NULL;
3026 
3027  ocs_memset(&dma, 0, sizeof(dma));
3028 
3029  for (i = 0; i < (num_rq_pairs * 2); i++) {
3031  n_entries, SLI_PAGE_SIZE)) {
3032  goto error;
3033  }
3034  }
3035 
3036  total_page_count = sli_page_count(qs[0]->dma.size, SLI_PAGE_SIZE) * num_rq_pairs * 2;
3037 
3038  /* Payload length must accomodate both request and response */
3039  payload_size = max((sizeof(sli4_req_fcoe_rq_create_v1_t) + (8 * total_page_count)),
3041 
3042  if (ocs_dma_alloc(sli4->os, &dma, payload_size, SLI_PAGE_SIZE)) {
3043  ocs_log_err(sli4->os, "DMA allocation failed\n");
3044  goto error;
3045  }
3046  ocs_memset(dma.virt, 0, payload_size);
3047 
3048  if (sli_cmd_sli_config(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE,
3049  payload_size, &dma) == -1) {
3050  goto error;
3051  }
3052  req = (sli4_req_fcoe_rq_create_v2_t *)((uint8_t *)dma.virt);
3053 
3054  /* Fill Header fields */
3057  req->hdr.version = 2;
3059  + (8 * total_page_count);
3060 
3061  /* Fill Payload fields */
3062  req->num_pages = sli_page_count(qs[0]->dma.size, SLI_PAGE_SIZE);
3063  req->rqe_count = qs[0]->dma.size / SLI4_FCOE_RQE_SIZE;
3066  req->rq_count = num_rq_pairs * 2;
3067  req->base_cq_id = base_cq_id;
3068  req->hdr_buffer_size = header_buffer_size;
3069  req->payload_buffer_size = payload_buffer_size;
3070 
3071  for (i = 0; i < (num_rq_pairs * 2); i++) {
3072  for (p = 0, addr = qs[i]->dma.phys; p < req->num_pages; p++, addr += SLI_PAGE_SIZE) {
3073  req->page_physical_address[offset].low = ocs_addr32_lo(addr);
3074  req->page_physical_address[offset].high = ocs_addr32_hi(addr);
3075  offset++;
3076  }
3077  }
3078 
3079  if (sli_bmbx_command(sli4)){
3080  ocs_log_crit(sli4->os, "bootstrap mailbox write faild RQSet\n");
3081  goto error;
3082  }
3083 
3084 
3085  rsp = (void *)((uint8_t *)dma.virt);
3086  if (rsp->hdr.status) {
3087  ocs_log_err(sli4->os, "bad create RQSet status=%#x addl=%#x\n",
3088  rsp->hdr.status, rsp->hdr.additional_status);
3089  goto error;
3090  } else {
3091  for (i = 0; i < (num_rq_pairs * 2); i++) {
3092  qs[i]->id = i + rsp->q_id;
3093  if ((qs[i]->id & 1) == 0) {
3094  qs[i]->u.flag.is_hdr = TRUE;
3095  } else {
3096  qs[i]->u.flag.is_hdr = FALSE;
3097  }
3098  qs[i]->doorbell_offset = regmap[SLI4_REG_FCOE_RQ_DOORBELL][sli4->if_type].off;
3099  qs[i]->doorbell_rset = regmap[SLI4_REG_FCOE_RQ_DOORBELL][sli4->if_type].rset;
3100  }
3101  }
3102 
3103  ocs_dma_free(sli4->os, &dma);
3104 
3105  return 0;
3106 
3107 error:
3108  for (i = 0; i < (num_rq_pairs * 2); i++) {
3109  if (qs[i]->dma.size) {
3110  ocs_dma_free(sli4->os, &qs[i]->dma);
3111  }
3112  }
3113 
3114  if (dma.size) {
3115  ocs_dma_free(sli4->os, &dma);
3116  }
3117 
3118  return -1;
3119 }
3120 
3121 /**
3122  * @ingroup sli_fc
3123  * @brief Get the RPI resource requirements.
3124  *
3125  * @param sli4 SLI context.
3126  * @param n_rpi Number of RPIs desired.
3127  *
3128  * @return Returns the number of bytes needed. This value may be zero.
3129  */
3130 uint32_t
3131 sli_fc_get_rpi_requirements(sli4_t *sli4, uint32_t n_rpi)
3132 {
3133  uint32_t bytes = 0;
3134 
3135  /* Check if header templates needed */
3136  if (sli4->config.hdr_template_req) {
3137  /* round up to a page */
3139  }
3140 
3141  return bytes;
3142 }
3143 
3144 /**
3145  * @ingroup sli_fc
3146  * @brief Return a text string corresponding to a CQE status value
3147  *
3148  * @param status Status value
3149  *
3150  * @return Returns corresponding string, otherwise "unknown"
3151  */
3152 const char *
3154 {
3155  static struct {
3156  uint32_t code;
3157  const char *label;
3158  } lookup[] = {
3159  {SLI4_FC_WCQE_STATUS_SUCCESS, "SUCCESS"},
3160  {SLI4_FC_WCQE_STATUS_FCP_RSP_FAILURE, "FCP_RSP_FAILURE"},
3161  {SLI4_FC_WCQE_STATUS_REMOTE_STOP, "REMOTE_STOP"},
3162  {SLI4_FC_WCQE_STATUS_LOCAL_REJECT, "LOCAL_REJECT"},
3163  {SLI4_FC_WCQE_STATUS_NPORT_RJT, "NPORT_RJT"},
3164  {SLI4_FC_WCQE_STATUS_FABRIC_RJT, "FABRIC_RJT"},
3165  {SLI4_FC_WCQE_STATUS_NPORT_BSY, "NPORT_BSY"},
3166  {SLI4_FC_WCQE_STATUS_FABRIC_BSY, "FABRIC_BSY"},
3167  {SLI4_FC_WCQE_STATUS_LS_RJT, "LS_RJT"},
3168  {SLI4_FC_WCQE_STATUS_CMD_REJECT, "CMD_REJECT"},
3169  {SLI4_FC_WCQE_STATUS_FCP_TGT_LENCHECK, "FCP_TGT_LENCHECK"},
3170  {SLI4_FC_WCQE_STATUS_RQ_BUF_LEN_EXCEEDED, "BUF_LEN_EXCEEDED"},
3171  {SLI4_FC_WCQE_STATUS_RQ_INSUFF_BUF_NEEDED, "RQ_INSUFF_BUF_NEEDED"},
3172  {SLI4_FC_WCQE_STATUS_RQ_INSUFF_FRM_DISC, "RQ_INSUFF_FRM_DESC"},
3173  {SLI4_FC_WCQE_STATUS_RQ_DMA_FAILURE, "RQ_DMA_FAILURE"},
3174  {SLI4_FC_WCQE_STATUS_FCP_RSP_TRUNCATE, "FCP_RSP_TRUNCATE"},
3175  {SLI4_FC_WCQE_STATUS_DI_ERROR, "DI_ERROR"},
3176  {SLI4_FC_WCQE_STATUS_BA_RJT, "BA_RJT"},
3177  {SLI4_FC_WCQE_STATUS_RQ_INSUFF_XRI_NEEDED, "RQ_INSUFF_XRI_NEEDED"},
3178  {SLI4_FC_WCQE_STATUS_RQ_INSUFF_XRI_DISC, "INSUFF_XRI_DISC"},
3179  {SLI4_FC_WCQE_STATUS_RX_ERROR_DETECT, "RX_ERROR_DETECT"},
3180  {SLI4_FC_WCQE_STATUS_RX_ABORT_REQUEST, "RX_ABORT_REQUEST"},
3181  };
3182  uint32_t i;
3183 
3184  for (i = 0; i < ARRAY_SIZE(lookup); i++) {
3185  if (status == lookup[i].code) {
3186  return lookup[i].label;
3187  }
3188  }
3189  return "unknown";
3190 }
3191 /* vim: set noexpandtab textwidth=120: */
sli4_req_hdr_t hdr
Definition: sli4_fc.h:163
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
#define SLI4_LINK_ATTN_16G
Definition: sli4_fc.h:1490
const char * sli_fc_get_status_string(uint32_t status)
Return a text string corresponding to a CQE status value.
Definition: sli4_fc.c:3153
int32_t(* link)(void *, void *)
Definition: sli4.h:3687
#define SLI4_CMD_FCP_TSEND64_WQE
Definition: sli4_fc.h:421
#define SLI4_CQE_CODE_RELEASE_WQE
Definition: sli4_fc.h:1887
ocs_os_handle_t os
Definition: sli4.h:3602
#define SLI4_FCOE_HDR_TEMPLATE_SIZE
Definition: sli4_fc.h:374
uint32_t sge_type
Definition: sli4.h:501
uint32_t page0_high
Definition: sli4_fc.h:157
uint32_t buffer_length
Definition: sli4.h:504
#define SLI4_FCOE_FIP_FCF_MODIFIED
Definition: sli4_fc.h:1550
int32_t sli_cmd_fcoe_post_hdr_templates(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma, uint16_t rpi, ocs_dma_t *payload_dma)
Write an FCOE_POST_HDR_TEMPLATES command.
Definition: sli4_fc.c:585
uint32_t rq_element_index
Definition: sli4_fc.h:1774
sli4_port_type_e port_type
Definition: sli4.h:3603
WQE used to create an FCP initiator no data command.
Definition: sli4_fc.h:633
WQE used to create an FCP initiator read.
Definition: sli4_fc.h:691
uint32_t page1_high
Definition: sli4_fc.h:159
void * fip_arg
Definition: sli4.h:3690
#define SLI4_WQE_FCP_TRECEIVE64
Definition: sli4_fc.h:401
uint32_t uint32_t xri_tag
Definition: sli4_fc.h:697
uint32_t fcp_cmd_buffer_length
Definition: sli4_fc.h:694
union sli4_bde_t::@27 u
Generic Common Create EQ/CQ/MQ/WQ/RQ Queue completion.
Definition: sli4.h:1831
sli4_bde_t sequence_payload
Definition: sli4_fc.h:1246
uint32_t hw_status
Definition: sli4_fc.h:1597
#define SLI4_FC_WCQE_STATUS_REMOTE_STOP
Definition: sli4_fc.h:1640
int32_t sli_fc_process_sli_port_event(sli4_t *sli4, void *acqe)
Process an asynchronous sli port event.
Definition: sli4_fc.c:2295
#define SLI4_WQE_XMIT_BLS_RSP
Definition: sli4_fc.h:408
#define SLI4_CQE_CODE_OPTIMIZED_WRITE_CMD
Definition: sli4_fc.h:1894
#define SLI4_CMD_ABORT_WQE
Definition: sli4_fc.h:425
#define SLI4_WQE_FCP_CONT_TRECEIVE64
Definition: sli4_fc.h:402
uint32_t uint32_t dword
Definition: sli4_fc.h:820
uint32_t uint32_t len_loc
Definition: sli4_fc.h:713
uint32_t tcm_parity_event
Definition: sli4_fc.c:2224
#define SLI4_FC_TRUNK_4_PORT_CONFIG
Definition: sli4_fc.h:1513
FCOE_RQ_DESTROY.
Definition: sli4_fc.h:284
#define SLI4_OPC_FCOE_WQ_DESTROY
Definition: sli4_fc.h:71
static int32_t sli_fc_process_fc_link_attention(sli4_t *sli4, sli4_link_attention_t *link_attn, sli4_link_event_t *event)
Definition: sli4_fc.c:2356
uint32_t uint32_t hlm
Definition: sli4_fc.h:655
#define SLI4_BDE_TYPE_BLP
Definition: sli4.h:492
#define SLI4_WQE_XMIT_SEQUENCE64
Definition: sli4_fc.h:410
uint32_t wq_id
Definition: sli4_fc.h:1623
uint32_t context_tag
Definition: sli4_fc.h:1077
uint32_t uint32_t hlm
Definition: sli4_fc.h:1328
uint32_t fc_header_2_5[4]
Definition: sli4_fc.h:1114
uint32_t criteria
Definition: sli4_fc.h:494
uint16_t size
Definition: sli4.h:3453
FCOE_REDISCOVER_FCF.
Definition: sli4_fc.h:379
uint32_t max_response_payload_length
Definition: sli4_fc.h:603
#define SLI4_PORT_LINK_STATUS_PHYSICAL_UP
Definition: sli4_fc.h:1568
#define SLI4_FC_WCQE_STATUS_FABRIC_BSY
Definition: sli4_fc.h:1645
#define SLI4_LINK_TYPE_ETHERNET
Definition: sli4_fc.h:1497
#define SLI4_FC_COALESCE_RQ_SUCCESS
Definition: sli4_fc.h:1814
#define SLI4_LINK_ATTN_64G
Definition: sli4_fc.h:1492
WQE used to create an FCP target send (DATA IN).
Definition: sli4_fc.h:940
#define SLI4_WQE_FCP_TSEND64
Definition: sli4_fc.h:404
uint32_t fcf_count
Definition: sli4_fc.h:1578
#define SLI4_ELS_REQUEST64_PLOGI
Definition: sli4_fc.h:624
#define SLI4_LINK_ATTN_TYPE_LINK_DOWN
Definition: sli4_fc.h:1476
uint32_t sequence_payload_length
Definition: sli4_fc.h:1248
#define SLI4_FCOE_FIP_FCF_DISCOVERED
Definition: sli4_fc.h:1546
FCOE_POST_HDR_TEMPLATES.
Definition: sli4_fc.h:363
int32_t sli_xmit_sequence64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *payload, uint32_t payload_len, uint8_t timeout, uint16_t ox_id, uint16_t xri, uint16_t tag, ocs_remote_node_t *rnode, uint8_t r_ctl, uint8_t type, uint8_t df_ctl)
Write a XMIT_SEQUENCE64 work queue entry.
Definition: sli4_fc.c:1799
uint32_t suppress_rsp
Definition: sli4_fc.h:985
uint32_t fcp_data_transmit_length
Definition: sli4_fc.h:991
#define SLI4_WQE_SIZE
Definition: sli4_fc.h:430
#define SLI4_ELS_REQUEST64_CMD_FABRIC
Definition: sli4_fc.h:628
WQE used to create a general request.
Definition: sli4_fc.h:1014
#define SLI4_FCOE_RQE_SIZE
Definition: sli4_fc.h:277
uint32_t uint32_t additional_status
Definition: sli4.h:1685
uint32_t uint32_t qosd
Definition: sli4_fc.h:513
struct sli_bls_payload_t::@52::@53 acc
#define SLI4_FC_TRUNK_LINK_STATE_MASK
Definition: sli4_fc.h:1501
uint32_t event_information
Definition: sli4_fc.h:1577
#define SLI4_FCOE_RQ_CREATE_V0_MAX_PAGES
Definition: sli4_fc.h:199
uint32_t buffer_length
Definition: sli4.h:469
uint8_t p3_linkstate
Definition: sli4.h:3366
#define SLI4_CMD_FCP_IWRITE64_WQE
Definition: sli4_fc.h:418
#define SLI4_FCOE_WQ_CREATE_V1_MAX_PAGES
Definition: sli4_fc.h:133
sli4_qentry_e
Definition: sli4.h:3436
#define SLI4_OPC_FCOE_RQ_DESTROY
Definition: sli4_fc.h:74
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 event_type
Definition: sli4_fc.h:1581
uint8_t dual_ulp_capable
Definition: sli4.h:3636
uint32_t event_tag
Definition: sli4_fc.h:1580
#define SLI4_FCOE_FIP_FCF_CLEAR_VLINK
Definition: sli4_fc.h:1549
#define SLI4_LINK_ATTN_8G
Definition: sli4_fc.h:1488
#define SLI4_CMD_XMIT_SEQUENCE64_WQE
Definition: sli4_fc.h:426
#define SLI4_CMD_FCP_TRECEIVE64_WQE
Definition: sli4_fc.h:419
uint32_t sgl_pre_registered
Definition: sli4.h:3654
#define SLI4_FC_EVENT_LINK_ATTENTION
Definition: sli4_fc.h:1554
#define SLI4_FC_WCQE_STATUS_LOCAL_REJECT
Definition: sli4_fc.h:1641
#define SLI4_CQE_CODE_MARKER
Definition: sli4_fc.h:1896
#define SLI4_FC_WCQE_STATUS_FABRIC_RJT
Definition: sli4_fc.h:1643
uint32_t relative_offset
Definition: sli4_fc.h:944
#define SLI4_FC_WCQE_STATUS_FCP_TGT_LENCHECK
Definition: sli4_fc.h:1648
uint32_t rset
Definition: sli4.h:3419
WQE used to create an ELS request.
Definition: sli4_fc.h:557
#define SLI_PAGE_SIZE
Definition: sli4.h:43
uint32_t header_data_placement_length
Definition: sli4_fc.h:1740
#define SLI4_CMD_XMIT_BLS_RSP64_WQE
Definition: sli4_fc.h:424
sli4_fcoe_post_sgl_page_desc_t page_desc[0]
Definition: sli4_fc.h:167
uint32_t hdr_template_req
Definition: sli4.h:3654
WQE used to create an ELS response.
Definition: sli4_fc.h:1394
uint32_t uint32_t disable_cqe
Definition: sli4_fc.h:1207
#define SLI4_CMD_SEND_FRAME_WQE
Definition: sli4_fc.h:428
#define SLI4_CMD_FCP_IREAD64_WQE
Definition: sli4_fc.h:416
FCOE_POST_SGL_PAGES.
Definition: sli4_fc.h:155
struct sli4_bde_t::@27::@28 data
int32_t sli_xmit_bcast64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *payload, uint32_t payload_len, uint8_t timeout, uint16_t xri, uint16_t tag, uint16_t cq_id, ocs_remote_node_t *rnode, uint8_t r_ctl, uint8_t type, uint8_t df_ctl)
Definition: sli4_fc.c:1903
#define SLI4_OPC_FCOE_POST_SGL_PAGES
Definition: sli4_fc.h:72
sli4_bde_t first_data_bde
Definition: sli4_fc.h:996
uint32_t uint32_t dbde
Definition: sli4_fc.h:713
#define SLI4_FCOE_FIP_FCF_TABLE_FULL
Definition: sli4_fc.h:1547
static void sli_fc_log_link_state(sli4_t *sli4, uint8_t state)
Definition: sli4_fc.c:2238
#define SLI4_FC_WCQE_STATUS_RQ_BUF_LEN_EXCEEDED
Definition: sli4_fc.h:1649
#define FC_ELS_CMD_FDISC
Definition: ocs_fcp.h:50
uint32_t uint32_t uint32_t xri_tag
Definition: sli4_fc.h:1398
WQE used to create an FCP target receive, and FCP target receive continue.
Definition: sli4_fc.h:809
uint32_t wqe_specific_2
Definition: sli4_fc.h:1601
uint32_t app_id_valid
Definition: sli4_fc.h:966
uint32_t uint32_t qosd
Definition: sli4_fc.h:1035
#define SLI4_WQE_GEN_REQUEST64
Definition: sli4_fc.h:405
uint32_t status
Definition: sli4_fc.h:1597
Asynchronouse Event: FCoE/FIP ACQE.
Definition: sli4_fc.h:1575
#define SLI4_IO_DNRX
Definition: sli4_fc.h:1002
#define SLI4_OPC_FCOE_POST_HDR_TEMPLATES
Definition: sli4_fc.h:76
uint32_t sli_fc_io_length(sli4_t *sli4, uint8_t *cqe)
Return the FCP IO length.
Definition: sli4_fc.c:2693
#define SLI4_OPC_FCOE_REDISCOVER_FCF
Definition: sli4_fc.h:77
#define SLI4_ELS_REQUEST64_LOGO
Definition: sli4_fc.h:621
sli4_bde_t bde
Definition: sli4_fc.h:879
#define SLI4_CMD_REQUEUE_XRI_WQE
Definition: sli4_fc.h:427
#define SLI4_CMD_GEN_REQUEST64_WQE
Definition: sli4_fc.h:422
#define SLI4_ELS_REQUEST64_CONTEXT_VPI
Definition: sli4_fc.h:610
uint32_t frame_length
Definition: sli4_fc.h:1075
uint32_t uint32_t uint32_t payload_data_placement_length
Definition: sli4_fc.h:1753
#define SLI4_WQE_FCP_ICMND64
Definition: sli4_fc.h:400
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 request_tag
Definition: sli4_fc.h:513
uint32_t cq_id
Definition: sli4_fc.h:532
#define SLI4_FC_WCQE_STATUS_FCP_RSP_TRUNCATE
Definition: sli4_fc.h:1653
uint32_t uint32_t hlm
Definition: sli4_fc.h:713
uint32_t uint32_t hlm
Definition: sli4_fc.h:768
uint32_t remote_n_port_id
Definition: sli4_fc.h:792
static void sli_fc_process_trunk_link_attention(sli4_t *sli4, sli4_link_attention_t *link_attn)
Definition: sli4_fc.c:2428
#define SLI4_FC_WCQE_STATUS_CMD_REJECT
Definition: sli4_fc.h:1647
#define SLI4_LINK_ATTN_SERDES_LOOPBACK
Definition: sli4_fc.h:1483
int32_t sli_xmit_els_rsp64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *rsp, uint32_t rsp_len, uint16_t xri, uint16_t tag, uint16_t cq_id, uint16_t ox_id, ocs_remote_node_t *rnode, uint32_t flags, uint32_t s_id)
Write a XMIT_ELS_RSP64_WQE work queue entry.
Definition: sli4_fc.c:2066
uint32_t uint32_t dbde
Definition: sli4_fc.h:1035
uint32_t request_tag
Definition: sli4_fc.h:902
WQE used to create a transmit sequence.
Definition: sli4_fc.h:1123
WQE used to abort exchanges.
Definition: sli4_fc.h:489
uint32_t max_response_payload_length
Definition: sli4_fc.h:1063
#define SLI4_WQE_SEND_FRAME
Definition: sli4_fc.h:406
uint32_t uint32_t uint32_t xri_tag
Definition: sli4_fc.h:561
uint32_t remote_xid
Definition: sli4_fc.h:902
uint32_t wqe_specific_1
Definition: sli4_fc.h:1600
#define FC_ELS_CMD_LOGO
Definition: ocs_fcp.h:45
FCOE_RQ_CREATE_V1.
Definition: sli4_fc.h:208
#define SLI4_WQE_EXT_BYTES
Definition: sli4_fc.h:434
#define SLI4_FC_WCQE_STATUS_SUCCESS
FC/FCoE Completion Status Codes.
Definition: sli4_fc.h:1638
#define SLI4_FC_EVENT_SHARED_LINK_ATTENTION
Definition: sli4_fc.h:1555
uint32_t uint32_t qosd
Definition: sli4_fc.h:1328
#define SLI4_CQE_CODE_XRI_ABORTED
Definition: sli4_fc.h:1889
int32_t sli_fc_rq_alloc(sli4_t *sli4, sli4_queue_t *q, uint32_t n_entries, uint32_t buffer_size, sli4_queue_t *cq, uint16_t ulp, uint8_t is_hdr)
Allocate a receive queue.
Definition: sli4_fc.c:2948
uint32_t app_id_valid
Definition: sli4_fc.h:904
struct sli4_t::@47 config
uint32_t doorbell_offset
Definition: sli4.h:3458
uint32_t initial_transfer_length
Definition: sli4_fc.h:753
uint32_t opcode
Definition: sli4.h:1668
uint8_t dpp
Definition: sli4.h:3679
#define SLI4_FCOE_RQ_CREATE_V0_MIN_BUF_SIZE
Definition: sli4_fc.h:200
uint32_t fcp_data_receive_length
Definition: sli4_fc.h:866
#define SLI4_LINK_ATTN_INTERNAL_LOOPBACK
Definition: sli4_fc.h:1482
#define SLI4_FC_WCQE_STATUS_RQ_INSUFF_XRI_NEEDED
Definition: sli4_fc.h:1656
Definition: sli4.h:3601
size_t wqe_size
Definition: sli4.h:3678
#define SLI4_BMBX_SIZE
Definition: sli4.h:150
#define SLI4_FC_WCQE_STATUS_RX_ERROR_DETECT
Definition: sli4_fc.h:1658
uint32_t sli_fc_get_rpi_requirements(sli4_t *sli4, uint32_t n_rpi)
Get the RPI resource requirements.
Definition: sli4_fc.c:3131
uint32_t local_n_port_id
Definition: sli4_fc.h:1310
#define SLI4_FCOE_RQ_CREATE_V0_MAX_BUF_SIZE
Definition: sli4_fc.h:201
#define SLI4_FC_WCQE_STATUS_RQ_INSUFF_XRI_DISC
Definition: sli4_fc.h:1657
uint32_t uint32_t len_loc
Definition: sli4_fc.h:655
WQE used to create a send frame request.
Definition: sli4_fc.h:1072
int32_t sli_cmd_fcoe_rq_create_v1(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *qmem, uint16_t cq_id, uint16_t ulp, uint16_t buffer_size)
Write an FCOE_RQ_CREATE_V1 command.
Definition: sli4_fc.c:426
#define SLI4_ABORT_CRITERIA_XRI_TAG
Definition: sli4_fc.h:542
uint32_t payload_data_placement_length
Definition: sli4_fc.h:1737
uint32_t request_tag
Definition: sli4_fc.h:964
#define SLI4_FC_WCQE_STATUS_RQ_INSUFF_FRM_DISC
Definition: sli4_fc.h:1651
FC/FCoE WQ completion queue entry.
Definition: sli4_fc.h:1595
#define SLI4_FCOE_RQ_PAGE_SIZE_4096
Definition: sli4_fc.h:271
uint32_t rq_element_index
Definition: sli4_fc.h:1732
#define SLI4_FC_WCQE_STATUS_NPORT_RJT
Definition: sli4_fc.h:1642
int32_t sli_requeue_xri_wqe(sli4_t *sli4, void *buf, size_t size, uint16_t xri, uint16_t tag, uint16_t cq_id)
Write a REQUEUE_XRI_WQE work queue entry.
Definition: sli4_fc.c:1885
#define SLI4_FCOE_RQE_SIZE_8
Definition: sli4_fc.h:265
#define SLI4_MAX_IF_TYPES
Definition: sli4.h:118
uint32_t uint32_t xbl
Definition: sli4_fc.h:1035
uint32_t rq_max_buf_size
Definition: sli4.h:3624
#define SLI4_ELS_REQUEST64_CONTEXT_RPI
Definition: sli4_fc.h:609
uint32_t fcp_cmd_buffer_length
Definition: sli4_fc.h:750
int32_t sli_fc_els_did(sli4_t *sli4, uint8_t *cqe, uint32_t *d_id)
Retrieve the D_ID from the completion.
Definition: sli4_fc.c:2711
uint32_t uint32_t ar
Definition: sli4_fc.h:1310
void * link_arg
Definition: sli4.h:3688
int32_t sli_fcp_treceive64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint32_t first_data_sge, uint32_t relative_off, uint32_t xfer_len, uint16_t xri, uint16_t tag, uint16_t cq_id, uint16_t xid, uint32_t rpi, ocs_remote_node_t *rnode, uint32_t flags, uint8_t dif, uint8_t bs, uint8_t csctl, uint32_t app_id, uint8_t timer)
Write an FCP_TRECEIVE64_WQE work queue entry.
Definition: sli4_fc.c:1204
#define SLI4_ELS_REQUEST64_CONTEXT_FCFI
Definition: sli4_fc.h:612
FCOE_READ_FCF_TABLE.
Definition: sli4_fc.h:300
uint32_t uint32_t iod
Definition: sli4_fc.h:1035
uint32_t page0_low
Definition: sli4_fc.h:156
struct sli4_t::@47::@50 extent[SLI_RSRC_MAX]
int32_t sli_fc_rq_set_alloc(sli4_t *sli4, uint32_t num_rq_pairs, sli4_queue_t *qs[], uint32_t base_cq_id, uint32_t n_entries, uint32_t header_buffer_size, uint32_t payload_buffer_size, uint16_t ulp)
Allocate a receive queue set.
Definition: sli4_fc.c:3015
sli4_req_hdr_t hdr
Definition: sli4_fc.h:285
#define SLI4_ACQE_PORT_EVENT_TYPE_MISCONF_PHYPORTS
Definition: sli4.h:3390
int32_t sli_send_frame_wqe(sli4_t *sli4, void *buf, size_t size, uint8_t sof, uint8_t eof, uint32_t *hdr, ocs_dma_t *payload, uint32_t req_len, uint8_t timeout, uint16_t xri, uint16_t req_tag)
Write a SEND_FRAME work queue entry.
Definition: sli4_fc.c:1724
sli4_physical_page_descriptor_t page_physical_address[8]
Definition: sli4_fc.h:127
sli4_bde_t first_data_bde
Definition: sli4_fc.h:741
uint32_t uint32_t relative_offset
Definition: sli4_fc.h:1126
#define SLI4_FCOE_FIP_FCF_DEAD
Definition: sli4_fc.h:1548
#define SLI4_WQE_FCP_IREAD64
Definition: sli4_fc.h:398
uint32_t uint32_t qosd
Definition: sli4_fc.h:1207
int32_t sli_cmd_fcoe_read_fcf_table(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *dma, uint16_t index)
Write an FCOE_READ_FCF_TABLE command.
Definition: sli4_fc.c:549
uint32_t request_tag
Definition: sli4_fc.h:655
#define SLI4_FC_TRUNK_CONFIG_MASK
Definition: sli4_fc.h:1500
uint32_t uint32_t len_loc
Definition: sli4_fc.h:768
struct sli4_queue_t::@44::@45 flag
#define FC_ELS_CMD_PLOGI
Definition: ocs_fcp.h:43
#define SLI4_LINK_ATTN_128G
Definition: sli4_fc.h:1493
uint32_t remote_n_port_id
Definition: sli4_fc.h:639
uint8_t p1_linkstate
Definition: sli4.h:3364
const char * SLI_QNAME[]
Definition: sli4.c:104
#define SLI4_CQE_CODE_OFFSET
Definition: sli4_fc.h:1884
sli4_req_hdr_t hdr
Definition: sli4_fc.h:95
uint16_t rq_min_buf_size
Definition: sli4.h:3623
#define SLI4_OPC_FCOE_WQ_CREATE
Definition: sli4_fc.h:70
#define SLI4_MASK_CCP
Definition: sli4_fc.h:437
uint32_t xri_count
Definition: sli4_fc.h:165
uint32_t uint32_t uint32_t context_tag
Definition: sli4_fc.h:1398
uint32_t payload_offset_length
Definition: sli4_fc.h:694
uint32_t version
Definition: sli4.h:1673
#define FC_ELS_CMD_FLOGI
Definition: ocs_fcp.h:44
int32_t sli_fcp_iread64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint32_t first_data_sge, uint32_t xfer_len, uint16_t xri, uint16_t tag, uint16_t cq_id, uint32_t rpi, ocs_remote_node_t *rnode, uint8_t dif, uint8_t bs, uint8_t timeout)
Write an FCP_IREAD64_WQE work queue entry.
Definition: sli4_fc.c:996
sli4_abort_type_e
Definition: sli4_fc.h:547
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
uint32_t uint32_t xc
Definition: sli4_fc.h:1207
WQE used unblock the specified XRI and to release it to the SLI Port&#39;s free pool. ...
Definition: sli4_fc.h:1187
uint32_t if_type
Definition: sli4.h:3607
uint16_t id
Definition: sli4.h:3456
#define SLI4_FC_WCQE_STATUS_NPORT_BSY
Definition: sli4_fc.h:1644
uint32_t perf_hint
Definition: sli4.h:3654
uint32_t ir
Definition: sli4_fc.h:494
#define FC_ELS_CMD_SCR
Definition: ocs_fcp.h:53
int32_t sli_abort_wqe(sli4_t *sli4, void *buf, size_t size, sli4_abort_type_e type, uint32_t send_abts, uint32_t ids, uint32_t mask, uint16_t tag, uint16_t cq_id)
Write an ABORT_WQE work queue entry.
Definition: sli4_fc.c:682
uint32_t uint32_t dbde
Definition: sli4_fc.h:655
uint32_t command
Definition: sli4_fc.h:503
#define SLI4_LINK_ATTN_32G
Definition: sli4_fc.h:1491
#define SLI4_FC_WCQE_STATUS_RQ_INSUFF_BUF_NEEDED
Definition: sli4_fc.h:1650
sli4_physical_page_descriptor_t page_physical_address[SLI4_FCOE_WQ_CREATE_V0_MAX_PAGES]
Definition: sli4_fc.h:101
FCOE_WQ_CREATE_V1.
Definition: sli4_fc.h:116
#define SLI4_FCOE_WQ_CREATE_V0_MAX_PAGES
FCOE_WQ_CREATE.
Definition: sli4_fc.h:92
uint32_t dw[32]
Definition: sli4_fc.h:802
uint16_t ox_id
Definition: sli4_fc.h:1370
uint32_t uint32_t context_tag
Definition: sli4_fc.h:639
int32_t sli_fc_process_fcoe(sli4_t *sli4, void *acqe)
Process an asynchronous FCoE event entry.
Definition: sli4_fc.c:2880
WQE used to create an FCP initiator write.
Definition: sli4_fc.h:747
uint32_t sli_fc_ext_status(sli4_t *sli4, uint8_t *cqe)
Definition: sli4_fc.c:2726
#define SLI4_FC_WCQE_STATUS_RX_ABORT_REQUEST
Definition: sli4_fc.h:1659
uint32_t subsystem
Definition: sli4.h:1668
Definition: sli4_fc.h:162
int32_t sli_cmd_fcoe_post_sgl_pages(sli4_t *sli4, void *buf, size_t size, uint16_t xri, uint32_t xri_count, ocs_dma_t *page0[], ocs_dma_t *page1[], ocs_dma_t *dma)
Write an FCOE_POST_SGL_PAGES command.
Definition: sli4_fc.c:276
#define SLI4_LINK_ATTN_TYPE_LINK_UP
Definition: sli4_fc.h:1475
FCOE_WQ_DESTROY.
Definition: sli4_fc.h:140
uint32_t event_type
Definition: sli4.h:3369
uint16_t doorbell_rset
Definition: sli4.h:3459
#define SLI4_CQE_CODE_WORK_REQUEST_COMPLETION
Definition: sli4_fc.h:1886
uint32_t xri_start
Definition: sli4_fc.h:165
static void sli_fc_report_link_state(sli4_t *sli4, sli4_port_event_acqe_t *pe_acqe)
Definition: sli4_fc.c:2260
FCOE_RQ_CREATE_V2.
Definition: sli4_fc.h:236
uint16_t rx_id
Definition: sli4_fc.h:1371
uint32_t header_data_placement_length
Definition: sli4_fc.h:1761
#define SLI4_CQE_CODE_RQ_COALESCING
Definition: sli4_fc.h:1890
#define SLI4_FC_ASYNC_RQ_SUCCESS
Definition: sli4_fc.h:1790
#define SLI4_ELS_REQUEST64_CLASS_3
Definition: sli4_fc.h:615
union sli4_fcp_treceive64_wqe_t::@51 dword5
uint32_t uint32_t dbde
Definition: sli4_fc.h:768
#define SLI4_ELS_REQUEST64_FDISC
Definition: sli4_fc.h:622
#define SLI4_FC_TRUNK_2_PORT_HI_CONFIG
Definition: sli4_fc.h:1510
sli4_bde_t els_response_payload
Definition: sli4_fc.h:1395
int32_t sli_fcp_icmnd64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint16_t xri, uint16_t tag, uint16_t cq_id, uint32_t rpi, ocs_remote_node_t *rnode, uint8_t timeout)
Write an FCP_ICMND64_WQE work queue entry.
Definition: sli4_fc.c:915
uint32_t uint32_t remote_id
Definition: sli4_fc.h:561
static void sli_fc_report_trunk_links(sli4_t *sli4, uint8_t ports_active, char *active_ports_str, size_t max_str_len)
Definition: sli4_fc.c:2402
int32_t sli_els_request64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint8_t req_type, uint32_t req_len, uint32_t max_rsp_len, uint8_t timeout, uint16_t xri, uint16_t tag, uint16_t cq_id, ocs_remote_node_t *rnode)
Write an ELS_REQUEST64_WQE work queue entry.
Definition: sli4_fc.c:744
#define SLI4_CMD_FCP_TRSP64_WQE
Definition: sli4_fc.h:420
WQE used to create an FCP target response.
Definition: sli4_fc.h:878
#define SLI4_FC_WCQE_STATUS_LS_RJT
Definition: sli4_fc.h:1646
struct sli4_bde_t::@27::@30 blp
uint32_t total_transfer_length
Definition: sli4_fc.h:696
sli4_req_hdr_t hdr
Definition: sli4_fc.h:141
#define SLI4_PORT_LINK_STATUS_LOGICAL_DOWN
Definition: sli4_fc.h:1569
#define SLI4_FC_WCQE_STATUS_BA_RJT
Definition: sli4_fc.h:1655
static uint32_t sli_page_count(size_t bytes, uint32_t page_size)
Definition: sli4.h:53
#define SLI4_ELS_REQUEST64_CMD_NON_FABRIC
Definition: sli4_fc.h:627
uint32_t request_payload_length
Definition: sli4_fc.h:1017
uint32_t uint32_t context_tag
Definition: sli4_fc.h:697
#define SLI4_LINK_ATTN_FC_AL
Definition: sli4_fc.h:1481
uint32_t els_response_payload_length
Definition: sli4_fc.h:1397
FC/FCoE WQ consumed CQ queue entry.
Definition: sli4_fc.h:1619
#define SLI4_WQE_ABORT
Definition: sli4_fc.h:395
uint32_t payload_offset_length
Definition: sli4_fc.h:750
uint32_t sli_fc_response_length(sli4_t *sli4, uint8_t *cqe)
Return the ELS/CT response length.
Definition: sli4_fc.c:2676
#define SLI4_ABORT_CRITERIA_REQUEST_TAG
Definition: sli4_fc.h:544
uint32_t sli4_bde_t first_data_bde
Definition: sli4_fc.h:792
#define SLI4_CQE_CODE_OPTIMIZED_WRITE_DATA
Definition: sli4_fc.h:1895
uint32_t buffer_address_low
Definition: sli4.h:500
#define SLI4_IF_TYPE_LANCER_G7
Definition: sli4.h:117
WQE used to create a BLS response.
Definition: sli4_fc.h:1302
int32_t sli_fc_process_link_attention(sli4_t *sli4, void *acqe)
Process an asynchronous Link Attention event entry.
Definition: sli4_fc.c:2485
#define SLI_ROUND_PAGE(b)
Definition: sli4.h:46
#define SLI4_OPC_FCOE_READ_FCF_TABLE
Definition: sli4_fc.h:75
uint32_t sequence_reporting_placement_length
Definition: sli4_fc.h:1803
int32_t sli_cmd_fcoe_rq_create(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *qmem, uint16_t cq_id, uint16_t ulp, uint16_t buffer_size)
Write an FCOE_RQ_CREATE command.
Definition: sli4_fc.c:345
int32_t __sli_create_queue(sli4_t *sli4, sli4_queue_t *q)
Issue the command to create a queue.
Definition: sli4.c:4893
sli4_physical_page_descriptor_t page_physical_address[0]
Definition: sli4_fc.h:254
#define SLI4_CMD_XMIT_BCAST64_WQE
Definition: sli4_fc.h:423
uint32_t xb
Definition: sli4_fc.h:1602
WQE used to send a single frame sequence to broadcast address.
Definition: sli4_fc.h:1245
uint32_t payload_offset_length
Definition: sli4_fc.h:636
sli4_physical_page_descriptor_t page_physical_address[8]
Definition: sli4_fc.h:193
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
static uint32_t sli_fc_decode_port_speed(uint32_t speed_code)
Definition: sli4_fc.c:2326
#define SLI4_LINK_ATTN_10G
Definition: sli4_fc.h:1489
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
#define SLI4_ELS_REQUEST64_DIR_WRITE
Definition: sli4_fc.h:617
#define SLI4_FC_WCQE_STATUS_FCP_RSP_FAILURE
Definition: sli4_fc.h:1639
ocs_dma_t bmbx
Definition: sli4.h:3692
#define SLI4_IO_AUTO_GOOD_RESPONSE
Definition: sli4_fc.h:1000
uint32_t uint32_t xri_tag
Definition: sli4_fc.h:639
sli_bls_type_e type
Definition: sli4_fc.h:1369
sli4_req_hdr_t hdr
Definition: sli4_fc.h:179
#define SLI4_WQE_ELS_RSP64
Definition: sli4_fc.h:409
sli4_bde_t els_request_payload
Definition: sli4_fc.h:558
#define SLI4_LINK_ATTN_TYPE_TRUNK_EVENT
Definition: sli4_fc.h:1478
#define SLI4_IF_TYPE_BE3_SKH_PF
Definition: sli4.h:113
#define SLI4_CQE_CODE_RQ_ASYNC
Definition: sli4_fc.h:1888
union sli_bls_payload_t::@52 u
sli4_physical_page_descriptor_t page_physical_address[8]
Definition: sli4_fc.h:224
#define SLI4_ELS_REQUEST64_DIR_READ
Definition: sli4_fc.h:618
uint32_t uint32_t xbl
Definition: sli4_fc.h:768
uint32_t index
Definition: sli4.h:3561
uint32_t uint32_t status
Definition: sli4.h:1685
uint32_t uint32_t xbl
Definition: sli4_fc.h:655
uint8_t port_number
Definition: sli4.h:3632
#define SLI4_IO_CONTINUATION
Definition: sli4_fc.h:999
uint32_t uint32_t remote_id
Definition: sli4_fc.h:1398
int32_t sli_gen_request64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint32_t req_len, uint32_t max_rsp_len, uint8_t timeout, uint16_t xri, uint16_t tag, uint16_t cq_id, ocs_remote_node_t *rnode, uint8_t r_ctl, uint8_t type, uint8_t df_ctl)
Write a GEN_REQUEST64 work queue entry.
Definition: sli4_fc.c:1633
uint32_t uint32_t uint32_t context_tag
Definition: sli4_fc.h:561
#define SLI4_WQE_FCP_IWRITE64
Definition: sli4_fc.h:399
#define SLI4_LINK_ATTN_TYPE_NO_HARD_ALPA
Definition: sli4_fc.h:1477
uint32_t buffer_address_high
Definition: sli4.h:499
#define SLI4_FCOE_RQ_CREATE_V1_MAX_PAGES
Definition: sli4_fc.h:261
uint32_t fcp_response_length
Definition: sli4_fc.h:881
#define SLI4_OPC_FCOE_RQ_CREATE
Definition: sli4_fc.h:73
#define SLI4_SUBSYSTEM_FCFCOE
Definition: sli4.h:1600
#define SLI4_FC_TRUNK_2_PORT_CONFIG
Definition: sli4_fc.h:1507
int32_t sli_xmit_bls_rsp64_wqe(sli4_t *sli4, void *buf, size_t size, sli_bls_payload_t *payload, uint16_t xri, uint16_t tag, uint16_t cq_id, ocs_remote_node_t *rnode, uint32_t s_id)
Write an XMIT_BLS_RSP64_WQE work queue entry.
Definition: sli4_fc.c:1973
int32_t sli_bmbx_command(sli4_t *sli4)
Submit a command to the bootstrap mailbox and check the status.
Definition: sli4.c:493
sli4_bde_t first_data_bde
Definition: sli4_fc.h:871
#define SLI4_FC_WCQE_STATUS_RQ_DMA_FAILURE
Definition: sli4_fc.h:1652
int32_t sli_fc_process_link_state(sli4_t *sli4, void *acqe)
Process an asynchronous Link State event entry.
Definition: sli4_fc.c:2145
#define SLI4_ELS_REQUEST64_OTHER
Definition: sli4_fc.h:620
int32_t sli_fcp_tsend64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint32_t first_data_sge, uint32_t relative_off, uint32_t xfer_len, uint16_t xri, uint16_t tag, uint16_t cq_id, uint16_t xid, uint32_t rpi, ocs_remote_node_t *rnode, uint32_t flags, uint8_t dif, uint8_t bs, uint8_t csctl, uint32_t app_id)
Write an FCP_TSEND64_WQE work queue entry.
Definition: sli4_fc.c:1500
uint32_t type
Definition: sli4.h:3560
uint32_t request_tag
Definition: sli4_fc.h:1089
int32_t sli_fcp_iwrite64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint32_t first_data_sge, uint32_t xfer_len, uint32_t first_burst, uint16_t xri, uint16_t tag, uint16_t cq_id, uint32_t rpi, ocs_remote_node_t *rnode, uint8_t dif, uint8_t bs, uint8_t timeout)
Write an FCP_IWRITE64_WQE work queue entry.
Definition: sli4_fc.c:1098
Scatter-Gather Entry (SGE)
Definition: sli4.h:497
uint32_t off
Definition: sli4.h:3420
#define SLI4_WQE_REQUEUE_XRI
Definition: sli4_fc.h:411
uint32_t bde_type
Definition: sli4.h:469
uint32_t els_request_payload_length
Definition: sli4_fc.h:560
#define SLI4_BDE_TYPE_BDE_64
Definition: sli4.h:490
#define SLI4_SGE_TYPE_SKIP
Definition: sli4.h:598
#define SLI4_ABORT_CRITERIA_ABORT_TAG
Definition: sli4_fc.h:543
uint32_t uint32_t iod
Definition: sli4_fc.h:713
uint32_t request_length
Definition: sli4.h:1672
uint32_t page1_low
Definition: sli4_fc.h:158
#define SLI4_WQE_XMIT_BCAST64
Definition: sli4_fc.h:407
#define SLI4_WQE_EXT_SIZE
Definition: sli4_fc.h:431
#define SLI4_WQE_FCP_TRSP64
Definition: sli4_fc.h:403
#define SLI4_LINK_ATTN_256G
Definition: sli4_fc.h:1494
Generic Command Request header.
Definition: sli4.h:1666
#define SLI4_PORT_LINK_STATUS_LOGICAL_UP
Definition: sli4_fc.h:1570
#define SLI4_IO_SUPPRESS_RESPONSE
Definition: sli4_fc.h:1003
Generic Command Response header.
Definition: sli4.h:1683
uint32_t cmd_type
Definition: sli4_fc.h:532
int32_t(* fip)(void *, void *)
Definition: sli4.h:3689
uint32_t request_tag
Definition: sli4_fc.h:1597
struct sli_bls_payload_t::@52::@54 rjt
uint32_t fc_header_0_1[2]
Definition: sli4_fc.h:1076
uint32_t remote_n_port_id
Definition: sli4_fc.h:697
uint8_t p0_linkstate
Definition: sli4.h:3363
#define SLI4_ELS_REQUEST64_FLOGIN
Definition: sli4_fc.h:623
uint32_t rq_element_index
Definition: sli4_fc.h:1753
uint32_t total_transfer_length
Definition: sli4_fc.h:752
#define SLI4_CMD_FCP_ICMND64_WQE
Definition: sli4_fc.h:417
int32_t sli_fcp_cont_treceive64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint32_t first_data_sge, uint32_t relative_off, uint32_t xfer_len, uint16_t xri, uint16_t sec_xri, uint16_t tag, uint16_t cq_id, uint16_t xid, uint32_t rpi, ocs_remote_node_t *rnode, uint32_t flags, uint8_t dif, uint8_t bs, uint8_t csctl, uint32_t app_id, uint8_t timer)
Write an FCP_CONT_TRECEIVE64_WQE work queue entry.
Definition: sli4_fc.c:1357
int32_t sli_fcp_trsp64_wqe(sli4_t *sli4, void *buf, size_t size, ocs_dma_t *sgl, uint32_t rsp_len, uint16_t xri, uint16_t tag, uint16_t cq_id, uint16_t xid, uint32_t rpi, ocs_remote_node_t *rnode, uint32_t flags, uint8_t csctl, uint8_t port_owned, uint32_t app_id)
Write an FCP_TRSP64_WQE work queue entry.
Definition: sli4_fc.c:1400
uint32_t uint32_t hlm
Definition: sli4_fc.h:1035
#define SLI4_ELS_REQUEST64_CMD_GEN
Definition: sli4_fc.h:626
uint32_t ia
Definition: sli4_fc.h:494
#define SLI4_LINK_ATTN_P2P
Definition: sli4_fc.h:1480
#define SLI4_ACQE_PORT_EVENT_TYPE_ITCM_PARITY_EVENT
Definition: sli4.h:3391
#define SLI4_CQE_CODE_RQ_ASYNC_V1
Definition: sli4_fc.h:1893
union sli4_queue_t::@44 u
uint32_t uint32_t remote_id
Definition: sli4_fc.h:1310
uint32_t uint32_t xbl
Definition: sli4_fc.h:713
int32_t sli_fc_rqe_rqid_and_index(sli4_t *sli4, uint8_t *cqe, uint16_t *rq_id, uint32_t *index)
Retrieve the RQ index from the completion.
Definition: sli4_fc.c:2768
uint32_t t_mask
Definition: sli4_fc.h:500
#define SLI4_FC_WCQE_STATUS_DI_ERROR
Definition: sli4_fc.h:1654
uint32_t t_tag
Definition: sli4_fc.h:512
ocs_dma_t dma
Definition: sli4.h:3450
uint32_t uint32_t uint32_t rq_id
Definition: sli4_fc.h:1753
#define SLI4_WQE_ELS_REQUEST64
Definition: sli4_fc.h:396
uint8_t p2_linkstate
Definition: sli4.h:3365
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
FCOE_RQ_CREATE.
Definition: sli4_fc.h:178
#define SLI4_PORT_LINK_STATUS_PHYSICAL_DOWN
Definition: sli4_fc.h:1567
int32_t sli_cmd_fcoe_rediscover_fcf(sli4_t *sli4, void *buf, size_t size, uint16_t index)
Definition: sli4_fc.c:637
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 request_tag
Definition: sli4_fc.h:713
#define FC_ADDR_FABRIC
Definition: ocs_fcp.h:61
uint32_t payload_offset_length
Definition: sli4_fc.h:812