aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/bfa/bfa_defs.h1
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c727
-rw-r--r--drivers/scsi/bfa/bfa_ioc.h7
-rw-r--r--drivers/scsi/bfa/bfa_ioc_cb.c23
-rw-r--r--drivers/scsi/bfa/bfad_bsg.c15
-rw-r--r--drivers/scsi/bfa/bfad_bsg.h1
-rw-r--r--drivers/scsi/bfa/bfi.h39
7 files changed, 767 insertions, 46 deletions
diff --git a/drivers/scsi/bfa/bfa_defs.h b/drivers/scsi/bfa/bfa_defs.h
index d40a79f5265f..877b86dd2837 100644
--- a/drivers/scsi/bfa/bfa_defs.h
+++ b/drivers/scsi/bfa/bfa_defs.h
@@ -132,6 +132,7 @@ enum bfa_status {
132 BFA_STATUS_ETIMER = 5, /* Timer expired - Retry, if persists, 132 BFA_STATUS_ETIMER = 5, /* Timer expired - Retry, if persists,
133 * contact support */ 133 * contact support */
134 BFA_STATUS_EPROTOCOL = 6, /* Protocol error */ 134 BFA_STATUS_EPROTOCOL = 6, /* Protocol error */
135 BFA_STATUS_BADFLASH = 9, /* Flash is bad */
135 BFA_STATUS_SFP_UNSUPP = 10, /* Unsupported SFP - Replace SFP */ 136 BFA_STATUS_SFP_UNSUPP = 10, /* Unsupported SFP - Replace SFP */
136 BFA_STATUS_UNKNOWN_VFID = 11, /* VF_ID not found */ 137 BFA_STATUS_UNKNOWN_VFID = 11, /* VF_ID not found */
137 BFA_STATUS_DATACORRUPTED = 12, /* Diag returned data corrupted */ 138 BFA_STATUS_DATACORRUPTED = 12, /* Diag returned data corrupted */
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index f78bcb6696b2..65180e15de6e 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -21,6 +21,7 @@
21#include "bfi_reg.h" 21#include "bfi_reg.h"
22#include "bfa_defs.h" 22#include "bfa_defs.h"
23#include "bfa_defs_svc.h" 23#include "bfa_defs_svc.h"
24#include "bfi.h"
24 25
25BFA_TRC_FILE(CNA, IOC); 26BFA_TRC_FILE(CNA, IOC);
26 27
@@ -45,6 +46,14 @@ BFA_TRC_FILE(CNA, IOC);
45 46
46#define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn)) 47#define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
47 48
49#define bfa_ioc_state_disabled(__sm) \
50 (((__sm) == BFI_IOC_UNINIT) || \
51 ((__sm) == BFI_IOC_INITING) || \
52 ((__sm) == BFI_IOC_HWINIT) || \
53 ((__sm) == BFI_IOC_DISABLED) || \
54 ((__sm) == BFI_IOC_FAIL) || \
55 ((__sm) == BFI_IOC_CFG_DISABLED))
56
48/* 57/*
49 * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details. 58 * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details.
50 */ 59 */
@@ -102,6 +111,12 @@ static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
102static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc); 111static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
103static void bfa_ioc_fail_notify(struct bfa_ioc_s *ioc); 112static void bfa_ioc_fail_notify(struct bfa_ioc_s *ioc);
104static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc); 113static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc);
114static enum bfi_ioc_img_ver_cmp_e bfa_ioc_fw_ver_patch_cmp(
115 struct bfi_ioc_image_hdr_s *base_fwhdr,
116 struct bfi_ioc_image_hdr_s *fwhdr_to_cmp);
117static enum bfi_ioc_img_ver_cmp_e bfa_ioc_flash_fwver_cmp(
118 struct bfa_ioc_s *ioc,
119 struct bfi_ioc_image_hdr_s *base_fwhdr);
105 120
106/* 121/*
107 * IOC state machine definitions/declarations 122 * IOC state machine definitions/declarations
@@ -1454,28 +1469,42 @@ bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
1454} 1469}
1455 1470
1456/* 1471/*
1457 * Returns TRUE if same. 1472 * Returns TRUE if driver is willing to work with current smem f/w version.
1458 */ 1473 */
1459bfa_boolean_t 1474bfa_boolean_t
1460bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) 1475bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc,
1476 struct bfi_ioc_image_hdr_s *smem_fwhdr)
1461{ 1477{
1462 struct bfi_ioc_image_hdr_s *drv_fwhdr; 1478 struct bfi_ioc_image_hdr_s *drv_fwhdr;
1463 int i; 1479 enum bfi_ioc_img_ver_cmp_e smem_flash_cmp, drv_smem_cmp;
1464 1480
1465 drv_fwhdr = (struct bfi_ioc_image_hdr_s *) 1481 drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
1466 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0); 1482 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
1467 1483
1468 for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) { 1484 /*
1469 if (fwhdr->md5sum[i] != cpu_to_le32(drv_fwhdr->md5sum[i])) { 1485 * If smem is incompatible or old, driver should not work with it.
1470 bfa_trc(ioc, i); 1486 */
1471 bfa_trc(ioc, fwhdr->md5sum[i]); 1487 drv_smem_cmp = bfa_ioc_fw_ver_patch_cmp(drv_fwhdr, smem_fwhdr);
1472 bfa_trc(ioc, drv_fwhdr->md5sum[i]); 1488 if (drv_smem_cmp == BFI_IOC_IMG_VER_INCOMP ||
1473 return BFA_FALSE; 1489 drv_smem_cmp == BFI_IOC_IMG_VER_OLD) {
1474 } 1490 return BFA_FALSE;
1475 } 1491 }
1476 1492
1477 bfa_trc(ioc, fwhdr->md5sum[0]); 1493 /*
1478 return BFA_TRUE; 1494 * IF Flash has a better F/W than smem do not work with smem.
1495 * If smem f/w == flash f/w, as smem f/w not old | incmp, work with it.
1496 * If Flash is old or incomp work with smem iff smem f/w == drv f/w.
1497 */
1498 smem_flash_cmp = bfa_ioc_flash_fwver_cmp(ioc, smem_fwhdr);
1499
1500 if (smem_flash_cmp == BFI_IOC_IMG_VER_BETTER) {
1501 return BFA_FALSE;
1502 } else if (smem_flash_cmp == BFI_IOC_IMG_VER_SAME) {
1503 return BFA_TRUE;
1504 } else {
1505 return (drv_smem_cmp == BFI_IOC_IMG_VER_SAME) ?
1506 BFA_TRUE : BFA_FALSE;
1507 }
1479} 1508}
1480 1509
1481/* 1510/*
@@ -1485,17 +1514,9 @@ bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
1485static bfa_boolean_t 1514static bfa_boolean_t
1486bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env) 1515bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env)
1487{ 1516{
1488 struct bfi_ioc_image_hdr_s fwhdr, *drv_fwhdr; 1517 struct bfi_ioc_image_hdr_s fwhdr;
1489 1518
1490 bfa_ioc_fwver_get(ioc, &fwhdr); 1519 bfa_ioc_fwver_get(ioc, &fwhdr);
1491 drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
1492 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
1493
1494 if (fwhdr.signature != cpu_to_le32(drv_fwhdr->signature)) {
1495 bfa_trc(ioc, fwhdr.signature);
1496 bfa_trc(ioc, drv_fwhdr->signature);
1497 return BFA_FALSE;
1498 }
1499 1520
1500 if (swab32(fwhdr.bootenv) != boot_env) { 1521 if (swab32(fwhdr.bootenv) != boot_env) {
1501 bfa_trc(ioc, fwhdr.bootenv); 1522 bfa_trc(ioc, fwhdr.bootenv);
@@ -1506,6 +1527,168 @@ bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc, u32 boot_env)
1506 return bfa_ioc_fwver_cmp(ioc, &fwhdr); 1527 return bfa_ioc_fwver_cmp(ioc, &fwhdr);
1507} 1528}
1508 1529
1530static bfa_boolean_t
1531bfa_ioc_fwver_md5_check(struct bfi_ioc_image_hdr_s *fwhdr_1,
1532 struct bfi_ioc_image_hdr_s *fwhdr_2)
1533{
1534 int i;
1535
1536 for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++)
1537 if (fwhdr_1->md5sum[i] != fwhdr_2->md5sum[i])
1538 return BFA_FALSE;
1539
1540 return BFA_TRUE;
1541}
1542
1543/*
1544 * Returns TRUE if major minor and maintainence are same.
1545 * If patch versions are same, check for MD5 Checksum to be same.
1546 */
1547static bfa_boolean_t
1548bfa_ioc_fw_ver_compatible(struct bfi_ioc_image_hdr_s *drv_fwhdr,
1549 struct bfi_ioc_image_hdr_s *fwhdr_to_cmp)
1550{
1551 if (drv_fwhdr->signature != fwhdr_to_cmp->signature)
1552 return BFA_FALSE;
1553
1554 if (drv_fwhdr->fwver.major != fwhdr_to_cmp->fwver.major)
1555 return BFA_FALSE;
1556
1557 if (drv_fwhdr->fwver.minor != fwhdr_to_cmp->fwver.minor)
1558 return BFA_FALSE;
1559
1560 if (drv_fwhdr->fwver.maint != fwhdr_to_cmp->fwver.maint)
1561 return BFA_FALSE;
1562
1563 if (drv_fwhdr->fwver.patch == fwhdr_to_cmp->fwver.patch &&
1564 drv_fwhdr->fwver.phase == fwhdr_to_cmp->fwver.phase &&
1565 drv_fwhdr->fwver.build == fwhdr_to_cmp->fwver.build) {
1566 return bfa_ioc_fwver_md5_check(drv_fwhdr, fwhdr_to_cmp);
1567 }
1568
1569 return BFA_TRUE;
1570}
1571
1572static bfa_boolean_t
1573bfa_ioc_flash_fwver_valid(struct bfi_ioc_image_hdr_s *flash_fwhdr)
1574{
1575 if (flash_fwhdr->fwver.major == 0 || flash_fwhdr->fwver.major == 0xFF)
1576 return BFA_FALSE;
1577
1578 return BFA_TRUE;
1579}
1580
1581static bfa_boolean_t fwhdr_is_ga(struct bfi_ioc_image_hdr_s *fwhdr)
1582{
1583 if (fwhdr->fwver.phase == 0 &&
1584 fwhdr->fwver.build == 0)
1585 return BFA_TRUE;
1586
1587 return BFA_FALSE;
1588}
1589
1590/*
1591 * Returns TRUE if both are compatible and patch of fwhdr_to_cmp is better.
1592 */
1593static enum bfi_ioc_img_ver_cmp_e
1594bfa_ioc_fw_ver_patch_cmp(struct bfi_ioc_image_hdr_s *base_fwhdr,
1595 struct bfi_ioc_image_hdr_s *fwhdr_to_cmp)
1596{
1597 if (bfa_ioc_fw_ver_compatible(base_fwhdr, fwhdr_to_cmp) == BFA_FALSE)
1598 return BFI_IOC_IMG_VER_INCOMP;
1599
1600 if (fwhdr_to_cmp->fwver.patch > base_fwhdr->fwver.patch)
1601 return BFI_IOC_IMG_VER_BETTER;
1602
1603 else if (fwhdr_to_cmp->fwver.patch < base_fwhdr->fwver.patch)
1604 return BFI_IOC_IMG_VER_OLD;
1605
1606 /*
1607 * GA takes priority over internal builds of the same patch stream.
1608 * At this point major minor maint and patch numbers are same.
1609 */
1610
1611 if (fwhdr_is_ga(base_fwhdr) == BFA_TRUE) {
1612 if (fwhdr_is_ga(fwhdr_to_cmp))
1613 return BFI_IOC_IMG_VER_SAME;
1614 else
1615 return BFI_IOC_IMG_VER_OLD;
1616 } else {
1617 if (fwhdr_is_ga(fwhdr_to_cmp))
1618 return BFI_IOC_IMG_VER_BETTER;
1619 }
1620
1621 if (fwhdr_to_cmp->fwver.phase > base_fwhdr->fwver.phase)
1622 return BFI_IOC_IMG_VER_BETTER;
1623 else if (fwhdr_to_cmp->fwver.phase < base_fwhdr->fwver.phase)
1624 return BFI_IOC_IMG_VER_OLD;
1625
1626 if (fwhdr_to_cmp->fwver.build > base_fwhdr->fwver.build)
1627 return BFI_IOC_IMG_VER_BETTER;
1628 else if (fwhdr_to_cmp->fwver.build < base_fwhdr->fwver.build)
1629 return BFI_IOC_IMG_VER_OLD;
1630
1631 /*
1632 * All Version Numbers are equal.
1633 * Md5 check to be done as a part of compatibility check.
1634 */
1635 return BFI_IOC_IMG_VER_SAME;
1636}
1637
1638#define BFA_FLASH_PART_FWIMG_ADDR 0x100000 /* fw image address */
1639
1640bfa_status_t
1641bfa_ioc_flash_img_get_chnk(struct bfa_ioc_s *ioc, u32 off,
1642 u32 *fwimg)
1643{
1644 return bfa_flash_raw_read(ioc->pcidev.pci_bar_kva,
1645 BFA_FLASH_PART_FWIMG_ADDR + (off * sizeof(u32)),
1646 (char *)fwimg, BFI_FLASH_CHUNK_SZ);
1647}
1648
1649static enum bfi_ioc_img_ver_cmp_e
1650bfa_ioc_flash_fwver_cmp(struct bfa_ioc_s *ioc,
1651 struct bfi_ioc_image_hdr_s *base_fwhdr)
1652{
1653 struct bfi_ioc_image_hdr_s *flash_fwhdr;
1654 bfa_status_t status;
1655 u32 fwimg[BFI_FLASH_CHUNK_SZ_WORDS];
1656
1657 status = bfa_ioc_flash_img_get_chnk(ioc, 0, fwimg);
1658 if (status != BFA_STATUS_OK)
1659 return BFI_IOC_IMG_VER_INCOMP;
1660
1661 flash_fwhdr = (struct bfi_ioc_image_hdr_s *) fwimg;
1662 if (bfa_ioc_flash_fwver_valid(flash_fwhdr) == BFA_TRUE)
1663 return bfa_ioc_fw_ver_patch_cmp(base_fwhdr, flash_fwhdr);
1664 else
1665 return BFI_IOC_IMG_VER_INCOMP;
1666}
1667
1668
1669/*
1670 * Invalidate fwver signature
1671 */
1672bfa_status_t
1673bfa_ioc_fwsig_invalidate(struct bfa_ioc_s *ioc)
1674{
1675
1676 u32 pgnum, pgoff;
1677 u32 loff = 0;
1678 enum bfi_ioc_state ioc_fwstate;
1679
1680 ioc_fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc);
1681 if (!bfa_ioc_state_disabled(ioc_fwstate))
1682 return BFA_STATUS_ADAPTER_ENABLED;
1683
1684 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
1685 pgoff = PSS_SMEM_PGOFF(loff);
1686 writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1687 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, BFA_IOC_FW_INV_SIGN);
1688
1689 return BFA_STATUS_OK;
1690}
1691
1509/* 1692/*
1510 * Conditionally flush any pending message from firmware at start. 1693 * Conditionally flush any pending message from firmware at start.
1511 */ 1694 */
@@ -1544,8 +1727,8 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
1544 BFA_FALSE : bfa_ioc_fwver_valid(ioc, boot_env); 1727 BFA_FALSE : bfa_ioc_fwver_valid(ioc, boot_env);
1545 1728
1546 if (!fwvalid) { 1729 if (!fwvalid) {
1547 bfa_ioc_boot(ioc, boot_type, boot_env); 1730 if (bfa_ioc_boot(ioc, boot_type, boot_env) == BFA_STATUS_OK)
1548 bfa_ioc_poll_fwinit(ioc); 1731 bfa_ioc_poll_fwinit(ioc);
1549 return; 1732 return;
1550 } 1733 }
1551 1734
@@ -1580,8 +1763,8 @@ bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
1580 /* 1763 /*
1581 * Initialize the h/w for any other states. 1764 * Initialize the h/w for any other states.
1582 */ 1765 */
1583 bfa_ioc_boot(ioc, boot_type, boot_env); 1766 if (bfa_ioc_boot(ioc, boot_type, boot_env) == BFA_STATUS_OK)
1584 bfa_ioc_poll_fwinit(ioc); 1767 bfa_ioc_poll_fwinit(ioc);
1585} 1768}
1586 1769
1587static void 1770static void
@@ -1684,7 +1867,7 @@ bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
1684/* 1867/*
1685 * Initiate a full firmware download. 1868 * Initiate a full firmware download.
1686 */ 1869 */
1687static void 1870static bfa_status_t
1688bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type, 1871bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1689 u32 boot_env) 1872 u32 boot_env)
1690{ 1873{
@@ -1694,28 +1877,60 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1694 u32 chunkno = 0; 1877 u32 chunkno = 0;
1695 u32 i; 1878 u32 i;
1696 u32 asicmode; 1879 u32 asicmode;
1880 u32 fwimg_size;
1881 u32 fwimg_buf[BFI_FLASH_CHUNK_SZ_WORDS];
1882 bfa_status_t status;
1883
1884 if (boot_env == BFI_FWBOOT_ENV_OS &&
1885 boot_type == BFI_FWBOOT_TYPE_FLASH) {
1886 fwimg_size = BFI_FLASH_IMAGE_SZ/sizeof(u32);
1887
1888 status = bfa_ioc_flash_img_get_chnk(ioc,
1889 BFA_IOC_FLASH_CHUNK_ADDR(chunkno), fwimg_buf);
1890 if (status != BFA_STATUS_OK)
1891 return status;
1892
1893 fwimg = fwimg_buf;
1894 } else {
1895 fwimg_size = bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc));
1896 fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc),
1897 BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
1898 }
1899
1900 bfa_trc(ioc, fwimg_size);
1697 1901
1698 bfa_trc(ioc, bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)));
1699 fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), chunkno);
1700 1902
1701 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff); 1903 pgnum = PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, loff);
1702 pgoff = PSS_SMEM_PGOFF(loff); 1904 pgoff = PSS_SMEM_PGOFF(loff);
1703 1905
1704 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 1906 writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1705 1907
1706 for (i = 0; i < bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)); i++) { 1908 for (i = 0; i < fwimg_size; i++) {
1707 1909
1708 if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) { 1910 if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
1709 chunkno = BFA_IOC_FLASH_CHUNK_NO(i); 1911 chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
1710 fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 1912
1913 if (boot_env == BFI_FWBOOT_ENV_OS &&
1914 boot_type == BFI_FWBOOT_TYPE_FLASH) {
1915 status = bfa_ioc_flash_img_get_chnk(ioc,
1916 BFA_IOC_FLASH_CHUNK_ADDR(chunkno),
1917 fwimg_buf);
1918 if (status != BFA_STATUS_OK)
1919 return status;
1920
1921 fwimg = fwimg_buf;
1922 } else {
1923 fwimg = bfa_cb_image_get_chunk(
1924 bfa_ioc_asic_gen(ioc),
1711 BFA_IOC_FLASH_CHUNK_ADDR(chunkno)); 1925 BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
1926 }
1712 } 1927 }
1713 1928
1714 /* 1929 /*
1715 * write smem 1930 * write smem
1716 */ 1931 */
1717 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, 1932 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
1718 cpu_to_le32(fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)])); 1933 fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)]);
1719 1934
1720 loff += sizeof(u32); 1935 loff += sizeof(u32);
1721 1936
@@ -1733,8 +1948,12 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1733 ioc->ioc_regs.host_page_num_fn); 1948 ioc->ioc_regs.host_page_num_fn);
1734 1949
1735 /* 1950 /*
1736 * Set boot type and device mode at the end. 1951 * Set boot type, env and device mode at the end.
1737 */ 1952 */
1953 if (boot_env == BFI_FWBOOT_ENV_OS &&
1954 boot_type == BFI_FWBOOT_TYPE_FLASH) {
1955 boot_type = BFI_FWBOOT_TYPE_NORMAL;
1956 }
1738 asicmode = BFI_FWBOOT_DEVMODE(ioc->asic_gen, ioc->asic_mode, 1957 asicmode = BFI_FWBOOT_DEVMODE(ioc->asic_gen, ioc->asic_mode,
1739 ioc->port0_mode, ioc->port1_mode); 1958 ioc->port0_mode, ioc->port1_mode);
1740 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_DEVMODE_OFF, 1959 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_DEVMODE_OFF,
@@ -1743,6 +1962,7 @@ bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1743 swab32(boot_type)); 1962 swab32(boot_type));
1744 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_ENV_OFF, 1963 bfa_mem_write(ioc->ioc_regs.smem_page_start, BFI_FWBOOT_ENV_OFF,
1745 swab32(boot_env)); 1964 swab32(boot_env));
1965 return BFA_STATUS_OK;
1746} 1966}
1747 1967
1748 1968
@@ -2002,13 +2222,30 @@ bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
2002 * Interface used by diag module to do firmware boot with memory test 2222 * Interface used by diag module to do firmware boot with memory test
2003 * as the entry vector. 2223 * as the entry vector.
2004 */ 2224 */
2005void 2225bfa_status_t
2006bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env) 2226bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env)
2007{ 2227{
2228 struct bfi_ioc_image_hdr_s *drv_fwhdr;
2229 bfa_status_t status;
2008 bfa_ioc_stats(ioc, ioc_boots); 2230 bfa_ioc_stats(ioc, ioc_boots);
2009 2231
2010 if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK) 2232 if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK)
2011 return; 2233 return BFA_STATUS_FAILED;
2234
2235 if (boot_env == BFI_FWBOOT_ENV_OS &&
2236 boot_type == BFI_FWBOOT_TYPE_NORMAL) {
2237
2238 drv_fwhdr = (struct bfi_ioc_image_hdr_s *)
2239 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
2240
2241 /*
2242 * Work with Flash iff flash f/w is better than driver f/w.
2243 * Otherwise push drivers firmware.
2244 */
2245 if (bfa_ioc_flash_fwver_cmp(ioc, drv_fwhdr) ==
2246 BFI_IOC_IMG_VER_BETTER)
2247 boot_type = BFI_FWBOOT_TYPE_FLASH;
2248 }
2012 2249
2013 /* 2250 /*
2014 * Initialize IOC state of all functions on a chip reset. 2251 * Initialize IOC state of all functions on a chip reset.
@@ -2022,8 +2259,14 @@ bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_env)
2022 } 2259 }
2023 2260
2024 bfa_ioc_msgflush(ioc); 2261 bfa_ioc_msgflush(ioc);
2025 bfa_ioc_download_fw(ioc, boot_type, boot_env); 2262 status = bfa_ioc_download_fw(ioc, boot_type, boot_env);
2026 bfa_ioc_lpu_start(ioc); 2263 if (status == BFA_STATUS_OK)
2264 bfa_ioc_lpu_start(ioc);
2265 else {
2266 WARN_ON(boot_type == BFI_FWBOOT_TYPE_MEMTEST);
2267 bfa_iocpf_timeout(ioc);
2268 }
2269 return status;
2027} 2270}
2028 2271
2029/* 2272/*
@@ -2419,14 +2662,6 @@ bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
2419 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_mismatch); 2662 bfa_fsm_cmp_state(&ioc->iocpf, bfa_iocpf_sm_mismatch);
2420} 2663}
2421 2664
2422#define bfa_ioc_state_disabled(__sm) \
2423 (((__sm) == BFI_IOC_UNINIT) || \
2424 ((__sm) == BFI_IOC_INITING) || \
2425 ((__sm) == BFI_IOC_HWINIT) || \
2426 ((__sm) == BFI_IOC_DISABLED) || \
2427 ((__sm) == BFI_IOC_FAIL) || \
2428 ((__sm) == BFI_IOC_CFG_DISABLED))
2429
2430/* 2665/*
2431 * Check if adapter is disabled -- both IOCs should be in a disabled 2666 * Check if adapter is disabled -- both IOCs should be in a disabled
2432 * state. 2667 * state.
@@ -6423,3 +6658,407 @@ bfa_fru_intr(void *fruarg, struct bfi_mbmsg_s *msg)
6423 WARN_ON(1); 6658 WARN_ON(1);
6424 } 6659 }
6425} 6660}
6661
6662/*
6663 * register definitions
6664 */
6665#define FLI_CMD_REG 0x0001d000
6666#define FLI_RDDATA_REG 0x0001d010
6667#define FLI_ADDR_REG 0x0001d004
6668#define FLI_DEV_STATUS_REG 0x0001d014
6669
6670#define BFA_FLASH_FIFO_SIZE 128 /* fifo size */
6671#define BFA_FLASH_CHECK_MAX 10000 /* max # of status check */
6672#define BFA_FLASH_BLOCKING_OP_MAX 1000000 /* max # of blocking op check */
6673#define BFA_FLASH_WIP_MASK 0x01 /* write in progress bit mask */
6674
6675enum bfa_flash_cmd {
6676 BFA_FLASH_FAST_READ = 0x0b, /* fast read */
6677 BFA_FLASH_READ_STATUS = 0x05, /* read status */
6678};
6679
6680/**
6681 * @brief hardware error definition
6682 */
6683enum bfa_flash_err {
6684 BFA_FLASH_NOT_PRESENT = -1, /*!< flash not present */
6685 BFA_FLASH_UNINIT = -2, /*!< flash not initialized */
6686 BFA_FLASH_BAD = -3, /*!< flash bad */
6687 BFA_FLASH_BUSY = -4, /*!< flash busy */
6688 BFA_FLASH_ERR_CMD_ACT = -5, /*!< command active never cleared */
6689 BFA_FLASH_ERR_FIFO_CNT = -6, /*!< fifo count never cleared */
6690 BFA_FLASH_ERR_WIP = -7, /*!< write-in-progress never cleared */
6691 BFA_FLASH_ERR_TIMEOUT = -8, /*!< fli timeout */
6692 BFA_FLASH_ERR_LEN = -9, /*!< invalid length */
6693};
6694
6695/**
6696 * @brief flash command register data structure
6697 */
6698union bfa_flash_cmd_reg_u {
6699 struct {
6700#ifdef __BIG_ENDIAN
6701 u32 act:1;
6702 u32 rsv:1;
6703 u32 write_cnt:9;
6704 u32 read_cnt:9;
6705 u32 addr_cnt:4;
6706 u32 cmd:8;
6707#else
6708 u32 cmd:8;
6709 u32 addr_cnt:4;
6710 u32 read_cnt:9;
6711 u32 write_cnt:9;
6712 u32 rsv:1;
6713 u32 act:1;
6714#endif
6715 } r;
6716 u32 i;
6717};
6718
6719/**
6720 * @brief flash device status register data structure
6721 */
6722union bfa_flash_dev_status_reg_u {
6723 struct {
6724#ifdef __BIG_ENDIAN
6725 u32 rsv:21;
6726 u32 fifo_cnt:6;
6727 u32 busy:1;
6728 u32 init_status:1;
6729 u32 present:1;
6730 u32 bad:1;
6731 u32 good:1;
6732#else
6733 u32 good:1;
6734 u32 bad:1;
6735 u32 present:1;
6736 u32 init_status:1;
6737 u32 busy:1;
6738 u32 fifo_cnt:6;
6739 u32 rsv:21;
6740#endif
6741 } r;
6742 u32 i;
6743};
6744
6745/**
6746 * @brief flash address register data structure
6747 */
6748union bfa_flash_addr_reg_u {
6749 struct {
6750#ifdef __BIG_ENDIAN
6751 u32 addr:24;
6752 u32 dummy:8;
6753#else
6754 u32 dummy:8;
6755 u32 addr:24;
6756#endif
6757 } r;
6758 u32 i;
6759};
6760
6761/**
6762 * dg flash_raw_private Flash raw private functions
6763 */
6764static void
6765bfa_flash_set_cmd(void __iomem *pci_bar, u8 wr_cnt,
6766 u8 rd_cnt, u8 ad_cnt, u8 op)
6767{
6768 union bfa_flash_cmd_reg_u cmd;
6769
6770 cmd.i = 0;
6771 cmd.r.act = 1;
6772 cmd.r.write_cnt = wr_cnt;
6773 cmd.r.read_cnt = rd_cnt;
6774 cmd.r.addr_cnt = ad_cnt;
6775 cmd.r.cmd = op;
6776 writel(cmd.i, (pci_bar + FLI_CMD_REG));
6777}
6778
6779static void
6780bfa_flash_set_addr(void __iomem *pci_bar, u32 address)
6781{
6782 union bfa_flash_addr_reg_u addr;
6783
6784 addr.r.addr = address & 0x00ffffff;
6785 addr.r.dummy = 0;
6786 writel(addr.i, (pci_bar + FLI_ADDR_REG));
6787}
6788
6789static int
6790bfa_flash_cmd_act_check(void __iomem *pci_bar)
6791{
6792 union bfa_flash_cmd_reg_u cmd;
6793
6794 cmd.i = readl(pci_bar + FLI_CMD_REG);
6795
6796 if (cmd.r.act)
6797 return BFA_FLASH_ERR_CMD_ACT;
6798
6799 return 0;
6800}
6801
6802/**
6803 * @brief
6804 * Flush FLI data fifo.
6805 *
6806 * @param[in] pci_bar - pci bar address
6807 * @param[in] dev_status - device status
6808 *
6809 * Return 0 on success, negative error number on error.
6810 */
6811static u32
6812bfa_flash_fifo_flush(void __iomem *pci_bar)
6813{
6814 u32 i;
6815 u32 t;
6816 union bfa_flash_dev_status_reg_u dev_status;
6817
6818 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
6819
6820 if (!dev_status.r.fifo_cnt)
6821 return 0;
6822
6823 /* fifo counter in terms of words */
6824 for (i = 0; i < dev_status.r.fifo_cnt; i++)
6825 t = readl(pci_bar + FLI_RDDATA_REG);
6826
6827 /*
6828 * Check the device status. It may take some time.
6829 */
6830 for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) {
6831 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
6832 if (!dev_status.r.fifo_cnt)
6833 break;
6834 }
6835
6836 if (dev_status.r.fifo_cnt)
6837 return BFA_FLASH_ERR_FIFO_CNT;
6838
6839 return 0;
6840}
6841
6842/**
6843 * @brief
6844 * Read flash status.
6845 *
6846 * @param[in] pci_bar - pci bar address
6847 *
6848 * Return 0 on success, negative error number on error.
6849*/
6850static u32
6851bfa_flash_status_read(void __iomem *pci_bar)
6852{
6853 union bfa_flash_dev_status_reg_u dev_status;
6854 u32 status;
6855 u32 ret_status;
6856 int i;
6857
6858 status = bfa_flash_fifo_flush(pci_bar);
6859 if (status < 0)
6860 return status;
6861
6862 bfa_flash_set_cmd(pci_bar, 0, 4, 0, BFA_FLASH_READ_STATUS);
6863
6864 for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) {
6865 status = bfa_flash_cmd_act_check(pci_bar);
6866 if (!status)
6867 break;
6868 }
6869
6870 if (status)
6871 return status;
6872
6873 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
6874 if (!dev_status.r.fifo_cnt)
6875 return BFA_FLASH_BUSY;
6876
6877 ret_status = readl(pci_bar + FLI_RDDATA_REG);
6878 ret_status >>= 24;
6879
6880 status = bfa_flash_fifo_flush(pci_bar);
6881 if (status < 0)
6882 return status;
6883
6884 return ret_status;
6885}
6886
6887/**
6888 * @brief
6889 * Start flash read operation.
6890 *
6891 * @param[in] pci_bar - pci bar address
6892 * @param[in] offset - flash address offset
6893 * @param[in] len - read data length
6894 * @param[in] buf - read data buffer
6895 *
6896 * Return 0 on success, negative error number on error.
6897 */
6898static u32
6899bfa_flash_read_start(void __iomem *pci_bar, u32 offset, u32 len,
6900 char *buf)
6901{
6902 u32 status;
6903
6904 /*
6905 * len must be mutiple of 4 and not exceeding fifo size
6906 */
6907 if (len == 0 || len > BFA_FLASH_FIFO_SIZE || (len & 0x03) != 0)
6908 return BFA_FLASH_ERR_LEN;
6909
6910 /*
6911 * check status
6912 */
6913 status = bfa_flash_status_read(pci_bar);
6914 if (status == BFA_FLASH_BUSY)
6915 status = bfa_flash_status_read(pci_bar);
6916
6917 if (status < 0)
6918 return status;
6919
6920 /*
6921 * check if write-in-progress bit is cleared
6922 */
6923 if (status & BFA_FLASH_WIP_MASK)
6924 return BFA_FLASH_ERR_WIP;
6925
6926 bfa_flash_set_addr(pci_bar, offset);
6927
6928 bfa_flash_set_cmd(pci_bar, 0, (u8)len, 4, BFA_FLASH_FAST_READ);
6929
6930 return 0;
6931}
6932
6933/**
6934 * @brief
6935 * Check flash read operation.
6936 *
6937 * @param[in] pci_bar - pci bar address
6938 *
6939 * Return flash device status, 1 if busy, 0 if not.
6940 */
6941static u32
6942bfa_flash_read_check(void __iomem *pci_bar)
6943{
6944 if (bfa_flash_cmd_act_check(pci_bar))
6945 return 1;
6946
6947 return 0;
6948}
6949/**
6950 * @brief
6951 * End flash read operation.
6952 *
6953 * @param[in] pci_bar - pci bar address
6954 * @param[in] len - read data length
6955 * @param[in] buf - read data buffer
6956 *
6957 */
6958static void
6959bfa_flash_read_end(void __iomem *pci_bar, u32 len, char *buf)
6960{
6961
6962 u32 i;
6963
6964 /*
6965 * read data fifo up to 32 words
6966 */
6967 for (i = 0; i < len; i += 4) {
6968 u32 w = readl(pci_bar + FLI_RDDATA_REG);
6969 *((u32 *) (buf + i)) = swab32(w);
6970 }
6971
6972 bfa_flash_fifo_flush(pci_bar);
6973}
6974
6975/**
6976 * @brief
6977 * Perform flash raw read.
6978 *
6979 * @param[in] pci_bar - pci bar address
6980 * @param[in] offset - flash partition address offset
6981 * @param[in] buf - read data buffer
6982 * @param[in] len - read data length
6983 *
6984 * Return status.
6985 */
6986
6987
6988#define FLASH_BLOCKING_OP_MAX 500
6989#define FLASH_SEM_LOCK_REG 0x18820
6990
6991static int
6992bfa_raw_sem_get(void __iomem *bar)
6993{
6994 int locked;
6995
6996 locked = readl((bar + FLASH_SEM_LOCK_REG));
6997 return !locked;
6998
6999}
7000
7001bfa_status_t
7002bfa_flash_sem_get(void __iomem *bar)
7003{
7004 u32 n = FLASH_BLOCKING_OP_MAX;
7005
7006 while (!bfa_raw_sem_get(bar)) {
7007 if (--n <= 0)
7008 return BFA_STATUS_BADFLASH;
7009 udelay(10000);
7010 }
7011 return BFA_STATUS_OK;
7012}
7013
7014void
7015bfa_flash_sem_put(void __iomem *bar)
7016{
7017 writel(0, (bar + FLASH_SEM_LOCK_REG));
7018}
7019
7020bfa_status_t
7021bfa_flash_raw_read(void __iomem *pci_bar, u32 offset, char *buf,
7022 u32 len)
7023{
7024 u32 n, status;
7025 u32 off, l, s, residue, fifo_sz;
7026
7027 residue = len;
7028 off = 0;
7029 fifo_sz = BFA_FLASH_FIFO_SIZE;
7030 status = bfa_flash_sem_get(pci_bar);
7031 if (status != BFA_STATUS_OK)
7032 return status;
7033
7034 while (residue) {
7035 s = offset + off;
7036 n = s / fifo_sz;
7037 l = (n + 1) * fifo_sz - s;
7038 if (l > residue)
7039 l = residue;
7040
7041 status = bfa_flash_read_start(pci_bar, offset + off, l,
7042 &buf[off]);
7043 if (status < 0) {
7044 bfa_flash_sem_put(pci_bar);
7045 return BFA_STATUS_FAILED;
7046 }
7047
7048 n = BFA_FLASH_BLOCKING_OP_MAX;
7049 while (bfa_flash_read_check(pci_bar)) {
7050 if (--n <= 0) {
7051 bfa_flash_sem_put(pci_bar);
7052 return BFA_STATUS_FAILED;
7053 }
7054 }
7055
7056 bfa_flash_read_end(pci_bar, l, &buf[off]);
7057
7058 residue -= l;
7059 off += l;
7060 }
7061 bfa_flash_sem_put(pci_bar);
7062
7063 return BFA_STATUS_OK;
7064}
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
index 90814fe85ac1..2e28392c2fb6 100644
--- a/drivers/scsi/bfa/bfa_ioc.h
+++ b/drivers/scsi/bfa/bfa_ioc.h
@@ -515,6 +515,8 @@ void bfa_flash_attach(struct bfa_flash_s *flash, struct bfa_ioc_s *ioc,
515 void *dev, struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg); 515 void *dev, struct bfa_trc_mod_s *trcmod, bfa_boolean_t mincfg);
516void bfa_flash_memclaim(struct bfa_flash_s *flash, 516void bfa_flash_memclaim(struct bfa_flash_s *flash,
517 u8 *dm_kva, u64 dm_pa, bfa_boolean_t mincfg); 517 u8 *dm_kva, u64 dm_pa, bfa_boolean_t mincfg);
518bfa_status_t bfa_flash_raw_read(void __iomem *pci_bar_kva,
519 u32 offset, char *buf, u32 len);
518 520
519/* 521/*
520 * DIAG module specific 522 * DIAG module specific
@@ -888,7 +890,7 @@ void bfa_ioc_enable(struct bfa_ioc_s *ioc);
888void bfa_ioc_disable(struct bfa_ioc_s *ioc); 890void bfa_ioc_disable(struct bfa_ioc_s *ioc);
889bfa_boolean_t bfa_ioc_intx_claim(struct bfa_ioc_s *ioc); 891bfa_boolean_t bfa_ioc_intx_claim(struct bfa_ioc_s *ioc);
890 892
891void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, 893bfa_status_t bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type,
892 u32 boot_env); 894 u32 boot_env);
893void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg); 895void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg);
894void bfa_ioc_error_isr(struct bfa_ioc_s *ioc); 896void bfa_ioc_error_isr(struct bfa_ioc_s *ioc);
@@ -919,6 +921,7 @@ bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata,
919 int *trclen); 921 int *trclen);
920bfa_status_t bfa_ioc_debug_fwcore(struct bfa_ioc_s *ioc, void *buf, 922bfa_status_t bfa_ioc_debug_fwcore(struct bfa_ioc_s *ioc, void *buf,
921 u32 *offset, int *buflen); 923 u32 *offset, int *buflen);
924bfa_status_t bfa_ioc_fwsig_invalidate(struct bfa_ioc_s *ioc);
922bfa_boolean_t bfa_ioc_sem_get(void __iomem *sem_reg); 925bfa_boolean_t bfa_ioc_sem_get(void __iomem *sem_reg);
923void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, 926void bfa_ioc_fwver_get(struct bfa_ioc_s *ioc,
924 struct bfi_ioc_image_hdr_s *fwhdr); 927 struct bfi_ioc_image_hdr_s *fwhdr);
@@ -956,6 +959,8 @@ bfa_status_t bfa_ablk_optrom_en(struct bfa_ablk_s *ablk,
956bfa_status_t bfa_ablk_optrom_dis(struct bfa_ablk_s *ablk, 959bfa_status_t bfa_ablk_optrom_dis(struct bfa_ablk_s *ablk,
957 bfa_ablk_cbfn_t cbfn, void *cbarg); 960 bfa_ablk_cbfn_t cbfn, void *cbarg);
958 961
962bfa_status_t bfa_ioc_flash_img_get_chnk(struct bfa_ioc_s *ioc, u32 off,
963 u32 *fwimg);
959/* 964/*
960 * bfa mfg wwn API functions 965 * bfa mfg wwn API functions
961 */ 966 */
diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c
index e3b928746674..453c2f5b5561 100644
--- a/drivers/scsi/bfa/bfa_ioc_cb.c
+++ b/drivers/scsi/bfa/bfa_ioc_cb.c
@@ -81,6 +81,29 @@ bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc)
81static bfa_boolean_t 81static bfa_boolean_t
82bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc) 82bfa_ioc_cb_firmware_lock(struct bfa_ioc_s *ioc)
83{ 83{
84 enum bfi_ioc_state alt_fwstate, cur_fwstate;
85 struct bfi_ioc_image_hdr_s fwhdr;
86
87 cur_fwstate = bfa_ioc_cb_get_cur_ioc_fwstate(ioc);
88 bfa_trc(ioc, cur_fwstate);
89 alt_fwstate = bfa_ioc_cb_get_alt_ioc_fwstate(ioc);
90 bfa_trc(ioc, alt_fwstate);
91
92 /*
93 * Uninit implies this is the only driver as of now.
94 */
95 if (cur_fwstate == BFI_IOC_UNINIT)
96 return BFA_TRUE;
97 /*
98 * Check if another driver with a different firmware is active
99 */
100 bfa_ioc_fwver_get(ioc, &fwhdr);
101 if (!bfa_ioc_fwver_cmp(ioc, &fwhdr) &&
102 alt_fwstate != BFI_IOC_DISABLED) {
103 bfa_trc(ioc, alt_fwstate);
104 return BFA_FALSE;
105 }
106
84 return BFA_TRUE; 107 return BFA_TRUE;
85} 108}
86 109
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 0467c349251a..157f6044a9bb 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -229,6 +229,18 @@ bfad_iocmd_iocfc_get_attr(struct bfad_s *bfad, void *cmd)
229} 229}
230 230
231int 231int
232bfad_iocmd_ioc_fw_sig_inv(struct bfad_s *bfad, void *cmd)
233{
234 struct bfa_bsg_gen_s *iocmd = (struct bfa_bsg_gen_s *)cmd;
235 unsigned long flags;
236
237 spin_lock_irqsave(&bfad->bfad_lock, flags);
238 iocmd->status = bfa_ioc_fwsig_invalidate(&bfad->bfa.ioc);
239 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
240 return 0;
241}
242
243int
232bfad_iocmd_iocfc_set_intr(struct bfad_s *bfad, void *cmd) 244bfad_iocmd_iocfc_set_intr(struct bfad_s *bfad, void *cmd)
233{ 245{
234 struct bfa_bsg_iocfc_intr_s *iocmd = (struct bfa_bsg_iocfc_intr_s *)cmd; 246 struct bfa_bsg_iocfc_intr_s *iocmd = (struct bfa_bsg_iocfc_intr_s *)cmd;
@@ -2893,6 +2905,9 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
2893 case IOCMD_IOC_PCIFN_CFG: 2905 case IOCMD_IOC_PCIFN_CFG:
2894 rc = bfad_iocmd_ioc_get_pcifn_cfg(bfad, iocmd); 2906 rc = bfad_iocmd_ioc_get_pcifn_cfg(bfad, iocmd);
2895 break; 2907 break;
2908 case IOCMD_IOC_FW_SIG_INV:
2909 rc = bfad_iocmd_ioc_fw_sig_inv(bfad, iocmd);
2910 break;
2896 case IOCMD_PCIFN_CREATE: 2911 case IOCMD_PCIFN_CREATE:
2897 rc = bfad_iocmd_pcifn_create(bfad, iocmd); 2912 rc = bfad_iocmd_pcifn_create(bfad, iocmd);
2898 break; 2913 break;
diff --git a/drivers/scsi/bfa/bfad_bsg.h b/drivers/scsi/bfa/bfad_bsg.h
index 05f0fc9cf063..90abef691585 100644
--- a/drivers/scsi/bfa/bfad_bsg.h
+++ b/drivers/scsi/bfa/bfad_bsg.h
@@ -34,6 +34,7 @@ enum {
34 IOCMD_IOC_RESET_FWSTATS, 34 IOCMD_IOC_RESET_FWSTATS,
35 IOCMD_IOC_SET_ADAPTER_NAME, 35 IOCMD_IOC_SET_ADAPTER_NAME,
36 IOCMD_IOC_SET_PORT_NAME, 36 IOCMD_IOC_SET_PORT_NAME,
37 IOCMD_IOC_FW_SIG_INV,
37 IOCMD_IOCFC_GET_ATTR, 38 IOCMD_IOCFC_GET_ATTR,
38 IOCMD_IOCFC_SET_INTR, 39 IOCMD_IOCFC_SET_INTR,
39 IOCMD_PORT_ENABLE, 40 IOCMD_PORT_ENABLE,
diff --git a/drivers/scsi/bfa/bfi.h b/drivers/scsi/bfa/bfi.h
index 37bd2564e83b..bf05cc831cbc 100644
--- a/drivers/scsi/bfa/bfi.h
+++ b/drivers/scsi/bfa/bfi.h
@@ -46,6 +46,7 @@
46 */ 46 */
47#define BFI_FLASH_CHUNK_SZ 256 /* Flash chunk size */ 47#define BFI_FLASH_CHUNK_SZ 256 /* Flash chunk size */
48#define BFI_FLASH_CHUNK_SZ_WORDS (BFI_FLASH_CHUNK_SZ/sizeof(u32)) 48#define BFI_FLASH_CHUNK_SZ_WORDS (BFI_FLASH_CHUNK_SZ/sizeof(u32))
49#define BFI_FLASH_IMAGE_SZ 0x100000
49 50
50/* 51/*
51 * Msg header common to all msgs 52 * Msg header common to all msgs
@@ -324,7 +325,29 @@ struct bfi_ioc_getattr_reply_s {
324#define BFI_IOC_TRC_ENTS 256 325#define BFI_IOC_TRC_ENTS 256
325 326
326#define BFI_IOC_FW_SIGNATURE (0xbfadbfad) 327#define BFI_IOC_FW_SIGNATURE (0xbfadbfad)
328#define BFA_IOC_FW_INV_SIGN (0xdeaddead)
327#define BFI_IOC_MD5SUM_SZ 4 329#define BFI_IOC_MD5SUM_SZ 4
330
331struct bfi_ioc_fwver_s {
332#ifdef __BIG_ENDIAN
333 uint8_t patch;
334 uint8_t maint;
335 uint8_t minor;
336 uint8_t major;
337 uint8_t rsvd[2];
338 uint8_t build;
339 uint8_t phase;
340#else
341 uint8_t major;
342 uint8_t minor;
343 uint8_t maint;
344 uint8_t patch;
345 uint8_t phase;
346 uint8_t build;
347 uint8_t rsvd[2];
348#endif
349};
350
328struct bfi_ioc_image_hdr_s { 351struct bfi_ioc_image_hdr_s {
329 u32 signature; /* constant signature */ 352 u32 signature; /* constant signature */
330 u8 asic_gen; /* asic generation */ 353 u8 asic_gen; /* asic generation */
@@ -333,10 +356,18 @@ struct bfi_ioc_image_hdr_s {
333 u8 port1_mode; /* device mode for port 1 */ 356 u8 port1_mode; /* device mode for port 1 */
334 u32 exec; /* exec vector */ 357 u32 exec; /* exec vector */
335 u32 bootenv; /* fimware boot env */ 358 u32 bootenv; /* fimware boot env */
336 u32 rsvd_b[4]; 359 u32 rsvd_b[2];
360 struct bfi_ioc_fwver_s fwver;
337 u32 md5sum[BFI_IOC_MD5SUM_SZ]; 361 u32 md5sum[BFI_IOC_MD5SUM_SZ];
338}; 362};
339 363
364enum bfi_ioc_img_ver_cmp_e {
365 BFI_IOC_IMG_VER_INCOMP,
366 BFI_IOC_IMG_VER_OLD,
367 BFI_IOC_IMG_VER_SAME,
368 BFI_IOC_IMG_VER_BETTER
369};
370
340#define BFI_FWBOOT_DEVMODE_OFF 4 371#define BFI_FWBOOT_DEVMODE_OFF 4
341#define BFI_FWBOOT_TYPE_OFF 8 372#define BFI_FWBOOT_TYPE_OFF 8
342#define BFI_FWBOOT_ENV_OFF 12 373#define BFI_FWBOOT_ENV_OFF 12
@@ -346,6 +377,12 @@ struct bfi_ioc_image_hdr_s {
346 ((u32)(__p0_mode)) << 8 | \ 377 ((u32)(__p0_mode)) << 8 | \
347 ((u32)(__p1_mode))) 378 ((u32)(__p1_mode)))
348 379
380enum bfi_fwboot_type {
381 BFI_FWBOOT_TYPE_NORMAL = 0,
382 BFI_FWBOOT_TYPE_FLASH = 1,
383 BFI_FWBOOT_TYPE_MEMTEST = 2,
384};
385
349#define BFI_FWBOOT_TYPE_NORMAL 0 386#define BFI_FWBOOT_TYPE_NORMAL 0
350#define BFI_FWBOOT_TYPE_MEMTEST 2 387#define BFI_FWBOOT_TYPE_MEMTEST 2
351#define BFI_FWBOOT_ENV_OS 0 388#define BFI_FWBOOT_ENV_OS 0