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

Commit 8fa38513 authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.3.4: Various SLI4 fixes



Various SLI4 fixes

- Fix switch name not used in the FCF record for FCoE HBAs
- Enabled HBA UE error polling error-condition action code
- Rewrite lpfc_sli4_scmd_to_wqidx_distr() to handle counter rollover cleanly
- Modify resume_rpi mailbox data structure to match current SLI4 spec
- Do not issue mailbox command in MBX_POLL mode when LPFC_HBA_ERROR is set
- Wait for HBA POST completion before checking Online and UE registers
- Fix accumulated total length not being filled in on unsolicited IOCBs
- Use PCI config space register to determine SLI rev of HBA
- Turn on starting ELS tmo function timer during device initialization

Signed-off-by: default avatarJames Smart <James.Smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 66d6faec
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -616,6 +616,8 @@ struct lpfc_hba {
	uint32_t hbq_count;	        /* Count of configured HBQs */
	uint32_t hbq_count;	        /* Count of configured HBQs */
	struct hbq_s hbqs[LPFC_MAX_HBQS]; /* local copy of hbq indicies  */
	struct hbq_s hbqs[LPFC_MAX_HBQS]; /* local copy of hbq indicies  */


	uint32_t fcp_qidx;		/* next work queue to post work to */

	unsigned long pci_bar0_map;     /* Physical address for PCI BAR0 */
	unsigned long pci_bar0_map;     /* Physical address for PCI BAR0 */
	unsigned long pci_bar1_map;     /* Physical address for PCI BAR1 */
	unsigned long pci_bar1_map;     /* Physical address for PCI BAR1 */
	unsigned long pci_bar2_map;     /* Physical address for PCI BAR2 */
	unsigned long pci_bar2_map;     /* Physical address for PCI BAR2 */
+60 −6
Original line number Original line Diff line number Diff line
@@ -1053,6 +1053,39 @@ lpfc_fab_name_match(uint8_t *fab_name, struct fcf_record *new_fcf_record)
		return 0;
		return 0;
}
}


/**
 * lpfc_sw_name_match - Check if the fcf switch name match.
 * @fab_name: pointer to fabric name.
 * @new_fcf_record: pointer to fcf record.
 *
 * This routine compare the fcf record's switch name with provided
 * switch name. If the switch name are identical this function
 * returns 1 else return 0.
 **/
static uint32_t
lpfc_sw_name_match(uint8_t *sw_name, struct fcf_record *new_fcf_record)
{
	if ((sw_name[0] ==
		bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record)) &&
	    (sw_name[1] ==
		bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record)) &&
	    (sw_name[2] ==
		bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record)) &&
	    (sw_name[3] ==
		bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record)) &&
	    (sw_name[4] ==
		bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record)) &&
	    (sw_name[5] ==
		bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record)) &&
	    (sw_name[6] ==
		bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record)) &&
	    (sw_name[7] ==
		bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record)))
		return 1;
	else
		return 0;
}

/**
/**
 * lpfc_mac_addr_match - Check if the fcf mac address match.
 * lpfc_mac_addr_match - Check if the fcf mac address match.
 * @phba: pointer to lpfc hba data structure.
 * @phba: pointer to lpfc hba data structure.
@@ -1123,6 +1156,22 @@ lpfc_copy_fcf_record(struct lpfc_hba *phba, struct fcf_record *new_fcf_record)
		bf_get(lpfc_fcf_record_mac_5, new_fcf_record);
		bf_get(lpfc_fcf_record_mac_5, new_fcf_record);
	phba->fcf.fcf_indx = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record);
	phba->fcf.fcf_indx = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record);
	phba->fcf.priority = new_fcf_record->fip_priority;
	phba->fcf.priority = new_fcf_record->fip_priority;
	phba->fcf.switch_name[0] =
		bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record);
	phba->fcf.switch_name[1] =
		bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record);
	phba->fcf.switch_name[2] =
		bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record);
	phba->fcf.switch_name[3] =
		bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record);
	phba->fcf.switch_name[4] =
		bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record);
	phba->fcf.switch_name[5] =
		bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record);
	phba->fcf.switch_name[6] =
		bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record);
	phba->fcf.switch_name[7] =
		bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record);
}
}


/**
/**
@@ -1241,7 +1290,10 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
			!lpfc_fab_name_match(conn_entry->conn_rec.fabric_name,
			!lpfc_fab_name_match(conn_entry->conn_rec.fabric_name,
					     new_fcf_record))
					     new_fcf_record))
			continue;
			continue;

		if ((conn_entry->conn_rec.flags & FCFCNCT_SWNM_VALID) &&
			!lpfc_sw_name_match(conn_entry->conn_rec.switch_name,
					    new_fcf_record))
			continue;
		if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID) {
		if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID) {
			/*
			/*
			 * If the vlan bit map does not have the bit set for the
			 * If the vlan bit map does not have the bit set for the
@@ -1425,6 +1477,8 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
	if (phba->fcf.fcf_flag & FCF_IN_USE) {
	if (phba->fcf.fcf_flag & FCF_IN_USE) {
		if (lpfc_fab_name_match(phba->fcf.fabric_name,
		if (lpfc_fab_name_match(phba->fcf.fabric_name,
					new_fcf_record) &&
					new_fcf_record) &&
		    lpfc_sw_name_match(phba->fcf.switch_name,
					new_fcf_record) &&
		    lpfc_mac_addr_match(phba, new_fcf_record)) {
		    lpfc_mac_addr_match(phba, new_fcf_record)) {
			phba->fcf.fcf_flag |= FCF_AVAILABLE;
			phba->fcf.fcf_flag |= FCF_AVAILABLE;
			spin_unlock_irqrestore(&phba->hbalock, flags);
			spin_unlock_irqrestore(&phba->hbalock, flags);
@@ -1464,9 +1518,9 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
		 * If there is a record with lower priority value for
		 * If there is a record with lower priority value for
		 * the current FCF, use that record.
		 * the current FCF, use that record.
		 */
		 */
		if (lpfc_fab_name_match(phba->fcf.fabric_name, new_fcf_record)
		if (lpfc_fab_name_match(phba->fcf.fabric_name,
			&& (new_fcf_record->fip_priority <
					new_fcf_record) &&
				phba->fcf.priority)) {
		    (new_fcf_record->fip_priority < phba->fcf.priority)) {
			/* Use this FCF record */
			/* Use this FCF record */
			lpfc_copy_fcf_record(phba, new_fcf_record);
			lpfc_copy_fcf_record(phba, new_fcf_record);
			phba->fcf.addr_mode = addr_mode;
			phba->fcf.addr_mode = addr_mode;
+61 −13
Original line number Original line Diff line number Diff line
@@ -52,6 +52,31 @@ struct dma_address {
	uint32_t addr_hi;
	uint32_t addr_hi;
};
};


#define LPFC_SLIREV_CONF_WORD	0x58
struct lpfc_sli_intf {
	uint32_t word0;
#define lpfc_sli_intf_iftype_MASK 	0x00000007
#define lpfc_sli_intf_iftype_SHIFT	0
#define lpfc_sli_intf_iftype_WORD	word0
#define lpfc_sli_intf_rev_MASK 		0x0000000f
#define lpfc_sli_intf_rev_SHIFT		4
#define lpfc_sli_intf_rev_WORD		word0
#define LPFC_SLIREV_CONF_SLI4	4
#define lpfc_sli_intf_family_MASK 	0x000000ff
#define lpfc_sli_intf_family_SHIFT	8
#define lpfc_sli_intf_family_WORD	word0
#define lpfc_sli_intf_feat1_MASK 	0x000000ff
#define lpfc_sli_intf_feat1_SHIFT	16
#define lpfc_sli_intf_feat1_WORD	word0
#define lpfc_sli_intf_feat2_MASK 	0x0000001f
#define lpfc_sli_intf_feat2_SHIFT	24
#define lpfc_sli_intf_feat2_WORD	word0
#define lpfc_sli_intf_valid_MASK 	0x00000007
#define lpfc_sli_intf_valid_SHIFT	29
#define lpfc_sli_intf_valid_WORD	word0
#define LPFC_SLI_INTF_VALID		6
};

#define LPFC_SLI4_BAR0		1
#define LPFC_SLI4_BAR0		1
#define LPFC_SLI4_BAR1		2
#define LPFC_SLI4_BAR1		2
#define LPFC_SLI4_BAR2		4
#define LPFC_SLI4_BAR2		4
@@ -1181,6 +1206,32 @@ struct fcf_record {
#define lpfc_fcf_record_fcf_state_MASK		0x0000FFFF
#define lpfc_fcf_record_fcf_state_MASK		0x0000FFFF
#define lpfc_fcf_record_fcf_state_WORD		word8
#define lpfc_fcf_record_fcf_state_WORD		word8
	uint8_t vlan_bitmap[512];
	uint8_t vlan_bitmap[512];
	uint32_t word137;
#define lpfc_fcf_record_switch_name_0_SHIFT	0
#define lpfc_fcf_record_switch_name_0_MASK	0x000000FF
#define lpfc_fcf_record_switch_name_0_WORD	word137
#define lpfc_fcf_record_switch_name_1_SHIFT	8
#define lpfc_fcf_record_switch_name_1_MASK	0x000000FF
#define lpfc_fcf_record_switch_name_1_WORD	word137
#define lpfc_fcf_record_switch_name_2_SHIFT	16
#define lpfc_fcf_record_switch_name_2_MASK	0x000000FF
#define lpfc_fcf_record_switch_name_2_WORD	word137
#define lpfc_fcf_record_switch_name_3_SHIFT	24
#define lpfc_fcf_record_switch_name_3_MASK	0x000000FF
#define lpfc_fcf_record_switch_name_3_WORD	word137
	uint32_t word138;
#define lpfc_fcf_record_switch_name_4_SHIFT	0
#define lpfc_fcf_record_switch_name_4_MASK	0x000000FF
#define lpfc_fcf_record_switch_name_4_WORD	word138
#define lpfc_fcf_record_switch_name_5_SHIFT	8
#define lpfc_fcf_record_switch_name_5_MASK	0x000000FF
#define lpfc_fcf_record_switch_name_5_WORD	word138
#define lpfc_fcf_record_switch_name_6_SHIFT	16
#define lpfc_fcf_record_switch_name_6_MASK	0x000000FF
#define lpfc_fcf_record_switch_name_6_WORD	word138
#define lpfc_fcf_record_switch_name_7_SHIFT	24
#define lpfc_fcf_record_switch_name_7_MASK	0x000000FF
#define lpfc_fcf_record_switch_name_7_WORD	word138
};
};


struct lpfc_mbx_read_fcf_tbl {
struct lpfc_mbx_read_fcf_tbl {
@@ -1385,20 +1436,17 @@ struct lpfc_mbx_unreg_vfi {


struct lpfc_mbx_resume_rpi {
struct lpfc_mbx_resume_rpi {
	uint32_t word1;
	uint32_t word1;
#define lpfc_resume_rpi_rpi_SHIFT	0
#define lpfc_resume_rpi_index_SHIFT	0
#define lpfc_resume_rpi_rpi_MASK	0x0000FFFF
#define lpfc_resume_rpi_index_MASK	0x0000FFFF
#define lpfc_resume_rpi_rpi_WORD	word1
#define lpfc_resume_rpi_index_WORD	word1
#define lpfc_resume_rpi_ii_SHIFT	30
#define lpfc_resume_rpi_ii_MASK		0x00000003
#define lpfc_resume_rpi_ii_WORD		word1
#define RESUME_INDEX_RPI		0
#define RESUME_INDEX_VPI		1
#define RESUME_INDEX_VFI		2
#define RESUME_INDEX_FCFI		3
	uint32_t event_tag;
	uint32_t event_tag;
	uint32_t word3_rsvd;
	uint32_t word4_rsvd;
	uint32_t word5_rsvd;
	uint32_t word6;
#define lpfc_resume_rpi_vpi_SHIFT	0
#define lpfc_resume_rpi_vpi_MASK	0x0000FFFF
#define lpfc_resume_rpi_vpi_WORD	word6
#define lpfc_resume_rpi_vfi_SHIFT	16
#define lpfc_resume_rpi_vfi_MASK	0x0000FFFF
#define lpfc_resume_rpi_vfi_WORD	word6
};
};


#define REG_FCF_INVALID_QID	0xFFFF
#define REG_FCF_INVALID_QID	0xFFFF
+23 −25
Original line number Original line Diff line number Diff line
@@ -4488,23 +4488,6 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba)
	if (!phba->sli4_hba.STAregaddr)
	if (!phba->sli4_hba.STAregaddr)
		return -ENODEV;
		return -ENODEV;


	/* With uncoverable error, log the error message and return error */
	onlnreg0 = readl(phba->sli4_hba.ONLINE0regaddr);
	onlnreg1 = readl(phba->sli4_hba.ONLINE1regaddr);
	if ((onlnreg0 != LPFC_ONLINE_NERR) || (onlnreg1 != LPFC_ONLINE_NERR)) {
		uerrlo_reg.word0 = readl(phba->sli4_hba.UERRLOregaddr);
		uerrhi_reg.word0 = readl(phba->sli4_hba.UERRHIregaddr);
		if (uerrlo_reg.word0 || uerrhi_reg.word0) {
			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
					"1422 HBA Unrecoverable error: "
					"uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
					"online0_reg=0x%x, online1_reg=0x%x\n",
					uerrlo_reg.word0, uerrhi_reg.word0,
					onlnreg0, onlnreg1);
		}
		return -ENODEV;
	}

	/* Wait up to 30 seconds for the SLI Port POST done and ready */
	/* Wait up to 30 seconds for the SLI Port POST done and ready */
	for (i = 0; i < 3000; i++) {
	for (i = 0; i < 3000; i++) {
		sta_reg.word0 = readl(phba->sli4_hba.STAregaddr);
		sta_reg.word0 = readl(phba->sli4_hba.STAregaddr);
@@ -4544,6 +4527,23 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba)
			bf_get(lpfc_scratchpad_featurelevel1, &scratchpad),
			bf_get(lpfc_scratchpad_featurelevel1, &scratchpad),
			bf_get(lpfc_scratchpad_featurelevel2, &scratchpad));
			bf_get(lpfc_scratchpad_featurelevel2, &scratchpad));


	/* With uncoverable error, log the error message and return error */
	onlnreg0 = readl(phba->sli4_hba.ONLINE0regaddr);
	onlnreg1 = readl(phba->sli4_hba.ONLINE1regaddr);
	if ((onlnreg0 != LPFC_ONLINE_NERR) || (onlnreg1 != LPFC_ONLINE_NERR)) {
		uerrlo_reg.word0 = readl(phba->sli4_hba.UERRLOregaddr);
		uerrhi_reg.word0 = readl(phba->sli4_hba.UERRHIregaddr);
		if (uerrlo_reg.word0 || uerrhi_reg.word0) {
			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
					"1422 HBA Unrecoverable error: "
					"uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
					"online0_reg=0x%x, online1_reg=0x%x\n",
					uerrlo_reg.word0, uerrhi_reg.word0,
					onlnreg0, onlnreg1);
		}
		return -ENODEV;
	}

	return port_error;
	return port_error;
}
}


@@ -7635,19 +7635,17 @@ static int __devinit
lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
{
{
	int rc;
	int rc;
	uint16_t dev_id;
	struct lpfc_sli_intf intf;


	if (pci_read_config_word(pdev, PCI_DEVICE_ID, &dev_id))
	if (pci_read_config_dword(pdev, LPFC_SLIREV_CONF_WORD, &intf.word0))
		return -ENODEV;
		return -ENODEV;


	switch (dev_id) {
	if ((bf_get(lpfc_sli_intf_valid, &intf) == LPFC_SLI_INTF_VALID) &&
	case PCI_DEVICE_ID_TIGERSHARK:
		(bf_get(lpfc_sli_intf_rev, &intf) == LPFC_SLIREV_CONF_SLI4))
		rc = lpfc_pci_probe_one_s4(pdev, pid);
		rc = lpfc_pci_probe_one_s4(pdev, pid);
		break;
	else
	default:
		rc = lpfc_pci_probe_one_s3(pdev, pid);
		rc = lpfc_pci_probe_one_s3(pdev, pid);
		break;

	}
	return rc;
	return rc;
}
}


+3 −5
Original line number Original line Diff line number Diff line
@@ -1938,9 +1938,7 @@ lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp)
	memset(mbox, 0, sizeof(*mbox));
	memset(mbox, 0, sizeof(*mbox));
	resume_rpi = &mbox->u.mqe.un.resume_rpi;
	resume_rpi = &mbox->u.mqe.un.resume_rpi;
	bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_RESUME_RPI);
	bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_RESUME_RPI);
	bf_set(lpfc_resume_rpi_rpi, resume_rpi, ndlp->nlp_rpi);
	bf_set(lpfc_resume_rpi_index, resume_rpi, ndlp->nlp_rpi);
	bf_set(lpfc_resume_rpi_vpi, resume_rpi,
	bf_set(lpfc_resume_rpi_ii, resume_rpi, RESUME_INDEX_RPI);
	       ndlp->vport->vpi + ndlp->vport->phba->vpi_base);
	resume_rpi->event_tag = ndlp->phba->fc_eventTag;
	bf_set(lpfc_resume_rpi_vfi, resume_rpi,
	       ndlp->vport->vfi + ndlp->vport->phba->vfi_base);
}
}
Loading