[SCSI] bfa: FC credit recovery and misc bug fixes.

- Introduce FC credit recovery.
- Added module parameter to enable/disable credit recovery.

Bug Fixes:
- Removed check for ignoring plogi from initiator in switched fabric mode.
- The ABTS for PLOGI is going out few millisecs earlier due to FW
  timer calibration (around 300 miilisecs earlier). So there is a
  window if an accept comes during this time HBA would have initiated
  an ABORT.
- Added 1 to FC_ELS_TOV for compensating for FW timer.

Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
diff --git a/drivers/scsi/bfa/bfa_fcbuild.c b/drivers/scsi/bfa/bfa_fcbuild.c
index b7e2534..08fba37 100644
--- a/drivers/scsi/bfa/bfa_fcbuild.c
+++ b/drivers/scsi/bfa/bfa_fcbuild.c
@@ -94,7 +94,6 @@
 	 */
 	plogi_tmpl.csp.verhi = FC_PH_VER_PH_3;
 	plogi_tmpl.csp.verlo = FC_PH_VER_4_3;
-	plogi_tmpl.csp.bbcred = cpu_to_be16(0x0004);
 	plogi_tmpl.csp.ciro = 0x1;
 	plogi_tmpl.csp.cisc = 0x0;
 	plogi_tmpl.csp.altbbcred = 0x0;
@@ -207,7 +206,7 @@
 static          u16
 fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
 		 __be16 ox_id, wwn_t port_name, wwn_t node_name,
-		 u16 pdu_size, u8 els_code)
+		 u16 pdu_size, u16 bb_cr, u8 els_code)
 {
 	struct fc_logi_s *plogi = (struct fc_logi_s *) (pld);
 
@@ -220,6 +219,7 @@
 		fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 
 	plogi->csp.rxsz = plogi->class3.rxsz = cpu_to_be16(pdu_size);
+	plogi->csp.bbcred  = cpu_to_be16(bb_cr);
 
 	memcpy(&plogi->port_name, &port_name, sizeof(wwn_t));
 	memcpy(&plogi->node_name, &node_name, sizeof(wwn_t));
@@ -268,15 +268,17 @@
 u16
 fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
 		   __be16 ox_id, wwn_t port_name, wwn_t node_name,
-		   u16 pdu_size, u16 local_bb_credits)
+		   u16 pdu_size, u16 local_bb_credits, u8 bb_scn)
 {
 	u32        d_id = 0;
+	u16	   bbscn_rxsz = (bb_scn << 12) | pdu_size;
 
 	memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
 	fc_els_rsp_build(fchs, d_id, s_id, ox_id);
 
 	flogi->els_cmd.els_code = FC_ELS_ACC;
-	flogi->csp.rxsz = flogi->class3.rxsz = cpu_to_be16(pdu_size);
+	flogi->class3.rxsz = cpu_to_be16(pdu_size);
+	flogi->csp.rxsz  = cpu_to_be16(bbscn_rxsz);	/* bb_scn/rxsz */
 	flogi->port_name = port_name;
 	flogi->node_name = node_name;
 
@@ -306,19 +308,19 @@
 u16
 fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
 	       u16 ox_id, wwn_t port_name, wwn_t node_name,
-	       u16 pdu_size)
+	       u16 pdu_size, u16 bb_cr)
 {
 	return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
-				node_name, pdu_size, FC_ELS_PLOGI);
+				node_name, pdu_size, bb_cr, FC_ELS_PLOGI);
 }
 
 u16
 fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
 		   u16 ox_id, wwn_t port_name, wwn_t node_name,
-		   u16 pdu_size)
+		   u16 pdu_size, u16 bb_cr)
 {
 	return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
-				node_name, pdu_size, FC_ELS_ACC);
+				node_name, pdu_size, bb_cr, FC_ELS_ACC);
 }
 
 enum fc_parse_status