diff mbox

[U-Boot,1/3] e1000: releasing semaphore once no longer needed

Message ID 1432054880-20922-2-git-send-email-tharvey@gateworks.com
State Accepted
Delegated to: Joe Hershberger
Headers show

Commit Message

Tim Harvey May 19, 2015, 5:01 p.m. UTC
Once the hwsw semaphore is acquired, it must be released when access to the
hw is completed. Without this subsequent calls to acquire will timeout
obtaining the semaphore.

Cc: Marcel Ziswiler <marcel@ziswiler.com>
Cc: Marek Vasut <marex@denx.de>
Cc: Aneesh Bansal <aneesh.bansal@freescale.com>
Cc: Naveen Burmi <NaveenBurmi@freescale.com>
Cc: Po Liu <po.liu@freescale.com>
Cc: Bin Meng <bmeng.cn@gmail.com>
Cc: Alison Wang <alison.wang@freescale.com>
Cc: Reinhard Arlt <reinhard.arlt@esd-electronics.com>
Cc: Shengzhou Liu  <Shengzhou.Liu@freescale.com>
Cc: York Sun <yorksun@freescale.com>
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
 drivers/net/e1000.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

Comments

Bin Meng May 20, 2015, 10:06 a.m. UTC | #1
On Wed, May 20, 2015 at 1:01 AM, Tim Harvey <tharvey@gateworks.com> wrote:
> Once the hwsw semaphore is acquired, it must be released when access to the
> hw is completed. Without this subsequent calls to acquire will timeout
> obtaining the semaphore.
>
> Cc: Marcel Ziswiler <marcel@ziswiler.com>
> Cc: Marek Vasut <marex@denx.de>
> Cc: Aneesh Bansal <aneesh.bansal@freescale.com>
> Cc: Naveen Burmi <NaveenBurmi@freescale.com>
> Cc: Po Liu <po.liu@freescale.com>
> Cc: Bin Meng <bmeng.cn@gmail.com>
> Cc: Alison Wang <alison.wang@freescale.com>
> Cc: Reinhard Arlt <reinhard.arlt@esd-electronics.com>
> Cc: Shengzhou Liu  <Shengzhou.Liu@freescale.com>
> Cc: York Sun <yorksun@freescale.com>
> Signed-off-by: Tim Harvey <tharvey@gateworks.com>
> ---
>  drivers/net/e1000.c | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
>
> diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
> index cd44222..a64bc7b 100644
> --- a/drivers/net/e1000.c
> +++ b/drivers/net/e1000.c
> @@ -126,6 +126,7 @@ static int e1000_detect_gig_phy(struct e1000_hw *hw);
>  static void e1000_set_media_type(struct e1000_hw *hw);
>
>  static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
> +static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
>  static int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
>
>  #ifndef CONFIG_E1000_NO_NVM
> @@ -729,7 +730,10 @@ void e1000_release_eeprom(struct e1000_hw *hw)
>                 eecd &= ~E1000_EECD_REQ;
>                 E1000_WRITE_REG(hw, EECD, eecd);
>         }
> +
> +       e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
>  }
> +
>  /******************************************************************************
>   * Reads a 16 bit word from the EEPROM.
>   *
> @@ -1102,6 +1106,7 @@ e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
>         return E1000_SUCCESS;
>  }
>
> +/* Take ownership of the PHY */
>  static int32_t
>  e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask)
>  {
> @@ -1141,6 +1146,21 @@ e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask)
>         return E1000_SUCCESS;
>  }
>
> +static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask)
> +{
> +       uint32_t swfw_sync = 0;
> +
> +       DEBUGFUNC();
> +       while (e1000_get_hw_eeprom_semaphore(hw))
> +               ; /* Empty */
> +
> +       swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
> +       swfw_sync &= ~mask;
> +       E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync);
> +
> +       e1000_put_hw_eeprom_semaphore(hw);
> +}
> +
>  static bool e1000_is_second_port(struct e1000_hw *hw)
>  {
>         switch (hw->mac_type) {
> @@ -4462,6 +4482,8 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
>                 E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
>         }
>
> +       e1000_swfw_sync_release(hw, swfw);
> +
>         /* Wait for FW to finish PHY configuration. */
>         ret_val = e1000_get_phy_cfg_done(hw);
>         if (ret_val != E1000_SUCCESS)
> --

Tested on QEMU v2.3.0

Tested-by: Bin Meng <bmeng.cn@gmail.com>
Marcel Ziswiler May 20, 2015, 11:26 a.m. UTC | #2
On Tue, 2015-05-19 at 10:01 -0700, Tim Harvey wrote:
> Once the hwsw semaphore is acquired, it must be released when access to the
> hw is completed. Without this subsequent calls to acquire will timeout
> obtaining the semaphore.
> 
> Cc: Marcel Ziswiler <marcel@ziswiler.com>
> Cc: Marek Vasut <marex@denx.de>
> Cc: Aneesh Bansal <aneesh.bansal@freescale.com>
> Cc: Naveen Burmi <NaveenBurmi@freescale.com>
> Cc: Po Liu <po.liu@freescale.com>
> Cc: Bin Meng <bmeng.cn@gmail.com>
> Cc: Alison Wang <alison.wang@freescale.com>
> Cc: Reinhard Arlt <reinhard.arlt@esd-electronics.com>
> Cc: Shengzhou Liu  <Shengzhou.Liu@freescale.com>
> Cc: York Sun <yorksun@freescale.com>
> Signed-off-by: Tim Harvey <tharvey@gateworks.com>
> ---
>  drivers/net/e1000.c | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
> index cd44222..a64bc7b 100644
> --- a/drivers/net/e1000.c
> +++ b/drivers/net/e1000.c
> @@ -126,6 +126,7 @@ static int e1000_detect_gig_phy(struct e1000_hw *hw);
>  static void e1000_set_media_type(struct e1000_hw *hw);
>  
>  static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
> +static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
>  static int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
>  
>  #ifndef CONFIG_E1000_NO_NVM
> @@ -729,7 +730,10 @@ void e1000_release_eeprom(struct e1000_hw *hw)
>  		eecd &= ~E1000_EECD_REQ;
>  		E1000_WRITE_REG(hw, EECD, eecd);
>  	}
> +
> +	e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
>  }
> +
>  /******************************************************************************
>   * Reads a 16 bit word from the EEPROM.
>   *
> @@ -1102,6 +1106,7 @@ e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
>  	return E1000_SUCCESS;
>  }
>  
> +/* Take ownership of the PHY */
>  static int32_t
>  e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask)
>  {
> @@ -1141,6 +1146,21 @@ e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask)
>  	return E1000_SUCCESS;
>  }
>  
> +static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask)
> +{
> +	uint32_t swfw_sync = 0;
> +
> +	DEBUGFUNC();
> +	while (e1000_get_hw_eeprom_semaphore(hw))
> +		; /* Empty */
> +
> +	swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
> +	swfw_sync &= ~mask;
> +	E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync);
> +
> +	e1000_put_hw_eeprom_semaphore(hw);
> +}
> +
>  static bool e1000_is_second_port(struct e1000_hw *hw)
>  {
>  	switch (hw->mac_type) {
> @@ -4462,6 +4482,8 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
>  		E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
>  	}
>  
> +	e1000_swfw_sync_release(hw, swfw);
> +
>  	/* Wait for FW to finish PHY configuration. */
>  	ret_val = e1000_get_phy_cfg_done(hw);
>  	if (ret_val != E1000_SUCCESS)

Tested on Apalis T30 1GB V1.1A with properly fused i211
Tested on Apalis T30 2GB V1.1A with iNVM fused i210
Tested on Apalis T30 1GB V1.0A with tools only aka non fused i211
Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
---
BTW: Still fails on Apalis T30 2GB V1.0E with tools only aka non fused
i210 as follows:
e1000: e1000#0: ERROR: Hardware Initialization Failed
In our downstream production U-Boot we temporarily hacked this as
follows for now:
http://git.toradex.com/cgit/u-boot-toradex.git/commit/?h=2015.04-toradex&id=2d8ea651b6da79047b6fa729863d25b5eb9e15d7
Joe Hershberger Aug. 12, 2015, 7:31 p.m. UTC | #3
Hi Tim,

On Tue, May 19, 2015 at 12:01 PM, Tim Harvey <tharvey@gateworks.com> wrote:
> Once the hwsw semaphore is acquired, it must be released when access to the
> hw is completed. Without this subsequent calls to acquire will timeout
> obtaining the semaphore.
>
> Cc: Marcel Ziswiler <marcel@ziswiler.com>
> Cc: Marek Vasut <marex@denx.de>
> Cc: Aneesh Bansal <aneesh.bansal@freescale.com>
> Cc: Naveen Burmi <NaveenBurmi@freescale.com>
> Cc: Po Liu <po.liu@freescale.com>
> Cc: Bin Meng <bmeng.cn@gmail.com>
> Cc: Alison Wang <alison.wang@freescale.com>
> Cc: Reinhard Arlt <reinhard.arlt@esd-electronics.com>
> Cc: Shengzhou Liu  <Shengzhou.Liu@freescale.com>
> Cc: York Sun <yorksun@freescale.com>
> Signed-off-by: Tim Harvey <tharvey@gateworks.com>

Applied to u-boot-net, thanks!
-Joe
diff mbox

Patch

diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
index cd44222..a64bc7b 100644
--- a/drivers/net/e1000.c
+++ b/drivers/net/e1000.c
@@ -126,6 +126,7 @@  static int e1000_detect_gig_phy(struct e1000_hw *hw);
 static void e1000_set_media_type(struct e1000_hw *hw);
 
 static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
+static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
 static int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
 
 #ifndef CONFIG_E1000_NO_NVM
@@ -729,7 +730,10 @@  void e1000_release_eeprom(struct e1000_hw *hw)
 		eecd &= ~E1000_EECD_REQ;
 		E1000_WRITE_REG(hw, EECD, eecd);
 	}
+
+	e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
 }
+
 /******************************************************************************
  * Reads a 16 bit word from the EEPROM.
  *
@@ -1102,6 +1106,7 @@  e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
 	return E1000_SUCCESS;
 }
 
+/* Take ownership of the PHY */
 static int32_t
 e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask)
 {
@@ -1141,6 +1146,21 @@  e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask)
 	return E1000_SUCCESS;
 }
 
+static void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask)
+{
+	uint32_t swfw_sync = 0;
+
+	DEBUGFUNC();
+	while (e1000_get_hw_eeprom_semaphore(hw))
+		; /* Empty */
+
+	swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
+	swfw_sync &= ~mask;
+	E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync);
+
+	e1000_put_hw_eeprom_semaphore(hw);
+}
+
 static bool e1000_is_second_port(struct e1000_hw *hw)
 {
 	switch (hw->mac_type) {
@@ -4462,6 +4482,8 @@  e1000_phy_hw_reset(struct e1000_hw *hw)
 		E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
 	}
 
+	e1000_swfw_sync_release(hw, swfw);
+
 	/* Wait for FW to finish PHY configuration. */
 	ret_val = e1000_get_phy_cfg_done(hw);
 	if (ret_val != E1000_SUCCESS)