7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * CDDL HEADER START
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
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 *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * or http://www.opensolaris.org/os/licensing.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * See the License for the specific language governing permissions
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * and limitations under the License.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
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 *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * CDDL HEADER END
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * The following notice accompanied the original version of this file:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * BSD LICENSE
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Copyright(c) 2007 Intel Corporation. All rights reserved.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * All rights reserved.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
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 * are met:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
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 *
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.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
516aa12c0e0be4dde28b9fc2b3d928230a8e4c42Yu Renia Miao * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * This file defines interface functions between fcoe and fcoei driver.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/conf.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/ddi.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/stat.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/pci.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/sunddi.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/modctl.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/file.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/cred.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/byteorder.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/atomic.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/scsi/scsi.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/mac_client.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/modhash.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * LEADVILLE header files
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/fibre-channel/fc.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/fibre-channel/impl/fc_fcaif.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * COMSTAR header files
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/stmf_defines.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * FCOE header files
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <sys/fcoe/fcoe_common.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Driver's own header files
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang#include <fcoei.h>
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Forward declaration of internal functions
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
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 Wang
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 int size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_rx_frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Unsolicited frame is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frame = unsolicited frame that is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Return:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comment:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_rx_frame(fcoe_frame_t *frm)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (!(FRM2SS(frm)->ss_flags & SS_FLAG_LV_BOUND)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Release the frame and netb
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "not bound now");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm->frm_eport->eport_free_netb(frm->frm_netb);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm->frm_eport->eport_release_frame(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2IFM(frm)->ifm_ae.ae_type = AE_EVENT_UNSOL_FRAME;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2IFM(frm)->ifm_ae.ae_obj = frm;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_enter(&FRM2SS(frm)->ss_watchdog_mutex);
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 cv_signal(&FRM2SS(frm)->ss_watchdog_cv);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&FRM2SS(frm)->ss_watchdog_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_release_sol_frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Release the solicited frame that has just been sent out
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frame = solicited frame that has been sent out
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * After FCOE sends solicited frames out, it will call this to notify
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * FCOEI of the completion.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_release_sol_frame(fcoe_frame_t *frm)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
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 */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang switch (FRM2IFM(frm)->ifm_rctl) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_SOLICITED_DATA:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_COMMAND:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_ELS_REQ:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_UNSOL_CONTROL:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_LS_ABTS:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_eport->eport_release_frame(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang default:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2IFM(frm)->ifm_ae.ae_type = AE_EVENT_SOL_FRAME;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2IFM(frm)->ifm_ae.ae_obj = frm;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_enter(&FRM2SS(frm)->ss_watchdog_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang list_insert_tail(&FRM2SS(frm)->ss_event_list,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang &FRM2IFM(frm)->ifm_ae);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (FRM2SS(frm)->ss_flags & SS_FLAG_WATCHDOG_IDLE) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang cv_signal(&FRM2SS(frm)->ss_watchdog_cv);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&FRM2SS(frm)->ss_watchdog_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_unsol_xfer_rdy
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * XFER_RDY is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = XFER_RDY frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_process_unsol_xfer_rdy(fcoe_frame_t *frm)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint16_t sol_oxid;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_exchange_t *xch;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int rcv_buf_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int offset;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int left_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int data_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int frm_num;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int idx;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoe_frame_t *nfrm;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang sol_oxid = FRM_OXID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (mod_hash_find(FRM2SS(frm)->ss_sol_oxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FMHK(sol_oxid), (mod_hash_val_t *)&xch) != 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
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 */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_rxid = FRM_RXID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang rcv_buf_size = FCOE_B2V_4(frm->frm_payload + 4);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = FCOE_B2V_4(frm->frm_payload);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ASSERT(xch->xch_resid >= rcv_buf_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Local variables initialization
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang left_size = rcv_buf_size;
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
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang for (idx = 0; idx < frm_num - 1; idx++) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * The first (frm_num -1) frames are always full
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nfrm = FRM2SS(frm)->ss_eport->eport_alloc_frame(
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_eport, data_size + FCFH_SIZE, NULL);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (nfrm == NULL) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "can't alloc frame");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Copy the data payload that will be transferred
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(offset + (uint8_t *)xch->xch_fpkt->pkt_data,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nfrm->frm_payload, nfrm->frm_payload_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_R_CTL(R_CTL_SOLICITED_DATA, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_TYPE(FC_TYPE_SCSI_FCP, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_F_CTL(0x010008, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_OXID(xch->xch_oxid, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_RXID(xch->xch_rxid, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_S_ID(FRM_D_ID(frm), nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_D_ID(FRM_S_ID(frm), nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_SEQ_CNT(idx, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_PARAM(offset, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_init_ifm(nfrm, xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Submit the frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_ss->ss_eport->eport_tx_frame(nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Update offset and left_size
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += data_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang left_size -= data_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Send the last data frame of this sequence
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang data_size = left_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nfrm = xch->xch_ss->ss_eport->eport_alloc_frame(
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_ss->ss_eport, data_size + FCFH_SIZE, NULL);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (nfrm != NULL) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_init_ifm(nfrm, xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ASSERT(0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Copy the data payload that will be transferred
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(offset + (uint8_t *)xch->xch_fpkt->pkt_data,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nfrm->frm_payload, nfrm->frm_payload_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Set ifm_rctl for fcoei_handle_sol_frame_done
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2IFM(nfrm)->ifm_rctl = R_CTL_SOLICITED_DATA;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * FFM
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_R_CTL(R_CTL_SOLICITED_DATA, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_TYPE(FC_TYPE_SCSI_FCP, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_F_CTL(0x090008, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_OXID(xch->xch_oxid, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_RXID(xch->xch_rxid, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_S_ID(FRM_D_ID(frm), nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_D_ID(FRM_S_ID(frm), nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_SEQ_CNT(idx, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_PARAM(offset, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Submit the frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_ss->ss_eport->eport_tx_frame(nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Sequence is a transaction, so we need only update
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * xch_remained_bytes in the end.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_resid -= rcv_buf_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_unsol_els_req
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * els req frame is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = ELS request frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
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 */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_process_unsol_els_req(fcoe_frame_t *frm)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_unsol_buf_t *ub;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_rscn_t *rscn;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint32_t offset;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_exchange_t *xch_tmp;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Get the unsol rxid first
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_SET_UNSOL_FRM_RXID(frm, xch_tmp);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Do proper ub initialization
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ub = (fc_unsol_buf_t *)kmem_zalloc(sizeof (fc_unsol_buf_t), KM_SLEEP);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ub->ub_class = FC_TRAN_CLASS3;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ub->ub_bufsize = frm->frm_payload_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ub->ub_buffer = kmem_alloc(frm->frm_payload_size, KM_SLEEP);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ub->ub_port_handle = FRM2SS(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ub->ub_token = (uint64_t)(long)ub;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
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 */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_FRM2FHDR(frm, &ub->ub_frame);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * If it's FLOGI, and our FLOGI failed last time,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * then we post online event
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if ((FRM2SS(frm)->ss_flags & SS_FLAG_FLOGI_FAILED) &&
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (frm->frm_payload[0] == LA_ELS_FLOGI)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm->frm_eport->eport_flags |=
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang EPORT_FLAG_IS_DIRECT_P2P;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_bind_info.port_statec_cb(FRM2SS(frm)->ss_port,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_STATE_ONLINE);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang switch (frm->frm_payload[0]) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case LA_ELS_RSCN:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Only RSCN need byte swapping
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang rscn = (fc_rscn_t *)(void *)ub->ub_buffer;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang rscn->rscn_code = frm->frm_payload[0];
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang rscn->rscn_len = frm->frm_payload[1];
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang rscn->rscn_payload_len =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_B2V_2(frm->frm_payload + 2);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = 4;
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 offset) = FCOE_B2V_4(frm->frm_payload + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 4;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang default:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(frm->frm_payload, ub->ub_buffer, frm->frm_payload_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Pass this unsol ELS up to Leadville
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_bind_info.port_unsol_cb(FRM2SS(frm)->ss_port, ub, 0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_search_abort_xch
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Find the exchange that should be aborted
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * key = oxid of the exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * val = the exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * arg = the soft state
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * MH_WALK_TERMINATE = found it, terminate the walk
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * MH_WALK_CONTINUE = not found, continue the walk
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
516aa12c0e0be4dde28b9fc2b3d928230a8e4c42Yu Renia Miao/* ARGSUSED */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic uint32_t
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_search_abort_xch(mod_hash_key_t key, mod_hash_val_t *val, void *arg)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_walk_arg_t *wa = (fcoei_walk_arg_t *)arg;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_exchange_t *xch = (fcoei_exchange_t *)val;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (xch->xch_oxid == wa->wa_oxid) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang wa->wa_xch = xch;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ASSERT(xch->xch_oxid == CMHK(key));
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (MH_WALK_TERMINATE);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return (MH_WALK_CONTINUE);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_unsol_abts_req
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ABTS request is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = ABTS request frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * The remote side wants to abort one unsolicited exchange.
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_process_unsol_abts_req(fcoe_frame_t *frm)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_exchange_t *xch = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoe_frame_t *nfrm;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int payload_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_walk_arg_t walk_arg;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * According to spec, the responder could want to ABTS xch too
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (FRM_SENDER_IS_XCH_RESPONDER(frm)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint16_t sol_oxid = FRM_OXID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (void) mod_hash_find(FRM2SS(frm)->ss_sol_oxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FMHK(sol_oxid), (mod_hash_val_t *)&xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
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 */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang walk_arg.wa_xch = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang walk_arg.wa_oxid = FRM_OXID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mod_hash_walk(FRM2SS(frm)->ss_unsol_rxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_search_abort_xch, &walk_arg);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch = walk_arg.wa_xch;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (xch == NULL) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang payload_size = 4;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nfrm = FRM2SS(frm)->ss_eport->eport_alloc_frame(
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_eport,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang payload_size + FCFH_SIZE, NULL);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (nfrm == NULL) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "can't alloc frame");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bzero(nfrm->frm_payload, nfrm->frm_payload_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nfrm->frm_payload[1] = 0x05;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nfrm->frm_payload[3] = 0xAA;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_R_CTL(R_CTL_LS_BA_RJT, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_init_ifm(nfrm, xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We should complete the exchange with frm as NULL,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * and we don't care its success or failure
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_complete_xch(xch, NULL, FC_PKT_FAILURE, FC_REASON_ABTX);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Construct ABTS ACC frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang payload_size = 12;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nfrm = FRM2SS(frm)->ss_eport->eport_alloc_frame(
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_eport, payload_size + FCFH_SIZE, NULL);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (nfrm == NULL) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "can't alloc frame");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
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[5] = 0xFF & (xch->xch_oxid);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nfrm->frm_payload[6] = 0xFF & (xch->xch_rxid >> 8);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nfrm->frm_payload[7] = 0xFF & (xch->xch_rxid);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nfrm->frm_payload[10] = 0xFF;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang nfrm->frm_payload[11] = 0xFF;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_R_CTL(R_CTL_LS_BA_ACC, nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_init_ifm(nfrm, xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_D_ID(FRM_S_ID(frm), nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_S_ID(FRM_D_ID(frm), nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_TYPE(FRM_TYPE(frm), nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_F_CTL(FRM_F_CTL(frm), nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_OXID(FRM_OXID(frm), nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FFM_RXID(FRM_RXID(frm), nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_eport->eport_tx_frame(nfrm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_sol_fcp_resp
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * FCP response is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = FCP response frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_process_sol_fcp_resp(fcoe_frame_t *frm)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint16_t sol_oxid;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint32_t actual_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_exchange_t *xch = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_packet_t *fpkt = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mod_hash_val_t val;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint32_t i_fcp_status;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Firstly, we search the related exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang sol_oxid = FRM_OXID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (mod_hash_find(FRM2SS(frm)->ss_sol_oxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FMHK(sol_oxid), (mod_hash_val_t *)&xch) != 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang PRT_FRM_HDR(__FUNCTION__, frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "can't find the corresponding xch: "
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "oxid/%x %lu - %lu", sol_oxid,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang CURRENT_CLOCK, frm->frm_clock);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fpkt = xch->xch_fpkt;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Decide the actual response length
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang actual_size = fpkt->pkt_rsplen;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (actual_size > frm->frm_payload_size) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang actual_size = frm->frm_payload_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Update the exchange and hash table
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
ef4cb712a006dbd6839858fde222aedff76e1bcbZhong Wang (void) mod_hash_remove(FRM2SS(frm)->ss_sol_oxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FMHK(xch->xch_oxid), &val);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ASSERT((fcoei_exchange_t *)val == xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_flags &= ~XCH_FLAG_IN_SOL_HASH;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Upate fpkt related elements
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_FRM2FHDR(frm, &fpkt->pkt_resp_fhdr);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * we should set pkt_reason and pkt_state carefully
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fpkt->pkt_state = FC_PKT_SUCCESS;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fpkt->pkt_reason = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * First we zero the first 12 byte of dest
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bzero(xch->xch_fpkt->pkt_resp, 12);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang i_fcp_status = BE_IN32(frm->frm_payload + 8);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (i_fcp_status != 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_fill_fcp_resp(frm->frm_payload,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (uint8_t *)xch->xch_fpkt->pkt_resp, actual_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Update pkt_resp_resid
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fpkt->pkt_data_resid = xch->xch_resid;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if ((xch->xch_resid != 0) && ((xch->xch_resid % 0x200) == 0) &&
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ((xch->xch_fpkt->pkt_datalen % 0x200) == 0) &&
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (i_fcp_status == 0)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "frame lost no pause ? %x/%x",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_resid, xch->xch_fpkt->pkt_datalen);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fpkt->pkt_state = FC_PKT_LOCAL_RJT;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fpkt->pkt_reason = FC_REASON_UNDERRUN;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Notify LV it's over
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (fpkt->pkt_tran_flags & FC_TRAN_NO_INTR) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "BEFORE WAKEUP: %p-%p", fpkt, xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang sema_v(&xch->xch_sema);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "AFTERE WAKEUP: %p-%p", fpkt, xch);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_fpkt->pkt_comp(xch->xch_fpkt);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_sol_els_rsp
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ELS response is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = ELS response frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_process_sol_els_rsp(fcoe_frame_t *frm)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint16_t sol_oxid = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint32_t actual_size = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_exchange_t *xch;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_packet_t *fpkt;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Look for the related exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fpkt = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang sol_oxid = FRM_OXID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (mod_hash_find(FRM2SS(frm)->ss_sol_oxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FMHK(sol_oxid), (mod_hash_val_t *)&xch) != 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang PRT_FRM_HDR(__FUNCTION__, frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "can't find the "
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "corresponding xch: oxid/%x", sol_oxid);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_rxid = FRM_RXID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fpkt = xch->xch_fpkt;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Decide the actual response length
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang actual_size = frm->frm_payload_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (actual_size > fpkt->pkt_rsplen) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "pkt_rsplen is smaller"
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "0x(%x - %x)", actual_size, fpkt->pkt_rsplen);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang actual_size = fpkt->pkt_rsplen;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Upate fpkt related elements
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_FRM2FHDR(frm, &fpkt->pkt_resp_fhdr);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_fill_els_fpkt_resp(frm, xch, actual_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
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 */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (((ls_code_t *)(void *)xch->xch_fpkt->pkt_resp)->ls_code ==
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang LA_ELS_RJT) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_complete_xch(xch, NULL, FC_PKT_FABRIC_RJT,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FC_REASON_INVALID_PARAM);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_complete_xch(xch, NULL, FC_PKT_SUCCESS, 0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_sol_ct_rsp
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * CT response is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = CT response frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_process_sol_ct_rsp(fcoe_frame_t *frm)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint16_t sol_oxid = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint32_t actual_size = 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_exchange_t *xch;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fc_packet_t *fpkt;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Look for the related exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fpkt = NULL;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang sol_oxid = FRM_OXID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (mod_hash_find(FRM2SS(frm)->ss_sol_oxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FMHK(sol_oxid), (mod_hash_val_t *)&xch) != 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "can't find the "
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "corresponding xch: oxid/%x", sol_oxid);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_rxid = FRM_RXID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fpkt = xch->xch_fpkt;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Decide the actual response length
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang actual_size = fpkt->pkt_rsplen;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (actual_size > frm->frm_payload_size) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "payload is smaller"
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "0x(%x - %x)", actual_size, frm->frm_payload_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang actual_size = frm->frm_payload_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Update fpkt related elements
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Caution: we needn't do byte swapping for CT response
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_FRM2FHDR(frm, &fpkt->pkt_resp_fhdr);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(FPLD, (uint8_t *)xch->xch_fpkt->pkt_resp, actual_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Complete it with frm as NULL
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_complete_xch(xch, NULL, FC_PKT_SUCCESS, 0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_sol_abts_acc
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ABTS accpet is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = ABTS accept frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
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 */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_process_sol_abts_acc(fcoe_frame_t *frm)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "the remote side has agreed to "
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "abort the exchange: oxid-%x, rxid-%x",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_B2V_2(frm->frm_payload + 4),
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_B2V_2(frm->frm_payload + 6));
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_sol_abts_rjt
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ABTS reject is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frm = ABTS reject frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
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 */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_process_sol_abts_rjt(fcoe_frame_t *frm)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "the remote side rejected "
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "our request to abort one exchange.: %p", frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_fill_els_fpkt_resp
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Fill fpkt ELS response in host format according frm payload
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
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 *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
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 Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_fill_els_fpkt_resp(fcoe_frame_t *frm, fcoei_exchange_t *xch, int size)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint8_t *src = frm->frm_payload;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint8_t *dest = (uint8_t *)xch->xch_fpkt->pkt_resp;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ls_code_t *els_code = (ls_code_t *)(void *)dest;
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 la_els_rls_acc_t *els_rls;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang la_els_rnid_acc_t *els_rnid;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang struct fcp_prli_acc *prli_acc;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int offset;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_code->ls_code = FCOE_B2V_1(src);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (els_code->ls_code == LA_ELS_RJT) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "size :%d", size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang switch (((ls_code_t *)(void *)xch->xch_fpkt->pkt_cmd)->ls_code) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case LA_ELS_FLOGI:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy((char *)frm->frm_hdr - 22,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm->frm_eport->eport_efh_dst, ETHERADDRL);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (frm->frm_payload[8] & 0x10) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We are in fabric p2p mode
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint8_t src_addr[ETHERADDRL];
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm->frm_eport->eport_flags &=
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ~EPORT_FLAG_IS_DIRECT_P2P;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_SET_DEFAULT_OUI(src_addr);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(frm->frm_hdr->hdr_d_id, src_addr + 3, 3);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm->frm_eport->eport_set_mac_address(
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm->frm_eport, src_addr, 1);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We are in direct p2p mode
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm->frm_eport->eport_flags |=
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang EPORT_FLAG_IS_DIRECT_P2P;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (!(FRM2SS(frm)->ss_eport->eport_flags &
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang EPORT_FLAG_IS_DIRECT_P2P)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_p2p_info.fca_d_id = FRM_D_ID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /* FALLTHROUGH */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case LA_ELS_PLOGI:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (FRM2SS(frm)->ss_eport->eport_flags &
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang EPORT_FLAG_IS_DIRECT_P2P) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_p2p_info.fca_d_id = FRM_D_ID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_p2p_info.d_id = FRM_S_ID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = offsetof(la_els_logi_t, common_service);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->common_service.fcph_version = FCOE_B2V_2(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->common_service.btob_credit = FCOE_B2V_2(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->common_service.cmn_features = FCOE_B2V_2(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->common_service.rx_bufsize = FCOE_B2V_2(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->common_service.conc_sequences = FCOE_B2V_2(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->common_service.relative_offset = FCOE_B2V_2(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->common_service.e_d_tov = FCOE_B2V_4(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * port/node WWN
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = offsetof(la_els_logi_t, nport_ww_name);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(src + offset, &els_logi->nport_ww_name, 8);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = offsetof(la_els_logi_t, node_ww_name);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(src + offset, &els_logi->node_ww_name, 8);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * class_3
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = offsetof(la_els_logi_t, class_3);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->class_3.class_opt = FCOE_B2V_2(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->class_3.initiator_ctl = FCOE_B2V_2(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->class_3.recipient_ctl = FCOE_B2V_2(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->class_3.rcv_size = FCOE_B2V_2(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->class_3.conc_sequences = FCOE_B2V_2(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->class_3.n_port_e_to_e_credit = FCOE_B2V_2(src +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_logi->class_3.open_seq_per_xchng = FCOE_B2V_2(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case LA_ELS_PRLI:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * PRLI service parameter response page
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcp_prli_acc doesn't include ls_code, don't use offsetof
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = 4;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc = (struct fcp_prli_acc *)(void *)(dest + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc->type = FCOE_B2V_1(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Type code extension
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 1;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * PRLI response flags
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 1;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc->orig_process_assoc_valid =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (FCOE_B2V_2(src + offset) & BIT_15) ? 1 : 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc->resp_process_assoc_valid =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (FCOE_B2V_2(src + offset) & BIT_14) ? 1 : 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc->image_pair_established =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (FCOE_B2V_2(src + offset) & BIT_13) ? 1 : 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc->accept_response_code =
7386f4319a95797d8397f24d609435b2c0e027a6Richard Lowe (FCOE_B2V_2(src + offset) & 0x0F00) >> 8;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * process associator
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc->orig_process_associator = FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 4;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc->resp_process_associator = FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * FC-4 type
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 4;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc->initiator_fn =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (FCOE_B2V_4(src + offset) & BIT_5) ? 1 : 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc->target_fn =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (FCOE_B2V_4(src + offset) & BIT_4) ? 1 : 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc->cmd_data_mixed =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (FCOE_B2V_4(src + offset) & BIT_3) ? 1 : 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc->data_resp_mixed =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (FCOE_B2V_4(src + offset) & BIT_2) ? 1 : 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc->read_xfer_rdy_disabled =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (FCOE_B2V_4(src + offset) & BIT_1) ? 1 : 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang prli_acc->write_xfer_rdy_disabled =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (FCOE_B2V_4(src + offset) & BIT_0) ? 1 : 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case LA_ELS_LOGO:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * could only be LS_ACC, no additional information
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_code->ls_code = FCOE_B2V_1(src);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case LA_ELS_SCR:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * LS_ACC/LS_RJT, no additional information
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_code->ls_code = FCOE_B2V_1(src);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case LA_ELS_ADISC:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = 5;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_adisc->hard_addr.hard_addr = FCOE_B2V_3(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = offsetof(la_els_adisc_t, port_wwn);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(src + offset, &els_adisc->port_wwn, 8);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = offsetof(la_els_adisc_t, node_wwn);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(src + offset, &els_adisc->node_wwn, 8);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 9;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_adisc->nport_id.port_id = FCOE_B2V_3(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case LA_ELS_RLS:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_rls = (la_els_rls_acc_t *)(void *)dest;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_rls->ls_code.ls_code = FCOE_B2V_1(src);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = 4;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_rls->rls_link_params.rls_link_fail =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = 8;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_rls->rls_link_params.rls_sync_loss =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = 12;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_rls->rls_link_params.rls_sig_loss =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = 16;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_rls->rls_link_params.rls_prim_seq_err =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = 20;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_rls->rls_link_params.rls_invalid_word =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = 24;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_rls->rls_link_params.rls_invalid_crc =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case LA_ELS_RNID:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_rnid = (la_els_rnid_acc_t *)(void *)dest;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang els_rnid->ls_code.ls_code = FCOE_B2V_1(src);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = 4;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(src + offset, &els_rnid->hdr.data_format, 1);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = 5;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(src + offset, &els_rnid->hdr.cmn_len, 1);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = 7;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(src + offset, &els_rnid->hdr.specific_len, 1);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = 8;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(src + offset, els_rnid->data, FCIO_RNID_MAX_DATA_LEN);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang default:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "unsupported R_CTL");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_fill_fcp_resp
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Fill fpkt FCP response in host format according to frm payload
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
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 *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * This is called only for SCSI response with non good status
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangstatic void
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_fill_fcp_resp(uint8_t *src, uint8_t *dest, int size)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcp_rsp_t *fcp_rsp_iu = (fcp_rsp_t *)(void *)dest;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang int offset;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * set fcp_status
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = offsetof(fcp_rsp_t, fcp_u);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 2;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcp_rsp_iu->fcp_u.fcp_status.resid_under =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (FCOE_B2V_1(src + offset) & BIT_3) ? 1 : 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcp_rsp_iu->fcp_u.fcp_status.resid_over =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (FCOE_B2V_1(src + offset) & BIT_2) ? 1 : 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcp_rsp_iu->fcp_u.fcp_status.sense_len_set =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (FCOE_B2V_1(src + offset) & BIT_1) ? 1 : 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcp_rsp_iu->fcp_u.fcp_status.rsp_len_set =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (FCOE_B2V_1(src + offset) & BIT_0) ? 1 : 0;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 1;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcp_rsp_iu->fcp_u.fcp_status.scsi_status = FCOE_B2V_1(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcp_resid/fcp_sense_len/fcp_response_len
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = offsetof(fcp_rsp_t, fcp_resid);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcp_rsp_iu->fcp_resid = FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = offsetof(fcp_rsp_t, fcp_sense_len);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcp_rsp_iu->fcp_sense_len = FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset = offsetof(fcp_rsp_t, fcp_response_len);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcp_rsp_iu->fcp_response_len = FCOE_B2V_4(src + offset);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * sense or response
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += 4;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (fcp_rsp_iu->fcp_sense_len) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if ((offset + fcp_rsp_iu->fcp_sense_len) > size) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "buffer too small - sens");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(src + offset, dest + offset, fcp_rsp_iu->fcp_sense_len);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang offset += fcp_rsp_iu->fcp_sense_len;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (fcp_rsp_iu->fcp_response_len) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if ((offset + fcp_rsp_iu->fcp_response_len) > size) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "buffer too small - resp");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(src + offset, dest + offset,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcp_rsp_iu->fcp_response_len);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangvoid
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_init_ect_vectors(fcoe_client_t *ect)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ect->ect_rx_frame = fcoei_rx_frame;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ect->ect_port_event = fcoei_port_event;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ect->ect_release_sol_frame = fcoei_release_sol_frame;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_unsol_frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Unsolicited frame is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frame = unsolicited frame that is received
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
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 */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangvoid
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_process_unsol_frame(fcoe_frame_t *frm)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_exchange_t *xch;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang uint16_t sol_oxid;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang switch (FRM_R_CTL(frm)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_SOLICITED_DATA:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * READ data phase frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Find the associated exchange
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang sol_oxid = FRM_OXID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (mod_hash_find(FRM2SS(frm)->ss_sol_oxid_hash,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FMHK(sol_oxid), (mod_hash_val_t *)&xch) != 0) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang PRT_FRM_HDR(__FUNCTION__, frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "associated xch not found: "
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "oxid/%x %lu - %lu", sol_oxid,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang CURRENT_CLOCK, frm->frm_clock);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Copy data into fpkt data buffer, and update the counter
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang bcopy(frm->frm_payload, (uint8_t *)xch->xch_fpkt->pkt_data +
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM_PARAM(frm), frm->frm_payload_size);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_resid -= frm->frm_payload_size;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch->xch_rxid = FRM_RXID(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_XFER_RDY:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_process_unsol_xfer_rdy(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_STATUS:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_process_sol_fcp_resp(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_ELS_REQ:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_process_unsol_els_req(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_LS_ABTS:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_process_unsol_abts_req(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_ELS_RSP:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_process_sol_els_rsp(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_SOLICITED_CONTROL:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_process_sol_ct_rsp(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_LS_BA_ACC:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_process_sol_abts_acc(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_LS_BA_RJT:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_process_sol_abts_rjt(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang default:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Unsupported frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang PRT_FRM_HDR("Unsupported unsol frame: ", frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Release the frame and netb
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm->frm_eport->eport_free_netb(frm->frm_netb);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang frm->frm_eport->eport_release_frame(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_handle_sol_frame_done
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * solicited frame is just sent out
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * frame = solicited frame that has been sent out
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * watchdog will call this to handle solicited frames that FCOEI
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * has sent out Non-request frame post handling
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangvoid
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_handle_sol_frame_done(fcoe_frame_t *frm)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * the corresponding xch could be NULL at this time
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_exchange_t *xch = FRM2IFM(frm)->ifm_xch;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang switch (FRM2IFM(frm)->ifm_rctl) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_ELS_RSP:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Complete it with frm as NULL
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_complete_xch(xch, NULL, FC_PKT_SUCCESS, 0);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_LS_BA_ACC:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "BA_ACC out: xch-%p, frm-%p",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch, frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang PRT_FRM_HDR("LS_BA_ACC", frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case R_CTL_LS_BA_RJT:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "BA_RJT out: xch-%p, frm-%p",
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang xch, frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang PRT_FRM_HDR("LS_BA_RJT", frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang default:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Unsupported frame
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang PRT_FRM_HDR("Unsupported sol frame: ", frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang /*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * We should release only the frame, and we don't care its netb
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FRM2SS(frm)->ss_eport->eport_release_frame(frm);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_port_event
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * link/port state changed
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * eport = to indicate which port has changed
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * event = what change
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * refer fctl.h for ss_link_state value
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangvoid
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_port_event(fcoe_port_t *eport, uint32_t event)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_event_t *ae;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (!(EPORT2SS(eport)->ss_flags & SS_FLAG_LV_BOUND)) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "not bound now");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_enter(&EPORT2SS(eport)->ss_watchdog_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang switch (event) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case FCOE_NOTIFY_EPORT_LINK_DOWN:
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 break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang case FCOE_NOTIFY_EPORT_LINK_UP:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (eport->eport_mtu >= 2200) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang EPORT2SS(eport)->ss_fcp_data_payload_size =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_DEFAULT_FCP_DATA_PAYLOAD_SIZE;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "fcoei: MTU is not big enough. "
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang "we will use 1K frames in FCP data phase.");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang EPORT2SS(eport)->ss_fcp_data_payload_size =
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_MIN_FCP_DATA_PAYLOAD_SIZE;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
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 break;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang default:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "unsupported event");
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&EPORT2SS(eport)->ss_watchdog_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang return;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang EPORT2SS(eport)->ss_port_event_counter++;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ae = (fcoei_event_t *)kmem_zalloc(sizeof (fcoei_event_t), KM_SLEEP);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ae->ae_type = AE_EVENT_PORT;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ae->ae_obj = EPORT2SS(eport);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ae->ae_specific = EPORT2SS(eport)->ss_link_state;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang list_insert_tail(&EPORT2SS(eport)->ss_event_list, ae);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang mutex_exit(&EPORT2SS(eport)->ss_watchdog_mutex);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang/*
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * fcoei_process_event_port
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * link/port state changed
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Input:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * ae = link fcoei_event
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Returns:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * N/A
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang *
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * Comments:
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang * asynchronous events from FCOE
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang */
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangvoid
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wangfcoei_process_event_port(fcoei_event_t *ae)
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang{
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang fcoei_soft_state_t *ss = (fcoei_soft_state_t *)ae->ae_obj;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss->ss_eport->eport_link_speed == FCOE_PORT_SPEED_1G) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ae->ae_specific |= FC_STATE_1GBIT_SPEED;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else if (ss->ss_eport->eport_link_speed ==
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOE_PORT_SPEED_10G) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ae->ae_specific |= FC_STATE_10GBIT_SPEED;
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang if (ss->ss_flags & SS_FLAG_LV_BOUND) {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang ss->ss_bind_info.port_statec_cb(ss->ss_port,
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang (uint32_t)ae->ae_specific);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang } else {
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang FCOEI_LOG(__FUNCTION__, "ss %p not bound now", ss);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang }
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang
1a5e258f5471356ca102c7176637cdce45bac147Josef 'Jeff' Sipek atomic_dec_32(&ss->ss_port_event_counter);
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang kmem_free(ae, sizeof (fcoei_event_t));
7ff836697c120cb94bd30d5c2204eb9b74718e4cZhong Wang}