/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* The following notice accompanied the original version of this file:
*
* BSD LICENSE
*
* Copyright(c) 2007 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
*/
/*
* This file defines interface functions between fcoe and fcoei driver.
*/
#include <sys/byteorder.h>
#include <sys/mac_client.h>
/*
* LEADVILLE header files
*/
/*
* COMSTAR header files
*/
#include <sys/stmf_defines.h>
/*
* FCOE header files
*/
/*
* Driver's own header files
*/
#include <fcoei.h>
/*
* Forward declaration of internal functions
*/
int size);
/*
* fcoei_rx_frame
* Unsolicited frame is received
*
* Input:
* frame = unsolicited frame that is received
*
* Return:
* N/A
*
* Comment:
* N/A
*/
static void
{
/*
* Release the frame and netb
*/
return;
}
}
}
/*
* fcoei_release_sol_frame
* Release the solicited frame that has just been sent out
*
* Input:
* frame = solicited frame that has been sent out
*
* Returns:
* N/A
*
* Comments:
* After FCOE sends solicited frames out, it will call this to notify
* FCOEI of the completion.
*/
static void
{
/*
* For request-type frames, it's safe to be handled out of
* watchdog, because it needn't update anything
*/
case R_CTL_SOLICITED_DATA:
case R_CTL_COMMAND:
case R_CTL_ELS_REQ:
case R_CTL_UNSOL_CONTROL:
case R_CTL_LS_ABTS:
break;
default:
}
break;
}
}
/*
* fcoei_process_unsol_xfer_rdy
* XFER_RDY is received
*
* Input:
* frm = XFER_RDY frame
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
int rcv_buf_size;
int offset;
int left_size;
int data_size;
int frm_num;
int idx;
return;
}
/*
* rcv_buf_size is the total size of data that should be transferred
* in this sequence.
* offset is based on the exchange not the sequence.
*/
/*
* Local variables initialization
*/
/*
* The first (frm_num -1) frames are always full
*/
return;
}
/*
* Copy the data payload that will be transferred
*/
/*
* Submit the frame
*/
/*
* Update offset and left_size
*/
}
/*
* Send the last data frame of this sequence
*/
} else {
ASSERT(0);
return;
}
/*
* Copy the data payload that will be transferred
*/
/*
* Set ifm_rctl for fcoei_handle_sol_frame_done
*/
/*
* FFM
*/
/*
* Submit the frame
*/
/*
* Sequence is a transaction, so we need only update
* xch_remained_bytes in the end.
*/
}
/*
* fcoei_process_unsol_els_req
* els req frame is received
*
* Input:
* frm = ELS request frame
*
* Returns:
* N/A
*
* Comments:
* We will not create exchange data structure at this time,
* and we should create unsolicited buffer, which will only
* contain the exchange's request payload.
*/
static void
{
/*
* Get the unsol rxid first
*/
/*
* Do proper ub initialization
*/
/*
* header conversion
* Caution: ub_buffer is big endian, but ub_frame should be host-format
* RSCN is one exception.
*/
/*
* If it's FLOGI, and our FLOGI failed last time,
* then we post online event
*/
}
switch (frm->frm_payload[0]) {
case LA_ELS_RSCN:
/*
* Only RSCN need byte swapping
*/
offset = 4;
offset += 4;
}
break;
default:
break;
}
/*
* Pass this unsol ELS up to Leadville
*/
}
/*
* fcoei_search_abort_xch
* Find the exchange that should be aborted
*
* Input:
* key = oxid of the exchange
* val = the exchange
* arg = the soft state
*
* Returns:
* MH_WALK_TERMINATE = found it, terminate the walk
* MH_WALK_CONTINUE = not found, continue the walk
*
* Comments:
* N/A
*/
/* ARGSUSED */
static uint32_t
{
return (MH_WALK_TERMINATE);
}
return (MH_WALK_CONTINUE);
}
/*
* fcoei_process_unsol_abts_req
* ABTS request is received
*
* Input:
* frm = ABTS request frame
*
* Returns:
* N/A
*
* Comments:
* The remote side wants to abort one unsolicited exchange.
*/
static void
{
int payload_size;
/*
* According to spec, the responder could want to ABTS xch too
*/
if (FRM_SENDER_IS_XCH_RESPONDER(frm)) {
} else {
/*
* it's a unsolicited exchange, and we need find it out from
* unsolicited hash table. But at this time, RXID in frame could
* still be 0xFFFF in most cases, so we need do exaustive search
*/
}
payload_size = 4;
return;
}
} else {
/*
* We should complete the exchange with frm as NULL,
* and we don't care its success or failure
*/
/*
* Construct ABTS ACC frame
*/
payload_size = 12;
return;
}
}
}
/*
* fcoei_process_sol_fcp_resp
* FCP response is received
*
* Input:
* frm = FCP response frame
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
/*
* Firstly, we search the related exchange
*/
"oxid/%x %lu - %lu", sol_oxid,
return;
} else {
}
/*
* Decide the actual response length
*/
}
/*
* Update the exchange and hash table
*/
/*
* Upate fpkt related elements
*/
/*
* we should set pkt_reason and pkt_state carefully
*/
fpkt->pkt_reason = 0;
/*
* First we zero the first 12 byte of dest
*/
if (i_fcp_status != 0) {
}
/*
* Update pkt_resp_resid
*/
(i_fcp_status == 0)) {
}
/*
* Notify LV it's over
*/
} else {
}
}
/*
* fcoei_process_sol_els_rsp
* ELS response is received
*
* Input:
* frm = ELS response frame
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
/*
* Look for the related exchange
*/
"corresponding xch: oxid/%x", sol_oxid);
return;
}
/*
* Decide the actual response length
*/
}
/*
* Upate fpkt related elements
*/
/*
* we should set pkt_reason and pkt_state carefully now
* Need to analyze pkt_reason according to the response.
* Leave it untouched now.
*/
LA_ELS_RJT) {
} else {
}
}
/*
* fcoei_process_sol_ct_rsp
* CT response is received
*
* Input:
* frm = CT response frame
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
/*
* Look for the related exchange
*/
"corresponding xch: oxid/%x", sol_oxid);
return;
}
/*
* Decide the actual response length
*/
}
/*
* Update fpkt related elements
* Caution: we needn't do byte swapping for CT response
*/
/*
* Complete it with frm as NULL
*/
}
/*
* fcoei_process_sol_abts_acc
* ABTS accpet is received
*
* Input:
* frm = ABTS accept frame
*
* Returns:
* N/A
*
* Comments:
* We will always finish the abortion of solicited exchanges,
* so we will not depend on the response from the remote side.
* We just log one message.
*/
static void
{
"abort the exchange: oxid-%x, rxid-%x",
}
/*
* fcoei_process_sol_abts_rjt
* ABTS reject is received
*
* Input:
* frm = ABTS reject frame
*
* Returns:
* N/A
*
* Comments:
* We will alwayas finish the abortion of solicited exchanges,
* so we will not depend on the response from the remote side.
* We just log one message.
*/
static void
{
"our request to abort one exchange.: %p", frm);
}
/*
* fcoei_fill_els_fpkt_resp
* Fill fpkt ELS response in host format according frm payload
*
* Input:
* src = frm payload in link format
* dest = fpkt ELS response in host format
* size = Maximum conversion size
* els_op = ELS opcode
*
* Returns:
* N/A
*
* Comments:
* fpkt->pkt_resp must be mapped to one data structure, and it's
* different from the content in the raw frame
*/
static void
{
int offset;
return;
}
case LA_ELS_FLOGI:
/*
* We are in fabric p2p mode
*/
} else {
/*
* We are in direct p2p mode
*/
}
}
/* FALLTHROUGH */
case LA_ELS_PLOGI:
}
offset);
offset += 2;
offset);
offset += 2;
offset);
offset += 2;
offset);
offset += 2;
offset);
offset += 2;
offset);
offset += 2;
offset);
/*
*/
/*
* class_3
*/
offset += 2;
offset += 2;
offset += 2;
offset += 2;
offset += 2;
offset);
offset += 2;
break;
case LA_ELS_PRLI:
/*
* PRLI service parameter response page
*
* fcp_prli_acc doesn't include ls_code, don't use offsetof
*/
offset = 4;
/*
* Type code extension
*/
offset += 1;
/*
* PRLI response flags
*/
offset += 1;
/*
* process associator
*/
offset += 2;
offset += 4;
/*
* FC-4 type
*/
offset += 4;
break;
case LA_ELS_LOGO:
/*
* could only be LS_ACC, no additional information
*/
break;
case LA_ELS_SCR:
/*
*/
break;
case LA_ELS_ADISC:
offset = 5;
offset += 9;
break;
case LA_ELS_RLS:
offset = 4;
offset = 8;
offset = 12;
offset = 16;
offset = 20;
offset = 24;
break;
case LA_ELS_RNID:
offset = 4;
offset = 5;
offset = 7;
offset = 8;
break;
default:
break;
}
}
/*
* fcoei_fill_fcp_resp
* Fill fpkt FCP response in host format according to frm payload
*
* Input:
* src - frm payload in link format
* dest - fpkt FCP response in host format
* size - Maximum conversion size
*
* Returns:
* N/A
*
* Comments:
* This is called only for SCSI response with non good status
*/
static void
{
int offset;
/*
* set fcp_status
*/
offset += 2;
offset += 1;
/*
*/
/*
* sense or response
*/
offset += 4;
if (fcp_rsp_iu->fcp_sense_len) {
return;
}
}
if (fcp_rsp_iu->fcp_response_len) {
return;
}
}
}
void
{
}
/*
* fcoei_process_unsol_frame
* Unsolicited frame is received
*
* Input:
* frame = unsolicited frame that is received
*
* Returns:
* N/A
*
* Comments:
* watchdog will call this to process unsolicited frames that we
* just received fcoei_process_xx is used to handle different
* unsolicited frames
*/
void
{
case R_CTL_SOLICITED_DATA:
/*
* READ data phase frame
* Find the associated exchange
*/
"oxid/%x %lu - %lu", sol_oxid,
break;
}
/*
* Copy data into fpkt data buffer, and update the counter
*/
break;
case R_CTL_XFER_RDY:
break;
case R_CTL_STATUS:
break;
case R_CTL_ELS_REQ:
break;
case R_CTL_LS_ABTS:
break;
case R_CTL_ELS_RSP:
break;
case R_CTL_SOLICITED_CONTROL:
break;
case R_CTL_LS_BA_ACC:
break;
case R_CTL_LS_BA_RJT:
break;
default:
/*
* Unsupported frame
*/
}
/*
* Release the frame and netb
*/
}
/*
* fcoei_handle_sol_frame_done
* solicited frame is just sent out
*
* Input:
* frame = solicited frame that has been sent out
*
* Returns:
* N/A
*
* Comments:
* watchdog will call this to handle solicited frames that FCOEI
* has sent out Non-request frame post handling
*/
void
{
/*
* the corresponding xch could be NULL at this time
*/
case R_CTL_ELS_RSP:
/*
* Complete it with frm as NULL
*/
break;
case R_CTL_LS_BA_ACC:
break;
case R_CTL_LS_BA_RJT:
break;
default:
/*
* Unsupported frame
*/
}
/*
* We should release only the frame, and we don't care its netb
*/
}
/*
* fcoei_port_event
*
* Input:
* eport = to indicate which port has changed
* event = what change
*
* Returns:
* N/A
*
* Comments:
* refer fctl.h for ss_link_state value
*/
void
{
return;
}
switch (event) {
break;
} else {
"we will use 1K frames in FCP data phase.");
}
break;
default:
return;
}
}
/*
* fcoei_process_event_port
*
* Input:
* ae = link fcoei_event
*
* Returns:
* N/A
*
* Comments:
* asynchronous events from FCOE
*/
void
{
}
} else {
}
}