Emulex Logo
OneCoreā„¢ Storage SDK Release 11.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
elxu_mbox.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 #include <stdio.h>
34 #include <stdint.h>
35 #include <stdlib.h>
36 #include <stdarg.h>
37 #include <assert.h>
38 #include <string.h>
39 #include <sys/types.h>
40 #include <sys/ioctl.h>
41 #include <fcntl.h>
42 #include <dirent.h>
43 #include <unistd.h>
44 #include <ctype.h>
45 #include <sys/mman.h>
46 
47 #include <ocs_ioctl.h>
48 
49 #include <elxu_device.h>
50 #include <elxu_sli4.h>
51 #include <elxu_mbox.h>
52 #include <elxu_common.h>
53 #include <elxu_mgmt.h>
54 #include <elx_pt_ioctl.h>
55 #include <elxu_dump.h>
56 
57 #define IOCTL_BUFSIZE 64*1024
58 
59 #define DPORT_DYNAMIC_MODE 0x1
60 #define DPORT_STATIC_MODE 0x2
61 #define DPORT_QUERY_DYNAMIC_MODE 0x3
62 
63 static char* format_sli4_ip_address(uint32_t *address);
64 static int ocs_mbox(elxu_device_t *device, mbox_command_t *mboxcmd, uint32_t mboxcmdLength, void *inbuf,
65  uint32_t inbufLength, void *outbuf, uint32_t outbufLength);
66 static int pt_mbox(elxu_device_t *device, mbox_command_t *mboxcmd, uint32_t mboxcmdLength, void *inbuf,
67  uint32_t inbufLength, void *outbuf, uint32_t outbufLength);
68 #define VPD_LARGE_RESOURCE_TYPE_ID_STRING_TAG 0x82
69 #define VPD_LARGE_RESOURCE_TYPE_R_TAG 0x90
70 #define VPD_LARGE_RESOURCE_TYPE_W_TAG 0x91
71 #define VPD_SMALL_RESOURCE_TYPE_END_TAG 0x78
72 
73 typedef struct {
74  uint8_t *buffer;
75  uint32_t length;
76  uint32_t offset;
77  uint8_t checksum;
78 } vpdbuf_t;
79 
80 static inline int
82 {
83  return vpd->offset >= vpd->length;
84 }
85 
86 static inline int
88 {
89  int rc = -1;
90  if (vpd->offset < vpd->length) {
91  rc = vpd->buffer[vpd->offset++];
92  vpd->checksum += rc;
93  }
94  return rc;
95 }
96 
97 static inline uint8_t *
99 {
100  return &vpd->buffer[vpd->offset];
101 }
102 
103 static inline uint8_t *
104 elx_find_vpd(uint8_t *vpddata, uint32_t vpddata_length, const char *key)
105 {
106  vpdbuf_t vpdbuf;
107  uint8_t *pret = NULL;
108  uint8_t c0 = key[0];
109  uint8_t c1 = key[1];
110 
111  vpdbuf.buffer = (uint8_t*) vpddata;
112  vpdbuf.length = vpddata_length;
113  vpdbuf.offset = 0;
114  vpdbuf.checksum = 0;
115 
116  while (!vpddone(&vpdbuf)) {
117  int type = vpdnext(&vpdbuf);
118  int len_lo;
119  int len_hi;
120  int len;
121  int i;
122 
123  if (type == VPD_SMALL_RESOURCE_TYPE_END_TAG) {
124  break;
125  }
126 
127  len_lo = vpdnext(&vpdbuf);
128  len_hi = vpdnext(&vpdbuf);
129  len = len_lo + (len_hi << 8);
130 
132  while (len > 0) {
133  int rc0;
134  int rc1;
135  int sublen;
136  uint8_t *pstart;
137 
138  rc0 = vpdnext(&vpdbuf);
139  rc1 = vpdnext(&vpdbuf);
140 
141  /* Mark this location */
142  pstart = vpdref(&vpdbuf);
143 
144  sublen = vpdnext(&vpdbuf);
145 
146  /* Adjust remaining len */
147  len -= (sublen + 3);
148 
149  /* check for match with request */
150  if ((c0 == rc0) && (c1 == rc1)) {
151  pret = pstart;
152  for (i = 0; i < sublen; i++) {
153  vpdnext(&vpdbuf);
154  }
155  /* check for "RV" end */
156  } else if ('R' == rc0 && 'V' == rc1) {
157 
158  /* Read the checksum */
159  for (i = 0; i < sublen; i++) {
160  vpdnext(&vpdbuf);
161  }
162 
163  /* The accumulated checksum should be zero here */
164  if (vpdbuf.checksum != 0) {
165  printf("checksum error\n");
166  return NULL;
167  }
168  }
169  else
170  for (i = 0; i < sublen; i++) {
171  vpdnext(&vpdbuf);
172  }
173  }
174  }
175 
176  for (i = 0; i < len; i++) {
177  vpdnext(&vpdbuf);
178  }
179  }
180 
181  return pret;
182 }
183 
184 
185 /**
186  * @brief Issue read rev mailbox command
187  *
188  * Create a READ_REV mailbox command
189  *
190  * @param device device descriptor
191  *
192  * @return return zero for success, negative error code for error
193  */
195 {
196  char *value;
197 
198  value = elxu_device_get_value(device, "/ocs/fw_rev");
199  if (value) {
200  printf("FW Rev: %s\n", value);
201  }
202 
203  value = elxu_device_get_value(device, "/ocs/fw_rev2");
204  if (value) {
205  printf("FW Rev2: %s\n", value);
206  }
207 
208  value = elxu_device_get_value(device, "/ocs/hw_rev1");
209  if (value && (strlen(value) > 0)) {
210  printf("HW Rev1: %s\n", value);
211  }
212 
213  value = elxu_device_get_value(device, "/ocs/hw_rev2");
214  if (value && (strlen(value) > 0)) {
215  printf("HW Rev2: %s\n", value);
216  }
217 
218  value = elxu_device_get_value(device, "/ocs/hw_rev3");
219  if (value && (strlen(value) > 0)) {
220  printf("HW Rev3: %s\n", value);
221  }
222 
223  return 0;
224 }
225 
227 {
228  int no_of_desc = ((rsp->hdr.response_length - 16) / 12 );
229  int i = 0;
230 
231  printf("-------------------------------------------------------------- \n");
232  printf("Overall Test Result = %d \n", rsp->overall_test_result);
233  printf("Num Phases = %d \n", rsp->num_phases);
234  printf("Local Test Results = %d \n", rsp->local);
235  printf("Remote Test Results = %d \n", rsp->remote);
236  printf("Round Trip Latency = %d \n", rsp->round_trip_latency);
237  printf("Link Distance = %d \n", rsp->link_distance);
238  printf("Frame Size = %d \n", rsp->frame_size);
239  printf("Buffers Required = %d \n\n", rsp->buffers_required);
240  printf("Individual test results \n");
241  printf("=============================================================== \n");
242 
243  for(i=0; i < no_of_desc; i++) {
244  fcoe_test_result_descriptor_t *ptr = &(rsp->trd[i]);
245  switch (ptr->test_phase) {
246  case 0xD2:
247  printf("Electrical Loopback Test: ");
248  break;
249  case 0xD3:
250  printf("Optical Loopback Test: ");
251  break;
252  case 0xD4:
253  printf("Reverse Optical Loopback Test: ");
254  break;
255  case 0xD5:
256  printf("Link Traffic Test: ");
257  break;
258  case 0xD6:
259  printf("Reverse Link Traffic Test: ");
260  break;
261  default:
262  printf("Unknown");
263  }
264  switch (ptr->test_phase_result) {
265  case 0x00:
266  printf("Passed; ");
267  break;
268  case 0x01:
269  printf("Skipped; ");
270  break;
271  case 0x02:
272  printf("Failed; ");
273  break;
274  case 0x03:
275  printf("Stopped; ");
276  break;
277  default:
278  printf("unknown; ");
279  }
280  if(!ptr->err) {
281  printf("Phase Latency = 0x%X \n", ptr->w1);
282  }else {
283  printf("error = 0x%X \n", ptr->w1);
284  }
285  }
286  printf("=============================================================== \n");
287 }
288 
289 static int mbox_set_link_diag_state(elxu_device_t *device, void *mqe, int enable)
290 {
291  int rval = -1;
292  mbox_sli_config_t *sli_config = mqe;
293  mbox_req_fcoe_set_link_diag_state_t *link_diag_req = mqe + sizeof(mbox_sli_config_t);
295  memset(mqe, 0, MBOX_ENTRY_LENGTH);
296 
297  sli_config->command = MBOX_SLI_CONFIG;
298  sli_config->emb = 1; /* Embedded, Mbox Cmd data is placed in the 256 MQE */
299  sli_config->pcmd_count = 0;
301 
302  link_diag_req->hdr.opcode = MBOX_SET_LINK_DIAG_STATE;
303  link_diag_req->hdr.subsystem = MBOX_SUBSYSTEM_FCOE;
304  link_diag_req->hdr.timeout = 0;
305  link_diag_req->hdr.request_length = 4;
306  link_diag_req->diag = enable;
307  link_diag_req->div = 1;
308  link_diag_req->link_number = device->phy_port_num;
309  link_diag_req->link_type = 0x1; /* FC Link */
310  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, link_diag_req, sizeof (*link_diag_req), link_diag_rsp, sizeof (*link_diag_rsp));
311  if(rval) {
312  printf("mbox_set_link_diag_state command submission failed \n");
313  }else {
314  if(link_diag_rsp->hdr.status) {
315  printf("mbox_set_link_diag_state failed with status = %x, additional_status = %x \n",
316  link_diag_rsp->hdr.status, link_diag_rsp->hdr.additional_status);
317  rval = -1;
318  }
319  }
320  return rval;
321 }
322 
323 static int mbox_set_dport_mode(elxu_device_t *device, void *mqe, int mode, int enable)
324 {
325  int rval = -1;
326  mbox_sli_config_t *sli_config = mqe;
327  mbox_req_fcoe_set_dport_mode_t *dport_mode_req = mqe + sizeof(mbox_sli_config_t);
328  mbox_res_fcoe_set_dport_mode_t *dport_mode_rsp = (mbox_res_fcoe_set_dport_mode_t*)dport_mode_req;
329  memset(mqe, 0, MBOX_ENTRY_LENGTH);
330 
331  sli_config->command = MBOX_SLI_CONFIG;
332  sli_config->emb = 1; /* Embedded, Mbox Cmd data is placed in the 256 MQE */
333  sli_config->pcmd_count = 0;
334  sli_config->payload_length = sizeof(mbox_req_fcoe_set_dport_mode_t);
335 
336  dport_mode_req->hdr.opcode = MBOX_SET_DPORT_MODE;
337  dport_mode_req->hdr.subsystem = MBOX_SUBSYSTEM_FCOE;
338  dport_mode_req->hdr.request_length = 20;
339  dport_mode_req->hdr.timeout = 0;
340  dport_mode_req->dport_mode = mode;
341 
342  if (mode == DPORT_DYNAMIC_MODE) {
343  dport_mode_req->enable = enable;
344  } else if (mode == DPORT_STATIC_MODE) {
345  dport_mode_req->stop = enable ? 0 : 1;
346  }
347 
348  dport_mode_req->link_number = device->phy_port_num;
349  dport_mode_req->link_type = 0x1; /* FC Link */
350 
351  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, dport_mode_req, sizeof (*dport_mode_req), dport_mode_rsp, sizeof (*dport_mode_rsp));
352  if(rval) {
353  printf("mbox_set_dport_mode command submission failed \n");
354  } else {
355  if(dport_mode_rsp->hdr.status) {
356  printf("mbox_set_dport_mode failed with status = %x, additional_status = %x \n",
357  dport_mode_rsp->hdr.status, dport_mode_rsp->hdr.additional_status);
358  rval = -1;
359  } else {
360  /* If mode is query, return resp->enabled status. */
361  if ((mode == DPORT_QUERY_DYNAMIC_MODE) && (dport_mode_rsp->ev)) {
362  rval = dport_mode_rsp->enabled;
363  }
364  }
365  }
366  return rval;
367 }
368 
370 {
371  char mqe[MBOX_ENTRY_LENGTH];
372  int rval;
373 
374  rval = mbox_set_dport_mode(device, mqe, DPORT_QUERY_DYNAMIC_MODE, 0);
375  if (rval < 0) {
376  printf("Dport mode query failed \n");
377  } else {
378  printf("Dynamic dport mode %s for device%d.\n",
379  (rval == 0) ? "disabled" : "enabled", device->phy_port_num);
380  }
381  return rval;
382 }
383 
384 
385 int mbox_set_dynamic_dport(elxu_device_t *device, char *state_str)
386 {
387  char mqe[MBOX_ENTRY_LENGTH];
388  int rval = -1;
389  int state = 0;
390 
391  if (strcasecmp(state_str, "enable") == 0){
392  state = 1;
393  }
394 
395  rval = mbox_set_dport_mode(device, mqe, DPORT_DYNAMIC_MODE, state);
396 
397  printf("Set dynamic dport %s %s for device%d.\n", (state == 1) ? "enable" : "disable",
398  (rval == 0) ? "successfull" : "failed", device->phy_port_num);
399 
400  return rval;
401 }
402 
403 /**
404  * @brief Issue Get dport stats mailbox command
405  * Create a GET_DPORT_STAT mailbox command
406  * @return return zero for success, negative error code for error
407  */
409 {
410  void *mqe = zmalloc(MBOX_ENTRY_LENGTH);
411  mbox_sli_config_t *sli_config = mqe;
412  uint32_t link_status = 0;
413  int rval = -1, dynamic_dport_enabled = 0;
414  int retry = 0;
415  assert(device);
416 
417  if (!mqe) {
418  printf("Failed to alloc memory for mqe\n");
419  return -1;
420  }
421 
422  printf("Running D_Port Tests. Please wait for 2 minutes. Polling for results \n");
423 
424  rval = elxu_lancer_get_link_state(device, &link_status);
425  if (rval < 0) {
426  printf("Failed to get link status\n");
427  goto free_mqe;
428  }
429 
430  /* Step0: Query for the dport dymanic status */
431  dynamic_dport_enabled = mbox_set_dport_mode(device, mqe, DPORT_QUERY_DYNAMIC_MODE, 0);
432  if (dynamic_dport_enabled < 0) {
433  printf("Failed to get dynamic dport status\n");
434  goto free_mqe;
435  }
436 
437  if (dynamic_dport_enabled) {
438  rval = mbox_set_dport_mode(device, mqe, DPORT_DYNAMIC_MODE, 0);
439  if (rval < 0) {
440  printf("Failed to reset dynamic dport state\n");
441  }
442  }
443 
444  /* Step1: Set link to DIAG state */
445  rval = mbox_set_link_diag_state(device, mqe, 1);
446  if (rval < 0) {
447  printf(" Set link to DIAG state failed \n");
448  goto exit_mbox_get_dport_stats;
449  }
450 
451  /* Step2: Enable dport mode */
452  rval = mbox_set_dport_mode(device, mqe, DPORT_STATIC_MODE, 1);
453  if (rval < 0) {
454  printf(" Set link to dport mode failed \n");
455  goto exit_mbox_get_dport_stats;
456  }
457 
458  /* Step3: Poll dport results */
459  while(retry < 20) {
460  mbox_req_fcoe_get_dport_results_t *dport_results_req = mqe + sizeof(mbox_sli_config_t);
461  mbox_res_fcoe_get_dport_results_t *dport_results_rsp = (mbox_res_fcoe_get_dport_results_t*)dport_results_req;
462  memset(mqe, 0, MBOX_ENTRY_LENGTH);
463 
464  sli_config->command = MBOX_SLI_CONFIG;
465  sli_config->emb = 1; /* Embedded, Mbox Cmd data is placed in the 256 MQE */
466  sli_config->pcmd_count = 0;
468 
469  dport_results_req->hdr.opcode = MBOX_GET_DPORT_RESULTS;
470  dport_results_req->hdr.subsystem = MBOX_SUBSYSTEM_FCOE;
471  dport_results_req->hdr.request_length = 4;
472  dport_results_req->hdr.timeout = 0;
473  dport_results_req->link_number = device->phy_port_num;
474  dport_results_req->link_type = 0x1; /* FC Link */
475  dport_results_req->query_type = 0;
476 
477  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, dport_results_req,
478  sizeof (*dport_results_req), dport_results_rsp, sizeof(*dport_results_rsp));
479  if( rval == 0 ) {
480  if(dport_results_rsp->hdr.status == 0) {
481  parse_dport_result(dport_results_rsp);
482  break;
483  }
484  }
485  sleep(10);
486  retry++;
487  }
488 
489  /* Step4: Stop DPORT mode */
490  rval = mbox_set_dport_mode(device, mqe, DPORT_STATIC_MODE, 0);
491  if (rval < 0) {
492  printf(" Disabling dport mode failed \n");
493  goto exit_mbox_get_dport_stats;
494  }
495 
496  /* Step5: Set link to Normal mode from Diag mode */
497  rval = mbox_set_link_diag_state(device, mqe, 0);
498  if (rval < 0) {
499  printf(" Set link to Normal state failed \n");
500  goto exit_mbox_get_dport_stats;
501  }
502 
503 exit_mbox_get_dport_stats:
504  /* Do function reset even in case of failure. */
505  rval = elxu_device_exec(device, "/ocs/function_reset", NULL, 0, NULL, 0);
506  if (rval < 0) {
507  printf(" Function reset failed. \n");
508  }
509 
510  /* Set link to original state */
511  rval = elxu_lancer_set_link_state(device, &link_status);
512  if (rval < 0) {
513  printf("Failed to set link status\n");
514  }
515 
516  /* Set the original dynamic dport state */
517  if (dynamic_dport_enabled) {
518  rval = mbox_set_dport_mode(device, mqe, DPORT_DYNAMIC_MODE,
519  dynamic_dport_enabled);
520  if (rval < 0) {
521  printf("Failed to reset dynamic dport state\n");
522  }
523  }
524 free_mqe:
525  if (mqe) {
526  zfree(mqe);
527  }
528  return rval;
529 }
530 
531 /**
532  * @brief Issue set link diag loopback mailbox command
533  *
534  * Create a SET_LINK_DIAG_LOOPBACK mailbox command
535  *
536  * @param device device descriptor
537  * @param mqe
538  * @param type loopback test type
539  *
540  * @return return zero for success, negative error code for error
541  */
542 
543 int mbox_diag_loopback_tests(elxu_device_t *device, int loopback_type, int retry_count)
544 {
545 
546  void *mqe = NULL;
547  int rval = -1, i;
548  uint32_t link_status = 0;
549  assert(device);
550 
551  printf("\n============================================================\n\n");
552 
553  if (loopback_type == INTERNAL_LOOPBACK) {
554  printf("\nInternal Loopback test started......\n");
555  } else if (loopback_type == EXTERNAL_LOOPBACK) {
556  printf("\nExternal Loopback test started......\n");
557  } else if (loopback_type == PCI_LOOPBACK) {
558  printf("\nPCI Loopback test started......\n");
559  } else {
560  printf("Error: Unsupported Loopback type(%d) provided.\n", loopback_type);
561  printf("Usage(Loopback type)\n1 - Internal Loopback test\n");
562  printf(" 2 - External Loopback test\n");
563  printf(" 3 - PCI Loopback test\n");
564  goto exit_mbox_diag_loopback_tests;
565  }
566 
567  mqe = zmalloc(MBOX_ENTRY_LENGTH);
568  if (!mqe) {
569  printf("Unable to allocate memory for mbox command\n");
570  goto exit_mbox_diag_loopback_tests;
571  }
572 
573  if (loopback_type != PCI_LOOPBACK) {
574  rval = elxu_lancer_get_link_state(device, &link_status);
575  if (rval < 0) {
576  printf("Failed to get link status\n");
577  goto exit_mbox_diag_loopback_tests;
578  }
579 
580  /* Step1: Set link to DIAG state */
581  rval = mbox_set_link_diag_state(device, mqe, 1);
582  if (rval < 0) {
583  printf(" Set link to DIAG state failed \n");
584  goto exit_mbox_diag_loopback_tests;
585  }
586 
587  /* Step3: Set link into loopback mode */
588  rval = elxu_lancer_set_loopback(device, NULL, &loopback_type);
589  if (rval) {
590  printf("Please install proper SFP and loopback cable before running tests\n");
591  mbox_set_link_diag_state(device, mqe, 0);
592  goto exit_mbox_diag_loopback_tests;
593  }
594 
595  printf("Loopback test is in progress. Polling for results.....\n\n");
596  for (i = 0; i <= retry_count; i++) {
597  sleep(5);
598  rval = elxu_lancer_run_loopback(device, NULL, loopback_type);
599  if (rval < 0) {
600  continue;
601  } else {
602  if (i) {
603  printf("Loopback test passed after %d attempt\n", i+1);
604  }
605  printf(" Results: PASSED\n");
606  break;
607  }
608  }
609 
610  if (rval) {
611  printf("No loopback cable connected. Please install loopback cable before running the test\n");
612  printf(" Results: FAILED\n");
613  }
614  rval = mbox_set_link_diag_state(device, mqe, 0);
615  if (rval < 0) {
616  printf(" Set link to Normal state failed \n");
617  goto exit_mbox_diag_loopback_tests;
618  }
619  /* Set link to original state */
620  rval = elxu_lancer_set_link_state(device, &link_status);
621  if (rval < 0) {
622  printf("Failed to set link status\n");
623  goto exit_mbox_diag_loopback_tests;
624  }
625 
626  } else {
627  printf("PCI Loopback test is in progress. Polling for results.....\n\n");
628  for (i = 0; i <= retry_count; i++) {
629  rval = elxu_lancer_run_loopback(device, NULL, loopback_type);
630  if (rval < 0) {
631  continue;
632  } else {
633  if (i) {
634  printf("Loopback test passed after %d attempt\n", i+1);
635  }
636  printf(" Results: PASSED\n");
637  break;
638  }
639  sleep(2);
640  }
641 
642  if (rval) {
643  printf(" Results: FAILED\n");
644  }
645  }
646 exit_mbox_diag_loopback_tests:
647 
648  printf("============================================================\n\n");
649  if (mqe) {
650  zfree(mqe);
651  }
652  return rval;
653 }
654 
655 /**
656  * @brief Issue read link status mailbox command
657  *
658  * Create a READ_LNK_STAT mailbox command
659  *
660  * @param device device descriptor
661  * @param clof clear overflow flag
662  * @param clrc clear all counters floag
663  *
664  * @return return zero for success, negative error code for error
665  */
666 int mbox_read_link_status(elxu_device_t *device, int clof, int clrc)
667 {
668  void *mqe = zmalloc(MBOX_ENTRY_LENGTH);
669  mbox_read_link_status_t *read_link_status = mqe;
670 
671  int rval = -1;
672 
673  assert(device);
674 
675  if (!mqe)
676  goto done;
677 
678  read_link_status->command = MBOX_READ_LNK_STAT;
679  read_link_status->clof = clof;
680  read_link_status->clrc = clrc;
681  read_link_status->rec = 1;
682 
683  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, 0, 0, 0, 0);
684 
685  if (rval < 0) {
686  zfree(mqe);
687  return rval;
688  }
689 
690  /*
691  printf("GEC: %d\n", read_link_status->gec);
692  printf("W02Of: %d\n", read_link_status->w02of);
693  printf("W03Of: %d\n", read_link_status->w03of);
694  printf("W04Of: %d\n", read_link_status->w04of);
695  printf("W05Of: %d\n", read_link_status->w05of);
696  printf("W06Of: %d\n", read_link_status->w06of);
697  printf("W07Of: %d\n", read_link_status->w07of);
698  printf("W08Of: %d\n", read_link_status->w08of);
699  printf("W09Of: %d\n", read_link_status->w09of);
700  printf("W10Of: %d\n", read_link_status->w10of);
701  printf("W11Of: %d\n", read_link_status->w11of);
702  printf("W12Of: %d\n", read_link_status->w12of);
703  printf("W13Of: %d\n", read_link_status->w13of);
704  printf("W14Of: %d\n", read_link_status->w14of);
705  printf("W15Of: %d\n", read_link_status->w15of);
706  printf("W16Of: %d\n", read_link_status->w16of);
707  printf("W17Of: %d\n", read_link_status->w17of);
708  printf("W18Of: %d\n", read_link_status->w18of);
709  printf("W19Of: %d\n", read_link_status->w19of);
710  printf("W20Of: %d\n", read_link_status->w20of);
711  printf("W21Of: %d\n", read_link_status->w21of);
712  */
713 
714  printf("\n");
715  printf("Loss of Sync error count: %d\n", read_link_status->loss_of_sync_error_count);
716  printf("Loss of signal error count: %d\n", read_link_status->loss_of_signal_error_count);
717  printf("Primitive sequence error count: %d\n", read_link_status->primitive_sequence_error_count);
718  printf("Invalid TX word error count: %d\n", read_link_status->invalid_transmission_word_error_count);
719  printf("CRC error count: %d\n", read_link_status->crc_error_count);
720  printf("Primitive sequence event timeout count: %d\n", read_link_status->primitive_sequence_event_timeout_count);
721  printf("Elastic buffer overrun error count: %d\n", read_link_status->elastic_buffer_overrun_error_count);
722  printf("Arbitration (FC-AL) timeout-out count: %d\n", read_link_status->arbitration_timeout_count);
723  printf("Advertised RX buffer-to-buffer credit: %d\n", read_link_status->advertised_receive_buffer_to_buffer_credit);
724  printf("Current RX buffer-to-buffer credit: %d\n", read_link_status->current_receive_buffer_to_buffer_credit);
725  printf("Advertised TX buffer-to-buffer credit: %d\n", read_link_status->advertised_transmit_buffer_to_buffer_credit);
726  printf("Current TX buffer-to-buffer count: %d\n", read_link_status->current_transmit_buffer_to_buffer_credit);
727  printf("RX EOFa count: %d\n", read_link_status->received_eofa_count);
728  printf("RX EOFdti count: %d\n", read_link_status->received_eofdti_count);
729  printf("RX EOFni count: %d\n", read_link_status->received_eofni_count);
730  printf("RX SOFf count: %d\n", read_link_status->received_soff_count);
731  printf("RX dropped no AER count: %d\n", read_link_status->received_dropped_no_aer_count);
732  printf("RX dropped no available RPI resources count: %d\n", read_link_status->received_dropped_no_available_rpi_resources_count);
733  printf("RX dropped no avialable XRI resources count: %d\n", read_link_status->received_dropped_no_available_xri_resources_count);
734  printf("NOS count: %d\n", read_link_status->link_failure_error_count);
735  printf("Error frames: %d\n", read_link_status->crc_error_count);
736 
737  printf(" Link failure error count: %d\n", read_link_status->link_failure_error_count);
738  printf(" CRC error count: %d\n", read_link_status->crc_error_count);
739  printf(" Received EOFa count: %d\n", read_link_status->received_eofa_count);
740  printf(" Received EOFni count: %d\n", read_link_status->received_eofni_count);
741  printf(" Received LRR count: %d\n", read_link_status->lrr_count_local);
742  printf(" Received LR count: %d\n", read_link_status->lr_count_remote);
743  printf(" LIP count: %s\n", elxu_device_get_value(device, "/ocs/lip_count"));
744 
745  printf(" Active RPI count: %s\n", elxu_device_get_value(device, "/ocs/active_rpi_count"));
746  printf(" Active XRI count: %s\n", elxu_device_get_value(device, "/ocs/active_xri_count"));
747 
748 done:
749  zfree(mqe);
750  return rval;
751 }
752 
753 /**
754  * @brief Issue read status mailbox command
755  *
756  * Create a READ_STATUS mailbox command
757  *
758  * @param device device descriptor
759  * @param clear_counter clear counter flag
760  *
761  * @return return zero for success, negative error code for error
762  */
763 int mbox_read_status(elxu_device_t *device, uint32_t clear_counter)
764 {
765  void *mqe = zmalloc(MBOX_ENTRY_LENGTH);
766  mbox_read_status_t *read_status = mqe;
767 
768  int rval = -1;
769 
770  assert(device);
771 
772  if (!mqe)
773  goto done;
774 
775  read_status->command = MBOX_READ_STATUS;
776  read_status->cc = clear_counter;
777 
778  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, 0, 0, 0, 0);
779 
780  if (rval < 0) {
781  zfree(mqe);
782  return rval;
783  }
784 
785  printf("\n");
786  printf(" TX KBytes: %u\n", read_status->transmit_kbyte_count);
787  printf(" RX KBytes: %u\n", read_status->receive_kbyte_count);
788  printf(" TX Frames: %u\n", read_status->transmit_frame_count);
789  printf(" RX Frames: %u\n", read_status->receive_frame_count);
790  printf(" TX Bytes: %u\n", read_status->transmit_kbyte_count * 1024);
791  printf(" RX Bytes: %u\n", read_status->receive_kbyte_count * 1024);
792  printf(" TX Words: %u\n", read_status->transmit_kbyte_count * 256);
793  printf(" RX Words: %u\n", read_status->receive_kbyte_count * 256);
794  printf(" TX Sequences: %u\n", read_status->transmit_sequence_count);
795  printf(" RX Sequences: %u\n", read_status->receive_sequence_count);
796  printf("Total exchanges (Originator): %d\n", read_status->total_exchanges_originator);
797  printf("Total exchanges (Responder): %d\n", read_status->total_exchanges_responder);
798  printf("RX P_BSY count: %d\n", read_status->receive_p_bsy_count);
799  printf("RX F_BSY count: %d\n", read_status->receive_f_bsy_count);
800 
801  // these fields seem not supported yet?
802  /*
803  printf("Dropped frames due to no RQ buffer count: %d\n", read_status->dropped_frames_due_to_no_rq_buffer_count);
804  printf("Empty RQ timeout count: %d\n", read_status->empty_rq_timeout_count);
805  printf("Dropped frames due to no XRI count: %d\n", read_status->dropped_frames_due_to_no_xri_count);
806  printf("Empty XRI pool count: %d\n", read_status->empty_xri_pool_count);
807  */
808 
809 done:
810  zfree(mqe);
811  return rval;
812 }
813 
814 /**
815  * @brief Issue IOCTL_COMMON_ENABLE_DISABLE_PORT command
816  *
817  * create IOCTL_COMMON_ENABLE_DISABLE_PORT mailbox command
818  *
819  * @param device device descriptor
820  * @param port_status ENABLE (1) or DISABLE (0)
821  *
822  * @return return zero for success, negative error code for error
823  */
824 int mbox_ioctl_common_enable_disable_port(elxu_device_t *device, uint32_t port_status)
825 {
826  int rval=-1;
827  void *mqe = NULL;
829  mbox_sli_config_t *sli_config = NULL;
830  uint32_t request_Len = sizeof(sli4_ioctl_common_enable_disable_port_t) - sizeof(sli4_ioctl_header_t);
831 
832  assert(device);
833 
834  mqe = zmalloc(MBOX_ENTRY_LENGTH);
835  if (!mqe)
836  return rval;
837 
838  sli_config = mqe;
839  mbox = mqe + sizeof(mbox_sli_config_t);
840 
841  sli_config->command = MBOX_SLI_CONFIG;
842  sli_config->emb = 1; // Embedded
843  sli_config->pcmd_count = 0;
844  sli_config->payload_length = sizeof(*mbox);
845 
848  mbox->hdr.req.timeout = 0;
849  mbox->hdr.req.request_length = request_Len;
850 
851  mbox->port_status = port_status;
852 
853  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH,
854  mbox, request_Len, mbox, request_Len);
855 
856  if (rval != 0) { printf ("Error: rval %d\n", rval);
857  } else if (sli_config->status) {
858  printf ("status 0x%02X addl 0x%02X\n", sli_config->status, mbox->hdr.res.additional_status);
859  rval = -1;
860  }
861  zfree(mqe);
862  return rval;
863 }
864 
865 /**
866  * @brief Issue IOCTL_COMMON_SET_BE_CONFIGRATION_AND_RESOURCES command
867  *
868  * create IOCTL_COMMON_SET_BE_CONFIGURATION_AND_RESOURCES mailbox command
869  *
870  * @param device device descriptor
871  * @param mac_addr new MAC address
872  *
873  * @return return zero for success, negative error code for error
874  */
876 {
877  void *mqe = zmalloc(MBOX_ENTRY_LENGTH);
878  mbox_sli_config_t *sli_config = mqe;
879  uint32_t request_Len = sizeof(sli4_ioctl_common_set_be_configuration_and_resources_t) -
880  sizeof(sli4_ioctl_header_t);
881  int rval = -1;
883 
884  assert(device);
885 
886  if (!mqe)
887  goto done;
888 
889  set_mbox = mqe + sizeof(mbox_sli_config_t);
890 
891  sli_config->command = MBOX_SLI_CONFIG;
892  sli_config->emb = 1;
893  sli_config->pcmd_count = 0;
894  sli_config->payload_length = sizeof(*set_mbox);
895 
896  // set_be_configuration_and_resources
899  set_mbox->hdr.req.version = 1;
900  set_mbox->hdr.req.request_length = request_Len;
901 
902  set_mbox->resource_descriptor_count = 1;
903  set_mbox->be_resources[0].resource_type = 0x2;
904  set_mbox->be_resources[0].resource_descriptor.pf_num = device->deviceIndex + 2;
905  set_mbox->be_resources[0].resource_descriptor.vf_domain = 0xFF;
907  set_mbox->be_resources[0].resource_descriptor.session_count = UINT16_MAX;
908  set_mbox->be_resources[0].resource_descriptor.icd_count = UINT16_MAX;
909  set_mbox->be_resources[0].resource_descriptor.cq_count = UINT16_MAX;
910  set_mbox->be_resources[0].resource_descriptor.iscsi_mac_address[0] = (uint8_t)mac_addr[0];
911  set_mbox->be_resources[0].resource_descriptor.iscsi_mac_address[1] = (uint8_t)mac_addr[1];
912  set_mbox->be_resources[0].resource_descriptor.iscsi_mac_address[2] = (uint8_t)mac_addr[2];
913  set_mbox->be_resources[0].resource_descriptor.iscsi_mac_address[3] = (uint8_t)mac_addr[3];
914  set_mbox->be_resources[0].resource_descriptor.iscsi_mac_address[4] = (uint8_t)mac_addr[4];
915  set_mbox->be_resources[0].resource_descriptor.iscsi_mac_address[5] = (uint8_t)mac_addr[5];
917  set_mbox->be_resources[0].resource_descriptor.bw_percent = -1;
918  set_mbox->be_resources[0].resource_descriptor.vlan_id = -1;
919 
920  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH,
921  set_mbox, request_Len, set_mbox, request_Len);
922 
923  if (rval != 0) {
924  printf ("Error: rval %d\n", rval);
925  } else if (sli_config->status) {
926  printf ("status 0x%02X addl 0x%02X, MAC address may already be used\n",
927  sli_config->status, set_mbox->hdr.res.additional_status);
928  rval = -1;
929  }
930 
931 done:
932  zfree(mqe);
933  return rval;
934 }
935 
936 /**
937  * @brief Soft assign MAC
938  */
939 int mbox_soft_assign_mac(elxu_device_t *device, int *macaddr)
940 {
942 
944 
946 
947  return 0;
948 }
949 
950 void mbox_get_mac_pt(elxu_device_t *device, uint8_t *mac_addr)
951 {
952  uint32_t mbox_words[256];
955  elx_pt_ioctl_mbox_t mbox;
956  int rc;
957  int i;
958  int fd;
959 
960  if (device == NULL) {
961  return;
962  }
963 
964  if (mac_addr == NULL) {
965  return;
966  }
967 
968  fd = device->fd;
969 
970  bzero(mac_addr, 6);
971 
972  bzero(&mbox_words, sizeof(mbox_words));
973  config_res = (sli4_res_common_get_function_config_t *)&mbox_words;
974  config_req = (sli4_req_common_get_function_config_t *)&mbox_words;
975 
976  config_req->hdr.req.subsystem = MBOX_SUBSYSTEM_COMMON;
978  config_req->hdr.req.request_length = sizeof(mbox_words);
979  if (is_skyhawk(device)) {
980  config_req->hdr.req.version = 1;
981  } else {
982  config_req->hdr.req.version = 0;
983  }
984 
985  mbox.words = (uint32_t *)config_req;
986  mbox.num_words = (sizeof(mbox_words) + 3) / 4;
987 
988  rc = ioctl(fd, IOCTL_CMD_ELX_PT_MBOX, &mbox);
989  if (rc == 0) {
990  if (config_res->hdr.res.status == 0) {
991  switch(config_res->desc[0] & 0xff) {
992  case 0x41: /* NIC v0 */
993  {
995 
996  desc = (sli4_nic_resource_descriptor_v0_t *) &config_res->desc[0];
997  for (i=0; i<6; i++) {
998  mac_addr[i] = desc->mac_address[i];
999  }
1000  }
1001  break;
1002  case 0x51: /* NIC v1 */
1003  {
1005 
1006  desc = (sli4_nic_resource_descriptor_v1_t *) &config_res->desc[0];
1007  for (i=0; i<6; i++) {
1008  mac_addr[i] = desc->mac_address[i];
1009  }
1010  }
1011  break;
1012  case 0x52: /* iSCSI v1 */
1013  {
1015 
1016  desc = (sli4_iscsi_resource_descriptor_v1_t *) &config_res->desc[0];
1017  for (i=0; i<6; i++) {
1018  mac_addr[i] = desc->mac_address[i];
1019  }
1020  }
1021  break;
1022  default:
1023  break;
1024  }
1025  }
1026  }
1027 }
1028 
1029 void mbox_get_wwn_pt(int fd, uint8_t *wwnn, uint8_t *wwpn)
1030 {
1031  mbox_rw_nvparms_t req;
1032  elx_pt_ioctl_mbox_t mbox;
1033  int rc;
1034 
1035  bzero(wwnn, 8);
1036  bzero(wwpn, 8);
1037 
1038  bzero(&req, sizeof(req));
1039 
1040  req.command = MBOX_READ_NVPARMS;
1041 
1042  mbox.words = (uint32_t *) &req;
1043  mbox.num_words = (sizeof(req) + 3) / 4;
1044 
1045  rc = ioctl(fd, IOCTL_CMD_ELX_PT_MBOX_FC, &mbox);
1046  if (rc == 0) {
1047  if (req.status == 0) {
1048  memcpy(wwnn, req.wwnn, sizeof(req.wwnn));
1049  memcpy(wwpn, req.wwpn, sizeof(req.wwpn));
1050  }
1051  }
1052 }
1053 int mbox_get_serialnum_pt(elxu_device_t *device, char *serial_num, int serial_num_size)
1054 {
1055  mbox_read_rev_t read_rev;
1056  elx_pt_ioctl_mbox_t mbox;
1057  int rc = 0;
1058  memref_t *dma_mem = NULL;
1059 
1060  bzero(&read_rev, sizeof(read_rev));
1061  read_rev.command = MBOX_READ_REV;
1062 
1063  dma_mem = elx_pt_dma_alloc(device, 4096);
1064  if (dma_mem == NULL) {
1065  printf("%s: Failed to allocate DMA memory\n", __func__);
1066  return -1;
1067  }
1068 
1069  read_rev.vpd = 1;
1070  read_rev.available_length = dma_mem->size;
1071  read_rev.physical_address_low = (uint32_t)(dma_mem->paddr & 0xffffffffUL);
1072  read_rev.physical_address_high = (uint32_t)(dma_mem->paddr >> 32);
1073 
1074  mbox.words = (uint32_t *) &read_rev;
1075  mbox.num_words = (sizeof(read_rev) + 3) / 4;
1076 
1077  rc = ioctl(device->fd, IOCTL_CMD_ELX_PT_MBOX_FC, &mbox);
1078  if (!rc && !read_rev.status) {
1079  int serial_num_len = 0;
1080  uint8_t *pserial = NULL;
1081 
1082  pserial = elx_find_vpd(dma_mem->vaddr,read_rev.returned_vpd_length, "SN");
1083  if (pserial) {
1084  serial_num_len = *pserial++;
1085  if (serial_num_len > serial_num_size)
1086  serial_num_len = sizeof(serial_num);
1087 
1088  memcpy((uint8_t *)serial_num, pserial, serial_num_len);
1089  }
1090  }
1091 
1092  if (dma_mem)
1093  elx_pt_dma_free(dma_mem);
1094 
1095  return rc;
1096 }
1097 
1098 int mbox_set_nv_mac_pt(elxu_device_t *device, int *macaddr)
1099 {
1100  uint32_t mbox_words[1024];
1101  elx_pt_ioctl_mbox_t mbox;
1106  char *p;
1107  int pf;
1108  int rc;
1109  uint32_t *desc_pointer;
1110  int i;
1111  int type;
1112  int len;
1113  uint8_t *mac_pointer;
1114  uint8_t *temp_descriptor = NULL;
1115 
1116  /*
1117  * For Skyhawk, need to send a COMMON_SET_PROFILE_CONFIG_V1.
1118  * For Lancer NIC we need to send COMMON_SET_PROFILE_CONFIG_V0
1119  * The resource profile will need to be either a NIC profile or a
1120  * iSCSI profile depending on the type of port we're talking to.
1121  *
1122  * The ISAP bit needs to be off.
1123  * The NOSV bit needs to be off to make the change non-volatile.
1124  * Profile ID will be 0, indicating the current profile.
1125  */
1126 
1127  /* Get the PCI function from the bus address */
1128  p = strrchr(device->bus_addr, '.');
1129  if (p == NULL) {
1130  /* Can't determine PCI function from bus address */
1131  goto fail;
1132  }
1133  ++p;
1134  pf = strtol(p, NULL, 10);
1135 
1136  /* Send a COMMON_GET_PROFILE_CONFIG to the correct function */
1137  bzero(&mbox_words, sizeof(mbox_words));
1138  get_req = (sli4_req_common_get_profile_config_t *) mbox_words;
1141  if (is_skyhawk(device)) {
1142  get_req->hdr.req.version = 1;
1143  } else {
1144  get_req->hdr.req.version = 0;
1145  }
1146  get_req->hdr.req.request_length = sizeof(mbox_words);
1147  /*
1148  * NOTE: pf 0 means "all functions". To get data for one function you
1149  * need to use pf+1.
1150  */
1151  get_req->hdr.req.pf_number = pf+1;
1152  get_req->typ = 0x01; /* Factory Default */
1153  mbox.words = mbox_words;
1154  mbox.num_words = ARRAY_SIZE(mbox_words);
1155 
1156  rc = ioctl(device->fd, IOCTL_CMD_ELX_PT_MBOX, &mbox);
1157  if (rc != 0) {
1158  goto fail;
1159  }
1160  get_res = (sli4_res_common_get_profile_config_t *) mbox_words;
1161  if (get_res->hdr.res.status != 0) {
1162  printf("Status is %d\n", get_res->hdr.res.status);
1163  printf("Addl status: 0x%x\n", get_res->hdr.res.additional_status);
1164  goto fail;
1165  }
1166 
1167  desc_pointer = (uint32_t *)get_res->desc;
1168 
1169  /*
1170  * Extract the NIC or iSCSI descriptor from the response.
1171  * Find the descriptor that contains the MAC address. For an
1172  * iSCSI function there should be one iSCSI descriptor. For
1173  * a NIC function there will be two descriptors - we want the
1174  * one that does not have the VFT bit set.
1175  */
1176  mac_pointer = NULL;
1177  for (i=0; i<get_res->desc_count; i++) {
1178  type = *desc_pointer & 0x000000ff;
1179  /*
1180  * Version 1 descriptors are variable length, with the length in the
1181  * second byte of the first word. Version 0 descriptors are fixed
1182  * at 72 bytes.
1183  */
1184  if (is_skyhawk(device)) {
1185  len = (*desc_pointer & 0x0000ff00) >> 8;
1186  } else {
1187  len = 72;
1188  }
1189  if (type == 0x51) { /* NIC descriptor */
1191  descriptor = (sli4_nic_resource_descriptor_v1_t *) desc_pointer;
1192  if (descriptor->vft == 0) {
1193  mac_pointer = (uint8_t*) descriptor->mac_address;
1194  break;
1195  }
1196  } else if (type == 0x52) { /* iSCSI descriptor */
1198  descriptor = (sli4_iscsi_resource_descriptor_v1_t *) desc_pointer;
1199  mac_pointer = (uint8_t*) descriptor->mac_address;
1200  break;
1201  } else if (type == 0x41) { /* V0 NIC descriptor */
1203  descriptor = (sli4_nic_resource_descriptor_v0_t *) desc_pointer;
1204  mac_pointer = (uint8_t*) descriptor->mac_address;
1205  break;
1206  }
1207 
1208  desc_pointer += (len / sizeof(uint32_t));
1209  }
1210 
1211  if (mac_pointer == NULL) {
1212  /* Didn't find the expected descriptor with a MAC address */
1213  goto fail;
1214  }
1215 
1216  /* Modify the MAC address field */
1217  for (i=0;i<6;i++) {
1218  mac_pointer[i] = macaddr[i];
1219  }
1220 
1221  /*
1222  * The modified descriptor is sitting in the mbox word array.
1223  * Because we're about to build a new mailbox command we need
1224  * to save off this modified descriptor.
1225  */
1226  temp_descriptor = malloc(len);
1227  if (temp_descriptor == NULL) {
1228  goto fail;
1229  }
1230  memcpy(temp_descriptor, (uint8_t *)desc_pointer, len);
1231 
1232  /* Send the descriptor back with COMMON_SET_PROFILE_CONFIG */
1233  set_req = (sli4_req_common_set_profile_config_t *)mbox_words;
1234  bzero(&mbox_words, sizeof(mbox_words));
1237  if (is_skyhawk(device)) {
1238  set_req->hdr.req.version = 1;
1239  } else {
1240  set_req->hdr.req.version = 0;
1241  }
1242  set_req->hdr.req.request_length = sizeof(mbox_words);
1243  set_req->desc_count = 1;
1244  memcpy((uint8_t *)set_req->desc, temp_descriptor, len);
1245 
1246  rc = ioctl(device->fd, IOCTL_CMD_ELX_PT_MBOX, &mbox);
1247  if (rc != 0) {
1248  goto fail;
1249  }
1250  set_res = (sli4_res_common_set_profile_config_t *) mbox_words;
1251  if (set_res->hdr.res.status != 0) {
1252  printf("Status is %d\n", get_res->hdr.res.status);
1253  printf("Addl status: 0x%x\n", get_res->hdr.res.additional_status);
1254  goto fail;
1255  }
1256  free(temp_descriptor);
1257  return 0;
1258 
1259 fail:
1260  if (temp_descriptor)
1261  free(temp_descriptor);
1262  return -1;
1263 }
1264 
1265 /**
1266  * @brief Issue a set non-volatile WWNN/WWPN
1267  *
1268  * Create a WRITE NVPARAMS mailbox command
1269  *
1270  * @param device device descriptor
1271  * @param wwn world-wide name
1272  * @param name WWNN/WWPN flag to set
1273  *
1274  * @return return zero for success, negative error code for error
1275  */
1276 int mbox_set_nv_wwn_pt(elxu_device_t *device, char *wwpn_p, char *wwnn_p)
1277 {
1278  elx_pt_ioctl_mbox_fc_t mbox;
1279  mbox_rw_nvparms_t req;
1280  int rc;
1281 
1282  bzero(&req, sizeof(req));
1283  req.command = MBOX_READ_NVPARMS;
1284 
1285  mbox.words = (uint32_t *) &req;
1286  mbox.num_words = ((sizeof(req) + 3) / 4);
1287 
1288  rc = ioctl(device->fd, IOCTL_CMD_ELX_PT_MBOX_FC, &mbox);
1289  if (rc != 0 || req.status != 0) {
1290  return -1;
1291  }
1292 
1293  if (wwpn_p != NULL) {
1294  rc = sscanf(wwpn_p, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
1295  &(req.wwpn[0]), &(req.wwpn[1]), &(req.wwpn[2]),
1296  &(req.wwpn[3]), &(req.wwpn[4]), &(req.wwpn[5]),
1297  &(req.wwpn[6]), &(req.wwpn[7]));
1298  if (rc != 8) {
1299  printf(" Invalid WWPN: %s\n", wwpn_p);
1300  return -1;
1301  }
1302  }
1303 
1304  if (wwnn_p != NULL) {
1305  rc = sscanf(wwnn_p, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
1306  &(req.wwnn[0]), &(req.wwnn[1]), &(req.wwnn[2]),
1307  &(req.wwnn[3]), &(req.wwnn[4]), &(req.wwnn[5]),
1308  &(req.wwnn[6]), &(req.wwnn[7]));
1309  if (rc != 8) {
1310  printf(" Invalid WWNN: %s\n", wwnn_p);
1311  return -1;
1312  }
1313  }
1314 
1316 
1317  rc = ioctl(device->fd, IOCTL_CMD_ELX_PT_MBOX_FC, &mbox);
1318  if (rc != 0 || req.status != 0) {
1319  return -1;
1320  }
1321 
1322  return 0;
1323 }
1324 
1325 /**
1326  * @brief Issue read flashrom mailbox command
1327  *
1328  * Create a SLI_CONFIG Read Flashrom mailbox command
1329  *
1330  * @param device device descriptor
1331  * @param opcode READ/WRITE_FLASHROM opcode value
1332  * @param optype READ/WRITE_FLASHROM optype value
1333  * @param optype READ/WRITE_FLASHROM offset value
1334  * @param outbuf output buffer
1335  * @param outbufLength length in bytes of output buffer
1336  *
1337  * @return return zero for success, negative error code for error
1338  */
1339 int mbox_read_flashrom(elxu_device_t *device, uint32_t opcode, uint32_t optype, uint32_t offset, void *outbuf,
1340  uint32_t outbufLength)
1341 {
1342  void *mqe = zmalloc(MBOX_ENTRY_LENGTH);
1343  mbox_sli_config_t *sli_config = mqe;
1344  mbox_common_read_flashrom_t *mbox = zmalloc(sizeof(*mbox));
1346  int rval = -1;
1347  uint32_t localOutbufLength;
1348  void *localOutbuf = NULL;
1349 
1350  assert(device);
1351 
1352  if (!mqe)
1353  goto done;
1354  if (!mbox)
1355  goto done;
1356 
1357  // Need to allocate a read buffer that's big enough for the response
1358  localOutbufLength = outbufLength + sizeof(*mbox);
1359  localOutbuf = zmalloc(localOutbufLength);
1360  if (!localOutbuf)
1361  goto done;
1362 
1363  rsp = (mbox_common_read_flashrom_t*)localOutbuf;
1364 
1365  sli_config->command = MBOX_SLI_CONFIG;
1366  sli_config->emb = 0;
1367  sli_config->pcmd_count = 1;
1368  sli_config->payload_length = localOutbufLength;
1369 
1370  sli_config->sge[0].address_low = ~0;
1371  sli_config->sge[0].address_high = ~0;
1372  sli_config->sge[0].length = localOutbufLength;
1373 
1374  mbox->common.subsystem = MBOX_SUBSYSTEM_COMMON;
1375  mbox->common.opcode = OPCODE_COMMON_READ_FLASHROM;
1376  mbox->common.word1.out.timeout = 0;
1377  mbox->common.request_length = outbufLength + 0x14;
1378 
1379  mbox->flashrom_access_op_code = opcode;
1380  mbox->flashrom_access_op_type = optype;
1381  mbox->data_buffer_size = outbufLength;
1382  mbox->offset = offset;
1383 
1384  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, (uint8_t*)mbox, sizeof (*mbox), localOutbuf,
1385  localOutbufLength);
1386  if (rval < 0) {
1387  zfree(mqe);
1388  return rval;
1389  }
1390 
1391  rval = rsp->common.word1.in.status;
1392  if (rval)
1393  {
1394  rval = -rval;
1395  }
1396  else
1397  {
1398  if (outbuf)
1399  memcpy(outbuf, ((uint8_t*)localOutbuf) + sizeof (*mbox), outbufLength);
1400  }
1401 
1402 done:
1403  zfree(localOutbuf);
1404  zfree(mbox);
1405  zfree(mqe);
1406  return rval;
1407 }
1408 
1409 /**
1410  * @brief Issue write flashrom mailbox command
1411  *
1412  * @param device device descriptor
1413  * @param opcode READ/WRITE_FLASHROM opcode value
1414  * @param optype READ/WRITE_FLASHROM optype value
1415  * @param optype READ/WRITE_FLASHROM offset value
1416  * @param inbuf input buffer
1417  * @param inbufLength length in bytes of input buffer
1418  *
1419  * @return return zero for success, negative error code for error
1420  */
1421 int mbox_write_flashrom(elxu_device_t *device, uint32_t opcode, uint32_t optype, uint32_t offset, void *inbuf,
1422  uint32_t inbufLength)
1423 {
1424  void *mqe = zmalloc(MBOX_ENTRY_LENGTH);
1425  mbox_sli_config_t *sli_config = mqe;
1426  mbox_common_read_flashrom_t *mbox = NULL;
1427  mbox_common_read_flashrom_t *rsp = zmalloc(sizeof(*rsp));
1428  int rval = -1;
1429  uint32_t localInbufLength = sizeof(*mbox) + inbufLength;
1430 
1431  assert(device);
1432 
1433  mbox = zmalloc(localInbufLength);
1434 
1435  if (!mqe)
1436  goto done;
1437  if (!rsp)
1438  goto done;
1439  if (!mbox)
1440  goto done;
1441 
1442  sli_config->command = MBOX_SLI_CONFIG;
1443  sli_config->emb = 0;
1444  sli_config->pcmd_count = 1;
1445  sli_config->payload_length = localInbufLength;
1446 
1447  sli_config->sge[0].address_low = ~0;
1448  sli_config->sge[0].address_high = ~0;
1449  sli_config->sge[0].length = localInbufLength;
1450 
1453  mbox->common.word1.out.timeout = 0;
1454  mbox->common.request_length = inbufLength + 0x14;
1455 
1456  mbox->flashrom_access_op_code = opcode;
1457  mbox->flashrom_access_op_type = optype;
1458  mbox->data_buffer_size = inbufLength;
1459  mbox->offset = offset;
1460 
1461  // Copy write payload
1462  if (inbuf)
1463  memcpy(&mbox[1], inbuf, inbufLength);
1464 
1465  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, (uint8_t*)mbox, localInbufLength, (uint8_t*)rsp,
1466  sizeof(*rsp));
1467  if (rval < 0) {
1468  zfree(mqe);
1469  return rval;
1470  }
1471 
1472  rval = rsp->common.word1.in.status;
1473  if (rval)
1474  {
1475  rval = -rval;
1476  }
1477  else
1478  {
1479  if (inbuf)
1480  memcpy(inbuf, &rsp[1], inbufLength);
1481  }
1482 
1483 done:
1484  zfree(mbox);
1485  zfree(rsp);
1486  zfree(mqe);
1487  return rval;
1488 }
1489 
1490 /**
1491  * @brief Issue COMMON_MANAGE_FAT mailbox commands
1492  *
1493  * This function issues Manage FAT mailbox commands. There are four supported operations:
1494  *
1495  * FAT_OPERATION_RETRIEVE read the FAT contents
1496  * FAT_OPERATION_QUERY return the length of the FAT (may be zero)
1497  * FAT_OPERATION_CLEAR clear the FAT
1498  * FAT_OPERATION_TRIGGER trigger a UE that will append to FAT
1499  *
1500  * @param device device descriptor
1501  * @param fat_opration requested FAT operation
1502  * @param read_log_offset read offset (for FAT_OPERATION_RETRIEVE)
1503  * @param buffer read buffer (for FAT_OPERATION_RETRIEVE)
1504  * @param bufferLength read buffer length in bytes (for FAT_OPERATION_RETRIEVE)
1505  *
1506  * @returns number of bytes read for FAT_OPERATION_RETRIEVE, or negative error code
1507  * @returns length of FAT for FAT_OPERATION_QUERY, or negative error code
1508  * @returns 0, or negative error code for FAT_OPERATION_CLEAR, FAT_OPERATION_TRIGGER
1509  */
1510 int mbox_manage_fat(elxu_device_t *device, uint32_t fat_operation, uint32_t read_log_offset, void *buffer,
1511  uint32_t bufferLength)
1512 {
1513  void *mqe = zmalloc(MBOX_ENTRY_LENGTH);
1514  mbox_sli_config_t *sli_config = mqe;
1515  mbox_common_manage_fat_t *mbox = zmalloc(sizeof(*mbox));
1517  int rval = -1;
1518  uint32_t localBufferLength;
1519  void *localBuffer = NULL;
1520 
1521  assert(device);
1522 
1523  if (!mqe)
1524  goto done;
1525  if (!mbox)
1526  goto done;
1527 
1528  // Need to allocate a read buffer that's big enough for the response
1529  localBufferLength = bufferLength + sizeof(*mbox);
1530  localBuffer = zmalloc(localBufferLength);
1531  if (!localBuffer)
1532  goto done;
1533 
1534  rsp = (mbox_common_manage_fat_t*)localBuffer;
1535 
1536  sli_config->command = MBOX_SLI_CONFIG;
1537  sli_config->emb = 0;
1538  sli_config->pcmd_count = 1;
1539  sli_config->payload_length = localBufferLength;
1540 
1541  sli_config->sge[0].address_low = ~0;
1542  sli_config->sge[0].address_high = ~0;
1543  sli_config->sge[0].length = localBufferLength;
1544 
1545  mbox->common.subsystem = MBOX_SUBSYSTEM_COMMON;
1546  mbox->common.opcode = OPCODE_COMMON_MANAGE_FAT;
1547  mbox->common.word1.out.timeout = 0;
1548  mbox->common.request_length = bufferLength + 0x14;
1549 
1550  mbox->params.request.fat_operation = fat_operation;
1551  mbox->params.request.read_log_offset = read_log_offset;
1552  mbox->params.request.read_log_length = bufferLength;
1553  mbox->params.request.data_buffer_size = bufferLength;
1554 
1555  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, (uint8_t*)mbox, sizeof (*mbox), localBuffer, localBufferLength);
1556  if (rval < 0) {
1557  zfree(mqe);
1558  return rval;
1559  }
1560 
1561  rval = rsp->common.word1.in.status;
1562  if (rval)
1563  {
1564  printf ("status 0x%02X addl 0x%02X\n", rsp->common.word1.in.status, rsp->common.word1.in.additional_status);
1565  rval = -rval;
1566  }
1567  else
1568  {
1569  switch (fat_operation)
1570  {
1572  if (buffer)
1573  memcpy(buffer, ((uint8_t*)localBuffer) + sizeof (*mbox), bufferLength);
1574  // fall through
1575  case FAT_OPERATION_QUERY:
1576  rval = rsp->params.response.log_size;
1577  break;
1578  case FAT_OPERATION_CLEAR:
1579  case FAT_OPERATION_TRIGGER:
1580  break;
1581  }
1582  }
1583 
1584 done:
1585  zfree(localBuffer);
1586  zfree(mbox);
1587  zfree(mqe);
1588  return rval;
1589 }
1590 
1591 /**
1592  * @brief Issue EFD mailbox command
1593  *
1594  * Submits the mailbox command given by 'mbox' for 'mboxLength'. Note, that 'mboxLength'
1595  * will generally include a response payload
1596  *
1597  * @param device device descriptor
1598  * @param opcode common mailbox opcode
1599  * @param mbox pointer to common mailbox command + payload
1600  * @param mboxLength length of mailbox command + payload
1601  *
1602  * @return 0 if successful, a negative error code for failure
1603  */
1604 int mbox_ext_fat(elxu_device_t *device, uint32_t opcode, void *mbox, uint32_t mboxLength)
1605 {
1606  void *mqe = NULL;
1607  mbox_common_t *hdr = NULL;
1608  mbox_sli_config_t *sli_config = NULL;
1609  mbox_common_t *rsp = NULL;
1610  int rval = -1;
1611 
1612  assert(device);
1613  assert(mbox);
1614 
1615  mqe = zmalloc(MBOX_ENTRY_LENGTH);
1616  if (!mqe)
1617  return -1;
1618 
1619  sli_config = mqe;
1620  sli_config->command = MBOX_SLI_CONFIG;
1621  sli_config->emb = 0; // Not Embedded, Mbox Cmd data is a part of a payload buffer
1622  sli_config->pcmd_count = 1;
1623  sli_config->payload_length = mboxLength;
1624 
1625  sli_config->sge[0].address_low = ~0;
1626  sli_config->sge[0].address_high = ~0;
1627  sli_config->sge[0].length = mboxLength;
1628 
1629  hdr = mbox;
1631  hdr->opcode = opcode;
1632  hdr->word1.out.timeout = 0;
1633  hdr->request_length = mboxLength;
1634 
1635  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, mbox, mboxLength, mbox, mboxLength);
1636  if (rval < 0) {
1637  zfree(mqe);
1638  return rval;
1639  }
1640 
1641  rsp = mbox;
1642  rval = rsp->word1.in.status;
1643  if (rval)
1644  {
1645  printf ("Error: status 0x%02X addl 0x%02X\n", rsp->word1.in.status, rsp->word1.in.additional_status);
1646  rval = -rval;
1647  }
1648 
1649  zfree(mqe);
1650  return rval;
1651 }
1652 
1653 /**
1654  * @brief Issue the Set TCP Parameters mbox command
1655  *
1656  * @param device device descriptor
1657  * @param request_flags flags indicating which values should be updated
1658  * @param ackFrequency ACK frequency
1659  * @param delayedAckTimerValue delayed ACK timer value, in milliseconds
1660  *
1661  * @return 0 if successful, a negative error code for failure
1662  */
1663 int mbox_tcp_parameters(elxu_device_t *device, uint32_t request_flags, uint32_t ackFrequency,
1664  uint32_t delayedAckTimerValue)
1665 {
1666  void *mqe;
1667  mbox_sli_config_t *sli_config;
1669  int request_len = sizeof(mbox_common_iscsi_set_tcp_parameters_t) - sizeof(mbox_common_t);
1670  int rval = -1;
1671 
1672  assert(device);
1673 
1674  mqe = zmalloc(MBOX_ENTRY_LENGTH);
1675  if (!mqe) {
1676  return -1;
1677  }
1678 
1679  sli_config = (mbox_sli_config_t *) mqe;
1680  mbox = (mbox_common_iscsi_set_tcp_parameters_t*)(&sli_config[1]);
1681 
1682  sli_config->command = MBOX_SLI_CONFIG;
1683  sli_config->emb = 1;
1684  sli_config->pcmd_count = 1;
1685  sli_config->payload_length = sizeof(*mbox);
1686 
1689  mbox->common.word1.out.timeout = 0;
1690  mbox->common.request_length = request_len;
1691 
1692  mbox->params.request.request_flags = request_flags;
1693  mbox->params.request.delayed_ack_timer = delayedAckTimerValue;
1694  mbox->params.request.ack_frequency = ackFrequency;
1695 
1696  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, mbox, request_len, mbox, request_len);
1697 
1698  if (sli_config->status) {
1699  printf("sli status 0x%02x, mbox status 0x%02X, mbox addl 0x%02X\n",
1700  sli_config->status,
1701  mbox->common.word1.in.status,
1702  mbox->common.word1.in.additional_status);
1703  rval = -1;
1704  }
1705 
1706  zfree(mqe);
1707  return rval;
1708 }
1709 
1710 /*
1711  * @brief Issue the Connection Update mbox command
1712  *
1713  * @param device device descriptor
1714  * @param request_flags flags indicating which values should be updated
1715  * @param constrainWindowValue number of bytes by which to reduce the TCP window size
1716  *
1717  * @return 0 if successful, a negative error code for failure
1718  */
1719 int mbox_connection_update(elxu_device_t *device, uint32_t request_flags,
1720  uint16_t connectionId, uint32_t constrainWindowValue)
1721 {
1722  void *mqe;
1723  mbox_sli_config_t *sli_config;
1725  int request_len = sizeof(mbox_common_iscsi_connection_update_t);
1726  int rval = -1;
1727 
1728  assert(device);
1729 
1730  mqe = zmalloc(MBOX_ENTRY_LENGTH);
1731  if (!mqe) {
1732  return -1;
1733  }
1734 
1735  sli_config = (mbox_sli_config_t *) mqe;
1736  mbox = (mbox_common_iscsi_connection_update_t*)(&sli_config[1]);
1737 
1738  sli_config->command = MBOX_SLI_CONFIG;
1739  sli_config->emb = 1;
1740  sli_config->pcmd_count = 0;
1741  sli_config->payload_length = sizeof(*mbox);
1742 
1745  mbox->common.word1.out.timeout = 0;
1746  mbox->common.request_length = request_len;
1747 
1748  mbox->params.request.request_flags = request_flags;
1749  mbox->params.request.connection_id = connectionId;
1750  mbox->params.request.window_reduction = constrainWindowValue;
1751 
1752  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, mbox, request_len, mbox, request_len);
1753 
1754  if (sli_config->status) {
1755  printf("sli status 0x%02x, mbox status 0x%02X, mbox addl 0x%02X\n",
1756  sli_config->status,
1757  mbox->common.word1.in.status,
1758  mbox->common.word1.in.additional_status);
1759  rval = -1;
1760  }
1761 
1762  zfree(mqe);
1763  return rval;
1764 }
1765 
1766 /**
1767  * @brief Get connection info
1768  *
1769  * @param device device descriptor
1770  * @param connection the handle of the connection for which info is requested
1771  *
1772  * Only supported on Skyhawk
1773  *
1774  * @return 0 if successful, a negative error code for failure
1775  */
1776 int mbox_get_connection_info(elxu_device_t *device, uint32_t connectionHandle)
1777 {
1778  void *mqe;
1779  mbox_sli_config_t *sli_config;
1781  int request_len = sizeof(mbox_common_iscsi_get_connection_info_t) - sizeof(mbox_common_t);
1782  int rval = -1;
1783 
1784  assert(device);
1785 
1786  mqe = zmalloc(MBOX_ENTRY_LENGTH);
1787  if (!mqe) {
1788  return -1;
1789  }
1790 
1791  sli_config = (mbox_sli_config_t *) mqe;
1792  mbox = (mbox_common_iscsi_get_connection_info_t*)(&sli_config[1]);
1793 
1794  sli_config->command = MBOX_SLI_CONFIG;
1795  sli_config->emb = 1;
1796  sli_config->pcmd_count = 0;
1797  sli_config->payload_length = sizeof(*mbox);
1798 
1801  mbox->common.word1.out.timeout = 0;
1802  mbox->common.request_length = request_len;
1803 
1804  mbox->params.request.connection_handle = connectionHandle;
1805 
1806  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, mbox, request_len, mbox, request_len);
1807 
1808  switch (sli_config->status) {
1809  case 0:
1810  // Success, report results
1811  printf(" Connection Handle: 0x%x\n", connectionHandle);
1812  printf(" Source Address: %s\n",
1813  format_sli4_ip_address(mbox->params.response.source_ip_address));
1814  printf(" Source Port: %d\n", mbox->params.response.source_port);
1815  printf(" Dest Address: %s\n",
1816  format_sli4_ip_address(mbox->params.response.dest_ip_address));
1817  printf(" Dest Port: %d\n", mbox->params.response.dest_port);
1818  printf(" MSS: %d\n", mbox->params.response.tcp_mss);
1819  printf(" Interface Handle: 0x%08x\n", mbox->params.response.interface_handle);
1820  printf(" Window Scale Shift Count: %d\n", mbox->params.response.window_scale_shift_count);
1821  rval = 0;
1822  break;
1823  case 0x20:
1824  // Invalid connection handle
1825  printf("%x is not a valid connection handle\n", connectionHandle);
1826  rval = -1;
1827  break;
1828  default:
1829  // Some other error
1830  printf("sli status 0x%02x, mbox status 0x%02X, mbox addl 0x%02X\n",
1831  sli_config->status,
1832  mbox->common.word1.in.status,
1833  mbox->common.word1.in.additional_status);
1834  rval = -1;
1835  break;
1836  }
1837 
1838  zfree(mqe);
1839  return rval;
1840 }
1841 
1850 };
1851 
1852 /**
1853  * @brief Get the CLP string from the mgmt config string.
1854  *
1855  * @param mgmt_str mgmt string.
1856  *
1857  * @return Returns the CLP string corresponding to mgmt_str.
1858  */
1859 static const char *
1861 {
1862  uint32_t i;
1863 
1864  for (i = 0; i < ARRAY_SIZE(mbox_linkcfg_str); i++) {
1865  if (strncmp(mbox_linkcfg_str[i].mgmt_str, mgmt_str,
1866  strlen(mgmt_str)) == 0) {
1867  return mbox_linkcfg_str[i].clp_str;
1868  }
1869  }
1870  return NULL;
1871 }
1872 
1873 /**
1874  * @brief Get the mgmt config string from the CLP string.
1875  *
1876  * @param clp_str clp string.
1877  *
1878  * @return Returns the mgmt string corresponding to clp_str.
1879  */
1880 static char *
1882 {
1883  uint32_t i;
1884 
1885  for (i = 0; i < ARRAY_SIZE(mbox_linkcfg_str); i++) {
1886  if (strncmp(mbox_linkcfg_str[i].clp_str, clp_str,
1887  strlen(clp_str) - 2) == 0) {
1888  return mbox_linkcfg_str[i].mgmt_str;
1889  }
1890  }
1891  return NULL;
1892 }
1893 
1895 {
1896  sli4_res_dmtf_exec_clp_cmd_t *response = NULL;
1898  mbox_sli_config_t *sli_config = NULL;
1899  memref_t *clp_response = NULL;
1900  memref_t *clp_command = NULL;
1901  static char result[80];
1902  void *mqe = NULL;
1903  char *resp_str;
1904  char *mgmt_str;
1905  int rval = -1;
1906  int rc;
1907 
1908  assert(device);
1909 
1910  mqe = zmalloc(MBOX_ENTRY_LENGTH);
1911  if (mqe == NULL) {
1912  goto err;
1913  }
1914 
1915  clp_command = elx_pt_dma_alloc(device, 80);
1916  if (clp_command == NULL) {
1917  goto err;
1918  }
1919 
1920  clp_response = elx_pt_dma_alloc(device, 256);
1921  if (clp_response == NULL) {
1922  goto err;
1923  }
1924 
1925  response = zmalloc(sizeof(sli4_res_dmtf_exec_clp_cmd_t));
1926  if (response == NULL) {
1927  goto err;
1928  }
1929 
1930  snprintf(clp_command->vaddr, 80, "show / OEMELX_LinkConfig");
1931 
1932  sli_config = (mbox_sli_config_t *) mqe;
1933  sli_config->command = MBOX_SLI_CONFIG;
1934 
1935  request = (sli4_req_dmtf_exec_clp_cmd_t *)(&sli_config[1]);
1936 
1937  request->hdr.req.subsystem = MBOX_SUBSYSTEM_DMTF;
1939  request->hdr.req.request_length = sizeof(*request) -
1940  sizeof(sli4_ioctl_header_t);
1941  request->cmd_buf_length = 80;
1942  request->cmd_buf_addr_high = addr32_hi(clp_command->paddr);
1943  request->cmd_buf_addr_low = addr32_lo(clp_command->paddr);
1944  request->resp_buf_length = 256;
1945  request->resp_buf_addr_high = addr32_hi(clp_response->paddr);
1946  request->resp_buf_addr_low = addr32_lo(clp_response->paddr);
1947 
1948  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, request, sizeof(*request),
1949  response, sizeof(*response));
1950 
1951  rc = response->hdr.res.status;
1952  if (rval != 0 || rc != 0) {
1953  printf("Status %02x:%02x\n", response->hdr.res.status,
1954  response->hdr.res.additional_status);
1955  printf("clp_status = %02X, clp_addl_status = %02X\n",
1956  response->clp_status, response->clp_detailed_status);
1957  printf("Mbox write failed\n");
1958  goto err;
1959  }
1960 
1961  /* Parse the response */
1962  resp_str = strstr(clp_response->vaddr, "endoutput");
1963  if (resp_str == NULL) {
1964  printf("Parse failure\n");
1965  goto err;
1966  }
1967  *resp_str = '\0';
1968 
1969  resp_str = strstr(clp_response->vaddr, "retdata");
1970  if (resp_str == NULL) {
1971  printf("Parse failure\n");
1972  goto err;
1973  }
1974  resp_str += 8;
1975 
1976  mgmt_str = mbox_get_mgmt_from_clp_linkcfg_str(resp_str);
1977  if (mgmt_str != NULL && strlen(mgmt_str) < sizeof(result)) {
1978  strncpy(result, mgmt_str, sizeof(result));
1979  } else {
1980  strncpy(result, "UNKNOWN", sizeof(result));
1981  }
1982 
1983  elx_pt_dma_free(clp_response);
1984  elx_pt_dma_free(clp_command);
1985 
1986  /* Returning a static variable */
1987  return result;
1988 
1989 err:
1990  if (response != NULL) {
1991  zfree(response);
1992  }
1993  if (clp_response != NULL) {
1994  elx_pt_dma_free(clp_response);
1995  }
1996  if (clp_command != NULL) {
1997  elx_pt_dma_free(clp_command);
1998  }
1999  if (mqe != NULL) {
2000  zfree(mqe);
2001  }
2002 
2003  return NULL;
2004 }
2005 
2007 {
2008  sli4_res_get_reconfig_link_info_t *response = NULL;
2010  mbox_sli_config_t *sli_config = NULL;
2011  static char linkcfg_str[32];
2012  size_t response_len;
2013  void *mqe = NULL;
2014  int rval = -1;
2015  uint32_t i;
2016  int rc;
2017 
2018  assert(device);
2019 
2020  mqe = zmalloc(MBOX_ENTRY_LENGTH);
2021  if (mqe == NULL) {
2022  goto err;
2023  }
2024 
2025  /* Allocate a buffer big enough for the response, including
2026  * MAX_LINK_CONFIG_DESCRIPTORS link descriptors.
2027  */
2028  response_len = sizeof(sli4_res_get_reconfig_link_info_t) +
2030  response = zmalloc(response_len);
2031  if (response == NULL) {
2032  goto err;
2033  }
2034 
2035  sli_config = (mbox_sli_config_t *) mqe;
2036  sli_config->command = MBOX_SLI_CONFIG;
2037 
2038  request = (sli4_req_get_reconfig_link_info_t *)(&sli_config[1]);
2039 
2042  request->hdr.req.request_length = response_len;
2043 
2044  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, request, sizeof(*request),
2045  response, response_len);
2046 
2047  rc = response->hdr.res.status;
2048  if (rval != 0 || rc != 0) {
2049  printf("Status %02x:%02x\n", response->hdr.res.status,
2050  response->hdr.res.additional_status);
2051  printf("Mbox write failed\n");
2052  goto err;
2053  }
2054 
2055  strncpy(linkcfg_str, "UNKNOWN", sizeof(linkcfg_str));
2056  for (i = 0; i < response->link_config_desc_count; i++) {
2057  if (response->desc[i].link_config_id ==
2058  response->active_link_config_id) {
2059  memcpy(linkcfg_str, response->desc[i].config_description,
2060  sizeof(response->desc[i].config_description));
2061  goto err;
2062  }
2063  }
2064 
2065 err:
2066  if (response != NULL) {
2067  zfree(response);
2068  }
2069  if (mqe != NULL) {
2070  zfree(mqe);
2071  }
2072  /* Returning a static variable */
2073  return linkcfg_str;
2074 }
2075 
2076 /**
2077  * @brief Get Link configuration
2078  *
2079  * @par Description
2080  * Get Link configuration information via passthrough driver
2081  *
2082  * @param device device descriptor
2083  *
2084  * @return 0 if successful, a negative error code for failure
2085  */
2087 {
2088  char *linkcfg_str = NULL;
2089 
2090  if (is_lancer(device)) {
2091  linkcfg_str = mbox_get_linkcfg_lancer_pt(device);
2092  } else if(is_skyhawk(device)) {
2093  linkcfg_str = mbox_get_linkcfg_skyhawk_pt(device);
2094  }
2095 
2096  return linkcfg_str;
2097 }
2098 
2099 int mbox_set_linkcfg_lancer_pt(elxu_device_t *device, char *config)
2100 {
2101  sli4_res_dmtf_exec_clp_cmd_t *response = NULL;
2103  mbox_sli_config_t *sli_config = NULL;
2104  memref_t *clp_response = NULL;
2105  memref_t *clp_command = NULL;
2106  const char *linkcfg_str;
2107  void *mqe = NULL;
2108  int clp_status;
2109  char *resp_str;
2110  int rval = -1;
2111  int rc;
2112 
2113  assert(device);
2114 
2115  mqe = zmalloc(MBOX_ENTRY_LENGTH);
2116  if (mqe == NULL) {
2117  goto err;
2118  }
2119 
2120  clp_command = elx_pt_dma_alloc(device, 80);
2121  if (clp_command == NULL) {
2122  goto err;
2123  }
2124 
2125  clp_response = elx_pt_dma_alloc(device, 80);
2126  if (clp_response == NULL) {
2127  goto err;
2128  }
2129 
2130  response = zmalloc(sizeof(sli4_res_dmtf_exec_clp_cmd_t));
2131  if (response == NULL) {
2132  goto err;
2133  }
2134 
2135  /* translate mgmt linkcfg string to CLP string */
2136  linkcfg_str = mbox_get_clp_from_mgmt_linkcfg_str(config);
2137 
2138  snprintf(clp_command->vaddr, 80, "set / OEMELX_LinkConfig=%s", linkcfg_str);
2139 
2140  sli_config = (mbox_sli_config_t *) mqe;
2141  sli_config->command = MBOX_SLI_CONFIG;
2142 
2143  request = (sli4_req_dmtf_exec_clp_cmd_t *)(&sli_config[1]);
2144 
2145  request->hdr.req.subsystem = MBOX_SUBSYSTEM_DMTF;
2147  request->hdr.req.request_length = sizeof(*request) -
2148  sizeof(sli4_ioctl_header_t);
2149  request->cmd_buf_length = 80;
2150  request->cmd_buf_addr_high = addr32_hi(clp_command->paddr);
2151  request->cmd_buf_addr_low = addr32_lo(clp_command->paddr);
2152  request->resp_buf_length = 80;
2153  request->resp_buf_addr_high = addr32_hi(clp_response->paddr);
2154  request->resp_buf_addr_low = addr32_lo(clp_response->paddr);
2155 
2156  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, request, sizeof(*request),
2157  response, sizeof(*response));
2158 
2159  rc = response->hdr.res.status;
2160  if (rval != 0 || rc != 0) {
2161  printf("Status %02x:%02x\n", response->hdr.res.status,
2162  response->hdr.res.additional_status);
2163  printf("clp_status = %#X, clp_addl_status = %0#X\n",
2164  response->clp_status, response->clp_detailed_status);
2165  printf("Mbox write failed\n");
2166  goto err;
2167  }
2168 
2169  /* Parse the response */
2170  resp_str = strstr(clp_response->vaddr, "status=");
2171  if (resp_str == NULL) {
2172  printf("Parse failure\n");
2173  rval = -1;
2174  goto err;
2175  }
2176  resp_str += 7;
2177  clp_status = atoi(resp_str);
2178  if (clp_status != 0) {
2179  printf("Device returned status %d when setting link config.\n",
2180  clp_status);
2181  rval = -1;
2182  goto err;
2183  }
2184 
2185 err:
2186  if (response != NULL) {
2187  zfree(response);
2188  }
2189  if (clp_response != NULL) {
2190  elx_pt_dma_free(clp_response);
2191  }
2192  if (clp_command != NULL) {
2193  elx_pt_dma_free(clp_command);
2194  }
2195  if (mqe != NULL) {
2196  zfree(mqe);
2197  }
2198  return rval;
2199 }
2200 
2201 /**
2202  * @brief Mapping from mgmt string to Skyhawk config IDs
2203  *
2204  * This structure provides a mapping from the management string
2205  * (exposed to set-linkcfg) to the Skyhawk config IDs sent via
2206  * SET_RECONFIG_LINK_INFO command
2207  */
2208 typedef struct mbox_skyhawk_linkcfg_map_s {
2209  char *mgmt_str;
2210  uint32_t config_id;
2212 
2213 /**
2214  * @brief Mapping from mgmt string to Skyhawk config IDs
2215  */
2217  {OCS_CONFIG_LINKCFG_4X10G, 0x0a},
2218  {OCS_CONFIG_LINKCFG_1X40G, 0x09}
2219 };
2220 
2221 /**
2222  * @brief Get the config ID from the mgmt config string.
2223  *
2224  * @param mgmt_str mgmt string value.
2225  *
2226  * @return Returns the config ID value corresponding to mgmt_str.
2227  */
2228 static uint32_t
2230 {
2231  uint32_t i;
2232 
2233  for (i = 0; i < ARRAY_SIZE(mbox_skyhawk_linkcfg_map); i++) {
2234  if (strncmp(mbox_skyhawk_linkcfg_map[i].mgmt_str, mgmt_str,
2235  strlen(mgmt_str)) == 0) {
2236  return mbox_skyhawk_linkcfg_map[i].config_id;
2237  }
2238  }
2239  return 0;
2240 }
2241 
2242 int mbox_set_linkcfg_skyhawk_pt(elxu_device_t *device, char *config)
2243 {
2244  sli4_res_set_reconfig_link_info_t *response = NULL;
2246  mbox_sli_config_t *sli_config = NULL;
2247  void *mqe = NULL;
2248  int rval = -1;
2249  int rc = -1;
2250 
2251  assert(device);
2252 
2253  mqe = zmalloc(MBOX_ENTRY_LENGTH);
2254  if (mqe == NULL) {
2255  goto err;
2256  }
2257 
2258  response = zmalloc(sizeof(sli4_res_set_reconfig_link_info_t));
2259  if (response == NULL) {
2260  goto err;
2261  }
2262 
2263  sli_config = (mbox_sli_config_t *) mqe;
2264  sli_config->command = MBOX_SLI_CONFIG;
2265 
2266  request = (sli4_req_set_reconfig_link_info_t *)(&sli_config[1]);
2267 
2270  request->hdr.req.request_length = sizeof(*request) -
2271  sizeof(sli4_ioctl_header_t);
2272 
2274 
2275  rval = mbox_common(device, mqe, MBOX_ENTRY_LENGTH, request, sizeof(*request),
2276  response, sizeof(*response));
2277 
2278  rc = response->hdr.res.status;
2279  if (rval != 0 || rc != 0) {
2280  printf("Status %02x:%02x\n", response->hdr.res.status,
2281  response->hdr.res.additional_status);
2282  printf("Mbox write failed\n");
2283  }
2284 
2285 err:
2286  if (response != NULL) {
2287  zfree(response);
2288  }
2289  if (mqe != NULL) {
2290  zfree(mqe);
2291  }
2292  return rc;
2293 }
2294 
2295 /**
2296  * @brief Set Link configuration
2297  *
2298  * @par Description
2299  * Sends a set_linkcfg command via passthrough driver
2300  *
2301  * @param device device descriptor
2302  * @param config new link configuration string
2303  *
2304  * @return 0 if successful, a negative error code for failure
2305  */
2306 int mbox_set_linkcfg_pt(elxu_device_t *device, char *config)
2307 {
2308  int rc = -1;
2309 
2310  if (is_lancer(device)) {
2311  rc = mbox_set_linkcfg_lancer_pt(device, config);
2312  } else if(is_skyhawk(device)) {
2313  rc = mbox_set_linkcfg_skyhawk_pt(device,config);
2314  }
2315 
2316  return rc;
2317 }
2318 
2319 int create_vport(elxu_device_t *device_p, uint64_t wwnn, uint64_t wwpn, int targetFlag, int initiatorFlag)
2320 {
2321  ocs_ioctl_vport_t vport;
2322  int rc;
2323 
2324  memset(&vport, 0, sizeof(vport));
2325  vport.req_create = 1;
2326  vport.enable_tgt = targetFlag;
2327  vport.enable_ini = initiatorFlag;
2328  vport.wwnn = wwnn;
2329  vport.wwpn = wwpn;
2330 
2331  rc = elxu_ioctl_device(device_p, OCS_IOCTL_CMD_VPORT, &vport);
2332  if (rc) {
2333  fprintf(stderr, "vport creation failed\n");
2334  }
2335 
2336  return rc;
2337 }
2338 
2339 int remove_vport(elxu_device_t *device_p, uint64_t wwnn, uint64_t wwpn, int targetFlag, int initiatorFlag)
2340 {
2341  ocs_ioctl_vport_t vport;
2342  int rc;
2343 
2344  memset(&vport, 0, sizeof(vport));
2345  vport.req_create = 0;
2346  vport.enable_tgt = targetFlag;
2347  vport.enable_ini = initiatorFlag;
2348  vport.wwnn = wwnn;
2349  vport.wwpn = wwpn;
2350 
2351  rc = elxu_ioctl_device(device_p, OCS_IOCTL_CMD_VPORT, &vport);
2352  if (rc) {
2353  perror("ioctl");
2354  }
2355 
2356  return rc;
2357 }
2358 
2359 /**
2360  * @brief Given a 6-word IP address in the format specified in the SLI4 spec, return a printable IP address.
2361  *
2362  * @param address A pointer to an IP address in an array of six 32-bit words
2363  *
2364  * @return a pointer to a static array containing a printable IP address
2365  */
2366 static char* format_sli4_ip_address(uint32_t *address)
2367 {
2368  static char ret[40];
2369  int address_type;
2370  uint8_t *address_bytes = (uint8_t *)address;
2371 
2372  address_type = address_bytes[3];
2373 
2374  // TODO: These IP type numbers should be #defines somewhere
2375  if (address_type < 3) {
2376  /* Print the IP address in IPV4 format */
2377  sprintf(ret, "%d.%d.%d.%d",
2378  address_bytes[4],
2379  address_bytes[5],
2380  address_bytes[6],
2381  address_bytes[7]);
2382  } else {
2383  /* Print the IP address in IPV6 format */
2384  sprintf(ret,"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
2385  address_bytes[4], address_bytes[5],
2386  address_bytes[6], address_bytes[7],
2387  address_bytes[8], address_bytes[9],
2388  address_bytes[10], address_bytes[11],
2389  address_bytes[12], address_bytes[13],
2390  address_bytes[14], address_bytes[15],
2391  address_bytes[16], address_bytes[17],
2392  address_bytes[18], address_bytes[19]);
2393  }
2394 
2395  return ret;
2396 }
2397 
2398 /**
2399  * @brief Send a mailbox command
2400  *
2401  * Populates a mailbox command passing input and output buffer to the device
2402  *
2403  * For SLI_CONFIG commands with non-embedded command, the command should be
2404  * put in the inbuf, the mboxcmd will point to just the SLI_CONFIG command +
2405  * buffer descriptor
2406  *
2407  * @param device device descriptor
2408  * @param mboxcmd pointer to mailbox command data
2409  * @param mboxcmdLength length of mailbox command in bytes
2410  * @param inbuf input buffer
2411  * @param inbufLength length in bytes of input buffer in bytes
2412  * @param outbuf output buffer
2413  * @param outbufLength length in bytes of output buffer in bytes
2414  * @param timeout the mailbox timeout for the command to be carried out
2415  *
2416  * @return return zero for success, negative error code for error
2417  */
2418 int mbox_common(elxu_device_t *device, mbox_command_t *mboxcmd, uint32_t mboxcmdLength,
2419  void *inbuf, uint32_t inbufLength, void *outbuf, uint32_t outbufLength)
2420 {
2421  if (device == NULL) {
2422  return -1;
2423  }
2424 
2425  if (device->driver == DEVICE_DRIVER_OCS) {
2426  return ocs_mbox(device, mboxcmd, mboxcmdLength, inbuf, inbufLength, outbuf, outbufLength);
2427  } else if (device->driver == DEVICE_DRIVER_PT) {
2428  return pt_mbox(device, mboxcmd, mboxcmdLength, inbuf, inbufLength, outbuf, outbufLength);
2429  } else {
2430  return -1;
2431  }
2432 }
2433 
2434 static int pt_mbox(elxu_device_t *device, mbox_command_t *mboxcmd, uint32_t mboxcmdLength,
2435  void *inbuf, uint32_t inbufLength, void *outbuf, uint32_t outbufLength)
2436 {
2437  uint8_t *request;
2438  int rc;
2439 
2440  if (mboxcmd->request.command == MBOX_SLI_CONFIG) {
2441  elx_pt_ioctl_mbox_t mbox;
2442  /*
2443  * For a SLI_CONFIG command we can just send inbuf
2444  * to the elx_pt driver using the ELX_PT_MBOX ioctl.
2445  * The driver will handle creating a SLI_CONFIG MQE
2446  * and allocating DMA buffers.
2447  */
2448 
2449  request = malloc(inbufLength);
2450  if (request == NULL) {
2451  return -1;
2452  }
2453 
2454  memcpy(request, inbuf, inbufLength);
2455 
2456  mbox.num_words = (inbufLength + (sizeof(uint32_t)-1)) / sizeof(uint32_t);
2457  mbox.words = (uint32_t *)request;
2458 
2459  rc = ioctl(device->fd, IOCTL_CMD_ELX_PT_MBOX, &mbox);
2460 
2461  memcpy(outbuf, request, outbufLength);
2462  free(request);
2463 
2464  } else {
2465  elx_pt_ioctl_mbox_fc_t mbox;
2466  /*
2467  * The command is not a SLI_CONFIG. Just send it
2468  * as-is with ELX_PT_MBOX_FC
2469  */
2470  request = malloc(mboxcmdLength);
2471  if (request == NULL) {
2472  return -1;
2473  }
2474 
2475  memcpy(request, &(mboxcmd->request), mboxcmdLength);
2476 
2477  mbox.num_words = (mboxcmdLength + 3) / 4;
2478  mbox.words = (uint32_t *)request;
2479 
2480  rc = ioctl(device->fd, IOCTL_CMD_ELX_PT_MBOX_FC, &mbox);
2481 
2482  memcpy(&(mboxcmd->response), request, mboxcmdLength);
2483  free(request);
2484  }
2485 
2486  return rc;
2487 }
2488 
2489 static int ocs_mbox(elxu_device_t *device, mbox_command_t *mboxcmd, uint32_t mboxcmdLength, void *inbuf,
2490  uint32_t inbufLength, void *outbuf, uint32_t outbufLength)
2491 {
2492  int rval = -1;
2494 
2495  memset(&cmd, 0, sizeof(ocs_ioctl_elxu_mbox_t));
2496 
2497  cmd.magic = ELXU_BSD_MAGIC;
2498  cmd.size = sizeof(ocs_ioctl_elxu_mbox_t);
2499 
2500  if (mboxcmdLength > sizeof(cmd.payload)) {
2501  printf("%s: mboxcmd too big (actual=%d allowed=%zu)\n", __func__,
2502  mboxcmdLength, sizeof(cmd.payload));
2503  return -1;
2504  }
2505 
2506  memcpy(cmd.payload, mboxcmd, mboxcmdLength);
2507 
2508  switch (mboxcmd->request.command) {
2509  case MBOX_SLI_CONFIG:
2510  cmd.in_addr = (uint64_t)inbuf;
2511  cmd.in_bytes = inbufLength;
2512 
2513  cmd.out_addr = (uint64_t)outbuf;
2514  cmd.out_bytes = outbufLength;
2515  break;
2516 
2517  case MBOX_READ_REV:
2518  case MBOX_READ_STATUS:
2519  case MBOX_RUN_BIU_DIAG:
2520  case MBOX_READ_LNK_STAT:
2521  break;
2522 
2523  default:
2524  printf("%s, command %x not supported.\n", __func__, mboxcmd->request.command);
2525  break;
2526  }
2527 
2528  rval = elxu_ioctl_device(device, OCS_IOCTL_CMD_ELXU_MBOX, &cmd);
2529  if (rval < 0) {
2530  perror("ioctl");
2531  }
2532 
2533  memcpy(mboxcmd, cmd.payload, mboxcmdLength);
2534 
2535  return rval;
2536 }
2537 
2538 /**
2539  * @brief Request a DMA allocation through elx_pt
2540  *
2541  * @par Description
2542  * Requests a DMA buffer allocation from the driver.
2543  *
2544  * @param device device structure
2545  * @param size Size of the requested buffer in bytes
2546  *
2547  * @return a pointer to a new memref_t on success, NULL on failure
2548  */
2550 {
2551  int rc;
2552  elx_pt_ioctl_dma_alloc_t dma_alloc;
2553  memref_t *memref;
2554  long pagesize;
2555 
2556  pagesize = sysconf(_SC_PAGESIZE);
2557 
2558  memref = malloc(sizeof(memref_t));
2559  if (memref == NULL) {
2560  return NULL;
2561  }
2562 
2563  dma_alloc.req_size = size;
2564  rc = ioctl(device->fd, IOCTL_CMD_ELX_PT_DMA_ALLOC, &dma_alloc);
2565  if (rc != 0) {
2566  free(memref);
2567  return NULL;
2568  }
2569 
2570  memref->vaddr = mmap(NULL, ROUNDUP(size, pagesize), PROT_READ | PROT_WRITE, MAP_SHARED,
2571  device->fd, dma_alloc.tag * pagesize);
2572  if (memref->vaddr == MAP_FAILED) {
2573  perror("mmap");
2574  elx_pt_ioctl_dma_free_t dma_free;
2575 
2576  memset(&dma_free, 0, sizeof(dma_free));
2577  dma_free.tag = dma_alloc.tag;
2578  (void)ioctl(device->fd, IOCTL_CMD_ELX_PT_DMA_FREE, &dma_free);
2579 
2580  free(memref);
2581  memref = NULL;
2582  } else {
2583  memref->paddr = dma_alloc.paddr;
2584  memref->tag = dma_alloc.tag;
2585  memref->device = device;
2586  memref->size = size;
2587  }
2588 
2589  return memref;
2590 }
2591 
2592 /**
2593  * @brief Free a DMA allocation through elx_pt
2594  *
2595  * @par Description
2596  * Sends a DMA free request to the driver.
2597  *
2598  * @param memref The memref_t to be freed.
2599  *
2600  * @return nothing
2601  */
2603 {
2604  elx_pt_ioctl_dma_free_t dma_free;
2605  long pagesize;
2606 
2607  pagesize = sysconf(_SC_PAGESIZE);
2608 
2609  if (memref == NULL) {
2610  return;
2611  }
2612 
2613  if (memref->vaddr != NULL) {
2614  munmap(memref->vaddr, ROUNDUP(memref->size, pagesize));
2615 
2616  memset(&dma_free, 0, sizeof(dma_free));
2617  dma_free.tag = memref->tag;
2618 
2619  ioctl(memref->device->fd, IOCTL_CMD_ELX_PT_DMA_FREE, &dma_free);
2620  }
2621 
2622  free(memref);
2623 }
2624 
2625 int mbox_fw_reset_pt(elxu_device_t *device, int dd)
2626 {
2627  uint32_t value;
2628  int i;
2629 
2630  if (is_lancer(device)) {
2631  /* Set the FRST bit */
2632  value = SLI4_PHYSDEV_CONTROL_FRST;
2633  if (dd) {
2634  value |= SLI4_PHYSDEV_CONTROL_DD;
2635  }
2636 
2637  os_bar_write32(device, 0, SLI4_PHYSDEV_CONTROL, value);
2638 
2639  sleep(1);
2640  os_bar_read32(device, 0, SLI4_SLIPORT_STATUS, &value);
2641 
2642  /* Wait for SLIPORT_STATUS RDY */
2643  if (dd) {
2644  i = 3000;
2645  } else {
2646  i = 1000;
2647  }
2648  while (i > 0) {
2649  os_bar_read32(device, 0, SLI4_SLIPORT_STATUS, &value);
2650  if (value & SLI4_SLIPORT_STATUS_RDY) {
2651  break;
2652  }
2653  usleep(10000);
2654  --i;
2655  }
2656  if (!(value & SLI4_SLIPORT_STATUS_RDY)) {
2657  printf("Timed out waiting for SLIPORT_STATUS RDY\n");
2658  goto fail;
2659  }
2660 
2661  /* Wait for SLIPORT_SEMAPHORE ready */
2662  i = 1000;
2663  while (i > 0) {
2664  os_bar_read32(device, 0, SLI4_SLIPORT_SEMAPHORE_LAN, &value);
2666  break;
2667  }
2668  usleep(10000);
2669  --i;
2670  }
2672  printf("Timed out waiting for SLIPORT_SEMAPHORE\n");
2673  goto fail;
2674  }
2675 
2676  /* Wait for BMBX ready */
2677  i = 1000;
2678  while (i > 0) {
2679  os_bar_read32(device, 0, SLI4_BMBX, &value);
2680  if (value & SLI4_BMBX_RDY) {
2681  break;
2682  }
2683  usleep(10000);
2684  --i;
2685  }
2686  if (!(value & SLI4_BMBX_RDY)) {
2687  printf("Timed out waiting for BMBX RDY\n");
2688  goto fail;
2689  }
2690 
2691  /* Re-initialize */
2692  mbox_sli4_init_pt(device);
2693 
2694  } else {
2695  /* Read the SOFT_RESET_CSR */
2696  os_cfg_read32(device, SLI4_PCI_SOFT_RESET_CSR, &value);
2697 
2698  /* Set the SOFT_RESET bit */
2699  value |= SLI4_PCI_SOFT_RESET_MASK;
2700 
2701  /* Write the value back to the SOFT_RESET_CSR */
2702  os_cfg_write32(device, SLI4_PCI_SOFT_RESET_CSR, value);
2703 
2704  /* Wait for SLIPORT_SEMAPHORE ready */
2705  i = 3000;
2706  while (i > 0) {
2707  os_bar_read32(device, 1, SLI4_SLIPORT_SEMAPHORE_SH, &value);
2708 
2710  break;
2711  }
2712  usleep(10000);
2713  --i;
2714  }
2715 
2716  /* Wait for BMBX ready */
2717  i = 1000;
2718  while (i > 0) {
2719  os_bar_read32(device, 2, SLI4_BMBX, &value);
2720 
2721  if ((value & SLI4_BMBX_RDY)) {
2722  break;
2723  }
2724  usleep(10000);
2725  --i;
2726  }
2727 
2728  /* Send FW INIT */
2729  mbox_sli4_init_pt(device);
2730 
2731  }
2732  return 0;
2733 
2734 fail:
2735  return -1;
2736 }
2737 
2739 {
2740  int i;
2741  uint32_t words[2];
2742  uint32_t value;
2743 
2744  if (is_lancer(device)) {
2745  /* Write IP bit in SLIPORT_CONTROL */
2747 
2748  /* Wait for SLIPORT_STATUS RDY */
2749  i = 1000;
2750  while (i > 0) {
2751  os_bar_read32(device, 0, SLI4_SLIPORT_STATUS, &value);
2752  if (value & SLI4_SLIPORT_STATUS_RDY) {
2753  break;
2754  }
2755  usleep(10000);
2756  --i;
2757  }
2758  if (!(value & SLI4_SLIPORT_STATUS_RDY)) {
2759  printf("Timeout waiting for RDY\n");
2760  }
2761 
2762  } else {
2763  words[0] = 0xff1234ff;
2764  words[1] = 0xff5678ff;
2765  mbox_common(device, (mbox_command_t *)words, sizeof(words), NULL, 0, NULL, 0);
2766  }
2767 
2768  return 0;
2769 }
2770 
2771 int mbox_get_profile_list_pt(elxu_device_t *device, char *result, int result_len)
2772 {
2773  sli4_res_common_get_profile_list_t *response = NULL;
2775  void *mqe;
2776  mbox_sli_config_t *sli_config = NULL;
2777  size_t mbox_size;
2778  int rc = -1;
2779 
2780  assert(device);
2781 
2782  if (device->driver != DEVICE_DRIVER_PT) {
2783  return -1;
2784  }
2785 
2786  mqe = zmalloc(MBOX_ENTRY_LENGTH);
2787  if (mqe == NULL) {
2788  return -1;
2789  }
2790 
2791  /* Allocate a buffer big enough for the response, including up to
2792  * 40 profile descriptors
2793  */
2794  mbox_size = sizeof(sli4_res_common_get_profile_list_t) +
2795  40 * (sizeof(sli4_profile_descriptor_t));
2796  response = zmalloc(mbox_size);
2797  if (response == NULL) {
2798  goto err;
2799  }
2800 
2801  sli_config = (mbox_sli_config_t *) mqe;
2802  sli_config->command = MBOX_SLI_CONFIG;
2803 
2804  request = (sli4_req_common_get_profile_list_t *)(&sli_config[1]);
2807  request->hdr.req.request_length = mbox_size;
2808  request->start_profile_index = 0;
2809 
2810  mbox_common(device, mqe, MBOX_ENTRY_LENGTH, request, mbox_size,
2811  response, mbox_size);
2812 
2813  rc = response->hdr.res.status;
2814  if (rc == 0) {
2815  int i;
2816  int remaining_len = result_len;
2817  char description[MAX_DESCRIPTION + 8];
2818 
2819  result[0] = '\0';
2820  for (i = 0; i < response->desc_count; i++) {
2821  snprintf(description, sizeof(description), "0x%02x: %s\n",
2822  response->desc[i].profile_id,
2823  response->desc[i].profile_description_string);
2824 
2825  if (remaining_len <= strlen(description)) {
2826  break;
2827  }
2828 
2829  strncat(result, description, remaining_len);
2830  remaining_len -= strlen(description);
2831  }
2832  }
2833 
2834 err:
2835  if (response != NULL) {
2836  zfree(response);
2837  }
2838  if (mqe != NULL) {
2839  zfree(mqe);
2840  }
2841  return rc;
2842 }
2843 
2844 int mbox_get_active_profile_pt(elxu_device_t *device, char *result, int result_len)
2845 {
2846  sli4_res_common_get_active_profile_t *response = NULL;
2848  void *mqe;
2849  mbox_sli_config_t *sli_config = NULL;
2850  int rc = -1;
2851 
2852  assert(device);
2853 
2854  if (device->driver != DEVICE_DRIVER_PT) {
2855  return -1;
2856  }
2857 
2858  mqe = zmalloc(MBOX_ENTRY_LENGTH);
2859  if (mqe == NULL) {
2860  return -1;
2861  }
2862 
2863  response = zmalloc(sizeof(sli4_res_common_get_active_profile_t));
2864  if (response == NULL) {
2865  goto err;
2866  }
2867 
2868  sli_config = (mbox_sli_config_t *) mqe;
2869  sli_config->command = MBOX_SLI_CONFIG;
2870 
2871  request = (sli4_req_common_get_active_profile_t *)(&sli_config[1]);
2874  request->hdr.req.request_length = sizeof(*request) - sizeof(sli4_ioctl_header_t);
2875 
2876  mbox_common(device, mqe, MBOX_ENTRY_LENGTH, request, sizeof(*response),
2877  response, sizeof(*response));
2878 
2879  rc = response->hdr.res.status;
2880  if (rc == 0) {
2881  char profile_list[5 * 1024];
2882  char *result_p;
2883  char active_profile_str[8];
2884 
2885  /*
2886  * We now have the current active profile's index, in response->active_profile_id.
2887  * In order to get the description for that profile we have to do a
2888  * get_profile_list to get the list of all of the possible profiles.
2889  */
2890 
2891  rc = mbox_get_profile_list_pt(device, profile_list, sizeof(profile_list));
2892 
2893  if (rc == 0) {
2894  /*
2895  * profile_list now has the list of all possible profiles, formatted
2896  * for printing. We need to find the current profile ID among that
2897  * list.
2898  */
2899 
2900  sprintf(active_profile_str, "0x%02x:", response->active_profile_id);
2901  /*
2902  * active_profile_str is the printable form of the current index.
2903  * eg: if current profile is 0x13, active profile id is "0x13: "
2904  */
2905 
2906  /* Locate the current profile index in the list */
2907  result_p = strstr(profile_list, active_profile_str);
2908  if (result_p != NULL) {
2909  /*
2910  * result_p now points to the first character in the list
2911  * for the entry that we want. We now have to find the
2912  * end of that line and terminate the string there.
2913  */
2914 
2915  char *c = strchr(result_p, '\n');
2916  if (c != NULL) {
2917  *c = '\0';
2918  strncpy(result, result_p, result_len);
2919  } else {
2920  /* Couldn't find the end of the line */
2921  rc = -1;
2922  }
2923  } else {
2924  /* Couldn't find the current profile in the profile list */
2925  rc = -1;
2926  }
2927  }
2928  }
2929 
2930 err:
2931  if (response != NULL) {
2932  zfree(response);
2933  }
2934  if (mqe != NULL) {
2935  zfree(mqe);
2936  }
2937  return rc;
2938 }
2939 
2940 int mbox_set_active_profile_pt(elxu_device_t *device, char *new_profile_id)
2941 {
2942  sli4_res_common_set_active_profile_t *response = NULL;
2944  void *mqe;
2945  mbox_sli_config_t *sli_config = NULL;
2946  int32_t new_profile;
2947  int rc = -1;
2948 
2949  assert(device);
2950 
2951  if (device->driver != DEVICE_DRIVER_PT) {
2952  return -1;
2953  }
2954 
2955  mqe = zmalloc(MBOX_ENTRY_LENGTH);
2956  if (mqe == NULL) {
2957  return -1;
2958  }
2959 
2960  response = zmalloc(sizeof(sli4_res_common_set_active_profile_t));
2961  if (response == NULL) {
2962  goto err;
2963  }
2964 
2965  new_profile = strtoul(new_profile_id, NULL, 0);
2966 
2967  sli_config = (mbox_sli_config_t *) mqe;
2968  sli_config->command = MBOX_SLI_CONFIG;
2969 
2970  request = (sli4_req_common_set_active_profile_t *)(&sli_config[1]);
2973  request->hdr.req.request_length = sizeof(*request) - sizeof(sli4_ioctl_header_t);
2974  request->active_profile_id = new_profile;
2975 
2976  mbox_common(device, mqe, MBOX_ENTRY_LENGTH, request, sizeof(*request),
2977  response, sizeof(*response));
2978 
2979  rc = response->hdr.res.status;
2980 
2981 err:
2982  if (response != NULL) {
2983  zfree(response);
2984  }
2985  if (mqe != NULL) {
2986  zfree(mqe);
2987  }
2988  return rc;
2989 }
2990 
2991 
2992 /**
2993 * @page mbox_cmd.html Mailbox Command Construction
2994 *
2995 * The mbox_common API for Linux and FreeBSD operating systems provides
2996 * a common interface to send mailbox commands using the OneCore Storage IOCTL interface.
2997 *
2998 * The mbox_common() function sends mailbox commands using the OneCore Storage IOCTL interface.
2999 *
3000 */
#define MBOX_READ_REV
Definition: elxu_sli4.h:64
uint32_t total_exchanges_responder
Definition: elxu_sli4.h:234
struct mbox_common_manage_fat_t::@9::@11 response
static void parse_dport_result(mbox_res_fcoe_get_dport_results_t *rsp)
Definition: elxu_mbox.c:226
static mbox_skyhawk_linkcfg_map_t mbox_skyhawk_linkcfg_map[]
Mapping from mgmt string to Skyhawk config IDs.
Definition: elxu_mbox.c:2216
#define PCI_LOOPBACK
Definition: elxu_mbox.h:78
sli4_ioctl_header_t hdr
Definition: elxu_sli4.h:1252
#define OCS_IOCTL_CMD_ELXU_MBOX
Definition: ocs_ioctl.h:483
uint32_t payload_length
Definition: elxu_sli4.h:168
struct mbox_common_iscsi_get_connection_info_t::@29::@30 request
#define OCS_CONFIG_LINKCFG_4X10G
linkcfg strings
Definition: ocs_ioctl.h:472
#define DPORT_STATIC_MODE
Definition: elxu_mbox.c:60
memref_t * elx_pt_dma_alloc(elxu_device_t *device, int size)
Request a DMA allocation through elx_pt.
Definition: elxu_mbox.c:2549
#define OPCODE_COMMON_SET_ACTIVE_PROFILE
Definition: elxu_sli4.h:99
static int mbox_set_link_diag_state(elxu_device_t *device, void *mqe, int enable)
Definition: elxu_mbox.c:289
#define OPCODE_COMMON_ISCSI_GET_CONNECTION_INFO
Definition: elxu_sli4.h:115
static int vpdnext(vpdbuf_t *vpd)
Definition: elxu_mbox.c:87
struct mbox_common_iscsi_connection_update_t::@27::@28 request
#define FAT_OPERATION_TRIGGER
Definition: elxu_sli4.h:516
int mbox_connection_update(elxu_device_t *device, uint32_t request_flags, uint16_t connectionId, uint32_t constrainWindowValue)
Definition: elxu_mbox.c:1719
#define OPCODE_COMMON_SET_RECONFIG_LINK_INFO
Definition: elxu_sli4.h:105
unsigned command
Definition: elxu_sli4.h:185
#define OPCODE_COMMON_ISCSI_SET_TCP_PARAMETERS
Definition: elxu_sli4.h:113
union mbox_common_iscsi_get_connection_info_t::@29 params
uint32_t opcode
Definition: elxu_sli4.h:433
uint32_t vpd
Definition: elxu_sli4.h:188
#define MBOX_SUBSYSTEM_FCOE
Definition: elxu_sli4.h:77
sli4_ioctl_header_t hdr
Definition: elxu_sli4.h:1262
#define SLI4_SLIPORT_STATUS_RDY
Definition: elxu_sli4.h:48
static char * mbox_get_mgmt_from_clp_linkcfg_str(char *clp_str)
Get the mgmt config string from the CLP string.
Definition: elxu_mbox.c:1881
uint32_t offset
Definition: elxu_mbox.c:76
sli4_ioctl_request_header_t req
Definition: elxu_sli4.h:943
uint32_t uint32_t timeout
Definition: elxu_sli4.h:305
int mbox_ioctl_common_enable_disable_port(elxu_device_t *device, uint32_t port_status)
Issue IOCTL_COMMON_ENABLE_DISABLE_PORT command.
Definition: elxu_mbox.c:824
#define MAX_LINK_CONFIG_DESCRIPTORS
Definition: elxu_sli4.h:1277
uint32_t total_exchanges_originator
Definition: elxu_sli4.h:233
int mbox_set_nv_wwn_pt(elxu_device_t *device, char *wwpn_p, char *wwnn_p)
Issue a set non-volatile WWNN/WWPN.
Definition: elxu_mbox.c:1276
Mapping from mgmt string to Skyhawk config IDs.
Definition: elxu_mbox.c:2208
mgmt link config string to CLP string mapping.
Definition: elxu_mbox.h:68
#define VPD_SMALL_RESOURCE_TYPE_END_TAG
Definition: elxu_mbox.c:71
int mbox_tcp_parameters(elxu_device_t *device, uint32_t request_flags, uint32_t ackFrequency, uint32_t delayedAckTimerValue)
Issue the Set TCP Parameters mbox command.
Definition: elxu_mbox.c:1663
int elxu_device_exec(elxu_device_t *device, char *name, void *arg_in, int arg_in_len, void *arg_out, int arg_out_len)
Execute a management function on a device.
Definition: elxu_device.c:952
static uint32_t addr32_lo(uintptr_t addr)
Definition: elxu_common.h:50
union mbox_common_manage_fat_t::@9 params
uint32_t session_count
Definition: elxu_sli4.h:973
uint32_t uint32_t link_number
Definition: elxu_sli4.h:362
#define MBOX_READ_NVPARMS
Definition: elxu_sli4.h:67
int mbox_set_linkcfg_skyhawk_pt(elxu_device_t *device, char *config)
Definition: elxu_mbox.c:2242
#define MBOX_WRITE_NVPARMS
Definition: elxu_sli4.h:66
#define SLI4_SLIPORT_STATUS
Definition: elxu_sli4.h:47
#define FAT_OPERATION_CLEAR
Definition: elxu_sli4.h:515
struct mbox_common_t::@3::@4 out
#define OCS_CONFIG_LINKCFG_1X40G
Definition: ocs_ioctl.h:473
uint8_t iscsi_mac_address[6]
Definition: elxu_sli4.h:977
#define OPCODE_COMMON_ISCSI_CONNECTION_UPDATE
Definition: elxu_sli4.h:114
int mbox_set_dynamic_dport(elxu_device_t *device, char *state_str)
Definition: elxu_mbox.c:385
static const char * mbox_get_clp_from_mgmt_linkcfg_str(char *mgmt_str)
Get the CLP string from the mgmt config string.
Definition: elxu_mbox.c:1860
struct mbox_common_t::@3::@5 in
#define DPORT_QUERY_DYNAMIC_MODE
Definition: elxu_mbox.c:61
#define MBOX_SET_LINK_DIAG_STATE
Definition: elxu_sli4.h:68
#define OPCODE_DMTF_EXEC_CLP_CMD
Definition: elxu_sli4.h:121
int mbox_read_rev(elxu_device_t *device)
Issue read rev mailbox command.
Definition: elxu_mbox.c:194
#define OCS_IOCTL_CMD_VPORT
Definition: ocs_ioctl.h:488
int mbox_soft_assign_mac(elxu_device_t *device, int *macaddr)
Soft assign MAC.
Definition: elxu_mbox.c:939
int elxu_lancer_set_link_state(elxu_device_t *device_p, uint32_t *status)
Definition: elxu_device.c:868
int mbox_query_dynamic_dport_status(elxu_device_t *device)
Definition: elxu_mbox.c:369
#define MBOX_SET_DPORT_MODE
Definition: elxu_sli4.h:69
int mbox_common(elxu_device_t *device, mbox_command_t *mboxcmd, uint32_t mboxcmdLength, void *inbuf, uint32_t inbufLength, void *outbuf, uint32_t outbufLength)
Send a mailbox command.
Definition: elxu_mbox.c:2418
#define OPCODE_COMMON_GET_PROFILE_LIST
Definition: elxu_sli4.h:97
#define SLI4_SLIPORT_PORT_STATUS_MASK
Definition: elxu_sli4.h:52
#define OCS_CONFIG_LINKCFG_4X8G
Definition: ocs_ioctl.h:475
#define DPORT_DYNAMIC_MODE
Definition: elxu_mbox.c:59
void * zmalloc(uint32_t len)
Allocates and zeroes memory to be used.
Definition: elxu_common.c:63
#define VPD_LARGE_RESOURCE_TYPE_R_TAG
Definition: elxu_mbox.c:69
#define SLI4_SLIPORT_CONTROL_IP
Definition: elxu_sli4.h:59
static int pt_mbox(elxu_device_t *device, mbox_command_t *mboxcmd, uint32_t mboxcmdLength, void *inbuf, uint32_t inbufLength, void *outbuf, uint32_t outbufLength)
Definition: elxu_mbox.c:2434
void os_bar_read32(void *ctx, uint32_t bar, uint32_t offset, uint32_t *pdata)
Definition: elxu_dump.c:1237
int elxu_lancer_set_loopback(elxu_device_t *device_p, const char *fname, int *type)
Definition: elxu_device.c:843
unsigned command
Definition: elxu_sli4.h:219
char * mbox_get_linkcfg_lancer_pt(elxu_device_t *device)
Definition: elxu_mbox.c:1894
union mbox_common_iscsi_connection_update_t::@27 params
#define OPCODE_COMMON_GET_ACTIVE_PROFILE
Definition: elxu_sli4.h:98
uint32_t receive_frame_count
Definition: elxu_sli4.h:230
#define OPCODE_COMMON_MANAGE_FAT
Definition: elxu_sli4.h:87
#define SLI4_PORT_READY
Definition: elxu_sli4.h:53
char * mbox_get_linkcfg_skyhawk_pt(elxu_device_t *device)
Definition: elxu_mbox.c:2006
IOCTL_CMD_IOCTL_ELXU_MBOX ioctl structure.
Definition: ocs_ioctl.h:89
#define MBOX_SUBSYSTEM_COMMON_ISCSI
Definition: elxu_sli4.h:110
unsigned status
Definition: elxu_sli4.h:161
int mbox_set_linkcfg_pt(elxu_device_t *device, char *config)
Set Link configuration.
Definition: elxu_mbox.c:2306
uint32_t uint32_t physical_address_low
Definition: elxu_sli4.h:209
#define SLI4_BMBX
Definition: elxu_sli4.h:55
int elxu_ioctl_device(elxu_device_t *device, int req, void *arg)
Send an ioctl to a device.
Definition: elxu_device.c:322
void zfree(void *p)
Frees memory that has been allocated.
Definition: elxu_common.c:80
int is_lancer(elxu_device_t *device_p)
Return true IFF the HBA is a Lancer.
Definition: elxu_device.c:1236
#define SLI4_PHYSDEV_CONTROL_DD
Definition: elxu_sli4.h:44
static uint8_t * elx_find_vpd(uint8_t *vpddata, uint32_t vpddata_length, const char *key)
Definition: elxu_mbox.c:104
#define MBOX_RUN_BIU_DIAG
Definition: elxu_sli4.h:71
void os_cfg_read32(void *ctx, uint32_t offset, uint32_t *pdata)
Definition: elxu_dump.c:1050
#define OPCODE_COMMON_READ_FLASHROM
Definition: elxu_sli4.h:80
static int mbox_set_dport_mode(elxu_device_t *device, void *mqe, int mode, int enable)
Definition: elxu_mbox.c:323
#define MBOX_SLI_CONFIG
Definition: elxu_sli4.h:62
uint32_t uint32_t link_type
Definition: elxu_sli4.h:362
#define FAT_OPERATION_RETRIEVE
Definition: elxu_sli4.h:513
int remove_vport(elxu_device_t *device_p, uint64_t wwnn, uint64_t wwpn, int targetFlag, int initiatorFlag)
Definition: elxu_mbox.c:2339
#define CLP_LINKCFG_4X10G
CLP string used in the DMTF_CLP_CMD mailbox command.
Definition: elxu_mbox.h:53
uint32_t opcode
Definition: elxu_sli4.h:305
mbox_common_t common
Definition: elxu_sli4.h:509
#define INTERNAL_LOOPBACK
Definition: elxu_mbox.h:76
uint32_t receive_p_bsy_count
Definition: elxu_sli4.h:235
int mbox_get_dport_stats(elxu_device_t *device)
Issue Get dport stats mailbox command Create a GET_DPORT_STAT mailbox command.
Definition: elxu_mbox.c:408
int mbox_set_nv_mac_pt(elxu_device_t *device, int *macaddr)
Definition: elxu_mbox.c:1098
int mbox_read_status(elxu_device_t *device, uint32_t clear_counter)
Issue read status mailbox command.
Definition: elxu_mbox.c:763
uint32_t enable_tgt
Definition: ocs_ioctl.h:233
uint32_t command
Definition: elxu_sli4.h:416
uint32_t address_low
Definition: elxu_sli4.h:127
uint32_t uint8_t profile_description_string[MAX_DESCRIPTION]
Definition: elxu_sli4.h:1120
int mbox_ext_fat(elxu_device_t *device, uint32_t opcode, void *mbox, uint32_t mboxLength)
Issue EFD mailbox command.
Definition: elxu_mbox.c:1604
uint32_t uint32_t uint32_t response_length
Definition: elxu_sli4.h:322
uint32_t receive_sequence_count
Definition: elxu_sli4.h:232
#define CLP_LINKCFG_1X40G
Definition: elxu_mbox.h:54
uint32_t receive_kbyte_count
Definition: elxu_sli4.h:228
#define CLP_LINKCFG_2X10G_2X8G
Definition: elxu_mbox.h:59
#define MBOX_READ_STATUS
Definition: elxu_sli4.h:63
uint32_t transmit_frame_count
Definition: elxu_sli4.h:229
sli4_profile_descriptor_t desc[0]
Definition: elxu_sli4.h:1136
#define MBOX_ENTRY_LENGTH
Definition: elxu_sli4.h:123
int mbox_set_linkcfg_lancer_pt(elxu_device_t *device, char *config)
Definition: elxu_mbox.c:2099
#define OPCODE_COMMON_GET_RECONFIG_LINK_INFO
Definition: elxu_sli4.h:104
union mbox_common_iscsi_set_tcp_parameters_t::@25 params
#define CLP_LINKCFG_4X8G
Definition: elxu_mbox.h:56
#define OPCODE_COMMON_GET_PROFILE_CONFIG
Definition: elxu_sli4.h:95
int mbox_set_active_profile_pt(elxu_device_t *device, char *new_profile_id)
Definition: elxu_mbox.c:2940
static int ocs_mbox(elxu_device_t *device, mbox_command_t *mboxcmd, uint32_t mboxcmdLength, void *inbuf, uint32_t inbufLength, void *outbuf, uint32_t outbufLength)
Definition: elxu_mbox.c:2489
elxu_device_t * device
Definition: elxu_mbox.h:43
void os_cfg_write32(void *ctx, uint32_t offset, uint32_t data)
Definition: elxu_dump.c:1140
void mbox_get_wwn_pt(int fd, uint8_t *wwnn, uint8_t *wwpn)
Definition: elxu_mbox.c:1029
#define OPCODE_COMMON_ENABLE_DISABLE_PORT
Definition: elxu_sli4.h:84
uint8_t payload[256]
Definition: ocs_ioctl.h:92
#define FAT_OPERATION_QUERY
Definition: elxu_sli4.h:514
#define OCS_CONFIG_LINKCFG_4X1G
Definition: ocs_ioctl.h:476
#define SLI4_SLIPORT_SEMAPHORE_SH
Definition: elxu_sli4.h:51
struct mbox_command_t::@1 request
#define MBOX_SUBSYSTEM_COMMON
Definition: elxu_sli4.h:76
uint32_t command
Definition: elxu_sli4.h:145
#define OPCODE_COMMON_GET_FUNCTION_CONFIG
Definition: elxu_sli4.h:94
int mbox_manage_fat(elxu_device_t *device, uint32_t fat_operation, uint32_t read_log_offset, void *buffer, uint32_t bufferLength)
Issue COMMON_MANAGE_FAT mailbox commands.
Definition: elxu_mbox.c:1510
int mbox_read_flashrom(elxu_device_t *device, uint32_t opcode, uint32_t optype, uint32_t offset, void *outbuf, uint32_t outbufLength)
Issue read flashrom mailbox command.
Definition: elxu_mbox.c:1339
uint32_t deviceIndex
Definition: elxu_device.h:85
#define SLI4_SLIPORT_CONTROL
Definition: elxu_sli4.h:58
uint32_t request_length
Definition: elxu_sli4.h:450
#define MAX_DESCRIPTION
Definition: elxu_sli4.h:1118
uint32_t subsystem
Definition: elxu_sli4.h:305
sli4_ioctl_response_header_t res
Definition: elxu_sli4.h:944
uint32_t uint32_t valid_fields
Definition: elxu_sli4.h:967
#define OCS_CONFIG_LINKCFG_2X16G
Definition: ocs_ioctl.h:474
int is_skyhawk(elxu_device_t *device_p)
Return true IFF the HBA is a Skyhawk.
Definition: elxu_device.c:1219
struct mbox_command_t::@2 response
uint32_t phy_port_num
Definition: elxu_device.h:96
#define CLP_LINKCFG_2X16G
Definition: elxu_mbox.h:55
uint32_t address_high
Definition: elxu_sli4.h:128
int mbox_sli4_init_pt(elxu_device_t *device)
Definition: elxu_mbox.c:2738
#define SLI4_SLIPORT_SEMAPHORE_LAN
Definition: elxu_sli4.h:50
#define OPCODE_COMMON_WRITE_FLASHROM
Definition: elxu_sli4.h:81
int tag
Definition: elxu_mbox.h:47
uint32_t uint32_t w1
Definition: elxu_sli4.h:392
char * elxu_device_get_value(elxu_device_t *device, char *key)
Return a property value for a device.
Definition: elxu_device.c:765
int mbox_read_link_status(elxu_device_t *device, int clof, int clrc)
Issue read link status mailbox command.
Definition: elxu_mbox.c:666
unsigned command
Definition: elxu_sli4.h:160
#define ARRAY_SIZE(x)
Definition: elxu_common.h:46
unsigned pcmd_count
Definition: elxu_sli4.h:165
uint32_t status
Definition: elxu_sli4.h:416
void os_bar_write32(void *ctx, uint32_t bar, uint32_t offset, uint32_t data)
Definition: elxu_dump.c:1333
char * mbox_get_linkcfg_pt(elxu_device_t *device)
Get Link configuration.
Definition: elxu_mbox.c:2086
#define SLI4_PHYSDEV_CONTROL_FRST
Definition: elxu_sli4.h:43
#define OCS_CONFIG_LINKCFG_2X10G
Definition: ocs_ioctl.h:477
static char * format_sli4_ip_address(uint32_t *address)
Given a 6-word IP address in the format specified in the SLI4 spec, return a printable IP address...
Definition: elxu_mbox.c:2366
#define DISABLE
Definition: elxu_mbox.h:74
#define OPCODE_COMMON_SET_PROFILE_CONFIG
Definition: elxu_sli4.h:96
int mbox_get_active_profile_pt(elxu_device_t *device, char *result, int result_len)
Definition: elxu_mbox.c:2844
uint32_t length
Definition: elxu_mbox.c:75
uint32_t enable_ini
Definition: ocs_ioctl.h:233
uintptr_t paddr
Definition: elxu_mbox.h:45
OCS_IOCTL_CMD_VPORT ioctl structure.
Definition: ocs_ioctl.h:231
#define ENABLE
Definition: elxu_mbox.h:73
int create_vport(elxu_device_t *device_p, uint64_t wwnn, uint64_t wwpn, int targetFlag, int initiatorFlag)
Definition: elxu_mbox.c:2319
static uint8_t * vpdref(vpdbuf_t *vpd)
Definition: elxu_mbox.c:98
union mbox_common_t::@3 word1
#define ELXU_BSD_MAGIC
Definition: ocs_ioctl.h:80
uint8_t * buffer
Definition: elxu_mbox.c:74
uint32_t resource_type
Definition: elxu_sli4.h:987
static mbox_linkcfg_map_t mbox_linkcfg_str[]
Definition: elxu_mbox.c:1842
#define OPCODE_COMMON_SET_BE_CONFIGURATION_AND_RESOURCES
Definition: elxu_sli4.h:86
uint32_t transmit_sequence_count
Definition: elxu_sli4.h:231
int mbox_fw_reset_pt(elxu_device_t *device, int dd)
Definition: elxu_mbox.c:2625
#define CLP_LINKCFG_4X1G
Definition: elxu_mbox.h:57
int mbox_diag_loopback_tests(elxu_device_t *device, int loopback_type, int retry_count)
Issue set link diag loopback mailbox command.
Definition: elxu_mbox.c:543
uint32_t transmit_kbyte_count
Definition: elxu_sli4.h:227
static uint32_t addr32_hi(uintptr_t addr)
Definition: elxu_common.h:59
void mbox_get_mac_pt(elxu_device_t *device, uint8_t *mac_addr)
Definition: elxu_mbox.c:950
uint32_t be_resources_iscsi_v1 resource_descriptor
Definition: elxu_sli4.h:987
uint32_t available_length
Definition: elxu_sli4.h:209
int mbox_write_flashrom(elxu_device_t *device, uint32_t opcode, uint32_t optype, uint32_t offset, void *inbuf, uint32_t inbufLength)
Issue write flashrom mailbox command.
Definition: elxu_mbox.c:1421
struct mbox_common_iscsi_set_tcp_parameters_t::@25::@26 request
uint8_t checksum
Definition: elxu_mbox.c:77
#define SLI4_PCI_SOFT_RESET_MASK
Definition: elxu_sli4.h:40
void * vaddr
Definition: elxu_mbox.h:44
uint8_t wwpn[8]
Definition: elxu_sli4.h:420
uint32_t returned_vpd_length
Definition: elxu_sli4.h:213
uint8_t wwnn[8]
Definition: elxu_sli4.h:421
uint32_t physical_address_high
Definition: elxu_sli4.h:212
uint32_t req_create
Definition: ocs_ioctl.h:233
void elx_pt_dma_free(memref_t *memref)
Free a DMA allocation through elx_pt.
Definition: elxu_mbox.c:2602
uint32_t request_length
Definition: elxu_sli4.h:309
int elxu_lancer_run_loopback(elxu_device_t *device_p, const char *fname, int type)
Definition: elxu_device.c:785
int elxu_lancer_get_link_state(elxu_device_t *device_p, uint32_t *status)
Definition: elxu_device.c:857
size_t size
Definition: elxu_mbox.h:46
elxu_device_driver_e driver
Definition: elxu_device.h:90
#define EXTERNAL_LOOPBACK
Definition: elxu_mbox.h:77
#define ROUNDUP(x, y)
Definition: elxu_common.h:49
#define VPD_LARGE_RESOURCE_TYPE_W_TAG
Definition: elxu_mbox.c:70
#define CLP_LINKCFG_2X10G
Definition: elxu_mbox.h:58
int mbox_get_profile_list_pt(elxu_device_t *device, char *result, int result_len)
Definition: elxu_mbox.c:2771
char bus_addr[256]
Definition: elxu_device.h:80
#define MBOX_GET_DPORT_RESULTS
Definition: elxu_sli4.h:70
unsigned length
Definition: elxu_sli4.h:129
uint32_t subsystem
Definition: elxu_sli4.h:434
unsigned status
Definition: elxu_sli4.h:186
#define OCS_CONFIG_LINKCFG_2X10G_2X8G
Definition: ocs_ioctl.h:478
static uint32_t mbox_get_config_id_from_mgmt_str(char *mgmt_str)
Get the config ID from the mgmt config string.
Definition: elxu_mbox.c:2229
struct mbox_common_iscsi_get_connection_info_t::@29::@31 response
#define MBOX_SUBSYSTEM_DMTF
Definition: elxu_sli4.h:118
fcoe_test_result_descriptor_t trd[6]
Definition: elxu_sli4.h:411
static int vpddone(vpdbuf_t *vpd)
Definition: elxu_mbox.c:81
#define SLI4_PHYSDEV_CONTROL
Definition: elxu_sli4.h:42
uint32_t receive_f_bsy_count
Definition: elxu_sli4.h:236
mbox_sge_t sge[0]
Definition: elxu_sli4.h:176
#define SLI4_BMBX_RDY
Definition: elxu_sli4.h:56
int mbox_get_connection_info(elxu_device_t *device, uint32_t connectionHandle)
Get connection info.
Definition: elxu_mbox.c:1776
int mbox_get_serialnum_pt(elxu_device_t *device, char *serial_num, int serial_num_size)
Definition: elxu_mbox.c:1053
int mbox_ioctl_common_set_be_configuration_and_resources(elxu_device_t *device, int *mac_addr)
Issue IOCTL_COMMON_SET_BE_CONFIGRATION_AND_RESOURCES command.
Definition: elxu_mbox.c:875
#define SLI4_PCI_SOFT_RESET_CSR
Definition: elxu_sli4.h:39
#define MBOX_READ_LNK_STAT
Definition: elxu_sli4.h:65