aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2009-10-26 07:23:43 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-26 19:16:24 -0400
commitca15df58b1b98f073393eef3704674b45d1cb474 (patch)
treebfad45f9fdff8553d4984cd02f31bf5beccf8151
parentfa2ce13ca7a415332181adf2eb06d39e8e5054f7 (diff)
e1000e: separate mutex usage between NVM and PHY/CSR register for ICHx/PCH
Accesses to NVM and PHY/CSR registers on ICHx/PCH-based parts are protected from concurrent accesses with a mutex that is acquired when the access is initiated and released when the access has completed. However, the two types of accesses should not be protected by the same mutex because the driver may have to access the NVM while already holding the mutex over several consecutive PHY/CSR accesses which would result in livelock. Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/e1000e/ich8lan.c89
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)
578static DEFINE_MUTEX(nvm_mutex); 578static 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 **/
586static 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 **/
599static void e1000_release_nvm_ich8lan(struct e1000_hw *hw)
600{
601 mutex_unlock(&nvm_mutex);
602
603 return;
604}
605
606static 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 **/
588static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) 615static 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
634out: 661out:
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 **/
649static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) 675static 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
1396out: 1423out:
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 **/
1878void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw) 1907void 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
3164static struct e1000_nvm_operations ich8_nvm_ops = { 3191static 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,