Change the way PHY interrupts work: disable automatically. Then we have to re-subscribe each time after the interrupt fires

This commit is contained in:
Gregory Nutt
2014-08-17 16:51:56 -06:00
parent 2fab4eaa5a
commit 754541a381
5 changed files with 77 additions and 18 deletions
+18 -4
View File
@@ -1937,7 +1937,12 @@ static void sam_phydump(struct sam_emac_s *priv)
* Function: sam_phyintenable * Function: sam_phyintenable
* *
* Description: * Description:
* Enable link up/down PHY interrupts * Enable link up/down PHY interrupts. The interrupt protocol is like this:
*
* - Interrupt status is cleared when the interrupt is enabled.
* - Interrupt occurs. Interrupt is disabled (at the processor level) when
* is received.
* - Interrupt status is cleared when the interrupt is re-enabled.
* *
* Parameters: * Parameters:
* priv - A reference to the private driver state structure * priv - A reference to the private driver state structure
@@ -1952,6 +1957,7 @@ static int sam_phyintenable(struct sam_emac_s *priv)
{ {
#if defined(CONFIG_ETH0_PHY_KSZ8051) || defined(CONFIG_ETH0_PHY_KSZ8081) #if defined(CONFIG_ETH0_PHY_KSZ8051) || defined(CONFIG_ETH0_PHY_KSZ8081)
uint32_t regval; uint32_t regval;
uint16_t phyval;
int ret; int ret;
/* Enable management port */ /* Enable management port */
@@ -1959,10 +1965,18 @@ static int sam_phyintenable(struct sam_emac_s *priv)
regval = sam_getreg(priv, SAM_EMAC_NCR); regval = sam_getreg(priv, SAM_EMAC_NCR);
sam_putreg(priv, SAM_EMAC_NCR, regval | EMAC_NCR_MPE); sam_putreg(priv, SAM_EMAC_NCR, regval | EMAC_NCR_MPE);
/* Enable link up/down interrupts */ /* Read the interrupt status register in order to clear any pending
* interrupts
*/
ret = sam_phywrite(priv, priv->phyaddr, MII_KSZ8081_INT, ret = sam_phyread(priv, priv->phyaddr, MII_KSZ8081_INT, &phyval);
(MII_KSZ80x1_INT_LDEN | MII_KSZ80x1_INT_LUEN)); if (ret == OK)
{
/* Enable link up/down interrupts */
ret = sam_phywrite(priv, priv->phyaddr, MII_KSZ8081_INT,
(MII_KSZ80x1_INT_LDEN | MII_KSZ80x1_INT_LUEN));
}
/* Disable management port (probably) */ /* Disable management port (probably) */
+18 -4
View File
@@ -1978,7 +1978,12 @@ static void sam_phydump(struct sam_emac_s *priv)
* Function: sam_phyintenable * Function: sam_phyintenable
* *
* Description: * Description:
* Enable link up/down PHY interrupts * Enable link up/down PHY interrupts. The interrupt protocol is like this:
*
* - Interrupt status is cleared when the interrupt is enabled.
* - Interrupt occurs. Interrupt is disabled (at the processor level) when
* is received.
* - Interrupt status is cleared when the interrupt is re-enabled.
* *
* Parameters: * Parameters:
* priv - A reference to the private driver state structure * priv - A reference to the private driver state structure
@@ -1993,6 +1998,7 @@ static int sam_phyintenable(struct sam_emac_s *priv)
{ {
#if defined(SAMA5_EMAC_PHY_KSZ8051) || defined(SAMA5_EMAC_PHY_KSZ8081) #if defined(SAMA5_EMAC_PHY_KSZ8051) || defined(SAMA5_EMAC_PHY_KSZ8081)
uint32_t regval; uint32_t regval;
uint16_t phyval;
int ret; int ret;
/* Enable management port */ /* Enable management port */
@@ -2000,10 +2006,18 @@ static int sam_phyintenable(struct sam_emac_s *priv)
regval = sam_getreg(priv, SAM_EMAC_NCR); regval = sam_getreg(priv, SAM_EMAC_NCR);
sam_putreg(priv, SAM_EMAC_NCR, regval | EMAC_NCR_MPE); sam_putreg(priv, SAM_EMAC_NCR, regval | EMAC_NCR_MPE);
/* Enable link up/down interrupts */ /* Read the interrupt status register in order to clear any pending
* interrupts
*/
ret = sam_phywrite(priv, priv->phyaddr, MII_KSZ8081_INT, ret = sam_phyread(priv, priv->phyaddr, MII_KSZ8081_INT, &phyval);
(MII_KSZ80x1_INT_LDEN | MII_KSZ80x1_INT_LUEN)); if (ret == OK)
{
/* Enable link up/down interrupts */
ret = sam_phywrite(priv, priv->phyaddr, MII_KSZ8081_INT,
(MII_KSZ80x1_INT_LDEN | MII_KSZ80x1_INT_LUEN));
}
/* Disable management port (probably) */ /* Disable management port (probably) */
+18 -4
View File
@@ -2446,7 +2446,12 @@ static bool sam_is100fdx(struct sam_emac_s *priv, uint16_t physr)
* Function: sam_phyintenable * Function: sam_phyintenable
* *
* Description: * Description:
* Enable link up/down PHY interrupts * Enable link up/down PHY interrupts. The interrupt protocol is like this:
*
* - Interrupt status is cleared when the interrupt is enabled.
* - Interrupt occurs. Interrupt is disabled (at the processor level) when
* is received.
* - Interrupt status is cleared when the interrupt is re-enabled.
* *
* Parameters: * Parameters:
* priv - A reference to the private driver state structure * priv - A reference to the private driver state structure
@@ -2462,6 +2467,7 @@ static int sam_phyintenable(struct sam_emac_s *priv)
#if defined(SAMA5_EMAC0_PHY_KSZ8051) || defined(SAMA5_EMAC0_PHY_KSZ8081) || \ #if defined(SAMA5_EMAC0_PHY_KSZ8051) || defined(SAMA5_EMAC0_PHY_KSZ8081) || \
defined(SAMA5_EMAC1_PHY_KSZ8051) || defined(SAMA5_EMAC1_PHY_KSZ8081) defined(SAMA5_EMAC1_PHY_KSZ8051) || defined(SAMA5_EMAC1_PHY_KSZ8081)
uint32_t regval; uint32_t regval;
uint16_t phyval;
int ret; int ret;
/* Does this MAC support a KSZ80x1 PHY? */ /* Does this MAC support a KSZ80x1 PHY? */
@@ -2473,10 +2479,18 @@ static int sam_phyintenable(struct sam_emac_s *priv)
regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET); regval = sam_getreg(priv, SAM_EMAC_NCR_OFFSET);
sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval | EMAC_NCR_MPE); sam_putreg(priv, SAM_EMAC_NCR_OFFSET, regval | EMAC_NCR_MPE);
/* Enable link up/down interrupts */ /* Read the interrupt status register in order to clear any pending
* interrupts
*/
ret = sam_phywrite(priv, priv->phyaddr, MII_KSZ8081_INT, ret = sam_phyread(priv, priv->phyaddr, MII_KSZ8081_INT, &phyval);
(MII_KSZ80x1_INT_LDEN | MII_KSZ80x1_INT_LUEN)); if (ret == OK)
{
/* Enable link up/down interrupts */
ret = sam_phywrite(priv, priv->phyaddr, MII_KSZ8081_INT,
(MII_KSZ80x1_INT_LDEN | MII_KSZ80x1_INT_LUEN));
}
/* Disable management port (probably) */ /* Disable management port (probably) */
+17 -5
View File
@@ -1923,7 +1923,12 @@ static void sam_phydump(struct sam_gmac_s *priv)
* Function: sam_phyintenable * Function: sam_phyintenable
* *
* Description: * Description:
* Enable link up/down PHY interrupts * Enable link up/down PHY interrupts. The interrupt protocol is like this:
*
* - Interrupt status is cleared when the interrupt is enabled.
* - Interrupt occurs. Interrupt is disabled (at the processor level) when
* is received.
* - Interrupt status is cleared when the interrupt is re-enabled.
* *
* Parameters: * Parameters:
* priv - A reference to the private driver state structure * priv - A reference to the private driver state structure
@@ -1937,18 +1942,25 @@ static void sam_phydump(struct sam_gmac_s *priv)
static int sam_phyintenable(struct sam_emac_s *priv) static int sam_phyintenable(struct sam_emac_s *priv)
{ {
#if defined(SAMA5_GMAC_PHY_KSZ90x1) #if defined(SAMA5_GMAC_PHY_KSZ90x1)
uint16_t phyval;
int ret; int ret;
/* Enable the management port */ /* Enable the management port */
sam_enablemdio(priv); sam_enablemdio(priv);
/* Write to the requested register */ /* Read the interrupt status register in order to clear any pending
* interrupts
*/
/* Enable link up/down interrupts */ ret = sam_phyread(priv, priv->phyaddr, GMII_KSZ90x1_ICS, &phyval);
if (ret == OK)
{
/* Enable link up/down interrupts */
ret = sam_phywrite(priv, priv->phyaddr, GMII_KSZ90x1_ICS, ret = sam_phywrite(priv, priv->phyaddr, GMII_KSZ90x1_ICS,
(GMII_KSZ90x1_INT_LDEN | GMII_KSZ90x1_INT_LUEN)); (GMII_KSZ90x1_INT_LDEN | GMII_KSZ90x1_INT_LUEN));
}
/* Disable the management port */ /* Disable the management port */
+6 -1
View File
@@ -2572,7 +2572,12 @@ static int stm32_ioctl(struct net_driver_s *dev, int cmd, long arg)
* Function: stm32_phyintenable * Function: stm32_phyintenable
* *
* Description: * Description:
* Enable link up/down PHY interrupts * Enable link up/down PHY interrupts. The interrupt protocol is like this:
*
* - Interrupt status is cleared when the interrupt is enabled.
* - Interrupt occurs. Interrupt is disabled (at the processor level) when
* is received.
* - Interrupt status is cleared when the interrupt is re-enabled.
* *
* Parameters: * Parameters:
* priv - A reference to the private driver state structure * priv - A reference to the private driver state structure