/*
* 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
*/
/*
*/
/*
* This file defines interfaces between FCOE and LEADVILLE
*/
/*
* Driver kernel header files
*/
#include <sys/byteorder.h>
#include <sys/mac_client.h>
/*
* LEADVILLE header files
*/
/*
* COMSTAR head files (BIT_* macro)
*/
#include <sys/stmf_defines.h>
/*
* FCOE header files
*/
/*
* Driver's own header files
*/
#include <fcoei.h>
/*
* forward declaration of static functions
*/
static void fcoei_port_enabled(void *arg);
static void fcoei_logo_peer(void *arg);
static uint32_t
/*
* fcoei_bind_port
* Bind LV port instance with fcoei soft state
*
* Input:
* dip = dev info of fcoei soft state
* port_info = fcoei specific parameters about LV port
* bind_info = LV specific parameters about fcoei soft state
*
* Returns:
* The pointer to fcoei soft state
*
* Comments:
* Unpon the completion of this call, the port must be offline.
* fcoei_port_enabled could trigger it to online
*/
static void *
{
/*
* get state info based on the dip
*/
ss = (fcoei_soft_state_t *)
if (!ss) {
return (NULL);
}
/*
* make sure this port isn't bound
*/
return (NULL);
}
/*
* make sure request is in bounds
*/
return (NULL);
}
/*
* stash the ss_bind_info supplied by the FC Transport
*/
/*
* RNID parameter
*/
/*
* populate T11 FC-HBA details
*/
/*
* set port's current state, and it is always offline before binding
*
* We hack pi_port_state to tell LV if it's NODMA_FCA
*/
/*
* copy login param
*/
sizeof (la_els_logi_t));
/*
* Mark it as bound
*/
/*
* Let fcoe to report the link status
*/
fcoei_port_enabled((void *)ss);
return (ss);
}
/*
* fcoei_unbind_port
* Un-bind the fcoei port
*
* Input:
* fca_handle = fcoei soft state set in fcoei_bind_port
*
* Returns:
* N/A
*
* Comments:
* Clear binding flag
*/
static void
{
}
/*
* fcoei_init_pkt
* Initialize fcoei related part of fc_packet
*
* Input:
* fca_handle = fcoei soft state set in fcoei_bind_port
* fpkt = The pointer to fc_packet
* sleep = This call can sleep or not
*
* Returns:
* FC_SUCCESS - Initialization completed successfully
*
* Comments:
* Link the exchange elements with proper objects
*/
/* ARGSUSED */
static int
{
return (FC_SUCCESS);
}
/*
* fcoei_un_init_pkt
* Uninitialize fcoei related part of fc_packet
*
* Input:
* fca_handle = fcoei soft state set in fcoei_bind_port
* fpkt = The pointer to fc_packet
*
* Returns:
* FC_SUCCESS - Uninitialize successfully
*
* Comments:
* Very simple, just return successfully
*/
/* ARGSUSED */
static int
{
return (FC_SUCCESS);
}
/*
* fcoei_get_cap
* Export FCA hardware and software capability.
*
* Input:
* fca_handle = fcoei soft state set in fcoei_bind_port
* cap = pointer to the capability string
* ptr = buffer pointer for returning capability
*
* Returns:
* FC_CAP_ERROR - no such capability
* FC_CAP_FOUND - the capability was returned and cannot be set
*
* Comments:
* FC_CAP_UNSOL_BUF is one important capability, it will affect the
* implementation of fcoei_ub_alloc/free.
*/
static int
{
*rptr = FC_NO_DVMA_SPACE;
} else {
rval = FC_CAP_ERROR;
}
return (rval);
}
/*
* fcoei_set_cap
* Allow the FC Transport to set FCA capabilities if possible
*
* Input:
* fca_handle = fcoei soft state set in fcoei_bind_port
* cap = pointer to the capabilities string.
* ptr = buffer pointer for capability.
*
* Returns:
* FC_CAP_ERROR - no such capability
*
* Comments:
* Currently, all capabilities can't be changed.
*/
static int
{
return (FC_CAP_ERROR);
}
/*
* fcoei_getmap
* Get lilp map
*
* Input:
* fca_handle = fcoei soft state set in fcoei_bind_port
* mapbuf = the buffer to store lilp map
*
* Returns:
* FC_FAILURE - Can't get the lilp map
*
* Comments:
* fcoei can't work in loop topology, so it should never get called
*/
static int
{
return (FC_FAILURE);
}
/*
* fcoei_ub_alloc
* Pre-allocate unsolicited buffers at the request of LV
*
* Input:
* fca_handle = fcoei soft state set in fcoei_bind_port
* tokens = token array for each buffer.
* size = number of tokens
* count = the acutual number of allocated unsolicited buffers
* type = unsolicited buffer type
*
* Returns:
* FC_SUCCESS - The requested buffers have been freeed
*
* Comments:
* fcoei_get_cap will set UNSOL_BUF to 0, so it should never get called.
*/
static int
{
return (FC_SUCCESS);
}
/*
* fcoei_ub_free
* Free the pre-allocated unsolicited buffers at the request of LV
*
* Input:
* fca_handle = fcoei soft state set in fcoei_bind_port
* count = number of buffers.
* tokens = token array for each buffer.
*
* Returns:
* FC_SUCCESS - The requested buffers have been freeed
*
* Comments:
* fcoei_get_cap will set UNSOL_BUF to 0, so it should never get called.
*/
static int
{
return (FC_SUCCESS);
}
/*
* fcoei_ub_release
* Release unsolicited buffers from FC Transport to FCA for future use
*
* Input:
* fca_handle = fcoei soft state set in fcoei_bind_port
* count = number of buffers.
* tokens = token array for each buffer.
*
* Returns:
* FC_SUCCESS - The requested buffers have been released.
* FC_FAILURE - The requested buffers have not been released.
*
* Comments:
* It will always succeed. It has nothing to do with fcoei_ub_alloc/free.
*/
static int
{
if (count != 1) {
return (FC_FAILURE);
}
return (FC_SUCCESS);
}
/*
* fcoei_abort
* Direct FCA driver to abort an outstanding exchange associated with a
* specified fc_packet_t struct
*
* Input:
* fca_handle - fcoei soft state set in fcoei_bind_port
* fpkt - A pointer to the fc_packet_t for the exchange to be aborted.
* flags - Set to KM_SLEEP if the function may sleep, or KM_NOSLEEP if
* the function may not sleep.
*
* Returns:
* FC_ABORTED - The specified exchange was successfully aborted.
* FC_ABORTING - The specified exchange is being aborted.
* FC_ABORT_FAILED - The specified exchange could not be aborted.
* FC_TRANSPORT_ERROR - A transport error occurred while attempting to
* abort the specified exchange.
* FC_BADEXCHANGE - The specified exchange does not exist.
*
* Comments:
* After the exchange is aborted, the FCA driver must update the relevant
* fields in the fc_packet_t struct as per normal exchange completion and
* call the pkt_comp function to return the fc_packet_t struct to the FC
* Transport.
* When an exchange is successfully aborted, the FCA driver must set the
* pkt_reason field in the fc_packet_t to FC_REASON_ABORTED and the
* pkt_state field in the fc_packet_t to FC_PKT_LOCAL_RJT before returning
* the fc_packet_t to the FC Transport.
*
* Unfortunately, LV doesn't conform to the spec. It will take all these
* legal return value as failure to abort.
*/
static int
{
return (FC_SUCCESS);
}
/*
* fcoei_reset
* Reset link or hardware
*
* Input:
* fca_handle = fcoei soft state set in fcoei_bind_port
* cmd = reset type command
*
* Returns:
* FC_SUCCESS - Reset has completed successfully
* FC_FAILURE - Reset has failed
*
* Comments:
* N/A
*/
static int
{
switch (cmd) {
case FC_FCA_LINK_RESET:
rval = FC_FAILURE;
break;
}
/*
* This is linkreset phase I
*/
/*
* Perpare linkreset phase II
*/
break;
case FC_FCA_RESET:
break;
case FC_FCA_CORE:
break;
case FC_FCA_RESET_CORE:
break;
default:
rval = FC_FAILURE;
break;
}
return (rval);
}
/*
* fcoei_port_manage
* Perform various port management operations at the request of LV
*
* Input:
* fca_handle = fcoei soft state set in fcoei_bind_port
* pm = the pointer to the struct specifying the port management operation
*
* Returns:
* FC_SUCCESS - The request completed successfully
* FC_FAILURE - The request did not complete successfully
*
* Comments:
* N/A
*/
static int
{
return (rval);
}
switch (pm->pm_cmd_code) {
case FC_PORT_GET_NODE_ID:
{
break;
}
rval = FC_SUCCESS;
break;
}
case FC_PORT_SET_NODE_ID:
{
break;
}
rval = FC_SUCCESS;
break;
}
default:
break;
}
return (rval);
}
/*
* fcoei_get_device
* Get fcoei remote port with FCID of d_id
*
* Input:
* fca_handle = fcoei soft state set in fcoei_bind_port
* d_id = 24-bit FCID of remote port
*
* Returns:
* The pointer to fcoei remote port
*
* Comments:
* fcoei has no remote port device
*/
static void *
{
return (NULL);
}
/*
* fcoei_notify
* Notify the change of target device
*
* Input:
* fca_handle = fcoei soft state set in fcoei_bind_port
* cmd = detailed cmd
*
* Returns:
* FC_SUCCESS - Notification completed successfully
*
* Comments:
* It's only needed to support non-COMSTAR FC target, so it should
* never get called.
*/
static int
{
return (FC_SUCCESS);
}
/*
* fcoei_transport
*
* Input:
* fca_handle - fcoei soft state set in fcoei_bind_port
* fpkt - LV fc_packet
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static int
{
if (pkt_tran_flags & FC_TRAN_NO_INTR) {
}
}
if (pkt_tran_flags & FC_TRAN_NO_INTR) {
}
return (FC_SUCCESS);
}
/*
* fcoei_els_send
* Submit ELS request or response
*
* Input:
* fca_handle - fcoei soft state set in fcoei_bind_port
* fpkt = LV fc_packet
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static int
{
return (FC_BADPACKET);
}
/*
* LV could release ub after this call, so we must save the ub type
* for later use
*/
}
}
return (FC_SUCCESS);
}
/*
* fcoei_populate_hba_fru_details
* Fill detailed information about HBA
*
* Input:
* ss - fcoei soft state
* port_info = fc_fca_port_info_t that need be updated
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
int instance;
"Sun Microsystems, Inc.");
"%s", FCOEI_NAME_VERSION);
"%s", FCOEI_VERSION);
(short)(instance & 0x0000ffff);
}
/*
* fcoei_port_enabled
* Notify fcoe that the port has been enabled
*
* Input:
* arg = the related soft state
*
* Returns:
* N/A
*
* Comments:
* Only after this, fcoe will report the link status to us
*/
static void
{
}
/*
* fcoei_initiate_ct_req
* Fill and submit CT request
*
* Input:
* xch - the exchange that will be initiated
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
int offset;
int idx;
/*
* Ensure it's 4-byte aligned
*/
/*
* Allocate CT request frame
*/
return;
}
/*
* CT header (FC payload)
*/
offset = 0;
offset = 1;
offset = 4;
offset = 5;
offset = 6;
offset = 8;
offset = 10;
offset = 13;
offset = 14;
offset = 15;
/*
* CT payload (FC payload)
*/
switch (ct->ct_fcstype) {
case FCSTYPE_DIRECTORY:
case NS_GA_NXT:
case NS_GPN_ID:
case NS_GNN_ID:
case NS_GCS_ID:
case NS_GFT_ID:
case NS_GSPN_ID:
case NS_GPT_ID:
case NS_GID_FT:
case NS_GID_PT:
case NS_DA_ID:
offset = 16;
break;
case NS_GID_PN:
offset = 16;
break;
case NS_RNN_ID:
case NS_RPN_ID:
offset = 16;
offset = 20;
break;
case NS_RSPN_ID:
offset = 16;
offset = 20;
break;
case NS_RSNN_NN:
offset = 16;
offset = 24;
break;
case NS_RFT_ID:
offset = 16;
/*
* fp use bcopy to copy fp_fc4_types,
* we need to swap order for each integer
*/
offset = 20;
offset += 4;
}
break;
case NS_RCS_ID:
case NS_RPT_ID:
offset = 16;
offset = 20;
break;
case NS_RIP_NN:
offset = 16;
break;
default:
break;
}
break; /* FCSTYPE_DIRECTORY */
case FCSTYPE_MGMTSERVICE:
case MS_GIEL:
"MS_GIEL ct_fcstype %x, ct_cmdrsp: %x",
break;
default:
break;
}
break; /* FCSTYPE_MGMTSERVICE */
default:
break;
}
}
/*
* fcoei_initiate_fcp_cmd
* Submit FCP command
*
* Input:
* xch - the exchange to be submitted
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
int offset = 0;
if (!frm) {
ASSERT(0);
} else {
}
/*
* This will affect timing check
*/
/*
* Set exchange residual bytes
*/
/*
* Fill FCP command IU
*
* fcp_ent_addr
*/
offset += 2;
offset += 2;
offset += 2;
/*
* fcp_cntl
*/
offset += 1;
offset += 1;
offset += 1;
/*
* fcp_cdb
*/
/*
* fcp_data_len
*/
offset += FCP_CDB_SIZE;
/*
* FC frame header
*/
}
/*
* fcoei_initiate_els_req
* Initiate ELS request
*
* Input:
* xch = the exchange that will be initiated
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
if (!frm) {
ASSERT(0);
} else {
}
/*
* This will affect timing check
*/
case LA_ELS_FLOGI:
/*
* For FLOGI, we expect response within E_D_TOV
*/
FCOE_SEC2TICK(2);
/* FALLTHROUGH */
case LA_ELS_PLOGI:
break;
case LA_ELS_PRLI:
break;
case LA_ELS_SCR:
break;
case LA_ELS_LINIT:
break;
case LA_ELS_ADISC:
break;
case LA_ELS_LOGO:
/*
* For LOGO, we expect response within E_D_TOV
*/
FCOE_SEC2TICK(2);
break;
case LA_ELS_RLS:
break;
case LA_ELS_RNID:
break;
default:
return;
}
/*
* set ifm_rtcl
*/
/*
* FCPH
*/
}
/*
* fcoei_initiate_els_resp
* Originate ELS response
*
* Input:
* xch = the associated exchange
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
if (!frm) {
ASSERT(0);
} else {
}
/*
* This will affect timing check
*/
/*
* Set ifm_rctl
*/
/*
* FCPH
*/
case LA_ELS_FLOGI:
break;
case LA_ELS_PLOGI:
}
break;
case LA_ELS_PRLI:
break;
case LA_ELS_ADISC:
break;
case LA_ELS_LOGO:
break;
case LA_ELS_RSCN:
break;
default:
return;
}
}
/*
* fcoei_fill_els_logi_cmd
* Fill SCR (state change register) command frame
*
* Input:
* fpkt = LV fc_packet
* frm = Unsolicited frame containing LOGI response
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
int offset;
/*
* fill ls_code
*/
offset = 0;
/*
* fill common service parameters
*/
offset = 4;
offset = 6;
offset = 8;
offset = 10;
offset = 12;
offset = 14;
offset = 16;
/*
*/
offset = 20;
offset = 28;
/*
* class_3
*/
offset = 68;
offset = 70;
offset = 72;
offset = 74;
offset = 76;
offset = 78;
offset = 80;
/*
* needn't touch other fields
*/
}
/*
* fcoei_fill_prli_cmd
* Fill PRLI command frame
*
* Input:
* fpkt = LV fc_packet
* frm = Unsolicited frame containing PRLI response
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
int offset = 0;
/*
* fill basic PRLI fields
*/
offset = 0;
offset = 1;
offset = 2;
/*
* fill FCP service parameters page
*/
offset = 4;
/*
* PRLI flags, only 3 bits are valid
*/
offset = 6;
/*
* process associator
*/
offset = 8;
offset = 12;
/*
* FC-4 type
*/
offset = 16;
}
/*
* fcoei_fill_els_scr_cmd
* Fill SCR (state change register) command frame
*
* Input:
* fpkt = LV fc_packet
* frm = Unsolicited frame containing SCR command
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
int offset;
offset = 0;
offset = 7;
}
/*
* fcoei_fill_els_adisc_cmd
* Fill ADISC command frame
*
* Input:
* fpkt = LV fc_packet
* frm = Unsolicited frame containing ADISC command
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
int offset;
offset = 0;
offset = 5;
offset = 8;
offset = 16;
offset = 25;
}
/*
* fcoei_fill_els_linit_cmd
* Fill LINIT command frame
*
* Input:
* fpkt = LV fc_packet
* frm = Unsolicited frame containing LINIT command
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
/* ARGSUSED */
static void
{
}
/*
* fcoei_fill_els_logo_cmd
* Fill LOGO command frame
*
* Input:
* fpkt = LV fc_packet
* frm = Unsolicited frame containing LOGO command
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
int offset;
offset = 0;
offset = 5;
offset = 8;
}
static void
{
int offset;
offset = 0;
offset = 5;
}
static void
{
int offset;
offset = 0;
offset = 4;
}
/*
* fcoei_fill_els_acc_resp
* Fill ELS ACC response frame
*
* Input:
* fpkt = LV fc_packet
* frm = Unsolicited frame containing ELS ACC response
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
int offset;
offset = 0;
offset = 1;
}
/*
* fcoei_fill_els_rjt_resp
* Fill ELS RJT response frame
*
* Input:
* fpkt = LV fc_packet
* frm = Unsolicited frame containg ELS RJT response
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
int offset;
offset = 0; /* reset ls code */
}
/*
* fcoei_fill_els_adisc_resp
* Fill ADISC response frame
*
* Input:
* fpkt = LV fc_packet
* frm = Unsolicited frame containing ADISC response
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
int offset;
} else {
offset = 0;
offset = 5;
offset = 8;
offset = 16;
offset = 25;
}
}
/*
* fcoei_fill_els_logi_resp
*
* Input:
* fpkt = LV fc_packet
* frm = Unsolicited frame containing LOGI response
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
} else {
}
}
/*
* fcoei_fill_els_prli_resp
* Fill PRLI response frame
*
* Input:
* fpkt = LV fc_packet
* frm = Unsolicited frame containing PRLI response
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
} else {
}
}
/*
* fcoei_fill_els_logo_resp
* Fill LOGO response frame
*
* Input:
* fpkt = LV fc_packet
* frm = Unsolicited frame containing LOGO response
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
} else {
}
}
/*
* fcoei_logo_peer
* Send LOGO to the peer to emulate link offline event
*
* Input:
* arg - fcoei soft state set in fcoei_bind_port
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
static void
{
/*
* Allocate space for exchange
*/
/*
* Allocate space for fc_packet
*/
/*
* Link them together
*/
/*
* Initialize FC frame header
*/
} else {
}
/*
* Initialize LOGO payload
*/
/*
* Set the completion function
*/
}
}
/*
* fcoei_fpkt_comp
* internal exchange completion
*
* Input:
* fpkt - fc_packet_t to be completed
*
* Returns:
* N/A
*
* Comments:
*
*/
static void
{
}
/*
* fcoei_xch_abort
* Prepare to abort the exchange
*
* Input:
* val = the exchange
* arg = the soft state
*
* Returns:
* MH_WALK_CONTINUE = continue to walk
*
* Comments:
* N/A
*/
/* ARGSUSED */
static uint32_t
{
return (MH_WALK_CONTINUE);
}
/*
* fcoei_init_fcatran_vectors
* Initialize fc_fca_tran vectors that are defined in this file
*
* Input:
* fcatran - fc_fca_tran of the soft state
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
void
{
}
/*
* fcoei_process_event_reset
* link reset phase II
*
* Input:
* arg - fcoei soft state set in fcoei_bind_port
*
* Returns:
* N/A
*
* Comments:
*
*/
void
{
/*
* Notify LV that the link is up now
*/
}
/*
* fcoei_process_event_exchange
* Process exchange in the single thread context
*
* Input:
* ae = the exchange event
*
* Returns:
* N/A
*
* Comments:
* N/A
*/
void
{
/*
* These 4 elements need reset, pkt_state & pkt_reason will be set
*/
fpkt->pkt_action = 0;
fpkt->pkt_data_resid = 0;
fpkt->pkt_resp_resid = 0;
/*
* port state sanity checking
*/
/*
* LV will retry it after one second
*/
return;
}
case R_CTL_COMMAND:
break;
case R_CTL_ELS_REQ:
break;
case R_CTL_UNSOL_CONTROL:
break;
case R_CTL_ELS_RSP:
/*
* Caution: in leadville, it still uses pkt_cmd_fhdr
* oxid & rxid have been decided when we get unsolicited frames.
* pkt_cmd_fhdr has contained the right oxid and rxid now.
*/
break;
default:
}
}