aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/isp/isp.c
diff options
context:
space:
mode:
authorJoerg Pulz <Joerg.Pulz@frm2.tum.de>2023-07-07 21:43:34 +0000
committerWarner Losh <imp@FreeBSD.org>2023-07-07 21:45:30 +0000
commit707e4d1b20aa3983f7cd2f444d6ce41eebc02698 (patch)
tree7eb4fff7b6944b026eb324d0be3382f743edbad4 /sys/dev/isp/isp.c
parent27b4a1b7e5b871c248dc501aa359c93f7263b074 (diff)
Diffstat (limited to 'sys/dev/isp/isp.c')
-rw-r--r--sys/dev/isp/isp.c415
1 files changed, 235 insertions, 180 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c
index 14795198a850..87f2b04becdb 100644
--- a/sys/dev/isp/isp.c
+++ b/sys/dev/isp/isp.c
@@ -119,18 +119,16 @@ static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
static void isp_setdfltfcparm(ispsoftc_t *, int);
static int isp_read_nvram(ispsoftc_t *, int);
+static int isp_read_flthdr_2xxx(ispsoftc_t *);
+static void isp_rd_2xxx_flthdr(ispsoftc_t *, uint32_t, uint32_t *);
+static void isp_parse_flthdr_2xxx(ispsoftc_t *, uint8_t *);
+static int isp_read_flt_2xxx(ispsoftc_t *);
+static void isp_rd_2xxx_flt(ispsoftc_t *, uint32_t, uint32_t *);
+static int isp_parse_flt_2xxx(ispsoftc_t *, uint8_t *);
static int isp_read_nvram_2400(ispsoftc_t *);
static void isp_rd_2400_nvram(ispsoftc_t *, uint32_t, uint32_t *);
static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
-static int isp_read_flthdr_28xx(ispsoftc_t *);
-static void isp_rd_28xx_flthdr(ispsoftc_t *, uint32_t, uint32_t *);
-static void isp_parse_flthdr_28xx(ispsoftc_t *, uint8_t *);
-
-static int isp_read_flt_28xx(ispsoftc_t *);
-static void isp_rd_28xx_flt(ispsoftc_t *, uint32_t, uint32_t *);
-static int isp_parse_flt_28xx(ispsoftc_t *, uint8_t *);
-
static void
isp_change_fw_state(ispsoftc_t *isp, int chan, int state)
{
@@ -4342,157 +4340,65 @@ cleanup:
static int
isp_read_nvram(ispsoftc_t *isp, int bus)
{
- if (IS_28XX(isp)) {
- fcparam *fcp = FCPARAM(isp, 0);
- int r = 0;
+ fcparam *fcp = FCPARAM(isp, 0);
+ int r = 0;
- fcp->flash_data_addr = ISP28XX_BASE_ADDR;
+ if (isp->isp_type != ISP_HA_FC_2600) {
+ if (IS_28XX(isp)) {
+ fcp->flash_data_addr = ISP28XX_BASE_ADDR;
+ fcp->flt_region_flt = ISP28XX_FLT_ADDR;
+ } else if (IS_27XX(isp)) {
+ fcp->flash_data_addr = ISP27XX_BASE_ADDR;
+ fcp->flt_region_flt = ISP27XX_FLT_ADDR;
+ } else if (IS_25XX(isp)) {
+ fcp->flash_data_addr = ISP25XX_BASE_ADDR;
+ fcp->flt_region_flt = ISP25XX_FLT_ADDR;
+ } else {
+ fcp->flash_data_addr = ISP24XX_BASE_ADDR;
+ fcp->flt_region_flt = ISP24XX_FLT_ADDR;
+ }
fcp->flt_length = 0;
- r = isp_read_flthdr_28xx(isp);
+ r = isp_read_flthdr_2xxx(isp);
if (r == 0) {
- isp_read_flt_28xx(isp);
- } else {
- fcp->flt_region_nvram =
- (0x300000 + ISP2400_NVRAM_PORT_ADDR(isp->isp_port));
+ isp_read_flt_2xxx(isp);
+ } else { /* fallback to hardcoded NVRAM address */
+ if (IS_28XX(isp)) {
+ fcp->flt_region_nvram = 0x300000;
+ } else if (IS_27XX(isp)) {
+ fcp->flash_data_addr = 0x7fe7c000;
+ fcp->flt_region_nvram = 0;
+ } else if (IS_25XX(isp)) {
+ fcp->flt_region_nvram = 0x48000;
+ } else {
+ fcp->flash_data_addr = 0x7ffe0000;
+ fcp->flt_region_nvram = 0;
+ }
+ fcp->flt_region_nvram += ISP2400_NVRAM_PORT_ADDR(isp->isp_port);
}
+ } else {
+ fcp->flash_data_addr = 0x7fe7c000;
+ fcp->flt_region_nvram = 0;
+ fcp->flt_region_nvram += ISP2400_NVRAM_PORT_ADDR(isp->isp_port);
}
return (isp_read_nvram_2400(isp));
}
static int
-isp_read_nvram_2400(ispsoftc_t *isp)
-{
- fcparam *fcp = FCPARAM(isp, 0);
- int retval = 0;
- uint32_t addr, csum, lwrds, *dptr;
- uint8_t nvram_data[ISP2400_NVRAM_SIZE];
-
- if (IS_28XX(isp)) {
- addr = fcp->flt_region_nvram;
- } else {
- addr = ISP2400_NVRAM_PORT_ADDR(isp->isp_port);
- }
- dptr = (uint32_t *) nvram_data;
- for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
- isp_rd_2400_nvram(isp, addr++, dptr++);
- }
- if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
- nvram_data[2] != 'P') {
- isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
- nvram_data[0], nvram_data[1], nvram_data[2]);
- retval = -1;
- goto out;
- }
- dptr = (uint32_t *) nvram_data;
- for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
- uint32_t tmp;
- ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
- csum += tmp;
- }
- if (csum != 0) {
- isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
- retval = -1;
- goto out;
- }
- isp_parse_nvram_2400(isp, nvram_data);
-out:
- return (retval);
-}
-
-static void
-isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
-{
- int loops = 0;
- uint32_t base = 0x7ffe0000;
- uint32_t tmp = 0;
-
- if (IS_28XX(isp)) {
- fcparam *fcp = FCPARAM(isp, 0);
- base = fcp->flash_data_addr + addr;
- addr = 0;
- } else if (IS_26XX(isp)) {
- base = 0x7fe7c000; /* XXX: Observation, may be wrong. */
- } else if (IS_25XX(isp)) {
- base = 0x7ff00000 | 0x48000;
- }
- ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
- for (loops = 0; loops < 5000; loops++) {
- ISP_DELAY(10);
- tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
- if ((tmp & (1U << 31)) != 0) {
- break;
- }
- }
- if (tmp & (1U << 31)) {
- *rp = ISP_READ(isp, BIU2400_FLASH_DATA);
- ISP_SWIZZLE_NVRAM_LONG(isp, rp);
- } else {
- *rp = 0xffffffff;
- }
-}
-
-static void
-isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
+isp_read_flthdr_2xxx(ispsoftc_t *isp)
{
fcparam *fcp = FCPARAM(isp, 0);
- uint64_t wwn;
-
- isp_prt(isp, ISP_LOGDEBUG0,
- "NVRAM 0x%08x%08x 0x%08x%08x maxframelen %d",
- (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
- (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
- (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
- (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
- ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
- isp_prt(isp, ISP_LOGDEBUG0,
- "NVRAM loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
- ISP2400_NVRAM_HARDLOOPID(nvram_data),
- ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
- ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
- ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
-
- wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
- fcp->isp_wwpn_nvram = wwn;
-
- wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
- if (wwn) {
- if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
- wwn = 0;
- }
- }
- if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) {
- wwn = fcp->isp_wwpn_nvram;
- wwn &= ~((uint64_t) 0xfff << 48);
- }
- fcp->isp_wwnn_nvram = wwn;
-
- if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
- DEFAULT_FRAMESIZE(isp) =
- ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
- }
- if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
- fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
- }
- fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
- fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
- fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
-}
-
-static int
-isp_read_flthdr_28xx(ispsoftc_t *isp)
-{
int retval = 0;
uint32_t addr, lwrds, *dptr;
uint16_t csum;
uint8_t flthdr_data[FLT_HEADER_SIZE];
- addr = ISP28XX_FLT_ADDR;
+ addr = fcp->flt_region_flt;
dptr = (uint32_t *) flthdr_data;
isp_prt(isp, ISP_LOGDEBUG0,
- "FLTL[DEF]: 0x%x", ISP28XX_FLT_ADDR);
+ "FLTL[DEF]: 0x%x", addr);
for (lwrds = 0; lwrds < FLT_HEADER_SIZE >> 2; lwrds++) {
- isp_rd_28xx_flthdr(isp, addr++, dptr++);
+ isp_rd_2xxx_flthdr(isp, addr++, dptr++);
}
dptr = (uint32_t *) flthdr_data;
for (csum = 0, lwrds = 0; lwrds < FLT_HEADER_SIZE >> 4; lwrds++) {
@@ -4504,13 +4410,13 @@ isp_read_flthdr_28xx(ispsoftc_t *isp)
retval = -1;
goto out;
}
- isp_parse_flthdr_28xx(isp, flthdr_data);
+ isp_parse_flthdr_2xxx(isp, flthdr_data);
out:
return (retval);
}
static void
-isp_rd_28xx_flthdr(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
+isp_rd_2xxx_flthdr(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
{
fcparam *fcp = FCPARAM(isp, 0);
int loops = 0;
@@ -4534,28 +4440,28 @@ isp_rd_28xx_flthdr(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
}
static void
-isp_parse_flthdr_28xx(ispsoftc_t *isp, uint8_t *flthdr_data)
+isp_parse_flthdr_2xxx(ispsoftc_t *isp, uint8_t *flthdr_data)
{
fcparam *fcp = FCPARAM(isp, 0);
uint16_t ver, csum;
- ver = le16toh((uint16_t) (ISP28XX_FLT_VERSION(flthdr_data)));
- fcp->flt_length = le16toh((uint16_t) (ISP28XX_FLT_LENGTH(flthdr_data)));
- csum = le16toh((uint16_t) (ISP28XX_FLT_CSUM(flthdr_data)));
+ ver = le16toh((uint16_t) (ISP2XXX_FLT_VERSION(flthdr_data)));
+ fcp->flt_length = le16toh((uint16_t) (ISP2XXX_FLT_LENGTH(flthdr_data)));
+ csum = le16toh((uint16_t) (ISP2XXX_FLT_CSUM(flthdr_data)));
if ((fcp->flt_length == 0 ) ||
(fcp->flt_length > (FLT_HEADER_SIZE + FLT_REGIONS_SIZE))) {
- isp_prt(isp, ISP_LOGWARN,
+ isp_prt(isp, ISP_LOGERR,
"FLT[DEF]: Invalid length=0x%x(%d)",
fcp->flt_length, fcp->flt_length);
}
- isp_prt(isp, ISP_LOGDEBUG0,
+ isp_prt(isp, ISP_LOGCONFIG,
"FLT[DEF]: version=0x%x length=0x%x(%d) checksum=0x%x",
ver, fcp->flt_length, fcp->flt_length, csum);
}
static int
-isp_read_flt_28xx(ispsoftc_t *isp)
+isp_read_flt_2xxx(ispsoftc_t *isp)
{
fcparam *fcp = FCPARAM(isp, 0);
int retval = 0;
@@ -4564,19 +4470,19 @@ isp_read_flt_28xx(ispsoftc_t *isp)
uint8_t flt_data[len];
fcp->flt_region_entries = len / FLT_REGION_SIZE;
- addr = ISP28XX_FLT_ADDR + (FLT_HEADER_SIZE >> 2);
+ addr = fcp->flt_region_flt + (FLT_HEADER_SIZE >> 2);
dptr = (uint32_t *) flt_data;
- isp_prt(isp, ISP_LOGDEBUG0, "FLT[DEF]: regions=%d",
+ isp_prt(isp, ISP_LOGCONFIG, "FLT[DEF]: regions=%d",
fcp->flt_region_entries);
for (lwrds = 0; lwrds < len >> 2; lwrds++) {
- isp_rd_28xx_flt(isp, addr++, dptr++);
+ isp_rd_2xxx_flt(isp, addr++, dptr++);
}
- retval = isp_parse_flt_28xx(isp, flt_data);
+ retval = isp_parse_flt_2xxx(isp, flt_data);
return (retval);
}
static void
-isp_rd_28xx_flt(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
+isp_rd_2xxx_flt(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
{
fcparam *fcp = FCPARAM(isp, 0);
int loops = 0;
@@ -4600,7 +4506,7 @@ isp_rd_28xx_flt(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
}
static int
-isp_parse_flt_28xx(ispsoftc_t *isp, uint8_t *flt_data)
+isp_parse_flt_2xxx(ispsoftc_t *isp, uint8_t *flt_data)
{
fcparam *fcp = FCPARAM(isp, 0);
int count;
@@ -4608,17 +4514,17 @@ isp_parse_flt_28xx(ispsoftc_t *isp, uint8_t *flt_data)
for (count = 0; count < fcp->flt_region_entries; count++) {
region[count].code =
- le16toh((uint16_t) (ISP28XX_FLT_REG_CODE(flt_data, count)));
+ le16toh((uint16_t) (ISP2XXX_FLT_REG_CODE(flt_data, count)));
region[count].attribute =
- (uint8_t) (ISP28XX_FLT_REG_ATTR(flt_data, count));
+ (uint8_t) (ISP2XXX_FLT_REG_ATTR(flt_data, count));
region[count].reserved =
- (uint8_t) (ISP28XX_FLT_REG_RES(flt_data, count));
+ (uint8_t) (ISP2XXX_FLT_REG_RES(flt_data, count));
region[count].size =
- le32toh((uint32_t) (ISP28XX_FLT_REG_SIZE(flt_data, count)) >> 2);
+ le32toh((uint32_t) (ISP2XXX_FLT_REG_SIZE(flt_data, count)) >> 2);
region[count].start =
- le32toh((uint32_t) (ISP28XX_FLT_REG_START(flt_data, count)) >> 2);
+ le32toh((uint32_t) (ISP2XXX_FLT_REG_START(flt_data, count)) >> 2);
region[count].end =
- le32toh((uint32_t) (ISP28XX_FLT_REG_END(flt_data, count)) >> 2);
+ le32toh((uint32_t) (ISP2XXX_FLT_REG_END(flt_data, count)) >> 2);
isp_prt(isp, ISP_LOGDEBUG0,
"FLT[0x%x]: start=0x%x end=0x%x size=0x%x attribute=0x%x",
@@ -4642,10 +4548,14 @@ isp_parse_flt_28xx(ispsoftc_t *isp, uint8_t *flt_data)
fcp->flt_region_vpd = region[count].start;
break;
case FLT_REG_VPD_2:
+ if (!IS_27XX(isp))
+ break;
if (isp->isp_port == 2)
fcp->flt_region_vpd = region[count].start;
break;
case FLT_REG_VPD_3:
+ if (!IS_27XX(isp))
+ break;
if (isp->isp_port == 3)
fcp->flt_region_vpd = region[count].start;
break;
@@ -4658,10 +4568,14 @@ isp_parse_flt_28xx(ispsoftc_t *isp, uint8_t *flt_data)
fcp->flt_region_nvram = region[count].start;
break;
case FLT_REG_NVRAM_2:
+ if (!IS_27XX(isp))
+ break;
if (isp->isp_port == 2)
fcp->flt_region_nvram = region[count].start;
break;
case FLT_REG_NVRAM_3:
+ if (!IS_27XX(isp))
+ break;
if (isp->isp_port == 3)
fcp->flt_region_nvram = region[count].start;
break;
@@ -4690,48 +4604,79 @@ isp_parse_flt_28xx(ispsoftc_t *isp, uint8_t *flt_data)
if (isp->isp_port == 1)
fcp->flt_region_fcp_prio = region[count].start;
break;
+ case FLT_REG_IMG_PRI_27XX:
+ if (IS_27XX(isp))
+ fcp->flt_region_img_status_pri = region[count].start;
+ break;
+ case FLT_REG_IMG_SEC_27XX:
+ if (IS_27XX(isp))
+ fcp->flt_region_img_status_sec = region[count].start;
+ break;
+ case FLT_REG_FW_SEC_27XX:
+ if (IS_27XX(isp))
+ fcp->flt_region_fw_sec = region[count].start;
+ break;
+ case FLT_REG_BOOTLOAD_SEC_27XX:
+ if (IS_27XX(isp))
+ fcp->flt_region_boot_sec = region[count].start;
+ break;
case FLT_REG_AUX_IMG_PRI_28XX:
- fcp->flt_region_aux_img_status_pri = region[count].start;
+ if (IS_27XX(isp))
+ fcp->flt_region_aux_img_status_pri = region[count].start;
break;
case FLT_REG_AUX_IMG_SEC_28XX:
- fcp->flt_region_aux_img_status_sec = region[count].start;
+ if (IS_27XX(isp))
+ fcp->flt_region_aux_img_status_sec = region[count].start;
break;
case FLT_REG_NVRAM_SEC_28XX_0:
- if (isp->isp_port == 0)
- fcp->flt_region_nvram_sec = region[count].start;
+ if (IS_27XX(isp))
+ if (isp->isp_port == 0)
+ fcp->flt_region_nvram_sec = region[count].start;
break;
case FLT_REG_NVRAM_SEC_28XX_1:
- if (isp->isp_port == 1)
- fcp->flt_region_nvram_sec = region[count].start;
+ if (IS_27XX(isp))
+ if (isp->isp_port == 1)
+ fcp->flt_region_nvram_sec = region[count].start;
break;
case FLT_REG_NVRAM_SEC_28XX_2:
- if (isp->isp_port == 2)
- fcp->flt_region_nvram_sec = region[count].start;
+ if (IS_27XX(isp))
+ if (isp->isp_port == 2)
+ fcp->flt_region_nvram_sec = region[count].start;
break;
case FLT_REG_NVRAM_SEC_28XX_3:
- if (isp->isp_port == 3)
- fcp->flt_region_nvram_sec = region[count].start;
+ if (IS_27XX(isp))
+ if (isp->isp_port == 3)
+ fcp->flt_region_nvram_sec = region[count].start;
break;
+ case FLT_REG_VPD_SEC_27XX_0:
case FLT_REG_VPD_SEC_28XX_0:
- fcp->flt_region_vpd_nvram_sec = region[count].start;
- if (isp->isp_port == 0)
- fcp->flt_region_vpd_sec = region[count].start;
+ if (IS_27XX(isp)) {
+ fcp->flt_region_vpd_nvram_sec = region[count].start;
+ if (isp->isp_port == 0)
+ fcp->flt_region_vpd_sec = region[count].start;
+ }
break;
+ case FLT_REG_VPD_SEC_27XX_1:
case FLT_REG_VPD_SEC_28XX_1:
- if (isp->isp_port == 1)
- fcp->flt_region_vpd_sec = region[count].start;
+ if (IS_27XX(isp))
+ if (isp->isp_port == 1)
+ fcp->flt_region_vpd_sec = region[count].start;
break;
+ case FLT_REG_VPD_SEC_27XX_2:
case FLT_REG_VPD_SEC_28XX_2:
- if (isp->isp_port == 2)
- fcp->flt_region_vpd_sec = region[count].start;
+ if (IS_27XX(isp))
+ if (isp->isp_port == 2)
+ fcp->flt_region_vpd_sec = region[count].start;
break;
+ case FLT_REG_VPD_SEC_27XX_3:
case FLT_REG_VPD_SEC_28XX_3:
- if (isp->isp_port == 3)
- fcp->flt_region_vpd_sec = region[count].start;
+ if (IS_27XX(isp))
+ if (isp->isp_port == 3)
+ fcp->flt_region_vpd_sec = region[count].start;
break;
}
}
- isp_prt(isp, ISP_LOGDEBUG0,
+ isp_prt(isp, ISP_LOGCONFIG,
"FLT[FLT]: boot=0x%x fw=0x%x vpd_nvram=0x%x vpd=0x%x nvram 0x%x "
"fdt=0x%x flt=0x%x npiv=0x%x fcp_prif_cfg=0x%x",
fcp->flt_region_boot, fcp->flt_region_fw, fcp->flt_region_vpd_nvram,
@@ -4741,3 +4686,113 @@ isp_parse_flt_28xx(ispsoftc_t *isp, uint8_t *flt_data)
return (0);
}
+
+static int
+isp_read_nvram_2400(ispsoftc_t *isp)
+{
+ fcparam *fcp = FCPARAM(isp, 0);
+ int retval = 0;
+ uint32_t addr, csum, lwrds, *dptr;
+ uint8_t nvram_data[ISP2400_NVRAM_SIZE];
+
+ addr = fcp->flt_region_nvram;
+ dptr = (uint32_t *) nvram_data;
+ for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
+ isp_rd_2400_nvram(isp, addr++, dptr++);
+ }
+ if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
+ nvram_data[2] != 'P') {
+ isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
+ nvram_data[0], nvram_data[1], nvram_data[2]);
+ retval = -1;
+ goto out;
+ }
+ dptr = (uint32_t *) nvram_data;
+ for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
+ uint32_t tmp;
+ ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
+ csum += tmp;
+ }
+ if (csum != 0) {
+ isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
+ retval = -1;
+ goto out;
+ }
+ isp_parse_nvram_2400(isp, nvram_data);
+out:
+ return (retval);
+}
+
+static void
+isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
+{
+ fcparam *fcp = FCPARAM(isp, 0);
+ int loops = 0;
+ uint32_t base; // = 0x7ffe0000;
+ uint32_t tmp = 0;
+
+ base = fcp->flash_data_addr + addr;
+ addr = 0;
+
+ ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
+ for (loops = 0; loops < 5000; loops++) {
+ ISP_DELAY(10);
+ tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
+ if ((tmp & (1U << 31)) != 0) {
+ break;
+ }
+ }
+ if (tmp & (1U << 31)) {
+ *rp = ISP_READ(isp, BIU2400_FLASH_DATA);
+ ISP_SWIZZLE_NVRAM_LONG(isp, rp);
+ } else {
+ *rp = 0xffffffff;
+ }
+}
+
+static void
+isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
+{
+ fcparam *fcp = FCPARAM(isp, 0);
+ uint64_t wwn;
+
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "NVRAM 0x%08x%08x 0x%08x%08x maxframelen %d",
+ (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
+ (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
+ (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
+ (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
+ ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "NVRAM loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
+ ISP2400_NVRAM_HARDLOOPID(nvram_data),
+ ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
+ ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
+ ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
+
+ wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
+ fcp->isp_wwpn_nvram = wwn;
+
+ wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
+ if (wwn) {
+ if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
+ wwn = 0;
+ }
+ }
+ if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) {
+ wwn = fcp->isp_wwpn_nvram;
+ wwn &= ~((uint64_t) 0xfff << 48);
+ }
+ fcp->isp_wwnn_nvram = wwn;
+
+ if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
+ DEFAULT_FRAMESIZE(isp) =
+ ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
+ }
+ if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
+ fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
+ }
+ fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
+ fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
+ fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
+}