2010-09-15 22:50:55 +04:00
/*
* Copyright ( c ) 2005 - 2010 Brocade Communications Systems , Inc .
* All rights reserved
* www . brocade . com
*
* Linux driver for Brocade Fibre Channel Host Bus Adapter .
*
* 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 .
*/
2010-12-10 06:12:32 +03:00
# include "bfad_drv.h"
2011-07-21 03:59:13 +04:00
# include "bfad_im.h"
2010-09-15 22:50:55 +04:00
# include "bfa_plog.h"
# include "bfa_cs.h"
# include "bfa_modules.h"
BFA_TRC_FILE ( HAL , FCXP ) ;
2011-06-25 07:28:17 +04:00
BFA_MODULE ( fcdiag ) ;
2010-09-15 22:50:55 +04:00
BFA_MODULE ( fcxp ) ;
BFA_MODULE ( sgpg ) ;
BFA_MODULE ( lps ) ;
BFA_MODULE ( fcport ) ;
BFA_MODULE ( rport ) ;
BFA_MODULE ( uf ) ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* LPS related definitions
*/
# define BFA_LPS_MIN_LPORTS (1)
# define BFA_LPS_MAX_LPORTS (256)
/*
* Maximum Vports supported per physical port or vf .
*/
# define BFA_LPS_MAX_VPORTS_SUPP_CB 255
# define BFA_LPS_MAX_VPORTS_SUPP_CT 190
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* FC PORT related definitions
*/
/*
* The port is considered disabled if corresponding physical port or IOC are
* disabled explicitly
*/
# define BFA_PORT_IS_DISABLED(bfa) \
( ( bfa_fcport_is_disabled ( bfa ) = = BFA_TRUE ) | | \
( bfa_ioc_is_disabled ( & bfa - > ioc ) = = BFA_TRUE ) )
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* BFA port state machine events
*/
enum bfa_fcport_sm_event {
BFA_FCPORT_SM_START = 1 , /* start port state machine */
BFA_FCPORT_SM_STOP = 2 , /* stop port state machine */
BFA_FCPORT_SM_ENABLE = 3 , /* enable port */
BFA_FCPORT_SM_DISABLE = 4 , /* disable port state machine */
BFA_FCPORT_SM_FWRSP = 5 , /* firmware enable/disable rsp */
BFA_FCPORT_SM_LINKUP = 6 , /* firmware linkup event */
BFA_FCPORT_SM_LINKDOWN = 7 , /* firmware linkup down */
BFA_FCPORT_SM_QRESUME = 8 , /* CQ space available */
BFA_FCPORT_SM_HWFAIL = 9 , /* IOC h/w failure */
2012-09-22 04:26:07 +04:00
BFA_FCPORT_SM_DPORTENABLE = 10 , /* enable dport */
BFA_FCPORT_SM_DPORTDISABLE = 11 , /* disable dport */
2012-09-22 04:26:18 +04:00
BFA_FCPORT_SM_FAA_MISCONFIG = 12 , /* FAA misconfiguratin */
2013-05-13 13:33:21 +04:00
BFA_FCPORT_SM_DDPORTENABLE = 13 , /* enable ddport */
BFA_FCPORT_SM_DDPORTDISABLE = 14 , /* disable ddport */
2010-09-15 22:50:55 +04:00
} ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* BFA port link notification state machine events
*/
enum bfa_fcport_ln_sm_event {
BFA_FCPORT_LN_SM_LINKUP = 1 , /* linkup event */
BFA_FCPORT_LN_SM_LINKDOWN = 2 , /* linkdown event */
BFA_FCPORT_LN_SM_NOTIFICATION = 3 /* done notification */
} ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* RPORT related definitions
*/
# define bfa_rport_offline_cb(__rp) do { \
if ( ( __rp ) - > bfa - > fcs ) \
bfa_cb_rport_offline ( ( __rp ) - > rport_drv ) ; \
else { \
bfa_cb_queue ( ( __rp ) - > bfa , & ( __rp ) - > hcb_qe , \
__bfa_cb_rport_offline , ( __rp ) ) ; \
} \
} while ( 0 )
# define bfa_rport_online_cb(__rp) do { \
if ( ( __rp ) - > bfa - > fcs ) \
bfa_cb_rport_online ( ( __rp ) - > rport_drv ) ; \
else { \
bfa_cb_queue ( ( __rp ) - > bfa , & ( __rp ) - > hcb_qe , \
__bfa_cb_rport_online , ( __rp ) ) ; \
} \
} while ( 0 )
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* forward declarations FCXP related functions
*/
static void __bfa_fcxp_send_cbfn ( void * cbarg , bfa_boolean_t complete ) ;
static void hal_fcxp_rx_plog ( struct bfa_s * bfa , struct bfa_fcxp_s * fcxp ,
struct bfi_fcxp_send_rsp_s * fcxp_rsp ) ;
static void hal_fcxp_tx_plog ( struct bfa_s * bfa , u32 reqlen ,
struct bfa_fcxp_s * fcxp , struct fchs_s * fchs ) ;
static void bfa_fcxp_qresume ( void * cbarg ) ;
static void bfa_fcxp_queue ( struct bfa_fcxp_s * fcxp ,
struct bfi_fcxp_send_req_s * send_req ) ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* forward declarations for LPS functions
*/
2011-06-25 07:24:29 +04:00
static void bfa_lps_meminfo ( struct bfa_iocfc_cfg_s * cfg ,
struct bfa_meminfo_s * minfo , struct bfa_s * bfa ) ;
2010-09-15 22:50:55 +04:00
static void bfa_lps_attach ( struct bfa_s * bfa , void * bfad ,
struct bfa_iocfc_cfg_s * cfg ,
struct bfa_pcidev_s * pcidev ) ;
static void bfa_lps_detach ( struct bfa_s * bfa ) ;
static void bfa_lps_start ( struct bfa_s * bfa ) ;
static void bfa_lps_stop ( struct bfa_s * bfa ) ;
static void bfa_lps_iocdisable ( struct bfa_s * bfa ) ;
static void bfa_lps_login_rsp ( struct bfa_s * bfa ,
struct bfi_lps_login_rsp_s * rsp ) ;
2011-06-25 07:24:08 +04:00
static void bfa_lps_no_res ( struct bfa_lps_s * first_lps , u8 count ) ;
2010-09-15 22:50:55 +04:00
static void bfa_lps_logout_rsp ( struct bfa_s * bfa ,
struct bfi_lps_logout_rsp_s * rsp ) ;
static void bfa_lps_reqq_resume ( void * lps_arg ) ;
static void bfa_lps_free ( struct bfa_lps_s * lps ) ;
static void bfa_lps_send_login ( struct bfa_lps_s * lps ) ;
static void bfa_lps_send_logout ( struct bfa_lps_s * lps ) ;
2010-12-14 03:17:42 +03:00
static void bfa_lps_send_set_n2n_pid ( struct bfa_lps_s * lps ) ;
2010-09-15 22:50:55 +04:00
static void bfa_lps_login_comp ( struct bfa_lps_s * lps ) ;
static void bfa_lps_logout_comp ( struct bfa_lps_s * lps ) ;
static void bfa_lps_cvl_event ( struct bfa_lps_s * lps ) ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* forward declaration for LPS state machine
*/
static void bfa_lps_sm_init ( struct bfa_lps_s * lps , enum bfa_lps_event event ) ;
static void bfa_lps_sm_login ( struct bfa_lps_s * lps , enum bfa_lps_event event ) ;
static void bfa_lps_sm_loginwait ( struct bfa_lps_s * lps , enum bfa_lps_event
event ) ;
static void bfa_lps_sm_online ( struct bfa_lps_s * lps , enum bfa_lps_event event ) ;
2010-12-14 03:17:42 +03:00
static void bfa_lps_sm_online_n2n_pid_wait ( struct bfa_lps_s * lps ,
enum bfa_lps_event event ) ;
2010-09-15 22:50:55 +04:00
static void bfa_lps_sm_logout ( struct bfa_lps_s * lps , enum bfa_lps_event event ) ;
static void bfa_lps_sm_logowait ( struct bfa_lps_s * lps , enum bfa_lps_event
event ) ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* forward declaration for FC Port functions
*/
static bfa_boolean_t bfa_fcport_send_enable ( struct bfa_fcport_s * fcport ) ;
static bfa_boolean_t bfa_fcport_send_disable ( struct bfa_fcport_s * fcport ) ;
static void bfa_fcport_update_linkinfo ( struct bfa_fcport_s * fcport ) ;
static void bfa_fcport_reset_linkinfo ( struct bfa_fcport_s * fcport ) ;
static void bfa_fcport_set_wwns ( struct bfa_fcport_s * fcport ) ;
static void __bfa_cb_fcport_event ( void * cbarg , bfa_boolean_t complete ) ;
static void bfa_fcport_scn ( struct bfa_fcport_s * fcport ,
enum bfa_port_linkstate event , bfa_boolean_t trunk ) ;
static void bfa_fcport_queue_cb ( struct bfa_fcport_ln_s * ln ,
enum bfa_port_linkstate event ) ;
static void __bfa_cb_fcport_stats_clr ( void * cbarg , bfa_boolean_t complete ) ;
static void bfa_fcport_stats_get_timeout ( void * cbarg ) ;
static void bfa_fcport_stats_clr_timeout ( void * cbarg ) ;
static void bfa_trunk_iocdisable ( struct bfa_s * bfa ) ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* forward declaration for FC PORT state machine
*/
static void bfa_fcport_sm_uninit ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event ) ;
static void bfa_fcport_sm_enabling_qwait ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event ) ;
static void bfa_fcport_sm_enabling ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event ) ;
static void bfa_fcport_sm_linkdown ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event ) ;
static void bfa_fcport_sm_linkup ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event ) ;
static void bfa_fcport_sm_disabling ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event ) ;
static void bfa_fcport_sm_disabling_qwait ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event ) ;
static void bfa_fcport_sm_toggling_qwait ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event ) ;
static void bfa_fcport_sm_disabled ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event ) ;
static void bfa_fcport_sm_stopped ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event ) ;
static void bfa_fcport_sm_iocdown ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event ) ;
static void bfa_fcport_sm_iocfail ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event ) ;
2012-09-22 04:26:07 +04:00
static void bfa_fcport_sm_dport ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event ) ;
2013-05-13 13:33:21 +04:00
static void bfa_fcport_sm_ddport ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event ) ;
2012-09-22 04:26:18 +04:00
static void bfa_fcport_sm_faa_misconfig ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event ) ;
2010-09-15 22:50:55 +04:00
static void bfa_fcport_ln_sm_dn ( struct bfa_fcport_ln_s * ln ,
enum bfa_fcport_ln_sm_event event ) ;
static void bfa_fcport_ln_sm_dn_nf ( struct bfa_fcport_ln_s * ln ,
enum bfa_fcport_ln_sm_event event ) ;
static void bfa_fcport_ln_sm_dn_up_nf ( struct bfa_fcport_ln_s * ln ,
enum bfa_fcport_ln_sm_event event ) ;
static void bfa_fcport_ln_sm_up ( struct bfa_fcport_ln_s * ln ,
enum bfa_fcport_ln_sm_event event ) ;
static void bfa_fcport_ln_sm_up_nf ( struct bfa_fcport_ln_s * ln ,
enum bfa_fcport_ln_sm_event event ) ;
static void bfa_fcport_ln_sm_up_dn_nf ( struct bfa_fcport_ln_s * ln ,
enum bfa_fcport_ln_sm_event event ) ;
static void bfa_fcport_ln_sm_up_dn_up_nf ( struct bfa_fcport_ln_s * ln ,
enum bfa_fcport_ln_sm_event event ) ;
static struct bfa_sm_table_s hal_port_sm_table [ ] = {
{ BFA_SM ( bfa_fcport_sm_uninit ) , BFA_PORT_ST_UNINIT } ,
{ BFA_SM ( bfa_fcport_sm_enabling_qwait ) , BFA_PORT_ST_ENABLING_QWAIT } ,
{ BFA_SM ( bfa_fcport_sm_enabling ) , BFA_PORT_ST_ENABLING } ,
{ BFA_SM ( bfa_fcport_sm_linkdown ) , BFA_PORT_ST_LINKDOWN } ,
{ BFA_SM ( bfa_fcport_sm_linkup ) , BFA_PORT_ST_LINKUP } ,
{ BFA_SM ( bfa_fcport_sm_disabling_qwait ) , BFA_PORT_ST_DISABLING_QWAIT } ,
{ BFA_SM ( bfa_fcport_sm_toggling_qwait ) , BFA_PORT_ST_TOGGLING_QWAIT } ,
{ BFA_SM ( bfa_fcport_sm_disabling ) , BFA_PORT_ST_DISABLING } ,
{ BFA_SM ( bfa_fcport_sm_disabled ) , BFA_PORT_ST_DISABLED } ,
{ BFA_SM ( bfa_fcport_sm_stopped ) , BFA_PORT_ST_STOPPED } ,
{ BFA_SM ( bfa_fcport_sm_iocdown ) , BFA_PORT_ST_IOCDOWN } ,
{ BFA_SM ( bfa_fcport_sm_iocfail ) , BFA_PORT_ST_IOCDOWN } ,
2012-09-22 04:26:07 +04:00
{ BFA_SM ( bfa_fcport_sm_dport ) , BFA_PORT_ST_DPORT } ,
2013-05-13 13:33:21 +04:00
{ BFA_SM ( bfa_fcport_sm_ddport ) , BFA_PORT_ST_DDPORT } ,
2012-09-22 04:26:18 +04:00
{ BFA_SM ( bfa_fcport_sm_faa_misconfig ) , BFA_PORT_ST_FAA_MISCONFIG } ,
2010-09-15 22:50:55 +04:00
} ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* forward declaration for RPORT related functions
*/
static struct bfa_rport_s * bfa_rport_alloc ( struct bfa_rport_mod_s * rp_mod ) ;
static void bfa_rport_free ( struct bfa_rport_s * rport ) ;
static bfa_boolean_t bfa_rport_send_fwcreate ( struct bfa_rport_s * rp ) ;
static bfa_boolean_t bfa_rport_send_fwdelete ( struct bfa_rport_s * rp ) ;
static bfa_boolean_t bfa_rport_send_fwspeed ( struct bfa_rport_s * rp ) ;
static void __bfa_cb_rport_online ( void * cbarg ,
bfa_boolean_t complete ) ;
static void __bfa_cb_rport_offline ( void * cbarg ,
bfa_boolean_t complete ) ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* forward declaration for RPORT state machine
*/
static void bfa_rport_sm_uninit ( struct bfa_rport_s * rp ,
enum bfa_rport_event event ) ;
static void bfa_rport_sm_created ( struct bfa_rport_s * rp ,
enum bfa_rport_event event ) ;
static void bfa_rport_sm_fwcreate ( struct bfa_rport_s * rp ,
enum bfa_rport_event event ) ;
static void bfa_rport_sm_online ( struct bfa_rport_s * rp ,
enum bfa_rport_event event ) ;
static void bfa_rport_sm_fwdelete ( struct bfa_rport_s * rp ,
enum bfa_rport_event event ) ;
static void bfa_rport_sm_offline ( struct bfa_rport_s * rp ,
enum bfa_rport_event event ) ;
static void bfa_rport_sm_deleting ( struct bfa_rport_s * rp ,
enum bfa_rport_event event ) ;
static void bfa_rport_sm_offline_pending ( struct bfa_rport_s * rp ,
enum bfa_rport_event event ) ;
static void bfa_rport_sm_delete_pending ( struct bfa_rport_s * rp ,
enum bfa_rport_event event ) ;
static void bfa_rport_sm_iocdisable ( struct bfa_rport_s * rp ,
enum bfa_rport_event event ) ;
static void bfa_rport_sm_fwcreate_qfull ( struct bfa_rport_s * rp ,
enum bfa_rport_event event ) ;
static void bfa_rport_sm_fwdelete_qfull ( struct bfa_rport_s * rp ,
enum bfa_rport_event event ) ;
static void bfa_rport_sm_deleting_qfull ( struct bfa_rport_s * rp ,
enum bfa_rport_event event ) ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* PLOG related definitions
*/
static int
plkd_validate_logrec ( struct bfa_plog_rec_s * pl_rec )
{
if ( ( pl_rec - > log_type ! = BFA_PL_LOG_TYPE_INT ) & &
( pl_rec - > log_type ! = BFA_PL_LOG_TYPE_STRING ) )
return 1 ;
if ( ( pl_rec - > log_type ! = BFA_PL_LOG_TYPE_INT ) & &
( pl_rec - > log_num_ints > BFA_PL_INT_LOG_SZ ) )
return 1 ;
return 0 ;
}
2010-12-10 06:12:32 +03:00
static u64
bfa_get_log_time ( void )
{
u64 system_time = 0 ;
struct timeval tv ;
do_gettimeofday ( & tv ) ;
/* We are interested in seconds only. */
system_time = tv . tv_sec ;
return system_time ;
}
2010-09-15 22:50:55 +04:00
static void
bfa_plog_add ( struct bfa_plog_s * plog , struct bfa_plog_rec_s * pl_rec )
{
u16 tail ;
struct bfa_plog_rec_s * pl_recp ;
if ( plog - > plog_enabled = = 0 )
return ;
if ( plkd_validate_logrec ( pl_rec ) ) {
2010-12-27 08:46:35 +03:00
WARN_ON ( 1 ) ;
2010-09-15 22:50:55 +04:00
return ;
}
tail = plog - > tail ;
pl_recp = & ( plog - > plog_recs [ tail ] ) ;
2010-10-19 04:08:54 +04:00
memcpy ( pl_recp , pl_rec , sizeof ( struct bfa_plog_rec_s ) ) ;
2010-09-15 22:50:55 +04:00
2010-12-10 06:12:32 +03:00
pl_recp - > tv = bfa_get_log_time ( ) ;
2010-09-15 22:50:55 +04:00
BFA_PL_LOG_REC_INCR ( plog - > tail ) ;
if ( plog - > head = = plog - > tail )
BFA_PL_LOG_REC_INCR ( plog - > head ) ;
}
void
bfa_plog_init ( struct bfa_plog_s * plog )
{
2010-10-19 04:08:54 +04:00
memset ( ( char * ) plog , 0 , sizeof ( struct bfa_plog_s ) ) ;
2010-09-15 22:50:55 +04:00
2010-10-19 04:08:54 +04:00
memcpy ( plog - > plog_sig , BFA_PL_SIG_STR , BFA_PL_SIG_LEN ) ;
2010-09-15 22:50:55 +04:00
plog - > head = plog - > tail = 0 ;
plog - > plog_enabled = 1 ;
}
void
bfa_plog_str ( struct bfa_plog_s * plog , enum bfa_plog_mid mid ,
enum bfa_plog_eid event ,
u16 misc , char * log_str )
{
struct bfa_plog_rec_s lp ;
if ( plog - > plog_enabled ) {
2010-10-19 04:08:54 +04:00
memset ( & lp , 0 , sizeof ( struct bfa_plog_rec_s ) ) ;
2010-09-15 22:50:55 +04:00
lp . mid = mid ;
lp . eid = event ;
lp . log_type = BFA_PL_LOG_TYPE_STRING ;
lp . misc = misc ;
strncpy ( lp . log_entry . string_log , log_str ,
BFA_PL_STRING_LOG_SZ - 1 ) ;
lp . log_entry . string_log [ BFA_PL_STRING_LOG_SZ - 1 ] = ' \0 ' ;
bfa_plog_add ( plog , & lp ) ;
}
}
void
bfa_plog_intarr ( struct bfa_plog_s * plog , enum bfa_plog_mid mid ,
enum bfa_plog_eid event ,
u16 misc , u32 * intarr , u32 num_ints )
{
struct bfa_plog_rec_s lp ;
u32 i ;
if ( num_ints > BFA_PL_INT_LOG_SZ )
num_ints = BFA_PL_INT_LOG_SZ ;
if ( plog - > plog_enabled ) {
2010-10-19 04:08:54 +04:00
memset ( & lp , 0 , sizeof ( struct bfa_plog_rec_s ) ) ;
2010-09-15 22:50:55 +04:00
lp . mid = mid ;
lp . eid = event ;
lp . log_type = BFA_PL_LOG_TYPE_INT ;
lp . misc = misc ;
for ( i = 0 ; i < num_ints ; i + + )
2010-10-19 04:08:54 +04:00
lp . log_entry . int_log [ i ] = intarr [ i ] ;
2010-09-15 22:50:55 +04:00
lp . log_num_ints = ( u8 ) num_ints ;
bfa_plog_add ( plog , & lp ) ;
}
}
void
bfa_plog_fchdr ( struct bfa_plog_s * plog , enum bfa_plog_mid mid ,
enum bfa_plog_eid event ,
u16 misc , struct fchs_s * fchdr )
{
struct bfa_plog_rec_s lp ;
u32 * tmp_int = ( u32 * ) fchdr ;
u32 ints [ BFA_PL_INT_LOG_SZ ] ;
if ( plog - > plog_enabled ) {
2010-10-19 04:08:54 +04:00
memset ( & lp , 0 , sizeof ( struct bfa_plog_rec_s ) ) ;
2010-09-15 22:50:55 +04:00
ints [ 0 ] = tmp_int [ 0 ] ;
ints [ 1 ] = tmp_int [ 1 ] ;
ints [ 2 ] = tmp_int [ 4 ] ;
bfa_plog_intarr ( plog , mid , event , misc , ints , 3 ) ;
}
}
void
bfa_plog_fchdr_and_pl ( struct bfa_plog_s * plog , enum bfa_plog_mid mid ,
enum bfa_plog_eid event , u16 misc , struct fchs_s * fchdr ,
u32 pld_w0 )
{
struct bfa_plog_rec_s lp ;
u32 * tmp_int = ( u32 * ) fchdr ;
u32 ints [ BFA_PL_INT_LOG_SZ ] ;
if ( plog - > plog_enabled ) {
2010-10-19 04:08:54 +04:00
memset ( & lp , 0 , sizeof ( struct bfa_plog_rec_s ) ) ;
2010-09-15 22:50:55 +04:00
ints [ 0 ] = tmp_int [ 0 ] ;
ints [ 1 ] = tmp_int [ 1 ] ;
ints [ 2 ] = tmp_int [ 4 ] ;
ints [ 3 ] = pld_w0 ;
bfa_plog_intarr ( plog , mid , event , misc , ints , 4 ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* fcxp_pvt BFA FCXP private functions
*/
static void
2011-06-25 07:24:29 +04:00
claim_fcxps_mem ( struct bfa_fcxp_mod_s * mod )
2010-09-15 22:50:55 +04:00
{
u16 i ;
struct bfa_fcxp_s * fcxp ;
2011-06-25 07:24:29 +04:00
fcxp = ( struct bfa_fcxp_s * ) bfa_mem_kva_curp ( mod ) ;
2010-10-19 04:08:54 +04:00
memset ( fcxp , 0 , sizeof ( struct bfa_fcxp_s ) * mod - > num_fcxps ) ;
2010-09-15 22:50:55 +04:00
2012-08-23 06:51:08 +04:00
INIT_LIST_HEAD ( & mod - > fcxp_req_free_q ) ;
INIT_LIST_HEAD ( & mod - > fcxp_rsp_free_q ) ;
2010-09-15 22:50:55 +04:00
INIT_LIST_HEAD ( & mod - > fcxp_active_q ) ;
2012-08-23 06:51:08 +04:00
INIT_LIST_HEAD ( & mod - > fcxp_req_unused_q ) ;
INIT_LIST_HEAD ( & mod - > fcxp_rsp_unused_q ) ;
2010-09-15 22:50:55 +04:00
mod - > fcxp_list = fcxp ;
for ( i = 0 ; i < mod - > num_fcxps ; i + + ) {
fcxp - > fcxp_mod = mod ;
fcxp - > fcxp_tag = i ;
2012-08-23 06:51:08 +04:00
if ( i < ( mod - > num_fcxps / 2 ) ) {
list_add_tail ( & fcxp - > qe , & mod - > fcxp_req_free_q ) ;
fcxp - > req_rsp = BFA_TRUE ;
} else {
list_add_tail ( & fcxp - > qe , & mod - > fcxp_rsp_free_q ) ;
fcxp - > req_rsp = BFA_FALSE ;
}
2010-09-15 22:50:55 +04:00
bfa_reqq_winit ( & fcxp - > reqq_wqe , bfa_fcxp_qresume , fcxp ) ;
fcxp - > reqq_waiting = BFA_FALSE ;
fcxp = fcxp + 1 ;
}
2011-06-25 07:24:29 +04:00
bfa_mem_kva_curp ( mod ) = ( void * ) fcxp ;
2010-09-15 22:50:55 +04:00
}
static void
2011-06-25 07:24:29 +04:00
bfa_fcxp_meminfo ( struct bfa_iocfc_cfg_s * cfg , struct bfa_meminfo_s * minfo ,
struct bfa_s * bfa )
2010-09-15 22:50:55 +04:00
{
2011-06-25 07:24:29 +04:00
struct bfa_fcxp_mod_s * fcxp_mod = BFA_FCXP_MOD ( bfa ) ;
struct bfa_mem_kva_s * fcxp_kva = BFA_MEM_FCXP_KVA ( bfa ) ;
struct bfa_mem_dma_s * seg_ptr ;
u16 nsegs , idx , per_seg_fcxp ;
u16 num_fcxps = cfg - > fwcfg . num_fcxp_reqs ;
u32 per_fcxp_sz ;
2010-09-15 22:50:55 +04:00
2011-06-25 07:24:29 +04:00
if ( num_fcxps = = 0 )
2010-09-15 22:50:55 +04:00
return ;
if ( cfg - > drvcfg . min_cfg )
2011-06-25 07:24:29 +04:00
per_fcxp_sz = 2 * BFA_FCXP_MAX_IBUF_SZ ;
2010-09-15 22:50:55 +04:00
else
2011-06-25 07:24:29 +04:00
per_fcxp_sz = BFA_FCXP_MAX_IBUF_SZ + BFA_FCXP_MAX_LBUF_SZ ;
2010-09-15 22:50:55 +04:00
2011-06-25 07:24:29 +04:00
/* dma memory */
nsegs = BFI_MEM_DMA_NSEGS ( num_fcxps , per_fcxp_sz ) ;
per_seg_fcxp = BFI_MEM_NREQS_SEG ( per_fcxp_sz ) ;
bfa_mem_dma_seg_iter ( fcxp_mod , seg_ptr , nsegs , idx ) {
if ( num_fcxps > = per_seg_fcxp ) {
num_fcxps - = per_seg_fcxp ;
bfa_mem_dma_setup ( minfo , seg_ptr ,
per_seg_fcxp * per_fcxp_sz ) ;
} else
bfa_mem_dma_setup ( minfo , seg_ptr ,
num_fcxps * per_fcxp_sz ) ;
}
/* kva memory */
bfa_mem_kva_setup ( minfo , fcxp_kva ,
cfg - > fwcfg . num_fcxp_reqs * sizeof ( struct bfa_fcxp_s ) ) ;
2010-09-15 22:50:55 +04:00
}
static void
bfa_fcxp_attach ( struct bfa_s * bfa , void * bfad , struct bfa_iocfc_cfg_s * cfg ,
2011-06-25 07:24:29 +04:00
struct bfa_pcidev_s * pcidev )
2010-09-15 22:50:55 +04:00
{
struct bfa_fcxp_mod_s * mod = BFA_FCXP_MOD ( bfa ) ;
mod - > bfa = bfa ;
mod - > num_fcxps = cfg - > fwcfg . num_fcxp_reqs ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Initialize FCXP request and response payload sizes .
*/
mod - > req_pld_sz = mod - > rsp_pld_sz = BFA_FCXP_MAX_IBUF_SZ ;
if ( ! cfg - > drvcfg . min_cfg )
mod - > rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ ;
2012-08-23 06:51:08 +04:00
INIT_LIST_HEAD ( & mod - > req_wait_q ) ;
INIT_LIST_HEAD ( & mod - > rsp_wait_q ) ;
2010-09-15 22:50:55 +04:00
2011-06-25 07:24:29 +04:00
claim_fcxps_mem ( mod ) ;
2010-09-15 22:50:55 +04:00
}
static void
bfa_fcxp_detach ( struct bfa_s * bfa )
{
}
static void
bfa_fcxp_start ( struct bfa_s * bfa )
{
}
static void
bfa_fcxp_stop ( struct bfa_s * bfa )
{
}
static void
bfa_fcxp_iocdisable ( struct bfa_s * bfa )
{
struct bfa_fcxp_mod_s * mod = BFA_FCXP_MOD ( bfa ) ;
struct bfa_fcxp_s * fcxp ;
struct list_head * qe , * qen ;
2011-06-25 07:24:08 +04:00
/* Enqueue unused fcxp resources to free_q */
2012-08-23 06:51:08 +04:00
list_splice_tail_init ( & mod - > fcxp_req_unused_q , & mod - > fcxp_req_free_q ) ;
list_splice_tail_init ( & mod - > fcxp_rsp_unused_q , & mod - > fcxp_rsp_free_q ) ;
2011-06-25 07:24:08 +04:00
2010-09-15 22:50:55 +04:00
list_for_each_safe ( qe , qen , & mod - > fcxp_active_q ) {
fcxp = ( struct bfa_fcxp_s * ) qe ;
if ( fcxp - > caller = = NULL ) {
fcxp - > send_cbfn ( fcxp - > caller , fcxp , fcxp - > send_cbarg ,
BFA_STATUS_IOC_FAILURE , 0 , 0 , NULL ) ;
bfa_fcxp_free ( fcxp ) ;
} else {
fcxp - > rsp_status = BFA_STATUS_IOC_FAILURE ;
bfa_cb_queue ( bfa , & fcxp - > hcb_qe ,
__bfa_fcxp_send_cbfn , fcxp ) ;
}
}
}
static struct bfa_fcxp_s *
2012-08-23 06:51:08 +04:00
bfa_fcxp_get ( struct bfa_fcxp_mod_s * fm , bfa_boolean_t req )
2010-09-15 22:50:55 +04:00
{
struct bfa_fcxp_s * fcxp ;
2012-08-23 06:51:08 +04:00
if ( req )
bfa_q_deq ( & fm - > fcxp_req_free_q , & fcxp ) ;
else
bfa_q_deq ( & fm - > fcxp_rsp_free_q , & fcxp ) ;
2010-09-15 22:50:55 +04:00
if ( fcxp )
list_add_tail ( & fcxp - > qe , & fm - > fcxp_active_q ) ;
return fcxp ;
}
static void
bfa_fcxp_init_reqrsp ( struct bfa_fcxp_s * fcxp ,
struct bfa_s * bfa ,
u8 * use_ibuf ,
u32 * nr_sgles ,
bfa_fcxp_get_sgaddr_t * r_sga_cbfn ,
bfa_fcxp_get_sglen_t * r_sglen_cbfn ,
struct list_head * r_sgpg_q ,
int n_sgles ,
bfa_fcxp_get_sgaddr_t sga_cbfn ,
bfa_fcxp_get_sglen_t sglen_cbfn )
{
2010-12-27 08:46:35 +03:00
WARN_ON ( bfa = = NULL ) ;
2010-09-15 22:50:55 +04:00
bfa_trc ( bfa , fcxp - > fcxp_tag ) ;
if ( n_sgles = = 0 ) {
* use_ibuf = 1 ;
} else {
2010-12-27 08:46:35 +03:00
WARN_ON ( * sga_cbfn = = NULL ) ;
WARN_ON ( * sglen_cbfn = = NULL ) ;
2010-09-15 22:50:55 +04:00
* use_ibuf = 0 ;
* r_sga_cbfn = sga_cbfn ;
* r_sglen_cbfn = sglen_cbfn ;
* nr_sgles = n_sgles ;
/*
* alloc required sgpgs
*/
if ( n_sgles > BFI_SGE_INLINE )
2010-12-27 08:46:35 +03:00
WARN_ON ( 1 ) ;
2010-09-15 22:50:55 +04:00
}
}
static void
bfa_fcxp_init ( struct bfa_fcxp_s * fcxp ,
void * caller , struct bfa_s * bfa , int nreq_sgles ,
int nrsp_sgles , bfa_fcxp_get_sgaddr_t req_sga_cbfn ,
bfa_fcxp_get_sglen_t req_sglen_cbfn ,
bfa_fcxp_get_sgaddr_t rsp_sga_cbfn ,
bfa_fcxp_get_sglen_t rsp_sglen_cbfn )
{
2010-12-27 08:46:35 +03:00
WARN_ON ( bfa = = NULL ) ;
2010-09-15 22:50:55 +04:00
bfa_trc ( bfa , fcxp - > fcxp_tag ) ;
fcxp - > caller = caller ;
bfa_fcxp_init_reqrsp ( fcxp , bfa ,
& fcxp - > use_ireqbuf , & fcxp - > nreq_sgles , & fcxp - > req_sga_cbfn ,
& fcxp - > req_sglen_cbfn , & fcxp - > req_sgpg_q ,
nreq_sgles , req_sga_cbfn , req_sglen_cbfn ) ;
bfa_fcxp_init_reqrsp ( fcxp , bfa ,
& fcxp - > use_irspbuf , & fcxp - > nrsp_sgles , & fcxp - > rsp_sga_cbfn ,
& fcxp - > rsp_sglen_cbfn , & fcxp - > rsp_sgpg_q ,
nrsp_sgles , rsp_sga_cbfn , rsp_sglen_cbfn ) ;
}
static void
bfa_fcxp_put ( struct bfa_fcxp_s * fcxp )
{
struct bfa_fcxp_mod_s * mod = fcxp - > fcxp_mod ;
struct bfa_fcxp_wqe_s * wqe ;
2012-08-23 06:51:08 +04:00
if ( fcxp - > req_rsp )
bfa_q_deq ( & mod - > req_wait_q , & wqe ) ;
else
bfa_q_deq ( & mod - > rsp_wait_q , & wqe ) ;
2010-09-15 22:50:55 +04:00
if ( wqe ) {
bfa_trc ( mod - > bfa , fcxp - > fcxp_tag ) ;
bfa_fcxp_init ( fcxp , wqe - > caller , wqe - > bfa , wqe - > nreq_sgles ,
wqe - > nrsp_sgles , wqe - > req_sga_cbfn ,
wqe - > req_sglen_cbfn , wqe - > rsp_sga_cbfn ,
wqe - > rsp_sglen_cbfn ) ;
wqe - > alloc_cbfn ( wqe - > alloc_cbarg , fcxp ) ;
return ;
}
2010-12-27 08:46:35 +03:00
WARN_ON ( ! bfa_q_is_on_q ( & mod - > fcxp_active_q , fcxp ) ) ;
2010-09-15 22:50:55 +04:00
list_del ( & fcxp - > qe ) ;
2012-08-23 06:51:08 +04:00
if ( fcxp - > req_rsp )
list_add_tail ( & fcxp - > qe , & mod - > fcxp_req_free_q ) ;
else
list_add_tail ( & fcxp - > qe , & mod - > fcxp_rsp_free_q ) ;
2010-09-15 22:50:55 +04:00
}
static void
bfa_fcxp_null_comp ( void * bfad_fcxp , struct bfa_fcxp_s * fcxp , void * cbarg ,
bfa_status_t req_status , u32 rsp_len ,
u32 resid_len , struct fchs_s * rsp_fchs )
{
/* discarded fcxp completion */
}
static void
__bfa_fcxp_send_cbfn ( void * cbarg , bfa_boolean_t complete )
{
struct bfa_fcxp_s * fcxp = cbarg ;
if ( complete ) {
fcxp - > send_cbfn ( fcxp - > caller , fcxp , fcxp - > send_cbarg ,
fcxp - > rsp_status , fcxp - > rsp_len ,
fcxp - > residue_len , & fcxp - > rsp_fchs ) ;
} else {
bfa_fcxp_free ( fcxp ) ;
}
}
static void
hal_fcxp_send_comp ( struct bfa_s * bfa , struct bfi_fcxp_send_rsp_s * fcxp_rsp )
{
struct bfa_fcxp_mod_s * mod = BFA_FCXP_MOD ( bfa ) ;
struct bfa_fcxp_s * fcxp ;
2010-10-19 04:10:50 +04:00
u16 fcxp_tag = be16_to_cpu ( fcxp_rsp - > fcxp_tag ) ;
2010-09-15 22:50:55 +04:00
bfa_trc ( bfa , fcxp_tag ) ;
2010-10-19 04:10:50 +04:00
fcxp_rsp - > rsp_len = be32_to_cpu ( fcxp_rsp - > rsp_len ) ;
2010-09-15 22:50:55 +04:00
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* @ todo f / w should not set residue to non - 0 when everything
* is received .
*/
if ( fcxp_rsp - > req_status = = BFA_STATUS_OK )
fcxp_rsp - > residue_len = 0 ;
else
2010-10-19 04:10:50 +04:00
fcxp_rsp - > residue_len = be32_to_cpu ( fcxp_rsp - > residue_len ) ;
2010-09-15 22:50:55 +04:00
fcxp = BFA_FCXP_FROM_TAG ( mod , fcxp_tag ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( fcxp - > send_cbfn = = NULL ) ;
2010-09-15 22:50:55 +04:00
hal_fcxp_rx_plog ( mod - > bfa , fcxp , fcxp_rsp ) ;
if ( fcxp - > send_cbfn ! = NULL ) {
bfa_trc ( mod - > bfa , ( NULL = = fcxp - > caller ) ) ;
if ( fcxp - > caller = = NULL ) {
fcxp - > send_cbfn ( fcxp - > caller , fcxp , fcxp - > send_cbarg ,
fcxp_rsp - > req_status , fcxp_rsp - > rsp_len ,
fcxp_rsp - > residue_len , & fcxp_rsp - > fchs ) ;
/*
* fcxp automatically freed on return from the callback
*/
bfa_fcxp_free ( fcxp ) ;
} else {
fcxp - > rsp_status = fcxp_rsp - > req_status ;
fcxp - > rsp_len = fcxp_rsp - > rsp_len ;
fcxp - > residue_len = fcxp_rsp - > residue_len ;
fcxp - > rsp_fchs = fcxp_rsp - > fchs ;
bfa_cb_queue ( bfa , & fcxp - > hcb_qe ,
__bfa_fcxp_send_cbfn , fcxp ) ;
}
} else {
bfa_trc ( bfa , ( NULL = = fcxp - > send_cbfn ) ) ;
}
}
static void
hal_fcxp_tx_plog ( struct bfa_s * bfa , u32 reqlen , struct bfa_fcxp_s * fcxp ,
struct fchs_s * fchs )
{
/*
* TODO : TX ox_id
*/
if ( reqlen > 0 ) {
if ( fcxp - > use_ireqbuf ) {
u32 pld_w0 =
* ( ( u32 * ) BFA_FCXP_REQ_PLD ( fcxp ) ) ;
bfa_plog_fchdr_and_pl ( bfa - > plog , BFA_PL_MID_HAL_FCXP ,
BFA_PL_EID_TX ,
reqlen + sizeof ( struct fchs_s ) , fchs ,
pld_w0 ) ;
} else {
bfa_plog_fchdr ( bfa - > plog , BFA_PL_MID_HAL_FCXP ,
BFA_PL_EID_TX ,
reqlen + sizeof ( struct fchs_s ) ,
fchs ) ;
}
} else {
bfa_plog_fchdr ( bfa - > plog , BFA_PL_MID_HAL_FCXP , BFA_PL_EID_TX ,
reqlen + sizeof ( struct fchs_s ) , fchs ) ;
}
}
static void
hal_fcxp_rx_plog ( struct bfa_s * bfa , struct bfa_fcxp_s * fcxp ,
struct bfi_fcxp_send_rsp_s * fcxp_rsp )
{
if ( fcxp_rsp - > rsp_len > 0 ) {
if ( fcxp - > use_irspbuf ) {
u32 pld_w0 =
* ( ( u32 * ) BFA_FCXP_RSP_PLD ( fcxp ) ) ;
bfa_plog_fchdr_and_pl ( bfa - > plog , BFA_PL_MID_HAL_FCXP ,
BFA_PL_EID_RX ,
( u16 ) fcxp_rsp - > rsp_len ,
& fcxp_rsp - > fchs , pld_w0 ) ;
} else {
bfa_plog_fchdr ( bfa - > plog , BFA_PL_MID_HAL_FCXP ,
BFA_PL_EID_RX ,
( u16 ) fcxp_rsp - > rsp_len ,
& fcxp_rsp - > fchs ) ;
}
} else {
bfa_plog_fchdr ( bfa - > plog , BFA_PL_MID_HAL_FCXP , BFA_PL_EID_RX ,
( u16 ) fcxp_rsp - > rsp_len , & fcxp_rsp - > fchs ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Handler to resume sending fcxp when space in available in cpe queue .
*/
static void
bfa_fcxp_qresume ( void * cbarg )
{
struct bfa_fcxp_s * fcxp = cbarg ;
struct bfa_s * bfa = fcxp - > fcxp_mod - > bfa ;
struct bfi_fcxp_send_req_s * send_req ;
fcxp - > reqq_waiting = BFA_FALSE ;
send_req = bfa_reqq_next ( bfa , BFA_REQQ_FCXP ) ;
bfa_fcxp_queue ( fcxp , send_req ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Queue fcxp send request to foimrware .
*/
static void
bfa_fcxp_queue ( struct bfa_fcxp_s * fcxp , struct bfi_fcxp_send_req_s * send_req )
{
struct bfa_s * bfa = fcxp - > fcxp_mod - > bfa ;
struct bfa_fcxp_req_info_s * reqi = & fcxp - > req_info ;
struct bfa_fcxp_rsp_info_s * rspi = & fcxp - > rsp_info ;
struct bfa_rport_s * rport = reqi - > bfa_rport ;
bfi_h2i_set ( send_req - > mh , BFI_MC_FCXP , BFI_FCXP_H2I_SEND_REQ ,
2011-06-25 07:24:08 +04:00
bfa_fn_lpu ( bfa ) ) ;
2010-09-15 22:50:55 +04:00
2010-10-19 04:10:50 +04:00
send_req - > fcxp_tag = cpu_to_be16 ( fcxp - > fcxp_tag ) ;
2010-09-15 22:50:55 +04:00
if ( rport ) {
send_req - > rport_fw_hndl = rport - > fw_handle ;
2010-10-19 04:10:50 +04:00
send_req - > max_frmsz = cpu_to_be16 ( rport - > rport_info . max_frmsz ) ;
2010-09-15 22:50:55 +04:00
if ( send_req - > max_frmsz = = 0 )
2010-10-19 04:10:50 +04:00
send_req - > max_frmsz = cpu_to_be16 ( FC_MAX_PDUSZ ) ;
2010-09-15 22:50:55 +04:00
} else {
send_req - > rport_fw_hndl = 0 ;
2010-10-19 04:10:50 +04:00
send_req - > max_frmsz = cpu_to_be16 ( FC_MAX_PDUSZ ) ;
2010-09-15 22:50:55 +04:00
}
2010-10-19 04:10:50 +04:00
send_req - > vf_id = cpu_to_be16 ( reqi - > vf_id ) ;
2011-06-25 07:24:08 +04:00
send_req - > lp_fwtag = bfa_lps_get_fwtag ( bfa , reqi - > lp_tag ) ;
2010-09-15 22:50:55 +04:00
send_req - > class = reqi - > class ;
send_req - > rsp_timeout = rspi - > rsp_timeout ;
send_req - > cts = reqi - > cts ;
send_req - > fchs = reqi - > fchs ;
2010-10-19 04:10:50 +04:00
send_req - > req_len = cpu_to_be32 ( reqi - > req_tot_len ) ;
send_req - > rsp_maxlen = cpu_to_be32 ( rspi - > rsp_maxlen ) ;
2010-09-15 22:50:55 +04:00
/*
* setup req sgles
*/
if ( fcxp - > use_ireqbuf = = 1 ) {
2011-06-14 02:39:36 +04:00
bfa_alen_set ( & send_req - > req_alen , reqi - > req_tot_len ,
2010-09-15 22:50:55 +04:00
BFA_FCXP_REQ_PLD_PA ( fcxp ) ) ;
} else {
if ( fcxp - > nreq_sgles > 0 ) {
2010-12-27 08:46:35 +03:00
WARN_ON ( fcxp - > nreq_sgles ! = 1 ) ;
2011-06-14 02:39:36 +04:00
bfa_alen_set ( & send_req - > req_alen , reqi - > req_tot_len ,
fcxp - > req_sga_cbfn ( fcxp - > caller , 0 ) ) ;
2010-09-15 22:50:55 +04:00
} else {
2010-12-27 08:46:35 +03:00
WARN_ON ( reqi - > req_tot_len ! = 0 ) ;
2011-06-14 02:39:36 +04:00
bfa_alen_set ( & send_req - > rsp_alen , 0 , 0 ) ;
2010-09-15 22:50:55 +04:00
}
}
/*
* setup rsp sgles
*/
if ( fcxp - > use_irspbuf = = 1 ) {
2010-12-27 08:46:35 +03:00
WARN_ON ( rspi - > rsp_maxlen > BFA_FCXP_MAX_LBUF_SZ ) ;
2010-09-15 22:50:55 +04:00
2011-06-14 02:39:36 +04:00
bfa_alen_set ( & send_req - > rsp_alen , rspi - > rsp_maxlen ,
2010-09-15 22:50:55 +04:00
BFA_FCXP_RSP_PLD_PA ( fcxp ) ) ;
} else {
if ( fcxp - > nrsp_sgles > 0 ) {
2010-12-27 08:46:35 +03:00
WARN_ON ( fcxp - > nrsp_sgles ! = 1 ) ;
2011-06-14 02:39:36 +04:00
bfa_alen_set ( & send_req - > rsp_alen , rspi - > rsp_maxlen ,
fcxp - > rsp_sga_cbfn ( fcxp - > caller , 0 ) ) ;
2010-09-15 22:50:55 +04:00
} else {
2010-12-27 08:46:35 +03:00
WARN_ON ( rspi - > rsp_maxlen ! = 0 ) ;
2011-06-14 02:39:36 +04:00
bfa_alen_set ( & send_req - > rsp_alen , 0 , 0 ) ;
2010-09-15 22:50:55 +04:00
}
}
hal_fcxp_tx_plog ( bfa , reqi - > req_tot_len , fcxp , & reqi - > fchs ) ;
2011-06-25 07:24:08 +04:00
bfa_reqq_produce ( bfa , BFA_REQQ_FCXP , send_req - > mh ) ;
2010-09-15 22:50:55 +04:00
bfa_trc ( bfa , bfa_reqq_pi ( bfa , BFA_REQQ_FCXP ) ) ;
bfa_trc ( bfa , bfa_reqq_ci ( bfa , BFA_REQQ_FCXP ) ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Allocate an FCXP instance to send a response or to send a request
* that has a response . Request / response buffers are allocated by caller .
*
* @ param [ in ] bfa BFA bfa instance
* @ param [ in ] nreq_sgles Number of SG elements required for request
* buffer . 0 , if fcxp internal buffers are used .
* Use bfa_fcxp_get_reqbuf ( ) to get the
* internal req buffer .
* @ param [ in ] req_sgles SG elements describing request buffer . Will be
* copied in by BFA and hence can be freed on
* return from this function .
* @ param [ in ] get_req_sga function ptr to be called to get a request SG
* Address ( given the sge index ) .
* @ param [ in ] get_req_sglen function ptr to be called to get a request SG
* len ( given the sge index ) .
* @ param [ in ] get_rsp_sga function ptr to be called to get a response SG
* Address ( given the sge index ) .
* @ param [ in ] get_rsp_sglen function ptr to be called to get a response SG
* len ( given the sge index ) .
2012-08-23 06:51:08 +04:00
* @ param [ in ] req Allocated FCXP is used to send req or rsp ?
* request - BFA_TRUE , response - BFA_FALSE
2010-09-15 22:50:55 +04:00
*
* @ return FCXP instance . NULL on failure .
*/
struct bfa_fcxp_s *
2012-08-23 06:51:08 +04:00
bfa_fcxp_req_rsp_alloc ( void * caller , struct bfa_s * bfa , int nreq_sgles ,
int nrsp_sgles , bfa_fcxp_get_sgaddr_t req_sga_cbfn ,
bfa_fcxp_get_sglen_t req_sglen_cbfn ,
bfa_fcxp_get_sgaddr_t rsp_sga_cbfn ,
bfa_fcxp_get_sglen_t rsp_sglen_cbfn , bfa_boolean_t req )
2010-09-15 22:50:55 +04:00
{
struct bfa_fcxp_s * fcxp = NULL ;
2010-12-27 08:46:35 +03:00
WARN_ON ( bfa = = NULL ) ;
2010-09-15 22:50:55 +04:00
2012-08-23 06:51:08 +04:00
fcxp = bfa_fcxp_get ( BFA_FCXP_MOD ( bfa ) , req ) ;
2010-09-15 22:50:55 +04:00
if ( fcxp = = NULL )
return NULL ;
bfa_trc ( bfa , fcxp - > fcxp_tag ) ;
bfa_fcxp_init ( fcxp , caller , bfa , nreq_sgles , nrsp_sgles , req_sga_cbfn ,
req_sglen_cbfn , rsp_sga_cbfn , rsp_sglen_cbfn ) ;
return fcxp ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Get the internal request buffer pointer
*
* @ param [ in ] fcxp BFA fcxp pointer
*
* @ return pointer to the internal request buffer
*/
void *
bfa_fcxp_get_reqbuf ( struct bfa_fcxp_s * fcxp )
{
struct bfa_fcxp_mod_s * mod = fcxp - > fcxp_mod ;
void * reqbuf ;
2010-12-27 08:46:35 +03:00
WARN_ON ( fcxp - > use_ireqbuf ! = 1 ) ;
2011-06-25 07:24:29 +04:00
reqbuf = bfa_mem_get_dmabuf_kva ( mod , fcxp - > fcxp_tag ,
mod - > req_pld_sz + mod - > rsp_pld_sz ) ;
2010-09-15 22:50:55 +04:00
return reqbuf ;
}
u32
bfa_fcxp_get_reqbufsz ( struct bfa_fcxp_s * fcxp )
{
struct bfa_fcxp_mod_s * mod = fcxp - > fcxp_mod ;
return mod - > req_pld_sz ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Get the internal response buffer pointer
*
* @ param [ in ] fcxp BFA fcxp pointer
*
* @ return pointer to the internal request buffer
*/
void *
bfa_fcxp_get_rspbuf ( struct bfa_fcxp_s * fcxp )
{
struct bfa_fcxp_mod_s * mod = fcxp - > fcxp_mod ;
2011-06-25 07:24:29 +04:00
void * fcxp_buf ;
2010-09-15 22:50:55 +04:00
2010-12-27 08:46:35 +03:00
WARN_ON ( fcxp - > use_irspbuf ! = 1 ) ;
2010-09-15 22:50:55 +04:00
2011-06-25 07:24:29 +04:00
fcxp_buf = bfa_mem_get_dmabuf_kva ( mod , fcxp - > fcxp_tag ,
mod - > req_pld_sz + mod - > rsp_pld_sz ) ;
/* fcxp_buf = req_buf + rsp_buf :- add req_buf_sz to get to rsp_buf */
return ( ( u8 * ) fcxp_buf ) + mod - > req_pld_sz ;
2010-09-15 22:50:55 +04:00
}
2010-10-19 04:17:23 +04:00
/*
2010-12-10 06:13:20 +03:00
* Free the BFA FCXP
2010-09-15 22:50:55 +04:00
*
* @ param [ in ] fcxp BFA fcxp pointer
*
* @ return void
*/
void
bfa_fcxp_free ( struct bfa_fcxp_s * fcxp )
{
struct bfa_fcxp_mod_s * mod = fcxp - > fcxp_mod ;
2010-12-27 08:46:35 +03:00
WARN_ON ( fcxp = = NULL ) ;
2010-09-15 22:50:55 +04:00
bfa_trc ( mod - > bfa , fcxp - > fcxp_tag ) ;
bfa_fcxp_put ( fcxp ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Send a FCXP request
*
* @ param [ in ] fcxp BFA fcxp pointer
* @ param [ in ] rport BFA rport pointer . Could be left NULL for WKA rports
* @ param [ in ] vf_id virtual Fabric ID
* @ param [ in ] lp_tag lport tag
2011-03-31 05:57:33 +04:00
* @ param [ in ] cts use Continuous sequence
2010-09-15 22:50:55 +04:00
* @ param [ in ] cos fc Class of Service
* @ param [ in ] reqlen request length , does not include FCHS length
* @ param [ in ] fchs fc Header Pointer . The header content will be copied
* in by BFA .
*
* @ param [ in ] cbfn call back function to be called on receiving
* the response
* @ param [ in ] cbarg arg for cbfn
* @ param [ in ] rsp_timeout
* response timeout
*
* @ return bfa_status_t
*/
void
bfa_fcxp_send ( struct bfa_fcxp_s * fcxp , struct bfa_rport_s * rport ,
u16 vf_id , u8 lp_tag , bfa_boolean_t cts , enum fc_cos cos ,
u32 reqlen , struct fchs_s * fchs , bfa_cb_fcxp_send_t cbfn ,
void * cbarg , u32 rsp_maxlen , u8 rsp_timeout )
{
struct bfa_s * bfa = fcxp - > fcxp_mod - > bfa ;
struct bfa_fcxp_req_info_s * reqi = & fcxp - > req_info ;
struct bfa_fcxp_rsp_info_s * rspi = & fcxp - > rsp_info ;
struct bfi_fcxp_send_req_s * send_req ;
bfa_trc ( bfa , fcxp - > fcxp_tag ) ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* setup request / response info
*/
reqi - > bfa_rport = rport ;
reqi - > vf_id = vf_id ;
reqi - > lp_tag = lp_tag ;
reqi - > class = cos ;
rspi - > rsp_timeout = rsp_timeout ;
reqi - > cts = cts ;
reqi - > fchs = * fchs ;
reqi - > req_tot_len = reqlen ;
rspi - > rsp_maxlen = rsp_maxlen ;
fcxp - > send_cbfn = cbfn ? cbfn : bfa_fcxp_null_comp ;
fcxp - > send_cbarg = cbarg ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* If no room in CPE queue , wait for space in request queue
*/
send_req = bfa_reqq_next ( bfa , BFA_REQQ_FCXP ) ;
if ( ! send_req ) {
bfa_trc ( bfa , fcxp - > fcxp_tag ) ;
fcxp - > reqq_waiting = BFA_TRUE ;
bfa_reqq_wait ( bfa , BFA_REQQ_FCXP , & fcxp - > reqq_wqe ) ;
return ;
}
bfa_fcxp_queue ( fcxp , send_req ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Abort a BFA FCXP
*
* @ param [ in ] fcxp BFA fcxp pointer
*
* @ return void
*/
bfa_status_t
bfa_fcxp_abort ( struct bfa_fcxp_s * fcxp )
{
bfa_trc ( fcxp - > fcxp_mod - > bfa , fcxp - > fcxp_tag ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( 1 ) ;
2010-09-15 22:50:55 +04:00
return BFA_STATUS_OK ;
}
void
2012-08-23 06:51:08 +04:00
bfa_fcxp_req_rsp_alloc_wait ( struct bfa_s * bfa , struct bfa_fcxp_wqe_s * wqe ,
2010-09-15 22:50:55 +04:00
bfa_fcxp_alloc_cbfn_t alloc_cbfn , void * alloc_cbarg ,
void * caller , int nreq_sgles ,
int nrsp_sgles , bfa_fcxp_get_sgaddr_t req_sga_cbfn ,
bfa_fcxp_get_sglen_t req_sglen_cbfn ,
bfa_fcxp_get_sgaddr_t rsp_sga_cbfn ,
2012-08-23 06:51:08 +04:00
bfa_fcxp_get_sglen_t rsp_sglen_cbfn , bfa_boolean_t req )
2010-09-15 22:50:55 +04:00
{
struct bfa_fcxp_mod_s * mod = BFA_FCXP_MOD ( bfa ) ;
2012-08-23 06:51:08 +04:00
if ( req )
WARN_ON ( ! list_empty ( & mod - > fcxp_req_free_q ) ) ;
else
WARN_ON ( ! list_empty ( & mod - > fcxp_rsp_free_q ) ) ;
2010-09-15 22:50:55 +04:00
wqe - > alloc_cbfn = alloc_cbfn ;
wqe - > alloc_cbarg = alloc_cbarg ;
wqe - > caller = caller ;
wqe - > bfa = bfa ;
wqe - > nreq_sgles = nreq_sgles ;
wqe - > nrsp_sgles = nrsp_sgles ;
wqe - > req_sga_cbfn = req_sga_cbfn ;
wqe - > req_sglen_cbfn = req_sglen_cbfn ;
wqe - > rsp_sga_cbfn = rsp_sga_cbfn ;
wqe - > rsp_sglen_cbfn = rsp_sglen_cbfn ;
2012-08-23 06:51:08 +04:00
if ( req )
list_add_tail ( & wqe - > qe , & mod - > req_wait_q ) ;
else
list_add_tail ( & wqe - > qe , & mod - > rsp_wait_q ) ;
2010-09-15 22:50:55 +04:00
}
void
bfa_fcxp_walloc_cancel ( struct bfa_s * bfa , struct bfa_fcxp_wqe_s * wqe )
{
struct bfa_fcxp_mod_s * mod = BFA_FCXP_MOD ( bfa ) ;
2012-08-23 06:51:08 +04:00
WARN_ON ( ! bfa_q_is_on_q ( & mod - > req_wait_q , wqe ) | |
! bfa_q_is_on_q ( & mod - > rsp_wait_q , wqe ) ) ;
2010-09-15 22:50:55 +04:00
list_del ( & wqe - > qe ) ;
}
void
bfa_fcxp_discard ( struct bfa_fcxp_s * fcxp )
{
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* If waiting for room in request queue , cancel reqq wait
* and free fcxp .
*/
if ( fcxp - > reqq_waiting ) {
fcxp - > reqq_waiting = BFA_FALSE ;
bfa_reqq_wcancel ( & fcxp - > reqq_wqe ) ;
bfa_fcxp_free ( fcxp ) ;
return ;
}
fcxp - > send_cbfn = bfa_fcxp_null_comp ;
}
void
bfa_fcxp_isr ( struct bfa_s * bfa , struct bfi_msg_s * msg )
{
switch ( msg - > mhdr . msg_id ) {
case BFI_FCXP_I2H_SEND_RSP :
hal_fcxp_send_comp ( bfa , ( struct bfi_fcxp_send_rsp_s * ) msg ) ;
break ;
default :
bfa_trc ( bfa , msg - > mhdr . msg_id ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( 1 ) ;
2010-09-15 22:50:55 +04:00
}
}
u32
bfa_fcxp_get_maxrsp ( struct bfa_s * bfa )
{
struct bfa_fcxp_mod_s * mod = BFA_FCXP_MOD ( bfa ) ;
return mod - > rsp_pld_sz ;
}
2011-06-25 07:24:08 +04:00
void
bfa_fcxp_res_recfg ( struct bfa_s * bfa , u16 num_fcxp_fw )
{
struct bfa_fcxp_mod_s * mod = BFA_FCXP_MOD ( bfa ) ;
struct list_head * qe ;
int i ;
for ( i = 0 ; i < ( mod - > num_fcxps - num_fcxp_fw ) ; i + + ) {
2012-08-23 06:51:08 +04:00
if ( i < ( ( mod - > num_fcxps - num_fcxp_fw ) / 2 ) ) {
bfa_q_deq_tail ( & mod - > fcxp_req_free_q , & qe ) ;
list_add_tail ( qe , & mod - > fcxp_req_unused_q ) ;
} else {
bfa_q_deq_tail ( & mod - > fcxp_rsp_free_q , & qe ) ;
list_add_tail ( qe , & mod - > fcxp_rsp_unused_q ) ;
}
2011-06-25 07:24:08 +04:00
}
}
2010-09-15 22:50:55 +04:00
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* BFA LPS state machine functions
*/
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Init state - - no login
*/
static void
bfa_lps_sm_init ( struct bfa_lps_s * lps , enum bfa_lps_event event )
{
2011-06-25 07:24:08 +04:00
bfa_trc ( lps - > bfa , lps - > bfa_tag ) ;
2010-09-15 22:50:55 +04:00
bfa_trc ( lps - > bfa , event ) ;
switch ( event ) {
case BFA_LPS_SM_LOGIN :
if ( bfa_reqq_full ( lps - > bfa , lps - > reqq ) ) {
bfa_sm_set_state ( lps , bfa_lps_sm_loginwait ) ;
bfa_reqq_wait ( lps - > bfa , lps - > reqq , & lps - > wqe ) ;
} else {
bfa_sm_set_state ( lps , bfa_lps_sm_login ) ;
bfa_lps_send_login ( lps ) ;
}
if ( lps - > fdisc )
bfa_plog_str ( lps - > bfa - > plog , BFA_PL_MID_LPS ,
BFA_PL_EID_LOGIN , 0 , " FDISC Request " ) ;
else
bfa_plog_str ( lps - > bfa - > plog , BFA_PL_MID_LPS ,
BFA_PL_EID_LOGIN , 0 , " FLOGI Request " ) ;
break ;
case BFA_LPS_SM_LOGOUT :
bfa_lps_logout_comp ( lps ) ;
break ;
case BFA_LPS_SM_DELETE :
bfa_lps_free ( lps ) ;
break ;
case BFA_LPS_SM_RX_CVL :
case BFA_LPS_SM_OFFLINE :
break ;
case BFA_LPS_SM_FWRSP :
/*
* Could happen when fabric detects loopback and discards
* the lps request . Fw will eventually sent out the timeout
* Just ignore
*/
break ;
2012-09-22 04:23:59 +04:00
case BFA_LPS_SM_SET_N2N_PID :
/*
* When topology is set to loop , bfa_lps_set_n2n_pid ( ) sends
* this event . Ignore this event .
*/
break ;
2010-09-15 22:50:55 +04:00
default :
bfa_sm_fault ( lps - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* login is in progress - - awaiting response from firmware
*/
static void
bfa_lps_sm_login ( struct bfa_lps_s * lps , enum bfa_lps_event event )
{
2011-06-25 07:24:08 +04:00
bfa_trc ( lps - > bfa , lps - > bfa_tag ) ;
2010-09-15 22:50:55 +04:00
bfa_trc ( lps - > bfa , event ) ;
switch ( event ) {
case BFA_LPS_SM_FWRSP :
if ( lps - > status = = BFA_STATUS_OK ) {
bfa_sm_set_state ( lps , bfa_lps_sm_online ) ;
if ( lps - > fdisc )
bfa_plog_str ( lps - > bfa - > plog , BFA_PL_MID_LPS ,
BFA_PL_EID_LOGIN , 0 , " FDISC Accept " ) ;
else
bfa_plog_str ( lps - > bfa - > plog , BFA_PL_MID_LPS ,
BFA_PL_EID_LOGIN , 0 , " FLOGI Accept " ) ;
2010-12-14 03:17:42 +03:00
/* If N2N, send the assigned PID to FW */
bfa_trc ( lps - > bfa , lps - > fport ) ;
bfa_trc ( lps - > bfa , lps - > lp_pid ) ;
if ( ! lps - > fport & & lps - > lp_pid )
bfa_sm_send_event ( lps , BFA_LPS_SM_SET_N2N_PID ) ;
2010-09-15 22:50:55 +04:00
} else {
bfa_sm_set_state ( lps , bfa_lps_sm_init ) ;
if ( lps - > fdisc )
bfa_plog_str ( lps - > bfa - > plog , BFA_PL_MID_LPS ,
BFA_PL_EID_LOGIN , 0 ,
" FDISC Fail (RJT or timeout) " ) ;
else
bfa_plog_str ( lps - > bfa - > plog , BFA_PL_MID_LPS ,
BFA_PL_EID_LOGIN , 0 ,
" FLOGI Fail (RJT or timeout) " ) ;
}
bfa_lps_login_comp ( lps ) ;
break ;
2013-05-13 13:49:44 +04:00
case BFA_LPS_SM_OFFLINE :
2011-06-14 02:53:04 +04:00
case BFA_LPS_SM_DELETE :
2010-09-15 22:50:55 +04:00
bfa_sm_set_state ( lps , bfa_lps_sm_init ) ;
break ;
2010-12-14 03:17:42 +03:00
case BFA_LPS_SM_SET_N2N_PID :
bfa_trc ( lps - > bfa , lps - > fport ) ;
bfa_trc ( lps - > bfa , lps - > lp_pid ) ;
break ;
2010-09-15 22:50:55 +04:00
default :
bfa_sm_fault ( lps - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* login pending - awaiting space in request queue
*/
static void
bfa_lps_sm_loginwait ( struct bfa_lps_s * lps , enum bfa_lps_event event )
{
2011-06-25 07:24:08 +04:00
bfa_trc ( lps - > bfa , lps - > bfa_tag ) ;
2010-09-15 22:50:55 +04:00
bfa_trc ( lps - > bfa , event ) ;
switch ( event ) {
case BFA_LPS_SM_RESUME :
bfa_sm_set_state ( lps , bfa_lps_sm_login ) ;
2012-03-14 04:40:31 +04:00
bfa_lps_send_login ( lps ) ;
2010-09-15 22:50:55 +04:00
break ;
case BFA_LPS_SM_OFFLINE :
2011-06-14 02:53:04 +04:00
case BFA_LPS_SM_DELETE :
2010-09-15 22:50:55 +04:00
bfa_sm_set_state ( lps , bfa_lps_sm_init ) ;
bfa_reqq_wcancel ( & lps - > wqe ) ;
break ;
case BFA_LPS_SM_RX_CVL :
/*
* Login was not even sent out ; so when getting out
* of this state , it will appear like a login retry
* after Clear virtual link
*/
break ;
default :
bfa_sm_fault ( lps - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* login complete
*/
static void
bfa_lps_sm_online ( struct bfa_lps_s * lps , enum bfa_lps_event event )
{
2011-06-25 07:24:08 +04:00
bfa_trc ( lps - > bfa , lps - > bfa_tag ) ;
2010-09-15 22:50:55 +04:00
bfa_trc ( lps - > bfa , event ) ;
switch ( event ) {
case BFA_LPS_SM_LOGOUT :
if ( bfa_reqq_full ( lps - > bfa , lps - > reqq ) ) {
bfa_sm_set_state ( lps , bfa_lps_sm_logowait ) ;
bfa_reqq_wait ( lps - > bfa , lps - > reqq , & lps - > wqe ) ;
} else {
bfa_sm_set_state ( lps , bfa_lps_sm_logout ) ;
bfa_lps_send_logout ( lps ) ;
}
bfa_plog_str ( lps - > bfa - > plog , BFA_PL_MID_LPS ,
BFA_PL_EID_LOGO , 0 , " Logout " ) ;
break ;
case BFA_LPS_SM_RX_CVL :
bfa_sm_set_state ( lps , bfa_lps_sm_init ) ;
/* Let the vport module know about this event */
bfa_lps_cvl_event ( lps ) ;
bfa_plog_str ( lps - > bfa - > plog , BFA_PL_MID_LPS ,
BFA_PL_EID_FIP_FCF_CVL , 0 , " FCF Clear Virt. Link Rx " ) ;
break ;
2010-12-14 03:17:42 +03:00
case BFA_LPS_SM_SET_N2N_PID :
if ( bfa_reqq_full ( lps - > bfa , lps - > reqq ) ) {
bfa_sm_set_state ( lps , bfa_lps_sm_online_n2n_pid_wait ) ;
bfa_reqq_wait ( lps - > bfa , lps - > reqq , & lps - > wqe ) ;
} else
bfa_lps_send_set_n2n_pid ( lps ) ;
break ;
2010-09-15 22:50:55 +04:00
case BFA_LPS_SM_OFFLINE :
case BFA_LPS_SM_DELETE :
bfa_sm_set_state ( lps , bfa_lps_sm_init ) ;
break ;
default :
bfa_sm_fault ( lps - > bfa , event ) ;
}
}
2010-12-27 08:50:10 +03:00
/*
2010-12-14 03:17:42 +03:00
* login complete
*/
static void
bfa_lps_sm_online_n2n_pid_wait ( struct bfa_lps_s * lps , enum bfa_lps_event event )
{
2011-06-25 07:24:08 +04:00
bfa_trc ( lps - > bfa , lps - > bfa_tag ) ;
2010-12-14 03:17:42 +03:00
bfa_trc ( lps - > bfa , event ) ;
switch ( event ) {
case BFA_LPS_SM_RESUME :
bfa_sm_set_state ( lps , bfa_lps_sm_online ) ;
bfa_lps_send_set_n2n_pid ( lps ) ;
break ;
case BFA_LPS_SM_LOGOUT :
bfa_sm_set_state ( lps , bfa_lps_sm_logowait ) ;
bfa_plog_str ( lps - > bfa - > plog , BFA_PL_MID_LPS ,
BFA_PL_EID_LOGO , 0 , " Logout " ) ;
break ;
case BFA_LPS_SM_RX_CVL :
bfa_sm_set_state ( lps , bfa_lps_sm_init ) ;
bfa_reqq_wcancel ( & lps - > wqe ) ;
/* Let the vport module know about this event */
bfa_lps_cvl_event ( lps ) ;
bfa_plog_str ( lps - > bfa - > plog , BFA_PL_MID_LPS ,
BFA_PL_EID_FIP_FCF_CVL , 0 , " FCF Clear Virt. Link Rx " ) ;
break ;
case BFA_LPS_SM_OFFLINE :
case BFA_LPS_SM_DELETE :
bfa_sm_set_state ( lps , bfa_lps_sm_init ) ;
bfa_reqq_wcancel ( & lps - > wqe ) ;
break ;
default :
bfa_sm_fault ( lps - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* logout in progress - awaiting firmware response
*/
static void
bfa_lps_sm_logout ( struct bfa_lps_s * lps , enum bfa_lps_event event )
{
2011-06-25 07:24:08 +04:00
bfa_trc ( lps - > bfa , lps - > bfa_tag ) ;
2010-09-15 22:50:55 +04:00
bfa_trc ( lps - > bfa , event ) ;
switch ( event ) {
case BFA_LPS_SM_FWRSP :
2012-08-23 06:52:02 +04:00
case BFA_LPS_SM_OFFLINE :
2010-09-15 22:50:55 +04:00
bfa_sm_set_state ( lps , bfa_lps_sm_init ) ;
bfa_lps_logout_comp ( lps ) ;
break ;
2011-06-14 02:53:04 +04:00
case BFA_LPS_SM_DELETE :
2010-09-15 22:50:55 +04:00
bfa_sm_set_state ( lps , bfa_lps_sm_init ) ;
break ;
default :
bfa_sm_fault ( lps - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* logout pending - - awaiting space in request queue
*/
static void
bfa_lps_sm_logowait ( struct bfa_lps_s * lps , enum bfa_lps_event event )
{
2011-06-25 07:24:08 +04:00
bfa_trc ( lps - > bfa , lps - > bfa_tag ) ;
2010-09-15 22:50:55 +04:00
bfa_trc ( lps - > bfa , event ) ;
switch ( event ) {
case BFA_LPS_SM_RESUME :
bfa_sm_set_state ( lps , bfa_lps_sm_logout ) ;
bfa_lps_send_logout ( lps ) ;
break ;
case BFA_LPS_SM_OFFLINE :
2011-06-14 02:53:04 +04:00
case BFA_LPS_SM_DELETE :
2010-09-15 22:50:55 +04:00
bfa_sm_set_state ( lps , bfa_lps_sm_init ) ;
bfa_reqq_wcancel ( & lps - > wqe ) ;
break ;
default :
bfa_sm_fault ( lps - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* lps_pvt BFA LPS private functions
*/
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* return memory requirement
*/
static void
2011-06-25 07:24:29 +04:00
bfa_lps_meminfo ( struct bfa_iocfc_cfg_s * cfg , struct bfa_meminfo_s * minfo ,
struct bfa_s * bfa )
2010-09-15 22:50:55 +04:00
{
2011-06-25 07:24:29 +04:00
struct bfa_mem_kva_s * lps_kva = BFA_MEM_LPS_KVA ( bfa ) ;
2010-09-15 22:50:55 +04:00
if ( cfg - > drvcfg . min_cfg )
2011-06-25 07:24:29 +04:00
bfa_mem_kva_setup ( minfo , lps_kva ,
sizeof ( struct bfa_lps_s ) * BFA_LPS_MIN_LPORTS ) ;
2010-09-15 22:50:55 +04:00
else
2011-06-25 07:24:29 +04:00
bfa_mem_kva_setup ( minfo , lps_kva ,
sizeof ( struct bfa_lps_s ) * BFA_LPS_MAX_LPORTS ) ;
2010-09-15 22:50:55 +04:00
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* bfa module attach at initialization time
*/
static void
bfa_lps_attach ( struct bfa_s * bfa , void * bfad , struct bfa_iocfc_cfg_s * cfg ,
2011-06-25 07:24:29 +04:00
struct bfa_pcidev_s * pcidev )
2010-09-15 22:50:55 +04:00
{
struct bfa_lps_mod_s * mod = BFA_LPS_MOD ( bfa ) ;
struct bfa_lps_s * lps ;
int i ;
mod - > num_lps = BFA_LPS_MAX_LPORTS ;
if ( cfg - > drvcfg . min_cfg )
mod - > num_lps = BFA_LPS_MIN_LPORTS ;
else
mod - > num_lps = BFA_LPS_MAX_LPORTS ;
2011-06-25 07:24:29 +04:00
mod - > lps_arr = lps = ( struct bfa_lps_s * ) bfa_mem_kva_curp ( mod ) ;
2010-09-15 22:50:55 +04:00
2011-06-25 07:24:29 +04:00
bfa_mem_kva_curp ( mod ) + = mod - > num_lps * sizeof ( struct bfa_lps_s ) ;
2010-09-15 22:50:55 +04:00
INIT_LIST_HEAD ( & mod - > lps_free_q ) ;
INIT_LIST_HEAD ( & mod - > lps_active_q ) ;
2011-06-25 07:24:08 +04:00
INIT_LIST_HEAD ( & mod - > lps_login_q ) ;
2010-09-15 22:50:55 +04:00
for ( i = 0 ; i < mod - > num_lps ; i + + , lps + + ) {
lps - > bfa = bfa ;
2011-06-25 07:24:08 +04:00
lps - > bfa_tag = ( u8 ) i ;
2010-09-15 22:50:55 +04:00
lps - > reqq = BFA_REQQ_LPS ;
bfa_reqq_winit ( & lps - > wqe , bfa_lps_reqq_resume , lps ) ;
list_add_tail ( & lps - > qe , & mod - > lps_free_q ) ;
}
}
static void
bfa_lps_detach ( struct bfa_s * bfa )
{
}
static void
bfa_lps_start ( struct bfa_s * bfa )
{
}
static void
bfa_lps_stop ( struct bfa_s * bfa )
{
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* IOC in disabled state - - consider all lps offline
*/
static void
bfa_lps_iocdisable ( struct bfa_s * bfa )
{
struct bfa_lps_mod_s * mod = BFA_LPS_MOD ( bfa ) ;
struct bfa_lps_s * lps ;
struct list_head * qe , * qen ;
list_for_each_safe ( qe , qen , & mod - > lps_active_q ) {
lps = ( struct bfa_lps_s * ) qe ;
bfa_sm_send_event ( lps , BFA_LPS_SM_OFFLINE ) ;
}
2011-06-25 07:24:08 +04:00
list_for_each_safe ( qe , qen , & mod - > lps_login_q ) {
lps = ( struct bfa_lps_s * ) qe ;
bfa_sm_send_event ( lps , BFA_LPS_SM_OFFLINE ) ;
}
list_splice_tail_init ( & mod - > lps_login_q , & mod - > lps_active_q ) ;
2010-09-15 22:50:55 +04:00
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Firmware login response
*/
static void
bfa_lps_login_rsp ( struct bfa_s * bfa , struct bfi_lps_login_rsp_s * rsp )
{
struct bfa_lps_mod_s * mod = BFA_LPS_MOD ( bfa ) ;
struct bfa_lps_s * lps ;
2011-06-25 07:24:08 +04:00
WARN_ON ( rsp - > bfa_tag > = mod - > num_lps ) ;
lps = BFA_LPS_FROM_TAG ( mod , rsp - > bfa_tag ) ;
2010-09-15 22:50:55 +04:00
lps - > status = rsp - > status ;
switch ( rsp - > status ) {
case BFA_STATUS_OK :
2011-06-25 07:24:08 +04:00
lps - > fw_tag = rsp - > fw_tag ;
2010-09-15 22:50:55 +04:00
lps - > fport = rsp - > f_port ;
2010-12-14 03:17:42 +03:00
if ( lps - > fport )
lps - > lp_pid = rsp - > lp_pid ;
2010-09-15 22:50:55 +04:00
lps - > npiv_en = rsp - > npiv_en ;
2010-10-19 04:10:50 +04:00
lps - > pr_bbcred = be16_to_cpu ( rsp - > bb_credit ) ;
2010-09-15 22:50:55 +04:00
lps - > pr_pwwn = rsp - > port_name ;
lps - > pr_nwwn = rsp - > node_name ;
lps - > auth_req = rsp - > auth_req ;
lps - > lp_mac = rsp - > lp_mac ;
lps - > brcd_switch = rsp - > brcd_switch ;
lps - > fcf_mac = rsp - > fcf_mac ;
break ;
case BFA_STATUS_FABRIC_RJT :
lps - > lsrjt_rsn = rsp - > lsrjt_rsn ;
lps - > lsrjt_expl = rsp - > lsrjt_expl ;
break ;
case BFA_STATUS_EPROTOCOL :
lps - > ext_status = rsp - > ext_status ;
break ;
2011-06-25 07:24:08 +04:00
case BFA_STATUS_VPORT_MAX :
2012-03-14 04:40:31 +04:00
if ( rsp - > ext_status )
2011-06-25 07:24:08 +04:00
bfa_lps_no_res ( lps , rsp - > ext_status ) ;
break ;
2010-09-15 22:50:55 +04:00
default :
/* Nothing to do with other status */
break ;
}
2011-06-25 07:24:08 +04:00
list_del ( & lps - > qe ) ;
list_add_tail ( & lps - > qe , & mod - > lps_active_q ) ;
2010-09-15 22:50:55 +04:00
bfa_sm_send_event ( lps , BFA_LPS_SM_FWRSP ) ;
}
2011-06-25 07:24:08 +04:00
static void
bfa_lps_no_res ( struct bfa_lps_s * first_lps , u8 count )
{
struct bfa_s * bfa = first_lps - > bfa ;
struct bfa_lps_mod_s * mod = BFA_LPS_MOD ( bfa ) ;
struct list_head * qe , * qe_next ;
struct bfa_lps_s * lps ;
bfa_trc ( bfa , count ) ;
qe = bfa_q_next ( first_lps ) ;
while ( count & & qe ) {
qe_next = bfa_q_next ( qe ) ;
lps = ( struct bfa_lps_s * ) qe ;
bfa_trc ( bfa , lps - > bfa_tag ) ;
lps - > status = first_lps - > status ;
list_del ( & lps - > qe ) ;
list_add_tail ( & lps - > qe , & mod - > lps_active_q ) ;
bfa_sm_send_event ( lps , BFA_LPS_SM_FWRSP ) ;
qe = qe_next ;
count - - ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Firmware logout response
*/
static void
bfa_lps_logout_rsp ( struct bfa_s * bfa , struct bfi_lps_logout_rsp_s * rsp )
{
struct bfa_lps_mod_s * mod = BFA_LPS_MOD ( bfa ) ;
struct bfa_lps_s * lps ;
2011-06-25 07:24:08 +04:00
WARN_ON ( rsp - > bfa_tag > = mod - > num_lps ) ;
lps = BFA_LPS_FROM_TAG ( mod , rsp - > bfa_tag ) ;
2010-09-15 22:50:55 +04:00
bfa_sm_send_event ( lps , BFA_LPS_SM_FWRSP ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Firmware received a Clear virtual link request ( for FCoE )
*/
static void
bfa_lps_rx_cvl_event ( struct bfa_s * bfa , struct bfi_lps_cvl_event_s * cvl )
{
struct bfa_lps_mod_s * mod = BFA_LPS_MOD ( bfa ) ;
struct bfa_lps_s * lps ;
2011-06-25 07:24:08 +04:00
lps = BFA_LPS_FROM_TAG ( mod , cvl - > bfa_tag ) ;
2010-09-15 22:50:55 +04:00
bfa_sm_send_event ( lps , BFA_LPS_SM_RX_CVL ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Space is available in request queue , resume queueing request to firmware .
*/
static void
bfa_lps_reqq_resume ( void * lps_arg )
{
struct bfa_lps_s * lps = lps_arg ;
bfa_sm_send_event ( lps , BFA_LPS_SM_RESUME ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* lps is freed - - triggered by vport delete
*/
static void
bfa_lps_free ( struct bfa_lps_s * lps )
{
struct bfa_lps_mod_s * mod = BFA_LPS_MOD ( lps - > bfa ) ;
lps - > lp_pid = 0 ;
list_del ( & lps - > qe ) ;
list_add_tail ( & lps - > qe , & mod - > lps_free_q ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* send login request to firmware
*/
static void
bfa_lps_send_login ( struct bfa_lps_s * lps )
{
2011-06-25 07:24:08 +04:00
struct bfa_lps_mod_s * mod = BFA_LPS_MOD ( lps - > bfa ) ;
2010-09-15 22:50:55 +04:00
struct bfi_lps_login_req_s * m ;
m = bfa_reqq_next ( lps - > bfa , lps - > reqq ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( ! m ) ;
2010-09-15 22:50:55 +04:00
bfi_h2i_set ( m - > mh , BFI_MC_LPS , BFI_LPS_H2I_LOGIN_REQ ,
2011-06-25 07:24:08 +04:00
bfa_fn_lpu ( lps - > bfa ) ) ;
2010-09-15 22:50:55 +04:00
2011-06-25 07:24:08 +04:00
m - > bfa_tag = lps - > bfa_tag ;
2010-09-15 22:50:55 +04:00
m - > alpa = lps - > alpa ;
2010-10-19 04:10:50 +04:00
m - > pdu_size = cpu_to_be16 ( lps - > pdusz ) ;
2010-09-15 22:50:55 +04:00
m - > pwwn = lps - > pwwn ;
m - > nwwn = lps - > nwwn ;
m - > fdisc = lps - > fdisc ;
m - > auth_en = lps - > auth_en ;
2011-06-25 07:24:08 +04:00
bfa_reqq_produce ( lps - > bfa , lps - > reqq , m - > mh ) ;
list_del ( & lps - > qe ) ;
list_add_tail ( & lps - > qe , & mod - > lps_login_q ) ;
2010-09-15 22:50:55 +04:00
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* send logout request to firmware
*/
static void
bfa_lps_send_logout ( struct bfa_lps_s * lps )
{
struct bfi_lps_logout_req_s * m ;
m = bfa_reqq_next ( lps - > bfa , lps - > reqq ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( ! m ) ;
2010-09-15 22:50:55 +04:00
bfi_h2i_set ( m - > mh , BFI_MC_LPS , BFI_LPS_H2I_LOGOUT_REQ ,
2011-06-25 07:24:08 +04:00
bfa_fn_lpu ( lps - > bfa ) ) ;
2010-09-15 22:50:55 +04:00
2011-06-25 07:24:08 +04:00
m - > fw_tag = lps - > fw_tag ;
2010-09-15 22:50:55 +04:00
m - > port_name = lps - > pwwn ;
2011-06-25 07:24:08 +04:00
bfa_reqq_produce ( lps - > bfa , lps - > reqq , m - > mh ) ;
2010-09-15 22:50:55 +04:00
}
2010-12-27 08:50:10 +03:00
/*
2010-12-14 03:17:42 +03:00
* send n2n pid set request to firmware
*/
static void
bfa_lps_send_set_n2n_pid ( struct bfa_lps_s * lps )
{
struct bfi_lps_n2n_pid_req_s * m ;
m = bfa_reqq_next ( lps - > bfa , lps - > reqq ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( ! m ) ;
2010-12-14 03:17:42 +03:00
bfi_h2i_set ( m - > mh , BFI_MC_LPS , BFI_LPS_H2I_N2N_PID_REQ ,
2011-06-25 07:24:08 +04:00
bfa_fn_lpu ( lps - > bfa ) ) ;
2010-12-14 03:17:42 +03:00
2011-06-25 07:24:08 +04:00
m - > fw_tag = lps - > fw_tag ;
2010-12-14 03:17:42 +03:00
m - > lp_pid = lps - > lp_pid ;
2011-06-25 07:24:08 +04:00
bfa_reqq_produce ( lps - > bfa , lps - > reqq , m - > mh ) ;
2010-12-14 03:17:42 +03:00
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Indirect login completion handler for non - fcs
*/
static void
bfa_lps_login_comp_cb ( void * arg , bfa_boolean_t complete )
{
struct bfa_lps_s * lps = arg ;
if ( ! complete )
return ;
if ( lps - > fdisc )
bfa_cb_lps_fdisc_comp ( lps - > bfa - > bfad , lps - > uarg , lps - > status ) ;
else
bfa_cb_lps_flogi_comp ( lps - > bfa - > bfad , lps - > uarg , lps - > status ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Login completion handler - - direct call for fcs , queue for others
*/
static void
bfa_lps_login_comp ( struct bfa_lps_s * lps )
{
if ( ! lps - > bfa - > fcs ) {
bfa_cb_queue ( lps - > bfa , & lps - > hcb_qe , bfa_lps_login_comp_cb ,
lps ) ;
return ;
}
if ( lps - > fdisc )
bfa_cb_lps_fdisc_comp ( lps - > bfa - > bfad , lps - > uarg , lps - > status ) ;
else
bfa_cb_lps_flogi_comp ( lps - > bfa - > bfad , lps - > uarg , lps - > status ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Indirect logout completion handler for non - fcs
*/
static void
bfa_lps_logout_comp_cb ( void * arg , bfa_boolean_t complete )
{
struct bfa_lps_s * lps = arg ;
if ( ! complete )
return ;
if ( lps - > fdisc )
bfa_cb_lps_fdisclogo_comp ( lps - > bfa - > bfad , lps - > uarg ) ;
2012-08-23 06:52:02 +04:00
else
bfa_cb_lps_flogo_comp ( lps - > bfa - > bfad , lps - > uarg ) ;
2010-09-15 22:50:55 +04:00
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Logout completion handler - - direct call for fcs , queue for others
*/
static void
bfa_lps_logout_comp ( struct bfa_lps_s * lps )
{
if ( ! lps - > bfa - > fcs ) {
bfa_cb_queue ( lps - > bfa , & lps - > hcb_qe , bfa_lps_logout_comp_cb ,
lps ) ;
return ;
}
if ( lps - > fdisc )
bfa_cb_lps_fdisclogo_comp ( lps - > bfa - > bfad , lps - > uarg ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Clear virtual link completion handler for non - fcs
*/
static void
bfa_lps_cvl_event_cb ( void * arg , bfa_boolean_t complete )
{
struct bfa_lps_s * lps = arg ;
if ( ! complete )
return ;
/* Clear virtual link to base port will result in link down */
if ( lps - > fdisc )
bfa_cb_lps_cvl_event ( lps - > bfa - > bfad , lps - > uarg ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Received Clear virtual link event - - direct call for fcs ,
* queue for others
*/
static void
bfa_lps_cvl_event ( struct bfa_lps_s * lps )
{
if ( ! lps - > bfa - > fcs ) {
bfa_cb_queue ( lps - > bfa , & lps - > hcb_qe , bfa_lps_cvl_event_cb ,
lps ) ;
return ;
}
/* Clear virtual link to base port will result in link down */
if ( lps - > fdisc )
bfa_cb_lps_cvl_event ( lps - > bfa - > bfad , lps - > uarg ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* lps_public BFA LPS public functions
*/
u32
bfa_lps_get_max_vport ( struct bfa_s * bfa )
{
if ( bfa_ioc_devid ( & bfa - > ioc ) = = BFA_PCI_DEVICE_ID_CT )
return BFA_LPS_MAX_VPORTS_SUPP_CT ;
else
return BFA_LPS_MAX_VPORTS_SUPP_CB ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Allocate a lport srvice tag .
*/
struct bfa_lps_s *
bfa_lps_alloc ( struct bfa_s * bfa )
{
struct bfa_lps_mod_s * mod = BFA_LPS_MOD ( bfa ) ;
struct bfa_lps_s * lps = NULL ;
bfa_q_deq ( & mod - > lps_free_q , & lps ) ;
if ( lps = = NULL )
return NULL ;
list_add_tail ( & lps - > qe , & mod - > lps_active_q ) ;
bfa_sm_set_state ( lps , bfa_lps_sm_init ) ;
return lps ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Free lport service tag . This can be called anytime after an alloc .
* No need to wait for any pending login / logout completions .
*/
void
bfa_lps_delete ( struct bfa_lps_s * lps )
{
bfa_sm_send_event ( lps , BFA_LPS_SM_DELETE ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Initiate a lport login .
*/
void
bfa_lps_flogi ( struct bfa_lps_s * lps , void * uarg , u8 alpa , u16 pdusz ,
2013-05-13 13:33:19 +04:00
wwn_t pwwn , wwn_t nwwn , bfa_boolean_t auth_en )
2010-09-15 22:50:55 +04:00
{
lps - > uarg = uarg ;
lps - > alpa = alpa ;
lps - > pdusz = pdusz ;
lps - > pwwn = pwwn ;
lps - > nwwn = nwwn ;
lps - > fdisc = BFA_FALSE ;
lps - > auth_en = auth_en ;
bfa_sm_send_event ( lps , BFA_LPS_SM_LOGIN ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Initiate a lport fdisc login .
*/
void
bfa_lps_fdisc ( struct bfa_lps_s * lps , void * uarg , u16 pdusz , wwn_t pwwn ,
wwn_t nwwn )
{
lps - > uarg = uarg ;
lps - > alpa = 0 ;
lps - > pdusz = pdusz ;
lps - > pwwn = pwwn ;
lps - > nwwn = nwwn ;
lps - > fdisc = BFA_TRUE ;
lps - > auth_en = BFA_FALSE ;
bfa_sm_send_event ( lps , BFA_LPS_SM_LOGIN ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Initiate a lport FDSIC logout .
*/
void
bfa_lps_fdisclogo ( struct bfa_lps_s * lps )
{
bfa_sm_send_event ( lps , BFA_LPS_SM_LOGOUT ) ;
}
2011-06-25 07:24:08 +04:00
u8
bfa_lps_get_fwtag ( struct bfa_s * bfa , u8 lp_tag )
{
struct bfa_lps_mod_s * mod = BFA_LPS_MOD ( bfa ) ;
return BFA_LPS_FROM_TAG ( mod , lp_tag ) - > fw_tag ;
}
2010-09-15 22:50:55 +04:00
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Return lport services tag given the pid
*/
u8
bfa_lps_get_tag_from_pid ( struct bfa_s * bfa , u32 pid )
{
struct bfa_lps_mod_s * mod = BFA_LPS_MOD ( bfa ) ;
struct bfa_lps_s * lps ;
int i ;
for ( i = 0 , lps = mod - > lps_arr ; i < mod - > num_lps ; i + + , lps + + ) {
if ( lps - > lp_pid = = pid )
2011-06-25 07:24:08 +04:00
return lps - > bfa_tag ;
2010-09-15 22:50:55 +04:00
}
/* Return base port tag anyway */
return 0 ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* return port id assigned to the base lport
*/
u32
bfa_lps_get_base_pid ( struct bfa_s * bfa )
{
struct bfa_lps_mod_s * mod = BFA_LPS_MOD ( bfa ) ;
return BFA_LPS_FROM_TAG ( mod , 0 ) - > lp_pid ;
}
2010-12-27 08:50:10 +03:00
/*
2010-12-14 03:17:42 +03:00
* Set PID in case of n2n ( which is assigned during PLOGI )
*/
void
bfa_lps_set_n2n_pid ( struct bfa_lps_s * lps , uint32_t n2n_pid )
{
2011-06-25 07:24:08 +04:00
bfa_trc ( lps - > bfa , lps - > bfa_tag ) ;
2010-12-14 03:17:42 +03:00
bfa_trc ( lps - > bfa , n2n_pid ) ;
lps - > lp_pid = n2n_pid ;
bfa_sm_send_event ( lps , BFA_LPS_SM_SET_N2N_PID ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* LPS firmware message class handler .
*/
void
bfa_lps_isr ( struct bfa_s * bfa , struct bfi_msg_s * m )
{
union bfi_lps_i2h_msg_u msg ;
bfa_trc ( bfa , m - > mhdr . msg_id ) ;
msg . msg = m ;
switch ( m - > mhdr . msg_id ) {
2011-06-14 02:46:21 +04:00
case BFI_LPS_I2H_LOGIN_RSP :
2010-09-15 22:50:55 +04:00
bfa_lps_login_rsp ( bfa , msg . login_rsp ) ;
break ;
2011-06-14 02:46:21 +04:00
case BFI_LPS_I2H_LOGOUT_RSP :
2010-09-15 22:50:55 +04:00
bfa_lps_logout_rsp ( bfa , msg . logout_rsp ) ;
break ;
2011-06-14 02:46:21 +04:00
case BFI_LPS_I2H_CVL_EVENT :
2010-09-15 22:50:55 +04:00
bfa_lps_rx_cvl_event ( bfa , msg . cvl_event ) ;
break ;
default :
bfa_trc ( bfa , m - > mhdr . msg_id ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( 1 ) ;
2010-09-15 22:50:55 +04:00
}
}
2011-07-21 03:59:13 +04:00
static void
bfa_fcport_aen_post ( struct bfa_fcport_s * fcport , enum bfa_port_aen_event event )
{
struct bfad_s * bfad = ( struct bfad_s * ) fcport - > bfa - > bfad ;
struct bfa_aen_entry_s * aen_entry ;
bfad_get_aen_entry ( bfad , aen_entry ) ;
if ( ! aen_entry )
return ;
aen_entry - > aen_data . port . ioc_type = bfa_get_type ( fcport - > bfa ) ;
aen_entry - > aen_data . port . pwwn = fcport - > pwwn ;
/* Send the AEN notification */
bfad_im_post_vendor_event ( aen_entry , bfad , + + fcport - > bfa - > bfa_aen_seq ,
BFA_AEN_CAT_PORT , event ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* FC PORT state machine functions
*/
static void
bfa_fcport_sm_uninit ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event )
{
bfa_trc ( fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_SM_START :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Start event after IOC is configured and BFA is started .
*/
2010-12-14 03:16:50 +03:00
fcport - > use_flash_cfg = BFA_TRUE ;
2010-09-15 22:50:55 +04:00
if ( bfa_fcport_send_enable ( fcport ) ) {
bfa_trc ( fcport - > bfa , BFA_TRUE ) ;
bfa_sm_set_state ( fcport , bfa_fcport_sm_enabling ) ;
} else {
bfa_trc ( fcport - > bfa , BFA_FALSE ) ;
bfa_sm_set_state ( fcport ,
bfa_fcport_sm_enabling_qwait ) ;
}
break ;
case BFA_FCPORT_SM_ENABLE :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Port is persistently configured to be in enabled state . Do
* not change state . Port enabling is done when START event is
* received .
*/
break ;
case BFA_FCPORT_SM_DISABLE :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* If a port is persistently configured to be disabled , the
* first event will a port disable request .
*/
bfa_sm_set_state ( fcport , bfa_fcport_sm_disabled ) ;
break ;
case BFA_FCPORT_SM_HWFAIL :
bfa_sm_set_state ( fcport , bfa_fcport_sm_iocdown ) ;
break ;
default :
bfa_sm_fault ( fcport - > bfa , event ) ;
}
}
static void
bfa_fcport_sm_enabling_qwait ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event )
{
char pwwn_buf [ BFA_STRING_32 ] ;
struct bfad_s * bfad = ( struct bfad_s * ) fcport - > bfa - > bfad ;
bfa_trc ( fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_SM_QRESUME :
bfa_sm_set_state ( fcport , bfa_fcport_sm_enabling ) ;
bfa_fcport_send_enable ( fcport ) ;
break ;
case BFA_FCPORT_SM_STOP :
bfa_reqq_wcancel ( & fcport - > reqq_wait ) ;
bfa_sm_set_state ( fcport , bfa_fcport_sm_stopped ) ;
break ;
case BFA_FCPORT_SM_ENABLE :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Already enable is in progress .
*/
break ;
case BFA_FCPORT_SM_DISABLE :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Just send disable request to firmware when room becomes
* available in request queue .
*/
bfa_sm_set_state ( fcport , bfa_fcport_sm_disabled ) ;
bfa_reqq_wcancel ( & fcport - > reqq_wait ) ;
bfa_plog_str ( fcport - > bfa - > plog , BFA_PL_MID_HAL ,
BFA_PL_EID_PORT_DISABLE , 0 , " Port Disable " ) ;
wwn2str ( pwwn_buf , fcport - > pwwn ) ;
2010-12-10 04:11:53 +03:00
BFA_LOG ( KERN_INFO , bfad , bfa_log_level ,
2010-09-15 22:50:55 +04:00
" Base port disabled: WWN = %s \n " , pwwn_buf ) ;
2011-07-21 03:59:13 +04:00
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_DISABLE ) ;
2010-09-15 22:50:55 +04:00
break ;
case BFA_FCPORT_SM_LINKUP :
case BFA_FCPORT_SM_LINKDOWN :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Possible to get link events when doing back - to - back
* enable / disables .
*/
break ;
case BFA_FCPORT_SM_HWFAIL :
bfa_reqq_wcancel ( & fcport - > reqq_wait ) ;
bfa_sm_set_state ( fcport , bfa_fcport_sm_iocdown ) ;
break ;
2012-09-22 04:26:18 +04:00
case BFA_FCPORT_SM_FAA_MISCONFIG :
bfa_fcport_reset_linkinfo ( fcport ) ;
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_DISCONNECT ) ;
bfa_sm_set_state ( fcport , bfa_fcport_sm_faa_misconfig ) ;
break ;
2010-09-15 22:50:55 +04:00
default :
bfa_sm_fault ( fcport - > bfa , event ) ;
}
}
static void
bfa_fcport_sm_enabling ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event )
{
char pwwn_buf [ BFA_STRING_32 ] ;
struct bfad_s * bfad = ( struct bfad_s * ) fcport - > bfa - > bfad ;
bfa_trc ( fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_SM_FWRSP :
case BFA_FCPORT_SM_LINKDOWN :
bfa_sm_set_state ( fcport , bfa_fcport_sm_linkdown ) ;
break ;
case BFA_FCPORT_SM_LINKUP :
bfa_fcport_update_linkinfo ( fcport ) ;
bfa_sm_set_state ( fcport , bfa_fcport_sm_linkup ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( ! fcport - > event_cbfn ) ;
2010-09-15 22:50:55 +04:00
bfa_fcport_scn ( fcport , BFA_PORT_LINKUP , BFA_FALSE ) ;
break ;
case BFA_FCPORT_SM_ENABLE :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Already being enabled .
*/
break ;
case BFA_FCPORT_SM_DISABLE :
if ( bfa_fcport_send_disable ( fcport ) )
bfa_sm_set_state ( fcport , bfa_fcport_sm_disabling ) ;
else
bfa_sm_set_state ( fcport ,
bfa_fcport_sm_disabling_qwait ) ;
bfa_plog_str ( fcport - > bfa - > plog , BFA_PL_MID_HAL ,
BFA_PL_EID_PORT_DISABLE , 0 , " Port Disable " ) ;
wwn2str ( pwwn_buf , fcport - > pwwn ) ;
2010-12-10 04:11:53 +03:00
BFA_LOG ( KERN_INFO , bfad , bfa_log_level ,
2010-09-15 22:50:55 +04:00
" Base port disabled: WWN = %s \n " , pwwn_buf ) ;
2011-07-21 03:59:13 +04:00
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_DISABLE ) ;
2010-09-15 22:50:55 +04:00
break ;
case BFA_FCPORT_SM_STOP :
bfa_sm_set_state ( fcport , bfa_fcport_sm_stopped ) ;
break ;
case BFA_FCPORT_SM_HWFAIL :
bfa_sm_set_state ( fcport , bfa_fcport_sm_iocdown ) ;
break ;
2012-09-22 04:26:18 +04:00
case BFA_FCPORT_SM_FAA_MISCONFIG :
bfa_fcport_reset_linkinfo ( fcport ) ;
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_DISCONNECT ) ;
bfa_sm_set_state ( fcport , bfa_fcport_sm_faa_misconfig ) ;
break ;
2010-09-15 22:50:55 +04:00
default :
bfa_sm_fault ( fcport - > bfa , event ) ;
}
}
static void
bfa_fcport_sm_linkdown ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event )
{
struct bfi_fcport_event_s * pevent = fcport - > event_arg . i2hmsg . event ;
char pwwn_buf [ BFA_STRING_32 ] ;
struct bfad_s * bfad = ( struct bfad_s * ) fcport - > bfa - > bfad ;
bfa_trc ( fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_SM_LINKUP :
bfa_fcport_update_linkinfo ( fcport ) ;
bfa_sm_set_state ( fcport , bfa_fcport_sm_linkup ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( ! fcport - > event_cbfn ) ;
2010-09-15 22:50:55 +04:00
bfa_plog_str ( fcport - > bfa - > plog , BFA_PL_MID_HAL ,
BFA_PL_EID_PORT_ST_CHANGE , 0 , " Port Linkup " ) ;
if ( ! bfa_ioc_get_fcmode ( & fcport - > bfa - > ioc ) ) {
bfa_trc ( fcport - > bfa ,
2012-09-22 04:23:59 +04:00
pevent - > link_state . attr . vc_fcf . fcf . fipenabled ) ;
2010-09-15 22:50:55 +04:00
bfa_trc ( fcport - > bfa ,
2012-09-22 04:23:59 +04:00
pevent - > link_state . attr . vc_fcf . fcf . fipfailed ) ;
2010-09-15 22:50:55 +04:00
2012-09-22 04:23:59 +04:00
if ( pevent - > link_state . attr . vc_fcf . fcf . fipfailed )
2010-09-15 22:50:55 +04:00
bfa_plog_str ( fcport - > bfa - > plog , BFA_PL_MID_HAL ,
BFA_PL_EID_FIP_FCF_DISC , 0 ,
" FIP FCF Discovery Failed " ) ;
else
bfa_plog_str ( fcport - > bfa - > plog , BFA_PL_MID_HAL ,
BFA_PL_EID_FIP_FCF_DISC , 0 ,
" FIP FCF Discovered " ) ;
}
bfa_fcport_scn ( fcport , BFA_PORT_LINKUP , BFA_FALSE ) ;
wwn2str ( pwwn_buf , fcport - > pwwn ) ;
2010-12-10 04:11:53 +03:00
BFA_LOG ( KERN_INFO , bfad , bfa_log_level ,
2010-09-15 22:50:55 +04:00
" Base port online: WWN = %s \n " , pwwn_buf ) ;
2011-07-21 03:59:13 +04:00
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_ONLINE ) ;
2011-07-21 04:03:09 +04:00
/* If QoS is enabled and it is not online, send AEN */
if ( fcport - > cfg . qos_enabled & &
fcport - > qos_attr . state ! = BFA_QOS_ONLINE )
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_QOS_NEG ) ;
2010-09-15 22:50:55 +04:00
break ;
case BFA_FCPORT_SM_LINKDOWN :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Possible to get link down event .
*/
break ;
case BFA_FCPORT_SM_ENABLE :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Already enabled .
*/
break ;
case BFA_FCPORT_SM_DISABLE :
if ( bfa_fcport_send_disable ( fcport ) )
bfa_sm_set_state ( fcport , bfa_fcport_sm_disabling ) ;
else
bfa_sm_set_state ( fcport ,
bfa_fcport_sm_disabling_qwait ) ;
bfa_plog_str ( fcport - > bfa - > plog , BFA_PL_MID_HAL ,
BFA_PL_EID_PORT_DISABLE , 0 , " Port Disable " ) ;
wwn2str ( pwwn_buf , fcport - > pwwn ) ;
2010-12-10 04:11:53 +03:00
BFA_LOG ( KERN_INFO , bfad , bfa_log_level ,
2010-09-15 22:50:55 +04:00
" Base port disabled: WWN = %s \n " , pwwn_buf ) ;
2011-07-21 03:59:13 +04:00
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_DISABLE ) ;
2010-09-15 22:50:55 +04:00
break ;
case BFA_FCPORT_SM_STOP :
bfa_sm_set_state ( fcport , bfa_fcport_sm_stopped ) ;
break ;
case BFA_FCPORT_SM_HWFAIL :
bfa_sm_set_state ( fcport , bfa_fcport_sm_iocdown ) ;
break ;
2012-09-22 04:26:18 +04:00
case BFA_FCPORT_SM_FAA_MISCONFIG :
bfa_fcport_reset_linkinfo ( fcport ) ;
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_DISCONNECT ) ;
bfa_sm_set_state ( fcport , bfa_fcport_sm_faa_misconfig ) ;
break ;
2010-09-15 22:50:55 +04:00
default :
bfa_sm_fault ( fcport - > bfa , event ) ;
}
}
static void
bfa_fcport_sm_linkup ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event )
{
char pwwn_buf [ BFA_STRING_32 ] ;
struct bfad_s * bfad = ( struct bfad_s * ) fcport - > bfa - > bfad ;
bfa_trc ( fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_SM_ENABLE :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Already enabled .
*/
break ;
case BFA_FCPORT_SM_DISABLE :
if ( bfa_fcport_send_disable ( fcport ) )
bfa_sm_set_state ( fcport , bfa_fcport_sm_disabling ) ;
else
bfa_sm_set_state ( fcport ,
bfa_fcport_sm_disabling_qwait ) ;
bfa_fcport_reset_linkinfo ( fcport ) ;
bfa_fcport_scn ( fcport , BFA_PORT_LINKDOWN , BFA_FALSE ) ;
bfa_plog_str ( fcport - > bfa - > plog , BFA_PL_MID_HAL ,
BFA_PL_EID_PORT_DISABLE , 0 , " Port Disable " ) ;
wwn2str ( pwwn_buf , fcport - > pwwn ) ;
2010-12-10 04:11:53 +03:00
BFA_LOG ( KERN_INFO , bfad , bfa_log_level ,
2010-09-15 22:50:55 +04:00
" Base port offline: WWN = %s \n " , pwwn_buf ) ;
2011-07-21 03:59:13 +04:00
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_OFFLINE ) ;
2010-12-10 04:11:53 +03:00
BFA_LOG ( KERN_INFO , bfad , bfa_log_level ,
2010-09-15 22:50:55 +04:00
" Base port disabled: WWN = %s \n " , pwwn_buf ) ;
2011-07-21 03:59:13 +04:00
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_DISABLE ) ;
2010-09-15 22:50:55 +04:00
break ;
case BFA_FCPORT_SM_LINKDOWN :
bfa_sm_set_state ( fcport , bfa_fcport_sm_linkdown ) ;
bfa_fcport_reset_linkinfo ( fcport ) ;
bfa_fcport_scn ( fcport , BFA_PORT_LINKDOWN , BFA_FALSE ) ;
bfa_plog_str ( fcport - > bfa - > plog , BFA_PL_MID_HAL ,
BFA_PL_EID_PORT_ST_CHANGE , 0 , " Port Linkdown " ) ;
wwn2str ( pwwn_buf , fcport - > pwwn ) ;
2011-07-21 03:59:13 +04:00
if ( BFA_PORT_IS_DISABLED ( fcport - > bfa ) ) {
2010-12-10 04:11:53 +03:00
BFA_LOG ( KERN_INFO , bfad , bfa_log_level ,
2010-09-15 22:50:55 +04:00
" Base port offline: WWN = %s \n " , pwwn_buf ) ;
2011-07-21 03:59:13 +04:00
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_OFFLINE ) ;
} else {
2010-12-10 04:11:53 +03:00
BFA_LOG ( KERN_ERR , bfad , bfa_log_level ,
2010-09-15 22:50:55 +04:00
" Base port (WWN = %s) "
" lost fabric connectivity \n " , pwwn_buf ) ;
2011-07-21 03:59:13 +04:00
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_DISCONNECT ) ;
}
2010-09-15 22:50:55 +04:00
break ;
case BFA_FCPORT_SM_STOP :
bfa_sm_set_state ( fcport , bfa_fcport_sm_stopped ) ;
bfa_fcport_reset_linkinfo ( fcport ) ;
wwn2str ( pwwn_buf , fcport - > pwwn ) ;
2011-07-21 03:59:13 +04:00
if ( BFA_PORT_IS_DISABLED ( fcport - > bfa ) ) {
2010-12-10 04:11:53 +03:00
BFA_LOG ( KERN_INFO , bfad , bfa_log_level ,
2010-09-15 22:50:55 +04:00
" Base port offline: WWN = %s \n " , pwwn_buf ) ;
2011-07-21 03:59:13 +04:00
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_OFFLINE ) ;
} else {
2010-12-10 04:11:53 +03:00
BFA_LOG ( KERN_ERR , bfad , bfa_log_level ,
2010-09-15 22:50:55 +04:00
" Base port (WWN = %s) "
" lost fabric connectivity \n " , pwwn_buf ) ;
2011-07-21 03:59:13 +04:00
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_DISCONNECT ) ;
}
2010-09-15 22:50:55 +04:00
break ;
case BFA_FCPORT_SM_HWFAIL :
bfa_sm_set_state ( fcport , bfa_fcport_sm_iocdown ) ;
bfa_fcport_reset_linkinfo ( fcport ) ;
bfa_fcport_scn ( fcport , BFA_PORT_LINKDOWN , BFA_FALSE ) ;
wwn2str ( pwwn_buf , fcport - > pwwn ) ;
2011-07-21 03:59:13 +04:00
if ( BFA_PORT_IS_DISABLED ( fcport - > bfa ) ) {
2010-12-10 04:11:53 +03:00
BFA_LOG ( KERN_INFO , bfad , bfa_log_level ,
2010-09-15 22:50:55 +04:00
" Base port offline: WWN = %s \n " , pwwn_buf ) ;
2011-07-21 03:59:13 +04:00
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_OFFLINE ) ;
} else {
2010-12-10 04:11:53 +03:00
BFA_LOG ( KERN_ERR , bfad , bfa_log_level ,
2010-09-15 22:50:55 +04:00
" Base port (WWN = %s) "
" lost fabric connectivity \n " , pwwn_buf ) ;
2011-07-21 03:59:13 +04:00
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_DISCONNECT ) ;
}
2010-09-15 22:50:55 +04:00
break ;
2012-09-22 04:26:18 +04:00
case BFA_FCPORT_SM_FAA_MISCONFIG :
bfa_fcport_reset_linkinfo ( fcport ) ;
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_DISCONNECT ) ;
bfa_sm_set_state ( fcport , bfa_fcport_sm_faa_misconfig ) ;
break ;
2010-09-15 22:50:55 +04:00
default :
bfa_sm_fault ( fcport - > bfa , event ) ;
}
}
static void
bfa_fcport_sm_disabling_qwait ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event )
{
bfa_trc ( fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_SM_QRESUME :
bfa_sm_set_state ( fcport , bfa_fcport_sm_disabling ) ;
bfa_fcport_send_disable ( fcport ) ;
break ;
case BFA_FCPORT_SM_STOP :
bfa_sm_set_state ( fcport , bfa_fcport_sm_stopped ) ;
bfa_reqq_wcancel ( & fcport - > reqq_wait ) ;
break ;
case BFA_FCPORT_SM_ENABLE :
bfa_sm_set_state ( fcport , bfa_fcport_sm_toggling_qwait ) ;
break ;
case BFA_FCPORT_SM_DISABLE :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Already being disabled .
*/
break ;
case BFA_FCPORT_SM_LINKUP :
case BFA_FCPORT_SM_LINKDOWN :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Possible to get link events when doing back - to - back
* enable / disables .
*/
break ;
case BFA_FCPORT_SM_HWFAIL :
bfa_sm_set_state ( fcport , bfa_fcport_sm_iocfail ) ;
bfa_reqq_wcancel ( & fcport - > reqq_wait ) ;
break ;
2012-09-22 04:26:18 +04:00
case BFA_FCPORT_SM_FAA_MISCONFIG :
bfa_fcport_reset_linkinfo ( fcport ) ;
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_DISCONNECT ) ;
bfa_sm_set_state ( fcport , bfa_fcport_sm_faa_misconfig ) ;
break ;
2010-09-15 22:50:55 +04:00
default :
bfa_sm_fault ( fcport - > bfa , event ) ;
}
}
static void
bfa_fcport_sm_toggling_qwait ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event )
{
bfa_trc ( fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_SM_QRESUME :
bfa_sm_set_state ( fcport , bfa_fcport_sm_disabling ) ;
bfa_fcport_send_disable ( fcport ) ;
if ( bfa_fcport_send_enable ( fcport ) )
bfa_sm_set_state ( fcport , bfa_fcport_sm_enabling ) ;
else
bfa_sm_set_state ( fcport ,
bfa_fcport_sm_enabling_qwait ) ;
break ;
case BFA_FCPORT_SM_STOP :
bfa_sm_set_state ( fcport , bfa_fcport_sm_stopped ) ;
bfa_reqq_wcancel ( & fcport - > reqq_wait ) ;
break ;
case BFA_FCPORT_SM_ENABLE :
break ;
case BFA_FCPORT_SM_DISABLE :
bfa_sm_set_state ( fcport , bfa_fcport_sm_disabling_qwait ) ;
break ;
case BFA_FCPORT_SM_LINKUP :
case BFA_FCPORT_SM_LINKDOWN :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Possible to get link events when doing back - to - back
* enable / disables .
*/
break ;
case BFA_FCPORT_SM_HWFAIL :
bfa_sm_set_state ( fcport , bfa_fcport_sm_iocfail ) ;
bfa_reqq_wcancel ( & fcport - > reqq_wait ) ;
break ;
default :
bfa_sm_fault ( fcport - > bfa , event ) ;
}
}
static void
bfa_fcport_sm_disabling ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event )
{
char pwwn_buf [ BFA_STRING_32 ] ;
struct bfad_s * bfad = ( struct bfad_s * ) fcport - > bfa - > bfad ;
bfa_trc ( fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_SM_FWRSP :
bfa_sm_set_state ( fcport , bfa_fcport_sm_disabled ) ;
break ;
case BFA_FCPORT_SM_DISABLE :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Already being disabled .
*/
break ;
case BFA_FCPORT_SM_ENABLE :
if ( bfa_fcport_send_enable ( fcport ) )
bfa_sm_set_state ( fcport , bfa_fcport_sm_enabling ) ;
else
bfa_sm_set_state ( fcport ,
bfa_fcport_sm_enabling_qwait ) ;
bfa_plog_str ( fcport - > bfa - > plog , BFA_PL_MID_HAL ,
BFA_PL_EID_PORT_ENABLE , 0 , " Port Enable " ) ;
wwn2str ( pwwn_buf , fcport - > pwwn ) ;
2010-12-10 04:11:53 +03:00
BFA_LOG ( KERN_INFO , bfad , bfa_log_level ,
2010-09-15 22:50:55 +04:00
" Base port enabled: WWN = %s \n " , pwwn_buf ) ;
2011-07-21 03:59:13 +04:00
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_ENABLE ) ;
2010-09-15 22:50:55 +04:00
break ;
case BFA_FCPORT_SM_STOP :
bfa_sm_set_state ( fcport , bfa_fcport_sm_stopped ) ;
break ;
case BFA_FCPORT_SM_LINKUP :
case BFA_FCPORT_SM_LINKDOWN :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Possible to get link events when doing back - to - back
* enable / disables .
*/
break ;
case BFA_FCPORT_SM_HWFAIL :
bfa_sm_set_state ( fcport , bfa_fcport_sm_iocfail ) ;
break ;
default :
bfa_sm_fault ( fcport - > bfa , event ) ;
}
}
static void
bfa_fcport_sm_disabled ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event )
{
char pwwn_buf [ BFA_STRING_32 ] ;
struct bfad_s * bfad = ( struct bfad_s * ) fcport - > bfa - > bfad ;
bfa_trc ( fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_SM_START :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Ignore start event for a port that is disabled .
*/
break ;
case BFA_FCPORT_SM_STOP :
bfa_sm_set_state ( fcport , bfa_fcport_sm_stopped ) ;
break ;
case BFA_FCPORT_SM_ENABLE :
if ( bfa_fcport_send_enable ( fcport ) )
bfa_sm_set_state ( fcport , bfa_fcport_sm_enabling ) ;
else
bfa_sm_set_state ( fcport ,
bfa_fcport_sm_enabling_qwait ) ;
bfa_plog_str ( fcport - > bfa - > plog , BFA_PL_MID_HAL ,
BFA_PL_EID_PORT_ENABLE , 0 , " Port Enable " ) ;
wwn2str ( pwwn_buf , fcport - > pwwn ) ;
2010-12-10 04:11:53 +03:00
BFA_LOG ( KERN_INFO , bfad , bfa_log_level ,
2010-09-15 22:50:55 +04:00
" Base port enabled: WWN = %s \n " , pwwn_buf ) ;
2011-07-21 03:59:13 +04:00
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_ENABLE ) ;
2010-09-15 22:50:55 +04:00
break ;
case BFA_FCPORT_SM_DISABLE :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Already disabled .
*/
break ;
case BFA_FCPORT_SM_HWFAIL :
bfa_sm_set_state ( fcport , bfa_fcport_sm_iocfail ) ;
break ;
2012-09-22 04:26:07 +04:00
case BFA_FCPORT_SM_DPORTENABLE :
bfa_sm_set_state ( fcport , bfa_fcport_sm_dport ) ;
break ;
2013-05-13 13:33:21 +04:00
case BFA_FCPORT_SM_DDPORTENABLE :
bfa_sm_set_state ( fcport , bfa_fcport_sm_ddport ) ;
break ;
2010-09-15 22:50:55 +04:00
default :
bfa_sm_fault ( fcport - > bfa , event ) ;
}
}
static void
bfa_fcport_sm_stopped ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event )
{
bfa_trc ( fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_SM_START :
if ( bfa_fcport_send_enable ( fcport ) )
bfa_sm_set_state ( fcport , bfa_fcport_sm_enabling ) ;
else
bfa_sm_set_state ( fcport ,
bfa_fcport_sm_enabling_qwait ) ;
break ;
default :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Ignore all other events .
*/
;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Port is enabled . IOC is down / failed .
*/
static void
bfa_fcport_sm_iocdown ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event )
{
bfa_trc ( fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_SM_START :
if ( bfa_fcport_send_enable ( fcport ) )
bfa_sm_set_state ( fcport , bfa_fcport_sm_enabling ) ;
else
bfa_sm_set_state ( fcport ,
bfa_fcport_sm_enabling_qwait ) ;
break ;
default :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Ignore all events .
*/
;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Port is disabled . IOC is down / failed .
*/
static void
bfa_fcport_sm_iocfail ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event )
{
bfa_trc ( fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_SM_START :
bfa_sm_set_state ( fcport , bfa_fcport_sm_disabled ) ;
break ;
case BFA_FCPORT_SM_ENABLE :
bfa_sm_set_state ( fcport , bfa_fcport_sm_iocdown ) ;
break ;
default :
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Ignore all events .
*/
;
}
}
2012-09-22 04:26:07 +04:00
static void
bfa_fcport_sm_dport ( struct bfa_fcport_s * fcport , enum bfa_fcport_sm_event event )
{
bfa_trc ( fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_SM_DPORTENABLE :
case BFA_FCPORT_SM_DISABLE :
case BFA_FCPORT_SM_ENABLE :
case BFA_FCPORT_SM_START :
/*
* Ignore event for a port that is dport
*/
break ;
case BFA_FCPORT_SM_STOP :
bfa_sm_set_state ( fcport , bfa_fcport_sm_stopped ) ;
break ;
case BFA_FCPORT_SM_HWFAIL :
bfa_sm_set_state ( fcport , bfa_fcport_sm_iocfail ) ;
break ;
case BFA_FCPORT_SM_DPORTDISABLE :
bfa_sm_set_state ( fcport , bfa_fcport_sm_disabled ) ;
break ;
default :
bfa_sm_fault ( fcport - > bfa , event ) ;
}
}
2013-05-13 13:33:21 +04:00
static void
bfa_fcport_sm_ddport ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event )
{
bfa_trc ( fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_SM_DISABLE :
case BFA_FCPORT_SM_DDPORTDISABLE :
bfa_sm_set_state ( fcport , bfa_fcport_sm_disabled ) ;
break ;
case BFA_FCPORT_SM_DPORTENABLE :
case BFA_FCPORT_SM_DPORTDISABLE :
case BFA_FCPORT_SM_ENABLE :
case BFA_FCPORT_SM_START :
/**
* Ignore event for a port that is ddport
*/
break ;
case BFA_FCPORT_SM_STOP :
bfa_sm_set_state ( fcport , bfa_fcport_sm_stopped ) ;
break ;
case BFA_FCPORT_SM_HWFAIL :
bfa_sm_set_state ( fcport , bfa_fcport_sm_iocfail ) ;
break ;
default :
bfa_sm_fault ( fcport - > bfa , event ) ;
}
}
2012-09-22 04:26:18 +04:00
static void
bfa_fcport_sm_faa_misconfig ( struct bfa_fcport_s * fcport ,
enum bfa_fcport_sm_event event )
{
bfa_trc ( fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_SM_DPORTENABLE :
case BFA_FCPORT_SM_ENABLE :
case BFA_FCPORT_SM_START :
/*
* Ignore event for a port as there is FAA misconfig
*/
break ;
case BFA_FCPORT_SM_DISABLE :
if ( bfa_fcport_send_disable ( fcport ) )
bfa_sm_set_state ( fcport , bfa_fcport_sm_disabling ) ;
else
bfa_sm_set_state ( fcport , bfa_fcport_sm_disabling_qwait ) ;
bfa_fcport_reset_linkinfo ( fcport ) ;
bfa_fcport_scn ( fcport , BFA_PORT_LINKDOWN , BFA_FALSE ) ;
bfa_plog_str ( fcport - > bfa - > plog , BFA_PL_MID_HAL ,
BFA_PL_EID_PORT_DISABLE , 0 , " Port Disable " ) ;
bfa_fcport_aen_post ( fcport , BFA_PORT_AEN_DISABLE ) ;
break ;
case BFA_FCPORT_SM_STOP :
bfa_sm_set_state ( fcport , bfa_fcport_sm_stopped ) ;
break ;
case BFA_FCPORT_SM_HWFAIL :
bfa_fcport_reset_linkinfo ( fcport ) ;
bfa_fcport_scn ( fcport , BFA_PORT_LINKDOWN , BFA_FALSE ) ;
bfa_sm_set_state ( fcport , bfa_fcport_sm_iocdown ) ;
break ;
default :
bfa_sm_fault ( fcport - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Link state is down
*/
static void
bfa_fcport_ln_sm_dn ( struct bfa_fcport_ln_s * ln ,
enum bfa_fcport_ln_sm_event event )
{
bfa_trc ( ln - > fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_LN_SM_LINKUP :
bfa_sm_set_state ( ln , bfa_fcport_ln_sm_up_nf ) ;
bfa_fcport_queue_cb ( ln , BFA_PORT_LINKUP ) ;
break ;
default :
bfa_sm_fault ( ln - > fcport - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Link state is waiting for down notification
*/
static void
bfa_fcport_ln_sm_dn_nf ( struct bfa_fcport_ln_s * ln ,
enum bfa_fcport_ln_sm_event event )
{
bfa_trc ( ln - > fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_LN_SM_LINKUP :
bfa_sm_set_state ( ln , bfa_fcport_ln_sm_dn_up_nf ) ;
break ;
case BFA_FCPORT_LN_SM_NOTIFICATION :
bfa_sm_set_state ( ln , bfa_fcport_ln_sm_dn ) ;
break ;
default :
bfa_sm_fault ( ln - > fcport - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Link state is waiting for down notification and there is a pending up
*/
static void
bfa_fcport_ln_sm_dn_up_nf ( struct bfa_fcport_ln_s * ln ,
enum bfa_fcport_ln_sm_event event )
{
bfa_trc ( ln - > fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_LN_SM_LINKDOWN :
bfa_sm_set_state ( ln , bfa_fcport_ln_sm_dn_nf ) ;
break ;
case BFA_FCPORT_LN_SM_NOTIFICATION :
bfa_sm_set_state ( ln , bfa_fcport_ln_sm_up_nf ) ;
bfa_fcport_queue_cb ( ln , BFA_PORT_LINKUP ) ;
break ;
default :
bfa_sm_fault ( ln - > fcport - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Link state is up
*/
static void
bfa_fcport_ln_sm_up ( struct bfa_fcport_ln_s * ln ,
enum bfa_fcport_ln_sm_event event )
{
bfa_trc ( ln - > fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_LN_SM_LINKDOWN :
bfa_sm_set_state ( ln , bfa_fcport_ln_sm_dn_nf ) ;
bfa_fcport_queue_cb ( ln , BFA_PORT_LINKDOWN ) ;
break ;
default :
bfa_sm_fault ( ln - > fcport - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Link state is waiting for up notification
*/
static void
bfa_fcport_ln_sm_up_nf ( struct bfa_fcport_ln_s * ln ,
enum bfa_fcport_ln_sm_event event )
{
bfa_trc ( ln - > fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_LN_SM_LINKDOWN :
bfa_sm_set_state ( ln , bfa_fcport_ln_sm_up_dn_nf ) ;
break ;
case BFA_FCPORT_LN_SM_NOTIFICATION :
bfa_sm_set_state ( ln , bfa_fcport_ln_sm_up ) ;
break ;
default :
bfa_sm_fault ( ln - > fcport - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Link state is waiting for up notification and there is a pending down
*/
static void
bfa_fcport_ln_sm_up_dn_nf ( struct bfa_fcport_ln_s * ln ,
enum bfa_fcport_ln_sm_event event )
{
bfa_trc ( ln - > fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_LN_SM_LINKUP :
bfa_sm_set_state ( ln , bfa_fcport_ln_sm_up_dn_up_nf ) ;
break ;
case BFA_FCPORT_LN_SM_NOTIFICATION :
bfa_sm_set_state ( ln , bfa_fcport_ln_sm_dn_nf ) ;
bfa_fcport_queue_cb ( ln , BFA_PORT_LINKDOWN ) ;
break ;
default :
bfa_sm_fault ( ln - > fcport - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Link state is waiting for up notification and there are pending down and up
*/
static void
bfa_fcport_ln_sm_up_dn_up_nf ( struct bfa_fcport_ln_s * ln ,
enum bfa_fcport_ln_sm_event event )
{
bfa_trc ( ln - > fcport - > bfa , event ) ;
switch ( event ) {
case BFA_FCPORT_LN_SM_LINKDOWN :
bfa_sm_set_state ( ln , bfa_fcport_ln_sm_up_dn_nf ) ;
break ;
case BFA_FCPORT_LN_SM_NOTIFICATION :
bfa_sm_set_state ( ln , bfa_fcport_ln_sm_dn_up_nf ) ;
bfa_fcport_queue_cb ( ln , BFA_PORT_LINKDOWN ) ;
break ;
default :
bfa_sm_fault ( ln - > fcport - > bfa , event ) ;
}
}
static void
__bfa_cb_fcport_event ( void * cbarg , bfa_boolean_t complete )
{
struct bfa_fcport_ln_s * ln = cbarg ;
if ( complete )
ln - > fcport - > event_cbfn ( ln - > fcport - > event_cbarg , ln - > ln_event ) ;
else
bfa_sm_send_event ( ln , BFA_FCPORT_LN_SM_NOTIFICATION ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Send SCN notification to upper layers .
* trunk - false if caller is fcport to ignore fcport event in trunked mode
*/
static void
bfa_fcport_scn ( struct bfa_fcport_s * fcport , enum bfa_port_linkstate event ,
bfa_boolean_t trunk )
{
if ( fcport - > cfg . trunked & & ! trunk )
return ;
switch ( event ) {
case BFA_PORT_LINKUP :
bfa_sm_send_event ( & fcport - > ln , BFA_FCPORT_LN_SM_LINKUP ) ;
break ;
case BFA_PORT_LINKDOWN :
bfa_sm_send_event ( & fcport - > ln , BFA_FCPORT_LN_SM_LINKDOWN ) ;
break ;
default :
2010-12-27 08:46:35 +03:00
WARN_ON ( 1 ) ;
2010-09-15 22:50:55 +04:00
}
}
static void
bfa_fcport_queue_cb ( struct bfa_fcport_ln_s * ln , enum bfa_port_linkstate event )
{
struct bfa_fcport_s * fcport = ln - > fcport ;
if ( fcport - > bfa - > fcs ) {
fcport - > event_cbfn ( fcport - > event_cbarg , event ) ;
bfa_sm_send_event ( ln , BFA_FCPORT_LN_SM_NOTIFICATION ) ;
} else {
ln - > ln_event = event ;
bfa_cb_queue ( fcport - > bfa , & ln - > ln_qe ,
__bfa_cb_fcport_event , ln ) ;
}
}
# define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \
BFA_CACHELINE_SZ ) )
static void
2011-06-25 07:24:29 +04:00
bfa_fcport_meminfo ( struct bfa_iocfc_cfg_s * cfg , struct bfa_meminfo_s * minfo ,
struct bfa_s * bfa )
2010-09-15 22:50:55 +04:00
{
2011-06-25 07:24:29 +04:00
struct bfa_mem_dma_s * fcport_dma = BFA_MEM_FCPORT_DMA ( bfa ) ;
bfa_mem_dma_setup ( minfo , fcport_dma , FCPORT_STATS_DMA_SZ ) ;
2010-09-15 22:50:55 +04:00
}
static void
bfa_fcport_qresume ( void * cbarg )
{
struct bfa_fcport_s * fcport = cbarg ;
bfa_sm_send_event ( fcport , BFA_FCPORT_SM_QRESUME ) ;
}
static void
2011-06-25 07:24:29 +04:00
bfa_fcport_mem_claim ( struct bfa_fcport_s * fcport )
2010-09-15 22:50:55 +04:00
{
2011-06-25 07:24:29 +04:00
struct bfa_mem_dma_s * fcport_dma = & fcport - > fcport_dma ;
2010-09-15 22:50:55 +04:00
2011-06-25 07:24:29 +04:00
fcport - > stats_kva = bfa_mem_dma_virt ( fcport_dma ) ;
fcport - > stats_pa = bfa_mem_dma_phys ( fcport_dma ) ;
fcport - > stats = ( union bfa_fcport_stats_u * )
bfa_mem_dma_virt ( fcport_dma ) ;
2010-09-15 22:50:55 +04:00
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Memory initialization .
*/
static void
bfa_fcport_attach ( struct bfa_s * bfa , void * bfad , struct bfa_iocfc_cfg_s * cfg ,
2011-06-25 07:24:29 +04:00
struct bfa_pcidev_s * pcidev )
2010-09-15 22:50:55 +04:00
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
struct bfa_port_cfg_s * port_cfg = & fcport - > cfg ;
struct bfa_fcport_ln_s * ln = & fcport - > ln ;
2010-12-10 06:12:32 +03:00
struct timeval tv ;
2010-09-15 22:50:55 +04:00
fcport - > bfa = bfa ;
ln - > fcport = fcport ;
2011-06-25 07:24:29 +04:00
bfa_fcport_mem_claim ( fcport ) ;
2010-09-15 22:50:55 +04:00
bfa_sm_set_state ( fcport , bfa_fcport_sm_uninit ) ;
bfa_sm_set_state ( ln , bfa_fcport_ln_sm_dn ) ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* initialize time stamp for stats reset
*/
2010-12-10 06:12:32 +03:00
do_gettimeofday ( & tv ) ;
2010-09-15 22:50:55 +04:00
fcport - > stats_reset_time = tv . tv_sec ;
2012-09-22 04:26:31 +04:00
fcport - > stats_dma_ready = BFA_FALSE ;
2010-09-15 22:50:55 +04:00
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* initialize and set default configuration
*/
port_cfg - > topology = BFA_PORT_TOPOLOGY_P2P ;
port_cfg - > speed = BFA_PORT_SPEED_AUTO ;
port_cfg - > trunked = BFA_FALSE ;
port_cfg - > maxfrsize = 0 ;
port_cfg - > trl_def_speed = BFA_PORT_SPEED_1GBPS ;
2012-09-22 04:26:31 +04:00
port_cfg - > qos_bw . high = BFA_QOS_BW_HIGH ;
port_cfg - > qos_bw . med = BFA_QOS_BW_MED ;
port_cfg - > qos_bw . low = BFA_QOS_BW_LOW ;
2010-09-15 22:50:55 +04:00
2013-05-13 13:33:20 +04:00
fcport - > fec_state = BFA_FEC_OFFLINE ;
2011-07-21 04:02:11 +04:00
INIT_LIST_HEAD ( & fcport - > stats_pending_q ) ;
INIT_LIST_HEAD ( & fcport - > statsclr_pending_q ) ;
2010-09-15 22:50:55 +04:00
bfa_reqq_winit ( & fcport - > reqq_wait , bfa_fcport_qresume , fcport ) ;
}
static void
bfa_fcport_detach ( struct bfa_s * bfa )
{
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Called when IOC is ready .
*/
static void
bfa_fcport_start ( struct bfa_s * bfa )
{
bfa_sm_send_event ( BFA_FCPORT_MOD ( bfa ) , BFA_FCPORT_SM_START ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Called before IOC is stopped .
*/
static void
bfa_fcport_stop ( struct bfa_s * bfa )
{
bfa_sm_send_event ( BFA_FCPORT_MOD ( bfa ) , BFA_FCPORT_SM_STOP ) ;
bfa_trunk_iocdisable ( bfa ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Called when IOC failure is detected .
*/
static void
bfa_fcport_iocdisable ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
bfa_sm_send_event ( fcport , BFA_FCPORT_SM_HWFAIL ) ;
bfa_trunk_iocdisable ( bfa ) ;
}
2012-09-22 04:23:59 +04:00
/*
* Update loop info in fcport for SCN online
*/
static void
bfa_fcport_update_loop_info ( struct bfa_fcport_s * fcport ,
struct bfa_fcport_loop_info_s * loop_info )
{
fcport - > myalpa = loop_info - > myalpa ;
fcport - > alpabm_valid =
loop_info - > alpabm_val ;
memcpy ( fcport - > alpabm . alpa_bm ,
loop_info - > alpabm . alpa_bm ,
sizeof ( struct fc_alpabm_s ) ) ;
}
2010-09-15 22:50:55 +04:00
static void
bfa_fcport_update_linkinfo ( struct bfa_fcport_s * fcport )
{
struct bfi_fcport_event_s * pevent = fcport - > event_arg . i2hmsg . event ;
struct bfa_fcport_trunk_s * trunk = & fcport - > trunk ;
fcport - > speed = pevent - > link_state . speed ;
fcport - > topology = pevent - > link_state . topology ;
2012-09-22 04:23:59 +04:00
if ( fcport - > topology = = BFA_PORT_TOPOLOGY_LOOP ) {
bfa_fcport_update_loop_info ( fcport ,
& pevent - > link_state . attr . loop_info ) ;
return ;
}
2010-09-15 22:50:55 +04:00
/* QoS Details */
2010-10-19 04:08:54 +04:00
fcport - > qos_attr = pevent - > link_state . qos_attr ;
2012-09-22 04:23:59 +04:00
fcport - > qos_vc_attr = pevent - > link_state . attr . vc_fcf . qos_vc_attr ;
2010-09-15 22:50:55 +04:00
2013-05-13 13:33:19 +04:00
if ( fcport - > cfg . bb_cr_enabled )
fcport - > bbcr_attr = pevent - > link_state . attr . bbcr_attr ;
2013-05-13 13:33:20 +04:00
fcport - > fec_state = pevent - > link_state . fec_state ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* update trunk state if applicable
*/
if ( ! fcport - > cfg . trunked )
trunk - > attr . state = BFA_TRUNK_DISABLED ;
/* update FCoE specific */
2012-09-22 04:23:59 +04:00
fcport - > fcoe_vlan =
be16_to_cpu ( pevent - > link_state . attr . vc_fcf . fcf . vlan ) ;
2010-09-15 22:50:55 +04:00
bfa_trc ( fcport - > bfa , fcport - > speed ) ;
bfa_trc ( fcport - > bfa , fcport - > topology ) ;
}
static void
bfa_fcport_reset_linkinfo ( struct bfa_fcport_s * fcport )
{
fcport - > speed = BFA_PORT_SPEED_UNKNOWN ;
fcport - > topology = BFA_PORT_TOPOLOGY_NONE ;
2013-05-13 13:33:20 +04:00
fcport - > fec_state = BFA_FEC_OFFLINE ;
2010-09-15 22:50:55 +04:00
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Send port enable message to firmware .
*/
static bfa_boolean_t
bfa_fcport_send_enable ( struct bfa_fcport_s * fcport )
{
struct bfi_fcport_enable_req_s * m ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Increment message tag before queue check , so that responses to old
* requests are discarded .
*/
fcport - > msgtag + + ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* check for room in queue to send request now
*/
m = bfa_reqq_next ( fcport - > bfa , BFA_REQQ_PORT ) ;
if ( ! m ) {
bfa_reqq_wait ( fcport - > bfa , BFA_REQQ_PORT ,
& fcport - > reqq_wait ) ;
return BFA_FALSE ;
}
bfi_h2i_set ( m - > mh , BFI_MC_FCPORT , BFI_FCPORT_H2I_ENABLE_REQ ,
2011-06-25 07:24:08 +04:00
bfa_fn_lpu ( fcport - > bfa ) ) ;
2010-09-15 22:50:55 +04:00
m - > nwwn = fcport - > nwwn ;
m - > pwwn = fcport - > pwwn ;
m - > port_cfg = fcport - > cfg ;
m - > msgtag = fcport - > msgtag ;
2010-10-19 04:10:50 +04:00
m - > port_cfg . maxfrsize = cpu_to_be16 ( fcport - > cfg . maxfrsize ) ;
2010-12-14 03:16:50 +03:00
m - > use_flash_cfg = fcport - > use_flash_cfg ;
2010-09-15 22:50:55 +04:00
bfa_dma_be_addr_set ( m - > stats_dma_addr , fcport - > stats_pa ) ;
bfa_trc ( fcport - > bfa , m - > stats_dma_addr . a32 . addr_lo ) ;
bfa_trc ( fcport - > bfa , m - > stats_dma_addr . a32 . addr_hi ) ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* queue I / O message to firmware
*/
2011-06-25 07:24:08 +04:00
bfa_reqq_produce ( fcport - > bfa , BFA_REQQ_PORT , m - > mh ) ;
2010-09-15 22:50:55 +04:00
return BFA_TRUE ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Send port disable message to firmware .
*/
static bfa_boolean_t
bfa_fcport_send_disable ( struct bfa_fcport_s * fcport )
{
struct bfi_fcport_req_s * m ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Increment message tag before queue check , so that responses to old
* requests are discarded .
*/
fcport - > msgtag + + ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* check for room in queue to send request now
*/
m = bfa_reqq_next ( fcport - > bfa , BFA_REQQ_PORT ) ;
if ( ! m ) {
bfa_reqq_wait ( fcport - > bfa , BFA_REQQ_PORT ,
& fcport - > reqq_wait ) ;
return BFA_FALSE ;
}
bfi_h2i_set ( m - > mh , BFI_MC_FCPORT , BFI_FCPORT_H2I_DISABLE_REQ ,
2011-06-25 07:24:08 +04:00
bfa_fn_lpu ( fcport - > bfa ) ) ;
2010-09-15 22:50:55 +04:00
m - > msgtag = fcport - > msgtag ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* queue I / O message to firmware
*/
2011-06-25 07:24:08 +04:00
bfa_reqq_produce ( fcport - > bfa , BFA_REQQ_PORT , m - > mh ) ;
2010-09-15 22:50:55 +04:00
return BFA_TRUE ;
}
static void
bfa_fcport_set_wwns ( struct bfa_fcport_s * fcport )
{
2010-12-10 06:08:43 +03:00
fcport - > pwwn = fcport - > bfa - > ioc . attr - > pwwn ;
fcport - > nwwn = fcport - > bfa - > ioc . attr - > nwwn ;
2010-09-15 22:50:55 +04:00
bfa_trc ( fcport - > bfa , fcport - > pwwn ) ;
bfa_trc ( fcport - > bfa , fcport - > nwwn ) ;
}
static void
bfa_fcport_qos_stats_swap ( struct bfa_qos_stats_s * d ,
struct bfa_qos_stats_s * s )
{
u32 * dip = ( u32 * ) d ;
2010-11-30 05:26:32 +03:00
__be32 * sip = ( __be32 * ) s ;
2010-09-15 22:50:55 +04:00
int i ;
/* Now swap the 32 bit fields */
for ( i = 0 ; i < ( sizeof ( struct bfa_qos_stats_s ) / sizeof ( u32 ) ) ; + + i )
2010-10-19 04:10:50 +04:00
dip [ i ] = be32_to_cpu ( sip [ i ] ) ;
2010-09-15 22:50:55 +04:00
}
static void
bfa_fcport_fcoe_stats_swap ( struct bfa_fcoe_stats_s * d ,
struct bfa_fcoe_stats_s * s )
{
u32 * dip = ( u32 * ) d ;
2010-11-30 05:26:32 +03:00
__be32 * sip = ( __be32 * ) s ;
2010-09-15 22:50:55 +04:00
int i ;
for ( i = 0 ; i < ( ( sizeof ( struct bfa_fcoe_stats_s ) ) / sizeof ( u32 ) ) ;
i = i + 2 ) {
2010-12-10 06:12:32 +03:00
# ifdef __BIG_ENDIAN
2010-10-19 04:10:50 +04:00
dip [ i ] = be32_to_cpu ( sip [ i ] ) ;
dip [ i + 1 ] = be32_to_cpu ( sip [ i + 1 ] ) ;
2010-09-15 22:50:55 +04:00
# else
2010-10-19 04:10:50 +04:00
dip [ i ] = be32_to_cpu ( sip [ i + 1 ] ) ;
dip [ i + 1 ] = be32_to_cpu ( sip [ i ] ) ;
2010-09-15 22:50:55 +04:00
# endif
}
}
static void
__bfa_cb_fcport_stats_get ( void * cbarg , bfa_boolean_t complete )
{
2011-07-21 04:02:11 +04:00
struct bfa_fcport_s * fcport = ( struct bfa_fcport_s * ) cbarg ;
struct bfa_cb_pending_q_s * cb ;
struct list_head * qe , * qen ;
union bfa_fcport_stats_u * ret ;
2010-09-15 22:50:55 +04:00
if ( complete ) {
2011-07-21 04:02:11 +04:00
struct timeval tv ;
if ( fcport - > stats_status = = BFA_STATUS_OK )
do_gettimeofday ( & tv ) ;
list_for_each_safe ( qe , qen , & fcport - > stats_pending_q ) {
bfa_q_deq ( & fcport - > stats_pending_q , & qe ) ;
cb = ( struct bfa_cb_pending_q_s * ) qe ;
if ( fcport - > stats_status = = BFA_STATUS_OK ) {
ret = ( union bfa_fcport_stats_u * ) cb - > data ;
/* Swap FC QoS or FCoE stats */
if ( bfa_ioc_get_fcmode ( & fcport - > bfa - > ioc ) )
bfa_fcport_qos_stats_swap ( & ret - > fcqos ,
& fcport - > stats - > fcqos ) ;
else {
bfa_fcport_fcoe_stats_swap ( & ret - > fcoe ,
& fcport - > stats - > fcoe ) ;
ret - > fcoe . secs_reset =
2010-09-15 22:50:55 +04:00
tv . tv_sec - fcport - > stats_reset_time ;
2011-07-21 04:02:11 +04:00
}
2010-09-15 22:50:55 +04:00
}
2011-07-21 04:02:11 +04:00
bfa_cb_queue_status ( fcport - > bfa , & cb - > hcb_qe ,
fcport - > stats_status ) ;
2010-09-15 22:50:55 +04:00
}
2011-07-21 04:02:11 +04:00
fcport - > stats_status = BFA_STATUS_OK ;
2010-09-15 22:50:55 +04:00
} else {
2011-07-21 04:02:11 +04:00
INIT_LIST_HEAD ( & fcport - > stats_pending_q ) ;
2010-09-15 22:50:55 +04:00
fcport - > stats_status = BFA_STATUS_OK ;
}
}
static void
bfa_fcport_stats_get_timeout ( void * cbarg )
{
struct bfa_fcport_s * fcport = ( struct bfa_fcport_s * ) cbarg ;
bfa_trc ( fcport - > bfa , fcport - > stats_qfull ) ;
if ( fcport - > stats_qfull ) {
bfa_reqq_wcancel ( & fcport - > stats_reqq_wait ) ;
fcport - > stats_qfull = BFA_FALSE ;
}
fcport - > stats_status = BFA_STATUS_ETIMER ;
2011-07-21 04:02:11 +04:00
__bfa_cb_fcport_stats_get ( fcport , BFA_TRUE ) ;
2010-09-15 22:50:55 +04:00
}
static void
bfa_fcport_send_stats_get ( void * cbarg )
{
struct bfa_fcport_s * fcport = ( struct bfa_fcport_s * ) cbarg ;
struct bfi_fcport_req_s * msg ;
msg = bfa_reqq_next ( fcport - > bfa , BFA_REQQ_PORT ) ;
if ( ! msg ) {
fcport - > stats_qfull = BFA_TRUE ;
bfa_reqq_winit ( & fcport - > stats_reqq_wait ,
bfa_fcport_send_stats_get , fcport ) ;
bfa_reqq_wait ( fcport - > bfa , BFA_REQQ_PORT ,
& fcport - > stats_reqq_wait ) ;
return ;
}
fcport - > stats_qfull = BFA_FALSE ;
2010-10-19 04:08:54 +04:00
memset ( msg , 0 , sizeof ( struct bfi_fcport_req_s ) ) ;
2010-09-15 22:50:55 +04:00
bfi_h2i_set ( msg - > mh , BFI_MC_FCPORT , BFI_FCPORT_H2I_STATS_GET_REQ ,
2011-06-25 07:24:08 +04:00
bfa_fn_lpu ( fcport - > bfa ) ) ;
bfa_reqq_produce ( fcport - > bfa , BFA_REQQ_PORT , msg - > mh ) ;
2010-09-15 22:50:55 +04:00
}
static void
__bfa_cb_fcport_stats_clr ( void * cbarg , bfa_boolean_t complete )
{
2011-07-21 04:02:11 +04:00
struct bfa_fcport_s * fcport = ( struct bfa_fcport_s * ) cbarg ;
struct bfa_cb_pending_q_s * cb ;
struct list_head * qe , * qen ;
2010-09-15 22:50:55 +04:00
if ( complete ) {
2010-12-10 06:12:32 +03:00
struct timeval tv ;
2010-09-15 22:50:55 +04:00
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* re - initialize time stamp for stats reset
*/
2010-12-10 06:12:32 +03:00
do_gettimeofday ( & tv ) ;
2010-09-15 22:50:55 +04:00
fcport - > stats_reset_time = tv . tv_sec ;
2011-07-21 04:02:11 +04:00
list_for_each_safe ( qe , qen , & fcport - > statsclr_pending_q ) {
bfa_q_deq ( & fcport - > statsclr_pending_q , & qe ) ;
cb = ( struct bfa_cb_pending_q_s * ) qe ;
bfa_cb_queue_status ( fcport - > bfa , & cb - > hcb_qe ,
fcport - > stats_status ) ;
}
fcport - > stats_status = BFA_STATUS_OK ;
2010-09-15 22:50:55 +04:00
} else {
2011-07-21 04:02:11 +04:00
INIT_LIST_HEAD ( & fcport - > statsclr_pending_q ) ;
2010-09-15 22:50:55 +04:00
fcport - > stats_status = BFA_STATUS_OK ;
}
}
static void
bfa_fcport_stats_clr_timeout ( void * cbarg )
{
struct bfa_fcport_s * fcport = ( struct bfa_fcport_s * ) cbarg ;
bfa_trc ( fcport - > bfa , fcport - > stats_qfull ) ;
if ( fcport - > stats_qfull ) {
bfa_reqq_wcancel ( & fcport - > stats_reqq_wait ) ;
fcport - > stats_qfull = BFA_FALSE ;
}
fcport - > stats_status = BFA_STATUS_ETIMER ;
2011-07-21 04:02:11 +04:00
__bfa_cb_fcport_stats_clr ( fcport , BFA_TRUE ) ;
2010-09-15 22:50:55 +04:00
}
static void
bfa_fcport_send_stats_clear ( void * cbarg )
{
struct bfa_fcport_s * fcport = ( struct bfa_fcport_s * ) cbarg ;
struct bfi_fcport_req_s * msg ;
msg = bfa_reqq_next ( fcport - > bfa , BFA_REQQ_PORT ) ;
if ( ! msg ) {
fcport - > stats_qfull = BFA_TRUE ;
bfa_reqq_winit ( & fcport - > stats_reqq_wait ,
bfa_fcport_send_stats_clear , fcport ) ;
bfa_reqq_wait ( fcport - > bfa , BFA_REQQ_PORT ,
& fcport - > stats_reqq_wait ) ;
return ;
}
fcport - > stats_qfull = BFA_FALSE ;
2010-10-19 04:08:54 +04:00
memset ( msg , 0 , sizeof ( struct bfi_fcport_req_s ) ) ;
2010-09-15 22:50:55 +04:00
bfi_h2i_set ( msg - > mh , BFI_MC_FCPORT , BFI_FCPORT_H2I_STATS_CLEAR_REQ ,
2011-06-25 07:24:08 +04:00
bfa_fn_lpu ( fcport - > bfa ) ) ;
bfa_reqq_produce ( fcport - > bfa , BFA_REQQ_PORT , msg - > mh ) ;
2010-09-15 22:50:55 +04:00
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Handle trunk SCN event from firmware .
*/
static void
bfa_trunk_scn ( struct bfa_fcport_s * fcport , struct bfi_fcport_trunk_scn_s * scn )
{
struct bfa_fcport_trunk_s * trunk = & fcport - > trunk ;
struct bfi_fcport_trunk_link_s * tlink ;
struct bfa_trunk_link_attr_s * lattr ;
enum bfa_trunk_state state_prev ;
int i ;
int link_bm = 0 ;
bfa_trc ( fcport - > bfa , fcport - > cfg . trunked ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( scn - > trunk_state ! = BFA_TRUNK_ONLINE & &
scn - > trunk_state ! = BFA_TRUNK_OFFLINE ) ;
2010-09-15 22:50:55 +04:00
bfa_trc ( fcport - > bfa , trunk - > attr . state ) ;
bfa_trc ( fcport - > bfa , scn - > trunk_state ) ;
bfa_trc ( fcport - > bfa , scn - > trunk_speed ) ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Save off new state for trunk attribute query
*/
state_prev = trunk - > attr . state ;
if ( fcport - > cfg . trunked & & ( trunk - > attr . state ! = BFA_TRUNK_DISABLED ) )
trunk - > attr . state = scn - > trunk_state ;
trunk - > attr . speed = scn - > trunk_speed ;
for ( i = 0 ; i < BFA_TRUNK_MAX_PORTS ; i + + ) {
lattr = & trunk - > attr . link_attr [ i ] ;
tlink = & scn - > tlink [ i ] ;
lattr - > link_state = tlink - > state ;
lattr - > trunk_wwn = tlink - > trunk_wwn ;
lattr - > fctl = tlink - > fctl ;
lattr - > speed = tlink - > speed ;
2010-10-19 04:10:50 +04:00
lattr - > deskew = be32_to_cpu ( tlink - > deskew ) ;
2010-09-15 22:50:55 +04:00
if ( tlink - > state = = BFA_TRUNK_LINK_STATE_UP ) {
fcport - > speed = tlink - > speed ;
fcport - > topology = BFA_PORT_TOPOLOGY_P2P ;
link_bm | = 1 < < i ;
}
bfa_trc ( fcport - > bfa , lattr - > link_state ) ;
bfa_trc ( fcport - > bfa , lattr - > trunk_wwn ) ;
bfa_trc ( fcport - > bfa , lattr - > fctl ) ;
bfa_trc ( fcport - > bfa , lattr - > speed ) ;
bfa_trc ( fcport - > bfa , lattr - > deskew ) ;
}
switch ( link_bm ) {
case 3 :
bfa_plog_str ( fcport - > bfa - > plog , BFA_PL_MID_HAL ,
BFA_PL_EID_TRUNK_SCN , 0 , " Trunk up(0,1) " ) ;
break ;
case 2 :
bfa_plog_str ( fcport - > bfa - > plog , BFA_PL_MID_HAL ,
BFA_PL_EID_TRUNK_SCN , 0 , " Trunk up(-,1) " ) ;
break ;
case 1 :
bfa_plog_str ( fcport - > bfa - > plog , BFA_PL_MID_HAL ,
BFA_PL_EID_TRUNK_SCN , 0 , " Trunk up(0,-) " ) ;
break ;
default :
bfa_plog_str ( fcport - > bfa - > plog , BFA_PL_MID_HAL ,
BFA_PL_EID_TRUNK_SCN , 0 , " Trunk down " ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Notify upper layers if trunk state changed .
*/
if ( ( state_prev ! = trunk - > attr . state ) | |
( scn - > trunk_state = = BFA_TRUNK_OFFLINE ) ) {
bfa_fcport_scn ( fcport , ( scn - > trunk_state = = BFA_TRUNK_ONLINE ) ?
BFA_PORT_LINKUP : BFA_PORT_LINKDOWN , BFA_TRUE ) ;
}
}
static void
bfa_trunk_iocdisable ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
int i = 0 ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* In trunked mode , notify upper layers that link is down
*/
if ( fcport - > cfg . trunked ) {
if ( fcport - > trunk . attr . state = = BFA_TRUNK_ONLINE )
bfa_fcport_scn ( fcport , BFA_PORT_LINKDOWN , BFA_TRUE ) ;
fcport - > trunk . attr . state = BFA_TRUNK_OFFLINE ;
fcport - > trunk . attr . speed = BFA_PORT_SPEED_UNKNOWN ;
for ( i = 0 ; i < BFA_TRUNK_MAX_PORTS ; i + + ) {
fcport - > trunk . attr . link_attr [ i ] . trunk_wwn = 0 ;
fcport - > trunk . attr . link_attr [ i ] . fctl =
BFA_TRUNK_LINK_FCTL_NORMAL ;
fcport - > trunk . attr . link_attr [ i ] . link_state =
BFA_TRUNK_LINK_STATE_DN_LINKDN ;
fcport - > trunk . attr . link_attr [ i ] . speed =
BFA_PORT_SPEED_UNKNOWN ;
fcport - > trunk . attr . link_attr [ i ] . deskew = 0 ;
}
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Called to initialize port attributes
*/
void
bfa_fcport_init ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Initialize port attributes from IOC hardware data .
*/
bfa_fcport_set_wwns ( fcport ) ;
if ( fcport - > cfg . maxfrsize = = 0 )
fcport - > cfg . maxfrsize = bfa_ioc_maxfrsize ( & bfa - > ioc ) ;
fcport - > cfg . rx_bbcredit = bfa_ioc_rx_bbcredit ( & bfa - > ioc ) ;
fcport - > speed_sup = bfa_ioc_speed_sup ( & bfa - > ioc ) ;
2011-06-14 02:46:21 +04:00
if ( bfa_fcport_is_pbcdisabled ( bfa ) )
bfa - > modules . port . pbc_disabled = BFA_TRUE ;
2010-12-27 08:46:35 +03:00
WARN_ON ( ! fcport - > cfg . maxfrsize ) ;
WARN_ON ( ! fcport - > cfg . rx_bbcredit ) ;
WARN_ON ( ! fcport - > speed_sup ) ;
2010-09-15 22:50:55 +04:00
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Firmware message handler .
*/
void
bfa_fcport_isr ( struct bfa_s * bfa , struct bfi_msg_s * msg )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
union bfi_fcport_i2h_msg_u i2hmsg ;
i2hmsg . msg = msg ;
fcport - > event_arg . i2hmsg = i2hmsg ;
bfa_trc ( bfa , msg - > mhdr . msg_id ) ;
bfa_trc ( bfa , bfa_sm_to_state ( hal_port_sm_table , fcport - > sm ) ) ;
switch ( msg - > mhdr . msg_id ) {
case BFI_FCPORT_I2H_ENABLE_RSP :
2010-12-14 03:16:50 +03:00
if ( fcport - > msgtag = = i2hmsg . penable_rsp - > msgtag ) {
2012-09-22 04:26:31 +04:00
fcport - > stats_dma_ready = BFA_TRUE ;
2010-12-14 03:16:50 +03:00
if ( fcport - > use_flash_cfg ) {
fcport - > cfg = i2hmsg . penable_rsp - > port_cfg ;
fcport - > cfg . maxfrsize =
cpu_to_be16 ( fcport - > cfg . maxfrsize ) ;
fcport - > cfg . path_tov =
cpu_to_be16 ( fcport - > cfg . path_tov ) ;
fcport - > cfg . q_depth =
cpu_to_be16 ( fcport - > cfg . q_depth ) ;
if ( fcport - > cfg . trunked )
fcport - > trunk . attr . state =
BFA_TRUNK_OFFLINE ;
else
fcport - > trunk . attr . state =
BFA_TRUNK_DISABLED ;
2012-09-22 04:26:31 +04:00
fcport - > qos_attr . qos_bw =
i2hmsg . penable_rsp - > port_cfg . qos_bw ;
2010-12-14 03:16:50 +03:00
fcport - > use_flash_cfg = BFA_FALSE ;
}
2011-07-21 04:03:09 +04:00
if ( fcport - > cfg . qos_enabled )
fcport - > qos_attr . state = BFA_QOS_OFFLINE ;
else
fcport - > qos_attr . state = BFA_QOS_DISABLED ;
2012-09-22 04:26:31 +04:00
fcport - > qos_attr . qos_bw_op =
i2hmsg . penable_rsp - > port_cfg . qos_bw ;
2013-05-13 13:33:19 +04:00
if ( fcport - > cfg . bb_cr_enabled )
fcport - > bbcr_attr . state = BFA_BBCR_OFFLINE ;
else
fcport - > bbcr_attr . state = BFA_BBCR_DISABLED ;
2010-09-15 22:50:55 +04:00
bfa_sm_send_event ( fcport , BFA_FCPORT_SM_FWRSP ) ;
2010-12-14 03:16:50 +03:00
}
2010-09-15 22:50:55 +04:00
break ;
case BFI_FCPORT_I2H_DISABLE_RSP :
if ( fcport - > msgtag = = i2hmsg . penable_rsp - > msgtag )
bfa_sm_send_event ( fcport , BFA_FCPORT_SM_FWRSP ) ;
break ;
case BFI_FCPORT_I2H_EVENT :
2013-05-13 13:33:19 +04:00
if ( fcport - > cfg . bb_cr_enabled )
fcport - > bbcr_attr . state = BFA_BBCR_OFFLINE ;
else
fcport - > bbcr_attr . state = BFA_BBCR_DISABLED ;
2010-09-15 22:50:55 +04:00
if ( i2hmsg . event - > link_state . linkstate = = BFA_PORT_LINKUP )
bfa_sm_send_event ( fcport , BFA_FCPORT_SM_LINKUP ) ;
2012-09-22 04:26:18 +04:00
else {
if ( i2hmsg . event - > link_state . linkstate_rsn = =
BFA_PORT_LINKSTATE_RSN_FAA_MISCONFIG )
bfa_sm_send_event ( fcport ,
BFA_FCPORT_SM_FAA_MISCONFIG ) ;
else
bfa_sm_send_event ( fcport ,
BFA_FCPORT_SM_LINKDOWN ) ;
}
2012-09-22 04:26:31 +04:00
fcport - > qos_attr . qos_bw_op =
i2hmsg . event - > link_state . qos_attr . qos_bw_op ;
2010-09-15 22:50:55 +04:00
break ;
case BFI_FCPORT_I2H_TRUNK_SCN :
bfa_trunk_scn ( fcport , i2hmsg . trunk_scn ) ;
break ;
case BFI_FCPORT_I2H_STATS_GET_RSP :
/*
* check for timer pop before processing the rsp
*/
2011-07-21 04:02:11 +04:00
if ( list_empty ( & fcport - > stats_pending_q ) | |
( fcport - > stats_status = = BFA_STATUS_ETIMER ) )
2010-09-15 22:50:55 +04:00
break ;
bfa_timer_stop ( & fcport - > timer ) ;
fcport - > stats_status = i2hmsg . pstatsget_rsp - > status ;
2011-07-21 04:02:11 +04:00
__bfa_cb_fcport_stats_get ( fcport , BFA_TRUE ) ;
2010-09-15 22:50:55 +04:00
break ;
case BFI_FCPORT_I2H_STATS_CLEAR_RSP :
/*
* check for timer pop before processing the rsp
*/
2011-07-21 04:02:11 +04:00
if ( list_empty ( & fcport - > statsclr_pending_q ) | |
( fcport - > stats_status = = BFA_STATUS_ETIMER ) )
2010-09-15 22:50:55 +04:00
break ;
bfa_timer_stop ( & fcport - > timer ) ;
fcport - > stats_status = BFA_STATUS_OK ;
2011-07-21 04:02:11 +04:00
__bfa_cb_fcport_stats_clr ( fcport , BFA_TRUE ) ;
2010-09-15 22:50:55 +04:00
break ;
case BFI_FCPORT_I2H_ENABLE_AEN :
bfa_sm_send_event ( fcport , BFA_FCPORT_SM_ENABLE ) ;
break ;
case BFI_FCPORT_I2H_DISABLE_AEN :
bfa_sm_send_event ( fcport , BFA_FCPORT_SM_DISABLE ) ;
break ;
default :
2010-12-27 08:46:35 +03:00
WARN_ON ( 1 ) ;
2010-09-15 22:50:55 +04:00
break ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Registered callback for port events .
*/
void
bfa_fcport_event_register ( struct bfa_s * bfa ,
void ( * cbfn ) ( void * cbarg ,
enum bfa_port_linkstate event ) ,
void * cbarg )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
fcport - > event_cbfn = cbfn ;
fcport - > event_cbarg = cbarg ;
}
bfa_status_t
bfa_fcport_enable ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
2011-06-14 02:46:21 +04:00
if ( bfa_fcport_is_pbcdisabled ( bfa ) )
return BFA_STATUS_PBC ;
2010-09-15 22:50:55 +04:00
if ( bfa_ioc_is_disabled ( & bfa - > ioc ) )
return BFA_STATUS_IOC_DISABLED ;
if ( fcport - > diag_busy )
return BFA_STATUS_DIAG_BUSY ;
bfa_sm_send_event ( BFA_FCPORT_MOD ( bfa ) , BFA_FCPORT_SM_ENABLE ) ;
return BFA_STATUS_OK ;
}
bfa_status_t
bfa_fcport_disable ( struct bfa_s * bfa )
{
2011-06-14 02:46:21 +04:00
if ( bfa_fcport_is_pbcdisabled ( bfa ) )
return BFA_STATUS_PBC ;
2010-09-15 22:50:55 +04:00
if ( bfa_ioc_is_disabled ( & bfa - > ioc ) )
return BFA_STATUS_IOC_DISABLED ;
bfa_sm_send_event ( BFA_FCPORT_MOD ( bfa ) , BFA_FCPORT_SM_DISABLE ) ;
return BFA_STATUS_OK ;
}
2011-06-14 02:46:21 +04:00
/* If PBC is disabled on port, return error */
bfa_status_t
bfa_fcport_is_pbcdisabled ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
struct bfa_iocfc_s * iocfc = & bfa - > iocfc ;
struct bfi_iocfc_cfgrsp_s * cfgrsp = iocfc - > cfgrsp ;
if ( cfgrsp - > pbc_cfg . port_enabled = = BFI_PBC_PORT_DISABLED ) {
bfa_trc ( bfa , fcport - > pwwn ) ;
return BFA_STATUS_PBC ;
}
return BFA_STATUS_OK ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Configure port speed .
*/
bfa_status_t
bfa_fcport_cfg_speed ( struct bfa_s * bfa , enum bfa_port_speed speed )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
bfa_trc ( bfa , speed ) ;
if ( fcport - > cfg . trunked = = BFA_TRUE )
return BFA_STATUS_TRUNK_ENABLED ;
2012-09-22 04:23:59 +04:00
if ( ( fcport - > cfg . topology = = BFA_PORT_TOPOLOGY_LOOP ) & &
( speed = = BFA_PORT_SPEED_16GBPS ) )
return BFA_STATUS_UNSUPP_SPEED ;
2010-09-15 22:50:55 +04:00
if ( ( speed ! = BFA_PORT_SPEED_AUTO ) & & ( speed > fcport - > speed_sup ) ) {
bfa_trc ( bfa , fcport - > speed_sup ) ;
return BFA_STATUS_UNSUPP_SPEED ;
}
2012-03-14 04:41:02 +04:00
/* Port speed entered needs to be checked */
if ( bfa_ioc_get_type ( & fcport - > bfa - > ioc ) = = BFA_IOC_TYPE_FC ) {
/* For CT2, 1G is not supported */
if ( ( speed = = BFA_PORT_SPEED_1GBPS ) & &
( bfa_asic_id_ct2 ( bfa - > ioc . pcidev . device_id ) ) )
return BFA_STATUS_UNSUPP_SPEED ;
/* Already checked for Auto Speed and Max Speed supp */
if ( ! ( speed = = BFA_PORT_SPEED_1GBPS | |
speed = = BFA_PORT_SPEED_2GBPS | |
speed = = BFA_PORT_SPEED_4GBPS | |
speed = = BFA_PORT_SPEED_8GBPS | |
speed = = BFA_PORT_SPEED_16GBPS | |
speed = = BFA_PORT_SPEED_AUTO ) )
return BFA_STATUS_UNSUPP_SPEED ;
} else {
if ( speed ! = BFA_PORT_SPEED_10GBPS )
return BFA_STATUS_UNSUPP_SPEED ;
2011-06-25 07:23:19 +04:00
}
2010-09-15 22:50:55 +04:00
fcport - > cfg . speed = speed ;
return BFA_STATUS_OK ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Get current speed .
*/
enum bfa_port_speed
bfa_fcport_get_speed ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
return fcport - > speed ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Configure port topology .
*/
bfa_status_t
bfa_fcport_cfg_topology ( struct bfa_s * bfa , enum bfa_port_topology topology )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
bfa_trc ( bfa , topology ) ;
bfa_trc ( bfa , fcport - > cfg . topology ) ;
switch ( topology ) {
case BFA_PORT_TOPOLOGY_P2P :
2012-09-22 04:23:59 +04:00
break ;
2010-09-15 22:50:55 +04:00
case BFA_PORT_TOPOLOGY_LOOP :
2012-09-22 04:23:59 +04:00
if ( ( bfa_fcport_is_qos_enabled ( bfa ) ! = BFA_FALSE ) | |
( fcport - > qos_attr . state ! = BFA_QOS_DISABLED ) )
return BFA_STATUS_ERROR_QOS_ENABLED ;
if ( fcport - > cfg . ratelimit ! = BFA_FALSE )
return BFA_STATUS_ERROR_TRL_ENABLED ;
if ( ( bfa_fcport_is_trunk_enabled ( bfa ) ! = BFA_FALSE ) | |
( fcport - > trunk . attr . state ! = BFA_TRUNK_DISABLED ) )
return BFA_STATUS_ERROR_TRUNK_ENABLED ;
if ( ( bfa_fcport_get_speed ( bfa ) = = BFA_PORT_SPEED_16GBPS ) | |
( fcport - > cfg . speed = = BFA_PORT_SPEED_16GBPS ) )
return BFA_STATUS_UNSUPP_SPEED ;
if ( bfa_mfg_is_mezz ( bfa - > ioc . attr - > card_type ) )
return BFA_STATUS_LOOP_UNSUPP_MEZZ ;
2012-09-22 04:26:07 +04:00
if ( bfa_fcport_is_dport ( bfa ) ! = BFA_FALSE )
return BFA_STATUS_DPORT_ERR ;
2013-05-13 13:33:21 +04:00
if ( bfa_fcport_is_ddport ( bfa ) ! = BFA_FALSE )
return BFA_STATUS_DPORT_ERR ;
2012-09-22 04:23:59 +04:00
break ;
2010-09-15 22:50:55 +04:00
case BFA_PORT_TOPOLOGY_AUTO :
break ;
default :
return BFA_STATUS_EINVAL ;
}
fcport - > cfg . topology = topology ;
return BFA_STATUS_OK ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Get current topology .
*/
enum bfa_port_topology
bfa_fcport_get_topology ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
return fcport - > topology ;
}
2012-09-22 04:23:59 +04:00
/**
* Get config topology .
*/
enum bfa_port_topology
bfa_fcport_get_cfg_topology ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
return fcport - > cfg . topology ;
}
2010-09-15 22:50:55 +04:00
bfa_status_t
bfa_fcport_cfg_hardalpa ( struct bfa_s * bfa , u8 alpa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
bfa_trc ( bfa , alpa ) ;
bfa_trc ( bfa , fcport - > cfg . cfg_hardalpa ) ;
bfa_trc ( bfa , fcport - > cfg . hardalpa ) ;
fcport - > cfg . cfg_hardalpa = BFA_TRUE ;
fcport - > cfg . hardalpa = alpa ;
return BFA_STATUS_OK ;
}
bfa_status_t
bfa_fcport_clr_hardalpa ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
bfa_trc ( bfa , fcport - > cfg . cfg_hardalpa ) ;
bfa_trc ( bfa , fcport - > cfg . hardalpa ) ;
fcport - > cfg . cfg_hardalpa = BFA_FALSE ;
return BFA_STATUS_OK ;
}
bfa_boolean_t
bfa_fcport_get_hardalpa ( struct bfa_s * bfa , u8 * alpa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
* alpa = fcport - > cfg . hardalpa ;
return fcport - > cfg . cfg_hardalpa ;
}
u8
bfa_fcport_get_myalpa ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
return fcport - > myalpa ;
}
bfa_status_t
bfa_fcport_cfg_maxfrsize ( struct bfa_s * bfa , u16 maxfrsize )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
bfa_trc ( bfa , maxfrsize ) ;
bfa_trc ( bfa , fcport - > cfg . maxfrsize ) ;
/* with in range */
if ( ( maxfrsize > FC_MAX_PDUSZ ) | | ( maxfrsize < FC_MIN_PDUSZ ) )
return BFA_STATUS_INVLD_DFSZ ;
/* power of 2, if not the max frame size of 2112 */
if ( ( maxfrsize ! = FC_MAX_PDUSZ ) & & ( maxfrsize & ( maxfrsize - 1 ) ) )
return BFA_STATUS_INVLD_DFSZ ;
fcport - > cfg . maxfrsize = maxfrsize ;
return BFA_STATUS_OK ;
}
u16
bfa_fcport_get_maxfrsize ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
return fcport - > cfg . maxfrsize ;
}
u8
bfa_fcport_get_rx_bbcredit ( struct bfa_s * bfa )
{
2012-09-22 04:23:59 +04:00
if ( bfa_fcport_get_topology ( bfa ) ! = BFA_PORT_TOPOLOGY_LOOP )
return ( BFA_FCPORT_MOD ( bfa ) ) - > cfg . rx_bbcredit ;
2010-09-15 22:50:55 +04:00
2012-09-22 04:23:59 +04:00
else
return 0 ;
2010-09-15 22:50:55 +04:00
}
void
2013-05-13 13:33:19 +04:00
bfa_fcport_set_tx_bbcredit ( struct bfa_s * bfa , u16 tx_bbcredit )
2010-09-15 22:50:55 +04:00
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
fcport - > cfg . tx_bbcredit = ( u8 ) tx_bbcredit ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Get port attributes .
*/
wwn_t
bfa_fcport_get_wwn ( struct bfa_s * bfa , bfa_boolean_t node )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
if ( node )
return fcport - > nwwn ;
else
return fcport - > pwwn ;
}
void
bfa_fcport_get_attr ( struct bfa_s * bfa , struct bfa_port_attr_s * attr )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
2010-10-19 04:08:54 +04:00
memset ( attr , 0 , sizeof ( struct bfa_port_attr_s ) ) ;
2010-09-15 22:50:55 +04:00
attr - > nwwn = fcport - > nwwn ;
attr - > pwwn = fcport - > pwwn ;
2010-12-10 06:08:43 +03:00
attr - > factorypwwn = bfa - > ioc . attr - > mfg_pwwn ;
attr - > factorynwwn = bfa - > ioc . attr - > mfg_nwwn ;
2010-09-15 22:50:55 +04:00
2010-10-19 04:08:54 +04:00
memcpy ( & attr - > pport_cfg , & fcport - > cfg ,
2010-09-15 22:50:55 +04:00
sizeof ( struct bfa_port_cfg_s ) ) ;
/* speed attributes */
attr - > pport_cfg . speed = fcport - > cfg . speed ;
attr - > speed_supported = fcport - > speed_sup ;
attr - > speed = fcport - > speed ;
attr - > cos_supported = FC_CLASS_3 ;
/* topology attributes */
attr - > pport_cfg . topology = fcport - > cfg . topology ;
attr - > topology = fcport - > topology ;
attr - > pport_cfg . trunked = fcport - > cfg . trunked ;
/* beacon attributes */
attr - > beacon = fcport - > beacon ;
attr - > link_e2e_beacon = fcport - > link_e2e_beacon ;
attr - > pport_cfg . path_tov = bfa_fcpim_path_tov_get ( bfa ) ;
attr - > pport_cfg . q_depth = bfa_fcpim_qdepth_get ( bfa ) ;
attr - > port_state = bfa_sm_to_state ( hal_port_sm_table , fcport - > sm ) ;
2011-06-14 02:46:21 +04:00
2013-05-13 13:33:20 +04:00
attr - > fec_state = fcport - > fec_state ;
2011-06-14 02:46:21 +04:00
/* PBC Disabled State */
if ( bfa_fcport_is_pbcdisabled ( bfa ) )
attr - > port_state = BFA_PORT_ST_PREBOOT_DISABLED ;
else {
if ( bfa_ioc_is_disabled ( & fcport - > bfa - > ioc ) )
attr - > port_state = BFA_PORT_ST_IOCDIS ;
else if ( bfa_ioc_fw_mismatch ( & fcport - > bfa - > ioc ) )
attr - > port_state = BFA_PORT_ST_FWMISMATCH ;
}
2010-09-15 22:50:55 +04:00
/* FCoE vlan */
attr - > fcoe_vlan = fcport - > fcoe_vlan ;
}
# define BFA_FCPORT_STATS_TOV 1000
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Fetch port statistics ( FCQoS or FCoE ) .
*/
bfa_status_t
2011-07-21 04:02:11 +04:00
bfa_fcport_get_stats ( struct bfa_s * bfa , struct bfa_cb_pending_q_s * cb )
2010-09-15 22:50:55 +04:00
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
2012-09-22 04:26:31 +04:00
if ( ! bfa_iocfc_is_operational ( bfa ) | |
! fcport - > stats_dma_ready )
return BFA_STATUS_IOC_NON_OP ;
2010-09-15 22:50:55 +04:00
2011-07-21 04:02:11 +04:00
if ( ! list_empty ( & fcport - > statsclr_pending_q ) )
return BFA_STATUS_DEVBUSY ;
2010-09-15 22:50:55 +04:00
2011-07-21 04:02:11 +04:00
if ( list_empty ( & fcport - > stats_pending_q ) ) {
list_add_tail ( & cb - > hcb_qe . qe , & fcport - > stats_pending_q ) ;
bfa_fcport_send_stats_get ( fcport ) ;
bfa_timer_start ( bfa , & fcport - > timer ,
bfa_fcport_stats_get_timeout ,
fcport , BFA_FCPORT_STATS_TOV ) ;
} else
list_add_tail ( & cb - > hcb_qe . qe , & fcport - > stats_pending_q ) ;
2010-09-15 22:50:55 +04:00
return BFA_STATUS_OK ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Reset port statistics ( FCQoS or FCoE ) .
*/
bfa_status_t
2011-07-21 04:02:11 +04:00
bfa_fcport_clear_stats ( struct bfa_s * bfa , struct bfa_cb_pending_q_s * cb )
2010-09-15 22:50:55 +04:00
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
2012-09-22 04:26:31 +04:00
if ( ! bfa_iocfc_is_operational ( bfa ) | |
! fcport - > stats_dma_ready )
return BFA_STATUS_IOC_NON_OP ;
2011-07-21 04:02:11 +04:00
if ( ! list_empty ( & fcport - > stats_pending_q ) )
2010-09-15 22:50:55 +04:00
return BFA_STATUS_DEVBUSY ;
2011-07-21 04:02:11 +04:00
if ( list_empty ( & fcport - > statsclr_pending_q ) ) {
list_add_tail ( & cb - > hcb_qe . qe , & fcport - > statsclr_pending_q ) ;
bfa_fcport_send_stats_clear ( fcport ) ;
bfa_timer_start ( bfa , & fcport - > timer ,
bfa_fcport_stats_clr_timeout ,
fcport , BFA_FCPORT_STATS_TOV ) ;
} else
list_add_tail ( & cb - > hcb_qe . qe , & fcport - > statsclr_pending_q ) ;
2010-09-15 22:50:55 +04:00
return BFA_STATUS_OK ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Fetch port attributes .
*/
bfa_boolean_t
bfa_fcport_is_disabled ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
return bfa_sm_to_state ( hal_port_sm_table , fcport - > sm ) = =
BFA_PORT_ST_DISABLED ;
}
2012-09-22 04:26:07 +04:00
bfa_boolean_t
bfa_fcport_is_dport ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
return ( bfa_sm_to_state ( hal_port_sm_table , fcport - > sm ) = =
BFA_PORT_ST_DPORT ) ;
}
2013-05-13 13:33:21 +04:00
bfa_boolean_t
bfa_fcport_is_ddport ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
return ( bfa_sm_to_state ( hal_port_sm_table , fcport - > sm ) = =
BFA_PORT_ST_DDPORT ) ;
}
2012-09-22 04:26:31 +04:00
bfa_status_t
bfa_fcport_set_qos_bw ( struct bfa_s * bfa , struct bfa_qos_bw_s * qos_bw )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
enum bfa_ioc_type_e ioc_type = bfa_get_type ( bfa ) ;
bfa_trc ( bfa , ioc_type ) ;
if ( ( qos_bw - > high = = 0 ) | | ( qos_bw - > med = = 0 ) | | ( qos_bw - > low = = 0 ) )
return BFA_STATUS_QOS_BW_INVALID ;
if ( ( qos_bw - > high + qos_bw - > med + qos_bw - > low ) ! = 100 )
return BFA_STATUS_QOS_BW_INVALID ;
if ( ( qos_bw - > med > qos_bw - > high ) | | ( qos_bw - > low > qos_bw - > med ) | |
( qos_bw - > low > qos_bw - > high ) )
return BFA_STATUS_QOS_BW_INVALID ;
if ( ( ioc_type = = BFA_IOC_TYPE_FC ) & &
( fcport - > cfg . topology ! = BFA_PORT_TOPOLOGY_LOOP ) )
fcport - > cfg . qos_bw = * qos_bw ;
return BFA_STATUS_OK ;
}
2010-09-15 22:50:55 +04:00
bfa_boolean_t
bfa_fcport_is_ratelim ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
return fcport - > cfg . ratelimit ? BFA_TRUE : BFA_FALSE ;
}
2011-06-25 07:23:19 +04:00
/*
* Enable / Disable FAA feature in port config
*/
void
bfa_fcport_cfg_faa ( struct bfa_s * bfa , u8 state )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
bfa_trc ( bfa , state ) ;
fcport - > cfg . faa_state = state ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Get default minimum ratelim speed
*/
enum bfa_port_speed
bfa_fcport_get_ratelim_speed ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
bfa_trc ( bfa , fcport - > cfg . trl_def_speed ) ;
return fcport - > cfg . trl_def_speed ;
}
2011-06-25 07:28:17 +04:00
void
bfa_fcport_beacon ( void * dev , bfa_boolean_t beacon ,
bfa_boolean_t link_e2e_beacon )
{
struct bfa_s * bfa = dev ;
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
bfa_trc ( bfa , beacon ) ;
bfa_trc ( bfa , link_e2e_beacon ) ;
bfa_trc ( bfa , fcport - > beacon ) ;
bfa_trc ( bfa , fcport - > link_e2e_beacon ) ;
fcport - > beacon = beacon ;
fcport - > link_e2e_beacon = link_e2e_beacon ;
}
2010-09-15 22:50:55 +04:00
bfa_boolean_t
bfa_fcport_is_linkup ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
return ( ! fcport - > cfg . trunked & &
bfa_sm_cmp_state ( fcport , bfa_fcport_sm_linkup ) ) | |
( fcport - > cfg . trunked & &
fcport - > trunk . attr . state = = BFA_TRUNK_ONLINE ) ;
}
bfa_boolean_t
bfa_fcport_is_qos_enabled ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
return fcport - > cfg . qos_enabled ;
}
2011-06-14 02:53:04 +04:00
bfa_boolean_t
bfa_fcport_is_trunk_enabled ( struct bfa_s * bfa )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
return fcport - > cfg . trunked ;
}
2013-05-13 13:33:19 +04:00
bfa_status_t
bfa_fcport_cfg_bbcr ( struct bfa_s * bfa , bfa_boolean_t on_off , u8 bb_scn )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
bfa_trc ( bfa , on_off ) ;
if ( bfa_ioc_get_type ( & fcport - > bfa - > ioc ) ! = BFA_IOC_TYPE_FC )
return BFA_STATUS_BBCR_FC_ONLY ;
if ( bfa_mfg_is_mezz ( bfa - > ioc . attr - > card_type ) & &
( bfa - > ioc . attr - > card_type ! = BFA_MFG_TYPE_CHINOOK ) )
return BFA_STATUS_CMD_NOTSUPP_MEZZ ;
if ( on_off ) {
if ( fcport - > cfg . topology = = BFA_PORT_TOPOLOGY_LOOP )
return BFA_STATUS_TOPOLOGY_LOOP ;
if ( fcport - > cfg . qos_enabled )
return BFA_STATUS_ERROR_QOS_ENABLED ;
if ( fcport - > cfg . trunked )
return BFA_STATUS_TRUNK_ENABLED ;
if ( ( fcport - > cfg . speed ! = BFA_PORT_SPEED_AUTO ) & &
( fcport - > cfg . speed < bfa_ioc_speed_sup ( & bfa - > ioc ) ) )
return BFA_STATUS_ERR_BBCR_SPEED_UNSUPPORT ;
if ( bfa_ioc_speed_sup ( & bfa - > ioc ) < BFA_PORT_SPEED_8GBPS )
return BFA_STATUS_FEATURE_NOT_SUPPORTED ;
if ( fcport - > cfg . bb_cr_enabled ) {
if ( bb_scn ! = fcport - > cfg . bb_scn )
return BFA_STATUS_BBCR_CFG_NO_CHANGE ;
else
return BFA_STATUS_NO_CHANGE ;
}
if ( ( bb_scn = = 0 ) | | ( bb_scn > BFA_BB_SCN_MAX ) )
bb_scn = BFA_BB_SCN_DEF ;
fcport - > cfg . bb_cr_enabled = on_off ;
fcport - > cfg . bb_scn = bb_scn ;
} else {
if ( ! fcport - > cfg . bb_cr_enabled )
return BFA_STATUS_NO_CHANGE ;
fcport - > cfg . bb_cr_enabled = on_off ;
fcport - > cfg . bb_scn = 0 ;
}
return BFA_STATUS_OK ;
}
bfa_status_t
bfa_fcport_get_bbcr_attr ( struct bfa_s * bfa ,
struct bfa_bbcr_attr_s * bbcr_attr )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( bfa ) ;
if ( bfa_ioc_get_type ( & fcport - > bfa - > ioc ) ! = BFA_IOC_TYPE_FC )
return BFA_STATUS_BBCR_FC_ONLY ;
if ( fcport - > cfg . topology = = BFA_PORT_TOPOLOGY_LOOP )
return BFA_STATUS_TOPOLOGY_LOOP ;
* bbcr_attr = fcport - > bbcr_attr ;
return BFA_STATUS_OK ;
}
2012-09-22 04:26:07 +04:00
void
bfa_fcport_dportenable ( struct bfa_s * bfa )
{
/*
* Assume caller check for port is in disable state
*/
bfa_sm_send_event ( BFA_FCPORT_MOD ( bfa ) , BFA_FCPORT_SM_DPORTENABLE ) ;
bfa_port_set_dportenabled ( & bfa - > modules . port , BFA_TRUE ) ;
}
void
bfa_fcport_dportdisable ( struct bfa_s * bfa )
{
/*
* Assume caller check for port is in disable state
*/
bfa_sm_send_event ( BFA_FCPORT_MOD ( bfa ) , BFA_FCPORT_SM_DPORTDISABLE ) ;
bfa_port_set_dportenabled ( & bfa - > modules . port , BFA_FALSE ) ;
}
2013-05-13 13:33:21 +04:00
void
bfa_fcport_ddportenable ( struct bfa_s * bfa )
{
/*
* Assume caller check for port is in disable state
*/
bfa_sm_send_event ( BFA_FCPORT_MOD ( bfa ) , BFA_FCPORT_SM_DDPORTENABLE ) ;
}
void
bfa_fcport_ddportdisable ( struct bfa_s * bfa )
{
/*
* Assume caller check for port is in disable state
*/
bfa_sm_send_event ( BFA_FCPORT_MOD ( bfa ) , BFA_FCPORT_SM_DDPORTDISABLE ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Rport State machine functions
*/
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Beginning state , only online event expected .
*/
static void
bfa_rport_sm_uninit ( struct bfa_rport_s * rp , enum bfa_rport_event event )
{
bfa_trc ( rp - > bfa , rp - > rport_tag ) ;
bfa_trc ( rp - > bfa , event ) ;
switch ( event ) {
case BFA_RPORT_SM_CREATE :
bfa_stats ( rp , sm_un_cr ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_created ) ;
break ;
default :
bfa_stats ( rp , sm_un_unexp ) ;
bfa_sm_fault ( rp - > bfa , event ) ;
}
}
static void
bfa_rport_sm_created ( struct bfa_rport_s * rp , enum bfa_rport_event event )
{
bfa_trc ( rp - > bfa , rp - > rport_tag ) ;
bfa_trc ( rp - > bfa , event ) ;
switch ( event ) {
case BFA_RPORT_SM_ONLINE :
bfa_stats ( rp , sm_cr_on ) ;
if ( bfa_rport_send_fwcreate ( rp ) )
bfa_sm_set_state ( rp , bfa_rport_sm_fwcreate ) ;
else
bfa_sm_set_state ( rp , bfa_rport_sm_fwcreate_qfull ) ;
break ;
case BFA_RPORT_SM_DELETE :
bfa_stats ( rp , sm_cr_del ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_uninit ) ;
bfa_rport_free ( rp ) ;
break ;
case BFA_RPORT_SM_HWFAIL :
bfa_stats ( rp , sm_cr_hwf ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_iocdisable ) ;
break ;
default :
bfa_stats ( rp , sm_cr_unexp ) ;
bfa_sm_fault ( rp - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Waiting for rport create response from firmware .
*/
static void
bfa_rport_sm_fwcreate ( struct bfa_rport_s * rp , enum bfa_rport_event event )
{
bfa_trc ( rp - > bfa , rp - > rport_tag ) ;
bfa_trc ( rp - > bfa , event ) ;
switch ( event ) {
case BFA_RPORT_SM_FWRSP :
bfa_stats ( rp , sm_fwc_rsp ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_online ) ;
bfa_rport_online_cb ( rp ) ;
break ;
case BFA_RPORT_SM_DELETE :
bfa_stats ( rp , sm_fwc_del ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_delete_pending ) ;
break ;
case BFA_RPORT_SM_OFFLINE :
bfa_stats ( rp , sm_fwc_off ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_offline_pending ) ;
break ;
case BFA_RPORT_SM_HWFAIL :
bfa_stats ( rp , sm_fwc_hwf ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_iocdisable ) ;
break ;
default :
bfa_stats ( rp , sm_fwc_unexp ) ;
bfa_sm_fault ( rp - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Request queue is full , awaiting queue resume to send create request .
*/
static void
bfa_rport_sm_fwcreate_qfull ( struct bfa_rport_s * rp , enum bfa_rport_event event )
{
bfa_trc ( rp - > bfa , rp - > rport_tag ) ;
bfa_trc ( rp - > bfa , event ) ;
switch ( event ) {
case BFA_RPORT_SM_QRESUME :
bfa_sm_set_state ( rp , bfa_rport_sm_fwcreate ) ;
bfa_rport_send_fwcreate ( rp ) ;
break ;
case BFA_RPORT_SM_DELETE :
bfa_stats ( rp , sm_fwc_del ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_uninit ) ;
bfa_reqq_wcancel ( & rp - > reqq_wait ) ;
bfa_rport_free ( rp ) ;
break ;
case BFA_RPORT_SM_OFFLINE :
bfa_stats ( rp , sm_fwc_off ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_offline ) ;
bfa_reqq_wcancel ( & rp - > reqq_wait ) ;
bfa_rport_offline_cb ( rp ) ;
break ;
case BFA_RPORT_SM_HWFAIL :
bfa_stats ( rp , sm_fwc_hwf ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_iocdisable ) ;
bfa_reqq_wcancel ( & rp - > reqq_wait ) ;
break ;
default :
bfa_stats ( rp , sm_fwc_unexp ) ;
bfa_sm_fault ( rp - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Online state - normal parking state .
*/
static void
bfa_rport_sm_online ( struct bfa_rport_s * rp , enum bfa_rport_event event )
{
struct bfi_rport_qos_scn_s * qos_scn ;
bfa_trc ( rp - > bfa , rp - > rport_tag ) ;
bfa_trc ( rp - > bfa , event ) ;
switch ( event ) {
case BFA_RPORT_SM_OFFLINE :
bfa_stats ( rp , sm_on_off ) ;
if ( bfa_rport_send_fwdelete ( rp ) )
bfa_sm_set_state ( rp , bfa_rport_sm_fwdelete ) ;
else
bfa_sm_set_state ( rp , bfa_rport_sm_fwdelete_qfull ) ;
break ;
case BFA_RPORT_SM_DELETE :
bfa_stats ( rp , sm_on_del ) ;
if ( bfa_rport_send_fwdelete ( rp ) )
bfa_sm_set_state ( rp , bfa_rport_sm_deleting ) ;
else
bfa_sm_set_state ( rp , bfa_rport_sm_deleting_qfull ) ;
break ;
case BFA_RPORT_SM_HWFAIL :
bfa_stats ( rp , sm_on_hwf ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_iocdisable ) ;
break ;
case BFA_RPORT_SM_SET_SPEED :
bfa_rport_send_fwspeed ( rp ) ;
break ;
case BFA_RPORT_SM_QOS_SCN :
qos_scn = ( struct bfi_rport_qos_scn_s * ) rp - > event_arg . fw_msg ;
rp - > qos_attr = qos_scn - > new_qos_attr ;
bfa_trc ( rp - > bfa , qos_scn - > old_qos_attr . qos_flow_id ) ;
bfa_trc ( rp - > bfa , qos_scn - > new_qos_attr . qos_flow_id ) ;
bfa_trc ( rp - > bfa , qos_scn - > old_qos_attr . qos_priority ) ;
bfa_trc ( rp - > bfa , qos_scn - > new_qos_attr . qos_priority ) ;
qos_scn - > old_qos_attr . qos_flow_id =
2010-10-19 04:10:50 +04:00
be32_to_cpu ( qos_scn - > old_qos_attr . qos_flow_id ) ;
2010-09-15 22:50:55 +04:00
qos_scn - > new_qos_attr . qos_flow_id =
2010-10-19 04:10:50 +04:00
be32_to_cpu ( qos_scn - > new_qos_attr . qos_flow_id ) ;
2010-09-15 22:50:55 +04:00
if ( qos_scn - > old_qos_attr . qos_flow_id ! =
qos_scn - > new_qos_attr . qos_flow_id )
bfa_cb_rport_qos_scn_flowid ( rp - > rport_drv ,
qos_scn - > old_qos_attr ,
qos_scn - > new_qos_attr ) ;
if ( qos_scn - > old_qos_attr . qos_priority ! =
qos_scn - > new_qos_attr . qos_priority )
bfa_cb_rport_qos_scn_prio ( rp - > rport_drv ,
qos_scn - > old_qos_attr ,
qos_scn - > new_qos_attr ) ;
break ;
default :
bfa_stats ( rp , sm_on_unexp ) ;
bfa_sm_fault ( rp - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Firmware rport is being deleted - awaiting f / w response .
*/
static void
bfa_rport_sm_fwdelete ( struct bfa_rport_s * rp , enum bfa_rport_event event )
{
bfa_trc ( rp - > bfa , rp - > rport_tag ) ;
bfa_trc ( rp - > bfa , event ) ;
switch ( event ) {
case BFA_RPORT_SM_FWRSP :
bfa_stats ( rp , sm_fwd_rsp ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_offline ) ;
bfa_rport_offline_cb ( rp ) ;
break ;
case BFA_RPORT_SM_DELETE :
bfa_stats ( rp , sm_fwd_del ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_deleting ) ;
break ;
case BFA_RPORT_SM_HWFAIL :
bfa_stats ( rp , sm_fwd_hwf ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_iocdisable ) ;
bfa_rport_offline_cb ( rp ) ;
break ;
default :
bfa_stats ( rp , sm_fwd_unexp ) ;
bfa_sm_fault ( rp - > bfa , event ) ;
}
}
static void
bfa_rport_sm_fwdelete_qfull ( struct bfa_rport_s * rp , enum bfa_rport_event event )
{
bfa_trc ( rp - > bfa , rp - > rport_tag ) ;
bfa_trc ( rp - > bfa , event ) ;
switch ( event ) {
case BFA_RPORT_SM_QRESUME :
bfa_sm_set_state ( rp , bfa_rport_sm_fwdelete ) ;
bfa_rport_send_fwdelete ( rp ) ;
break ;
case BFA_RPORT_SM_DELETE :
bfa_stats ( rp , sm_fwd_del ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_deleting_qfull ) ;
break ;
case BFA_RPORT_SM_HWFAIL :
bfa_stats ( rp , sm_fwd_hwf ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_iocdisable ) ;
bfa_reqq_wcancel ( & rp - > reqq_wait ) ;
bfa_rport_offline_cb ( rp ) ;
break ;
default :
bfa_stats ( rp , sm_fwd_unexp ) ;
bfa_sm_fault ( rp - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Offline state .
*/
static void
bfa_rport_sm_offline ( struct bfa_rport_s * rp , enum bfa_rport_event event )
{
bfa_trc ( rp - > bfa , rp - > rport_tag ) ;
bfa_trc ( rp - > bfa , event ) ;
switch ( event ) {
case BFA_RPORT_SM_DELETE :
bfa_stats ( rp , sm_off_del ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_uninit ) ;
bfa_rport_free ( rp ) ;
break ;
case BFA_RPORT_SM_ONLINE :
bfa_stats ( rp , sm_off_on ) ;
if ( bfa_rport_send_fwcreate ( rp ) )
bfa_sm_set_state ( rp , bfa_rport_sm_fwcreate ) ;
else
bfa_sm_set_state ( rp , bfa_rport_sm_fwcreate_qfull ) ;
break ;
case BFA_RPORT_SM_HWFAIL :
bfa_stats ( rp , sm_off_hwf ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_iocdisable ) ;
break ;
2012-08-23 06:52:58 +04:00
case BFA_RPORT_SM_OFFLINE :
bfa_rport_offline_cb ( rp ) ;
break ;
2010-09-15 22:50:55 +04:00
default :
bfa_stats ( rp , sm_off_unexp ) ;
bfa_sm_fault ( rp - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Rport is deleted , waiting for firmware response to delete .
*/
static void
bfa_rport_sm_deleting ( struct bfa_rport_s * rp , enum bfa_rport_event event )
{
bfa_trc ( rp - > bfa , rp - > rport_tag ) ;
bfa_trc ( rp - > bfa , event ) ;
switch ( event ) {
case BFA_RPORT_SM_FWRSP :
bfa_stats ( rp , sm_del_fwrsp ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_uninit ) ;
bfa_rport_free ( rp ) ;
break ;
case BFA_RPORT_SM_HWFAIL :
bfa_stats ( rp , sm_del_hwf ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_uninit ) ;
bfa_rport_free ( rp ) ;
break ;
default :
bfa_sm_fault ( rp - > bfa , event ) ;
}
}
static void
bfa_rport_sm_deleting_qfull ( struct bfa_rport_s * rp , enum bfa_rport_event event )
{
bfa_trc ( rp - > bfa , rp - > rport_tag ) ;
bfa_trc ( rp - > bfa , event ) ;
switch ( event ) {
case BFA_RPORT_SM_QRESUME :
bfa_stats ( rp , sm_del_fwrsp ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_deleting ) ;
bfa_rport_send_fwdelete ( rp ) ;
break ;
case BFA_RPORT_SM_HWFAIL :
bfa_stats ( rp , sm_del_hwf ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_uninit ) ;
bfa_reqq_wcancel ( & rp - > reqq_wait ) ;
bfa_rport_free ( rp ) ;
break ;
default :
bfa_sm_fault ( rp - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Waiting for rport create response from firmware . A delete is pending .
*/
static void
bfa_rport_sm_delete_pending ( struct bfa_rport_s * rp ,
enum bfa_rport_event event )
{
bfa_trc ( rp - > bfa , rp - > rport_tag ) ;
bfa_trc ( rp - > bfa , event ) ;
switch ( event ) {
case BFA_RPORT_SM_FWRSP :
bfa_stats ( rp , sm_delp_fwrsp ) ;
if ( bfa_rport_send_fwdelete ( rp ) )
bfa_sm_set_state ( rp , bfa_rport_sm_deleting ) ;
else
bfa_sm_set_state ( rp , bfa_rport_sm_deleting_qfull ) ;
break ;
case BFA_RPORT_SM_HWFAIL :
bfa_stats ( rp , sm_delp_hwf ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_uninit ) ;
bfa_rport_free ( rp ) ;
break ;
default :
bfa_stats ( rp , sm_delp_unexp ) ;
bfa_sm_fault ( rp - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Waiting for rport create response from firmware . Rport offline is pending .
*/
static void
bfa_rport_sm_offline_pending ( struct bfa_rport_s * rp ,
enum bfa_rport_event event )
{
bfa_trc ( rp - > bfa , rp - > rport_tag ) ;
bfa_trc ( rp - > bfa , event ) ;
switch ( event ) {
case BFA_RPORT_SM_FWRSP :
bfa_stats ( rp , sm_offp_fwrsp ) ;
if ( bfa_rport_send_fwdelete ( rp ) )
bfa_sm_set_state ( rp , bfa_rport_sm_fwdelete ) ;
else
bfa_sm_set_state ( rp , bfa_rport_sm_fwdelete_qfull ) ;
break ;
case BFA_RPORT_SM_DELETE :
bfa_stats ( rp , sm_offp_del ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_delete_pending ) ;
break ;
case BFA_RPORT_SM_HWFAIL :
bfa_stats ( rp , sm_offp_hwf ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_iocdisable ) ;
2012-08-23 06:52:58 +04:00
bfa_rport_offline_cb ( rp ) ;
2010-09-15 22:50:55 +04:00
break ;
default :
bfa_stats ( rp , sm_offp_unexp ) ;
bfa_sm_fault ( rp - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* IOC h / w failed .
*/
static void
bfa_rport_sm_iocdisable ( struct bfa_rport_s * rp , enum bfa_rport_event event )
{
bfa_trc ( rp - > bfa , rp - > rport_tag ) ;
bfa_trc ( rp - > bfa , event ) ;
switch ( event ) {
case BFA_RPORT_SM_OFFLINE :
bfa_stats ( rp , sm_iocd_off ) ;
bfa_rport_offline_cb ( rp ) ;
break ;
case BFA_RPORT_SM_DELETE :
bfa_stats ( rp , sm_iocd_del ) ;
bfa_sm_set_state ( rp , bfa_rport_sm_uninit ) ;
bfa_rport_free ( rp ) ;
break ;
case BFA_RPORT_SM_ONLINE :
bfa_stats ( rp , sm_iocd_on ) ;
if ( bfa_rport_send_fwcreate ( rp ) )
bfa_sm_set_state ( rp , bfa_rport_sm_fwcreate ) ;
else
bfa_sm_set_state ( rp , bfa_rport_sm_fwcreate_qfull ) ;
break ;
case BFA_RPORT_SM_HWFAIL :
break ;
default :
bfa_stats ( rp , sm_iocd_unexp ) ;
bfa_sm_fault ( rp - > bfa , event ) ;
}
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* bfa_rport_private BFA rport private functions
*/
static void
__bfa_cb_rport_online ( void * cbarg , bfa_boolean_t complete )
{
struct bfa_rport_s * rp = cbarg ;
if ( complete )
bfa_cb_rport_online ( rp - > rport_drv ) ;
}
static void
__bfa_cb_rport_offline ( void * cbarg , bfa_boolean_t complete )
{
struct bfa_rport_s * rp = cbarg ;
if ( complete )
bfa_cb_rport_offline ( rp - > rport_drv ) ;
}
static void
bfa_rport_qresume ( void * cbarg )
{
struct bfa_rport_s * rp = cbarg ;
bfa_sm_send_event ( rp , BFA_RPORT_SM_QRESUME ) ;
}
static void
2011-06-25 07:24:29 +04:00
bfa_rport_meminfo ( struct bfa_iocfc_cfg_s * cfg , struct bfa_meminfo_s * minfo ,
struct bfa_s * bfa )
2010-09-15 22:50:55 +04:00
{
2011-06-25 07:24:29 +04:00
struct bfa_mem_kva_s * rport_kva = BFA_MEM_RPORT_KVA ( bfa ) ;
2010-09-15 22:50:55 +04:00
if ( cfg - > fwcfg . num_rports < BFA_RPORT_MIN )
cfg - > fwcfg . num_rports = BFA_RPORT_MIN ;
2011-06-25 07:24:29 +04:00
/* kva memory */
bfa_mem_kva_setup ( minfo , rport_kva ,
cfg - > fwcfg . num_rports * sizeof ( struct bfa_rport_s ) ) ;
2010-09-15 22:50:55 +04:00
}
static void
bfa_rport_attach ( struct bfa_s * bfa , void * bfad , struct bfa_iocfc_cfg_s * cfg ,
2011-06-25 07:24:29 +04:00
struct bfa_pcidev_s * pcidev )
2010-09-15 22:50:55 +04:00
{
struct bfa_rport_mod_s * mod = BFA_RPORT_MOD ( bfa ) ;
struct bfa_rport_s * rp ;
u16 i ;
INIT_LIST_HEAD ( & mod - > rp_free_q ) ;
INIT_LIST_HEAD ( & mod - > rp_active_q ) ;
2011-06-25 07:24:08 +04:00
INIT_LIST_HEAD ( & mod - > rp_unused_q ) ;
2010-09-15 22:50:55 +04:00
2011-06-25 07:24:29 +04:00
rp = ( struct bfa_rport_s * ) bfa_mem_kva_curp ( mod ) ;
2010-09-15 22:50:55 +04:00
mod - > rps_list = rp ;
mod - > num_rports = cfg - > fwcfg . num_rports ;
2010-12-27 08:46:35 +03:00
WARN_ON ( ! mod - > num_rports | |
( mod - > num_rports & ( mod - > num_rports - 1 ) ) ) ;
2010-09-15 22:50:55 +04:00
for ( i = 0 ; i < mod - > num_rports ; i + + , rp + + ) {
2010-10-19 04:08:54 +04:00
memset ( rp , 0 , sizeof ( struct bfa_rport_s ) ) ;
2010-09-15 22:50:55 +04:00
rp - > bfa = bfa ;
rp - > rport_tag = i ;
bfa_sm_set_state ( rp , bfa_rport_sm_uninit ) ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* - is unused
*/
if ( i )
list_add_tail ( & rp - > qe , & mod - > rp_free_q ) ;
bfa_reqq_winit ( & rp - > reqq_wait , bfa_rport_qresume , rp ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* consume memory
*/
2011-06-25 07:24:29 +04:00
bfa_mem_kva_curp ( mod ) = ( u8 * ) rp ;
2010-09-15 22:50:55 +04:00
}
static void
bfa_rport_detach ( struct bfa_s * bfa )
{
}
static void
bfa_rport_start ( struct bfa_s * bfa )
{
}
static void
bfa_rport_stop ( struct bfa_s * bfa )
{
}
static void
bfa_rport_iocdisable ( struct bfa_s * bfa )
{
struct bfa_rport_mod_s * mod = BFA_RPORT_MOD ( bfa ) ;
struct bfa_rport_s * rport ;
struct list_head * qe , * qen ;
2011-06-25 07:24:08 +04:00
/* Enqueue unused rport resources to free_q */
list_splice_tail_init ( & mod - > rp_unused_q , & mod - > rp_free_q ) ;
2010-09-15 22:50:55 +04:00
list_for_each_safe ( qe , qen , & mod - > rp_active_q ) {
rport = ( struct bfa_rport_s * ) qe ;
bfa_sm_send_event ( rport , BFA_RPORT_SM_HWFAIL ) ;
}
}
static struct bfa_rport_s *
bfa_rport_alloc ( struct bfa_rport_mod_s * mod )
{
struct bfa_rport_s * rport ;
bfa_q_deq ( & mod - > rp_free_q , & rport ) ;
if ( rport )
list_add_tail ( & rport - > qe , & mod - > rp_active_q ) ;
return rport ;
}
static void
bfa_rport_free ( struct bfa_rport_s * rport )
{
struct bfa_rport_mod_s * mod = BFA_RPORT_MOD ( rport - > bfa ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( ! bfa_q_is_on_q ( & mod - > rp_active_q , rport ) ) ;
2010-09-15 22:50:55 +04:00
list_del ( & rport - > qe ) ;
list_add_tail ( & rport - > qe , & mod - > rp_free_q ) ;
}
static bfa_boolean_t
bfa_rport_send_fwcreate ( struct bfa_rport_s * rp )
{
struct bfi_rport_create_req_s * m ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* check for room in queue to send request now
*/
m = bfa_reqq_next ( rp - > bfa , BFA_REQQ_RPORT ) ;
if ( ! m ) {
bfa_reqq_wait ( rp - > bfa , BFA_REQQ_RPORT , & rp - > reqq_wait ) ;
return BFA_FALSE ;
}
bfi_h2i_set ( m - > mh , BFI_MC_RPORT , BFI_RPORT_H2I_CREATE_REQ ,
2011-06-25 07:24:08 +04:00
bfa_fn_lpu ( rp - > bfa ) ) ;
2010-09-15 22:50:55 +04:00
m - > bfa_handle = rp - > rport_tag ;
2010-10-19 04:10:50 +04:00
m - > max_frmsz = cpu_to_be16 ( rp - > rport_info . max_frmsz ) ;
2010-09-15 22:50:55 +04:00
m - > pid = rp - > rport_info . pid ;
2011-06-25 07:24:08 +04:00
m - > lp_fwtag = bfa_lps_get_fwtag ( rp - > bfa , ( u8 ) rp - > rport_info . lp_tag ) ;
2010-09-15 22:50:55 +04:00
m - > local_pid = rp - > rport_info . local_pid ;
m - > fc_class = rp - > rport_info . fc_class ;
m - > vf_en = rp - > rport_info . vf_en ;
m - > vf_id = rp - > rport_info . vf_id ;
m - > cisc = rp - > rport_info . cisc ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* queue I / O message to firmware
*/
2011-06-25 07:24:08 +04:00
bfa_reqq_produce ( rp - > bfa , BFA_REQQ_RPORT , m - > mh ) ;
2010-09-15 22:50:55 +04:00
return BFA_TRUE ;
}
static bfa_boolean_t
bfa_rport_send_fwdelete ( struct bfa_rport_s * rp )
{
struct bfi_rport_delete_req_s * m ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* check for room in queue to send request now
*/
m = bfa_reqq_next ( rp - > bfa , BFA_REQQ_RPORT ) ;
if ( ! m ) {
bfa_reqq_wait ( rp - > bfa , BFA_REQQ_RPORT , & rp - > reqq_wait ) ;
return BFA_FALSE ;
}
bfi_h2i_set ( m - > mh , BFI_MC_RPORT , BFI_RPORT_H2I_DELETE_REQ ,
2011-06-25 07:24:08 +04:00
bfa_fn_lpu ( rp - > bfa ) ) ;
2010-09-15 22:50:55 +04:00
m - > fw_handle = rp - > fw_handle ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* queue I / O message to firmware
*/
2011-06-25 07:24:08 +04:00
bfa_reqq_produce ( rp - > bfa , BFA_REQQ_RPORT , m - > mh ) ;
2010-09-15 22:50:55 +04:00
return BFA_TRUE ;
}
static bfa_boolean_t
bfa_rport_send_fwspeed ( struct bfa_rport_s * rp )
{
struct bfa_rport_speed_req_s * m ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* check for room in queue to send request now
*/
m = bfa_reqq_next ( rp - > bfa , BFA_REQQ_RPORT ) ;
if ( ! m ) {
bfa_trc ( rp - > bfa , rp - > rport_info . speed ) ;
return BFA_FALSE ;
}
bfi_h2i_set ( m - > mh , BFI_MC_RPORT , BFI_RPORT_H2I_SET_SPEED_REQ ,
2011-06-25 07:24:08 +04:00
bfa_fn_lpu ( rp - > bfa ) ) ;
2010-09-15 22:50:55 +04:00
m - > fw_handle = rp - > fw_handle ;
m - > speed = ( u8 ) rp - > rport_info . speed ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* queue I / O message to firmware
*/
2011-06-25 07:24:08 +04:00
bfa_reqq_produce ( rp - > bfa , BFA_REQQ_RPORT , m - > mh ) ;
2010-09-15 22:50:55 +04:00
return BFA_TRUE ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* bfa_rport_public
*/
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Rport interrupt processing .
*/
void
bfa_rport_isr ( struct bfa_s * bfa , struct bfi_msg_s * m )
{
union bfi_rport_i2h_msg_u msg ;
struct bfa_rport_s * rp ;
bfa_trc ( bfa , m - > mhdr . msg_id ) ;
msg . msg = m ;
switch ( m - > mhdr . msg_id ) {
case BFI_RPORT_I2H_CREATE_RSP :
rp = BFA_RPORT_FROM_TAG ( bfa , msg . create_rsp - > bfa_handle ) ;
rp - > fw_handle = msg . create_rsp - > fw_handle ;
rp - > qos_attr = msg . create_rsp - > qos_attr ;
2011-07-21 04:04:03 +04:00
bfa_rport_set_lunmask ( bfa , rp ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( msg . create_rsp - > status ! = BFA_STATUS_OK ) ;
2010-09-15 22:50:55 +04:00
bfa_sm_send_event ( rp , BFA_RPORT_SM_FWRSP ) ;
break ;
case BFI_RPORT_I2H_DELETE_RSP :
rp = BFA_RPORT_FROM_TAG ( bfa , msg . delete_rsp - > bfa_handle ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( msg . delete_rsp - > status ! = BFA_STATUS_OK ) ;
2011-07-21 04:04:03 +04:00
bfa_rport_unset_lunmask ( bfa , rp ) ;
2010-09-15 22:50:55 +04:00
bfa_sm_send_event ( rp , BFA_RPORT_SM_FWRSP ) ;
break ;
case BFI_RPORT_I2H_QOS_SCN :
rp = BFA_RPORT_FROM_TAG ( bfa , msg . qos_scn_evt - > bfa_handle ) ;
rp - > event_arg . fw_msg = msg . qos_scn_evt ;
bfa_sm_send_event ( rp , BFA_RPORT_SM_QOS_SCN ) ;
break ;
2012-09-22 04:23:59 +04:00
case BFI_RPORT_I2H_LIP_SCN_ONLINE :
bfa_fcport_update_loop_info ( BFA_FCPORT_MOD ( bfa ) ,
& msg . lip_scn - > loop_info ) ;
bfa_cb_rport_scn_online ( bfa ) ;
break ;
case BFI_RPORT_I2H_LIP_SCN_OFFLINE :
bfa_cb_rport_scn_offline ( bfa ) ;
break ;
case BFI_RPORT_I2H_NO_DEV :
rp = BFA_RPORT_FROM_TAG ( bfa , msg . lip_scn - > bfa_handle ) ;
bfa_cb_rport_scn_no_dev ( rp - > rport_drv ) ;
break ;
2010-09-15 22:50:55 +04:00
default :
bfa_trc ( bfa , m - > mhdr . msg_id ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( 1 ) ;
2010-09-15 22:50:55 +04:00
}
}
2011-06-25 07:24:08 +04:00
void
bfa_rport_res_recfg ( struct bfa_s * bfa , u16 num_rport_fw )
{
struct bfa_rport_mod_s * mod = BFA_RPORT_MOD ( bfa ) ;
struct list_head * qe ;
int i ;
2010-09-15 22:50:55 +04:00
2011-06-25 07:24:08 +04:00
for ( i = 0 ; i < ( mod - > num_rports - num_rport_fw ) ; i + + ) {
bfa_q_deq_tail ( & mod - > rp_free_q , & qe ) ;
list_add_tail ( qe , & mod - > rp_unused_q ) ;
}
}
2010-09-15 22:50:55 +04:00
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* bfa_rport_api
*/
struct bfa_rport_s *
bfa_rport_create ( struct bfa_s * bfa , void * rport_drv )
{
struct bfa_rport_s * rp ;
rp = bfa_rport_alloc ( BFA_RPORT_MOD ( bfa ) ) ;
if ( rp = = NULL )
return NULL ;
rp - > bfa = bfa ;
rp - > rport_drv = rport_drv ;
2010-12-10 06:08:43 +03:00
memset ( & rp - > stats , 0 , sizeof ( rp - > stats ) ) ;
2010-09-15 22:50:55 +04:00
2010-12-27 08:46:35 +03:00
WARN_ON ( ! bfa_sm_cmp_state ( rp , bfa_rport_sm_uninit ) ) ;
2010-09-15 22:50:55 +04:00
bfa_sm_send_event ( rp , BFA_RPORT_SM_CREATE ) ;
return rp ;
}
void
bfa_rport_online ( struct bfa_rport_s * rport , struct bfa_rport_info_s * rport_info )
{
2010-12-27 08:46:35 +03:00
WARN_ON ( rport_info - > max_frmsz = = 0 ) ;
2010-09-15 22:50:55 +04:00
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Some JBODs are seen to be not setting PDU size correctly in PLOGI
* responses . Default to minimum size .
*/
if ( rport_info - > max_frmsz = = 0 ) {
bfa_trc ( rport - > bfa , rport - > rport_tag ) ;
rport_info - > max_frmsz = FC_MIN_PDUSZ ;
}
2010-10-19 04:08:54 +04:00
rport - > rport_info = * rport_info ;
2010-09-15 22:50:55 +04:00
bfa_sm_send_event ( rport , BFA_RPORT_SM_ONLINE ) ;
}
void
bfa_rport_speed ( struct bfa_rport_s * rport , enum bfa_port_speed speed )
{
2010-12-27 08:46:35 +03:00
WARN_ON ( speed = = 0 ) ;
WARN_ON ( speed = = BFA_PORT_SPEED_AUTO ) ;
2010-09-15 22:50:55 +04:00
2012-08-23 06:52:58 +04:00
if ( rport ) {
rport - > rport_info . speed = speed ;
bfa_sm_send_event ( rport , BFA_RPORT_SM_SET_SPEED ) ;
}
2010-09-15 22:50:55 +04:00
}
2011-07-21 04:04:03 +04:00
/* Set Rport LUN Mask */
void
bfa_rport_set_lunmask ( struct bfa_s * bfa , struct bfa_rport_s * rp )
{
struct bfa_lps_mod_s * lps_mod = BFA_LPS_MOD ( bfa ) ;
wwn_t lp_wwn , rp_wwn ;
u8 lp_tag = ( u8 ) rp - > rport_info . lp_tag ;
rp_wwn = ( ( struct bfa_fcs_rport_s * ) rp - > rport_drv ) - > pwwn ;
lp_wwn = ( BFA_LPS_FROM_TAG ( lps_mod , rp - > rport_info . lp_tag ) ) - > pwwn ;
BFA_LPS_FROM_TAG ( lps_mod , rp - > rport_info . lp_tag ) - > lun_mask =
rp - > lun_mask = BFA_TRUE ;
bfa_fcpim_lunmask_rp_update ( bfa , lp_wwn , rp_wwn , rp - > rport_tag , lp_tag ) ;
}
/* Unset Rport LUN mask */
void
bfa_rport_unset_lunmask ( struct bfa_s * bfa , struct bfa_rport_s * rp )
{
struct bfa_lps_mod_s * lps_mod = BFA_LPS_MOD ( bfa ) ;
wwn_t lp_wwn , rp_wwn ;
rp_wwn = ( ( struct bfa_fcs_rport_s * ) rp - > rport_drv ) - > pwwn ;
lp_wwn = ( BFA_LPS_FROM_TAG ( lps_mod , rp - > rport_info . lp_tag ) ) - > pwwn ;
BFA_LPS_FROM_TAG ( lps_mod , rp - > rport_info . lp_tag ) - > lun_mask =
rp - > lun_mask = BFA_FALSE ;
bfa_fcpim_lunmask_rp_update ( bfa , lp_wwn , rp_wwn ,
BFA_RPORT_TAG_INVALID , BFA_LP_TAG_INVALID ) ;
}
2010-09-15 22:50:55 +04:00
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* SGPG related functions
*/
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Compute and return memory needed by FCP ( im ) module .
*/
static void
2011-06-25 07:24:29 +04:00
bfa_sgpg_meminfo ( struct bfa_iocfc_cfg_s * cfg , struct bfa_meminfo_s * minfo ,
struct bfa_s * bfa )
2010-09-15 22:50:55 +04:00
{
2011-06-25 07:24:29 +04:00
struct bfa_sgpg_mod_s * sgpg_mod = BFA_SGPG_MOD ( bfa ) ;
struct bfa_mem_kva_s * sgpg_kva = BFA_MEM_SGPG_KVA ( bfa ) ;
struct bfa_mem_dma_s * seg_ptr ;
u16 nsegs , idx , per_seg_sgpg , num_sgpg ;
u32 sgpg_sz = sizeof ( struct bfi_sgpg_s ) ;
2010-09-15 22:50:55 +04:00
if ( cfg - > drvcfg . num_sgpgs < BFA_SGPG_MIN )
cfg - > drvcfg . num_sgpgs = BFA_SGPG_MIN ;
2011-06-25 07:24:29 +04:00
else if ( cfg - > drvcfg . num_sgpgs > BFA_SGPG_MAX )
cfg - > drvcfg . num_sgpgs = BFA_SGPG_MAX ;
2010-09-15 22:50:55 +04:00
2011-06-25 07:24:29 +04:00
num_sgpg = cfg - > drvcfg . num_sgpgs ;
nsegs = BFI_MEM_DMA_NSEGS ( num_sgpg , sgpg_sz ) ;
per_seg_sgpg = BFI_MEM_NREQS_SEG ( sgpg_sz ) ;
bfa_mem_dma_seg_iter ( sgpg_mod , seg_ptr , nsegs , idx ) {
if ( num_sgpg > = per_seg_sgpg ) {
num_sgpg - = per_seg_sgpg ;
bfa_mem_dma_setup ( minfo , seg_ptr ,
per_seg_sgpg * sgpg_sz ) ;
} else
bfa_mem_dma_setup ( minfo , seg_ptr ,
num_sgpg * sgpg_sz ) ;
}
2010-09-15 22:50:55 +04:00
2011-06-25 07:24:29 +04:00
/* kva memory */
bfa_mem_kva_setup ( minfo , sgpg_kva ,
cfg - > drvcfg . num_sgpgs * sizeof ( struct bfa_sgpg_s ) ) ;
}
2010-09-15 22:50:55 +04:00
static void
bfa_sgpg_attach ( struct bfa_s * bfa , void * bfad , struct bfa_iocfc_cfg_s * cfg ,
2011-06-25 07:24:29 +04:00
struct bfa_pcidev_s * pcidev )
2010-09-15 22:50:55 +04:00
{
struct bfa_sgpg_mod_s * mod = BFA_SGPG_MOD ( bfa ) ;
struct bfa_sgpg_s * hsgpg ;
struct bfi_sgpg_s * sgpg ;
u64 align_len ;
2011-06-25 07:24:29 +04:00
struct bfa_mem_dma_s * seg_ptr ;
u32 sgpg_sz = sizeof ( struct bfi_sgpg_s ) ;
u16 i , idx , nsegs , per_seg_sgpg , num_sgpg ;
2010-09-15 22:50:55 +04:00
union {
u64 pa ;
union bfi_addr_u addr ;
} sgpg_pa , sgpg_pa_tmp ;
INIT_LIST_HEAD ( & mod - > sgpg_q ) ;
INIT_LIST_HEAD ( & mod - > sgpg_wait_q ) ;
bfa_trc ( bfa , cfg - > drvcfg . num_sgpgs ) ;
2011-06-25 07:24:29 +04:00
mod - > free_sgpgs = mod - > num_sgpgs = cfg - > drvcfg . num_sgpgs ;
num_sgpg = cfg - > drvcfg . num_sgpgs ;
nsegs = BFI_MEM_DMA_NSEGS ( num_sgpg , sgpg_sz ) ;
/* dma/kva mem claim */
hsgpg = ( struct bfa_sgpg_s * ) bfa_mem_kva_curp ( mod ) ;
bfa_mem_dma_seg_iter ( mod , seg_ptr , nsegs , idx ) {
if ( ! bfa_mem_dma_virt ( seg_ptr ) )
break ;
align_len = BFA_SGPG_ROUNDUP ( bfa_mem_dma_phys ( seg_ptr ) ) -
bfa_mem_dma_phys ( seg_ptr ) ;
sgpg = ( struct bfi_sgpg_s * )
( ( ( u8 * ) bfa_mem_dma_virt ( seg_ptr ) ) + align_len ) ;
sgpg_pa . pa = bfa_mem_dma_phys ( seg_ptr ) + align_len ;
WARN_ON ( sgpg_pa . pa & ( sgpg_sz - 1 ) ) ;
per_seg_sgpg = ( seg_ptr - > mem_len - ( u32 ) align_len ) / sgpg_sz ;
for ( i = 0 ; num_sgpg > 0 & & i < per_seg_sgpg ; i + + , num_sgpg - - ) {
memset ( hsgpg , 0 , sizeof ( * hsgpg ) ) ;
memset ( sgpg , 0 , sizeof ( * sgpg ) ) ;
hsgpg - > sgpg = sgpg ;
sgpg_pa_tmp . pa = bfa_sgaddr_le ( sgpg_pa . pa ) ;
hsgpg - > sgpg_pa = sgpg_pa_tmp . addr ;
list_add_tail ( & hsgpg - > qe , & mod - > sgpg_q ) ;
sgpg + + ;
hsgpg + + ;
sgpg_pa . pa + = sgpg_sz ;
}
2010-09-15 22:50:55 +04:00
}
2011-06-25 07:24:29 +04:00
bfa_mem_kva_curp ( mod ) = ( u8 * ) hsgpg ;
2010-09-15 22:50:55 +04:00
}
static void
bfa_sgpg_detach ( struct bfa_s * bfa )
{
}
static void
bfa_sgpg_start ( struct bfa_s * bfa )
{
}
static void
bfa_sgpg_stop ( struct bfa_s * bfa )
{
}
static void
bfa_sgpg_iocdisable ( struct bfa_s * bfa )
{
}
bfa_status_t
bfa_sgpg_malloc ( struct bfa_s * bfa , struct list_head * sgpg_q , int nsgpgs )
{
struct bfa_sgpg_mod_s * mod = BFA_SGPG_MOD ( bfa ) ;
struct bfa_sgpg_s * hsgpg ;
int i ;
if ( mod - > free_sgpgs < nsgpgs )
return BFA_STATUS_ENOMEM ;
for ( i = 0 ; i < nsgpgs ; i + + ) {
bfa_q_deq ( & mod - > sgpg_q , & hsgpg ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( ! hsgpg ) ;
2010-09-15 22:50:55 +04:00
list_add_tail ( & hsgpg - > qe , sgpg_q ) ;
}
mod - > free_sgpgs - = nsgpgs ;
return BFA_STATUS_OK ;
}
void
bfa_sgpg_mfree ( struct bfa_s * bfa , struct list_head * sgpg_q , int nsgpg )
{
struct bfa_sgpg_mod_s * mod = BFA_SGPG_MOD ( bfa ) ;
struct bfa_sgpg_wqe_s * wqe ;
mod - > free_sgpgs + = nsgpg ;
2010-12-27 08:46:35 +03:00
WARN_ON ( mod - > free_sgpgs > mod - > num_sgpgs ) ;
2010-09-15 22:50:55 +04:00
list_splice_tail_init ( sgpg_q , & mod - > sgpg_q ) ;
if ( list_empty ( & mod - > sgpg_wait_q ) )
return ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* satisfy as many waiting requests as possible
*/
do {
wqe = bfa_q_first ( & mod - > sgpg_wait_q ) ;
if ( mod - > free_sgpgs < wqe - > nsgpg )
nsgpg = mod - > free_sgpgs ;
else
nsgpg = wqe - > nsgpg ;
bfa_sgpg_malloc ( bfa , & wqe - > sgpg_q , nsgpg ) ;
wqe - > nsgpg - = nsgpg ;
if ( wqe - > nsgpg = = 0 ) {
list_del ( & wqe - > qe ) ;
wqe - > cbfn ( wqe - > cbarg ) ;
}
} while ( mod - > free_sgpgs & & ! list_empty ( & mod - > sgpg_wait_q ) ) ;
}
void
bfa_sgpg_wait ( struct bfa_s * bfa , struct bfa_sgpg_wqe_s * wqe , int nsgpg )
{
struct bfa_sgpg_mod_s * mod = BFA_SGPG_MOD ( bfa ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( nsgpg < = 0 ) ;
WARN_ON ( nsgpg < = mod - > free_sgpgs ) ;
2010-09-15 22:50:55 +04:00
wqe - > nsgpg_total = wqe - > nsgpg = nsgpg ;
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* allocate any left to this one first
*/
if ( mod - > free_sgpgs ) {
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* no one else is waiting for SGPG
*/
2010-12-27 08:46:35 +03:00
WARN_ON ( ! list_empty ( & mod - > sgpg_wait_q ) ) ;
2010-09-15 22:50:55 +04:00
list_splice_tail_init ( & mod - > sgpg_q , & wqe - > sgpg_q ) ;
wqe - > nsgpg - = mod - > free_sgpgs ;
mod - > free_sgpgs = 0 ;
}
list_add_tail ( & wqe - > qe , & mod - > sgpg_wait_q ) ;
}
void
bfa_sgpg_wcancel ( struct bfa_s * bfa , struct bfa_sgpg_wqe_s * wqe )
{
struct bfa_sgpg_mod_s * mod = BFA_SGPG_MOD ( bfa ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( ! bfa_q_is_on_q ( & mod - > sgpg_wait_q , wqe ) ) ;
2010-09-15 22:50:55 +04:00
list_del ( & wqe - > qe ) ;
if ( wqe - > nsgpg_total ! = wqe - > nsgpg )
bfa_sgpg_mfree ( bfa , & wqe - > sgpg_q ,
wqe - > nsgpg_total - wqe - > nsgpg ) ;
}
void
bfa_sgpg_winit ( struct bfa_sgpg_wqe_s * wqe , void ( * cbfn ) ( void * cbarg ) ,
void * cbarg )
{
INIT_LIST_HEAD ( & wqe - > sgpg_q ) ;
wqe - > cbfn = cbfn ;
wqe - > cbarg = cbarg ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* UF related functions
*/
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Internal functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
static void
__bfa_cb_uf_recv ( void * cbarg , bfa_boolean_t complete )
{
struct bfa_uf_s * uf = cbarg ;
struct bfa_uf_mod_s * ufm = BFA_UF_MOD ( uf - > bfa ) ;
if ( complete )
ufm - > ufrecv ( ufm - > cbarg , uf ) ;
}
static void
2011-06-25 07:24:29 +04:00
claim_uf_post_msgs ( struct bfa_uf_mod_s * ufm )
2010-09-15 22:50:55 +04:00
{
struct bfi_uf_buf_post_s * uf_bp_msg ;
u16 i ;
u16 buf_len ;
2011-06-25 07:24:29 +04:00
ufm - > uf_buf_posts = ( struct bfi_uf_buf_post_s * ) bfa_mem_kva_curp ( ufm ) ;
2010-09-15 22:50:55 +04:00
uf_bp_msg = ufm - > uf_buf_posts ;
for ( i = 0 , uf_bp_msg = ufm - > uf_buf_posts ; i < ufm - > num_ufs ;
i + + , uf_bp_msg + + ) {
2010-10-19 04:08:54 +04:00
memset ( uf_bp_msg , 0 , sizeof ( struct bfi_uf_buf_post_s ) ) ;
2010-09-15 22:50:55 +04:00
uf_bp_msg - > buf_tag = i ;
buf_len = sizeof ( struct bfa_uf_buf_s ) ;
2010-10-19 04:10:50 +04:00
uf_bp_msg - > buf_len = cpu_to_be16 ( buf_len ) ;
2010-09-15 22:50:55 +04:00
bfi_h2i_set ( uf_bp_msg - > mh , BFI_MC_UF , BFI_UF_H2I_BUF_POST ,
2011-06-25 07:24:08 +04:00
bfa_fn_lpu ( ufm - > bfa ) ) ;
2011-06-14 02:39:36 +04:00
bfa_alen_set ( & uf_bp_msg - > alen , buf_len , ufm_pbs_pa ( ufm , i ) ) ;
2010-09-15 22:50:55 +04:00
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* advance pointer beyond consumed memory
*/
2011-06-25 07:24:29 +04:00
bfa_mem_kva_curp ( ufm ) = ( u8 * ) uf_bp_msg ;
2010-09-15 22:50:55 +04:00
}
static void
2011-06-25 07:24:29 +04:00
claim_ufs ( struct bfa_uf_mod_s * ufm )
2010-09-15 22:50:55 +04:00
{
u16 i ;
struct bfa_uf_s * uf ;
/*
* Claim block of memory for UF list
*/
2011-06-25 07:24:29 +04:00
ufm - > uf_list = ( struct bfa_uf_s * ) bfa_mem_kva_curp ( ufm ) ;
2010-09-15 22:50:55 +04:00
/*
* Initialize UFs and queue it in UF free queue
*/
for ( i = 0 , uf = ufm - > uf_list ; i < ufm - > num_ufs ; i + + , uf + + ) {
2010-10-19 04:08:54 +04:00
memset ( uf , 0 , sizeof ( struct bfa_uf_s ) ) ;
2010-09-15 22:50:55 +04:00
uf - > bfa = ufm - > bfa ;
uf - > uf_tag = i ;
2011-06-25 07:24:29 +04:00
uf - > pb_len = BFA_PER_UF_DMA_SZ ;
uf - > buf_kva = bfa_mem_get_dmabuf_kva ( ufm , i , BFA_PER_UF_DMA_SZ ) ;
2010-09-15 22:50:55 +04:00
uf - > buf_pa = ufm_pbs_pa ( ufm , i ) ;
list_add_tail ( & uf - > qe , & ufm - > uf_free_q ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* advance memory pointer
*/
2011-06-25 07:24:29 +04:00
bfa_mem_kva_curp ( ufm ) = ( u8 * ) uf ;
2010-09-15 22:50:55 +04:00
}
static void
2011-06-25 07:24:29 +04:00
uf_mem_claim ( struct bfa_uf_mod_s * ufm )
2010-09-15 22:50:55 +04:00
{
2011-06-25 07:24:29 +04:00
claim_ufs ( ufm ) ;
claim_uf_post_msgs ( ufm ) ;
2010-09-15 22:50:55 +04:00
}
static void
2011-06-25 07:24:29 +04:00
bfa_uf_meminfo ( struct bfa_iocfc_cfg_s * cfg , struct bfa_meminfo_s * minfo ,
struct bfa_s * bfa )
2010-09-15 22:50:55 +04:00
{
2011-06-25 07:24:29 +04:00
struct bfa_uf_mod_s * ufm = BFA_UF_MOD ( bfa ) ;
struct bfa_mem_kva_s * uf_kva = BFA_MEM_UF_KVA ( bfa ) ;
u32 num_ufs = cfg - > fwcfg . num_uf_bufs ;
struct bfa_mem_dma_s * seg_ptr ;
u16 nsegs , idx , per_seg_uf = 0 ;
nsegs = BFI_MEM_DMA_NSEGS ( num_ufs , BFA_PER_UF_DMA_SZ ) ;
per_seg_uf = BFI_MEM_NREQS_SEG ( BFA_PER_UF_DMA_SZ ) ;
bfa_mem_dma_seg_iter ( ufm , seg_ptr , nsegs , idx ) {
if ( num_ufs > = per_seg_uf ) {
num_ufs - = per_seg_uf ;
bfa_mem_dma_setup ( minfo , seg_ptr ,
per_seg_uf * BFA_PER_UF_DMA_SZ ) ;
} else
bfa_mem_dma_setup ( minfo , seg_ptr ,
num_ufs * BFA_PER_UF_DMA_SZ ) ;
}
2010-09-15 22:50:55 +04:00
2011-06-25 07:24:29 +04:00
/* kva memory */
bfa_mem_kva_setup ( minfo , uf_kva , cfg - > fwcfg . num_uf_bufs *
( sizeof ( struct bfa_uf_s ) + sizeof ( struct bfi_uf_buf_post_s ) ) ) ;
2010-09-15 22:50:55 +04:00
}
static void
bfa_uf_attach ( struct bfa_s * bfa , void * bfad , struct bfa_iocfc_cfg_s * cfg ,
2011-06-25 07:24:29 +04:00
struct bfa_pcidev_s * pcidev )
2010-09-15 22:50:55 +04:00
{
struct bfa_uf_mod_s * ufm = BFA_UF_MOD ( bfa ) ;
ufm - > bfa = bfa ;
ufm - > num_ufs = cfg - > fwcfg . num_uf_bufs ;
INIT_LIST_HEAD ( & ufm - > uf_free_q ) ;
INIT_LIST_HEAD ( & ufm - > uf_posted_q ) ;
2011-06-25 07:24:08 +04:00
INIT_LIST_HEAD ( & ufm - > uf_unused_q ) ;
2010-09-15 22:50:55 +04:00
2011-06-25 07:24:29 +04:00
uf_mem_claim ( ufm ) ;
2010-09-15 22:50:55 +04:00
}
static void
bfa_uf_detach ( struct bfa_s * bfa )
{
}
static struct bfa_uf_s *
bfa_uf_get ( struct bfa_uf_mod_s * uf_mod )
{
struct bfa_uf_s * uf ;
bfa_q_deq ( & uf_mod - > uf_free_q , & uf ) ;
return uf ;
}
static void
bfa_uf_put ( struct bfa_uf_mod_s * uf_mod , struct bfa_uf_s * uf )
{
list_add_tail ( & uf - > qe , & uf_mod - > uf_free_q ) ;
}
static bfa_status_t
bfa_uf_post ( struct bfa_uf_mod_s * ufm , struct bfa_uf_s * uf )
{
struct bfi_uf_buf_post_s * uf_post_msg ;
uf_post_msg = bfa_reqq_next ( ufm - > bfa , BFA_REQQ_FCXP ) ;
if ( ! uf_post_msg )
return BFA_STATUS_FAILED ;
2010-10-19 04:08:54 +04:00
memcpy ( uf_post_msg , & ufm - > uf_buf_posts [ uf - > uf_tag ] ,
2010-09-15 22:50:55 +04:00
sizeof ( struct bfi_uf_buf_post_s ) ) ;
2011-06-25 07:24:08 +04:00
bfa_reqq_produce ( ufm - > bfa , BFA_REQQ_FCXP , uf_post_msg - > mh ) ;
2010-09-15 22:50:55 +04:00
bfa_trc ( ufm - > bfa , uf - > uf_tag ) ;
list_add_tail ( & uf - > qe , & ufm - > uf_posted_q ) ;
return BFA_STATUS_OK ;
}
static void
bfa_uf_post_all ( struct bfa_uf_mod_s * uf_mod )
{
struct bfa_uf_s * uf ;
while ( ( uf = bfa_uf_get ( uf_mod ) ) ! = NULL ) {
if ( bfa_uf_post ( uf_mod , uf ) ! = BFA_STATUS_OK )
break ;
}
}
static void
uf_recv ( struct bfa_s * bfa , struct bfi_uf_frm_rcvd_s * m )
{
struct bfa_uf_mod_s * ufm = BFA_UF_MOD ( bfa ) ;
u16 uf_tag = m - > buf_tag ;
struct bfa_uf_s * uf = & ufm - > uf_list [ uf_tag ] ;
2011-06-25 07:24:29 +04:00
struct bfa_uf_buf_s * uf_buf ;
uint8_t * buf ;
2010-09-15 22:50:55 +04:00
struct fchs_s * fchs ;
2011-06-25 07:24:29 +04:00
uf_buf = ( struct bfa_uf_buf_s * )
bfa_mem_get_dmabuf_kva ( ufm , uf_tag , uf - > pb_len ) ;
buf = & uf_buf - > d [ 0 ] ;
2010-10-19 04:10:50 +04:00
m - > frm_len = be16_to_cpu ( m - > frm_len ) ;
m - > xfr_len = be16_to_cpu ( m - > xfr_len ) ;
2010-09-15 22:50:55 +04:00
fchs = ( struct fchs_s * ) uf_buf ;
list_del ( & uf - > qe ) ; /* dequeue from posted queue */
uf - > data_ptr = buf ;
uf - > data_len = m - > xfr_len ;
2010-12-27 08:46:35 +03:00
WARN_ON ( uf - > data_len < sizeof ( struct fchs_s ) ) ;
2010-09-15 22:50:55 +04:00
if ( uf - > data_len = = sizeof ( struct fchs_s ) ) {
bfa_plog_fchdr ( bfa - > plog , BFA_PL_MID_HAL_UF , BFA_PL_EID_RX ,
uf - > data_len , ( struct fchs_s * ) buf ) ;
} else {
u32 pld_w0 = * ( ( u32 * ) ( buf + sizeof ( struct fchs_s ) ) ) ;
bfa_plog_fchdr_and_pl ( bfa - > plog , BFA_PL_MID_HAL_UF ,
BFA_PL_EID_RX , uf - > data_len ,
( struct fchs_s * ) buf , pld_w0 ) ;
}
if ( bfa - > fcs )
__bfa_cb_uf_recv ( uf , BFA_TRUE ) ;
else
bfa_cb_queue ( bfa , & uf - > hcb_qe , __bfa_cb_uf_recv , uf ) ;
}
static void
bfa_uf_stop ( struct bfa_s * bfa )
{
}
static void
bfa_uf_iocdisable ( struct bfa_s * bfa )
{
struct bfa_uf_mod_s * ufm = BFA_UF_MOD ( bfa ) ;
struct bfa_uf_s * uf ;
struct list_head * qe , * qen ;
2011-06-25 07:24:08 +04:00
/* Enqueue unused uf resources to free_q */
list_splice_tail_init ( & ufm - > uf_unused_q , & ufm - > uf_free_q ) ;
2010-09-15 22:50:55 +04:00
list_for_each_safe ( qe , qen , & ufm - > uf_posted_q ) {
uf = ( struct bfa_uf_s * ) qe ;
list_del ( & uf - > qe ) ;
bfa_uf_put ( ufm , uf ) ;
}
}
static void
bfa_uf_start ( struct bfa_s * bfa )
{
bfa_uf_post_all ( BFA_UF_MOD ( bfa ) ) ;
}
2010-10-19 04:17:23 +04:00
/*
2011-03-31 05:57:33 +04:00
* Register handler for all unsolicted receive frames .
2010-09-15 22:50:55 +04:00
*
* @ param [ in ] bfa BFA instance
* @ param [ in ] ufrecv receive handler function
* @ param [ in ] cbarg receive handler arg
*/
void
bfa_uf_recv_register ( struct bfa_s * bfa , bfa_cb_uf_recv_t ufrecv , void * cbarg )
{
struct bfa_uf_mod_s * ufm = BFA_UF_MOD ( bfa ) ;
ufm - > ufrecv = ufrecv ;
ufm - > cbarg = cbarg ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* Free an unsolicited frame back to BFA .
*
* @ param [ in ] uf unsolicited frame to be freed
*
* @ return None
*/
void
bfa_uf_free ( struct bfa_uf_s * uf )
{
bfa_uf_put ( BFA_UF_MOD ( uf - > bfa ) , uf ) ;
bfa_uf_post_all ( BFA_UF_MOD ( uf - > bfa ) ) ;
}
2010-10-19 04:17:23 +04:00
/*
2010-09-15 22:50:55 +04:00
* uf_pub BFA uf module public functions
*/
void
bfa_uf_isr ( struct bfa_s * bfa , struct bfi_msg_s * msg )
{
bfa_trc ( bfa , msg - > mhdr . msg_id ) ;
switch ( msg - > mhdr . msg_id ) {
case BFI_UF_I2H_FRM_RCVD :
uf_recv ( bfa , ( struct bfi_uf_frm_rcvd_s * ) msg ) ;
break ;
default :
bfa_trc ( bfa , msg - > mhdr . msg_id ) ;
2010-12-27 08:46:35 +03:00
WARN_ON ( 1 ) ;
2010-09-15 22:50:55 +04:00
}
}
2011-06-25 07:24:08 +04:00
void
bfa_uf_res_recfg ( struct bfa_s * bfa , u16 num_uf_fw )
{
struct bfa_uf_mod_s * mod = BFA_UF_MOD ( bfa ) ;
struct list_head * qe ;
int i ;
2010-09-15 22:50:55 +04:00
2011-06-25 07:24:08 +04:00
for ( i = 0 ; i < ( mod - > num_ufs - num_uf_fw ) ; i + + ) {
bfa_q_deq_tail ( & mod - > uf_free_q , & qe ) ;
list_add_tail ( qe , & mod - > uf_unused_q ) ;
}
}
2011-06-25 07:28:17 +04:00
2012-09-22 04:26:07 +04:00
/*
* Dport forward declaration
*/
2013-05-13 13:33:21 +04:00
enum bfa_dport_test_state_e {
BFA_DPORT_ST_DISABLED = 0 , /*!< dport is disabled */
BFA_DPORT_ST_INP = 1 , /*!< test in progress */
BFA_DPORT_ST_COMP = 2 , /*!< test complete successfully */
BFA_DPORT_ST_NO_SFP = 3 , /*!< sfp is not present */
BFA_DPORT_ST_NOTSTART = 4 , /*!< test not start dport is enabled */
} ;
2012-09-22 04:26:07 +04:00
/*
* BFA DPORT state machine events
*/
enum bfa_dport_sm_event {
BFA_DPORT_SM_ENABLE = 1 , /* dport enable event */
BFA_DPORT_SM_DISABLE = 2 , /* dport disable event */
BFA_DPORT_SM_FWRSP = 3 , /* fw enable/disable rsp */
BFA_DPORT_SM_QRESUME = 4 , /* CQ space available */
BFA_DPORT_SM_HWFAIL = 5 , /* IOC h/w failure */
2013-05-13 13:33:21 +04:00
BFA_DPORT_SM_START = 6 , /* re-start dport test */
BFA_DPORT_SM_REQFAIL = 7 , /* request failure */
BFA_DPORT_SM_SCN = 8 , /* state change notify frm fw */
2012-09-22 04:26:07 +04:00
} ;
static void bfa_dport_sm_disabled ( struct bfa_dport_s * dport ,
enum bfa_dport_sm_event event ) ;
static void bfa_dport_sm_enabling_qwait ( struct bfa_dport_s * dport ,
enum bfa_dport_sm_event event ) ;
static void bfa_dport_sm_enabling ( struct bfa_dport_s * dport ,
enum bfa_dport_sm_event event ) ;
static void bfa_dport_sm_enabled ( struct bfa_dport_s * dport ,
enum bfa_dport_sm_event event ) ;
static void bfa_dport_sm_disabling_qwait ( struct bfa_dport_s * dport ,
enum bfa_dport_sm_event event ) ;
static void bfa_dport_sm_disabling ( struct bfa_dport_s * dport ,
enum bfa_dport_sm_event event ) ;
2013-05-13 13:33:21 +04:00
static void bfa_dport_sm_starting_qwait ( struct bfa_dport_s * dport ,
enum bfa_dport_sm_event event ) ;
static void bfa_dport_sm_starting ( struct bfa_dport_s * dport ,
enum bfa_dport_sm_event event ) ;
static void bfa_dport_sm_dynamic_disabling ( struct bfa_dport_s * dport ,
enum bfa_dport_sm_event event ) ;
static void bfa_dport_sm_dynamic_disabling_qwait ( struct bfa_dport_s * dport ,
enum bfa_dport_sm_event event ) ;
2012-09-22 04:26:07 +04:00
static void bfa_dport_qresume ( void * cbarg ) ;
static void bfa_dport_req_comp ( struct bfa_dport_s * dport ,
2013-05-13 13:33:21 +04:00
struct bfi_diag_dport_rsp_s * msg ) ;
static void bfa_dport_scn ( struct bfa_dport_s * dport ,
struct bfi_diag_dport_scn_s * msg ) ;
2012-09-22 04:26:07 +04:00
2011-06-25 07:28:17 +04:00
/*
* BFA fcdiag module
*/
# define BFA_DIAG_QTEST_TOV 1000 /* msec */
/*
* Set port status to busy
*/
static void
bfa_fcdiag_set_busy_status ( struct bfa_fcdiag_s * fcdiag )
{
struct bfa_fcport_s * fcport = BFA_FCPORT_MOD ( fcdiag - > bfa ) ;
if ( fcdiag - > lb . lock )
fcport - > diag_busy = BFA_TRUE ;
else
fcport - > diag_busy = BFA_FALSE ;
}
static void
bfa_fcdiag_meminfo ( struct bfa_iocfc_cfg_s * cfg , struct bfa_meminfo_s * meminfo ,
struct bfa_s * bfa )
{
}
static void
bfa_fcdiag_attach ( struct bfa_s * bfa , void * bfad , struct bfa_iocfc_cfg_s * cfg ,
struct bfa_pcidev_s * pcidev )
{
struct bfa_fcdiag_s * fcdiag = BFA_FCDIAG_MOD ( bfa ) ;
2012-09-22 04:26:07 +04:00
struct bfa_dport_s * dport = & fcdiag - > dport ;
2011-06-25 07:28:17 +04:00
fcdiag - > bfa = bfa ;
fcdiag - > trcmod = bfa - > trcmod ;
/* The common DIAG attach bfa_diag_attach() will do all memory claim */
2012-09-22 04:26:07 +04:00
dport - > bfa = bfa ;
bfa_sm_set_state ( dport , bfa_dport_sm_disabled ) ;
bfa_reqq_winit ( & dport - > reqq_wait , bfa_dport_qresume , dport ) ;
dport - > cbfn = NULL ;
dport - > cbarg = NULL ;
2013-05-13 13:33:21 +04:00
dport - > test_state = BFA_DPORT_ST_DISABLED ;
memset ( & dport - > result , 0 , sizeof ( struct bfa_diag_dport_result_s ) ) ;
2011-06-25 07:28:17 +04:00
}
static void
bfa_fcdiag_iocdisable ( struct bfa_s * bfa )
{
struct bfa_fcdiag_s * fcdiag = BFA_FCDIAG_MOD ( bfa ) ;
2012-09-22 04:26:07 +04:00
struct bfa_dport_s * dport = & fcdiag - > dport ;
2011-06-25 07:28:17 +04:00
bfa_trc ( fcdiag , fcdiag - > lb . lock ) ;
if ( fcdiag - > lb . lock ) {
fcdiag - > lb . status = BFA_STATUS_IOC_FAILURE ;
fcdiag - > lb . cbfn ( fcdiag - > lb . cbarg , fcdiag - > lb . status ) ;
fcdiag - > lb . lock = 0 ;
bfa_fcdiag_set_busy_status ( fcdiag ) ;
}
2012-09-22 04:26:07 +04:00
bfa_sm_send_event ( dport , BFA_DPORT_SM_HWFAIL ) ;
2011-06-25 07:28:17 +04:00
}
static void
bfa_fcdiag_detach ( struct bfa_s * bfa )
{
}
static void
bfa_fcdiag_start ( struct bfa_s * bfa )
{
}
static void
bfa_fcdiag_stop ( struct bfa_s * bfa )
{
}
static void
bfa_fcdiag_queuetest_timeout ( void * cbarg )
{
struct bfa_fcdiag_s * fcdiag = cbarg ;
struct bfa_diag_qtest_result_s * res = fcdiag - > qtest . result ;
bfa_trc ( fcdiag , fcdiag - > qtest . all ) ;
bfa_trc ( fcdiag , fcdiag - > qtest . count ) ;
fcdiag - > qtest . timer_active = 0 ;
res - > status = BFA_STATUS_ETIMER ;
res - > count = QTEST_CNT_DEFAULT - fcdiag - > qtest . count ;
if ( fcdiag - > qtest . all )
res - > queue = fcdiag - > qtest . all ;
bfa_trc ( fcdiag , BFA_STATUS_ETIMER ) ;
fcdiag - > qtest . status = BFA_STATUS_ETIMER ;
fcdiag - > qtest . cbfn ( fcdiag - > qtest . cbarg , fcdiag - > qtest . status ) ;
fcdiag - > qtest . lock = 0 ;
}
static bfa_status_t
bfa_fcdiag_queuetest_send ( struct bfa_fcdiag_s * fcdiag )
{
u32 i ;
struct bfi_diag_qtest_req_s * req ;
req = bfa_reqq_next ( fcdiag - > bfa , fcdiag - > qtest . queue ) ;
if ( ! req )
return BFA_STATUS_DEVBUSY ;
/* build host command */
bfi_h2i_set ( req - > mh , BFI_MC_DIAG , BFI_DIAG_H2I_QTEST ,
bfa_fn_lpu ( fcdiag - > bfa ) ) ;
for ( i = 0 ; i < BFI_LMSG_PL_WSZ ; i + + )
req - > data [ i ] = QTEST_PAT_DEFAULT ;
bfa_trc ( fcdiag , fcdiag - > qtest . queue ) ;
/* ring door bell */
bfa_reqq_produce ( fcdiag - > bfa , fcdiag - > qtest . queue , req - > mh ) ;
return BFA_STATUS_OK ;
}
static void
bfa_fcdiag_queuetest_comp ( struct bfa_fcdiag_s * fcdiag ,
bfi_diag_qtest_rsp_t * rsp )
{
struct bfa_diag_qtest_result_s * res = fcdiag - > qtest . result ;
bfa_status_t status = BFA_STATUS_OK ;
int i ;
/* Check timer, should still be active */
if ( ! fcdiag - > qtest . timer_active ) {
bfa_trc ( fcdiag , fcdiag - > qtest . timer_active ) ;
return ;
}
/* update count */
fcdiag - > qtest . count - - ;
/* Check result */
for ( i = 0 ; i < BFI_LMSG_PL_WSZ ; i + + ) {
if ( rsp - > data [ i ] ! = ~ ( QTEST_PAT_DEFAULT ) ) {
res - > status = BFA_STATUS_DATACORRUPTED ;
break ;
}
}
if ( res - > status = = BFA_STATUS_OK ) {
if ( fcdiag - > qtest . count > 0 ) {
status = bfa_fcdiag_queuetest_send ( fcdiag ) ;
if ( status = = BFA_STATUS_OK )
return ;
else
res - > status = status ;
} else if ( fcdiag - > qtest . all > 0 & &
fcdiag - > qtest . queue < ( BFI_IOC_MAX_CQS - 1 ) ) {
fcdiag - > qtest . count = QTEST_CNT_DEFAULT ;
fcdiag - > qtest . queue + + ;
status = bfa_fcdiag_queuetest_send ( fcdiag ) ;
if ( status = = BFA_STATUS_OK )
return ;
else
res - > status = status ;
}
}
/* Stop timer when we comp all queue */
if ( fcdiag - > qtest . timer_active ) {
bfa_timer_stop ( & fcdiag - > qtest . timer ) ;
fcdiag - > qtest . timer_active = 0 ;
}
res - > queue = fcdiag - > qtest . queue ;
res - > count = QTEST_CNT_DEFAULT - fcdiag - > qtest . count ;
bfa_trc ( fcdiag , res - > count ) ;
bfa_trc ( fcdiag , res - > status ) ;
fcdiag - > qtest . status = res - > status ;
fcdiag - > qtest . cbfn ( fcdiag - > qtest . cbarg , fcdiag - > qtest . status ) ;
fcdiag - > qtest . lock = 0 ;
}
static void
bfa_fcdiag_loopback_comp ( struct bfa_fcdiag_s * fcdiag ,
struct bfi_diag_lb_rsp_s * rsp )
{
struct bfa_diag_loopback_result_s * res = fcdiag - > lb . result ;
res - > numtxmfrm = be32_to_cpu ( rsp - > res . numtxmfrm ) ;
res - > numosffrm = be32_to_cpu ( rsp - > res . numosffrm ) ;
res - > numrcvfrm = be32_to_cpu ( rsp - > res . numrcvfrm ) ;
res - > badfrminf = be32_to_cpu ( rsp - > res . badfrminf ) ;
res - > badfrmnum = be32_to_cpu ( rsp - > res . badfrmnum ) ;
res - > status = rsp - > res . status ;
fcdiag - > lb . status = rsp - > res . status ;
bfa_trc ( fcdiag , fcdiag - > lb . status ) ;
fcdiag - > lb . cbfn ( fcdiag - > lb . cbarg , fcdiag - > lb . status ) ;
fcdiag - > lb . lock = 0 ;
bfa_fcdiag_set_busy_status ( fcdiag ) ;
}
static bfa_status_t
bfa_fcdiag_loopback_send ( struct bfa_fcdiag_s * fcdiag ,
struct bfa_diag_loopback_s * loopback )
{
struct bfi_diag_lb_req_s * lb_req ;
lb_req = bfa_reqq_next ( fcdiag - > bfa , BFA_REQQ_DIAG ) ;
if ( ! lb_req )
return BFA_STATUS_DEVBUSY ;
/* build host command */
bfi_h2i_set ( lb_req - > mh , BFI_MC_DIAG , BFI_DIAG_H2I_LOOPBACK ,
bfa_fn_lpu ( fcdiag - > bfa ) ) ;
lb_req - > lb_mode = loopback - > lb_mode ;
lb_req - > speed = loopback - > speed ;
lb_req - > loopcnt = loopback - > loopcnt ;
lb_req - > pattern = loopback - > pattern ;
/* ring door bell */
bfa_reqq_produce ( fcdiag - > bfa , BFA_REQQ_DIAG , lb_req - > mh ) ;
bfa_trc ( fcdiag , loopback - > lb_mode ) ;
bfa_trc ( fcdiag , loopback - > speed ) ;
bfa_trc ( fcdiag , loopback - > loopcnt ) ;
bfa_trc ( fcdiag , loopback - > pattern ) ;
return BFA_STATUS_OK ;
}
/*
* cpe / rme intr handler
*/
void
bfa_fcdiag_intr ( struct bfa_s * bfa , struct bfi_msg_s * msg )
{
struct bfa_fcdiag_s * fcdiag = BFA_FCDIAG_MOD ( bfa ) ;
switch ( msg - > mhdr . msg_id ) {
case BFI_DIAG_I2H_LOOPBACK :
bfa_fcdiag_loopback_comp ( fcdiag ,
( struct bfi_diag_lb_rsp_s * ) msg ) ;
break ;
case BFI_DIAG_I2H_QTEST :
bfa_fcdiag_queuetest_comp ( fcdiag , ( bfi_diag_qtest_rsp_t * ) msg ) ;
break ;
2012-09-22 04:26:07 +04:00
case BFI_DIAG_I2H_DPORT :
2013-05-13 13:33:21 +04:00
bfa_dport_req_comp ( & fcdiag - > dport ,
( struct bfi_diag_dport_rsp_s * ) msg ) ;
break ;
case BFI_DIAG_I2H_DPORT_SCN :
bfa_dport_scn ( & fcdiag - > dport ,
( struct bfi_diag_dport_scn_s * ) msg ) ;
2012-09-22 04:26:07 +04:00
break ;
2011-06-25 07:28:17 +04:00
default :
bfa_trc ( fcdiag , msg - > mhdr . msg_id ) ;
WARN_ON ( 1 ) ;
}
}
/*
* Loopback test
*
* @ param [ in ] * bfa - bfa data struct
* @ param [ in ] opmode - port operation mode
* @ param [ in ] speed - port speed
* @ param [ in ] lpcnt - loop count
* @ param [ in ] pat - pattern to build packet
* @ param [ in ] * result - pt to bfa_diag_loopback_result_t data struct
* @ param [ in ] cbfn - callback function
* @ param [ in ] cbarg - callback functioin arg
*
* @ param [ out ]
*/
bfa_status_t
bfa_fcdiag_loopback ( struct bfa_s * bfa , enum bfa_port_opmode opmode ,
enum bfa_port_speed speed , u32 lpcnt , u32 pat ,
struct bfa_diag_loopback_result_s * result , bfa_cb_diag_t cbfn ,
void * cbarg )
{
struct bfa_diag_loopback_s loopback ;
struct bfa_port_attr_s attr ;
bfa_status_t status ;
struct bfa_fcdiag_s * fcdiag = BFA_FCDIAG_MOD ( bfa ) ;
if ( ! bfa_iocfc_is_operational ( bfa ) )
return BFA_STATUS_IOC_NON_OP ;
/* if port is PBC disabled, return error */
if ( bfa_fcport_is_pbcdisabled ( bfa ) ) {
bfa_trc ( fcdiag , BFA_STATUS_PBC ) ;
return BFA_STATUS_PBC ;
}
if ( bfa_fcport_is_disabled ( bfa ) = = BFA_FALSE ) {
bfa_trc ( fcdiag , opmode ) ;
return BFA_STATUS_PORT_NOT_DISABLED ;
}
2011-07-21 04:01:07 +04:00
/*
* Check if input speed is supported by the port mode
*/
if ( bfa_ioc_get_type ( & bfa - > ioc ) = = BFA_IOC_TYPE_FC ) {
if ( ! ( speed = = BFA_PORT_SPEED_1GBPS | |
speed = = BFA_PORT_SPEED_2GBPS | |
speed = = BFA_PORT_SPEED_4GBPS | |
speed = = BFA_PORT_SPEED_8GBPS | |
speed = = BFA_PORT_SPEED_16GBPS | |
speed = = BFA_PORT_SPEED_AUTO ) ) {
bfa_trc ( fcdiag , speed ) ;
return BFA_STATUS_UNSUPP_SPEED ;
}
bfa_fcport_get_attr ( bfa , & attr ) ;
bfa_trc ( fcdiag , attr . speed_supported ) ;
if ( speed > attr . speed_supported )
return BFA_STATUS_UNSUPP_SPEED ;
} else {
if ( speed ! = BFA_PORT_SPEED_10GBPS ) {
bfa_trc ( fcdiag , speed ) ;
return BFA_STATUS_UNSUPP_SPEED ;
}
}
2011-06-25 07:28:17 +04:00
2012-09-22 04:26:07 +04:00
/*
* For CT2 , 1 G is not supported
*/
if ( ( speed = = BFA_PORT_SPEED_1GBPS ) & &
( bfa_asic_id_ct2 ( bfa - > ioc . pcidev . device_id ) ) ) {
bfa_trc ( fcdiag , speed ) ;
return BFA_STATUS_UNSUPP_SPEED ;
}
2011-06-25 07:28:17 +04:00
/* For Mezz card, port speed entered needs to be checked */
if ( bfa_mfg_is_mezz ( bfa - > ioc . attr - > card_type ) ) {
if ( bfa_ioc_get_type ( & bfa - > ioc ) = = BFA_IOC_TYPE_FC ) {
if ( ! ( speed = = BFA_PORT_SPEED_1GBPS | |
speed = = BFA_PORT_SPEED_2GBPS | |
speed = = BFA_PORT_SPEED_4GBPS | |
speed = = BFA_PORT_SPEED_8GBPS | |
speed = = BFA_PORT_SPEED_16GBPS | |
speed = = BFA_PORT_SPEED_AUTO ) )
return BFA_STATUS_UNSUPP_SPEED ;
} else {
if ( speed ! = BFA_PORT_SPEED_10GBPS )
return BFA_STATUS_UNSUPP_SPEED ;
}
}
2013-05-13 13:33:21 +04:00
/* check to see if fcport is dport */
if ( bfa_fcport_is_dport ( bfa ) ) {
bfa_trc ( fcdiag , fcdiag - > lb . lock ) ;
return BFA_STATUS_DPORT_ENABLED ;
}
2011-06-25 07:28:17 +04:00
/* check to see if there is another destructive diag cmd running */
if ( fcdiag - > lb . lock ) {
bfa_trc ( fcdiag , fcdiag - > lb . lock ) ;
return BFA_STATUS_DEVBUSY ;
}
fcdiag - > lb . lock = 1 ;
loopback . lb_mode = opmode ;
loopback . speed = speed ;
loopback . loopcnt = lpcnt ;
loopback . pattern = pat ;
fcdiag - > lb . result = result ;
fcdiag - > lb . cbfn = cbfn ;
fcdiag - > lb . cbarg = cbarg ;
memset ( result , 0 , sizeof ( struct bfa_diag_loopback_result_s ) ) ;
bfa_fcdiag_set_busy_status ( fcdiag ) ;
/* Send msg to fw */
status = bfa_fcdiag_loopback_send ( fcdiag , & loopback ) ;
return status ;
}
/*
* DIAG queue test command
*
* @ param [ in ] * bfa - bfa data struct
* @ param [ in ] force - 1 : don ' t do ioc op checking
* @ param [ in ] queue - queue no . to test
* @ param [ in ] * result - pt to bfa_diag_qtest_result_t data struct
* @ param [ in ] cbfn - callback function
* @ param [ in ] * cbarg - callback functioin arg
*
* @ param [ out ]
*/
bfa_status_t
bfa_fcdiag_queuetest ( struct bfa_s * bfa , u32 force , u32 queue ,
struct bfa_diag_qtest_result_s * result , bfa_cb_diag_t cbfn ,
void * cbarg )
{
struct bfa_fcdiag_s * fcdiag = BFA_FCDIAG_MOD ( bfa ) ;
bfa_status_t status ;
bfa_trc ( fcdiag , force ) ;
bfa_trc ( fcdiag , queue ) ;
if ( ! force & & ! bfa_iocfc_is_operational ( bfa ) )
return BFA_STATUS_IOC_NON_OP ;
/* check to see if there is another destructive diag cmd running */
if ( fcdiag - > qtest . lock ) {
bfa_trc ( fcdiag , fcdiag - > qtest . lock ) ;
return BFA_STATUS_DEVBUSY ;
}
/* Initialization */
fcdiag - > qtest . lock = 1 ;
fcdiag - > qtest . cbfn = cbfn ;
fcdiag - > qtest . cbarg = cbarg ;
fcdiag - > qtest . result = result ;
fcdiag - > qtest . count = QTEST_CNT_DEFAULT ;
/* Init test results */
fcdiag - > qtest . result - > status = BFA_STATUS_OK ;
fcdiag - > qtest . result - > count = 0 ;
/* send */
if ( queue < BFI_IOC_MAX_CQS ) {
fcdiag - > qtest . result - > queue = ( u8 ) queue ;
fcdiag - > qtest . queue = ( u8 ) queue ;
fcdiag - > qtest . all = 0 ;
} else {
fcdiag - > qtest . result - > queue = 0 ;
fcdiag - > qtest . queue = 0 ;
fcdiag - > qtest . all = 1 ;
}
status = bfa_fcdiag_queuetest_send ( fcdiag ) ;
/* Start a timer */
if ( status = = BFA_STATUS_OK ) {
bfa_timer_start ( bfa , & fcdiag - > qtest . timer ,
bfa_fcdiag_queuetest_timeout , fcdiag ,
BFA_DIAG_QTEST_TOV ) ;
fcdiag - > qtest . timer_active = 1 ;
}
return status ;
}
/*
* DIAG PLB is running
*
* @ param [ in ] * bfa - bfa data struct
*
* @ param [ out ]
*/
bfa_status_t
bfa_fcdiag_lb_is_running ( struct bfa_s * bfa )
{
struct bfa_fcdiag_s * fcdiag = BFA_FCDIAG_MOD ( bfa ) ;
return fcdiag - > lb . lock ? BFA_STATUS_DIAG_BUSY : BFA_STATUS_OK ;
}
2012-09-22 04:26:07 +04:00
/*
* D - port
*/
2013-05-13 13:33:21 +04:00
# define bfa_dport_result_start(__dport, __mode) do { \
( __dport ) - > result . start_time = bfa_get_log_time ( ) ; \
( __dport ) - > result . status = DPORT_TEST_ST_INPRG ; \
( __dport ) - > result . mode = ( __mode ) ; \
( __dport ) - > result . rp_pwwn = ( __dport ) - > rp_pwwn ; \
( __dport ) - > result . rp_nwwn = ( __dport ) - > rp_nwwn ; \
( __dport ) - > result . lpcnt = ( __dport ) - > lpcnt ; \
} while ( 0 )
2012-09-22 04:26:07 +04:00
static bfa_boolean_t bfa_dport_send_req ( struct bfa_dport_s * dport ,
enum bfi_dport_req req ) ;
static void
bfa_cb_fcdiag_dport ( struct bfa_dport_s * dport , bfa_status_t bfa_status )
{
if ( dport - > cbfn ! = NULL ) {
dport - > cbfn ( dport - > cbarg , bfa_status ) ;
dport - > cbfn = NULL ;
dport - > cbarg = NULL ;
}
}
static void
bfa_dport_sm_disabled ( struct bfa_dport_s * dport , enum bfa_dport_sm_event event )
{
bfa_trc ( dport - > bfa , event ) ;
switch ( event ) {
case BFA_DPORT_SM_ENABLE :
bfa_fcport_dportenable ( dport - > bfa ) ;
if ( bfa_dport_send_req ( dport , BFI_DPORT_ENABLE ) )
bfa_sm_set_state ( dport , bfa_dport_sm_enabling ) ;
else
bfa_sm_set_state ( dport , bfa_dport_sm_enabling_qwait ) ;
break ;
case BFA_DPORT_SM_DISABLE :
/* Already disabled */
break ;
case BFA_DPORT_SM_HWFAIL :
/* ignore */
break ;
2013-05-13 13:33:21 +04:00
case BFA_DPORT_SM_SCN :
if ( dport - > i2hmsg . scn . state = = BFI_DPORT_SCN_DDPORT_ENABLE ) {
bfa_fcport_ddportenable ( dport - > bfa ) ;
dport - > dynamic = BFA_TRUE ;
dport - > test_state = BFA_DPORT_ST_NOTSTART ;
bfa_sm_set_state ( dport , bfa_dport_sm_enabled ) ;
} else {
bfa_trc ( dport - > bfa , dport - > i2hmsg . scn . state ) ;
WARN_ON ( 1 ) ;
}
break ;
2012-09-22 04:26:07 +04:00
default :
bfa_sm_fault ( dport - > bfa , event ) ;
}
}
static void
bfa_dport_sm_enabling_qwait ( struct bfa_dport_s * dport ,
enum bfa_dport_sm_event event )
{
bfa_trc ( dport - > bfa , event ) ;
switch ( event ) {
case BFA_DPORT_SM_QRESUME :
bfa_sm_set_state ( dport , bfa_dport_sm_enabling ) ;
bfa_dport_send_req ( dport , BFI_DPORT_ENABLE ) ;
break ;
case BFA_DPORT_SM_HWFAIL :
bfa_reqq_wcancel ( & dport - > reqq_wait ) ;
bfa_sm_set_state ( dport , bfa_dport_sm_disabled ) ;
bfa_cb_fcdiag_dport ( dport , BFA_STATUS_FAILED ) ;
break ;
default :
bfa_sm_fault ( dport - > bfa , event ) ;
}
}
static void
bfa_dport_sm_enabling ( struct bfa_dport_s * dport , enum bfa_dport_sm_event event )
{
bfa_trc ( dport - > bfa , event ) ;
switch ( event ) {
case BFA_DPORT_SM_FWRSP :
2013-05-13 13:33:21 +04:00
memset ( & dport - > result , 0 ,
sizeof ( struct bfa_diag_dport_result_s ) ) ;
if ( dport - > i2hmsg . rsp . status = = BFA_STATUS_DPORT_INV_SFP ) {
dport - > test_state = BFA_DPORT_ST_NO_SFP ;
} else {
dport - > test_state = BFA_DPORT_ST_INP ;
bfa_dport_result_start ( dport , BFA_DPORT_OPMODE_AUTO ) ;
}
2012-09-22 04:26:07 +04:00
bfa_sm_set_state ( dport , bfa_dport_sm_enabled ) ;
break ;
2013-05-13 13:33:21 +04:00
case BFA_DPORT_SM_REQFAIL :
dport - > test_state = BFA_DPORT_ST_DISABLED ;
bfa_fcport_dportdisable ( dport - > bfa ) ;
bfa_sm_set_state ( dport , bfa_dport_sm_disabled ) ;
break ;
2012-09-22 04:26:07 +04:00
case BFA_DPORT_SM_HWFAIL :
bfa_sm_set_state ( dport , bfa_dport_sm_disabled ) ;
bfa_cb_fcdiag_dport ( dport , BFA_STATUS_FAILED ) ;
break ;
default :
bfa_sm_fault ( dport - > bfa , event ) ;
}
}
static void
bfa_dport_sm_enabled ( struct bfa_dport_s * dport , enum bfa_dport_sm_event event )
{
bfa_trc ( dport - > bfa , event ) ;
switch ( event ) {
2013-05-13 13:33:21 +04:00
case BFA_DPORT_SM_START :
if ( bfa_dport_send_req ( dport , BFI_DPORT_START ) )
bfa_sm_set_state ( dport , bfa_dport_sm_starting ) ;
else
bfa_sm_set_state ( dport , bfa_dport_sm_starting_qwait ) ;
2012-09-22 04:26:07 +04:00
break ;
case BFA_DPORT_SM_DISABLE :
bfa_fcport_dportdisable ( dport - > bfa ) ;
if ( bfa_dport_send_req ( dport , BFI_DPORT_DISABLE ) )
bfa_sm_set_state ( dport , bfa_dport_sm_disabling ) ;
else
bfa_sm_set_state ( dport , bfa_dport_sm_disabling_qwait ) ;
break ;
case BFA_DPORT_SM_HWFAIL :
bfa_sm_set_state ( dport , bfa_dport_sm_disabled ) ;
break ;
2013-05-13 13:33:21 +04:00
case BFA_DPORT_SM_SCN :
switch ( dport - > i2hmsg . scn . state ) {
case BFI_DPORT_SCN_TESTCOMP :
dport - > test_state = BFA_DPORT_ST_COMP ;
break ;
case BFI_DPORT_SCN_TESTSTART :
dport - > test_state = BFA_DPORT_ST_INP ;
break ;
case BFI_DPORT_SCN_TESTSKIP :
case BFI_DPORT_SCN_SUBTESTSTART :
/* no state change */
break ;
case BFI_DPORT_SCN_SFP_REMOVED :
dport - > test_state = BFA_DPORT_ST_NO_SFP ;
break ;
case BFI_DPORT_SCN_DDPORT_DISABLE :
bfa_fcport_ddportdisable ( dport - > bfa ) ;
if ( bfa_dport_send_req ( dport , BFI_DPORT_DYN_DISABLE ) )
bfa_sm_set_state ( dport ,
bfa_dport_sm_dynamic_disabling ) ;
else
bfa_sm_set_state ( dport ,
bfa_dport_sm_dynamic_disabling_qwait ) ;
break ;
case BFI_DPORT_SCN_FCPORT_DISABLE :
bfa_fcport_ddportdisable ( dport - > bfa ) ;
bfa_sm_set_state ( dport , bfa_dport_sm_disabled ) ;
dport - > dynamic = BFA_FALSE ;
break ;
default :
bfa_trc ( dport - > bfa , dport - > i2hmsg . scn . state ) ;
bfa_sm_fault ( dport - > bfa , event ) ;
}
break ;
2012-09-22 04:26:07 +04:00
default :
bfa_sm_fault ( dport - > bfa , event ) ;
}
}
static void
bfa_dport_sm_disabling_qwait ( struct bfa_dport_s * dport ,
enum bfa_dport_sm_event event )
{
bfa_trc ( dport - > bfa , event ) ;
switch ( event ) {
case BFA_DPORT_SM_QRESUME :
bfa_sm_set_state ( dport , bfa_dport_sm_disabling ) ;
bfa_dport_send_req ( dport , BFI_DPORT_DISABLE ) ;
break ;
case BFA_DPORT_SM_HWFAIL :
bfa_sm_set_state ( dport , bfa_dport_sm_disabled ) ;
bfa_reqq_wcancel ( & dport - > reqq_wait ) ;
bfa_cb_fcdiag_dport ( dport , BFA_STATUS_OK ) ;
break ;
2013-05-13 13:33:21 +04:00
case BFA_DPORT_SM_SCN :
/* ignore */
break ;
2012-09-22 04:26:07 +04:00
default :
bfa_sm_fault ( dport - > bfa , event ) ;
}
}
static void
bfa_dport_sm_disabling ( struct bfa_dport_s * dport , enum bfa_dport_sm_event event )
{
bfa_trc ( dport - > bfa , event ) ;
switch ( event ) {
case BFA_DPORT_SM_FWRSP :
2013-05-13 13:33:21 +04:00
dport - > test_state = BFA_DPORT_ST_DISABLED ;
bfa_sm_set_state ( dport , bfa_dport_sm_disabled ) ;
break ;
case BFA_DPORT_SM_HWFAIL :
2012-09-22 04:26:07 +04:00
bfa_sm_set_state ( dport , bfa_dport_sm_disabled ) ;
2013-05-13 13:33:21 +04:00
bfa_cb_fcdiag_dport ( dport , BFA_STATUS_OK ) ;
break ;
case BFA_DPORT_SM_SCN :
/* no state change */
break ;
default :
bfa_sm_fault ( dport - > bfa , event ) ;
}
}
static void
bfa_dport_sm_starting_qwait ( struct bfa_dport_s * dport ,
enum bfa_dport_sm_event event )
{
bfa_trc ( dport - > bfa , event ) ;
switch ( event ) {
case BFA_DPORT_SM_QRESUME :
bfa_sm_set_state ( dport , bfa_dport_sm_starting ) ;
bfa_dport_send_req ( dport , BFI_DPORT_START ) ;
break ;
case BFA_DPORT_SM_HWFAIL :
bfa_reqq_wcancel ( & dport - > reqq_wait ) ;
bfa_sm_set_state ( dport , bfa_dport_sm_disabled ) ;
bfa_cb_fcdiag_dport ( dport , BFA_STATUS_FAILED ) ;
break ;
default :
bfa_sm_fault ( dport - > bfa , event ) ;
}
}
static void
bfa_dport_sm_starting ( struct bfa_dport_s * dport , enum bfa_dport_sm_event event )
{
bfa_trc ( dport - > bfa , event ) ;
switch ( event ) {
case BFA_DPORT_SM_FWRSP :
memset ( & dport - > result , 0 ,
sizeof ( struct bfa_diag_dport_result_s ) ) ;
if ( dport - > i2hmsg . rsp . status = = BFA_STATUS_DPORT_INV_SFP ) {
dport - > test_state = BFA_DPORT_ST_NO_SFP ;
} else {
dport - > test_state = BFA_DPORT_ST_INP ;
bfa_dport_result_start ( dport , BFA_DPORT_OPMODE_MANU ) ;
}
/* fall thru */
case BFA_DPORT_SM_REQFAIL :
bfa_sm_set_state ( dport , bfa_dport_sm_enabled ) ;
break ;
case BFA_DPORT_SM_HWFAIL :
bfa_sm_set_state ( dport , bfa_dport_sm_disabled ) ;
bfa_cb_fcdiag_dport ( dport , BFA_STATUS_FAILED ) ;
break ;
default :
bfa_sm_fault ( dport - > bfa , event ) ;
}
}
static void
bfa_dport_sm_dynamic_disabling ( struct bfa_dport_s * dport ,
enum bfa_dport_sm_event event )
{
bfa_trc ( dport - > bfa , event ) ;
switch ( event ) {
case BFA_DPORT_SM_SCN :
switch ( dport - > i2hmsg . scn . state ) {
case BFI_DPORT_SCN_DDPORT_DISABLED :
bfa_sm_set_state ( dport , bfa_dport_sm_disabled ) ;
dport - > dynamic = BFA_FALSE ;
bfa_fcport_enable ( dport - > bfa ) ;
break ;
default :
bfa_trc ( dport - > bfa , dport - > i2hmsg . scn . state ) ;
bfa_sm_fault ( dport - > bfa , event ) ;
}
2012-09-22 04:26:07 +04:00
break ;
case BFA_DPORT_SM_HWFAIL :
bfa_sm_set_state ( dport , bfa_dport_sm_disabled ) ;
bfa_cb_fcdiag_dport ( dport , BFA_STATUS_OK ) ;
break ;
default :
bfa_sm_fault ( dport - > bfa , event ) ;
}
}
2013-05-13 13:33:21 +04:00
static void
bfa_dport_sm_dynamic_disabling_qwait ( struct bfa_dport_s * dport ,
enum bfa_dport_sm_event event )
{
bfa_trc ( dport - > bfa , event ) ;
switch ( event ) {
case BFA_DPORT_SM_QRESUME :
bfa_sm_set_state ( dport , bfa_dport_sm_dynamic_disabling ) ;
bfa_dport_send_req ( dport , BFI_DPORT_DYN_DISABLE ) ;
break ;
case BFA_DPORT_SM_HWFAIL :
bfa_sm_set_state ( dport , bfa_dport_sm_disabled ) ;
bfa_reqq_wcancel ( & dport - > reqq_wait ) ;
bfa_cb_fcdiag_dport ( dport , BFA_STATUS_OK ) ;
break ;
case BFA_DPORT_SM_SCN :
/* ignore */
break ;
default :
bfa_sm_fault ( dport - > bfa , event ) ;
}
}
2012-09-22 04:26:07 +04:00
static bfa_boolean_t
bfa_dport_send_req ( struct bfa_dport_s * dport , enum bfi_dport_req req )
{
struct bfi_diag_dport_req_s * m ;
/*
* check for room in queue to send request now
*/
m = bfa_reqq_next ( dport - > bfa , BFA_REQQ_DIAG ) ;
if ( ! m ) {
bfa_reqq_wait ( dport - > bfa , BFA_REQQ_PORT , & dport - > reqq_wait ) ;
return BFA_FALSE ;
}
bfi_h2i_set ( m - > mh , BFI_MC_DIAG , BFI_DIAG_H2I_DPORT ,
bfa_fn_lpu ( dport - > bfa ) ) ;
m - > req = req ;
2013-05-13 13:33:21 +04:00
if ( ( req = = BFI_DPORT_ENABLE ) | | ( req = = BFI_DPORT_START ) ) {
m - > lpcnt = cpu_to_be32 ( dport - > lpcnt ) ;
m - > payload = cpu_to_be32 ( dport - > payload ) ;
}
2012-09-22 04:26:07 +04:00
/*
* queue I / O message to firmware
*/
bfa_reqq_produce ( dport - > bfa , BFA_REQQ_DIAG , m - > mh ) ;
return BFA_TRUE ;
}
static void
bfa_dport_qresume ( void * cbarg )
{
struct bfa_dport_s * dport = cbarg ;
bfa_sm_send_event ( dport , BFA_DPORT_SM_QRESUME ) ;
}
static void
2013-05-13 13:33:21 +04:00
bfa_dport_req_comp ( struct bfa_dport_s * dport , struct bfi_diag_dport_rsp_s * msg )
2012-09-22 04:26:07 +04:00
{
2013-05-13 13:33:21 +04:00
msg - > status = cpu_to_be32 ( msg - > status ) ;
dport - > i2hmsg . rsp . status = msg - > status ;
dport - > rp_pwwn = msg - > pwwn ;
dport - > rp_nwwn = msg - > nwwn ;
if ( ( msg - > status = = BFA_STATUS_OK ) | |
( msg - > status = = BFA_STATUS_DPORT_NO_SFP ) ) {
bfa_trc ( dport - > bfa , msg - > status ) ;
bfa_trc ( dport - > bfa , dport - > rp_pwwn ) ;
bfa_trc ( dport - > bfa , dport - > rp_nwwn ) ;
bfa_sm_send_event ( dport , BFA_DPORT_SM_FWRSP ) ;
} else {
bfa_trc ( dport - > bfa , msg - > status ) ;
bfa_sm_send_event ( dport , BFA_DPORT_SM_REQFAIL ) ;
}
2012-09-22 04:26:07 +04:00
bfa_cb_fcdiag_dport ( dport , msg - > status ) ;
}
2013-05-13 13:33:21 +04:00
static bfa_boolean_t
bfa_dport_is_sending_req ( struct bfa_dport_s * dport )
{
if ( bfa_sm_cmp_state ( dport , bfa_dport_sm_enabling ) | |
bfa_sm_cmp_state ( dport , bfa_dport_sm_enabling_qwait ) | |
bfa_sm_cmp_state ( dport , bfa_dport_sm_disabling ) | |
bfa_sm_cmp_state ( dport , bfa_dport_sm_disabling_qwait ) | |
bfa_sm_cmp_state ( dport , bfa_dport_sm_starting ) | |
bfa_sm_cmp_state ( dport , bfa_dport_sm_starting_qwait ) ) {
return BFA_TRUE ;
} else {
return BFA_FALSE ;
}
}
static void
bfa_dport_scn ( struct bfa_dport_s * dport , struct bfi_diag_dport_scn_s * msg )
{
int i ;
uint8_t subtesttype ;
bfa_trc ( dport - > bfa , msg - > state ) ;
dport - > i2hmsg . scn . state = msg - > state ;
switch ( dport - > i2hmsg . scn . state ) {
case BFI_DPORT_SCN_TESTCOMP :
dport - > result . end_time = bfa_get_log_time ( ) ;
bfa_trc ( dport - > bfa , dport - > result . end_time ) ;
dport - > result . status = msg - > info . testcomp . status ;
bfa_trc ( dport - > bfa , dport - > result . status ) ;
dport - > result . roundtrip_latency =
cpu_to_be32 ( msg - > info . testcomp . latency ) ;
dport - > result . est_cable_distance =
cpu_to_be32 ( msg - > info . testcomp . distance ) ;
dport - > result . buffer_required =
be16_to_cpu ( msg - > info . testcomp . numbuffer ) ;
dport - > result . frmsz = be16_to_cpu ( msg - > info . testcomp . frm_sz ) ;
dport - > result . speed = msg - > info . testcomp . speed ;
bfa_trc ( dport - > bfa , dport - > result . roundtrip_latency ) ;
bfa_trc ( dport - > bfa , dport - > result . est_cable_distance ) ;
bfa_trc ( dport - > bfa , dport - > result . buffer_required ) ;
bfa_trc ( dport - > bfa , dport - > result . frmsz ) ;
bfa_trc ( dport - > bfa , dport - > result . speed ) ;
for ( i = DPORT_TEST_ELOOP ; i < DPORT_TEST_MAX ; i + + ) {
dport - > result . subtest [ i ] . status =
msg - > info . testcomp . subtest_status [ i ] ;
bfa_trc ( dport - > bfa , dport - > result . subtest [ i ] . status ) ;
}
break ;
case BFI_DPORT_SCN_TESTSKIP :
case BFI_DPORT_SCN_DDPORT_ENABLE :
memset ( & dport - > result , 0 ,
sizeof ( struct bfa_diag_dport_result_s ) ) ;
break ;
case BFI_DPORT_SCN_TESTSTART :
memset ( & dport - > result , 0 ,
sizeof ( struct bfa_diag_dport_result_s ) ) ;
dport - > rp_pwwn = msg - > info . teststart . pwwn ;
dport - > rp_nwwn = msg - > info . teststart . nwwn ;
dport - > lpcnt = cpu_to_be32 ( msg - > info . teststart . numfrm ) ;
2013-11-21 13:37:47 +04:00
bfa_dport_result_start ( dport , msg - > info . teststart . mode ) ;
2013-05-13 13:33:21 +04:00
break ;
case BFI_DPORT_SCN_SUBTESTSTART :
subtesttype = msg - > info . teststart . type ;
dport - > result . subtest [ subtesttype ] . start_time =
bfa_get_log_time ( ) ;
dport - > result . subtest [ subtesttype ] . status =
DPORT_TEST_ST_INPRG ;
bfa_trc ( dport - > bfa , subtesttype ) ;
bfa_trc ( dport - > bfa ,
dport - > result . subtest [ subtesttype ] . start_time ) ;
break ;
case BFI_DPORT_SCN_SFP_REMOVED :
case BFI_DPORT_SCN_DDPORT_DISABLED :
case BFI_DPORT_SCN_DDPORT_DISABLE :
case BFI_DPORT_SCN_FCPORT_DISABLE :
dport - > result . status = DPORT_TEST_ST_IDLE ;
break ;
default :
bfa_sm_fault ( dport - > bfa , msg - > state ) ;
}
bfa_sm_send_event ( dport , BFA_DPORT_SM_SCN ) ;
}
2012-09-22 04:26:07 +04:00
/*
* Dport enable
*
* @ param [ in ] * bfa - bfa data struct
*/
bfa_status_t
2013-05-13 13:33:21 +04:00
bfa_dport_enable ( struct bfa_s * bfa , u32 lpcnt , u32 pat ,
bfa_cb_diag_t cbfn , void * cbarg )
2012-09-22 04:26:07 +04:00
{
struct bfa_fcdiag_s * fcdiag = BFA_FCDIAG_MOD ( bfa ) ;
struct bfa_dport_s * dport = & fcdiag - > dport ;
/*
* Dport is not support in MEZZ card
*/
if ( bfa_mfg_is_mezz ( dport - > bfa - > ioc . attr - > card_type ) ) {
bfa_trc ( dport - > bfa , BFA_STATUS_PBC ) ;
return BFA_STATUS_CMD_NOTSUPP_MEZZ ;
}
2013-05-13 13:33:21 +04:00
/*
* Dport is supported in CT2 or above
*/
if ( ! ( bfa_asic_id_ct2 ( dport - > bfa - > ioc . pcidev . device_id ) ) ) {
bfa_trc ( dport - > bfa , dport - > bfa - > ioc . pcidev . device_id ) ;
return BFA_STATUS_FEATURE_NOT_SUPPORTED ;
}
2012-09-22 04:26:07 +04:00
/*
* Check to see if IOC is down
*/
if ( ! bfa_iocfc_is_operational ( bfa ) )
return BFA_STATUS_IOC_NON_OP ;
/* if port is PBC disabled, return error */
if ( bfa_fcport_is_pbcdisabled ( bfa ) ) {
bfa_trc ( dport - > bfa , BFA_STATUS_PBC ) ;
return BFA_STATUS_PBC ;
}
/*
* Check if port mode is FC port
*/
if ( bfa_ioc_get_type ( & bfa - > ioc ) ! = BFA_IOC_TYPE_FC ) {
bfa_trc ( dport - > bfa , bfa_ioc_get_type ( & bfa - > ioc ) ) ;
return BFA_STATUS_CMD_NOTSUPP_CNA ;
}
/*
* Check if port is in LOOP mode
*/
if ( ( bfa_fcport_get_cfg_topology ( bfa ) = = BFA_PORT_TOPOLOGY_LOOP ) | |
( bfa_fcport_get_topology ( bfa ) = = BFA_PORT_TOPOLOGY_LOOP ) ) {
bfa_trc ( dport - > bfa , 0 ) ;
return BFA_STATUS_TOPOLOGY_LOOP ;
}
/*
* Check if port is TRUNK mode
*/
if ( bfa_fcport_is_trunk_enabled ( bfa ) ) {
bfa_trc ( dport - > bfa , 0 ) ;
return BFA_STATUS_ERROR_TRUNK_ENABLED ;
}
2013-05-13 13:33:21 +04:00
/*
* Check if diag loopback is running
*/
if ( bfa_fcdiag_lb_is_running ( bfa ) ) {
bfa_trc ( dport - > bfa , 0 ) ;
return BFA_STATUS_DIAG_BUSY ;
}
2012-09-22 04:26:07 +04:00
/*
* Check to see if port is disable or in dport state
*/
if ( ( bfa_fcport_is_disabled ( bfa ) = = BFA_FALSE ) & &
( bfa_fcport_is_dport ( bfa ) = = BFA_FALSE ) ) {
bfa_trc ( dport - > bfa , 0 ) ;
return BFA_STATUS_PORT_NOT_DISABLED ;
}
2013-05-13 13:33:21 +04:00
/*
* Check if dport is in dynamic mode
*/
if ( dport - > dynamic )
return BFA_STATUS_DDPORT_ERR ;
2012-09-22 04:26:07 +04:00
/*
* Check if dport is busy
*/
2013-05-13 13:33:21 +04:00
if ( bfa_dport_is_sending_req ( dport ) )
2012-09-22 04:26:07 +04:00
return BFA_STATUS_DEVBUSY ;
/*
* Check if dport is already enabled
*/
if ( bfa_sm_cmp_state ( dport , bfa_dport_sm_enabled ) ) {
bfa_trc ( dport - > bfa , 0 ) ;
return BFA_STATUS_DPORT_ENABLED ;
}
2013-05-13 13:33:21 +04:00
bfa_trc ( dport - > bfa , lpcnt ) ;
bfa_trc ( dport - > bfa , pat ) ;
dport - > lpcnt = ( lpcnt ) ? lpcnt : DPORT_ENABLE_LOOPCNT_DEFAULT ;
dport - > payload = ( pat ) ? pat : LB_PATTERN_DEFAULT ;
2012-09-22 04:26:07 +04:00
dport - > cbfn = cbfn ;
dport - > cbarg = cbarg ;
bfa_sm_send_event ( dport , BFA_DPORT_SM_ENABLE ) ;
return BFA_STATUS_OK ;
}
/*
* Dport disable
*
* @ param [ in ] * bfa - bfa data struct
*/
bfa_status_t
bfa_dport_disable ( struct bfa_s * bfa , bfa_cb_diag_t cbfn , void * cbarg )
{
struct bfa_fcdiag_s * fcdiag = BFA_FCDIAG_MOD ( bfa ) ;
struct bfa_dport_s * dport = & fcdiag - > dport ;
if ( bfa_ioc_is_disabled ( & bfa - > ioc ) )
return BFA_STATUS_IOC_DISABLED ;
/* if port is PBC disabled, return error */
if ( bfa_fcport_is_pbcdisabled ( bfa ) ) {
bfa_trc ( dport - > bfa , BFA_STATUS_PBC ) ;
return BFA_STATUS_PBC ;
}
2013-05-13 13:33:21 +04:00
/*
* Check if dport is in dynamic mode
*/
if ( dport - > dynamic ) {
return BFA_STATUS_DDPORT_ERR ;
}
2012-09-22 04:26:07 +04:00
/*
* Check to see if port is disable or in dport state
*/
if ( ( bfa_fcport_is_disabled ( bfa ) = = BFA_FALSE ) & &
( bfa_fcport_is_dport ( bfa ) = = BFA_FALSE ) ) {
bfa_trc ( dport - > bfa , 0 ) ;
return BFA_STATUS_PORT_NOT_DISABLED ;
}
/*
* Check if dport is busy
*/
2013-05-13 13:33:21 +04:00
if ( bfa_dport_is_sending_req ( dport ) )
2012-09-22 04:26:07 +04:00
return BFA_STATUS_DEVBUSY ;
/*
* Check if dport is already disabled
*/
if ( bfa_sm_cmp_state ( dport , bfa_dport_sm_disabled ) ) {
bfa_trc ( dport - > bfa , 0 ) ;
return BFA_STATUS_DPORT_DISABLED ;
}
dport - > cbfn = cbfn ;
dport - > cbarg = cbarg ;
bfa_sm_send_event ( dport , BFA_DPORT_SM_DISABLE ) ;
return BFA_STATUS_OK ;
}
/*
2013-05-13 13:33:21 +04:00
* Dport start - - restart dport test
2012-09-22 04:26:07 +04:00
*
2013-05-13 13:33:21 +04:00
* @ param [ in ] * bfa - bfa data struct
2012-09-22 04:26:07 +04:00
*/
2013-05-13 13:33:21 +04:00
bfa_status_t
bfa_dport_start ( struct bfa_s * bfa , u32 lpcnt , u32 pat ,
bfa_cb_diag_t cbfn , void * cbarg )
{
struct bfa_fcdiag_s * fcdiag = BFA_FCDIAG_MOD ( bfa ) ;
struct bfa_dport_s * dport = & fcdiag - > dport ;
2012-09-22 04:26:07 +04:00
2013-05-13 13:33:21 +04:00
/*
* Check to see if IOC is down
*/
if ( ! bfa_iocfc_is_operational ( bfa ) )
return BFA_STATUS_IOC_NON_OP ;
/*
* Check if dport is in dynamic mode
*/
if ( dport - > dynamic )
return BFA_STATUS_DDPORT_ERR ;
/*
* Check if dport is busy
*/
if ( bfa_dport_is_sending_req ( dport ) )
return BFA_STATUS_DEVBUSY ;
/*
* Check if dport is in enabled state .
* Test can only be restart when previous test has completed
*/
if ( ! bfa_sm_cmp_state ( dport , bfa_dport_sm_enabled ) ) {
bfa_trc ( dport - > bfa , 0 ) ;
return BFA_STATUS_DPORT_DISABLED ;
} else {
if ( dport - > test_state = = BFA_DPORT_ST_NO_SFP )
return BFA_STATUS_DPORT_INV_SFP ;
if ( dport - > test_state = = BFA_DPORT_ST_INP )
return BFA_STATUS_DEVBUSY ;
WARN_ON ( dport - > test_state ! = BFA_DPORT_ST_COMP ) ;
}
bfa_trc ( dport - > bfa , lpcnt ) ;
bfa_trc ( dport - > bfa , pat ) ;
dport - > lpcnt = ( lpcnt ) ? lpcnt : DPORT_ENABLE_LOOPCNT_DEFAULT ;
dport - > payload = ( pat ) ? pat : LB_PATTERN_DEFAULT ;
dport - > cbfn = cbfn ;
dport - > cbarg = cbarg ;
bfa_sm_send_event ( dport , BFA_DPORT_SM_START ) ;
return BFA_STATUS_OK ;
}
/*
* Dport show - - return dport test result
*
* @ param [ in ] * bfa - bfa data struct
*/
2012-09-22 04:26:07 +04:00
bfa_status_t
2013-05-13 13:33:21 +04:00
bfa_dport_show ( struct bfa_s * bfa , struct bfa_diag_dport_result_s * result )
2012-09-22 04:26:07 +04:00
{
struct bfa_fcdiag_s * fcdiag = BFA_FCDIAG_MOD ( bfa ) ;
struct bfa_dport_s * dport = & fcdiag - > dport ;
2013-05-13 13:33:21 +04:00
/*
* Check to see if IOC is down
*/
if ( ! bfa_iocfc_is_operational ( bfa ) )
return BFA_STATUS_IOC_NON_OP ;
/*
* Check if dport is busy
*/
if ( bfa_dport_is_sending_req ( dport ) )
return BFA_STATUS_DEVBUSY ;
/*
* Check if dport is in enabled state .
*/
if ( ! bfa_sm_cmp_state ( dport , bfa_dport_sm_enabled ) ) {
bfa_trc ( dport - > bfa , 0 ) ;
return BFA_STATUS_DPORT_DISABLED ;
2012-09-22 04:26:07 +04:00
}
2013-05-13 13:33:21 +04:00
/*
* Check if there is SFP
*/
if ( dport - > test_state = = BFA_DPORT_ST_NO_SFP )
return BFA_STATUS_DPORT_INV_SFP ;
memcpy ( result , & dport - > result , sizeof ( struct bfa_diag_dport_result_s ) ) ;
2012-09-22 04:26:07 +04:00
return BFA_STATUS_OK ;
}