Commit ee1a4a42 authored by Krishna Gudipati's avatar Krishna Gudipati Committed by James Bottomley

[SCSI] bfa: FCS remote port enhancements.

- Introduced rport qualifier structure and modified design to
  export remote ports with valid pid or valid pwwn to the user space.
- Introduced old_pid field in the rport structure and made changes to
  prevent re-creating a new remote port for an already existing rport
  that is transitioning to a delete state. (Happens if we receive a RSCN
  on the existing remote port that is getting deleted).
Signed-off-by: default avatarKrishna Gudipati <kgudipat@brocade.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent ebfe8392
...@@ -410,6 +410,11 @@ struct bfa_rport_remote_link_stats_s { ...@@ -410,6 +410,11 @@ struct bfa_rport_remote_link_stats_s {
u32 icc; /* Invalid CRC Count */ 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_MAX_IO_INDEX 7
#define BFA_NO_IO_INDEX 9 #define BFA_NO_IO_INDEX 9
......
...@@ -286,9 +286,8 @@ bfa_fcs_lport_get_drvport(struct bfa_fcs_lport_s *port) ...@@ -286,9 +286,8 @@ bfa_fcs_lport_get_drvport(struct bfa_fcs_lport_s *port)
bfa_boolean_t bfa_fcs_lport_is_online(struct bfa_fcs_lport_s *port); 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); 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, void bfa_fcs_lport_get_rport_quals(struct bfa_fcs_lport_s *port,
wwn_t rport_wwns[], int *nrports); struct bfa_rport_qualifier_s rport[], int *nrports);
wwn_t bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, wwn_t bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn,
int index, int nrports, bfa_boolean_t bwwn); int index, int nrports, bfa_boolean_t bwwn);
...@@ -326,10 +325,14 @@ void bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port); ...@@ -326,10 +325,14 @@ void bfa_fcs_lport_offline(struct bfa_fcs_lport_s *port);
void bfa_fcs_lport_delete(struct bfa_fcs_lport_s *port); 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_rport_s *bfa_fcs_lport_get_rport_by_pid(
struct bfa_fcs_lport_s *port, u32 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_rport_s *bfa_fcs_lport_get_rport_by_pwwn(
struct bfa_fcs_lport_s *port, wwn_t 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_rport_s *bfa_fcs_lport_get_rport_by_nwwn(
struct bfa_fcs_lport_s *port, wwn_t 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, void bfa_fcs_lport_add_rport(struct bfa_fcs_lport_s *port,
struct bfa_fcs_rport_s *rport); struct bfa_fcs_rport_s *rport);
void bfa_fcs_lport_del_rport(struct bfa_fcs_lport_s *port, void bfa_fcs_lport_del_rport(struct bfa_fcs_lport_s *port,
...@@ -421,6 +424,7 @@ struct bfa_fcs_rport_s { ...@@ -421,6 +424,7 @@ struct bfa_fcs_rport_s {
struct bfa_fcs_s *fcs; /* fcs instance */ struct bfa_fcs_s *fcs; /* fcs instance */
struct bfad_rport_s *rp_drv; /* driver peer instance */ struct bfad_rport_s *rp_drv; /* driver peer instance */
u32 pid; /* port ID of rport */ u32 pid; /* port ID of rport */
u32 old_pid; /* PID before rport goes offline */
u16 maxfrsize; /* maximum frame size */ u16 maxfrsize; /* maximum frame size */
__be16 reply_oxid; /* OX_ID of inbound requests */ __be16 reply_oxid; /* OX_ID of inbound requests */
enum fc_cos fc_cos; /* FC classes of service supp */ enum fc_cos fc_cos; /* FC classes of service supp */
......
...@@ -853,6 +853,25 @@ bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid) ...@@ -853,6 +853,25 @@ bfa_fcs_lport_get_rport_by_pid(struct bfa_fcs_lport_s *port, u32 pid)
return NULL; 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 * PWWN based Lookup for a R-Port in the Port R-Port Queue
*/ */
...@@ -891,6 +910,26 @@ bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn) ...@@ -891,6 +910,26 @@ bfa_fcs_lport_get_rport_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t nwwn)
return NULL; 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. * Called by rport module when new rports are discovered.
*/ */
...@@ -4759,6 +4798,9 @@ bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid) ...@@ -4759,6 +4798,9 @@ bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid)
* Otherwise let rport handle the RSCN event. * Otherwise let rport handle the RSCN event.
*/ */
rport = bfa_fcs_lport_get_rport_by_pid(port, rpid); 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 (rport == NULL) {
/* /*
* If min cfg mode is enabled, we donot need to * If min cfg mode is enabled, we donot need to
...@@ -4951,15 +4993,15 @@ bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index, ...@@ -4951,15 +4993,15 @@ bfa_fcs_lport_get_rport(struct bfa_fcs_lport_s *port, wwn_t wwn, int index,
} }
void void
bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port, bfa_fcs_lport_get_rport_quals(struct bfa_fcs_lport_s *port,
wwn_t rport_wwns[], int *nrports) struct bfa_rport_qualifier_s rports[], int *nrports)
{ {
struct list_head *qh, *qe; struct list_head *qh, *qe;
struct bfa_fcs_rport_s *rport = NULL; struct bfa_fcs_rport_s *rport = NULL;
int i; int i;
struct bfa_fcs_s *fcs; struct bfa_fcs_s *fcs;
if (port == NULL || rport_wwns == NULL || *nrports == 0) if (port == NULL || rports == NULL || *nrports == 0)
return; return;
fcs = port->fcs; fcs = port->fcs;
...@@ -4979,7 +5021,13 @@ bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port, ...@@ -4979,7 +5021,13 @@ bfa_fcs_lport_get_rports(struct bfa_fcs_lport_s *port,
continue; 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++; i++;
qe = bfa_q_next(qe); qe = bfa_q_next(qe);
......
...@@ -397,6 +397,7 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event) ...@@ -397,6 +397,7 @@ bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
BFA_FCS_RETRY_TIMEOUT); BFA_FCS_RETRY_TIMEOUT);
} else { } else {
bfa_stats(rport->port, rport_del_max_plogi_retry); bfa_stats(rport->port, rport_del_max_plogi_retry);
rport->old_pid = rport->pid;
rport->pid = 0; rport->pid = 0;
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
bfa_timer_start(rport->fcs->bfa, &rport->timer, bfa_timer_start(rport->fcs->bfa, &rport->timer,
...@@ -1296,6 +1297,7 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport, ...@@ -1296,6 +1297,7 @@ bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
bfa_fcs_rport_sm_nsdisc_sending); bfa_fcs_rport_sm_nsdisc_sending);
bfa_fcs_rport_send_nsdisc(rport, NULL); bfa_fcs_rport_send_nsdisc(rport, NULL);
} else { } else {
rport->old_pid = rport->pid;
rport->pid = 0; rport->pid = 0;
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
bfa_timer_start(rport->fcs->bfa, &rport->timer, bfa_timer_start(rport->fcs->bfa, &rport->timer,
...@@ -1981,6 +1983,7 @@ bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid) ...@@ -1981,6 +1983,7 @@ bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
rport->rp_drv = rport_drv; rport->rp_drv = rport_drv;
rport->pid = rpid; rport->pid = rpid;
rport->pwwn = pwwn; rport->pwwn = pwwn;
rport->old_pid = 0;
/* /*
* allocate BFA rport * allocate BFA rport
......
...@@ -941,15 +941,16 @@ bfad_im_num_of_discovered_ports_show(struct device *dev, ...@@ -941,15 +941,16 @@ bfad_im_num_of_discovered_ports_show(struct device *dev,
struct bfad_port_s *port = im_port->port; struct bfad_port_s *port = im_port->port;
struct bfad_s *bfad = im_port->bfad; struct bfad_s *bfad = im_port->bfad;
int nrports = 2048; int nrports = 2048;
wwn_t *rports = NULL; struct bfa_rport_qualifier_s *rports = NULL;
unsigned long flags; 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) if (rports == NULL)
return snprintf(buf, PAGE_SIZE, "Failed\n"); return snprintf(buf, PAGE_SIZE, "Failed\n");
spin_lock_irqsave(&bfad->bfad_lock, flags); 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); spin_unlock_irqrestore(&bfad->bfad_lock, flags);
kfree(rports); kfree(rports);
......
...@@ -535,7 +535,8 @@ bfad_iocmd_lport_get_rports(struct bfad_s *bfad, void *cmd, ...@@ -535,7 +535,8 @@ bfad_iocmd_lport_get_rports(struct bfad_s *bfad, void *cmd,
if (bfad_chk_iocmd_sz(payload_len, if (bfad_chk_iocmd_sz(payload_len,
sizeof(struct bfa_bsg_lport_get_rports_s), 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; iocmd->status = BFA_STATUS_VERSION_FAIL;
return 0; return 0;
} }
...@@ -552,7 +553,8 @@ bfad_iocmd_lport_get_rports(struct bfad_s *bfad, void *cmd, ...@@ -552,7 +553,8 @@ bfad_iocmd_lport_get_rports(struct bfad_s *bfad, void *cmd,
goto out; goto out;
} }
bfa_fcs_lport_get_rports(fcs_port, (wwn_t *)iocmd_bufptr, bfa_fcs_lport_get_rport_quals(fcs_port,
(struct bfa_rport_qualifier_s *)iocmd_bufptr,
&iocmd->nrports); &iocmd->nrports);
spin_unlock_irqrestore(&bfad->bfad_lock, flags); spin_unlock_irqrestore(&bfad->bfad_lock, flags);
iocmd->status = BFA_STATUS_OK; iocmd->status = BFA_STATUS_OK;
...@@ -578,6 +580,10 @@ bfad_iocmd_rport_get_attr(struct bfad_s *bfad, void *cmd) ...@@ -578,6 +580,10 @@ bfad_iocmd_rport_get_attr(struct bfad_s *bfad, void *cmd)
goto out; goto out;
} }
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); fcs_rport = bfa_fcs_rport_lookup(fcs_port, iocmd->rpwwn);
if (fcs_rport == NULL) { if (fcs_rport == NULL) {
bfa_trc(bfad, 0); bfa_trc(bfad, 0);
......
...@@ -319,6 +319,8 @@ struct bfa_bsg_rport_attr_s { ...@@ -319,6 +319,8 @@ struct bfa_bsg_rport_attr_s {
u16 vf_id; u16 vf_id;
wwn_t pwwn; wwn_t pwwn;
wwn_t rpwwn; wwn_t rpwwn;
u32 pid;
u32 rsvd;
struct bfa_rport_attr_s attr; struct bfa_rport_attr_s attr;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment