diff options
author | Ajit Khaparde <ajitkhaparde@gmail.com> | 2010-02-08 20:30:35 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-12 15:27:57 -0500 |
commit | 3f0d4560aedaa67546eaeb3dc75fcdf68ec21036 (patch) | |
tree | 419489b855a61a6f4a347ff143a4576305a84d39 /drivers/net/benet/be_main.c | |
parent | e254f6ecaeb4e7c0588e739bf4641df0e8c22bba (diff) |
be2net: bug fix for flashing the BladeEngine3 ASIC
Now flashing both BE2 and BE3 devices is supported.
From: Naresh G <nareshg@serverengines.com>
Signed-off-by: Ajit Khaparde <ajitk@serverengines.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/benet/be_main.c')
-rw-r--r-- | drivers/net/benet/be_main.c | 239 |
1 files changed, 127 insertions, 112 deletions
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 0779f6b5e29..99061488eeb 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -1798,15 +1798,19 @@ char flash_cookie[2][16] = {"*** SE FLAS", | |||
1798 | "H DIRECTORY *** "}; | 1798 | "H DIRECTORY *** "}; |
1799 | 1799 | ||
1800 | static bool be_flash_redboot(struct be_adapter *adapter, | 1800 | static bool be_flash_redboot(struct be_adapter *adapter, |
1801 | const u8 *p) | 1801 | const u8 *p, u32 img_start, int image_size, |
1802 | int hdr_size) | ||
1802 | { | 1803 | { |
1803 | u32 crc_offset; | 1804 | u32 crc_offset; |
1804 | u8 flashed_crc[4]; | 1805 | u8 flashed_crc[4]; |
1805 | int status; | 1806 | int status; |
1806 | crc_offset = FLASH_REDBOOT_START + FLASH_REDBOOT_IMAGE_MAX_SIZE - 4 | 1807 | |
1807 | + sizeof(struct flash_file_hdr) - 32*1024; | 1808 | crc_offset = hdr_size + img_start + image_size - 4; |
1809 | |||
1808 | p += crc_offset; | 1810 | p += crc_offset; |
1809 | status = be_cmd_get_flash_crc(adapter, flashed_crc); | 1811 | |
1812 | status = be_cmd_get_flash_crc(adapter, flashed_crc, | ||
1813 | (img_start + image_size - 4)); | ||
1810 | if (status) { | 1814 | if (status) { |
1811 | dev_err(&adapter->pdev->dev, | 1815 | dev_err(&adapter->pdev->dev, |
1812 | "could not get crc from flash, not flashing redboot\n"); | 1816 | "could not get crc from flash, not flashing redboot\n"); |
@@ -1818,102 +1822,124 @@ static bool be_flash_redboot(struct be_adapter *adapter, | |||
1818 | return false; | 1822 | return false; |
1819 | else | 1823 | else |
1820 | return true; | 1824 | return true; |
1821 | |||
1822 | } | 1825 | } |
1823 | 1826 | ||
1824 | static int be_flash_image(struct be_adapter *adapter, | 1827 | static int be_flash_data(struct be_adapter *adapter, |
1825 | const struct firmware *fw, | 1828 | const struct firmware *fw, |
1826 | struct be_dma_mem *flash_cmd, u32 flash_type) | 1829 | struct be_dma_mem *flash_cmd, int num_of_images) |
1830 | |||
1827 | { | 1831 | { |
1828 | int status; | 1832 | int status = 0, i, filehdr_size = 0; |
1829 | u32 flash_op, image_offset = 0, total_bytes, image_size = 0; | 1833 | u32 total_bytes = 0, flash_op; |
1830 | int num_bytes; | 1834 | int num_bytes; |
1831 | const u8 *p = fw->data; | 1835 | const u8 *p = fw->data; |
1832 | struct be_cmd_write_flashrom *req = flash_cmd->va; | 1836 | struct be_cmd_write_flashrom *req = flash_cmd->va; |
1833 | 1837 | struct flash_comp *pflashcomp; | |
1834 | switch (flash_type) { | 1838 | |
1835 | case FLASHROM_TYPE_ISCSI_ACTIVE: | 1839 | struct flash_comp gen3_flash_types[8] = { |
1836 | image_offset = FLASH_iSCSI_PRIMARY_IMAGE_START; | 1840 | { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE, |
1837 | image_size = FLASH_IMAGE_MAX_SIZE; | 1841 | FLASH_IMAGE_MAX_SIZE_g3}, |
1838 | break; | 1842 | { FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT, |
1839 | case FLASHROM_TYPE_ISCSI_BACKUP: | 1843 | FLASH_REDBOOT_IMAGE_MAX_SIZE_g3}, |
1840 | image_offset = FLASH_iSCSI_BACKUP_IMAGE_START; | 1844 | { FLASH_iSCSI_BIOS_START_g3, IMG_TYPE_BIOS, |
1841 | image_size = FLASH_IMAGE_MAX_SIZE; | 1845 | FLASH_BIOS_IMAGE_MAX_SIZE_g3}, |
1842 | break; | 1846 | { FLASH_PXE_BIOS_START_g3, IMG_TYPE_PXE_BIOS, |
1843 | case FLASHROM_TYPE_FCOE_FW_ACTIVE: | 1847 | FLASH_BIOS_IMAGE_MAX_SIZE_g3}, |
1844 | image_offset = FLASH_FCoE_PRIMARY_IMAGE_START; | 1848 | { FLASH_FCoE_BIOS_START_g3, IMG_TYPE_FCOE_BIOS, |
1845 | image_size = FLASH_IMAGE_MAX_SIZE; | 1849 | FLASH_BIOS_IMAGE_MAX_SIZE_g3}, |
1846 | break; | 1850 | { FLASH_iSCSI_BACKUP_IMAGE_START_g3, IMG_TYPE_ISCSI_BACKUP, |
1847 | case FLASHROM_TYPE_FCOE_FW_BACKUP: | 1851 | FLASH_IMAGE_MAX_SIZE_g3}, |
1848 | image_offset = FLASH_FCoE_BACKUP_IMAGE_START; | 1852 | { FLASH_FCoE_PRIMARY_IMAGE_START_g3, IMG_TYPE_FCOE_FW_ACTIVE, |
1849 | image_size = FLASH_IMAGE_MAX_SIZE; | 1853 | FLASH_IMAGE_MAX_SIZE_g3}, |
1850 | break; | 1854 | { FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP, |
1851 | case FLASHROM_TYPE_BIOS: | 1855 | FLASH_IMAGE_MAX_SIZE_g3} |
1852 | image_offset = FLASH_iSCSI_BIOS_START; | 1856 | }; |
1853 | image_size = FLASH_BIOS_IMAGE_MAX_SIZE; | 1857 | struct flash_comp gen2_flash_types[8] = { |
1854 | break; | 1858 | { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE, |
1855 | case FLASHROM_TYPE_FCOE_BIOS: | 1859 | FLASH_IMAGE_MAX_SIZE_g2}, |
1856 | image_offset = FLASH_FCoE_BIOS_START; | 1860 | { FLASH_REDBOOT_START_g2, IMG_TYPE_REDBOOT, |
1857 | image_size = FLASH_BIOS_IMAGE_MAX_SIZE; | 1861 | FLASH_REDBOOT_IMAGE_MAX_SIZE_g2}, |
1858 | break; | 1862 | { FLASH_iSCSI_BIOS_START_g2, IMG_TYPE_BIOS, |
1859 | case FLASHROM_TYPE_PXE_BIOS: | 1863 | FLASH_BIOS_IMAGE_MAX_SIZE_g2}, |
1860 | image_offset = FLASH_PXE_BIOS_START; | 1864 | { FLASH_PXE_BIOS_START_g2, IMG_TYPE_PXE_BIOS, |
1861 | image_size = FLASH_BIOS_IMAGE_MAX_SIZE; | 1865 | FLASH_BIOS_IMAGE_MAX_SIZE_g2}, |
1862 | break; | 1866 | { FLASH_FCoE_BIOS_START_g2, IMG_TYPE_FCOE_BIOS, |
1863 | case FLASHROM_TYPE_REDBOOT: | 1867 | FLASH_BIOS_IMAGE_MAX_SIZE_g2}, |
1864 | if (!be_flash_redboot(adapter, fw->data)) | 1868 | { FLASH_iSCSI_BACKUP_IMAGE_START_g2, IMG_TYPE_ISCSI_BACKUP, |
1865 | return 0; | 1869 | FLASH_IMAGE_MAX_SIZE_g2}, |
1866 | image_offset = FLASH_REDBOOT_ISM_START; | 1870 | { FLASH_FCoE_PRIMARY_IMAGE_START_g2, IMG_TYPE_FCOE_FW_ACTIVE, |
1867 | image_size = FLASH_REDBOOT_IMAGE_MAX_SIZE; | 1871 | FLASH_IMAGE_MAX_SIZE_g2}, |
1868 | break; | 1872 | { FLASH_FCoE_BACKUP_IMAGE_START_g2, IMG_TYPE_FCOE_FW_BACKUP, |
1869 | default: | 1873 | FLASH_IMAGE_MAX_SIZE_g2} |
1870 | return 0; | 1874 | }; |
1875 | |||
1876 | if (adapter->generation == BE_GEN3) { | ||
1877 | pflashcomp = gen3_flash_types; | ||
1878 | filehdr_size = sizeof(struct flash_file_hdr_g3); | ||
1879 | } else { | ||
1880 | pflashcomp = gen2_flash_types; | ||
1881 | filehdr_size = sizeof(struct flash_file_hdr_g2); | ||
1871 | } | 1882 | } |
1872 | 1883 | for (i = 0; i < 8; i++) { | |
1873 | p += sizeof(struct flash_file_hdr) + image_offset; | 1884 | if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) && |
1874 | if (p + image_size > fw->data + fw->size) | 1885 | (!be_flash_redboot(adapter, fw->data, |
1886 | pflashcomp[i].offset, pflashcomp[i].size, | ||
1887 | filehdr_size))) | ||
1888 | continue; | ||
1889 | p = fw->data; | ||
1890 | p += filehdr_size + pflashcomp[i].offset | ||
1891 | + (num_of_images * sizeof(struct image_hdr)); | ||
1892 | if (p + pflashcomp[i].size > fw->data + fw->size) | ||
1875 | return -1; | 1893 | return -1; |
1876 | 1894 | total_bytes = pflashcomp[i].size; | |
1877 | total_bytes = image_size; | 1895 | while (total_bytes) { |
1878 | 1896 | if (total_bytes > 32*1024) | |
1879 | while (total_bytes) { | 1897 | num_bytes = 32*1024; |
1880 | if (total_bytes > 32*1024) | 1898 | else |
1881 | num_bytes = 32*1024; | 1899 | num_bytes = total_bytes; |
1882 | else | 1900 | total_bytes -= num_bytes; |
1883 | num_bytes = total_bytes; | 1901 | |
1884 | total_bytes -= num_bytes; | 1902 | if (!total_bytes) |
1885 | 1903 | flash_op = FLASHROM_OPER_FLASH; | |
1886 | if (!total_bytes) | 1904 | else |
1887 | flash_op = FLASHROM_OPER_FLASH; | 1905 | flash_op = FLASHROM_OPER_SAVE; |
1888 | else | 1906 | memcpy(req->params.data_buf, p, num_bytes); |
1889 | flash_op = FLASHROM_OPER_SAVE; | 1907 | p += num_bytes; |
1890 | memcpy(req->params.data_buf, p, num_bytes); | 1908 | status = be_cmd_write_flashrom(adapter, flash_cmd, |
1891 | p += num_bytes; | 1909 | pflashcomp[i].optype, flash_op, num_bytes); |
1892 | status = be_cmd_write_flashrom(adapter, flash_cmd, | 1910 | if (status) { |
1893 | flash_type, flash_op, num_bytes); | 1911 | dev_err(&adapter->pdev->dev, |
1894 | if (status) { | 1912 | "cmd to write to flash rom failed.\n"); |
1895 | dev_err(&adapter->pdev->dev, | 1913 | return -1; |
1896 | "cmd to write to flash rom failed. type/op %d/%d\n", | 1914 | } |
1897 | flash_type, flash_op); | 1915 | yield(); |
1898 | return -1; | ||
1899 | } | 1916 | } |
1900 | yield(); | ||
1901 | } | 1917 | } |
1902 | |||
1903 | return 0; | 1918 | return 0; |
1904 | } | 1919 | } |
1905 | 1920 | ||
1921 | static int get_ufigen_type(struct flash_file_hdr_g2 *fhdr) | ||
1922 | { | ||
1923 | if (fhdr == NULL) | ||
1924 | return 0; | ||
1925 | if (fhdr->build[0] == '3') | ||
1926 | return BE_GEN3; | ||
1927 | else if (fhdr->build[0] == '2') | ||
1928 | return BE_GEN2; | ||
1929 | else | ||
1930 | return 0; | ||
1931 | } | ||
1932 | |||
1906 | int be_load_fw(struct be_adapter *adapter, u8 *func) | 1933 | int be_load_fw(struct be_adapter *adapter, u8 *func) |
1907 | { | 1934 | { |
1908 | char fw_file[ETHTOOL_FLASH_MAX_FILENAME]; | 1935 | char fw_file[ETHTOOL_FLASH_MAX_FILENAME]; |
1909 | const struct firmware *fw; | 1936 | const struct firmware *fw; |
1910 | struct flash_file_hdr *fhdr; | 1937 | struct flash_file_hdr_g2 *fhdr; |
1911 | struct flash_section_info *fsec = NULL; | 1938 | struct flash_file_hdr_g3 *fhdr3; |
1939 | struct image_hdr *img_hdr_ptr = NULL; | ||
1912 | struct be_dma_mem flash_cmd; | 1940 | struct be_dma_mem flash_cmd; |
1913 | int status; | 1941 | int status, i = 0; |
1914 | const u8 *p; | 1942 | const u8 *p; |
1915 | bool entry_found = false; | ||
1916 | int flash_type; | ||
1917 | char fw_ver[FW_VER_LEN]; | 1943 | char fw_ver[FW_VER_LEN]; |
1918 | char fw_cfg; | 1944 | char fw_cfg; |
1919 | 1945 | ||
@@ -1931,34 +1957,9 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) | |||
1931 | goto fw_exit; | 1957 | goto fw_exit; |
1932 | 1958 | ||
1933 | p = fw->data; | 1959 | p = fw->data; |
1934 | fhdr = (struct flash_file_hdr *) p; | 1960 | fhdr = (struct flash_file_hdr_g2 *) p; |
1935 | if (memcmp(fhdr->sign, FW_FILE_HDR_SIGN, strlen(FW_FILE_HDR_SIGN))) { | ||
1936 | dev_err(&adapter->pdev->dev, | ||
1937 | "Firmware(%s) load error (signature did not match)\n", | ||
1938 | fw_file); | ||
1939 | status = -1; | ||
1940 | goto fw_exit; | ||
1941 | } | ||
1942 | |||
1943 | dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file); | 1961 | dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file); |
1944 | 1962 | ||
1945 | p += sizeof(struct flash_file_hdr); | ||
1946 | while (p < (fw->data + fw->size)) { | ||
1947 | fsec = (struct flash_section_info *)p; | ||
1948 | if (!memcmp(flash_cookie, fsec->cookie, sizeof(flash_cookie))) { | ||
1949 | entry_found = true; | ||
1950 | break; | ||
1951 | } | ||
1952 | p += 32; | ||
1953 | } | ||
1954 | |||
1955 | if (!entry_found) { | ||
1956 | status = -1; | ||
1957 | dev_err(&adapter->pdev->dev, | ||
1958 | "Flash cookie not found in firmware image\n"); | ||
1959 | goto fw_exit; | ||
1960 | } | ||
1961 | |||
1962 | flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024; | 1963 | flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024; |
1963 | flash_cmd.va = pci_alloc_consistent(adapter->pdev, flash_cmd.size, | 1964 | flash_cmd.va = pci_alloc_consistent(adapter->pdev, flash_cmd.size, |
1964 | &flash_cmd.dma); | 1965 | &flash_cmd.dma); |
@@ -1969,12 +1970,26 @@ int be_load_fw(struct be_adapter *adapter, u8 *func) | |||
1969 | goto fw_exit; | 1970 | goto fw_exit; |
1970 | } | 1971 | } |
1971 | 1972 | ||
1972 | for (flash_type = FLASHROM_TYPE_ISCSI_ACTIVE; | 1973 | if ((adapter->generation == BE_GEN3) && |
1973 | flash_type <= FLASHROM_TYPE_FCOE_FW_BACKUP; flash_type++) { | 1974 | (get_ufigen_type(fhdr) == BE_GEN3)) { |
1974 | status = be_flash_image(adapter, fw, &flash_cmd, | 1975 | fhdr3 = (struct flash_file_hdr_g3 *) fw->data; |
1975 | flash_type); | 1976 | for (i = 0; i < fhdr3->num_imgs; i++) { |
1976 | if (status) | 1977 | img_hdr_ptr = (struct image_hdr *) (fw->data + |
1977 | break; | 1978 | (sizeof(struct flash_file_hdr_g3) + |
1979 | i * sizeof(struct image_hdr))); | ||
1980 | if (img_hdr_ptr->imageid == 1) { | ||
1981 | status = be_flash_data(adapter, fw, | ||
1982 | &flash_cmd, fhdr3->num_imgs); | ||
1983 | } | ||
1984 | |||
1985 | } | ||
1986 | } else if ((adapter->generation == BE_GEN2) && | ||
1987 | (get_ufigen_type(fhdr) == BE_GEN2)) { | ||
1988 | status = be_flash_data(adapter, fw, &flash_cmd, 0); | ||
1989 | } else { | ||
1990 | dev_err(&adapter->pdev->dev, | ||
1991 | "UFI and Interface are not compatible for flashing\n"); | ||
1992 | status = -1; | ||
1978 | } | 1993 | } |
1979 | 1994 | ||
1980 | pci_free_consistent(adapter->pdev, flash_cmd.size, flash_cmd.va, | 1995 | pci_free_consistent(adapter->pdev, flash_cmd.size, flash_cmd.va, |