7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * CDDL HEADER START
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * The contents of this file are subject to the terms of the
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Common Development and Distribution License (the "License").
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * You may not use this file except in compliance with the License.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * See the License for the specific language governing permissions
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * and limitations under the License.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * When distributing Covered Code, include this CDDL HEADER in each
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * If applicable, add the following below this CDDL HEADER, with the
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fields enclosed by brackets "[]" replaced with your own identifying
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * information: Portions Copyright [yyyy] [name of copyright owner]
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * CDDL HEADER END
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * The following notice accompanied the original version of this file:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * BSD LICENSE
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Copyright(c) 2007 Intel Corporation. All rights reserved.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * All rights reserved.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Redistribution and use in source and binary forms, with or without
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * modification, are permitted provided that the following conditions
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * * Redistributions of source code must retain the above copyright
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * notice, this list of conditions and the following disclaimer.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * * Redistributions in binary form must reproduce the above copyright
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * notice, this list of conditions and the following disclaimer in
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * the documentation and/or other materials provided with the
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * distribution.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * * Neither the name of Intel Corporation nor the names of its
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * contributors may be used to endorse or promote products derived
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * from this software without specific prior written permission.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
516aa12c0e0be4dde28b9fc2b3d928230a8e4c42Yu Renia Miao * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * This file defines interface functions between fcoe and fcoei driver.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * LEADVILLE header files
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * COMSTAR header files
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * FCOE header files
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Driver's own header files
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Forward declaration of internal functions
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void fcoei_process_unsol_els_req(fcoe_frame_t *frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void fcoei_process_sol_els_rsp(fcoe_frame_t *frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void fcoei_process_unsol_abts_req(fcoe_frame_t *frame);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void fcoei_process_sol_abts_acc(fcoe_frame_t *frame);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void fcoei_process_sol_abts_rjt(fcoe_frame_t *frame);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void fcoei_process_sol_ct_rsp(fcoe_frame_t *frame);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void fcoei_process_unsol_xfer_rdy(fcoe_frame_t *frame);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void fcoei_process_sol_fcp_resp(fcoe_frame_t *frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void fcoei_fill_fcp_resp(uint8_t *src, uint8_t *dest, int size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void fcoei_fill_els_fpkt_resp(fcoe_frame_t *frm, fcoei_exchange_t *xch,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_rx_frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Unsolicited frame is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frame = unsolicited frame that is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (!(FRM2SS(frm)->ss_flags & SS_FLAG_LV_BOUND)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Release the frame and netb
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2IFM(frm)->ifm_ae.ae_type = AE_EVENT_UNSOL_FRAME;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang list_insert_tail(&FRM2SS(frm)->ss_event_list, &FRM2IFM(frm)->ifm_ae);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (FRM2SS(frm)->ss_flags & SS_FLAG_WATCHDOG_IDLE) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_release_sol_frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Release the solicited frame that has just been sent out
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frame = solicited frame that has been sent out
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * After FCOE sends solicited frames out, it will call this to notify
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * FCOEI of the completion.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * For request-type frames, it's safe to be handled out of
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * watchdog, because it needn't update anything
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2IFM(frm)->ifm_ae.ae_type = AE_EVENT_SOL_FRAME;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (FRM2SS(frm)->ss_flags & SS_FLAG_WATCHDOG_IDLE) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_unsol_xfer_rdy
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * XFER_RDY is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = XFER_RDY frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * rcv_buf_size is the total size of data that should be transferred
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * in this sequence.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * offset is based on the exchange not the sequence.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Local variables initialization
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang data_size = FRM2SS(frm)->ss_fcp_data_payload_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm_num = (rcv_buf_size + data_size - 1) / data_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * The first (frm_num -1) frames are always full
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_eport, data_size + FCFH_SIZE, NULL);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Copy the data payload that will be transferred
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(offset + (uint8_t *)xch->xch_fpkt->pkt_data,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Submit the frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Update offset and left_size
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Send the last data frame of this sequence
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_ss->ss_eport, data_size + FCFH_SIZE, NULL);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Copy the data payload that will be transferred
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(offset + (uint8_t *)xch->xch_fpkt->pkt_data,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Set ifm_rctl for fcoei_handle_sol_frame_done
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Submit the frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Sequence is a transaction, so we need only update
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * xch_remained_bytes in the end.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_unsol_els_req
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * els req frame is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = ELS request frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We will not create exchange data structure at this time,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * and we should create unsolicited buffer, which will only
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * contain the exchange's request payload.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Get the unsol rxid first
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Do proper ub initialization
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ub = (fc_unsol_buf_t *)kmem_zalloc(sizeof (fc_unsol_buf_t), KM_SLEEP);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ub->ub_buffer = kmem_alloc(frm->frm_payload_size, KM_SLEEP);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * header conversion
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Caution: ub_buffer is big endian, but ub_frame should be host-format
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * RSCN is one exception.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * If it's FLOGI, and our FLOGI failed last time,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * then we post online event
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if ((FRM2SS(frm)->ss_flags & SS_FLAG_FLOGI_FAILED) &&
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_bind_info.port_statec_cb(FRM2SS(frm)->ss_port,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Only RSCN need byte swapping
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang for (int i = 0; i < rscn->rscn_payload_len - 4; i += 4) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *(uint32_t *)((intptr_t)(uint8_t *)ub->ub_buffer +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(frm->frm_payload, ub->ub_buffer, frm->frm_payload_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Pass this unsol ELS up to Leadville
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_bind_info.port_unsol_cb(FRM2SS(frm)->ss_port, ub, 0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_search_abort_xch
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Find the exchange that should be aborted
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * key = oxid of the exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * val = the exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * arg = the soft state
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * MH_WALK_TERMINATE = found it, terminate the walk
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * MH_WALK_CONTINUE = not found, continue the walk
516aa12c0e0be4dde28b9fc2b3d928230a8e4c42Yu Renia Miao/* ARGSUSED */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_search_abort_xch(mod_hash_key_t key, mod_hash_val_t *val, void *arg)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_unsol_abts_req
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ABTS request is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = ABTS request frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * The remote side wants to abort one unsolicited exchange.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * According to spec, the responder could want to ABTS xch too
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (void) mod_hash_find(FRM2SS(frm)->ss_sol_oxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * it's a unsolicited exchange, and we need find it out from
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * unsolicited hash table. But at this time, RXID in frame could
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * still be 0xFFFF in most cases, so we need do exaustive search
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bzero(nfrm->frm_payload, nfrm->frm_payload_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We should complete the exchange with frm as NULL,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * and we don't care its success or failure
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_complete_xch(xch, NULL, FC_PKT_FAILURE, FC_REASON_ABTX);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Construct ABTS ACC frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_eport, payload_size + FCFH_SIZE, NULL);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bzero(nfrm->frm_payload, nfrm->frm_payload_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nfrm->frm_payload[4] = 0xFF & (xch->xch_oxid >> 8);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nfrm->frm_payload[6] = 0xFF & (xch->xch_rxid >> 8);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_sol_fcp_resp
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * FCP response is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = FCP response frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Firstly, we search the related exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "can't find the corresponding xch: "
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Decide the actual response length
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Update the exchange and hash table
ef4cb712a006dbd6839858fde222aedff76e1bcbZhong Wang (void) mod_hash_remove(FRM2SS(frm)->ss_sol_oxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Upate fpkt related elements
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * we should set pkt_reason and pkt_state carefully
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * First we zero the first 12 byte of dest
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (uint8_t *)xch->xch_fpkt->pkt_resp, actual_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Update pkt_resp_resid
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if ((xch->xch_resid != 0) && ((xch->xch_resid % 0x200) == 0) &&
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "frame lost no pause ? %x/%x",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Notify LV it's over
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "BEFORE WAKEUP: %p-%p", fpkt, xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "AFTERE WAKEUP: %p-%p", fpkt, xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_sol_els_rsp
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ELS response is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = ELS response frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Look for the related exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Decide the actual response length
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Upate fpkt related elements
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * we should set pkt_reason and pkt_state carefully now
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Need to analyze pkt_reason according to the response.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Leave it untouched now.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (((ls_code_t *)(void *)xch->xch_fpkt->pkt_resp)->ls_code ==
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_complete_xch(xch, NULL, FC_PKT_SUCCESS, 0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_sol_ct_rsp
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * CT response is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = CT response frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Look for the related exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Decide the actual response length
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "0x(%x - %x)", actual_size, frm->frm_payload_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Update fpkt related elements
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Caution: we needn't do byte swapping for CT response
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(FPLD, (uint8_t *)xch->xch_fpkt->pkt_resp, actual_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Complete it with frm as NULL
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_complete_xch(xch, NULL, FC_PKT_SUCCESS, 0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_sol_abts_acc
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ABTS accpet is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = ABTS accept frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We will always finish the abortion of solicited exchanges,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * so we will not depend on the response from the remote side.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We just log one message.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "the remote side has agreed to "
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "abort the exchange: oxid-%x, rxid-%x",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_sol_abts_rjt
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ABTS reject is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = ABTS reject frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We will alwayas finish the abortion of solicited exchanges,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * so we will not depend on the response from the remote side.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We just log one message.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "the remote side rejected "
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_fill_els_fpkt_resp
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Fill fpkt ELS response in host format according frm payload
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * src = frm payload in link format
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * dest = fpkt ELS response in host format
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * size = Maximum conversion size
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * els_op = ELS opcode
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fpkt->pkt_resp must be mapped to one data structure, and it's
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * different from the content in the raw frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_fill_els_fpkt_resp(fcoe_frame_t *frm, fcoei_exchange_t *xch, int size)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint8_t *dest = (uint8_t *)xch->xch_fpkt->pkt_resp;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang la_els_logi_t *els_logi = (la_els_logi_t *)(void *)dest;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang la_els_adisc_t *els_adisc = (la_els_adisc_t *)(void *)dest;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang switch (((ls_code_t *)(void *)xch->xch_fpkt->pkt_cmd)->ls_code) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We are in fabric p2p mode
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We are in direct p2p mode
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_p2p_info.fca_d_id = FRM_D_ID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* FALLTHROUGH */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_p2p_info.fca_d_id = FRM_D_ID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = offsetof(la_els_logi_t, common_service);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->common_service.fcph_version = FCOE_B2V_2(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->common_service.btob_credit = FCOE_B2V_2(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->common_service.cmn_features = FCOE_B2V_2(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->common_service.rx_bufsize = FCOE_B2V_2(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->common_service.conc_sequences = FCOE_B2V_2(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->common_service.relative_offset = FCOE_B2V_2(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->common_service.e_d_tov = FCOE_B2V_4(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(src + offset, &els_logi->nport_ww_name, 8);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->class_3.class_opt = FCOE_B2V_2(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->class_3.initiator_ctl = FCOE_B2V_2(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->class_3.recipient_ctl = FCOE_B2V_2(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->class_3.rcv_size = FCOE_B2V_2(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->class_3.conc_sequences = FCOE_B2V_2(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->class_3.n_port_e_to_e_credit = FCOE_B2V_2(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->class_3.open_seq_per_xchng = FCOE_B2V_2(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * PRLI service parameter response page
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcp_prli_acc doesn't include ls_code, don't use offsetof
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc = (struct fcp_prli_acc *)(void *)(dest + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Type code extension
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * PRLI response flags
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * process associator
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc->orig_process_associator = FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc->resp_process_associator = FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * could only be LS_ACC, no additional information
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * LS_ACC/LS_RJT, no additional information
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_adisc->hard_addr.hard_addr = FCOE_B2V_3(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_adisc->nport_id.port_id = FCOE_B2V_3(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(src + offset, &els_rnid->hdr.data_format, 1);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(src + offset, &els_rnid->hdr.specific_len, 1);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(src + offset, els_rnid->data, FCIO_RNID_MAX_DATA_LEN);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_fill_fcp_resp
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Fill fpkt FCP response in host format according to frm payload
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * src - frm payload in link format
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * dest - fpkt FCP response in host format
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * size - Maximum conversion size
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * This is called only for SCSI response with non good status
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_fill_fcp_resp(uint8_t *src, uint8_t *dest, int size)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcp_rsp_t *fcp_rsp_iu = (fcp_rsp_t *)(void *)dest;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * set fcp_status
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcp_rsp_iu->fcp_u.fcp_status.scsi_status = FCOE_B2V_1(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcp_rsp_iu->fcp_resid = FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcp_rsp_iu->fcp_sense_len = FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcp_rsp_iu->fcp_response_len = FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * sense or response
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if ((offset + fcp_rsp_iu->fcp_sense_len) > size) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "buffer too small - sens");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(src + offset, dest + offset, fcp_rsp_iu->fcp_sense_len);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if ((offset + fcp_rsp_iu->fcp_response_len) > size) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "buffer too small - resp");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ect->ect_release_sol_frame = fcoei_release_sol_frame;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_unsol_frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Unsolicited frame is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frame = unsolicited frame that is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * watchdog will call this to process unsolicited frames that we
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * just received fcoei_process_xx is used to handle different
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * unsolicited frames
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * READ data phase frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Find the associated exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "associated xch not found: "
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Copy data into fpkt data buffer, and update the counter
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(frm->frm_payload, (uint8_t *)xch->xch_fpkt->pkt_data +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Unsupported frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Release the frame and netb
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_handle_sol_frame_done
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * solicited frame is just sent out
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frame = solicited frame that has been sent out
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * watchdog will call this to handle solicited frames that FCOEI
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * has sent out Non-request frame post handling
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * the corresponding xch could be NULL at this time
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Complete it with frm as NULL
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_complete_xch(xch, NULL, FC_PKT_SUCCESS, 0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "BA_ACC out: xch-%p, frm-%p",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "BA_RJT out: xch-%p, frm-%p",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Unsupported frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We should release only the frame, and we don't care its netb
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_port_event
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * link/port state changed
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * eport = to indicate which port has changed
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * event = what change
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * refer fctl.h for ss_link_state value
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_port_event(fcoe_port_t *eport, uint32_t event)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (!(EPORT2SS(eport)->ss_flags & SS_FLAG_LV_BOUND)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_enter(&EPORT2SS(eport)->ss_watchdog_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang EPORT2SS(eport)->ss_link_state = FC_STATE_OFFLINE;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang cmn_err(CE_NOTE, "%02x%02x%02x%02x%02x%02x%02x%02x Link down",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang eport->eport_portwwn[0], eport->eport_portwwn[1],
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang eport->eport_portwwn[2], eport->eport_portwwn[3],
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang eport->eport_portwwn[4], eport->eport_portwwn[5],
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang eport->eport_portwwn[6], eport->eport_portwwn[7]);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "fcoei: MTU is not big enough. "
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "we will use 1K frames in FCP data phase.");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang cmn_err(CE_NOTE, "%02x%02x%02x%02x%02x%02x%02x%02x Link up",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang eport->eport_portwwn[0], eport->eport_portwwn[1],
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang eport->eport_portwwn[2], eport->eport_portwwn[3],
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang eport->eport_portwwn[4], eport->eport_portwwn[5],
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang eport->eport_portwwn[6], eport->eport_portwwn[7]);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang EPORT2SS(eport)->ss_link_state = FC_STATE_ONLINE;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ae = (fcoei_event_t *)kmem_zalloc(sizeof (fcoei_event_t), KM_SLEEP);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ae->ae_specific = EPORT2SS(eport)->ss_link_state;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang list_insert_tail(&EPORT2SS(eport)->ss_event_list, ae);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_event_port
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * link/port state changed
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ae = link fcoei_event
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * asynchronous events from FCOE
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_soft_state_t *ss = (fcoei_soft_state_t *)ae->ae_obj;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss->ss_eport->eport_link_speed == FCOE_PORT_SPEED_1G) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "ss %p not bound now", ss);