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

Commit 2fcee4bf authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.3.20: Implement new SLI4 init procedures based on if_type



Implement new SLI4 init procedures based on if_type:

- Add structure changes for new SLIPORT registers and BAR changes.
- Update register names to be consistent with inteface spec terms.
- Added union to encapsulate Hardward error registers.
- Rework lpfc_sli4_post_status_check() around SLI-4's SLI_INTF type
- Removed the lpfc_sli4_fw_cfg_check routine
- Segmented driver logic to include evaluation of the if_type to
  engage different behaviors.

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 <James.Bottomley@suse.de>
parent 70f3c073
Loading
Loading
Loading
Loading
+42 −66
Original line number Diff line number Diff line
@@ -460,42 +460,41 @@ struct lpfc_register {
	uint32_t word0;
};

/* The SLI4 INTF register offset is common to all if_type values. */
#define LPFC_SLI_INTF			0x0058

/* The following BAR0 Registers apply to SLI4 if_type 0 UCNAs. */
#define LPFC_UERR_STATUS_HI		0x00A4
#define LPFC_UERR_STATUS_LO		0x00A0
#define LPFC_UE_MASK_HI			0x00AC
#define LPFC_UE_MASK_LO			0x00A8

#define LPFC_HST_STATE			0x00AC
#define lpfc_hst_state_perr_SHIFT	31
#define lpfc_hst_state_perr_MASK	0x1
#define lpfc_hst_state_perr_WORD	word0
#define lpfc_hst_state_sfi_SHIFT	30
#define lpfc_hst_state_sfi_MASK		0x1
#define lpfc_hst_state_sfi_WORD		word0
#define lpfc_hst_state_nip_SHIFT	29
#define lpfc_hst_state_nip_MASK		0x1
#define lpfc_hst_state_nip_WORD		word0
#define lpfc_hst_state_ipc_SHIFT	28
#define lpfc_hst_state_ipc_MASK		0x1
#define lpfc_hst_state_ipc_WORD		word0
#define lpfc_hst_state_xrom_SHIFT	27
#define lpfc_hst_state_xrom_MASK	0x1
#define lpfc_hst_state_xrom_WORD	word0
#define lpfc_hst_state_dl_SHIFT		26
#define lpfc_hst_state_dl_MASK		0x1
#define lpfc_hst_state_dl_WORD		word0
#define lpfc_hst_state_port_status_SHIFT	0
#define lpfc_hst_state_port_status_MASK		0xFFFF
#define lpfc_hst_state_port_status_WORD		word0
/* The following BAR0 register sets are defined for if_type 0 and 2 UCNAs. */
#define LPFC_SLI_INTF			0x0058

#define LPFC_SLIPORT_IF2_SMPHR		0x0400
#define lpfc_port_smphr_perr_SHIFT	31
#define lpfc_port_smphr_perr_MASK	0x1
#define lpfc_port_smphr_perr_WORD	word0
#define lpfc_port_smphr_sfi_SHIFT	30
#define lpfc_port_smphr_sfi_MASK	0x1
#define lpfc_port_smphr_sfi_WORD	word0
#define lpfc_port_smphr_nip_SHIFT	29
#define lpfc_port_smphr_nip_MASK	0x1
#define lpfc_port_smphr_nip_WORD	word0
#define lpfc_port_smphr_ipc_SHIFT	28
#define lpfc_port_smphr_ipc_MASK	0x1
#define lpfc_port_smphr_ipc_WORD	word0
#define lpfc_port_smphr_scr1_SHIFT	27
#define lpfc_port_smphr_scr1_MASK	0x1
#define lpfc_port_smphr_scr1_WORD	word0
#define lpfc_port_smphr_scr2_SHIFT	26
#define lpfc_port_smphr_scr2_MASK	0x1
#define lpfc_port_smphr_scr2_WORD	word0
#define lpfc_port_smphr_host_scratch_SHIFT	16
#define lpfc_port_smphr_host_scratch_MASK	0xFF
#define lpfc_port_smphr_host_scratch_WORD	word0
#define lpfc_port_smphr_port_status_SHIFT	0
#define lpfc_port_smphr_port_status_MASK	0xFFFF
#define lpfc_port_smphr_port_status_WORD	word0

/*
 * The following Port Status Values apply to SLI4, if_type 0 and 2
 * UCNAs.
 */
#define LPFC_POST_STAGE_POWER_ON_RESET			0x0000
#define LPFC_POST_STAGE_AWAITING_HOST_RDY		0x0001
#define LPFC_POST_STAGE_HOST_RDY			0x0002
@@ -527,36 +526,8 @@ struct lpfc_register {
#define LPFC_POST_STAGE_RC_DONE				0x0B07
#define LPFC_POST_STAGE_REBOOT_SYSTEM			0x0B08
#define LPFC_POST_STAGE_MAC_ADDRESS			0x0C00
#define LPFC_POST_STAGE_ARMFW_READY			0xC000
#define LPFC_POST_STAGE_ARMFW_UE 			0xF000


/* The following BAR0 register sets are defined for if_type 2 UCNAs. */
#define LPFC_SLIPORT_SEMAPHORE		0x0400
#define lpfc_sliport_smphr_perr_SHIFT	31
#define lpfc_sliport_smphr_perr_MASK	0x1
#define lpfc_sliport_smphr_perr_WORD	word0
#define lpfc_sliport_smphr_sfi_SHIFT	30
#define lpfc_sliport_smphr_sfi_MASK	0x1
#define lpfc_sliport_smphr_sfi_WORD	word0
#define lpfc_sliport_smphr_nip_SHIFT	29
#define lpfc_sliport_smphr_nip_MASK	0x1
#define lpfc_sliport_smphr_nip_WORD	word0
#define lpfc_sliport_smphr_ipc_SHIFT	28
#define lpfc_sliport_smphr_ipc_MASK	0x1
#define lpfc_sliport_smphr_ipc_WORD	word0
#define lpfc_sliport_smphr_scr1_SHIFT	27
#define lpfc_sliport_smphr_scr1_MASK	0x1
#define lpfc_sliport_smphr_scr1_WORD	word0
#define lpfc_sliport_smphr_scr2_SHIFT	26
#define lpfc_sliport_smphr_scr2_MASK	0x1
#define lpfc_sliport_smphr_scr2_WORD	word0
#define lpfc_sliport_smphr_host_scratch_SHIFT	16
#define lpfc_sliport_smphr_host_scratch_MASK	0xFF
#define lpfc_sliport_smphr_host_scratch_WORD	word0
#define lpfc_sliport_smphr_port_status_SHIFT	0
#define lpfc_sliport_smphr_port_status_MASK	0xFFFF
#define lpfc_sliport_smphr_port_status_WORD	word0
#define LPFC_POST_STAGE_PORT_READY			0xC000
#define LPFC_POST_STAGE_PORT_UE 			0xF000

#define LPFC_SLIPORT_STATUS		0x0404
#define lpfc_sliport_status_err_SHIFT	31
@@ -574,8 +545,9 @@ struct lpfc_register {
#define lpfc_sliport_status_rdy_SHIFT	23
#define lpfc_sliport_status_rdy_MASK	0x1
#define lpfc_sliport_status_rdy_WORD	word0
#define MAX_IF_TYPE_2_RESETS	1000

#define LPFC_SLIPORT_CONTROL		0x0408
#define LPFC_SLIPORT_CNTRL		0x0408
#define lpfc_sliport_ctrl_end_SHIFT	30
#define lpfc_sliport_ctrl_end_MASK	0x1
#define lpfc_sliport_ctrl_end_WORD	word0
@@ -584,11 +556,16 @@ struct lpfc_register {
#define lpfc_sliport_ctrl_ip_SHIFT	27
#define lpfc_sliport_ctrl_ip_MASK	0x1
#define lpfc_sliport_ctrl_ip_WORD	word0
#define LPFC_SLIPORT_INIT_PORT	1

#define LPFC_SLIPORT_ERROR_1		0x040C
#define LPFC_SLIPORT_ERROR_2		0x0410
#define LPFC_SLIPORT_ERR_1		0x040C
#define LPFC_SLIPORT_ERR_2		0x0410

/* The following Registers apply to SLI4 if_type 0 UCNAs. They typically
 * reside in BAR 2.
 */
#define LPFC_SLIPORT_IF0_SMPHR	0x00AC

/* BAR1 Registers */
#define LPFC_IMR_MASK_ALL	0xFFFFFFFF
#define LPFC_ISCR_CLEAR_ALL	0xFFFFFFFF

@@ -647,7 +624,7 @@ struct lpfc_register {
 * The Doorbell registers defined here exist in different BAR
 * register sets depending on the UCNA Port's reported if_type
 * value.  For UCNA ports running SLI4 and if_type 0, they reside in
 * BAR2.  For UCNA ports running SLI4 and if_type 2, they reside in
 * BAR4.  For UCNA ports running SLI4 and if_type 2, they reside in
 * BAR0.  The offsets are the same so the driver must account for
 * any base address difference.
 */
@@ -2378,7 +2355,7 @@ struct wqe_common {
#define wqe_rcvoxid_WORD      word9
	uint32_t word10;
#define wqe_ebde_cnt_SHIFT    0
#define wqe_ebde_cnt_MASK     0x00000007
#define wqe_ebde_cnt_MASK     0x0000000f
#define wqe_ebde_cnt_WORD     word10
#define wqe_lenloc_SHIFT      7
#define wqe_lenloc_MASK       0x00000003
@@ -2570,7 +2547,6 @@ struct xmit_seq64_wqe {
	uint32_t relative_offset;
	struct wqe_rctl_dfctl wge_ctl;
	struct wqe_common wqe_com; /* words 6-11 */
	/* Note: word10 different REVISIT */
	uint32_t xmit_len;
	uint32_t rsvd_12_15[3];
};
+435 −225

File changed.

Preview size limit exceeded, changes collapsed.

+59 −18
Original line number Diff line number Diff line
@@ -4690,6 +4690,10 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
	struct lpfc_vport *vport = phba->pport;
	struct lpfc_dmabuf *mp;

	/*
	 * TODO:  Why does this routine execute these task in a different
	 * order from probe?
	 */
	/* Perform a PCI function reset to start from clean */
	rc = lpfc_pci_function_reset(phba);
	if (unlikely(rc))
@@ -8439,29 +8443,66 @@ static int
lpfc_sli4_eratt_read(struct lpfc_hba *phba)
{
	uint32_t uerr_sta_hi, uerr_sta_lo;
	uint32_t if_type, portsmphr;
	struct lpfc_register portstat_reg;

	/* For now, use the SLI4 device internal unrecoverable error
	/*
	 * For now, use the SLI4 device internal unrecoverable error
	 * registers for error attention. This can be changed later.
	 */
	uerr_sta_lo = readl(phba->sli4_hba.UERRLOregaddr);
	uerr_sta_hi = readl(phba->sli4_hba.UERRHIregaddr);
	if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
	switch (if_type) {
	case LPFC_SLI_INTF_IF_TYPE_0:
		uerr_sta_lo = readl(phba->sli4_hba.u.if_type0.UERRLOregaddr);
		uerr_sta_hi = readl(phba->sli4_hba.u.if_type0.UERRHIregaddr);
		if ((~phba->sli4_hba.ue_mask_lo & uerr_sta_lo) ||
		    (~phba->sli4_hba.ue_mask_hi & uerr_sta_hi)) {
			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
					"1423 HBA Unrecoverable error: "
					"uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
				"ue_mask_lo_reg=0x%x, ue_mask_hi_reg=0x%x\n",
					"ue_mask_lo_reg=0x%x, "
					"ue_mask_hi_reg=0x%x\n",
					uerr_sta_lo, uerr_sta_hi,
					phba->sli4_hba.ue_mask_lo,
					phba->sli4_hba.ue_mask_hi);
			phba->work_status[0] = uerr_sta_lo;
			phba->work_status[1] = uerr_sta_hi;
		/* Set the driver HA work bitmap */
			phba->work_ha |= HA_ERATT;
		/* Indicate polling handles this ERATT */
			phba->hba_flag |= HBA_ERATT_HANDLED;
			return 1;
		}
		break;
	case LPFC_SLI_INTF_IF_TYPE_2:
		portstat_reg.word0 =
			readl(phba->sli4_hba.u.if_type2.STATUSregaddr);
		portsmphr = readl(phba->sli4_hba.PSMPHRregaddr);
		if (bf_get(lpfc_sliport_status_err, &portstat_reg)) {
			phba->work_status[0] =
				readl(phba->sli4_hba.u.if_type2.ERR1regaddr);
			phba->work_status[1] =
				readl(phba->sli4_hba.u.if_type2.ERR2regaddr);
			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
					"2885 Port Error Detected: "
					"port status reg 0x%x, "
					"port smphr reg 0x%x, "
					"error 1=0x%x, error 2=0x%x\n",
					portstat_reg.word0,
					portsmphr,
					phba->work_status[0],
					phba->work_status[1]);
			phba->work_ha |= HA_ERATT;
			phba->hba_flag |= HBA_ERATT_HANDLED;
			return 1;
		}
		break;
	case LPFC_SLI_INTF_IF_TYPE_1:
	default:
		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
				"2886 HBA Error Attention on unsupported "
				"if type %d.", if_type);
		return 1;
	}

	return 0;
}

@@ -8516,7 +8557,7 @@ lpfc_sli_check_eratt(struct lpfc_hba *phba)
		ha_copy = lpfc_sli_eratt_read(phba);
		break;
	case LPFC_SLI_REV4:
		/* Read devcie Uncoverable Error (UERR) registers */
		/* Read device Uncoverable Error (UERR) registers */
		ha_copy = lpfc_sli4_eratt_read(phba);
		break;
	default:
+33 −17
Original line number Diff line number Diff line
@@ -369,23 +369,39 @@ struct lpfc_sli4_hba {
					     PCI BAR1, control registers */
	void __iomem *drbl_regs_memmap_p; /* Kernel memory mapped address for
					     PCI BAR2, doorbell registers */
	/* BAR0 PCI config space register memory map */
	void __iomem *UERRLOregaddr; /* Address to UERR_STATUS_LO register */
	void __iomem *UERRHIregaddr; /* Address to UERR_STATUS_HI register */
	void __iomem *UEMASKLOregaddr; /* Address to UE_MASK_LO register */
	void __iomem *UEMASKHIregaddr; /* Address to UE_MASK_HI register */
	void __iomem *SLIINTFregaddr; /* Address to SLI_INTF register */
	/* BAR1 FCoE function CSR register memory map */
	void __iomem *STAregaddr;    /* Address to HST_STATE register */
	void __iomem *ISRregaddr;    /* Address to HST_ISR register */
	void __iomem *IMRregaddr;    /* Address to HST_IMR register */
	void __iomem *ISCRregaddr;   /* Address to HST_ISCR register */
	/* BAR2 VF-0 doorbell register memory map */
	void __iomem *RQDBregaddr;   /* Address to RQ_DOORBELL register */
	void __iomem *WQDBregaddr;   /* Address to WQ_DOORBELL register */
	void __iomem *EQCQDBregaddr; /* Address to EQCQ_DOORBELL register */
	void __iomem *MQDBregaddr;   /* Address to MQ_DOORBELL register */
	void __iomem *BMBXregaddr;   /* Address to BootStrap MBX register */
	union {
		struct {
			/* IF Type 0, BAR 0 PCI cfg space reg mem map */
			void __iomem *UERRLOregaddr;
			void __iomem *UERRHIregaddr;
			void __iomem *UEMASKLOregaddr;
			void __iomem *UEMASKHIregaddr;
		} if_type0;
		struct {
			/* IF Type 2, BAR 0 PCI cfg space reg mem map. */
			void __iomem *STATUSregaddr;
			void __iomem *CTRLregaddr;
			void __iomem *ERR1regaddr;
			void __iomem *ERR2regaddr;
		} if_type2;
	} u;

	/* IF type 0, BAR1 and if type 2, Bar 0 CSR register memory map */
	void __iomem *PSMPHRregaddr;

	/* Well-known SLI INTF register memory map. */
	void __iomem *SLIINTFregaddr;

	/* IF type 0, BAR 1 function CSR register memory map */
	void __iomem *ISRregaddr;	/* HST_ISR register */
	void __iomem *IMRregaddr;	/* HST_IMR register */
	void __iomem *ISCRregaddr;	/* HST_ISCR register */
	/* IF type 0, BAR 0 and if type 2, BAR 0 doorbell register memory map */
	void __iomem *RQDBregaddr;	/* RQ_DOORBELL register */
	void __iomem *WQDBregaddr;	/* WQ_DOORBELL register */
	void __iomem *EQCQDBregaddr;	/* EQCQ_DOORBELL register */
	void __iomem *MQDBregaddr;	/* MQ_DOORBELL register */
	void __iomem *BMBXregaddr;	/* BootStrap MBX register */

	uint32_t ue_mask_lo;
	uint32_t ue_mask_hi;