u32 icc; /* Invalid CRC Count */
};
+struct bfa_rport_qualifier_s {
+ wwn_t pwwn; /* Port WWN */
+ u32 pid; /* port ID */
+ u32 rsvd;
+};
#define BFA_MAX_IO_INDEX 7
#define BFA_NO_IO_INDEX 9
bfa_boolean_t bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port);
struct bfa_fcs_lport_s *bfa_fcs_get_base_port(struct bfa_fcs_s *fcs);
-void bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port,
- wwn_t rport_wwns[], int *nrports);
-
+void bfa_fcs_lport_get_rport_quals(struct bfa_fcs_lport_s *port,
+ struct bfa_rport_qualifier_s rport[], int *nrports);
wwn_t bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn,
int index, int nrports, bfa_boolean_t bwwn);
void bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port);
struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_pid(
struct bfa_fcs_lport_s *port, u32 pid);
+struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_old_pid(
+ struct bfa_fcs_lport_s *port, u32 pid);
struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_pwwn(
struct bfa_fcs_lport_s *port, wwn_t pwwn);
struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_nwwn(
struct bfa_fcs_lport_s *port, wwn_t nwwn);
+struct bfa_fcs_rport_s *bfa_fcs_lport_get_rport_by_qualifier(
+ struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 pid);
void bfa_fcs_lport_add_rport(struct bfa_fcs_lport_s *port,
struct bfa_fcs_rport_s *rport);
void bfa_fcs_lport_del_rport(struct bfa_fcs_lport_s *port,
struct bfa_fcs_s *fcs; /* fcs instance */
struct bfad_rport_s *rp_drv; /* driver peer instance */
u32 pid; /* port ID of rport */
+ u32 old_pid; /* PID before rport goes offline */
u16 maxfrsize; /* maximum frame size */
__be16 reply_oxid; /* OX_ID of inbound requests */
enum fc_cos fc_cos; /* FC classes of service supp */
return NULL;
}
+/*
+ * OLD_PID based Lookup for a R-Port in the Port R-Port Queue
+ */
+struct bfa_fcs_rport_s *
+bfa_fcs_lport_get_rport_by_old_pid(struct bfa_fcs_lport_s *port, u32 pid)
+{
+ struct bfa_fcs_rport_s *rport;
+ struct list_head *qe;
+
+ list_for_each(qe, &port->rport_q) {
+ rport = (struct bfa_fcs_rport_s *) qe;
+ if (rport->old_pid == pid)
+ return rport;
+ }
+
+ bfa_trc(port->fcs, pid);
+ return NULL;
+}
+
/*
* PWWN based Lookup for a R-Port in the Port R-Port Queue
*/
return NULL;
}
+/*
+ * PWWN & PID based Lookup for a R-Port in the Port R-Port Queue
+ */
+struct bfa_fcs_rport_s *
+bfa_fcs_lport_get_rport_by_qualifier(struct bfa_fcs_lport_s *port,
+ wwn_t pwwn, u32 pid)
+{
+ struct bfa_fcs_rport_s *rport;
+ struct list_head *qe;
+
+ list_for_each(qe, &port->rport_q) {
+ rport = (struct bfa_fcs_rport_s *) qe;
+ if (wwn_is_equal(rport->pwwn, pwwn) && rport->pid == pid)
+ return rport;
+ }
+
+ bfa_trc(port->fcs, pwwn);
+ return NULL;
+}
+
/*
* Called by rport module when new rports are discovered.
*/
* Otherwise let rport handle the RSCN event.
*/
rport = bfa_fcs_lport_get_rport_by_pid(port, rpid);
+ if (!rport)
+ rport = bfa_fcs_lport_get_rport_by_old_pid(port, rpid);
+
if (rport == NULL) {
/*
* If min cfg mode is enabled, we donot need to
}
void
-bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port,
- wwn_t rport_wwns[], int *nrports)
+bfa_fcs_lport_get_rport_quals(struct bfa_fcs_lport_s *port,
+ struct bfa_rport_qualifier_s rports[], int *nrports)
{
struct list_head *qh, *qe;
struct bfa_fcs_rport_s *rport = NULL;
int i;
struct bfa_fcs_s *fcs;
- if (port == NULL || rport_wwns == NULL || *nrports == 0)
+ if (port == NULL || rports == NULL || *nrports == 0)
return;
fcs = port->fcs;
continue;
}
- rport_wwns[i] = rport->pwwn;
+ if (!rport->pwwn && !rport->pid) {
+ qe = bfa_q_next(qe);
+ continue;
+ }
+
+ rports[i].pwwn = rport->pwwn;
+ rports[i].pid = rport->pid;
i++;
qe = bfa_q_next(qe);
BFA_FCS_RETRY_TIMEOUT);
} else {
bfa_stats(rport->port, rport_del_max_plogi_retry);
+ rport->old_pid = rport->pid;
rport->pid = 0;
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
bfa_timer_start(rport->fcs->bfa, &rport->timer,
bfa_fcs_rport_sm_nsdisc_sending);
bfa_fcs_rport_send_nsdisc(rport, NULL);
} else {
+ rport->old_pid = rport->pid;
rport->pid = 0;
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
bfa_timer_start(rport->fcs->bfa, &rport->timer,
rport->rp_drv = rport_drv;
rport->pid = rpid;
rport->pwwn = pwwn;
+ rport->old_pid = 0;
/*
* allocate BFA rport
struct bfad_port_s *port = im_port->port;
struct bfad_s *bfad = im_port->bfad;
int nrports = 2048;
- wwn_t *rports = NULL;
+ struct bfa_rport_qualifier_s *rports = NULL;
unsigned long flags;
- rports = kzalloc(sizeof(wwn_t) * nrports , GFP_ATOMIC);
+ rports = kzalloc(sizeof(struct bfa_rport_qualifier_s) * nrports,
+ GFP_ATOMIC);
if (rports == NULL)
return snprintf(buf, PAGE_SIZE, "Failed\n");
spin_lock_irqsave(&bfad->bfad_lock, flags);
- bfa_fcs_lport_get_rports(port->fcs_port, rports, &nrports);
+ bfa_fcs_lport_get_rport_quals(port->fcs_port, rports, &nrports);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
kfree(rports);
if (bfad_chk_iocmd_sz(payload_len,
sizeof(struct bfa_bsg_lport_get_rports_s),
- sizeof(wwn_t) * iocmd->nrports) != BFA_STATUS_OK) {
+ sizeof(struct bfa_rport_qualifier_s) * iocmd->nrports)
+ != BFA_STATUS_OK) {
iocmd->status = BFA_STATUS_VERSION_FAIL;
return 0;
}
goto out;
}
- bfa_fcs_lport_get_rports(fcs_port, (wwn_t *)iocmd_bufptr,
- &iocmd->nrports);
+ bfa_fcs_lport_get_rport_quals(fcs_port,
+ (struct bfa_rport_qualifier_s *)iocmd_bufptr,
+ &iocmd->nrports);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
iocmd->status = BFA_STATUS_OK;
out:
goto out;
}
- fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn);
+ if (iocmd->pid)
+ fcs_rport = bfa_fcs_lport_get_rport_by_qualifier(fcs_port,
+ iocmd->rpwwn, iocmd->pid);
+ else
+ fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn);
if (fcs_rport == NULL) {
bfa_trc(bfad, 0);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
u16 vf_id;
wwn_t pwwn;
wwn_t rpwwn;
+ u32 pid;
+ u32 rsvd;
struct bfa_rport_attr_s attr;
};