Lines Matching full:hw
34 * Defines and implements the Hardware Abstraction Layer (HW).
35 * All interaction with the hardware is performed through the HW, which abstracts
69 /* HW global data */
73 static void ocs_hw_adjust_wqs(ocs_hw_t *hw);
74 static uint32_t ocs_hw_get_num_chutes(ocs_hw_t *hw);
88 static void ocs_hw_io_quarantine(ocs_hw_t *hw, hw_wq_t *wq, ocs_hw_io_t *io);
91 static ocs_hw_rtn_e ocs_hw_firmware_write_lancer(ocs_hw_t *hw, ocs_dma_t *dma, uint32_t size, uint32_t offset, int last, ocs_hw_fw_cb_t cb, void *arg);
96 static int32_t ocs_hw_cb_host_stat(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg);
97 static void ocs_hw_dmtf_clp_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg);
98 static int32_t ocs_hw_clp_resp_get_value(ocs_hw_t *hw, const char *keyword, char *value, uint32_t value_len, const char *resp, uint32_t resp_len);
99 typedef void (*ocs_hw_dmtf_clp_cb_t)(ocs_hw_t *hw, int32_t status, uint32_t result_len, void *arg);
100 static ocs_hw_rtn_e ocs_hw_exec_dmtf_clp_cmd(ocs_hw_t *hw, ocs_dma_t *dma_cmd, ocs_dma_t *dma_resp, uint32_t opts, ocs_hw_dmtf_clp_cb_t cb, void *arg);
101 static void ocs_hw_linkcfg_dmtf_clp_cb(ocs_hw_t *hw, int32_t status, uint32_t result_len, void *arg);
111 static ocs_hw_rtn_e ocs_hw_set_eth_license(ocs_hw_t *hw, uint32_t license);
112 static ocs_hw_rtn_e ocs_hw_set_dif_seed(ocs_hw_t *hw);
113 static ocs_hw_rtn_e ocs_hw_set_dif_mode(ocs_hw_t *hw);
116 static ocs_hw_rtn_e ocs_hw_config_auto_xfer_rdy_t10pi(ocs_hw_t *hw, uint8_t *buf);
117 static ocs_hw_rtn_e ocs_hw_config_set_fdt_xfer_hint(ocs_hw_t *hw, uint32_t fdt_xfer_hint);
119 static int32_t ocs_hw_config_mrq(ocs_hw_t *hw, uint8_t, uint16_t, uint16_t);
120 static ocs_hw_rtn_e ocs_hw_config_watchdog_timer(ocs_hw_t *hw);
121 static ocs_hw_rtn_e ocs_hw_config_sli_port_health_check(ocs_hw_t *hw, uint8_t query, uint8_t enable);
123 /* HW domain database operations */
142 static int32_t __ocs_hw_port_realloc_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg);
145 static void ocs_hw_check_sec_hio_list(ocs_hw_t *hw);
149 static void shutdown_target_wqe_timer(ocs_hw_t *hw);
164 ocs_hw_add_io_timed_wqe(ocs_hw_t *hw, ocs_hw_io_t *io)
166 if (hw->config.emulate_wqe_timeout && io->wqe_timeout) {
171 ocs_lock(&hw->io_lock);
172 ocs_list_add_tail(&hw->io_timed_wqe, io);
174 ocs_unlock(&hw->io_lock);
179 ocs_hw_remove_io_timed_wqe(ocs_hw_t *hw, ocs_hw_io_t *io)
181 if (hw->config.emulate_wqe_timeout) {
186 ocs_lock(&hw->io_lock);
188 ocs_list_remove(&hw->io_timed_wqe, io);
190 ocs_unlock(&hw->io_lock);
234 * @param hw Hardware context allocated by the caller.
239 ocs_hw_get_num_chutes(ocs_hw_t *hw)
243 if (sli_get_is_dual_ulp_capable(&hw->sli) &&
244 sli_get_is_ulp_enabled(&hw->sli, 0) &&
245 sli_get_is_ulp_enabled(&hw->sli, 1)) {
252 ocs_hw_link_event_init(ocs_hw_t *hw)
254 ocs_hw_assert(hw);
256 hw->link.status = SLI_LINK_STATUS_MAX;
257 hw->link.topology = SLI_LINK_TOPO_NONE;
258 hw->link.medium = SLI_LINK_MEDIUM_MAX;
259 hw->link.speed = 0;
260 hw->link.loop_map = NULL;
261 hw->link.fc_id = UINT32_MAX;
273 * @param hw Hardware context allocated by the caller.
278 ocs_hw_read_max_dump_size(ocs_hw_t *hw)
285 if ((SLI4_IF_TYPE_LANCER_FC_ETH != sli_get_if_type(&hw->sli)) &&
286 (SLI4_IF_TYPE_LANCER_G7 != sli_get_if_type(&hw->sli))) {
287 ocs_log_debug(hw->os, "Function only supported for I/F type 2\n");
295 if (hw->workaround.disable_dump_loc) {
296 ocs_log_test(hw->os, "FW version is too old for this feature\n");
301 ocs_get_bus_dev_func(hw->os, &bus, &dev, &func);
303 if (sli_cmd_common_set_dump_location(&hw->sli, buf,
310 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
312 ocs_log_test(hw->os, "set dump location command failed\n");
315 hw->dump_size = rsp->buffer_length;
316 ocs_log_debug(hw->os, "Dump size %x\n", rsp->buffer_length);
330 * @param hw Hardware context allocated by the caller.
339 ocs_hw_setup(ocs_hw_t *hw, ocs_os_handle_t os, sli4_port_type_e port_type)
344 if (hw == NULL) {
345 ocs_log_err(os, "bad parameter(s) hw=%p\n", hw);
349 if (hw->hw_setup_called) {
353 ocs_hw_workaround_setup(hw);
362 ocs_memset(hw, 0, sizeof(ocs_hw_t));
364 hw->hw_setup_called = TRUE;
366 hw->os = os;
368 ocs_lock_init(hw->os, &hw->cmd_lock, "HW_cmd_lock[%d]", ocs_instance(hw->os));
369 ocs_list_init(&hw->cmd_head, ocs_command_ctx_t, link);
370 ocs_list_init(&hw->cmd_pending, ocs_command_ctx_t, link);
371 hw->cmd_head_count = 0;
373 ocs_lock_init(hw->os, &hw->io_lock, "HW_io_lock[%d]", ocs_instance(hw->os));
374 ocs_lock_init(hw->os, &hw->io_abort_lock, "HW_io_abort_lock[%d]", ocs_instance(hw->os));
376 ocs_atomic_init(&hw->io_alloc_failed_count, 0);
378 hw->config.speed = FC_LINK_SPEED_AUTO_16_8_4;
379 hw->config.dif_seed = 0;
380 hw->config.auto_xfer_rdy_blk_size_chip = OCS_HW_AUTO_XFER_RDY_BLK_SIZE_DEFAULT;
381 hw->config.auto_xfer_rdy_ref_tag_is_lba = OCS_HW_AUTO_XFER_RDY_REF_TAG_IS_LBA_DEFAULT;
382 hw->config.auto_xfer_rdy_app_tag_valid = OCS_HW_AUTO_XFER_RDY_APP_TAG_VALID_DEFAULT;
383 hw->config.auto_xfer_rdy_app_tag_value = OCS_HW_AUTO_XFER_RDY_APP_TAG_VALUE_DEFAULT;
385 if (sli_setup(&hw->sli, hw->os, port_type)) {
386 ocs_log_err(hw->os, "SLI setup failed\n");
390 ocs_memset(hw->domains, 0, sizeof(hw->domains));
392 ocs_memset(hw->fcf_index_fcfi, 0, sizeof(hw->fcf_index_fcfi));
394 ocs_hw_link_event_init(hw);
396 sli_callback(&hw->sli, SLI4_CB_LINK, ocs_hw_cb_link, hw);
397 sli_callback(&hw->sli, SLI4_CB_FIP, ocs_hw_cb_fip, hw);
403 for (i = 0; i < ARRAY_SIZE(hw->num_qentries); i++) {
404 hw->num_qentries[i] = sli_get_max_qentries(&hw->sli, i);
410 hw->config.rq_default_buffer_size = OCS_HW_RQ_SIZE_PAYLOAD;
411 hw->config.n_io = sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_XRI);
413 hw->config.auto_xfer_rdy_xri_cnt = ocs_strtoul(prop_buf, 0, 0);
417 hw->config.i_only_aab = TRUE;
420 ocs_hw_workaround_setup(hw);
423 if (hw->workaround.override_fcfi) {
424 hw->first_domain_idx = -1;
428 if ((SLI4_IF_TYPE_LANCER_FC_ETH == sli_get_if_type(&hw->sli)) ||
429 (SLI4_IF_TYPE_LANCER_G7 == sli_get_if_type(&hw->sli))) {
431 (void)ocs_hw_read_max_dump_size(hw);
435 ocs_hw_adjust_wqs(hw);
438 if (! sli_is_dif_inline_capable(&hw->sli)) {
439 ocs_log_test(hw->os, "not inline capable, setting mode to separate\n");
440 hw->config.dif_mode = OCS_HW_DIF_MODE_SEPARATE;
443 if (hw->workaround.use_dif_sec_xri) {
444 ocs_list_init(&hw->sec_hio_wait_list, ocs_hw_io_t, link);
451 if (sli_get_is_dual_ulp_capable(&hw->sli)) {
452 if (sli_get_is_ulp_enabled(&hw->sli, 0) &&
453 sli_get_is_ulp_enabled(&hw->sli, 1)) {
454 hw->ulp_start = 0;
455 hw->ulp_max = 1;
456 } else if (sli_get_is_ulp_enabled(&hw->sli, 0)) {
457 hw->ulp_start = 0;
458 hw->ulp_max = 0;
460 hw->ulp_start = 1;
461 hw->ulp_max = 1;
464 if (sli_get_is_ulp_enabled(&hw->sli, 0)) {
465 hw->ulp_start = 0;
466 hw->ulp_max = 0;
468 hw->ulp_start = 1;
469 hw->ulp_max = 1;
472 ocs_log_debug(hw->os, "ulp_start %d, ulp_max %d\n",
473 hw->ulp_start, hw->ulp_max);
474 hw->config.queue_topology = hw_global.queue_topology_string;
476 hw->qtop = ocs_hw_qtop_parse(hw, hw->config.queue_topology);
478 hw->config.n_eq = hw->qtop->entry_counts[QTOP_EQ];
479 hw->config.n_cq = hw->qtop->entry_counts[QTOP_CQ];
480 hw->config.n_rq = hw->qtop->entry_counts[QTOP_RQ];
481 hw->config.n_wq = hw->qtop->entry_counts[QTOP_WQ];
482 hw->config.n_mq = hw->qtop->entry_counts[QTOP_MQ];
485 if (hw->config.n_rq > OCE_HW_MAX_NUM_MRQ_PAIRS) {
486 ocs_log_crit(hw->os, "Max supported MRQ pairs = %d\n",
491 if (hw->config.n_eq > OCS_HW_MAX_NUM_EQ) {
492 ocs_log_crit(hw->os, "Max supported EQs = %d\n",
497 if (hw->config.n_cq > OCS_HW_MAX_NUM_CQ) {
498 ocs_log_crit(hw->os, "Max supported CQs = %d\n",
503 if (hw->config.n_wq > OCS_HW_MAX_NUM_WQ) {
504 ocs_log_crit(hw->os, "Max supported WQs = %d\n",
509 if (hw->config.n_mq > OCS_HW_MAX_NUM_MQ) {
510 ocs_log_crit(hw->os, "Max supported MQs = %d\n",
527 * may not be changed without tearing down the HW (ocs_hw_teardown()).
529 * @param hw Hardware context allocated by the caller.
534 ocs_hw_init(ocs_hw_t *hw)
552 ocs_lock(&hw->cmd_lock);
553 if (!ocs_list_empty(&hw->cmd_head)) {
554 ocs_log_test(hw->os, "command found on cmd list\n");
555 ocs_unlock(&hw->cmd_lock);
558 if (!ocs_list_empty(&hw->cmd_pending)) {
559 ocs_log_test(hw->os, "command found on pending list\n");
560 ocs_unlock(&hw->cmd_lock);
563 ocs_unlock(&hw->cmd_lock);
566 ocs_hw_rx_free(hw);
579 if (ocs_list_valid(&hw->io_wait_free)) {
580 while ((!ocs_list_empty(&hw->io_wait_free))) {
582 ocs_list_remove_head(&hw->io_wait_free);
585 ocs_log_debug(hw->os, "removed %d items from io_wait_free list\n", rem_count);
589 if (ocs_list_valid(&hw->io_inuse)) {
590 while ((!ocs_list_empty(&hw->io_inuse))) {
592 ocs_list_remove_head(&hw->io_inuse);
595 ocs_log_debug(hw->os, "removed %d items from io_inuse list\n", rem_count);
599 if (ocs_list_valid(&hw->io_free)) {
600 while ((!ocs_list_empty(&hw->io_free))) {
602 ocs_list_remove_head(&hw->io_free);
605 ocs_log_debug(hw->os, "removed %d items from io_free list\n", rem_count);
608 if (ocs_list_valid(&hw->io_port_owned)) {
609 while ((!ocs_list_empty(&hw->io_port_owned))) {
610 ocs_list_remove_head(&hw->io_port_owned);
613 ocs_list_init(&hw->io_inuse, ocs_hw_io_t, link);
614 ocs_list_init(&hw->io_free, ocs_hw_io_t, link);
615 ocs_list_init(&hw->io_port_owned, ocs_hw_io_t, link);
616 ocs_list_init(&hw->io_wait_free, ocs_hw_io_t, link);
617 ocs_list_init(&hw->io_timed_wqe, ocs_hw_io_t, wqe_link);
618 ocs_list_init(&hw->io_port_dnrx, ocs_hw_io_t, dnrx_link);
621 if (hw->config.n_rq == 1) {
622 hw->sli.config.features.flag.mrqp = FALSE;
625 if (sli_init(&hw->sli)) {
626 ocs_log_err(hw->os, "SLI failed to initialize\n");
633 hw->auto_xfer_rdy_enabled = FALSE;
634 if (sli_get_auto_xfer_rdy_capable(&hw->sli) &&
635 hw->config.auto_xfer_rdy_size > 0) {
636 if (hw->config.esoc){
640 written_size = sli_cmd_config_auto_xfer_rdy_hp(&hw->sli, buf, SLI4_BMBX_SIZE, hw->config.auto_xfer_rdy_size, 1, ramdisc_blocksize);
642 written_size = sli_cmd_config_auto_xfer_rdy(&hw->sli, buf, SLI4_BMBX_SIZE, hw->config.auto_xfer_rdy_size);
645 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
647 ocs_log_err(hw->os, "config auto xfer rdy failed\n");
651 hw->auto_xfer_rdy_enabled = TRUE;
653 if (hw->config.auto_xfer_rdy_t10_enable) {
654 rc = ocs_hw_config_auto_xfer_rdy_t10pi(hw, buf);
656 ocs_log_err(hw->os, "set parameters auto xfer rdy T10 PI failed\n");
662 if(hw->sliport_healthcheck) {
663 rc = ocs_hw_config_sli_port_health_check(hw, 0, 1);
665 ocs_log_err(hw->os, "Enabling Sliport Health check failed \n");
673 if ((hw->sli.if_type == SLI4_IF_TYPE_LANCER_FC_ETH) && (OCS_HW_FDT_XFER_HINT != 0)) {
678 ocs_hw_config_set_fdt_xfer_hint(hw, OCS_HW_FDT_XFER_HINT);
684 q_count = MIN(sli_get_max_queue(&hw->sli, SLI_QTYPE_EQ),
686 if (hw->config.n_eq > q_count) {
687 ocs_log_err(hw->os, "requested %d EQ but %d allowed\n",
688 hw->config.n_eq, q_count);
692 q_count = MIN(sli_get_max_queue(&hw->sli, SLI_QTYPE_CQ),
694 if (hw->config.n_cq > q_count) {
695 ocs_log_err(hw->os, "requested %d CQ but %d allowed\n",
696 hw->config.n_cq, q_count);
700 q_count = MIN(sli_get_max_queue(&hw->sli, SLI_QTYPE_MQ),
702 if (hw->config.n_mq > q_count) {
703 ocs_log_err(hw->os, "requested %d MQ but %d allowed\n",
704 hw->config.n_mq, q_count);
708 q_count = MIN(sli_get_max_queue(&hw->sli, SLI_QTYPE_RQ),
710 if (hw->config.n_rq > q_count) {
711 ocs_log_err(hw->os, "requested %d RQ but %d allowed\n",
712 hw->config.n_rq, q_count);
716 q_count = MIN(sli_get_max_queue(&hw->sli, SLI_QTYPE_WQ),
718 if (hw->config.n_wq > q_count) {
719 ocs_log_err(hw->os, "requested %d WQ but %d allowed\n",
720 hw->config.n_wq, q_count);
725 ocs_memset(hw->cq_hash, 0, sizeof(hw->cq_hash));
726 ocs_log_debug(hw->os, "Max CQs %d, hash size = %d\n",
729 ocs_memset(hw->rq_hash, 0, sizeof(hw->rq_hash));
730 ocs_log_debug(hw->os, "Max RQs %d, hash size = %d\n",
733 ocs_memset(hw->wq_hash, 0, sizeof(hw->wq_hash));
734 ocs_log_debug(hw->os, "Max WQs %d, hash size = %d\n",
737 rc = ocs_hw_init_queues(hw, hw->qtop);
742 max_rpi = sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_RPI);
743 i = sli_fc_get_rpi_requirements(&hw->sli, max_rpi);
749 if (hw->rnode_mem.size) {
750 ocs_dma_free(hw->os, &hw->rnode_mem);
753 if (ocs_dma_alloc(hw->os, &hw->rnode_mem, i, 4096)) {
754 ocs_log_err(hw->os, "remote node memory allocation fail\n");
759 if (sli_cmd_fcoe_post_hdr_templates(&hw->sli, buf, SLI4_BMBX_SIZE,
760 &hw->rnode_mem, UINT16_MAX, &payload_memory)) {
761 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
765 ocs_dma_free(hw->os, &payload_memory);
770 ocs_log_err(hw->os, "header template registration failed\n");
776 rc = ocs_hw_rx_allocate(hw);
778 ocs_log_err(hw->os, "rx_allocate failed\n");
782 /* Populate hw->seq_free_list */
783 if (hw->seq_pool == NULL) {
788 for (i = 0; i < hw->hw_rq_count; i++) {
789 count += hw->hw_rq[i]->entry_count;
792 hw->seq_pool = ocs_array_alloc(hw->os, sizeof(ocs_hw_sequence_t), count);
793 if (hw->seq_pool == NULL) {
794 ocs_log_err(hw->os, "malloc seq_pool failed\n");
799 if(ocs_hw_rx_post(hw)) {
800 ocs_log_err(hw->os, "WARNING - error posting RQ buffers\n");
804 if (hw->rpi_ref == NULL) {
805 hw->rpi_ref = ocs_malloc(hw->os, max_rpi * sizeof(*hw->rpi_ref),
807 if (hw->rpi_ref == NULL) {
808 ocs_log_err(hw->os, "rpi_ref allocation failure (%d)\n", i);
814 ocs_atomic_init(&hw->rpi_ref[i].rpi_count, 0);
815 ocs_atomic_init(&hw->rpi_ref[i].rpi_attached, 0);
818 ocs_memset(hw->domains, 0, sizeof(hw->domains));
821 if (hw->workaround.override_fcfi) {
822 hw->first_domain_idx = -1;
825 ocs_memset(hw->fcf_index_fcfi, 0, sizeof(hw->fcf_index_fcfi));
828 if (sli_get_medium(&hw->sli) == SLI_LINK_MEDIUM_FC) {
829 if (hw->hw_mrq_count) {
830 ocs_log_debug(hw->os, "using REG_FCFI MRQ\n");
832 rc = ocs_hw_config_mrq(hw, SLI4_CMD_REG_FCFI_SET_FCFI_MODE, 0, 0);
834 ocs_log_err(hw->os, "REG_FCFI_MRQ FCFI registration failed\n");
838 rc = ocs_hw_config_mrq(hw, SLI4_CMD_REG_FCFI_SET_MRQ_MODE, 0, 0);
840 ocs_log_err(hw->os, "REG_FCFI_MRQ MRQ registration failed\n");
846 ocs_log_debug(hw->os, "using REG_FCFI standard\n");
848 /* Set the filter match/mask values from hw's filter_def values */
851 rq_cfg[i].r_ctl_mask = (uint8_t) hw->config.filter_def[i];
852 rq_cfg[i].r_ctl_match = (uint8_t) (hw->config.filter_def[i] >> 8);
853 rq_cfg[i].type_mask = (uint8_t) (hw->config.filter_def[i] >> 16);
854 rq_cfg[i].type_match = (uint8_t) (hw->config.filter_def[i] >> 24);
861 for (i = 0; i < OCS_MIN(hw->hw_rq_count, SLI4_CMD_REG_FCFI_NUM_RQ_CFG); i++) {
862 hw_rq_t *rq = hw->hw_rq[i];
868 ocs_log_debug(hw->os, "REG_FCFI: filter[%d] %08X -> RQ[%d] id=%d\n",
869 j, hw->config.filter_def[j], i, rq->hdr->id);
876 if (sli_cmd_reg_fcfi(&hw->sli, buf, SLI4_BMBX_SIZE, 0, rq_cfg, 0)) {
877 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
881 ocs_log_err(hw->os, "FCFI registration failed\n");
884 hw->fcf_indicator = ((sli4_cmd_reg_fcfi_t *)buf)->fcfi;
892 rc = ocs_hw_reqtag_init(hw);
894 ocs_log_err(hw->os, "ocs_pool_alloc hw_wq_callback_t failed: %d\n", rc);
898 rc = ocs_hw_setup_io(hw);
900 ocs_log_err(hw->os, "IO allocation failure\n");
904 rc = ocs_hw_init_io(hw);
906 ocs_log_err(hw->os, "IO initialization failure\n");
910 ocs_queue_history_init(hw->os, &hw->q_hist);
912 /* get hw link config; polling, so callback will be called immediately */
913 hw->linkcfg = OCS_HW_LINKCFG_NA;
914 ocs_hw_get_linkcfg(hw, OCS_CMD_POLL, ocs_hw_init_linkcfg_cb, hw);
917 if ((hw->sli.if_type == SLI4_IF_TYPE_LANCER_FC_ETH) &&
918 (sli_get_medium(&hw->sli) == SLI_LINK_MEDIUM_ETHERNET)) {
919 if (ocs_hw_set_eth_license(hw, hw->eth_license)) {
921 ocs_log_err(hw->os, "Failed to set ethernet license\n");
926 if (SLI4_IF_TYPE_LANCER_FC_ETH == sli_get_if_type(&hw->sli) &&
927 ocs_hw_set_dif_seed(hw) != OCS_HW_RTN_SUCCESS) {
928 ocs_log_err(hw->os, "Failed to set DIF seed value\n");
933 if (SLI4_IF_TYPE_BE3_SKH_PF == sli_get_if_type(&hw->sli) &&
934 sli_get_dif_capable(&hw->sli)) {
935 rc = ocs_hw_set_dif_mode(hw);
937 ocs_log_err(hw->os, "Failed to set DIF mode value\n");
945 for (i = 0; i < hw->eq_count; i++) {
946 sli_queue_arm(&hw->sli, &hw->eq[i], TRUE);
952 for (i = 0; i < hw->rq_count; i++) {
953 ocs_hw_queue_hash_add(hw->rq_hash, hw->rq[i].id, i);
959 for (i = 0; i < hw->wq_count; i++) {
960 ocs_hw_queue_hash_add(hw->wq_hash, hw->wq[i].id, i);
966 for (i = 0; i < hw->cq_count; i++) {
967 ocs_hw_queue_hash_add(hw->cq_hash, hw->cq[i].id, i);
968 sli_queue_arm(&hw->sli, &hw->cq[i], TRUE);
972 hw->state = OCS_HW_STATE_ACTIVE;
975 if (ocs_hw_rqpair_init(hw)) {
976 ocs_log_err(hw->os, "WARNING - error initializing RQ pair\n");
980 if (hw->config.emulate_wqe_timeout) {
981 ocs_setup_timer(hw->os, &hw->wqe_timer, target_wqe_timer_cb, hw,
986 * Allocate a HW IOs for send frame. Allocate one for each Class 1 WQ, or if there
989 if ((count = ocs_varray_get_count(hw->wq_class_array[1])) > 0) {
991 hw_wq_t *wq = ocs_varray_iter_next(hw->wq_class_array[1]);
992 wq->send_frame_io = ocs_hw_io_alloc(hw);
994 ocs_log_err(hw->os, "ocs_hw_io_alloc for send_frame_io failed\n");
998 hw->hw_wq[0]->send_frame_io = ocs_hw_io_alloc(hw);
999 if (hw->hw_wq[0]->send_frame_io == NULL) {
1000 ocs_log_err(hw->os, "ocs_hw_io_alloc for send_frame_io failed\n");
1005 ocs_atomic_init(&hw->send_frame_seq_id, 0);
1008 hw->expiration_logged = 0;
1009 if(hw->watchdog_timeout) {
1010 if((hw->watchdog_timeout < 1) || (hw->watchdog_timeout > 65534)) {
1011 ocs_log_err(hw->os, "watchdog_timeout out of range: Valid range is 1 - 65534\n");
1012 }else if(!ocs_hw_config_watchdog_timer(hw)) {
1013 ocs_log_info(hw->os, "watchdog timer configured with timeout = %d seconds \n", hw->watchdog_timeout);
1017 if (ocs_dma_alloc(hw->os, &hw->domain_dmem, 112, 4)) {
1018 ocs_log_err(hw->os, "domain node memory allocation fail\n");
1022 if (ocs_dma_alloc(hw->os, &hw->fcf_dmem, OCS_HW_READ_FCF_SIZE, OCS_HW_READ_FCF_SIZE)) {
1023 ocs_log_err(hw->os, "domain fcf memory allocation fail\n");
1027 if ((0 == hw->loop_map.size) && ocs_dma_alloc(hw->os, &hw->loop_map,
1029 ocs_log_err(hw->os, "Loop dma alloc failed size:%d \n", hw->loop_map.size);
1038 * @param hw Hardware context allocated by the caller.
1046 ocs_hw_config_mrq(ocs_hw_t *hw, uint8_t mode, uint16_t vlanid, uint16_t fcf_index)
1059 /* Set the filter match/mask values from hw's filter_def values */
1062 rq_filter[i].r_ctl_mask = (uint8_t) hw->config.filter_def[i];
1063 rq_filter[i].r_ctl_match = (uint8_t) (hw->config.filter_def[i] >> 8);
1064 rq_filter[i].type_mask = (uint8_t) (hw->config.filter_def[i] >> 16);
1065 rq_filter[i].type_match = (uint8_t) (hw->config.filter_def[i] >> 24);
1069 for (i = 0; i < hw->hw_rq_count; i++) {
1070 rq = hw->hw_rq[i];
1076 ocs_log_err(hw->os, "Wrong queue topology.\n");
1094 rc = sli_cmd_reg_fcfi_mrq(&hw->sli,
1100 hw->config.rq_selection_policy, /* RQ selection policy*/
1102 hw->hw_mrq_count, /* num_mrqs */
1105 ocs_log_err(hw->os, "sli_cmd_reg_fcfi_mrq() failed: %d\n", rc);
1109 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
1114 ocs_log_err(hw->os, "FCFI MRQ registration failed. cmd = %x status = %x\n",
1120 hw->fcf_indicator = rsp->fcfi;
1126 * @brief Callback function for getting linkcfg during HW initialization.
1137 ocs_hw_t *hw = (ocs_hw_t *)arg;
1139 hw->linkcfg = (ocs_hw_linkcfg_e)value;
1141 hw->linkcfg = OCS_HW_LINKCFG_NA;
1143 ocs_log_debug(hw->os, "linkcfg=%d\n", hw->linkcfg);
1152 * not free the HW context memory (which is done by the caller).
1154 * @param hw Hardware context allocated by the caller.
1159 ocs_hw_teardown(ocs_hw_t *hw)
1167 if (!hw) {
1168 ocs_log_err(NULL, "bad parameter(s) hw=%p\n", hw);
1172 destroy_queues = (hw->state == OCS_HW_STATE_ACTIVE);
1173 free_memory = (hw->state != OCS_HW_STATE_UNINITIALIZED);
1176 shutdown_target_wqe_timer(hw);
1179 if(hw->watchdog_timeout) {
1180 hw->watchdog_timeout = 0;
1181 ocs_hw_config_watchdog_timer(hw);
1185 if(hw->sliport_healthcheck) {
1186 hw->sliport_healthcheck = 0;
1187 ocs_hw_config_sli_port_health_check(hw, 0, 0);
1190 if (hw->state != OCS_HW_STATE_QUEUES_ALLOCATED) {
1191 hw->state = OCS_HW_STATE_TEARDOWN_IN_PROGRESS;
1193 ocs_hw_flush(hw);
1196 while (!ocs_list_empty(&hw->cmd_head) && iters) {
1198 ocs_hw_flush(hw);
1202 if (ocs_list_empty(&hw->cmd_head)) {
1203 ocs_log_debug(hw->os, "All commands completed on MQ queue\n");
1205 ocs_log_debug(hw->os, "Some commands still pending on MQ queue\n");
1209 ocs_hw_command_cancel(hw);
1211 hw->state = OCS_HW_STATE_TEARDOWN_IN_PROGRESS;
1214 ocs_lock_free(&hw->cmd_lock);
1217 if (hw->workaround.use_unregistered_rpi) {
1218 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_RPI, hw->workaround.unregistered_rid);
1221 max_rpi = sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_RPI);
1222 if (hw->rpi_ref) {
1224 if (ocs_atomic_read(&hw->rpi_ref[i].rpi_count)) {
1225 ocs_log_debug(hw->os, "non-zero ref [%d]=%d\n",
1226 i, ocs_atomic_read(&hw->rpi_ref[i].rpi_count));
1229 ocs_free(hw->os, hw->rpi_ref, max_rpi * sizeof(*hw->rpi_ref));
1230 hw->rpi_ref = NULL;
1233 ocs_dma_free(hw->os, &hw->rnode_mem);
1235 if (hw->io) {
1236 for (i = 0; i < hw->config.n_io; i++) {
1237 if (hw->io[i] && (hw->io[i]->sgl != NULL) &&
1238 (hw->io[i]->sgl->virt != NULL)) {
1239 if(hw->io[i]->is_port_owned) {
1240 ocs_lock_free(&hw->io[i]->axr_lock);
1242 ocs_dma_free(hw->os, hw->io[i]->sgl);
1244 ocs_free(hw->os, hw->io[i], sizeof(ocs_hw_io_t));
1245 hw->io[i] = NULL;
1247 ocs_free(hw->os, hw->wqe_buffs, hw->config.n_io * hw->sli.config.wqe_size);
1248 hw->wqe_buffs = NULL;
1249 ocs_free(hw->os, hw->io, hw->config.n_io * sizeof(ocs_hw_io_t *));
1250 hw->io = NULL;
1253 ocs_dma_free(hw->os, &hw->xfer_rdy);
1254 ocs_dma_free(hw->os, &hw->dump_sges);
1255 ocs_dma_free(hw->os, &hw->loop_map);
1257 ocs_lock_free(&hw->io_lock);
1258 ocs_lock_free(&hw->io_abort_lock);
1260 for (i = 0; i < hw->wq_count; i++) {
1261 sli_queue_free(&hw->sli, &hw->wq[i], destroy_queues, free_memory);
1264 for (i = 0; i < hw->rq_count; i++) {
1265 sli_queue_free(&hw->sli, &hw->rq[i], destroy_queues, free_memory);
1268 for (i = 0; i < hw->mq_count; i++) {
1269 sli_queue_free(&hw->sli, &hw->mq[i], destroy_queues, free_memory);
1272 for (i = 0; i < hw->cq_count; i++) {
1273 sli_queue_free(&hw->sli, &hw->cq[i], destroy_queues, free_memory);
1276 for (i = 0; i < hw->eq_count; i++) {
1277 sli_queue_free(&hw->sli, &hw->eq[i], destroy_queues, free_memory);
1280 ocs_hw_qtop_free(hw->qtop);
1283 ocs_hw_rx_free(hw);
1285 hw_queue_teardown(hw);
1287 ocs_hw_rqpair_teardown(hw);
1289 if (sli_teardown(&hw->sli)) {
1290 ocs_log_err(hw->os, "SLI teardown failed\n");
1293 ocs_queue_history_free(&hw->q_hist);
1296 hw->state = OCS_HW_STATE_UNINITIALIZED;
1299 ocs_array_free(hw->seq_pool);
1300 hw->seq_pool = NULL;
1303 ocs_pool_free(hw->wq_reqtag_pool);
1305 ocs_dma_free(hw->os, &hw->domain_dmem);
1306 ocs_dma_free(hw->os, &hw->fcf_dmem);
1307 /* Mark HW setup as not having been called */
1308 hw->hw_setup_called = FALSE;
1314 ocs_hw_reset(ocs_hw_t *hw, ocs_hw_reset_e reset)
1319 ocs_hw_state_e prev_state = hw->state;
1321 if (hw->state != OCS_HW_STATE_ACTIVE) {
1322 ocs_log_test(hw->os, "HW state %d is not active\n", hw->state);
1325 hw->state = OCS_HW_STATE_RESET_IN_PROGRESS;
1328 shutdown_target_wqe_timer(hw);
1330 ocs_hw_flush(hw);
1338 while (!ocs_list_empty(&hw->cmd_head) && iters) {
1340 ocs_hw_flush(hw);
1344 if (ocs_list_empty(&hw->cmd_head)) {
1345 ocs_log_debug(hw->os, "All commands completed on MQ queue\n");
1347 ocs_log_debug(hw->os, "Some commands still pending on MQ queue\n");
1353 ocs_log_debug(hw->os, "issuing function level reset\n");
1354 if (sli_reset(&hw->sli)) {
1355 ocs_log_err(hw->os, "sli_reset failed\n");
1360 ocs_log_debug(hw->os, "issuing firmware reset\n");
1361 if (sli_fw_reset(&hw->sli)) {
1362 ocs_log_err(hw->os, "sli_soft_reset failed\n");
1369 ocs_log_debug(hw->os, "issuing function level reset\n");
1370 if (sli_reset(&hw->sli)) {
1371 ocs_log_err(hw->os, "sli_reset failed\n");
1376 ocs_log_test(hw->os, "unknown reset type - no reset performed\n");
1377 hw->state = prev_state;
1383 ocs_hw_command_cancel(hw);
1386 ocs_hw_io_cancel(hw);
1388 ocs_memset(hw->domains, 0, sizeof(hw->domains));
1389 ocs_memset(hw->fcf_index_fcfi, 0, sizeof(hw->fcf_index_fcfi));
1391 ocs_hw_link_event_init(hw);
1393 ocs_lock(&hw->io_lock);
1395 while (!ocs_list_empty(&hw->io_timed_wqe)) {
1396 ocs_list_remove_head(&hw->io_timed_wqe);
1400 while (!ocs_list_empty(&hw->io_free)) {
1401 ocs_list_remove_head(&hw->io_free);
1403 while (!ocs_list_empty(&hw->io_wait_free)) {
1404 ocs_list_remove_head(&hw->io_wait_free);
1407 /* Reset the request tag pool, the HW IO request tags are reassigned in ocs_hw_setup_io() */
1408 ocs_hw_reqtag_reset(hw);
1410 ocs_unlock(&hw->io_lock);
1414 for (i = 0; i < hw->wq_count; i++) {
1415 sli_queue_reset(&hw->sli, &hw->wq[i]);
1418 for (i = 0; i < hw->rq_count; i++) {
1419 sli_queue_reset(&hw->sli, &hw->rq[i]);
1422 for (i = 0; i < hw->hw_rq_count; i++) {
1423 hw_rq_t *rq = hw->hw_rq[i];
1433 for (i = 0; i < hw->mq_count; i++) {
1434 sli_queue_reset(&hw->sli, &hw->mq[i]);
1437 for (i = 0; i < hw->cq_count; i++) {
1438 sli_queue_reset(&hw->sli, &hw->cq[i]);
1441 for (i = 0; i < hw->eq_count; i++) {
1442 sli_queue_reset(&hw->sli, &hw->eq[i]);
1446 ocs_hw_rx_free(hw);
1448 /* Teardown the HW queue topology */
1449 hw_queue_teardown(hw);
1452 ocs_hw_rx_free(hw);
1459 ocs_hw_workaround_setup(hw);
1460 hw->state = OCS_HW_STATE_QUEUES_ALLOCATED;
1466 ocs_hw_get_num_eq(ocs_hw_t *hw)
1468 return hw->eq_count;
1472 ocs_hw_get_fw_timed_out(ocs_hw_t *hw)
1477 return (sli_reg_read(&hw->sli, SLI4_REG_SLIPORT_ERROR1) == 0x2 &&
1478 sli_reg_read(&hw->sli, SLI4_REG_SLIPORT_ERROR2) == 0x10);
1482 ocs_hw_get(ocs_hw_t *hw, ocs_hw_property_e prop, uint32_t *value)
1495 *value = hw->config.n_io;
1498 *value = (hw->config.n_sgl - SLI4_SGE_MAX_RESERVED);
1501 *value = sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_XRI);
1504 *value = sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_RPI);
1507 *value = hw->num_qentries[SLI_QTYPE_RQ];
1510 *value = hw->config.rq_default_buffer_size;
1513 *value = sli_get_auto_xfer_rdy_capable(&hw->sli);
1516 *value = hw->config.auto_xfer_rdy_xri_cnt;
1519 *value = hw->config.auto_xfer_rdy_size;
1522 switch (hw->config.auto_xfer_rdy_blk_size_chip) {
1545 *value = hw->config.auto_xfer_rdy_t10_enable;
1548 *value = hw->config.auto_xfer_rdy_p_type;
1551 *value = hw->config.auto_xfer_rdy_ref_tag_is_lba;
1554 *value = hw->config.auto_xfer_rdy_app_tag_valid;
1557 *value = hw->config.auto_xfer_rdy_app_tag_value;
1560 *value = sli_get_max_sge(&hw->sli);
1563 *value = sli_get_max_sgl(&hw->sli);
1570 if (hw->link.speed == 0) {
1574 switch (hw->link.topology) {
1585 ocs_log_test(hw->os, "unsupported topology %#x\n", hw->link.topology);
1591 *value = hw->config.topology;
1594 *value = hw->link.speed;
1597 switch (hw->config.speed) {
1620 ocs_log_test(hw->os, "unsupported speed %#x\n", hw->config.speed);
1626 *value = sli_get_if_type(&hw->sli);
1629 *value = sli_get_sli_rev(&hw->sli);
1632 *value = sli_get_sli_family(&hw->sli);
1635 *value = sli_get_dif_capable(&hw->sli);
1638 *value = hw->config.dif_seed;
1641 *value = hw->config.dif_mode;
1645 if (hw->sli.if_type == SLI4_IF_TYPE_LANCER_FC_ETH) {
1652 *value = hw->dump_size;
1655 *value = sli_dump_is_ready(&hw->sli);
1658 *value = sli_dump_is_present(&hw->sli);
1661 tmp = sli_reset_required(&hw->sli);
1669 *value = sli_fw_error_status(&hw->sli);
1672 *value = sli_fw_ready(&hw->sli);
1675 *value = ocs_hw_get_fw_timed_out(hw);
1678 *value = sli_get_hlm_capable(&hw->sli);
1681 *value = sli_get_sgl_preregister_required(&hw->sli);
1684 *value = sli_get_hw_revision(&hw->sli, 0);
1687 *value = sli_get_hw_revision(&hw->sli, 1);
1690 *value = sli_get_hw_revision(&hw->sli, 2);
1693 *value = hw->linkcfg;
1696 *value = hw->eth_license;
1699 *value = sli_get_link_module_type(&hw->sli);
1702 *value = ocs_hw_get_num_chutes(hw);
1705 *value = hw->workaround.disable_ar_tgt_dif;
1708 *value = hw->config.i_only_aab;
1711 *value = hw->config.emulate_wqe_timeout;
1714 *value = sli_get_vpd_len(&hw->sli);
1717 *value = sli_get_is_sgl_chaining_capable(&hw->sli) || hw->workaround.sglc_misreported;
1726 if ((sli_get_is_sgl_chaining_capable(&hw->sli) || hw->workaround.sglc_misreported) &&
1727 !sli_get_sgl_preregister(&hw->sli) &&
1728 SLI4_IF_TYPE_LANCER_FC_ETH == sli_get_if_type(&hw->sli)) {
1732 if ((sli_get_is_sgl_chaining_capable(&hw->sli) || hw->workaround.sglc_misreported) &&
1733 sli_get_sgl_preregister(&hw->sli) &&
1734 ((SLI4_IF_TYPE_BE3_SKH_PF == sli_get_if_type(&hw->sli)) ||
1735 (SLI4_IF_TYPE_BE3_SKH_VF == sli_get_if_type(&hw->sli)))) {
1741 *value = ((sli_get_is_sgl_chaining_capable(&hw->sli) || hw->workaround.sglc_misreported) &&
1742 (SLI4_IF_TYPE_LANCER_FC_ETH == sli_get_if_type(&hw->sli)));
1745 if (hw->workaround.ignore_send_frame) {
1749 *value = sli_get_if_type(&hw->sli) == SLI4_IF_TYPE_LANCER_FC_ETH;
1753 *value = hw->config.rq_selection_policy;
1756 *value = hw->config.rr_quanta;
1759 *value = sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_VPI);
1762 ocs_log_test(hw->os, "unsupported property %#x\n", prop);
1770 ocs_hw_get_ptr(ocs_hw_t *hw, ocs_hw_property_e prop)
1776 rc = sli_get_wwn_node(&hw->sli);
1779 rc = sli_get_wwn_port(&hw->sli);
1783 if (sli_get_vpd_len(&hw->sli)) {
1784 rc = sli_get_vpd(&hw->sli);
1788 rc = sli_get_fw_name(&hw->sli, 0);
1791 rc = sli_get_fw_name(&hw->sli, 1);
1794 rc = sli_get_ipl_name(&hw->sli);
1797 rc = sli_get_portnum(&hw->sli);
1800 rc = sli_get_bios_version_string(&hw->sli);
1803 ocs_log_test(hw->os, "unsupported property %#x\n", prop);
1810 ocs_hw_set(ocs_hw_t *hw, ocs_hw_property_e prop, uint32_t value)
1816 if (value > sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_XRI) ||
1818 ocs_log_test(hw->os, "IO value out of range %d vs %d\n",
1819 value, sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_XRI));
1822 hw->config.n_io = value;
1827 if (value > sli_get_max_sgl(&hw->sli)) {
1828 ocs_log_test(hw->os, "SGL value out of range %d vs %d\n",
1829 value, sli_get_max_sgl(&hw->sli));
1832 hw->config.n_sgl = value;
1836 if ((sli_get_medium(&hw->sli) != SLI_LINK_MEDIUM_FC) &&
1838 ocs_log_test(hw->os, "unsupported topology=%#x medium=%#x\n",
1839 value, sli_get_medium(&hw->sli));
1846 if (sli_get_medium(&hw->sli) == SLI_LINK_MEDIUM_FC) {
1847 sli_set_topology(&hw->sli, SLI4_READ_CFG_TOPO_FC);
1849 sli_set_topology(&hw->sli, SLI4_READ_CFG_TOPO_FCOE);
1853 sli_set_topology(&hw->sli, SLI4_READ_CFG_TOPO_FC_DA);
1856 sli_set_topology(&hw->sli, SLI4_READ_CFG_TOPO_FC_AL);
1859 ocs_log_test(hw->os, "unsupported topology %#x\n", value);
1862 hw->config.topology = value;
1865 if (sli_get_medium(&hw->sli) != SLI_LINK_MEDIUM_FC) {
1869 hw->config.speed = FC_LINK_SPEED_10G;
1872 ocs_log_test(hw->os, "unsupported speed=%#x medium=%#x\n",
1873 value, sli_get_medium(&hw->sli));
1881 hw->config.speed = FC_LINK_SPEED_AUTO_16_8_4;
1884 hw->config.speed = FC_LINK_SPEED_2G;
1887 hw->config.speed = FC_LINK_SPEED_4G;
1890 hw->config.speed = FC_LINK_SPEED_8G;
1893 hw->config.speed = FC_LINK_SPEED_16G;
1896 hw->config.speed = FC_LINK_SPEED_32G;
1899 ocs_log_test(hw->os, "unsupported speed %d\n", value);
1905 if (SLI4_IF_TYPE_LANCER_FC_ETH != sli_get_if_type(&hw->sli)) {
1906 ocs_log_test(hw->os, "DIF seed not supported for this device\n");
1909 hw->config.dif_seed = value;
1921 if (sli_is_dif_inline_capable(&hw->sli)) {
1922 hw->config.dif_mode = value;
1924 ocs_log_test(hw->os, "chip does not support DIF inline\n");
1930 if (sli_is_dif_separate_capable(&hw->sli)) {
1931 hw->config.dif_mode = value;
1933 ocs_log_test(hw->os, "chip does not support DIF separate\n");
1943 for (i = 0; i < hw->hw_rq_count; i++) {
1944 rq = hw->hw_rq[i];
1945 hw->cq[rq->cq->instance].proc_limit = value;
1950 hw->config.rq_default_buffer_size = value;
1953 hw->config.auto_xfer_rdy_xri_cnt = value;
1956 hw->config.auto_xfer_rdy_size = value;
1961 hw->config.auto_xfer_rdy_blk_size_chip = 0;
1964 hw->config.auto_xfer_rdy_blk_size_chip = 1;
1967 hw->config.auto_xfer_rdy_blk_size_chip = 2;
1970 hw->config.auto_xfer_rdy_blk_size_chip = 3;
1973 hw->config.auto_xfer_rdy_blk_size_chip = 4;
1976 ocs_log_err(hw->os, "Invalid block size %d\n",
1982 hw->config.auto_xfer_rdy_t10_enable = value;
1985 hw->config.auto_xfer_rdy_p_type = value;
1988 hw->config.auto_xfer_rdy_ref_tag_is_lba = value;
1991 hw->config.auto_xfer_rdy_app_tag_valid = value;
1994 hw->config.auto_xfer_rdy_app_tag_value = value;
1997 hw->config.esoc = value;
2000 rc = sli_set_hlm(&hw->sli, value);
2003 rc = sli_set_sgl_preregister(&hw->sli, value);
2006 hw->eth_license = value;
2009 hw->config.i_only_aab = value;
2012 hw->config.emulate_wqe_timeout = value;
2015 hw->config.bounce = value;
2018 hw->config.rq_selection_policy = value;
2021 hw->config.rr_quanta = value;
2024 ocs_log_test(hw->os, "unsupported property %#x\n", prop);
2032 ocs_hw_set_ptr(ocs_hw_t *hw, ocs_hw_property_e prop, void *value)
2038 hw->hw_war_version = value;
2044 for (idx = 0; idx < ARRAY_SIZE(hw->config.filter_def); idx++) {
2045 hw->config.filter_def[idx] = 0;
2048 for (idx = 0; (idx < ARRAY_SIZE(hw->config.filter_def)) && (p != NULL) && *p; ) {
2049 hw->config.filter_def[idx++] = ocs_strtoul(p, 0, 0);
2059 ocs_log_test(hw->os, "unsupported property %#x\n", prop);
2069 * @param hw Hardware context.
2075 ocs_hw_event_check(ocs_hw_t *hw, uint32_t vector)
2079 if (!hw) {
2080 ocs_log_err(NULL, "HW context NULL?!?\n");
2084 if (vector > hw->eq_count) {
2085 ocs_log_err(hw->os, "vector %d. max %d\n",
2086 vector, hw->eq_count);
2101 if (hw->state != OCS_HW_STATE_UNINITIALIZED) {
2102 rc = sli_queue_is_empty(&hw->sli, &hw->eq[vector]);
2106 sli_queue_arm(&hw->sli, &hw->eq[vector], TRUE);
2116 ocs_hw_t *hw = seq->hw;
2118 ocs_hw_assert(hw != NULL);
2119 ocs_hw_assert(hw->callback.unsolicited != NULL);
2121 hw->callback.unsolicited(hw->args.unsolicited, seq);
2125 ocs_hw_process(ocs_hw_t *hw, uint32_t vector, uint32_t max_isr_time_msec)
2143 if (hw->state == OCS_HW_STATE_UNINITIALIZED) {
2148 eq = hw->hw_eq[vector];
2152 rc = ocs_hw_eq_process(hw, eq, max_isr_time_msec);
2172 * @param hw Hardware context.
2173 * @param eq Pointer to HW EQ object.
2179 ocs_hw_eq_process(ocs_hw_t *hw, hw_eq_t *eq, uint32_t max_isr_time_msec)
2192 while (!done && !sli_queue_read(&hw->sli, eq->queue, eqe)) {
2196 rc = sli_eq_parse(&hw->sli, eqe, &cq_id);
2205 for (i = 0; i < hw->cq_count; i++) {
2206 ocs_hw_cq_process(hw, hw->hw_cq[i]);
2213 int32_t index = ocs_hw_queue_hash_find(hw->cq_hash, cq_id);
2215 ocs_hw_cq_process(hw, hw->hw_cq[index]);
2217 ocs_log_err(hw->os, "bad CQ_ID %#06x\n", cq_id);
2222 sli_queue_arm(&hw->sli, eq->queue, FALSE);
2233 sli_queue_eq_arm(&hw->sli, eq->queue, TRUE);
2243 * --- Assumes that hw->cmd_lock is held ---
2245 * @param hw Hardware context.
2250 ocs_hw_cmd_submit_pending(ocs_hw_t *hw)
2258 while (hw->cmd_head_count < (OCS_HW_MQ_DEPTH - 1)) {
2259 ctx = ocs_list_remove_head(&hw->cmd_pending);
2263 ocs_list_add_tail(&hw->cmd_head, ctx);
2264 hw->cmd_head_count++;
2265 if (sli_queue_write(&hw->sli, hw->mq, ctx->buf) < 0) {
2266 ocs_log_test(hw->os, "sli_queue_write failed: %d\n", rc);
2282 * @param hw Hardware context.
2297 ocs_hw_command(ocs_hw_t *hw, uint8_t *cmd, uint32_t opts, void *cb, void *arg)
2305 if (sli_fw_error_status(&hw->sli) > 0) {
2306 uint32_t err1 = sli_reg_read(&hw->sli, SLI4_REG_SLIPORT_ERROR1);
2307 uint32_t err2 = sli_reg_read(&hw->sli, SLI4_REG_SLIPORT_ERROR2);
2308 if (hw->expiration_logged == 0 && err1 == 0x2 && err2 == 0x10) {
2309 hw->expiration_logged = 1;
2310 ocs_log_crit(hw->os,"Emulex: Heartbeat expired after %d seconds\n",
2311 hw->watchdog_timeout);
2313 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2314 ocs_log_crit(hw->os, "status=%#x error1=%#x error2=%#x\n",
2315 sli_reg_read(&hw->sli, SLI4_REG_SLIPORT_STATUS),
2322 ocs_lock(&hw->cmd_lock);
2323 if (hw->mq->length && !sli_queue_is_empty(&hw->sli, hw->mq)) {
2331 void *bmbx = hw->sli.bmbx.virt;
2336 if (sli_bmbx_command(&hw->sli) == 0) {
2341 ocs_unlock(&hw->cmd_lock);
2345 ctx = ocs_malloc(hw->os, sizeof(ocs_command_ctx_t), OCS_M_ZERO | OCS_M_NOWAIT);
2347 ocs_log_err(hw->os, "can't allocate command context\n");
2351 if (hw->state != OCS_HW_STATE_ACTIVE) {
2352 ocs_log_err(hw->os, "Can't send command, HW state=%d\n", hw->state);
2353 ocs_free(hw->os, ctx, sizeof(*ctx));
2362 ctx->ctx = hw;
2364 ocs_lock(&hw->cmd_lock);
2367 ocs_list_add_tail(&hw->cmd_pending, ctx);
2370 if (ocs_hw_cmd_submit_pending(hw) == 0) {
2374 ocs_unlock(&hw->cmd_lock);
2384 * @param hw Hardware context.
2392 ocs_hw_callback(ocs_hw_t *hw, ocs_hw_callback_e which, void *func, void *arg)
2395 if (!hw || !func || (which >= OCS_HW_CB_MAX)) {
2396 ocs_log_err(NULL, "bad parameter hw=%p which=%#x func=%p\n",
2397 hw, which, func);
2403 hw->callback.domain = func;
2404 hw->args.domain = arg;
2407 hw->callback.port = func;
2408 hw->args.port = arg;
2411 hw->callback.unsolicited = func;
2412 hw->args.unsolicited = arg;
2415 hw->callback.rnode = func;
2416 hw->args.rnode = arg;
2419 hw->callback.bounce = func;
2420 hw->args.bounce = arg;
2423 ocs_log_test(hw->os, "unknown callback %#x\n", which);
2438 * @param hw Hardware context.
2446 ocs_hw_port_alloc(ocs_hw_t *hw, ocs_sli_port_t *sport, ocs_domain_t *domain,
2454 sport->hw = hw;
2461 if (sli_fw_error_status(&hw->sli) > 0) {
2462 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2470 if (sli_resource_alloc(&hw->sli, SLI_RSRC_FCOE_VPI, &sport->indicator, &index)) {
2471 ocs_log_err(hw->os, "FCOE_VPI allocation failure\n");
2478 cmd = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
2480 ocs_log_err(hw->os, "command memory allocation failed\n");
2496 /* This is the convention for the HW, not SLI */
2497 ocs_log_test(hw->os, "need WWN for physical port\n");
2506 ocs_free(hw->os, cmd, SLI4_BMBX_SIZE);
2508 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VPI, sport->indicator);
2522 * @param hw Hardware context.
2529 ocs_hw_port_attach(ocs_hw_t *hw, ocs_sli_port_t *sport, uint32_t fc_id)
2534 if (!hw || !sport) {
2535 ocs_log_err(hw ? hw->os : NULL,
2536 "bad parameter(s) hw=%p sport=%p\n", hw,
2544 if (sli_fw_error_status(&hw->sli) > 0) {
2545 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2549 buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
2551 ocs_log_err(hw->os, "no buffer for command\n");
2566 * @param hw Hardware context.
2574 ocs_hw_cb_port_control(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
2576 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
2588 * The HW generates an OCS_HW_DOMAIN_FOUND event when the link comes up.
2592 * The HW generates an OCS_HW_DOMAIN_LOST event when the link is down.
2597 * @param hw Hardware context.
2623 ocs_hw_port_control(ocs_hw_t *hw, ocs_hw_port_e ctrl, uintptr_t value, ocs_hw_port_control_cb_t cb, void *arg)
2634 if (SLI_LINK_MEDIUM_FC == sli_get_medium(&hw->sli)) {
2637 cfg_link = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
2639 ocs_log_err(hw->os, "no buffer for command\n");
2643 if (sli_cmd_config_link(&hw->sli, cfg_link, SLI4_BMBX_SIZE)) {
2644 rc = ocs_hw_command(hw, cfg_link, OCS_CMD_NOWAIT,
2649 ocs_free(hw->os, cfg_link, SLI4_BMBX_SIZE);
2650 ocs_log_err(hw->os, "CONFIG_LINK failed\n");
2653 speed = hw->config.speed;
2662 if (hw->workaround.fw_version_too_low) {
2663 if (SLI4_IF_TYPE_LANCER_FC_ETH == hw->sli.if_type) {
2664 ocs_log_err(hw->os, "Cannot bring up link. Please update firmware to %s or later (current version is %s)\n",
2665 OCS_FW_VER_STR(OCS_MIN_FW_VER_LANCER), (char *) sli_get_fw_name(&hw->sli,0));
2667 ocs_log_err(hw->os, "Cannot bring up link. Please update firmware to %s or later (current version is %s)\n",
2668 OCS_FW_VER_STR(OCS_MIN_FW_VER_SKYHAWK), (char *) sli_get_fw_name(&hw->sli, 0));
2677 init_link = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
2679 ocs_log_err(hw->os, "no buffer for command\n");
2683 if (sli_cmd_init_link(&hw->sli, init_link, SLI4_BMBX_SIZE, speed, reset_alpa)) {
2684 rc = ocs_hw_command(hw, init_link, OCS_CMD_NOWAIT,
2689 ocs_free(hw->os, init_link, SLI4_BMBX_SIZE);
2690 ocs_log_err(hw->os, "INIT_LINK failed\n");
2698 down_link = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
2700 ocs_log_err(hw->os, "no buffer for command\n");
2703 if (sli_cmd_down_link(&hw->sli, down_link, SLI4_BMBX_SIZE)) {
2704 rc = ocs_hw_command(hw, down_link, OCS_CMD_NOWAIT,
2709 ocs_free(hw->os, down_link, SLI4_BMBX_SIZE);
2710 ocs_log_err(hw->os, "DOWN_LINK failed\n");
2715 rc = ocs_hw_set_linkcfg(hw, (ocs_hw_linkcfg_e)value, OCS_CMD_NOWAIT, cb, arg);
2718 ocs_log_test(hw->os, "unhandled control %#x\n", ctrl);
2732 * @param hw Hardware context.
2738 ocs_hw_port_free(ocs_hw_t *hw, ocs_sli_port_t *sport)
2742 if (!hw || !sport) {
2743 ocs_log_err(hw ? hw->os : NULL,
2744 "bad parameter(s) hw=%p sport=%p\n", hw,
2752 if (sli_fw_error_status(&hw->sli) > 0) {
2753 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2772 * @n @n Upon successful allocation, the HW generates a OCS_HW_DOMAIN_ALLOC_OK
2775 * @param hw Hardware context.
2783 ocs_hw_domain_alloc(ocs_hw_t *hw, ocs_domain_t *domain, uint32_t fcf, uint32_t vlan)
2788 if (!hw || !domain || !domain->sport) {
2789 ocs_log_err(NULL, "bad parameter(s) hw=%p domain=%p sport=%p\n",
2790 hw, domain, domain ? domain->sport : NULL);
2797 if (sli_fw_error_status(&hw->sli) > 0) {
2798 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2802 cmd = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
2804 ocs_log_err(hw->os, "command memory allocation failed\n");
2808 domain->dma = hw->domain_dmem;
2810 domain->hw = hw;
2817 if (sli_resource_alloc(&hw->sli, SLI_RSRC_FCOE_VFI, &domain->indicator, &index)) {
2818 ocs_log_err(hw->os, "FCOE_VFI allocation failure\n");
2820 ocs_free(hw->os, cmd, SLI4_BMBX_SIZE);
2833 * @param hw Hardware context.
2840 ocs_hw_domain_attach(ocs_hw_t *hw, ocs_domain_t *domain, uint32_t fc_id)
2845 if (!hw || !domain) {
2846 ocs_log_err(hw ? hw->os : NULL,
2847 "bad parameter(s) hw=%p domain=%p\n",
2848 hw, domain);
2855 if (sli_fw_error_status(&hw->sli) > 0) {
2856 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2860 buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
2862 ocs_log_err(hw->os, "no buffer for command\n");
2878 * @param hw Hardware context.
2884 ocs_hw_domain_free(ocs_hw_t *hw, ocs_domain_t *domain)
2888 if (!hw || !domain) {
2889 ocs_log_err(hw ? hw->os : NULL,
2890 "bad parameter(s) hw=%p domain=%p\n",
2891 hw, domain);
2898 if (sli_fw_error_status(&hw->sli) > 0) {
2899 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2916 * @param hw Hardware context.
2922 ocs_hw_domain_force_free(ocs_hw_t *hw, ocs_domain_t *domain)
2924 if (!hw || !domain) {
2925 ocs_log_err(NULL, "bad parameter(s) hw=%p domain=%p\n", hw, domain);
2929 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VFI, domain->indicator);
2938 * @param hw Hardware context.
2946 ocs_hw_node_alloc(ocs_hw_t *hw, ocs_remote_node_t *rnode, uint32_t fc_addr,
2951 ocs_log_err(hw->os, "FCOE_RPI allocation failure addr=%#x rpi=%#x\n",
2959 if (sli_fw_error_status(&hw->sli) > 0) {
2960 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2967 if (sli_resource_alloc(&hw->sli, SLI_RSRC_FCOE_RPI, &rnode->indicator, &rnode->index)) {
2968 ocs_log_err(hw->os, "FCOE_RPI allocation failure addr=%#x\n",
2983 * @param hw Hardware context.
2990 ocs_hw_node_attach(ocs_hw_t *hw, ocs_remote_node_t *rnode, ocs_dma_t *sparms)
2996 if (!hw || !rnode || !sparms) {
2997 ocs_log_err(NULL, "bad parameter(s) hw=%p rnode=%p sparms=%p\n",
2998 hw, rnode, sparms);
3005 if (sli_fw_error_status(&hw->sli) > 0) {
3006 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
3010 buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
3012 ocs_log_err(hw->os, "no buffer for command\n");
3022 ocs_free(hw->os, buf, SLI4_BMBX_SIZE);
3025 count = ocs_atomic_add_return(&hw->rpi_ref[rnode->index].rpi_count, 1);
3031 if (sli_get_hlm(&hw->sli) == FALSE) {
3032 ocs_log_test(hw->os, "attach to already attached node HLM=%d count=%d\n",
3033 sli_get_hlm(&hw->sli), count);
3037 rnode->attached = ocs_atomic_read(&hw->rpi_ref[rnode->index].rpi_attached);
3044 if (sli_cmd_reg_rpi(&hw->sli, buf, SLI4_BMBX_SIZE, rnode->fc_id,
3046 sparms, 0, (hw->auto_xfer_rdy_enabled && hw->config.auto_xfer_rdy_t10_enable))) {
3047 rc = ocs_hw_command(hw, buf, OCS_CMD_NOWAIT,
3054 ocs_atomic_sub_return(&hw->rpi_ref[rnode->index].rpi_count, 1);
3055 ocs_log_err(hw->os, "%s error\n", count ? "HLM" : "REG_RPI");
3057 ocs_free(hw->os, buf, SLI4_BMBX_SIZE);
3067 * @param hw Hardware context.
3073 ocs_hw_node_free_resources(ocs_hw_t *hw, ocs_remote_node_t *rnode)
3077 if (!hw || !rnode) {
3078 ocs_log_err(NULL, "bad parameter(s) hw=%p rnode=%p\n",
3079 hw, rnode);
3086 if (sli_resource_free(&hw->sli, SLI_RSRC_FCOE_RPI, rnode->indicator)) {
3087 ocs_log_err(hw->os, "FCOE_RPI free failure RPI %d addr=%#x\n",
3098 ocs_log_err(hw->os, "Error: rnode is still attached\n");
3110 * @param hw Hardware context.
3116 ocs_hw_node_detach(ocs_hw_t *hw, ocs_remote_node_t *rnode)
3122 if (!hw || !rnode) {
3123 ocs_log_err(NULL, "bad parameter(s) hw=%p rnode=%p\n",
3124 hw, rnode);
3131 if (sli_fw_error_status(&hw->sli) > 0) {
3132 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
3146 buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
3148 ocs_log_err(hw->os, "no buffer for command\n");
3152 count = ocs_atomic_sub_return(&hw->rpi_ref[index].rpi_count, 1);
3161 if (sli_get_hlm(&hw->sli) == FALSE) {
3162 ocs_log_test(hw->os, "Invalid count with HLM disabled, count=%d\n",
3170 if (sli_cmd_unreg_rpi(&hw->sli, buf, SLI4_BMBX_SIZE, rnode->indicator,
3172 rc = ocs_hw_command(hw, buf, OCS_CMD_NOWAIT, ocs_hw_cb_node_free, rnode);
3176 ocs_log_err(hw->os, "UNREG_RPI failed\n");
3177 ocs_free(hw->os, buf, SLI4_BMBX_SIZE);
3189 * @param hw Hardware context.
3194 ocs_hw_node_free_all(ocs_hw_t *hw)
3199 if (!hw) {
3200 ocs_log_err(NULL, "bad parameter hw=%p\n", hw);
3207 if (sli_fw_error_status(&hw->sli) > 0) {
3208 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
3212 buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
3214 ocs_log_err(hw->os, "no buffer for command\n");
3218 if (sli_cmd_unreg_rpi(&hw->sli, buf, SLI4_BMBX_SIZE, 0xffff,
3220 rc = ocs_hw_command(hw, buf, OCS_CMD_NOWAIT, ocs_hw_cb_node_free_all,
3225 ocs_log_err(hw->os, "UNREG_RPI failed\n");
3226 ocs_free(hw->os, buf, SLI4_BMBX_SIZE);
3234 ocs_hw_node_group_alloc(ocs_hw_t *hw, ocs_remote_node_group_t *ngroup)
3237 if (!hw || !ngroup) {
3238 ocs_log_err(NULL, "bad parameter hw=%p ngroup=%p\n",
3239 hw, ngroup);
3243 if (sli_resource_alloc(&hw->sli, SLI_RSRC_FCOE_RPI, &ngroup->indicator,
3245 ocs_log_err(hw->os, "FCOE_RPI allocation failure addr=%#x\n",
3254 ocs_hw_node_group_attach(ocs_hw_t *hw, ocs_remote_node_group_t *ngroup, ocs_remote_node_t *rnode)
3257 if (!hw || !ngroup || !rnode) {
3258 ocs_log_err(NULL, "bad parameter hw=%p ngroup=%p rnode=%p\n",
3259 hw, ngroup, rnode);
3264 ocs_log_err(hw->os, "node already attached RPI=%#x addr=%#x\n",
3269 if (sli_resource_free(&hw->sli, SLI_RSRC_FCOE_RPI, rnode->indicator)) {
3270 ocs_log_err(hw->os, "FCOE_RPI free failure RPI=%#x\n",
3282 ocs_hw_node_group_free(ocs_hw_t *hw, ocs_remote_node_group_t *ngroup)
3286 if (!hw || !ngroup) {
3287 ocs_log_err(NULL, "bad parameter hw=%p ngroup=%p\n",
3288 hw, ngroup);
3292 ref = ocs_atomic_read(&hw->rpi_ref[ngroup->index].rpi_count);
3295 ocs_log_debug(hw->os, "node group reference=%d (RPI=%#x)\n",
3298 if (sli_resource_free(&hw->sli, SLI_RSRC_FCOE_RPI, ngroup->indicator)) {
3299 ocs_log_err(hw->os, "FCOE_RPI free failure RPI=%#x\n",
3304 ocs_atomic_set(&hw->rpi_ref[ngroup->index].rpi_count, 0);
3321 * @param io Pointer to HW IO.
3344 * @brief Lockless allocate a HW IO object.
3347 * Assume that hw->ocs_lock is held. This function is only used if
3350 * @param hw Hardware context.
3355 _ocs_hw_io_alloc(ocs_hw_t *hw)
3359 if (NULL != (io = ocs_list_remove_head(&hw->io_free))) {
3360 ocs_list_add_tail(&hw->io_inuse, io);
3367 ocs_atomic_add_return(&hw->io_alloc_failed_count, 1);
3374 * @brief Allocate a HW IO object.
3380 * @param hw Hardware context.
3385 ocs_hw_io_alloc(ocs_hw_t *hw)
3389 ocs_lock(&hw->io_lock);
3390 io = _ocs_hw_io_alloc(hw);
3391 ocs_unlock(&hw->io_lock);
3398 * @brief Allocate/Activate a port owned HW IO object.
3402 * allocated by the SLI-Port. This will "activate" the HW IO
3407 * @param hw Hardware context.
3408 * @param io Pointer HW IO to activate/allocate.
3413 ocs_hw_io_activate_port_owned(ocs_hw_t *hw, ocs_hw_io_t *io)
3416 ocs_log_err(hw->os, "Bad parameter: refcount > 0\n");
3421 ocs_log_err(hw->os, "XRI %x already in use\n", io->indicator);
3437 * @n @b Note: Assumes that the hw->io_lock is held and the item has been removed
3440 * @param hw Hardware context.
3444 ocs_hw_io_free_move_correct_list(ocs_hw_t *hw, ocs_hw_io_t *io)
3448 ocs_list_add_tail(&hw->io_wait_free, io);
3452 ocs_list_add_tail(&hw->io_free, io);
3457 if (hw->workaround.use_dif_sec_xri) {
3458 ocs_hw_check_sec_hio_list(hw);
3464 * @brief Free a HW IO object. Perform cleanup common to
3467 * @param hw Hardware context.
3468 * @param io Pointer to the HW IO object.
3471 ocs_hw_io_free_common(ocs_hw_t *hw, ocs_hw_io_t *io)
3477 ocs_hw_io_restore_sgl(hw, io);
3482 * @brief Free a HW IO object associated with a port-owned XRI.
3484 * @param arg Pointer to the HW IO object.
3490 ocs_hw_t *hw = io->hw;
3497 ocs_lock(&hw->io_lock);
3500 ocs_list_add_tail(&hw->io_port_dnrx, io);
3501 ocs_unlock(&hw->io_lock);
3505 ocs_hw_io_free_common(hw, io);
3510 * @brief Free a previously-allocated HW IO object. Called when
3513 * @param arg Pointer to the HW IO object.
3519 ocs_hw_t *hw = io->hw;
3522 ocs_hw_io_free_common(hw, io);
3524 ocs_lock(&hw->io_lock);
3526 ocs_list_remove(&hw->io_inuse, io);
3527 ocs_hw_io_free_move_correct_list(hw, io);
3528 ocs_unlock(&hw->io_lock);
3533 * @brief Free a previously-allocated HW IO object.
3538 * @param hw Hardware context.
3539 * @param io Pointer to the HW IO object.
3541 * @return Returns a non-zero value if HW IO was freed, 0 if references
3545 ocs_hw_io_free(ocs_hw_t *hw, ocs_hw_io_t *io)
3549 ocs_log_err(hw->os, "Bad parameter: refcount <= 0 xri=%x tag=%x\n",
3559 * @brief Check if given HW IO is in-use
3562 * This function returns TRUE if the given HW IO has been
3566 * @param hw Hardware context.
3567 * @param io Pointer to the HW IO object.
3572 ocs_hw_io_inuse(ocs_hw_t *hw, ocs_hw_io_t *io)
3578 * @brief Write a HW IO to a work queue.
3581 * A HW IO is written to a work queue.
3609 queue_rc = _sli_queue_write(&wq->hw->sli, wq->queue, wqe->wqebuf);
3615 ocs_queue_history_wq(&wq->hw->q_hist, (void *) wqe->wqebuf, wq->queue->id, queue_rc);
3622 * @brief Write a HW IO to a work queue.
3625 * A HW IO is written to a work queue.
3650 sli_abort_wqe(&wq->hw->sli, wqe->wqebuf, wq->hw->sli.config.wqe_size, SLI_ABORT_XRI,
3672 * @brief Update free count and submit any pending HW IOs
3675 * The WQ free count is updated, and any pending HW IOs are submitted that
3698 sli_abort_wqe(&wq->hw->sli, wqe->wqebuf, wq->hw->sli.config.wqe_size, SLI_ABORT_XRI,
3712 * Checks hw->sec_hio_wait_list, if an IO is waiting for a HW IO, then try
3713 * to allocate a secondary HW io, and dispatch it.
3715 * @n @b Note: hw->io_lock MUST be taken when called.
3717 * @param hw pointer to HW object
3722 ocs_hw_check_sec_hio_list(ocs_hw_t *hw)
3728 while (!ocs_list_empty(&hw->sec_hio_wait_list)) {
3731 sec_io = _ocs_hw_io_alloc(hw);
3736 io = ocs_list_remove_head(&hw->sec_hio_wait_list);
3737 ocs_list_add_tail(&hw->io_inuse, io);
3757 if (sli_fcp_cont_treceive64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &io->def_sgl,
3764 ocs_log_test(hw->os, "TRECEIVE WQE error\n");
3768 if (sli_fcp_treceive64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &io->def_sgl,
3776 ocs_log_test(hw->os, "TRECEIVE WQE error\n");
3782 io->wq = ocs_hw_queue_next_wq(hw, io);
3791 ocs_hw_add_io_timed_wqe(hw, io);
3798 ocs_log_err(hw->os, "sli_queue_write failed: %d\n", rc);
3800 ocs_hw_remove_io_timed_wqe(hw, io);
3823 * @param hw Hardware context.
3825 * @param io Previously-allocated HW IO object.
3837 ocs_hw_srrs_send(ocs_hw_t *hw, ocs_hw_io_type_e type, ocs_hw_io_t *io,
3846 if (!hw || !io || !rnode || !iparam) {
3847 ocs_log_err(NULL, "bad parm hw=%p io=%p send=%p receive=%p rnode=%p iparam=%p\n",
3848 hw, io, send, receive, rnode, iparam);
3852 if (hw->state != OCS_HW_STATE_ACTIVE) {
3853 ocs_log_test(hw->os, "cannot send SRRS, HW state=%d\n", hw->state);
3857 if (ocs_hw_is_xri_port_owned(hw, io->indicator)) {
3890 if ( (!send) || sli_els_request64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, io->sgl,
3894 ocs_log_err(hw->os, "REQ WQE error\n");
3899 if ( (!send) || sli_xmit_els_rsp64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, send, len,
3903 ocs_log_err(hw->os, "RSP WQE error\n");
3908 if ( (!send) || sli_xmit_els_rsp64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, send, len,
3912 ocs_log_err(hw->os, "RSP (SID) WQE error\n");
3917 if ( (!send) || sli_gen_request64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, io->sgl, len,
3921 ocs_log_err(hw->os, "GEN WQE error\n");
3926 if ( (!send) || sli_xmit_sequence64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, io->sgl, len,
3930 ocs_log_err(hw->os, "XMIT SEQ WQE error\n");
3950 if (sli_xmit_bls_rsp64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &bls,
3954 ocs_log_err(hw->os, "XMIT_BLS_RSP64 WQE error\n");
3969 if (sli_xmit_bls_rsp64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &bls,
3973 ocs_log_err(hw->os, "XMIT_BLS_RSP64 WQE SID error\n");
3979 if ( (!send) || sli_xmit_bcast64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, send, len,
3983 ocs_log_err(hw->os, "XMIT_BCAST64 WQE error\n");
3988 ocs_log_err(hw->os, "bad SRRS type %#x\n", type);
3994 io->wq = ocs_hw_queue_next_wq(hw, io);
4004 ocs_hw_add_io_timed_wqe(hw, io);
4011 ocs_log_err(hw->os, "sli_queue_write failed: %d\n", rc);
4013 ocs_hw_remove_io_timed_wqe(hw, io);
4030 * This routine assumes all IOs use the SGL associated with the HW IO. Prior to
4033 * @param hw Hardware context.
4035 * @param io Previously-allocated HW IO object.
4049 ocs_hw_io_send(ocs_hw_t *hw, ocs_hw_io_type_e type, ocs_hw_io_t *io,
4060 if (!hw || !io || !rnode || !iparam) {
4061 ocs_log_err(NULL, "bad parm hw=%p io=%p iparam=%p rnode=%p\n",
4062 hw, io, iparam, rnode);
4066 if (hw->state != OCS_HW_STATE_ACTIVE) {
4067 ocs_log_err(hw->os, "cannot send IO, HW state=%d\n", hw->state);
4073 if (hw->workaround.use_unregistered_rpi && (rpi == UINT32_MAX)) {
4074 rpi = hw->workaround.unregistered_rid;
4075 ocs_log_test(hw->os, "using unregistered RPI: %d\n", rpi);
4097 if (hw->workaround.use_dif_quarantine && (hw->config.dif_mode == OCS_HW_DIF_MODE_SEPARATE) &&
4102 ocs_hw_io_ini_sge(hw, io, iparam->fcp_ini.cmnd, iparam->fcp_ini.cmnd_size,
4105 if (sli_fcp_iread64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &io->def_sgl, io->first_data_sge, len,
4109 ocs_log_err(hw->os, "IREAD WQE error\n");
4116 ocs_hw_io_ini_sge(hw, io, iparam->fcp_ini.cmnd, iparam->fcp_ini.cmnd_size,
4119 if (sli_fcp_iwrite64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &io->def_sgl, io->first_data_sge,
4125 ocs_log_err(hw->os, "IWRITE WQE error\n");
4132 ocs_hw_io_ini_sge(hw, io, iparam->fcp_ini.cmnd, iparam->fcp_ini.cmnd_size,
4135 if (sli_fcp_icmnd64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &io->def_sgl,
4138 ocs_log_err(hw->os, "ICMND WQE error\n");
4165 if (hw->workaround.use_dif_quarantine && (hw->config.dif_mode == OCS_HW_DIF_MODE_SEPARATE) &&
4175 * are on hw->sec_hio_wait_list. If this secondary XRI is not for the first
4178 if (hw->workaround.use_dif_sec_xri && (iparam->fcp_tgt.dif_oper != OCS_HW_DIF_OPER_DISABLED)) {
4187 io->sec_hio = ocs_hw_io_alloc(hw);
4195 ocs_lock(&hw->io_lock);
4196 ocs_list_remove(&hw->io_inuse, io);
4197 ocs_list_add_tail(&hw->sec_hio_wait_list, io);
4199 hw->sec_hio_wait_count++;
4200 ocs_unlock(&hw->io_lock);
4216 if (sli_fcp_cont_treceive64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &io->def_sgl, io->first_data_sge,
4223 ocs_log_err(hw->os, "TRECEIVE WQE error\n");
4227 if (sli_fcp_treceive64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &io->def_sgl, io->first_data_sge,
4234 ocs_log_err(hw->os, "TRECEIVE WQE error\n");
4250 if (sli_fcp_tsend64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &io->def_sgl, io->first_data_sge,
4259 ocs_log_err(hw->os, "TSEND WQE error\n");
4261 } else if (hw->workaround.retain_tsend_io_length) {
4276 if (hw->auto_xfer_rdy_enabled && io->is_port_owned) {
4277 if ((io->auto_xfer_rdy_dnrx = ocs_hw_rqpair_auto_xfer_rdy_buffer_post(hw, io, 1))) {
4283 if (sli_fcp_trsp64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size,
4293 ocs_log_err(hw->os, "TRSP WQE error\n");
4300 ocs_log_err(hw->os, "unsupported IO type %#x\n", type);
4306 io->wq = ocs_hw_queue_next_wq(hw, io);
4316 OCS_STAT(hw->tcmd_wq_submit[io->wq->instance]++);
4318 ocs_hw_add_io_timed_wqe(hw, io);
4325 ocs_log_err(hw->os, "sli_queue_write failed: %d\n", rc);
4327 ocs_hw_remove_io_timed_wqe(hw, io);
4340 * @param hw Pointer to HW object.
4352 ocs_hw_send_frame(ocs_hw_t *hw, fc_header_le_t *hdr, uint8_t sof, uint8_t eof, ocs_dma_t *payload,
4363 ctx->hw = hw;
4366 ctx->wqcb = ocs_hw_reqtag_alloc(hw, callback, arg);
4368 ocs_log_err(hw->os, "can't allocate request tag\n");
4373 wq = ocs_varray_iter_next(hw->wq_class_array[1]);
4375 wq = hw->hw_wq[0];
4382 rc = sli_send_frame_wqe(&hw->sli, wqe->wqebuf, hw->sli.config.wqe_size, sof, eof, (uint32_t*) hdr, payload,
4385 ocs_log_err(hw->os, "sli_send_frame_wqe failed: %d\n", rc);
4392 ocs_log_err(hw->os, "hw_wq_write failed: %d\n", rc);
4402 ocs_hw_io_register_sgl(ocs_hw_t *hw, ocs_hw_io_t *io, ocs_dma_t *sgl, uint32_t sgl_count)
4404 if (sli_get_sgl_preregister(&hw->sli)) {
4405 ocs_log_err(hw->os, "can't use temporary SGL with pre-registered SGLs\n");
4416 ocs_hw_io_restore_sgl(ocs_hw_t *hw, ocs_hw_io_t *io)
4431 ocs_hw_io_free(hw, io->ovfl_io);
4445 * @param hw Hardware context.
4446 * @param io Previously-allocated HW IO object.
4452 ocs_hw_io_init_sges(ocs_hw_t *hw, ocs_hw_io_t *io, ocs_hw_io_type_e type)
4458 if (!hw || !io) {
4459 ocs_log_err(hw ? hw->os : NULL, "bad parameter hw=%p io=%p\n",
4460 hw, io);
4531 ocs_log_err(hw->os, "unsupported IO type %#x\n", type);
4557 * @param hw Hardware context.
4558 * @param io Previously-allocated HW IO object.
4564 ocs_hw_io_add_seed_sge(ocs_hw_t *hw, ocs_hw_io_t *io, ocs_hw_dif_info_t *dif_info)
4574 if (!hw || !io) {
4575 ocs_log_err(hw ? hw->os : NULL, "bad parameter hw=%p io=%p dif_info=%p\n",
4576 hw, io, dif_info);
4590 if (SLI4_IF_TYPE_LANCER_FC_ETH != hw->sli.if_type) {
4597 (SLI4_IF_TYPE_LANCER_FC_ETH != hw->sli.if_type) && dif_info->dif_separate) {
4647 ocs_log_err(hw->os, "unsupported DIF operation %#x\n",
4666 ocs_hw_io_overflow_sgl(ocs_hw_t *hw, ocs_hw_io_t *io)
4681 if (sli_get_sgl_preregister(&hw->sli) &&
4684 ((SLI4_IF_TYPE_BE3_SKH_PF == sli_get_if_type(&hw->sli)) ||
4685 (SLI4_IF_TYPE_BE3_SKH_VF == sli_get_if_type(&hw->sli)))) {
4686 io->ovfl_io = ocs_hw_io_alloc(hw);
4713 if ((SLI4_IF_TYPE_BE3_SKH_PF == sli_get_if_type(&hw->sli)) ||
4714 (SLI4_IF_TYPE_BE3_SKH_VF == sli_get_if_type(&hw->sli))) {
4715 sli_skh_chain_sge_build(&hw->sli,
4741 * @param hw Hardware context.
4742 * @param io Previously-allocated HW IO object.
4749 ocs_hw_io_add_sge(ocs_hw_t *hw, ocs_hw_io_t *io, uintptr_t addr, uint32_t length)
4753 if (!hw || !io || !addr || !length) {
4754 ocs_log_err(hw ? hw->os : NULL,
4755 "bad parameter hw=%p io=%p addr=%lx length=%u\n",
4756 hw, io, addr, length);
4761 if (ocs_hw_io_overflow_sgl(hw, io) != OCS_HW_RTN_SUCCESS) {
4762 ocs_log_err(hw->os, "SGL full (%d)\n", io->n_sge);
4767 if (length > sli_get_max_sge(&hw->sli)) {
4768 ocs_log_err(hw->os, "length of SGE %d bigger than allowed %d\n",
4769 length, sli_get_max_sge(&hw->sli));
4811 * @param hw Hardware context.
4812 * @param io Previously-allocated HW IO object.
4818 ocs_hw_io_add_dif_sge(ocs_hw_t *hw, ocs_hw_io_t *io, uintptr_t addr)
4822 if (!hw || !io || !addr) {
4823 ocs_log_err(hw ? hw->os : NULL,
4824 "bad parameter hw=%p io=%p addr=%lx\n",
4825 hw, io, addr);
4829 if ((io->n_sge + 1) > hw->config.n_sgl) {
4830 if (ocs_hw_io_overflow_sgl(hw, io) != OCS_HW_RTN_ERROR) {
4831 ocs_log_err(hw->os, "SGL full (%d)\n", io->n_sge);
4842 (SLI4_IF_TYPE_LANCER_FC_ETH != hw->sli.if_type)) {
4868 * @param hw Hardware context.
4878 ocs_hw_io_abort(ocs_hw_t *hw, ocs_hw_io_t *io_to_abort, uint32_t send_abts, void *cb, void *arg)
4885 if (!hw || !io_to_abort) {
4886 ocs_log_err(hw ? hw->os : NULL,
4887 "bad parameter hw=%p io=%p\n",
4888 hw, io_to_abort);
4892 if (hw->state != OCS_HW_STATE_ACTIVE) {
4893 ocs_log_err(hw->os, "cannot send IO abort, HW state=%d\n",
4894 hw->state);
4901 ocs_log_test(hw ? hw->os : NULL,
4910 ocs_log_test(hw->os, "io_to_abort xri=0x%x not active on WQ\n",
4917 ocs_lock(&hw->io_abort_lock);
4919 ocs_unlock(&hw->io_abort_lock);
4921 ocs_log_debug(hw ? hw->os : NULL,
4932 ocs_unlock(&hw->io_abort_lock);
4955 wqcb = ocs_hw_reqtag_alloc(hw, ocs_hw_wq_process_abort, io_to_abort);
4957 ocs_log_err(hw->os, "can't allocate request tag\n");
4979 if (sli_abort_wqe(&hw->sli, io_to_abort->wqe.wqebuf, hw->sli.config.wqe_size, atype, send_abts, id, mask,
4981 ocs_log_err(hw->os, "ABORT WQE error\n");
4983 ocs_hw_reqtag_free(hw, wqcb);
4989 io_to_abort->wq = ocs_hw_queue_next_wq(hw, io_to_abort);
5005 ocs_lock(&hw->io_abort_lock);
5007 ocs_unlock(&hw->io_abort_lock);
5017 * @param hw Hardware context.
5018 * @param io HW IO object.
5023 ocs_hw_io_get_xid(ocs_hw_t *hw, ocs_hw_io_t *io)
5025 if (!hw || !io) {
5026 ocs_log_err(hw ? hw->os : NULL,
5027 "bad parameter hw=%p io=%p\n", hw, io);
5078 * @param hw Hardware context.
5092 ocs_hw_firmware_write(ocs_hw_t *hw, ocs_dma_t *dma, uint32_t size, uint32_t offset, int last, ocs_hw_fw_cb_t cb, void *arg)
5094 if (hw->sli.if_type == SLI4_IF_TYPE_LANCER_FC_ETH) {
5095 return ocs_hw_firmware_write_lancer(hw, dma, size, offset, last, cb, arg);
5111 * @param hw Hardware context.
5124 ocs_hw_firmware_write_lancer(ocs_hw_t *hw, ocs_dma_t *dma, uint32_t size, uint32_t offset, int last, ocs_hw_fw_cb_t cb, void *arg)
5131 if (SLI4_IF_TYPE_LANCER_FC_ETH != sli_get_if_type(&hw->sli)) {
5132 ocs_log_test(hw->os, "Function only supported for I/F type 2\n");
5136 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
5138 ocs_log_err(hw->os, "failed to malloc mbox\n");
5142 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_fw_write_cb_arg_t), OCS_M_NOWAIT);
5144 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
5145 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5152 if (sli_cmd_common_write_object(&hw->sli, mbxdata, SLI4_BMBX_SIZE, noc, last,
5154 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_cb_fw_write, cb_arg);
5158 ocs_log_test(hw->os, "COMMON_WRITE_OBJECT failed\n");
5159 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5160 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_fw_write_cb_arg_t));
5175 * @param hw Hardware context.
5184 ocs_hw_cb_fw_write(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
5198 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
5208 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_fw_write_cb_arg_t));
5222 * @param hw Hardware context.
5232 ocs_hw_cb_sfp(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
5248 cb_arg->cb(hw->os, status, bytes_written, mbox_rsp->page_data, cb_arg->arg);
5251 ocs_dma_free(hw->os, &cb_arg->payload);
5252 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_sfp_cb_arg_t));
5255 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
5263 * @param hw Hardware context.
5271 ocs_hw_get_sfp(ocs_hw_t *hw, uint16_t page, ocs_hw_sfp_cb_t cb, void *arg)
5278 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
5280 ocs_log_err(hw->os, "failed to malloc mbox\n");
5285 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_sfp_cb_arg_t), OCS_M_NOWAIT);
5287 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
5288 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5296 if (ocs_dma_alloc(hw->os, &cb_arg->payload, sizeof(sli4_res_common_read_transceiver_data_t),
5298 ocs_log_err(hw->os, "Failed to allocate DMA buffer\n");
5299 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_sfp_cb_arg_t));
5300 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5304 /* Send the HW command */
5305 if (sli_cmd_common_read_transceiver_data(&hw->sli, mbxdata, SLI4_BMBX_SIZE, page,
5307 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_cb_sfp, cb_arg);
5311 ocs_log_test(hw->os, "READ_TRANSCEIVER_DATA failed with status %d\n",
5313 ocs_dma_free(hw->os, &cb_arg->payload);
5314 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_sfp_cb_arg_t));
5315 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5324 * @param hw Hardware context.
5331 ocs_hw_get_temperature(ocs_hw_t *hw, ocs_hw_temp_cb_t cb, void *arg)
5337 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
5339 ocs_log_err(hw->os, "failed to malloc mbox");
5343 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_temp_cb_arg_t), OCS_M_NOWAIT);
5345 ocs_log_err(hw->os, "failed to malloc cb_arg");
5346 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5353 if (sli_cmd_dump_type4(&hw->sli, mbxdata, SLI4_BMBX_SIZE,
5355 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_cb_temp, cb_arg);
5359 ocs_log_test(hw->os, "DUMP_TYPE4 failed\n");
5360 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5361 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_temp_cb_arg_t));
5374 * @param hw Hardware context.
5383 ocs_hw_cb_temp(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
5410 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_temp_cb_arg_t));
5412 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
5420 * @param hw Hardware context.
5430 ocs_hw_get_link_stats(ocs_hw_t *hw,
5441 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
5443 ocs_log_err(hw->os, "failed to malloc mbox");
5447 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_link_stat_cb_arg_t), OCS_M_NOWAIT);
5449 ocs_log_err(hw->os, "failed to malloc cb_arg");
5450 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5457 if (sli_cmd_read_link_stats(&hw->sli, mbxdata, SLI4_BMBX_SIZE,
5461 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_cb_link_stat, cb_arg);
5465 ocs_log_test(hw->os, "READ_LINK_STATS failed\n");
5466 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5467 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_link_stat_cb_arg_t));
5480 * @param hw Hardware context.
5489 ocs_hw_cb_link_stat(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
5553 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_link_stat_cb_arg_t));
5555 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
5563 * @param hw Hardware context.
5571 ocs_hw_get_host_stats(ocs_hw_t *hw, uint8_t cc, ocs_hw_host_stat_cb_t cb, void *arg)
5577 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO);
5579 ocs_log_err(hw->os, "failed to malloc mbox");
5583 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_host_stat_cb_arg_t), 0);
5585 ocs_log_err(hw->os, "failed to malloc cb_arg");
5586 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5593 /* Send the HW command to get the host stats */
5594 if (sli_cmd_read_status(&hw->sli, mbxdata, SLI4_BMBX_SIZE, cc)) {
5595 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_cb_host_stat, cb_arg);
5599 ocs_log_test(hw->os, "READ_HOST_STATS failed\n");
5600 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5601 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_host_stat_cb_arg_t));
5615 * @param hw Hardware context.
5625 ocs_hw_cb_host_stat(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
5662 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_host_stat_cb_arg_t));
5664 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
5670 * @brief HW link configuration enum to the CLP string value mapping.
5683 * @brief Mapping from the HW linkcfg enum to the CLP command value
5696 * @brief HW link configuration enum to Skyhawk link config ID mapping.
5708 * @brief Mapping from the HW linkcfg enum to the Skyhawk link config IDs
5716 * @brief Helper function for getting the HW linkcfg enum from the CLP
5721 * @return Returns the HW linkcfg enum corresponding to clp_str.
5736 * @brief Helper function for getting the CLP string value from the HW
5739 * @param linkcfg HW linkcfg enum.
5757 * @brief Helper function for getting a Skyhawk link config ID from the HW
5760 * @param linkcfg HW linkcfg enum.
5778 * @brief Helper function for getting the HW linkcfg enum from a
5783 * @return Returns the HW linkcfg enum corresponding to config_id.
5813 * @param hw Hardware context.
5823 ocs_hw_set_linkcfg(ocs_hw_t *hw, ocs_hw_linkcfg_e value, uint32_t opts, ocs_hw_port_control_cb_t cb, void *arg)
5825 if (!sli_link_is_configurable(&hw->sli)) {
5826 ocs_log_debug(hw->os, "Function not supported\n");
5830 if (SLI4_IF_TYPE_LANCER_FC_ETH == sli_get_if_type(&hw->sli)) {
5831 return ocs_hw_set_linkcfg_lancer(hw, value, opts, cb, arg);
5832 } else if ((SLI4_IF_TYPE_BE3_SKH_PF == sli_get_if_type(&hw->sli)) ||
5833 (SLI4_IF_TYPE_BE3_SKH_VF == sli_get_if_type(&hw->sli))) {
5834 return ocs_hw_set_linkcfg_skyhawk(hw, value, opts, cb, arg);
5836 ocs_log_test(hw->os, "Function not supported for this IF_TYPE\n");
5844 * @param hw Hardware context.
5854 ocs_hw_set_linkcfg_lancer(ocs_hw_t *hw, ocs_hw_linkcfg_e value, uint32_t opts, ocs_hw_port_control_cb_t cb, void *arg)
5865 cb_arg = ocs_malloc(hw->os, sizeof(*cb_arg), OCS_M_NOWAIT);
5867 ocs_log_err(hw->os, "failed to malloc cb_arg");
5873 if (ocs_dma_alloc(hw->os, &cb_arg->dma_cmd, ocs_strlen(cmd)+1, 4096)) {
5874 ocs_log_err(hw->os, "malloc failed\n");
5875 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
5882 if (ocs_dma_alloc(hw->os, &cb_arg->dma_resp, OCS_HW_DMTF_CLP_RSP_MAX, 4096)) {
5883 ocs_log_err(hw->os, "malloc failed\n");
5884 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
5885 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
5892 rc = ocs_hw_exec_dmtf_clp_cmd(hw, &cb_arg->dma_cmd, &cb_arg->dma_resp,
5900 ocs_log_test(hw->os, "CLP cmd=\"%s\" failed\n",
5903 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
5904 ocs_dma_free(hw->os, &cb_arg->dma_resp);
5905 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
5913 * @param hw Hardware context.
5921 ocs_hw_set_active_link_config_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
5926 ocs_log_test(hw->os, "SET_RECONFIG_LINK_ID failed, status=%d\n", status);
5936 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
5943 * @param hw Hardware context.
5953 ocs_hw_set_linkcfg_skyhawk(ocs_hw_t *hw, ocs_hw_linkcfg_e value, uint32_t opts, ocs_hw_port_control_cb_t cb, void *arg)
5963 ocs_log_test(hw->os, "Link config %d not supported by Skyhawk\n", value);
5968 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
5970 ocs_log_err(hw->os, "failed to malloc mbox\n");
5975 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_linkcfg_cb_arg_t), OCS_M_NOWAIT);
5977 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
5978 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5985 if (sli_cmd_common_set_reconfig_link_id(&hw->sli, mbxdata, SLI4_BMBX_SIZE, NULL, 0, config_id)) {
5986 rc = ocs_hw_command(hw, mbxdata, opts, ocs_hw_set_active_link_config_cb, cb_arg);
5990 ocs_log_err(hw->os, "SET_RECONFIG_LINK_ID failed\n");
5991 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5992 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_linkcfg_cb_arg_t));
5995 ocs_hw_set_active_link_config_cb(hw, 0, mbxdata, cb_arg);
5996 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5997 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_linkcfg_cb_arg_t));
6000 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6009 * @param hw Hardware context.
6017 ocs_hw_get_linkcfg(ocs_hw_t *hw, uint32_t opts, ocs_hw_port_control_cb_t cb, void *arg)
6019 if (!sli_link_is_configurable(&hw->sli)) {
6020 ocs_log_debug(hw->os, "Function not supported\n");
6024 if ((SLI4_IF_TYPE_LANCER_FC_ETH == sli_get_if_type(&hw->sli)) ||
6025 (SLI4_IF_TYPE_LANCER_G7 == sli_get_if_type(&hw->sli))){
6026 return ocs_hw_get_linkcfg_lancer(hw, opts, cb, arg);
6027 } else if ((SLI4_IF_TYPE_BE3_SKH_PF == sli_get_if_type(&hw->sli)) ||
6028 (SLI4_IF_TYPE_BE3_SKH_VF == sli_get_if_type(&hw->sli))) {
6029 return ocs_hw_get_linkcfg_skyhawk(hw, opts, cb, arg);
6031 ocs_log_test(hw->os, "Function not supported for this IF_TYPE\n");
6039 * @param hw Hardware context.
6047 ocs_hw_get_linkcfg_lancer(ocs_hw_t *hw, uint32_t opts, ocs_hw_port_control_cb_t cb, void *arg)
6054 cb_arg = ocs_malloc(hw->os, sizeof(*cb_arg), OCS_M_NOWAIT);
6056 ocs_log_err(hw->os, "failed to malloc cb_arg");
6063 if (ocs_dma_alloc(hw->os, &cb_arg->dma_cmd, ocs_strlen(cmd)+1, 4096)) {
6064 ocs_log_err(hw->os, "malloc failed\n");
6065 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6074 if (ocs_dma_alloc(hw->os, &cb_arg->dma_resp, OCS_HW_DMTF_CLP_RSP_MAX, 4096)) {
6075 ocs_log_err(hw->os, "malloc failed\n");
6076 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
6077 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6084 rc = ocs_hw_exec_dmtf_clp_cmd(hw, &cb_arg->dma_cmd, &cb_arg->dma_resp,
6092 ocs_log_test(hw->os, "CLP cmd=\"%s\" failed\n",
6095 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
6096 ocs_dma_free(hw->os, &cb_arg->dma_resp);
6097 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6105 * @param hw Hardware context.
6113 ocs_hw_get_active_link_config_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
6120 ocs_log_test(hw->os, "GET_RECONFIG_LINK_INFO failed, status=%d\n", status);
6133 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
6134 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6141 * @param hw Hardware context.
6149 ocs_hw_get_linkcfg_skyhawk(ocs_hw_t *hw, uint32_t opts, ocs_hw_port_control_cb_t cb, void *arg)
6156 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
6158 ocs_log_err(hw->os, "failed to malloc mbox\n");
6163 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_linkcfg_cb_arg_t), OCS_M_NOWAIT);
6165 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
6166 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6175 if (ocs_dma_alloc(hw->os, &cb_arg->dma_cmd, sizeof(sli4_res_common_get_reconfig_link_info_t), 4)) {
6176 ocs_log_err(hw->os, "Failed to allocate DMA buffer\n");
6177 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6178 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_linkcfg_cb_arg_t));
6182 if (sli_cmd_common_get_reconfig_link_info(&hw->sli, mbxdata, SLI4_BMBX_SIZE, &cb_arg->dma_cmd)) {
6183 rc = ocs_hw_command(hw, mbxdata, opts, ocs_hw_get_active_link_config_cb, cb_arg);
6187 ocs_log_err(hw->os, "GET_RECONFIG_LINK_INFO failed\n");
6188 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6189 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
6190 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_linkcfg_cb_arg_t));
6193 ocs_hw_get_active_link_config_cb(hw, 0, mbxdata, cb_arg);
6194 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6195 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
6196 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_linkcfg_cb_arg_t));
6199 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6208 * @param hw Hardware context.
6213 ocs_hw_set_dif_seed(ocs_hw_t *hw)
6220 seed_param.seed = hw->config.dif_seed;
6223 if (sli_cmd_common_set_features(&hw->sli, buf, SLI4_BMBX_SIZE,
6227 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
6229 ocs_log_err(hw->os, "ocs_hw_command returns %d\n", rc);
6231 ocs_log_debug(hw->os, "DIF seed set to 0x%x\n",
6232 hw->config.dif_seed);
6235 ocs_log_err(hw->os, "sli_cmd_common_set_features failed\n");
6244 * @param hw Hardware context.
6249 ocs_hw_set_dif_mode(ocs_hw_t *hw)
6256 mode_param.tmm = (hw->config.dif_mode == OCS_HW_DIF_MODE_INLINE ? 0 : 1);
6259 if (sli_cmd_common_set_features(&hw->sli, buf, SLI4_BMBX_SIZE,
6263 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
6265 ocs_log_err(hw->os, "ocs_hw_command returns %d\n", rc);
6267 ocs_log_test(hw->os, "DIF mode set to %s\n",
6268 (hw->config.dif_mode == OCS_HW_DIF_MODE_INLINE ? "inline" : "separate"));
6271 ocs_log_err(hw->os, "sli_cmd_common_set_features failed\n");
6280 ocs_hw_t *hw = (ocs_hw_t *)arg;
6282 ocs_hw_config_watchdog_timer(hw);
6287 ocs_hw_cb_cfg_watchdog(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
6289 uint16_t timeout = hw->watchdog_timeout;
6292 ocs_log_err(hw->os, "config watchdog timer failed, rc = %d\n", status);
6296 ocs_setup_timer(hw->os, &hw->watchdog_timer, ocs_hw_watchdog_timer_cb, hw, (timeout*1000 - 500) );
6298 ocs_del_timer(&hw->watchdog_timer);
6302 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
6309 * @param hw Hardware context.
6315 ocs_hw_config_watchdog_timer(ocs_hw_t *hw)
6318 uint8_t *buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
6321 ocs_log_err(hw->os, "no buffer for command\n");
6325 sli4_cmd_lowlevel_set_watchdog(&hw->sli, buf, SLI4_BMBX_SIZE, hw->watchdog_timeout);
6326 rc = ocs_hw_command(hw, buf, OCS_CMD_NOWAIT, ocs_hw_cb_cfg_watchdog, NULL);
6328 ocs_free(hw->os, buf, SLI4_BMBX_SIZE);
6329 ocs_log_err(hw->os, "config watchdog timer failed, rc = %d\n", rc);
6337 * @param hw Hardware context.
6343 ocs_hw_config_auto_xfer_rdy_t10pi(ocs_hw_t *hw, uint8_t *buf)
6349 param.rtc = (hw->config.auto_xfer_rdy_ref_tag_is_lba ? 0 : 1);
6350 param.atv = (hw->config.auto_xfer_rdy_app_tag_valid ? 1 : 0);
6351 param.tmm = ((hw->config.dif_mode == OCS_HW_DIF_MODE_INLINE) ? 0 : 1);
6352 param.app_tag = hw->config.auto_xfer_rdy_app_tag_value;
6353 param.blk_size = hw->config.auto_xfer_rdy_blk_size_chip;
6355 switch (hw->config.auto_xfer_rdy_p_type) {
6363 ocs_log_err(hw->os, "unsupported p_type %d\n",
6364 hw->config.auto_xfer_rdy_p_type);
6369 sli_cmd_common_set_features(&hw->sli, buf, SLI4_BMBX_SIZE,
6374 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
6376 ocs_log_err(hw->os, "ocs_hw_command returns %d\n", rc);
6378 ocs_log_test(hw->os, "Auto XFER RDY T10 PI configured rtc:%d atv:%d p_type:%d app_tag:%x blk_size:%d\n",
6389 * @param hw Hardware context.
6398 ocs_hw_config_sli_port_health_check(ocs_hw_t *hw, uint8_t query, uint8_t enable)
6409 sli_cmd_common_set_features(&hw->sli, buf, SLI4_BMBX_SIZE,
6414 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
6416 ocs_log_err(hw->os, "ocs_hw_command returns %d\n", rc);
6418 ocs_log_test(hw->os, "SLI Port Health Check is enabled \n");
6427 * @param hw Hardware context.
6433 ocs_hw_config_set_fdt_xfer_hint(ocs_hw_t *hw, uint32_t fdt_xfer_hint)
6442 sli_cmd_common_set_features(&hw->sli, buf, SLI4_BMBX_SIZE,
6447 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
6449 ocs_log_warn(hw->os, "set FDT hint %d failed: %d\n", fdt_xfer_hint, rc);
6451 ocs_log_debug(hw->os, "Set FTD transfer hint to %d\n", param.fdt_xfer_hint);
6460 * @param hw Hardware context.
6468 ocs_hw_linkcfg_dmtf_clp_cb(ocs_hw_t *hw, int32_t status, uint32_t result_len, void *arg)
6476 ocs_log_test(hw->os, "CLP cmd failed, status=%d\n", status);
6479 rval = ocs_hw_clp_resp_get_value(hw, "retdata", retdata_str,
6485 ocs_log_err(hw->os, "failed to get retdata %d\n", result_len);
6487 /* translate string into hw enum */
6499 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
6500 ocs_dma_free(hw->os, &cb_arg->dma_resp);
6501 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6511 * @param hw Hardware context.
6518 ocs_hw_set_dump_location(ocs_hw_t *hw, uint32_t num_buffers, ocs_dma_t *dump_buffers, uint8_t fdb)
6528 if (hw->workaround.disable_dump_loc) {
6529 ocs_log_test(hw->os, "FW version is too old for this feature\n");
6534 ocs_get_bus_dev_func(hw->os, &bus, &dev, &func);
6536 ocs_log_test(hw->os, "function only valid for pci function 0, %d passed\n",
6550 if (hw->dump_sges.size < sge_size) {
6551 ocs_dma_free(hw->os, &hw->dump_sges);
6552 if (ocs_dma_alloc(hw->os, &hw->dump_sges, sge_size, OCS_MIN_DMA_ALIGNMENT)) {
6553 ocs_log_err(hw->os, "SGE DMA allocation failed\n");
6558 ocs_memset(hw->dump_sges.virt, 0, hw->dump_sges.size);
6559 hw->dump_sges.len = sge_size;
6560 sge = hw->dump_sges.virt;
6567 rc = sli_cmd_common_set_dump_location(&hw->sli, (void *)buf,
6569 &hw->dump_sges, fdb);
6572 rc = sli_cmd_common_set_dump_location(&hw->sli, (void *)buf,
6578 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL,
6581 ocs_log_err(hw->os, "ocs_hw_command returns %d\n",
6585 ocs_log_err(hw->os,
6602 * @param hw Hardware context.
6608 ocs_hw_set_eth_license(ocs_hw_t *hw, uint32_t license)
6616 if (SLI4_IF_TYPE_LANCER_FC_ETH != sli_get_if_type(&hw->sli)) {
6617 ocs_log_test(hw->os, "Function only supported for I/F type 2\n");
6623 if (ocs_dma_alloc(hw->os, &dma_cmd, ocs_strlen(cmd)+1, 4096)) {
6624 ocs_log_err(hw->os, "malloc failed\n");
6631 if (ocs_dma_alloc(hw->os, &dma_resp, OCS_HW_DMTF_CLP_RSP_MAX, 4096)) {
6632 ocs_log_err(hw->os, "malloc failed\n");
6633 ocs_dma_free(hw->os, &dma_cmd);
6638 if (ocs_hw_exec_dmtf_clp_cmd(hw, &dma_cmd, &dma_resp, OCS_CMD_POLL, NULL, NULL)) {
6639 ocs_log_err(hw->os, "CLP cmd=\"%s\" failed\n", (char *)dma_cmd.virt);
6643 ocs_dma_free(hw->os, &dma_cmd);
6644 ocs_dma_free(hw->os, &dma_resp);
6662 * @param hw Hardware context.
6673 ocs_hw_exec_dmtf_clp_cmd(ocs_hw_t *hw, ocs_dma_t *dma_cmd, ocs_dma_t *dma_resp, uint32_t opts, ocs_hw_dmtf_clp_cb_t cb, void *arg)
6680 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
6682 ocs_log_err(hw->os, "failed to malloc mbox\n");
6687 cb_arg = ocs_malloc(hw->os, sizeof(*cb_arg), OCS_M_NOWAIT);
6689 ocs_log_err(hw->os, "failed to malloc cb_arg");
6690 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6699 /* Send the HW command */
6700 if (sli_cmd_dmtf_exec_clp_cmd(&hw->sli, mbxdata, SLI4_BMBX_SIZE,
6702 rc = ocs_hw_command(hw, mbxdata, opts, ocs_hw_dmtf_clp_cb, cb_arg);
6707 ocs_memcpy(mbxdata, hw->sli.bmbx.virt, SLI4_BMBX_SIZE);
6708 ocs_hw_dmtf_clp_cb(hw, 0, mbxdata, cb_arg);
6717 ocs_log_test(hw->os, "ocs_hw_command failed\n");
6719 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6720 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6723 ocs_log_test(hw->os, "sli_cmd_dmtf_exec_clp_cmd failed\n");
6725 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6726 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6735 * @param hw Hardware context.
6744 ocs_hw_dmtf_clp_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
6758 ocs_log_debug(hw->os, "status=x%x/x%x/x%x addl=x%x clp=x%x detail=x%x\n",
6781 ocs_log_test(hw->os, "Invalid response length: resp_len=%zu result len=%d\n",
6788 stat_len = ocs_hw_clp_resp_get_value(hw, "status", stat_str,
6794 ocs_log_test(hw->os, "failed to get status %d\n", stat_len);
6800 ocs_log_test(hw->os, "CLP status indicates failure=%s\n", stat_str);
6810 cb_arg->cb(hw, cb_status, result_len, cb_arg->arg);
6814 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6815 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
6823 * @param hw Hardware context.
6835 ocs_hw_clp_resp_get_value(ocs_hw_t *hw, const char *keyword, char *value, uint32_t value_len, const char *resp, uint32_t resp_len)
6843 ocs_log_test(hw->os, "could not find keyword=%s in CLP response\n",
6851 ocs_log_test(hw->os, "could not find \'=\' in CLP response for keyword=%s\n",
6860 ocs_log_test(hw->os, "could not find \\r\\n for keyword=%s in CLP response\n",
6867 ocs_log_test(hw->os, "value len=%d not large enough for actual=%ld\n",
6885 * @param hw Hardware context.
6892 ocs_hw_raise_ue(ocs_hw_t *hw, uint8_t dump)
6896 if (sli_raise_ue(&hw->sli, dump) != 0) {
6899 if (hw->state != OCS_HW_STATE_UNINITIALIZED) {
6900 hw->state = OCS_HW_STATE_QUEUES_ALLOCATED;
6915 * @param hw Hardware context.
6924 ocs_hw_cb_dump_get(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
6943 ocs_free(hw->os, cb_arg->mbox_cmd, SLI4_BMBX_SIZE);
6944 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_dump_get_cb_arg_t));
6959 * @param hw Hardware context.
6971 ocs_hw_dump_get(ocs_hw_t *hw, ocs_dma_t *dma, uint32_t size, uint32_t offset, ocs_hw_dump_get_cb_t cb, void *arg)
6976 uint32_t opts = (hw->state == OCS_HW_STATE_ACTIVE ? OCS_CMD_NOWAIT : OCS_CMD_POLL);
6978 if (SLI4_IF_TYPE_LANCER_FC_ETH != sli_get_if_type(&hw->sli)) {
6979 ocs_log_test(hw->os, "Function only supported for I/F type 2\n");
6983 if (1 != sli_dump_is_present(&hw->sli)) {
6984 ocs_log_test(hw->os, "No dump is present\n");
6988 if (1 == sli_reset_required(&hw->sli)) {
6989 ocs_log_test(hw->os, "device reset required\n");
6993 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
6995 ocs_log_err(hw->os, "failed to malloc mbox\n");
6999 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_dump_get_cb_arg_t), OCS_M_NOWAIT);
7001 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7002 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7010 if (sli_cmd_common_read_object(&hw->sli, mbxdata, SLI4_BMBX_SIZE,
7012 rc = ocs_hw_command(hw, mbxdata, opts, ocs_hw_cb_dump_get, cb_arg);
7014 ocs_memcpy(mbxdata, hw->sli.bmbx.virt, SLI4_BMBX_SIZE);
7015 rc = ocs_hw_cb_dump_get(hw, 0, mbxdata, cb_arg);
7020 ocs_log_test(hw->os, "COMMON_READ_OBJECT failed\n");
7021 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7022 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_dump_get_cb_arg_t));
7035 * @param hw Hardware context.
7044 ocs_hw_cb_dump_clear(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
7057 ocs_free(hw->os, cb_arg->mbox_cmd, SLI4_BMBX_SIZE);
7058 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_dump_clear_cb_arg_t));
7073 * @param hw Hardware context.
7082 ocs_hw_dump_clear(ocs_hw_t *hw, ocs_hw_dump_clear_cb_t cb, void *arg)
7087 uint32_t opts = (hw->state == OCS_HW_STATE_ACTIVE ? OCS_CMD_NOWAIT : OCS_CMD_POLL);
7089 if (SLI4_IF_TYPE_LANCER_FC_ETH != sli_get_if_type(&hw->sli)) {
7090 ocs_log_test(hw->os, "Function only supported for I/F type 2\n");
7094 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7096 ocs_log_err(hw->os, "failed to malloc mbox\n");
7100 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_dump_clear_cb_arg_t), OCS_M_NOWAIT);
7102 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7103 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7111 if (sli_cmd_common_delete_object(&hw->sli, mbxdata, SLI4_BMBX_SIZE,
7113 rc = ocs_hw_command(hw, mbxdata, opts, ocs_hw_cb_dump_clear, cb_arg);
7115 ocs_memcpy(mbxdata, hw->sli.bmbx.virt, SLI4_BMBX_SIZE);
7116 rc = ocs_hw_cb_dump_clear(hw, 0, mbxdata, cb_arg);
7121 ocs_log_test(hw->os, "COMMON_DELETE_OBJECT failed\n");
7122 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7123 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_dump_clear_cb_arg_t));
7140 * @param hw Hardware context.
7148 ocs_hw_get_port_protocol_cb(ocs_hw_t *hw, int32_t status,
7192 ocs_dma_free(hw->os, &cb_arg->payload);
7193 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_port_protocol_cb_arg_t));
7194 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
7207 * @param hw Hardware context.
7220 ocs_hw_get_port_protocol(ocs_hw_t *hw, uint32_t pci_func,
7228 if (sli_get_if_type(&hw->sli) != SLI4_IF_TYPE_BE3_SKH_PF) {
7233 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7235 ocs_log_err(hw->os, "failed to malloc mbox\n");
7240 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_get_port_protocol_cb_arg_t), OCS_M_NOWAIT);
7242 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7243 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7252 if (ocs_dma_alloc(hw->os, &cb_arg->payload, 4096, 4)) {
7253 ocs_log_err(hw->os, "Failed to allocate DMA buffer\n");
7254 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7255 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_port_protocol_cb_arg_t));
7259 if (sli_cmd_common_get_profile_config(&hw->sli, mbxdata, SLI4_BMBX_SIZE, &cb_arg->payload)) {
7260 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_get_port_protocol_cb, cb_arg);
7264 ocs_log_test(hw->os, "GET_PROFILE_CONFIG failed\n");
7265 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7266 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_fw_write_cb_arg_t));
7267 ocs_dma_free(hw->os, &cb_arg->payload);
7292 * @param hw Hardware context.
7300 ocs_hw_set_port_protocol_cb2(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
7308 ocs_dma_free(hw->os, &(cb_arg->payload));
7309 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
7310 ocs_free(hw->os, arg, sizeof(ocs_hw_set_port_protocol_cb_arg_t));
7331 * @param hw Hardware context.
7339 ocs_hw_set_port_protocol_cb1(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
7373 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7375 ocs_log_err(hw->os, "failed to malloc mbox\n");
7380 new_cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_set_port_protocol_cb_arg_t), OCS_M_NOWAIT);
7382 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7383 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7392 if (ocs_dma_alloc(hw->os, &new_cb_arg->payload, sizeof(sli4_req_common_set_profile_config_t) +
7395 ocs_log_err(hw->os, "Failed to allocate DMA buffer\n");
7396 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7397 ocs_free(hw->os, new_cb_arg, sizeof(ocs_hw_set_port_protocol_cb_arg_t));
7401 sli_cmd_common_set_profile_config(&hw->sli, mbxdata, SLI4_BMBX_SIZE,
7464 ocs_dma_free(hw->os, &cb_arg->payload);
7465 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
7466 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_set_port_protocol_cb_arg_t));
7469 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_set_port_protocol_cb2, new_cb_arg);
7471 ocs_log_err(hw->os, "Error posting COMMON_SET_PROFILE_CONFIG\n");
7478 ocs_dma_free(hw->os, &new_cb_arg->payload);
7479 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7480 ocs_free(hw->os, new_cb_arg, sizeof(ocs_hw_set_port_protocol_cb_arg_t));
7499 * @param hw Hardware context.
7513 ocs_hw_set_port_protocol(ocs_hw_t *hw, ocs_hw_port_protocol_e new_protocol,
7521 if (sli_get_if_type(&hw->sli) != SLI4_IF_TYPE_BE3_SKH_PF) {
7526 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7528 ocs_log_err(hw->os, "failed to malloc mbox\n");
7533 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_set_port_protocol_cb_arg_t), OCS_M_NOWAIT);
7535 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7536 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7546 if (ocs_dma_alloc(hw->os, &cb_arg->payload, 4096, 4)) {
7547 ocs_log_err(hw->os, "Failed to allocate DMA buffer\n");
7548 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7549 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_port_protocol_cb_arg_t));
7553 if (sli_cmd_common_get_profile_config(&hw->sli, mbxdata, SLI4_BMBX_SIZE, &cb_arg->payload)) {
7554 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_set_port_protocol_cb1, cb_arg);
7558 ocs_log_test(hw->os, "GET_PROFILE_CONFIG failed\n");
7559 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7560 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_fw_write_cb_arg_t));
7561 ocs_dma_free(hw->os, &cb_arg->payload);
7583 * @param hw Hardware context.
7591 ocs_hw_get_profile_list_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
7600 list = ocs_malloc(hw->os, sizeof(ocs_hw_profile_list_t), OCS_M_ZERO);
7602 ocs_log_err(hw->os, "failed to malloc list\n");
7622 ocs_free(hw->os, list, sizeof(*list));
7625 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
7626 ocs_dma_free(hw->os, &cb_arg->payload);
7627 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_profile_list_cb_arg_t));
7640 * @param hw Hardware context.
7654 ocs_hw_get_profile_list(ocs_hw_t *hw, ocs_get_profile_list_cb_t cb, void* ul_arg)
7661 if (sli_get_if_type(&hw->sli) != SLI4_IF_TYPE_BE3_SKH_PF) {
7666 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7668 ocs_log_err(hw->os, "failed to malloc mbox\n");
7673 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_get_profile_list_cb_arg_t), OCS_M_NOWAIT);
7675 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7676 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7684 if (ocs_dma_alloc(hw->os, &cb_arg->payload, sizeof(sli4_res_common_get_profile_list_t), 4)) {
7685 ocs_log_err(hw->os, "Failed to allocate DMA buffer\n");
7686 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7687 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_profile_list_cb_arg_t));
7691 if (sli_cmd_common_get_profile_list(&hw->sli, mbxdata, SLI4_BMBX_SIZE, 0, &cb_arg->payload)) {
7692 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_get_profile_list_cb, cb_arg);
7696 ocs_log_test(hw->os, "GET_PROFILE_LIST failed\n");
7697 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7698 ocs_dma_free(hw->os, &cb_arg->payload);
7699 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_profile_list_cb_arg_t));
7714 * @param hw Hardware context.
7722 ocs_hw_get_active_profile_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
7735 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
7736 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_active_profile_cb_arg_t));
7749 * @param hw Hardware context.
7763 ocs_hw_get_active_profile(ocs_hw_t *hw, ocs_get_active_profile_cb_t cb, void* ul_arg)
7770 if (sli_get_if_type(&hw->sli) != SLI4_IF_TYPE_BE3_SKH_PF) {
7775 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7777 ocs_log_err(hw->os, "failed to malloc mbox\n");
7782 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_get_active_profile_cb_arg_t), OCS_M_NOWAIT);
7784 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7785 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7792 if (sli_cmd_common_get_active_profile(&hw->sli, mbxdata, SLI4_BMBX_SIZE)) {
7793 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_get_active_profile_cb, cb_arg);
7797 ocs_log_test(hw->os, "GET_ACTIVE_PROFILE failed\n");
7798 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7799 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_active_profile_cb_arg_t));
7814 * @param hw Hardware context.
7822 ocs_hw_get_nvparms_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
7832 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
7833 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_nvparms_cb_arg_t));
7846 * @param hw Hardware context.
7860 ocs_hw_get_nvparms(ocs_hw_t *hw, ocs_get_nvparms_cb_t cb, void* ul_arg)
7867 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7869 ocs_log_err(hw->os, "failed to malloc mbox\n");
7874 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_get_nvparms_cb_arg_t), OCS_M_NOWAIT);
7876 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7877 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7884 if (sli_cmd_read_nvparms(&hw->sli, mbxdata, SLI4_BMBX_SIZE)) {
7885 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_get_nvparms_cb, cb_arg);
7889 ocs_log_test(hw->os, "READ_NVPARMS failed\n");
7890 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7891 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_nvparms_cb_arg_t));
7906 * @param hw Hardware context.
7914 ocs_hw_set_nvparms_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
7922 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
7923 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_set_nvparms_cb_arg_t));
7936 * @param hw Hardware context.
7957 ocs_hw_set_nvparms(ocs_hw_t *hw, ocs_set_nvparms_cb_t cb, uint8_t *wwpn,
7965 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7967 ocs_log_err(hw->os, "failed to malloc mbox\n");
7972 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_set_nvparms_cb_arg_t), OCS_M_NOWAIT);
7974 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7975 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7982 if (sli_cmd_write_nvparms(&hw->sli, mbxdata, SLI4_BMBX_SIZE, wwpn, wwnn, hard_alpa, preferred_d_id)) {
7983 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_set_nvparms_cb, cb_arg);
7987 ocs_log_test(hw->os, "SET_NVPARMS failed\n");
7988 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7989 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_set_nvparms_cb_arg_t));
7998 * @param hw Hardware context.
8004 ocs_hw_io_get_count(ocs_hw_t *hw, ocs_hw_io_count_type_e io_count_type)
8009 ocs_lock(&hw->io_lock);
8013 ocs_list_foreach(&hw->io_inuse, io) {
8018 ocs_list_foreach(&hw->io_free, io) {
8023 ocs_list_foreach(&hw->io_wait_free, io) {
8028 ocs_list_foreach(&hw->io_port_owned, io) {
8033 count = hw->config.n_io;
8037 ocs_unlock(&hw->io_lock);
8045 * @param hw Hardware context.
8050 ocs_hw_get_rqes_produced_count(ocs_hw_t *hw)
8056 for (i = 0; i < hw->hw_rq_count; i++) {
8057 hw_rq_t *rq = hw->hw_rq[i];
8079 * @param hw Hardware context.
8087 ocs_hw_set_active_profile_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
8095 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
8096 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_active_profile_cb_arg_t));
8109 * @param hw Hardware context.
8122 ocs_hw_set_active_profile(ocs_hw_t *hw, ocs_set_active_profile_cb_t cb, uint32_t profile_id, void* ul_arg)
8129 if (sli_get_if_type(&hw->sli) != SLI4_IF_TYPE_BE3_SKH_PF) {
8134 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
8136 ocs_log_err(hw->os, "failed to malloc mbox\n");
8141 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_set_active_profile_cb_arg_t), OCS_M_NOWAIT);
8143 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
8144 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
8151 if (sli_cmd_common_set_active_profile(&hw->sli, mbxdata, SLI4_BMBX_SIZE, 0, profile_id)) {
8152 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_set_active_profile_cb, cb_arg);
8156 ocs_log_test(hw->os, "SET_ACTIVE_PROFILE failed\n");
8157 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
8158 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_set_active_profile_cb_arg_t));
8200 * @return Returns the index into the HW cq array or -1 if not found.
8226 ocs_hw_domain_add(ocs_hw_t *hw, ocs_domain_t *domain)
8231 if ((hw == NULL) || (domain == NULL)) {
8232 ocs_log_err(NULL, "bad parameter hw=%p domain=%p\n",
8233 hw, domain);
8242 ocs_log_debug(hw->os, "adding domain %p @ %#x\n",
8244 hw->domains[fcfi] = domain;
8247 if (hw->workaround.override_fcfi) {
8248 if (hw->first_domain_idx < 0) {
8249 hw->first_domain_idx = fcfi;
8256 ocs_log_debug(hw->os, "adding map of FCF index %d to FCFI %d\n",
8258 hw->fcf_index_fcfi[fcf_index] = fcfi;
8261 ocs_log_test(hw->os, "FCF index %d out of range (max %d)\n",
8263 hw->domains[fcfi] = NULL;
8266 ocs_log_test(hw->os, "FCFI %#x out of range (max %#x)\n",
8274 ocs_hw_domain_del(ocs_hw_t *hw, ocs_domain_t *domain)
8279 if ((hw == NULL) || (domain == NULL)) {
8280 ocs_log_err(NULL, "bad parameter hw=%p domain=%p\n",
8281 hw, domain);
8290 ocs_log_debug(hw->os, "deleting domain %p @ %#x\n",
8293 if (domain != hw->domains[fcfi]) {
8294 ocs_log_test(hw->os, "provided domain %p does not match stored domain %p\n",
8295 domain, hw->domains[fcfi]);
8299 hw->domains[fcfi] = NULL;
8302 if (hw->workaround.override_fcfi) {
8303 if (hw->first_domain_idx == fcfi) {
8304 hw->first_domain_idx = -1;
8311 if (hw->fcf_index_fcfi[fcf_index] == fcfi) {
8312 hw->fcf_index_fcfi[fcf_index] = 0;
8315 ocs_log_test(hw->os, "indexed FCFI %#x doesn't match provided %#x @ %d\n",
8316 hw->fcf_index_fcfi[fcf_index], fcfi, fcf_index);
8319 ocs_log_test(hw->os, "FCF index %d out of range (max %d)\n",
8323 ocs_log_test(hw->os, "FCFI %#x out of range (max %#x)\n",
8331 ocs_hw_domain_get(ocs_hw_t *hw, uint16_t fcfi)
8334 if (hw == NULL) {
8335 ocs_log_err(NULL, "bad parameter hw=%p\n", hw);
8340 return hw->domains[fcfi];
8342 ocs_log_test(hw->os, "FCFI %#x out of range (max %#x)\n",
8349 ocs_hw_domain_get_indexed(ocs_hw_t *hw, uint16_t fcf_index)
8352 if (hw == NULL) {
8353 ocs_log_err(NULL, "bad parameter hw=%p\n", hw);
8358 return ocs_hw_domain_get(hw, hw->fcf_index_fcfi[fcf_index]);
8360 ocs_log_test(hw->os, "FCF index %d out of range (max %d)\n",
8376 * @param hw Hardware context.
8381 ocs_hw_io_quarantine(ocs_hw_t *hw, hw_wq_t *wq, ocs_hw_io_t *io)
8395 ocs_log_debug(hw ? hw->os : NULL,
8416 * @param hw Hardware context.
8417 * @param cq Pointer to the HW completion queue object.
8422 ocs_hw_cq_process(ocs_hw_t *hw, hw_cq_t *cq)
8434 while (!sli_queue_read(&hw->sli, cq->queue, cqe)) {
8435 status = sli_cq_parse(&hw->sli, cq->queue, cqe, &ctype, &rid);
8454 sli_cqe_async(&hw->sli, cqe);
8462 ocs_hw_mq_process(hw, status, hw->mq);
8465 ocs_hw_rqpair_process_auto_xfr_rdy_cmd(hw, cq, cqe);
8468 ocs_hw_rqpair_process_auto_xfr_rdy_data(hw, cq, cqe);
8472 ocs_hw_wq_process(hw, cq, cqe, status, rid);
8476 int32_t index = ocs_hw_queue_hash_find(hw->wq_hash, wq_id);
8479 ocs_log_err(hw->os, "unknown idx=%#x rid=%#x\n",
8484 hw_wq_t *wq = hw->hw_wq[index];
8486 /* Submit any HW IOs that are on the WQ pending list */
8494 ocs_hw_rqpair_process_rq(hw, cq, cqe);
8498 ocs_hw_xabt_process(hw, cq, cqe, rid);
8502 ocs_log_test(hw->os, "unhandled ctype=%#x rid=%#x\n", ctype, rid);
8512 sli_queue_arm(&hw->sli, cq->queue, FALSE);
8516 sli_queue_arm(&hw->sli, cq->queue, TRUE);
8530 * @param hw Hardware context.
8531 * @param cq Pointer to the HW completion queue object.
8539 ocs_hw_wq_process(ocs_hw_t *hw, hw_cq_t *cq, uint8_t *cqe, int32_t status, uint16_t rid)
8543 ocs_queue_history_cqe(&hw->q_hist, SLI_QENTRY_WQ, (void *)cqe, ((sli4_fc_wcqe_t *)cqe)->status, cq->queue->id,
8548 ocs_log_err(hw->os, "reque xri failed, status = %d \n", status);
8553 wqcb = ocs_hw_reqtag_get_instance(hw, rid);
8555 ocs_log_err(hw->os, "invalid request tag: x%x\n", rid);
8560 ocs_log_err(hw->os, "wqcb callback is NULL\n");
8575 * @n @b Note: Regarding io->reqtag, the reqtag is assigned once when HW IOs are initialized
8576 * in ocs_hw_setup_io(), and don't need to be returned to the hw->wq_reqtag_pool.
8584 ocs_hw_t *hw = io->hw;
8604 ocs_hw_io_quarantine(hw, io->wq, io);
8608 /* BZ 161832 - free secondary HW IO */
8619 ocs_hw_io_quarantine(hw, io->wq, io->sec_hio);
8622 ocs_hw_remove_io_timed_wqe(hw, io);
8635 sli_fc_els_did(&hw->sli, cqe, &ext);
8636 len = sli_fc_response_length(&hw->sli, cqe);
8643 len = sli_fc_response_length(&hw->sli, cqe);
8646 len = sli_fc_io_length(&hw->sli, cqe);
8655 len = sli_fc_io_length(&hw->sli, cqe);
8661 if (hw->workaround.retain_tsend_io_length && !len && !status) {
8679 len = sli_fc_io_length(&hw->sli, cqe);
8682 len = sli_fc_io_length(&hw->sli, cqe);
8688 //ocs_hw_io_free(hw, io);
8691 ocs_log_test(hw->os, "XXX unhandled io type %#x for XRI 0x%x\n",
8696 ext = sli_fc_ext_status(&hw->sli, cqe);
8700 if (hw->config.i_only_aab &&
8705 ocs_log_debug(hw->os, "aborting xri=%#x tag=%#x\n",
8712 rc = ocs_hw_io_abort(hw, io, TRUE, NULL, NULL);
8727 ocs_log_debug(hw->os, "abort in progress xri=%#x tag=%#x\n",
8732 ocs_log_test(hw->os, "Failed to abort xri=%#x tag=%#x rc=%d\n",
8738 * If we're not an originator IO, and XB is set, then issue abort for the IO from within the HW
8743 ocs_log_debug(hw->os, "aborting xri=%#x tag=%#x\n", io->indicator, io->reqtag);
8749 rc = ocs_hw_io_abort(hw, io, FALSE, NULL, NULL);
8763 ocs_log_debug(hw->os, "abort in progress xri=%#x tag=%#x\n",
8768 ocs_log_test(hw->os, "Failed to abort xri=%#x tag=%#x rc=%d\n",
8773 /* BZ 161832 - free secondary HW IO */
8775 ocs_hw_io_free(hw, io->sec_hio);
8794 ocs_hw_io_restore_sgl(hw, io);
8800 if (hw->config.bounce) {
8805 if (hw->callback.bounce != NULL) {
8806 (*hw->callback.bounce)(ocs_hw_unsol_process_bounce, io->axr_buf->cmd_seq, s_id, d_id, ox_id);
8809 hw->callback.unsolicited(hw->args.unsolicited, io->axr_buf->cmd_seq);
8814 if (hw->config.bounce) {
8819 if (hw->callback.bounce != NULL) {
8820 (*hw->callback.bounce)(ocs_hw_unsol_process_bounce, &io->axr_buf->seq, s_id, d_id, ox_id);
8823 hw->callback.unsolicited(hw->args.unsolicited, &io->axr_buf->seq);
8847 ocs_hw_t *hw = io->hw;
8857 ext = sli_fc_ext_status(&hw->sli, cqe);
8887 ocs_lock(&hw->io_abort_lock);
8890 ocs_unlock(&hw->io_abort_lock);
8894 wqcb = ocs_hw_reqtag_get_instance(hw, io->abort_reqtag);
8895 ocs_hw_reqtag_free(hw, wqcb);
8901 (void)ocs_hw_io_free(hw, io);
8907 * @param hw Hardware context.
8908 * @param cq Pointer to the HW completion queue object.
8916 ocs_hw_xabt_process(ocs_hw_t *hw, hw_cq_t *cq, uint8_t *cqe, uint16_t rid)
8921 io = ocs_hw_io_lookup(hw, rid);
8923 ocs_queue_history_cqe(&hw->q_hist, SLI_QENTRY_XABT, (void *)cqe, 0, cq->queue->id,
8927 ocs_log_err(hw->os, "Error: xabt io lookup failed rid=%#x\n", rid);
8932 ocs_log_debug(hw->os, "xabt io not busy rid=%#x\n", rid);
8939 ocs_lock(&hw->io_lock);
8942 ocs_unlock(&hw->io_lock);
8963 ocs_lock(&hw->io_lock);
8964 ocs_hw_reque_xri(hw, io);
8965 ocs_unlock(&hw->io_lock);
8967 ocs_hw_io_free(hw, io);
8971 ocs_lock(&hw->io_lock);
8980 ocs_list_remove(&hw->io_wait_free, io);
8981 ocs_hw_io_free_move_correct_list(hw, io);
8984 ocs_unlock(&hw->io_lock);
8988 * @brief Adjust the number of WQs and CQs within the HW.
8991 * Calculates the number of WQs and associated CQs needed in the HW based on
8995 * @param hw Hardware context allocated by the caller.
8998 ocs_hw_adjust_wqs(ocs_hw_t *hw)
9000 uint32_t max_wq_num = sli_get_max_queue(&hw->sli, SLI_QTYPE_WQ);
9001 uint32_t max_wq_entries = hw->num_qentries[SLI_QTYPE_WQ];
9002 uint32_t max_cq_entries = hw->num_qentries[SLI_QTYPE_CQ];
9010 max_wq_entries = hw->num_qentries[SLI_QTYPE_WQ] = max_cq_entries / 2;
9021 hw->config.n_wq = ((hw->config.n_io * 2) + (max_wq_entries - 1)) / max_wq_entries;
9027 if (hw->config.n_wq < 4 &&
9028 SLI4_IF_TYPE_BE3_SKH_PF == sli_get_if_type(&hw->sli)) {
9029 hw->config.n_wq = 4;
9035 if (hw->config.n_wq < 2 &&
9036 ocs_hw_get_num_chutes(hw) > 1) {
9037 hw->config.n_wq = 2;
9040 /* make sure we haven't exceeded the max supported in the HW */
9041 if (hw->config.n_wq > OCS_HW_MAX_NUM_WQ) {
9042 hw->config.n_wq = OCS_HW_MAX_NUM_WQ;
9046 if (hw->config.n_wq > max_wq_num) {
9047 hw->config.n_wq = max_wq_num;
9053 hw->config.n_wq /= ocs_hw_get_num_chutes(hw);
9057 ocs_hw_command_process(ocs_hw_t *hw, int32_t status, uint8_t *mqe, size_t size)
9061 ocs_lock(&hw->cmd_lock);
9062 if (NULL == (ctx = ocs_list_remove_head(&hw->cmd_head))) {
9063 ocs_log_err(hw->os, "XXX no command context?!?\n");
9064 ocs_unlock(&hw->cmd_lock);
9068 hw->cmd_head_count--;
9071 ocs_hw_cmd_submit_pending(hw);
9073 ocs_unlock(&hw->cmd_lock);
9079 ctx->cb(hw, status, ctx->buf, ctx->arg);
9083 ocs_free(hw->os, ctx, sizeof(ocs_command_ctx_t));
9091 * @param hw Hardware context.
9098 ocs_hw_mq_process(ocs_hw_t *hw, int32_t status, sli4_queue_t *mq)
9102 if (!sli_queue_read(&hw->sli, mq, mqe)) {
9103 ocs_hw_command_process(hw, status, mqe, mq->size);
9112 * @param hw Hardware context.
9120 ocs_hw_read_fcf(ocs_hw_t *hw, uint32_t index)
9125 buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
9127 ocs_log_err(hw->os, "no buffer for command\n");
9131 if (sli_cmd_fcoe_read_fcf_table(&hw->sli, buf, SLI4_BMBX_SIZE, &hw->fcf_dmem,
9133 rc = ocs_hw_command(hw, buf, OCS_CMD_NOWAIT, ocs_hw_cb_read_fcf, &hw->fcf_dmem);
9137 ocs_log_test(hw->os, "FCOE_READ_FCF_TABLE failed\n");
9138 ocs_free(hw->os, buf, SLI4_BMBX_SIZE);
9155 * @param hw Hardware context.
9163 ocs_hw_cb_read_fcf(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
9169 ocs_log_test(hw->os, "bad status cqe=%#x mqe=%#x\n",
9177 if (hw->callback.domain != NULL) {
9185 drec.speed = hw->link.speed;
9186 drec.fc_id = hw->link.fc_id;
9188 if (SLI_LINK_TOPO_LOOP == hw->link.topology) {
9190 ocs_memcpy(drec.map.loop, hw->link.loop_map,
9192 } else if (SLI_LINK_TOPO_NPORT == hw->link.topology) {
9211 hw->callback.domain(hw->args.domain,
9217 ocs_log_test(hw->os, "ignore invalid FCF entry\n");
9221 ocs_hw_read_fcf(hw, read_fcf->next_index);
9225 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
9226 //ocs_dma_free(hw->os, dma);
9227 //ocs_free(hw->os, dma, sizeof(ocs_dma_t));
9246 ocs_hw_t *hw = ctx;
9251 ocs_t *ocs = hw->os;
9253 ocs_hw_link_event_init(hw);
9258 hw->link = *event;
9262 ocs_hw_read_fcf(hw, SLI4_FCOE_FCF_TABLE_FIRST);
9267 buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
9269 ocs_log_err(hw->os, "no buffer for command\n");
9273 if (sli_cmd_read_topology(&hw->sli, buf, SLI4_BMBX_SIZE, &hw->loop_map)) {
9274 rc = ocs_hw_command(hw, buf, OCS_CMD_NOWAIT, __ocs_read_topology_cb, NULL);
9278 ocs_log_test(hw->os, "READ_TOPOLOGY failed\n");
9279 ocs_free(hw->os, buf, SLI4_BMBX_SIZE);
9289 hw->link.status = event->status;
9292 d = hw->domains[i];
9294 hw->callback.domain != NULL) {
9295 hw->callback.domain(hw->args.domain, OCS_HW_DOMAIN_LOST, d);
9300 ocs_log_test(hw->os, "unhandled link status %#x\n", event->status);
9310 ocs_hw_t *hw = ctx;
9315 ocs_hw_assert(hw);
9326 d = hw->domains[i];
9343 domain = ocs_hw_domain_get_indexed(hw, event->index);
9348 ocs_hw_read_fcf(hw, event->index);
9352 hw->callback.domain != NULL) {
9353 hw->callback.domain(hw->args.domain, OCS_HW_DOMAIN_LOST, domain);
9358 hw->callback.domain != NULL) {
9364 hw->callback.domain(hw->args.domain, OCS_HW_DOMAIN_LOST, domain);
9369 hw->callback.domain != NULL) {
9370 hw->callback.domain(hw->args.domain, OCS_HW_DOMAIN_LOST, domain);
9373 ocs_hw_read_fcf(hw, event->index);
9376 ocs_log_test(hw->os, "unsupported event %#x\n", event->type);
9383 ocs_hw_cb_node_attach(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
9390 ocs_log_debug(hw->os, "bad status cqe=%#x mqe=%#x\n", status,
9392 ocs_atomic_sub_return(&hw->rpi_ref[rnode->index].rpi_count, 1);
9394 ocs_atomic_set(&hw->rpi_ref[rnode->index].rpi_attached, 0);
9398 ocs_atomic_set(&hw->rpi_ref[rnode->index].rpi_attached, 1);
9402 if (hw->callback.rnode != NULL) {
9403 hw->callback.rnode(hw->args.rnode, evt, rnode);
9405 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
9411 ocs_hw_cb_node_free(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
9419 ocs_log_debug(hw->os, "bad status cqe=%#x mqe=%#x\n", status,
9428 if (!rnode->attached || ((sli_get_hlm(&hw->sli) == TRUE) && !rnode->node_group) ||
9438 if (ocs_atomic_read(&hw->rpi_ref[rnode->index].rpi_count) == 0) {
9439 ocs_atomic_set(&hw->rpi_ref[rnode->index].rpi_attached, 0);
9445 if (hw->callback.rnode != NULL) {
9446 hw->callback.rnode(hw->args.rnode, evt, rnode);
9449 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
9455 ocs_hw_cb_node_free_all(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
9463 ocs_log_debug(hw->os, "bad status cqe=%#x mqe=%#x\n", status,
9470 for (i = 0; i < sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_RPI); i++) {
9471 ocs_atomic_set(&hw->rpi_ref[i].rpi_count, 0);
9474 if (sli_resource_reset(&hw->sli, SLI_RSRC_FCOE_RPI)) {
9475 ocs_log_test(hw->os, "FCOE_RPI free all failure\n");
9480 if (hw->callback.rnode != NULL) {
9481 hw->callback.rnode(hw->args.rnode, evt, NULL);
9484 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
9490 * @brief Initialize the pool of HW IO objects.
9492 * @param hw Hardware context.
9497 ocs_hw_setup_io(ocs_hw_t *hw)
9506 if (NULL == hw->io) {
9507 hw->io = ocs_malloc(hw->os, hw->config.n_io * sizeof(ocs_hw_io_t *), OCS_M_ZERO | OCS_M_NOWAIT);
9509 if (NULL == hw->io) {
9510 ocs_log_err(hw->os, "IO pointer memory allocation failed, %d Ios at size %zu\n",
9511 hw->config.n_io,
9515 for (i = 0; i < hw->config.n_io; i++) {
9516 hw->io[i] = ocs_malloc(hw->os, sizeof(ocs_hw_io_t),
9518 if (hw->io[i] == NULL) {
9519 ocs_log_err(hw->os, "IO(%d) memory allocation failed\n", i);
9525 hw->wqe_buffs = ocs_malloc(hw->os, hw->config.n_io * hw->sli.config.wqe_size,
9527 if (NULL == hw->wqe_buffs) {
9528 ocs_free(hw->os, hw->io, hw->config.n_io * sizeof(ocs_hw_io_t));
9529 ocs_log_err(hw->os, "%s: IO WQE buff allocation failed, %d Ios at size %zu\n",
9530 __func__, hw->config.n_io, hw->sli.config.wqe_size);
9540 if (ocs_dma_alloc(hw->os, &hw->xfer_rdy,
9541 sizeof(fcp_xfer_rdy_iu_t) * hw->config.n_io,
9543 ocs_log_err(hw->os, "XFER_RDY buffer allocation failed\n");
9547 xfer_virt = (uintptr_t)hw->xfer_rdy.virt;
9548 xfer_phys = hw->xfer_rdy.phys;
9550 for (i = 0; i < hw->config.n_io; i++) {
9553 io = hw->io[i];
9556 io->hw = hw;
9559 io->wqe.wqebuf = &hw->wqe_buffs[i * hw->sli.config.wqe_size];
9562 wqcb = ocs_hw_reqtag_alloc(hw, ocs_hw_wq_process_io, io);
9564 ocs_log_err(hw->os, "can't allocate request tag\n");
9575 if (sli_resource_alloc(&hw->sli, SLI_RSRC_FCOE_XRI, &io->indicator, &index)) {
9576 ocs_log_err(hw->os, "sli_resource_alloc failed @ %d\n", i);
9580 if (new_alloc && ocs_dma_alloc(hw->os, &io->def_sgl, hw->config.n_sgl * sizeof(sli4_sge_t), 64)) {
9581 ocs_log_err(hw->os, "ocs_dma_alloc failed @ %d\n", i);
9585 io->def_sgl_count = hw->config.n_sgl;
9589 if (hw->xfer_rdy.size) {
9601 for (i = 0; i < hw->config.n_io && hw->io[i]; i++) {
9602 ocs_free(hw->os, hw->io[i], sizeof(ocs_hw_io_t));
9603 hw->io[i] = NULL;
9610 ocs_hw_init_io(ocs_hw_t *hw)
9623 prereg = sli_get_sgl_preregister(&hw->sli);
9626 sgls = ocs_malloc(hw->os, sizeof(*sgls) * sgls_per_request, OCS_M_NOWAIT);
9628 ocs_log_err(hw->os, "ocs_malloc sgls failed\n");
9632 rc = ocs_dma_alloc(hw->os, &reqbuf, 32 + sgls_per_request*16, OCS_MIN_DMA_ALIGNMENT);
9634 ocs_log_err(hw->os, "ocs_dma_alloc reqbuf failed\n");
9635 ocs_free(hw->os, sgls, sizeof(*sgls) * sgls_per_request);
9640 io = hw->io[io_index];
9641 for (nremaining = hw->config.n_io; nremaining; nremaining -= n) {
9649 if (hw->io[io_index + n]->indicator != (hw->io[io_index + n-1]->indicator+1)) {
9653 sgls[n] = hw->io[io_index + n]->sgl;
9656 if (sli_cmd_fcoe_post_sgl_pages(&hw->sli, cmd, sizeof(cmd),
9658 if (ocs_hw_command(hw, cmd, OCS_CMD_POLL, NULL, NULL)) {
9660 ocs_log_err(hw->os, "SGL post failed\n");
9672 ocs_list_add_tail(&hw->io_free, io);
9673 io = hw->io[io_index+1];
9679 ocs_dma_free(hw->os, &reqbuf);
9680 ocs_free(hw->os, sgls, sizeof(*sgls) * sgls_per_request);
9687 ocs_hw_flush(ocs_hw_t *hw)
9692 for (i = 0; i < hw->eq_count; i++) {
9693 ocs_hw_process(hw, i, ~0);
9700 ocs_hw_command_cancel(ocs_hw_t *hw)
9703 ocs_lock(&hw->cmd_lock);
9710 while (!ocs_list_empty(&hw->cmd_head)) {
9712 ocs_command_ctx_t *ctx = ocs_list_get_head(&hw->cmd_head);
9714 ocs_log_test(hw->os, "hung command %08x\n",
9717 ocs_unlock(&hw->cmd_lock);
9718 ocs_hw_command_process(hw, -1/*Bad status*/, mqe, SLI4_BMBX_SIZE);
9719 ocs_lock(&hw->cmd_lock);
9722 ocs_unlock(&hw->cmd_lock);
9730 * @param hw Hal context.
9736 ocs_hw_io_lookup(ocs_hw_t *hw, uint32_t xri)
9739 ioindex = xri - hw->sli.config.extent[SLI_RSRC_FCOE_XRI].base[0];
9740 return hw->io[ioindex];
9746 * @param hw Hal context.
9750 ocs_hw_io_cancel_cleanup(ocs_hw_t *hw, ocs_hw_io_t *io)
9757 ocs_list_remove(&hw->io_timed_wqe, io);
9769 ocs_unlock(&hw->io_lock);
9771 ocs_lock(&hw->io_lock);
9778 ocs_unlock(&hw->io_lock);
9780 ocs_lock(&hw->io_lock);
9785 ocs_hw_io_cancel(ocs_hw_t *hw)
9795 ocs_lock(&hw->io_lock);
9796 ocs_list_foreach_safe(&hw->io_inuse, io, tmp_io) {
9800 ocs_hw_io_cancel_cleanup(hw, io);
9819 ocs_hw_io_free_common(hw, io);
9820 ocs_list_remove(&hw->io_inuse, io);
9821 ocs_hw_io_free_move_correct_list(hw, io);
9829 ocs_list_foreach_safe(&hw->io_port_owned, io, tmp_io) {
9832 ocs_list_remove(&hw->io_port_dnrx, io);
9835 ocs_hw_io_cancel_cleanup(hw, io);
9836 ocs_list_remove(&hw->io_port_owned, io);
9837 ocs_hw_io_free_common(hw, io);
9839 ocs_unlock(&hw->io_lock);
9845 } while (!ocs_list_empty(&hw->io_inuse) && iters);
9848 if (!ocs_list_empty(&hw->io_inuse)) {
9849 ocs_log_test(hw->os, "io_inuse list is not empty\n");
9856 ocs_hw_io_ini_sge(ocs_hw_t *hw, ocs_hw_io_t *io, ocs_dma_t *cmnd, uint32_t cmnd_size,
9861 if (!hw || !io) {
9862 ocs_log_err(NULL, "bad parm hw=%p io=%p\n", hw, io);
9883 __ocs_read_topology_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
9888 ocs_log_debug(hw->os, "bad status cqe=%#x mqe=%#x\n",
9890 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
9896 hw->link.status = SLI_LINK_STATUS_UP;
9899 hw->link.status = SLI_LINK_STATUS_DOWN;
9902 hw->link.status = SLI_LINK_STATUS_NO_ALPA;
9905 hw->link.status = SLI_LINK_STATUS_MAX;
9911 hw->link.topology = SLI_LINK_TOPO_NPORT;
9914 hw->link.topology = SLI_LINK_TOPO_LOOP;
9915 if (SLI_LINK_STATUS_UP == hw->link.status) {
9916 hw->link.loop_map = hw->loop_map.virt;
9918 hw->link.fc_id = read_topo->acquired_al_pa;
9921 hw->link.topology = SLI_LINK_TOPO_MAX;
9925 hw->link.medium = SLI_LINK_MEDIUM_FC;
9929 hw->link.speed = 1 * 1000;
9932 hw->link.speed = 2 * 1000;
9935 hw->link.speed = 4 * 1000;
9938 hw->link.speed = 8 * 1000;
9941 hw->link.speed = 16 * 1000;
9942 hw->link.loop_map = NULL;
9945 hw->link.speed = 32 * 1000;
9946 hw->link.loop_map = NULL;
9950 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
9952 ocs_hw_read_fcf(hw, SLI4_FCOE_FCF_TABLE_FIRST);
9961 ocs_hw_t *hw = sport->hw;
9973 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
9977 ocs_log_test(hw->os, "%s %-20s not handled\n", funcname, ocs_sm_event_name(evt));
9988 ocs_hw_t *hw = sport->hw;
9995 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
9997 if (hw->callback.port != NULL) {
9998 hw->callback.port(hw->args.port,
10013 ocs_hw_t *hw = sport->hw;
10020 if (sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VPI, sport->indicator)) {
10021 ocs_log_err(hw->os, "FCOE_VPI free failure addr=%#x\n", sport->fc_id);
10026 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10028 if (hw->callback.port != NULL) {
10029 hw->callback.port(hw->args.port,
10044 ocs_hw_t *hw = sport->hw;
10051 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VPI, sport->indicator);
10055 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10058 if (hw->callback.port != NULL) {
10059 hw->callback.port(hw->args.port,
10078 ocs_hw_t *hw = sport->hw;
10086 cmd = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
10092 if (0 == sli_cmd_unreg_vpi(&hw->sli, cmd, SLI4_BMBX_SIZE, sport->indicator,
10094 ocs_log_err(hw->os, "UNREG_VPI format failure\n");
10095 ocs_free(hw->os, cmd, SLI4_BMBX_SIZE);
10100 if (ocs_hw_command(hw, cmd, OCS_CMD_NOWAIT, __ocs_hw_port_cb, sport)) {
10101 ocs_log_err(hw->os, "UNREG_VPI command failure\n");
10102 ocs_free(hw->os, cmd, SLI4_BMBX_SIZE);
10125 ocs_hw_t *hw = sport->hw;
10132 if (ocs_hw_async_call(hw, __ocs_hw_port_realloc_cb, sport)) {
10133 ocs_log_err(hw->os, "ocs_hw_async_call failed\n");
10153 ocs_hw_t *hw = sport->hw;
10160 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10162 if (hw->callback.port != NULL) {
10163 hw->callback.port(hw->args.port,
10186 ocs_hw_t *hw = sport->hw;
10192 if (0 == sli_cmd_reg_vpi(&hw->sli, data, SLI4_BMBX_SIZE, sport, FALSE)) {
10193 ocs_log_err(hw->os, "REG_VPI format failure\n");
10198 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_port_cb, sport)) {
10199 ocs_log_err(hw->os, "REG_VPI command failure\n");
10226 ocs_hw_t *hw = sport->hw;
10233 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VPI, sport->indicator);
10237 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10252 ocs_hw_t *hw = sport->hw;
10259 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10261 if (hw->callback.port != NULL) {
10262 hw->callback.port(hw->args.port,
10280 if (SLI4_IF_TYPE_LANCER_FC_ETH == sli_get_if_type(&hw->sli)) {
10306 ocs_hw_t *hw = sport->hw;
10313 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VPI, sport->indicator);
10317 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10320 if (hw->callback.port != NULL) {
10321 hw->callback.port(hw->args.port,
10342 ocs_hw_t *hw = sport->hw;
10350 if (ocs_dma_alloc(hw->os, &sport->dma, 112, 4)) {
10351 ocs_log_err(hw->os, "Failed to allocate DMA memory\n");
10356 if (0 == sli_cmd_read_sparm64(&hw->sli, data, SLI4_BMBX_SIZE,
10358 ocs_log_err(hw->os, "READ_SPARM64 allocation failure\n");
10359 ocs_dma_free(hw->os, &sport->dma);
10364 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_port_cb, sport)) {
10365 ocs_log_err(hw->os, "READ_SPARM64 command failure\n");
10366 ocs_dma_free(hw->os, &sport->dma);
10381 ocs_dma_free(hw->os, &sport->dma);
10385 ocs_dma_free(hw->os, &sport->dma);
10435 ocs_hw_t *hw = sport->hw;
10452 if (0 == sli_cmd_init_vpi(&hw->sli, data, SLI4_BMBX_SIZE,
10454 ocs_log_err(hw->os, "INIT_VPI allocation failure\n");
10459 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_port_cb, sport)) {
10460 ocs_log_err(hw->os, "INIT_VPI command failure\n");
10486 __ocs_hw_port_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
10493 ocs_log_debug(hw->os, "bad status vpi=%#x st=%x hdr=%x\n",
10506 __ocs_hw_port_realloc_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
10514 ocs_log_debug(hw->os, "bad status vpi=%#x st=%x hdr=%x\n",
10525 mqecpy = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
10527 ocs_log_err(hw->os, "malloc mqecpy failed\n");
10545 ocs_hw_t *hw = domain->hw;
10555 ocs_log_test(hw->os, "%s %-20s not handled\n", funcname, ocs_sm_event_name(evt));
10566 ocs_hw_t *hw = domain->hw;
10574 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10577 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VFI, domain->indicator);
10580 if (hw->callback.domain != NULL) {
10581 hw->callback.domain(hw->args.domain,
10598 ocs_hw_t *hw = domain->hw;
10605 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10609 if (hw->callback.domain != NULL) {
10610 hw->callback.domain(hw->args.domain,
10630 ocs_hw_t *hw = domain->hw;
10637 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10640 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VFI, domain->indicator);
10643 if (hw->callback.domain != NULL) {
10644 hw->callback.domain(hw->args.domain,
10663 ocs_hw_t *hw = domain->hw;
10672 if (0 == sli_cmd_reg_vfi(&hw->sli, data, SLI4_BMBX_SIZE, domain)) {
10673 ocs_log_err(hw->os, "REG_VFI format failure\n");
10678 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_domain_cb, domain)) {
10679 ocs_log_err(hw->os, "REG_VFI command failure\n");
10702 ocs_hw_t *hw = domain->hw;
10709 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10712 ocs_hw_domain_add(hw, domain);
10715 if (hw->callback.domain != NULL) {
10716 hw->callback.domain(hw->args.domain,
10726 if (SLI4_IF_TYPE_BE3_SKH_PF == sli_get_if_type(&hw->sli)) {
10744 ocs_hw_t *hw = domain->hw;
10750 if (0 == sli_cmd_read_sparm64(&hw->sli, data, SLI4_BMBX_SIZE,
10752 ocs_log_err(hw->os, "READ_SPARM64 format failure\n");
10757 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_domain_cb, domain)) {
10758 ocs_log_err(hw->os, "READ_SPARM64 command failure\n");
10786 ocs_hw_t *hw = domain->hw;
10792 if (0 == sli_cmd_init_vfi(&hw->sli, data, SLI4_BMBX_SIZE, domain->indicator,
10794 ocs_log_err(hw->os, "INIT_VFI format failure\n");
10798 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_domain_cb, domain)) {
10799 ocs_log_err(hw->os, "INIT_VFI command failure\n");
10824 ocs_hw_t *hw = domain->hw;
10833 /* Set the filter match/mask values from hw's filter_def values */
10836 rq_cfg[i].r_ctl_mask = (uint8_t) hw->config.filter_def[i];
10837 rq_cfg[i].r_ctl_match = (uint8_t) (hw->config.filter_def[i] >> 8);
10838 rq_cfg[i].type_mask = (uint8_t) (hw->config.filter_def[i] >> 16);
10839 rq_cfg[i].type_match = (uint8_t) (hw->config.filter_def[i] >> 24);
10843 for (i = 0; i < hw->hw_rq_count; i++) {
10845 ocs_log_warn(hw->os, "more RQs than REG_FCFI filter entries\n");
10848 rq_cfg[i].rq_id = hw->hw_rq[i]->hdr->id;
10856 if (hw->hw_mrq_count) {
10857 if (OCS_HW_RTN_SUCCESS != ocs_hw_config_mrq(hw, SLI4_CMD_REG_FCFI_SET_FCFI_MODE,
10859 ocs_log_err(hw->os, "REG_FCFI_MRQ format failure\n");
10865 if (0 == sli_cmd_reg_fcfi(&hw->sli, data, SLI4_BMBX_SIZE, domain->fcf,
10867 ocs_log_err(hw->os, "REG_FCFI format failure\n");
10873 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_domain_cb, domain)) {
10874 ocs_log_err(hw->os, "REG_FCFI command failure\n");
10895 if (SLI4_IF_TYPE_BE3_SKH_PF == sli_get_if_type(&hw->sli)) {
10916 ocs_hw_t *hw = domain->hw;
10922 if (sli_get_medium(&hw->sli) == SLI_LINK_MEDIUM_FC) {
10924 * For FC, the HW alread registered a FCFI
10927 domain->fcf_indicator = hw->fcf_indicator;
10951 ocs_hw_t *hw = domain->hw;
10953 ocs_hw_domain_del(hw, domain);
10955 if (hw->callback.domain != NULL) {
10956 hw->callback.domain(hw->args.domain,
10964 ocs_free(domain != NULL ? domain->hw->os : NULL, data, SLI4_BMBX_SIZE);
10988 ocs_hw_t *hw = domain->hw;
10991 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VFI,
10994 ocs_hw_domain_del(hw, domain);
10997 if (hw->callback.domain != NULL) {
10998 hw->callback.domain(hw->args.domain,
11021 ocs_hw_t *hw = domain->hw;
11028 if (hw->state == OCS_HW_STATE_TEARDOWN_IN_PROGRESS) {
11032 if (0 == sli_cmd_fcoe_rediscover_fcf(&hw->sli, data, SLI4_BMBX_SIZE, domain->fcf)) {
11033 ocs_log_err(hw->os, "REDISCOVER_FCF format failure\n");
11038 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_domain_cb, domain)) {
11039 ocs_log_err(hw->os, "REDISCOVER_FCF command failure\n");
11062 ocs_hw_t *hw = domain->hw;
11069 data = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
11076 if (0 == sli_cmd_unreg_fcfi(&hw->sli, data, SLI4_BMBX_SIZE, domain->fcf_indicator)) {
11077 ocs_log_err(hw->os, "UNREG_FCFI format failure\n");
11078 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
11083 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_domain_cb, domain)) {
11084 ocs_log_err(hw->os, "UNREG_FCFI command failure\n");
11085 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
11115 ocs_hw_t *hw = domain->hw;
11120 is_fc = (sli_get_medium(&hw->sli) == SLI_LINK_MEDIUM_FC);
11125 data = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
11132 if (0 == sli_cmd_unreg_vfi(&hw->sli, data, SLI4_BMBX_SIZE, domain,
11134 ocs_log_err(hw->os, "UNREG_VFI format failure\n");
11135 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
11140 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_domain_cb, domain)) {
11141 ocs_log_err(hw->os, "UNREG_VFI command failure\n");
11142 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
11171 __ocs_hw_domain_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
11178 ocs_log_debug(hw->os, "bad status vfi=%#x st=%x hdr=%x\n",
11191 target_wqe_timer_nop_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
11201 ocs_log_debug(hw->os, "bad status st=%x hdr=%x\n",
11207 ocs_lock(&hw->io_lock);
11208 ocs_list_foreach_safe(&hw->io_timed_wqe, io, io_next) {
11217 ocs_log_info(hw->os, "IO timeout xri=0x%x tag=0x%x type=%d elapsed time:%u\n",
11221 ocs_list_remove(&hw->io_timed_wqe, io);
11230 rc = ocs_hw_io_abort(hw, io, TRUE, NULL, NULL);
11232 ocs_log_test(hw->os,
11242 ocs_unlock(&hw->io_lock);
11245 if (!hw->active_wqe_timer_shutdown) {
11246 ocs_setup_timer(hw->os, &hw->wqe_timer, target_wqe_timer_cb, hw, OCS_HW_WQ_TIMER_PERIOD_MS);
11248 hw->in_active_wqe_timer = FALSE;
11255 ocs_hw_t *hw = (ocs_hw_t *)arg;
11258 hw->in_active_wqe_timer = TRUE;
11261 if (ocs_hw_async_call(hw, target_wqe_timer_nop_cb, hw)) {
11262 ocs_log_test(hw->os, "ocs_hw_async_call failed\n");
11267 shutdown_target_wqe_timer(ocs_hw_t *hw)
11271 if (hw->config.emulate_wqe_timeout) {
11273 hw->active_wqe_timer_shutdown = TRUE;
11276 ocs_del_timer(&hw->wqe_timer);
11279 while (hw->in_active_wqe_timer && iters) {
11284 ocs_hw_flush(hw);
11289 ocs_log_test(hw->os, "Failed to shutdown active wqe timer\n");
11295 * @brief Determine if HW IO is owned by the port.
11298 * Determines if the given HW IO has been posted to the chip.
11300 * @param hw Hardware context allocated by the caller.
11301 * @param io HW IO.
11303 * @return Returns TRUE if given HW IO is port-owned.
11306 ocs_hw_is_io_port_owned(ocs_hw_t *hw, ocs_hw_io_t *io)
11318 * @param hw Hardware context.
11325 ocs_hw_is_xri_port_owned(ocs_hw_t *hw, uint32_t xri)
11327 ocs_hw_io_t *io = ocs_hw_io_lookup(hw, xri);
11337 * @param hw Hardware context.
11342 ocs_hw_reclaim_xri(ocs_hw_t *hw, uint16_t xri_base, uint16_t xri_count)
11348 io = ocs_hw_io_lookup(hw, xri_base + i);
11354 if (hw->auto_xfer_rdy_enabled) {
11355 ocs_hw_rqpair_auto_xfer_rdy_move_to_host(hw, io);
11358 ocs_lock(&hw->io_lock);
11359 ocs_list_remove(&hw->io_port_owned, io);
11361 ocs_list_add_tail(&hw->io_free, io);
11362 ocs_unlock(&hw->io_lock);
11372 * @param hw Hardware context.
11380 ocs_hw_cb_post_xri(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
11386 ocs_log_debug(hw->os, "Status 0x%x for XRI base 0x%x, cnt =x%x\n",
11388 ocs_hw_reclaim_xri(hw, post_xri->xri_base, post_xri->xri_count);
11391 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
11398 * @param hw Hardware context.
11406 ocs_hw_post_xri(ocs_hw_t *hw, uint32_t xri_start, uint32_t num_to_post)
11412 post_xri = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
11414 ocs_log_err(hw->os, "no buffer for command\n");
11419 if (sli_cmd_post_xri(&hw->sli, post_xri, SLI4_BMBX_SIZE,
11421 rc = ocs_hw_command(hw, post_xri, OCS_CMD_NOWAIT, ocs_hw_cb_post_xri, NULL);
11423 ocs_free(hw->os, post_xri, SLI4_BMBX_SIZE);
11424 ocs_log_err(hw->os, "post_xri failed\n");
11436 * @param hw Hardware context.
11443 ocs_hw_xri_move_to_port_owned(ocs_hw_t *hw, uint32_t num_xri)
11454 ocs_lock(&hw->io_lock);
11457 if (NULL != (io = ocs_list_remove_head(&hw->io_free))) {
11466 if (hw->auto_xfer_rdy_enabled) {
11468 ocs_unlock(&hw->io_lock);
11469 rc = ocs_hw_rqpair_auto_xfer_rdy_move_to_port(hw, io);
11470 ocs_lock(&hw->io_lock);
11472 ocs_list_add_head(&hw->io_free, io);
11476 ocs_lock_init(hw->os, &io->axr_lock, "HW_axr_lock[%d]", io->indicator);
11478 ocs_list_add_tail(&hw->io_port_owned, io);
11481 if (ocs_hw_post_xri(hw, io->indicator, 1) != OCS_HW_RTN_SUCCESS ) {
11482 ocs_hw_reclaim_xri(hw, io->indicator, i);
11491 ocs_unlock(&hw->io_lock);
11502 * @param hw Hardware context.
11510 ocs_hw_cb_release_xri(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
11517 ocs_log_err(hw->os, "Status 0x%x\n", status);
11522 ocs_hw_reclaim_xri(hw, xri, 1);
11526 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
11535 * @param hw Hardware context.
11542 ocs_hw_xri_move_to_host_owned(ocs_hw_t *hw, uint8_t num_xri)
11548 release_xri = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
11550 ocs_log_err(hw->os, "no buffer for command\n");
11555 if (sli_cmd_release_xri(&hw->sli, release_xri, SLI4_BMBX_SIZE, num_xri)) {
11556 rc = ocs_hw_command(hw, release_xri, OCS_CMD_NOWAIT, ocs_hw_cb_release_xri, NULL);
11558 ocs_log_err(hw->os, "release_xri failed\n");
11563 ocs_free(hw->os, release_xri, SLI4_BMBX_SIZE);
11574 * @param hw Pointer to HW object.
11582 ocs_hw_rx_buffer_alloc(ocs_hw_t *hw, uint32_t rqindex, uint32_t count, uint32_t size)
11584 ocs_t *ocs = hw->os;
11590 rq_buf = ocs_malloc(hw->os, sizeof(*rq_buf) * count, OCS_M_NOWAIT | OCS_M_ZERO);
11592 ocs_log_err(hw->os, "Failure to allocate unsolicited DMA trackers\n");
11599 ocs_log_err(hw->os, "DMA allocation failed\n");
11600 ocs_free(hw->os, rq_buf, sizeof(*rq_buf) * count);
11615 * @param hw Pointer to HW object.
11622 ocs_hw_rx_buffer_free(ocs_hw_t *hw, ocs_hw_rq_buffer_t *rq_buf, uint32_t count)
11624 ocs_t *ocs = hw->os;
11632 ocs_free(hw->os, rq_buf, sizeof(*rq_buf) * count);
11639 * @param hw Pointer to HW object.
11644 ocs_hw_rx_allocate(ocs_hw_t *hw)
11646 ocs_t *ocs = hw->os;
11652 uint32_t payload_size = hw->config.rq_default_buffer_size;
11656 for (i = 0; i < hw->hw_rq_count; i++) {
11657 rq = hw->hw_rq[i];
11660 rq->hdr_buf = ocs_hw_rx_buffer_alloc(hw, rqindex, rq->entry_count, hdr_size);
11667 ocs_log_debug(hw->os, "rq[%2d] rq_id %02d header %4d by %4d bytes\n", i, rq->hdr->id,
11673 rq->payload_buf = ocs_hw_rx_buffer_alloc(hw, rqindex, rq->entry_count, payload_size);
11679 ocs_log_debug(hw->os, "rq[%2d] rq_id %02d default %4d by %4d bytes\n", i, rq->data->id,
11690 * @param hw Pointer to HW object.
11695 ocs_hw_rx_post(ocs_hw_t *hw)
11706 for (rq_idx = 0, idx = 0; rq_idx < hw->hw_rq_count; rq_idx++) {
11707 hw_rq_t *rq = hw->hw_rq[rq_idx];
11710 ocs_hw_sequence_t *seq = ocs_array_get(hw->seq_pool, idx++);
11717 rc = ocs_hw_sequence_free(hw, seq);
11733 * @param hw Pointer to HW object.
11737 ocs_hw_rx_free(ocs_hw_t *hw)
11743 for (i = 0; i < hw->hw_rq_count; i++) {
11744 rq = hw->hw_rq[i];
11746 ocs_hw_rx_buffer_free(hw, rq->hdr_buf, rq->entry_count);
11748 ocs_hw_rx_buffer_free(hw, rq->payload_buf, rq->entry_count);
11755 * @brief HW async call context structure.
11764 * @brief HW async callback handler
11770 * @param hw Pointer to HW object.
11778 ocs_hw_async_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
11784 (*ctx->callback)(hw, status, mqe, ctx->arg);
11786 ocs_free(hw->os, ctx, sizeof(*ctx));
11797 * @param hw Pointer to HW object.
11804 ocs_hw_async_call(ocs_hw_t *hw, ocs_hw_async_cb_t callback, void *arg)
11813 ctx = ocs_malloc(hw->os, sizeof(*ctx), OCS_M_ZERO | OCS_M_NOWAIT);
11815 ocs_log_err(hw->os, "failed to malloc async call context\n");
11822 if (sli_cmd_common_nop(&hw->sli, ctx->cmd, sizeof(ctx->cmd), 0) == 0) {
11823 ocs_log_err(hw->os, "COMMON_NOP format failure\n");
11824 ocs_free(hw->os, ctx, sizeof(*ctx));
11828 if (ocs_hw_command(hw, ctx->cmd, OCS_CMD_NOWAIT, ocs_hw_async_cb, ctx)) {
11829 ocs_log_err(hw->os, "COMMON_NOP command failure\n");
11830 ocs_free(hw->os, ctx, sizeof(*ctx));
11842 * @param hw Pointer to HW object.
11847 ocs_hw_reqtag_init(ocs_hw_t *hw)
11849 if (hw->wq_reqtag_pool == NULL) {
11850 hw->wq_reqtag_pool = ocs_pool_alloc(hw->os, sizeof(hw_wq_callback_t), 65536, TRUE);
11851 if (hw->wq_reqtag_pool == NULL) {
11852 ocs_log_err(hw->os, "ocs_pool_alloc hw_wq_callback_t failed\n");
11856 ocs_hw_reqtag_reset(hw);
11865 * @param hw Pointer to HW object.
11872 ocs_hw_reqtag_alloc(ocs_hw_t *hw, void (*callback)(void *arg, uint8_t *cqe, int32_t status), void *arg)
11878 wqcb = ocs_pool_get(hw->wq_reqtag_pool);
11892 * @param hw Pointer to HW object.
11898 ocs_hw_reqtag_free(ocs_hw_t *hw, hw_wq_callback_t *wqcb)
11903 ocs_pool_put(hw->wq_reqtag_pool, wqcb);
11912 * @param hw Pointer to HW object.
11918 ocs_hw_reqtag_get_instance(ocs_hw_t *hw, uint32_t instance_index)
11922 wqcb = ocs_pool_get_instance(hw->wq_reqtag_pool, instance_index);
11924 ocs_log_err(hw->os, "wqcb for instance %d is null\n", instance_index);
11935 * @param hw pointer to HW object.
11940 ocs_hw_reqtag_reset(ocs_hw_t *hw)
11946 while(ocs_pool_get(hw->wq_reqtag_pool) != NULL) {
11951 for (i = 0; ((wqcb = ocs_pool_get_instance(hw->wq_reqtag_pool, i)) != NULL); i++) {
11955 ocs_pool_put(hw->wq_reqtag_pool, wqcb);
11960 * @brief Handle HW assertion
11962 * HW assert, display diagnostic message, and abort.
11973 ocs_printf("%s(%d): HW assertion (%s) failed\n", filename, linenum, cond);
11979 * @brief Handle HW verify
11981 * HW verify, display diagnostic message, dump stack and return.
11992 ocs_printf("%s(%d): HW verify (%s) failed\n", filename, linenum, cond);
12002 * @param hw Pointer to HW object.
12003 * @param io Pointer to HW IO
12008 ocs_hw_reque_xri( ocs_hw_t *hw, ocs_hw_io_t *io )
12012 rc = ocs_hw_rqpair_auto_xfer_rdy_buffer_post(hw, io, 1);
12014 ocs_list_add_tail(&hw->io_port_dnrx, io);
12021 if (sli_requeue_xri_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, io->indicator, OCS_HW_REQUE_XRI_REGTAG, SLI4_CQ_DEFAULT)) {
12023 ocs_pool_put(hw->auto_xfer_rdy_buf_pool, io->axr_buf);
12026 ocs_log_err(hw->os, "requeue_xri WQE error\n");
12027 ocs_list_add_tail(&hw->io_port_dnrx, io);
12034 io->wq = ocs_hw_queue_next_wq(hw, io);
12042 OCS_STAT(hw->tcmd_wq_submit[io->wq->instance]++);
12047 ocs_log_err(hw->os, "sli_queue_write reque xri failed: %d\n", rc);
12058 sli4_t *sli4 = &ocs->hw.sli;
12091 ocs_hw_get_config_persistent_topology(ocs_hw_t *hw)
12094 sli4_t *sli = &hw->sli;
12129 * @param hw Hardware context.
12137 ocs_hw_set_persistent_topolgy_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
12172 * @param hw Pointer to hw
12179 ocs_hw_set_persistent_topology(ocs_hw_t *hw, uint32_t topology, uint32_t opts)
12191 if (sli_get_asic_type(&hw->sli) == SLI4_ASIC_TYPE_LANCER) {
12211 ocs_log_err(hw->os, "unsupported topology %#x\n", topology);
12218 sli_cmd_common_set_features(&hw->sli, buf, SLI4_BMBX_SIZE,
12222 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
12224 ocs_log_err(hw->os, "Failed to set persistent topology, rc: %#x\n", rc);
12230 rc = ocs_hw_command(hw, buf, OCS_CMD_NOWAIT, ocs_hw_set_persistent_topolgy_cb, &request);
12232 ocs_log_err(hw->os, "Failed to set persistent topology, rc: %#x\n", rc);
12237 ocs_log_err(hw->os, "ocs_sem_p failed\n");
12242 ocs_log_err(hw->os, "set persistent topology failed; status: %d\n", request.status);
12247 sli_config_persistent_topology(&hw->sli, ¶m);
12253 * @page fc_hw_api_overview HW APIs
12262 * The Hardware Abstraction Layer (HW) insulates the higher-level code from the SLI-4
12264 * IT nexuses, and IOs. The HW API is designed to help the higher level manage
12267 * The HW uses function callbacks to notify the higher-level code of events
12272 * within the HW. Examples include a new FCF is discovered, a connection
12281 * <img src="elx_fc_hw.jpg" alt="FC/FCoE HW" title="FC/FCoE HW" align="right"/>
12282 * <h2>FC/FCoE HW API</h2>
12283 * The FC/FCoE HW component builds upon the SLI-4 component to establish a flexible
12288 * <ul><li>Setting-up and tearing-down of the HW.</li>
12292 * <h3>HW Setup</h3>
12293 * To set up the HW:
12296 * <li>Set up the HW object using ocs_hw_setup().<br>
12297 * This step performs a basic configuration of the SLI-4 component and the HW to
12298 * enable querying the hardware for its capabilities. At this stage, the HW is not
12300 * <li>Configure the HW according to the driver requirements.<br>
12301 * The HW provides functions to discover hardware capabilities (ocs_hw_get()), as
12305 * @b Note: Once configured, the driver must initialize the HW (ocs_hw_init()). This
12311 * When the link comes up, the HW determines if a domain is present and notifies the
12359 * @b Note: The HW manages both the well known fabric address and the name server as
12364 * The HW provides separate interfaces for sending BLS/ ELS/ FC-CT and FCP, but the
12366 * the caller must provide a HW I/O object that maintains the I/O state, as well as
12368 * operations, but each operation must use a unique HW I/O object. In the SLI-4
12369 * architecture, there is a direct association between the HW I/O object and the SGL used
12372 * <ul><li>Allocates a HW I/O object (ocs_hw_io_alloc()).</li>
12373 * <li>Formats the SGL, specifying both the HW I/O object and the SGL.
12375 * <li>Sends the HW I/O (ocs_hw_io_send()).</li></ul>
12377 * <h3>HW Tear Down</h3>
12378 * To tear-down the HW:
12382 * <li>Destroy the HW object (ocs_hw_teardown()).</li>
12383 * <li>Free any memory used by the HW, such as buffers for unsolicited data.</li></ol>
12390 * This contains all hw runtime workaround code. Based on the asic type,
12393 * A workaround may consist of overriding a particular HW/SLI4 value that was initialized
12399 * would have the driver look like: "if (hw->workaround.enable_xxx) then ...", rather than
12520 static int32_t ocs_hw_workaround_match(ocs_hw_t *hw, hw_workaround_t *w);
12563 * @param hw Pointer to the HW structure
12570 ocs_hw_workaround_match(ocs_hw_t *hw, hw_workaround_t *w)
12572 return (((w->asic_type == SLI4_ASIC_TYPE_ANY) || (w->asic_type == hw->sli.asic_type)) &&
12573 ((w->asic_rev == SLI4_ASIC_REV_ANY) || (w->asic_rev == hw->sli.asic_rev)) &&
12574 (w->fwrev_low <= hw->workaround.fwrev) &&
12575 ((w->fwrev_high == HW_FWREV_MAX) || (hw->workaround.fwrev < w->fwrev_high)));
12579 * @brief Setup HW runtime workarounds
12582 * based on the HW/SLI setup.
12584 * @param hw Pointer to HW structure
12590 ocs_hw_workaround_setup(struct ocs_hw_s *hw)
12593 sli4_t *sli4 = &hw->sli;
12597 ocs_memset(&hw->workaround, 0, sizeof(hw->workaround));
12603 if (hw->hw_war_version) {
12604 hw->workaround.fwrev = parse_fw_version(hw->hw_war_version);
12606 hw->workaround.fwrev = parse_fw_version((char*) sli4->config.fw_name[0]);
12611 if (ocs_hw_workaround_match(hw, w)) {
12614 ocs_log_debug(hw->os, "Override: test: %d\n", w->value);
12619 ocs_log_debug(hw->os, "HW Workaround: retain TSEND IO length\n");
12620 hw->workaround.retain_tsend_io_length = 1;
12626 ocs_log_debug(hw->os, "HW Workaround: override max_qentries: %d\n", w->value);
12628 if (hw->num_qentries[q] > w->value) {
12629 hw->num_qentries[q] = w->value;
12635 ocs_log_debug(hw->os, "HW Workaround: override RQ max_qentries: %d\n", w->value);
12636 if (hw->num_qentries[SLI_QTYPE_RQ] > w->value) {
12637 hw->num_qentries[SLI_QTYPE_RQ] = w->value;
12642 ocs_log_debug(hw->os, "HW Workaround: set WQE count method=%d\n", w->value);
12648 ocs_log_debug(hw->os, "HW Workaround: set RQE count method=%d\n", w->value);
12654 ocs_log_debug(hw->os, "HW Workaround: use unreg'd RPI if rnode->indicator == 0xFFFF\n");
12655 hw->workaround.use_unregistered_rpi = TRUE;
12660 if (sli_resource_alloc(&hw->sli, SLI_RSRC_FCOE_RPI, &hw->workaround.unregistered_rid,
12661 &hw->workaround.unregistered_index)) {
12662 ocs_log_err(hw->os, "sli_resource_alloc unregistered RPI failed\n");
12663 hw->workaround.use_unregistered_rpi = FALSE;
12667 ocs_log_debug(hw->os, "HW Workaround: disable AR on T10-PI TSEND\n");
12668 hw->workaround.disable_ar_tgt_dif = TRUE;
12671 ocs_log_debug(hw->os, "HW Workaround: disable set_dump_loc\n");
12672 hw->workaround.disable_dump_loc = TRUE;
12675 ocs_log_debug(hw->os, "HW Workaround: use DIF quarantine\n");
12676 hw->workaround.use_dif_quarantine = TRUE;
12679 ocs_log_debug(hw->os, "HW Workaround: use DIF secondary xri\n");
12680 hw->workaround.use_dif_sec_xri = TRUE;
12683 ocs_log_debug(hw->os, "HW Workaround: override FCFI in SRB\n");
12684 hw->workaround.override_fcfi = TRUE;
12688 ocs_log_debug(hw->os, "HW Workaround: fw version is below the minimum for this driver\n");
12689 hw->workaround.fw_version_too_low = TRUE;
12692 ocs_log_debug(hw->os, "HW Workaround: SGLC misreported - chaining is enabled\n");
12693 hw->workaround.sglc_misreported = TRUE;
12696 ocs_log_debug(hw->os, "HW Workaround: not SEND_FRAME capable - disabled\n");
12697 hw->workaround.ignore_send_frame = TRUE;