Commit ff78d8f9 authored by James Smart's avatar James Smart Committed by James Bottomley

[SCSI] lpfc 8.3.28: SLI fixes and added SLI4 support

Adapter (SLI) interface fixes:

- Modify WQ handling to use entry_repost (CR 123981)
- Fix for ABTS.  Do not free original IOCB whenever ABTS fails. (CR 115829)
- Check board for FCoE before reading FCoE paramaters (CR124731)
- Add support for SLI4 FC Loop mode (CR 124721)
- Add support for resource count changes during fw reset. (CR 125888, 125675)
- Increase CQE count from 256 to 1024. (CR 126149)
Signed-off-by: default avatarAlex Iannicelli <alex.iannicelli@emulex.com>
Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 026abb87
...@@ -2777,6 +2777,14 @@ lpfc_topology_store(struct device *dev, struct device_attribute *attr, ...@@ -2777,6 +2777,14 @@ lpfc_topology_store(struct device *dev, struct device_attribute *attr,
if (val >= 0 && val <= 6) { if (val >= 0 && val <= 6) {
prev_val = phba->cfg_topology; prev_val = phba->cfg_topology;
phba->cfg_topology = val; phba->cfg_topology = val;
if (phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G &&
val == 4) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
"3113 Loop mode not supported at speed %d\n",
phba->cfg_link_speed);
phba->cfg_topology = prev_val;
return -EINVAL;
}
if (nolip) if (nolip)
return strlen(buf); return strlen(buf);
...@@ -3222,6 +3230,14 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr, ...@@ -3222,6 +3230,14 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
val); val);
return -EINVAL; return -EINVAL;
} }
if (val == LPFC_USER_LINK_SPEED_16G &&
phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3112 lpfc_link_speed attribute cannot be set "
"to %d. Speed is not supported in loop mode.\n",
val);
return -EINVAL;
}
if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) && if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
(LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) { (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
prev_val = phba->cfg_link_speed; prev_val = phba->cfg_link_speed;
...@@ -3266,6 +3282,13 @@ lpfc_param_show(link_speed) ...@@ -3266,6 +3282,13 @@ lpfc_param_show(link_speed)
static int static int
lpfc_link_speed_init(struct lpfc_hba *phba, int val) lpfc_link_speed_init(struct lpfc_hba *phba, int val)
{ {
if (val == LPFC_USER_LINK_SPEED_16G && phba->cfg_topology == 4) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"3111 lpfc_link_speed of %d cannot "
"support loop mode, setting topology to default.\n",
val);
phba->cfg_topology = 0;
}
if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) && if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) &&
(LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) { (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) {
phba->cfg_link_speed = val; phba->cfg_link_speed = val;
......
...@@ -453,3 +453,5 @@ int lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *, int); ...@@ -453,3 +453,5 @@ int lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *, int);
uint16_t lpfc_sli_sriov_nr_virtfn_get(struct lpfc_hba *); uint16_t lpfc_sli_sriov_nr_virtfn_get(struct lpfc_hba *);
int lpfc_sli4_queue_create(struct lpfc_hba *); int lpfc_sli4_queue_create(struct lpfc_hba *);
void lpfc_sli4_queue_destroy(struct lpfc_hba *); void lpfc_sli4_queue_destroy(struct lpfc_hba *);
int lpfc_sli4_read_config(struct lpfc_hba *phba);
int lpfc_scsi_buf_update(struct lpfc_hba *phba);
...@@ -909,15 +909,15 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ...@@ -909,15 +909,15 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
*/ */
if (phba->alpa_map[0] == 0) { if (phba->alpa_map[0] == 0) {
vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS; vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS;
if ((phba->sli_rev == LPFC_SLI_REV4) && }
(!(vport->fc_flag & FC_VFI_REGISTERED) || if ((phba->sli_rev == LPFC_SLI_REV4) &&
(vport->fc_prevDID != vport->fc_myDID))) { (!(vport->fc_flag & FC_VFI_REGISTERED) ||
if (vport->fc_flag & FC_VFI_REGISTERED) (vport->fc_prevDID != vport->fc_myDID))) {
lpfc_sli4_unreg_all_rpis(vport); if (vport->fc_flag & FC_VFI_REGISTERED)
lpfc_issue_reg_vfi(vport); lpfc_sli4_unreg_all_rpis(vport);
lpfc_nlp_put(ndlp); lpfc_issue_reg_vfi(vport);
goto out; lpfc_nlp_put(ndlp);
} goto out;
} }
goto flogifail; goto flogifail;
} }
......
...@@ -2858,7 +2858,6 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) ...@@ -2858,7 +2858,6 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
if (vport->port_state == LPFC_FABRIC_CFG_LINK) { if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
/* For private loop just start discovery and we are done. */ /* For private loop just start discovery and we are done. */
if ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) && if ((phba->fc_topology == LPFC_TOPOLOGY_LOOP) &&
(phba->alpa_map[0] == 0) &&
!(vport->fc_flag & FC_PUBLIC_LOOP)) { !(vport->fc_flag & FC_PUBLIC_LOOP)) {
/* Use loop map to make discovery list */ /* Use loop map to make discovery list */
lpfc_disc_list_loopmap(vport); lpfc_disc_list_loopmap(vport);
......
...@@ -62,7 +62,6 @@ static int lpfc_post_rcv_buf(struct lpfc_hba *); ...@@ -62,7 +62,6 @@ static int lpfc_post_rcv_buf(struct lpfc_hba *);
static int lpfc_sli4_queue_verify(struct lpfc_hba *); static int lpfc_sli4_queue_verify(struct lpfc_hba *);
static int lpfc_create_bootstrap_mbox(struct lpfc_hba *); static int lpfc_create_bootstrap_mbox(struct lpfc_hba *);
static int lpfc_setup_endian_order(struct lpfc_hba *); static int lpfc_setup_endian_order(struct lpfc_hba *);
static int lpfc_sli4_read_config(struct lpfc_hba *);
static void lpfc_destroy_bootstrap_mbox(struct lpfc_hba *); static void lpfc_destroy_bootstrap_mbox(struct lpfc_hba *);
static void lpfc_free_sgl_list(struct lpfc_hba *); static void lpfc_free_sgl_list(struct lpfc_hba *);
static int lpfc_init_sgl_list(struct lpfc_hba *); static int lpfc_init_sgl_list(struct lpfc_hba *);
...@@ -2654,6 +2653,32 @@ lpfc_offline(struct lpfc_hba *phba) ...@@ -2654,6 +2653,32 @@ lpfc_offline(struct lpfc_hba *phba)
lpfc_destroy_vport_work_array(phba, vports); lpfc_destroy_vport_work_array(phba, vports);
} }
/**
* lpfc_scsi_buf_update - Update the scsi_buffers that are already allocated.
* @phba: pointer to lpfc hba data structure.
*
* This routine goes through all the scsi buffers in the system and updates the
* Physical XRIs assigned to the SCSI buffer because these may change after any
* firmware reset
*
* Return codes
* 0 - successful (for now, it always returns 0)
**/
int
lpfc_scsi_buf_update(struct lpfc_hba *phba)
{
struct lpfc_scsi_buf *sb, *sb_next;
spin_lock_irq(&phba->hbalock);
spin_lock(&phba->scsi_buf_list_lock);
list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list)
sb->cur_iocbq.sli4_xritag =
phba->sli4_hba.xri_ids[sb->cur_iocbq.sli4_lxritag];
spin_unlock(&phba->scsi_buf_list_lock);
spin_unlock_irq(&phba->hbalock);
return 0;
}
/** /**
* lpfc_scsi_free - Free all the SCSI buffers and IOCBs from driver lists * lpfc_scsi_free - Free all the SCSI buffers and IOCBs from driver lists
* @phba: pointer to lpfc hba data structure. * @phba: pointer to lpfc hba data structure.
...@@ -5021,15 +5046,8 @@ lpfc_sli4_init_rpi_hdrs(struct lpfc_hba *phba) ...@@ -5021,15 +5046,8 @@ lpfc_sli4_init_rpi_hdrs(struct lpfc_hba *phba)
struct lpfc_rpi_hdr *rpi_hdr; struct lpfc_rpi_hdr *rpi_hdr;
INIT_LIST_HEAD(&phba->sli4_hba.lpfc_rpi_hdr_list); INIT_LIST_HEAD(&phba->sli4_hba.lpfc_rpi_hdr_list);
/* if (!phba->sli4_hba.rpi_hdrs_in_use)
* If the SLI4 port supports extents, posting the rpi header isn't
* required. Set the expected maximum count and let the actual value
* get set when extents are fully allocated.
*/
if (!phba->sli4_hba.rpi_hdrs_in_use) {
phba->sli4_hba.next_rpi = phba->sli4_hba.max_cfg_param.max_rpi;
return rc; return rc;
}
if (phba->sli4_hba.extents_in_use) if (phba->sli4_hba.extents_in_use)
return -EIO; return -EIO;
...@@ -5923,7 +5941,7 @@ lpfc_destroy_bootstrap_mbox(struct lpfc_hba *phba) ...@@ -5923,7 +5941,7 @@ lpfc_destroy_bootstrap_mbox(struct lpfc_hba *phba)
* -ENOMEM - No available memory * -ENOMEM - No available memory
* -EIO - The mailbox failed to complete successfully. * -EIO - The mailbox failed to complete successfully.
**/ **/
static int int
lpfc_sli4_read_config(struct lpfc_hba *phba) lpfc_sli4_read_config(struct lpfc_hba *phba)
{ {
LPFC_MBOXQ_t *pmb; LPFC_MBOXQ_t *pmb;
...@@ -5955,6 +5973,20 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) ...@@ -5955,6 +5973,20 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
rc = -EIO; rc = -EIO;
} else { } else {
rd_config = &pmb->u.mqe.un.rd_config; rd_config = &pmb->u.mqe.un.rd_config;
if (bf_get(lpfc_mbx_rd_conf_lnk_ldv, rd_config)) {
phba->sli4_hba.lnk_info.lnk_dv = LPFC_LNK_DAT_VAL;
phba->sli4_hba.lnk_info.lnk_tp =
bf_get(lpfc_mbx_rd_conf_lnk_type, rd_config);
phba->sli4_hba.lnk_info.lnk_no =
bf_get(lpfc_mbx_rd_conf_lnk_numb, rd_config);
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
"3081 lnk_type:%d, lnk_numb:%d\n",
phba->sli4_hba.lnk_info.lnk_tp,
phba->sli4_hba.lnk_info.lnk_no);
} else
lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
"3082 Mailbox (x%x) returned ldv:x0\n",
bf_get(lpfc_mqe_command, &pmb->u.mqe));
phba->sli4_hba.extents_in_use = phba->sli4_hba.extents_in_use =
bf_get(lpfc_mbx_rd_conf_extnts_inuse, rd_config); bf_get(lpfc_mbx_rd_conf_extnts_inuse, rd_config);
phba->sli4_hba.max_cfg_param.max_xri = phba->sli4_hba.max_cfg_param.max_xri =
......
This diff is collapsed.
...@@ -291,7 +291,7 @@ struct lpfc_bmbx { ...@@ -291,7 +291,7 @@ struct lpfc_bmbx {
#define LPFC_RQE_SIZE 8 #define LPFC_RQE_SIZE 8
#define LPFC_EQE_DEF_COUNT 1024 #define LPFC_EQE_DEF_COUNT 1024
#define LPFC_CQE_DEF_COUNT 256 #define LPFC_CQE_DEF_COUNT 1024
#define LPFC_WQE_DEF_COUNT 256 #define LPFC_WQE_DEF_COUNT 256
#define LPFC_MQE_DEF_COUNT 16 #define LPFC_MQE_DEF_COUNT 16
#define LPFC_RQE_DEF_COUNT 512 #define LPFC_RQE_DEF_COUNT 512
......
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