diff options
author | Francois Romieu <romieu@fr.zoreil.com> | 2011-06-17 18:10:29 -0400 |
---|---|---|
committer | Francois Romieu <romieu@fr.zoreil.com> | 2011-06-18 05:40:48 -0400 |
commit | fd112f2e15ba85d387de446a81aeb11e46ecc55d (patch) | |
tree | eadd165d2d8137220029bf674d456410bd577722 /drivers/net/r8169.c | |
parent | 960aee6c7d5951ac20c0227ad73bad56392f0afc (diff) |
r8169: check firmware content sooner.
Firmware checking is only performed when the firmware is loaded
instead of each time the driver inits the phy.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r-- | drivers/net/r8169.c | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 7074989d5f75..bc5bb378d008 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -1815,18 +1815,12 @@ out: | |||
1815 | return rc; | 1815 | return rc; |
1816 | } | 1816 | } |
1817 | 1817 | ||
1818 | static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) | 1818 | static bool rtl_fw_data_ok(struct rtl8169_private *tp, struct net_device *dev, |
1819 | struct rtl_fw_phy_action *pa) | ||
1819 | { | 1820 | { |
1820 | struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; | 1821 | bool rc = false; |
1821 | struct net_device *dev = tp->dev; | ||
1822 | u32 predata, count; | ||
1823 | size_t index; | 1822 | size_t index; |
1824 | 1823 | ||
1825 | if (!rtl_fw_format_ok(tp, rtl_fw)) { | ||
1826 | netif_err(tp, probe, dev, "invalid firwmare\n"); | ||
1827 | return; | ||
1828 | } | ||
1829 | |||
1830 | for (index = 0; index < pa->size; index++) { | 1824 | for (index = 0; index < pa->size; index++) { |
1831 | u32 action = le32_to_cpu(pa->code[index]); | 1825 | u32 action = le32_to_cpu(pa->code[index]); |
1832 | u32 regno = (action & 0x0fff0000) >> 16; | 1826 | u32 regno = (action & 0x0fff0000) >> 16; |
@@ -1844,25 +1838,25 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) | |||
1844 | 1838 | ||
1845 | case PHY_BJMPN: | 1839 | case PHY_BJMPN: |
1846 | if (regno > index) { | 1840 | if (regno > index) { |
1847 | netif_err(tp, probe, tp->dev, | 1841 | netif_err(tp, ifup, tp->dev, |
1848 | "Out of range of firmware\n"); | 1842 | "Out of range of firmware\n"); |
1849 | return; | 1843 | goto out; |
1850 | } | 1844 | } |
1851 | break; | 1845 | break; |
1852 | case PHY_READCOUNT_EQ_SKIP: | 1846 | case PHY_READCOUNT_EQ_SKIP: |
1853 | if (index + 2 >= pa->size) { | 1847 | if (index + 2 >= pa->size) { |
1854 | netif_err(tp, probe, tp->dev, | 1848 | netif_err(tp, ifup, tp->dev, |
1855 | "Out of range of firmware\n"); | 1849 | "Out of range of firmware\n"); |
1856 | return; | 1850 | goto out; |
1857 | } | 1851 | } |
1858 | break; | 1852 | break; |
1859 | case PHY_COMP_EQ_SKIPN: | 1853 | case PHY_COMP_EQ_SKIPN: |
1860 | case PHY_COMP_NEQ_SKIPN: | 1854 | case PHY_COMP_NEQ_SKIPN: |
1861 | case PHY_SKIPN: | 1855 | case PHY_SKIPN: |
1862 | if (index + 1 + regno >= pa->size) { | 1856 | if (index + 1 + regno >= pa->size) { |
1863 | netif_err(tp, probe, tp->dev, | 1857 | netif_err(tp, ifup, tp->dev, |
1864 | "Out of range of firmware\n"); | 1858 | "Out of range of firmware\n"); |
1865 | return; | 1859 | goto out; |
1866 | } | 1860 | } |
1867 | break; | 1861 | break; |
1868 | 1862 | ||
@@ -1870,14 +1864,39 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) | |||
1870 | case PHY_WRITE_MAC_BYTE: | 1864 | case PHY_WRITE_MAC_BYTE: |
1871 | case PHY_WRITE_ERI_WORD: | 1865 | case PHY_WRITE_ERI_WORD: |
1872 | default: | 1866 | default: |
1873 | netif_err(tp, probe, tp->dev, | 1867 | netif_err(tp, ifup, tp->dev, |
1874 | "Invalid action 0x%08x\n", action); | 1868 | "Invalid action 0x%08x\n", action); |
1875 | return; | 1869 | goto out; |
1876 | } | 1870 | } |
1877 | } | 1871 | } |
1872 | rc = true; | ||
1873 | out: | ||
1874 | return rc; | ||
1875 | } | ||
1878 | 1876 | ||
1879 | predata = 0; | 1877 | static int rtl_check_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) |
1880 | count = 0; | 1878 | { |
1879 | struct net_device *dev = tp->dev; | ||
1880 | int rc = -EINVAL; | ||
1881 | |||
1882 | if (!rtl_fw_format_ok(tp, rtl_fw)) { | ||
1883 | netif_err(tp, ifup, dev, "invalid firwmare\n"); | ||
1884 | goto out; | ||
1885 | } | ||
1886 | |||
1887 | if (rtl_fw_data_ok(tp, dev, &rtl_fw->phy_action)) | ||
1888 | rc = 0; | ||
1889 | out: | ||
1890 | return rc; | ||
1891 | } | ||
1892 | |||
1893 | static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) | ||
1894 | { | ||
1895 | struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; | ||
1896 | u32 predata, count; | ||
1897 | size_t index; | ||
1898 | |||
1899 | predata = count = 0; | ||
1881 | 1900 | ||
1882 | for (index = 0; index < pa->size; ) { | 1901 | for (index = 0; index < pa->size; ) { |
1883 | u32 action = le32_to_cpu(pa->code[index]); | 1902 | u32 action = le32_to_cpu(pa->code[index]); |
@@ -3605,10 +3624,16 @@ static void rtl_request_uncached_firmware(struct rtl8169_private *tp) | |||
3605 | if (rc < 0) | 3624 | if (rc < 0) |
3606 | goto err_free; | 3625 | goto err_free; |
3607 | 3626 | ||
3627 | rc = rtl_check_firmware(tp, rtl_fw); | ||
3628 | if (rc < 0) | ||
3629 | goto err_release_firmware; | ||
3630 | |||
3608 | tp->rtl_fw = rtl_fw; | 3631 | tp->rtl_fw = rtl_fw; |
3609 | out: | 3632 | out: |
3610 | return; | 3633 | return; |
3611 | 3634 | ||
3635 | err_release_firmware: | ||
3636 | release_firmware(rtl_fw->fw); | ||
3612 | err_free: | 3637 | err_free: |
3613 | kfree(rtl_fw); | 3638 | kfree(rtl_fw); |
3614 | err_warn: | 3639 | err_warn: |