Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1a898a79 authored by Vijaya Mohan Guvva's avatar Vijaya Mohan Guvva Committed by James Bottomley
Browse files

[SCSI] bfa: Add dynamic diagnostic port support



D-Port is a new port type created with the intention of running link
level diagnostic tests like loopback, traffic test. In static D-port
mode, user configures the port to D-port mode and starts the test, but
in dynamic D-port, once the Brocade switch port is configured to
D-port, it will reject the regular FLOGI from HBA with reason that it is
in D-port mode. So based on the reason code HBA port will turn itself into
D-port and start diagnostic test.

Signed-off-by: default avatarSudarsana Reddy Kalluru <skalluru@brocade.com>
Signed-off-by: default avatarVijaya Mohan Guvva <vmohan@brocade.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 4e1e0d8d
Loading
Loading
Loading
Loading
+68 −11
Original line number Original line Diff line number Diff line
@@ -199,15 +199,34 @@ enum bfa_status {
	BFA_STATUS_DPORT_DISABLED = 236, /* D-port mode is already disabled */
	BFA_STATUS_DPORT_DISABLED = 236, /* D-port mode is already disabled */
	BFA_STATUS_CMD_NOTSUPP_MEZZ = 239, /* Cmd not supported for MEZZ card */
	BFA_STATUS_CMD_NOTSUPP_MEZZ = 239, /* Cmd not supported for MEZZ card */
	BFA_STATUS_FRU_NOT_PRESENT = 240, /* fru module not present */
	BFA_STATUS_FRU_NOT_PRESENT = 240, /* fru module not present */
	BFA_STATUS_DPORT_NO_SFP = 243, /* SFP is not present.\n D-port will be
					* enabled but it will be operational
					* only after inserting a valid SFP. */
	BFA_STATUS_DPORT_ERR = 245,	/* D-port mode is enabled */
	BFA_STATUS_DPORT_ERR = 245,	/* D-port mode is enabled */
	BFA_STATUS_DPORT_ENOSYS = 254, /* Switch has no D_Port functionality */
	BFA_STATUS_DPORT_CANT_PERF = 255, /* Switch port is not D_Port capable
					* or D_Port is disabled */
	BFA_STATUS_DPORT_LOGICALERR = 256, /* Switch D_Port fail */
	BFA_STATUS_DPORT_SWBUSY = 257, /* Switch port busy */
	BFA_STATUS_ERR_BBCR_SPEED_UNSUPPORT = 258, /*!< BB credit recovery is
	BFA_STATUS_ERR_BBCR_SPEED_UNSUPPORT = 258, /*!< BB credit recovery is
					* supported at max port speed alone */
					* supported at max port speed alone */
	BFA_STATUS_ERROR_BBCR_ENABLED  = 259, /*!< BB credit recovery
	BFA_STATUS_ERROR_BBCR_ENABLED  = 259, /*!< BB credit recovery
					* is enabled */
					* is enabled */
	BFA_STATUS_INVALID_BBSCN = 260, /*!< Invalid BBSCN value.
	BFA_STATUS_INVALID_BBSCN = 260, /*!< Invalid BBSCN value.
					 * Valid range is [1-15] */
					 * Valid range is [1-15] */
	BFA_STATUS_DDPORT_ERR = 261, /* Dynamic D_Port mode is active.\n To
					* exit dynamic mode, disable D_Port on
					* the remote port */
	BFA_STATUS_DPORT_SFPWRAP_ERR = 262, /* Clear e/o_wrap fail, check or
						* replace SFP */
	BFA_STATUS_BBCR_CFG_NO_CHANGE = 265, /*!< BBCR is operational.
	BFA_STATUS_BBCR_CFG_NO_CHANGE = 265, /*!< BBCR is operational.
			* Disable BBCR and try this operation again. */
			* Disable BBCR and try this operation again. */
	BFA_STATUS_DPORT_SW_NOTREADY = 268, /* Remote port is not ready to
					* start dport test. Check remote
					* port status. */
	BFA_STATUS_DPORT_INV_SFP = 271, /* Invalid SFP for D-PORT mode. */
	BFA_STATUS_DPORT_CMD_NOTSUPP    = 273, /* Dport is not supported by
					* remote port */
	BFA_STATUS_MAX_VAL		/* Unknown error code */
	BFA_STATUS_MAX_VAL		/* Unknown error code */
};
};
#define bfa_status_t enum bfa_status
#define bfa_status_t enum bfa_status
@@ -526,17 +545,6 @@ struct bfa_ioc_aen_data_s {
	mac_t	mac;
	mac_t	mac;
};
};


/*
 *	D-port states
 *
*/
enum bfa_dport_state {
	BFA_DPORT_ST_DISABLED	= 0,	/* D-port is Disabled */
	BFA_DPORT_ST_DISABLING	= 1,	/* D-port is Disabling */
	BFA_DPORT_ST_ENABLING	= 2,	/* D-port is Enabling */
	BFA_DPORT_ST_ENABLED	= 3,	/* D-port is Enabled */
};

/*
/*
 * ---------------------- mfg definitions ------------
 * ---------------------- mfg definitions ------------
 */
 */
@@ -1136,6 +1144,7 @@ struct bfa_flash_attr_s {
#define LB_PATTERN_DEFAULT	0xB5B5B5B5
#define LB_PATTERN_DEFAULT	0xB5B5B5B5
#define QTEST_CNT_DEFAULT	10
#define QTEST_CNT_DEFAULT	10
#define QTEST_PAT_DEFAULT	LB_PATTERN_DEFAULT
#define QTEST_PAT_DEFAULT	LB_PATTERN_DEFAULT
#define DPORT_ENABLE_LOOPCNT_DEFAULT (1024 * 1024)


struct bfa_diag_memtest_s {
struct bfa_diag_memtest_s {
	u8	algo;
	u8	algo;
@@ -1164,6 +1173,54 @@ struct bfa_diag_loopback_result_s {
	u8	rsvd[3];
	u8	rsvd[3];
};
};


enum bfa_diag_dport_test_status {
	DPORT_TEST_ST_IDLE	= 0,    /* the test has not started yet. */
	DPORT_TEST_ST_FINAL	= 1,    /* the test done successfully */
	DPORT_TEST_ST_SKIP	= 2,    /* the test skipped */
	DPORT_TEST_ST_FAIL	= 3,    /* the test failed */
	DPORT_TEST_ST_INPRG	= 4,    /* the testing is in progress */
	DPORT_TEST_ST_RESPONDER	= 5,    /* test triggered from remote port */
	DPORT_TEST_ST_STOPPED	= 6,    /* the test stopped by user. */
	DPORT_TEST_ST_MAX
};

enum bfa_diag_dport_test_type {
	DPORT_TEST_ELOOP	= 0,
	DPORT_TEST_OLOOP	= 1,
	DPORT_TEST_ROLOOP	= 2,
	DPORT_TEST_LINK		= 3,
	DPORT_TEST_MAX
};

enum bfa_diag_dport_test_opmode {
	BFA_DPORT_OPMODE_AUTO	= 0,
	BFA_DPORT_OPMODE_MANU	= 1,
};

struct bfa_diag_dport_subtest_result_s {
	u8	status;		/* bfa_diag_dport_test_status */
	u8	rsvd[7];	/* 64bit align */
	u64	start_time;	/* timestamp  */
};

struct bfa_diag_dport_result_s {
	wwn_t	rp_pwwn;	/* switch port wwn  */
	wwn_t	rp_nwwn;	/* switch node wwn  */
	u64	start_time;	/* user/sw start time */
	u64	end_time;	/* timestamp  */
	u8	status;		/* bfa_diag_dport_test_status */
	u8	mode;		/* bfa_diag_dport_test_opmode */
	u8	rsvd;		/* 64bit align */
	u8	speed;		/* link speed for buf_reqd */
	u16	buffer_required;
	u16	frmsz;		/* frame size for buf_reqd */
	u32	lpcnt;		/* Frame count */
	u32	pat;		/* Pattern */
	u32	roundtrip_latency;	/* in nano sec */
	u32	est_cable_distance;	/* in meter */
	struct bfa_diag_dport_subtest_result_s subtest[DPORT_TEST_MAX];
};

struct bfa_diag_ledtest_s {
struct bfa_diag_ledtest_s {
	u32	cmd;    /* bfa_led_op_t */
	u32	cmd;    /* bfa_led_op_t */
	u32	color;  /* bfa_led_color_t */
	u32	color;  /* bfa_led_color_t */
+1 −0
Original line number Original line Diff line number Diff line
@@ -761,6 +761,7 @@ enum bfa_port_states {
	BFA_PORT_ST_TOGGLING_QWAIT	= 14,
	BFA_PORT_ST_TOGGLING_QWAIT	= 14,
	BFA_PORT_ST_FAA_MISCONFIG	= 15,
	BFA_PORT_ST_FAA_MISCONFIG	= 15,
	BFA_PORT_ST_DPORT		= 16,
	BFA_PORT_ST_DPORT		= 16,
	BFA_PORT_ST_DDPORT		= 17,
	BFA_PORT_ST_MAX_STATE,
	BFA_PORT_ST_MAX_STATE,
};
};


+555 −40

File changed.

Preview size limit exceeded, changes collapsed.

+16 −5
Original line number Original line Diff line number Diff line
@@ -551,6 +551,7 @@ void bfa_fcport_event_register(struct bfa_s *bfa,
			enum bfa_port_linkstate event), void *event_cbarg);
			enum bfa_port_linkstate event), void *event_cbarg);
bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa);
bfa_boolean_t bfa_fcport_is_disabled(struct bfa_s *bfa);
bfa_boolean_t bfa_fcport_is_dport(struct bfa_s *bfa);
bfa_boolean_t bfa_fcport_is_dport(struct bfa_s *bfa);
bfa_boolean_t bfa_fcport_is_ddport(struct bfa_s *bfa);
bfa_status_t bfa_fcport_set_qos_bw(struct bfa_s *bfa,
bfa_status_t bfa_fcport_set_qos_bw(struct bfa_s *bfa,
				   struct bfa_qos_bw_s *qos_bw);
				   struct bfa_qos_bw_s *qos_bw);
enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa);
enum bfa_port_speed bfa_fcport_get_ratelim_speed(struct bfa_s *bfa);
@@ -715,10 +716,18 @@ struct bfa_fcdiag_lb_s {
struct bfa_dport_s {
struct bfa_dport_s {
	struct bfa_s	*bfa;		/* Back pointer to BFA	*/
	struct bfa_s	*bfa;		/* Back pointer to BFA	*/
	bfa_sm_t	sm;		/* finite state machine */
	bfa_sm_t	sm;		/* finite state machine */
	u32		msgtag;		/* firmware msg tag for reply */
	struct bfa_reqq_wait_s reqq_wait;
	struct bfa_reqq_wait_s reqq_wait;
	bfa_cb_diag_t	cbfn;
	bfa_cb_diag_t	cbfn;
	void		*cbarg;
	void		*cbarg;
	union bfi_diag_dport_msg_u i2hmsg;
	u8		test_state;	/* enum dport_test_state  */
	u8		dynamic;	/* boolean_t  */
	u8		rsvd[2];
	u32		lpcnt;
	u32		payload;	/* user defined payload pattern */
	wwn_t		rp_pwwn;
	wwn_t		rp_nwwn;
	struct bfa_diag_dport_result_s result;
};
};


struct bfa_fcdiag_s {
struct bfa_fcdiag_s {
@@ -742,11 +751,13 @@ bfa_status_t bfa_fcdiag_queuetest(struct bfa_s *bfa, u32 ignore,
			u32 queue, struct bfa_diag_qtest_result_s *result,
			u32 queue, struct bfa_diag_qtest_result_s *result,
			bfa_cb_diag_t cbfn, void *cbarg);
			bfa_cb_diag_t cbfn, void *cbarg);
bfa_status_t	bfa_fcdiag_lb_is_running(struct bfa_s *bfa);
bfa_status_t	bfa_fcdiag_lb_is_running(struct bfa_s *bfa);
bfa_status_t	bfa_dport_enable(struct bfa_s *bfa, bfa_cb_diag_t cbfn,
bfa_status_t	bfa_dport_enable(struct bfa_s *bfa, u32 lpcnt, u32 pat,
				 void *cbarg);
					bfa_cb_diag_t cbfn, void *cbarg);
bfa_status_t	bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn,
bfa_status_t	bfa_dport_disable(struct bfa_s *bfa, bfa_cb_diag_t cbfn,
				  void *cbarg);
				  void *cbarg);
bfa_status_t	bfa_dport_get_state(struct bfa_s *bfa,
bfa_status_t	bfa_dport_start(struct bfa_s *bfa, u32 lpcnt, u32 pat,
				    enum bfa_dport_state *state);
				bfa_cb_diag_t cbfn, void *cbarg);
bfa_status_t	bfa_dport_show(struct bfa_s *bfa,
				struct bfa_diag_dport_result_s *result);


#endif /* __BFA_SVC_H__ */
#endif /* __BFA_SVC_H__ */
+61 −20
Original line number Original line Diff line number Diff line
@@ -1785,51 +1785,87 @@ bfad_iocmd_diag_lb_stat(struct bfad_s *bfad, void *cmd)
}
}


int
int
bfad_iocmd_diag_cfg_dport(struct bfad_s *bfad, unsigned int cmd, void *pcmd)
bfad_iocmd_diag_dport_enable(struct bfad_s *bfad, void *pcmd)
{
{
	struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd;
	struct bfa_bsg_dport_enable_s *iocmd =
				(struct bfa_bsg_dport_enable_s *)pcmd;
	unsigned long	flags;
	unsigned long	flags;
	struct bfad_hal_comp fcomp;
	struct bfad_hal_comp fcomp;


	init_completion(&fcomp.comp);
	init_completion(&fcomp.comp);
	spin_lock_irqsave(&bfad->bfad_lock, flags);
	spin_lock_irqsave(&bfad->bfad_lock, flags);
	if (cmd == IOCMD_DIAG_DPORT_ENABLE)
	iocmd->status = bfa_dport_enable(&bfad->bfa, iocmd->lpcnt,
		iocmd->status = bfa_dport_enable(&bfad->bfa,
					iocmd->pat, bfad_hcb_comp, &fcomp);
					bfad_hcb_comp, &fcomp);
	else if (cmd == IOCMD_DIAG_DPORT_DISABLE)
		iocmd->status = bfa_dport_disable(&bfad->bfa,
					bfad_hcb_comp, &fcomp);
	else {
		bfa_trc(bfad, 0);
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
		return -EINVAL;
	if (iocmd->status != BFA_STATUS_OK)
		bfa_trc(bfad, iocmd->status);
	else {
		wait_for_completion(&fcomp.comp);
		iocmd->status = fcomp.status;
	}
	return 0;
}
}
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);


int
bfad_iocmd_diag_dport_disable(struct bfad_s *bfad, void *pcmd)
{
	struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)pcmd;
	unsigned long	flags;
	struct bfad_hal_comp fcomp;

	init_completion(&fcomp.comp);
	spin_lock_irqsave(&bfad->bfad_lock, flags);
	iocmd->status = bfa_dport_disable(&bfad->bfa, bfad_hcb_comp, &fcomp);
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
	if (iocmd->status != BFA_STATUS_OK)
	if (iocmd->status != BFA_STATUS_OK)
		bfa_trc(bfad, iocmd->status);
		bfa_trc(bfad, iocmd->status);
	else {
	else {
		wait_for_completion(&fcomp.comp);
		wait_for_completion(&fcomp.comp);
		iocmd->status = fcomp.status;
		iocmd->status = fcomp.status;
	}
	}
	return 0;
}

int
bfad_iocmd_diag_dport_start(struct bfad_s *bfad, void *pcmd)
{
	struct bfa_bsg_dport_enable_s *iocmd =
				(struct bfa_bsg_dport_enable_s *)pcmd;
	unsigned long   flags;
	struct bfad_hal_comp fcomp;

	init_completion(&fcomp.comp);
	spin_lock_irqsave(&bfad->bfad_lock, flags);
	iocmd->status = bfa_dport_start(&bfad->bfa, iocmd->lpcnt,
					iocmd->pat, bfad_hcb_comp,
					&fcomp);
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);

	if (iocmd->status != BFA_STATUS_OK) {
		bfa_trc(bfad, iocmd->status);
	} else {
		wait_for_completion(&fcomp.comp);
		iocmd->status = fcomp.status;
	}


	return 0;
	return 0;
}
}


int
int
bfad_iocmd_diag_dport_get_state(struct bfad_s *bfad, void *pcmd)
bfad_iocmd_diag_dport_show(struct bfad_s *bfad, void *pcmd)
{
{
	struct bfa_bsg_diag_dport_get_state_s *iocmd =
	struct bfa_bsg_diag_dport_show_s *iocmd =
			(struct bfa_bsg_diag_dport_get_state_s *)pcmd;
				(struct bfa_bsg_diag_dport_show_s *)pcmd;
	unsigned long   flags;
	unsigned long   flags;


	spin_lock_irqsave(&bfad->bfad_lock, flags);
	spin_lock_irqsave(&bfad->bfad_lock, flags);
	iocmd->status = bfa_dport_get_state(&bfad->bfa, &iocmd->state);
	iocmd->status = bfa_dport_show(&bfad->bfa, &iocmd->result);
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
	spin_unlock_irqrestore(&bfad->bfad_lock, flags);


	return 0;
	return 0;
}
}



int
int
bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd)
bfad_iocmd_phy_get_attr(struct bfad_s *bfad, void *cmd)
{
{
@@ -2934,11 +2970,16 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
		rc = bfad_iocmd_diag_lb_stat(bfad, iocmd);
		rc = bfad_iocmd_diag_lb_stat(bfad, iocmd);
		break;
		break;
	case IOCMD_DIAG_DPORT_ENABLE:
	case IOCMD_DIAG_DPORT_ENABLE:
		rc = bfad_iocmd_diag_dport_enable(bfad, iocmd);
		break;
	case IOCMD_DIAG_DPORT_DISABLE:
	case IOCMD_DIAG_DPORT_DISABLE:
		rc = bfad_iocmd_diag_cfg_dport(bfad, cmd, iocmd);
		rc = bfad_iocmd_diag_dport_disable(bfad, iocmd);
		break;
	case IOCMD_DIAG_DPORT_SHOW:
		rc = bfad_iocmd_diag_dport_show(bfad, iocmd);
		break;
		break;
	case IOCMD_DIAG_DPORT_GET_STATE:
	case IOCMD_DIAG_DPORT_START:
		rc = bfad_iocmd_diag_dport_get_state(bfad, iocmd);
		rc = bfad_iocmd_diag_dport_start(bfad, iocmd);
		break;
		break;
	case IOCMD_PHY_GET_ATTR:
	case IOCMD_PHY_GET_ATTR:
		rc = bfad_iocmd_phy_get_attr(bfad, iocmd);
		rc = bfad_iocmd_phy_get_attr(bfad, iocmd);
Loading