Lines Matching refs:hw

75 static void ocs_hw_adjust_wqs(ocs_hw_t *hw);
76 static uint32_t ocs_hw_get_num_chutes(ocs_hw_t *hw);
90 static void ocs_hw_io_quarantine(ocs_hw_t *hw, hw_wq_t *wq, ocs_hw_io_t *io);
93 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);
98 static int32_t ocs_hw_cb_host_stat(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg);
99 static void ocs_hw_dmtf_clp_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg);
100 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);
101 typedef void (*ocs_hw_dmtf_clp_cb_t)(ocs_hw_t *hw, int32_t status, uint32_t result_len, void *arg);
102 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);
103 static void ocs_hw_linkcfg_dmtf_clp_cb(ocs_hw_t *hw, int32_t status, uint32_t result_len, void *arg);
113 static ocs_hw_rtn_e ocs_hw_set_eth_license(ocs_hw_t *hw, uint32_t license);
114 static ocs_hw_rtn_e ocs_hw_set_dif_seed(ocs_hw_t *hw);
115 static ocs_hw_rtn_e ocs_hw_set_dif_mode(ocs_hw_t *hw);
118 static ocs_hw_rtn_e ocs_hw_config_auto_xfer_rdy_t10pi(ocs_hw_t *hw, uint8_t *buf);
119 static ocs_hw_rtn_e ocs_hw_config_set_fdt_xfer_hint(ocs_hw_t *hw, uint32_t fdt_xfer_hint);
121 static int32_t ocs_hw_config_mrq(ocs_hw_t *hw, uint8_t, uint16_t, uint16_t);
122 static ocs_hw_rtn_e ocs_hw_config_watchdog_timer(ocs_hw_t *hw);
123 static ocs_hw_rtn_e ocs_hw_config_sli_port_health_check(ocs_hw_t *hw, uint8_t query, uint8_t enable);
145 static int32_t __ocs_hw_port_realloc_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg);
148 static void ocs_hw_check_sec_hio_list(ocs_hw_t *hw);
152 static void shutdown_target_wqe_timer(ocs_hw_t *hw);
155 ocs_hw_add_io_timed_wqe(ocs_hw_t *hw, ocs_hw_io_t *io)
157 if (hw->config.emulate_tgt_wqe_timeout && io->tgt_wqe_timeout) {
162 ocs_lock(&hw->io_lock);
163 ocs_list_add_tail(&hw->io_timed_wqe, io);
165 ocs_unlock(&hw->io_lock);
170 ocs_hw_remove_io_timed_wqe(ocs_hw_t *hw, ocs_hw_io_t *io)
172 if (hw->config.emulate_tgt_wqe_timeout) {
177 ocs_lock(&hw->io_lock);
179 ocs_list_remove(&hw->io_timed_wqe, io);
181 ocs_unlock(&hw->io_lock);
225 * @param hw Hardware context allocated by the caller.
230 ocs_hw_get_num_chutes(ocs_hw_t *hw)
234 if (sli_get_is_dual_ulp_capable(&hw->sli) &&
235 sli_get_is_ulp_enabled(&hw->sli, 0) &&
236 sli_get_is_ulp_enabled(&hw->sli, 1)) {
243 ocs_hw_link_event_init(ocs_hw_t *hw)
245 if (hw == NULL) {
246 ocs_log_err(hw->os, "bad parameter hw=%p\n", hw);
250 hw->link.status = SLI_LINK_STATUS_MAX;
251 hw->link.topology = SLI_LINK_TOPO_NONE;
252 hw->link.medium = SLI_LINK_MEDIUM_MAX;
253 hw->link.speed = 0;
254 hw->link.loop_map = NULL;
255 hw->link.fc_id = UINT32_MAX;
267 * @param hw Hardware context allocated by the caller.
272 ocs_hw_read_max_dump_size(ocs_hw_t *hw)
279 if (SLI4_IF_TYPE_LANCER_FC_ETH != sli_get_if_type(&hw->sli)) {
280 ocs_log_debug(hw->os, "Function only supported for I/F type 2\n");
288 if (hw->workaround.disable_dump_loc) {
289 ocs_log_test(hw->os, "FW version is too old for this feature\n");
294 ocs_get_bus_dev_func(hw->os, &bus, &dev, &func);
296 if (sli_cmd_common_set_dump_location(&hw->sli, buf,
303 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
305 ocs_log_test(hw->os, "set dump location command failed\n");
308 hw->dump_size = rsp->buffer_length;
309 ocs_log_debug(hw->os, "Dump size %x\n", rsp->buffer_length);
323 * @param hw Hardware context allocated by the caller.
332 ocs_hw_setup(ocs_hw_t *hw, ocs_os_handle_t os, sli4_port_type_e port_type)
337 if (hw == NULL) {
338 ocs_log_err(os, "bad parameter(s) hw=%p\n", hw);
342 if (hw->hw_setup_called) {
346 ocs_hw_workaround_setup(hw);
355 ocs_memset(hw, 0, sizeof(ocs_hw_t));
357 hw->hw_setup_called = TRUE;
359 hw->os = os;
361 ocs_lock_init(hw->os, &hw->cmd_lock, "HW_cmd_lock[%d]", ocs_instance(hw->os));
362 ocs_list_init(&hw->cmd_head, ocs_command_ctx_t, link);
363 ocs_list_init(&hw->cmd_pending, ocs_command_ctx_t, link);
364 hw->cmd_head_count = 0;
366 ocs_lock_init(hw->os, &hw->io_lock, "HW_io_lock[%d]", ocs_instance(hw->os));
367 ocs_lock_init(hw->os, &hw->io_abort_lock, "HW_io_abort_lock[%d]", ocs_instance(hw->os));
369 ocs_atomic_init(&hw->io_alloc_failed_count, 0);
371 hw->config.speed = FC_LINK_SPEED_AUTO_16_8_4;
372 hw->config.dif_seed = 0;
373 hw->config.auto_xfer_rdy_blk_size_chip = OCS_HW_AUTO_XFER_RDY_BLK_SIZE_DEFAULT;
374 hw->config.auto_xfer_rdy_ref_tag_is_lba = OCS_HW_AUTO_XFER_RDY_REF_TAG_IS_LBA_DEFAULT;
375 hw->config.auto_xfer_rdy_app_tag_valid = OCS_HW_AUTO_XFER_RDY_APP_TAG_VALID_DEFAULT;
376 hw->config.auto_xfer_rdy_app_tag_value = OCS_HW_AUTO_XFER_RDY_APP_TAG_VALUE_DEFAULT;
379 if (sli_setup(&hw->sli, hw->os, port_type)) {
380 ocs_log_err(hw->os, "SLI setup failed\n");
384 ocs_memset(hw->domains, 0, sizeof(hw->domains));
386 ocs_memset(hw->fcf_index_fcfi, 0, sizeof(hw->fcf_index_fcfi));
388 ocs_hw_link_event_init(hw);
390 sli_callback(&hw->sli, SLI4_CB_LINK, ocs_hw_cb_link, hw);
391 sli_callback(&hw->sli, SLI4_CB_FIP, ocs_hw_cb_fip, hw);
397 for (i = 0; i < ARRAY_SIZE(hw->num_qentries); i++) {
398 hw->num_qentries[i] = sli_get_max_qentries(&hw->sli, i);
404 hw->config.rq_default_buffer_size = OCS_HW_RQ_SIZE_PAYLOAD;
405 hw->config.n_io = sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_XRI);
407 hw->config.auto_xfer_rdy_xri_cnt = ocs_strtoul(prop_buf, 0, 0);
411 hw->config.i_only_aab = TRUE;
414 ocs_hw_workaround_setup(hw);
417 if (hw->workaround.override_fcfi) {
418 hw->first_domain_idx = -1;
422 if (SLI4_IF_TYPE_LANCER_FC_ETH == sli_get_if_type(&hw->sli)) {
423 (void)ocs_hw_read_max_dump_size(hw);
427 ocs_hw_adjust_wqs(hw);
430 if (! sli_is_dif_inline_capable(&hw->sli)) {
431 ocs_log_test(hw->os, "not inline capable, setting mode to separate\n");
432 hw->config.dif_mode = OCS_HW_DIF_MODE_SEPARATE;
435 if (hw->workaround.use_dif_sec_xri) {
436 ocs_list_init(&hw->sec_hio_wait_list, ocs_hw_io_t, link);
443 if (sli_get_is_dual_ulp_capable(&hw->sli)) {
444 if (sli_get_is_ulp_enabled(&hw->sli, 0) &&
445 sli_get_is_ulp_enabled(&hw->sli, 1)) {
446 hw->ulp_start = 0;
447 hw->ulp_max = 1;
448 } else if (sli_get_is_ulp_enabled(&hw->sli, 0)) {
449 hw->ulp_start = 0;
450 hw->ulp_max = 0;
452 hw->ulp_start = 1;
453 hw->ulp_max = 1;
456 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 ocs_log_debug(hw->os, "ulp_start %d, ulp_max %d\n",
465 hw->ulp_start, hw->ulp_max);
466 hw->config.queue_topology = hw_global.queue_topology_string;
468 hw->qtop = ocs_hw_qtop_parse(hw, hw->config.queue_topology);
470 hw->config.n_eq = hw->qtop->entry_counts[QTOP_EQ];
471 hw->config.n_cq = hw->qtop->entry_counts[QTOP_CQ];
472 hw->config.n_rq = hw->qtop->entry_counts[QTOP_RQ];
473 hw->config.n_wq = hw->qtop->entry_counts[QTOP_WQ];
474 hw->config.n_mq = hw->qtop->entry_counts[QTOP_MQ];
477 if (hw->config.n_rq > OCE_HW_MAX_NUM_MRQ_PAIRS) {
478 ocs_log_crit(hw->os, "Max supported MRQ pairs = %d\n",
483 if (hw->config.n_eq > OCS_HW_MAX_NUM_EQ) {
484 ocs_log_crit(hw->os, "Max supported EQs = %d\n",
489 if (hw->config.n_cq > OCS_HW_MAX_NUM_CQ) {
490 ocs_log_crit(hw->os, "Max supported CQs = %d\n",
495 if (hw->config.n_wq > OCS_HW_MAX_NUM_WQ) {
496 ocs_log_crit(hw->os, "Max supported WQs = %d\n",
501 if (hw->config.n_mq > OCS_HW_MAX_NUM_MQ) {
502 ocs_log_crit(hw->os, "Max supported MQs = %d\n",
521 * @param hw Hardware context allocated by the caller.
526 ocs_hw_init(ocs_hw_t *hw)
544 ocs_lock(&hw->cmd_lock);
545 if (!ocs_list_empty(&hw->cmd_head)) {
546 ocs_log_test(hw->os, "command found on cmd list\n");
547 ocs_unlock(&hw->cmd_lock);
550 if (!ocs_list_empty(&hw->cmd_pending)) {
551 ocs_log_test(hw->os, "command found on pending list\n");
552 ocs_unlock(&hw->cmd_lock);
555 ocs_unlock(&hw->cmd_lock);
558 ocs_hw_rx_free(hw);
571 if (ocs_list_valid(&hw->io_wait_free)) {
572 while ((!ocs_list_empty(&hw->io_wait_free))) {
574 ocs_list_remove_head(&hw->io_wait_free);
577 ocs_log_debug(hw->os, "removed %d items from io_wait_free list\n", rem_count);
581 if (ocs_list_valid(&hw->io_inuse)) {
582 while ((!ocs_list_empty(&hw->io_inuse))) {
584 ocs_list_remove_head(&hw->io_inuse);
587 ocs_log_debug(hw->os, "removed %d items from io_inuse list\n", rem_count);
591 if (ocs_list_valid(&hw->io_free)) {
592 while ((!ocs_list_empty(&hw->io_free))) {
594 ocs_list_remove_head(&hw->io_free);
597 ocs_log_debug(hw->os, "removed %d items from io_free list\n", rem_count);
600 if (ocs_list_valid(&hw->io_port_owned)) {
601 while ((!ocs_list_empty(&hw->io_port_owned))) {
602 ocs_list_remove_head(&hw->io_port_owned);
605 ocs_list_init(&hw->io_inuse, ocs_hw_io_t, link);
606 ocs_list_init(&hw->io_free, ocs_hw_io_t, link);
607 ocs_list_init(&hw->io_port_owned, ocs_hw_io_t, link);
608 ocs_list_init(&hw->io_wait_free, ocs_hw_io_t, link);
609 ocs_list_init(&hw->io_timed_wqe, ocs_hw_io_t, wqe_link);
610 ocs_list_init(&hw->io_port_dnrx, ocs_hw_io_t, dnrx_link);
613 if (hw->config.n_rq == 1) {
614 hw->sli.config.features.flag.mrqp = FALSE;
617 if (sli_init(&hw->sli)) {
618 ocs_log_err(hw->os, "SLI failed to initialize\n");
625 hw->auto_xfer_rdy_enabled = FALSE;
626 if (sli_get_auto_xfer_rdy_capable(&hw->sli) &&
627 hw->config.auto_xfer_rdy_size > 0) {
628 if (hw->config.esoc){
632 written_size = sli_cmd_config_auto_xfer_rdy_hp(&hw->sli, buf, SLI4_BMBX_SIZE, hw->config.auto_xfer_rdy_size, 1, ramdisc_blocksize);
634 written_size = sli_cmd_config_auto_xfer_rdy(&hw->sli, buf, SLI4_BMBX_SIZE, hw->config.auto_xfer_rdy_size);
637 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
639 ocs_log_err(hw->os, "config auto xfer rdy failed\n");
643 hw->auto_xfer_rdy_enabled = TRUE;
645 if (hw->config.auto_xfer_rdy_t10_enable) {
646 rc = ocs_hw_config_auto_xfer_rdy_t10pi(hw, buf);
648 ocs_log_err(hw->os, "set parameters auto xfer rdy T10 PI failed\n");
654 if(hw->sliport_healthcheck) {
655 rc = ocs_hw_config_sli_port_health_check(hw, 0, 1);
657 ocs_log_err(hw->os, "Enabling Sliport Health check failed \n");
665 if ((hw->sli.if_type == SLI4_IF_TYPE_LANCER_FC_ETH) && (OCS_HW_FDT_XFER_HINT != 0)) {
670 ocs_hw_config_set_fdt_xfer_hint(hw, OCS_HW_FDT_XFER_HINT);
676 q_count = MIN(sli_get_max_queue(&hw->sli, SLI_QTYPE_EQ),
678 if (hw->config.n_eq > q_count) {
679 ocs_log_err(hw->os, "requested %d EQ but %d allowed\n",
680 hw->config.n_eq, q_count);
684 q_count = MIN(sli_get_max_queue(&hw->sli, SLI_QTYPE_CQ),
686 if (hw->config.n_cq > q_count) {
687 ocs_log_err(hw->os, "requested %d CQ but %d allowed\n",
688 hw->config.n_cq, q_count);
692 q_count = MIN(sli_get_max_queue(&hw->sli, SLI_QTYPE_MQ),
694 if (hw->config.n_mq > q_count) {
695 ocs_log_err(hw->os, "requested %d MQ but %d allowed\n",
696 hw->config.n_mq, q_count);
700 q_count = MIN(sli_get_max_queue(&hw->sli, SLI_QTYPE_RQ),
702 if (hw->config.n_rq > q_count) {
703 ocs_log_err(hw->os, "requested %d RQ but %d allowed\n",
704 hw->config.n_rq, q_count);
708 q_count = MIN(sli_get_max_queue(&hw->sli, SLI_QTYPE_WQ),
710 if (hw->config.n_wq > q_count) {
711 ocs_log_err(hw->os, "requested %d WQ but %d allowed\n",
712 hw->config.n_wq, q_count);
717 ocs_memset(hw->cq_hash, 0, sizeof(hw->cq_hash));
718 ocs_log_debug(hw->os, "Max CQs %d, hash size = %d\n",
721 ocs_memset(hw->rq_hash, 0, sizeof(hw->rq_hash));
722 ocs_log_debug(hw->os, "Max RQs %d, hash size = %d\n",
725 ocs_memset(hw->wq_hash, 0, sizeof(hw->wq_hash));
726 ocs_log_debug(hw->os, "Max WQs %d, hash size = %d\n",
730 rc = ocs_hw_init_queues(hw, hw->qtop);
735 max_rpi = sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_RPI);
736 i = sli_fc_get_rpi_requirements(&hw->sli, max_rpi);
742 if (hw->rnode_mem.size) {
743 ocs_dma_free(hw->os, &hw->rnode_mem);
746 if (ocs_dma_alloc(hw->os, &hw->rnode_mem, i, 4096)) {
747 ocs_log_err(hw->os, "remote node memory allocation fail\n");
752 if (sli_cmd_fcoe_post_hdr_templates(&hw->sli, buf, SLI4_BMBX_SIZE,
753 &hw->rnode_mem, UINT16_MAX, &payload_memory)) {
754 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
758 ocs_dma_free(hw->os, &payload_memory);
763 ocs_log_err(hw->os, "header template registration failed\n");
769 rc = ocs_hw_rx_allocate(hw);
771 ocs_log_err(hw->os, "rx_allocate failed\n");
775 /* Populate hw->seq_free_list */
776 if (hw->seq_pool == NULL) {
781 for (i = 0; i < hw->hw_rq_count; i++) {
782 count += hw->hw_rq[i]->entry_count;
785 hw->seq_pool = ocs_array_alloc(hw->os, sizeof(ocs_hw_sequence_t), count);
786 if (hw->seq_pool == NULL) {
787 ocs_log_err(hw->os, "malloc seq_pool failed\n");
792 if(ocs_hw_rx_post(hw)) {
793 ocs_log_err(hw->os, "WARNING - error posting RQ buffers\n");
797 if (hw->rpi_ref == NULL) {
798 hw->rpi_ref = ocs_malloc(hw->os, max_rpi * sizeof(*hw->rpi_ref),
800 if (hw->rpi_ref == NULL) {
801 ocs_log_err(hw->os, "rpi_ref allocation failure (%d)\n", i);
807 ocs_atomic_init(&hw->rpi_ref[i].rpi_count, 0);
808 ocs_atomic_init(&hw->rpi_ref[i].rpi_attached, 0);
811 ocs_memset(hw->domains, 0, sizeof(hw->domains));
814 if (hw->workaround.override_fcfi) {
815 hw->first_domain_idx = -1;
818 ocs_memset(hw->fcf_index_fcfi, 0, sizeof(hw->fcf_index_fcfi));
821 if (sli_get_medium(&hw->sli) == SLI_LINK_MEDIUM_FC) {
823 if (hw->hw_mrq_count) {
824 ocs_log_debug(hw->os, "using REG_FCFI MRQ\n");
826 rc = ocs_hw_config_mrq(hw, SLI4_CMD_REG_FCFI_SET_FCFI_MODE, 0, 0);
828 ocs_log_err(hw->os, "REG_FCFI_MRQ FCFI registration failed\n");
832 rc = ocs_hw_config_mrq(hw, SLI4_CMD_REG_FCFI_SET_MRQ_MODE, 0, 0);
834 ocs_log_err(hw->os, "REG_FCFI_MRQ MRQ registration failed\n");
840 ocs_log_debug(hw->os, "using REG_FCFI standard\n");
842 /* Set the filter match/mask values from hw's filter_def values */
845 rq_cfg[i].r_ctl_mask = (uint8_t) hw->config.filter_def[i];
846 rq_cfg[i].r_ctl_match = (uint8_t) (hw->config.filter_def[i] >> 8);
847 rq_cfg[i].type_mask = (uint8_t) (hw->config.filter_def[i] >> 16);
848 rq_cfg[i].type_match = (uint8_t) (hw->config.filter_def[i] >> 24);
855 for (i = 0; i < OCS_MIN(hw->hw_rq_count, SLI4_CMD_REG_FCFI_NUM_RQ_CFG); i++) {
856 hw_rq_t *rq = hw->hw_rq[i];
862 ocs_log_debug(hw->os, "REG_FCFI: filter[%d] %08X -> RQ[%d] id=%d\n",
863 j, hw->config.filter_def[j], i, rq->hdr->id);
870 if (sli_cmd_reg_fcfi(&hw->sli, buf, SLI4_BMBX_SIZE, 0, rq_cfg, 0)) {
871 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
875 ocs_log_err(hw->os, "FCFI registration failed\n");
878 hw->fcf_indicator = ((sli4_cmd_reg_fcfi_t *)buf)->fcfi;
887 rc = ocs_hw_reqtag_init(hw);
889 ocs_log_err(hw->os, "ocs_pool_alloc hw_wq_callback_t failed: %d\n", rc);
893 rc = ocs_hw_setup_io(hw);
895 ocs_log_err(hw->os, "IO allocation failure\n");
899 rc = ocs_hw_init_io(hw);
901 ocs_log_err(hw->os, "IO initialization failure\n");
905 ocs_queue_history_init(hw->os, &hw->q_hist);
907 /* get hw link config; polling, so callback will be called immediately */
908 hw->linkcfg = OCS_HW_LINKCFG_NA;
909 ocs_hw_get_linkcfg(hw, OCS_CMD_POLL, ocs_hw_init_linkcfg_cb, hw);
912 if ((hw->sli.if_type == SLI4_IF_TYPE_LANCER_FC_ETH) &&
913 (sli_get_medium(&hw->sli) == SLI_LINK_MEDIUM_ETHERNET)) {
914 if (ocs_hw_set_eth_license(hw, hw->eth_license)) {
916 ocs_log_err(hw->os, "Failed to set ethernet license\n");
921 if (SLI4_IF_TYPE_LANCER_FC_ETH == sli_get_if_type(&hw->sli) &&
922 ocs_hw_set_dif_seed(hw) != OCS_HW_RTN_SUCCESS) {
923 ocs_log_err(hw->os, "Failed to set DIF seed value\n");
928 if (SLI4_IF_TYPE_BE3_SKH_PF == sli_get_if_type(&hw->sli) &&
929 sli_get_dif_capable(&hw->sli)) {
930 rc = ocs_hw_set_dif_mode(hw);
932 ocs_log_err(hw->os, "Failed to set DIF mode value\n");
940 for (i = 0; i < hw->eq_count; i++) {
941 sli_queue_arm(&hw->sli, &hw->eq[i], TRUE);
947 for (i = 0; i < hw->rq_count; i++) {
948 ocs_hw_queue_hash_add(hw->rq_hash, hw->rq[i].id, i);
954 for (i = 0; i < hw->wq_count; i++) {
955 ocs_hw_queue_hash_add(hw->wq_hash, hw->wq[i].id, i);
961 for (i = 0; i < hw->cq_count; i++) {
962 ocs_hw_queue_hash_add(hw->cq_hash, hw->cq[i].id, i);
963 sli_queue_arm(&hw->sli, &hw->cq[i], TRUE);
967 hw->state = OCS_HW_STATE_ACTIVE;
970 if (ocs_hw_rqpair_init(hw)) {
971 ocs_log_err(hw->os, "WARNING - error initializing RQ pair\n");
975 if (hw->config.emulate_tgt_wqe_timeout) {
976 ocs_setup_timer(hw->os, &hw->wqe_timer, target_wqe_timer_cb, hw,
984 if ((count = ocs_varray_get_count(hw->wq_class_array[1])) > 0) {
986 hw_wq_t *wq = ocs_varray_iter_next(hw->wq_class_array[1]);
987 wq->send_frame_io = ocs_hw_io_alloc(hw);
989 ocs_log_err(hw->os, "ocs_hw_io_alloc for send_frame_io failed\n");
993 hw->hw_wq[0]->send_frame_io = ocs_hw_io_alloc(hw);
994 if (hw->hw_wq[0]->send_frame_io == NULL) {
995 ocs_log_err(hw->os, "ocs_hw_io_alloc for send_frame_io failed\n");
1000 ocs_atomic_init(&hw->send_frame_seq_id, 0);
1003 hw->expiration_logged = 0;
1004 if(hw->watchdog_timeout) {
1005 if((hw->watchdog_timeout < 1) || (hw->watchdog_timeout > 65534)) {
1006 ocs_log_err(hw->os, "watchdog_timeout out of range: Valid range is 1 - 65534\n");
1007 }else if(!ocs_hw_config_watchdog_timer(hw)) {
1008 ocs_log_info(hw->os, "watchdog timer configured with timeout = %d seconds \n", hw->watchdog_timeout);
1012 if (ocs_dma_alloc(hw->os, &hw->domain_dmem, 112, 4)) {
1013 ocs_log_err(hw->os, "domain node memory allocation fail\n");
1017 if (ocs_dma_alloc(hw->os, &hw->fcf_dmem, OCS_HW_READ_FCF_SIZE, OCS_HW_READ_FCF_SIZE)) {
1018 ocs_log_err(hw->os, "domain fcf memory allocation fail\n");
1022 if ((0 == hw->loop_map.size) && ocs_dma_alloc(hw->os, &hw->loop_map,
1024 ocs_log_err(hw->os, "Loop dma alloc failed size:%d \n", hw->loop_map.size);
1033 * @param hw Hardware context allocated by the caller.
1041 ocs_hw_config_mrq(ocs_hw_t *hw, uint8_t mode, uint16_t vlanid, uint16_t fcf_index)
1054 /* Set the filter match/mask values from hw's filter_def values */
1057 rq_filter[i].r_ctl_mask = (uint8_t) hw->config.filter_def[i];
1058 rq_filter[i].r_ctl_match = (uint8_t) (hw->config.filter_def[i] >> 8);
1059 rq_filter[i].type_mask = (uint8_t) (hw->config.filter_def[i] >> 16);
1060 rq_filter[i].type_match = (uint8_t) (hw->config.filter_def[i] >> 24);
1064 for (i = 0; i < hw->hw_rq_count; i++) {
1065 rq = hw->hw_rq[i];
1071 ocs_log_err(hw->os, "Wrong queue topology.\n");
1089 rc = sli_cmd_reg_fcfi_mrq(&hw->sli,
1095 hw->config.rq_selection_policy, /* RQ selection policy*/
1097 hw->hw_mrq_count, /* num_mrqs */
1100 ocs_log_err(hw->os, "sli_cmd_reg_fcfi_mrq() failed: %d\n", rc);
1104 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
1109 ocs_log_err(hw->os, "FCFI MRQ registration failed. cmd = %x status = %x\n",
1115 hw->fcf_indicator = rsp->fcfi;
1132 ocs_hw_t *hw = (ocs_hw_t *)arg;
1134 hw->linkcfg = (ocs_hw_linkcfg_e)value;
1136 hw->linkcfg = OCS_HW_LINKCFG_NA;
1138 ocs_log_debug(hw->os, "linkcfg=%d\n", hw->linkcfg);
1149 * @param hw Hardware context allocated by the caller.
1154 ocs_hw_teardown(ocs_hw_t *hw)
1162 if (!hw) {
1163 ocs_log_err(NULL, "bad parameter(s) hw=%p\n", hw);
1167 destroy_queues = (hw->state == OCS_HW_STATE_ACTIVE);
1168 free_memory = (hw->state != OCS_HW_STATE_UNINITIALIZED);
1171 shutdown_target_wqe_timer(hw);
1174 if(hw->watchdog_timeout) {
1175 hw->watchdog_timeout = 0;
1176 ocs_hw_config_watchdog_timer(hw);
1180 if(hw->sliport_healthcheck) {
1181 hw->sliport_healthcheck = 0;
1182 ocs_hw_config_sli_port_health_check(hw, 0, 0);
1185 if (hw->state != OCS_HW_STATE_QUEUES_ALLOCATED) {
1187 hw->state = OCS_HW_STATE_TEARDOWN_IN_PROGRESS;
1189 ocs_hw_flush(hw);
1192 while (!ocs_list_empty(&hw->cmd_head) && iters) {
1194 ocs_hw_flush(hw);
1198 if (ocs_list_empty(&hw->cmd_head)) {
1199 ocs_log_debug(hw->os, "All commands completed on MQ queue\n");
1201 ocs_log_debug(hw->os, "Some commands still pending on MQ queue\n");
1205 ocs_hw_command_cancel(hw);
1207 hw->state = OCS_HW_STATE_TEARDOWN_IN_PROGRESS;
1210 ocs_lock_free(&hw->cmd_lock);
1213 if (hw->workaround.use_unregistered_rpi) {
1214 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_RPI, hw->workaround.unregistered_rid);
1217 max_rpi = sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_RPI);
1218 if (hw->rpi_ref) {
1220 if (ocs_atomic_read(&hw->rpi_ref[i].rpi_count)) {
1221 ocs_log_debug(hw->os, "non-zero ref [%d]=%d\n",
1222 i, ocs_atomic_read(&hw->rpi_ref[i].rpi_count));
1225 ocs_free(hw->os, hw->rpi_ref, max_rpi * sizeof(*hw->rpi_ref));
1226 hw->rpi_ref = NULL;
1229 ocs_dma_free(hw->os, &hw->rnode_mem);
1231 if (hw->io) {
1232 for (i = 0; i < hw->config.n_io; i++) {
1233 if (hw->io[i] && (hw->io[i]->sgl != NULL) &&
1234 (hw->io[i]->sgl->virt != NULL)) {
1235 if(hw->io[i]->is_port_owned) {
1236 ocs_lock_free(&hw->io[i]->axr_lock);
1238 ocs_dma_free(hw->os, hw->io[i]->sgl);
1240 ocs_free(hw->os, hw->io[i], sizeof(ocs_hw_io_t));
1241 hw->io[i] = NULL;
1243 ocs_free(hw->os, hw->wqe_buffs, hw->config.n_io * hw->sli.config.wqe_size);
1244 hw->wqe_buffs = NULL;
1245 ocs_free(hw->os, hw->io, hw->config.n_io * sizeof(ocs_hw_io_t *));
1246 hw->io = NULL;
1249 ocs_dma_free(hw->os, &hw->xfer_rdy);
1250 ocs_dma_free(hw->os, &hw->dump_sges);
1251 ocs_dma_free(hw->os, &hw->loop_map);
1253 ocs_lock_free(&hw->io_lock);
1254 ocs_lock_free(&hw->io_abort_lock);
1257 for (i = 0; i < hw->wq_count; i++) {
1258 sli_queue_free(&hw->sli, &hw->wq[i], destroy_queues, free_memory);
1262 for (i = 0; i < hw->rq_count; i++) {
1263 sli_queue_free(&hw->sli, &hw->rq[i], destroy_queues, free_memory);
1266 for (i = 0; i < hw->mq_count; i++) {
1267 sli_queue_free(&hw->sli, &hw->mq[i], destroy_queues, free_memory);
1270 for (i = 0; i < hw->cq_count; i++) {
1271 sli_queue_free(&hw->sli, &hw->cq[i], destroy_queues, free_memory);
1274 for (i = 0; i < hw->eq_count; i++) {
1275 sli_queue_free(&hw->sli, &hw->eq[i], destroy_queues, free_memory);
1278 ocs_hw_qtop_free(hw->qtop);
1281 ocs_hw_rx_free(hw);
1283 hw_queue_teardown(hw);
1285 ocs_hw_rqpair_teardown(hw);
1287 if (sli_teardown(&hw->sli)) {
1288 ocs_log_err(hw->os, "SLI teardown failed\n");
1291 ocs_queue_history_free(&hw->q_hist);
1294 hw->state = OCS_HW_STATE_UNINITIALIZED;
1297 ocs_array_free(hw->seq_pool);
1298 hw->seq_pool = NULL;
1301 ocs_pool_free(hw->wq_reqtag_pool);
1303 ocs_dma_free(hw->os, &hw->domain_dmem);
1304 ocs_dma_free(hw->os, &hw->fcf_dmem);
1306 hw->hw_setup_called = FALSE;
1312 ocs_hw_reset(ocs_hw_t *hw, ocs_hw_reset_e reset)
1317 ocs_hw_state_e prev_state = hw->state;
1319 if (hw->state != OCS_HW_STATE_ACTIVE) {
1320 ocs_log_test(hw->os, "HW state %d is not active\n", hw->state);
1323 hw->state = OCS_HW_STATE_RESET_IN_PROGRESS;
1326 shutdown_target_wqe_timer(hw);
1328 ocs_hw_flush(hw);
1336 while (!ocs_list_empty(&hw->cmd_head) && iters) {
1338 ocs_hw_flush(hw);
1342 if (ocs_list_empty(&hw->cmd_head)) {
1343 ocs_log_debug(hw->os, "All commands completed on MQ queue\n");
1345 ocs_log_debug(hw->os, "Some commands still pending on MQ queue\n");
1351 ocs_log_debug(hw->os, "issuing function level reset\n");
1352 if (sli_reset(&hw->sli)) {
1353 ocs_log_err(hw->os, "sli_reset failed\n");
1358 ocs_log_debug(hw->os, "issuing firmware reset\n");
1359 if (sli_fw_reset(&hw->sli)) {
1360 ocs_log_err(hw->os, "sli_soft_reset failed\n");
1367 ocs_log_debug(hw->os, "issuing function level reset\n");
1368 if (sli_reset(&hw->sli)) {
1369 ocs_log_err(hw->os, "sli_reset failed\n");
1374 ocs_log_test(hw->os, "unknown reset type - no reset performed\n");
1375 hw->state = prev_state;
1381 ocs_hw_command_cancel(hw);
1384 ocs_hw_io_cancel(hw);
1386 ocs_memset(hw->domains, 0, sizeof(hw->domains));
1387 ocs_memset(hw->fcf_index_fcfi, 0, sizeof(hw->fcf_index_fcfi));
1389 ocs_hw_link_event_init(hw);
1391 ocs_lock(&hw->io_lock);
1393 while (!ocs_list_empty(&hw->io_timed_wqe)) {
1394 ocs_list_remove_head(&hw->io_timed_wqe);
1398 while (!ocs_list_empty(&hw->io_free)) {
1399 ocs_list_remove_head(&hw->io_free);
1401 while (!ocs_list_empty(&hw->io_wait_free)) {
1402 ocs_list_remove_head(&hw->io_wait_free);
1406 ocs_hw_reqtag_reset(hw);
1408 ocs_unlock(&hw->io_lock);
1412 for (i = 0; i < hw->wq_count; i++) {
1413 sli_queue_reset(&hw->sli, &hw->wq[i]);
1416 for (i = 0; i < hw->rq_count; i++) {
1417 sli_queue_reset(&hw->sli, &hw->rq[i]);
1420 for (i = 0; i < hw->hw_rq_count; i++) {
1421 hw_rq_t *rq = hw->hw_rq[i];
1431 for (i = 0; i < hw->mq_count; i++) {
1432 sli_queue_reset(&hw->sli, &hw->mq[i]);
1435 for (i = 0; i < hw->cq_count; i++) {
1436 sli_queue_reset(&hw->sli, &hw->cq[i]);
1439 for (i = 0; i < hw->eq_count; i++) {
1440 sli_queue_reset(&hw->sli, &hw->eq[i]);
1444 ocs_hw_rx_free(hw);
1447 hw_queue_teardown(hw);
1451 ocs_hw_rx_free(hw);
1458 ocs_hw_workaround_setup(hw);
1459 hw->state = OCS_HW_STATE_QUEUES_ALLOCATED;
1465 ocs_hw_get_num_eq(ocs_hw_t *hw)
1467 return hw->eq_count;
1471 ocs_hw_get_fw_timed_out(ocs_hw_t *hw)
1476 return (sli_reg_read(&hw->sli, SLI4_REG_SLIPORT_ERROR1) == 0x2 &&
1477 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_tgt_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);
1761 ocs_log_test(hw->os, "unsupported property %#x\n", prop);
1769 ocs_hw_get_ptr(ocs_hw_t *hw, ocs_hw_property_e prop)
1775 rc = sli_get_wwn_node(&hw->sli);
1778 rc = sli_get_wwn_port(&hw->sli);
1782 if (sli_get_vpd_len(&hw->sli)) {
1783 rc = sli_get_vpd(&hw->sli);
1787 rc = sli_get_fw_name(&hw->sli, 0);
1790 rc = sli_get_fw_name(&hw->sli, 1);
1793 rc = sli_get_ipl_name(&hw->sli);
1796 rc = sli_get_portnum(&hw->sli);
1799 rc = sli_get_bios_version_string(&hw->sli);
1802 ocs_log_test(hw->os, "unsupported property %#x\n", prop);
1811 ocs_hw_set(ocs_hw_t *hw, ocs_hw_property_e prop, uint32_t value)
1817 if (value > sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_XRI) ||
1819 ocs_log_test(hw->os, "IO value out of range %d vs %d\n",
1820 value, sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_XRI));
1823 hw->config.n_io = value;
1828 if (value > sli_get_max_sgl(&hw->sli)) {
1829 ocs_log_test(hw->os, "SGL value out of range %d vs %d\n",
1830 value, sli_get_max_sgl(&hw->sli));
1833 hw->config.n_sgl = value;
1837 if ((sli_get_medium(&hw->sli) != SLI_LINK_MEDIUM_FC) &&
1839 ocs_log_test(hw->os, "unsupported topology=%#x medium=%#x\n",
1840 value, sli_get_medium(&hw->sli));
1847 if (sli_get_medium(&hw->sli) == SLI_LINK_MEDIUM_FC) {
1848 sli_set_topology(&hw->sli, SLI4_READ_CFG_TOPO_FC);
1850 sli_set_topology(&hw->sli, SLI4_READ_CFG_TOPO_FCOE);
1854 sli_set_topology(&hw->sli, SLI4_READ_CFG_TOPO_FC_DA);
1857 sli_set_topology(&hw->sli, SLI4_READ_CFG_TOPO_FC_AL);
1860 ocs_log_test(hw->os, "unsupported topology %#x\n", value);
1863 hw->config.topology = value;
1866 if (sli_get_medium(&hw->sli) != SLI_LINK_MEDIUM_FC) {
1870 hw->config.speed = FC_LINK_SPEED_10G;
1873 ocs_log_test(hw->os, "unsupported speed=%#x medium=%#x\n",
1874 value, sli_get_medium(&hw->sli));
1882 hw->config.speed = FC_LINK_SPEED_AUTO_16_8_4;
1885 hw->config.speed = FC_LINK_SPEED_2G;
1888 hw->config.speed = FC_LINK_SPEED_4G;
1891 hw->config.speed = FC_LINK_SPEED_8G;
1894 hw->config.speed = FC_LINK_SPEED_16G;
1897 hw->config.speed = FC_LINK_SPEED_32G;
1900 ocs_log_test(hw->os, "unsupported speed %d\n", value);
1906 if (SLI4_IF_TYPE_LANCER_FC_ETH != sli_get_if_type(&hw->sli)) {
1907 ocs_log_test(hw->os, "DIF seed not supported for this device\n");
1910 hw->config.dif_seed = value;
1922 if (sli_is_dif_inline_capable(&hw->sli)) {
1923 hw->config.dif_mode = value;
1925 ocs_log_test(hw->os, "chip does not support DIF inline\n");
1931 if (sli_is_dif_separate_capable(&hw->sli)) {
1932 hw->config.dif_mode = value;
1934 ocs_log_test(hw->os, "chip does not support DIF separate\n");
1944 for (i = 0; i < hw->hw_rq_count; i++) {
1945 rq = hw->hw_rq[i];
1946 hw->cq[rq->cq->instance].proc_limit = value;
1951 hw->config.rq_default_buffer_size = value;
1954 hw->config.auto_xfer_rdy_xri_cnt = value;
1957 hw->config.auto_xfer_rdy_size = value;
1962 hw->config.auto_xfer_rdy_blk_size_chip = 0;
1965 hw->config.auto_xfer_rdy_blk_size_chip = 1;
1968 hw->config.auto_xfer_rdy_blk_size_chip = 2;
1971 hw->config.auto_xfer_rdy_blk_size_chip = 3;
1974 hw->config.auto_xfer_rdy_blk_size_chip = 4;
1977 ocs_log_err(hw->os, "Invalid block size %d\n",
1983 hw->config.auto_xfer_rdy_t10_enable = value;
1986 hw->config.auto_xfer_rdy_p_type = value;
1989 hw->config.auto_xfer_rdy_ref_tag_is_lba = value;
1992 hw->config.auto_xfer_rdy_app_tag_valid = value;
1995 hw->config.auto_xfer_rdy_app_tag_value = value;
1998 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_tgt_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);
2033 ocs_hw_set_ptr(ocs_hw_t *hw, ocs_hw_property_e prop, void *value)
2039 hw->hw_war_version = value;
2045 for (idx = 0; idx < ARRAY_SIZE(hw->config.filter_def); idx++) {
2046 hw->config.filter_def[idx] = 0;
2049 for (idx = 0; (idx < ARRAY_SIZE(hw->config.filter_def)) && (p != NULL) && *p; ) {
2050 hw->config.filter_def[idx++] = ocs_strtoul(p, 0, 0);
2060 ocs_log_test(hw->os, "unsupported property %#x\n", prop);
2070 * @param hw Hardware context.
2076 ocs_hw_event_check(ocs_hw_t *hw, uint32_t vector)
2080 if (!hw) {
2085 if (vector > hw->eq_count) {
2086 ocs_log_err(hw->os, "vector %d. max %d\n",
2087 vector, hw->eq_count);
2102 if (hw->state != OCS_HW_STATE_UNINITIALIZED) {
2103 rc = sli_queue_is_empty(&hw->sli, &hw->eq[vector]);
2107 sli_queue_arm(&hw->sli, &hw->eq[vector], TRUE);
2117 ocs_hw_t *hw = seq->hw;
2119 ocs_hw_assert(hw != NULL);
2120 ocs_hw_assert(hw->callback.unsolicited != NULL);
2122 hw->callback.unsolicited(hw->args.unsolicited, seq);
2126 ocs_hw_process(ocs_hw_t *hw, uint32_t vector, uint32_t max_isr_time_msec)
2144 if (hw->state == OCS_HW_STATE_UNINITIALIZED) {
2149 eq = hw->hw_eq[vector];
2153 rc = ocs_hw_eq_process(hw, eq, max_isr_time_msec);
2173 * @param hw Hardware context.
2180 ocs_hw_eq_process(ocs_hw_t *hw, hw_eq_t *eq, uint32_t max_isr_time_msec)
2193 while (!done && !sli_queue_read(&hw->sli, eq->queue, eqe)) {
2197 rc = sli_eq_parse(&hw->sli, eqe, &cq_id);
2206 for (i = 0; i < hw->cq_count; i++) {
2207 ocs_hw_cq_process(hw, hw->hw_cq[i]);
2214 int32_t index = ocs_hw_queue_hash_find(hw->cq_hash, cq_id);
2216 ocs_hw_cq_process(hw, hw->hw_cq[index]);
2218 ocs_log_err(hw->os, "bad CQ_ID %#06x\n", cq_id);
2224 sli_queue_arm(&hw->sli, eq->queue, FALSE);
2235 sli_queue_eq_arm(&hw->sli, eq->queue, TRUE);
2245 * --- Assumes that hw->cmd_lock is held ---
2247 * @param hw Hardware context.
2252 ocs_hw_cmd_submit_pending(ocs_hw_t *hw)
2260 while (hw->cmd_head_count < (OCS_HW_MQ_DEPTH - 1)) {
2261 ctx = ocs_list_remove_head(&hw->cmd_pending);
2265 ocs_list_add_tail(&hw->cmd_head, ctx);
2266 hw->cmd_head_count++;
2267 if (sli_queue_write(&hw->sli, hw->mq, ctx->buf) < 0) {
2268 ocs_log_test(hw->os, "sli_queue_write failed: %d\n", rc);
2284 * @param hw Hardware context.
2299 ocs_hw_command(ocs_hw_t *hw, uint8_t *cmd, uint32_t opts, void *cb, void *arg)
2307 if (sli_fw_error_status(&hw->sli) > 0) {
2308 uint32_t err1 = sli_reg_read(&hw->sli, SLI4_REG_SLIPORT_ERROR1);
2309 uint32_t err2 = sli_reg_read(&hw->sli, SLI4_REG_SLIPORT_ERROR2);
2310 if (hw->expiration_logged == 0 && err1 == 0x2 && err2 == 0x10) {
2311 hw->expiration_logged = 1;
2312 ocs_log_crit(hw->os,"Emulex: Heartbeat expired after %d seconds\n",
2313 hw->watchdog_timeout);
2315 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2316 ocs_log_crit(hw->os, "status=%#x error1=%#x error2=%#x\n",
2317 sli_reg_read(&hw->sli, SLI4_REG_SLIPORT_STATUS),
2325 ocs_lock(&hw->cmd_lock);
2326 if (hw->mq->length && !sli_queue_is_empty(&hw->sli, hw->mq)) {
2334 void *bmbx = hw->sli.bmbx.virt;
2339 if (sli_bmbx_command(&hw->sli) == 0) {
2344 ocs_unlock(&hw->cmd_lock);
2348 ctx = ocs_malloc(hw->os, sizeof(ocs_command_ctx_t), OCS_M_ZERO | OCS_M_NOWAIT);
2350 ocs_log_err(hw->os, "can't allocate command context\n");
2354 if (hw->state != OCS_HW_STATE_ACTIVE) {
2355 ocs_log_err(hw->os, "Can't send command, HW state=%d\n", hw->state);
2356 ocs_free(hw->os, ctx, sizeof(*ctx));
2365 ctx->ctx = hw;
2367 ocs_lock(&hw->cmd_lock);
2370 ocs_list_add_tail(&hw->cmd_pending, ctx);
2373 if (ocs_hw_cmd_submit_pending(hw) == 0) {
2377 ocs_unlock(&hw->cmd_lock);
2387 * @param hw Hardware context.
2395 ocs_hw_callback(ocs_hw_t *hw, ocs_hw_callback_e which, void *func, void *arg)
2398 if (!hw || !func || (which >= OCS_HW_CB_MAX)) {
2399 ocs_log_err(NULL, "bad parameter hw=%p which=%#x func=%p\n",
2400 hw, which, func);
2406 hw->callback.domain = func;
2407 hw->args.domain = arg;
2410 hw->callback.port = func;
2411 hw->args.port = arg;
2414 hw->callback.unsolicited = func;
2415 hw->args.unsolicited = arg;
2418 hw->callback.rnode = func;
2419 hw->args.rnode = arg;
2422 hw->callback.bounce = func;
2423 hw->args.bounce = arg;
2426 ocs_log_test(hw->os, "unknown callback %#x\n", which);
2441 * @param hw Hardware context.
2449 ocs_hw_port_alloc(ocs_hw_t *hw, ocs_sli_port_t *sport, ocs_domain_t *domain,
2457 sport->hw = hw;
2464 if (sli_fw_error_status(&hw->sli) > 0) {
2465 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2473 if (sli_resource_alloc(&hw->sli, SLI_RSRC_FCOE_VPI, &sport->indicator, &index)) {
2474 ocs_log_err(hw->os, "FCOE_VPI allocation failure\n");
2481 cmd = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
2483 ocs_log_err(hw->os, "command memory allocation failed\n");
2500 ocs_log_test(hw->os, "need WWN for physical port\n");
2509 ocs_free(hw->os, cmd, SLI4_BMBX_SIZE);
2511 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VPI, sport->indicator);
2525 * @param hw Hardware context.
2532 ocs_hw_port_attach(ocs_hw_t *hw, ocs_sli_port_t *sport, uint32_t fc_id)
2537 if (!hw || !sport) {
2538 ocs_log_err(hw ? hw->os : NULL,
2539 "bad parameter(s) hw=%p sport=%p\n", hw,
2547 if (sli_fw_error_status(&hw->sli) > 0) {
2548 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2552 buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
2554 ocs_log_err(hw->os, "no buffer for command\n");
2569 * @param hw Hardware context.
2577 ocs_hw_cb_port_control(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
2579 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
2600 * @param hw Hardware context.
2626 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)
2637 if (SLI_LINK_MEDIUM_FC == sli_get_medium(&hw->sli)) {
2640 cfg_link = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
2642 ocs_log_err(hw->os, "no buffer for command\n");
2646 if (sli_cmd_config_link(&hw->sli, cfg_link, SLI4_BMBX_SIZE)) {
2647 rc = ocs_hw_command(hw, cfg_link, OCS_CMD_NOWAIT,
2652 ocs_free(hw->os, cfg_link, SLI4_BMBX_SIZE);
2653 ocs_log_err(hw->os, "CONFIG_LINK failed\n");
2656 speed = hw->config.speed;
2665 if (hw->workaround.fw_version_too_low) {
2666 if (SLI4_IF_TYPE_LANCER_FC_ETH == hw->sli.if_type) {
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_LANCER), (char *) sli_get_fw_name(&hw->sli,0));
2670 ocs_log_err(hw->os, "Cannot bring up link. Please update firmware to %s or later (current version is %s)\n",
2671 OCS_FW_VER_STR(OCS_MIN_FW_VER_SKYHAWK), (char *) sli_get_fw_name(&hw->sli, 0));
2680 init_link = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
2682 ocs_log_err(hw->os, "no buffer for command\n");
2687 if (sli_cmd_init_link(&hw->sli, init_link, SLI4_BMBX_SIZE, speed, reset_alpa)) {
2688 rc = ocs_hw_command(hw, init_link, OCS_CMD_NOWAIT,
2693 ocs_free(hw->os, init_link, SLI4_BMBX_SIZE);
2694 ocs_log_err(hw->os, "INIT_LINK failed\n");
2702 down_link = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
2704 ocs_log_err(hw->os, "no buffer for command\n");
2707 if (sli_cmd_down_link(&hw->sli, down_link, SLI4_BMBX_SIZE)) {
2708 rc = ocs_hw_command(hw, down_link, OCS_CMD_NOWAIT,
2713 ocs_free(hw->os, down_link, SLI4_BMBX_SIZE);
2714 ocs_log_err(hw->os, "DOWN_LINK failed\n");
2719 rc = ocs_hw_set_linkcfg(hw, (ocs_hw_linkcfg_e)value, OCS_CMD_NOWAIT, cb, arg);
2722 ocs_log_test(hw->os, "unhandled control %#x\n", ctrl);
2737 * @param hw Hardware context.
2743 ocs_hw_port_free(ocs_hw_t *hw, ocs_sli_port_t *sport)
2747 if (!hw || !sport) {
2748 ocs_log_err(hw ? hw->os : NULL,
2749 "bad parameter(s) hw=%p sport=%p\n", hw,
2757 if (sli_fw_error_status(&hw->sli) > 0) {
2758 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2780 * @param hw Hardware context.
2788 ocs_hw_domain_alloc(ocs_hw_t *hw, ocs_domain_t *domain, uint32_t fcf, uint32_t vlan)
2793 if (!hw || !domain || !domain->sport) {
2794 ocs_log_err(NULL, "bad parameter(s) hw=%p domain=%p sport=%p\n",
2795 hw, domain, domain ? domain->sport : NULL);
2802 if (sli_fw_error_status(&hw->sli) > 0) {
2803 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2807 cmd = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
2809 ocs_log_err(hw->os, "command memory allocation failed\n");
2813 domain->dma = hw->domain_dmem;
2815 domain->hw = hw;
2822 if (sli_resource_alloc(&hw->sli, SLI_RSRC_FCOE_VFI, &domain->indicator, &index)) {
2823 ocs_log_err(hw->os, "FCOE_VFI allocation failure\n");
2825 ocs_free(hw->os, cmd, SLI4_BMBX_SIZE);
2838 * @param hw Hardware context.
2845 ocs_hw_domain_attach(ocs_hw_t *hw, ocs_domain_t *domain, uint32_t fc_id)
2850 if (!hw || !domain) {
2851 ocs_log_err(hw ? hw->os : NULL,
2852 "bad parameter(s) hw=%p domain=%p\n",
2853 hw, domain);
2860 if (sli_fw_error_status(&hw->sli) > 0) {
2861 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2865 buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
2867 ocs_log_err(hw->os, "no buffer for command\n");
2883 * @param hw Hardware context.
2889 ocs_hw_domain_free(ocs_hw_t *hw, ocs_domain_t *domain)
2893 if (!hw || !domain) {
2894 ocs_log_err(hw ? hw->os : NULL,
2895 "bad parameter(s) hw=%p domain=%p\n",
2896 hw, domain);
2903 if (sli_fw_error_status(&hw->sli) > 0) {
2904 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2921 * @param hw Hardware context.
2927 ocs_hw_domain_force_free(ocs_hw_t *hw, ocs_domain_t *domain)
2929 if (!hw || !domain) {
2930 ocs_log_err(NULL, "bad parameter(s) hw=%p domain=%p\n", hw, domain);
2934 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VFI, domain->indicator);
2943 * @param hw Hardware context.
2951 ocs_hw_node_alloc(ocs_hw_t *hw, ocs_remote_node_t *rnode, uint32_t fc_addr,
2956 ocs_log_err(hw->os, "FCOE_RPI allocation failure addr=%#x rpi=%#x\n",
2964 if (sli_fw_error_status(&hw->sli) > 0) {
2965 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
2972 if (sli_resource_alloc(&hw->sli, SLI_RSRC_FCOE_RPI, &rnode->indicator, &rnode->index)) {
2973 ocs_log_err(hw->os, "FCOE_RPI allocation failure addr=%#x\n",
2988 * @param hw Hardware context.
2995 ocs_hw_node_attach(ocs_hw_t *hw, ocs_remote_node_t *rnode, ocs_dma_t *sparms)
3001 if (!hw || !rnode || !sparms) {
3002 ocs_log_err(NULL, "bad parameter(s) hw=%p rnode=%p sparms=%p\n",
3003 hw, rnode, sparms);
3010 if (sli_fw_error_status(&hw->sli) > 0) {
3011 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
3015 buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
3017 ocs_log_err(hw->os, "no buffer for command\n");
3027 ocs_free(hw->os, buf, SLI4_BMBX_SIZE);
3030 count = ocs_atomic_add_return(&hw->rpi_ref[rnode->index].rpi_count, 1);
3036 if (sli_get_hlm(&hw->sli) == FALSE) {
3037 ocs_log_test(hw->os, "attach to already attached node HLM=%d count=%d\n",
3038 sli_get_hlm(&hw->sli), count);
3042 rnode->attached = ocs_atomic_read(&hw->rpi_ref[rnode->index].rpi_attached);
3049 if (sli_cmd_reg_rpi(&hw->sli, buf, SLI4_BMBX_SIZE, rnode->fc_id,
3051 sparms, 0, (hw->auto_xfer_rdy_enabled && hw->config.auto_xfer_rdy_t10_enable))) {
3052 rc = ocs_hw_command(hw, buf, OCS_CMD_NOWAIT,
3059 ocs_atomic_sub_return(&hw->rpi_ref[rnode->index].rpi_count, 1);
3060 ocs_log_err(hw->os, "%s error\n", count ? "HLM" : "REG_RPI");
3062 ocs_free(hw->os, buf, SLI4_BMBX_SIZE);
3072 * @param hw Hardware context.
3078 ocs_hw_node_free_resources(ocs_hw_t *hw, ocs_remote_node_t *rnode)
3082 if (!hw || !rnode) {
3083 ocs_log_err(NULL, "bad parameter(s) hw=%p rnode=%p\n",
3084 hw, rnode);
3091 if (sli_resource_free(&hw->sli, SLI_RSRC_FCOE_RPI, rnode->indicator)) {
3092 ocs_log_err(hw->os, "FCOE_RPI free failure RPI %d addr=%#x\n",
3103 ocs_log_err(hw->os, "Error: rnode is still attached\n");
3116 * @param hw Hardware context.
3122 ocs_hw_node_detach(ocs_hw_t *hw, ocs_remote_node_t *rnode)
3128 if (!hw || !rnode) {
3129 ocs_log_err(NULL, "bad parameter(s) hw=%p rnode=%p\n",
3130 hw, rnode);
3137 if (sli_fw_error_status(&hw->sli) > 0) {
3138 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
3152 buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
3154 ocs_log_err(hw->os, "no buffer for command\n");
3158 count = ocs_atomic_sub_return(&hw->rpi_ref[index].rpi_count, 1);
3167 if (sli_get_hlm(&hw->sli) == FALSE) {
3168 ocs_log_test(hw->os, "Invalid count with HLM disabled, count=%d\n",
3176 if (sli_cmd_unreg_rpi(&hw->sli, buf, SLI4_BMBX_SIZE, rnode->indicator,
3178 rc = ocs_hw_command(hw, buf, OCS_CMD_NOWAIT, ocs_hw_cb_node_free, rnode);
3182 ocs_log_err(hw->os, "UNREG_RPI failed\n");
3183 ocs_free(hw->os, buf, SLI4_BMBX_SIZE);
3195 * @param hw Hardware context.
3200 ocs_hw_node_free_all(ocs_hw_t *hw)
3205 if (!hw) {
3206 ocs_log_err(NULL, "bad parameter hw=%p\n", hw);
3213 if (sli_fw_error_status(&hw->sli) > 0) {
3214 ocs_log_crit(hw->os, "Chip is in an error state - reset needed\n");
3218 buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
3220 ocs_log_err(hw->os, "no buffer for command\n");
3224 if (sli_cmd_unreg_rpi(&hw->sli, buf, SLI4_BMBX_SIZE, 0xffff,
3226 rc = ocs_hw_command(hw, buf, OCS_CMD_NOWAIT, ocs_hw_cb_node_free_all,
3231 ocs_log_err(hw->os, "UNREG_RPI failed\n");
3232 ocs_free(hw->os, buf, SLI4_BMBX_SIZE);
3240 ocs_hw_node_group_alloc(ocs_hw_t *hw, ocs_remote_node_group_t *ngroup)
3243 if (!hw || !ngroup) {
3244 ocs_log_err(NULL, "bad parameter hw=%p ngroup=%p\n",
3245 hw, ngroup);
3249 if (sli_resource_alloc(&hw->sli, SLI_RSRC_FCOE_RPI, &ngroup->indicator,
3251 ocs_log_err(hw->os, "FCOE_RPI allocation failure addr=%#x\n",
3260 ocs_hw_node_group_attach(ocs_hw_t *hw, ocs_remote_node_group_t *ngroup, ocs_remote_node_t *rnode)
3263 if (!hw || !ngroup || !rnode) {
3264 ocs_log_err(NULL, "bad parameter hw=%p ngroup=%p rnode=%p\n",
3265 hw, ngroup, rnode);
3270 ocs_log_err(hw->os, "node already attached RPI=%#x addr=%#x\n",
3275 if (sli_resource_free(&hw->sli, SLI_RSRC_FCOE_RPI, rnode->indicator)) {
3276 ocs_log_err(hw->os, "FCOE_RPI free failure RPI=%#x\n",
3288 ocs_hw_node_group_free(ocs_hw_t *hw, ocs_remote_node_group_t *ngroup)
3292 if (!hw || !ngroup) {
3293 ocs_log_err(NULL, "bad parameter hw=%p ngroup=%p\n",
3294 hw, ngroup);
3298 ref = ocs_atomic_read(&hw->rpi_ref[ngroup->index].rpi_count);
3301 ocs_log_debug(hw->os, "node group reference=%d (RPI=%#x)\n",
3304 if (sli_resource_free(&hw->sli, SLI_RSRC_FCOE_RPI, ngroup->indicator)) {
3305 ocs_log_err(hw->os, "FCOE_RPI free failure RPI=%#x\n",
3310 ocs_atomic_set(&hw->rpi_ref[ngroup->index].rpi_count, 0);
3353 * Assume that hw->ocs_lock is held. This function is only used if
3356 * @param hw Hardware context.
3361 _ocs_hw_io_alloc(ocs_hw_t *hw)
3365 if (NULL != (io = ocs_list_remove_head(&hw->io_free))) {
3366 ocs_list_add_tail(&hw->io_inuse, io);
3373 ocs_atomic_add_return(&hw->io_alloc_failed_count, 1);
3386 * @param hw Hardware context.
3391 ocs_hw_io_alloc(ocs_hw_t *hw)
3395 ocs_lock(&hw->io_lock);
3396 io = _ocs_hw_io_alloc(hw);
3397 ocs_unlock(&hw->io_lock);
3413 * @param hw Hardware context.
3419 ocs_hw_io_activate_port_owned(ocs_hw_t *hw, ocs_hw_io_t *io)
3422 ocs_log_err(hw->os, "Bad parameter: refcount > 0\n");
3427 ocs_log_err(hw->os, "XRI %x already in use\n", io->indicator);
3443 * @n @b Note: Assumes that the hw->io_lock is held and the item has been removed
3446 * @param hw Hardware context.
3450 ocs_hw_io_free_move_correct_list(ocs_hw_t *hw, ocs_hw_io_t *io)
3454 ocs_list_add_tail(&hw->io_wait_free, io);
3458 ocs_list_add_tail(&hw->io_free, io);
3463 if (hw->workaround.use_dif_sec_xri) {
3464 ocs_hw_check_sec_hio_list(hw);
3473 * @param hw Hardware context.
3477 ocs_hw_io_free_common(ocs_hw_t *hw, ocs_hw_io_t *io)
3483 ocs_hw_io_restore_sgl(hw, io);
3496 ocs_hw_t *hw = io->hw;
3503 ocs_lock(&hw->io_lock);
3506 ocs_list_add_tail(&hw->io_port_dnrx, io);
3507 ocs_unlock(&hw->io_lock);
3511 ocs_hw_io_free_common(hw, io);
3525 ocs_hw_t *hw = io->hw;
3528 ocs_hw_io_free_common(hw, io);
3530 ocs_lock(&hw->io_lock);
3532 ocs_list_remove(&hw->io_inuse, io);
3533 ocs_hw_io_free_move_correct_list(hw, io);
3534 ocs_unlock(&hw->io_lock);
3544 * @param hw Hardware context.
3551 ocs_hw_io_free(ocs_hw_t *hw, ocs_hw_io_t *io)
3555 ocs_log_err(hw->os, "Bad parameter: refcount <= 0 xri=%x tag=%x\n",
3572 * @param hw Hardware context.
3578 ocs_hw_io_inuse(ocs_hw_t *hw, ocs_hw_io_t *io)
3615 queue_rc = _sli_queue_write(&wq->hw->sli, wq->queue, wqe->wqebuf);
3621 ocs_queue_history_wq(&wq->hw->q_hist, (void *) wqe->wqebuf, wq->queue->id, queue_rc);
3656 sli_abort_wqe(&wq->hw->sli, wqe->wqebuf, wq->hw->sli.config.wqe_size, SLI_ABORT_XRI,
3704 sli_abort_wqe(&wq->hw->sli, wqe->wqebuf, wq->hw->sli.config.wqe_size, SLI_ABORT_XRI,
3718 * Checks hw->sec_hio_wait_list, if an IO is waiting for a HW IO, then try
3721 * @n @b Note: hw->io_lock MUST be taken when called.
3723 * @param hw pointer to HW object
3728 ocs_hw_check_sec_hio_list(ocs_hw_t *hw)
3734 while (!ocs_list_empty(&hw->sec_hio_wait_list)) {
3737 sec_io = _ocs_hw_io_alloc(hw);
3742 io = ocs_list_remove_head(&hw->sec_hio_wait_list);
3743 ocs_list_add_tail(&hw->io_inuse, io);
3763 if (sli_fcp_cont_treceive64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &io->def_sgl,
3770 ocs_log_test(hw->os, "TRECEIVE WQE error\n");
3774 if (sli_fcp_treceive64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &io->def_sgl,
3782 ocs_log_test(hw->os, "TRECEIVE WQE error\n");
3788 io->wq = ocs_hw_queue_next_wq(hw, io);
3797 ocs_hw_add_io_timed_wqe(hw, io);
3804 ocs_log_err(hw->os, "sli_queue_write failed: %d\n", rc);
3806 ocs_hw_remove_io_timed_wqe(hw, io);
3829 * @param hw Hardware context.
3843 ocs_hw_srrs_send(ocs_hw_t *hw, ocs_hw_io_type_e type, ocs_hw_io_t *io,
3852 if (!hw || !io || !rnode || !iparam) {
3853 ocs_log_err(NULL, "bad parm hw=%p io=%p send=%p receive=%p rnode=%p iparam=%p\n",
3854 hw, io, send, receive, rnode, iparam);
3858 if (hw->state != OCS_HW_STATE_ACTIVE) {
3859 ocs_log_test(hw->os, "cannot send SRRS, HW state=%d\n", hw->state);
3863 if (ocs_hw_is_xri_port_owned(hw, io->indicator)) {
3896 if ( (!send) || sli_els_request64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, io->sgl,
3900 ocs_log_err(hw->os, "REQ WQE error\n");
3905 if ( (!send) || sli_xmit_els_rsp64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, send, len,
3909 ocs_log_err(hw->os, "RSP WQE error\n");
3914 if ( (!send) || sli_xmit_els_rsp64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, send, len,
3918 ocs_log_err(hw->os, "RSP (SID) WQE error\n");
3923 if ( (!send) || sli_gen_request64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, io->sgl, len,
3927 ocs_log_err(hw->os, "GEN WQE error\n");
3932 if ( (!send) || sli_xmit_sequence64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, io->sgl, len,
3936 ocs_log_err(hw->os, "XMIT SEQ WQE error\n");
3956 if (sli_xmit_bls_rsp64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &bls,
3960 ocs_log_err(hw->os, "XMIT_BLS_RSP64 WQE error\n");
3975 if (sli_xmit_bls_rsp64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &bls,
3979 ocs_log_err(hw->os, "XMIT_BLS_RSP64 WQE SID error\n");
3985 if ( (!send) || sli_xmit_bcast64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, send, len,
3989 ocs_log_err(hw->os, "XMIT_BCAST64 WQE error\n");
3994 ocs_log_err(hw->os, "bad SRRS type %#x\n", type);
4000 io->wq = ocs_hw_queue_next_wq(hw, io);
4010 ocs_hw_add_io_timed_wqe(hw, io);
4017 ocs_log_err(hw->os, "sli_queue_write failed: %d\n", rc);
4019 ocs_hw_remove_io_timed_wqe(hw, io);
4039 * @param hw Hardware context.
4055 ocs_hw_io_send(ocs_hw_t *hw, ocs_hw_io_type_e type, ocs_hw_io_t *io,
4065 if (!hw || !io || !rnode || !iparam) {
4066 ocs_log_err(NULL, "bad parm hw=%p io=%p iparam=%p rnode=%p\n",
4067 hw, io, iparam, rnode);
4071 if (hw->state != OCS_HW_STATE_ACTIVE) {
4072 ocs_log_err(hw->os, "cannot send IO, HW state=%d\n", hw->state);
4078 if (hw->workaround.use_unregistered_rpi && (rpi == UINT32_MAX)) {
4079 rpi = hw->workaround.unregistered_rid;
4080 ocs_log_test(hw->os, "using unregistered RPI: %d\n", rpi);
4100 if (hw->workaround.use_dif_quarantine && (hw->config.dif_mode == OCS_HW_DIF_MODE_SEPARATE) &&
4105 ocs_hw_io_ini_sge(hw, io, iparam->fcp_ini.cmnd, iparam->fcp_ini.cmnd_size,
4108 if (sli_fcp_iread64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &io->def_sgl, io->first_data_sge, len,
4112 ocs_log_err(hw->os, "IREAD WQE error\n");
4117 ocs_hw_io_ini_sge(hw, io, iparam->fcp_ini.cmnd, iparam->fcp_ini.cmnd_size,
4120 if (sli_fcp_iwrite64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &io->def_sgl, io->first_data_sge,
4126 ocs_log_err(hw->os, "IWRITE WQE error\n");
4131 ocs_hw_io_ini_sge(hw, io, iparam->fcp_ini.cmnd, iparam->fcp_ini.cmnd_size,
4134 if (sli_fcp_icmnd64_wqe(&hw->sli, io->wqe.wqebuf, hw->sli.config.wqe_size, &io->def_sgl,
4137 ocs_log_err(hw->os, "ICMND WQE error\n");
4164 if (hw->workaround.use_dif_quarantine && (hw->config.dif_mode == OCS_HW_DIF_MODE_SEPARATE) &&
4174 * are on hw->sec_hio_wait_list. If this secondary XRI is not for the first
4177 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.
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.
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.
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.
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.
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);
5079 * @param hw Hardware context.
5093 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)
5095 if (hw->sli.if_type == SLI4_IF_TYPE_LANCER_FC_ETH) {
5096 return ocs_hw_firmware_write_lancer(hw, dma, size, offset, last, cb, arg);
5112 * @param hw Hardware context.
5125 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)
5132 if (SLI4_IF_TYPE_LANCER_FC_ETH != sli_get_if_type(&hw->sli)) {
5133 ocs_log_test(hw->os, "Function only supported for I/F type 2\n");
5137 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
5139 ocs_log_err(hw->os, "failed to malloc mbox\n");
5143 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_fw_write_cb_arg_t), OCS_M_NOWAIT);
5145 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
5146 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5153 if (sli_cmd_common_write_object(&hw->sli, mbxdata, SLI4_BMBX_SIZE, noc, last,
5155 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_cb_fw_write, cb_arg);
5159 ocs_log_test(hw->os, "COMMON_WRITE_OBJECT failed\n");
5160 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5161 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_fw_write_cb_arg_t));
5176 * @param hw Hardware context.
5185 ocs_hw_cb_fw_write(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
5199 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
5209 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_fw_write_cb_arg_t));
5223 * @param hw Hardware context.
5233 ocs_hw_cb_sfp(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
5249 cb_arg->cb(hw->os, status, bytes_written, mbox_rsp->page_data, cb_arg->arg);
5252 ocs_dma_free(hw->os, &cb_arg->payload);
5253 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_sfp_cb_arg_t));
5256 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
5264 * @param hw Hardware context.
5272 ocs_hw_get_sfp(ocs_hw_t *hw, uint16_t page, ocs_hw_sfp_cb_t cb, void *arg)
5279 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
5281 ocs_log_err(hw->os, "failed to malloc mbox\n");
5286 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_sfp_cb_arg_t), OCS_M_NOWAIT);
5288 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
5289 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5297 if (ocs_dma_alloc(hw->os, &cb_arg->payload, sizeof(sli4_res_common_read_transceiver_data_t),
5299 ocs_log_err(hw->os, "Failed to allocate DMA buffer\n");
5300 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_sfp_cb_arg_t));
5301 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5306 if (sli_cmd_common_read_transceiver_data(&hw->sli, mbxdata, SLI4_BMBX_SIZE, page,
5308 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_cb_sfp, cb_arg);
5312 ocs_log_test(hw->os, "READ_TRANSCEIVER_DATA failed with status %d\n",
5314 ocs_dma_free(hw->os, &cb_arg->payload);
5315 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_sfp_cb_arg_t));
5316 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5325 * @param hw Hardware context.
5332 ocs_hw_get_temperature(ocs_hw_t *hw, ocs_hw_temp_cb_t cb, void *arg)
5338 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
5340 ocs_log_err(hw->os, "failed to malloc mbox");
5344 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_temp_cb_arg_t), OCS_M_NOWAIT);
5346 ocs_log_err(hw->os, "failed to malloc cb_arg");
5347 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5354 if (sli_cmd_dump_type4(&hw->sli, mbxdata, SLI4_BMBX_SIZE,
5356 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_cb_temp, cb_arg);
5360 ocs_log_test(hw->os, "DUMP_TYPE4 failed\n");
5361 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5362 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_temp_cb_arg_t));
5375 * @param hw Hardware context.
5384 ocs_hw_cb_temp(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
5411 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_temp_cb_arg_t));
5413 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
5421 * @param hw Hardware context.
5431 ocs_hw_get_link_stats(ocs_hw_t *hw,
5442 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
5444 ocs_log_err(hw->os, "failed to malloc mbox");
5448 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_link_stat_cb_arg_t), OCS_M_NOWAIT);
5450 ocs_log_err(hw->os, "failed to malloc cb_arg");
5451 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5458 if (sli_cmd_read_link_stats(&hw->sli, mbxdata, SLI4_BMBX_SIZE,
5462 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_cb_link_stat, cb_arg);
5466 ocs_log_test(hw->os, "READ_LINK_STATS failed\n");
5467 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5468 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_link_stat_cb_arg_t));
5481 * @param hw Hardware context.
5490 ocs_hw_cb_link_stat(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
5554 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_link_stat_cb_arg_t));
5556 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
5564 * @param hw Hardware context.
5572 ocs_hw_get_host_stats(ocs_hw_t *hw, uint8_t cc, ocs_hw_host_stat_cb_t cb, void *arg)
5578 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO);
5580 ocs_log_err(hw->os, "failed to malloc mbox");
5584 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_host_stat_cb_arg_t), 0);
5586 ocs_log_err(hw->os, "failed to malloc cb_arg");
5587 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5595 if (sli_cmd_read_status(&hw->sli, mbxdata, SLI4_BMBX_SIZE, cc)) {
5596 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_cb_host_stat, cb_arg);
5600 ocs_log_test(hw->os, "READ_HOST_STATS failed\n");
5601 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5602 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_host_stat_cb_arg_t));
5617 * @param hw Hardware context.
5627 ocs_hw_cb_host_stat(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
5665 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_host_stat_cb_arg_t));
5667 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
5816 * @param hw Hardware context.
5826 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)
5828 if (!sli_link_is_configurable(&hw->sli)) {
5829 ocs_log_debug(hw->os, "Function not supported\n");
5833 if (SLI4_IF_TYPE_LANCER_FC_ETH == sli_get_if_type(&hw->sli)) {
5834 return ocs_hw_set_linkcfg_lancer(hw, value, opts, cb, arg);
5835 } else if ((SLI4_IF_TYPE_BE3_SKH_PF == sli_get_if_type(&hw->sli)) ||
5836 (SLI4_IF_TYPE_BE3_SKH_VF == sli_get_if_type(&hw->sli))) {
5837 return ocs_hw_set_linkcfg_skyhawk(hw, value, opts, cb, arg);
5839 ocs_log_test(hw->os, "Function not supported for this IF_TYPE\n");
5847 * @param hw Hardware context.
5857 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)
5868 cb_arg = ocs_malloc(hw->os, sizeof(*cb_arg), OCS_M_NOWAIT);
5870 ocs_log_err(hw->os, "failed to malloc cb_arg");
5876 if (ocs_dma_alloc(hw->os, &cb_arg->dma_cmd, ocs_strlen(cmd)+1, 4096)) {
5877 ocs_log_err(hw->os, "malloc failed\n");
5878 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
5885 if (ocs_dma_alloc(hw->os, &cb_arg->dma_resp, OCS_HW_DMTF_CLP_RSP_MAX, 4096)) {
5886 ocs_log_err(hw->os, "malloc failed\n");
5887 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
5888 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
5895 rc = ocs_hw_exec_dmtf_clp_cmd(hw, &cb_arg->dma_cmd, &cb_arg->dma_resp,
5903 ocs_log_test(hw->os, "CLP cmd=\"%s\" failed\n",
5906 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
5907 ocs_dma_free(hw->os, &cb_arg->dma_resp);
5908 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
5916 * @param hw Hardware context.
5924 ocs_hw_set_active_link_config_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
5929 ocs_log_test(hw->os, "SET_RECONFIG_LINK_ID failed, status=%d\n", status);
5939 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
5946 * @param hw Hardware context.
5956 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)
5966 ocs_log_test(hw->os, "Link config %d not supported by Skyhawk\n", value);
5971 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
5973 ocs_log_err(hw->os, "failed to malloc mbox\n");
5978 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_linkcfg_cb_arg_t), OCS_M_NOWAIT);
5980 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
5981 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5988 if (sli_cmd_common_set_reconfig_link_id(&hw->sli, mbxdata, SLI4_BMBX_SIZE, NULL, 0, config_id)) {
5989 rc = ocs_hw_command(hw, mbxdata, opts, ocs_hw_set_active_link_config_cb, cb_arg);
5993 ocs_log_err(hw->os, "SET_RECONFIG_LINK_ID failed\n");
5994 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
5995 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_linkcfg_cb_arg_t));
5998 ocs_hw_set_active_link_config_cb(hw, 0, mbxdata, cb_arg);
5999 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6000 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_linkcfg_cb_arg_t));
6003 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6012 * @param hw Hardware context.
6020 ocs_hw_get_linkcfg(ocs_hw_t *hw, uint32_t opts, ocs_hw_port_control_cb_t cb, void *arg)
6022 if (!sli_link_is_configurable(&hw->sli)) {
6023 ocs_log_debug(hw->os, "Function not supported\n");
6027 if (SLI4_IF_TYPE_LANCER_FC_ETH == sli_get_if_type(&hw->sli)) {
6028 return ocs_hw_get_linkcfg_lancer(hw, opts, cb, arg);
6029 } else if ((SLI4_IF_TYPE_BE3_SKH_PF == sli_get_if_type(&hw->sli)) ||
6030 (SLI4_IF_TYPE_BE3_SKH_VF == sli_get_if_type(&hw->sli))) {
6031 return ocs_hw_get_linkcfg_skyhawk(hw, opts, cb, arg);
6033 ocs_log_test(hw->os, "Function not supported for this IF_TYPE\n");
6041 * @param hw Hardware context.
6049 ocs_hw_get_linkcfg_lancer(ocs_hw_t *hw, uint32_t opts, ocs_hw_port_control_cb_t cb, void *arg)
6056 cb_arg = ocs_malloc(hw->os, sizeof(*cb_arg), OCS_M_NOWAIT);
6058 ocs_log_err(hw->os, "failed to malloc cb_arg");
6065 if (ocs_dma_alloc(hw->os, &cb_arg->dma_cmd, ocs_strlen(cmd)+1, 4096)) {
6066 ocs_log_err(hw->os, "malloc failed\n");
6067 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6076 if (ocs_dma_alloc(hw->os, &cb_arg->dma_resp, OCS_HW_DMTF_CLP_RSP_MAX, 4096)) {
6077 ocs_log_err(hw->os, "malloc failed\n");
6078 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
6079 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6086 rc = ocs_hw_exec_dmtf_clp_cmd(hw, &cb_arg->dma_cmd, &cb_arg->dma_resp,
6094 ocs_log_test(hw->os, "CLP cmd=\"%s\" failed\n",
6097 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
6098 ocs_dma_free(hw->os, &cb_arg->dma_resp);
6099 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6108 * @param hw Hardware context.
6116 ocs_hw_get_active_link_config_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
6123 ocs_log_test(hw->os, "GET_RECONFIG_LINK_INFO failed, status=%d\n", status);
6136 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
6137 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6144 * @param hw Hardware context.
6152 ocs_hw_get_linkcfg_skyhawk(ocs_hw_t *hw, uint32_t opts, ocs_hw_port_control_cb_t cb, void *arg)
6159 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
6161 ocs_log_err(hw->os, "failed to malloc mbox\n");
6166 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_linkcfg_cb_arg_t), OCS_M_NOWAIT);
6168 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
6169 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6178 if (ocs_dma_alloc(hw->os, &cb_arg->dma_cmd, sizeof(sli4_res_common_get_reconfig_link_info_t), 4)) {
6179 ocs_log_err(hw->os, "Failed to allocate DMA buffer\n");
6180 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6181 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_linkcfg_cb_arg_t));
6185 if (sli_cmd_common_get_reconfig_link_info(&hw->sli, mbxdata, SLI4_BMBX_SIZE, &cb_arg->dma_cmd)) {
6186 rc = ocs_hw_command(hw, mbxdata, opts, ocs_hw_get_active_link_config_cb, cb_arg);
6190 ocs_log_err(hw->os, "GET_RECONFIG_LINK_INFO failed\n");
6191 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6192 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
6193 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_linkcfg_cb_arg_t));
6196 ocs_hw_get_active_link_config_cb(hw, 0, mbxdata, cb_arg);
6197 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6198 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
6199 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_linkcfg_cb_arg_t));
6202 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6211 * @param hw Hardware context.
6216 ocs_hw_set_dif_seed(ocs_hw_t *hw)
6223 seed_param.seed = hw->config.dif_seed;
6226 if (sli_cmd_common_set_features(&hw->sli, buf, SLI4_BMBX_SIZE,
6230 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
6232 ocs_log_err(hw->os, "ocs_hw_command returns %d\n", rc);
6234 ocs_log_debug(hw->os, "DIF seed set to 0x%x\n",
6235 hw->config.dif_seed);
6238 ocs_log_err(hw->os, "sli_cmd_common_set_features failed\n");
6248 * @param hw Hardware context.
6253 ocs_hw_set_dif_mode(ocs_hw_t *hw)
6260 mode_param.tmm = (hw->config.dif_mode == OCS_HW_DIF_MODE_INLINE ? 0 : 1);
6263 if (sli_cmd_common_set_features(&hw->sli, buf, SLI4_BMBX_SIZE,
6267 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
6269 ocs_log_err(hw->os, "ocs_hw_command returns %d\n", rc);
6271 ocs_log_test(hw->os, "DIF mode set to %s\n",
6272 (hw->config.dif_mode == OCS_HW_DIF_MODE_INLINE ? "inline" : "separate"));
6275 ocs_log_err(hw->os, "sli_cmd_common_set_features failed\n");
6284 ocs_hw_t *hw = (ocs_hw_t *)arg;
6286 ocs_hw_config_watchdog_timer(hw);
6291 ocs_hw_cb_cfg_watchdog(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
6293 uint16_t timeout = hw->watchdog_timeout;
6296 ocs_log_err(hw->os, "config watchdog timer failed, rc = %d\n", status);
6300 ocs_setup_timer(hw->os, &hw->watchdog_timer, ocs_hw_watchdog_timer_cb, hw, (timeout*1000 - 500) );
6302 ocs_del_timer(&hw->watchdog_timer);
6306 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
6313 * @param hw Hardware context.
6319 ocs_hw_config_watchdog_timer(ocs_hw_t *hw)
6322 uint8_t *buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
6324 sli4_cmd_lowlevel_set_watchdog(&hw->sli, buf, SLI4_BMBX_SIZE, hw->watchdog_timeout);
6325 rc = ocs_hw_command(hw, buf, OCS_CMD_NOWAIT, ocs_hw_cb_cfg_watchdog, NULL);
6327 ocs_free(hw->os, buf, SLI4_BMBX_SIZE);
6328 ocs_log_err(hw->os, "config watchdog timer failed, rc = %d\n", rc);
6336 * @param hw Hardware context.
6342 ocs_hw_config_auto_xfer_rdy_t10pi(ocs_hw_t *hw, uint8_t *buf)
6348 param.rtc = (hw->config.auto_xfer_rdy_ref_tag_is_lba ? 0 : 1);
6349 param.atv = (hw->config.auto_xfer_rdy_app_tag_valid ? 1 : 0);
6350 param.tmm = ((hw->config.dif_mode == OCS_HW_DIF_MODE_INLINE) ? 0 : 1);
6351 param.app_tag = hw->config.auto_xfer_rdy_app_tag_value;
6352 param.blk_size = hw->config.auto_xfer_rdy_blk_size_chip;
6354 switch (hw->config.auto_xfer_rdy_p_type) {
6362 ocs_log_err(hw->os, "unsupported p_type %d\n",
6363 hw->config.auto_xfer_rdy_p_type);
6368 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",
6390 * @param hw Hardware context.
6399 ocs_hw_config_sli_port_health_check(ocs_hw_t *hw, uint8_t query, uint8_t enable)
6410 sli_cmd_common_set_features(&hw->sli, buf, SLI4_BMBX_SIZE,
6415 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
6417 ocs_log_err(hw->os, "ocs_hw_command returns %d\n", rc);
6419 ocs_log_test(hw->os, "SLI Port Health Check is enabled \n");
6428 * @param hw Hardware context.
6434 ocs_hw_config_set_fdt_xfer_hint(ocs_hw_t *hw, uint32_t fdt_xfer_hint)
6443 sli_cmd_common_set_features(&hw->sli, buf, SLI4_BMBX_SIZE,
6449 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL, NULL, NULL);
6451 ocs_log_warn(hw->os, "set FDT hint %d failed: %d\n", fdt_xfer_hint, rc);
6453 ocs_log_debug(hw->os, "Set FTD transfer hint to %d\n", param.fdt_xfer_hint);
6462 * @param hw Hardware context.
6470 ocs_hw_linkcfg_dmtf_clp_cb(ocs_hw_t *hw, int32_t status, uint32_t result_len, void *arg)
6478 ocs_log_test(hw->os, "CLP cmd failed, status=%d\n", status);
6481 rval = ocs_hw_clp_resp_get_value(hw, "retdata", retdata_str,
6487 ocs_log_err(hw->os, "failed to get retdata %d\n", result_len);
6489 /* translate string into hw enum */
6501 ocs_dma_free(hw->os, &cb_arg->dma_cmd);
6502 ocs_dma_free(hw->os, &cb_arg->dma_resp);
6503 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6513 * @param hw Hardware context.
6520 ocs_hw_set_dump_location(ocs_hw_t *hw, uint32_t num_buffers, ocs_dma_t *dump_buffers, uint8_t fdb)
6530 if (hw->workaround.disable_dump_loc) {
6531 ocs_log_test(hw->os, "FW version is too old for this feature\n");
6536 ocs_get_bus_dev_func(hw->os, &bus, &dev, &func);
6538 ocs_log_test(hw->os, "function only valid for pci function 0, %d passed\n",
6552 if (hw->dump_sges.size < sge_size) {
6553 ocs_dma_free(hw->os, &hw->dump_sges);
6554 if (ocs_dma_alloc(hw->os, &hw->dump_sges, sge_size, OCS_MIN_DMA_ALIGNMENT)) {
6555 ocs_log_err(hw->os, "SGE DMA allocation failed\n");
6560 ocs_memset(hw->dump_sges.virt, 0, hw->dump_sges.size);
6561 hw->dump_sges.len = sge_size;
6562 sge = hw->dump_sges.virt;
6569 rc = sli_cmd_common_set_dump_location(&hw->sli, (void *)buf,
6571 &hw->dump_sges, fdb);
6574 rc = sli_cmd_common_set_dump_location(&hw->sli, (void *)buf,
6580 rc = ocs_hw_command(hw, buf, OCS_CMD_POLL,
6583 ocs_log_err(hw->os, "ocs_hw_command returns %d\n",
6587 ocs_log_err(hw->os,
6605 * @param hw Hardware context.
6611 ocs_hw_set_eth_license(ocs_hw_t *hw, uint32_t license)
6619 if (SLI4_IF_TYPE_LANCER_FC_ETH != sli_get_if_type(&hw->sli)) {
6620 ocs_log_test(hw->os, "Function only supported for I/F type 2\n");
6626 if (ocs_dma_alloc(hw->os, &dma_cmd, ocs_strlen(cmd)+1, 4096)) {
6627 ocs_log_err(hw->os, "malloc failed\n");
6634 if (ocs_dma_alloc(hw->os, &dma_resp, OCS_HW_DMTF_CLP_RSP_MAX, 4096)) {
6635 ocs_log_err(hw->os, "malloc failed\n");
6636 ocs_dma_free(hw->os, &dma_cmd);
6641 if (ocs_hw_exec_dmtf_clp_cmd(hw, &dma_cmd, &dma_resp, OCS_CMD_POLL, NULL, NULL)) {
6642 ocs_log_err(hw->os, "CLP cmd=\"%s\" failed\n", (char *)dma_cmd.virt);
6646 ocs_dma_free(hw->os, &dma_cmd);
6647 ocs_dma_free(hw->os, &dma_resp);
6665 * @param hw Hardware context.
6676 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)
6683 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
6685 ocs_log_err(hw->os, "failed to malloc mbox\n");
6690 cb_arg = ocs_malloc(hw->os, sizeof(*cb_arg), OCS_M_NOWAIT);
6692 ocs_log_err(hw->os, "failed to malloc cb_arg");
6693 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6703 if (sli_cmd_dmtf_exec_clp_cmd(&hw->sli, mbxdata, SLI4_BMBX_SIZE,
6705 rc = ocs_hw_command(hw, mbxdata, opts, ocs_hw_dmtf_clp_cb, cb_arg);
6710 ocs_memcpy(mbxdata, hw->sli.bmbx.virt, SLI4_BMBX_SIZE);
6711 ocs_hw_dmtf_clp_cb(hw, 0, mbxdata, cb_arg);
6720 ocs_log_test(hw->os, "ocs_hw_command failed\n");
6722 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6723 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6726 ocs_log_test(hw->os, "sli_cmd_dmtf_exec_clp_cmd failed\n");
6728 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
6729 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6739 * @param hw Hardware context.
6748 ocs_hw_dmtf_clp_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
6762 ocs_log_debug(hw->os, "status=x%x/x%x/x%x addl=x%x clp=x%x detail=x%x\n",
6785 ocs_log_test(hw->os, "Invalid response length: resp_len=%zu result len=%d\n",
6792 stat_len = ocs_hw_clp_resp_get_value(hw, "status", stat_str,
6798 ocs_log_test(hw->os, "failed to get status %d\n", stat_len);
6804 ocs_log_test(hw->os, "CLP status indicates failure=%s\n", stat_str);
6814 cb_arg->cb(hw, cb_status, result_len, cb_arg->arg);
6818 ocs_free(hw->os, cb_arg, sizeof(*cb_arg));
6819 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
6827 * @param hw Hardware context.
6839 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)
6847 ocs_log_test(hw->os, "could not find keyword=%s in CLP response\n",
6855 ocs_log_test(hw->os, "could not find \'=\' in CLP response for keyword=%s\n",
6864 ocs_log_test(hw->os, "could not find \\r\\n for keyword=%s in CLP response\n",
6871 ocs_log_test(hw->os, "value len=%d not large enough for actual=%ld\n",
6889 * @param hw Hardware context.
6896 ocs_hw_raise_ue(ocs_hw_t *hw, uint8_t dump)
6900 if (sli_raise_ue(&hw->sli, dump) != 0) {
6903 if (hw->state != OCS_HW_STATE_UNINITIALIZED) {
6904 hw->state = OCS_HW_STATE_QUEUES_ALLOCATED;
6919 * @param hw Hardware context.
6928 ocs_hw_cb_dump_get(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
6947 ocs_free(hw->os, cb_arg->mbox_cmd, SLI4_BMBX_SIZE);
6948 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_dump_get_cb_arg_t));
6964 * @param hw Hardware context.
6976 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)
6981 uint32_t opts = (hw->state == OCS_HW_STATE_ACTIVE ? OCS_CMD_NOWAIT : OCS_CMD_POLL);
6983 if (SLI4_IF_TYPE_LANCER_FC_ETH != sli_get_if_type(&hw->sli)) {
6984 ocs_log_test(hw->os, "Function only supported for I/F type 2\n");
6988 if (1 != sli_dump_is_present(&hw->sli)) {
6989 ocs_log_test(hw->os, "No dump is present\n");
6993 if (1 == sli_reset_required(&hw->sli)) {
6994 ocs_log_test(hw->os, "device reset required\n");
6998 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7000 ocs_log_err(hw->os, "failed to malloc mbox\n");
7004 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_dump_get_cb_arg_t), OCS_M_NOWAIT);
7006 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7007 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7015 if (sli_cmd_common_read_object(&hw->sli, mbxdata, SLI4_BMBX_SIZE,
7017 rc = ocs_hw_command(hw, mbxdata, opts, ocs_hw_cb_dump_get, cb_arg);
7019 ocs_memcpy(mbxdata, hw->sli.bmbx.virt, SLI4_BMBX_SIZE);
7020 rc = ocs_hw_cb_dump_get(hw, 0, mbxdata, cb_arg);
7025 ocs_log_test(hw->os, "COMMON_READ_OBJECT failed\n");
7026 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7027 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_dump_get_cb_arg_t));
7040 * @param hw Hardware context.
7049 ocs_hw_cb_dump_clear(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
7062 ocs_free(hw->os, cb_arg->mbox_cmd, SLI4_BMBX_SIZE);
7063 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_dump_clear_cb_arg_t));
7078 * @param hw Hardware context.
7087 ocs_hw_dump_clear(ocs_hw_t *hw, ocs_hw_dump_clear_cb_t cb, void *arg)
7092 uint32_t opts = (hw->state == OCS_HW_STATE_ACTIVE ? OCS_CMD_NOWAIT : OCS_CMD_POLL);
7094 if (SLI4_IF_TYPE_LANCER_FC_ETH != sli_get_if_type(&hw->sli)) {
7095 ocs_log_test(hw->os, "Function only supported for I/F type 2\n");
7099 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7101 ocs_log_err(hw->os, "failed to malloc mbox\n");
7105 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_dump_clear_cb_arg_t), OCS_M_NOWAIT);
7107 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7108 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7116 if (sli_cmd_common_delete_object(&hw->sli, mbxdata, SLI4_BMBX_SIZE,
7118 rc = ocs_hw_command(hw, mbxdata, opts, ocs_hw_cb_dump_clear, cb_arg);
7120 ocs_memcpy(mbxdata, hw->sli.bmbx.virt, SLI4_BMBX_SIZE);
7121 rc = ocs_hw_cb_dump_clear(hw, 0, mbxdata, cb_arg);
7126 ocs_log_test(hw->os, "COMMON_DELETE_OBJECT failed\n");
7127 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7128 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_dump_clear_cb_arg_t));
7145 * @param hw Hardware context.
7153 ocs_hw_get_port_protocol_cb(ocs_hw_t *hw, int32_t status,
7198 ocs_dma_free(hw->os, &cb_arg->payload);
7199 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_port_protocol_cb_arg_t));
7200 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
7213 * @param hw Hardware context.
7226 ocs_hw_get_port_protocol(ocs_hw_t *hw, uint32_t pci_func,
7234 if (sli_get_if_type(&hw->sli) != SLI4_IF_TYPE_BE3_SKH_PF) {
7239 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7241 ocs_log_err(hw->os, "failed to malloc mbox\n");
7247 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_get_port_protocol_cb_arg_t), OCS_M_NOWAIT);
7249 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7250 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7259 if (ocs_dma_alloc(hw->os, &cb_arg->payload, 4096, 4)) {
7260 ocs_log_err(hw->os, "Failed to allocate DMA buffer\n");
7261 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7262 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_port_protocol_cb_arg_t));
7266 if (sli_cmd_common_get_profile_config(&hw->sli, mbxdata, SLI4_BMBX_SIZE, &cb_arg->payload)) {
7267 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_get_port_protocol_cb, cb_arg);
7271 ocs_log_test(hw->os, "GET_PROFILE_CONFIG failed\n");
7272 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7273 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_fw_write_cb_arg_t));
7274 ocs_dma_free(hw->os, &cb_arg->payload);
7299 * @param hw Hardware context.
7307 ocs_hw_set_port_protocol_cb2(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
7315 ocs_dma_free(hw->os, &(cb_arg->payload));
7316 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
7317 ocs_free(hw->os, arg, sizeof(ocs_hw_set_port_protocol_cb_arg_t));
7338 * @param hw Hardware context.
7346 ocs_hw_set_port_protocol_cb1(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
7380 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7382 ocs_log_err(hw->os, "failed to malloc mbox\n");
7388 new_cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_set_port_protocol_cb_arg_t), OCS_M_NOWAIT);
7390 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7391 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7400 if (ocs_dma_alloc(hw->os, &new_cb_arg->payload, sizeof(sli4_req_common_set_profile_config_t) +
7403 ocs_log_err(hw->os, "Failed to allocate DMA buffer\n");
7404 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7405 ocs_free(hw->os, new_cb_arg, sizeof(ocs_hw_set_port_protocol_cb_arg_t));
7409 sli_cmd_common_set_profile_config(&hw->sli, mbxdata, SLI4_BMBX_SIZE,
7473 ocs_dma_free(hw->os, &cb_arg->payload);
7474 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
7475 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_set_port_protocol_cb_arg_t));
7479 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_set_port_protocol_cb2, new_cb_arg);
7481 ocs_log_err(hw->os, "Error posting COMMON_SET_PROFILE_CONFIG\n");
7488 ocs_dma_free(hw->os, &new_cb_arg->payload);
7489 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7490 ocs_free(hw->os, new_cb_arg, sizeof(ocs_hw_set_port_protocol_cb_arg_t));
7510 * @param hw Hardware context.
7524 ocs_hw_set_port_protocol(ocs_hw_t *hw, ocs_hw_port_protocol_e new_protocol,
7532 if (sli_get_if_type(&hw->sli) != SLI4_IF_TYPE_BE3_SKH_PF) {
7537 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7539 ocs_log_err(hw->os, "failed to malloc mbox\n");
7545 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_set_port_protocol_cb_arg_t), OCS_M_NOWAIT);
7547 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7548 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7558 if (ocs_dma_alloc(hw->os, &cb_arg->payload, 4096, 4)) {
7559 ocs_log_err(hw->os, "Failed to allocate DMA buffer\n");
7560 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7561 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_port_protocol_cb_arg_t));
7565 if (sli_cmd_common_get_profile_config(&hw->sli, mbxdata, SLI4_BMBX_SIZE, &cb_arg->payload)) {
7566 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_set_port_protocol_cb1, cb_arg);
7570 ocs_log_test(hw->os, "GET_PROFILE_CONFIG failed\n");
7571 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7572 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_fw_write_cb_arg_t));
7573 ocs_dma_free(hw->os, &cb_arg->payload);
7595 * @param hw Hardware context.
7603 ocs_hw_get_profile_list_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
7612 list = ocs_malloc(hw->os, sizeof(ocs_hw_profile_list_t), OCS_M_ZERO);
7629 ocs_free(hw->os, list, sizeof(*list));
7632 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
7633 ocs_dma_free(hw->os, &cb_arg->payload);
7634 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_profile_list_cb_arg_t));
7647 * @param hw Hardware context.
7661 ocs_hw_get_profile_list(ocs_hw_t *hw, ocs_get_profile_list_cb_t cb, void* ul_arg)
7668 if (sli_get_if_type(&hw->sli) != SLI4_IF_TYPE_BE3_SKH_PF) {
7673 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7675 ocs_log_err(hw->os, "failed to malloc mbox\n");
7681 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_get_profile_list_cb_arg_t), OCS_M_NOWAIT);
7683 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7684 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7692 if (ocs_dma_alloc(hw->os, &cb_arg->payload, sizeof(sli4_res_common_get_profile_list_t), 4)) {
7693 ocs_log_err(hw->os, "Failed to allocate DMA buffer\n");
7694 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7695 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_profile_list_cb_arg_t));
7699 if (sli_cmd_common_get_profile_list(&hw->sli, mbxdata, SLI4_BMBX_SIZE, 0, &cb_arg->payload)) {
7700 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_get_profile_list_cb, cb_arg);
7704 ocs_log_test(hw->os, "GET_PROFILE_LIST failed\n");
7705 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7706 ocs_dma_free(hw->os, &cb_arg->payload);
7707 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_profile_list_cb_arg_t));
7722 * @param hw Hardware context.
7730 ocs_hw_get_active_profile_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
7743 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
7744 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_active_profile_cb_arg_t));
7757 * @param hw Hardware context.
7771 ocs_hw_get_active_profile(ocs_hw_t *hw, ocs_get_active_profile_cb_t cb, void* ul_arg)
7778 if (sli_get_if_type(&hw->sli) != SLI4_IF_TYPE_BE3_SKH_PF) {
7783 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7785 ocs_log_err(hw->os, "failed to malloc mbox\n");
7790 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_get_active_profile_cb_arg_t), OCS_M_NOWAIT);
7792 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7793 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7800 if (sli_cmd_common_get_active_profile(&hw->sli, mbxdata, SLI4_BMBX_SIZE)) {
7801 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_get_active_profile_cb, cb_arg);
7805 ocs_log_test(hw->os, "GET_ACTIVE_PROFILE failed\n");
7806 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7807 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_active_profile_cb_arg_t));
7822 * @param hw Hardware context.
7830 ocs_hw_get_nvparms_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
7840 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
7841 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_nvparms_cb_arg_t));
7854 * @param hw Hardware context.
7868 ocs_hw_get_nvparms(ocs_hw_t *hw, ocs_get_nvparms_cb_t cb, void* ul_arg)
7875 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7877 ocs_log_err(hw->os, "failed to malloc mbox\n");
7882 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_get_nvparms_cb_arg_t), OCS_M_NOWAIT);
7884 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7885 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7892 if (sli_cmd_read_nvparms(&hw->sli, mbxdata, SLI4_BMBX_SIZE)) {
7893 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_get_nvparms_cb, cb_arg);
7897 ocs_log_test(hw->os, "READ_NVPARMS failed\n");
7898 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7899 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_nvparms_cb_arg_t));
7914 * @param hw Hardware context.
7922 ocs_hw_set_nvparms_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
7930 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
7931 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_set_nvparms_cb_arg_t));
7944 * @param hw Hardware context.
7965 ocs_hw_set_nvparms(ocs_hw_t *hw, ocs_set_nvparms_cb_t cb, uint8_t *wwpn,
7973 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
7975 ocs_log_err(hw->os, "failed to malloc mbox\n");
7980 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_set_nvparms_cb_arg_t), OCS_M_NOWAIT);
7982 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
7983 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7990 if (sli_cmd_write_nvparms(&hw->sli, mbxdata, SLI4_BMBX_SIZE, wwpn, wwnn, hard_alpa, preferred_d_id)) {
7991 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_set_nvparms_cb, cb_arg);
7995 ocs_log_test(hw->os, "SET_NVPARMS failed\n");
7996 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
7997 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_set_nvparms_cb_arg_t));
8008 * @param hw Hardware context.
8014 ocs_hw_io_get_count(ocs_hw_t *hw, ocs_hw_io_count_type_e io_count_type)
8019 ocs_lock(&hw->io_lock);
8023 ocs_list_foreach(&hw->io_inuse, io) {
8028 ocs_list_foreach(&hw->io_free, io) {
8033 ocs_list_foreach(&hw->io_wait_free, io) {
8038 ocs_list_foreach(&hw->io_port_owned, io) {
8043 count = hw->config.n_io;
8047 ocs_unlock(&hw->io_lock);
8055 * @param hw Hardware context.
8060 ocs_hw_get_rqes_produced_count(ocs_hw_t *hw)
8066 for (i = 0; i < hw->hw_rq_count; i++) {
8067 hw_rq_t *rq = hw->hw_rq[i];
8089 * @param hw Hardware context.
8097 ocs_hw_set_active_profile_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
8105 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
8106 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_get_active_profile_cb_arg_t));
8119 * @param hw Hardware context.
8132 ocs_hw_set_active_profile(ocs_hw_t *hw, ocs_set_active_profile_cb_t cb, uint32_t profile_id, void* ul_arg)
8139 if (sli_get_if_type(&hw->sli) != SLI4_IF_TYPE_BE3_SKH_PF) {
8144 mbxdata = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
8146 ocs_log_err(hw->os, "failed to malloc mbox\n");
8152 cb_arg = ocs_malloc(hw->os, sizeof(ocs_hw_set_active_profile_cb_arg_t), OCS_M_NOWAIT);
8154 ocs_log_err(hw->os, "failed to malloc cb_arg\n");
8155 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
8162 if (sli_cmd_common_set_active_profile(&hw->sli, mbxdata, SLI4_BMBX_SIZE, 0, profile_id)) {
8163 rc = ocs_hw_command(hw, mbxdata, OCS_CMD_NOWAIT, ocs_hw_set_active_profile_cb, cb_arg);
8167 ocs_log_test(hw->os, "SET_ACTIVE_PROFILE failed\n");
8168 ocs_free(hw->os, mbxdata, SLI4_BMBX_SIZE);
8169 ocs_free(hw->os, cb_arg, sizeof(ocs_hw_set_active_profile_cb_arg_t));
8239 ocs_hw_domain_add(ocs_hw_t *hw, ocs_domain_t *domain)
8244 if ((hw == NULL) || (domain == NULL)) {
8245 ocs_log_err(NULL, "bad parameter hw=%p domain=%p\n",
8246 hw, domain);
8255 ocs_log_debug(hw->os, "adding domain %p @ %#x\n",
8257 hw->domains[fcfi] = domain;
8260 if (hw->workaround.override_fcfi) {
8261 if (hw->first_domain_idx < 0) {
8262 hw->first_domain_idx = fcfi;
8269 ocs_log_debug(hw->os, "adding map of FCF index %d to FCFI %d\n",
8271 hw->fcf_index_fcfi[fcf_index] = fcfi;
8274 ocs_log_test(hw->os, "FCF index %d out of range (max %d)\n",
8276 hw->domains[fcfi] = NULL;
8279 ocs_log_test(hw->os, "FCFI %#x out of range (max %#x)\n",
8287 ocs_hw_domain_del(ocs_hw_t *hw, ocs_domain_t *domain)
8292 if ((hw == NULL) || (domain == NULL)) {
8293 ocs_log_err(NULL, "bad parameter hw=%p domain=%p\n",
8294 hw, domain);
8303 ocs_log_debug(hw->os, "deleting domain %p @ %#x\n",
8306 if (domain != hw->domains[fcfi]) {
8307 ocs_log_test(hw->os, "provided domain %p does not match stored domain %p\n",
8308 domain, hw->domains[fcfi]);
8312 hw->domains[fcfi] = NULL;
8315 if (hw->workaround.override_fcfi) {
8316 if (hw->first_domain_idx == fcfi) {
8317 hw->first_domain_idx = -1;
8324 if (hw->fcf_index_fcfi[fcf_index] == fcfi) {
8325 hw->fcf_index_fcfi[fcf_index] = 0;
8328 ocs_log_test(hw->os, "indexed FCFI %#x doesn't match provided %#x @ %d\n",
8329 hw->fcf_index_fcfi[fcf_index], fcfi, fcf_index);
8332 ocs_log_test(hw->os, "FCF index %d out of range (max %d)\n",
8336 ocs_log_test(hw->os, "FCFI %#x out of range (max %#x)\n",
8344 ocs_hw_domain_get(ocs_hw_t *hw, uint16_t fcfi)
8347 if (hw == NULL) {
8348 ocs_log_err(NULL, "bad parameter hw=%p\n", hw);
8353 return hw->domains[fcfi];
8355 ocs_log_test(hw->os, "FCFI %#x out of range (max %#x)\n",
8362 ocs_hw_domain_get_indexed(ocs_hw_t *hw, uint16_t fcf_index)
8365 if (hw == NULL) {
8366 ocs_log_err(NULL, "bad parameter hw=%p\n", hw);
8371 return ocs_hw_domain_get(hw, hw->fcf_index_fcfi[fcf_index]);
8373 ocs_log_test(hw->os, "FCF index %d out of range (max %d)\n",
8389 * @param hw Hardware context.
8394 ocs_hw_io_quarantine(ocs_hw_t *hw, hw_wq_t *wq, ocs_hw_io_t *io)
8408 ocs_log_debug(hw ? hw->os : NULL,
8429 * @param hw Hardware context.
8435 ocs_hw_cq_process(ocs_hw_t *hw, hw_cq_t *cq)
8447 while (!sli_queue_read(&hw->sli, cq->queue, cqe)) {
8448 status = sli_cq_parse(&hw->sli, cq->queue, cqe, &ctype, &rid);
8467 sli_cqe_async(&hw->sli, cqe);
8475 ocs_hw_mq_process(hw, status, hw->mq);
8478 ocs_hw_rqpair_process_auto_xfr_rdy_cmd(hw, cq, cqe);
8481 ocs_hw_rqpair_process_auto_xfr_rdy_data(hw, cq, cqe);
8485 ocs_hw_wq_process(hw, cq, cqe, status, rid);
8489 uint32_t index = ocs_hw_queue_hash_find(hw->wq_hash, wq_id);
8490 hw_wq_t *wq = hw->hw_wq[index];
8500 ocs_hw_rqpair_process_rq(hw, cq, cqe);
8504 ocs_hw_xabt_process(hw, cq, cqe, rid);
8509 ocs_log_test(hw->os, "unhandled ctype=%#x rid=%#x\n", ctype, rid);
8519 sli_queue_arm(&hw->sli, cq->queue, FALSE);
8523 sli_queue_arm(&hw->sli, cq->queue, TRUE);
8537 * @param hw Hardware context.
8546 ocs_hw_wq_process(ocs_hw_t *hw, hw_cq_t *cq, uint8_t *cqe, int32_t status, uint16_t rid)
8550 ocs_queue_history_cqe(&hw->q_hist, SLI_QENTRY_WQ, (void *)cqe, ((sli4_fc_wcqe_t *)cqe)->status, cq->queue->id,
8555 ocs_log_err(hw->os, "reque xri failed, status = %d \n", status);
8560 wqcb = ocs_hw_reqtag_get_instance(hw, rid);
8562 ocs_log_err(hw->os, "invalid request tag: x%x\n", rid);
8567 ocs_log_err(hw->os, "wqcb callback is NULL\n");
8583 * in ocs_hw_setup_io(), and don't need to be returned to the hw->wq_reqtag_pool.
8591 ocs_hw_t *hw = io->hw;
8611 ocs_hw_io_quarantine(hw, io->wq, io);
8626 ocs_hw_io_quarantine(hw, io->wq, io->sec_hio);
8629 ocs_hw_remove_io_timed_wqe(hw, io);
8642 sli_fc_els_did(&hw->sli, cqe, &ext);
8643 len = sli_fc_response_length(&hw->sli, cqe);
8650 len = sli_fc_response_length(&hw->sli, cqe);
8653 len = sli_fc_io_length(&hw->sli, cqe);
8662 len = sli_fc_io_length(&hw->sli, cqe);
8668 if (hw->workaround.retain_tsend_io_length && !len && !status) {
8686 len = sli_fc_io_length(&hw->sli, cqe);
8689 len = sli_fc_io_length(&hw->sli, cqe);
8695 //ocs_hw_io_free(hw, io);
8698 ocs_log_test(hw->os, "XXX unhandled io type %#x for XRI 0x%x\n",
8703 ext = sli_fc_ext_status(&hw->sli, cqe);
8707 if (hw->config.i_only_aab &&
8712 ocs_log_debug(hw->os, "aborting xri=%#x tag=%#x\n",
8719 rc = ocs_hw_io_abort(hw, io, TRUE, NULL, NULL);
8734 ocs_log_debug(hw->os, "abort in progress xri=%#x tag=%#x\n",
8739 ocs_log_test(hw->os, "Failed to abort xri=%#x tag=%#x rc=%d\n",
8750 ocs_log_debug(hw->os, "aborting xri=%#x tag=%#x\n", io->indicator, io->reqtag);
8756 rc = ocs_hw_io_abort(hw, io, FALSE, NULL, NULL);
8770 ocs_log_debug(hw->os, "abort in progress xri=%#x tag=%#x\n",
8775 ocs_log_test(hw->os, "Failed to abort xri=%#x tag=%#x rc=%d\n",
8782 ocs_hw_io_free(hw, io->sec_hio);
8801 ocs_hw_io_restore_sgl(hw, io);
8807 if (hw->config.bounce) {
8812 if (hw->callback.bounce != NULL) {
8813 (*hw->callback.bounce)(ocs_hw_unsol_process_bounce, io->axr_buf->cmd_seq, s_id, d_id, ox_id);
8816 hw->callback.unsolicited(hw->args.unsolicited, io->axr_buf->cmd_seq);
8821 if (hw->config.bounce) {
8826 if (hw->callback.bounce != NULL) {
8827 (*hw->callback.bounce)(ocs_hw_unsol_process_bounce, &io->axr_buf->seq, s_id, d_id, ox_id);
8830 hw->callback.unsolicited(hw->args.unsolicited, &io->axr_buf->seq);
8854 ocs_hw_t *hw = io->hw;
8864 ext = sli_fc_ext_status(&hw->sli, cqe);
8894 ocs_lock(&hw->io_abort_lock);
8897 ocs_unlock(&hw->io_abort_lock);
8901 wqcb = ocs_hw_reqtag_get_instance(hw, io->abort_reqtag);
8902 ocs_hw_reqtag_free(hw, wqcb);
8908 (void)ocs_hw_io_free(hw, io);
8914 * @param hw Hardware context.
8923 ocs_hw_xabt_process(ocs_hw_t *hw, hw_cq_t *cq, uint8_t *cqe, uint16_t rid)
8928 io = ocs_hw_io_lookup(hw, rid);
8930 ocs_queue_history_cqe(&hw->q_hist, SLI_QENTRY_XABT, (void *)cqe, 0, cq->queue->id,
8934 ocs_log_err(hw->os, "Error: xabt io lookup failed rid=%#x\n", rid);
8939 ocs_log_debug(hw->os, "xabt io not busy rid=%#x\n", rid);
8946 ocs_lock(&hw->io_lock);
8949 ocs_unlock(&hw->io_lock);
8972 ocs_lock(&hw->io_lock);
8973 ocs_hw_reque_xri(hw, io);
8974 ocs_unlock(&hw->io_lock);
8976 ocs_hw_io_free(hw, io);
8980 ocs_lock(&hw->io_lock);
8989 ocs_list_remove(&hw->io_wait_free, io);
8990 ocs_hw_io_free_move_correct_list(hw, io);
8993 ocs_unlock(&hw->io_lock);
9004 * @param hw Hardware context allocated by the caller.
9007 ocs_hw_adjust_wqs(ocs_hw_t *hw)
9009 uint32_t max_wq_num = sli_get_max_queue(&hw->sli, SLI_QTYPE_WQ);
9010 uint32_t max_wq_entries = hw->num_qentries[SLI_QTYPE_WQ];
9011 uint32_t max_cq_entries = hw->num_qentries[SLI_QTYPE_CQ];
9019 max_wq_entries = hw->num_qentries[SLI_QTYPE_WQ] = max_cq_entries / 2;
9030 hw->config.n_wq = ((hw->config.n_io * 2) + (max_wq_entries - 1)) / max_wq_entries;
9036 if (hw->config.n_wq < 4 &&
9037 SLI4_IF_TYPE_BE3_SKH_PF == sli_get_if_type(&hw->sli)) {
9038 hw->config.n_wq = 4;
9044 if (hw->config.n_wq < 2 &&
9045 ocs_hw_get_num_chutes(hw) > 1) {
9046 hw->config.n_wq = 2;
9050 if (hw->config.n_wq > OCS_HW_MAX_NUM_WQ) {
9051 hw->config.n_wq = OCS_HW_MAX_NUM_WQ;
9055 if (hw->config.n_wq > max_wq_num) {
9056 hw->config.n_wq = max_wq_num;
9062 hw->config.n_wq /= ocs_hw_get_num_chutes(hw);
9066 ocs_hw_command_process(ocs_hw_t *hw, int32_t status, uint8_t *mqe, size_t size)
9070 ocs_lock(&hw->cmd_lock);
9071 if (NULL == (ctx = ocs_list_remove_head(&hw->cmd_head))) {
9072 ocs_log_err(hw->os, "XXX no command context?!?\n");
9073 ocs_unlock(&hw->cmd_lock);
9077 hw->cmd_head_count--;
9080 ocs_hw_cmd_submit_pending(hw);
9082 ocs_unlock(&hw->cmd_lock);
9088 ctx->cb(hw, status, ctx->buf, ctx->arg);
9092 ocs_free(hw->os, ctx, sizeof(ocs_command_ctx_t));
9103 * @param hw Hardware context.
9110 ocs_hw_mq_process(ocs_hw_t *hw, int32_t status, sli4_queue_t *mq)
9114 if (!sli_queue_read(&hw->sli, mq, mqe)) {
9115 ocs_hw_command_process(hw, status, mqe, mq->size);
9124 * @param hw Hardware context.
9132 ocs_hw_read_fcf(ocs_hw_t *hw, uint32_t index)
9137 buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
9139 ocs_log_err(hw->os, "no buffer for command\n");
9143 if (sli_cmd_fcoe_read_fcf_table(&hw->sli, buf, SLI4_BMBX_SIZE, &hw->fcf_dmem,
9145 rc = ocs_hw_command(hw, buf, OCS_CMD_NOWAIT, ocs_hw_cb_read_fcf, &hw->fcf_dmem);
9149 ocs_log_test(hw->os, "FCOE_READ_FCF_TABLE failed\n");
9150 ocs_free(hw->os, buf, SLI4_BMBX_SIZE);
9167 * @param hw Hardware context.
9175 ocs_hw_cb_read_fcf(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
9181 ocs_log_test(hw->os, "bad status cqe=%#x mqe=%#x\n",
9189 if (hw->callback.domain != NULL) {
9197 drec.speed = hw->link.speed;
9198 drec.fc_id = hw->link.fc_id;
9200 if (SLI_LINK_TOPO_LOOP == hw->link.topology) {
9202 ocs_memcpy(drec.map.loop, hw->link.loop_map,
9204 } else if (SLI_LINK_TOPO_NPORT == hw->link.topology) {
9223 hw->callback.domain(hw->args.domain,
9229 ocs_log_test(hw->os, "ignore invalid FCF entry\n");
9233 ocs_hw_read_fcf(hw, read_fcf->next_index);
9237 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
9238 //ocs_dma_free(hw->os, dma);
9239 //ocs_free(hw->os, dma, sizeof(ocs_dma_t));
9258 ocs_hw_t *hw = ctx;
9263 ocs_t *ocs = hw->os;
9265 ocs_hw_link_event_init(hw);
9270 hw->link = *event;
9274 ocs_hw_read_fcf(hw, SLI4_FCOE_FCF_TABLE_FIRST);
9279 buf = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
9281 ocs_log_err(hw->os, "no buffer for command\n");
9285 if (sli_cmd_read_topology(&hw->sli, buf, SLI4_BMBX_SIZE, &hw->loop_map)) {
9286 rc = ocs_hw_command(hw, buf, OCS_CMD_NOWAIT, __ocs_read_topology_cb, NULL);
9290 ocs_log_test(hw->os, "READ_TOPOLOGY failed\n");
9291 ocs_free(hw->os, buf, SLI4_BMBX_SIZE);
9301 hw->link.status = event->status;
9303 for (i = 0; d = hw->domains[i], i < SLI4_MAX_FCFI; i++) {
9305 hw->callback.domain != NULL) {
9306 hw->callback.domain(hw->args.domain, OCS_HW_DOMAIN_LOST, d);
9311 ocs_log_test(hw->os, "unhandled link status %#x\n", event->status);
9321 ocs_hw_t *hw = ctx;
9333 for (i = 0; d = hw->domains[i], i < SLI4_MAX_FCFI; i++) {
9350 domain = ocs_hw_domain_get_indexed(hw, event->index);
9355 ocs_hw_read_fcf(hw, event->index);
9359 hw->callback.domain != NULL) {
9360 hw->callback.domain(hw->args.domain, OCS_HW_DOMAIN_LOST, domain);
9365 hw->callback.domain != NULL) {
9371 hw->callback.domain(hw->args.domain, OCS_HW_DOMAIN_LOST, domain);
9376 hw->callback.domain != NULL) {
9377 hw->callback.domain(hw->args.domain, OCS_HW_DOMAIN_LOST, domain);
9380 ocs_hw_read_fcf(hw, event->index);
9383 ocs_log_test(hw->os, "unsupported event %#x\n", event->type);
9390 ocs_hw_cb_node_attach(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
9397 ocs_log_debug(hw->os, "bad status cqe=%#x mqe=%#x\n", status,
9399 ocs_atomic_sub_return(&hw->rpi_ref[rnode->index].rpi_count, 1);
9401 ocs_atomic_set(&hw->rpi_ref[rnode->index].rpi_attached, 0);
9405 ocs_atomic_set(&hw->rpi_ref[rnode->index].rpi_attached, 1);
9409 if (hw->callback.rnode != NULL) {
9410 hw->callback.rnode(hw->args.rnode, evt, rnode);
9412 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
9418 ocs_hw_cb_node_free(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
9426 ocs_log_debug(hw->os, "bad status cqe=%#x mqe=%#x\n", status,
9435 if (!rnode->attached || ((sli_get_hlm(&hw->sli) == TRUE) && !rnode->node_group) ||
9445 if (ocs_atomic_read(&hw->rpi_ref[rnode->index].rpi_count) == 0) {
9446 ocs_atomic_set(&hw->rpi_ref[rnode->index].rpi_attached, 0);
9452 if (hw->callback.rnode != NULL) {
9453 hw->callback.rnode(hw->args.rnode, evt, rnode);
9456 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
9462 ocs_hw_cb_node_free_all(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
9470 ocs_log_debug(hw->os, "bad status cqe=%#x mqe=%#x\n", status,
9477 for (i = 0; i < sli_get_max_rsrc(&hw->sli, SLI_RSRC_FCOE_RPI); i++) {
9478 ocs_atomic_set(&hw->rpi_ref[i].rpi_count, 0);
9481 if (sli_resource_reset(&hw->sli, SLI_RSRC_FCOE_RPI)) {
9482 ocs_log_test(hw->os, "FCOE_RPI free all failure\n");
9487 if (hw->callback.rnode != NULL) {
9488 hw->callback.rnode(hw->args.rnode, evt, NULL);
9491 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
9499 * @param hw Hardware context.
9504 ocs_hw_setup_io(ocs_hw_t *hw)
9513 if (NULL == hw->io) {
9514 hw->io = ocs_malloc(hw->os, hw->config.n_io * sizeof(ocs_hw_io_t *), OCS_M_ZERO | OCS_M_NOWAIT);
9516 if (NULL == hw->io) {
9517 ocs_log_err(hw->os, "IO pointer memory allocation failed, %d Ios at size %zu\n",
9518 hw->config.n_io,
9522 for (i = 0; i < hw->config.n_io; i++) {
9523 hw->io[i] = ocs_malloc(hw->os, sizeof(ocs_hw_io_t),
9525 if (hw->io[i] == NULL) {
9526 ocs_log_err(hw->os, "IO(%d) memory allocation failed\n", i);
9532 hw->wqe_buffs = ocs_malloc(hw->os, hw->config.n_io * hw->sli.config.wqe_size,
9534 if (NULL == hw->wqe_buffs) {
9535 ocs_free(hw->os, hw->io, hw->config.n_io * sizeof(ocs_hw_io_t));
9536 ocs_log_err(hw->os, "%s: IO WQE buff allocation failed, %d Ios at size %zu\n",
9537 __func__, hw->config.n_io, hw->sli.config.wqe_size);
9547 if (ocs_dma_alloc(hw->os, &hw->xfer_rdy,
9548 sizeof(fcp_xfer_rdy_iu_t) * hw->config.n_io,
9550 ocs_log_err(hw->os, "XFER_RDY buffer allocation failed\n");
9554 xfer_virt = (uintptr_t)hw->xfer_rdy.virt;
9555 xfer_phys = hw->xfer_rdy.phys;
9557 for (i = 0; i < hw->config.n_io; i++) {
9560 io = hw->io[i];
9563 io->hw = hw;
9566 io->wqe.wqebuf = &hw->wqe_buffs[i * hw->sli.config.wqe_size];
9569 wqcb = ocs_hw_reqtag_alloc(hw, ocs_hw_wq_process_io, io);
9571 ocs_log_err(hw->os, "can't allocate request tag\n");
9582 if (sli_resource_alloc(&hw->sli, SLI_RSRC_FCOE_XRI, &io->indicator, &index)) {
9583 ocs_log_err(hw->os, "sli_resource_alloc failed @ %d\n", i);
9587 if (new_alloc && ocs_dma_alloc(hw->os, &io->def_sgl, hw->config.n_sgl * sizeof(sli4_sge_t), 64)) {
9588 ocs_log_err(hw->os, "ocs_dma_alloc failed @ %d\n", i);
9592 io->def_sgl_count = hw->config.n_sgl;
9596 if (hw->xfer_rdy.size) {
9608 for (i = 0; i < hw->config.n_io && hw->io[i]; i++) {
9609 ocs_free(hw->os, hw->io[i], sizeof(ocs_hw_io_t));
9610 hw->io[i] = NULL;
9617 ocs_hw_init_io(ocs_hw_t *hw)
9630 prereg = sli_get_sgl_preregister(&hw->sli);
9633 sgls = ocs_malloc(hw->os, sizeof(*sgls) * sgls_per_request, OCS_M_NOWAIT);
9635 ocs_log_err(hw->os, "ocs_malloc sgls failed\n");
9639 rc = ocs_dma_alloc(hw->os, &reqbuf, 32 + sgls_per_request*16, OCS_MIN_DMA_ALIGNMENT);
9641 ocs_log_err(hw->os, "ocs_dma_alloc reqbuf failed\n");
9642 ocs_free(hw->os, sgls, sizeof(*sgls) * sgls_per_request);
9647 io = hw->io[io_index];
9648 for (nremaining = hw->config.n_io; nremaining; nremaining -= n) {
9656 if (hw->io[io_index + n]->indicator != (hw->io[io_index + n-1]->indicator+1)) {
9660 sgls[n] = hw->io[io_index + n]->sgl;
9663 if (sli_cmd_fcoe_post_sgl_pages(&hw->sli, cmd, sizeof(cmd),
9665 if (ocs_hw_command(hw, cmd, OCS_CMD_POLL, NULL, NULL)) {
9667 ocs_log_err(hw->os, "SGL post failed\n");
9679 ocs_list_add_tail(&hw->io_free, io);
9680 io = hw->io[io_index+1];
9686 ocs_dma_free(hw->os, &reqbuf);
9687 ocs_free(hw->os, sgls, sizeof(*sgls) * sgls_per_request);
9694 ocs_hw_flush(ocs_hw_t *hw)
9699 for (i = 0; i < hw->eq_count; i++) {
9700 ocs_hw_process(hw, i, ~0);
9707 ocs_hw_command_cancel(ocs_hw_t *hw)
9710 ocs_lock(&hw->cmd_lock);
9717 while (!ocs_list_empty(&hw->cmd_head)) {
9719 ocs_command_ctx_t *ctx = ocs_list_get_head(&hw->cmd_head);
9721 ocs_log_test(hw->os, "hung command %08x\n",
9724 ocs_unlock(&hw->cmd_lock);
9725 ocs_hw_command_process(hw, -1/*Bad status*/, mqe, SLI4_BMBX_SIZE);
9726 ocs_lock(&hw->cmd_lock);
9729 ocs_unlock(&hw->cmd_lock);
9737 * @param hw Hal context.
9743 ocs_hw_io_lookup(ocs_hw_t *hw, uint32_t xri)
9746 ioindex = xri - hw->sli.config.extent[SLI_RSRC_FCOE_XRI].base[0];
9747 return hw->io[ioindex];
9753 * @param hw Hal context.
9757 ocs_hw_io_cancel_cleanup(ocs_hw_t *hw, ocs_hw_io_t *io)
9764 ocs_list_remove(&hw->io_timed_wqe, io);
9776 ocs_unlock(&hw->io_lock);
9778 ocs_lock(&hw->io_lock);
9785 ocs_unlock(&hw->io_lock);
9787 ocs_lock(&hw->io_lock);
9792 ocs_hw_io_cancel(ocs_hw_t *hw)
9802 ocs_lock(&hw->io_lock);
9803 ocs_list_foreach_safe(&hw->io_inuse, io, tmp_io) {
9807 ocs_hw_io_cancel_cleanup(hw, io);
9826 ocs_hw_io_free_common(hw, io);
9827 ocs_list_remove(&hw->io_inuse, io);
9828 ocs_hw_io_free_move_correct_list(hw, io);
9836 ocs_list_foreach_safe(&hw->io_port_owned, io, tmp_io) {
9839 ocs_list_remove(&hw->io_port_dnrx, io);
9842 ocs_hw_io_cancel_cleanup(hw, io);
9843 ocs_list_remove(&hw->io_port_owned, io);
9844 ocs_hw_io_free_common(hw, io);
9846 ocs_unlock(&hw->io_lock);
9852 } while (!ocs_list_empty(&hw->io_inuse) && iters);
9855 if (!ocs_list_empty(&hw->io_inuse)) {
9856 ocs_log_test(hw->os, "io_inuse list is not empty\n");
9863 ocs_hw_io_ini_sge(ocs_hw_t *hw, ocs_hw_io_t *io, ocs_dma_t *cmnd, uint32_t cmnd_size,
9868 if (!hw || !io) {
9869 ocs_log_err(NULL, "bad parm hw=%p io=%p\n", hw, io);
9890 __ocs_read_topology_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
9895 ocs_log_debug(hw->os, "bad status cqe=%#x mqe=%#x\n",
9897 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
9903 hw->link.status = SLI_LINK_STATUS_UP;
9906 hw->link.status = SLI_LINK_STATUS_DOWN;
9909 hw->link.status = SLI_LINK_STATUS_NO_ALPA;
9912 hw->link.status = SLI_LINK_STATUS_MAX;
9918 hw->link.topology = SLI_LINK_TOPO_NPORT;
9921 hw->link.topology = SLI_LINK_TOPO_LOOP;
9922 if (SLI_LINK_STATUS_UP == hw->link.status) {
9923 hw->link.loop_map = hw->loop_map.virt;
9925 hw->link.fc_id = read_topo->acquired_al_pa;
9928 hw->link.topology = SLI_LINK_TOPO_MAX;
9932 hw->link.medium = SLI_LINK_MEDIUM_FC;
9936 hw->link.speed = 1 * 1000;
9939 hw->link.speed = 2 * 1000;
9942 hw->link.speed = 4 * 1000;
9945 hw->link.speed = 8 * 1000;
9948 hw->link.speed = 16 * 1000;
9949 hw->link.loop_map = NULL;
9952 hw->link.speed = 32 * 1000;
9953 hw->link.loop_map = NULL;
9957 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
9959 ocs_hw_read_fcf(hw, SLI4_FCOE_FCF_TABLE_FIRST);
9968 ocs_hw_t *hw = sport->hw;
9980 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
9984 ocs_log_test(hw->os, "%s %-20s not handled\n", funcname, ocs_sm_event_name(evt));
9995 ocs_hw_t *hw = sport->hw;
10002 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10004 if (hw->callback.port != NULL) {
10005 hw->callback.port(hw->args.port,
10020 ocs_hw_t *hw = sport->hw;
10027 if (sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VPI, sport->indicator)) {
10028 ocs_log_err(hw->os, "FCOE_VPI free failure addr=%#x\n", sport->fc_id);
10033 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10035 if (hw->callback.port != NULL) {
10036 hw->callback.port(hw->args.port,
10051 ocs_hw_t *hw = sport->hw;
10058 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VPI, sport->indicator);
10062 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10065 if (hw->callback.port != NULL) {
10066 hw->callback.port(hw->args.port,
10085 ocs_hw_t *hw = sport->hw;
10093 cmd = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
10099 if (0 == sli_cmd_unreg_vpi(&hw->sli, cmd, SLI4_BMBX_SIZE, sport->indicator,
10101 ocs_log_err(hw->os, "UNREG_VPI format failure\n");
10102 ocs_free(hw->os, cmd, SLI4_BMBX_SIZE);
10107 if (ocs_hw_command(hw, cmd, OCS_CMD_NOWAIT, __ocs_hw_port_cb, sport)) {
10108 ocs_log_err(hw->os, "UNREG_VPI command failure\n");
10109 ocs_free(hw->os, cmd, SLI4_BMBX_SIZE);
10132 ocs_hw_t *hw = sport->hw;
10139 if (ocs_hw_async_call(hw, __ocs_hw_port_realloc_cb, sport)) {
10140 ocs_log_err(hw->os, "ocs_hw_async_call failed\n");
10160 ocs_hw_t *hw = sport->hw;
10167 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10169 if (hw->callback.port != NULL) {
10170 hw->callback.port(hw->args.port,
10193 ocs_hw_t *hw = sport->hw;
10199 if (0 == sli_cmd_reg_vpi(&hw->sli, data, SLI4_BMBX_SIZE, sport, FALSE)) {
10200 ocs_log_err(hw->os, "REG_VPI format failure\n");
10205 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_port_cb, sport)) {
10206 ocs_log_err(hw->os, "REG_VPI command failure\n");
10233 ocs_hw_t *hw = sport->hw;
10240 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VPI, sport->indicator);
10244 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10259 ocs_hw_t *hw = sport->hw;
10266 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10268 if (hw->callback.port != NULL) {
10269 hw->callback.port(hw->args.port,
10287 if (SLI4_IF_TYPE_LANCER_FC_ETH == sli_get_if_type(&hw->sli)) {
10313 ocs_hw_t *hw = sport->hw;
10320 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VPI, sport->indicator);
10324 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10327 if (hw->callback.port != NULL) {
10328 hw->callback.port(hw->args.port,
10349 ocs_hw_t *hw = sport->hw;
10357 if (ocs_dma_alloc(hw->os, &sport->dma, 112, 4)) {
10358 ocs_log_err(hw->os, "Failed to allocate DMA memory\n");
10363 if (0 == sli_cmd_read_sparm64(&hw->sli, data, SLI4_BMBX_SIZE,
10365 ocs_log_err(hw->os, "READ_SPARM64 allocation failure\n");
10366 ocs_dma_free(hw->os, &sport->dma);
10371 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_port_cb, sport)) {
10372 ocs_log_err(hw->os, "READ_SPARM64 command failure\n");
10373 ocs_dma_free(hw->os, &sport->dma);
10388 ocs_dma_free(hw->os, &sport->dma);
10392 ocs_dma_free(hw->os, &sport->dma);
10442 ocs_hw_t *hw = sport->hw;
10459 if (0 == sli_cmd_init_vpi(&hw->sli, data, SLI4_BMBX_SIZE,
10461 ocs_log_err(hw->os, "INIT_VPI allocation failure\n");
10466 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_port_cb, sport)) {
10467 ocs_log_err(hw->os, "INIT_VPI command failure\n");
10493 __ocs_hw_port_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
10500 ocs_log_debug(hw->os, "bad status vpi=%#x st=%x hdr=%x\n",
10513 __ocs_hw_port_realloc_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
10521 ocs_log_debug(hw->os, "bad status vpi=%#x st=%x hdr=%x\n",
10532 mqecpy = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
10534 ocs_log_err(hw->os, "malloc mqecpy failed\n");
10552 ocs_hw_t *hw = domain->hw;
10562 ocs_log_test(hw->os, "%s %-20s not handled\n", funcname, ocs_sm_event_name(evt));
10573 ocs_hw_t *hw = domain->hw;
10581 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10584 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VFI, domain->indicator);
10587 if (hw->callback.domain != NULL) {
10588 hw->callback.domain(hw->args.domain,
10605 ocs_hw_t *hw = domain->hw;
10612 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10616 if (hw->callback.domain != NULL) {
10617 hw->callback.domain(hw->args.domain,
10637 ocs_hw_t *hw = domain->hw;
10644 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10647 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VFI, domain->indicator);
10650 if (hw->callback.domain != NULL) {
10651 hw->callback.domain(hw->args.domain,
10670 ocs_hw_t *hw = domain->hw;
10679 if (0 == sli_cmd_reg_vfi(&hw->sli, data, SLI4_BMBX_SIZE, domain)) {
10680 ocs_log_err(hw->os, "REG_VFI format failure\n");
10685 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_domain_cb, domain)) {
10686 ocs_log_err(hw->os, "REG_VFI command failure\n");
10709 ocs_hw_t *hw = domain->hw;
10716 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
10719 ocs_hw_domain_add(hw, domain);
10722 if (hw->callback.domain != NULL) {
10723 hw->callback.domain(hw->args.domain,
10733 if (SLI4_IF_TYPE_BE3_SKH_PF == sli_get_if_type(&hw->sli)) {
10751 ocs_hw_t *hw = domain->hw;
10757 if (0 == sli_cmd_read_sparm64(&hw->sli, data, SLI4_BMBX_SIZE,
10759 ocs_log_err(hw->os, "READ_SPARM64 format failure\n");
10764 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_domain_cb, domain)) {
10765 ocs_log_err(hw->os, "READ_SPARM64 command failure\n");
10793 ocs_hw_t *hw = domain->hw;
10799 if (0 == sli_cmd_init_vfi(&hw->sli, data, SLI4_BMBX_SIZE, domain->indicator,
10801 ocs_log_err(hw->os, "INIT_VFI format failure\n");
10805 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_domain_cb, domain)) {
10806 ocs_log_err(hw->os, "INIT_VFI command failure\n");
10831 ocs_hw_t *hw = domain->hw;
10840 /* Set the filter match/mask values from hw's filter_def values */
10843 rq_cfg[i].r_ctl_mask = (uint8_t) hw->config.filter_def[i];
10844 rq_cfg[i].r_ctl_match = (uint8_t) (hw->config.filter_def[i] >> 8);
10845 rq_cfg[i].type_mask = (uint8_t) (hw->config.filter_def[i] >> 16);
10846 rq_cfg[i].type_match = (uint8_t) (hw->config.filter_def[i] >> 24);
10850 for (i = 0; i < hw->hw_rq_count; i++) {
10852 ocs_log_warn(hw->os, "more RQs than REG_FCFI filter entries\n");
10855 rq_cfg[i].rq_id = hw->hw_rq[i]->hdr->id;
10863 if (hw->hw_mrq_count) {
10864 if (OCS_HW_RTN_SUCCESS != ocs_hw_config_mrq(hw, SLI4_CMD_REG_FCFI_SET_FCFI_MODE,
10866 ocs_log_err(hw->os, "REG_FCFI_MRQ format failure\n");
10872 if (0 == sli_cmd_reg_fcfi(&hw->sli, data, SLI4_BMBX_SIZE, domain->fcf,
10874 ocs_log_err(hw->os, "REG_FCFI format failure\n");
10880 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_domain_cb, domain)) {
10881 ocs_log_err(hw->os, "REG_FCFI command failure\n");
10902 if (SLI4_IF_TYPE_BE3_SKH_PF == sli_get_if_type(&hw->sli)) {
10923 ocs_hw_t *hw = domain->hw;
10929 if (sli_get_medium(&hw->sli) == SLI_LINK_MEDIUM_FC) {
10934 domain->fcf_indicator = hw->fcf_indicator;
10958 ocs_hw_t *hw = domain->hw;
10960 ocs_hw_domain_del(hw, domain);
10962 if (hw->callback.domain != NULL) {
10963 hw->callback.domain(hw->args.domain,
10971 ocs_free(domain != NULL ? domain->hw->os : NULL, data, SLI4_BMBX_SIZE);
10995 ocs_hw_t *hw = domain->hw;
10998 sli_resource_free(&hw->sli, SLI_RSRC_FCOE_VFI,
11001 ocs_hw_domain_del(hw, domain);
11004 if (hw->callback.domain != NULL) {
11005 hw->callback.domain(hw->args.domain,
11029 ocs_hw_t *hw = domain->hw;
11036 if (hw->state == OCS_HW_STATE_TEARDOWN_IN_PROGRESS) {
11040 if (0 == sli_cmd_fcoe_rediscover_fcf(&hw->sli, data, SLI4_BMBX_SIZE, domain->fcf)) {
11041 ocs_log_err(hw->os, "REDISCOVER_FCF format failure\n");
11046 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_domain_cb, domain)) {
11047 ocs_log_err(hw->os, "REDISCOVER_FCF command failure\n");
11070 ocs_hw_t *hw = domain->hw;
11077 data = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
11084 if (0 == sli_cmd_unreg_fcfi(&hw->sli, data, SLI4_BMBX_SIZE, domain->fcf_indicator)) {
11085 ocs_log_err(hw->os, "UNREG_FCFI format failure\n");
11086 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
11091 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_domain_cb, domain)) {
11092 ocs_log_err(hw->os, "UNREG_FCFI command failure\n");
11093 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
11123 ocs_hw_t *hw = domain->hw;
11128 is_fc = (sli_get_medium(&hw->sli) == SLI_LINK_MEDIUM_FC);
11133 data = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
11140 if (0 == sli_cmd_unreg_vfi(&hw->sli, data, SLI4_BMBX_SIZE, domain,
11142 ocs_log_err(hw->os, "UNREG_VFI format failure\n");
11143 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
11148 if (ocs_hw_command(hw, data, OCS_CMD_NOWAIT, __ocs_hw_domain_cb, domain)) {
11149 ocs_log_err(hw->os, "UNREG_VFI command failure\n");
11150 ocs_free(hw->os, data, SLI4_BMBX_SIZE);
11179 __ocs_hw_domain_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
11186 ocs_log_debug(hw->os, "bad status vfi=%#x st=%x hdr=%x\n",
11199 target_wqe_timer_nop_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
11209 ocs_log_debug(hw->os, "bad status st=%x hdr=%x\n",
11215 ocs_lock(&hw->io_lock);
11216 ocs_list_foreach_safe(&hw->io_timed_wqe, io, io_next) {
11224 ocs_log_test(hw->os, "IO timeout xri=0x%x tag=0x%x type=%d\n",
11228 ocs_list_remove(&hw->io_timed_wqe, io);
11237 ocs_hw_io_abort(hw, io, FALSE, NULL, NULL);
11244 ocs_unlock(&hw->io_lock);
11247 if (!hw->active_wqe_timer_shutdown) {
11248 ocs_setup_timer(hw->os, &hw->wqe_timer, target_wqe_timer_cb, hw, OCS_HW_WQ_TIMER_PERIOD_MS);
11250 hw->in_active_wqe_timer = FALSE;
11257 ocs_hw_t *hw = (ocs_hw_t *)arg;
11260 hw->in_active_wqe_timer = TRUE;
11261 ocs_del_timer(&hw->wqe_timer);
11264 if (ocs_hw_async_call(hw, target_wqe_timer_nop_cb, hw)) {
11265 ocs_log_test(hw->os, "ocs_hw_async_call failed\n");
11270 shutdown_target_wqe_timer(ocs_hw_t *hw)
11274 if (hw->config.emulate_tgt_wqe_timeout) {
11276 hw->active_wqe_timer_shutdown = TRUE;
11279 ocs_del_timer(&hw->wqe_timer);
11282 while (hw->in_active_wqe_timer && iters) {
11287 ocs_hw_flush(hw);
11292 ocs_log_test(hw->os, "Failed to shutdown active wqe timer\n");
11303 * @param hw Hardware context allocated by the caller.
11309 ocs_hw_is_io_port_owned(ocs_hw_t *hw, ocs_hw_io_t *io)
11321 * @param hw Hardware context.
11328 ocs_hw_is_xri_port_owned(ocs_hw_t *hw, uint32_t xri)
11330 ocs_hw_io_t *io = ocs_hw_io_lookup(hw, xri);
11340 * @param hw Hardware context.
11345 ocs_hw_reclaim_xri(ocs_hw_t *hw, uint16_t xri_base, uint16_t xri_count)
11351 io = ocs_hw_io_lookup(hw, xri_base + i);
11357 if (hw->auto_xfer_rdy_enabled) {
11358 ocs_hw_rqpair_auto_xfer_rdy_move_to_host(hw, io);
11361 ocs_lock(&hw->io_lock);
11362 ocs_list_remove(&hw->io_port_owned, io);
11364 ocs_list_add_tail(&hw->io_free, io);
11365 ocs_unlock(&hw->io_lock);
11375 * @param hw Hardware context.
11383 ocs_hw_cb_post_xri(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
11389 ocs_log_debug(hw->os, "Status 0x%x for XRI base 0x%x, cnt =x%x\n",
11391 ocs_hw_reclaim_xri(hw, post_xri->xri_base, post_xri->xri_count);
11394 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
11401 * @param hw Hardware context.
11409 ocs_hw_post_xri(ocs_hw_t *hw, uint32_t xri_start, uint32_t num_to_post)
11415 post_xri = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
11417 ocs_log_err(hw->os, "no buffer for command\n");
11422 if (sli_cmd_post_xri(&hw->sli, post_xri, SLI4_BMBX_SIZE,
11424 rc = ocs_hw_command(hw, post_xri, OCS_CMD_NOWAIT, ocs_hw_cb_post_xri, NULL);
11426 ocs_free(hw->os, post_xri, SLI4_BMBX_SIZE);
11427 ocs_log_err(hw->os, "post_xri failed\n");
11439 * @param hw Hardware context.
11446 ocs_hw_xri_move_to_port_owned(ocs_hw_t *hw, uint32_t num_xri)
11457 ocs_lock(&hw->io_lock);
11461 if (NULL != (io = ocs_list_remove_head(&hw->io_free))) {
11470 if (hw->auto_xfer_rdy_enabled) {
11472 ocs_unlock(&hw->io_lock);
11473 rc = ocs_hw_rqpair_auto_xfer_rdy_move_to_port(hw, io);
11474 ocs_lock(&hw->io_lock);
11476 ocs_list_add_head(&hw->io_free, io);
11480 ocs_lock_init(hw->os, &io->axr_lock, "HW_axr_lock[%d]", io->indicator);
11482 ocs_list_add_tail(&hw->io_port_owned, io);
11485 if (ocs_hw_post_xri(hw, io->indicator, 1) != OCS_HW_RTN_SUCCESS ) {
11486 ocs_hw_reclaim_xri(hw, io->indicator, i);
11495 ocs_unlock(&hw->io_lock);
11506 * @param hw Hardware context.
11514 ocs_hw_cb_release_xri(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
11521 ocs_log_err(hw->os, "Status 0x%x\n", status);
11526 ocs_hw_reclaim_xri(hw, xri, 1);
11530 ocs_free(hw->os, mqe, SLI4_BMBX_SIZE);
11539 * @param hw Hardware context.
11546 ocs_hw_xri_move_to_host_owned(ocs_hw_t *hw, uint8_t num_xri)
11552 release_xri = ocs_malloc(hw->os, SLI4_BMBX_SIZE, OCS_M_NOWAIT);
11554 ocs_log_err(hw->os, "no buffer for command\n");
11559 if (sli_cmd_release_xri(&hw->sli, release_xri, SLI4_BMBX_SIZE, num_xri)) {
11560 rc = ocs_hw_command(hw, release_xri, OCS_CMD_NOWAIT, ocs_hw_cb_release_xri, NULL);
11562 ocs_log_err(hw->os, "release_xri failed\n");
11567 ocs_free(hw->os, release_xri, SLI4_BMBX_SIZE);
11579 * @param hw Pointer to HW object.
11587 ocs_hw_rx_buffer_alloc(ocs_hw_t *hw, uint32_t rqindex, uint32_t count, uint32_t size)
11589 ocs_t *ocs = hw->os;
11595 rq_buf = ocs_malloc(hw->os, sizeof(*rq_buf) * count, OCS_M_NOWAIT | OCS_M_ZERO);
11597 ocs_log_err(hw->os, "Failure to allocate unsolicited DMA trackers\n");
11604 ocs_log_err(hw->os, "DMA allocation failed\n");
11605 ocs_free(hw->os, rq_buf, sizeof(*rq_buf) * count);
11620 * @param hw Pointer to HW object.
11627 ocs_hw_rx_buffer_free(ocs_hw_t *hw, ocs_hw_rq_buffer_t *rq_buf, uint32_t count)
11629 ocs_t *ocs = hw->os;
11637 ocs_free(hw->os, rq_buf, sizeof(*rq_buf) * count);
11644 * @param hw Pointer to HW object.
11649 ocs_hw_rx_allocate(ocs_hw_t *hw)
11651 ocs_t *ocs = hw->os;
11657 uint32_t payload_size = hw->config.rq_default_buffer_size;
11661 for (i = 0; i < hw->hw_rq_count; i++) {
11662 rq = hw->hw_rq[i];
11665 rq->hdr_buf = ocs_hw_rx_buffer_alloc(hw, rqindex, rq->entry_count, hdr_size);
11672 ocs_log_debug(hw->os, "rq[%2d] rq_id %02d header %4d by %4d bytes\n", i, rq->hdr->id,
11678 rq->payload_buf = ocs_hw_rx_buffer_alloc(hw, rqindex, rq->entry_count, payload_size);
11684 ocs_log_debug(hw->os, "rq[%2d] rq_id %02d default %4d by %4d bytes\n", i, rq->data->id,
11695 * @param hw Pointer to HW object.
11700 ocs_hw_rx_post(ocs_hw_t *hw)
11711 for (rq_idx = 0, idx = 0; rq_idx < hw->hw_rq_count; rq_idx++) {
11712 hw_rq_t *rq = hw->hw_rq[rq_idx];
11715 ocs_hw_sequence_t *seq = ocs_array_get(hw->seq_pool, idx++);
11722 rc = ocs_hw_sequence_free(hw, seq);
11738 * @param hw Pointer to HW object.
11742 ocs_hw_rx_free(ocs_hw_t *hw)
11748 for (i = 0; i < hw->hw_rq_count; i++) {
11749 rq = hw->hw_rq[i];
11751 ocs_hw_rx_buffer_free(hw, rq->hdr_buf, rq->entry_count);
11753 ocs_hw_rx_buffer_free(hw, rq->payload_buf, rq->entry_count);
11775 * @param hw Pointer to HW object.
11783 ocs_hw_async_cb(ocs_hw_t *hw, int32_t status, uint8_t *mqe, void *arg)
11789 (*ctx->callback)(hw, status, mqe, ctx->arg);
11791 ocs_free(hw->os, ctx, sizeof(*ctx));
11802 * @param hw Pointer to HW object.
11809 ocs_hw_async_call(ocs_hw_t *hw, ocs_hw_async_cb_t callback, void *arg)
11819 ctx = ocs_malloc(hw->os, sizeof(*ctx), OCS_M_ZERO | OCS_M_NOWAIT);
11821 ocs_log_err(hw->os, "failed to malloc async call context\n");
11828 if (sli_cmd_common_nop(&hw->sli, ctx->cmd, sizeof(ctx->cmd), 0) == 0) {
11829 ocs_log_err(hw->os, "COMMON_NOP format failure\n");
11830 ocs_free(hw->os, ctx, sizeof(*ctx));
11834 if (ocs_hw_command(hw, ctx->cmd, OCS_CMD_NOWAIT, ocs_hw_async_cb, ctx)) {
11835 ocs_log_err(hw->os, "COMMON_NOP command failure\n");
11836 ocs_free(hw->os, ctx, sizeof(*ctx));
11848 * @param hw Pointer to HW object.
11853 ocs_hw_reqtag_init(ocs_hw_t *hw)
11855 if (hw->wq_reqtag_pool == NULL) {
11856 hw->wq_reqtag_pool = ocs_pool_alloc(hw->os, sizeof(hw_wq_callback_t), 65536, TRUE);
11857 if (hw->wq_reqtag_pool == NULL) {
11858 ocs_log_err(hw->os, "ocs_pool_alloc hw_wq_callback_t failed\n");
11862 ocs_hw_reqtag_reset(hw);
11871 * @param hw Pointer to HW object.
11878 ocs_hw_reqtag_alloc(ocs_hw_t *hw, void (*callback)(void *arg, uint8_t *cqe, int32_t status), void *arg)
11884 wqcb = ocs_pool_get(hw->wq_reqtag_pool);
11898 * @param hw Pointer to HW object.
11904 ocs_hw_reqtag_free(ocs_hw_t *hw, hw_wq_callback_t *wqcb)
11909 ocs_pool_put(hw->wq_reqtag_pool, wqcb);
11918 * @param hw Pointer to HW object.
11924 ocs_hw_reqtag_get_instance(ocs_hw_t *hw, uint32_t instance_index)
11928 wqcb = ocs_pool_get_instance(hw->wq_reqtag_pool, instance_index);
11930 ocs_log_err(hw->os, "wqcb for instance %d is null\n", instance_index);
11941 * @param hw pointer to HW object.
11946 ocs_hw_reqtag_reset(ocs_hw_t *hw)
11952 while(ocs_pool_get(hw->wq_reqtag_pool) != NULL) {
11957 for (i = 0; ((wqcb = ocs_pool_get_instance(hw->wq_reqtag_pool, i)) != NULL); i++) {
11961 ocs_pool_put(hw->wq_reqtag_pool, wqcb);
12008 * @param hw Pointer to HW object.
12014 ocs_hw_reque_xri( ocs_hw_t *hw, ocs_hw_io_t *io )
12018 rc = ocs_hw_rqpair_auto_xfer_rdy_buffer_post(hw, io, 1);
12020 ocs_list_add_tail(&hw->io_port_dnrx, io);
12027 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)) {
12029 ocs_pool_put(hw->auto_xfer_rdy_buf_pool, io->axr_buf);
12032 ocs_log_err(hw->os, "requeue_xri WQE error\n");
12033 ocs_list_add_tail(&hw->io_port_dnrx, io);
12040 io->wq = ocs_hw_queue_next_wq(hw, io);
12048 OCS_STAT(hw->tcmd_wq_submit[io->wq->instance]++);
12053 ocs_log_err(hw->os, "sli_queue_write reque xri failed: %d\n", rc);
12064 sli4_t *sli4 = &ocs->hw.sli;
12237 * This contains all hw runtime workaround code. Based on the asic type,
12246 * would have the driver look like: "if (hw->workaround.enable_xxx) then ...", rather than
12368 static int32_t ocs_hw_workaround_match(ocs_hw_t *hw, hw_workaround_t *w);
12411 * @param hw Pointer to the HW structure
12418 ocs_hw_workaround_match(ocs_hw_t *hw, hw_workaround_t *w)
12420 return (((w->asic_type == SLI4_ASIC_TYPE_ANY) || (w->asic_type == hw->sli.asic_type)) &&
12421 ((w->asic_rev == SLI4_ASIC_REV_ANY) || (w->asic_rev == hw->sli.asic_rev)) &&
12422 (w->fwrev_low <= hw->workaround.fwrev) &&
12423 ((w->fwrev_high == HW_FWREV_MAX) || (hw->workaround.fwrev < w->fwrev_high)));
12432 * @param hw Pointer to HW structure
12438 ocs_hw_workaround_setup(struct ocs_hw_s *hw)
12441 sli4_t *sli4 = &hw->sli;
12445 ocs_memset(&hw->workaround, 0, sizeof(hw->workaround));
12451 if (hw->hw_war_version) {
12452 hw->workaround.fwrev = parse_fw_version(hw->hw_war_version);
12454 hw->workaround.fwrev = parse_fw_version((char*) sli4->config.fw_name[0]);
12459 if (ocs_hw_workaround_match(hw, w)) {
12463 ocs_log_debug(hw->os, "Override: test: %d\n", w->value);
12468 ocs_log_debug(hw->os, "HW Workaround: retain TSEND IO length\n");
12469 hw->workaround.retain_tsend_io_length = 1;
12475 ocs_log_debug(hw->os, "HW Workaround: override max_qentries: %d\n", w->value);
12477 if (hw->num_qentries[q] > w->value) {
12478 hw->num_qentries[q] = w->value;
12484 ocs_log_debug(hw->os, "HW Workaround: override RQ max_qentries: %d\n", w->value);
12485 if (hw->num_qentries[SLI_QTYPE_RQ] > w->value) {
12486 hw->num_qentries[SLI_QTYPE_RQ] = w->value;
12491 ocs_log_debug(hw->os, "HW Workaround: set WQE count method=%d\n", w->value);
12497 ocs_log_debug(hw->os, "HW Workaround: set RQE count method=%d\n", w->value);
12503 ocs_log_debug(hw->os, "HW Workaround: use unreg'd RPI if rnode->indicator == 0xFFFF\n");
12504 hw->workaround.use_unregistered_rpi = TRUE;
12509 if (sli_resource_alloc(&hw->sli, SLI_RSRC_FCOE_RPI, &hw->workaround.unregistered_rid,
12510 &hw->workaround.unregistered_index)) {
12511 ocs_log_err(hw->os, "sli_resource_alloc unregistered RPI failed\n");
12512 hw->workaround.use_unregistered_rpi = FALSE;
12516 ocs_log_debug(hw->os, "HW Workaround: disable AR on T10-PI TSEND\n");
12517 hw->workaround.disable_ar_tgt_dif = TRUE;
12520 ocs_log_debug(hw->os, "HW Workaround: disable set_dump_loc\n");
12521 hw->workaround.disable_dump_loc = TRUE;
12524 ocs_log_debug(hw->os, "HW Workaround: use DIF quarantine\n");
12525 hw->workaround.use_dif_quarantine = TRUE;
12528 ocs_log_debug(hw->os, "HW Workaround: use DIF secondary xri\n");
12529 hw->workaround.use_dif_sec_xri = TRUE;
12532 ocs_log_debug(hw->os, "HW Workaround: override FCFI in SRB\n");
12533 hw->workaround.override_fcfi = TRUE;
12537 ocs_log_debug(hw->os, "HW Workaround: fw version is below the minimum for this driver\n");
12538 hw->workaround.fw_version_too_low = TRUE;
12541 ocs_log_debug(hw->os, "HW Workaround: SGLC misreported - chaining is enabled\n");
12542 hw->workaround.sglc_misreported = TRUE;
12545 ocs_log_debug(hw->os, "HW Workaround: not SEND_FRAME capable - disabled\n");
12546 hw->workaround.ignore_send_frame = TRUE;