[SCSI] qla2xxx: Add ISP81XX support.

Codes to support new FCoE boards.

Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 628d79c..303f8ee 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -425,27 +425,27 @@
 #define OPTROM_BURST_DWORDS	(OPTROM_BURST_SIZE / 4)
 
 static inline uint32_t
-flash_conf_to_access_addr(uint32_t faddr)
+flash_conf_addr(struct qla_hw_data *ha, uint32_t faddr)
 {
-	return FARX_ACCESS_FLASH_CONF | faddr;
+	return ha->flash_conf_off | faddr;
 }
 
 static inline uint32_t
-flash_data_to_access_addr(uint32_t faddr)
+flash_data_addr(struct qla_hw_data *ha, uint32_t faddr)
 {
-	return FARX_ACCESS_FLASH_DATA | faddr;
+	return ha->flash_data_off | faddr;
 }
 
 static inline uint32_t
-nvram_conf_to_access_addr(uint32_t naddr)
+nvram_conf_addr(struct qla_hw_data *ha, uint32_t naddr)
 {
-	return FARX_ACCESS_NVRAM_CONF | naddr;
+	return ha->nvram_conf_off | naddr;
 }
 
 static inline uint32_t
-nvram_data_to_access_addr(uint32_t naddr)
+nvram_data_addr(struct qla_hw_data *ha, uint32_t naddr)
 {
-	return FARX_ACCESS_NVRAM_DATA | naddr;
+	return ha->nvram_data_off | naddr;
 }
 
 static uint32_t
@@ -481,10 +481,12 @@
     uint32_t dwords)
 {
 	uint32_t i;
+	struct qla_hw_data *ha = vha->hw;
+
 	/* Dword reads to flash. */
 	for (i = 0; i < dwords; i++, faddr++)
-		dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(vha->hw,
-		    flash_data_to_access_addr(faddr)));
+		dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
+		    flash_data_addr(ha, faddr)));
 
 	return dwptr;
 }
@@ -518,7 +520,7 @@
 {
 	uint32_t ids;
 
-	ids = qla24xx_read_flash_dword(ha, flash_data_to_access_addr(0xd03ab));
+	ids = qla24xx_read_flash_dword(ha, flash_conf_addr(ha, 0x03ab));
 	*man_id = LSB(ids);
 	*flash_id = MSB(ids);
 
@@ -530,8 +532,7 @@
 		 * Example: ATMEL 0x00 01 45 1F
 		 * Extract MFG and Dev ID from last two bytes.
 		 */
-		ids = qla24xx_read_flash_dword(ha,
-		    flash_data_to_access_addr(0xd009f));
+		ids = qla24xx_read_flash_dword(ha, flash_conf_addr(ha, 0x009f));
 		*man_id = LSB(ids);
 		*flash_id = MSB(ids);
 	}
@@ -555,9 +556,13 @@
 
 	/* Begin with sane defaults. */
 	loc = locations[0];
-	*start = IS_QLA24XX_TYPE(ha) ? FA_FLASH_LAYOUT_ADDR_24:
-	    FA_FLASH_LAYOUT_ADDR;
-
+	*start = 0;
+	if (IS_QLA24XX_TYPE(ha))
+		*start = FA_FLASH_LAYOUT_ADDR_24;
+	else if (IS_QLA25XX(ha))
+		*start = FA_FLASH_LAYOUT_ADDR;
+	else if (IS_QLA81XX(ha))
+		*start = FA_FLASH_LAYOUT_ADDR_81;
 	/* Begin with first PCI expansion ROM header. */
 	buf = (uint8_t *)req->ring;
 	dcode = (uint32_t *)req->ring;
@@ -618,6 +623,22 @@
 qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
 {
 	const char *loc, *locations[] = { "DEF", "FLT" };
+	const uint32_t def_fw[] =
+		{ FA_RISC_CODE_ADDR, FA_RISC_CODE_ADDR, FA_RISC_CODE_ADDR_81 };
+	const uint32_t def_boot[] =
+		{ FA_BOOT_CODE_ADDR, FA_BOOT_CODE_ADDR, FA_BOOT_CODE_ADDR_81 };
+	const uint32_t def_vpd_nvram[] =
+		{ FA_VPD_NVRAM_ADDR, FA_VPD_NVRAM_ADDR, FA_VPD_NVRAM_ADDR_81 };
+	const uint32_t def_fdt[] =
+		{ FA_FLASH_DESCR_ADDR_24, FA_FLASH_DESCR_ADDR,
+			FA_FLASH_DESCR_ADDR_81 };
+	const uint32_t def_npiv_conf0[] =
+		{ FA_NPIV_CONF0_ADDR_24, FA_NPIV_CONF0_ADDR,
+			FA_NPIV_CONF0_ADDR_81 };
+	const uint32_t def_npiv_conf1[] =
+		{ FA_NPIV_CONF1_ADDR_24, FA_NPIV_CONF1_ADDR,
+			FA_NPIV_CONF1_ADDR_81 };
+	uint32_t def;
 	uint16_t *wptr;
 	uint16_t cnt, chksum;
 	uint32_t start;
@@ -677,11 +698,11 @@
 			ha->flt_region_fdt = start;
 			break;
 		case FLT_REG_NPIV_CONF_0:
-			if (!PCI_FUNC(ha->pdev->devfn))
+			if (!(PCI_FUNC(ha->pdev->devfn) & 1))
 				ha->flt_region_npiv_conf = start;
 			break;
 		case FLT_REG_NPIV_CONF_1:
-			if (PCI_FUNC(ha->pdev->devfn))
+			if (PCI_FUNC(ha->pdev->devfn) & 1)
 				ha->flt_region_npiv_conf = start;
 			break;
 		}
@@ -691,14 +712,19 @@
 no_flash_data:
 	/* Use hardcoded defaults. */
 	loc = locations[0];
-	ha->flt_region_fw = FA_RISC_CODE_ADDR;
-	ha->flt_region_boot = FA_BOOT_CODE_ADDR;
-	ha->flt_region_vpd_nvram = FA_VPD_NVRAM_ADDR;
-	ha->flt_region_fdt = IS_QLA24XX_TYPE(ha) ? FA_FLASH_DESCR_ADDR_24:
-	    FA_FLASH_DESCR_ADDR;
-	ha->flt_region_npiv_conf = !PCI_FUNC(ha->pdev->devfn) ?
-	    (IS_QLA24XX_TYPE(ha) ? FA_NPIV_CONF0_ADDR_24: FA_NPIV_CONF0_ADDR):
-	    (IS_QLA24XX_TYPE(ha) ? FA_NPIV_CONF1_ADDR_24: FA_NPIV_CONF1_ADDR);
+	def = 0;
+	if (IS_QLA24XX_TYPE(ha))
+		def = 0;
+	else if (IS_QLA25XX(ha))
+		def = 1;
+	else if (IS_QLA81XX(ha))
+		def = 2;
+	ha->flt_region_fw = def_fw[def];
+	ha->flt_region_boot = def_boot[def];
+	ha->flt_region_vpd_nvram = def_vpd_nvram[def];
+	ha->flt_region_fdt = def_fdt[def];
+	ha->flt_region_npiv_conf = !(PCI_FUNC(ha->pdev->devfn) & 1) ?
+	    def_npiv_conf0[def]: def_npiv_conf1[def];
 done:
 	DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x "
 	    "vpd_nvram=0x%x fdt=0x%x flt=0x%x npiv=0x%x.\n", loc,
@@ -746,14 +772,14 @@
 	mid = le16_to_cpu(fdt->man_id);
 	fid = le16_to_cpu(fdt->id);
 	ha->fdt_wrt_disable = fdt->wrt_disable_bits;
-	ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd);
+	ha->fdt_erase_cmd = flash_conf_addr(ha, 0x0300 | fdt->erase_cmd);
 	ha->fdt_block_size = le32_to_cpu(fdt->block_size);
 	if (fdt->unprotect_sec_cmd) {
-		ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0300 |
+		ha->fdt_unprotect_sec_cmd = flash_conf_addr(ha, 0x0300 |
 		    fdt->unprotect_sec_cmd);
 		ha->fdt_protect_sec_cmd = fdt->protect_sec_cmd ?
-		    flash_conf_to_access_addr(0x0300 | fdt->protect_sec_cmd):
-		    flash_conf_to_access_addr(0x0336);
+		    flash_conf_addr(ha, 0x0300 | fdt->protect_sec_cmd):
+		    flash_conf_addr(ha, 0x0336);
 	}
 	goto done;
 no_flash_data:
@@ -762,7 +788,7 @@
 	mid = man_id;
 	fid = flash_id;
 	ha->fdt_wrt_disable = 0x9c;
-	ha->fdt_erase_cmd = flash_conf_to_access_addr(0x03d8);
+	ha->fdt_erase_cmd = flash_conf_addr(ha, 0x03d8);
 	switch (man_id) {
 	case 0xbf: /* STT flash. */
 		if (flash_id == 0x8e)
@@ -771,16 +797,16 @@
 			ha->fdt_block_size = FLASH_BLK_SIZE_32K;
 
 		if (flash_id == 0x80)
-			ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0352);
+			ha->fdt_erase_cmd = flash_conf_addr(ha, 0x0352);
 		break;
 	case 0x13: /* ST M25P80. */
 		ha->fdt_block_size = FLASH_BLK_SIZE_64K;
 		break;
 	case 0x1f: /* Atmel 26DF081A. */
 		ha->fdt_block_size = FLASH_BLK_SIZE_4K;
-		ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0320);
-		ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0339);
-		ha->fdt_protect_sec_cmd = flash_conf_to_access_addr(0x0336);
+		ha->fdt_erase_cmd = flash_conf_addr(ha, 0x0320);
+		ha->fdt_unprotect_sec_cmd = flash_conf_addr(ha, 0x0339);
+		ha->fdt_protect_sec_cmd = flash_conf_addr(ha, 0x0336);
 		break;
 	default:
 		/* Default to 64 kb sector size. */
@@ -802,7 +828,7 @@
 	uint32_t flt_addr;
 	struct qla_hw_data *ha = vha->hw;
 
-	if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
+	if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && !IS_QLA81XX(ha))
 		return QLA_SUCCESS;
 
 	ret = qla2xxx_find_flt_start(vha, &flt_addr);
@@ -827,7 +853,7 @@
 	struct qla_npiv_entry *entry;
 	struct qla_hw_data *ha = vha->hw;
 
-	if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
+	if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) && !IS_QLA81XX(ha))
 		return;
 
 	ha->isp_ops->read_optrom(vha, (uint8_t *)&hdr,
@@ -919,9 +945,9 @@
 		return;
 
 	/* Disable flash write-protection. */
-	qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0);
+	qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
 	/* Some flash parts need an additional zero-write to clear bits.*/
-	qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0);
+	qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
 }
 
 static void
@@ -934,11 +960,10 @@
 		goto skip_wrt_protect;
 
 	/* Enable flash write-protection and wait for completion. */
-	qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101),
+	qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101),
 	    ha->fdt_wrt_disable);
 	for (cnt = 300; cnt &&
-	    qla24xx_read_flash_dword(ha,
-		    flash_conf_to_access_addr(0x005)) & BIT_0;
+	    qla24xx_read_flash_dword(ha, flash_conf_addr(ha, 0x005)) & BIT_0;
 	    cnt--) {
 		udelay(10);
 	}
@@ -966,7 +991,7 @@
 	ret = QLA_SUCCESS;
 
 	/* Prepare burst-capable write on supported ISPs. */
-	if (IS_QLA25XX(ha) && !(faddr & 0xfff) &&
+	if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && !(faddr & 0xfff) &&
 	    dwords > OPTROM_BURST_DWORDS) {
 		optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE,
 		    &optrom_dma, GFP_KERNEL);
@@ -978,7 +1003,7 @@
 	}
 
 	rest_addr = (ha->fdt_block_size >> 2) - 1;
-	sec_mask = 0x80000 - (ha->fdt_block_size >> 2);
+	sec_mask = (ha->optrom_size >> 2) - (ha->fdt_block_size >> 2);
 
 	qla24xx_unprotect_flash(ha);
 
@@ -1013,13 +1038,13 @@
 				*s = cpu_to_le32(*d);
 
 			ret = qla2x00_load_ram(vha, optrom_dma,
-			    flash_data_to_access_addr(faddr),
+			    flash_data_addr(ha, faddr),
 			    OPTROM_BURST_DWORDS);
 			if (ret != QLA_SUCCESS) {
 				qla_printk(KERN_WARNING, ha,
 				    "Unable to burst-write optrom segment "
 				    "(%x/%x/%llx).\n", ret,
-				    flash_data_to_access_addr(faddr),
+				    flash_data_addr(ha, faddr),
 				    (unsigned long long)optrom_dma);
 				qla_printk(KERN_WARNING, ha,
 				    "Reverting to slow-write.\n");
@@ -1036,7 +1061,7 @@
 		}
 
 		ret = qla24xx_write_flash_dword(ha,
-		    flash_data_to_access_addr(faddr), cpu_to_le32(*dwptr));
+		    flash_data_addr(ha, faddr), cpu_to_le32(*dwptr));
 		if (ret != QLA_SUCCESS) {
 			DEBUG9(printk("%s(%ld) Unable to program flash "
 			    "address=%x data=%x.\n", __func__,
@@ -1087,12 +1112,13 @@
 {
 	uint32_t i;
 	uint32_t *dwptr;
+	struct qla_hw_data *ha = vha->hw;
 
 	/* Dword reads to flash. */
 	dwptr = (uint32_t *)buf;
 	for (i = 0; i < bytes >> 2; i++, naddr++)
-		dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(vha->hw,
-		    nvram_data_to_access_addr(naddr)));
+		dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
+		    nvram_data_addr(ha, naddr)));
 
 	return buf;
 }
@@ -1149,17 +1175,14 @@
 	RD_REG_DWORD(&reg->ctrl_status);	/* PCI Posting. */
 
 	/* Disable NVRAM write-protection. */
-	qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),
-	    0);
-	qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),
-	    0);
+	qla24xx_write_flash_dword(ha, nvram_conf_addr(ha, 0x101), 0);
+	qla24xx_write_flash_dword(ha, nvram_conf_addr(ha, 0x101), 0);
 
 	/* Dword writes to flash. */
 	dwptr = (uint32_t *)buf;
 	for (i = 0; i < bytes >> 2; i++, naddr++, dwptr++) {
 		ret = qla24xx_write_flash_dword(ha,
-		    nvram_data_to_access_addr(naddr),
-		    cpu_to_le32(*dwptr));
+		    nvram_data_addr(ha, naddr), cpu_to_le32(*dwptr));
 		if (ret != QLA_SUCCESS) {
 			DEBUG9(qla_printk("Unable to program nvram address=%x "
 			    "data=%x.\n", naddr, *dwptr));
@@ -1168,8 +1191,7 @@
 	}
 
 	/* Enable NVRAM write-protection. */
-	qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),
-	    0x8c);
+	qla24xx_write_flash_dword(ha, nvram_conf_addr(ha, 0x101), 0x8c);
 
 	/* Disable flash write. */
 	WRT_REG_DWORD(&reg->ctrl_status,
@@ -1191,8 +1213,7 @@
 	dwptr = (uint32_t *)buf;
 	for (i = 0; i < bytes >> 2; i++, naddr++)
 		dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
-		    flash_data_to_access_addr(ha->flt_region_vpd_nvram |
-		    naddr)));
+		    flash_data_addr(ha, ha->flt_region_vpd_nvram | naddr)));
 
 	return buf;
 }
@@ -2235,12 +2256,12 @@
 			burst = left;
 
 		rval = qla2x00_dump_ram(vha, optrom_dma,
-		    flash_data_to_access_addr(faddr), burst);
+		    flash_data_addr(ha, faddr), burst);
 		if (rval) {
 			qla_printk(KERN_WARNING, ha,
 			    "Unable to burst-read optrom segment "
 			    "(%x/%x/%llx).\n", rval,
-			    flash_data_to_access_addr(faddr),
+			    flash_data_addr(ha, faddr),
 			    (unsigned long long)optrom_dma);
 			qla_printk(KERN_WARNING, ha,
 			    "Reverting to slow-read.\n");