Skip to content

Commit

Permalink
[SCSI] bfa: Add support for FC Arbitrated Loop topology.
Browse files Browse the repository at this point in the history
- Add private loop topology support at 2G/4G/8G speeds with following
  limitations
  1. No support for multiple initiators in the loop
  2. No public loop support. If attached to a loop with an FL_Port,
     device continues to work as a private NL_Port in the loop
  3. No auto topology detection. User has to manually set the
     configured topology to loop if attaching to loop.
- When loop topology is configured, enabling FC port features
  QoS/Trunk/TRL are not allowed and vice versa.

Signed-off-by: Vijaya Mohan Guvva <vmohan@brocade.com>
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
  • Loading branch information
Krishna Gudipati authored and James Bottomley committed Oct 7, 2012
1 parent 56d92aa commit bc0e2c2
Show file tree
Hide file tree
Showing 12 changed files with 713 additions and 119 deletions.
5 changes: 5 additions & 0 deletions drivers/scsi/bfa/bfa_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ enum bfa_status {
BFA_STATUS_BEACON_ON = 72, /* Port Beacon already on */
BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */
BFA_STATUS_IOC_DISABLED = 82, /* IOC is already disabled */
BFA_STATUS_ERROR_TRL_ENABLED = 87, /* TRL is enabled */
BFA_STATUS_ERROR_QOS_ENABLED = 88, /* QoS is enabled */
BFA_STATUS_NO_SFP_DEV = 89, /* No SFP device check or replace SFP */
BFA_STATUS_MEMTEST_FAILED = 90, /* Memory test failed contact support */
BFA_STATUS_LEDTEST_OP = 109, /* LED test is operating */
Expand All @@ -184,6 +186,9 @@ enum bfa_status {
BFA_STATUS_FAA_ACQ_ADDR = 200, /* Acquiring addr */
BFA_STATUS_ERROR_TRUNK_ENABLED = 203, /* Trunk enabled on adapter */
BFA_STATUS_MAX_ENTRY_REACHED = 212, /* MAX entry reached */
BFA_STATUS_TOPOLOGY_LOOP = 230, /* Topology is set to Loop */
BFA_STATUS_LOOP_UNSUPP_MEZZ = 231, /* Loop topology is not supported
* on mezz cards */
BFA_STATUS_MAX_VAL /* Unknown error code */
};
#define bfa_status_t enum bfa_status
Expand Down
87 changes: 69 additions & 18 deletions drivers/scsi/bfa/bfa_defs_svc.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,12 +324,46 @@ struct bfa_fw_fcoe_port_stats_s {
struct bfa_fw_fip_stats_s fip_stats;
};

/**
* @brief LPSM statistics
*/
struct bfa_fw_lpsm_stats_s {
u32 cls_rx; /* LPSM cls_rx */
u32 cls_tx; /* LPSM cls_tx */
u32 arbf0_rx; /* LPSM abrf0 rcvd */
u32 arbf0_tx; /* LPSM abrf0 xmit */
u32 init_rx; /* LPSM loop init start */
u32 unexp_hwst; /* LPSM unknown hw state */
u32 unexp_frame; /* LPSM unknown_frame */
u32 unexp_prim; /* LPSM unexpected primitive */
u32 prev_alpa_unavail; /* LPSM prev alpa unavailable */
u32 alpa_unavail; /* LPSM alpa not available */
u32 lip_rx; /* LPSM lip rcvd */
u32 lip_f7f7_rx; /* LPSM lip f7f7 rcvd */
u32 lip_f8_rx; /* LPSM lip f8 rcvd */
u32 lip_f8f7_rx; /* LPSM lip f8f7 rcvd */
u32 lip_other_rx; /* LPSM lip other rcvd */
u32 lip_tx; /* LPSM lip xmit */
u32 retry_tov; /* LPSM retry TOV */
u32 lip_tov; /* LPSM LIP wait TOV */
u32 idle_tov; /* LPSM idle wait TOV */
u32 arbf0_tov; /* LPSM arbfo wait TOV */
u32 stop_loop_tov; /* LPSM stop loop wait TOV */
u32 lixa_tov; /* LPSM lisa wait TOV */
u32 lixx_tov; /* LPSM lilp/lirp wait TOV */
u32 cls_tov; /* LPSM cls wait TOV */
u32 sler; /* LPSM SLER recvd */
u32 failed; /* LPSM failed */
u32 success; /* LPSM online */
};

/*
* IOC firmware FC uport stats
*/
struct bfa_fw_fc_uport_stats_s {
struct bfa_fw_port_snsm_stats_s snsm_stats;
struct bfa_fw_port_lksm_stats_s lksm_stats;
struct bfa_fw_lpsm_stats_s lpsm_stats;
};

/*
Expand Down Expand Up @@ -357,11 +391,6 @@ struct bfa_fw_fcxchg_stats_s {
u32 ua_state_inv;
};

struct bfa_fw_lpsm_stats_s {
u32 cls_rx;
u32 cls_tx;
};

/*
* Trunk statistics
*/
Expand Down Expand Up @@ -454,7 +483,6 @@ struct bfa_fw_stats_s {
struct bfa_fw_io_stats_s io_stats;
struct bfa_fw_port_stats_s port_stats;
struct bfa_fw_fcxchg_stats_s fcxchg_stats;
struct bfa_fw_lpsm_stats_s lpsm_stats;
struct bfa_fw_lps_stats_s lps_stats;
struct bfa_fw_trunk_stats_s trunk_stats;
struct bfa_fw_advsm_stats_s advsm_stats;
Expand Down Expand Up @@ -498,9 +526,10 @@ enum bfa_qos_bw_alloc {
* QoS attribute returned in QoS Query
*/
struct bfa_qos_attr_s {
u8 state; /* QoS current state */
u8 rsvd[3];
u32 total_bb_cr; /* Total BB Credits */
u8 state; /* QoS current state */
u8 rsvd1[3];
u32 total_bb_cr; /* Total BB Credits */
u32 rsvd2[2];
};

/*
Expand Down Expand Up @@ -714,9 +743,11 @@ enum bfa_port_type {
*/
enum bfa_port_topology {
BFA_PORT_TOPOLOGY_NONE = 0, /* No valid topology */
BFA_PORT_TOPOLOGY_P2P = 1, /* P2P only */
BFA_PORT_TOPOLOGY_LOOP = 2, /* LOOP topology */
BFA_PORT_TOPOLOGY_AUTO = 3, /* auto topology selection */
BFA_PORT_TOPOLOGY_P2P_OLD_VER = 1, /* P2P def for older ver */
BFA_PORT_TOPOLOGY_LOOP = 2, /* LOOP topology */
BFA_PORT_TOPOLOGY_AUTO_OLD_VER = 3, /* auto def for older ver */
BFA_PORT_TOPOLOGY_AUTO = 4, /* auto topology selection */
BFA_PORT_TOPOLOGY_P2P = 5, /* P2P only */
};

/*
Expand Down Expand Up @@ -851,9 +882,10 @@ struct bfa_port_cfg_s {
u8 bb_scn; /* BB_SCN value from FLOGI Exchg */
u8 bb_scn_state; /* Config state of BB_SCN */
u8 faa_state; /* FAA enabled/disabled */
u8 rsvd[1];
u8 rsvd1;
u16 path_tov; /* device path timeout */
u16 q_depth; /* SCSI Queue depth */
u32 rsvd2;
};
#pragma pack()

Expand Down Expand Up @@ -971,6 +1003,13 @@ struct bfa_trunk_vc_attr_s {
u16 vc_credits[8];
};

struct bfa_fcport_loop_info_s {
u8 myalpa; /* alpa claimed */
u8 alpabm_val; /* alpa bitmap valid or not (1 or 0) */
u8 resvd[6];
struct fc_alpabm_s alpabm; /* alpa bitmap */
};

/*
* Link state information
*/
Expand All @@ -981,13 +1020,18 @@ struct bfa_port_link_s {
u8 speed; /* Link speed (1/2/4/8 G) */
u32 linkstate_opt; /* Linkstate optional data (debug) */
u8 trunked; /* Trunked or not (1 or 0) */
u8 resvd[3];
u8 resvd[7];
struct bfa_qos_attr_s qos_attr; /* QoS Attributes */
union {
struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */
struct bfa_trunk_vc_attr_s trunk_vc_attr;
struct bfa_fcport_fcf_s fcf; /* FCF information (for FCoE) */
} vc_fcf;
struct bfa_fcport_loop_info_s loop_info;
union {
struct bfa_qos_vc_attr_s qos_vc_attr;
/* VC info from ELP */
struct bfa_trunk_vc_attr_s trunk_vc_attr;
struct bfa_fcport_fcf_s fcf;
/* FCF information (for FCoE) */
} vc_fcf;
} attr;
};
#pragma pack()

Expand Down Expand Up @@ -1112,13 +1156,19 @@ struct bfa_port_fc_stats_s {
u64 tx_frames; /* Tx frames */
u64 tx_words; /* Tx words */
u64 tx_lip; /* Tx LIP */
u64 tx_lip_f7f7; /* Tx LIP_F7F7 */
u64 tx_lip_f8f7; /* Tx LIP_F8F7 */
u64 tx_arbf0; /* Tx ARB F0 */
u64 tx_nos; /* Tx NOS */
u64 tx_ols; /* Tx OLS */
u64 tx_lr; /* Tx LR */
u64 tx_lrr; /* Tx LRR */
u64 rx_frames; /* Rx frames */
u64 rx_words; /* Rx words */
u64 lip_count; /* Rx LIP */
u64 rx_lip_f7f7; /* Rx LIP_F7F7 */
u64 rx_lip_f8f7; /* Rx LIP_F8F7 */
u64 rx_arbf0; /* Rx ARB F0 */
u64 nos_count; /* Rx NOS */
u64 ols_count; /* Rx OLS */
u64 lr_count; /* Rx LR */
Expand All @@ -1140,6 +1190,7 @@ struct bfa_port_fc_stats_s {
u64 bbsc_frames_lost; /* Credit Recovery-Frames Lost */
u64 bbsc_credits_lost; /* Credit Recovery-Credits Lost */
u64 bbsc_link_resets; /* Credit Recovery-Link Resets */
u64 loop_timeouts; /* Loop timeouts */
};

/*
Expand Down
5 changes: 5 additions & 0 deletions drivers/scsi/bfa/bfa_fc.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ typedef u64 wwn_t;

#define WWN_NULL (0)
#define FC_SYMNAME_MAX 256 /* max name server symbolic name size */
#define FC_ALPA_MAX 128

#pragma pack(1)

Expand Down Expand Up @@ -1015,6 +1016,10 @@ struct fc_symname_s {
u8 symname[FC_SYMNAME_MAX];
};

struct fc_alpabm_s {
u8 alpa_bm[FC_ALPA_MAX / 8];
};

/*
* protocol default timeout values
*/
Expand Down
4 changes: 4 additions & 0 deletions drivers/scsi/bfa/bfa_fcbuild.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,

memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s));

/* For FC AL bb_cr is 0 and altbbcred is 1 */
if (!bb_cr)
plogi->csp.altbbcred = 1;

plogi->els_cmd.els_code = els_code;
if (els_code == FC_ELS_PLOGI)
fc_els_req_build(fchs, d_id, s_id, ox_id);
Expand Down
64 changes: 51 additions & 13 deletions drivers/scsi/bfa/bfa_fcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,16 +303,30 @@ static void
bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event)
{
struct bfa_s *bfa = fabric->fcs->bfa;

bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
bfa_trc(fabric->fcs, event);

switch (event) {
case BFA_FCS_FABRIC_SM_START:
if (bfa_fcport_is_linkup(fabric->fcs->bfa)) {
if (!bfa_fcport_is_linkup(fabric->fcs->bfa)) {
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
break;
}
if (bfa_fcport_get_topology(bfa) ==
BFA_PORT_TOPOLOGY_LOOP) {
fabric->fab_type = BFA_FCS_FABRIC_LOOP;
fabric->bport.pid = bfa_fcport_get_myalpa(bfa);
fabric->bport.pid = bfa_hton3b(fabric->bport.pid);
bfa_sm_set_state(fabric,
bfa_fcs_fabric_sm_online);
bfa_fcs_fabric_set_opertype(fabric);
bfa_fcs_lport_online(&fabric->bport);
} else {
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
bfa_fcs_fabric_login(fabric);
} else
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
}
break;

case BFA_FCS_FABRIC_SM_LINK_UP:
Expand All @@ -337,16 +351,28 @@ static void
bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event)
{
struct bfa_s *bfa = fabric->fcs->bfa;

bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
bfa_trc(fabric->fcs, event);

switch (event) {
case BFA_FCS_FABRIC_SM_LINK_UP:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
bfa_fcs_fabric_login(fabric);
if (bfa_fcport_get_topology(bfa) != BFA_PORT_TOPOLOGY_LOOP) {
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
bfa_fcs_fabric_login(fabric);
break;
}
fabric->fab_type = BFA_FCS_FABRIC_LOOP;
fabric->bport.pid = bfa_fcport_get_myalpa(bfa);
fabric->bport.pid = bfa_hton3b(fabric->bport.pid);
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
bfa_fcs_fabric_set_opertype(fabric);
bfa_fcs_lport_online(&fabric->bport);
break;

case BFA_FCS_FABRIC_SM_RETRY_OP:
case BFA_FCS_FABRIC_SM_LOOPBACK:
break;

case BFA_FCS_FABRIC_SM_DELETE:
Expand Down Expand Up @@ -595,14 +621,20 @@ void
bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event)
{
struct bfa_s *bfa = fabric->fcs->bfa;

bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
bfa_trc(fabric->fcs, event);

switch (event) {
case BFA_FCS_FABRIC_SM_LINK_DOWN:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
bfa_fcs_fabric_notify_offline(fabric);
if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) {
bfa_fcs_lport_offline(&fabric->bport);
} else {
bfa_sm_send_event(fabric->lps, BFA_LPS_SM_OFFLINE);
bfa_fcs_fabric_notify_offline(fabric);
}
break;

case BFA_FCS_FABRIC_SM_DELETE:
Expand Down Expand Up @@ -719,20 +751,29 @@ static void
bfa_fcs_fabric_sm_stopping(struct bfa_fcs_fabric_s *fabric,
enum bfa_fcs_fabric_event event)
{
struct bfa_s *bfa = fabric->fcs->bfa;

bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
bfa_trc(fabric->fcs, event);

switch (event) {
case BFA_FCS_FABRIC_SM_STOPCOMP:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
bfa_sm_send_event(fabric->lps, BFA_LPS_SM_LOGOUT);
if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP) {
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
} else {
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
bfa_sm_send_event(fabric->lps, BFA_LPS_SM_LOGOUT);
}
break;

case BFA_FCS_FABRIC_SM_LINK_UP:
break;

case BFA_FCS_FABRIC_SM_LINK_DOWN:
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
else
bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_cleanup);
break;

default:
Expand Down Expand Up @@ -975,9 +1016,6 @@ bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
struct bfa_lport_cfg_s *pcfg = &fabric->bport.port_cfg;
u8 alpa = 0, bb_scn = 0;

if (bfa_fcport_get_topology(bfa) == BFA_PORT_TOPOLOGY_LOOP)
alpa = bfa_fcport_get_myalpa(bfa);

if (bfa_fcs_fabric_is_bbscn_enabled(fabric) &&
(!fabric->fcs->bbscn_flogi_rjt))
bb_scn = BFA_FCS_PORT_DEF_BB_SCN;
Expand Down
Loading

0 comments on commit bc0e2c2

Please sign in to comment.