2009-09-24 04:46:15 +04:00
/*
2015-11-26 11:54:45 +03:00
* Copyright ( c ) 2005 - 2014 Brocade Communications Systems , Inc .
* Copyright ( c ) 2014 - QLogic Corporation .
2009-09-24 04:46:15 +04:00
* All rights reserved
2015-11-26 11:54:45 +03:00
* www . qlogic . com
2009-09-24 04:46:15 +04:00
*
2015-11-26 11:54:46 +03:00
* Linux driver for QLogic BR - series Fibre Channel Host Bus Adapter .
2009-09-24 04:46:15 +04:00
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License ( GPL ) Version 2 as
* published by the Free Software Foundation
*
* This program is distributed in the hope that it will be useful , but
* WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* General Public License for more details .
*/
/*
* fcbuild . c - FC link service frame building and parsing routines
*/
2010-12-10 06:12:32 +03:00
# include "bfad_drv.h"
2010-09-15 22:50:55 +04:00
# include "bfa_fcbuild.h"
2009-09-24 04:46:15 +04:00
/*
* static build functions
*/
2010-09-15 22:50:55 +04:00
static void fc_els_rsp_build ( struct fchs_s * fchs , u32 d_id , u32 s_id ,
2010-11-30 05:26:32 +03:00
__be16 ox_id ) ;
2010-09-15 22:50:55 +04:00
static void fc_bls_rsp_build ( struct fchs_s * fchs , u32 d_id , u32 s_id ,
2010-11-30 05:26:32 +03:00
__be16 ox_id ) ;
2010-09-15 22:50:55 +04:00
static struct fchs_s fc_els_req_tmpl ;
static struct fchs_s fc_els_rsp_tmpl ;
static struct fchs_s fc_bls_req_tmpl ;
static struct fchs_s fc_bls_rsp_tmpl ;
2009-09-24 04:46:15 +04:00
static struct fc_ba_acc_s ba_acc_tmpl ;
static struct fc_logi_s plogi_tmpl ;
static struct fc_prli_s prli_tmpl ;
static struct fc_rrq_s rrq_tmpl ;
2010-09-15 22:50:55 +04:00
static struct fchs_s fcp_fchs_tmpl ;
2009-09-24 04:46:15 +04:00
void
fcbuild_init ( void )
{
/*
* fc_els_req_tmpl
*/
fc_els_req_tmpl . routing = FC_RTG_EXT_LINK ;
fc_els_req_tmpl . cat_info = FC_CAT_LD_REQUEST ;
fc_els_req_tmpl . type = FC_TYPE_ELS ;
fc_els_req_tmpl . f_ctl =
2010-12-10 06:12:32 +03:00
bfa_hton3b ( FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
2009-09-24 04:46:15 +04:00
FCTL_SI_XFER ) ;
fc_els_req_tmpl . rx_id = FC_RXID_ANY ;
/*
* fc_els_rsp_tmpl
*/
fc_els_rsp_tmpl . routing = FC_RTG_EXT_LINK ;
fc_els_rsp_tmpl . cat_info = FC_CAT_LD_REPLY ;
fc_els_rsp_tmpl . type = FC_TYPE_ELS ;
fc_els_rsp_tmpl . f_ctl =
2010-12-10 06:12:32 +03:00
bfa_hton3b ( FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
2009-09-24 04:46:15 +04:00
FCTL_END_SEQ | FCTL_SI_XFER ) ;
fc_els_rsp_tmpl . rx_id = FC_RXID_ANY ;
/*
* fc_bls_req_tmpl
*/
fc_bls_req_tmpl . routing = FC_RTG_BASIC_LINK ;
fc_bls_req_tmpl . type = FC_TYPE_BLS ;
2010-12-10 06:12:32 +03:00
fc_bls_req_tmpl . f_ctl = bfa_hton3b ( FCTL_END_SEQ | FCTL_SI_XFER ) ;
2009-09-24 04:46:15 +04:00
fc_bls_req_tmpl . rx_id = FC_RXID_ANY ;
/*
* fc_bls_rsp_tmpl
*/
fc_bls_rsp_tmpl . routing = FC_RTG_BASIC_LINK ;
fc_bls_rsp_tmpl . cat_info = FC_CAT_BA_ACC ;
fc_bls_rsp_tmpl . type = FC_TYPE_BLS ;
fc_bls_rsp_tmpl . f_ctl =
2010-12-10 06:12:32 +03:00
bfa_hton3b ( FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
2009-09-24 04:46:15 +04:00
FCTL_END_SEQ | FCTL_SI_XFER ) ;
fc_bls_rsp_tmpl . rx_id = FC_RXID_ANY ;
/*
* ba_acc_tmpl
*/
ba_acc_tmpl . seq_id_valid = 0 ;
ba_acc_tmpl . low_seq_cnt = 0 ;
ba_acc_tmpl . high_seq_cnt = 0xFFFF ;
/*
* plogi_tmpl
*/
plogi_tmpl . csp . verhi = FC_PH_VER_PH_3 ;
plogi_tmpl . csp . verlo = FC_PH_VER_4_3 ;
plogi_tmpl . csp . ciro = 0x1 ;
plogi_tmpl . csp . cisc = 0x0 ;
plogi_tmpl . csp . altbbcred = 0x0 ;
2010-10-19 04:10:50 +04:00
plogi_tmpl . csp . conseq = cpu_to_be16 ( 0x00FF ) ;
plogi_tmpl . csp . ro_bitmap = cpu_to_be16 ( 0x0002 ) ;
plogi_tmpl . csp . e_d_tov = cpu_to_be32 ( 2000 ) ;
2009-09-24 04:46:15 +04:00
plogi_tmpl . class3 . class_valid = 1 ;
plogi_tmpl . class3 . sequential = 1 ;
plogi_tmpl . class3 . conseq = 0xFF ;
plogi_tmpl . class3 . ospx = 1 ;
/*
* prli_tmpl
*/
prli_tmpl . command = FC_ELS_PRLI ;
prli_tmpl . pglen = 0x10 ;
2010-10-19 04:10:50 +04:00
prli_tmpl . pagebytes = cpu_to_be16 ( 0x0014 ) ;
2009-09-24 04:46:15 +04:00
prli_tmpl . parampage . type = FC_TYPE_FCP ;
prli_tmpl . parampage . imagepair = 1 ;
prli_tmpl . parampage . servparams . rxrdisab = 1 ;
/*
* rrq_tmpl
*/
rrq_tmpl . els_cmd . els_code = FC_ELS_RRQ ;
/*
2010-09-15 22:50:55 +04:00
* fcp_struct fchs_s mpl
2009-09-24 04:46:15 +04:00
*/
fcp_fchs_tmpl . routing = FC_RTG_FC4_DEV_DATA ;
fcp_fchs_tmpl . cat_info = FC_CAT_UNSOLICIT_CMD ;
fcp_fchs_tmpl . type = FC_TYPE_FCP ;
fcp_fchs_tmpl . f_ctl =
2010-12-10 06:12:32 +03:00
bfa_hton3b ( FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER ) ;
2009-09-24 04:46:15 +04:00
fcp_fchs_tmpl . seq_id = 1 ;
fcp_fchs_tmpl . rx_id = FC_RXID_ANY ;
}
static void
2010-09-15 22:50:55 +04:00
fc_gs_fchdr_build ( struct fchs_s * fchs , u32 d_id , u32 s_id , u32 ox_id )
2009-09-24 04:46:15 +04:00
{
2010-10-19 04:08:54 +04:00
memset ( fchs , 0 , sizeof ( struct fchs_s ) ) ;
2009-09-24 04:46:15 +04:00
fchs - > routing = FC_RTG_FC4_DEV_DATA ;
fchs - > cat_info = FC_CAT_UNSOLICIT_CTRL ;
fchs - > type = FC_TYPE_SERVICES ;
fchs - > f_ctl =
2010-12-10 06:12:32 +03:00
bfa_hton3b ( FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
2009-09-24 04:46:15 +04:00
FCTL_SI_XFER ) ;
fchs - > rx_id = FC_RXID_ANY ;
fchs - > d_id = ( d_id ) ;
fchs - > s_id = ( s_id ) ;
2010-10-19 04:10:50 +04:00
fchs - > ox_id = cpu_to_be16 ( ox_id ) ;
2009-09-24 04:46:15 +04:00
2010-10-19 04:17:23 +04:00
/*
2009-09-24 04:46:15 +04:00
* @ todo no need to set ox_id for request
* no need to set rx_id for response
*/
}
2011-06-25 07:24:52 +04:00
static void
fc_gsresp_fchdr_build ( struct fchs_s * fchs , u32 d_id , u32 s_id , u16 ox_id )
{
memset ( fchs , 0 , sizeof ( struct fchs_s ) ) ;
fchs - > routing = FC_RTG_FC4_DEV_DATA ;
fchs - > cat_info = FC_CAT_SOLICIT_CTRL ;
fchs - > type = FC_TYPE_SERVICES ;
fchs - > f_ctl =
bfa_hton3b ( FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
FCTL_END_SEQ | FCTL_SI_XFER ) ;
fchs - > d_id = d_id ;
fchs - > s_id = s_id ;
fchs - > ox_id = ox_id ;
}
2009-09-24 04:46:15 +04:00
void
2010-11-30 05:26:32 +03:00
fc_els_req_build ( struct fchs_s * fchs , u32 d_id , u32 s_id , __be16 ox_id )
2009-09-24 04:46:15 +04:00
{
2010-10-19 04:08:54 +04:00
memcpy ( fchs , & fc_els_req_tmpl , sizeof ( struct fchs_s ) ) ;
2009-09-24 04:46:15 +04:00
fchs - > d_id = ( d_id ) ;
fchs - > s_id = ( s_id ) ;
2010-10-19 04:10:50 +04:00
fchs - > ox_id = cpu_to_be16 ( ox_id ) ;
2009-09-24 04:46:15 +04:00
}
static void
2010-11-30 05:26:32 +03:00
fc_els_rsp_build ( struct fchs_s * fchs , u32 d_id , u32 s_id , __be16 ox_id )
2009-09-24 04:46:15 +04:00
{
2010-10-19 04:08:54 +04:00
memcpy ( fchs , & fc_els_rsp_tmpl , sizeof ( struct fchs_s ) ) ;
2009-09-24 04:46:15 +04:00
fchs - > d_id = d_id ;
fchs - > s_id = s_id ;
fchs - > ox_id = ox_id ;
}
enum fc_parse_status
fc_els_rsp_parse ( struct fchs_s * fchs , int len )
{
2010-09-15 22:50:55 +04:00
struct fc_els_cmd_s * els_cmd = ( struct fc_els_cmd_s * ) ( fchs + 1 ) ;
struct fc_ls_rjt_s * ls_rjt = ( struct fc_ls_rjt_s * ) els_cmd ;
2009-09-24 04:46:15 +04:00
len = len ;
switch ( els_cmd - > els_code ) {
case FC_ELS_LS_RJT :
if ( ls_rjt - > reason_code = = FC_LS_RJT_RSN_LOGICAL_BUSY )
2009-09-25 23:29:54 +04:00
return FC_PARSE_BUSY ;
2009-09-24 04:46:15 +04:00
else
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
case FC_ELS_ACC :
2009-09-25 23:29:54 +04:00
return FC_PARSE_OK ;
2009-09-24 04:46:15 +04:00
}
2009-09-25 23:29:54 +04:00
return FC_PARSE_OK ;
2009-09-24 04:46:15 +04:00
}
static void
2010-11-30 05:26:32 +03:00
fc_bls_rsp_build ( struct fchs_s * fchs , u32 d_id , u32 s_id , __be16 ox_id )
2009-09-24 04:46:15 +04:00
{
2010-10-19 04:08:54 +04:00
memcpy ( fchs , & fc_bls_rsp_tmpl , sizeof ( struct fchs_s ) ) ;
2009-09-24 04:46:15 +04:00
fchs - > d_id = d_id ;
fchs - > s_id = s_id ;
fchs - > ox_id = ox_id ;
}
static u16
fc_plogi_x_build ( struct fchs_s * fchs , void * pld , u32 d_id , u32 s_id ,
2010-11-30 05:26:32 +03:00
__be16 ox_id , wwn_t port_name , wwn_t node_name ,
2011-06-14 02:53:04 +04:00
u16 pdu_size , u16 bb_cr , u8 els_code )
2009-09-24 04:46:15 +04:00
{
2010-09-15 22:50:55 +04:00
struct fc_logi_s * plogi = ( struct fc_logi_s * ) ( pld ) ;
2009-09-24 04:46:15 +04:00
2010-10-19 04:08:54 +04:00
memcpy ( plogi , & plogi_tmpl , sizeof ( struct fc_logi_s ) ) ;
2009-09-24 04:46:15 +04:00
2012-09-22 04:23:59 +04:00
/* For FC AL bb_cr is 0 and altbbcred is 1 */
if ( ! bb_cr )
plogi - > csp . altbbcred = 1 ;
2009-09-24 04:46:15 +04:00
plogi - > els_cmd . els_code = els_code ;
if ( els_code = = FC_ELS_PLOGI )
fc_els_req_build ( fchs , d_id , s_id , ox_id ) ;
else
fc_els_rsp_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:10:50 +04:00
plogi - > csp . rxsz = plogi - > class3 . rxsz = cpu_to_be16 ( pdu_size ) ;
2011-06-14 02:53:04 +04:00
plogi - > csp . bbcred = cpu_to_be16 ( bb_cr ) ;
2009-09-24 04:46:15 +04:00
2010-10-19 04:08:54 +04:00
memcpy ( & plogi - > port_name , & port_name , sizeof ( wwn_t ) ) ;
memcpy ( & plogi - > node_name , & node_name , sizeof ( wwn_t ) ) ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_logi_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_flogi_build ( struct fchs_s * fchs , struct fc_logi_s * flogi , u32 s_id ,
2010-09-15 22:50:55 +04:00
u16 ox_id , wwn_t port_name , wwn_t node_name , u16 pdu_size ,
u8 set_npiv , u8 set_auth , u16 local_bb_credits )
2009-09-24 04:46:15 +04:00
{
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_FABRIC_PORT ) ;
2010-11-30 05:26:32 +03:00
__be32 * vvl_info ;
2009-09-24 04:46:15 +04:00
2010-10-19 04:08:54 +04:00
memcpy ( flogi , & plogi_tmpl , sizeof ( struct fc_logi_s ) ) ;
2009-09-24 04:46:15 +04:00
flogi - > els_cmd . els_code = FC_ELS_FLOGI ;
fc_els_req_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:10:50 +04:00
flogi - > csp . rxsz = flogi - > class3 . rxsz = cpu_to_be16 ( pdu_size ) ;
2009-09-24 04:46:15 +04:00
flogi - > port_name = port_name ;
flogi - > node_name = node_name ;
/*
* Set the NPIV Capability Bit ( word 1 , bit 31 ) of Common
* Service Parameters .
*/
flogi - > csp . ciro = set_npiv ;
/* set AUTH capability */
flogi - > csp . security = set_auth ;
2010-10-19 04:10:50 +04:00
flogi - > csp . bbcred = cpu_to_be16 ( local_bb_credits ) ;
2009-09-24 04:46:15 +04:00
/* Set brcd token in VVL */
vvl_info = ( u32 * ) & flogi - > vvl [ 0 ] ;
/* set the flag to indicate the presence of VVL */
flogi - > csp . npiv_supp = 1 ; /* @todo. field name is not correct */
2010-10-19 04:10:50 +04:00
vvl_info [ 0 ] = cpu_to_be32 ( FLOGI_VVL_BRCD ) ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_logi_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_flogi_acc_build ( struct fchs_s * fchs , struct fc_logi_s * flogi , u32 s_id ,
2010-11-30 05:26:32 +03:00
__be16 ox_id , wwn_t port_name , wwn_t node_name ,
2011-06-14 02:53:04 +04:00
u16 pdu_size , u16 local_bb_credits , u8 bb_scn )
2009-09-24 04:46:15 +04:00
{
u32 d_id = 0 ;
2011-06-14 02:53:04 +04:00
u16 bbscn_rxsz = ( bb_scn < < 12 ) | pdu_size ;
2009-09-24 04:46:15 +04:00
2010-10-19 04:08:54 +04:00
memcpy ( flogi , & plogi_tmpl , sizeof ( struct fc_logi_s ) ) ;
2009-09-24 04:46:15 +04:00
fc_els_rsp_build ( fchs , d_id , s_id , ox_id ) ;
flogi - > els_cmd . els_code = FC_ELS_ACC ;
2011-06-14 02:53:04 +04:00
flogi - > class3 . rxsz = cpu_to_be16 ( pdu_size ) ;
flogi - > csp . rxsz = cpu_to_be16 ( bbscn_rxsz ) ; /* bb_scn/rxsz */
2009-09-24 04:46:15 +04:00
flogi - > port_name = port_name ;
flogi - > node_name = node_name ;
2010-10-19 04:10:50 +04:00
flogi - > csp . bbcred = cpu_to_be16 ( local_bb_credits ) ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_logi_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_fdisc_build ( struct fchs_s * fchs , struct fc_logi_s * flogi , u32 s_id ,
2010-09-15 22:50:55 +04:00
u16 ox_id , wwn_t port_name , wwn_t node_name , u16 pdu_size )
2009-09-24 04:46:15 +04:00
{
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_FABRIC_PORT ) ;
2009-09-24 04:46:15 +04:00
2010-10-19 04:08:54 +04:00
memcpy ( flogi , & plogi_tmpl , sizeof ( struct fc_logi_s ) ) ;
2009-09-24 04:46:15 +04:00
flogi - > els_cmd . els_code = FC_ELS_FDISC ;
fc_els_req_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:10:50 +04:00
flogi - > csp . rxsz = flogi - > class3 . rxsz = cpu_to_be16 ( pdu_size ) ;
2009-09-24 04:46:15 +04:00
flogi - > port_name = port_name ;
flogi - > node_name = node_name ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_logi_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_plogi_build ( struct fchs_s * fchs , void * pld , u32 d_id , u32 s_id ,
u16 ox_id , wwn_t port_name , wwn_t node_name ,
2011-06-14 02:53:04 +04:00
u16 pdu_size , u16 bb_cr )
2009-09-24 04:46:15 +04:00
{
return fc_plogi_x_build ( fchs , pld , d_id , s_id , ox_id , port_name ,
2011-06-14 02:53:04 +04:00
node_name , pdu_size , bb_cr , FC_ELS_PLOGI ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_plogi_acc_build ( struct fchs_s * fchs , void * pld , u32 d_id , u32 s_id ,
u16 ox_id , wwn_t port_name , wwn_t node_name ,
2011-06-14 02:53:04 +04:00
u16 pdu_size , u16 bb_cr )
2009-09-24 04:46:15 +04:00
{
return fc_plogi_x_build ( fchs , pld , d_id , s_id , ox_id , port_name ,
2011-06-14 02:53:04 +04:00
node_name , pdu_size , bb_cr , FC_ELS_ACC ) ;
2009-09-24 04:46:15 +04:00
}
enum fc_parse_status
fc_plogi_rsp_parse ( struct fchs_s * fchs , int len , wwn_t port_name )
{
2010-09-15 22:50:55 +04:00
struct fc_els_cmd_s * els_cmd = ( struct fc_els_cmd_s * ) ( fchs + 1 ) ;
struct fc_logi_s * plogi ;
struct fc_ls_rjt_s * ls_rjt ;
2009-09-24 04:46:15 +04:00
switch ( els_cmd - > els_code ) {
case FC_ELS_LS_RJT :
ls_rjt = ( struct fc_ls_rjt_s * ) ( fchs + 1 ) ;
if ( ls_rjt - > reason_code = = FC_LS_RJT_RSN_LOGICAL_BUSY )
2009-09-25 23:29:54 +04:00
return FC_PARSE_BUSY ;
2009-09-24 04:46:15 +04:00
else
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
case FC_ELS_ACC :
plogi = ( struct fc_logi_s * ) ( fchs + 1 ) ;
if ( len < sizeof ( struct fc_logi_s ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
if ( ! wwn_is_equal ( plogi - > port_name , port_name ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
if ( ! plogi - > class3 . class_valid )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
2010-10-19 04:10:50 +04:00
if ( be16_to_cpu ( plogi - > class3 . rxsz ) < ( FC_MIN_PDUSZ ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return FC_PARSE_OK ;
2009-09-24 04:46:15 +04:00
default :
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
}
}
enum fc_parse_status
fc_plogi_parse ( struct fchs_s * fchs )
{
2010-09-15 22:50:55 +04:00
struct fc_logi_s * plogi = ( struct fc_logi_s * ) ( fchs + 1 ) ;
2009-09-24 04:46:15 +04:00
if ( plogi - > class3 . class_valid ! = 1 )
return FC_PARSE_FAILURE ;
2010-10-19 04:10:50 +04:00
if ( ( be16_to_cpu ( plogi - > class3 . rxsz ) < FC_MIN_PDUSZ )
| | ( be16_to_cpu ( plogi - > class3 . rxsz ) > FC_MAX_PDUSZ )
2009-09-24 04:46:15 +04:00
| | ( plogi - > class3 . rxsz = = 0 ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
return FC_PARSE_OK ;
}
u16
fc_prli_build ( struct fchs_s * fchs , void * pld , u32 d_id , u32 s_id ,
u16 ox_id )
{
2010-09-15 22:50:55 +04:00
struct fc_prli_s * prli = ( struct fc_prli_s * ) ( pld ) ;
2009-09-24 04:46:15 +04:00
fc_els_req_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:08:54 +04:00
memcpy ( prli , & prli_tmpl , sizeof ( struct fc_prli_s ) ) ;
2009-09-24 04:46:15 +04:00
prli - > command = FC_ELS_PRLI ;
prli - > parampage . servparams . initiator = 1 ;
prli - > parampage . servparams . retry = 1 ;
prli - > parampage . servparams . rec_support = 1 ;
prli - > parampage . servparams . task_retry_id = 0 ;
prli - > parampage . servparams . confirm = 1 ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_prli_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_prli_acc_build ( struct fchs_s * fchs , void * pld , u32 d_id , u32 s_id ,
2010-11-30 05:26:32 +03:00
__be16 ox_id , enum bfa_lport_role role )
2009-09-24 04:46:15 +04:00
{
2010-09-15 22:50:55 +04:00
struct fc_prli_s * prli = ( struct fc_prli_s * ) ( pld ) ;
2009-09-24 04:46:15 +04:00
fc_els_rsp_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:08:54 +04:00
memcpy ( prli , & prli_tmpl , sizeof ( struct fc_prli_s ) ) ;
2009-09-24 04:46:15 +04:00
prli - > command = FC_ELS_ACC ;
2010-09-15 22:50:55 +04:00
prli - > parampage . servparams . initiator = 1 ;
2009-09-24 04:46:15 +04:00
prli - > parampage . rspcode = FC_PRLI_ACC_XQTD ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_prli_s ) ;
2009-09-24 04:46:15 +04:00
}
enum fc_parse_status
fc_prli_rsp_parse ( struct fc_prli_s * prli , int len )
{
if ( len < sizeof ( struct fc_prli_s ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
if ( prli - > command ! = FC_ELS_ACC )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
if ( ( prli - > parampage . rspcode ! = FC_PRLI_ACC_XQTD )
& & ( prli - > parampage . rspcode ! = FC_PRLI_ACC_PREDEF_IMG ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
if ( prli - > parampage . servparams . target ! = 1 )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return FC_PARSE_OK ;
2009-09-24 04:46:15 +04:00
}
enum fc_parse_status
fc_prli_parse ( struct fc_prli_s * prli )
{
if ( prli - > parampage . type ! = FC_TYPE_FCP )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
if ( ! prli - > parampage . imagepair )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
if ( ! prli - > parampage . servparams . initiator )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return FC_PARSE_OK ;
2009-09-24 04:46:15 +04:00
}
u16
2010-09-15 22:50:55 +04:00
fc_logo_build ( struct fchs_s * fchs , struct fc_logo_s * logo , u32 d_id , u32 s_id ,
u16 ox_id , wwn_t port_name )
2009-09-24 04:46:15 +04:00
{
fc_els_req_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:08:54 +04:00
memset ( logo , ' \0 ' , sizeof ( struct fc_logo_s ) ) ;
2009-09-24 04:46:15 +04:00
logo - > els_cmd . els_code = FC_ELS_LOGO ;
logo - > nport_id = ( s_id ) ;
logo - > orig_port_name = port_name ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_logo_s ) ;
2009-09-24 04:46:15 +04:00
}
2010-12-10 06:13:20 +03:00
static u16
2009-09-24 04:46:15 +04:00
fc_adisc_x_build ( struct fchs_s * fchs , struct fc_adisc_s * adisc , u32 d_id ,
2010-11-30 05:26:32 +03:00
u32 s_id , __be16 ox_id , wwn_t port_name ,
2009-09-24 04:46:15 +04:00
wwn_t node_name , u8 els_code )
{
2010-10-19 04:08:54 +04:00
memset ( adisc , ' \0 ' , sizeof ( struct fc_adisc_s ) ) ;
2009-09-24 04:46:15 +04:00
adisc - > els_cmd . els_code = els_code ;
if ( els_code = = FC_ELS_ADISC )
fc_els_req_build ( fchs , d_id , s_id , ox_id ) ;
else
fc_els_rsp_build ( fchs , d_id , s_id , ox_id ) ;
adisc - > orig_HA = 0 ;
adisc - > orig_port_name = port_name ;
adisc - > orig_node_name = node_name ;
adisc - > nport_id = ( s_id ) ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_adisc_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_adisc_build ( struct fchs_s * fchs , struct fc_adisc_s * adisc , u32 d_id ,
2010-11-30 05:26:32 +03:00
u32 s_id , __be16 ox_id , wwn_t port_name , wwn_t node_name )
2009-09-24 04:46:15 +04:00
{
return fc_adisc_x_build ( fchs , adisc , d_id , s_id , ox_id , port_name ,
node_name , FC_ELS_ADISC ) ;
}
u16
fc_adisc_acc_build ( struct fchs_s * fchs , struct fc_adisc_s * adisc , u32 d_id ,
2010-11-30 05:26:32 +03:00
u32 s_id , __be16 ox_id , wwn_t port_name ,
2009-09-24 04:46:15 +04:00
wwn_t node_name )
{
return fc_adisc_x_build ( fchs , adisc , d_id , s_id , ox_id , port_name ,
node_name , FC_ELS_ACC ) ;
}
enum fc_parse_status
fc_adisc_rsp_parse ( struct fc_adisc_s * adisc , int len , wwn_t port_name ,
wwn_t node_name )
{
if ( len < sizeof ( struct fc_adisc_s ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
if ( adisc - > els_cmd . els_code ! = FC_ELS_ACC )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
if ( ! wwn_is_equal ( adisc - > orig_port_name , port_name ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return FC_PARSE_OK ;
2009-09-24 04:46:15 +04:00
}
enum fc_parse_status
2010-09-15 22:50:55 +04:00
fc_adisc_parse ( struct fchs_s * fchs , void * pld , u32 host_dap , wwn_t node_name ,
wwn_t port_name )
2009-09-24 04:46:15 +04:00
{
2010-09-15 22:50:55 +04:00
struct fc_adisc_s * adisc = ( struct fc_adisc_s * ) pld ;
2009-09-24 04:46:15 +04:00
if ( adisc - > els_cmd . els_code ! = FC_ELS_ACC )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
if ( ( adisc - > nport_id = = ( host_dap ) )
& & wwn_is_equal ( adisc - > orig_port_name , port_name )
& & wwn_is_equal ( adisc - > orig_node_name , node_name ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_OK ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
}
enum fc_parse_status
fc_pdisc_parse ( struct fchs_s * fchs , wwn_t node_name , wwn_t port_name )
{
2010-09-15 22:50:55 +04:00
struct fc_logi_s * pdisc = ( struct fc_logi_s * ) ( fchs + 1 ) ;
2009-09-24 04:46:15 +04:00
if ( pdisc - > class3 . class_valid ! = 1 )
return FC_PARSE_FAILURE ;
2010-10-19 04:10:50 +04:00
if ( ( be16_to_cpu ( pdisc - > class3 . rxsz ) <
2010-09-15 22:50:55 +04:00
( FC_MIN_PDUSZ - sizeof ( struct fchs_s ) ) )
2009-09-24 04:46:15 +04:00
| | ( pdisc - > class3 . rxsz = = 0 ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
if ( ! wwn_is_equal ( pdisc - > port_name , port_name ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
if ( ! wwn_is_equal ( pdisc - > node_name , node_name ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
return FC_PARSE_OK ;
}
u16
fc_abts_build ( struct fchs_s * fchs , u32 d_id , u32 s_id , u16 ox_id )
{
2010-10-19 04:08:54 +04:00
memcpy ( fchs , & fc_bls_req_tmpl , sizeof ( struct fchs_s ) ) ;
2009-09-24 04:46:15 +04:00
fchs - > cat_info = FC_CAT_ABTS ;
fchs - > d_id = ( d_id ) ;
fchs - > s_id = ( s_id ) ;
2010-10-19 04:10:50 +04:00
fchs - > ox_id = cpu_to_be16 ( ox_id ) ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return sizeof ( struct fchs_s ) ;
2009-09-24 04:46:15 +04:00
}
enum fc_parse_status
fc_abts_rsp_parse ( struct fchs_s * fchs , int len )
{
if ( ( fchs - > cat_info = = FC_CAT_BA_ACC )
| | ( fchs - > cat_info = = FC_CAT_BA_RJT ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_OK ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
}
u16
2010-09-15 22:50:55 +04:00
fc_rrq_build ( struct fchs_s * fchs , struct fc_rrq_s * rrq , u32 d_id , u32 s_id ,
u16 ox_id , u16 rrq_oxid )
2009-09-24 04:46:15 +04:00
{
fc_els_req_build ( fchs , d_id , s_id , ox_id ) ;
/*
* build rrq payload
*/
2010-10-19 04:08:54 +04:00
memcpy ( rrq , & rrq_tmpl , sizeof ( struct fc_rrq_s ) ) ;
2009-09-24 04:46:15 +04:00
rrq - > s_id = ( s_id ) ;
2010-10-19 04:10:50 +04:00
rrq - > ox_id = cpu_to_be16 ( rrq_oxid ) ;
2009-09-24 04:46:15 +04:00
rrq - > rx_id = FC_RXID_ANY ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_rrq_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_logo_acc_build ( struct fchs_s * fchs , void * pld , u32 d_id , u32 s_id ,
2010-11-30 05:26:32 +03:00
__be16 ox_id )
2009-09-24 04:46:15 +04:00
{
2010-09-15 22:50:55 +04:00
struct fc_els_cmd_s * acc = pld ;
2009-09-24 04:46:15 +04:00
fc_els_rsp_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:08:54 +04:00
memset ( acc , 0 , sizeof ( struct fc_els_cmd_s ) ) ;
2009-09-24 04:46:15 +04:00
acc - > els_code = FC_ELS_ACC ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_els_cmd_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_ls_rjt_build ( struct fchs_s * fchs , struct fc_ls_rjt_s * ls_rjt , u32 d_id ,
2010-11-30 05:26:32 +03:00
u32 s_id , __be16 ox_id , u8 reason_code ,
2009-09-24 04:46:15 +04:00
u8 reason_code_expl )
{
fc_els_rsp_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:08:54 +04:00
memset ( ls_rjt , 0 , sizeof ( struct fc_ls_rjt_s ) ) ;
2009-09-24 04:46:15 +04:00
ls_rjt - > els_cmd . els_code = FC_ELS_LS_RJT ;
ls_rjt - > reason_code = reason_code ;
ls_rjt - > reason_code_expl = reason_code_expl ;
ls_rjt - > vendor_unique = 0x00 ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_ls_rjt_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_ba_acc_build ( struct fchs_s * fchs , struct fc_ba_acc_s * ba_acc , u32 d_id ,
2010-11-30 05:26:32 +03:00
u32 s_id , __be16 ox_id , u16 rx_id )
2009-09-24 04:46:15 +04:00
{
fc_bls_rsp_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:08:54 +04:00
memcpy ( ba_acc , & ba_acc_tmpl , sizeof ( struct fc_ba_acc_s ) ) ;
2009-09-24 04:46:15 +04:00
fchs - > rx_id = rx_id ;
ba_acc - > ox_id = fchs - > ox_id ;
ba_acc - > rx_id = fchs - > rx_id ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_ba_acc_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
2010-09-15 22:50:55 +04:00
fc_ls_acc_build ( struct fchs_s * fchs , struct fc_els_cmd_s * els_cmd , u32 d_id ,
2010-11-30 05:26:32 +03:00
u32 s_id , __be16 ox_id )
2009-09-24 04:46:15 +04:00
{
fc_els_rsp_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:08:54 +04:00
memset ( els_cmd , 0 , sizeof ( struct fc_els_cmd_s ) ) ;
2009-09-24 04:46:15 +04:00
els_cmd - > els_code = FC_ELS_ACC ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_els_cmd_s ) ;
2009-09-24 04:46:15 +04:00
}
int
fc_logout_params_pages ( struct fchs_s * fc_frame , u8 els_code )
{
int num_pages = 0 ;
2010-09-15 22:50:55 +04:00
struct fc_prlo_s * prlo ;
struct fc_tprlo_s * tprlo ;
2009-09-24 04:46:15 +04:00
if ( els_code = = FC_ELS_PRLO ) {
prlo = ( struct fc_prlo_s * ) ( fc_frame + 1 ) ;
2010-10-19 04:10:50 +04:00
num_pages = ( be16_to_cpu ( prlo - > payload_len ) - 4 ) / 16 ;
2009-09-24 04:46:15 +04:00
} else {
tprlo = ( struct fc_tprlo_s * ) ( fc_frame + 1 ) ;
2010-10-19 04:10:50 +04:00
num_pages = ( be16_to_cpu ( tprlo - > payload_len ) - 4 ) / 16 ;
2009-09-24 04:46:15 +04:00
}
return num_pages ;
}
u16
fc_tprlo_acc_build ( struct fchs_s * fchs , struct fc_tprlo_acc_s * tprlo_acc ,
2010-11-30 05:26:32 +03:00
u32 d_id , u32 s_id , __be16 ox_id , int num_pages )
2009-09-24 04:46:15 +04:00
{
int page ;
fc_els_rsp_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:08:54 +04:00
memset ( tprlo_acc , 0 , ( num_pages * 16 ) + 4 ) ;
2009-09-24 04:46:15 +04:00
tprlo_acc - > command = FC_ELS_ACC ;
tprlo_acc - > page_len = 0x10 ;
2010-10-19 04:10:50 +04:00
tprlo_acc - > payload_len = cpu_to_be16 ( ( num_pages * 16 ) + 4 ) ;
2009-09-24 04:46:15 +04:00
for ( page = 0 ; page < num_pages ; page + + ) {
tprlo_acc - > tprlo_acc_params [ page ] . opa_valid = 0 ;
tprlo_acc - > tprlo_acc_params [ page ] . rpa_valid = 0 ;
tprlo_acc - > tprlo_acc_params [ page ] . fc4type_csp = FC_TYPE_FCP ;
tprlo_acc - > tprlo_acc_params [ page ] . orig_process_assc = 0 ;
tprlo_acc - > tprlo_acc_params [ page ] . resp_process_assc = 0 ;
}
2010-10-19 04:10:50 +04:00
return be16_to_cpu ( tprlo_acc - > payload_len ) ;
2009-09-24 04:46:15 +04:00
}
u16
2010-09-15 22:50:55 +04:00
fc_prlo_acc_build ( struct fchs_s * fchs , struct fc_prlo_acc_s * prlo_acc , u32 d_id ,
2010-11-30 05:26:32 +03:00
u32 s_id , __be16 ox_id , int num_pages )
2009-09-24 04:46:15 +04:00
{
int page ;
fc_els_rsp_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:08:54 +04:00
memset ( prlo_acc , 0 , ( num_pages * 16 ) + 4 ) ;
2009-09-24 04:46:15 +04:00
prlo_acc - > command = FC_ELS_ACC ;
prlo_acc - > page_len = 0x10 ;
2010-10-19 04:10:50 +04:00
prlo_acc - > payload_len = cpu_to_be16 ( ( num_pages * 16 ) + 4 ) ;
2009-09-24 04:46:15 +04:00
for ( page = 0 ; page < num_pages ; page + + ) {
prlo_acc - > prlo_acc_params [ page ] . opa_valid = 0 ;
prlo_acc - > prlo_acc_params [ page ] . rpa_valid = 0 ;
prlo_acc - > prlo_acc_params [ page ] . fc4type_csp = FC_TYPE_FCP ;
prlo_acc - > prlo_acc_params [ page ] . orig_process_assc = 0 ;
prlo_acc - > prlo_acc_params [ page ] . resp_process_assc = 0 ;
}
2010-10-19 04:10:50 +04:00
return be16_to_cpu ( prlo_acc - > payload_len ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_rnid_build ( struct fchs_s * fchs , struct fc_rnid_cmd_s * rnid , u32 d_id ,
2010-09-15 22:50:55 +04:00
u32 s_id , u16 ox_id , u32 data_format )
2009-09-24 04:46:15 +04:00
{
fc_els_req_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:08:54 +04:00
memset ( rnid , 0 , sizeof ( struct fc_rnid_cmd_s ) ) ;
2009-09-24 04:46:15 +04:00
rnid - > els_cmd . els_code = FC_ELS_RNID ;
rnid - > node_id_data_format = data_format ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_rnid_cmd_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
2010-09-15 22:50:55 +04:00
fc_rnid_acc_build ( struct fchs_s * fchs , struct fc_rnid_acc_s * rnid_acc , u32 d_id ,
2010-11-30 05:26:32 +03:00
u32 s_id , __be16 ox_id , u32 data_format ,
2010-09-15 22:50:55 +04:00
struct fc_rnid_common_id_data_s * common_id_data ,
struct fc_rnid_general_topology_data_s * gen_topo_data )
2009-09-24 04:46:15 +04:00
{
2010-10-19 04:08:54 +04:00
memset ( rnid_acc , 0 , sizeof ( struct fc_rnid_acc_s ) ) ;
2009-09-24 04:46:15 +04:00
fc_els_rsp_build ( fchs , d_id , s_id , ox_id ) ;
rnid_acc - > els_cmd . els_code = FC_ELS_ACC ;
rnid_acc - > node_id_data_format = data_format ;
rnid_acc - > common_id_data_length =
sizeof ( struct fc_rnid_common_id_data_s ) ;
rnid_acc - > common_id_data = * common_id_data ;
if ( data_format = = RNID_NODEID_DATA_FORMAT_DISCOVERY ) {
rnid_acc - > specific_id_data_length =
sizeof ( struct fc_rnid_general_topology_data_s ) ;
2010-10-19 04:08:54 +04:00
rnid_acc - > gen_topology_data = * gen_topo_data ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_rnid_acc_s ) ;
2009-09-24 04:46:15 +04:00
} else {
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_rnid_acc_s ) -
sizeof ( struct fc_rnid_general_topology_data_s ) ;
2009-09-24 04:46:15 +04:00
}
}
u16
fc_rpsc_build ( struct fchs_s * fchs , struct fc_rpsc_cmd_s * rpsc , u32 d_id ,
2010-09-15 22:50:55 +04:00
u32 s_id , u16 ox_id )
2009-09-24 04:46:15 +04:00
{
fc_els_req_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:08:54 +04:00
memset ( rpsc , 0 , sizeof ( struct fc_rpsc_cmd_s ) ) ;
2009-09-24 04:46:15 +04:00
rpsc - > els_cmd . els_code = FC_ELS_RPSC ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_rpsc_cmd_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
2010-09-15 22:50:55 +04:00
fc_rpsc2_build ( struct fchs_s * fchs , struct fc_rpsc2_cmd_s * rpsc2 , u32 d_id ,
u32 s_id , u32 * pid_list , u16 npids )
2009-09-24 04:46:15 +04:00
{
2010-12-10 06:12:32 +03:00
u32 dctlr_id = FC_DOMAIN_CTRLR ( bfa_hton3b ( d_id ) ) ;
2009-09-24 04:46:15 +04:00
int i = 0 ;
2010-12-10 06:12:32 +03:00
fc_els_req_build ( fchs , bfa_hton3b ( dctlr_id ) , s_id , 0 ) ;
2009-09-24 04:46:15 +04:00
2010-10-19 04:08:54 +04:00
memset ( rpsc2 , 0 , sizeof ( struct fc_rpsc2_cmd_s ) ) ;
2009-09-24 04:46:15 +04:00
rpsc2 - > els_cmd . els_code = FC_ELS_RPSC ;
2010-10-19 04:10:50 +04:00
rpsc2 - > token = cpu_to_be32 ( FC_BRCD_TOKEN ) ;
rpsc2 - > num_pids = cpu_to_be16 ( npids ) ;
2009-09-24 04:46:15 +04:00
for ( i = 0 ; i < npids ; i + + )
rpsc2 - > pid_list [ i ] . pid = pid_list [ i ] ;
2010-09-15 22:50:55 +04:00
return sizeof ( struct fc_rpsc2_cmd_s ) + ( ( npids - 1 ) * ( sizeof ( u32 ) ) ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_rpsc_acc_build ( struct fchs_s * fchs , struct fc_rpsc_acc_s * rpsc_acc ,
2010-11-30 05:26:32 +03:00
u32 d_id , u32 s_id , __be16 ox_id ,
2010-09-15 22:50:55 +04:00
struct fc_rpsc_speed_info_s * oper_speed )
2009-09-24 04:46:15 +04:00
{
2010-10-19 04:08:54 +04:00
memset ( rpsc_acc , 0 , sizeof ( struct fc_rpsc_acc_s ) ) ;
2009-09-24 04:46:15 +04:00
fc_els_rsp_build ( fchs , d_id , s_id , ox_id ) ;
rpsc_acc - > command = FC_ELS_ACC ;
2010-10-19 04:10:50 +04:00
rpsc_acc - > num_entries = cpu_to_be16 ( 1 ) ;
2009-09-24 04:46:15 +04:00
rpsc_acc - > speed_info [ 0 ] . port_speed_cap =
2010-10-19 04:10:50 +04:00
cpu_to_be16 ( oper_speed - > port_speed_cap ) ;
2009-09-24 04:46:15 +04:00
rpsc_acc - > speed_info [ 0 ] . port_op_speed =
2010-10-19 04:10:50 +04:00
cpu_to_be16 ( oper_speed - > port_op_speed ) ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_rpsc_acc_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_logo_rsp_parse ( struct fchs_s * fchs , int len )
{
2010-09-15 22:50:55 +04:00
struct fc_els_cmd_s * els_cmd = ( struct fc_els_cmd_s * ) ( fchs + 1 ) ;
2009-09-24 04:46:15 +04:00
len = len ;
if ( els_cmd - > els_code ! = FC_ELS_ACC )
return FC_PARSE_FAILURE ;
return FC_PARSE_OK ;
}
u16
2010-09-15 22:50:55 +04:00
fc_pdisc_build ( struct fchs_s * fchs , u32 d_id , u32 s_id , u16 ox_id ,
wwn_t port_name , wwn_t node_name , u16 pdu_size )
2009-09-24 04:46:15 +04:00
{
2010-09-15 22:50:55 +04:00
struct fc_logi_s * pdisc = ( struct fc_logi_s * ) ( fchs + 1 ) ;
2009-09-24 04:46:15 +04:00
2010-10-19 04:08:54 +04:00
memcpy ( pdisc , & plogi_tmpl , sizeof ( struct fc_logi_s ) ) ;
2009-09-24 04:46:15 +04:00
pdisc - > els_cmd . els_code = FC_ELS_PDISC ;
fc_els_req_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:10:50 +04:00
pdisc - > csp . rxsz = pdisc - > class3 . rxsz = cpu_to_be16 ( pdu_size ) ;
2009-09-24 04:46:15 +04:00
pdisc - > port_name = port_name ;
pdisc - > node_name = node_name ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_logi_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_pdisc_rsp_parse ( struct fchs_s * fchs , int len , wwn_t port_name )
{
2010-09-15 22:50:55 +04:00
struct fc_logi_s * pdisc = ( struct fc_logi_s * ) ( fchs + 1 ) ;
2009-09-24 04:46:15 +04:00
if ( len < sizeof ( struct fc_logi_s ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_LEN_INVAL ;
2009-09-24 04:46:15 +04:00
if ( pdisc - > els_cmd . els_code ! = FC_ELS_ACC )
2009-09-25 23:29:54 +04:00
return FC_PARSE_ACC_INVAL ;
2009-09-24 04:46:15 +04:00
if ( ! wwn_is_equal ( pdisc - > port_name , port_name ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_PWWN_NOT_EQUAL ;
2009-09-24 04:46:15 +04:00
if ( ! pdisc - > class3 . class_valid )
2009-09-25 23:29:54 +04:00
return FC_PARSE_NWWN_NOT_EQUAL ;
2009-09-24 04:46:15 +04:00
2010-10-19 04:10:50 +04:00
if ( be16_to_cpu ( pdisc - > class3 . rxsz ) < ( FC_MIN_PDUSZ ) )
2009-09-25 23:29:54 +04:00
return FC_PARSE_RXSZ_INVAL ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return FC_PARSE_OK ;
2009-09-24 04:46:15 +04:00
}
u16
fc_prlo_build ( struct fchs_s * fchs , u32 d_id , u32 s_id , u16 ox_id ,
int num_pages )
{
2010-09-15 22:50:55 +04:00
struct fc_prlo_s * prlo = ( struct fc_prlo_s * ) ( fchs + 1 ) ;
2009-09-24 04:46:15 +04:00
int page ;
fc_els_req_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:08:54 +04:00
memset ( prlo , 0 , ( num_pages * 16 ) + 4 ) ;
2009-09-24 04:46:15 +04:00
prlo - > command = FC_ELS_PRLO ;
prlo - > page_len = 0x10 ;
2010-10-19 04:10:50 +04:00
prlo - > payload_len = cpu_to_be16 ( ( num_pages * 16 ) + 4 ) ;
2009-09-24 04:46:15 +04:00
for ( page = 0 ; page < num_pages ; page + + ) {
prlo - > prlo_params [ page ] . type = FC_TYPE_FCP ;
prlo - > prlo_params [ page ] . opa_valid = 0 ;
prlo - > prlo_params [ page ] . rpa_valid = 0 ;
prlo - > prlo_params [ page ] . orig_process_assc = 0 ;
prlo - > prlo_params [ page ] . resp_process_assc = 0 ;
}
2010-10-19 04:10:50 +04:00
return be16_to_cpu ( prlo - > payload_len ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_prlo_rsp_parse ( struct fchs_s * fchs , int len )
{
2010-09-15 22:50:55 +04:00
struct fc_prlo_acc_s * prlo = ( struct fc_prlo_acc_s * ) ( fchs + 1 ) ;
2009-09-24 04:46:15 +04:00
int num_pages = 0 ;
int page = 0 ;
len = len ;
if ( prlo - > command ! = FC_ELS_ACC )
2009-09-25 23:29:54 +04:00
return FC_PARSE_FAILURE ;
2009-09-24 04:46:15 +04:00
2010-10-19 04:10:50 +04:00
num_pages = ( ( be16_to_cpu ( prlo - > payload_len ) ) - 4 ) / 16 ;
2009-09-24 04:46:15 +04:00
for ( page = 0 ; page < num_pages ; page + + ) {
if ( prlo - > prlo_acc_params [ page ] . type ! = FC_TYPE_FCP )
return FC_PARSE_FAILURE ;
if ( prlo - > prlo_acc_params [ page ] . opa_valid ! = 0 )
return FC_PARSE_FAILURE ;
if ( prlo - > prlo_acc_params [ page ] . rpa_valid ! = 0 )
return FC_PARSE_FAILURE ;
if ( prlo - > prlo_acc_params [ page ] . orig_process_assc ! = 0 )
return FC_PARSE_FAILURE ;
if ( prlo - > prlo_acc_params [ page ] . resp_process_assc ! = 0 )
return FC_PARSE_FAILURE ;
}
2009-09-25 23:29:54 +04:00
return FC_PARSE_OK ;
2009-09-24 04:46:15 +04:00
}
u16
2010-09-15 22:50:55 +04:00
fc_tprlo_build ( struct fchs_s * fchs , u32 d_id , u32 s_id , u16 ox_id ,
int num_pages , enum fc_tprlo_type tprlo_type , u32 tpr_id )
2009-09-24 04:46:15 +04:00
{
2010-09-15 22:50:55 +04:00
struct fc_tprlo_s * tprlo = ( struct fc_tprlo_s * ) ( fchs + 1 ) ;
2009-09-24 04:46:15 +04:00
int page ;
fc_els_req_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:08:54 +04:00
memset ( tprlo , 0 , ( num_pages * 16 ) + 4 ) ;
2009-09-24 04:46:15 +04:00
tprlo - > command = FC_ELS_TPRLO ;
tprlo - > page_len = 0x10 ;
2010-10-19 04:10:50 +04:00
tprlo - > payload_len = cpu_to_be16 ( ( num_pages * 16 ) + 4 ) ;
2009-09-24 04:46:15 +04:00
for ( page = 0 ; page < num_pages ; page + + ) {
tprlo - > tprlo_params [ page ] . type = FC_TYPE_FCP ;
tprlo - > tprlo_params [ page ] . opa_valid = 0 ;
tprlo - > tprlo_params [ page ] . rpa_valid = 0 ;
tprlo - > tprlo_params [ page ] . orig_process_assc = 0 ;
tprlo - > tprlo_params [ page ] . resp_process_assc = 0 ;
if ( tprlo_type = = FC_GLOBAL_LOGO ) {
tprlo - > tprlo_params [ page ] . global_process_logout = 1 ;
} else if ( tprlo_type = = FC_TPR_LOGO ) {
tprlo - > tprlo_params [ page ] . tpo_nport_valid = 1 ;
tprlo - > tprlo_params [ page ] . tpo_nport_id = ( tpr_id ) ;
}
}
2010-10-19 04:10:50 +04:00
return be16_to_cpu ( tprlo - > payload_len ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_tprlo_rsp_parse ( struct fchs_s * fchs , int len )
{
struct fc_tprlo_acc_s * tprlo = ( struct fc_tprlo_acc_s * ) ( fchs + 1 ) ;
int num_pages = 0 ;
int page = 0 ;
len = len ;
if ( tprlo - > command ! = FC_ELS_ACC )
2009-09-25 23:29:54 +04:00
return FC_PARSE_ACC_INVAL ;
2009-09-24 04:46:15 +04:00
2010-10-19 04:10:50 +04:00
num_pages = ( be16_to_cpu ( tprlo - > payload_len ) - 4 ) / 16 ;
2009-09-24 04:46:15 +04:00
for ( page = 0 ; page < num_pages ; page + + ) {
if ( tprlo - > tprlo_acc_params [ page ] . type ! = FC_TYPE_FCP )
2009-09-25 23:29:54 +04:00
return FC_PARSE_NOT_FCP ;
2009-09-24 04:46:15 +04:00
if ( tprlo - > tprlo_acc_params [ page ] . opa_valid ! = 0 )
2009-09-25 23:29:54 +04:00
return FC_PARSE_OPAFLAG_INVAL ;
2009-09-24 04:46:15 +04:00
if ( tprlo - > tprlo_acc_params [ page ] . rpa_valid ! = 0 )
2009-09-25 23:29:54 +04:00
return FC_PARSE_RPAFLAG_INVAL ;
2009-09-24 04:46:15 +04:00
if ( tprlo - > tprlo_acc_params [ page ] . orig_process_assc ! = 0 )
2009-09-25 23:29:54 +04:00
return FC_PARSE_OPA_INVAL ;
2009-09-24 04:46:15 +04:00
if ( tprlo - > tprlo_acc_params [ page ] . resp_process_assc ! = 0 )
2009-09-25 23:29:54 +04:00
return FC_PARSE_RPA_INVAL ;
2009-09-24 04:46:15 +04:00
}
2009-09-25 23:29:54 +04:00
return FC_PARSE_OK ;
2009-09-24 04:46:15 +04:00
}
enum fc_parse_status
fc_rrq_rsp_parse ( struct fchs_s * fchs , int len )
{
2010-09-15 22:50:55 +04:00
struct fc_els_cmd_s * els_cmd = ( struct fc_els_cmd_s * ) ( fchs + 1 ) ;
2009-09-24 04:46:15 +04:00
len = len ;
if ( els_cmd - > els_code ! = FC_ELS_ACC )
return FC_PARSE_FAILURE ;
return FC_PARSE_OK ;
}
u16
2010-11-30 05:26:32 +03:00
fc_ba_rjt_build ( struct fchs_s * fchs , u32 d_id , u32 s_id , __be16 ox_id ,
2010-09-15 22:50:55 +04:00
u32 reason_code , u32 reason_expl )
2009-09-24 04:46:15 +04:00
{
2010-09-15 22:50:55 +04:00
struct fc_ba_rjt_s * ba_rjt = ( struct fc_ba_rjt_s * ) ( fchs + 1 ) ;
2009-09-24 04:46:15 +04:00
fc_bls_rsp_build ( fchs , d_id , s_id , ox_id ) ;
fchs - > cat_info = FC_CAT_BA_RJT ;
ba_rjt - > reason_code = reason_code ;
ba_rjt - > reason_expl = reason_expl ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_ba_rjt_s ) ;
2009-09-24 04:46:15 +04:00
}
static void
fc_gs_cthdr_build ( struct ct_hdr_s * cthdr , u32 s_id , u16 cmd_code )
{
2010-10-19 04:08:54 +04:00
memset ( cthdr , 0 , sizeof ( struct ct_hdr_s ) ) ;
2009-09-24 04:46:15 +04:00
cthdr - > rev_id = CT_GS3_REVISION ;
cthdr - > gs_type = CT_GSTYPE_DIRSERVICE ;
cthdr - > gs_sub_type = CT_GSSUBTYPE_NAMESERVER ;
2010-10-19 04:10:50 +04:00
cthdr - > cmd_rsp_code = cpu_to_be16 ( cmd_code ) ;
2009-09-24 04:46:15 +04:00
}
static void
fc_gs_fdmi_cthdr_build ( struct ct_hdr_s * cthdr , u32 s_id , u16 cmd_code )
{
2010-10-19 04:08:54 +04:00
memset ( cthdr , 0 , sizeof ( struct ct_hdr_s ) ) ;
2009-09-24 04:46:15 +04:00
cthdr - > rev_id = CT_GS3_REVISION ;
cthdr - > gs_type = CT_GSTYPE_MGMTSERVICE ;
cthdr - > gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER ;
2010-10-19 04:10:50 +04:00
cthdr - > cmd_rsp_code = cpu_to_be16 ( cmd_code ) ;
2009-09-24 04:46:15 +04:00
}
static void
fc_gs_ms_cthdr_build ( struct ct_hdr_s * cthdr , u32 s_id , u16 cmd_code ,
u8 sub_type )
{
2010-10-19 04:08:54 +04:00
memset ( cthdr , 0 , sizeof ( struct ct_hdr_s ) ) ;
2009-09-24 04:46:15 +04:00
cthdr - > rev_id = CT_GS3_REVISION ;
cthdr - > gs_type = CT_GSTYPE_MGMTSERVICE ;
cthdr - > gs_sub_type = sub_type ;
2010-10-19 04:10:50 +04:00
cthdr - > cmd_rsp_code = cpu_to_be16 ( cmd_code ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_gidpn_build ( struct fchs_s * fchs , void * pyld , u32 s_id , u16 ox_id ,
wwn_t port_name )
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
struct fcgs_gidpn_req_s * gidpn = ( struct fcgs_gidpn_req_s * ) ( cthdr + 1 ) ;
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_NAME_SERVER ) ;
2009-09-24 04:46:15 +04:00
fc_gs_fchdr_build ( fchs , d_id , s_id , ox_id ) ;
fc_gs_cthdr_build ( cthdr , s_id , GS_GID_PN ) ;
2010-10-19 04:08:54 +04:00
memset ( gidpn , 0 , sizeof ( struct fcgs_gidpn_req_s ) ) ;
2009-09-24 04:46:15 +04:00
gidpn - > port_name = port_name ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fcgs_gidpn_req_s ) + sizeof ( struct ct_hdr_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_gpnid_build ( struct fchs_s * fchs , void * pyld , u32 s_id , u16 ox_id ,
u32 port_id )
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
2009-09-24 04:46:15 +04:00
fcgs_gpnid_req_t * gpnid = ( fcgs_gpnid_req_t * ) ( cthdr + 1 ) ;
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_NAME_SERVER ) ;
2009-09-24 04:46:15 +04:00
fc_gs_fchdr_build ( fchs , d_id , s_id , ox_id ) ;
fc_gs_cthdr_build ( cthdr , s_id , GS_GPN_ID ) ;
2010-10-19 04:08:54 +04:00
memset ( gpnid , 0 , sizeof ( fcgs_gpnid_req_t ) ) ;
2009-09-24 04:46:15 +04:00
gpnid - > dap = port_id ;
2009-09-25 23:29:54 +04:00
return sizeof ( fcgs_gpnid_req_t ) + sizeof ( struct ct_hdr_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_gnnid_build ( struct fchs_s * fchs , void * pyld , u32 s_id , u16 ox_id ,
u32 port_id )
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
2009-09-24 04:46:15 +04:00
fcgs_gnnid_req_t * gnnid = ( fcgs_gnnid_req_t * ) ( cthdr + 1 ) ;
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_NAME_SERVER ) ;
2009-09-24 04:46:15 +04:00
fc_gs_fchdr_build ( fchs , d_id , s_id , ox_id ) ;
fc_gs_cthdr_build ( cthdr , s_id , GS_GNN_ID ) ;
2010-10-19 04:08:54 +04:00
memset ( gnnid , 0 , sizeof ( fcgs_gnnid_req_t ) ) ;
2009-09-24 04:46:15 +04:00
gnnid - > dap = port_id ;
2009-09-25 23:29:54 +04:00
return sizeof ( fcgs_gnnid_req_t ) + sizeof ( struct ct_hdr_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_ct_rsp_parse ( struct ct_hdr_s * cthdr )
{
2010-10-19 04:10:50 +04:00
if ( be16_to_cpu ( cthdr - > cmd_rsp_code ) ! = CT_RSP_ACCEPT ) {
2009-09-24 04:46:15 +04:00
if ( cthdr - > reason_code = = CT_RSN_LOGICAL_BUSY )
return FC_PARSE_BUSY ;
else
return FC_PARSE_FAILURE ;
}
return FC_PARSE_OK ;
}
2011-06-25 07:24:52 +04:00
u16
fc_gs_rjt_build ( struct fchs_s * fchs , struct ct_hdr_s * cthdr ,
u32 d_id , u32 s_id , u16 ox_id , u8 reason_code ,
u8 reason_code_expl )
{
fc_gsresp_fchdr_build ( fchs , d_id , s_id , ox_id ) ;
cthdr - > cmd_rsp_code = cpu_to_be16 ( CT_RSP_REJECT ) ;
cthdr - > rev_id = CT_GS3_REVISION ;
cthdr - > reason_code = reason_code ;
cthdr - > exp_code = reason_code_expl ;
return sizeof ( struct ct_hdr_s ) ;
}
2009-09-24 04:46:15 +04:00
u16
2010-09-15 22:50:55 +04:00
fc_scr_build ( struct fchs_s * fchs , struct fc_scr_s * scr ,
u8 set_br_reg , u32 s_id , u16 ox_id )
2009-09-24 04:46:15 +04:00
{
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_FABRIC_CONTROLLER ) ;
2009-09-24 04:46:15 +04:00
fc_els_req_build ( fchs , d_id , s_id , ox_id ) ;
2010-10-19 04:08:54 +04:00
memset ( scr , 0 , sizeof ( struct fc_scr_s ) ) ;
2009-09-24 04:46:15 +04:00
scr - > command = FC_ELS_SCR ;
scr - > reg_func = FC_SCR_REG_FUNC_FULL ;
if ( set_br_reg )
scr - > vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_scr_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
2010-09-15 22:50:55 +04:00
fc_rscn_build ( struct fchs_s * fchs , struct fc_rscn_pl_s * rscn ,
u32 s_id , u16 ox_id )
2009-09-24 04:46:15 +04:00
{
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_FABRIC_CONTROLLER ) ;
2009-09-24 04:46:15 +04:00
u16 payldlen ;
fc_els_req_build ( fchs , d_id , s_id , ox_id ) ;
rscn - > command = FC_ELS_RSCN ;
rscn - > pagelen = sizeof ( rscn - > event [ 0 ] ) ;
payldlen = sizeof ( u32 ) + rscn - > pagelen ;
2010-10-19 04:10:50 +04:00
rscn - > payldlen = cpu_to_be16 ( payldlen ) ;
2009-09-24 04:46:15 +04:00
rscn - > event [ 0 ] . format = FC_RSCN_FORMAT_PORTID ;
rscn - > event [ 0 ] . portid = s_id ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fc_rscn_pl_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_rftid_build ( struct fchs_s * fchs , void * pyld , u32 s_id , u16 ox_id ,
2010-09-15 22:50:55 +04:00
enum bfa_lport_role roles )
2009-09-24 04:46:15 +04:00
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
struct fcgs_rftid_req_s * rftid = ( struct fcgs_rftid_req_s * ) ( cthdr + 1 ) ;
2010-12-10 06:12:32 +03:00
u32 type_value , d_id = bfa_hton3b ( FC_NAME_SERVER ) ;
2009-09-24 04:46:15 +04:00
u8 index ;
fc_gs_fchdr_build ( fchs , d_id , s_id , ox_id ) ;
fc_gs_cthdr_build ( cthdr , s_id , GS_RFT_ID ) ;
2010-10-19 04:08:54 +04:00
memset ( rftid , 0 , sizeof ( struct fcgs_rftid_req_s ) ) ;
2009-09-24 04:46:15 +04:00
rftid - > dap = s_id ;
/* By default, FCP FC4 Type is registered */
index = FC_TYPE_FCP > > 5 ;
type_value = 1 < < ( FC_TYPE_FCP % 32 ) ;
2010-10-19 04:10:50 +04:00
rftid - > fc4_type [ index ] = cpu_to_be32 ( type_value ) ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return sizeof ( struct fcgs_rftid_req_s ) + sizeof ( struct ct_hdr_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
2010-09-15 22:50:55 +04:00
fc_rftid_build_sol ( struct fchs_s * fchs , void * pyld , u32 s_id , u16 ox_id ,
u8 * fc4_bitmap , u32 bitmap_size )
2009-09-24 04:46:15 +04:00
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
struct fcgs_rftid_req_s * rftid = ( struct fcgs_rftid_req_s * ) ( cthdr + 1 ) ;
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_NAME_SERVER ) ;
2009-09-24 04:46:15 +04:00
fc_gs_fchdr_build ( fchs , d_id , s_id , ox_id ) ;
fc_gs_cthdr_build ( cthdr , s_id , GS_RFT_ID ) ;
2010-10-19 04:08:54 +04:00
memset ( rftid , 0 , sizeof ( struct fcgs_rftid_req_s ) ) ;
2009-09-24 04:46:15 +04:00
rftid - > dap = s_id ;
2010-10-19 04:08:54 +04:00
memcpy ( ( void * ) rftid - > fc4_type , ( void * ) fc4_bitmap ,
2010-09-15 22:50:55 +04:00
( bitmap_size < 32 ? bitmap_size : 32 ) ) ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return sizeof ( struct fcgs_rftid_req_s ) + sizeof ( struct ct_hdr_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_rffid_build ( struct fchs_s * fchs , void * pyld , u32 s_id , u16 ox_id ,
u8 fc4_type , u8 fc4_ftrs )
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
struct fcgs_rffid_req_s * rffid = ( struct fcgs_rffid_req_s * ) ( cthdr + 1 ) ;
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_NAME_SERVER ) ;
2009-09-24 04:46:15 +04:00
fc_gs_fchdr_build ( fchs , d_id , s_id , ox_id ) ;
fc_gs_cthdr_build ( cthdr , s_id , GS_RFF_ID ) ;
2010-10-19 04:08:54 +04:00
memset ( rffid , 0 , sizeof ( struct fcgs_rffid_req_s ) ) ;
2009-09-24 04:46:15 +04:00
2010-09-15 22:50:55 +04:00
rffid - > dap = s_id ;
2009-09-24 04:46:15 +04:00
rffid - > fc4ftr_bits = fc4_ftrs ;
2010-09-15 22:50:55 +04:00
rffid - > fc4_type = fc4_type ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return sizeof ( struct fcgs_rffid_req_s ) + sizeof ( struct ct_hdr_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_rspnid_build ( struct fchs_s * fchs , void * pyld , u32 s_id , u16 ox_id ,
u8 * name )
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
2009-09-24 04:46:15 +04:00
struct fcgs_rspnid_req_s * rspnid =
2010-09-15 22:50:55 +04:00
( struct fcgs_rspnid_req_s * ) ( cthdr + 1 ) ;
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_NAME_SERVER ) ;
2009-09-24 04:46:15 +04:00
fc_gs_fchdr_build ( fchs , d_id , s_id , ox_id ) ;
fc_gs_cthdr_build ( cthdr , s_id , GS_RSPN_ID ) ;
2010-10-19 04:08:54 +04:00
memset ( rspnid , 0 , sizeof ( struct fcgs_rspnid_req_s ) ) ;
2009-09-24 04:46:15 +04:00
rspnid - > dap = s_id ;
2017-12-04 17:47:00 +03:00
strlcpy ( rspnid - > spn , name , sizeof ( rspnid - > spn ) ) ;
rspnid - > spn_len = ( u8 ) strlen ( rspnid - > spn ) ;
2009-09-24 04:46:15 +04:00
2009-09-25 23:29:54 +04:00
return sizeof ( struct fcgs_rspnid_req_s ) + sizeof ( struct ct_hdr_s ) ;
2009-09-24 04:46:15 +04:00
}
2012-08-23 06:52:43 +04:00
u16
fc_rsnn_nn_build ( struct fchs_s * fchs , void * pyld , u32 s_id ,
wwn_t node_name , u8 * name )
{
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
struct fcgs_rsnn_nn_req_s * rsnn_nn =
( struct fcgs_rsnn_nn_req_s * ) ( cthdr + 1 ) ;
u32 d_id = bfa_hton3b ( FC_NAME_SERVER ) ;
fc_gs_fchdr_build ( fchs , d_id , s_id , 0 ) ;
fc_gs_cthdr_build ( cthdr , s_id , GS_RSNN_NN ) ;
memset ( rsnn_nn , 0 , sizeof ( struct fcgs_rsnn_nn_req_s ) ) ;
rsnn_nn - > node_name = node_name ;
2017-12-04 17:47:00 +03:00
strlcpy ( rsnn_nn - > snn , name , sizeof ( rsnn_nn - > snn ) ) ;
rsnn_nn - > snn_len = ( u8 ) strlen ( rsnn_nn - > snn ) ;
2012-08-23 06:52:43 +04:00
return sizeof ( struct fcgs_rsnn_nn_req_s ) + sizeof ( struct ct_hdr_s ) ;
}
2009-09-24 04:46:15 +04:00
u16
2010-09-15 22:50:55 +04:00
fc_gid_ft_build ( struct fchs_s * fchs , void * pyld , u32 s_id , u8 fc4_type )
2009-09-24 04:46:15 +04:00
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
struct fcgs_gidft_req_s * gidft = ( struct fcgs_gidft_req_s * ) ( cthdr + 1 ) ;
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_NAME_SERVER ) ;
2009-09-24 04:46:15 +04:00
fc_gs_fchdr_build ( fchs , d_id , s_id , 0 ) ;
fc_gs_cthdr_build ( cthdr , s_id , GS_GID_FT ) ;
2010-10-19 04:08:54 +04:00
memset ( gidft , 0 , sizeof ( struct fcgs_gidft_req_s ) ) ;
2009-09-24 04:46:15 +04:00
gidft - > fc4_type = fc4_type ;
gidft - > domain_id = 0 ;
gidft - > area_id = 0 ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fcgs_gidft_req_s ) + sizeof ( struct ct_hdr_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_rpnid_build ( struct fchs_s * fchs , void * pyld , u32 s_id , u32 port_id ,
wwn_t port_name )
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
struct fcgs_rpnid_req_s * rpnid = ( struct fcgs_rpnid_req_s * ) ( cthdr + 1 ) ;
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_NAME_SERVER ) ;
2009-09-24 04:46:15 +04:00
fc_gs_fchdr_build ( fchs , d_id , s_id , 0 ) ;
fc_gs_cthdr_build ( cthdr , s_id , GS_RPN_ID ) ;
2010-10-19 04:08:54 +04:00
memset ( rpnid , 0 , sizeof ( struct fcgs_rpnid_req_s ) ) ;
2009-09-24 04:46:15 +04:00
rpnid - > port_id = port_id ;
rpnid - > port_name = port_name ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fcgs_rpnid_req_s ) + sizeof ( struct ct_hdr_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_rnnid_build ( struct fchs_s * fchs , void * pyld , u32 s_id , u32 port_id ,
wwn_t node_name )
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
struct fcgs_rnnid_req_s * rnnid = ( struct fcgs_rnnid_req_s * ) ( cthdr + 1 ) ;
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_NAME_SERVER ) ;
2009-09-24 04:46:15 +04:00
fc_gs_fchdr_build ( fchs , d_id , s_id , 0 ) ;
fc_gs_cthdr_build ( cthdr , s_id , GS_RNN_ID ) ;
2010-10-19 04:08:54 +04:00
memset ( rnnid , 0 , sizeof ( struct fcgs_rnnid_req_s ) ) ;
2009-09-24 04:46:15 +04:00
rnnid - > port_id = port_id ;
rnnid - > node_name = node_name ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fcgs_rnnid_req_s ) + sizeof ( struct ct_hdr_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_rcsid_build ( struct fchs_s * fchs , void * pyld , u32 s_id , u32 port_id ,
u32 cos )
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
2009-09-24 04:46:15 +04:00
struct fcgs_rcsid_req_s * rcsid =
( struct fcgs_rcsid_req_s * ) ( cthdr + 1 ) ;
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_NAME_SERVER ) ;
2009-09-24 04:46:15 +04:00
fc_gs_fchdr_build ( fchs , d_id , s_id , 0 ) ;
fc_gs_cthdr_build ( cthdr , s_id , GS_RCS_ID ) ;
2010-10-19 04:08:54 +04:00
memset ( rcsid , 0 , sizeof ( struct fcgs_rcsid_req_s ) ) ;
2009-09-24 04:46:15 +04:00
rcsid - > port_id = port_id ;
rcsid - > cos = cos ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fcgs_rcsid_req_s ) + sizeof ( struct ct_hdr_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_rptid_build ( struct fchs_s * fchs , void * pyld , u32 s_id , u32 port_id ,
u8 port_type )
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
struct fcgs_rptid_req_s * rptid = ( struct fcgs_rptid_req_s * ) ( cthdr + 1 ) ;
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_NAME_SERVER ) ;
2009-09-24 04:46:15 +04:00
fc_gs_fchdr_build ( fchs , d_id , s_id , 0 ) ;
fc_gs_cthdr_build ( cthdr , s_id , GS_RPT_ID ) ;
2010-10-19 04:08:54 +04:00
memset ( rptid , 0 , sizeof ( struct fcgs_rptid_req_s ) ) ;
2009-09-24 04:46:15 +04:00
rptid - > port_id = port_id ;
rptid - > port_type = port_type ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct fcgs_rptid_req_s ) + sizeof ( struct ct_hdr_s ) ;
2009-09-24 04:46:15 +04:00
}
u16
fc_ganxt_build ( struct fchs_s * fchs , void * pyld , u32 s_id , u32 port_id )
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
struct fcgs_ganxt_req_s * ganxt = ( struct fcgs_ganxt_req_s * ) ( cthdr + 1 ) ;
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_NAME_SERVER ) ;
2009-09-24 04:46:15 +04:00
fc_gs_fchdr_build ( fchs , d_id , s_id , 0 ) ;
fc_gs_cthdr_build ( cthdr , s_id , GS_GA_NXT ) ;
2010-10-19 04:08:54 +04:00
memset ( ganxt , 0 , sizeof ( struct fcgs_ganxt_req_s ) ) ;
2009-09-24 04:46:15 +04:00
ganxt - > port_id = port_id ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct ct_hdr_s ) + sizeof ( struct fcgs_ganxt_req_s ) ;
2009-09-24 04:46:15 +04:00
}
/*
* Builds fc hdr and ct hdr for FDMI requests .
*/
u16
fc_fdmi_reqhdr_build ( struct fchs_s * fchs , void * pyld , u32 s_id ,
u16 cmd_code )
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_MGMT_SERVER ) ;
2009-09-24 04:46:15 +04:00
fc_gs_fchdr_build ( fchs , d_id , s_id , 0 ) ;
fc_gs_fdmi_cthdr_build ( cthdr , s_id , cmd_code ) ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct ct_hdr_s ) ;
2009-09-24 04:46:15 +04:00
}
/*
* Given a FC4 Type , this function returns a fc4 type bitmask
*/
void
fc_get_fc4type_bitmask ( u8 fc4_type , u8 * bit_mask )
{
u8 index ;
2010-11-30 05:26:32 +03:00
__be32 * ptr = ( __be32 * ) bit_mask ;
2009-09-24 04:46:15 +04:00
u32 type_value ;
/*
* @ todo : Check for bitmask size
*/
index = fc4_type > > 5 ;
type_value = 1 < < ( fc4_type % 32 ) ;
2010-10-19 04:10:50 +04:00
ptr [ index ] = cpu_to_be32 ( type_value ) ;
2009-09-24 04:46:15 +04:00
}
/*
2010-09-15 22:50:55 +04:00
* GMAL Request
2009-09-24 04:46:15 +04:00
*/
u16
fc_gmal_req_build ( struct fchs_s * fchs , void * pyld , u32 s_id , wwn_t wwn )
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
2009-09-24 04:46:15 +04:00
fcgs_gmal_req_t * gmal = ( fcgs_gmal_req_t * ) ( cthdr + 1 ) ;
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_MGMT_SERVER ) ;
2009-09-24 04:46:15 +04:00
fc_gs_fchdr_build ( fchs , d_id , s_id , 0 ) ;
fc_gs_ms_cthdr_build ( cthdr , s_id , GS_FC_GMAL_CMD ,
CT_GSSUBTYPE_CFGSERVER ) ;
2010-10-19 04:08:54 +04:00
memset ( gmal , 0 , sizeof ( fcgs_gmal_req_t ) ) ;
2009-09-24 04:46:15 +04:00
gmal - > wwn = wwn ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct ct_hdr_s ) + sizeof ( fcgs_gmal_req_t ) ;
2009-09-24 04:46:15 +04:00
}
/*
* GFN ( Get Fabric Name ) Request
*/
u16
fc_gfn_req_build ( struct fchs_s * fchs , void * pyld , u32 s_id , wwn_t wwn )
{
2010-09-15 22:50:55 +04:00
struct ct_hdr_s * cthdr = ( struct ct_hdr_s * ) pyld ;
2009-09-24 04:46:15 +04:00
fcgs_gfn_req_t * gfn = ( fcgs_gfn_req_t * ) ( cthdr + 1 ) ;
2010-12-10 06:12:32 +03:00
u32 d_id = bfa_hton3b ( FC_MGMT_SERVER ) ;
2009-09-24 04:46:15 +04:00
fc_gs_fchdr_build ( fchs , d_id , s_id , 0 ) ;
fc_gs_ms_cthdr_build ( cthdr , s_id , GS_FC_GFN_CMD ,
CT_GSSUBTYPE_CFGSERVER ) ;
2010-10-19 04:08:54 +04:00
memset ( gfn , 0 , sizeof ( fcgs_gfn_req_t ) ) ;
2009-09-24 04:46:15 +04:00
gfn - > wwn = wwn ;
2009-09-25 23:29:54 +04:00
return sizeof ( struct ct_hdr_s ) + sizeof ( fcgs_gfn_req_t ) ;
2009-09-24 04:46:15 +04:00
}