aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/spider_net.c
diff options
context:
space:
mode:
authorKou Ishizaki <kou.ishizaki@toshiba.co.jp>2007-02-20 17:34:50 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-27 04:16:03 -0500
commit3cf761ddccb9332218973e17f9b987bb5cae7b69 (patch)
treecde24a6922ef6988d301dff011782bb83cc2dd50 /drivers/net/spider_net.c
parentabdb66b566fce5641c90100e0a113a94bab43fda (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>
Diffstat (limited to 'drivers/net/spider_net.c')
-rw-r--r--drivers/net/spider_net.c247
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 */
1715static int
1716spider_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 */
1772static int
1773spider_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
1798try_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
1816done:
1817 return err;
1818out_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);
1763alloc_tx_failed: 1885alloc_tx_failed:
1764 del_timer_sync(&card->aneg_timer); 1886 del_timer_sync(&card->aneg_timer);
1887init_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 */
1883static int
1884spider_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 */
1940static int
1941spider_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
1966try_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
1984done:
1985 return err;
1986out_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;