예제 #1
0
/**
 *   Called by fcs/port to notify transition to online state.
 */
void
bfa_fcs_port_n2n_online(struct bfa_fcs_port_s *port)
{
	struct bfa_fcs_port_n2n_s *n2n_port = &port->port_topo.pn2n;
	struct bfa_port_cfg_s *pcfg = &port->port_cfg;
	struct bfa_fcs_rport_s *rport;

	bfa_trc(port->fcs, pcfg->pwwn);

	/*
	 * If our PWWN is > than that of the r-port, we have to initiate PLOGI
	 * and assign an Address. if not, we need to wait for its PLOGI.
	 *
	 * If our PWWN is < than that of the remote port, it will send a PLOGI
	 * with the PIDs assigned. The rport state machine take care of this
	 * incoming PLOGI.
	 */
	if (memcmp
	    ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn,
	     sizeof(wwn_t)) > 0) {
		port->pid = N2N_LOCAL_PID;
		/**
		 * First, check if we know the device by pwwn.
		 */
		rport = bfa_fcs_port_get_rport_by_pwwn(port,
						       n2n_port->rem_port_wwn);
		if (rport) {
			bfa_trc(port->fcs, rport->pid);
			bfa_trc(port->fcs, rport->pwwn);
			rport->pid = N2N_REMOTE_PID;
			bfa_fcs_rport_online(rport);
			return;
		}

		/*
		 * In n2n there can be only one rport. Delete the old one whose
		 * pid should be zero, because it is offline.
		 */
		if (port->num_rports > 0) {
			rport = bfa_fcs_port_get_rport_by_pid(port, 0);
			bfa_assert(rport != NULL);
			if (rport) {
				bfa_trc(port->fcs, rport->pwwn);
				bfa_fcs_rport_delete(rport);
			}
		}
		bfa_fcs_rport_create(port, N2N_REMOTE_PID);
	}
}
예제 #2
0
/*
 * Process the PID list in GID_FT response
 */
static void
bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s *port,
				   u32 *pid_buf, u32 n_pids)
{
	struct fcgs_gidft_resp_s *gidft_entry;
	struct bfa_fcs_rport_s *rport;
	u32        ii;

	for (ii = 0; ii < n_pids; ii++) {
		gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii];

		if (gidft_entry->pid == port->pid)
			continue;

		/*
		 * Check if this rport already exists
		 */
		rport = bfa_fcs_port_get_rport_by_pid(port, gidft_entry->pid);
		if (rport == NULL) {
			/*
			 * this is a new device. create rport
			 */
			rport = bfa_fcs_rport_create(port, gidft_entry->pid);
		} else {
			/*
			 * this rport already exists
			 */
			bfa_fcs_rport_scn(rport);
		}

		bfa_trc(port->fcs, gidft_entry->pid);

		/*
		 * if the last entry bit is set, bail out.
		 */
		if (gidft_entry->last)
			return;
	}
}
예제 #3
0
void
bfa_fcs_port_loop_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
				 void *cbarg, bfa_status_t req_status,
				 u32 rsp_len, u32 resid_len,
				 struct fchs_s *rsp_fchs)
{
	struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg;
	struct bfa_fcs_rport_s *rport;
	struct fc_adisc_s     *adisc_resp;
	struct fc_els_cmd_s   *els_cmd;
	u32        pid = rsp_fchs->s_id;

	bfa_trc(port->fcs, req_status);

	
	if (req_status != BFA_STATUS_OK) {
		
		bfa_fcxp_free(fcxp);
		return;
	}

	els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
	adisc_resp = (struct fc_adisc_s *) els_cmd;

	if (els_cmd->els_code == FC_ELS_ACC) {
	} else {
		bfa_trc(port->fcs, adisc_resp->els_cmd.els_code);

		
		rport = bfa_fcs_port_get_rport_by_pid(port, pid);
		if (rport) {
			list_del(&rport->qe);
			bfa_fcs_rport_delete(rport);
		}

	}
	return;
}