aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRasesh Mody <rmody@brocade.com>2013-12-17 20:07:41 -0500
committerDavid S. Miller <davem@davemloft.net>2013-12-18 00:30:34 -0500
commitc107ba171f3dabf93b577bb58e3a2275632ec274 (patch)
tree5f434eda7b8c62993d4f5294d4c750a64b6dc5a5 /drivers
parent24f5d33d42d648bce9ae7d3c115816c20ae48217 (diff)
bna: Firmware Patch Simplification
This patch includes change to enable firmware patch simplication feature. This feature is targeted to address the requirement to have independent patch release for firmware. Prior to the 3.2.3.0 firmware, releasing a patch fix for firmware would require changes to bna driver, to use new firmware images. However with these changes, if the new firmware is flashed on to the Adapter, the driver will use the new firmware after checking the patch release byte in the firmware version. Update the f/w version to 3.2.3.0 Signed-off-by: Rasesh Mody <rmody@brocade.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_ioc.c618
-rw-r--r--drivers/net/ethernet/brocade/bna/bfa_ioc.h1
-rw-r--r--drivers/net/ethernet/brocade/bna/bfi.h33
-rw-r--r--drivers/net/ethernet/brocade/bna/cna.h4
4 files changed, 626 insertions, 30 deletions
diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
index b81132a8ee79..537bba14f913 100644
--- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c
+++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c
@@ -22,6 +22,14 @@
22 22
23/* IOC local definitions */ 23/* IOC local definitions */
24 24
25#define bfa_ioc_state_disabled(__sm) \
26 (((__sm) == BFI_IOC_UNINIT) || \
27 ((__sm) == BFI_IOC_INITING) || \
28 ((__sm) == BFI_IOC_HWINIT) || \
29 ((__sm) == BFI_IOC_DISABLED) || \
30 ((__sm) == BFI_IOC_FAIL) || \
31 ((__sm) == BFI_IOC_CFG_DISABLED))
32
25/* Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details. */ 33/* Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details. */
26 34
27#define bfa_ioc_firmware_lock(__ioc) \ 35#define bfa_ioc_firmware_lock(__ioc) \
@@ -84,8 +92,8 @@ static void bfa_ioc_pf_disabled(struct bfa_ioc *ioc);
84static void bfa_ioc_pf_failed(struct bfa_ioc *ioc); 92static void bfa_ioc_pf_failed(struct bfa_ioc *ioc);
85static void bfa_ioc_pf_hwfailed(struct bfa_ioc *ioc); 93static void bfa_ioc_pf_hwfailed(struct bfa_ioc *ioc);
86static void bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc); 94static void bfa_ioc_pf_fwmismatch(struct bfa_ioc *ioc);
87static void bfa_ioc_boot(struct bfa_ioc *ioc, enum bfi_fwboot_type boot_type, 95static enum bfa_status bfa_ioc_boot(struct bfa_ioc *ioc,
88 u32 boot_param); 96 enum bfi_fwboot_type boot_type, u32 boot_param);
89static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr); 97static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr);
90static void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, 98static void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc,
91 char *serial_num); 99 char *serial_num);
@@ -1139,6 +1147,25 @@ bfa_nw_ioc_sem_release(void __iomem *sem_reg)
1139 writel(1, sem_reg); 1147 writel(1, sem_reg);
1140} 1148}
1141 1149
1150/* Invalidate fwver signature */
1151enum bfa_status
1152bfa_nw_ioc_fwsig_invalidate(struct bfa_ioc *ioc)
1153{
1154 u32 pgnum, pgoff;
1155 u32 loff = 0;
1156 enum bfi_ioc_state ioc_fwstate;
1157
1158 ioc_fwstate = bfa_ioc_get_cur_ioc_fwstate(ioc);
1159 if (!bfa_ioc_state_disabled(ioc_fwstate))
1160 return BFA_STATUS_ADAPTER_ENABLED;
1161
1162 pgnum = bfa_ioc_smem_pgnum(ioc, loff);
1163 pgoff = PSS_SMEM_PGOFF(loff);
1164 writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1165 writel(BFI_IOC_FW_INV_SIGN, ioc->ioc_regs.smem_page_start + loff);
1166 return BFA_STATUS_OK;
1167}
1168
1142/* Clear fwver hdr */ 1169/* Clear fwver hdr */
1143static void 1170static void
1144bfa_ioc_fwver_clear(struct bfa_ioc *ioc) 1171bfa_ioc_fwver_clear(struct bfa_ioc *ioc)
@@ -1317,22 +1344,510 @@ bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr)
1317 } 1344 }
1318} 1345}
1319 1346
1320/* Returns TRUE if same. */ 1347static bool
1348bfa_ioc_fwver_md5_check(struct bfi_ioc_image_hdr *fwhdr_1,
1349 struct bfi_ioc_image_hdr *fwhdr_2)
1350{
1351 int i;
1352
1353 for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) {
1354 if (fwhdr_1->md5sum[i] != fwhdr_2->md5sum[i])
1355 return false;
1356 }
1357
1358 return true;
1359}
1360
1361/* Returns TRUE if major minor and maintainence are same.
1362 * If patch version are same, check for MD5 Checksum to be same.
1363 */
1364static bool
1365bfa_ioc_fw_ver_compatible(struct bfi_ioc_image_hdr *drv_fwhdr,
1366 struct bfi_ioc_image_hdr *fwhdr_to_cmp)
1367{
1368 if (drv_fwhdr->signature != fwhdr_to_cmp->signature)
1369 return false;
1370 if (drv_fwhdr->fwver.major != fwhdr_to_cmp->fwver.major)
1371 return false;
1372 if (drv_fwhdr->fwver.minor != fwhdr_to_cmp->fwver.minor)
1373 return false;
1374 if (drv_fwhdr->fwver.maint != fwhdr_to_cmp->fwver.maint)
1375 return false;
1376 if (drv_fwhdr->fwver.patch == fwhdr_to_cmp->fwver.patch &&
1377 drv_fwhdr->fwver.phase == fwhdr_to_cmp->fwver.phase &&
1378 drv_fwhdr->fwver.build == fwhdr_to_cmp->fwver.build)
1379 return bfa_ioc_fwver_md5_check(drv_fwhdr, fwhdr_to_cmp);
1380
1381 return true;
1382}
1383
1384static bool
1385bfa_ioc_flash_fwver_valid(struct bfi_ioc_image_hdr *flash_fwhdr)
1386{
1387 if (flash_fwhdr->fwver.major == 0 || flash_fwhdr->fwver.major == 0xFF)
1388 return false;
1389
1390 return true;
1391}
1392
1393static bool
1394fwhdr_is_ga(struct bfi_ioc_image_hdr *fwhdr)
1395{
1396 if (fwhdr->fwver.phase == 0 &&
1397 fwhdr->fwver.build == 0)
1398 return false;
1399
1400 return true;
1401}
1402
1403/* Returns TRUE if both are compatible and patch of fwhdr_to_cmp is better. */
1404static enum bfi_ioc_img_ver_cmp
1405bfa_ioc_fw_ver_patch_cmp(struct bfi_ioc_image_hdr *base_fwhdr,
1406 struct bfi_ioc_image_hdr *fwhdr_to_cmp)
1407{
1408 if (bfa_ioc_fw_ver_compatible(base_fwhdr, fwhdr_to_cmp) == false)
1409 return BFI_IOC_IMG_VER_INCOMP;
1410
1411 if (fwhdr_to_cmp->fwver.patch > base_fwhdr->fwver.patch)
1412 return BFI_IOC_IMG_VER_BETTER;
1413 else if (fwhdr_to_cmp->fwver.patch < base_fwhdr->fwver.patch)
1414 return BFI_IOC_IMG_VER_OLD;
1415
1416 /* GA takes priority over internal builds of the same patch stream.
1417 * At this point major minor maint and patch numbers are same.
1418 */
1419 if (fwhdr_is_ga(base_fwhdr) == true)
1420 if (fwhdr_is_ga(fwhdr_to_cmp))
1421 return BFI_IOC_IMG_VER_SAME;
1422 else
1423 return BFI_IOC_IMG_VER_OLD;
1424 else
1425 if (fwhdr_is_ga(fwhdr_to_cmp))
1426 return BFI_IOC_IMG_VER_BETTER;
1427
1428 if (fwhdr_to_cmp->fwver.phase > base_fwhdr->fwver.phase)
1429 return BFI_IOC_IMG_VER_BETTER;
1430 else if (fwhdr_to_cmp->fwver.phase < base_fwhdr->fwver.phase)
1431 return BFI_IOC_IMG_VER_OLD;
1432
1433 if (fwhdr_to_cmp->fwver.build > base_fwhdr->fwver.build)
1434 return BFI_IOC_IMG_VER_BETTER;
1435 else if (fwhdr_to_cmp->fwver.build < base_fwhdr->fwver.build)
1436 return BFI_IOC_IMG_VER_OLD;
1437
1438 /* All Version Numbers are equal.
1439 * Md5 check to be done as a part of compatibility check.
1440 */
1441 return BFI_IOC_IMG_VER_SAME;
1442}
1443
1444/* register definitions */
1445#define FLI_CMD_REG 0x0001d000
1446#define FLI_WRDATA_REG 0x0001d00c
1447#define FLI_RDDATA_REG 0x0001d010
1448#define FLI_ADDR_REG 0x0001d004
1449#define FLI_DEV_STATUS_REG 0x0001d014
1450
1451#define BFA_FLASH_FIFO_SIZE 128 /* fifo size */
1452#define BFA_FLASH_CHECK_MAX 10000 /* max # of status check */
1453#define BFA_FLASH_BLOCKING_OP_MAX 1000000 /* max # of blocking op check */
1454#define BFA_FLASH_WIP_MASK 0x01 /* write in progress bit mask */
1455
1456#define NFC_STATE_RUNNING 0x20000001
1457#define NFC_STATE_PAUSED 0x00004560
1458#define NFC_VER_VALID 0x147
1459
1460enum bfa_flash_cmd {
1461 BFA_FLASH_FAST_READ = 0x0b, /* fast read */
1462 BFA_FLASH_WRITE_ENABLE = 0x06, /* write enable */
1463 BFA_FLASH_SECTOR_ERASE = 0xd8, /* sector erase */
1464 BFA_FLASH_WRITE = 0x02, /* write */
1465 BFA_FLASH_READ_STATUS = 0x05, /* read status */
1466};
1467
1468/* hardware error definition */
1469enum bfa_flash_err {
1470 BFA_FLASH_NOT_PRESENT = -1, /*!< flash not present */
1471 BFA_FLASH_UNINIT = -2, /*!< flash not initialized */
1472 BFA_FLASH_BAD = -3, /*!< flash bad */
1473 BFA_FLASH_BUSY = -4, /*!< flash busy */
1474 BFA_FLASH_ERR_CMD_ACT = -5, /*!< command active never cleared */
1475 BFA_FLASH_ERR_FIFO_CNT = -6, /*!< fifo count never cleared */
1476 BFA_FLASH_ERR_WIP = -7, /*!< write-in-progress never cleared */
1477 BFA_FLASH_ERR_TIMEOUT = -8, /*!< fli timeout */
1478 BFA_FLASH_ERR_LEN = -9, /*!< invalid length */
1479};
1480
1481/* flash command register data structure */
1482union bfa_flash_cmd_reg {
1483 struct {
1484#ifdef __BIG_ENDIAN
1485 u32 act:1;
1486 u32 rsv:1;
1487 u32 write_cnt:9;
1488 u32 read_cnt:9;
1489 u32 addr_cnt:4;
1490 u32 cmd:8;
1491#else
1492 u32 cmd:8;
1493 u32 addr_cnt:4;
1494 u32 read_cnt:9;
1495 u32 write_cnt:9;
1496 u32 rsv:1;
1497 u32 act:1;
1498#endif
1499 } r;
1500 u32 i;
1501};
1502
1503/* flash device status register data structure */
1504union bfa_flash_dev_status_reg {
1505 struct {
1506#ifdef __BIG_ENDIAN
1507 u32 rsv:21;
1508 u32 fifo_cnt:6;
1509 u32 busy:1;
1510 u32 init_status:1;
1511 u32 present:1;
1512 u32 bad:1;
1513 u32 good:1;
1514#else
1515 u32 good:1;
1516 u32 bad:1;
1517 u32 present:1;
1518 u32 init_status:1;
1519 u32 busy:1;
1520 u32 fifo_cnt:6;
1521 u32 rsv:21;
1522#endif
1523 } r;
1524 u32 i;
1525};
1526
1527/* flash address register data structure */
1528union bfa_flash_addr_reg {
1529 struct {
1530#ifdef __BIG_ENDIAN
1531 u32 addr:24;
1532 u32 dummy:8;
1533#else
1534 u32 dummy:8;
1535 u32 addr:24;
1536#endif
1537 } r;
1538 u32 i;
1539};
1540
1541/* Flash raw private functions */
1542static void
1543bfa_flash_set_cmd(void __iomem *pci_bar, u8 wr_cnt,
1544 u8 rd_cnt, u8 ad_cnt, u8 op)
1545{
1546 union bfa_flash_cmd_reg cmd;
1547
1548 cmd.i = 0;
1549 cmd.r.act = 1;
1550 cmd.r.write_cnt = wr_cnt;
1551 cmd.r.read_cnt = rd_cnt;
1552 cmd.r.addr_cnt = ad_cnt;
1553 cmd.r.cmd = op;
1554 writel(cmd.i, (pci_bar + FLI_CMD_REG));
1555}
1556
1557static void
1558bfa_flash_set_addr(void __iomem *pci_bar, u32 address)
1559{
1560 union bfa_flash_addr_reg addr;
1561
1562 addr.r.addr = address & 0x00ffffff;
1563 addr.r.dummy = 0;
1564 writel(addr.i, (pci_bar + FLI_ADDR_REG));
1565}
1566
1567static int
1568bfa_flash_cmd_act_check(void __iomem *pci_bar)
1569{
1570 union bfa_flash_cmd_reg cmd;
1571
1572 cmd.i = readl(pci_bar + FLI_CMD_REG);
1573
1574 if (cmd.r.act)
1575 return BFA_FLASH_ERR_CMD_ACT;
1576
1577 return 0;
1578}
1579
1580/* Flush FLI data fifo. */
1581static u32
1582bfa_flash_fifo_flush(void __iomem *pci_bar)
1583{
1584 u32 i;
1585 u32 t;
1586 union bfa_flash_dev_status_reg dev_status;
1587
1588 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
1589
1590 if (!dev_status.r.fifo_cnt)
1591 return 0;
1592
1593 /* fifo counter in terms of words */
1594 for (i = 0; i < dev_status.r.fifo_cnt; i++)
1595 t = readl(pci_bar + FLI_RDDATA_REG);
1596
1597 /* Check the device status. It may take some time. */
1598 for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) {
1599 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
1600 if (!dev_status.r.fifo_cnt)
1601 break;
1602 }
1603
1604 if (dev_status.r.fifo_cnt)
1605 return BFA_FLASH_ERR_FIFO_CNT;
1606
1607 return 0;
1608}
1609
1610/* Read flash status. */
1611static u32
1612bfa_flash_status_read(void __iomem *pci_bar)
1613{
1614 union bfa_flash_dev_status_reg dev_status;
1615 u32 status;
1616 u32 ret_status;
1617 int i;
1618
1619 status = bfa_flash_fifo_flush(pci_bar);
1620 if (status < 0)
1621 return status;
1622
1623 bfa_flash_set_cmd(pci_bar, 0, 4, 0, BFA_FLASH_READ_STATUS);
1624
1625 for (i = 0; i < BFA_FLASH_CHECK_MAX; i++) {
1626 status = bfa_flash_cmd_act_check(pci_bar);
1627 if (!status)
1628 break;
1629 }
1630
1631 if (status)
1632 return status;
1633
1634 dev_status.i = readl(pci_bar + FLI_DEV_STATUS_REG);
1635 if (!dev_status.r.fifo_cnt)
1636 return BFA_FLASH_BUSY;
1637
1638 ret_status = readl(pci_bar + FLI_RDDATA_REG);
1639 ret_status >>= 24;
1640
1641 status = bfa_flash_fifo_flush(pci_bar);
1642 if (status < 0)
1643 return status;
1644
1645 return ret_status;
1646}
1647
1648/* Start flash read operation. */
1649static u32
1650bfa_flash_read_start(void __iomem *pci_bar, u32 offset, u32 len,
1651 char *buf)
1652{
1653 u32 status;
1654
1655 /* len must be mutiple of 4 and not exceeding fifo size */
1656 if (len == 0 || len > BFA_FLASH_FIFO_SIZE || (len & 0x03) != 0)
1657 return BFA_FLASH_ERR_LEN;
1658
1659 /* check status */
1660 status = bfa_flash_status_read(pci_bar);
1661 if (status == BFA_FLASH_BUSY)
1662 status = bfa_flash_status_read(pci_bar);
1663
1664 if (status < 0)
1665 return status;
1666
1667 /* check if write-in-progress bit is cleared */
1668 if (status & BFA_FLASH_WIP_MASK)
1669 return BFA_FLASH_ERR_WIP;
1670
1671 bfa_flash_set_addr(pci_bar, offset);
1672
1673 bfa_flash_set_cmd(pci_bar, 0, (u8)len, 4, BFA_FLASH_FAST_READ);
1674
1675 return 0;
1676}
1677
1678/* Check flash read operation. */
1679static u32
1680bfa_flash_read_check(void __iomem *pci_bar)
1681{
1682 if (bfa_flash_cmd_act_check(pci_bar))
1683 return 1;
1684
1685 return 0;
1686}
1687
1688/* End flash read operation. */
1689static void
1690bfa_flash_read_end(void __iomem *pci_bar, u32 len, char *buf)
1691{
1692 u32 i;
1693
1694 /* read data fifo up to 32 words */
1695 for (i = 0; i < len; i += 4) {
1696 u32 w = readl(pci_bar + FLI_RDDATA_REG);
1697 *((u32 *)(buf + i)) = swab32(w);
1698 }
1699
1700 bfa_flash_fifo_flush(pci_bar);
1701}
1702
1703/* Perform flash raw read. */
1704
1705#define FLASH_BLOCKING_OP_MAX 500
1706#define FLASH_SEM_LOCK_REG 0x18820
1707
1708static int
1709bfa_raw_sem_get(void __iomem *bar)
1710{
1711 int locked;
1712
1713 locked = readl((bar + FLASH_SEM_LOCK_REG));
1714
1715 return !locked;
1716}
1717
1718static enum bfa_status
1719bfa_flash_sem_get(void __iomem *bar)
1720{
1721 u32 n = FLASH_BLOCKING_OP_MAX;
1722
1723 while (!bfa_raw_sem_get(bar)) {
1724 if (--n <= 0)
1725 return BFA_STATUS_BADFLASH;
1726 udelay(10000);
1727 }
1728 return BFA_STATUS_OK;
1729}
1730
1731static void
1732bfa_flash_sem_put(void __iomem *bar)
1733{
1734 writel(0, (bar + FLASH_SEM_LOCK_REG));
1735}
1736
1737static enum bfa_status
1738bfa_flash_raw_read(void __iomem *pci_bar, u32 offset, char *buf,
1739 u32 len)
1740{
1741 u32 n, status;
1742 u32 off, l, s, residue, fifo_sz;
1743
1744 residue = len;
1745 off = 0;
1746 fifo_sz = BFA_FLASH_FIFO_SIZE;
1747 status = bfa_flash_sem_get(pci_bar);
1748 if (status != BFA_STATUS_OK)
1749 return status;
1750
1751 while (residue) {
1752 s = offset + off;
1753 n = s / fifo_sz;
1754 l = (n + 1) * fifo_sz - s;
1755 if (l > residue)
1756 l = residue;
1757
1758 status = bfa_flash_read_start(pci_bar, offset + off, l,
1759 &buf[off]);
1760 if (status < 0) {
1761 bfa_flash_sem_put(pci_bar);
1762 return BFA_STATUS_FAILED;
1763 }
1764
1765 n = BFA_FLASH_BLOCKING_OP_MAX;
1766 while (bfa_flash_read_check(pci_bar)) {
1767 if (--n <= 0) {
1768 bfa_flash_sem_put(pci_bar);
1769 return BFA_STATUS_FAILED;
1770 }
1771 }
1772
1773 bfa_flash_read_end(pci_bar, l, &buf[off]);
1774
1775 residue -= l;
1776 off += l;
1777 }
1778 bfa_flash_sem_put(pci_bar);
1779
1780 return BFA_STATUS_OK;
1781}
1782
1783u32
1784bfa_nw_ioc_flash_img_get_size(struct bfa_ioc *ioc)
1785{
1786 return BFI_FLASH_IMAGE_SZ/sizeof(u32);
1787}
1788
1789#define BFA_FLASH_PART_FWIMG_ADDR 0x100000 /* fw image address */
1790
1791enum bfa_status
1792bfa_nw_ioc_flash_img_get_chnk(struct bfa_ioc *ioc, u32 off,
1793 u32 *fwimg)
1794{
1795 return bfa_flash_raw_read(ioc->pcidev.pci_bar_kva,
1796 BFA_FLASH_PART_FWIMG_ADDR + (off * sizeof(u32)),
1797 (char *)fwimg, BFI_FLASH_CHUNK_SZ);
1798}
1799
1800static enum bfi_ioc_img_ver_cmp
1801bfa_ioc_flash_fwver_cmp(struct bfa_ioc *ioc,
1802 struct bfi_ioc_image_hdr *base_fwhdr)
1803{
1804 struct bfi_ioc_image_hdr *flash_fwhdr;
1805 enum bfa_status status;
1806 u32 fwimg[BFI_FLASH_CHUNK_SZ_WORDS];
1807
1808 status = bfa_nw_ioc_flash_img_get_chnk(ioc, 0, fwimg);
1809 if (status != BFA_STATUS_OK)
1810 return BFI_IOC_IMG_VER_INCOMP;
1811
1812 flash_fwhdr = (struct bfi_ioc_image_hdr *)fwimg;
1813 if (bfa_ioc_flash_fwver_valid(flash_fwhdr))
1814 return bfa_ioc_fw_ver_patch_cmp(base_fwhdr, flash_fwhdr);
1815 else
1816 return BFI_IOC_IMG_VER_INCOMP;
1817}
1818
1819/**
1820 * Returns TRUE if driver is willing to work with current smem f/w version.
1821 */
1321bool 1822bool
1322bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) 1823bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr)
1323{ 1824{
1324 struct bfi_ioc_image_hdr *drv_fwhdr; 1825 struct bfi_ioc_image_hdr *drv_fwhdr;
1325 int i; 1826 enum bfi_ioc_img_ver_cmp smem_flash_cmp, drv_smem_cmp;
1326 1827
1327 drv_fwhdr = (struct bfi_ioc_image_hdr *) 1828 drv_fwhdr = (struct bfi_ioc_image_hdr *)
1328 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0); 1829 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
1329 1830
1330 for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) { 1831 /* If smem is incompatible or old, driver should not work with it. */
1331 if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i]) 1832 drv_smem_cmp = bfa_ioc_fw_ver_patch_cmp(drv_fwhdr, fwhdr);
1332 return false; 1833 if (drv_smem_cmp == BFI_IOC_IMG_VER_INCOMP ||
1834 drv_smem_cmp == BFI_IOC_IMG_VER_OLD) {
1835 return false;
1333 } 1836 }
1334 1837
1335 return true; 1838 /* IF Flash has a better F/W than smem do not work with smem.
1839 * If smem f/w == flash f/w, as smem f/w not old | incmp, work with it.
1840 * If Flash is old or incomp work with smem iff smem f/w == drv f/w.
1841 */
1842 smem_flash_cmp = bfa_ioc_flash_fwver_cmp(ioc, fwhdr);
1843
1844 if (smem_flash_cmp == BFI_IOC_IMG_VER_BETTER)
1845 return false;
1846 else if (smem_flash_cmp == BFI_IOC_IMG_VER_SAME)
1847 return true;
1848 else
1849 return (drv_smem_cmp == BFI_IOC_IMG_VER_SAME) ?
1850 true : false;
1336} 1851}
1337 1852
1338/* Return true if current running version is valid. Firmware signature and 1853/* Return true if current running version is valid. Firmware signature and
@@ -1341,15 +1856,9 @@ bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr)
1341static bool 1856static bool
1342bfa_ioc_fwver_valid(struct bfa_ioc *ioc, u32 boot_env) 1857bfa_ioc_fwver_valid(struct bfa_ioc *ioc, u32 boot_env)
1343{ 1858{
1344 struct bfi_ioc_image_hdr fwhdr, *drv_fwhdr; 1859 struct bfi_ioc_image_hdr fwhdr;
1345 1860
1346 bfa_nw_ioc_fwver_get(ioc, &fwhdr); 1861 bfa_nw_ioc_fwver_get(ioc, &fwhdr);
1347 drv_fwhdr = (struct bfi_ioc_image_hdr *)
1348 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
1349
1350 if (fwhdr.signature != drv_fwhdr->signature)
1351 return false;
1352
1353 if (swab32(fwhdr.bootenv) != boot_env) 1862 if (swab32(fwhdr.bootenv) != boot_env)
1354 return false; 1863 return false;
1355 1864
@@ -1388,8 +1897,10 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
1388 false : bfa_ioc_fwver_valid(ioc, boot_env); 1897 false : bfa_ioc_fwver_valid(ioc, boot_env);
1389 1898
1390 if (!fwvalid) { 1899 if (!fwvalid) {
1391 bfa_ioc_boot(ioc, BFI_FWBOOT_TYPE_NORMAL, boot_env); 1900 if (bfa_ioc_boot(ioc, BFI_FWBOOT_TYPE_NORMAL, boot_env) ==
1392 bfa_ioc_poll_fwinit(ioc); 1901 BFA_STATUS_OK)
1902 bfa_ioc_poll_fwinit(ioc);
1903
1393 return; 1904 return;
1394 } 1905 }
1395 1906
@@ -1419,8 +1930,9 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force)
1419 /** 1930 /**
1420 * Initialize the h/w for any other states. 1931 * Initialize the h/w for any other states.
1421 */ 1932 */
1422 bfa_ioc_boot(ioc, BFI_FWBOOT_TYPE_NORMAL, boot_env); 1933 if (bfa_ioc_boot(ioc, BFI_FWBOOT_TYPE_NORMAL, boot_env) ==
1423 bfa_ioc_poll_fwinit(ioc); 1934 BFA_STATUS_OK)
1935 bfa_ioc_poll_fwinit(ioc);
1424} 1936}
1425 1937
1426void 1938void
@@ -1525,7 +2037,7 @@ bfa_ioc_hb_stop(struct bfa_ioc *ioc)
1525} 2037}
1526 2038
1527/* Initiate a full firmware download. */ 2039/* Initiate a full firmware download. */
1528static void 2040static enum bfa_status
1529bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type, 2041bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
1530 u32 boot_env) 2042 u32 boot_env)
1531{ 2043{
@@ -1535,18 +2047,47 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
1535 u32 chunkno = 0; 2047 u32 chunkno = 0;
1536 u32 i; 2048 u32 i;
1537 u32 asicmode; 2049 u32 asicmode;
2050 u32 fwimg_size;
2051 u32 fwimg_buf[BFI_FLASH_CHUNK_SZ_WORDS];
2052 enum bfa_status status;
2053
2054 if (boot_env == BFI_FWBOOT_ENV_OS &&
2055 boot_type == BFI_FWBOOT_TYPE_FLASH) {
2056 fwimg_size = BFI_FLASH_IMAGE_SZ/sizeof(u32);
2057
2058 status = bfa_nw_ioc_flash_img_get_chnk(ioc,
2059 BFA_IOC_FLASH_CHUNK_ADDR(chunkno), fwimg_buf);
2060 if (status != BFA_STATUS_OK)
2061 return status;
1538 2062
1539 fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), chunkno); 2063 fwimg = fwimg_buf;
2064 } else {
2065 fwimg_size = bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc));
2066 fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc),
2067 BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
2068 }
1540 2069
1541 pgnum = bfa_ioc_smem_pgnum(ioc, loff); 2070 pgnum = bfa_ioc_smem_pgnum(ioc, loff);
1542 2071
1543 writel(pgnum, ioc->ioc_regs.host_page_num_fn); 2072 writel(pgnum, ioc->ioc_regs.host_page_num_fn);
1544 2073
1545 for (i = 0; i < bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)); i++) { 2074 for (i = 0; i < fwimg_size; i++) {
1546 if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) { 2075 if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) {
1547 chunkno = BFA_IOC_FLASH_CHUNK_NO(i); 2076 chunkno = BFA_IOC_FLASH_CHUNK_NO(i);
1548 fwimg = bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 2077 if (boot_env == BFI_FWBOOT_ENV_OS &&
2078 boot_type == BFI_FWBOOT_TYPE_FLASH) {
2079 status = bfa_nw_ioc_flash_img_get_chnk(ioc,
2080 BFA_IOC_FLASH_CHUNK_ADDR(chunkno),
2081 fwimg_buf);
2082 if (status != BFA_STATUS_OK)
2083 return status;
2084
2085 fwimg = fwimg_buf;
2086 } else {
2087 fwimg = bfa_cb_image_get_chunk(
2088 bfa_ioc_asic_gen(ioc),
1549 BFA_IOC_FLASH_CHUNK_ADDR(chunkno)); 2089 BFA_IOC_FLASH_CHUNK_ADDR(chunkno));
2090 }
1550 } 2091 }
1551 2092
1552 /** 2093 /**
@@ -1574,6 +2115,10 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
1574 /* 2115 /*
1575 * Set boot type, env and device mode at the end. 2116 * Set boot type, env and device mode at the end.
1576 */ 2117 */
2118 if (boot_env == BFI_FWBOOT_ENV_OS &&
2119 boot_type == BFI_FWBOOT_TYPE_FLASH) {
2120 boot_type = BFI_FWBOOT_TYPE_NORMAL;
2121 }
1577 asicmode = BFI_FWBOOT_DEVMODE(ioc->asic_gen, ioc->asic_mode, 2122 asicmode = BFI_FWBOOT_DEVMODE(ioc->asic_gen, ioc->asic_mode,
1578 ioc->port0_mode, ioc->port1_mode); 2123 ioc->port0_mode, ioc->port1_mode);
1579 writel(asicmode, ((ioc->ioc_regs.smem_page_start) 2124 writel(asicmode, ((ioc->ioc_regs.smem_page_start)
@@ -1582,6 +2127,7 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type,
1582 + (BFI_FWBOOT_TYPE_OFF))); 2127 + (BFI_FWBOOT_TYPE_OFF)));
1583 writel(boot_env, ((ioc->ioc_regs.smem_page_start) 2128 writel(boot_env, ((ioc->ioc_regs.smem_page_start)
1584 + (BFI_FWBOOT_ENV_OFF))); 2129 + (BFI_FWBOOT_ENV_OFF)));
2130 return BFA_STATUS_OK;
1585} 2131}
1586 2132
1587static void 2133static void
@@ -1854,14 +2400,27 @@ bfa_ioc_pll_init(struct bfa_ioc *ioc)
1854/* Interface used by diag module to do firmware boot with memory test 2400/* Interface used by diag module to do firmware boot with memory test
1855 * as the entry vector. 2401 * as the entry vector.
1856 */ 2402 */
1857static void 2403static enum bfa_status
1858bfa_ioc_boot(struct bfa_ioc *ioc, enum bfi_fwboot_type boot_type, 2404bfa_ioc_boot(struct bfa_ioc *ioc, enum bfi_fwboot_type boot_type,
1859 u32 boot_env) 2405 u32 boot_env)
1860{ 2406{
2407 struct bfi_ioc_image_hdr *drv_fwhdr;
2408 enum bfa_status status;
1861 bfa_ioc_stats(ioc, ioc_boots); 2409 bfa_ioc_stats(ioc, ioc_boots);
1862 2410
1863 if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK) 2411 if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK)
1864 return; 2412 return BFA_STATUS_FAILED;
2413 if (boot_env == BFI_FWBOOT_ENV_OS &&
2414 boot_type == BFI_FWBOOT_TYPE_NORMAL) {
2415 drv_fwhdr = (struct bfi_ioc_image_hdr *)
2416 bfa_cb_image_get_chunk(bfa_ioc_asic_gen(ioc), 0);
2417 /* Work with Flash iff flash f/w is better than driver f/w.
2418 * Otherwise push drivers firmware.
2419 */
2420 if (bfa_ioc_flash_fwver_cmp(ioc, drv_fwhdr) ==
2421 BFI_IOC_IMG_VER_BETTER)
2422 boot_type = BFI_FWBOOT_TYPE_FLASH;
2423 }
1865 2424
1866 /** 2425 /**
1867 * Initialize IOC state of all functions on a chip reset. 2426 * Initialize IOC state of all functions on a chip reset.
@@ -1875,8 +2434,13 @@ bfa_ioc_boot(struct bfa_ioc *ioc, enum bfi_fwboot_type boot_type,
1875 } 2434 }
1876 2435
1877 bfa_ioc_msgflush(ioc); 2436 bfa_ioc_msgflush(ioc);
1878 bfa_ioc_download_fw(ioc, boot_type, boot_env); 2437 status = bfa_ioc_download_fw(ioc, boot_type, boot_env);
1879 bfa_ioc_lpu_start(ioc); 2438 if (status == BFA_STATUS_OK)
2439 bfa_ioc_lpu_start(ioc);
2440 else
2441 bfa_nw_iocpf_timeout(ioc);
2442
2443 return status;
1880} 2444}
1881 2445
1882/* Enable/disable IOC failure auto recovery. */ 2446/* Enable/disable IOC failure auto recovery. */
diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.h b/drivers/net/ethernet/brocade/bna/bfa_ioc.h
index 9521cbf446a8..20cff7df4b55 100644
--- a/drivers/net/ethernet/brocade/bna/bfa_ioc.h
+++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.h
@@ -298,6 +298,7 @@ void bfa_nw_ioc_error_isr(struct bfa_ioc *ioc);
298bool bfa_nw_ioc_is_disabled(struct bfa_ioc *ioc); 298bool bfa_nw_ioc_is_disabled(struct bfa_ioc *ioc);
299bool bfa_nw_ioc_is_operational(struct bfa_ioc *ioc); 299bool bfa_nw_ioc_is_operational(struct bfa_ioc *ioc);
300void bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr); 300void bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr);
301enum bfa_status bfa_nw_ioc_fwsig_invalidate(struct bfa_ioc *ioc);
301void bfa_nw_ioc_notify_register(struct bfa_ioc *ioc, 302void bfa_nw_ioc_notify_register(struct bfa_ioc *ioc,
302 struct bfa_ioc_notify *notify); 303 struct bfa_ioc_notify *notify);
303bool bfa_nw_ioc_sem_get(void __iomem *sem_reg); 304bool bfa_nw_ioc_sem_get(void __iomem *sem_reg);
diff --git a/drivers/net/ethernet/brocade/bna/bfi.h b/drivers/net/ethernet/brocade/bna/bfi.h
index 1f24c23dc786..8c563a77cdf6 100644
--- a/drivers/net/ethernet/brocade/bna/bfi.h
+++ b/drivers/net/ethernet/brocade/bna/bfi.h
@@ -25,6 +25,7 @@
25/* BFI FW image type */ 25/* BFI FW image type */
26#define BFI_FLASH_CHUNK_SZ 256 /*!< Flash chunk size */ 26#define BFI_FLASH_CHUNK_SZ 256 /*!< Flash chunk size */
27#define BFI_FLASH_CHUNK_SZ_WORDS (BFI_FLASH_CHUNK_SZ/sizeof(u32)) 27#define BFI_FLASH_CHUNK_SZ_WORDS (BFI_FLASH_CHUNK_SZ/sizeof(u32))
28#define BFI_FLASH_IMAGE_SZ 0x100000
28 29
29/* Msg header common to all msgs */ 30/* Msg header common to all msgs */
30struct bfi_mhdr { 31struct bfi_mhdr {
@@ -233,7 +234,29 @@ struct bfi_ioc_getattr_reply {
233#define BFI_IOC_TRC_HDR_SZ 32 234#define BFI_IOC_TRC_HDR_SZ 32
234 235
235#define BFI_IOC_FW_SIGNATURE (0xbfadbfad) 236#define BFI_IOC_FW_SIGNATURE (0xbfadbfad)
237#define BFI_IOC_FW_INV_SIGN (0xdeaddead)
236#define BFI_IOC_MD5SUM_SZ 4 238#define BFI_IOC_MD5SUM_SZ 4
239
240struct bfi_ioc_fwver {
241#ifdef __BIG_ENDIAN
242 u8 patch;
243 u8 maint;
244 u8 minor;
245 u8 major;
246 u8 rsvd[2];
247 u8 build;
248 u8 phase;
249#else
250 u8 major;
251 u8 minor;
252 u8 maint;
253 u8 patch;
254 u8 phase;
255 u8 build;
256 u8 rsvd[2];
257#endif
258};
259
237struct bfi_ioc_image_hdr { 260struct bfi_ioc_image_hdr {
238 u32 signature; /*!< constant signature */ 261 u32 signature; /*!< constant signature */
239 u8 asic_gen; /*!< asic generation */ 262 u8 asic_gen; /*!< asic generation */
@@ -242,10 +265,18 @@ struct bfi_ioc_image_hdr {
242 u8 port1_mode; /*!< device mode for port 1 */ 265 u8 port1_mode; /*!< device mode for port 1 */
243 u32 exec; /*!< exec vector */ 266 u32 exec; /*!< exec vector */
244 u32 bootenv; /*!< firmware boot env */ 267 u32 bootenv; /*!< firmware boot env */
245 u32 rsvd_b[4]; 268 u32 rsvd_b[2];
269 struct bfi_ioc_fwver fwver;
246 u32 md5sum[BFI_IOC_MD5SUM_SZ]; 270 u32 md5sum[BFI_IOC_MD5SUM_SZ];
247}; 271};
248 272
273enum bfi_ioc_img_ver_cmp {
274 BFI_IOC_IMG_VER_INCOMP,
275 BFI_IOC_IMG_VER_OLD,
276 BFI_IOC_IMG_VER_SAME,
277 BFI_IOC_IMG_VER_BETTER
278};
279
249#define BFI_FWBOOT_DEVMODE_OFF 4 280#define BFI_FWBOOT_DEVMODE_OFF 4
250#define BFI_FWBOOT_TYPE_OFF 8 281#define BFI_FWBOOT_TYPE_OFF 8
251#define BFI_FWBOOT_ENV_OFF 12 282#define BFI_FWBOOT_ENV_OFF 12
diff --git a/drivers/net/ethernet/brocade/bna/cna.h b/drivers/net/ethernet/brocade/bna/cna.h
index 43405f654b4a..b3ff6d507951 100644
--- a/drivers/net/ethernet/brocade/bna/cna.h
+++ b/drivers/net/ethernet/brocade/bna/cna.h
@@ -37,8 +37,8 @@
37 37
38extern char bfa_version[]; 38extern char bfa_version[];
39 39
40#define CNA_FW_FILE_CT "ctfw-3.2.1.1.bin" 40#define CNA_FW_FILE_CT "ctfw-3.2.3.0.bin"
41#define CNA_FW_FILE_CT2 "ct2fw-3.2.1.1.bin" 41#define CNA_FW_FILE_CT2 "ct2fw-3.2.3.0.bin"
42#define FC_SYMNAME_MAX 256 /*!< max name server symbolic name size */ 42#define FC_SYMNAME_MAX 256 /*!< max name server symbolic name size */
43 43
44#pragma pack(1) 44#pragma pack(1)