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

Commit b704495c authored by Krishna Gudipati's avatar Krishna Gudipati Committed by James Bottomley
Browse files

[SCSI] bfa: direct attach mode fix.



- Direct attach is not working due to the check of PID in fcxp_send request.
- Added logic to set the lps->lp_pid with the PID assigned for n2n mode.

Signed-off-by: default avatarKrishna Gudipati <kgudipat@brocade.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent f1d584d7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ enum bfa_lps_event {
	BFA_LPS_SM_DELETE	= 5,	/* lps delete from user         */
	BFA_LPS_SM_OFFLINE	= 6,	/* Link is offline              */
	BFA_LPS_SM_RX_CVL	= 7,	/* Rx clear virtual link        */
	BFA_LPS_SM_SET_N2N_PID  = 8,	/* Set assigned PID for n2n */
};


+3 −0
Original line number Diff line number Diff line
@@ -309,6 +309,7 @@ bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
			return;
		}
		port->pid  = rx_fchs->d_id;
		bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
	}

	/*
@@ -323,6 +324,7 @@ bfa_fcs_lport_plogi(struct bfa_fcs_lport_s *port,
			(memcmp((void *)&bfa_fcs_lport_get_pwwn(port),
			(void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
			port->pid  = rx_fchs->d_id;
			bfa_lps_set_n2n_pid(port->fabric->lps, rx_fchs->d_id);
			rport->pid = rx_fchs->s_id;
		}
		bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
@@ -979,6 +981,7 @@ bfa_fcs_lport_n2n_online(struct bfa_fcs_lport_s *port)
	    ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn,
	     sizeof(wwn_t)) > 0) {
		port->pid = N2N_LOCAL_PID;
		bfa_lps_set_n2n_pid(port->fabric->lps, N2N_LOCAL_PID);
		/*
		 * First, check if we know the device by pwwn.
		 */
+98 −1
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ 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);
static void bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps);
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);
@@ -143,6 +144,8 @@ 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);
static void bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps,
					enum bfa_lps_event event);
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);
@@ -1254,6 +1257,12 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
			else
				bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
					BFA_PL_EID_LOGIN, 0, "FLOGI Accept");
			/* 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);
		} else {
			bfa_sm_set_state(lps, bfa_lps_sm_init);
			if (lps->fdisc)
@@ -1272,6 +1281,11 @@ bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
		bfa_sm_set_state(lps, bfa_lps_sm_init);
		break;

	case BFA_LPS_SM_SET_N2N_PID:
		bfa_trc(lps->bfa, lps->fport);
		bfa_trc(lps->bfa, lps->lp_pid);
		break;

	default:
		bfa_sm_fault(lps->bfa, event);
	}
@@ -1340,9 +1354,59 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
			BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
		break;

	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;

	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);
	}
}

/**
 * login complete
 */
static void
bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, enum bfa_lps_event event)
{
	bfa_trc(lps->bfa, lps->lp_tag);
	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:
@@ -1498,8 +1562,9 @@ bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp)
	switch (rsp->status) {
	case BFA_STATUS_OK:
		lps->fport	= rsp->f_port;
		lps->npiv_en	= rsp->npiv_en;
		if (lps->fport)
			lps->lp_pid = rsp->lp_pid;
		lps->npiv_en	= rsp->npiv_en;
		lps->pr_bbcred	= be16_to_cpu(rsp->bb_credit);
		lps->pr_pwwn	= rsp->port_name;
		lps->pr_nwwn	= rsp->node_name;
@@ -1626,6 +1691,25 @@ bfa_lps_send_logout(struct bfa_lps_s *lps)
	bfa_reqq_produce(lps->bfa, lps->reqq);
}

/**
 * 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);
	bfa_assert(m);

	bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_N2N_PID_REQ,
		bfa_lpuid(lps->bfa));

	m->lp_tag = lps->lp_tag;
	m->lp_pid = lps->lp_pid;
	bfa_reqq_produce(lps->bfa, lps->reqq);
}

/*
 * Indirect login completion handler for non-fcs
 */
@@ -1846,6 +1930,19 @@ bfa_lps_get_base_pid(struct bfa_s *bfa)
	return BFA_LPS_FROM_TAG(mod, 0)->lp_pid;
}

/**
 * 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)
{
	bfa_trc(lps->bfa, lps->lp_tag);
	bfa_trc(lps->bfa, n2n_pid);

	lps->lp_pid = n2n_pid;
	bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID);
}

/*
 * LPS firmware message class handler.
 */
+1 −0
Original line number Diff line number Diff line
@@ -610,6 +610,7 @@ void bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa,
void bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz,
		   wwn_t pwwn, wwn_t nwwn);
void bfa_lps_fdisclogo(struct bfa_lps_s *lps);
void bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, u32 n2n_pid);
u32 bfa_lps_get_base_pid(struct bfa_s *bfa);
u8 bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid);
void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status);
+8 −0
Original line number Diff line number Diff line
@@ -342,6 +342,7 @@ struct bfi_uf_frm_rcvd_s {
enum bfi_lps_h2i_msgs {
	BFI_LPS_H2I_LOGIN_REQ	= 1,
	BFI_LPS_H2I_LOGOUT_REQ	= 2,
	BFI_LPS_H2I_N2N_PID_REQ = 3,
};

enum bfi_lps_i2h_msgs {
@@ -401,10 +402,17 @@ struct bfi_lps_cvl_event_s {
	u8		rsvd[3];
};

struct bfi_lps_n2n_pid_req_s {
	struct bfi_mhdr_s	mh;	/*  common msg header		*/
	u8	lp_tag;
	u32	lp_pid:24;
};

union bfi_lps_h2i_msg_u {
	struct bfi_mhdr_s		*msg;
	struct bfi_lps_login_req_s	*login_req;
	struct bfi_lps_logout_req_s	*logout_req;
	struct bfi_lps_n2n_pid_req_s	*n2n_pid_req;
};

union bfi_lps_i2h_msg_u {