diff options
author | Kou Ishizaki <kou.ishizaki@toshiba.co.jp> | 2007-02-20 17:34:50 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-27 04:16:03 -0500 |
commit | 3cf761ddccb9332218973e17f9b987bb5cae7b69 (patch) | |
tree | cde24a6922ef6988d301dff011782bb83cc2dd50 | |
parent | abdb66b566fce5641c90100e0a113a94bab43fda (diff) |
spidernet: load firmware when open
This patch moves calling init_firmware() from spider_net_probe() to
spider_net_open() so as to use the driver by built-in.
Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/net/spider_net.c | 247 |
1 files changed, 123 insertions, 124 deletions
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 8aa3ebe2a0ec..fef455694d7a 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c | |||
@@ -1705,6 +1705,124 @@ spider_net_enable_card(struct spider_net_card *card) | |||
1705 | } | 1705 | } |
1706 | 1706 | ||
1707 | /** | 1707 | /** |
1708 | * spider_net_download_firmware - loads firmware into the adapter | ||
1709 | * @card: card structure | ||
1710 | * @firmware_ptr: pointer to firmware data | ||
1711 | * | ||
1712 | * spider_net_download_firmware loads the firmware data into the | ||
1713 | * adapter. It assumes the length etc. to be allright. | ||
1714 | */ | ||
1715 | static int | ||
1716 | spider_net_download_firmware(struct spider_net_card *card, | ||
1717 | const void *firmware_ptr) | ||
1718 | { | ||
1719 | int sequencer, i; | ||
1720 | const u32 *fw_ptr = firmware_ptr; | ||
1721 | |||
1722 | /* stop sequencers */ | ||
1723 | spider_net_write_reg(card, SPIDER_NET_GSINIT, | ||
1724 | SPIDER_NET_STOP_SEQ_VALUE); | ||
1725 | |||
1726 | for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS; | ||
1727 | sequencer++) { | ||
1728 | spider_net_write_reg(card, | ||
1729 | SPIDER_NET_GSnPRGADR + sequencer * 8, 0); | ||
1730 | for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) { | ||
1731 | spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + | ||
1732 | sequencer * 8, *fw_ptr); | ||
1733 | fw_ptr++; | ||
1734 | } | ||
1735 | } | ||
1736 | |||
1737 | if (spider_net_read_reg(card, SPIDER_NET_GSINIT)) | ||
1738 | return -EIO; | ||
1739 | |||
1740 | spider_net_write_reg(card, SPIDER_NET_GSINIT, | ||
1741 | SPIDER_NET_RUN_SEQ_VALUE); | ||
1742 | |||
1743 | return 0; | ||
1744 | } | ||
1745 | |||
1746 | /** | ||
1747 | * spider_net_init_firmware - reads in firmware parts | ||
1748 | * @card: card structure | ||
1749 | * | ||
1750 | * Returns 0 on success, <0 on failure | ||
1751 | * | ||
1752 | * spider_net_init_firmware opens the sequencer firmware and does some basic | ||
1753 | * checks. This function opens and releases the firmware structure. A call | ||
1754 | * to download the firmware is performed before the release. | ||
1755 | * | ||
1756 | * Firmware format | ||
1757 | * =============== | ||
1758 | * spider_fw.bin is expected to be a file containing 6*1024*4 bytes, 4k being | ||
1759 | * the program for each sequencer. Use the command | ||
1760 | * tail -q -n +2 Seq_code1_0x088.txt Seq_code2_0x090.txt \ | ||
1761 | * Seq_code3_0x098.txt Seq_code4_0x0A0.txt Seq_code5_0x0A8.txt \ | ||
1762 | * Seq_code6_0x0B0.txt | xxd -r -p -c4 > spider_fw.bin | ||
1763 | * | ||
1764 | * to generate spider_fw.bin, if you have sequencer programs with something | ||
1765 | * like the following contents for each sequencer: | ||
1766 | * <ONE LINE COMMENT> | ||
1767 | * <FIRST 4-BYTES-WORD FOR SEQUENCER> | ||
1768 | * <SECOND 4-BYTES-WORD FOR SEQUENCER> | ||
1769 | * ... | ||
1770 | * <1024th 4-BYTES-WORD FOR SEQUENCER> | ||
1771 | */ | ||
1772 | static int | ||
1773 | spider_net_init_firmware(struct spider_net_card *card) | ||
1774 | { | ||
1775 | struct firmware *firmware = NULL; | ||
1776 | struct device_node *dn; | ||
1777 | const u8 *fw_prop = NULL; | ||
1778 | int err = -ENOENT; | ||
1779 | int fw_size; | ||
1780 | |||
1781 | if (request_firmware((const struct firmware **)&firmware, | ||
1782 | SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) == 0) { | ||
1783 | if ( (firmware->size != SPIDER_NET_FIRMWARE_LEN) && | ||
1784 | netif_msg_probe(card) ) { | ||
1785 | pr_err("Incorrect size of spidernet firmware in " \ | ||
1786 | "filesystem. Looking in host firmware...\n"); | ||
1787 | goto try_host_fw; | ||
1788 | } | ||
1789 | err = spider_net_download_firmware(card, firmware->data); | ||
1790 | |||
1791 | release_firmware(firmware); | ||
1792 | if (err) | ||
1793 | goto try_host_fw; | ||
1794 | |||
1795 | goto done; | ||
1796 | } | ||
1797 | |||
1798 | try_host_fw: | ||
1799 | dn = pci_device_to_OF_node(card->pdev); | ||
1800 | if (!dn) | ||
1801 | goto out_err; | ||
1802 | |||
1803 | fw_prop = get_property(dn, "firmware", &fw_size); | ||
1804 | if (!fw_prop) | ||
1805 | goto out_err; | ||
1806 | |||
1807 | if ( (fw_size != SPIDER_NET_FIRMWARE_LEN) && | ||
1808 | netif_msg_probe(card) ) { | ||
1809 | pr_err("Incorrect size of spidernet firmware in " \ | ||
1810 | "host firmware\n"); | ||
1811 | goto done; | ||
1812 | } | ||
1813 | |||
1814 | err = spider_net_download_firmware(card, fw_prop); | ||
1815 | |||
1816 | done: | ||
1817 | return err; | ||
1818 | out_err: | ||
1819 | if (netif_msg_probe(card)) | ||
1820 | pr_err("Couldn't find spidernet firmware in filesystem " \ | ||
1821 | "or host firmware\n"); | ||
1822 | return err; | ||
1823 | } | ||
1824 | |||
1825 | /** | ||
1708 | * spider_net_open - called upon ifonfig up | 1826 | * spider_net_open - called upon ifonfig up |
1709 | * @netdev: interface device structure | 1827 | * @netdev: interface device structure |
1710 | * | 1828 | * |
@@ -1719,6 +1837,10 @@ spider_net_open(struct net_device *netdev) | |||
1719 | struct spider_net_card *card = netdev_priv(netdev); | 1837 | struct spider_net_card *card = netdev_priv(netdev); |
1720 | int result; | 1838 | int result; |
1721 | 1839 | ||
1840 | result = spider_net_init_firmware(card); | ||
1841 | if (result) | ||
1842 | goto init_firmware_failed; | ||
1843 | |||
1722 | /* start probing with copper */ | 1844 | /* start probing with copper */ |
1723 | spider_net_setup_aneg(card); | 1845 | spider_net_setup_aneg(card); |
1724 | if (card->phy.def->phy_id) | 1846 | if (card->phy.def->phy_id) |
@@ -1762,6 +1884,7 @@ alloc_rx_failed: | |||
1762 | spider_net_free_chain(card, &card->tx_chain); | 1884 | spider_net_free_chain(card, &card->tx_chain); |
1763 | alloc_tx_failed: | 1885 | alloc_tx_failed: |
1764 | del_timer_sync(&card->aneg_timer); | 1886 | del_timer_sync(&card->aneg_timer); |
1887 | init_firmware_failed: | ||
1765 | return result; | 1888 | return result; |
1766 | } | 1889 | } |
1767 | 1890 | ||
@@ -1873,124 +1996,6 @@ spider_net_setup_phy(struct spider_net_card *card) | |||
1873 | } | 1996 | } |
1874 | 1997 | ||
1875 | /** | 1998 | /** |
1876 | * spider_net_download_firmware - loads firmware into the adapter | ||
1877 | * @card: card structure | ||
1878 | * @firmware_ptr: pointer to firmware data | ||
1879 | * | ||
1880 | * spider_net_download_firmware loads the firmware data into the | ||
1881 | * adapter. It assumes the length etc. to be allright. | ||
1882 | */ | ||
1883 | static int | ||
1884 | spider_net_download_firmware(struct spider_net_card *card, | ||
1885 | const void *firmware_ptr) | ||
1886 | { | ||
1887 | int sequencer, i; | ||
1888 | const u32 *fw_ptr = firmware_ptr; | ||
1889 | |||
1890 | /* stop sequencers */ | ||
1891 | spider_net_write_reg(card, SPIDER_NET_GSINIT, | ||
1892 | SPIDER_NET_STOP_SEQ_VALUE); | ||
1893 | |||
1894 | for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS; | ||
1895 | sequencer++) { | ||
1896 | spider_net_write_reg(card, | ||
1897 | SPIDER_NET_GSnPRGADR + sequencer * 8, 0); | ||
1898 | for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) { | ||
1899 | spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + | ||
1900 | sequencer * 8, *fw_ptr); | ||
1901 | fw_ptr++; | ||
1902 | } | ||
1903 | } | ||
1904 | |||
1905 | if (spider_net_read_reg(card, SPIDER_NET_GSINIT)) | ||
1906 | return -EIO; | ||
1907 | |||
1908 | spider_net_write_reg(card, SPIDER_NET_GSINIT, | ||
1909 | SPIDER_NET_RUN_SEQ_VALUE); | ||
1910 | |||
1911 | return 0; | ||
1912 | } | ||
1913 | |||
1914 | /** | ||
1915 | * spider_net_init_firmware - reads in firmware parts | ||
1916 | * @card: card structure | ||
1917 | * | ||
1918 | * Returns 0 on success, <0 on failure | ||
1919 | * | ||
1920 | * spider_net_init_firmware opens the sequencer firmware and does some basic | ||
1921 | * checks. This function opens and releases the firmware structure. A call | ||
1922 | * to download the firmware is performed before the release. | ||
1923 | * | ||
1924 | * Firmware format | ||
1925 | * =============== | ||
1926 | * spider_fw.bin is expected to be a file containing 6*1024*4 bytes, 4k being | ||
1927 | * the program for each sequencer. Use the command | ||
1928 | * tail -q -n +2 Seq_code1_0x088.txt Seq_code2_0x090.txt \ | ||
1929 | * Seq_code3_0x098.txt Seq_code4_0x0A0.txt Seq_code5_0x0A8.txt \ | ||
1930 | * Seq_code6_0x0B0.txt | xxd -r -p -c4 > spider_fw.bin | ||
1931 | * | ||
1932 | * to generate spider_fw.bin, if you have sequencer programs with something | ||
1933 | * like the following contents for each sequencer: | ||
1934 | * <ONE LINE COMMENT> | ||
1935 | * <FIRST 4-BYTES-WORD FOR SEQUENCER> | ||
1936 | * <SECOND 4-BYTES-WORD FOR SEQUENCER> | ||
1937 | * ... | ||
1938 | * <1024th 4-BYTES-WORD FOR SEQUENCER> | ||
1939 | */ | ||
1940 | static int | ||
1941 | spider_net_init_firmware(struct spider_net_card *card) | ||
1942 | { | ||
1943 | struct firmware *firmware = NULL; | ||
1944 | struct device_node *dn; | ||
1945 | const u8 *fw_prop = NULL; | ||
1946 | int err = -ENOENT; | ||
1947 | int fw_size; | ||
1948 | |||
1949 | if (request_firmware((const struct firmware **)&firmware, | ||
1950 | SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) == 0) { | ||
1951 | if ( (firmware->size != SPIDER_NET_FIRMWARE_LEN) && | ||
1952 | netif_msg_probe(card) ) { | ||
1953 | pr_err("Incorrect size of spidernet firmware in " \ | ||
1954 | "filesystem. Looking in host firmware...\n"); | ||
1955 | goto try_host_fw; | ||
1956 | } | ||
1957 | err = spider_net_download_firmware(card, firmware->data); | ||
1958 | |||
1959 | release_firmware(firmware); | ||
1960 | if (err) | ||
1961 | goto try_host_fw; | ||
1962 | |||
1963 | goto done; | ||
1964 | } | ||
1965 | |||
1966 | try_host_fw: | ||
1967 | dn = pci_device_to_OF_node(card->pdev); | ||
1968 | if (!dn) | ||
1969 | goto out_err; | ||
1970 | |||
1971 | fw_prop = get_property(dn, "firmware", &fw_size); | ||
1972 | if (!fw_prop) | ||
1973 | goto out_err; | ||
1974 | |||
1975 | if ( (fw_size != SPIDER_NET_FIRMWARE_LEN) && | ||
1976 | netif_msg_probe(card) ) { | ||
1977 | pr_err("Incorrect size of spidernet firmware in " \ | ||
1978 | "host firmware\n"); | ||
1979 | goto done; | ||
1980 | } | ||
1981 | |||
1982 | err = spider_net_download_firmware(card, fw_prop); | ||
1983 | |||
1984 | done: | ||
1985 | return err; | ||
1986 | out_err: | ||
1987 | if (netif_msg_probe(card)) | ||
1988 | pr_err("Couldn't find spidernet firmware in filesystem " \ | ||
1989 | "or host firmware\n"); | ||
1990 | return err; | ||
1991 | } | ||
1992 | |||
1993 | /** | ||
1994 | * spider_net_workaround_rxramfull - work around firmware bug | 1999 | * spider_net_workaround_rxramfull - work around firmware bug |
1995 | * @card: card structure | 2000 | * @card: card structure |
1996 | * | 2001 | * |
@@ -2090,8 +2095,6 @@ spider_net_tx_timeout_task(struct work_struct *work) | |||
2090 | 2095 | ||
2091 | if (spider_net_setup_phy(card)) | 2096 | if (spider_net_setup_phy(card)) |
2092 | goto out; | 2097 | goto out; |
2093 | if (spider_net_init_firmware(card)) | ||
2094 | goto out; | ||
2095 | 2098 | ||
2096 | spider_net_open(netdev); | 2099 | spider_net_open(netdev); |
2097 | spider_net_kick_tx_dma(card); | 2100 | spider_net_kick_tx_dma(card); |
@@ -2363,10 +2366,6 @@ spider_net_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2363 | if (err) | 2366 | if (err) |
2364 | goto out_undo_pci; | 2367 | goto out_undo_pci; |
2365 | 2368 | ||
2366 | err = spider_net_init_firmware(card); | ||
2367 | if (err) | ||
2368 | goto out_undo_pci; | ||
2369 | |||
2370 | err = spider_net_setup_netdev(card); | 2369 | err = spider_net_setup_netdev(card); |
2371 | if (err) | 2370 | if (err) |
2372 | goto out_undo_pci; | 2371 | goto out_undo_pci; |