diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/e1000e/ich8lan.c | 89 |
1 files changed, 58 insertions, 31 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 2451dc8aef70..aaaaf2ca4084 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -578,12 +578,39 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) | |||
578 | static DEFINE_MUTEX(nvm_mutex); | 578 | static DEFINE_MUTEX(nvm_mutex); |
579 | 579 | ||
580 | /** | 580 | /** |
581 | * e1000_acquire_nvm_ich8lan - Acquire NVM mutex | ||
582 | * @hw: pointer to the HW structure | ||
583 | * | ||
584 | * Acquires the mutex for performing NVM operations. | ||
585 | **/ | ||
586 | static s32 e1000_acquire_nvm_ich8lan(struct e1000_hw *hw) | ||
587 | { | ||
588 | mutex_lock(&nvm_mutex); | ||
589 | |||
590 | return 0; | ||
591 | } | ||
592 | |||
593 | /** | ||
594 | * e1000_release_nvm_ich8lan - Release NVM mutex | ||
595 | * @hw: pointer to the HW structure | ||
596 | * | ||
597 | * Releases the mutex used while performing NVM operations. | ||
598 | **/ | ||
599 | static void e1000_release_nvm_ich8lan(struct e1000_hw *hw) | ||
600 | { | ||
601 | mutex_unlock(&nvm_mutex); | ||
602 | |||
603 | return; | ||
604 | } | ||
605 | |||
606 | static DEFINE_MUTEX(swflag_mutex); | ||
607 | |||
608 | /** | ||
581 | * e1000_acquire_swflag_ich8lan - Acquire software control flag | 609 | * e1000_acquire_swflag_ich8lan - Acquire software control flag |
582 | * @hw: pointer to the HW structure | 610 | * @hw: pointer to the HW structure |
583 | * | 611 | * |
584 | * Acquires the software control flag for performing NVM and PHY | 612 | * Acquires the software control flag for performing PHY and select |
585 | * operations. This is a function pointer entry point only called by | 613 | * MAC CSR accesses. |
586 | * read/write routines for the PHY and NVM parts. | ||
587 | **/ | 614 | **/ |
588 | static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) | 615 | static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) |
589 | { | 616 | { |
@@ -592,7 +619,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) | |||
592 | 619 | ||
593 | might_sleep(); | 620 | might_sleep(); |
594 | 621 | ||
595 | mutex_lock(&nvm_mutex); | 622 | mutex_lock(&swflag_mutex); |
596 | 623 | ||
597 | while (timeout) { | 624 | while (timeout) { |
598 | extcnf_ctrl = er32(EXTCNF_CTRL); | 625 | extcnf_ctrl = er32(EXTCNF_CTRL); |
@@ -633,7 +660,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) | |||
633 | 660 | ||
634 | out: | 661 | out: |
635 | if (ret_val) | 662 | if (ret_val) |
636 | mutex_unlock(&nvm_mutex); | 663 | mutex_unlock(&swflag_mutex); |
637 | 664 | ||
638 | return ret_val; | 665 | return ret_val; |
639 | } | 666 | } |
@@ -642,9 +669,8 @@ out: | |||
642 | * e1000_release_swflag_ich8lan - Release software control flag | 669 | * e1000_release_swflag_ich8lan - Release software control flag |
643 | * @hw: pointer to the HW structure | 670 | * @hw: pointer to the HW structure |
644 | * | 671 | * |
645 | * Releases the software control flag for performing NVM and PHY operations. | 672 | * Releases the software control flag for performing PHY and select |
646 | * This is a function pointer entry point only called by read/write | 673 | * MAC CSR accesses. |
647 | * routines for the PHY and NVM parts. | ||
648 | **/ | 674 | **/ |
649 | static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) | 675 | static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) |
650 | { | 676 | { |
@@ -654,7 +680,9 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) | |||
654 | extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; | 680 | extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; |
655 | ew32(EXTCNF_CTRL, extcnf_ctrl); | 681 | ew32(EXTCNF_CTRL, extcnf_ctrl); |
656 | 682 | ||
657 | mutex_unlock(&nvm_mutex); | 683 | mutex_unlock(&swflag_mutex); |
684 | |||
685 | return; | ||
658 | } | 686 | } |
659 | 687 | ||
660 | /** | 688 | /** |
@@ -1360,12 +1388,11 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, | |||
1360 | if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) || | 1388 | if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) || |
1361 | (words == 0)) { | 1389 | (words == 0)) { |
1362 | hw_dbg(hw, "nvm parameter(s) out of bounds\n"); | 1390 | hw_dbg(hw, "nvm parameter(s) out of bounds\n"); |
1363 | return -E1000_ERR_NVM; | 1391 | ret_val = -E1000_ERR_NVM; |
1392 | goto out; | ||
1364 | } | 1393 | } |
1365 | 1394 | ||
1366 | ret_val = e1000_acquire_swflag_ich8lan(hw); | 1395 | nvm->ops.acquire_nvm(hw); |
1367 | if (ret_val) | ||
1368 | goto out; | ||
1369 | 1396 | ||
1370 | ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); | 1397 | ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); |
1371 | if (ret_val) { | 1398 | if (ret_val) { |
@@ -1391,7 +1418,7 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, | |||
1391 | } | 1418 | } |
1392 | } | 1419 | } |
1393 | 1420 | ||
1394 | e1000_release_swflag_ich8lan(hw); | 1421 | nvm->ops.release_nvm(hw); |
1395 | 1422 | ||
1396 | out: | 1423 | out: |
1397 | if (ret_val) | 1424 | if (ret_val) |
@@ -1649,11 +1676,15 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, | |||
1649 | return -E1000_ERR_NVM; | 1676 | return -E1000_ERR_NVM; |
1650 | } | 1677 | } |
1651 | 1678 | ||
1679 | nvm->ops.acquire_nvm(hw); | ||
1680 | |||
1652 | for (i = 0; i < words; i++) { | 1681 | for (i = 0; i < words; i++) { |
1653 | dev_spec->shadow_ram[offset+i].modified = 1; | 1682 | dev_spec->shadow_ram[offset+i].modified = 1; |
1654 | dev_spec->shadow_ram[offset+i].value = data[i]; | 1683 | dev_spec->shadow_ram[offset+i].value = data[i]; |
1655 | } | 1684 | } |
1656 | 1685 | ||
1686 | nvm->ops.release_nvm(hw); | ||
1687 | |||
1657 | return 0; | 1688 | return 0; |
1658 | } | 1689 | } |
1659 | 1690 | ||
@@ -1683,9 +1714,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) | |||
1683 | if (nvm->type != e1000_nvm_flash_sw) | 1714 | if (nvm->type != e1000_nvm_flash_sw) |
1684 | goto out; | 1715 | goto out; |
1685 | 1716 | ||
1686 | ret_val = e1000_acquire_swflag_ich8lan(hw); | 1717 | nvm->ops.acquire_nvm(hw); |
1687 | if (ret_val) | ||
1688 | goto out; | ||
1689 | 1718 | ||
1690 | /* | 1719 | /* |
1691 | * We're writing to the opposite bank so if we're on bank 1, | 1720 | * We're writing to the opposite bank so if we're on bank 1, |
@@ -1703,7 +1732,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) | |||
1703 | old_bank_offset = 0; | 1732 | old_bank_offset = 0; |
1704 | ret_val = e1000_erase_flash_bank_ich8lan(hw, 1); | 1733 | ret_val = e1000_erase_flash_bank_ich8lan(hw, 1); |
1705 | if (ret_val) { | 1734 | if (ret_val) { |
1706 | e1000_release_swflag_ich8lan(hw); | 1735 | nvm->ops.release_nvm(hw); |
1707 | goto out; | 1736 | goto out; |
1708 | } | 1737 | } |
1709 | } else { | 1738 | } else { |
@@ -1711,7 +1740,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) | |||
1711 | new_bank_offset = 0; | 1740 | new_bank_offset = 0; |
1712 | ret_val = e1000_erase_flash_bank_ich8lan(hw, 0); | 1741 | ret_val = e1000_erase_flash_bank_ich8lan(hw, 0); |
1713 | if (ret_val) { | 1742 | if (ret_val) { |
1714 | e1000_release_swflag_ich8lan(hw); | 1743 | nvm->ops.release_nvm(hw); |
1715 | goto out; | 1744 | goto out; |
1716 | } | 1745 | } |
1717 | } | 1746 | } |
@@ -1769,7 +1798,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) | |||
1769 | if (ret_val) { | 1798 | if (ret_val) { |
1770 | /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */ | 1799 | /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */ |
1771 | hw_dbg(hw, "Flash commit failed.\n"); | 1800 | hw_dbg(hw, "Flash commit failed.\n"); |
1772 | e1000_release_swflag_ich8lan(hw); | 1801 | nvm->ops.release_nvm(hw); |
1773 | goto out; | 1802 | goto out; |
1774 | } | 1803 | } |
1775 | 1804 | ||
@@ -1782,7 +1811,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) | |||
1782 | act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD; | 1811 | act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD; |
1783 | ret_val = e1000_read_flash_word_ich8lan(hw, act_offset, &data); | 1812 | ret_val = e1000_read_flash_word_ich8lan(hw, act_offset, &data); |
1784 | if (ret_val) { | 1813 | if (ret_val) { |
1785 | e1000_release_swflag_ich8lan(hw); | 1814 | nvm->ops.release_nvm(hw); |
1786 | goto out; | 1815 | goto out; |
1787 | } | 1816 | } |
1788 | data &= 0xBFFF; | 1817 | data &= 0xBFFF; |
@@ -1790,7 +1819,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) | |||
1790 | act_offset * 2 + 1, | 1819 | act_offset * 2 + 1, |
1791 | (u8)(data >> 8)); | 1820 | (u8)(data >> 8)); |
1792 | if (ret_val) { | 1821 | if (ret_val) { |
1793 | e1000_release_swflag_ich8lan(hw); | 1822 | nvm->ops.release_nvm(hw); |
1794 | goto out; | 1823 | goto out; |
1795 | } | 1824 | } |
1796 | 1825 | ||
@@ -1803,7 +1832,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) | |||
1803 | act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1; | 1832 | act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1; |
1804 | ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0); | 1833 | ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0); |
1805 | if (ret_val) { | 1834 | if (ret_val) { |
1806 | e1000_release_swflag_ich8lan(hw); | 1835 | nvm->ops.release_nvm(hw); |
1807 | goto out; | 1836 | goto out; |
1808 | } | 1837 | } |
1809 | 1838 | ||
@@ -1813,7 +1842,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) | |||
1813 | dev_spec->shadow_ram[i].value = 0xFFFF; | 1842 | dev_spec->shadow_ram[i].value = 0xFFFF; |
1814 | } | 1843 | } |
1815 | 1844 | ||
1816 | e1000_release_swflag_ich8lan(hw); | 1845 | nvm->ops.release_nvm(hw); |
1817 | 1846 | ||
1818 | /* | 1847 | /* |
1819 | * Reload the EEPROM, or else modifications will not appear | 1848 | * Reload the EEPROM, or else modifications will not appear |
@@ -1877,14 +1906,12 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) | |||
1877 | **/ | 1906 | **/ |
1878 | void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw) | 1907 | void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw) |
1879 | { | 1908 | { |
1909 | struct e1000_nvm_info *nvm = &hw->nvm; | ||
1880 | union ich8_flash_protected_range pr0; | 1910 | union ich8_flash_protected_range pr0; |
1881 | union ich8_hws_flash_status hsfsts; | 1911 | union ich8_hws_flash_status hsfsts; |
1882 | u32 gfpreg; | 1912 | u32 gfpreg; |
1883 | s32 ret_val; | ||
1884 | 1913 | ||
1885 | ret_val = e1000_acquire_swflag_ich8lan(hw); | 1914 | nvm->ops.acquire_nvm(hw); |
1886 | if (ret_val) | ||
1887 | return; | ||
1888 | 1915 | ||
1889 | gfpreg = er32flash(ICH_FLASH_GFPREG); | 1916 | gfpreg = er32flash(ICH_FLASH_GFPREG); |
1890 | 1917 | ||
@@ -1905,7 +1932,7 @@ void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw) | |||
1905 | hsfsts.hsf_status.flockdn = true; | 1932 | hsfsts.hsf_status.flockdn = true; |
1906 | ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval); | 1933 | ew32flash(ICH_FLASH_HSFSTS, hsfsts.regval); |
1907 | 1934 | ||
1908 | e1000_release_swflag_ich8lan(hw); | 1935 | nvm->ops.release_nvm(hw); |
1909 | } | 1936 | } |
1910 | 1937 | ||
1911 | /** | 1938 | /** |
@@ -3162,9 +3189,9 @@ static struct e1000_phy_operations ich8_phy_ops = { | |||
3162 | }; | 3189 | }; |
3163 | 3190 | ||
3164 | static struct e1000_nvm_operations ich8_nvm_ops = { | 3191 | static struct e1000_nvm_operations ich8_nvm_ops = { |
3165 | .acquire_nvm = e1000_acquire_swflag_ich8lan, | 3192 | .acquire_nvm = e1000_acquire_nvm_ich8lan, |
3166 | .read_nvm = e1000_read_nvm_ich8lan, | 3193 | .read_nvm = e1000_read_nvm_ich8lan, |
3167 | .release_nvm = e1000_release_swflag_ich8lan, | 3194 | .release_nvm = e1000_release_nvm_ich8lan, |
3168 | .update_nvm = e1000_update_nvm_checksum_ich8lan, | 3195 | .update_nvm = e1000_update_nvm_checksum_ich8lan, |
3169 | .valid_led_default = e1000_valid_led_default_ich8lan, | 3196 | .valid_led_default = e1000_valid_led_default_ich8lan, |
3170 | .validate_nvm = e1000_validate_nvm_checksum_ich8lan, | 3197 | .validate_nvm = e1000_validate_nvm_checksum_ich8lan, |