Re: [PATCH] net: ethernet: ti: cpsw: remove unused priv lock

2016-06-03 Thread Grygorii Strashko

On 06/03/2016 01:37 AM, Ivan Khoronzhuk wrote:

There is no reason in this lock. At least for now.

Signed-off-by: Ivan Khoronzhuk 
---

Based on master

  drivers/net/ethernet/ti/cpsw.c | 3 ---
  1 file changed, 3 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 9919cb3..8d1d373 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -365,7 +365,6 @@ static inline void slave_write(struct cpsw_slave *slave, 
u32 val, u32 offset)
  }

  struct cpsw_priv {
-   spinlock_t  lock;
struct platform_device  *pdev;
struct net_device   *ndev;
struct napi_struct  napi_rx;
@@ -2413,7 +2412,6 @@ static int cpsw_probe_dual_emac(struct platform_device 
*pdev,
}

priv_sl2 = netdev_priv(ndev);
-   spin_lock_init(&priv_sl2->lock);
priv_sl2->data = *data;
priv_sl2->pdev = pdev;
priv_sl2->ndev = ndev;
@@ -2533,7 +2531,6 @@ static int cpsw_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, ndev);
priv = netdev_priv(ndev);
-   spin_lock_init(&priv->lock);
priv->pdev = pdev;
priv->ndev = ndev;
priv->dev  = &ndev->dev;



Reviewed-by: Grygorii Strashko 

--
regards,
-grygorii


Re: [PATCH] net: ethernet: ti: cpsw: fix rx-usecs interrupt pacing consistency

2016-06-03 Thread Grygorii Strashko

On 06/02/2016 04:30 PM, Ivan Khoronzhuk wrote:

On 02.06.16 16:14, Ivan Khoronzhuk wrote:

The rx-usecs shouldn't be changed while interface down/up.
Currently, for instance, if it's set to 100us, after interface
down/up it's 500us. It's a hidden bug that can lead to lavish
interrupt pacing time increasing while "down/up" up to max value.

Steps to reproduce:
- set rx-usecs to be 100us
- down/up interface
- read new unexpected rx-usecs

Signed-off-by: Ivan Khoronzhuk 
---

Based on ti-linux-4.4.y

Please ignore this line, it's added by mistake.
The patch is based on master.



Reviewed-by: Grygorii Strashko 





  drivers/net/ethernet/ti/cpsw.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c
b/drivers/net/ethernet/ti/cpsw.c
index 7b44587..9919cb3 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1352,7 +1352,7 @@ static int cpsw_ndo_open(struct net_device *ndev)
  if (priv->coal_intvl != 0) {
  struct ethtool_coalesce coal;

-coal.rx_coalesce_usecs = (priv->coal_intvl << 4);
+coal.rx_coalesce_usecs = priv->coal_intvl;
  cpsw_set_coalesce(ndev, &coal);
  }







--
regards,
-grygorii


Re: [PATCH] net: ethernet: ti: cpsw: remove rx_descs property

2016-06-03 Thread Grygorii Strashko

On 06/03/2016 01:43 AM, Ivan Khoronzhuk wrote:

There is no reason to hold s/w dependent parameter in device tree.
Even more, there is no reason in this parameter because davinici_cpdma
driver splits pool of descriptors equally between tx and rx channels.
That is, if number of descriptors 256, 128 of them are for rx
channels. While receiving, the descriptor is freed to the pool and
then allocated with new skb. And if in DT the "rx_descs" is set to
64, then 128 - 64 = 64 descriptors are always in the pool and cannot
be used, for tx, for instance. It's not correct resource usage,
better to set it to half of pool, then the rx pool can be used in
full. It will not have any impact on performance, as anyway, the
"redundant" descriptors were unused.

Signed-off-by: Ivan Khoronzhuk 
---

Based on master

  Documentation/devicetree/bindings/net/cpsw.txt |  3 ---
  arch/arm/boot/dts/am33xx.dtsi  |  1 -
  arch/arm/boot/dts/am4372.dtsi  |  1 -
  arch/arm/boot/dts/dm814x.dtsi  |  1 -
  arch/arm/boot/dts/dra7.dtsi|  1 -



Pls, split DT and non-DT changes, seems code changes should go first.


  drivers/net/ethernet/ti/cpsw.c | 13 +++--
  drivers/net/ethernet/ti/cpsw.h |  1 -
  drivers/net/ethernet/ti/davinci_cpdma.c|  6 ++
  drivers/net/ethernet/ti/davinci_cpdma.h|  1 +
  9 files changed, 10 insertions(+), 18 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/cpsw.txt 
b/Documentation/devicetree/bindings/net/cpsw.txt
index 0ae0649..5fe6239 100644
--- a/Documentation/devicetree/bindings/net/cpsw.txt
+++ b/Documentation/devicetree/bindings/net/cpsw.txt
@@ -15,7 +15,6 @@ Required properties:
  - cpdma_channels  : Specifies number of channels in CPDMA
  - ale_entries : Specifies No of entries ALE can hold
  - bd_ram_size : Specifies internal descriptor RAM size
-- rx_descs : Specifies number of Rx descriptors
  - mac_control : Specifies Default MAC control register content
  for the specific platform
  - slaves  : Specifies number for slaves
@@ -70,7 +69,6 @@ Examples:


[]


slaves = <2>;
active_slave = <0>;
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 4b08a2f..635be3e 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1277,6 +1277,7 @@ static int cpsw_ndo_open(struct net_device *ndev)
  ALE_ALL_PORTS, ALE_ALL_PORTS, 0, 0);

if (!cpsw_common_res_usage_state(priv)) {
+   int buf_num;
struct cpsw_priv *priv_sl0 = cpsw_get_slave_priv(priv, 0);

/* setup tx dma to fixed prio and zero offset */
@@ -1305,10 +1306,8 @@ static int cpsw_ndo_open(struct net_device *ndev)
enable_irq(priv->irqs_table[0]);
}

-   if (WARN_ON(!priv->data.rx_descs))
-   priv->data.rx_descs = 128;
-
-   for (i = 0; i < priv->data.rx_descs; i++) {
+   buf_num = cpdma_chan_get_buf_num(priv->dma) / 2;


Could you get rid of "/ 2", pls?


+   for (i = 0; i < buf_num; i++) {
struct sk_buff *skb;

ret = -ENOMEM;
@@ -1999,12 +1998,6 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
}
data->bd_ram_size = prop;

-   if (of_property_read_u32(node, "rx_descs", &prop)) {
-   dev_err(&pdev->dev, "Missing rx_descs property in the DT.\n");
-   return -EINVAL;
-   }
-   data->rx_descs = prop;
-
if (of_property_read_u32(node, "mac_control", &prop)) {
dev_err(&pdev->dev, "Missing mac_control property in the 
DT.\n");
return -EINVAL;
diff --git a/drivers/net/ethernet/ti/cpsw.h b/drivers/net/ethernet/ti/cpsw.h
index e50afd1..16b54c6 100644
--- a/drivers/net/ethernet/ti/cpsw.h
+++ b/drivers/net/ethernet/ti/cpsw.h
@@ -35,7 +35,6 @@ struct cpsw_platform_data {
u32 cpts_clock_shift; /* convert input clock ticks to nanoseconds */
u32 ale_entries;/* ale table size */
u32 bd_ram_size;  /*buffer descriptor ram size */
-   u32 rx_descs;   /* Number of Rx Descriptios */
u32 mac_control;/* Mac control register */
u16 default_vlan;   /* Def VLAN for ALE lookup in VLAN aware mode*/
booldual_emac;  /* Enable Dual EMAC mode */
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c 
b/drivers/net/ethernet/ti/davinci_cpdma.c
index 18bf3a8..395647c 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.c
+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -543,6 +543,12 @@ struct cpdma_chan *cpdma_chan_create(struct cpdma_ctlr 
*ctlr, int chan_num,
  }
  EXPORT_SYMBOL_GPL(cpdma_chan_create);

+int cpdma_chan_get_buf_num(struct cpdma_

Re: [PATCH] net: ethernet: ti: cpsw: remove rx_descs property

2016-06-03 Thread Grygorii Strashko
On 06/03/2016 09:25 PM, Ivan Khoronzhuk wrote:
> 
> 
> On 03.06.16 19:50, Grygorii Strashko wrote:
>> On 06/03/2016 01:43 AM, Ivan Khoronzhuk wrote:
>>> There is no reason to hold s/w dependent parameter in device tree.
>>> Even more, there is no reason in this parameter because davinici_cpdma
>>> driver splits pool of descriptors equally between tx and rx channels.
>>> That is, if number of descriptors 256, 128 of them are for rx
>>> channels. While receiving, the descriptor is freed to the pool and
>>> then allocated with new skb. And if in DT the "rx_descs" is set to
>>> 64, then 128 - 64 = 64 descriptors are always in the pool and cannot
>>> be used, for tx, for instance. It's not correct resource usage,
>>> better to set it to half of pool, then the rx pool can be used in
>>> full. It will not have any impact on performance, as anyway, the
>>> "redundant" descriptors were unused.
>>>
>>> Signed-off-by: Ivan Khoronzhuk 
>>> ---
>>>
>>> Based on master
>>>
>>>   Documentation/devicetree/bindings/net/cpsw.txt |  3 ---
>>>   arch/arm/boot/dts/am33xx.dtsi  |  1 -
>>>   arch/arm/boot/dts/am4372.dtsi  |  1 -
>>>   arch/arm/boot/dts/dm814x.dtsi  |  1 -
>>>   arch/arm/boot/dts/dra7.dtsi|  1 -
>>
>>
>> Pls, split DT and non-DT changes, seems code changes should go first.
> Ok.
> 
>>
>>>   drivers/net/ethernet/ti/cpsw.c | 13 +++--
>>>   drivers/net/ethernet/ti/cpsw.h |  1 -
>>>   drivers/net/ethernet/ti/davinci_cpdma.c|  6 ++
>>>   drivers/net/ethernet/ti/davinci_cpdma.h|  1 +
>>>   9 files changed, 10 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/net/cpsw.txt 
>>> b/Documentation/devicetree/bindings/net/cpsw.txt
>>> index 0ae0649..5fe6239 100644
>>> --- a/Documentation/devicetree/bindings/net/cpsw.txt
>>> +++ b/Documentation/devicetree/bindings/net/cpsw.txt
>>> @@ -15,7 +15,6 @@ Required properties:
>>>   - cpdma_channels : Specifies number of channels in CPDMA
>>>   - ale_entries: Specifies No of entries ALE can hold
>>>   - bd_ram_size: Specifies internal descriptor RAM size
>>> -- rx_descs: Specifies number of Rx descriptors
>>>   - mac_control: Specifies Default MAC control register content
>>> for the specific platform
>>>   - slaves: Specifies number for slaves
>>> @@ -70,7 +69,6 @@ Examples:
>>
>> []
>>
>>>   slaves = <2>;
>>>   active_slave = <0>;
>>> diff --git a/drivers/net/ethernet/ti/cpsw.c 
>>> b/drivers/net/ethernet/ti/cpsw.c
>>> index 4b08a2f..635be3e 100644
>>> --- a/drivers/net/ethernet/ti/cpsw.c
>>> +++ b/drivers/net/ethernet/ti/cpsw.c
>>> @@ -1277,6 +1277,7 @@ static int cpsw_ndo_open(struct net_device *ndev)
>>> ALE_ALL_PORTS, ALE_ALL_PORTS, 0, 0);
>>>
>>>   if (!cpsw_common_res_usage_state(priv)) {
>>> +int buf_num;
>>>   struct cpsw_priv *priv_sl0 = cpsw_get_slave_priv(priv, 0);
>>>
>>>   /* setup tx dma to fixed prio and zero offset */
>>> @@ -1305,10 +1306,8 @@ static int cpsw_ndo_open(struct net_device *ndev)
>>>   enable_irq(priv->irqs_table[0]);
>>>   }
>>>
>>> -if (WARN_ON(!priv->data.rx_descs))
>>> -priv->data.rx_descs = 128;
>>> -
>>> -for (i = 0; i < priv->data.rx_descs; i++) {
>>> +buf_num = cpdma_chan_get_buf_num(priv->dma) / 2;
>>
>> Could you get rid of "/ 2", pls?
>>
> Why? compiler is smart enough to translate it to shift.
> And this is not time critical place.
> Anyway, will change it to >> 1 while splitting.
> 

I mean here that cpsw, in general, should not have any knowledge about rules
 used by cpdma to split pool on rx and tx part. How about 
cpdma_chan_get_rx_buf_num()?


-- 
regards,
-grygorii


[PATCH 12/15] net: davinci_mdio: document missed "ti,am4372-mdio" compat string

2016-06-15 Thread Grygorii Strashko
Document missed "ti,am4372-mdio" compat string used for TI am437x SoC
(am4372.dtsi).

Signed-off-by: Grygorii Strashko 
---
 Documentation/devicetree/bindings/net/davinci-mdio.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/davinci-mdio.txt 
b/Documentation/devicetree/bindings/net/davinci-mdio.txt
index 0369e25..f2bba50 100644
--- a/Documentation/devicetree/bindings/net/davinci-mdio.txt
+++ b/Documentation/devicetree/bindings/net/davinci-mdio.txt
@@ -2,7 +2,8 @@ TI SoC Davinci/Keystone2 MDIO Controller Device Tree Bindings
 ---
 
 Required properties:
-- compatible   : Should be "ti,davinci_mdio" or "ti,keystone_mdio"
+- compatible   : Should be "ti,davinci_mdio", "ti,keystone_mdio",
+ "ti,am4372-mdio"
 - reg  : physical base address and size of the davinci mdio
  registers map
 - bus_freq : Mdio Bus frequency
-- 
2.8.4



[PATCH 13/15] net: davinci_mdio: introduce "ti,cpsw-mdio" compat string

2016-06-15 Thread Grygorii Strashko
Introduce "ti,cpsw-mdio" compatible string for Davinci MDIO, because
it's required to distinguish the case when MDIO is part of TI CPSW to
enable features supported by TI CPSW (for example, enable PM
management).

Signed-off-by: Grygorii Strashko 
---
 Documentation/devicetree/bindings/net/davinci-mdio.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/davinci-mdio.txt 
b/Documentation/devicetree/bindings/net/davinci-mdio.txt
index f2bba50..a3d6d4b 100644
--- a/Documentation/devicetree/bindings/net/davinci-mdio.txt
+++ b/Documentation/devicetree/bindings/net/davinci-mdio.txt
@@ -3,7 +3,7 @@ TI SoC Davinci/Keystone2 MDIO Controller Device Tree Bindings
 
 Required properties:
 - compatible   : Should be "ti,davinci_mdio", "ti,keystone_mdio",
- "ti,am4372-mdio"
+ "ti,am4372-mdio", "ti,cpsw-mdio"
 - reg  : physical base address and size of the davinci mdio
  registers map
 - bus_freq : Mdio Bus frequency
-- 
2.8.4



[PATCH 01/15] drivers: net: cpsw: fix suspend when all ethX devices are down

2016-06-15 Thread Grygorii Strashko
The cpsw_suspend() could trigger L3 error and CPSW will stop
functioning if System enters suspend when all ethX net-devices are
down - in this case CPSW could be already suspended by PM runtime, but
cpsw_suspend() will try to call soft_reset_slave() unconditionally
and access CPSW registers.

Hence, fix it by moving soft_reset_slave() from cpsw_suspend() to
cpsw_slave_stop(). This way slave ports will be reset when CPSW is
active and will be in proper state during Suspend.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/cpsw.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index e6bb0ec..736c77a 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1244,6 +1244,7 @@ static void cpsw_slave_stop(struct cpsw_slave *slave, 
struct cpsw_priv *priv)
slave->phy = NULL;
cpsw_ale_control_set(priv->ale, slave_port,
 ALE_PORT_STATE, ALE_PORT_STATE_DISABLE);
+   soft_reset_slave(slave);
 }
 
 static int cpsw_ndo_open(struct net_device *ndev)
@@ -2558,12 +2559,10 @@ static int cpsw_suspend(struct device *dev)
for (i = 0; i < priv->data.slaves; i++) {
if (netif_running(priv->slaves[i].ndev))
cpsw_ndo_stop(priv->slaves[i].ndev);
-   soft_reset_slave(priv->slaves + i);
}
} else {
if (netif_running(ndev))
cpsw_ndo_stop(ndev);
-   for_each_slave(priv, soft_reset_slave);
}
 
pm_runtime_put_sync(&pdev->dev);
-- 
2.8.4



[PATCH 11/15] drivers: net: davinci_mdio: implement pm runtime auto mode

2016-06-15 Thread Grygorii Strashko
Davinci MDIO is always used as slave device which services
read/write requests from MDIO/PHY core. It doesn't use IRQ also.

As result, It's possible to relax PM runtime constraints for Davinci
MDIO and enable it on demand, instead of powering it during probe
and powering off during removal.

Hence, implement PM runtime autosuspend for Davinci MDIO, but keep it
disabled by default, because Davinci MDIO is integrated in big set of
TI devices and not all of them expected to work corectly with RPM
 autosuspend enabled:
- expected to work on SoCs where MDIO is defined as part of TI CPSW in DT
(cpsw.c DRA7/am57x, am437x, am335x, dm814x)
- not verified on Keystone 2 and other SoCs where MDIO is used with TI EMAC IP
(davinci_emac.c:  dm6467-emac, am3517-emac, dm816-emac).

Davinci MDIO RPM autosuspend can be enabled through sysfs:
 echo 100 > 
/sys/devices/../48484000.ethernet/48485000.mdio/power/autosuspend_delay_ms

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/davinci_mdio.c | 48 +++---
 1 file changed, 39 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c 
b/drivers/net/ethernet/ti/davinci_mdio.c
index 13f5080..ce3ec42 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -93,6 +93,7 @@ struct davinci_mdio_data {
struct clk  *clk;
struct device   *dev;
struct mii_bus  *bus;
+   boolactive_in_suspend;
unsigned long   access_time; /* jiffies */
/* Indicates that driver shouldn't modify phy_mask in case
 * if MDIO bus is registered from DT.
@@ -141,8 +142,13 @@ static int davinci_mdio_reset(struct mii_bus *bus)
 {
struct davinci_mdio_data *data = bus->priv;
u32 phy_mask, ver;
+   int ret;
 
-   davinci_mdio_enable(data);
+   ret = pm_runtime_get_sync(data->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(data->dev);
+   return ret;
+   }
 
/* wait for scan logic to settle */
msleep(PHY_MAX_ADDR * data->access_time);
@@ -153,7 +159,7 @@ static int davinci_mdio_reset(struct mii_bus *bus)
 (ver >> 8) & 0xff, ver & 0xff);
 
if (data->skip_scan)
-   return 0;
+   goto done;
 
/* get phy mask from the alive register */
phy_mask = __raw_readl(&data->regs->alive);
@@ -168,6 +174,10 @@ static int davinci_mdio_reset(struct mii_bus *bus)
}
data->bus->phy_mask = phy_mask;
 
+done:
+   pm_runtime_mark_last_busy(data->dev);
+   pm_runtime_put_autosuspend(data->dev);
+
return 0;
 }
 
@@ -228,6 +238,12 @@ static int davinci_mdio_read(struct mii_bus *bus, int 
phy_id, int phy_reg)
if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
return -EINVAL;
 
+   ret = pm_runtime_get_sync(data->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(data->dev);
+   return ret;
+   }
+
reg = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) |
   (phy_id << 16));
 
@@ -251,6 +267,8 @@ static int davinci_mdio_read(struct mii_bus *bus, int 
phy_id, int phy_reg)
break;
}
 
+   pm_runtime_mark_last_busy(data->dev);
+   pm_runtime_put_autosuspend(data->dev);
return ret;
 }
 
@@ -264,6 +282,12 @@ static int davinci_mdio_write(struct mii_bus *bus, int 
phy_id,
if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
return -EINVAL;
 
+   ret = pm_runtime_get_sync(data->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(data->dev);
+   return ret;
+   }
+
reg = (USERACCESS_GO | USERACCESS_WRITE | (phy_reg << 21) |
   (phy_id << 16) | (phy_data & USERACCESS_DATA));
 
@@ -282,7 +306,10 @@ static int davinci_mdio_write(struct mii_bus *bus, int 
phy_id,
break;
}
 
-   return 0;
+   pm_runtime_mark_last_busy(data->dev);
+   pm_runtime_put_autosuspend(data->dev);
+
+   return ret;
 }
 
 #if IS_ENABLED(CONFIG_OF)
@@ -357,8 +384,9 @@ static int davinci_mdio_probe(struct platform_device *pdev)
 
davinci_mdio_init_clk(data);
 
+   pm_runtime_set_autosuspend_delay(&pdev->dev, -1);
+   pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_enable(&pdev->dev);
-   pm_runtime_get_sync(&pdev->dev);
 
/* register the mii bus
 * Create PHYs from DT only in case if PHY child nodes are explicitly
@@ -387,9 +415,8 @@ static int davinci_mdio_probe(struct platform_device *pdev)
return 0;
 
 bail_out:
-   pm_runtime_put_sync(&pdev->dev);
+   pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_disable(

[PATCH 04/15] drivers: net: cpsw: ethtool: fix accessing to suspended device

2016-06-15 Thread Grygorii Strashko
The CPSW might be suspended by RPM if all ethX interfaces are down,
but it still could be accesible through ethtool interfce. In this case
ethtool operations, requiring registers access, will cause L3 errors and
CPSW crash.

Hence, fix it by adding RPM get/put calls in ethtool callbcaks which
can access CPSW registers: .set_coalesce(), .get_ethtool_stats(),
.set_pauseparam(), .get_regs()

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/cpsw.c | 36 +++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index ba81d4e..1ba0c09 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -931,6 +931,13 @@ static int cpsw_set_coalesce(struct net_device *ndev,
u32 prescale = 0;
u32 addnl_dvdr = 1;
u32 coal_intvl = 0;
+   int ret;
+
+   ret = pm_runtime_get_sync(&priv->pdev->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(&priv->pdev->dev);
+   return ret;
+   }
 
coal_intvl = coal->rx_coalesce_usecs;
 
@@ -985,6 +992,8 @@ update_return:
priv->coal_intvl = coal_intvl;
}
 
+   pm_runtime_put(&priv->pdev->dev);
+
return 0;
 }
 
@@ -1022,7 +1031,13 @@ static void cpsw_get_ethtool_stats(struct net_device 
*ndev,
struct cpdma_chan_stats tx_stats;
u32 val;
u8 *p;
-   int i;
+   int i, ret;
+
+   ret = pm_runtime_get_sync(&priv->pdev->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(&priv->pdev->dev);
+   return;
+   }
 
/* Collect Davinci CPDMA stats for Rx and Tx Channel */
cpdma_chan_get_stats(priv->rxch, &rx_stats);
@@ -1049,6 +1064,8 @@ static void cpsw_get_ethtool_stats(struct net_device 
*ndev,
break;
}
}
+
+   pm_runtime_put(&priv->pdev->dev);
 }
 
 static int cpsw_common_res_usage_state(struct cpsw_priv *priv)
@@ -1780,11 +1797,20 @@ static void cpsw_get_regs(struct net_device *ndev,
 {
struct cpsw_priv *priv = netdev_priv(ndev);
u32 *reg = p;
+   int ret;
+
+   ret = pm_runtime_get_sync(&priv->pdev->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(&priv->pdev->dev);
+   return;
+   }
 
/* update CPSW IP version */
regs->version = priv->version;
 
cpsw_ale_dump(priv->ale, reg);
+
+   pm_runtime_put(&priv->pdev->dev);
 }
 
 static void cpsw_get_drvinfo(struct net_device *ndev,
@@ -1902,12 +1928,20 @@ static int cpsw_set_pauseparam(struct net_device *ndev,
 {
struct cpsw_priv *priv = netdev_priv(ndev);
bool link;
+   int ret;
+
+   ret = pm_runtime_get_sync(&priv->pdev->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(&priv->pdev->dev);
+   return ret;
+   }
 
priv->rx_pause = pause->rx_pause ? true : false;
priv->tx_pause = pause->tx_pause ? true : false;
 
for_each_slave(priv, _cpsw_adjust_link, priv, &link);
 
+   pm_runtime_put(&priv->pdev->dev);
return 0;
 }
 
-- 
2.8.4



[PATCH 08/15] drivers: net: davinci_mdio: drop suspended and lock fields from mdio_data

2016-06-15 Thread Grygorii Strashko
The Davinci MDIO is not expected to be accessible after its suspend
callbacks has been called:
 - all consumers of Davinci MDIO will stop/disconnect their phys at Device
suspend stage;
 - all phys are expected to be suspended already by PHY/MDIO core;
 - MDIO locking is done by MDIO Bus code.

Hence, it's safe to drop "suspended" and "lock" fields from mdio_data.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/davinci_mdio.c | 30 --
 1 file changed, 30 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c 
b/drivers/net/ethernet/ti/davinci_mdio.c
index 291c42e..b6d0059 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -90,11 +90,9 @@ static const struct mdio_platform_data default_pdata = {
 struct davinci_mdio_data {
struct mdio_platform_data pdata;
struct davinci_mdio_regs __iomem *regs;
-   spinlock_t  lock;
struct clk  *clk;
struct device   *dev;
struct mii_bus  *bus;
-   boolsuspended;
unsigned long   access_time; /* jiffies */
/* Indicates that driver shouldn't modify phy_mask in case
 * if MDIO bus is registered from DT.
@@ -225,13 +223,6 @@ static int davinci_mdio_read(struct mii_bus *bus, int 
phy_id, int phy_reg)
if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
return -EINVAL;
 
-   spin_lock(&data->lock);
-
-   if (data->suspended) {
-   spin_unlock(&data->lock);
-   return -ENODEV;
-   }
-
reg = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) |
   (phy_id << 16));
 
@@ -255,8 +246,6 @@ static int davinci_mdio_read(struct mii_bus *bus, int 
phy_id, int phy_reg)
break;
}
 
-   spin_unlock(&data->lock);
-
return ret;
 }
 
@@ -270,13 +259,6 @@ static int davinci_mdio_write(struct mii_bus *bus, int 
phy_id,
if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
return -EINVAL;
 
-   spin_lock(&data->lock);
-
-   if (data->suspended) {
-   spin_unlock(&data->lock);
-   return -ENODEV;
-   }
-
reg = (USERACCESS_GO | USERACCESS_WRITE | (phy_reg << 21) |
   (phy_id << 16) | (phy_data & USERACCESS_DATA));
 
@@ -295,8 +277,6 @@ static int davinci_mdio_write(struct mii_bus *bus, int 
phy_id,
break;
}
 
-   spin_unlock(&data->lock);
-
return 0;
 }
 
@@ -364,7 +344,6 @@ static int davinci_mdio_probe(struct platform_device *pdev)
 
dev_set_drvdata(dev, data);
data->dev = dev;
-   spin_lock_init(&data->lock);
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
data->regs = devm_ioremap_resource(dev, res);
@@ -426,17 +405,12 @@ static int davinci_mdio_suspend(struct device *dev)
struct davinci_mdio_data *data = dev_get_drvdata(dev);
u32 ctrl;
 
-   spin_lock(&data->lock);
-
/* shutdown the scan state machine */
ctrl = __raw_readl(&data->regs->control);
ctrl &= ~CONTROL_ENABLE;
__raw_writel(ctrl, &data->regs->control);
wait_for_idle(data);
 
-   data->suspended = true;
-   spin_unlock(&data->lock);
-
/* Select sleep pin state */
pinctrl_pm_select_sleep_state(dev);
 
@@ -450,13 +424,9 @@ static int davinci_mdio_resume(struct device *dev)
/* Select default pin state */
pinctrl_pm_select_default_state(dev);
 
-   spin_lock(&data->lock);
/* restart the scan state machine */
__davinci_mdio_reset(data);
 
-   data->suspended = false;
-   spin_unlock(&data->lock);
-
return 0;
 }
 #endif
-- 
2.8.4



[PATCH 14/15] drivers: net: davinci_mdio: enable pm runtime auto for ti cpsw-mdio

2016-06-15 Thread Grygorii Strashko
Use "ti,cpsw-mdio" to enable PM runtime auto-suspend on supported
platforms, where MDIO is implemented as part of TI CPSW.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/davinci_mdio.c | 45 +-
 1 file changed, 34 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c 
b/drivers/net/ethernet/ti/davinci_mdio.c
index ce3ec42..d1fb734 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -53,6 +53,10 @@
 
 #define DEF_OUT_FREQ   220 /* 2.2 MHz */
 
+struct davinci_mdio_of_param {
+   int autosuspend_delay_ms;
+};
+
 struct davinci_mdio_regs {
u32 version;
u32 control;
@@ -332,6 +336,19 @@ static int davinci_mdio_probe_dt(struct mdio_platform_data 
*data,
 }
 #endif
 
+#if IS_ENABLED(CONFIG_OF)
+static const struct davinci_mdio_of_param of_cpsw_mdio_data = {
+   .autosuspend_delay_ms = 100,
+};
+
+static const struct of_device_id davinci_mdio_of_mtable[] = {
+   { .compatible = "ti,davinci_mdio", },
+   { .compatible = "ti,cpsw-mdio", .data = &of_cpsw_mdio_data},
+   { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, davinci_mdio_of_mtable);
+#endif
+
 static int davinci_mdio_probe(struct platform_device *pdev)
 {
struct mdio_platform_data *pdata = dev_get_platdata(&pdev->dev);
@@ -340,6 +357,7 @@ static int davinci_mdio_probe(struct platform_device *pdev)
struct resource *res;
struct phy_device *phy;
int ret, addr;
+   int autosuspend_delay_ms = -1;
 
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
@@ -352,9 +370,22 @@ static int davinci_mdio_probe(struct platform_device *pdev)
}
 
if (dev->of_node) {
-   if (davinci_mdio_probe_dt(&data->pdata, pdev))
-   data->pdata = default_pdata;
+   const struct of_device_id   *of_id;
+
+   ret = davinci_mdio_probe_dt(data, pdev);
+   if (ret)
+   return ret;
snprintf(data->bus->id, MII_BUS_ID_SIZE, "%s", pdev->name);
+
+   of_id = of_match_device(davinci_mdio_of_mtable, &pdev->dev);
+   if (of_id) {
+   const struct davinci_mdio_of_param *of_mdio_data;
+
+   of_mdio_data = of_id->data;
+   if (of_mdio_data)
+   autosuspend_delay_ms =
+   of_mdio_data->autosuspend_delay_ms;
+   }
} else {
data->pdata = pdata ? (*pdata) : default_pdata;
snprintf(data->bus->id, MII_BUS_ID_SIZE, "%s-%x",
@@ -384,7 +415,7 @@ static int davinci_mdio_probe(struct platform_device *pdev)
 
davinci_mdio_init_clk(data);
 
-   pm_runtime_set_autosuspend_delay(&pdev->dev, -1);
+   pm_runtime_set_autosuspend_delay(&pdev->dev, autosuspend_delay_ms);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_enable(&pdev->dev);
 
@@ -495,14 +526,6 @@ static const struct dev_pm_ops davinci_mdio_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(davinci_mdio_suspend, davinci_mdio_resume)
 };
 
-#if IS_ENABLED(CONFIG_OF)
-static const struct of_device_id davinci_mdio_of_mtable[] = {
-   { .compatible = "ti,davinci_mdio", },
-   { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, davinci_mdio_of_mtable);
-#endif
-
 static struct platform_driver davinci_mdio_driver = {
.driver = {
.name= "davinci_mdio",
-- 
2.8.4



[PATCH 10/15] drivers: net: davinci_mdio: add pm runtime callbacks

2016-06-15 Thread Grygorii Strashko
Add PM runtime .runtime_suspend()/.runtime_resume() callbacks and
perform Davinci MDIO enabling/disabling from these callbacks. This
allows to reuse pm_runtime_force_suspend/resume() APIs during System
suspend and required for further implementation of PM runtime
autosuspend.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/davinci_mdio.c | 31 +++
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c 
b/drivers/net/ethernet/ti/davinci_mdio.c
index b206fd3..13f5080 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -406,8 +406,8 @@ static int davinci_mdio_remove(struct platform_device *pdev)
return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int davinci_mdio_suspend(struct device *dev)
+#ifdef CONFIG_PM
+static int davinci_mdio_runtime_suspend(struct device *dev)
 {
struct davinci_mdio_data *data = dev_get_drvdata(dev);
u32 ctrl;
@@ -418,6 +418,28 @@ static int davinci_mdio_suspend(struct device *dev)
__raw_writel(ctrl, &data->regs->control);
wait_for_idle(data);
 
+   return 0;
+}
+
+static int davinci_mdio_runtime_resume(struct device *dev)
+{
+   struct davinci_mdio_data *data = dev_get_drvdata(dev);
+
+   davinci_mdio_enable(data);
+   return 0;
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int davinci_mdio_suspend(struct device *dev)
+{
+   struct davinci_mdio_data *data = dev_get_drvdata(dev);
+   int ret = 0;
+
+   ret = pm_runtime_force_suspend(dev);
+   if (ret < 0)
+   return ret;
+
/* Select sleep pin state */
pinctrl_pm_select_sleep_state(dev);
 
@@ -431,14 +453,15 @@ static int davinci_mdio_resume(struct device *dev)
/* Select default pin state */
pinctrl_pm_select_default_state(dev);
 
-   /* restart the scan state machine */
-   davinci_mdio_enable(data);
+   pm_runtime_force_resume(dev);
 
return 0;
 }
 #endif
 
 static const struct dev_pm_ops davinci_mdio_pm_ops = {
+   SET_RUNTIME_PM_OPS(davinci_mdio_runtime_suspend,
+  davinci_mdio_runtime_resume, NULL)
SET_LATE_SYSTEM_SLEEP_PM_OPS(davinci_mdio_suspend, davinci_mdio_resume)
 };
 
-- 
2.8.4



[PATCH 15/15] ARM: dts: am335x/am437x/dra7: use new "ti,cpsw-mdio" compat string

2016-06-15 Thread Grygorii Strashko
Add "ti,cpsw-mdio" for am335x/am437x/dra7 SoCs where MDIO is
implemented as part of TI CPSW and, this way, enable PM runtime auto
suspend for Davinci MDIO driver on these paltforms.

Signed-off-by: Grygorii Strashko 
---
 arch/arm/boot/dts/am33xx.dtsi | 2 +-
 arch/arm/boot/dts/am4372.dtsi | 2 +-
 arch/arm/boot/dts/dra7.dtsi   | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 52be48b..7fa9a1d 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -789,7 +789,7 @@
status = "disabled";
 
davinci_mdio: mdio@4a101000 {
-   compatible = "ti,davinci_mdio";
+   compatible = "ti,cpsw-mdio","ti,davinci_mdio";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "davinci_mdio";
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index 12fcde4..ea76fa7 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -636,7 +636,7 @@
syscon = <&scm_conf>;
 
davinci_mdio: mdio@4a101000 {
-   compatible = "ti,am4372-mdio","ti,davinci_mdio";
+   compatible = 
"ti,am4372-mdio","ti,cpsw-mdio","ti,davinci_mdio";
reg = <0x4a101000 0x100>;
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index e007401..911ef85 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1661,7 +1661,7 @@
status = "disabled";
 
davinci_mdio: mdio@48485000 {
-   compatible = "ti,davinci_mdio";
+   compatible = "ti,cpsw-mdio","ti,davinci_mdio";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "davinci_mdio";
-- 
2.8.4



[PATCH 09/15] drivers: net: davinci_mdio: split reset function on init_clk and enable

2016-06-15 Thread Grygorii Strashko
The Davinci MDIO MDIO_CONTROL.CLKDIV can be calculated only once
during probe, hence split __davinci_mdio_reset() on
davinci_mdio_init_clk() and davinci_mdio_enable(). Initialize and
save CLKDIV in .probe(). Then just use saved value.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/davinci_mdio.c | 21 ++---
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c 
b/drivers/net/ethernet/ti/davinci_mdio.c
index b6d0059..b206fd3 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -98,9 +98,10 @@ struct davinci_mdio_data {
 * if MDIO bus is registered from DT.
 */
boolskip_scan;
+   u32 clk_div;
 };
 
-static void __davinci_mdio_reset(struct davinci_mdio_data *data)
+static void davinci_mdio_init_clk(struct davinci_mdio_data *data)
 {
u32 mdio_in, div, mdio_out_khz, access_time;
 
@@ -109,9 +110,7 @@ static void __davinci_mdio_reset(struct davinci_mdio_data 
*data)
if (div > CONTROL_MAX_DIV)
div = CONTROL_MAX_DIV;
 
-   /* set enable and clock divider */
-   __raw_writel(div | CONTROL_ENABLE, &data->regs->control);
-
+   data->clk_div = div;
/*
 * One mdio transaction consists of:
 *  32 bits of preamble
@@ -132,12 +131,18 @@ static void __davinci_mdio_reset(struct davinci_mdio_data 
*data)
data->access_time = 1;
 }
 
+static void davinci_mdio_enable(struct davinci_mdio_data *data)
+{
+   /* set enable and clock divider */
+   __raw_writel(data->clk_div | CONTROL_ENABLE, &data->regs->control);
+}
+
 static int davinci_mdio_reset(struct mii_bus *bus)
 {
struct davinci_mdio_data *data = bus->priv;
u32 phy_mask, ver;
 
-   __davinci_mdio_reset(data);
+   davinci_mdio_enable(data);
 
/* wait for scan logic to settle */
msleep(PHY_MAX_ADDR * data->access_time);
@@ -188,7 +193,7 @@ static inline int wait_for_user_access(struct 
davinci_mdio_data *data)
 * operation
 */
dev_warn(data->dev, "resetting idled controller\n");
-   __davinci_mdio_reset(data);
+   davinci_mdio_enable(data);
return -EAGAIN;
}
 
@@ -350,6 +355,8 @@ static int davinci_mdio_probe(struct platform_device *pdev)
if (IS_ERR(data->regs))
return PTR_ERR(data->regs);
 
+   davinci_mdio_init_clk(data);
+
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
 
@@ -425,7 +432,7 @@ static int davinci_mdio_resume(struct device *dev)
pinctrl_pm_select_default_state(dev);
 
/* restart the scan state machine */
-   __davinci_mdio_reset(data);
+   davinci_mdio_enable(data);
 
return 0;
 }
-- 
2.8.4



[PATCH 06/15] drivers: net: davinci_mdio: do pm runtime initialization later in probe

2016-06-15 Thread Grygorii Strashko
Do PM runtime initialization later in probe - this allows to simplify
error handling a bit.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/davinci_mdio.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c 
b/drivers/net/ethernet/ti/davinci_mdio.c
index 4e7c9b9..2e19dd1 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -356,14 +356,10 @@ static int davinci_mdio_probe(struct platform_device 
*pdev)
data->bus->parent   = dev;
data->bus->priv = data;
 
-   pm_runtime_enable(&pdev->dev);
-   pm_runtime_get_sync(&pdev->dev);
data->clk = devm_clk_get(dev, "fck");
if (IS_ERR(data->clk)) {
dev_err(dev, "failed to get device clock\n");
-   ret = PTR_ERR(data->clk);
-   data->clk = NULL;
-   goto bail_out;
+   return PTR_ERR(data->clk);
}
 
dev_set_drvdata(dev, data);
@@ -372,10 +368,11 @@ static int davinci_mdio_probe(struct platform_device 
*pdev)
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
data->regs = devm_ioremap_resource(dev, res);
-   if (IS_ERR(data->regs)) {
-   ret = PTR_ERR(data->regs);
-   goto bail_out;
-   }
+   if (IS_ERR(data->regs))
+   return PTR_ERR(data->regs);
+
+   pm_runtime_enable(&pdev->dev);
+   pm_runtime_get_sync(&pdev->dev);
 
/* register the mii bus
 * Create PHYs from DT only in case if PHY child nodes are explicitly
-- 
2.8.4



[PATCH 02/15] drivers: net: cpsw: check return code from pm runtime calls

2016-06-15 Thread Grygorii Strashko
Add missed check of return codes from PM runtime get() calls.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/cpsw.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 736c77a..c76f9db 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1253,7 +1253,11 @@ static int cpsw_ndo_open(struct net_device *ndev)
int i, ret;
u32 reg;
 
-   pm_runtime_get_sync(&priv->pdev->dev);
+   ret = pm_runtime_get_sync(&priv->pdev->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(&priv->pdev->dev);
+   return ret;
+   }
 
if (!cpsw_common_res_usage_state(priv))
cpsw_intr_disable(priv);
@@ -2322,7 +2326,11 @@ static int cpsw_probe(struct platform_device *pdev)
/* Need to enable clocks with runtime PM api to access module
 * registers
 */
-   pm_runtime_get_sync(&pdev->dev);
+   ret = pm_runtime_get_sync(&pdev->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(&pdev->dev);
+   goto clean_runtime_disable_ret;
+   }
priv->version = readl(&priv->regs->id_ver);
pm_runtime_put_sync(&pdev->dev);
 
-- 
2.8.4



[PATCH 05/15] drivers: net: cpsw: ndev: fix accessing to suspended device

2016-06-15 Thread Grygorii Strashko
The CPSW might be suspended by RPM if all ethX interfaces are down,
but it still could be accesible through net_device_ops interfce. In
this case net_device_ops operations, requiring registers access, will
cause L3 errors and CPSW crash.

Hence, fix it by adding RPM get/put calls in net_device_ops callbacks
which can access CPSW registers: .ndo_set_mac_address(),
.ndo_vlan_rx_add_vid(), .ndo_vlan_rx_kill_vid().

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/cpsw.c | 33 ++---
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 1ba0c09..591d1c3 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1633,10 +1633,17 @@ static int cpsw_ndo_set_mac_address(struct net_device 
*ndev, void *p)
struct sockaddr *addr = (struct sockaddr *)p;
int flags = 0;
u16 vid = 0;
+   int ret;
 
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
 
+   ret = pm_runtime_get_sync(&priv->pdev->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(&priv->pdev->dev);
+   return ret;
+   }
+
if (priv->data.dual_emac) {
vid = priv->slaves[priv->emac_port].port_vlan;
flags = ALE_VLAN;
@@ -1651,6 +1658,8 @@ static int cpsw_ndo_set_mac_address(struct net_device 
*ndev, void *p)
memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN);
for_each_slave(priv, cpsw_set_slave_mac, priv);
 
+   pm_runtime_put(&priv->pdev->dev);
+
return 0;
 }
 
@@ -1715,10 +1724,17 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device 
*ndev,
__be16 proto, u16 vid)
 {
struct cpsw_priv *priv = netdev_priv(ndev);
+   int ret;
 
if (vid == priv->data.default_vlan)
return 0;
 
+   ret = pm_runtime_get_sync(&priv->pdev->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(&priv->pdev->dev);
+   return ret;
+   }
+
if (priv->data.dual_emac) {
/* In dual EMAC, reserved VLAN id should not be used for
 * creating VLAN interfaces as this can break the dual
@@ -1733,7 +1749,10 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device 
*ndev,
}
 
dev_info(priv->dev, "Adding vlanid %d to vlan filter\n", vid);
-   return cpsw_add_vlan_ale_entry(priv, vid);
+   ret = cpsw_add_vlan_ale_entry(priv, vid);
+
+   pm_runtime_put(&priv->pdev->dev);
+   return ret;
 }
 
 static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev,
@@ -1745,6 +1764,12 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device 
*ndev,
if (vid == priv->data.default_vlan)
return 0;
 
+   ret = pm_runtime_get_sync(&priv->pdev->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(&priv->pdev->dev);
+   return ret;
+   }
+
if (priv->data.dual_emac) {
int i;
 
@@ -1764,8 +1789,10 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device 
*ndev,
if (ret != 0)
return ret;
 
-   return cpsw_ale_del_mcast(priv->ale, priv->ndev->broadcast,
- 0, ALE_VLAN, vid);
+   ret = cpsw_ale_del_mcast(priv->ale, priv->ndev->broadcast,
+0, ALE_VLAN, vid);
+   pm_runtime_put(&priv->pdev->dev);
+   return ret;
 }
 
 static const struct net_device_ops cpsw_netdev_ops = {
-- 
2.8.4



[PATCH 03/15] drivers: net: cpsw: remove pm runtime calls from suspend callbacks

2016-06-15 Thread Grygorii Strashko
PM runtime is properly handled in cpsw_ndo_open/stop(), as result it
isn't required to duplicate these calls in .suspend()/.resume()
callbacks. Moreover, it might cause unnecessary RPM resume of CPSW
during System suspend in the case it's already suspended because
all ethX interfaces are down, before System suspend started.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/cpsw.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index c76f9db..ba81d4e 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -2573,8 +2573,6 @@ static int cpsw_suspend(struct device *dev)
cpsw_ndo_stop(ndev);
}
 
-   pm_runtime_put_sync(&pdev->dev);
-
/* Select sleep pin state */
pinctrl_pm_select_sleep_state(&pdev->dev);
 
@@ -2587,8 +2585,6 @@ static int cpsw_resume(struct device *dev)
struct net_device   *ndev = platform_get_drvdata(pdev);
struct cpsw_priv*priv = netdev_priv(ndev);
 
-   pm_runtime_get_sync(&pdev->dev);
-
/* Select default pin state */
pinctrl_pm_select_default_state(&pdev->dev);
 
-- 
2.8.4



[PATCH 07/15] drivers: net: davinci_mdio: remove pm runtime calls from suspend callbacks

2016-06-15 Thread Grygorii Strashko
PM runtime is disabled when Davinci MDIO .suspend_late() and
.resume_early() callbacks are called. As result, any PM runtime calls here will
be just a nop and can be removed.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/davinci_mdio.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c 
b/drivers/net/ethernet/ti/davinci_mdio.c
index 2e19dd1..291c42e 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -436,7 +436,6 @@ static int davinci_mdio_suspend(struct device *dev)
 
data->suspended = true;
spin_unlock(&data->lock);
-   pm_runtime_put_sync(data->dev);
 
/* Select sleep pin state */
pinctrl_pm_select_sleep_state(dev);
@@ -451,8 +450,6 @@ static int davinci_mdio_resume(struct device *dev)
/* Select default pin state */
pinctrl_pm_select_default_state(dev);
 
-   pm_runtime_get_sync(data->dev);
-
spin_lock(&data->lock);
/* restart the scan state machine */
__davinci_mdio_reset(data);
-- 
2.8.4



[PATCH 00/15] drivers: net: cpsw: improve runtime pm

2016-06-15 Thread Grygorii Strashko
This series intended to improve runtime PM and allow CPSW to be
RPM suspended when all ethX netdevices are down.

To achieve above goal it is required to relax runtime PM constraints for
Davinci MDIO which blocks CPSW runtime PM now, because Davinci MDIO is always
powered on during probe and powered off only when it's going to be removed.
- Patches 6-11 implement PM runtime autosuspend for Davinci MDIO, but keep it
disabled by default, because Davinci MDIO is integrated in big set of TI devices
and not all of them verified to work correctly with RPM autosuspend enabled:
 expected to work on SoCs where MDIO is defined as part of CPSW in DT
 (cpsw.c DRA7/am57x, am437x, am335x)
The CPSW need to be fixed before RPM suspended can be allowed:
 - Patches 1-5 ensure that CPSW will not cause L3 errors while it is in RPM
   suspended state.

Davinci MDIO RPM autosuspend can be enabled through sysfs:
 echo 100 > 
/sys/devices/../48484000.ethernet/48485000.mdio/power/autosuspend_delay_ms

Patches 12 - 15: introduce new compatible string "ti,cpsw-mdio" which is used
then to enable RPM for am335x/am437x/dra7 SoCs.

Tested on am335x, am437x, am572x and k2g (on k2g with RPM disabled for Davinci 
MDIO)
These changes should not affect on errata i877 implementation on DRA7.

Power measurement on am335x GP EVM:
 Without this series:  547.60 mW total SoC power
 With this series + "ifconfig eth0 down": 477.32 mW Total Soc Power 

Grygorii Strashko (15):
  drivers: net: cpsw: fix suspend when all ethX devices are down
  drivers: net: cpsw: check return code from pm runtime calls
  drivers: net: cpsw: remove pm runtime calls from suspend callbacks
  drivers: net: cpsw: ethtool: fix accessing to suspended device
  drivers: net: cpsw: ndev: fix accessing to suspended device
  drivers: net: davinci_mdio: do pm runtime initialization later in
probe
  drivers: net: davinci_mdio: remove pm runtime calls from suspend
callbacks
  drivers: net: davinci_mdio: drop suspended and lock fields from
mdio_data
  drivers: net: davinci_mdio: split reset function on init_clk and
enable
  drivers: net: davinci_mdio: add pm runtime callbacks
  drivers: net: davinci_mdio: implement pm runtime auto mode
  net: davinci_mdio: document missed "ti,am4372-mdio" compat string
  net: davinci_mdio: introduce "ti,cpsw-mdio" compat string
  drivers: net: davinci_mdio: enable pm runtime auto for ti cpsw-mdio
  ARM: dts: am335x/am437x/dra7: use new "ti,cpsw-mdio" compat string

 .../devicetree/bindings/net/davinci-mdio.txt   |   3 +-
 arch/arm/boot/dts/am33xx.dtsi  |   2 +-
 arch/arm/boot/dts/am4372.dtsi  |   2 +-
 arch/arm/boot/dts/dra7.dtsi|   2 +-
 drivers/net/ethernet/ti/cpsw.c |  88 +--
 drivers/net/ethernet/ti/davinci_mdio.c | 169 +
 6 files changed, 189 insertions(+), 77 deletions(-)

-- 
2.8.4



Re: [PATCH 04/15] drivers: net: cpsw: ethtool: fix accessing to suspended device

2016-06-15 Thread Grygorii Strashko

On 06/15/2016 07:14 PM, Florian Fainelli wrote:

On 06/15/2016 04:55 AM, Grygorii Strashko wrote:

The CPSW might be suspended by RPM if all ethX interfaces are down,
but it still could be accesible through ethtool interfce. In this case
ethtool operations, requiring registers access, will cause L3 errors and
CPSW crash.

Hence, fix it by adding RPM get/put calls in ethtool callbcaks which
can access CPSW registers: .set_coalesce(), .get_ethtool_stats(),
.set_pauseparam(), .get_regs()


Provided that you implement an ethtool_ops::begin, it will be called
before each ethtool operation runs, so that could allow you to eliminate
some of the duplication here. Conversely ethtool_ops::end terminates
each operation and can be used for that purpose.


Ah. Thanks for the advice. (assume you've meant .complete())



--
regards,
-grygorii


Re: Keystone 2 boards boot failure

2016-02-03 Thread Grygorii Strashko
Hi Arnd,

On 02/03/2016 04:11 PM, Franklin S Cooper Jr. wrote:
> On 02/02/2016 07:19 PM, Franklin S Cooper Jr. wrote:
>>
>> On 02/02/2016 05:26 PM, Arnd Bergmann wrote:
>>> On Tuesday 02 February 2016 16:59:34 Franklin Cooper wrote:
>>>> On 02/02/2016 03:26 PM, Arnd Bergmann wrote:
>>>>> On Tuesday 02 February 2016 15:01:33 Franklin S Cooper Jr. wrote:
>>>>>> Yes. Here is a boot log on the latest master with the below
>>>>>> three patches reverted.
>>>>>> http://pastebin.com/W7RWSHpE (Working)
>>>>>>
>>>>>> I reverted these three patches. The two latest patches seem
>>>>>> to be trying to correct/expand upon the last patch on this list.
>>>>>>
>>>>>> commit 958d104e3d40eef5148c402887138f6594ff7e1e
>>>>>> netcp: fix regression in receive processing
>>>>>>
>>>>>> commit 9dd2d6c5c9755b160fe0111bcdad9491676feea8
>>>>>> netcp: add more __le32 annotations
>>>>>>
>>>>>> commit 899077791403ff7a2d8cfaa87bd1a82d729463e2
>>>>>> netcp: try to reduce type confusion in descriptors
>>>>>>
>>>>> The middle patch should have no effect on generated code, so I'm ignoring
>>>>> that for now.
>>>>>
>>>>> The next thing to rule out is an endianess bug. I assume you
>>>>> are running this on with a little-endian kernel, correct? If
>>>>> you are running big-endian, the base assumption that the driver needs
>>>>> to swap the data was flawed and that portion needs to be done.
>>>>>
>>>>> If you are running little-endian 32-bit, please try the partial
>>>>> revert below, which just undoes the attempt to make it work with
>>>>> 64-bit kernels.
>>>> Keystone 2 devices are little-endian 32-bit devices.
>>> I meant the kernel you are running on it, not the hardware.
>>> You should always be able to run both a big-endian kernel and
>>> a littl-endian kernel on any ARMv7 machine, and a couple of
>>> platforms use 64-bit physical addresses even on 32-bit machines
>>> (with the normal 32-bit instruction set).
>> I'm not sure if Keystone 2 devices support this or if we
>> have support for this. I'll have to double check.
>>> I wasn't completely sure if there are already keystone-derived
>>> products with 64-bit CPU cores, but I guess the driver would
>>> fail really badly on those (with or without the patch).
>>>
>>>> This partial revert fixes the boot problem for me.
>>> Ok.
>>>
>>>
>>> I tried to create a smaller version and stumbled over
>>> a typo, maybe that's the whole problem. Can you try this one:
>>>
>>> diff --git a/drivers/net/ethernet/ti/netcp_core.c 
>>> b/drivers/net/ethernet/ti/netcp_core.c
>>> index c61d66d38634..8490804416dd 100644
>>> --- a/drivers/net/ethernet/ti/netcp_core.c
>>> +++ b/drivers/net/ethernet/ti/netcp_core.c
>>> @@ -167,7 +167,7 @@ static void set_pad_info(u32 pad0, u32 pad1, u32 pad2, 
>>> struct knav_dma_desc *des
>>>   {
>>> desc->pad[0] = cpu_to_le32(pad0);
>>> desc->pad[1] = cpu_to_le32(pad1);
>>> -   desc->pad[2] = cpu_to_le32(pad1);
>>> +   desc->pad[2] = cpu_to_le32(pad2);
>>>   }
>>>   
>>>   static void set_org_pkt_info(dma_addr_t buff, u32 buff_len,
>>>
>>>
>> So only making this change on the latest master with no
>> other changes I see the boot problem again.

yep. I can confirm that.

Also, I'm today came up with the similar fix that you've proposed before in 
this thread.
So, Could we move forward this way?


>From 8280895f01b33edba303e7374431bef47630f26c Mon Sep 17 00:00:00 2001
From: Grygorii Strashko 
Date: Wed, 3 Feb 2016 15:11:40 +0200
Subject: [PATCH] net: ti: netcp: restore get/set_pad_info() functionality

The commit 899077791403 ("netcp: try to reduce type confusion in descriptors")
introduces a regression in Kernel 4.5-rc1 as it breaks
get/set_pad_info() functionality.

The TI NETCP driver uses pad0 and pad1 fields of knav_dma_desc to
store DMA/MEM buffer pointer and buffer size respectively. And in both
cases the pointer type size is 32 bit regardless of LAPE enabled or
not.
!LAPE   LPAE
sizeof(void*)   32bit   32bit
sizeof(dma_addr_t)  32bit   32bit
sizeof(phys_addr_t) 32bit   64bit

Unfortunately, above commit changed buffer's pointers save/re

Re: Keystone 2 boards boot failure

2016-02-03 Thread Grygorii Strashko

On 02/03/2016 06:20 PM, Arnd Bergmann wrote:

On Wednesday 03 February 2016 16:21:05 Grygorii Strashko wrote:

On 02/03/2016 04:11 PM, Franklin S Cooper Jr. wrote:

On 02/02/2016 07:19 PM, Franklin S Cooper Jr. wrote:



So only making this change on the latest master with no
other changes I see the boot problem again.


yep. I can confirm that.

Also, I'm today came up with the similar fix that you've proposed before in 
this thread.
So, Could we move forward this way?


I still think it would be good to actually understand what the actual
problem was.


 From 8280895f01b33edba303e7374431bef47630f26c Mon Sep 17 00:00:00 2001
From: Grygorii Strashko 
Date: Wed, 3 Feb 2016 15:11:40 +0200
Subject: [PATCH] net: ti: netcp: restore get/set_pad_info() functionality

The commit 899077791403 ("netcp: try to reduce type confusion in descriptors")
introduces a regression in Kernel 4.5-rc1 as it breaks
get/set_pad_info() functionality.

The TI NETCP driver uses pad0 and pad1 fields of knav_dma_desc to
store DMA/MEM buffer pointer and buffer size respectively. And in both
cases the pointer type size is 32 bit regardless of LAPE enabled or
not.
!LAPE   LPAE
sizeof(void*)   32bit   32bit
sizeof(dma_addr_t)  32bit   32bit
sizeof(phys_addr_t) 32bit   64bit



This looks wrong: I was getting the build warnings originally
because of 64-bit dma_addr_t, and that should be the only way that
this driver can operate, because in some configurations on keystone
there is no memory below 4GB, and there is no dma-ranges property
in the DT that shifts around the start of the DMA addresses.


see keystone.dtsi:
soc {
#address-cells = <1>;
#size-cells = <1>;
compatible = "ti,keystone","simple-bus";
interrupt-parent = <&gic>;
ranges = <0x0 0x0 0x0 0xc000>;
dma-ranges = <0x8000 0x8 0x 0x8000>;
^^^

config:

CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
CONFIG_PHYS_ADDR_T_64BIT=y

and

#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT <--- should not be defined for KS2
typedef u64 dma_addr_t;
#else
typedef u32 dma_addr_t;
#endif

Above is valid configuration for Keystone 2 with LPAE=y



This doesn't all fit together yet, maybe you have a better idea
of what is going on.

I don't think we should ever have a platform that has dma_addr_t
and phys_addr_t be different.


This is a valid case.




Unfortunately, above commit changed buffer's pointers save/restore
code (get/set_pad_info()) and added intermediate conversation to u64
which causes TI NETCP driver crash in RX/TX path due to "Unable to
handle kernel NULL pointer" exception.


The conversion is not what made it crash, it must be a bug in the
conversion ;-)


@@ -163,11 +153,10 @@ static void set_desc_info(u32 desc_info, u32 pkt_info,
desc->packet_info = cpu_to_le32(pkt_info);
  }

-static void set_pad_info(u32 pad0, u32 pad1, u32 pad2, struct knav_dma_desc 
*desc)
+static void set_pad_info(u32 pad0, u32 pad1, struct knav_dma_desc *desc)
  {
desc->pad[0] = cpu_to_le32(pad0);
desc->pad[1] = cpu_to_le32(pad1);
-   desc->pad[2] = cpu_to_le32(pad1);
  }


As in my earlier patch, the line you are removing here was clearly
broken, but evidently that is not the only bug.


  static void set_org_pkt_info(dma_addr_t buff, u32 buff_len,
@@ -581,7 +570,6 @@ static void netcp_free_rx_desc_chain(struct netcp_intf 
*netcp,
dma_addr_t dma_desc, dma_buf;
unsigned int buf_len, dma_sz = sizeof(*ndesc);
void *buf_ptr;
-   u32 pad[2];
u32 tmp;

get_words(&dma_desc, 1, &desc->next_desc);
@@ -593,14 +581,12 @@ static void netcp_free_rx_desc_chain(struct netcp_intf 
*netcp,
break;
}
get_pkt_info(&dma_buf, &tmp, &dma_desc, ndesc);
-   get_pad_ptr(&buf_ptr, ndesc);
+   get_pad_info((u32 *)&buf_ptr, &buf_len, ndesc);


I'd prefer not to put code like this back, as this cannot possibly
do the right thing on a 64-bit architecture.



@@ -1078,7 +1058,6 @@ netcp_tx_map_skb(struct sk_buff *skb, struct netcp_intf 
*netcp)
u32 page_offset = frag->page_offset;
u32 buf_len = skb_frag_size(frag);
dma_addr_t desc_dma;
-   u32 desc_dma_32;
u32 pkt_info;

dma_addr = dma_map_page(dev, page, page_offset, buf_len,
@@ -1100,8 +1079,7 @@ netcp_tx_map_skb(struct sk_buff *skb, struct netcp_intf 
*netcp)
(netcp->tx_compl_qid & KNAV_DMA_DESC_RETQ_MASK) <<
KNAV_DMA_DESC_RETQ_SHIFT;
set_pkt_info(dma_addr, buf_len, 0, ndesc);
-   desc_dma_32 = (u

Re: Keystone 2 boards boot failure

2016-02-04 Thread Grygorii Strashko
Hi Arnd,

On 02/03/2016 10:40 PM, Arnd Bergmann wrote:
> On Wednesday 03 February 2016 18:31:00 Grygorii Strashko wrote:
>> On 02/03/2016 06:20 PM, Arnd Bergmann wrote:
>>> On Wednesday 03 February 2016 16:21:05 Grygorii Strashko wrote:
>>>> On 02/03/2016 04:11 PM, Franklin S Cooper Jr. wrote:
>>>>> On 02/02/2016 07:19 PM, Franklin S Cooper Jr. wrote:
>>>
>>> This looks wrong: I was getting the build warnings originally
>>> because of 64-bit dma_addr_t, and that should be the only way that
>>> this driver can operate, because in some configurations on keystone
>>> there is no memory below 4GB, and there is no dma-ranges property
>>> in the DT that shifts around the start of the DMA addresses.
>>
>> see keystone.dtsi:
>>  soc {
>>  #address-cells = <1>;
>>  #size-cells = <1>;
>>  compatible = "ti,keystone","simple-bus";
>>  interrupt-parent = <&gic>;
>>  ranges = <0x0 0x0 0x0 0xc000>;
>>  dma-ranges = <0x8000 0x8 0x 0x8000>;
>>  ^^^
> 
> You are right, I totally missed it when I looked again. I thought it
> was correct but then couldn't find it in the dts.
> 
>> config:
>>
>> CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
>> CONFIG_PHYS_ADDR_T_64BIT=y
>>
>> and
>>
>> #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT <--- should not be defined for KS2
>> typedef u64 dma_addr_t;
>> #else
>> typedef u32 dma_addr_t;
>> #endif
>>
>> Above is valid configuration for Keystone 2 with LPAE=y
> 
> Ok, but what do you mean with "should not be defined"? It clearly is
> defined in any multiplatform configuration that enables another platform
> needing 64-bit dma_addr_t.
> 

Then we probably have bigger problem :) KS2 will not work as is with
such configuration and not only KS2 - LPAE is enabled for TI DRA7 also.

Problem here is that dma_addr_t is used to fill DMA controllers data or can be 
written directly to register, so all drivers need to be revised which was 
initially
created for 32-bit HW and with assumption that dma_addr_t is 32-bits.

Also, I'm not sure that it will be possible to support both LE/BE in such case.

Actually, I've tried current multi_v7_defconfig and can see:
# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
# CONFIG_PHYS_ADDR_T_64BIT is not set
# CONFIG_ARM_LPAE is not set
What is your "multiplatform configuration" ??

So I propose to fix this regression first (as we both did - revert changes in 
get/set_pad_info()) and have KS2 working again with current version of
defconfig files (keystone_defconfig & multi_v7_defconfig) while this discussion 
is continuing. 

-- 
regards,
-grygorii


Re: Keystone 2 boards boot failure

2016-02-04 Thread Grygorii Strashko
On 02/03/2016 06:20 PM, Arnd Bergmann wrote:
> On Wednesday 03 February 2016 16:21:05 Grygorii Strashko wrote:
>> On 02/03/2016 04:11 PM, Franklin S Cooper Jr. wrote:
>>> On 02/02/2016 07:19 PM, Franklin S Cooper Jr. wrote:
>>>>>
>>>> So only making this change on the latest master with no
>>>> other changes I see the boot problem again.
>>
>> yep. I can confirm that.
>>
>> Also, I'm today came up with the similar fix that you've proposed before in 
>> this thread.
>> So, Could we move forward this way?
> 
> I still think it would be good to actually understand what the actual
> problem was.
> 

[...]

>>  dma_addr = dma_map_page(dev, page, page_offset, buf_len,
>> @@ -1100,8 +1079,7 @@ netcp_tx_map_skb(struct sk_buff *skb, struct 
>> netcp_intf *netcp)
>>  (netcp->tx_compl_qid & KNAV_DMA_DESC_RETQ_MASK) <<
>>  KNAV_DMA_DESC_RETQ_SHIFT;
>>  set_pkt_info(dma_addr, buf_len, 0, ndesc);
>> -desc_dma_32 = (u32)desc_dma;
>> -set_words(&desc_dma_32, 1, &pdesc->next_desc);
>> +set_words(&desc_dma, 1, &pdesc->next_desc);
>>  pkt_len += buf_len;
>>  if (pdesc != desc)
>>  knav_pool_desc_map(netcp->tx_pool, pdesc,
> 
> This is clearly broken on big-endian kernels with 64-bit dma_addr_t, so even
> if we revert the rest I think this part has to stay.
> 
> I have another version for testing below. That removes the logic that
> splits and reassembles the 64-bit values, but leaves the other changes
> in place. Can you try this?
> 

Nop. It crashes kernel
   50.28] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[   50.266219] Unable to handle kernel NULL pointer dereference at virtual 
address 0001
[   50.274287] pgd = c0003000
[   50.277007] [0001] *pgd=884003, *pmd=
[   50.282412] Internal error: Oops: a07 [#1] PREEMPT SMP ARM
[   50.287881] Modules linked in:
[   50.290938] CPU: 0 PID: 0 Comm: swapper/0 Tainted: GW   
4.5.0-rc2-00179-gad2f022-dirty #30
[   50.300214] Hardware name: Keystone
[   50.303693] task: c07476c0 ti: c0742000 task.ti: c0742000
[   50.309082] PC is at _test_and_set_bit+0x4/0x4c
[   50.313607] LR is at __netif_schedule+0x1c/0x60
[   50.318127] pc : []lr : []psr: 2113
[   50.318127] sp : c0743d68  ip : 0001  fp : c0743d7c
[   50.329568] r10: c0743e00  r9 : c0744100  r8 : 9e75
[   50.334775] r7 :   r6 : 0040  r5 : de495b00  r4 : 6d3cdb51
[   50.341282] r3 : 0001  r2 : c07476c0  r1 : 6d3cdba9  r0 : 
[   50.347790] Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment 
kernel
[   50.355077] Control: 30c5387d  Table: 1878abc0  DAC: fffd
[   50.360803] Process swapper/0 (pid: 0, stack limit = 0xc0742210)
[   50.366790] Stack: (0xc0743d68 to 0xc0744000)
[   50.371137] 3d60:   d9a16a00 de495b00 c0743d94 c0743d80 
c04295a0 c04294e0
[   50.379291] 3d80: de7a9cc0 de495b00 c0743dbc c0743d98 c037396c c0429570 
c0061d34 0010
[   50.387445] 3da0: de7a9d80 de7a9d80 0040 012c c0743ddc c0743dc0 
c0375f58 c0373848
[   50.395599] 3dc0: de7a9d80 c0375f3c 0040 012c c0743e3c c0743de0 
c042a0cc c0375f48
[   50.403752] 3de0: c0743e9c c06635f8 c0744b1c c0744b1c c0773c46 1e46b000 
c0741000 debac000
[   50.411907] 3e00: c0743e00 c0743e00 c0743e08 c0743e08 de408000  
c074408c c0742000
[   50.420061] 3e20: 0101 0003 4003 c0744080 c0743e9c c0743e40 
c0026670 c0429ed8
[   50.428215] 3e40: d8722360 c0744808 0020 c0744100 9e74 c054088c 
000a c07779c0
[   50.436369] 3e60: c073d2c8 c0744080 c0743e40 c0742000 c0744808 c073dddc 
004e 
[   50.444522] 3e80:  de408000 c0773aa4 c07444fc c0743eb4 c0743ea0 
c0026a38 c0026548
[   50.452675] 3ea0: c073dddc 004e c0743edc c0743eb8 c0061d34 c00269c4 
c0744808 e080400c
[   50.460828] 3ec0: c0743f08 e0804000 e0805000 c0773aa4 c0743f04 c0743ee0 
c0009438 c0061cd8
[   50.468981] 3ee0: c0010314 6013  c0743f3c c0773aa4 c0773aa4 
c0743f64 c0743f08
[   50.477136] 3f00: c0013a80 c0009404  deba8348 70c8 c001f880 
c0742000 c07444b0
[   50.485289] 3f20: c073d324 c0743f78 c0773aa4 c0773aa4 c07444fc c0743f64 
c0743f68 c0743f58
[   50.493442] 3f40: c0010310 c0010314 6013  c006d624 c006a15c 
c0743f74 c0743f68
[   50.501595] 3f60: c00598c0 c00102e0 c0743f8c c0743f78 c00599dc c00598a4 
0002 
[   50.509749] 3f80: c0743fa4 c0743f90 c0538468 c00598d8 c0777050  
c0743ff4 c0743fa8
[   50.517902] 3fa0: c06fad60 c05383e4    c06fa6d8 
 
[   50.526056] 3fc0:  c0731a30  c0777294 c0744484 c0731a2c 
c0748878 80007000
[  

Re: Keystone 2 boards boot failure

2016-02-04 Thread Grygorii Strashko
On 02/04/2016 03:07 PM, Arnd Bergmann wrote:
> On Thursday 04 February 2016 14:19:54 Grygorii Strashko wrote:
>> On 02/03/2016 10:40 PM, Arnd Bergmann wrote:
>>> On Wednesday 03 February 2016 18:31:00 Grygorii Strashko wrote:
>>>> On 02/03/2016 06:20 PM, Arnd Bergmann wrote:
>>>>> On Wednesday 03 February 2016 16:21:05 Grygorii Strashko wrote:
>>>>>> On 02/03/2016 04:11 PM, Franklin S Cooper Jr. wrote:
>>>>>>> On 02/02/2016 07:19 PM, Franklin S Cooper Jr. wrote:
>>>> config:
>>>>
>>>> CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
>>>> CONFIG_PHYS_ADDR_T_64BIT=y
>>>>
>>>> and
>>>>
>>>> #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT <--- should not be defined for KS2
>>>> typedef u64 dma_addr_t;
>>>> #else
>>>> typedef u32 dma_addr_t;
>>>> #endif
>>>>
>>>> Above is valid configuration for Keystone 2 with LPAE=y
>>>
>>> Ok, but what do you mean with "should not be defined"? It clearly is
>>> defined in any multiplatform configuration that enables another platform
>>> needing 64-bit dma_addr_t.
>>>
>>
>> Then we probably have bigger problem :) KS2 will not work as is with
>> such configuration and not only KS2 - LPAE is enabled for TI DRA7 also.
>>
>> Problem here is that dma_addr_t is used to fill DMA controllers data or can 
>> be
>> written directly to register, so all drivers need to be revised which was 
>> initially
>> created for 32-bit HW and with assumption that dma_addr_t is 32-bits.
> 
> Almost everything should work fine. What all other drivers tend to do is
> something like
> 
>   writel(dma_addr, reg_base + REG_OFFSET);
> 
> which works for 64-bit dma_addr_t as long as the upper 32 bits are
> always zero, and that should be the case on keystone.
> 
> The part that does not work and that originally triggered the
> warning I was fixing is
> 
> void f(u32 *data)
> {
>   writel(*data, reg_base + reg_offset);
> }
> 
> ...
> 
>   f((u32 *)&dma_addr);
> 
> as this driver does. I have not seen the same warning for any
> other driver in the kernel, so it is clearly something that
> rarely happens, and it still works by chance on little-endian
> kernels, just not on big-endian.
> 
>> Also, I'm not sure that it will be possible to support both LE/BE in such 
>> case.
>>
>> Actually, I've tried current multi_v7_defconfig and can see:
>> # CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
>> # CONFIG_PHYS_ADDR_T_64BIT is not set
>> # CONFIG_ARM_LPAE is not set
>> What is your "multiplatform configuration" ??
> 
> kernelci is testing multi_v7_defconfig with LPAE and KVM enabled on top.
> This breaks all pre-Cortex-A15 platforms (A5, A8 and A9 don't have LPAE)
> but should work on any A7/A15/A17 machine.
>   
>> So I propose to fix this regression first (as we both did - revert changes in
>> get/set_pad_info()) and have KS2 working again with current version of
>> defconfig files (keystone_defconfig & multi_v7_defconfig) while this
>> discussion is continuing.
> 
> Could you please at least test the last patch I sent? It really shouldn't
> be too hard to find the line that was wrong in my patch.
> 

I don't see any build warnings (in netcp) with my patch + below diff and If I 
manually enable
ARCH_DMA_ADDR_T_64BIT. 

--- a/drivers/net/ethernet/ti/netcp_core.c
+++ b/drivers/net/ethernet/ti/netcp_core.c
@@ -1058,6 +1058,7 @@ netcp_tx_map_skb(struct sk_buff *skb, struct netcp_intf 
*netcp)
u32 page_offset = frag->page_offset;
u32 buf_len = skb_frag_size(frag);
dma_addr_t desc_dma;
+   u32 desc_dma_32;
u32 pkt_info;
 
dma_addr = dma_map_page(dev, page, page_offset, buf_len,
@@ -1079,7 +1080,8 @@ netcp_tx_map_skb(struct sk_buff *skb, struct netcp_intf 
*netcp)
(netcp->tx_compl_qid & KNAV_DMA_DESC_RETQ_MASK) <<
KNAV_DMA_DESC_RETQ_SHIFT;
set_pkt_info(dma_addr, buf_len, 0, ndesc);
-   set_words(&desc_dma, 1, &pdesc->next_desc);
+   desc_dma_32 = (u32)desc_dma;
+   set_words(&desc_dma_32, 1, &pdesc->next_desc);
pkt_len += buf_len;
if (pdesc != desc)
knav_pool_desc_map(netcp->tx_pool, pdesc,
 


-- 
regards,
-grygorii


Re: Keystone 2 boards boot failure

2016-02-05 Thread Grygorii Strashko
hi Arnd,

On 02/05/2016 06:18 PM, Arnd Bergmann wrote:
> On Thursday 04 February 2016 18:25:08 Grygorii Strashko wrote:
>>>
>>> I have another version for testing below. That removes the logic that
>>> splits and reassembles the 64-bit values, but leaves the other changes
>>> in place. Can you try this?
>>>
>>
>> Nop. It crashes kernel
> 
> Ah. too bad.
> 
>> 50.28] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
>> [   50.266219] Unable to handle kernel NULL pointer dereference at virtual 
>> address 0001
>> [   50.274287] pgd = c0003000
>> [   50.277007] [0001] *pgd=884003, *pmd=
>> [   50.282412] Internal error: Oops: a07 [#1] PREEMPT SMP ARM
>> [   50.287881] Modules linked in:
>> [   50.290938] CPU: 0 PID: 0 Comm: swapper/0 Tainted: GW   
>> 4.5.0-rc2-00179-gad2f022-dirty #30
>> [   50.300214] Hardware name: Keystone
>> [   50.303693] task: c07476c0 ti: c0742000 task.ti: c0742000
>> [   50.309082] PC is at _test_and_set_bit+0x4/0x4c
>> [   50.313607] LR is at __netif_schedule+0x1c/0x60
>> [   50.318127] pc : []lr : []psr: 2113
>> [   50.318127] sp : c0743d68  ip : 0001  fp : c0743d7c
>> [   50.329568] r10: c0743e00  r9 : c0744100  r8 : 9e75
>> [   50.334775] r7 :   r6 : 0040  r5 : de495b00  r4 : 6d3cdb51
>> [   50.341282] r3 : 0001  r2 : c07476c0  r1 : 6d3cdba9  r0 : 
>> [   50.347790] Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment 
>> kernel
>> [   50.355077] Control: 30c5387d  Table: 1878abc0  DAC: fffd
>> [   50.360803] Process swapper/0 (pid: 0, stack limit = 0xc0742210)
>> [   50.366790] Stack: (0xc0743d68 to 0xc0744000)
>> [   50.371137] 3d60:   d9a16a00 de495b00 c0743d94 c0743d80 
>> c04295a0 c04294e0
>> [   50.379291] 3d80: de7a9cc0 de495b00 c0743dbc c0743d98 c037396c c0429570 
>> c0061d34 0010
>> [   50.387445] 3da0: de7a9d80 de7a9d80 0040 012c c0743ddc c0743dc0 
>> c0375f58 c0373848
>> [   50.395599] 3dc0: de7a9d80 c0375f3c 0040 012c c0743e3c c0743de0 
>> c042a0cc c0375f48
>> [   50.403752] 3de0: c0743e9c c06635f8 c0744b1c c0744b1c c0773c46 1e46b000 
>> c0741000 debac000
>> [   50.411907] 3e00: c0743e00 c0743e00 c0743e08 c0743e08 de408000  
>> c074408c c0742000
>> [   50.420061] 3e20: 0101 0003 4003 c0744080 c0743e9c c0743e40 
>> c0026670 c0429ed8
>> [   50.428215] 3e40: d8722360 c0744808 0020 c0744100 9e74 c054088c 
>> 000a c07779c0
>> [   50.436369] 3e60: c073d2c8 c0744080 c0743e40 c0742000 c0744808 c073dddc 
>> 004e 
>> [   50.444522] 3e80:  de408000 c0773aa4 c07444fc c0743eb4 c0743ea0 
>> c0026a38 c0026548
>> [   50.452675] 3ea0: c073dddc 004e c0743edc c0743eb8 c0061d34 c00269c4 
>> c0744808 e080400c
>> [   50.460828] 3ec0: c0743f08 e0804000 e0805000 c0773aa4 c0743f04 c0743ee0 
>> c0009438 c0061cd8
>> [   50.468981] 3ee0: c0010314 6013  c0743f3c c0773aa4 c0773aa4 
>> c0743f64 c0743f08
>> [   50.477136] 3f00: c0013a80 c0009404  deba8348 70c8 c001f880 
>> c0742000 c07444b0
>> [   50.485289] 3f20: c073d324 c0743f78 c0773aa4 c0773aa4 c07444fc c0743f64 
>> c0743f68 c0743f58
>> [   50.493442] 3f40: c0010310 c0010314 6013  c006d624 c006a15c 
>> c0743f74 c0743f68
>> [   50.501595] 3f60: c00598c0 c00102e0 c0743f8c c0743f78 c00599dc c00598a4 
>> 0002 
>> [   50.509749] 3f80: c0743fa4 c0743f90 c0538468 c00598d8 c0777050  
>> c0743ff4 c0743fa8
>> [   50.517902] 3fa0: c06fad60 c05383e4    c06fa6d8 
>>  
>> [   50.526056] 3fc0:  c0731a30  c0777294 c0744484 c0731a2c 
>> c0748878 80007000
>> [   50.534210] 3fe0: 412fc0f4   c0743ff8 80008090 c06fa964 
>>  
>> [   50.542357] Backtrace:
>> [   50.544816] [] (__netif_schedule) from [] 
>> (netif_wake_subqueue+0x3c/0x44)
>> [   50.553312]  r5:de495b00 r4:d9a16a00
>> [   50.556909] [] (netif_wake_subqueue) from [] 
>> (netcp_process_tx_compl_packets+0x130/0x134)
>> [   50.566789]  r5:de495b00 r4:de7a9cc0
>> [   50.570381] [] (netcp_process_tx_compl_packets) from 
>> [] (netcp_tx_poll+0x1c/0x4c)
>> [   50.579570]  r7:012c r6:0040 r5:de7a9d80 r4:de7a9d80
>> [   50.585258] [] (netcp_tx_poll) from [] 
>> (net_rx_action+0x200/0x2f8)
>> [   50.593148]  r7:012c r6:0040 r5:c0375f3c r4:de7a9d80
>> [   50.598833] [] (net_rx_action) from [] 
>> (__do_softirq+0x134

[PATCH] net: ti: netcp: restore get/set_pad_info() functionality

2016-02-09 Thread Grygorii Strashko
From: Arnd Bergmann 

The commit 899077791403 ("netcp: try to reduce type confusion in descriptors")
introduces a regression in Kernel 4.5-rc1 and it breaks
get/set_pad_info() functionality.

The TI NETCP driver uses pad0 and pad1 fields of knav_dma_desc to
store DMA/MEM buffer pointer and buffer size respectively. And in both
cases for Keystone 2 the pointer type size is 32 bit regardless of
LAPE enabled or not, because CONFIG_ARCH_DMA_ADDR_T_64BIT originally
is not expected to be defined.

!LAPE   LPAE
sizeof(void*)   32bit   32bit
sizeof(dma_addr_t)  32bit   32bit
sizeof(phys_addr_t) 32bit   64bit

Unfortunately, above commit changed buffer's pointers save/restore
code (get/set_pad_info()) and added intermediate conversation to u64
which works incorrectly on 32bit Keystone 2 and causes TI NETCP driver
crash in RX/TX path due to "Unable to handle kernel NULL pointer"
exception. This issue was reported and discussed in [1].

Hence, fix it by partially reverting above commit and restoring
get/set_pad_info() functionality as it was before.

[1] https://www.mail-archive.com/netdev@vger.kernel.org/msg95361.html
Cc: Wingman Kwok 
Cc: Murali Karicheri 
Cc: Mugunthan V N 
Reported-by: Franklin S Cooper Jr 
Signed-off-by: Arnd Bergmann 
Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/netcp_core.c | 59 +++-
 1 file changed, 18 insertions(+), 41 deletions(-)

diff --git a/drivers/net/ethernet/ti/netcp_core.c 
b/drivers/net/ethernet/ti/netcp_core.c
index c61d66d..0b26e52 100644
--- a/drivers/net/ethernet/ti/netcp_core.c
+++ b/drivers/net/ethernet/ti/netcp_core.c
@@ -117,20 +117,10 @@ static void get_pkt_info(dma_addr_t *buff, u32 *buff_len, 
dma_addr_t *ndesc,
*ndesc = le32_to_cpu(desc->next_desc);
 }
 
-static void get_pad_info(u32 *pad0, u32 *pad1, u32 *pad2, struct knav_dma_desc 
*desc)
+static void get_pad_info(u32 *pad0, u32 *pad1, struct knav_dma_desc *desc)
 {
*pad0 = le32_to_cpu(desc->pad[0]);
*pad1 = le32_to_cpu(desc->pad[1]);
-   *pad2 = le32_to_cpu(desc->pad[2]);
-}
-
-static void get_pad_ptr(void **padptr, struct knav_dma_desc *desc)
-{
-   u64 pad64;
-
-   pad64 = le32_to_cpu(desc->pad[0]) +
-   ((u64)le32_to_cpu(desc->pad[1]) << 32);
-   *padptr = (void *)(uintptr_t)pad64;
 }
 
 static void get_org_pkt_info(dma_addr_t *buff, u32 *buff_len,
@@ -163,11 +153,10 @@ static void set_desc_info(u32 desc_info, u32 pkt_info,
desc->packet_info = cpu_to_le32(pkt_info);
 }
 
-static void set_pad_info(u32 pad0, u32 pad1, u32 pad2, struct knav_dma_desc 
*desc)
+static void set_pad_info(u32 pad0, u32 pad1, struct knav_dma_desc *desc)
 {
desc->pad[0] = cpu_to_le32(pad0);
desc->pad[1] = cpu_to_le32(pad1);
-   desc->pad[2] = cpu_to_le32(pad1);
 }
 
 static void set_org_pkt_info(dma_addr_t buff, u32 buff_len,
@@ -581,7 +570,6 @@ static void netcp_free_rx_desc_chain(struct netcp_intf 
*netcp,
dma_addr_t dma_desc, dma_buf;
unsigned int buf_len, dma_sz = sizeof(*ndesc);
void *buf_ptr;
-   u32 pad[2];
u32 tmp;
 
get_words(&dma_desc, 1, &desc->next_desc);
@@ -593,14 +581,12 @@ static void netcp_free_rx_desc_chain(struct netcp_intf 
*netcp,
break;
}
get_pkt_info(&dma_buf, &tmp, &dma_desc, ndesc);
-   get_pad_ptr(&buf_ptr, ndesc);
+   get_pad_info((u32 *)&buf_ptr, &buf_len, ndesc);
dma_unmap_page(netcp->dev, dma_buf, PAGE_SIZE, DMA_FROM_DEVICE);
__free_page(buf_ptr);
knav_pool_desc_put(netcp->rx_pool, desc);
}
-
-   get_pad_info(&pad[0], &pad[1], &buf_len, desc);
-   buf_ptr = (void *)(uintptr_t)(pad[0] + ((u64)pad[1] << 32));
+   get_pad_info((u32 *)&buf_ptr, &buf_len, desc);
 
if (buf_ptr)
netcp_frag_free(buf_len <= PAGE_SIZE, buf_ptr);
@@ -639,8 +625,8 @@ static int netcp_process_one_rx_packet(struct netcp_intf 
*netcp)
dma_addr_t dma_desc, dma_buff;
struct netcp_packet p_info;
struct sk_buff *skb;
-   u32 pad[2];
void *org_buf_ptr;
+   u32 tmp;
 
dma_desc = knav_queue_pop(netcp->rx_queue, &dma_sz);
if (!dma_desc)
@@ -653,8 +639,7 @@ static int netcp_process_one_rx_packet(struct netcp_intf 
*netcp)
}
 
get_pkt_info(&dma_buff, &buf_len, &dma_desc, desc);
-   get_pad_info(&pad[0], &pad[1], &org_buf_len, desc);
-   org_buf_ptr = (void *)(uintptr_t)(pad[0] + ((u64)pad[1] << 32));
+   get_pad_info((u32 *)&org_buf_ptr, &org_buf_len, desc);
 
if (unlikely(!org_buf_ptr)) {
dev_err(netcp->ndev_dev, "NULL bufptr in desc\n");
@@ -679,7 +664,6 @@ static in

Re: [PATCH] net: ti: netcp: restore get/set_pad_info() functionality

2016-02-10 Thread Grygorii Strashko
Hi All,

On 02/09/2016 09:38 PM, Arnd Bergmann wrote:
> On Tuesday 09 February 2016 16:55:42 Karicheri, Muralidharan wrote:
>>
>> The descriptors are usable by different drivers, one driver may use it as
>> buf ptr/ len, other for something else. So they should remain as generic
>> and it is up to individual drivers to use it in whatever way it requires.
>> My suggestion is to rename pad field in struct knav_dma_desc to sw_data
>> to avoid confusion. i.e
>>
>> +   __le32  pad[4];
>>
>> to
>>
>> +   __le32  sw_data[4];
>>
> 
> If the hardware doesn't access them, they can probably just be u32
> and not do any byte swapping.
> 

Most of propositions, mentioned in this thread (and not only), sounds 
reasonable,
and there are definitely a lot of optimization/cleanups and refactorings which
could be done for this driver (of course it's up to NETCP maintainers to 
decide).

But this particular patch is intended to fix regression and restore Keystone 2
networking functionality, *including NFS boot*, when vanilla's config files are 
used
(keystone_defconfig, multi_v7_defconfig). 
And this is "not" an optimization or cleanup - this is partial revert of buggy 
commit.

So, could we fix regression first, pleeeaaase? 
Then other things can be done if someone have time and would like to take the 
initiative
(and would be ready to get at minimum "Tested-by" tag from netcp maintainers 
:)).

-- 
regards,
-grygorii


Re: am335x: no multicast reception over VLAN

2016-03-29 Thread Grygorii Strashko
On 03/29/2016 08:21 AM, Yegor Yefremov wrote:
> Hi Mugunthan,
> 
> On Tue, Mar 29, 2016 at 6:00 AM, Mugunthan V N  wrote:
>> Hi Yegor
>>
>> On Wednesday 16 March 2016 08:35 PM, Yegor Yefremov wrote:
>>> I have an am335x based board using CPSW in Dual EMAC mode. Without
>>> VLAN IDs I can receive and send multicast packets [1]. When I create
>>> VLAN ID:
>>>
>>> ip link add link eth1 name eth1.100 type vlan id 100
>>> ip addr add 192.168.100.2/24 brd 192.168.100.255 dev eth1.100
>>> route add -net 224.0.0.0 netmask 224.0.0.0 eth1.100
>>>
>>> I can successfully send multicast packets, but not receive them. On
>>> the other side of the Ethernet cable I've used Pandaboard. Pandaboard
>>> could both receive and send multicast packets via VLAN.
>>
>> Are you trying multicast tx/rx on eth1 or eth1.100?
> 
> I'm trying multicast tx/rx on eth1.100.
> 
> eth1 has no problems.
> 

it'd be nice if will be able to post here output fom commands:
# switch-config -d [git://git.ti.com/switch-config/switch-config.git v4.1]
# ifconfig -a
# tcpdump -e -f -Q in -i eth0
# tcpdump -e -f -Q in -i eth0.100


-- 
regards,
-grygorii


Re: am335x: no multicast reception over VLAN

2016-03-29 Thread Grygorii Strashko
On 03/29/2016 03:35 PM, Yegor Yefremov wrote:
> On Tue, Mar 29, 2016 at 1:05 PM, Grygorii Strashko
>  wrote:
>> On 03/29/2016 08:21 AM, Yegor Yefremov wrote:
>>> Hi Mugunthan,
>>>
>>> On Tue, Mar 29, 2016 at 6:00 AM, Mugunthan V N  wrote:
>>>> Hi Yegor
>>>>
>>>> On Wednesday 16 March 2016 08:35 PM, Yegor Yefremov wrote:
>>>>> I have an am335x based board using CPSW in Dual EMAC mode. Without
>>>>> VLAN IDs I can receive and send multicast packets [1]. When I create
>>>>> VLAN ID:
>>>>>
>>>>> ip link add link eth1 name eth1.100 type vlan id 100
>>>>> ip addr add 192.168.100.2/24 brd 192.168.100.255 dev eth1.100
>>>>> route add -net 224.0.0.0 netmask 224.0.0.0 eth1.100
>>>>>
>>>>> I can successfully send multicast packets, but not receive them. On
>>>>> the other side of the Ethernet cable I've used Pandaboard. Pandaboard
>>>>> could both receive and send multicast packets via VLAN.
>>>>
>>>> Are you trying multicast tx/rx on eth1 or eth1.100?
>>>
>>> I'm trying multicast tx/rx on eth1.100.
>>>
>>> eth1 has no problems.
>>>
>>
>> it'd be nice if will be able to post here output fom commands:
>> # switch-config -d [git://git.ti.com/switch-config/switch-config.git v4.1]
>> # ifconfig -a
>> # tcpdump -e -f -Q in -i eth0
>> # tcpdump -e -f -Q in -i eth0.100
> 
> Which kernel/branch do you want me to test?
> 
> git://git.ti.com/ti-linux-kernel/ti-linux-kernel.git and ti-rt-linux-4.1.y?
> 
> So far I was using vanilla kernel.

Your branch (but better 4.5 kernels (or 4.4)). 
Just when you've done with configuration run cmds 1&2,
and when you run your use-case - run cmds 2&3 on receiver side (grap ~5-10 
packets).
then stop test and run cmd 1 again.

After all could you provide your console output here, pls.


-- 
regards,
-grygorii


Re: am335x: no multicast reception over VLAN

2016-04-01 Thread Grygorii Strashko
On 03/31/2016 10:52 AM, Yegor Yefremov wrote:
> On Thu, Mar 31, 2016 at 8:37 AM, Mugunthan V N  wrote:
>> On Thursday 31 March 2016 01:17 AM, Peter Korsgaard wrote:
 "Mugunthan" == Mugunthan V N  writes:
>>>
>>> Hi,
>>>
>>>   > You had received these packets as tcpdump will enable promiscuous mode
>>>   > so that you receive all the packets from the wire.
>>>
>>> FYI, you can use the -p option to tcpdump to not put the interface into
>>> promiscuous mode.
>>>
>>
>> Thanks for the information Peter Korsgaard.
>>
>> Yegor, can you provide tcpdump using -p as well in Grygorii commands.
> 
> Before VLAN configuration:
> 
> # switch-config -d
> cpsw hw version 1.12 (0)
> 0   : type: vlan , vid = 1, untag_force = 0x3, reg_mcast = 0x3,
> unreg_mcast = 0x0, member_list = 0x3
> 1   : type: mcast, vid = 1, addr = ff:ff:ff:ff:ff:ff, mcast_state = f,
> no super, port_mask = 0x3
> 2   : type: ucast, vid = 1, addr = 74:6a:8f:00:16:12, ucast_type =
> persistant, port_num = 0x0, Secure
> 3   : type: vlan , vid = 0, untag_force = 0x7, reg_mcast = 0x0,
> unreg_mcast = 0x0, member_list = 0x7
> 4   : type: mcast, vid = 1, addr = 01:00:5e:00:00:01, mcast_state = f,
> no super, port_mask = 0x3
> 5   : type: vlan , vid = 2, untag_force = 0x5, reg_mcast = 0x5,
> unreg_mcast = 0x0, member_list = 0x5
> 6   : type: mcast, vid = 2, addr = ff:ff:ff:ff:ff:ff, mcast_state = f,
> no super, port_mask = 0x5
> 7   : type: ucast, vid = 2, addr = 74:6a:8f:00:16:13, ucast_type =
> persistant, port_num = 0x0, Secure
> 8   : type: mcast, vid = 2, addr = 01:00:5e:00:00:01, mcast_state = f,
> no super, port_mask = 0x5
> 
> After VLAN configuration:
> 
> # switch-config -d
> cpsw hw version 1.12 (0)
> 0   : type: vlan , vid = 1, untag_force = 0x3, reg_mcast = 0x3,
> unreg_mcast = 0x0, member_list = 0x3
> 1   : type: mcast, vid = 1, addr = ff:ff:ff:ff:ff:ff, mcast_state = f,
> no super, port_mask = 0x3
> 2   : type: ucast, vid = 1, addr = 74:6a:8f:00:16:12, ucast_type =
> persistant, port_num = 0x0, Secure
> 3   : type: vlan , vid = 0, untag_force = 0x7, reg_mcast = 0x0,
> unreg_mcast = 0x0, member_list = 0x7
> 4   : type: mcast, vid = 1, addr = 01:00:5e:00:00:01, mcast_state = f,
> no super, port_mask = 0x3
> 5   : type: vlan , vid = 2, untag_force = 0x5, reg_mcast = 0x5,
> unreg_mcast = 0x0, member_list = 0x5
> 6   : type: mcast, vid = 2, addr = ff:ff:ff:ff:ff:ff, mcast_state = f,
> no super, port_mask = 0x5
> 7   : type: ucast, vid = 2, addr = 74:6a:8f:00:16:13, ucast_type =
> persistant, port_num = 0x0, Secure
> 8   : type: mcast, vid = 2, addr = 01:00:5e:00:00:01, mcast_state = f,
> no super, port_mask = 0x5
> 9   : type: vlan , vid = 100, untag_force = 0x0, reg_mcast = 0x5,
> unreg_mcast = 0x0, member_list = 0x5
> 10  : type: ucast, vid = 100, addr = 74:6a:8f:00:16:13, ucast_type =
> persistant, port_num = 0x0
> 11  : type: mcast, vid = 100, addr = ff:ff:ff:ff:ff:ff, mcast_state =
> f, no super, port_mask = 0x5
> 12  : type: mcast, vid = 2, addr = 01:80:c2:00:00:21, mcast_state = f,
> no super, port_mask = 0x5
> 
> During mulitcast receive:
> 
> # switch-config -d
> cpsw hw version 1.12 (0)
> 0   : type: vlan , vid = 1, untag_force = 0x3, reg_mcast = 0x3, unreg_mcast = 
> 0x0, member_list = 0x3
> 1   : type: mcast, vid = 1, addr = ff:ff:ff:ff:ff:ff, mcast_state = f, no 
> super, port_mask = 0x3
> 2   : type: ucast, vid = 1, addr = 74:6a:8f:00:16:12, ucast_type = 
> persistant, port_num = 0x0, Secure
> 3   : type: vlan , vid = 0, untag_force = 0x7, reg_mcast = 0x0, unreg_mcast = 
> 0x0, member_list = 0x7

unreg_mcast = 0x0 means unregistered multicast packets will be dropped

> 4   : type: mcast, vid = 1, addr = 01:00:5e:00:00:01, mcast_state = f, no 
> super, port_mask = 0x3
> 5   : type: vlan , vid = 2, untag_force = 0x5, reg_mcast = 0x5, unreg_mcast = 
> 0x0, member_list = 0x5

unreg_mcast = 0x0 

> 6   : type: mcast, vid = 2, addr = ff:ff:ff:ff:ff:ff, mcast_state = f, no 
> super, port_mask = 0x5
> 7   : type: ucast, vid = 2, addr = 74:6a:8f:00:16:13, ucast_type = 
> persistant, port_num = 0x0, Secure
> 8   : type: mcast, vid = 2, addr = 01:00:5e:00:00:01, mcast_state = f, no 
> super, port_mask = 0x5
> 9   : type: vlan , vid = 100, untag_force = 0x0, reg_mcast = 0x5, unreg_mcast 
> = 0x0, member_list = 0x5

unreg_mcast = 0x0 

> 10  : type: ucast, vid = 100, addr = 74:6a:8f:00:16:13, ucast_type = 
> persistant, port_num = 0x0
> 11  : type: mcast, vid = 100, addr = ff:ff:ff:ff:ff:ff, mcast_state = f, no 
> super, port_mask = 0x5
> 12  : type: mcast, vid = 2, addr = 01:80:c2:00:00:21, mcast_state = f, no 
> super, port_mask = 0x5
> 13  : type: mcast, vid = 2, addr = 01:00:5e:03:1d:47, mcast_state = f, no 
> super, port_mask = 0x5

This is requested mcast address, but it's registered for vid=2 (propagated 
through .ndo_set_rx_mode())

> 14  : type: ucast, vid = 100, addr = 66:22:04:bc:90:26, ucast_type = 
> untouched , port_num = 0x2

[...]
> 
> Both tcpdumps with -p option showed no packets. If I execute ping, I
> can see related ICM

[PATCH 1/2] drivers: net: cpsw: fix port_mask parameters in ale calls

2016-04-07 Thread Grygorii Strashko
ALE APIs expect to receive port masks as input values for arguments
port_mask, untag, reg_mcast, unreg_mcast. But there are few places in
code where port masks are passed left-shifted by cpsw_priv->host_port,
like below:

 cpsw_ale_add_vlan(priv->ale, priv->data.default_vlan,
  ALE_ALL_PORTS << priv->host_port,
  ALE_ALL_PORTS << priv->host_port, 0, 0);

and cpsw is still working just because priv->host_port == 0
and has never ever been changed.

Hence, fix port_mask parameters in ALE APIs calls and drop
"<< priv->host_port" from all places where it's used to
shift valid port mask.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/cpsw.c | 22 +-
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 42fdfd4..5292e70 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -535,7 +535,7 @@ static const struct cpsw_stats cpsw_gstrings_stats[] = {
ALE_VLAN, slave->port_vlan, 0); \
} else {\
cpsw_ale_add_mcast(priv->ale, addr, \
-   ALE_ALL_PORTS << priv->host_port,   \
+   ALE_ALL_PORTS,  \
0, 0, 0);   \
}   \
} while (0)
@@ -602,8 +602,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, 
bool enable)
cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1);
 
/* Clear all mcast from ALE */
-   cpsw_ale_flush_multicast(ale, ALE_ALL_PORTS <<
-priv->host_port, -1);
+   cpsw_ale_flush_multicast(ale, ALE_ALL_PORTS, -1);
 
/* Flood All Unicast Packets to Host port */
cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 1);
@@ -648,8 +647,7 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
cpsw_ale_set_allmulti(priv->ale, priv->ndev->flags & IFF_ALLMULTI);
 
/* Clear all mcast from ALE */
-   cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port,
-vid);
+   cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS, vid);
 
if (!netdev_mc_empty(ndev)) {
struct netdev_hw_addr *ha;
@@ -1172,7 +1170,6 @@ static void cpsw_slave_open(struct cpsw_slave *slave, 
struct cpsw_priv *priv)
 static inline void cpsw_add_default_vlan(struct cpsw_priv *priv)
 {
const int vlan = priv->data.default_vlan;
-   const int port = priv->host_port;
u32 reg;
int i;
int unreg_mcast_mask;
@@ -1190,9 +1187,9 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv 
*priv)
else
unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2;
 
-   cpsw_ale_add_vlan(priv->ale, vlan, ALE_ALL_PORTS << port,
- ALE_ALL_PORTS << port, ALE_ALL_PORTS << port,
- unreg_mcast_mask << port);
+   cpsw_ale_add_vlan(priv->ale, vlan, ALE_ALL_PORTS,
+ ALE_ALL_PORTS, ALE_ALL_PORTS,
+ unreg_mcast_mask);
 }
 
 static void cpsw_init_host_port(struct cpsw_priv *priv)
@@ -1273,8 +1270,7 @@ static int cpsw_ndo_open(struct net_device *ndev)
cpsw_add_default_vlan(priv);
else
cpsw_ale_add_vlan(priv->ale, priv->data.default_vlan,
- ALE_ALL_PORTS << priv->host_port,
- ALE_ALL_PORTS << priv->host_port, 0, 0);
+ ALE_ALL_PORTS, ALE_ALL_PORTS, 0, 0);
 
if (!cpsw_common_res_usage_state(priv)) {
struct cpsw_priv *priv_sl0 = cpsw_get_slave_priv(priv, 0);
@@ -1666,7 +1662,7 @@ static inline int cpsw_add_vlan_ale_entry(struct 
cpsw_priv *priv,
}
 
ret = cpsw_ale_add_vlan(priv->ale, vid, port_mask, 0, port_mask,
-   unreg_mcast_mask << priv->host_port);
+   unreg_mcast_mask);
if (ret != 0)
return ret;
 
@@ -1738,7 +1734,7 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device 
*ndev,
return ret;
 
ret = cpsw_ale_del_ucast(priv->ale, priv->mac_addr,
-priv->host_port, ALE_VLAN, vid);
+HOST_PORT_NUM, ALE_VLAN, vid);
if (ret != 0)
return ret;
 
-- 
2.8.0



[PATCH 2/2] drivers: net: cpsw: drop host_port field from struct cpsw_priv

2016-04-07 Thread Grygorii Strashko
The host_port field is constantly assigned to 0 and this value has
never changed (since time when cpsw driver was introduced. More over,
if this field will be assigned to non 0 value it will break current
driver functionality.

Hence, there are no reasons to continue maintaining this host_port
field and it can be removed, and the HOST_PORT_NUM and ALE_PORT_HOST
defines can be used instead.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/cpsw.c | 30 --
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 5292e70..54bcc38 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -381,7 +381,6 @@ struct cpsw_priv {
u32 coal_intvl;
u32 bus_freq_mhz;
int rx_packet_max;
-   int host_port;
struct clk  *clk;
u8  mac_addr[ETH_ALEN];
struct cpsw_slave   *slaves;
@@ -531,7 +530,7 @@ static const struct cpsw_stats cpsw_gstrings_stats[] = {
int slave_port = cpsw_get_slave_port(priv,  \
slave->slave_num);  \
cpsw_ale_add_mcast(priv->ale, addr, \
-   1 << slave_port | 1 << priv->host_port, \
+   1 << slave_port | ALE_PORT_HOST,\
ALE_VLAN, slave->port_vlan, 0); \
} else {\
cpsw_ale_add_mcast(priv->ale, addr, \
@@ -542,10 +541,7 @@ static const struct cpsw_stats cpsw_gstrings_stats[] = {
 
 static inline int cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
 {
-   if (priv->host_port == 0)
-   return slave_num + 1;
-   else
-   return slave_num;
+   return slave_num + 1;
 }
 
 static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
@@ -1090,7 +1086,7 @@ static inline void cpsw_add_dual_emac_def_ale_entries(
struct cpsw_priv *priv, struct cpsw_slave *slave,
u32 slave_port)
 {
-   u32 port_mask = 1 << slave_port | 1 << priv->host_port;
+   u32 port_mask = 1 << slave_port | ALE_PORT_HOST;
 
if (priv->version == CPSW_VERSION_1)
slave_write(slave, slave->port_vlan, CPSW1_PORT_VLAN);
@@ -1101,7 +1097,7 @@ static inline void cpsw_add_dual_emac_def_ale_entries(
cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
   port_mask, ALE_VLAN, slave->port_vlan, 0);
cpsw_ale_add_ucast(priv->ale, priv->mac_addr,
-   priv->host_port, ALE_VLAN | ALE_SECURE, slave->port_vlan);
+   HOST_PORT_NUM, ALE_VLAN | ALE_SECURE, slave->port_vlan);
 }
 
 static void soft_reset_slave(struct cpsw_slave *slave)
@@ -1202,7 +1198,7 @@ static void cpsw_init_host_port(struct cpsw_priv *priv)
cpsw_ale_start(priv->ale);
 
/* switch to vlan unaware mode */
-   cpsw_ale_control_set(priv->ale, priv->host_port, ALE_VLAN_AWARE,
+   cpsw_ale_control_set(priv->ale, HOST_PORT_NUM, ALE_VLAN_AWARE,
 CPSW_ALE_VLAN_AWARE);
control_reg = readl(&priv->regs->control);
control_reg |= CPSW_VLAN_AWARE;
@@ -1216,14 +1212,14 @@ static void cpsw_init_host_port(struct cpsw_priv *priv)
 &priv->host_port_regs->cpdma_tx_pri_map);
__raw_writel(0, &priv->host_port_regs->cpdma_rx_chan_map);
 
-   cpsw_ale_control_set(priv->ale, priv->host_port,
+   cpsw_ale_control_set(priv->ale, HOST_PORT_NUM,
 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
 
if (!priv->data.dual_emac) {
-   cpsw_ale_add_ucast(priv->ale, priv->mac_addr, priv->host_port,
+   cpsw_ale_add_ucast(priv->ale, priv->mac_addr, HOST_PORT_NUM,
   0, 0);
cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
-  1 << priv->host_port, 0, 0, ALE_MCAST_FWD_2);
+  ALE_PORT_HOST, 0, 0, ALE_MCAST_FWD_2);
}
 }
 
@@ -1616,9 +1612,9 @@ static int cpsw_ndo_set_mac_address(struct net_device 
*ndev, void *p)
flags = ALE_VLAN;
}
 
-   cpsw_ale_del_ucast(priv->ale, priv->mac_addr, priv->host_port,
+   cpsw_ale_del_ucast(priv->ale, priv->mac_addr, HOST_PORT_NUM,
   flags, vid);
-   cpsw_ale_add_ucast(priv->ale, addr->sa_data, priv->host_port,
+

[PATCH 0/2] drivers: net: cpsw: fix ale calls and drop host_port field from cpsw_priv

2016-04-07 Thread Grygorii Strashko
This clean up series intended to:
 - fix port_mask parameters in ale calls and drop unnecessary shifts
 - drop host_port field from struct cpsw_priv

Nothing critical. Tested on am437x-idk-evm in dual mac and switch modes.

Grygorii Strashko (2):
  drivers: net: cpsw: fix port_mask parameters in ale calls
  drivers: net: cpsw: drop host_port field from struct cpsw_priv

 drivers/net/ethernet/ti/cpsw.c | 52 +-
 1 file changed, 21 insertions(+), 31 deletions(-)

-- 
2.8.0



Re: [PATCH v2 1/1] drivers: net: cpsw: Prevent NUll pointer dereference with two PHYs

2016-04-19 Thread Grygorii Strashko
Hi,

On 04/19/2016 04:56 PM, Andrew Goodbody wrote:
> Adding a 2nd PHY to cpsw results in a NULL pointer dereference
> as below. Fix by maintaining a reference to each PHY node in slave
> struct instead of a single reference in the priv struct which was
> overwritten by the 2nd PHY.

David, Is it possible to drop prev version of this patch from linux-next
- it breaks boot on many TI boards with -next.


> 
> [   17.870933] Unable to handle kernel NULL pointer dereference at virtual 
> address 0180
> [   17.879557] pgd = dc8bc000
> [   17.882514] [0180] *pgd=9c882831, *pte=, *ppte=
> [   17.889213] Internal error: Oops: 17 [#1] ARM
> [   17.893838] Modules linked in:
> [   17.897102] CPU: 0 PID: 1657 Comm: connmand Not tainted 
> 4.5.0-ge463dfb-dirty #11
> [   17.904947] Hardware name: Cambrionix whippet
> [   17.909576] task: dc859240 ti: dc968000 task.ti: dc968000
> [   17.915339] PC is at phy_attached_print+0x18/0x8c
> [   17.920339] LR is at phy_attached_info+0x14/0x18
> [   17.925247] pc : []lr : []psr: 600f0113
> [   17.925247] sp : dc969cf8  ip : dc969d28  fp : dc969d18
> [   17.937425] r10: dda7a400  r9 :   r8 : 
> [   17.942971] r7 : 0001  r6 : ddb00480  r5 : ddb8cb34  r4 : 
> [   17.949898] r3 : c0954cc0  r2 : c09562b0  r1 :   r0 : 
> [   17.956829] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment 
> none
> [   17.964401] Control: 10c5387d  Table: 9c8bc019  DAC: 0051
> [   17.970500] Process connmand (pid: 1657, stack limit = 0xdc968210)
> [   17.977059] Stack: (0xdc969cf8 to 0xdc96a000)

[...]

> [   18.323956] [] (inet_ioctl) from [] 
> (sock_ioctl+0x15c/0x2d8)
> [   18.331829] [] (sock_ioctl) from [] 
> (do_vfs_ioctl+0x98/0x8d0)
> [   18.339765]  r7:8914 r6:dc8ab4c0 r5:dd257ae0 r4:beaeda20
> [   18.345822] [] (do_vfs_ioctl) from [] 
> (SyS_ioctl+0x74/0x84)
> [   18.353573]  r10: r9:0011 r8:beaeda20 r7:8914 r6:dc8ab4c0 
> r5:dc8ab4c0
> [   18.361924]  r4:
> [   18.364653] [] (SyS_ioctl) from [] 
> (ret_fast_syscall+0x0/0x3c)
> [   18.372682]  r9:dc968000 r8:c00165e8 r7:0036 r6:0002 r5:0011 
> r4:
> [   18.380960] Code: e92dd810 e24cb010 e24dd010 e59b4004 (e5902180)
> [   18.387580] ---[ end trace c80529466223f3f3 ]---

^ Could you make it shorter and drop timestamps, pls?

> 
> Signed-off-by: Andrew Goodbody 
> ---
> 
> v2 - Move allocation of memory for priv->slaves to inside cpsw_probe_dt so it
>   has data->slaves initialised first which is needed to calculate size
> 
>   drivers/net/ethernet/ti/cpsw.c | 30 +++---
>   1 file changed, 15 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
> index 42fdfd4..e62909c 100644
> --- a/drivers/net/ethernet/ti/cpsw.c
> +++ b/drivers/net/ethernet/ti/cpsw.c
> @@ -349,6 +349,7 @@ struct cpsw_slave {
>   struct cpsw_slave_data  *data;
>   struct phy_device   *phy;
>   struct net_device   *ndev;
> + struct device_node  *phy_node;
>   u32 port_vlan;
>   u32 open_stat;
>   };
> @@ -367,7 +368,6 @@ struct cpsw_priv {
>   spinlock_t  lock;
>   struct platform_device  *pdev;
>   struct net_device   *ndev;
> - struct device_node  *phy_node;
>   struct napi_struct  napi_rx;
>   struct napi_struct  napi_tx;
>   struct device   *dev;
> @@ -1148,8 +1148,8 @@ static void cpsw_slave_open(struct cpsw_slave *slave, 
> struct cpsw_priv *priv)
>   cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
>  1 << slave_port, 0, 0, ALE_MCAST_FWD_2);
>   
> - if (priv->phy_node)
> - slave->phy = of_phy_connect(priv->ndev, priv->phy_node,
> + if (slave->phy_node)
> + slave->phy = of_phy_connect(priv->ndev, slave->phy_node,
>&cpsw_adjust_link, 0, slave->data->phy_if);
>   else
>   slave->phy = phy_connect(priv->ndev, slave->data->phy_id,
> @@ -1946,7 +1946,7 @@ static int cpsw_probe_dt(struct cpsw_priv *priv,
>   struct device_node *node = pdev->dev.of_node;
>   struct device_node *slave_node;
>   struct cpsw_platform_data *data = &priv->data;
> - int i = 0, ret;
> + int i, ret;
>   u32 prop;
>   
>   if (!node)
> @@ -1958,6 +1958,14 @@ static int cpsw_probe_dt(struct cpsw_priv *priv,
>   }
>   data->slaves = prop;
>   
> + priv->slaves = devm_kzalloc(&pdev->dev,
> + sizeof(struct cpsw_slave) * data->slaves,
> + GFP_KERNEL);
> + if (!priv->slaves)
> + return -ENOMEM;
> + for (i = 0; i < data->slaves; i++)
> + priv->slaves[i].slave_num = i;
> +
>   if (of_prope

Re: [PATCH v2 1/1] drivers: net: cpsw: Prevent NUll pointer dereference with two PHYs

2016-04-19 Thread Grygorii Strashko
On 04/19/2016 06:01 PM, David Rivshin (Allworx) wrote:
> On Tue, 19 Apr 2016 17:41:07 +0300
> Grygorii Strashko  wrote:
> 
>> Hi,
>>
>> On 04/19/2016 04:56 PM, Andrew Goodbody wrote:
>>> Adding a 2nd PHY to cpsw results in a NULL pointer dereference
>>> as below. Fix by maintaining a reference to each PHY node in slave
>>> struct instead of a single reference in the priv struct which was
>>> overwritten by the 2nd PHY.
>>
>> David, Is it possible to drop prev version of this patch from linux-next
>> - it breaks boot on many TI boards with -next.
>>
>>
>>>
>>> [   17.870933] Unable to handle kernel NULL pointer dereference at virtual 
>>> address 0180
>>> [   17.879557] pgd = dc8bc000
>>> [   17.882514] [0180] *pgd=9c882831, *pte=, *ppte=
>>> [   17.889213] Internal error: Oops: 17 [#1] ARM
>>> [   17.893838] Modules linked in:
>>> [   17.897102] CPU: 0 PID: 1657 Comm: connmand Not tainted 
>>> 4.5.0-ge463dfb-dirty #11
>>> [   17.904947] Hardware name: Cambrionix whippet
>>> [   17.909576] task: dc859240 ti: dc968000 task.ti: dc968000
>>> [   17.915339] PC is at phy_attached_print+0x18/0x8c
>>> [   17.920339] LR is at phy_attached_info+0x14/0x18
>>> [   17.925247] pc : []lr : []psr: 600f0113
>>> [   17.925247] sp : dc969cf8  ip : dc969d28  fp : dc969d18
>>> [   17.937425] r10: dda7a400  r9 :   r8 : 
>>> [   17.942971] r7 : 0001  r6 : ddb00480  r5 : ddb8cb34  r4 : 
>>> [   17.949898] r3 : c0954cc0  r2 : c09562b0  r1 :   r0 : 
>>> [   17.956829] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment 
>>> none
>>> [   17.964401] Control: 10c5387d  Table: 9c8bc019  DAC: 0051
>>> [   17.970500] Process connmand (pid: 1657, stack limit = 0xdc968210)
>>> [   17.977059] Stack: (0xdc969cf8 to 0xdc96a000)
>>
>> [...]
>>
>>> [   18.323956] [] (inet_ioctl) from [] 
>>> (sock_ioctl+0x15c/0x2d8)
>>> [   18.331829] [] (sock_ioctl) from [] 
>>> (do_vfs_ioctl+0x98/0x8d0)
>>> [   18.339765]  r7:8914 r6:dc8ab4c0 r5:dd257ae0 r4:beaeda20
>>> [   18.345822] [] (do_vfs_ioctl) from [] 
>>> (SyS_ioctl+0x74/0x84)
>>> [   18.353573]  r10: r9:0011 r8:beaeda20 r7:8914 
>>> r6:dc8ab4c0 r5:dc8ab4c0
>>> [   18.361924]  r4:
>>> [   18.364653] [] (SyS_ioctl) from [] 
>>> (ret_fast_syscall+0x0/0x3c)
>>> [   18.372682]  r9:dc968000 r8:c00165e8 r7:0036 r6:0002 r5:0011 
>>> r4:
>>> [   18.380960] Code: e92dd810 e24cb010 e24dd010 e59b4004 (e5902180)
>>> [   18.387580] ---[ end trace c80529466223f3f3 ]---
>>
>> ^ Could you make it shorter and drop timestamps, pls?
>>
>>>
>>> Signed-off-by: Andrew Goodbody 
>>> ---
>>>
>>> v2 - Move allocation of memory for priv->slaves to inside cpsw_probe_dt so 
>>> it
>>>has data->slaves initialised first which is needed to calculate size
>>>
>>>drivers/net/ethernet/ti/cpsw.c | 30 +++---
>>>1 file changed, 15 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
>>> index 42fdfd4..e62909c 100644
>>> --- a/drivers/net/ethernet/ti/cpsw.c
>>> +++ b/drivers/net/ethernet/ti/cpsw.c
>>> @@ -349,6 +349,7 @@ struct cpsw_slave {
>>> struct cpsw_slave_data  *data;
>>> struct phy_device   *phy;
>>> struct net_device   *ndev;
>>> +   struct device_node  *phy_node;
>>> u32 port_vlan;
>>> u32 open_stat;
>>>};
>>> @@ -367,7 +368,6 @@ struct cpsw_priv {
>>> spinlock_t  lock;
>>> struct platform_device  *pdev;
>>> struct net_device   *ndev;
>>> -   struct device_node  *phy_node;
>>> struct napi_struct  napi_rx;
>>> struct napi_struct  napi_tx;
>>> struct device   *dev;
>>> @@ -1148,8 +1148,8 @@ static void cpsw_slave_open(struct cpsw_slave *slave, 
>>> struct cpsw_priv *priv)
>>> cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
>>>1 << slave_port, 0, 0, ALE_MCAST_FWD_2);
>>>
>>> -   if (pr

[PATCH] drivers: net: cpsw: fix wrong regs access in cpsw_ndo_open

2016-04-19 Thread Grygorii Strashko
The cpsw_ndo_open() could try to access CPSW registers before
calling pm_runtime_get_sync(). This will trigger L3 error:

 WARNING: CPU: 0 PID: 21 at drivers/bus/omap_l3_noc.c:147 
l3_interrupt_handler+0x220/0x34c()
 4400.ocp:L3 Custom Error: MASTER M2 (64-bit) TARGET L4_FAST (Idle): Data 
Access in Supervisor mode during Functional access

and CPSW will stop functioning.

Hence, fix it by moving pm_runtime_get_sync() before the first access
to CPSW registers in cpsw_ndo_open().

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/cpsw.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 54bcc38..0fa75a8 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1244,12 +1244,12 @@ static int cpsw_ndo_open(struct net_device *ndev)
int i, ret;
u32 reg;
 
+   pm_runtime_get_sync(&priv->pdev->dev);
+
if (!cpsw_common_res_usage_state(priv))
cpsw_intr_disable(priv);
netif_carrier_off(ndev);
 
-   pm_runtime_get_sync(&priv->pdev->dev);
-
reg = priv->version;
 
dev_info(priv->dev, "initializing cpsw version %d.%d (%d)\n",
-- 
2.8.1



Re: [PATCH v2 1/1] drivers: net: cpsw: Prevent NUll pointer dereference with two PHYs

2016-04-19 Thread Grygorii Strashko

On 04/19/2016 08:14 PM, David Rivshin (Allworx) wrote:

On Tue, 19 Apr 2016 18:44:41 +0300
Grygorii Strashko  wrote:


On 04/19/2016 06:01 PM, David Rivshin (Allworx) wrote:

On Tue, 19 Apr 2016 17:41:07 +0300
Grygorii Strashko  wrote:


Hi,

On 04/19/2016 04:56 PM, Andrew Goodbody wrote:

Adding a 2nd PHY to cpsw results in a NULL pointer dereference
as below. Fix by maintaining a reference to each PHY node in slave
struct instead of a single reference in the priv struct which was
overwritten by the 2nd PHY.


David, Is it possible to drop prev version of this patch from linux-next
- it breaks boot on many TI boards with -next.




[   17.870933] Unable to handle kernel NULL pointer dereference at virtual 
address 0180
[   17.879557] pgd = dc8bc000
[   17.882514] [0180] *pgd=9c882831, *pte=, *ppte=
[   17.889213] Internal error: Oops: 17 [#1] ARM
[   17.893838] Modules linked in:
[   17.897102] CPU: 0 PID: 1657 Comm: connmand Not tainted 4.5.0-ge463dfb-dirty 
#11
[   17.904947] Hardware name: Cambrionix whippet
[   17.909576] task: dc859240 ti: dc968000 task.ti: dc968000
[   17.915339] PC is at phy_attached_print+0x18/0x8c
[   17.920339] LR is at phy_attached_info+0x14/0x18
[   17.925247] pc : []lr : []psr: 600f0113
[   17.925247] sp : dc969cf8  ip : dc969d28  fp : dc969d18
[   17.937425] r10: dda7a400  r9 :   r8 : 
[   17.942971] r7 : 0001  r6 : ddb00480  r5 : ddb8cb34  r4 : 
[   17.949898] r3 : c0954cc0  r2 : c09562b0  r1 :   r0 : 
[   17.956829] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[   17.964401] Control: 10c5387d  Table: 9c8bc019  DAC: 0051
[   17.970500] Process connmand (pid: 1657, stack limit = 0xdc968210)
[   17.977059] Stack: (0xdc969cf8 to 0xdc96a000)


[...]


[   18.323956] [] (inet_ioctl) from [] 
(sock_ioctl+0x15c/0x2d8)
[   18.331829] [] (sock_ioctl) from [] 
(do_vfs_ioctl+0x98/0x8d0)
[   18.339765]  r7:8914 r6:dc8ab4c0 r5:dd257ae0 r4:beaeda20
[   18.345822] [] (do_vfs_ioctl) from [] 
(SyS_ioctl+0x74/0x84)
[   18.353573]  r10: r9:0011 r8:beaeda20 r7:8914 r6:dc8ab4c0 
r5:dc8ab4c0
[   18.361924]  r4:
[   18.364653] [] (SyS_ioctl) from [] 
(ret_fast_syscall+0x0/0x3c)
[   18.372682]  r9:dc968000 r8:c00165e8 r7:0036 r6:0002 r5:0011 
r4:
[   18.380960] Code: e92dd810 e24cb010 e24dd010 e59b4004 (e5902180)
[   18.387580] ---[ end trace c80529466223f3f3 ]---


^ Could you make it shorter and drop timestamps, pls?



Signed-off-by: Andrew Goodbody 
---

v2 - Move allocation of memory for priv->slaves to inside cpsw_probe_dt so it
has data->slaves initialised first which is needed to calculate size

drivers/net/ethernet/ti/cpsw.c | 30 +++---
1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 42fdfd4..e62909c 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -349,6 +349,7 @@ struct cpsw_slave {
struct cpsw_slave_data  *data;
struct phy_device   *phy;
struct net_device   *ndev;
+   struct device_node  *phy_node;
u32 port_vlan;
u32 open_stat;
};
@@ -367,7 +368,6 @@ struct cpsw_priv {
spinlock_t  lock;
struct platform_device  *pdev;
struct net_device   *ndev;
-   struct device_node  *phy_node;
struct napi_struct  napi_rx;
struct napi_struct  napi_tx;
struct device   *dev;
@@ -1148,8 +1148,8 @@ static void cpsw_slave_open(struct cpsw_slave *slave, 
struct cpsw_priv *priv)
cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
   1 << slave_port, 0, 0, ALE_MCAST_FWD_2);

-   if (priv->phy_node)
-   slave->phy = of_phy_connect(priv->ndev, priv->phy_node,
+   if (slave->phy_node)
+   slave->phy = of_phy_connect(priv->ndev, slave->phy_node,
 &cpsw_adjust_link, 0, slave->data->phy_if);
else
slave->phy = phy_connect(priv->ndev, slave->data->phy_id,
@@ -1946,7 +1946,7 @@ static int cpsw_probe_dt(struct cpsw_priv *priv,
struct device_node *node = pdev->dev.of_node;
struct device_node *slave_node;
struct cpsw_platform_data *data = &priv->data;
-   int i = 0, ret;
+   int i, ret;
u32 prop;

if (!node)
@@ -1958,6 +1958,14 @@ static int cpsw_probe_dt(struct cpsw_priv *priv,
}
data->slaves = prop;

+   priv->slaves = devm_kzalloc(&pdev->dev,
+   sizeof(struct cpsw_slave) * data->slaves,
+

Re: [PATCH v2 1/1] drivers: net: cpsw: Prevent NUll pointer dereference with two PHYs

2016-04-20 Thread Grygorii Strashko
On 04/20/2016 02:38 AM, David Rivshin (Allworx) wrote:
> On Tue, 19 Apr 2016 18:43:39 -0400 (EDT)
> David Miller  wrote:
> 
>> From: Grygorii Strashko 
>> Date: Tue, 19 Apr 2016 21:44:09 +0300
>>
>>> May be you can send revert + your patch 1 (only fix for this issue).
>>>
>>> Dave, Does that sound good to you?
>>
>> Sure.
> 
> OK, I will hopefully have that ready tomorrow evening.
> 
> Anything in particular I should mention in the revert commit message?
> I didn't find a discussion on it, other than the earlier statement that
> "it breaks boot on many TI boards".
> 

Such kind of issues are tracked automatically now for ARM through 
https://kernelci.org
Example:
https://storage.kernelci.org/next/next-20160419/arm-multi_v7_defconfig+CONFIG_EFI=y/lab-cambridge/boot-am335x-boneblack.txt

And We're trying to auto check it internally also
https://github.com/nmenon/kernel-test-logs

Below is my boot log:


 ata1: SATA max UDMA/133 mmio [mem 0x4a14-0x4a1410ff] port 0x100 irq 332
 mtdoops: mtd device (mtddev=name/number) must be supplied
 davinci_mdio 48485000.mdio: davinci mdio revision 1.6
 davinci_mdio 48485000.mdio: detected phy mask fff9
 libphy: 48485000.mdio: probed
 davinci_mdio 48485000.mdio: phy[1]: device 48485000.mdio:01, driver unknown
 davinci_mdio 48485000.mdio: phy[2]: device 48485000.mdio:02, driver unknown
 cpsw 48484000.ethernet: Detected MACID = 74:da:ea:47:7d:9c
 cpsw 48484000.ethernet: cpsw: Random MACID = ca:39:e7:f3:28:69
 Unable to handle kernel paging request at virtual address fffc
 pgd = c0004000
 [fffc] *pgd=affae861, *pte=, *ppte=
 Internal error: Oops: 37 [#1] SMP ARM
 Modules linked in:
 CPU: 1 PID: 1 Comm: swapper/0 Tainted: GW   
4.6.0-rc4-next-20160419-2-g94c3d2a #4
 Hardware name: Generic DRA74X (Flattened Device Tree)
 task: ee0c4d80 ti: ee0c6000 task.ti: ee0c6000
 PC is at kset_find_obj+0x28/0xa4
 LR is at kset_find_obj+0x3c/0xa4
 pc : []lr : []psr: a013
 sp : ee0c7ec8  ip :   fp : c0b005a0
 
 [] (kset_find_obj) from [] (driver_find+0x14/0x30)
 ata1: SATA link down (SStatus 0 SControl 300)
 [] (driver_find) from [] (driver_register+0x68/0xf8)
 [] (driver_register) from [] (do_one_initcall+0x3c/0x178)
 [] (do_one_initcall) from [] 
(kernel_init_freeable+0x218/0x2e8)
 [] (kernel_init_freeable) from [] (kernel_init+0x8/0x118)
 [] (kernel_init) from [] (ret_from_fork+0x14/0x24)
 Code: e5954000 e1550004 e2444004 0a0a (e5943000) 
 ---[ end trace 593c492662ed437e ]---
 Kernel panic - not syncing: Attempted to kill init! exitcode=0x000b
 
 CPU0: stopping
 CPU: 0 PID: 0 Comm: swapper/0 Tainted: G  D W   
4.6.0-rc4-next-20160419-2-g94c3d2a #4
 Hardware name: Generic DRA74X (Flattened Device Tree)
 [] (unwind_backtrace) from [] (show_stack+0x10/0x14)
 [] (show_stack) from [] (dump_stack+0xb0/0xe4)
 [] (dump_stack) from [] (handle_IPI+0x2c4/0x360)
 [] (handle_IPI) from [] (gic_handle_irq+0x84/0x94)
 [] (gic_handle_irq) from [] (__irq_svc+0x58/0x78)
 Exception stack(0xc0c01f58 to 0xc0c01fa0)
 1f40:   c0108318 
 1f60:   c0c02a34   c0cbe5f8 c0c029cc c0cbe5f8
 1f80: c0b71a38 c0cbd3a9  c0c01fa8 c0108318 c010831c 6013 
 [] (__irq_svc) from [] (arch_cpu_idle+0x20/0x3c)
 [] (arch_cpu_idle) from [] (cpu_startup_entry+0x30c/0x3f0)
 [] (cpu_startup_entry) from [] (start_kernel+0x33c/0x3b4)
 [] (start_kernel) from [<8000807c>] (0x8000807c)


-- 
regards,
-grygorii


[PATCH] MAINTAINERS: net: add entry for TI Ethernet Switch drivers

2016-04-20 Thread Grygorii Strashko
Add record for TI Ethernet Switch Driver CPSW/CPDMA/MDIO HW
(am33/am43/am57/dr7/davinci) to ensure that related patches
will go through dedicated linux-omap list.

Also add Mugunthan as maintainer and myself as the reviewer.

Cc: "David S. Miller" 
Cc: Mugunthan V N 
Cc: Richard Cochran 
Signed-off-by: Grygorii Strashko 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1d5b4be..aca864d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11071,6 +11071,14 @@ S: Maintained
 F: drivers/clk/ti/
 F: include/linux/clk/ti.h
 
+TI ETHERNET SWITCH DRIVER (CPSW)
+M: Mugunthan V N 
+R:     Grygorii Strashko 
+L: linux-o...@vger.kernel.org
+S: Maintained
+F: drivers/net/ethernet/ti/cpsw*
+F: drivers/net/ethernet/ti/davinci*
+
 TI FLASH MEDIA INTERFACE DRIVER
 M: Alex Dubov 
 S: Maintained
-- 
2.8.1



Re: [PATCH] MAINTAINERS: net: add entry for TI Ethernet Switch drivers

2016-04-20 Thread Grygorii Strashko
On 04/20/2016 05:23 PM, Tony Lindgren wrote:
> * Grygorii Strashko  [160420 04:26]:
>> Add record for TI Ethernet Switch Driver CPSW/CPDMA/MDIO HW
>> (am33/am43/am57/dr7/davinci) to ensure that related patches
>> will go through dedicated linux-omap list.
>>
>> Also add Mugunthan as maintainer and myself as the reviewer.
>>
>> Cc: "David S. Miller" 
>> Cc: Mugunthan V N 
>> Cc: Richard Cochran 
>> Signed-off-by: Grygorii Strashko 
>> ---
>>   MAINTAINERS | 8 
>>   1 file changed, 8 insertions(+)
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 1d5b4be..aca864d 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -11071,6 +11071,14 @@ S:  Maintained
>>   F: drivers/clk/ti/
>>   F: include/linux/clk/ti.h
>>   
>> +TI ETHERNET SWITCH DRIVER (CPSW)
>> +M:  Mugunthan V N 
>> +R:  Grygorii Strashko 
>> +L:  linux-o...@vger.kernel.org
>> +S:  Maintained
>> +F:  drivers/net/ethernet/ti/cpsw*
>> +F:  drivers/net/ethernet/ti/davinci*
>> +
>>   TI FLASH MEDIA INTERFACE DRIVER
>>   M: Alex Dubov 
>>   S: Maintained
>> -- 
> 
> Please add netdev list also there as the primary list:
> 
> L:netdev@vger.kernel.org
> L:linux-o...@vger.kernel.org
> 
> Then we can easily review and ack the patches for Dave to apply.
> 

I can, but want clarify if it really necessary, because get_maintainer.pl
automatically adds netdev@vger.kernel.org:

./scripts/get_maintainer.pl 
~/.../0001-drivers-net-cpsw-fix-port_mask-parameters-in-ale-cal.patch 
Mugunthan V N  (maintainer:TI ETHERNET SWITCH DRIVER 
(CPSW))
Grygorii Strashko  (reviewer:TI ETHERNET SWITCH 
DRIVER (CPSW))
linux-o...@vger.kernel.org (open list:TI ETHERNET SWITCH DRIVER (CPSW))
netdev@vger.kernel.org (open list:NETWORKING DRIVERS)
linux-ker...@vger.kernel.org (open list)
 


-- 
regards,
-grygorii


[PATCH v2] MAINTAINERS: net: add entry for TI Ethernet Switch drivers

2016-04-21 Thread Grygorii Strashko
Add record for TI Ethernet Switch Driver CPSW/CPDMA/MDIO HW
(am33/am43/am57/dr7/davinci) to ensure that related patches
will go through dedicated linux-omap list.

Also add Mugunthan as maintainer and myself as the reviewer.

Cc: "David S. Miller" 
Cc: Tony Lindgren 
Cc: Mugunthan V N 
Cc: Richard Cochran 
Signed-off-by: Grygorii Strashko 
---
Changes in v2:
 - added netdev@vger.kernel.org list

 MAINTAINERS | 9 +
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1d5b4be..8491336 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11071,6 +11071,15 @@ S: Maintained
 F: drivers/clk/ti/
 F: include/linux/clk/ti.h
 
+TI ETHERNET SWITCH DRIVER (CPSW)
+M: Mugunthan V N 
+R:     Grygorii Strashko 
+L: linux-o...@vger.kernel.org
+L: netdev@vger.kernel.org
+S: Maintained
+F: drivers/net/ethernet/ti/cpsw*
+F: drivers/net/ethernet/ti/davinci*
+
 TI FLASH MEDIA INTERFACE DRIVER
 M: Alex Dubov 
 S: Maintained
-- 
2.8.1



Re: [PATCH net v2 2/3] drivers: net: cpsw: fix error messages when using phy-handle DT property

2016-04-22 Thread Grygorii Strashko
On 04/21/2016 09:26 PM, David Rivshin (Allworx) wrote:
> From: David Rivshin 
> 
> The phy-handle, phy_id, and fixed-link properties are mutually exclusive,
> and only one need be specified. However if phy-handle was specified, an
> error message would complain about the lack of phy_id or fixed-link.
> 
> Also, if phy-handle was specified and the subsequent of_phy_connect()
> failed, the error message still referenced slaved->data->phy_id, which
> would be empty. Instead, use the name of the device_node as a useful
> identifier.
> 
> Fixes: 9e42f715264f ("drivers: net: cpsw: add phy-handle parsing")
> Signed-off-by: David Rivshin 
> Acked-by: Rob Herring 
> Tested-by: Nicolas Chauvet 
> ---
> If would like this for -stable it should apply cleanly as far back
> as 4.5. It failes on 4.4 due to some context differences, but can be
> applied with 'git am -C2'. Or, I can produce a separate patch against
> linux-4.4.y if preferred.
> 
> Changes since v1 [1]:
> - Rebased (no conflicts)
> - Added Tested-by from Nicolas Chauvet
> - Added Acked-by from Rob Herring for the binding change
> 
> [1] https://patchwork.ozlabs.org/patch/560324/
> 
>   Documentation/devicetree/bindings/net/cpsw.txt |  4 ++--
>   drivers/net/ethernet/ti/cpsw.c | 17 +
>   2 files changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/net/cpsw.txt 
> b/Documentation/devicetree/bindings/net/cpsw.txt
> index 28a4781..3033c0f 100644
> --- a/Documentation/devicetree/bindings/net/cpsw.txt
> +++ b/Documentation/devicetree/bindings/net/cpsw.txt
> @@ -46,16 +46,16 @@ Optional properties:
>   - dual_emac_res_vlan: Specifies VID to be used to segregate the 
> ports
>   - mac-address   : See ethernet.txt file in the same directory
>   - phy_id: Specifies slave phy id

May be the "phy_id" can be marked as deprecated? (while here)
The recommended property now is "phy-handle".

>   - phy-handle: See ethernet.txt file in the same directory
>   
>   Slave sub-nodes:
>   - fixed-link: See fixed-link.txt file in the same directory
> -   Either the property phy_id, or the sub-node
> -   fixed-link can be specified
> +
> +Note: Exactly one of phy_id, phy-handle, or fixed-link must be specified.
>   
>   Note: "ti,hwmods" field is used to fetch the base address and irq
>   resources from TI, omap hwmod data base during device registration.
>   Future plan is to migrate hwmod data base contents into device tree
>   blob so that, all the required data will be used from device tree dts
>   file.
>   
> diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
> index d69cb3f..3c81413 100644
> --- a/drivers/net/ethernet/ti/cpsw.c
> +++ b/drivers/net/ethernet/ti/cpsw.c
> @@ -1150,16 +1150,19 @@ static void cpsw_slave_open(struct cpsw_slave *slave, 
> struct cpsw_priv *priv)
>   if (slave->data->phy_node)
>   slave->phy = of_phy_connect(priv->ndev, slave->data->phy_node,
>&cpsw_adjust_link, 0, slave->data->phy_if);
>   else
>   slave->phy = phy_connect(priv->ndev, slave->data->phy_id,
>&cpsw_adjust_link, slave->data->phy_if);
>   if (IS_ERR(slave->phy)) {
> - dev_err(priv->dev, "phy %s not found on slave %d\n",
> - slave->data->phy_id, slave->slave_num);
> + dev_err(priv->dev, "phy \"%s\" not found on slave %d\n",
> + slave->data->phy_node ?
> + slave->data->phy_node->full_name :
> + slave->data->phy_id,
> + slave->slave_num);

Unfortunately,  there are some inconsistency between legacy and FDT API :(
of_phy_connect() will return valid phy_device or NULL, but phy_connect()
can return valid phy_device or ERR_PTR().



>   slave->phy = NULL;
>   } else {
>   phy_attached_info(slave->phy);
>   
>   phy_start(slave->phy);
>   
>   /* Configure GMII_SEL register */
> @@ -2030,15 +2033,19 @@ static int cpsw_probe_dt(struct cpsw_platform_data 
> *data,
>   /* This is no slave child node, continue */
>   if (strcmp(slave_node->name, "slave"))
>   continue;
>   
>   slave_data->phy_node = of_parse_phandle(slave_node,
>   "phy-handle", 0);
>   parp = of_get_property(slave_node, "phy_id", &lenp);
> - if (of_phy_is_fixed_link(slave_node)) {
> + if (slave_data->phy_node) {
> + dev_dbg(&pdev->dev,
> + "slave[%d] using phy-handle=\"%s\"\n",
> + i, slave_data->phy_node->full_name);
> + } else if (of_phy_is_fixed_link(slave_node)) {
>   struct device_node *phy_no

Re: [PATCH net v2 1/3] drivers: net: cpsw: fix parsing of phy-handle DT property in dual_emac config

2016-04-22 Thread Grygorii Strashko

On 04/21/2016 09:19 PM, David Rivshin (Allworx) wrote:

From: David Rivshin 

Commit 9e42f715264ff158478fa30eaed847f6e131366b ("drivers: net: cpsw: add
phy-handle parsing") saved the "phy-handle" phandle into a new cpsw_priv
field. However, phy connections are per-slave, so the phy_node field should
be in cpsw_slave_data rather than cpsw_priv.

This would go unnoticed in a single emac configuration. But in dual_emac
mode, the last "phy-handle" property parsed for either slave would be used
by both of them, causing them both to refer to the same phy_device.

Fixes: 9e42f715264f ("drivers: net: cpsw: add phy-handle parsing")
Signed-off-by: David Rivshin 
Tested-by: Nicolas Chauvet 
---
I would suggest this for -stable. It should apply cleanly as far back
as 4.4.

Changes since v1 [1]:
- Rebased (no conflicts)
- Added Tested-by from Nicolas Chauvet

[1] https://patchwork.ozlabs.org/patch/560326/


Reviewed-by: Grygorii Strashko 



  drivers/net/ethernet/ti/cpsw.c | 13 ++---
  drivers/net/ethernet/ti/cpsw.h |  1 +
  2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 42fdfd4..d69cb3f 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -363,15 +363,14 @@ static inline void slave_write(struct cpsw_slave *slave, 
u32 val, u32 offset)
__raw_writel(val, slave->regs + offset);
  }

  struct cpsw_priv {
spinlock_t  lock;
struct platform_device  *pdev;
struct net_device   *ndev;
-   struct device_node  *phy_node;
struct napi_struct  napi_rx;
struct napi_struct  napi_tx;
struct device   *dev;
struct cpsw_platform_data   data;
struct cpsw_ss_regs __iomem *regs;
struct cpsw_wr_regs __iomem *wr_regs;
u8 __iomem  *hw_stats;
@@ -1144,16 +1143,16 @@ static void cpsw_slave_open(struct cpsw_slave *slave, 
struct cpsw_priv *priv)

if (priv->data.dual_emac)
cpsw_add_dual_emac_def_ale_entries(priv, slave, slave_port);
else
cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
   1 << slave_port, 0, 0, ALE_MCAST_FWD_2);

-   if (priv->phy_node)
-   slave->phy = of_phy_connect(priv->ndev, priv->phy_node,
+   if (slave->data->phy_node)
+   slave->phy = of_phy_connect(priv->ndev, slave->data->phy_node,
 &cpsw_adjust_link, 0, slave->data->phy_if);
else
slave->phy = phy_connect(priv->ndev, slave->data->phy_id,
 &cpsw_adjust_link, slave->data->phy_if);
if (IS_ERR(slave->phy)) {
dev_err(priv->dev, "phy %s not found on slave %d\n",
slave->data->phy_id, slave->slave_num);
@@ -1936,20 +1935,19 @@ static void cpsw_slave_init(struct cpsw_slave *slave, 
struct cpsw_priv *priv,

slave->data  = data;
slave->regs  = regs + slave_reg_ofs;
slave->sliver= regs + sliver_reg_ofs;
slave->port_vlan = data->dual_emac_res_vlan;
  }

-static int cpsw_probe_dt(struct cpsw_priv *priv,
+static int cpsw_probe_dt(struct cpsw_platform_data *data,
 struct platform_device *pdev)
  {
struct device_node *node = pdev->dev.of_node;
struct device_node *slave_node;
-   struct cpsw_platform_data *data = &priv->data;
int i = 0, ret;
u32 prop;

if (!node)
return -EINVAL;

if (of_property_read_u32(node, "slaves", &prop)) {
@@ -2029,15 +2027,16 @@ static int cpsw_probe_dt(struct cpsw_priv *priv,
int lenp;
const __be32 *parp;

/* This is no slave child node, continue */
if (strcmp(slave_node->name, "slave"))
continue;

-   priv->phy_node = of_parse_phandle(slave_node, "phy-handle", 0);
+   slave_data->phy_node = of_parse_phandle(slave_node,
+   "phy-handle", 0);
parp = of_get_property(slave_node, "phy_id", &lenp);
if (of_phy_is_fixed_link(slave_node)) {
struct device_node *phy_node;
struct phy_device *phy_dev;

/* In the case of a fixed PHY, the DT node associated
 * to the PHY is the Ethernet MAC DT node.
@@ -2271,15 +2270,15 @@ static int cpsw_probe(struct platform_device *pdev)
 * This may be required here for chil

Re: [PATCH net v2 3/3] drivers: net: cpsw: use of_phy_connect() in fixed-link case

2016-04-22 Thread Grygorii Strashko

On 04/21/2016 09:41 PM, David Rivshin (Allworx) wrote:

From: David Rivshin 

If a fixed-link DT subnode is used, the phy_device was looked up so
that a PHY ID string could be constructed and passed to phy_connect().
This is not necessary, as the device_node can be passed directly to
of_phy_connect() instead. This reuses the same codepath as if the
phy-handle DT property was used.

Signed-off-by: David Rivshin 
Tested-by: Nicolas Chauvet 
---

Changes since v1 [1]:
- Rebased (trivial conflict, e5a03bfd modified the deleted snprintf)
- Added Tested-by from Nicolas Chauvet

[1] https://patchwork.ozlabs.org/patch/560327/



Reviewed-by: Grygorii Strashko 



  drivers/net/ethernet/ti/cpsw.c | 11 +--
  1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 3c81413..245f919 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -2038,30 +2038,21 @@ static int cpsw_probe_dt(struct cpsw_platform_data 
*data,
"phy-handle", 0);
parp = of_get_property(slave_node, "phy_id", &lenp);
if (slave_data->phy_node) {
dev_dbg(&pdev->dev,
"slave[%d] using phy-handle=\"%s\"\n",
i, slave_data->phy_node->full_name);
} else if (of_phy_is_fixed_link(slave_node)) {
-   struct device_node *phy_node;
-   struct phy_device *phy_dev;
-
/* In the case of a fixed PHY, the DT node associated
 * to the PHY is the Ethernet MAC DT node.
 */
ret = of_phy_register_fixed_link(slave_node);
if (ret)
return ret;
-   phy_node = of_node_get(slave_node);
-   phy_dev = of_phy_find_device(phy_node);
-   if (!phy_dev)
-   return -ENODEV;
-   snprintf(slave_data->phy_id, sizeof(slave_data->phy_id),
-PHY_ID_FMT, phy_dev->mdio.bus->id,
-phy_dev->mdio.addr);
+   slave_data->phy_node = of_node_get(slave_node);
} else if (parp) {
u32 phyid;
struct device_node *mdio_node;
struct platform_device *mdio;

if (lenp != (sizeof(__be32) * 2)) {
dev_err(&pdev->dev, "Invalid slave[%d] phy_id 
property\n", i);




--
regards,
-grygorii


Re: [PATCH net v2 2/3] drivers: net: cpsw: fix error messages when using phy-handle DT property

2016-04-25 Thread Grygorii Strashko
On 04/22/2016 06:45 PM, David Rivshin (Allworx) wrote:
> On Fri, 22 Apr 2016 16:03:34 +0300
> Grygorii Strashko  wrote:
> 
>> On 04/21/2016 09:26 PM, David Rivshin (Allworx) wrote:
>>> From: David Rivshin 
>>>
>>> The phy-handle, phy_id, and fixed-link properties are mutually exclusive,
>>> and only one need be specified. However if phy-handle was specified, an
>>> error message would complain about the lack of phy_id or fixed-link.

I think, commit message need to be updated.
You not only fix log messages - you also fix the issue with 
of_get_phy_mode(slave_node); which will not be called if phy-handle is used.
 

slave_data->phy_if = of_get_phy_mode(slave_node); 
^ see below
>>>
>>> Also, if phy-handle was specified and the subsequent of_phy_connect()
>>> failed, the error message still referenced slaved->data->phy_id, which
>>> would be empty. Instead, use the name of the device_node as a useful
>>> identifier.
>>>
>>> Fixes: 9e42f715264f ("drivers: net: cpsw: add phy-handle parsing")
>>> Signed-off-by: David Rivshin 
>>> Acked-by: Rob Herring 
>>> Tested-by: Nicolas Chauvet 
>>> ---
>>> If would like this for -stable it should apply cleanly as far back
>>> as 4.5. It failes on 4.4 due to some context differences, but can be
>>> applied with 'git am -C2'. Or, I can produce a separate patch against
>>> linux-4.4.y if preferred.
>>>
>>> Changes since v1 [1]:
>>> - Rebased (no conflicts)
>>> - Added Tested-by from Nicolas Chauvet
>>> - Added Acked-by from Rob Herring for the binding change
>>>
>>> [1] https://patchwork.ozlabs.org/patch/560324/
>>>
>>>Documentation/devicetree/bindings/net/cpsw.txt |  4 ++--
>>>drivers/net/ethernet/ti/cpsw.c | 17 +
>>>2 files changed, 15 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/net/cpsw.txt 
>>> b/Documentation/devicetree/bindings/net/cpsw.txt
>>> index 28a4781..3033c0f 100644
>>> --- a/Documentation/devicetree/bindings/net/cpsw.txt
>>> +++ b/Documentation/devicetree/bindings/net/cpsw.txt
>>> @@ -46,16 +46,16 @@ Optional properties:
>>>- dual_emac_res_vlan : Specifies VID to be used to segregate the 
>>> ports
>>>- mac-address: See ethernet.txt file in the same directory
>>>- phy_id : Specifies slave phy id
>>
>> May be the "phy_id" can be marked as deprecated? (while here)
>> The recommended property now is "phy-handle".
> 
> I can certainly do that. Perhaps something like this?
>   - phy_id: Specifies slave phy id (deprecated, use phy-handle)
> 
> Rob, would you have any issues with bundling that?
> 
>>
>>>- phy-handle : See ethernet.txt file in the same directory
>>>
>>>Slave sub-nodes:
>>>- fixed-link : See fixed-link.txt file in the same directory
>>> - Either the property phy_id, or the sub-node
>>> - fixed-link can be specified
>>> +
>>> +Note: Exactly one of phy_id, phy-handle, or fixed-link must be specified.
>>>
>>>Note: "ti,hwmods" field is used to fetch the base address and irq
>>>resources from TI, omap hwmod data base during device registration.
>>>Future plan is to migrate hwmod data base contents into device tree
>>>blob so that, all the required data will be used from device tree dts
>>>file.
>>>
>>> diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
>>> index d69cb3f..3c81413 100644
>>> --- a/drivers/net/ethernet/ti/cpsw.c
>>> +++ b/drivers/net/ethernet/ti/cpsw.c
>>> @@ -1150,16 +1150,19 @@ static void cpsw_slave_open(struct cpsw_slave 
>>> *slave, struct cpsw_priv *priv)
>>> if (slave->data->phy_node)
>>> slave->phy = of_phy_connect(priv->ndev, slave->data->phy_node,
>>>  &cpsw_adjust_link, 0, slave->data->phy_if);
>>> else
>>> slave->phy = phy_connect(priv->ndev, slave->data->phy_id,
>>>  &cpsw_adjust_link, slave->data->phy_if);
>>> if (IS_ERR(slave->phy)) {
>>> -   dev_err(priv->dev, "phy %s not found on slave %d\n",
>>> -   slave->data->phy_id, sl

Re: [PATCH net v2 1/3] drivers: net: cpsw: fix parsing of phy-handle DT property in dual_emac config

2016-04-25 Thread Grygorii Strashko
On 04/22/2016 04:03 PM, Grygorii Strashko wrote:
> On 04/21/2016 09:19 PM, David Rivshin (Allworx) wrote:
>> From: David Rivshin 
>>
>> Commit 9e42f715264ff158478fa30eaed847f6e131366b ("drivers: net: cpsw: add
>> phy-handle parsing") saved the "phy-handle" phandle into a new cpsw_priv
>> field. However, phy connections are per-slave, so the phy_node field 
>> should
>> be in cpsw_slave_data rather than cpsw_priv.
>>
>> This would go unnoticed in a single emac configuration. But in dual_emac
>> mode, the last "phy-handle" property parsed for either slave would be 
>> used
>> by both of them, causing them both to refer to the same phy_device.
>>
>> Fixes: 9e42f715264f ("drivers: net: cpsw: add phy-handle parsing")
>> Signed-off-by: David Rivshin 
>> Tested-by: Nicolas Chauvet 
>> ---
>> I would suggest this for -stable. It should apply cleanly as far back
>> as 4.4.
>>
>> Changes since v1 [1]:
>> - Rebased (no conflicts)
>> - Added Tested-by from Nicolas Chauvet
>>
>> [1] https://patchwork.ozlabs.org/patch/560326/
> 
> Reviewed-by: Grygorii Strashko 

In my opinion, it will be good to have this patch merged as part of -rc cycle, 
since
it will fix "NULL pointer dereference" issue with current LKML as reported by 
Andrew Goodbody.


> 
>>
>>   drivers/net/ethernet/ti/cpsw.c | 13 ++---
>>   drivers/net/ethernet/ti/cpsw.h |  1 +
>>   2 files changed, 7 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/ti/cpsw.c 
>> b/drivers/net/ethernet/ti/cpsw.c
>> index 42fdfd4..d69cb3f 100644
>> --- a/drivers/net/ethernet/ti/cpsw.c
>> +++ b/drivers/net/ethernet/ti/cpsw.c
>> @@ -363,15 +363,14 @@ static inline void slave_write(struct cpsw_slave 
>> *slave, u32 val, u32 offset)
>>   __raw_writel(val, slave->regs + offset);
>>   }
>>
>>   struct cpsw_priv {
>>   spinlock_tlock;
>>   struct platform_device*pdev;
>>   struct net_device*ndev;
>> -struct device_node*phy_node;
>>   struct napi_structnapi_rx;
>>   struct napi_structnapi_tx;
>>   struct device*dev;
>>   struct cpsw_platform_datadata;
>>   struct cpsw_ss_regs __iomem*regs;
>>   struct cpsw_wr_regs __iomem*wr_regs;
>>   u8 __iomem*hw_stats;
>> @@ -1144,16 +1143,16 @@ static void cpsw_slave_open(struct cpsw_slave 
>> *slave, struct cpsw_priv *priv)
>>
>>   if (priv->data.dual_emac)
>>   cpsw_add_dual_emac_def_ale_entries(priv, slave, slave_port);
>>   else
>>   cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
>>  1 << slave_port, 0, 0, ALE_MCAST_FWD_2);
>>
>> -if (priv->phy_node)
>> -slave->phy = of_phy_connect(priv->ndev, priv->phy_node,
>> +if (slave->data->phy_node)
>> +slave->phy = of_phy_connect(priv->ndev, slave->data->phy_node,
>>&cpsw_adjust_link, 0, slave->data->phy_if);
>>   else
>>   slave->phy = phy_connect(priv->ndev, slave->data->phy_id,
>>&cpsw_adjust_link, slave->data->phy_if);
>>   if (IS_ERR(slave->phy)) {
>>   dev_err(priv->dev, "phy %s not found on slave %d\n",
>>   slave->data->phy_id, slave->slave_num);
>> @@ -1936,20 +1935,19 @@ static void cpsw_slave_init(struct cpsw_slave 
>> *slave, struct cpsw_priv *priv,
>>
>>   slave->data= data;
>>   slave->regs= regs + slave_reg_ofs;
>>   slave->sliver= regs + sliver_reg_ofs;
>>   slave->port_vlan = data->dual_emac_res_vlan;
>>   }
>>

[..]

-- 
regards,
-grygorii


Re: [PATCH net v2 2/3] drivers: net: cpsw: fix error messages when using phy-handle DT property

2016-04-26 Thread Grygorii Strashko

On 04/26/2016 12:55 AM, David Rivshin (Allworx) wrote:

On Mon, 25 Apr 2016 22:12:20 +0300
Grygorii Strashko  wrote:


On 04/22/2016 06:45 PM, David Rivshin (Allworx) wrote:

On Fri, 22 Apr 2016 16:03:34 +0300
Grygorii Strashko  wrote:


On 04/21/2016 09:26 PM, David Rivshin (Allworx) wrote:

From: David Rivshin 

The phy-handle, phy_id, and fixed-link properties are mutually exclusive,
and only one need be specified. However if phy-handle was specified, an
error message would complain about the lack of phy_id or fixed-link.


I think, commit message need to be updated.
You not only fix log messages - you also fix the issue with
of_get_phy_mode(slave_node); which will not be called if phy-handle is used.


You are correct, and that is probably the more important fix compared
to the error messages.

Because the content is becoming less coherent, what I may do is split
this patch into 3 small patches:
A) devicetree binding documentation changes
B) cpsw_probe_dt changes, with the fixes for of_get_phy_mode() and
related error message
C) cpsw_slave_open changes, with the fixes for crash if of_phy_connect
returns NULL, and related error message

Does that sound reasonable?


Sounds reasonable for me.
Hope patch 1 from this series could be merged separately.






slave_data->phy_if = of_get_phy_mode(slave_node);
^ see below


Also, if phy-handle was specified and the subsequent of_phy_connect()
failed, the error message still referenced slaved->data->phy_id, which
would be empty. Instead, use the name of the device_node as a useful
identifier.

Fixes: 9e42f715264f ("drivers: net: cpsw: add phy-handle parsing")
Signed-off-by: David Rivshin 
Acked-by: Rob Herring 
Tested-by: Nicolas Chauvet 
---
If would like this for -stable it should apply cleanly as far back
as 4.5. It failes on 4.4 due to some context differences, but can be
applied with 'git am -C2'. Or, I can produce a separate patch against
linux-4.4.y if preferred.

Changes since v1 [1]:
- Rebased (no conflicts)
- Added Tested-by from Nicolas Chauvet
- Added Acked-by from Rob Herring for the binding change

[1] https://patchwork.ozlabs.org/patch/560324/

Documentation/devicetree/bindings/net/cpsw.txt |  4 ++--
drivers/net/ethernet/ti/cpsw.c | 17 +
2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/cpsw.txt 
b/Documentation/devicetree/bindings/net/cpsw.txt
index 28a4781..3033c0f 100644
--- a/Documentation/devicetree/bindings/net/cpsw.txt
+++ b/Documentation/devicetree/bindings/net/cpsw.txt
@@ -46,16 +46,16 @@ Optional properties:
- dual_emac_res_vlan: Specifies VID to be used to segregate the 
ports
- mac-address   : See ethernet.txt file in the same directory
- phy_id: Specifies slave phy id


May be the "phy_id" can be marked as deprecated? (while here)
The recommended property now is "phy-handle".


I can certainly do that. Perhaps something like this?
   - phy_id : Specifies slave phy id (deprecated, use phy-handle)

Rob, would you have any issues with bundling that?




- phy-handle: See ethernet.txt file in the same directory

Slave sub-nodes:
- fixed-link: See fixed-link.txt file in the same directory
- Either the property phy_id, or the sub-node
- fixed-link can be specified
+
+Note: Exactly one of phy_id, phy-handle, or fixed-link must be specified.

Note: "ti,hwmods" field is used to fetch the base address and irq
resources from TI, omap hwmod data base during device registration.
Future plan is to migrate hwmod data base contents into device tree
blob so that, all the required data will be used from device tree dts
file.

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index d69cb3f..3c81413 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1150,16 +1150,19 @@ static void cpsw_slave_open(struct cpsw_slave *slave, 
struct cpsw_priv *priv)
if (slave->data->phy_node)
slave->phy = of_phy_connect(priv->ndev, slave->data->phy_node,
 &cpsw_adjust_link, 0, slave->data->phy_if);
else
slave->phy = phy_connect(priv->ndev, slave->data->phy_id,
 &cpsw_adjust_link, slave->data->phy_if);
if (IS_ERR(slave->phy)) {
-   dev_err(priv->dev, "phy %s not found on slave %d\n",
-   slave->data->phy_id, slave->slave_num);
+   dev_err(priv->dev, "phy \"%s\" not found on slave %d\n",
+   slave->data->phy_node ?
+   slave->data->phy_node->full_name :
+  

Re: [PATCH net v3 0/5] drivers: net: cpsw: phy-handle fixes

2016-04-28 Thread Grygorii Strashko

On 04/28/2016 04:10 AM, David Rivshin (Allworx) wrote:

From: David Rivshin 

This series fixes a number of related issues around using phy-handle
properties in cpsw emac nodes.

Patch 1 fixes a bug if more than one slave is used, and either
slave uses the phy-handle property in the devicetree.

Patch 2 fixes a NULL pointer dereference which can occur if a
phy-handle property is used and of_phy_connect() return NULL,
such as with a bad devicetree.

Patch 3 fixes an issue where the phy-mode property would be ignored
if a phy-handle property was used. This also fixes a bogus error
message that would be emitted.

Patch 4 fixes makes the binding documentation more explicit that
exactly one PHY property should be used, and also marks phy_id as
deprecated.

Patch 5 cleans up the fixed-link case to work like the now-fixed
phy-handle case.

I have tested on the following hardware configurations:
  - (EVMSK) dual emac, phy_id property in both slaves
  - (EVMSK) dual emac, phy-handle property in both slaves
  - (EVMSK) a bad phy-handle property pointing to &mmc1
  - (EVMSK) phy_id property with incorrect PHY address
  - (BeagleBoneBlack) single emac, phy_id property
  - (custom) single emac, fixed-link subnode

Andrew Goodbody reported testing v2 on a board that doesn't use
dual_emac mode, but with 2 PHYs using phy-handle properties [1].

Nicolas Chauvet reported testing v2 on an HP t410 (dm8148).

Markus Brunner reported testing v1 on the following [2]:
  - emac0 with phy_id and emac1 with fixed phy
  - emac0 with phy-handle and emac1 with fixed phy
  - emac0 with fixed phy and emac1 with fixed phy

[1] https://lkml.org/lkml/2016/4/22/537
[2] http://www.spinics.net/lists/netdev/msg357890.html

David Rivshin (5):
   drivers: net: cpsw: fix parsing of phy-handle DT property in dual_emac
 config
   drivers: net: cpsw: fix segfault in case of bad phy-handle
   drivers: net: cpsw: don't ignore phy-mode if phy-handle is used
   dt: cpsw: phy-handle, phy_id, and fixed-link are mutually exclusive
   drivers: net: cpsw: use of_phy_connect() in fixed-link case

  Documentation/devicetree/bindings/net/cpsw.txt |  6 +--
  drivers/net/ethernet/ti/cpsw.c | 69 ++
  drivers/net/ethernet/ti/cpsw.h |  1 +
  3 files changed, 41 insertions(+), 35 deletions(-)



Thanks a lot.
Reviewed-by: Grygorii Strashko 

--
regards,
-grygorii


Re: [PATCH 12/15] net: davinci_mdio: document missed "ti,am4372-mdio" compat string

2016-06-22 Thread Grygorii Strashko
On 06/19/2016 05:35 PM, Rob Herring wrote:
> On Wed, Jun 15, 2016 at 02:56:00PM +0300, Grygorii Strashko wrote:
>> Document missed "ti,am4372-mdio" compat string used for TI am437x SoC
>> (am4372.dtsi).
>>
>> Signed-off-by: Grygorii Strashko 
>> ---
>>   Documentation/devicetree/bindings/net/davinci-mdio.txt | 3 ++-
>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/net/davinci-mdio.txt 
>> b/Documentation/devicetree/bindings/net/davinci-mdio.txt
>> index 0369e25..f2bba50 100644
>> --- a/Documentation/devicetree/bindings/net/davinci-mdio.txt
>> +++ b/Documentation/devicetree/bindings/net/davinci-mdio.txt
>> @@ -2,7 +2,8 @@ TI SoC Davinci/Keystone2 MDIO Controller Device Tree Bindings
>>   ---
>>   
>>   Required properties:
>> -- compatible: Should be "ti,davinci_mdio" or 
>> "ti,keystone_mdio"
>> +- compatible: Should be "ti,davinci_mdio", 
>> "ti,keystone_mdio",
>> +  "ti,am4372-mdio"
> 
> This is still an OR relationship?

I think it's AND relation. It should be smth. like this:
 [SoC,][IP family,] "ti,davinci_mdio"
where "ti,davinci_mdio" is mandatory always
 [IP family] - mandatory for IP/SOC family and can be "ti,keystone_mdio" or 
"ti,cpsw-mdio" (last one is added by subsequent patch)
 [SoC] - mandatory for SoC. now can be "ti,am4372-mdio"

I can update it as below:
- compatible: Should be "ti,davinci_mdio"  
  and "ti,keystone_mdio" for Keystone 2 SoCs
  and "ti,am4372-mdio" for am472x SoC
and in subsequent patch
 and "ti,cpsw-mdio" for am335x, am472x, am57xx/dra7, 
dm814x SoCs
 and "ti,am4372-mdio" for am472x SoC



> 
> It's preferred to list one per line.

ok



-- 
regards,
-grygorii


[PATCH] net: ethernet: ti: cpdma: switch to use genalloc

2016-06-23 Thread Grygorii Strashko
TI CPDMA currently uses a bitmap for tracking descriptors alloactions
allocations, but The genalloc already handles the same and can be used
as with special memory (SRAM) as with DMA cherent memory chank
(dma_alloc_coherent()). Hence, switch to using genalloc and add
desc_num property for each channel for limitation of max number of
allowed descriptors for each CPDMA channel. This patch do not affect
on net throuput.

Cc: Ivan Khoronzhuk 
Signed-off-by: Grygorii Strashko 
---
Testing
TCP window: 256K, bandwidth in Mbits/sec:
 host: iperf -s
 device: iperf -c  172.22.39.17 -t600 -i5 -d -w128K

AM437x-idk, 1Gbps link
 before: : 341.60, after: 232+123=355
am57xx-beagle-x15, 1Gbps link
 before: : 1112.80, after: 814+321=1135
am335x-boneblack, 100Mbps link
 before: : 162.40, after: 72+93=165

 drivers/net/ethernet/ti/davinci_cpdma.c | 136 +++-
 1 file changed, 62 insertions(+), 74 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c 
b/drivers/net/ethernet/ti/davinci_cpdma.c
index 18bf3a8..03b9882 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.c
+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -21,7 +21,7 @@
 #include 
 #include 
 #include 
-
+#include 
 #include "davinci_cpdma.h"
 
 /* DMA Registers */
@@ -87,9 +87,8 @@ struct cpdma_desc_pool {
void*cpumap;/* dma_alloc map */
int desc_size, mem_size;
int num_desc, used_desc;
-   unsigned long   *bitmap;
struct device   *dev;
-   spinlock_t  lock;
+   struct gen_pool *gen_pool;
 };
 
 enum cpdma_state {
@@ -117,6 +116,7 @@ struct cpdma_chan {
int chan_num;
spinlock_t  lock;
int count;
+   u32 desc_num;
u32 mask;
cpdma_handler_fnhandler;
enum dma_data_direction dir;
@@ -145,6 +145,20 @@ struct cpdma_chan {
 (directed << CPDMA_TO_PORT_SHIFT));\
} while (0)
 
+static void cpdma_desc_pool_destroy(struct cpdma_desc_pool *pool)
+{
+   if (!pool)
+   return;
+
+   WARN_ON(pool->used_desc);
+   if (pool->cpumap) {
+   dma_free_coherent(pool->dev, pool->mem_size, pool->cpumap,
+ pool->phys);
+   } else {
+   iounmap(pool->iomap);
+   }
+}
+
 /*
  * Utility constructs for a cpdma descriptor pool.  Some devices (e.g. davinci
  * emac) have dedicated on-chip memory for these descriptors.  Some other
@@ -155,24 +169,25 @@ static struct cpdma_desc_pool *
 cpdma_desc_pool_create(struct device *dev, u32 phys, dma_addr_t hw_addr,
int size, int align)
 {
-   int bitmap_size;
struct cpdma_desc_pool *pool;
+   int ret;
 
pool = devm_kzalloc(dev, sizeof(*pool), GFP_KERNEL);
if (!pool)
-   goto fail;
-
-   spin_lock_init(&pool->lock);
+   goto gen_pool_create_fail;
 
pool->dev   = dev;
pool->mem_size  = size;
pool->desc_size = ALIGN(sizeof(struct cpdma_desc), align);
pool->num_desc  = size / pool->desc_size;
 
-   bitmap_size  = (pool->num_desc / BITS_PER_LONG) * sizeof(long);
-   pool->bitmap = devm_kzalloc(dev, bitmap_size, GFP_KERNEL);
-   if (!pool->bitmap)
-   goto fail;
+   pool->gen_pool = devm_gen_pool_create(dev, ilog2(pool->desc_size), -1,
+ "cpdma");
+   if (IS_ERR(pool->gen_pool)) {
+   dev_err(dev, "pool create failed %ld\n",
+   PTR_ERR(pool->gen_pool));
+   goto gen_pool_create_fail;
+   }
 
if (phys) {
pool->phys  = phys;
@@ -185,24 +200,22 @@ cpdma_desc_pool_create(struct device *dev, u32 phys, 
dma_addr_t hw_addr,
pool->phys = pool->hw_addr; /* assumes no IOMMU, don't use this 
value */
}
 
-   if (pool->iomap)
-   return pool;
-fail:
-   return NULL;
-}
-
-static void cpdma_desc_pool_destroy(struct cpdma_desc_pool *pool)
-{
-   if (!pool)
-   return;
+   if (!pool->iomap)
+   goto gen_pool_create_fail;
 
-   WARN_ON(pool->used_desc);
-   if (pool->cpumap) {
-   dma_free_coherent(pool->dev, pool->mem_size, pool->cpumap,
- pool->phys);
-   } else {
-   iounmap(pool->iomap);
+   ret = gen_pool_add_virt(pool->gen_pool, (unsigned long)pool->iomap,
+   pool->phys, pool->mem_size, -1);
+   if (ret < 0) {
+   dev_err(dev, "pool

[PATCH v2] net: ethernet: ti: cpdma: switch to use genalloc

2016-06-24 Thread Grygorii Strashko
TI CPDMA currently uses a bitmap for tracking descriptors alloactions
allocations, but The genalloc already handles the same and can be used
as with special memory (SRAM) as with DMA cherent memory chank
(dma_alloc_coherent()). Hence, switch to using genalloc and add
desc_num property for each channel for limitation of max number of
allowed descriptors for each CPDMA channel. This patch do not affect
on net throuput.

Tested-by: Ivan Khoronzhuk  
Signed-off-by: Grygorii Strashko 
---
Testing
TCP window: 256K, bandwidth in Mbits/sec:
 host: iperf -s
 device: iperf -c  172.22.39.17 -t600 -i5 -d -w128K

AM437x-idk, 1Gbps link
 before: : 341.60, after: 232+123=355
am57xx-beagle-x15, 1Gbps link
 before: : 1112.80, after: 814+321=1135
am335x-boneblack, 100Mbps link
 before: : 162.40, after: 72+93=165

changes in v2:
 - reverted change in desc_phys() to keep am3517 which has separate CPPI
   addresses from EMAC and CPU perspective
 - minor format changes.

link on v1:
 https://lkml.org/lkml/2016/6/23/353

 drivers/net/ethernet/ti/davinci_cpdma.c | 132 +++-
 1 file changed, 60 insertions(+), 72 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c 
b/drivers/net/ethernet/ti/davinci_cpdma.c
index 63b3009..b40a402 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.c
+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -21,7 +21,7 @@
 #include 
 #include 
 #include 
-
+#include 
 #include "davinci_cpdma.h"
 
 /* DMA Registers */
@@ -87,9 +87,8 @@ struct cpdma_desc_pool {
void*cpumap;/* dma_alloc map */
int desc_size, mem_size;
int num_desc, used_desc;
-   unsigned long   *bitmap;
struct device   *dev;
-   spinlock_t  lock;
+   struct gen_pool *gen_pool;
 };
 
 enum cpdma_state {
@@ -117,6 +116,7 @@ struct cpdma_chan {
int chan_num;
spinlock_t  lock;
int count;
+   u32 desc_num;
u32 mask;
cpdma_handler_fnhandler;
enum dma_data_direction dir;
@@ -145,6 +145,20 @@ struct cpdma_chan {
 (directed << CPDMA_TO_PORT_SHIFT));\
} while (0)
 
+static void cpdma_desc_pool_destroy(struct cpdma_desc_pool *pool)
+{
+   if (!pool)
+   return;
+
+   WARN_ON(pool->used_desc);
+   if (pool->cpumap) {
+   dma_free_coherent(pool->dev, pool->mem_size, pool->cpumap,
+ pool->phys);
+   } else {
+   iounmap(pool->iomap);
+   }
+}
+
 /*
  * Utility constructs for a cpdma descriptor pool.  Some devices (e.g. davinci
  * emac) have dedicated on-chip memory for these descriptors.  Some other
@@ -155,24 +169,25 @@ static struct cpdma_desc_pool *
 cpdma_desc_pool_create(struct device *dev, u32 phys, dma_addr_t hw_addr,
int size, int align)
 {
-   int bitmap_size;
struct cpdma_desc_pool *pool;
+   int ret;
 
pool = devm_kzalloc(dev, sizeof(*pool), GFP_KERNEL);
if (!pool)
-   goto fail;
-
-   spin_lock_init(&pool->lock);
+   goto gen_pool_create_fail;
 
pool->dev   = dev;
pool->mem_size  = size;
pool->desc_size = ALIGN(sizeof(struct cpdma_desc), align);
pool->num_desc  = size / pool->desc_size;
 
-   bitmap_size  = (pool->num_desc / BITS_PER_LONG) * sizeof(long);
-   pool->bitmap = devm_kzalloc(dev, bitmap_size, GFP_KERNEL);
-   if (!pool->bitmap)
-   goto fail;
+   pool->gen_pool = devm_gen_pool_create(dev, ilog2(pool->desc_size), -1,
+ "cpdma");
+   if (IS_ERR(pool->gen_pool)) {
+   dev_err(dev, "pool create failed %ld\n",
+   PTR_ERR(pool->gen_pool));
+   goto gen_pool_create_fail;
+   }
 
if (phys) {
pool->phys  = phys;
@@ -185,24 +200,22 @@ cpdma_desc_pool_create(struct device *dev, u32 phys, 
dma_addr_t hw_addr,
pool->phys = pool->hw_addr; /* assumes no IOMMU, don't use this 
value */
}
 
-   if (pool->iomap)
-   return pool;
-fail:
-   return NULL;
-}
-
-static void cpdma_desc_pool_destroy(struct cpdma_desc_pool *pool)
-{
-   if (!pool)
-   return;
+   if (!pool->iomap)
+   goto gen_pool_create_fail;
 
-   WARN_ON(pool->used_desc);
-   if (pool->cpumap) {
-   dma_free_coherent(pool->dev, pool->mem_size, pool->cpumap,
- pool->phys);
-   } else {
-   iounmap(pool->iomap

Re: [PATCH] net: ethernet: ti: cpdma: switch to use genalloc

2016-06-24 Thread Grygorii Strashko
On 06/24/2016 07:15 PM, Lennart Sorensen wrote:
> On Fri, Jun 24, 2016 at 11:35:15AM +0530, Mugunthan V N wrote:
 +static void cpdma_desc_pool_destroy(struct cpdma_desc_pool *pool)
 +{
 +if (!pool)
 +return;
 +
 +WARN_ON(pool->used_desc);
 +if (pool->cpumap) {
 +dma_free_coherent(pool->dev, pool->mem_size, pool->cpumap,
 +  pool->phys);
 +} else {
 +iounmap(pool->iomap);
 +}
 +}
 +
>>> single if, brackets?
>>
>> if() has multiple line statement, so brackets are must.
> 
> It is line wrapped, it is still one statement.  And you can't argue the
> else being multiple lines, although the style does require using brackets
> for the else if the if required them.
> 
> Style says "Do not unnecessarily use braces where a single statement will do."
> It says statement, not line.  A multiline wrapped statement is still
> one statement.
> 
> I may personally hate the lack of brackets, but style wise it seems very
> clear that the linux kernel only uses brakcets when required, which is
> only when there is more than one statement.  I prefer what you did,
> but not as much as I prefer consistency.
> 

Oh. nice :( So, seems, I'd need to send v3. Right?
By the way, this code hasn't been introduced by this patch - I've
just moved whole function from one place to another.

-- 
regards,
-grygorii


[PATCH v2 15/15] ARM: dts: am335x/am437x/dra7: use new "ti,cpsw-mdio" compat string

2016-06-24 Thread Grygorii Strashko
Add "ti,cpsw-mdio" for am335x/am437x/dra7 SoCs where MDIO is
implemented as part of TI CPSW and, this way, enable PM runtime auto
suspend for Davinci MDIO driver on these paltforms.

Signed-off-by: Grygorii Strashko 
---
 arch/arm/boot/dts/am33xx.dtsi | 2 +-
 arch/arm/boot/dts/am4372.dtsi | 2 +-
 arch/arm/boot/dts/dra7.dtsi   | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 52be48b..7fa9a1d 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -789,7 +789,7 @@
status = "disabled";
 
davinci_mdio: mdio@4a101000 {
-   compatible = "ti,davinci_mdio";
+   compatible = "ti,cpsw-mdio","ti,davinci_mdio";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "davinci_mdio";
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index 12fcde4..ea76fa7 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -636,7 +636,7 @@
syscon = <&scm_conf>;
 
davinci_mdio: mdio@4a101000 {
-   compatible = "ti,am4372-mdio","ti,davinci_mdio";
+   compatible = 
"ti,am4372-mdio","ti,cpsw-mdio","ti,davinci_mdio";
reg = <0x4a101000 0x100>;
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 3a8f397..8275d2e 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1663,7 +1663,7 @@
status = "disabled";
 
davinci_mdio: mdio@48485000 {
-   compatible = "ti,davinci_mdio";
+   compatible = "ti,cpsw-mdio","ti,davinci_mdio";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "davinci_mdio";
-- 
2.9.0



[PATCH v2 14/15] drivers: net: davinci_mdio: enable pm runtime auto for ti cpsw-mdio

2016-06-24 Thread Grygorii Strashko
Use "ti,cpsw-mdio" to enable PM runtime auto-suspend on supported
platforms, where MDIO is implemented as part of TI CPSW.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/davinci_mdio.c | 45 +-
 1 file changed, 34 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c 
b/drivers/net/ethernet/ti/davinci_mdio.c
index ce3ec42..33df340 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -53,6 +53,10 @@
 
 #define DEF_OUT_FREQ   220 /* 2.2 MHz */
 
+struct davinci_mdio_of_param {
+   int autosuspend_delay_ms;
+};
+
 struct davinci_mdio_regs {
u32 version;
u32 control;
@@ -332,6 +336,19 @@ static int davinci_mdio_probe_dt(struct mdio_platform_data 
*data,
 }
 #endif
 
+#if IS_ENABLED(CONFIG_OF)
+static const struct davinci_mdio_of_param of_cpsw_mdio_data = {
+   .autosuspend_delay_ms = 100,
+};
+
+static const struct of_device_id davinci_mdio_of_mtable[] = {
+   { .compatible = "ti,davinci_mdio", },
+   { .compatible = "ti,cpsw-mdio", .data = &of_cpsw_mdio_data},
+   { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, davinci_mdio_of_mtable);
+#endif
+
 static int davinci_mdio_probe(struct platform_device *pdev)
 {
struct mdio_platform_data *pdata = dev_get_platdata(&pdev->dev);
@@ -340,6 +357,7 @@ static int davinci_mdio_probe(struct platform_device *pdev)
struct resource *res;
struct phy_device *phy;
int ret, addr;
+   int autosuspend_delay_ms = -1;
 
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
@@ -352,9 +370,22 @@ static int davinci_mdio_probe(struct platform_device *pdev)
}
 
if (dev->of_node) {
-   if (davinci_mdio_probe_dt(&data->pdata, pdev))
-   data->pdata = default_pdata;
+   const struct of_device_id   *of_id;
+
+   ret = davinci_mdio_probe_dt(&data->pdata, pdev);
+   if (ret)
+   return ret;
snprintf(data->bus->id, MII_BUS_ID_SIZE, "%s", pdev->name);
+
+   of_id = of_match_device(davinci_mdio_of_mtable, &pdev->dev);
+   if (of_id) {
+   const struct davinci_mdio_of_param *of_mdio_data;
+
+   of_mdio_data = of_id->data;
+   if (of_mdio_data)
+   autosuspend_delay_ms =
+   of_mdio_data->autosuspend_delay_ms;
+   }
} else {
data->pdata = pdata ? (*pdata) : default_pdata;
snprintf(data->bus->id, MII_BUS_ID_SIZE, "%s-%x",
@@ -384,7 +415,7 @@ static int davinci_mdio_probe(struct platform_device *pdev)
 
davinci_mdio_init_clk(data);
 
-   pm_runtime_set_autosuspend_delay(&pdev->dev, -1);
+   pm_runtime_set_autosuspend_delay(&pdev->dev, autosuspend_delay_ms);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_enable(&pdev->dev);
 
@@ -495,14 +526,6 @@ static const struct dev_pm_ops davinci_mdio_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(davinci_mdio_suspend, davinci_mdio_resume)
 };
 
-#if IS_ENABLED(CONFIG_OF)
-static const struct of_device_id davinci_mdio_of_mtable[] = {
-   { .compatible = "ti,davinci_mdio", },
-   { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, davinci_mdio_of_mtable);
-#endif
-
 static struct platform_driver davinci_mdio_driver = {
.driver = {
.name= "davinci_mdio",
-- 
2.9.0



[PATCH v2 13/15] net: davinci_mdio: introduce "ti,cpsw-mdio" compat string

2016-06-24 Thread Grygorii Strashko
Introduce "ti,cpsw-mdio" compatible string for Davinci MDIO, because
it's required to distinguish the case when MDIO is part of TI CPSW to
enable features supported by TI CPSW (for example, enable PM
management).

Signed-off-by: Grygorii Strashko 
---
 Documentation/devicetree/bindings/net/davinci-mdio.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/net/davinci-mdio.txt 
b/Documentation/devicetree/bindings/net/davinci-mdio.txt
index b6a4f48..621156c 100644
--- a/Documentation/devicetree/bindings/net/davinci-mdio.txt
+++ b/Documentation/devicetree/bindings/net/davinci-mdio.txt
@@ -4,6 +4,7 @@ TI SoC Davinci/Keystone2 MDIO Controller Device Tree Bindings
 Required properties:
 - compatible   : Should be "ti,davinci_mdio"
  and "ti,keystone_mdio" for Keystone 2 SoCs
+ and "ti,cpsw-mdio" for am335x, am472x, am57xx/dra7, 
dm814x SoCs
  and "ti,am4372-mdio" for am472x SoC
 - reg  : physical base address and size of the davinci mdio
  registers map
-- 
2.9.0



[PATCH v2 08/15] drivers: net: davinci_mdio: drop suspended and lock fields from mdio_data

2016-06-24 Thread Grygorii Strashko
It's not expected Davinci MDIO to be accessible after its suspend
callbacks have been called:
 - all consumers of Davinci MDIO will stop/disconnect phys at Device
suspend stage;
 - all phys are expected to be suspned already by PHY/MDIO core;
 - MDIO locking is done by MDIO Bus code.

Hence, it's safe to drop "suspended" and "lock" fields from mdio_data.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/davinci_mdio.c | 30 --
 1 file changed, 30 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c 
b/drivers/net/ethernet/ti/davinci_mdio.c
index 291c42e..b6d0059 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -90,11 +90,9 @@ static const struct mdio_platform_data default_pdata = {
 struct davinci_mdio_data {
struct mdio_platform_data pdata;
struct davinci_mdio_regs __iomem *regs;
-   spinlock_t  lock;
struct clk  *clk;
struct device   *dev;
struct mii_bus  *bus;
-   boolsuspended;
unsigned long   access_time; /* jiffies */
/* Indicates that driver shouldn't modify phy_mask in case
 * if MDIO bus is registered from DT.
@@ -225,13 +223,6 @@ static int davinci_mdio_read(struct mii_bus *bus, int 
phy_id, int phy_reg)
if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
return -EINVAL;
 
-   spin_lock(&data->lock);
-
-   if (data->suspended) {
-   spin_unlock(&data->lock);
-   return -ENODEV;
-   }
-
reg = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) |
   (phy_id << 16));
 
@@ -255,8 +246,6 @@ static int davinci_mdio_read(struct mii_bus *bus, int 
phy_id, int phy_reg)
break;
}
 
-   spin_unlock(&data->lock);
-
return ret;
 }
 
@@ -270,13 +259,6 @@ static int davinci_mdio_write(struct mii_bus *bus, int 
phy_id,
if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
return -EINVAL;
 
-   spin_lock(&data->lock);
-
-   if (data->suspended) {
-   spin_unlock(&data->lock);
-   return -ENODEV;
-   }
-
reg = (USERACCESS_GO | USERACCESS_WRITE | (phy_reg << 21) |
   (phy_id << 16) | (phy_data & USERACCESS_DATA));
 
@@ -295,8 +277,6 @@ static int davinci_mdio_write(struct mii_bus *bus, int 
phy_id,
break;
}
 
-   spin_unlock(&data->lock);
-
return 0;
 }
 
@@ -364,7 +344,6 @@ static int davinci_mdio_probe(struct platform_device *pdev)
 
dev_set_drvdata(dev, data);
data->dev = dev;
-   spin_lock_init(&data->lock);
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
data->regs = devm_ioremap_resource(dev, res);
@@ -426,17 +405,12 @@ static int davinci_mdio_suspend(struct device *dev)
struct davinci_mdio_data *data = dev_get_drvdata(dev);
u32 ctrl;
 
-   spin_lock(&data->lock);
-
/* shutdown the scan state machine */
ctrl = __raw_readl(&data->regs->control);
ctrl &= ~CONTROL_ENABLE;
__raw_writel(ctrl, &data->regs->control);
wait_for_idle(data);
 
-   data->suspended = true;
-   spin_unlock(&data->lock);
-
/* Select sleep pin state */
pinctrl_pm_select_sleep_state(dev);
 
@@ -450,13 +424,9 @@ static int davinci_mdio_resume(struct device *dev)
/* Select default pin state */
pinctrl_pm_select_default_state(dev);
 
-   spin_lock(&data->lock);
/* restart the scan state machine */
__davinci_mdio_reset(data);
 
-   data->suspended = false;
-   spin_unlock(&data->lock);
-
return 0;
 }
 #endif
-- 
2.9.0



[PATCH v2 12/15] net: davinci_mdio: document missed "ti,am4372-mdio" compat string

2016-06-24 Thread Grygorii Strashko
Document missed "ti,am4372-mdio" compat string used for TI am437x SoC
(am4372.dtsi).

Signed-off-by: Grygorii Strashko 
---
 Documentation/devicetree/bindings/net/davinci-mdio.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/davinci-mdio.txt 
b/Documentation/devicetree/bindings/net/davinci-mdio.txt
index 0369e25..b6a4f48 100644
--- a/Documentation/devicetree/bindings/net/davinci-mdio.txt
+++ b/Documentation/devicetree/bindings/net/davinci-mdio.txt
@@ -2,7 +2,9 @@ TI SoC Davinci/Keystone2 MDIO Controller Device Tree Bindings
 ---
 
 Required properties:
-- compatible   : Should be "ti,davinci_mdio" or "ti,keystone_mdio"
+- compatible   : Should be "ti,davinci_mdio"
+ and "ti,keystone_mdio" for Keystone 2 SoCs
+ and "ti,am4372-mdio" for am472x SoC
 - reg  : physical base address and size of the davinci mdio
  registers map
 - bus_freq : Mdio Bus frequency
-- 
2.9.0



[PATCH v2 07/15] drivers: net: davinci_mdio: remove pm runtime calls from suspend callbacks

2016-06-24 Thread Grygorii Strashko
PM runtime is disabled when Davinci MDIO .suspend_late() and
.resume_early() callbacks are called. As result, any PM runtime calls here will
be just a nop and can be removed.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/davinci_mdio.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c 
b/drivers/net/ethernet/ti/davinci_mdio.c
index 2e19dd1..291c42e 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -436,7 +436,6 @@ static int davinci_mdio_suspend(struct device *dev)
 
data->suspended = true;
spin_unlock(&data->lock);
-   pm_runtime_put_sync(data->dev);
 
/* Select sleep pin state */
pinctrl_pm_select_sleep_state(dev);
@@ -451,8 +450,6 @@ static int davinci_mdio_resume(struct device *dev)
/* Select default pin state */
pinctrl_pm_select_default_state(dev);
 
-   pm_runtime_get_sync(data->dev);
-
spin_lock(&data->lock);
/* restart the scan state machine */
__davinci_mdio_reset(data);
-- 
2.9.0



[PATCH v2 10/15] drivers: net: davinci_mdio: add pm runtime callbacks

2016-06-24 Thread Grygorii Strashko
Add PM runtime .runtime_suspend()/.runtime_resume() callbacks and
perform Davinci MDIO enabling/disabling from these callbacks. This
allows to reuse pm_runtime_force_suspend/resume() APIs during System
suspend and required for further implementation of PM runtime
autosuspend.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/davinci_mdio.c | 31 +++
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c 
b/drivers/net/ethernet/ti/davinci_mdio.c
index b206fd3..13f5080 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -406,8 +406,8 @@ static int davinci_mdio_remove(struct platform_device *pdev)
return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int davinci_mdio_suspend(struct device *dev)
+#ifdef CONFIG_PM
+static int davinci_mdio_runtime_suspend(struct device *dev)
 {
struct davinci_mdio_data *data = dev_get_drvdata(dev);
u32 ctrl;
@@ -418,6 +418,28 @@ static int davinci_mdio_suspend(struct device *dev)
__raw_writel(ctrl, &data->regs->control);
wait_for_idle(data);
 
+   return 0;
+}
+
+static int davinci_mdio_runtime_resume(struct device *dev)
+{
+   struct davinci_mdio_data *data = dev_get_drvdata(dev);
+
+   davinci_mdio_enable(data);
+   return 0;
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int davinci_mdio_suspend(struct device *dev)
+{
+   struct davinci_mdio_data *data = dev_get_drvdata(dev);
+   int ret = 0;
+
+   ret = pm_runtime_force_suspend(dev);
+   if (ret < 0)
+   return ret;
+
/* Select sleep pin state */
pinctrl_pm_select_sleep_state(dev);
 
@@ -431,14 +453,15 @@ static int davinci_mdio_resume(struct device *dev)
/* Select default pin state */
pinctrl_pm_select_default_state(dev);
 
-   /* restart the scan state machine */
-   davinci_mdio_enable(data);
+   pm_runtime_force_resume(dev);
 
return 0;
 }
 #endif
 
 static const struct dev_pm_ops davinci_mdio_pm_ops = {
+   SET_RUNTIME_PM_OPS(davinci_mdio_runtime_suspend,
+  davinci_mdio_runtime_resume, NULL)
SET_LATE_SYSTEM_SLEEP_PM_OPS(davinci_mdio_suspend, davinci_mdio_resume)
 };
 
-- 
2.9.0



[PATCH v2 06/15] drivers: net: davinci_mdio: do pm runtime initialization later in probe

2016-06-24 Thread Grygorii Strashko
Do PM runtime initialization later in probe - this allows to simplify
error handling a bit.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/davinci_mdio.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c 
b/drivers/net/ethernet/ti/davinci_mdio.c
index 4e7c9b9..2e19dd1 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -356,14 +356,10 @@ static int davinci_mdio_probe(struct platform_device 
*pdev)
data->bus->parent   = dev;
data->bus->priv = data;
 
-   pm_runtime_enable(&pdev->dev);
-   pm_runtime_get_sync(&pdev->dev);
data->clk = devm_clk_get(dev, "fck");
if (IS_ERR(data->clk)) {
dev_err(dev, "failed to get device clock\n");
-   ret = PTR_ERR(data->clk);
-   data->clk = NULL;
-   goto bail_out;
+   return PTR_ERR(data->clk);
}
 
dev_set_drvdata(dev, data);
@@ -372,10 +368,11 @@ static int davinci_mdio_probe(struct platform_device 
*pdev)
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
data->regs = devm_ioremap_resource(dev, res);
-   if (IS_ERR(data->regs)) {
-   ret = PTR_ERR(data->regs);
-   goto bail_out;
-   }
+   if (IS_ERR(data->regs))
+   return PTR_ERR(data->regs);
+
+   pm_runtime_enable(&pdev->dev);
+   pm_runtime_get_sync(&pdev->dev);
 
/* register the mii bus
 * Create PHYs from DT only in case if PHY child nodes are explicitly
-- 
2.9.0



[PATCH v2 04/15] drivers: net: cpsw: ethtool: fix accessing to suspended device

2016-06-24 Thread Grygorii Strashko
The CPSW might be suspended by RPM if all ethX interfaces are down,
but it still could be accesible through ethtool interfce. In this case
ethtool operations, requiring registers access, will cause L3 errors and
CPSW crash.

ethtool callbcaks which need to access CPSW registers now:
.set_coalesce(), .get_ethtool_stats(), .set_pauseparam(), .get_regs()

Hence, fix it by adding .begin()/.complete() ethtool callbacks, which
will be called before/after each ethtool operation runs, and do CPSW
RPM handling in these callbacks. That way CPSW will be active while
handling ethtool requests.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/cpsw.c | 27 ++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index ba81d4e..5fea986 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1907,10 +1907,33 @@ static int cpsw_set_pauseparam(struct net_device *ndev,
priv->tx_pause = pause->tx_pause ? true : false;
 
for_each_slave(priv, _cpsw_adjust_link, priv, &link);
-
return 0;
 }
 
+static int cpsw_ethtool_op_begin(struct net_device *ndev)
+{
+   struct cpsw_priv *priv = netdev_priv(ndev);
+   int ret;
+
+   ret = pm_runtime_get_sync(&priv->pdev->dev);
+   if (ret < 0) {
+   cpsw_err(priv, drv, "ethtool begin failed %d\n", ret);
+   pm_runtime_put_noidle(&priv->pdev->dev);
+   }
+
+   return ret;
+}
+
+static void cpsw_ethtool_op_complete(struct net_device *ndev)
+{
+   struct cpsw_priv *priv = netdev_priv(ndev);
+   int ret;
+
+   ret = pm_runtime_put(&priv->pdev->dev);
+   if (ret < 0)
+   cpsw_err(priv, drv, "ethtool complete failed %d\n", ret);
+}
+
 static const struct ethtool_ops cpsw_ethtool_ops = {
.get_drvinfo= cpsw_get_drvinfo,
.get_msglevel   = cpsw_get_msglevel,
@@ -1930,6 +1953,8 @@ static const struct ethtool_ops cpsw_ethtool_ops = {
.set_wol= cpsw_set_wol,
.get_regs_len   = cpsw_get_regs_len,
.get_regs   = cpsw_get_regs,
+   .begin  = cpsw_ethtool_op_begin,
+   .complete   = cpsw_ethtool_op_complete,
 };
 
 static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv,
-- 
2.9.0



[PATCH v2 05/15] drivers: net: cpsw: ndev: fix accessing to suspended device

2016-06-24 Thread Grygorii Strashko
The CPSW might be suspended by RPM if all ethX interfaces are down,
but it still could be accesible through net_device_ops interfce. In
this case net_device_ops operations requiring registers access will
cause L3 errors and CPSW crash.

Hence, fix it by adding RPM get/put calls in net_device_ops callbacks
which need to access CPSW registers: .ndo_set_mac_address(),
.ndo_vlan_rx_add_vid(), .ndo_vlan_rx_kill_vid().

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/cpsw.c | 33 ++---
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 5fea986..33f9957 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1616,10 +1616,17 @@ static int cpsw_ndo_set_mac_address(struct net_device 
*ndev, void *p)
struct sockaddr *addr = (struct sockaddr *)p;
int flags = 0;
u16 vid = 0;
+   int ret;
 
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
 
+   ret = pm_runtime_get_sync(&priv->pdev->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(&priv->pdev->dev);
+   return ret;
+   }
+
if (priv->data.dual_emac) {
vid = priv->slaves[priv->emac_port].port_vlan;
flags = ALE_VLAN;
@@ -1634,6 +1641,8 @@ static int cpsw_ndo_set_mac_address(struct net_device 
*ndev, void *p)
memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN);
for_each_slave(priv, cpsw_set_slave_mac, priv);
 
+   pm_runtime_put(&priv->pdev->dev);
+
return 0;
 }
 
@@ -1698,10 +1707,17 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device 
*ndev,
__be16 proto, u16 vid)
 {
struct cpsw_priv *priv = netdev_priv(ndev);
+   int ret;
 
if (vid == priv->data.default_vlan)
return 0;
 
+   ret = pm_runtime_get_sync(&priv->pdev->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(&priv->pdev->dev);
+   return ret;
+   }
+
if (priv->data.dual_emac) {
/* In dual EMAC, reserved VLAN id should not be used for
 * creating VLAN interfaces as this can break the dual
@@ -1716,7 +1732,10 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device 
*ndev,
}
 
dev_info(priv->dev, "Adding vlanid %d to vlan filter\n", vid);
-   return cpsw_add_vlan_ale_entry(priv, vid);
+   ret = cpsw_add_vlan_ale_entry(priv, vid);
+
+   pm_runtime_put(&priv->pdev->dev);
+   return ret;
 }
 
 static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev,
@@ -1728,6 +1747,12 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device 
*ndev,
if (vid == priv->data.default_vlan)
return 0;
 
+   ret = pm_runtime_get_sync(&priv->pdev->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(&priv->pdev->dev);
+   return ret;
+   }
+
if (priv->data.dual_emac) {
int i;
 
@@ -1747,8 +1772,10 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device 
*ndev,
if (ret != 0)
return ret;
 
-   return cpsw_ale_del_mcast(priv->ale, priv->ndev->broadcast,
- 0, ALE_VLAN, vid);
+   ret = cpsw_ale_del_mcast(priv->ale, priv->ndev->broadcast,
+0, ALE_VLAN, vid);
+   pm_runtime_put(&priv->pdev->dev);
+   return ret;
 }
 
 static const struct net_device_ops cpsw_netdev_ops = {
-- 
2.9.0



[PATCH v2 11/15] drivers: net: davinci_mdio: implement pm runtime auto mode

2016-06-24 Thread Grygorii Strashko
Davinci MDIO is always used as slave device which services
read/write requests from MDIO/PHY core. It doesn't use IRQ also.

As result, It's possible to relax PM runtime constraints for Davinci
MDIO and enable it on demand, instead of powering it during probe
and powering off during removal.

Hence, implement PM runtime autosuspend for Davinci MDIO, but keep it
disabled by default, because Davinci MDIO is integrated in big set of
TI devices and not all of them expected to work corectly with RPM
 autosuspend enabled:
- expected to work on SoCs where MDIO is part of TI CPSW
(cpsw.c DRA7/am57x, am437x, am335x, dm814x)
- not verified on Keystone 2 and other SoCs where MDIO is used with TI EMAC IP
(davinci_emac.c:  dm6467-emac, am3517-emac, dm816-emac).

Davinci MDIO RPM autosuspend can be enabled through sysfs:
 echo 100 > 
/sys/devices/../48484000.ethernet/48485000.mdio/power/autosuspend_delay_ms

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/davinci_mdio.c | 48 +++---
 1 file changed, 39 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c 
b/drivers/net/ethernet/ti/davinci_mdio.c
index 13f5080..ce3ec42 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -93,6 +93,7 @@ struct davinci_mdio_data {
struct clk  *clk;
struct device   *dev;
struct mii_bus  *bus;
+   boolactive_in_suspend;
unsigned long   access_time; /* jiffies */
/* Indicates that driver shouldn't modify phy_mask in case
 * if MDIO bus is registered from DT.
@@ -141,8 +142,13 @@ static int davinci_mdio_reset(struct mii_bus *bus)
 {
struct davinci_mdio_data *data = bus->priv;
u32 phy_mask, ver;
+   int ret;
 
-   davinci_mdio_enable(data);
+   ret = pm_runtime_get_sync(data->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(data->dev);
+   return ret;
+   }
 
/* wait for scan logic to settle */
msleep(PHY_MAX_ADDR * data->access_time);
@@ -153,7 +159,7 @@ static int davinci_mdio_reset(struct mii_bus *bus)
 (ver >> 8) & 0xff, ver & 0xff);
 
if (data->skip_scan)
-   return 0;
+   goto done;
 
/* get phy mask from the alive register */
phy_mask = __raw_readl(&data->regs->alive);
@@ -168,6 +174,10 @@ static int davinci_mdio_reset(struct mii_bus *bus)
}
data->bus->phy_mask = phy_mask;
 
+done:
+   pm_runtime_mark_last_busy(data->dev);
+   pm_runtime_put_autosuspend(data->dev);
+
return 0;
 }
 
@@ -228,6 +238,12 @@ static int davinci_mdio_read(struct mii_bus *bus, int 
phy_id, int phy_reg)
if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
return -EINVAL;
 
+   ret = pm_runtime_get_sync(data->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(data->dev);
+   return ret;
+   }
+
reg = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) |
   (phy_id << 16));
 
@@ -251,6 +267,8 @@ static int davinci_mdio_read(struct mii_bus *bus, int 
phy_id, int phy_reg)
break;
}
 
+   pm_runtime_mark_last_busy(data->dev);
+   pm_runtime_put_autosuspend(data->dev);
return ret;
 }
 
@@ -264,6 +282,12 @@ static int davinci_mdio_write(struct mii_bus *bus, int 
phy_id,
if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
return -EINVAL;
 
+   ret = pm_runtime_get_sync(data->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(data->dev);
+   return ret;
+   }
+
reg = (USERACCESS_GO | USERACCESS_WRITE | (phy_reg << 21) |
   (phy_id << 16) | (phy_data & USERACCESS_DATA));
 
@@ -282,7 +306,10 @@ static int davinci_mdio_write(struct mii_bus *bus, int 
phy_id,
break;
}
 
-   return 0;
+   pm_runtime_mark_last_busy(data->dev);
+   pm_runtime_put_autosuspend(data->dev);
+
+   return ret;
 }
 
 #if IS_ENABLED(CONFIG_OF)
@@ -357,8 +384,9 @@ static int davinci_mdio_probe(struct platform_device *pdev)
 
davinci_mdio_init_clk(data);
 
+   pm_runtime_set_autosuspend_delay(&pdev->dev, -1);
+   pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_enable(&pdev->dev);
-   pm_runtime_get_sync(&pdev->dev);
 
/* register the mii bus
 * Create PHYs from DT only in case if PHY child nodes are explicitly
@@ -387,9 +415,8 @@ static int davinci_mdio_probe(struct platform_device *pdev)
return 0;
 
 bail_out:
-   pm_runtime_put_sync(&pdev->dev);
+   pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-
return ret;
 

[PATCH v2 09/15] drivers: net: davinci_mdio: split reset function on init_clk and enable

2016-06-24 Thread Grygorii Strashko
The Davinci MDIO MDIO_CONTROL.CLKDIV can be calculated only once
during probe, hence split __davinci_mdio_reset() on
davinci_mdio_init_clk() and davinci_mdio_enable(). Initialize and
save CLKDIV in .probe(). Then just use saved value.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/davinci_mdio.c | 21 ++---
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c 
b/drivers/net/ethernet/ti/davinci_mdio.c
index b6d0059..b206fd3 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -98,9 +98,10 @@ struct davinci_mdio_data {
 * if MDIO bus is registered from DT.
 */
boolskip_scan;
+   u32 clk_div;
 };
 
-static void __davinci_mdio_reset(struct davinci_mdio_data *data)
+static void davinci_mdio_init_clk(struct davinci_mdio_data *data)
 {
u32 mdio_in, div, mdio_out_khz, access_time;
 
@@ -109,9 +110,7 @@ static void __davinci_mdio_reset(struct davinci_mdio_data 
*data)
if (div > CONTROL_MAX_DIV)
div = CONTROL_MAX_DIV;
 
-   /* set enable and clock divider */
-   __raw_writel(div | CONTROL_ENABLE, &data->regs->control);
-
+   data->clk_div = div;
/*
 * One mdio transaction consists of:
 *  32 bits of preamble
@@ -132,12 +131,18 @@ static void __davinci_mdio_reset(struct davinci_mdio_data 
*data)
data->access_time = 1;
 }
 
+static void davinci_mdio_enable(struct davinci_mdio_data *data)
+{
+   /* set enable and clock divider */
+   __raw_writel(data->clk_div | CONTROL_ENABLE, &data->regs->control);
+}
+
 static int davinci_mdio_reset(struct mii_bus *bus)
 {
struct davinci_mdio_data *data = bus->priv;
u32 phy_mask, ver;
 
-   __davinci_mdio_reset(data);
+   davinci_mdio_enable(data);
 
/* wait for scan logic to settle */
msleep(PHY_MAX_ADDR * data->access_time);
@@ -188,7 +193,7 @@ static inline int wait_for_user_access(struct 
davinci_mdio_data *data)
 * operation
 */
dev_warn(data->dev, "resetting idled controller\n");
-   __davinci_mdio_reset(data);
+   davinci_mdio_enable(data);
return -EAGAIN;
}
 
@@ -350,6 +355,8 @@ static int davinci_mdio_probe(struct platform_device *pdev)
if (IS_ERR(data->regs))
return PTR_ERR(data->regs);
 
+   davinci_mdio_init_clk(data);
+
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
 
@@ -425,7 +432,7 @@ static int davinci_mdio_resume(struct device *dev)
pinctrl_pm_select_default_state(dev);
 
/* restart the scan state machine */
-   __davinci_mdio_reset(data);
+   davinci_mdio_enable(data);
 
return 0;
 }
-- 
2.9.0



[PATCH v2 00/15] drivers: net: cpsw: improve runtime pm

2016-06-24 Thread Grygorii Strashko
This series intended to improve runtime PM and allow CPSW to be
RPM suspended when all ethX netdevices are down.

To achieve above goal it is required to relax runtime PM constraints for
Davinci MDIO which blocks CPSW runtime PM now, because Davinci MDIO is always
powered on during probe and powered off only when it's going to be removed.
- Patches 6-11 implement PM runtime autosuspend for Davinci MDIO, but keep it
disabled by default, because Davinci MDIO is integrated in big set of TI devices
and not all of them verified to work correctly with RPM autosuspend enabled:
 expected to work on SoCs where MDIO is defined as part of CPSW in DT
 (cpsw.c DRA7/am57x, am437x, am335x)
The CPSW need to be fixed before RPM suspended can be allowed:
 - Patches 1-5 ensure that CPSW will not cause L3 errors while it is in RPM
   suspended state.

Davinci MDIO RPM autosuspend can be enabled through sysfs:
 echo 100 > 
/sys/devices/../48484000.ethernet/48485000.mdio/power/autosuspend_delay_ms

Patches 12 - 15: introduce new compatible string "ti,cpsw-mdio" which is used
then to enable RPM for am335x/am437x/dra7 SoCs.

Tested on am335x, am437x, am572x and k2g (on k2g with RPM disabled for Davinci 
MDIO)
These changes should not affect on errata i877 implementation on DRA7.

Power measurement on am335x GP EVM:
 Without this series:  547.60 mW total SoC power
 With this series + "ifconfig eth0 down": 477.32 mW Total Soc Power

Changes in v2:
- CPSW ethtool interface updated to use .begin()/.complete() callbacks
- kbuild failure fixed
- davinci_mdio DT updated with proper description of allowed compatible strings
  combinations

Link on v1:
 https://lkml.org/lkml/2016/6/15/362

Grygorii Strashko (15):
  drivers: net: cpsw: fix suspend when all ethX devices are down
  drivers: net: cpsw: check return code from pm runtime calls
  drivers: net: cpsw: remove pm runtime calls from suspend callbacks
  drivers: net: cpsw: ethtool: fix accessing to suspended device
  drivers: net: cpsw: ndev: fix accessing to suspended device
  drivers: net: davinci_mdio: do pm runtime initialization later in probe
  drivers: net: davinci_mdio: remove pm runtime calls from suspend callbacks
  drivers: net: davinci_mdio: drop suspended and lock fields from mdio_data
  drivers: net: davinci_mdio: split reset function on init_clk and enable
  drivers: net: davinci_mdio: add pm runtime callbacks
  drivers: net: davinci_mdio: implement pm runtime auto mode
  net: davinci_mdio: document missed "ti,am4372-mdio" compat string
  net: davinci_mdio: introduce "ti,cpsw-mdio" compat string
  drivers: net: davinci_mdio: enable pm runtime auto for ti cpsw-mdio
  ARM: dts: am335x/am437x/dra7: use new "ti,cpsw-mdio" compat string

 .../devicetree/bindings/net/davinci-mdio.txt   |   5 +-
 arch/arm/boot/dts/am33xx.dtsi  |   2 +-
 arch/arm/boot/dts/am4372.dtsi  |   2 +-
 arch/arm/boot/dts/dra7.dtsi|   2 +-
 drivers/net/ethernet/ti/cpsw.c |  79 --
 drivers/net/ethernet/ti/davinci_mdio.c | 169 +
 6 files changed, 182 insertions(+), 77 deletions(-)

-- 
2.9.0



[PATCH v2 03/15] drivers: net: cpsw: remove pm runtime calls from suspend callbacks

2016-06-24 Thread Grygorii Strashko
PM runtime is properly handled in cpsw_ndo_open/stop(), as result it
isn't required to duplicate these calls in .suspend()/.resume()
callbacks. Moreover, it might cause unnecessary RPM resume of CPSW
during System suspend in the case it's already suspended because
all ethX interfaces are down already, before System suspend started.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/cpsw.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index c76f9db..ba81d4e 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -2573,8 +2573,6 @@ static int cpsw_suspend(struct device *dev)
cpsw_ndo_stop(ndev);
}
 
-   pm_runtime_put_sync(&pdev->dev);
-
/* Select sleep pin state */
pinctrl_pm_select_sleep_state(&pdev->dev);
 
@@ -2587,8 +2585,6 @@ static int cpsw_resume(struct device *dev)
struct net_device   *ndev = platform_get_drvdata(pdev);
struct cpsw_priv*priv = netdev_priv(ndev);
 
-   pm_runtime_get_sync(&pdev->dev);
-
/* Select default pin state */
pinctrl_pm_select_default_state(&pdev->dev);
 
-- 
2.9.0



[PATCH v2 01/15] drivers: net: cpsw: fix suspend when all ethX devices are down

2016-06-24 Thread Grygorii Strashko
The cpsw_suspend() could trigger L3 error and CPSW will stop
functioning if System enters suspend when all ethX net-devices are
down - in this case CPSW could be already suspended by PM runtime, but
cpsw_suspend() will try to call soft_reset_slave() unconditionally
and access CPSW registers.

Hence, fix it by moving soft_reset_slave() from cpsw_suspend() to
cpsw_slave_stop(). This way slave ports will be reset when CPSW is
active and will be in proper state during Suspend.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/cpsw.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index e6bb0ec..736c77a 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1244,6 +1244,7 @@ static void cpsw_slave_stop(struct cpsw_slave *slave, 
struct cpsw_priv *priv)
slave->phy = NULL;
cpsw_ale_control_set(priv->ale, slave_port,
 ALE_PORT_STATE, ALE_PORT_STATE_DISABLE);
+   soft_reset_slave(slave);
 }
 
 static int cpsw_ndo_open(struct net_device *ndev)
@@ -2558,12 +2559,10 @@ static int cpsw_suspend(struct device *dev)
for (i = 0; i < priv->data.slaves; i++) {
if (netif_running(priv->slaves[i].ndev))
cpsw_ndo_stop(priv->slaves[i].ndev);
-   soft_reset_slave(priv->slaves + i);
}
} else {
if (netif_running(ndev))
cpsw_ndo_stop(ndev);
-   for_each_slave(priv, soft_reset_slave);
}
 
pm_runtime_put_sync(&pdev->dev);
-- 
2.9.0



[PATCH v2 02/15] drivers: net: cpsw: check return code from pm runtime calls

2016-06-24 Thread Grygorii Strashko
Add missed check of return code from PM runtime get() calls.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/cpsw.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 736c77a..c76f9db 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1253,7 +1253,11 @@ static int cpsw_ndo_open(struct net_device *ndev)
int i, ret;
u32 reg;
 
-   pm_runtime_get_sync(&priv->pdev->dev);
+   ret = pm_runtime_get_sync(&priv->pdev->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(&priv->pdev->dev);
+   return ret;
+   }
 
if (!cpsw_common_res_usage_state(priv))
cpsw_intr_disable(priv);
@@ -2322,7 +2326,11 @@ static int cpsw_probe(struct platform_device *pdev)
/* Need to enable clocks with runtime PM api to access module
 * registers
 */
-   pm_runtime_get_sync(&pdev->dev);
+   ret = pm_runtime_get_sync(&pdev->dev);
+   if (ret < 0) {
+   pm_runtime_put_noidle(&pdev->dev);
+   goto clean_runtime_disable_ret;
+   }
priv->version = readl(&priv->regs->id_ver);
pm_runtime_put_sync(&pdev->dev);
 
-- 
2.9.0



[PATCH v3] net: ethernet: ti: cpdma: switch to use genalloc

2016-06-27 Thread Grygorii Strashko
TI CPDMA currently uses a bitmap for tracking descriptors alloactions
allocations, but The genalloc already handles the same and can be used
as with special memory (SRAM) as with DMA cherent memory chank
(dma_alloc_coherent()). Hence, switch to using genalloc and add
desc_num property for each channel for limitation of max number of
allowed descriptors for each CPDMA channel. This patch do not affect
on net throuput.

Acked-by: Mugunthan V N 
Tested-by: Ivan Khoronzhuk 
Signed-off-by: Grygorii Strashko 
---
Testing
TCP window: 256K, bandwidth in Mbits/sec:
 host: iperf -s
 device: iperf -c  172.22.39.17 -t600 -i5 -d -w128K

AM437x-idk, 1Gbps link
 before: : 341.60, after: 232+123=355
am57xx-beagle-x15, 1Gbps link
 before: : 1112.80, after: 814+321=1135
am335x-boneblack, 100Mbps link
 before: : 162.40, after: 72+93=165

changes in v3:
 - dropped braces from cpdma_desc_pool_destroy()
 - added 'acked-by' from Mugunthan
changes in v2:
 - reverted change in desc_phys() to keep am3517 which has separate CPPI
   addresses from EMAC and CPU perspective
 - minor format changes.

link on v2:
 http://www.spinics.net/lists/netdev/msg383486.html
link on v1:
 https://lkml.org/lkml/2016/6/23/353

 drivers/net/ethernet/ti/davinci_cpdma.c | 131 ++--
 1 file changed, 59 insertions(+), 72 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c 
b/drivers/net/ethernet/ti/davinci_cpdma.c
index 18bf3a8..73b5fa2 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.c
+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -21,7 +21,7 @@
 #include 
 #include 
 #include 
-
+#include 
 #include "davinci_cpdma.h"
 
 /* DMA Registers */
@@ -87,9 +87,8 @@ struct cpdma_desc_pool {
void*cpumap;/* dma_alloc map */
int desc_size, mem_size;
int num_desc, used_desc;
-   unsigned long   *bitmap;
struct device   *dev;
-   spinlock_t  lock;
+   struct gen_pool *gen_pool;
 };
 
 enum cpdma_state {
@@ -117,6 +116,7 @@ struct cpdma_chan {
int chan_num;
spinlock_t  lock;
int count;
+   u32 desc_num;
u32 mask;
cpdma_handler_fnhandler;
enum dma_data_direction dir;
@@ -145,6 +145,19 @@ struct cpdma_chan {
 (directed << CPDMA_TO_PORT_SHIFT));\
} while (0)
 
+static void cpdma_desc_pool_destroy(struct cpdma_desc_pool *pool)
+{
+   if (!pool)
+   return;
+
+   WARN_ON(pool->used_desc);
+   if (pool->cpumap)
+   dma_free_coherent(pool->dev, pool->mem_size, pool->cpumap,
+ pool->phys);
+   else
+   iounmap(pool->iomap);
+}
+
 /*
  * Utility constructs for a cpdma descriptor pool.  Some devices (e.g. davinci
  * emac) have dedicated on-chip memory for these descriptors.  Some other
@@ -155,24 +168,25 @@ static struct cpdma_desc_pool *
 cpdma_desc_pool_create(struct device *dev, u32 phys, dma_addr_t hw_addr,
int size, int align)
 {
-   int bitmap_size;
struct cpdma_desc_pool *pool;
+   int ret;
 
pool = devm_kzalloc(dev, sizeof(*pool), GFP_KERNEL);
if (!pool)
-   goto fail;
-
-   spin_lock_init(&pool->lock);
+   goto gen_pool_create_fail;
 
pool->dev   = dev;
pool->mem_size  = size;
pool->desc_size = ALIGN(sizeof(struct cpdma_desc), align);
pool->num_desc  = size / pool->desc_size;
 
-   bitmap_size  = (pool->num_desc / BITS_PER_LONG) * sizeof(long);
-   pool->bitmap = devm_kzalloc(dev, bitmap_size, GFP_KERNEL);
-   if (!pool->bitmap)
-   goto fail;
+   pool->gen_pool = devm_gen_pool_create(dev, ilog2(pool->desc_size), -1,
+ "cpdma");
+   if (IS_ERR(pool->gen_pool)) {
+   dev_err(dev, "pool create failed %ld\n",
+   PTR_ERR(pool->gen_pool));
+   goto gen_pool_create_fail;
+   }
 
if (phys) {
pool->phys  = phys;
@@ -185,24 +199,22 @@ cpdma_desc_pool_create(struct device *dev, u32 phys, 
dma_addr_t hw_addr,
pool->phys = pool->hw_addr; /* assumes no IOMMU, don't use this 
value */
}
 
-   if (pool->iomap)
-   return pool;
-fail:
-   return NULL;
-}
+   if (!pool->iomap)
+   goto gen_pool_create_fail;
 
-static void cpdma_desc_pool_destroy(struct cpdma_desc_pool *pool)
-{
-   if (!pool)
-   return;
-
-   WARN_ON(pool->used_desc);
-   if (pool->cpumap) {

Re: [4.1.3-rt8] [report][cpuhotplug] BUG: spinlock bad magic on CPU#0, sh/137

2015-10-13 Thread Grygorii Strashko
On 10/12/2015 11:16 AM, Thomas Gleixner wrote:
> On Fri, 9 Oct 2015, Grygorii Strashko wrote:
>> I can constantly see below error report with 4.1 RT-kernel on TI ARM dra7-evm
>> if I'm trying to unplug cpu1:
>>
>> [   57.737589] CPU1: shutdown
>> [   57.767537] BUG: spinlock bad magic on CPU#0, sh/137
>> [   57.767546]  lock: 0xee994730, .magic: , .owner: /-1, 
>> .owner_cpu: 0
> 
>> It looks like this backtrace was introduces by
>>
>> commit 91df05da13a6c6c358e71182e80f19f3c48d1615
>> net: Use skbufhead with raw lock
>>
>> I see the potential fix for this issue as below:
>>
>> index 4969c0d..f8c23de 100644
>> --- a/net/core/dev.c
>> +++ b/net/core/dev.c
>> @@ -7217,7 +7217,7 @@ static int dev_cpu_callback(struct notifier_block *nfb,
>>  netif_rx_ni(skb);
>>  input_queue_head_incr(oldsd);
>>  }
>> -   while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) {
>> +   while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) {
> 
> Your patch is white space damaged 
> 
>>  netif_rx_ni(skb);
>>  input_queue_head_incr(oldsd);
>>  }
>>
>> input_pkt_queue is per-cpu queue and at this moment cpu is dead already,
>> so no one should touch it. But I'm not sure if my assumption is correct.
> 
> It is. Picking it up for the next release
> 

Thanks & Sorry. I've not expected this diff/hack to be applied as patch :(

-- 
regards,
-grygorii
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] drivers: net: cpsw: use module_platform_driver

2015-10-23 Thread Grygorii Strashko
There is no reasons to probe cpsw from late_initcall level
and it's not recommended. Hence, use module_platform_driver()
to register and probe cpsw driver from module_init() level.

Cc: Tony Lindgren 
Acked-by: Mugunthan V N 
Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/cpsw.c | 12 +---
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 8fc90f1..e35a34d 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -2578,17 +2578,7 @@ static struct platform_driver cpsw_driver = {
.remove = cpsw_remove,
 };
 
-static int __init cpsw_init(void)
-{
-   return platform_driver_register(&cpsw_driver);
-}
-late_initcall(cpsw_init);
-
-static void __exit cpsw_exit(void)
-{
-   platform_driver_unregister(&cpsw_driver);
-}
-module_exit(cpsw_exit);
+module_platform_driver(cpsw_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Cyril Chemparathy ");
-- 
2.6.2

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[4.1.3-rt8] [report][cpuhotplug] BUG: spinlock bad magic on CPU#0, sh/137

2015-10-09 Thread Grygorii Strashko
Hi All,

I can constantly see below error report with 4.1 RT-kernel on TI ARM dra7-evm 
if I'm trying to unplug cpu1:

[   57.737589] CPU1: shutdown
[   57.767537] BUG: spinlock bad magic on CPU#0, sh/137
[   57.767546]  lock: 0xee994730, .magic: , .owner: /-1, 
.owner_cpu: 0
[   57.767552] CPU: 0 PID: 137 Comm: sh Not tainted 
4.1.10-rt8-01700-g2c38702-dirty #55
[   57.767555] Hardware name: Generic DRA74X (Flattened Device Tree)
[   57.767568] [] (unwind_backtrace) from [] 
(show_stack+0x20/0x24)
[   57.767579] [] (show_stack) from [] 
(dump_stack+0x84/0xa0)
[   57.767593] [] (dump_stack) from [] (spin_dump+0x84/0xac)
[   57.767603] [] (spin_dump) from [] (spin_bug+0x34/0x38)
[   57.767614] [] (spin_bug) from [] 
(do_raw_spin_lock+0x168/0x1c0)
[   57.767624] [] (do_raw_spin_lock) from [] 
(_raw_spin_lock+0x4c/0x54)
[   57.767631] [] (_raw_spin_lock) from [] 
(rt_spin_lock_slowlock+0x5c/0x374)
[   57.767638] [] (rt_spin_lock_slowlock) from [] 
(rt_spin_lock+0x38/0x70)
[   57.767649] [] (rt_spin_lock) from [] 
(skb_dequeue+0x28/0x7c)
[   57.767662] [] (skb_dequeue) from [] 
(dev_cpu_callback+0x1b8/0x240)
[   57.767673] [] (dev_cpu_callback) from [] 
(notifier_call_chain+0x3c/0xb4)
[   57.767683] [] (notifier_call_chain) from [] 
(__raw_notifier_call_chain+0x24/0x2c)
[   57.767692] [] (__raw_notifier_call_chain) from [] 
(cpu_notify+0x34/0x50)
[   57.767699] [] (cpu_notify) from [] 
(cpu_notify_nofail+0x18/0x24)
[   57.767707] [] (cpu_notify_nofail) from [] 
(_cpu_down+0x3e8/0x55c)
[   57.767715] [] (_cpu_down) from [] 
(disable_nonboot_cpus+0x118/0x5dc)
[   57.767722] [] (disable_nonboot_cpus) from [] 
(suspend_enter+0x2c4/0xd18)
[   57.767730] [] (suspend_enter) from [] 
(suspend_devices_and_enter+0xe4/0x65c)
[   57.767737] [] (suspend_devices_and_enter) from [] 
(enter_state+0x6c0/0x1050)
[   57.767744] [] (enter_state) from [] 
(pm_suspend+0x24/0x84)
[   57.767751] [] (pm_suspend) from [] 
(state_store+0x74/0xc8)
[   57.767760] [] (state_store) from [] 
(kobj_attr_store+0x1c/0x28)
[   57.767771] [] (kobj_attr_store) from [] 
(sysfs_kf_write+0x5c/0x60)
[   57.767781] [] (sysfs_kf_write) from [] 
(kernfs_fop_write+0xc8/0x1ac)
[   57.767792] [] (kernfs_fop_write) from [] 
(__vfs_write+0x38/0xec)
[   57.767801] [] (__vfs_write) from [] 
(vfs_write+0xa0/0x174)
[   57.767811] [] (vfs_write) from [] (SyS_write+0x54/0xb0)
[   57.767822] [] (SyS_write) from [] 
(ret_fast_syscall+0x0/0x54)
[   57.768224] Powerdomain (l3init_pwrdm) didn't enter target state 1

I'm working with TI RT-kernel:
git://git.ti.com/ti-linux-kernel/ti-linux-kernel.git
branch: ti-rt-linux-4.1.y

It looks like this backtrace was introduces by 

commit 91df05da13a6c6c358e71182e80f19f3c48d1615
Author: Thomas Gleixner 
Date:   Tue Jul 12 15:38:34 2011 +0200

net: Use skbufhead with raw lock


I see the potential fix for this issue as below: 

index 4969c0d..f8c23de 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -7217,7 +7217,7 @@ static int dev_cpu_callback(struct notifier_block *nfb,
netif_rx_ni(skb);
input_queue_head_incr(oldsd);
}
-   while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) {
+   while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) {
netif_rx_ni(skb);
input_queue_head_incr(oldsd);
}

input_pkt_queue is per-cpu queue and at this moment cpu is dead already,
so no one should touch it. But I'm not sure if my assumption is correct.

-- 
regards,
-grygorii
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] net/smsc911x: Fix deferred probe for interrupt

2015-08-31 Thread Grygorii Strashko
On 08/30/2015 12:33 AM, Sergei Shtylyov wrote:
> Hello.
> 
> On 8/28/2015 9:50 PM, Tony Lindgren wrote:
> 
>> The interrupt handler may not be available when smsc911x probes if the
>> interrupt handler is a GPIO controller for example. Let's fix that
>> by adding handling for -EPROBE_DEFER.
> 
>> Cc: Steve Glendinning 
>> Signed-off-by: Tony Lindgren 
>> ---
>>   drivers/net/ethernet/smsc/smsc911x.c | 5 -
>>   1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/ethernet/smsc/smsc911x.c 
>> b/drivers/net/ethernet/smsc/smsc911x.c
>> index 959aeea..cb9f166f 100644
>> --- a/drivers/net/ethernet/smsc/smsc911x.c
>> +++ b/drivers/net/ethernet/smsc/smsc911x.c
>> @@ -2435,7 +2435,10 @@ static int smsc911x_drv_probe(struct 
>> platform_device *pdev)
>>   res_size = resource_size(res);
>>
>>   irq = platform_get_irq(pdev, 0);
>> -if (irq <= 0) {
>> +if (irq == -EPROBE_DEFER) {
>> +retval = -EPROBE_DEFER;
>> +goto out_0;
>> +} else if (irq <= 0) {
>>   pr_warn("Could not allocate irq resource\n");
>>   retval = -ENODEV;
> 
> I'd propagate the error code from platfrom_get_irq() instead (in 
> fact, I've submitted a couple of such patches yesterday and they have 
> been already merged).

Have you paid some attention on current platform_get_irq_() implementation?

The platform_get_irq() can return 0 in case of DT-boot.


-- 
regards,
-grygorii
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [net-next,v2,01/10] soc: ti: K2G: enhancement to support QMSS in NSS

2018-03-28 Thread Grygorii Strashko
Hi Murali,

On 03/27/2018 11:31 AM, Murali Karicheri wrote:
> Navigator Subsystem (NSS) available on K2G SoC has a cut down
> version of QMSS with less number of queues, internal linking ram
> with lesser number of buffers etc.  It doesn't have status and
> explicit push register space as in QMSS available on other K2 SoCs.
> So define reg indices specific to QMSS on K2G. This patch introduces
> "keystone-navigator-qmss-l" compatibility to identify QMSS on
> K2G NSS (QMSS Lite) and to customize the dts handling code. Per
> Device manual, descriptors with index less than or equal to
> regions0_size is in region 0 in the case of QMSS where as for
> QMSS Lite, descriptors with index less than regions0_size is in
> region 0. So update the size accordingly in the regions0_size bits
> of the linking ram size 0 register.
> 
> Signed-off-by: Murali Karicheri 
> Signed-off-by: WingMan Kwok 
> ---
>   .../bindings/soc/ti/keystone-navigator-qmss.txt|  7 ++
>   drivers/soc/ti/knav_qmss.h |  6 ++
>   drivers/soc/ti/knav_qmss_queue.c   | 90 
> --
>   3 files changed, 81 insertions(+), 22 deletions(-)
> 
> diff --git 
> a/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt 
> b/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt
> index 77cd42c..1b0878a 100644
> --- a/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt
> +++ b/Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt
> @@ -18,6 +18,7 @@ pool management.
>   
>   Required properties:
>   - compatible: Must be "ti,keystone-navigator-qmss";
> + : Must be "ti,keystone-navigator-qmss-l" for NSS Lite


I think, It will be more accurate to add K2G specific compat string
like "ti,66ak2g-navss-qm":

compatible = "ti,66ak2g-navss-qm", "ti,keystone-navigator-qmss";

because 66ak2g TRM doesn't mention "Navss light" and this Navss version is used
only in 66ak2g Soc. As result, 66ak2g Navss QM is subset of of keystone 2 Navss 
QM 
which should be defined in DT by adding more specific compat string in addition
to generic one.  


>   - clocks: phandle to the reference clock for this device.
>   - queue-range   :  total range of queue numbers for the 
> device.
>   - linkram0  :  for internal link ram, where size is the total
> @@ -39,6 +40,12 @@ Required properties:
> - Descriptor memory setup region.
> - Queue Management/Queue Proxy region for queue Push.
> - Queue Management/Queue Proxy region for queue Pop.
> +
> +For NSS lite, following QMSS reg indexes are used in that order

For 66AK2G NAVSS QM..

> +   - Queue Peek region.
> +   - Queue configuration region.
> +   - Queue Management/Queue Proxy region for queue 
> Push/Pop.
> +
>   - queue-pools   : child node classifying the queue ranges into pools.
> Queue ranges are grouped into 3 type of pools:
> - qpend   : pool of qpend(interruptible) queues
> diff --git a/drivers/soc/ti/knav_qmss.h b/drivers/soc/ti/knav_qmss.h
> index 905b974..5fa1ce6 100644
> --- a/drivers/soc/ti/knav_qmss.h
> +++ b/drivers/soc/ti/knav_qmss.h
> @@ -292,6 +292,11 @@ struct knav_queue {
>   struct list_headlist;
>   };
>   
> +enum qmss_version {
> + QMSS,
> + QMSS_LITE,

QMSS_66AK2G

> +};
> +
>   struct knav_device {
>   struct device   *dev;
>   unsignedbase_id;
> @@ -305,6 +310,7 @@ struct knav_device {
>   struct list_headpools;
>   struct list_headpdsps;
>   struct list_headqmgrs;
> + enum qmss_version   version;
>   };
>   

[...]

>   }
>   
> +/* Match table for of_platform binding */
> +static const struct of_device_id keystone_qmss_of_match[] = {
> + {
> + .compatible = "ti,keystone-navigator-qmss",

.data   = (void *)QMSS,

> + },
> + {
> + .compatible = "ti,keystone-navigator-qmss-l",
> + .data   = (void *)QMSS_LITE,
> + },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, keystone_qmss_of_match);
> +
>   static int knav_queue_probe(struct platform_device *pdev)
>   {
>   struct device_node *node = pdev->dev.of_node;
>   struct device_node *qmgrs, *queue_pools, *regions, *pdsps;
> + const struct of_device_id *match;
>   struct device *dev = &pdev->dev;
>   u32 temp[2];
>   int ret;
> @@ -1700,6 +1749,10 @@ static int knav_queue_probe(struct platform_device 
> *pdev)
>   return -ENOMEM;
>   }
>   
> + match = of_match_device(of_match_ptr(keystone_qmss_of_match), dev);
> + if (match && match->data)
> + kdev->version = QMSS_LITE;

if (match)
kdev->version = match->d

Re: [PATCH] net: ethernet: ti: cpsw: fix tx vlan priority mapping

2018-04-12 Thread Grygorii Strashko


On 04/12/2018 09:25 AM, Ivan Khoronzhuk wrote:
> The CPDMA_TX_PRIORITY_MAP in real is vlan pcp field priority mapping
> register and basically replaces vlan pcp field for tagged packets.
> So, set it to be 1:1 mapping.

"Otherwise, it will cause unexpected change of egress vlan tagged packets,
 like prio 2 -> prio 5"


> 
> Signed-off-by: Ivan Khoronzhuk 
> ---
> Based on net/master

Fixes: e05 107 e6b 747 ("net: ethernet: ti: cpsw: add multi queue support")

Reviewed-by: Grygorii Strashko  

> 
>   drivers/net/ethernet/ti/cpsw.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
> index 3037127..74f8284 100644
> --- a/drivers/net/ethernet/ti/cpsw.c
> +++ b/drivers/net/ethernet/ti/cpsw.c
> @@ -129,7 +129,7 @@ do {  
> \
>   
>   #define RX_PRIORITY_MAPPING 0x76543210
>   #define TX_PRIORITY_MAPPING 0x33221100
> -#define CPDMA_TX_PRIORITY_MAP0x01234567
> +#define CPDMA_TX_PRIORITY_MAP0x76543210
>   
>   #define CPSW_VLAN_AWARE BIT(1)
>   #define CPSW_RX_VLAN_ENCAP  BIT(2)
> 

-- 
regards,
-grygorii


Re: [PATCH 35/61] net: ethernet: ti: simplify getting .drvdata

2018-04-19 Thread Grygorii Strashko



On 04/19/2018 09:06 AM, Wolfram Sang wrote:

We should get drvdata from struct device directly. Going via
platform_device is an unneeded step back and forth.

Signed-off-by: Wolfram Sang 
---

Build tested only. buildbot is happy. Please apply individually.


Reviewed-by: Grygorii Strashko 

--
regards,
-grygorii


Re: regression: ti: cpsw: warning from phy_connect()->sysfs_create_link()-sysfs_warn_dup()

2018-03-14 Thread Grygorii Strashko


On 02/26/2018 02:16 PM, Florian Fainelli wrote:
> On 02/26/2018 12:08 PM, Grygorii Strashko wrote:
>> Hi Florian,
>>
>> The TI CPSW driver produces warning as below when booted in switch mode:
>> [8.882295] sysfs: cannot create duplicate filename 
>> '/devices/platform/4400.ocp/48484000.ethernet/net/eth0/phydev'
>> [8.999859] CPU: 1 PID: 356 Comm: systemd-network Not tainted 
>> 4.16.0-rc3-00010-g6cc3ff6-dirty #225
>> ...
>> [9.012352] Hardware name: Generic DRA74X (Flattened Device Tree)
>> [9.018901] Backtrace:
>> [9.021376] [] (dump_backtrace) from [] 
>> (show_stack+0x18/0x1c)
>> [9.028986]  r7:ed036240 r6:60070013 r5: r4:c0d598a0
>> [9.034684] [] (show_stack) from [] 
>> (dump_stack+0x8c/0xa0)
>> [9.041954] [] (dump_stack) from [] 
>> (sysfs_warn_dup+0x60/0x6c)
>> [9.049564]  r7:ed036240 r6:ed036240 r5:c0b579bc r4:ed10c000
>> [9.055264] [] (sysfs_warn_dup) from [] 
>> (sysfs_do_create_link_sd+0xbc/0xc4)
>> [9.064006]  r7:ed036240 r6:ffef r5: r4:ed034660
>> [9.069701] [] (sysfs_do_create_link_sd) from [] 
>> (sysfs_create_link+0x30/0x3c)
>> [9.078706]  r9:0008 r8: r7:ed02f008 r6:ee015ae8 r5:ee015800 
>> r4:ed02f000
>> [9.086497] [] (sysfs_create_link) from [] 
>> (phy_attach_direct+0x180/0x1f4)
>> [9.095163] [] (phy_attach_direct) from [] 
>> (phy_connect_direct+0x1c/0x54)
>> [9.103735]  r10:0001 r9:ee015d0c r8:0008 r7:c062e84c r6:c062e84c 
>> r5:ed02f000
>> [9.111609]  r4:ed02f000 r3:0008
>> [9.115217] [] (phy_connect_direct) from [] 
>> (phy_connect+0x4c/0x80)
>> [9.123270]  r7:c062e84c r6:ee015800 r5:ed02f000 r4:ee693664
>> [9.128969] [] (phy_connect) from [] 
>> (cpsw_slave_open+0x21c/0x274)
>> [9.136926]  r9:ee015d0c r8:ee015d00 r7:ed018a10 r6:ee015800 r5:ee015d00 
>> r4:ed032630
>> [9.144715] [] (cpsw_slave_open) from [] 
>> (cpsw_ndo_open+0x158/0x55c)
>> [9.152860]  r10:0001 r9: r8:ee015d00 r7:c0d04c48 r6:ee015800 
>> r5:ed018a10
>> [9.160730]  r4:ed032630
>> [9.163291] [] (cpsw_ndo_open) from [] 
>> (__dev_open+0xd4/0x158)
>> [9.170900]  r10: r9:ec885db4 r8:ee01582c r7:c09a9c00 r6: 
>> r5:c0d04c48
>> [9.178768]  r4:ee015800
>> [9.181326] [] (__dev_open) from [] 
>> (__dev_change_flags+0x174/0x1c0)
>>
>> The reason of the warning is that in switch mode CPSW drivers is connecting 
>> two Net PHYs to
>> a single network device (it has been done this way when driver was initially 
>> introduced), so
>> now it produces warning during boot because of commits:
>>
>> 5568363f0cb3 ("net: phy: Create sysfs reciprocal links for 
>> attached_dev/phydev"
>> a3995460491d ("net: phy: Relax error checking on sysfs_create_link()"
>> ^ both went in v4.13
>>
>> Honestly, I'm not sure how to fix it the best way (the simplest fix is 
>> below), taking into account
>> that we are not ready to do big reworks in CPSW driver.

I've got additional testing data and this actually a *regression*, because 
second CPSW Port became broken after above commits due to Net PHY 
connection failure.

> 
> The CPSW driver is duplicating a fair amount of what the DSA subsystem
> does properly without breaking any assumptions about the 1:1 mapping
> that can exist between a network device and PHY device. Having a PHY
> device without a network device is fine in premise, although discouraged.
> 
> Migrating to DSA is certainly a big task, but I would strongly encourage
> you to consider doing it, since that would solve this problem, and
> probably many more.

We are actively investigating possibility to use DSA for this driver,
but unfortunately this is looks very problematic, because this is old driver 
with
stable ABI and stable device tree binding which are also ABI. 
So, this driver can't be simply migrating to use DSA and as possible solution
new driver can be introduced in long term perspective which will
follow DSA binding requirements and reuse as max as possible code
of the current CPSW driver. Even in this case, old driver
will need to be supported during some transition period and *be functional*.

For now I'd be very appreciated if functionality of current TI CPSW driver will 
be
restored and propose to consider below fix, which will make it work again:

=
>From 5f67320d985a533da785e3643e5e63ba7395b4ae Mon Sep 17 00:00:00 2001
From: Grygorii Strashko 
Date: Wed, 14 Mar 2018 14:01:12 -0500
Subject: [PATCH] net: phy: skip error checking when creating s

Re: regression: ti: cpsw: warning from phy_connect()->sysfs_create_link()-sysfs_warn_dup()

2018-03-14 Thread Grygorii Strashko


On 03/14/2018 02:50 PM, Florian Fainelli wrote:
> On 03/14/2018 12:40 PM, Grygorii Strashko wrote:
>>
>>
>> On 02/26/2018 02:16 PM, Florian Fainelli wrote:
>>> On 02/26/2018 12:08 PM, Grygorii Strashko wrote:
>>>> Hi Florian,
>>>>
>>>> The TI CPSW driver produces warning as below when booted in switch mode:
>>>> [8.882295] sysfs: cannot create duplicate filename 
>>>> '/devices/platform/4400.ocp/48484000.ethernet/net/eth0/phydev'
>>>> [8.999859] CPU: 1 PID: 356 Comm: systemd-network Not tainted 
>>>> 4.16.0-rc3-00010-g6cc3ff6-dirty #225
>>>> ...
>>>> [9.012352] Hardware name: Generic DRA74X (Flattened Device Tree)
>>>> [9.018901] Backtrace:
>>>> [9.021376] [] (dump_backtrace) from [] 
>>>> (show_stack+0x18/0x1c)
>>>> [9.028986]  r7:ed036240 r6:60070013 r5: r4:c0d598a0
>>>> [9.034684] [] (show_stack) from [] 
>>>> (dump_stack+0x8c/0xa0)
>>>> [9.041954] [] (dump_stack) from [] 
>>>> (sysfs_warn_dup+0x60/0x6c)
>>>> [9.049564]  r7:ed036240 r6:ed036240 r5:c0b579bc r4:ed10c000
>>>> [9.055264] [] (sysfs_warn_dup) from [] 
>>>> (sysfs_do_create_link_sd+0xbc/0xc4)
>>>> [9.064006]  r7:ed036240 r6:ffef r5: r4:ed034660
>>>> [9.069701] [] (sysfs_do_create_link_sd) from [] 
>>>> (sysfs_create_link+0x30/0x3c)
>>>> [9.078706]  r9:0008 r8: r7:ed02f008 r6:ee015ae8 
>>>> r5:ee015800 r4:ed02f000
>>>> [9.086497] [] (sysfs_create_link) from [] 
>>>> (phy_attach_direct+0x180/0x1f4)
>>>> [9.095163] [] (phy_attach_direct) from [] 
>>>> (phy_connect_direct+0x1c/0x54)
>>>> [9.103735]  r10:0001 r9:ee015d0c r8:0008 r7:c062e84c 
>>>> r6:c062e84c r5:ed02f000
>>>> [9.111609]  r4:ed02f000 r3:0008
>>>> [9.115217] [] (phy_connect_direct) from [] 
>>>> (phy_connect+0x4c/0x80)
>>>> [9.123270]  r7:c062e84c r6:ee015800 r5:ed02f000 r4:ee693664
>>>> [9.128969] [] (phy_connect) from [] 
>>>> (cpsw_slave_open+0x21c/0x274)
>>>> [9.136926]  r9:ee015d0c r8:ee015d00 r7:ed018a10 r6:ee015800 
>>>> r5:ee015d00 r4:ed032630
>>>> [9.144715] [] (cpsw_slave_open) from [] 
>>>> (cpsw_ndo_open+0x158/0x55c)
>>>> [9.152860]  r10:0001 r9: r8:ee015d00 r7:c0d04c48 
>>>> r6:ee015800 r5:ed018a10
>>>> [9.160730]  r4:ed032630
>>>> [9.163291] [] (cpsw_ndo_open) from [] 
>>>> (__dev_open+0xd4/0x158)
>>>> [9.170900]  r10: r9:ec885db4 r8:ee01582c r7:c09a9c00 
>>>> r6: r5:c0d04c48
>>>> [9.178768]  r4:ee015800
>>>> [9.181326] [] (__dev_open) from [] 
>>>> (__dev_change_flags+0x174/0x1c0)
>>>>
>>>> The reason of the warning is that in switch mode CPSW drivers is 
>>>> connecting two Net PHYs to
>>>> a single network device (it has been done this way when driver was 
>>>> initially introduced), so
>>>> now it produces warning during boot because of commits:
>>>>
>>>> 5568363f0cb3 ("net: phy: Create sysfs reciprocal links for 
>>>> attached_dev/phydev"
>>>> a3995460491d ("net: phy: Relax error checking on sysfs_create_link()"
>>>> ^ both went in v4.13
>>>>
>>>> Honestly, I'm not sure how to fix it the best way (the simplest fix is 
>>>> below), taking into account
>>>> that we are not ready to do big reworks in CPSW driver.
>>
>> I've got additional testing data and this actually a *regression*, because
>> second CPSW Port became broken after above commits due to Net PHY
>> connection failure.
>>
>>>
>>> The CPSW driver is duplicating a fair amount of what the DSA subsystem
>>> does properly without breaking any assumptions about the 1:1 mapping
>>> that can exist between a network device and PHY device. Having a PHY
>>> device without a network device is fine in premise, although discouraged.
>>>
>>> Migrating to DSA is certainly a big task, but I would strongly encourage
>>> you to consider doing it, since that would solve this problem, and
>>> probably many more.
>>
>> We are actively investigating possibility to use DSA for this driver,
>> but unfortunately this is looks very problemati

[PATCH 0/2] net: phy: relax error checking when creating sysfs link netdev->phydev

2018-03-14 Thread Grygorii Strashko
Some ethernet drivers (like TI CPSW) may connect and manage >1 Net PHYs per
one netdevice, as result such drivers will produce warning during system
boot and fail to connect second phy to netdevice when PHYLIB framework
will try to create sysfs link netdev->phydev for second PHY
in phy_attach_direct(), because sysfs link with the same name has been
created already for the first PHY.
As result, second CPSW external port will became unusable.
This issue was introduced by commits:
5568363f0cb3 ("net: phy: Create sysfs reciprocal links for attached_dev/phydev"
a3995460491d ("net: phy: Relax error checking on sysfs_create_link()"

Patch 1: exports sysfs_create_link_nowarn() function as preparation for Patch 2.
Patch 2: relaxes error checking when PHYLIB framework is creating sysfs
link netdev->phydev in phy_attach_direct(), suppress warning by using
sysfs_create_link_nowarn() and adds debug message instead.

This is stable material 4.13+.

Cc: Florian Fainelli 
Grygorii Strashko (2):
  sysfs: symlink: export sysfs_create_link_nowarn()
  net: phy: relax error checking when creating sysfs link netdev->phydev

 drivers/net/phy/phy_device.c | 15 +++
 fs/sysfs/symlink.c   |  1 +
 2 files changed, 12 insertions(+), 4 deletions(-)

-- 
2.10.5



[PATCH 1/2] sysfs: symlink: export sysfs_create_link_nowarn()

2018-03-14 Thread Grygorii Strashko
The sysfs_create_link_nowarn() is going to be used in phylib framework in
suseuent patch which can be built as module. Hence, export
sysfs_create_link_nowarn() to avoid build errors.

Cc: Florian Fainelli 
Fixes: a3995460491d ("net: phy: Relax error checking on sysfs_create_link()")
Signed-off-by: Grygorii Strashko 
---
"Fixes" added as there is dependency this and subsequent patch.
 fs/sysfs/symlink.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index 8664db2..215c225 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -106,6 +106,7 @@ int sysfs_create_link_nowarn(struct kobject *kobj, struct 
kobject *target,
 {
return sysfs_do_create_link(kobj, target, name, 0);
 }
+EXPORT_SYMBOL_GPL(sysfs_create_link_nowarn);
 
 /**
  * sysfs_delete_link - remove symlink in object's directory.
-- 
2.10.5



[PATCH 2/2] net: phy: relax error checking when creating sysfs link netdev->phydev

2018-03-14 Thread Grygorii Strashko
Some ethernet drivers (like TI CPSW) may connect and manage >1 Net PHYs per
one netdevice, as result such drivers will produce warning during system
boot and fail to connect second phy to netdevice when PHYLIB framework
will try to create sysfs link netdev->phydev for second PHY
in phy_attach_direct(), because sysfs link with the same name has been
created already for the first PHY. As result, second CPSW external
port will became unusable.

Fix it by relaxing error checking when PHYLIB framework is creating sysfs
link netdev->phydev in phy_attach_direct(), suppressing warning by using
sysfs_create_link_nowarn() and adding debug message instead.

Cc: Florian Fainelli 
Fixes: a3995460491d ("net: phy: Relax error checking on sysfs_create_link()")
Signed-off-by: Grygorii Strashko 
---
 drivers/net/phy/phy_device.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 478405e..fe16f58 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1012,10 +1012,17 @@ int phy_attach_direct(struct net_device *dev, struct 
phy_device *phydev,
err = sysfs_create_link(&phydev->mdio.dev.kobj, &dev->dev.kobj,
"attached_dev");
if (!err) {
-   err = sysfs_create_link(&dev->dev.kobj, &phydev->mdio.dev.kobj,
-   "phydev");
-   if (err)
-   goto error;
+   err = sysfs_create_link_nowarn(&dev->dev.kobj,
+  &phydev->mdio.dev.kobj,
+  "phydev");
+   if (err) {
+   dev_err(&dev->dev, "could not add device link to %s err 
%d\n",
+   kobject_name(&phydev->mdio.dev.kobj),
+   err);
+   /* non-fatal - some net drivers can use one netdevice
+* with more then one phy
+*/
+   }
 
phydev->sysfs_links = true;
}
-- 
2.10.5



Re: [PATCH 2/2] net: phy: relax error checking when creating sysfs link netdev->phydev

2018-03-15 Thread Grygorii Strashko


On 03/14/2018 09:26 PM, Greg Kroah-Hartman wrote:
> On Wed, Mar 14, 2018 at 05:26:24PM -0500, Grygorii Strashko wrote:
>> Some ethernet drivers (like TI CPSW) may connect and manage >1 Net PHYs per
>> one netdevice, as result such drivers will produce warning during system
>> boot and fail to connect second phy to netdevice when PHYLIB framework
>> will try to create sysfs link netdev->phydev for second PHY
>> in phy_attach_direct(), because sysfs link with the same name has been
>> created already for the first PHY. As result, second CPSW external
>> port will became unusable.
>>
>> Fix it by relaxing error checking when PHYLIB framework is creating sysfs
>> link netdev->phydev in phy_attach_direct(), suppressing warning by using
>> sysfs_create_link_nowarn() and adding debug message instead.
>>
>> Cc: Florian Fainelli 
>> Fixes: a3995460491d ("net: phy: Relax error checking on sysfs_create_link()")
>> Signed-off-by: Grygorii Strashko 
>> ---
>>   drivers/net/phy/phy_device.c | 15 +++
>>   1 file changed, 11 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
>> index 478405e..fe16f58 100644
>> --- a/drivers/net/phy/phy_device.c
>> +++ b/drivers/net/phy/phy_device.c
>> @@ -1012,10 +1012,17 @@ int phy_attach_direct(struct net_device *dev, struct 
>> phy_device *phydev,
>>  err = sysfs_create_link(&phydev->mdio.dev.kobj, &dev->dev.kobj,
>>  "attached_dev");
>>  if (!err) {
>> -err = sysfs_create_link(&dev->dev.kobj, &phydev->mdio.dev.kobj,
>> -"phydev");
>> -if (err)
>> -goto error;
>> +err = sysfs_create_link_nowarn(&dev->dev.kobj,
>> +   &phydev->mdio.dev.kobj,
>> +   "phydev");
>> +if (err) {
>> +dev_err(&dev->dev, "could not add device link to %s err 
>> %d\n",
>> +kobject_name(&phydev->mdio.dev.kobj),
>> +err);
> 
> dev_err() is not a "debugging" message :)

Sry for the mess. I've originally did it as dev_dbg() after searching for
other occurrences of sysfs_create_link_nowarn() in kernel.
And honestly, I was unsure what to use dbg or err here.

> 
> What is a user going to do with this new error?  If it's not important
> at all, why care about it?

Now I think that dev_err() is better to use here:
1) It will notify about link creation error in other drivers (which is
still not critical as networking functionality will not be broken and device
will be able to boot (in case of NFS usage for example).
2) in case of TI CPSW driver we can live with this error message and
it will stimulate us (or any other user of this driver) to find time and
do fix/rework TI CPSW driver.

> 
>> +/* non-fatal - some net drivers can use one netdevice
>> + * with more then one phy
>> + */
> 
> What about devices that do not have more than one phy and this call
> fails for?  Shouldn't you check for that?

As I mentioned before, this is not critical error. More over, as per code and
commit a3995460491d ("net: phy: Relax error checking on sysfs_create_link()")
- the error of creating link phydev->netdev already ignored in PHYLIB due to
"incorrect" initialization sequence of some network drivers.

if no objection i will repost after fixing commit messages. 

-- 
regards,
-grygorii


Re: [PATCH v2] net: ethernet: ti: cpsw: add check for in-band mode setting with RGMII PHY interface

2018-03-15 Thread Grygorii Strashko



On 03/15/2018 11:56 AM, SZ Lin (林上智) wrote:

According to AM335x TRM[1] 14.3.6.2, AM437x TRM[2] 15.3.6.2 and
DRA7 TRM[3] 24.11.4.8.7.3.3, in-band mode in EXT_EN(bit18) register is only
available when PHY is configured in RGMII mode with 10Mbps speed. It will
cause some networking issues without RGMII mode, such as carrier sense
errors and low throughput. TI also mentioned this issue in their forum[4].

This patch adds the check mechanism for PHY interface with RGMII interface
type, the in-band mode can only be set in RGMII mode with 10Mbps speed.

References:
[1]: https://www.ti.com/lit/ug/spruh73p/spruh73p.pdf
[2]: http://www.ti.com/lit/ug/spruhl7h/spruhl7h.pdf
[3]: http://www.ti.com/lit/ug/spruic2b/spruic2b.pdf
[4]: https://e2e.ti.com/support/arm/sitara_arm/f/791/p/640765/2392155

Suggested-by: Holsety Chen (陳憲輝) 
Signed-off-by: SZ Lin (林上智) 
Signed-off-by: Schuyler Patton 
---
Changes from v1:
- Use phy_interface_is_rgmii helper function
- Remove blank line



Reviewed-by: Grygorii Strashko 


  drivers/net/ethernet/ti/cpsw.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 1b1b78fdc138..b2b30c9df037 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -1014,7 +1014,8 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave,
/* set speed_in input in case RMII mode is used in 100Mbps */
if (phy->speed == 100)
mac_control |= BIT(15);
-   else if (phy->speed == 10)
+   /* in band mode only works in 10Mbps RGMII mode */
+   else if ((phy->speed == 10) && phy_interface_is_rgmii(phy))
mac_control |= BIT(18); /* In Band mode */
  
  		if (priv->rx_pause)




--
regards,
-grygorii


Re: [PATCH v2] net: ethernet: ti: cpsw: add check for in-band mode setting with RGMII PHY interface

2018-03-15 Thread Grygorii Strashko



On 03/15/2018 12:39 PM, Grygorii Strashko wrote:



On 03/15/2018 11:56 AM, SZ Lin (林上智) wrote:

According to AM335x TRM[1] 14.3.6.2, AM437x TRM[2] 15.3.6.2 and
DRA7 TRM[3] 24.11.4.8.7.3.3, in-band mode in EXT_EN(bit18) register is 
only

available when PHY is configured in RGMII mode with 10Mbps speed. It will
cause some networking issues without RGMII mode, such as carrier sense
errors and low throughput. TI also mentioned this issue in their 
forum[4].


This patch adds the check mechanism for PHY interface with RGMII 
interface

type, the in-band mode can only be set in RGMII mode with 10Mbps speed.

References:
[1]: https://www.ti.com/lit/ug/spruh73p/spruh73p.pdf
[2]: http://www.ti.com/lit/ug/spruhl7h/spruhl7h.pdf
[3]: http://www.ti.com/lit/ug/spruic2b/spruic2b.pdf
[4]: https://e2e.ti.com/support/arm/sitara_arm/f/791/p/640765/2392155

Suggested-by: Holsety Chen (陳憲輝) 
Signed-off-by: SZ Lin (林上智) 
Signed-off-by: Schuyler Patton 
---
Changes from v1:
- Use phy_interface_is_rgmii helper function
- Remove blank line



Reviewed-by: Grygorii Strashko 



Also could this be marked as stable material 4.9+?

--
regards,
-grygorii


Re: [PATCH v2] net: ethernet: ti: cpsw: add check for in-band mode setting with RGMII PHY interface

2018-03-15 Thread Grygorii Strashko


On 03/15/2018 01:29 PM, Florian Fainelli wrote:
> On 03/15/2018 11:18 AM, Grygorii Strashko wrote:
>>
>>
>> On 03/15/2018 12:39 PM, Grygorii Strashko wrote:
>>>
>>>
>>> On 03/15/2018 11:56 AM, SZ Lin (林上智) wrote:
>>>> According to AM335x TRM[1] 14.3.6.2, AM437x TRM[2] 15.3.6.2 and
>>>> DRA7 TRM[3] 24.11.4.8.7.3.3, in-band mode in EXT_EN(bit18) register
>>>> is only
>>>> available when PHY is configured in RGMII mode with 10Mbps speed. It
>>>> will
>>>> cause some networking issues without RGMII mode, such as carrier sense
>>>> errors and low throughput. TI also mentioned this issue in their
>>>> forum[4].
>>>>
>>>> This patch adds the check mechanism for PHY interface with RGMII
>>>> interface
>>>> type, the in-band mode can only be set in RGMII mode with 10Mbps speed.
>>>>
>>>> References:
>>>> [1]: https://www.ti.com/lit/ug/spruh73p/spruh73p.pdf
>>>> [2]: http://www.ti.com/lit/ug/spruhl7h/spruhl7h.pdf
>>>> [3]: http://www.ti.com/lit/ug/spruic2b/spruic2b.pdf
>>>> [4]: https://e2e.ti.com/support/arm/sitara_arm/f/791/p/640765/2392155
>>>>
>>>> Suggested-by: Holsety Chen (陳憲輝) 
>>>> Signed-off-by: SZ Lin (林上智) 
>>>> Signed-off-by: Schuyler Patton 
>>>> ---
>>>> Changes from v1:
>>>> - Use phy_interface_is_rgmii helper function
>>>> - Remove blank line
>>>>
>>>
>>> Reviewed-by: Grygorii Strashko 
>>>
>>
>> Also could this be marked as stable material 4.9+?
> 
> This is not how it works for networking changes, just make sure you
> provide a "Fixes:" tag, and David would usually take care of queueing
> the change to -stable accordingly:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/netdev-FAQ.txt#n148
> 

Sry, I know that, but this patch fixes very old commit [1] and it can't be
applied to old Kernels without merge conflicts or build errors:(, 
so I've manually checked if it can be applied to most recent stable kernels
and noted kernel versions here.
Also there is dependency from phy_interface_is_rgmii() which was merged in v4.2.

[1] commit a81d8762d713 ("drivers: net cpsw: Enable In Band mode in cpsw for 10 
mbps")
^ went in v3.13
-- 
regards,
-grygorii


[PATCH net-next] net: ethernet: ti: cpsw: enable vlan rx vlan offload

2018-03-15 Thread Grygorii Strashko
In VLAN_AWARE mode CPSW can insert VLAN header encapsulation word on Host
port 0 egress (RX) before the packet data if RX_VLAN_ENCAP bit is set in
CPSW_CONTROL register. VLAN header encapsulation word has following format:

 HDR_PKT_Priority bits 29-31 - Header Packet VLAN prio (Highest prio: 7)
 HDR_PKT_CFI  bits 28 - Header Packet VLAN CFI bit.
 HDR_PKT_Vid  bits 27-16 - Header Packet VLAN ID
 PKT_Type bits 8-9 - Packet Type. Indicates whether the packet is
VLAN-tagged, priority-tagged, or non-tagged.
00: VLAN-tagged packet
01: Reserved
10: Priority-tagged packet
11: Non-tagged packet

This feature can be used to implement TX VLAN offload in case of
VLAN-tagged packets and to insert VLAN tag in case Non-tagged packet was
received on port with PVID set. As per documentation, CPSW never modifies
packet data on Host egress (RX) and as result, without this feature
enabled, Host port will not be able to receive properly packets which
entered switch non-tagged through external Port with PVID set (when
non-tagged packet forwarded from external Port with PVID set to another
external Port - packet will be VLAN tagged properly).

Implementation details:
- on RX driver will check CPDMA status bit RX_VLAN_ENCAP BIT(19) in CPPI
descriptor to identify when VLAN header encapsulation word is present.
- PKT_Type = 0x01 or 0x02 then ignore VLAN header encapsulation word and
pass packet as is;
- if HDR_PKT_Vid = 0 then ignore VLAN header encapsulation word and pass
packet as is;
- In dual mac mode traffic is separated between ports using default port
vlans, which are not be visible to Host and so should not be reported.
Hence, check for default port vlans in dual mac mode and ignore VLAN header
encapsulation word;
- otherwise fill SKB with VLAN info using __vlan_hwaccel_put_tag();
- PKT_Type = 0x00 (VLAN-tagged) then strip out VLAN header from SKB.

Signed-off-by: Grygorii Strashko 
---
 drivers/net/ethernet/ti/cpsw.c  | 67 +++--
 drivers/net/ethernet/ti/davinci_cpdma.c |  2 +-
 drivers/net/ethernet/ti/davinci_cpdma.h |  2 +
 3 files changed, 67 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 1b1b78f..8af8891 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -120,14 +120,18 @@ do {  
\
 #define CPDMA_RXCP 0x60
 
 #define CPSW_POLL_WEIGHT   64
+#define CPSW_RX_VLAN_ENCAP_HDR_SIZE4
 #define CPSW_MIN_PACKET_SIZE   (VLAN_ETH_ZLEN)
-#define CPSW_MAX_PACKET_SIZE   (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)
+#define CPSW_MAX_PACKET_SIZE   (VLAN_ETH_FRAME_LEN +\
+ETH_FCS_LEN +\
+CPSW_RX_VLAN_ENCAP_HDR_SIZE)
 
 #define RX_PRIORITY_MAPPING0x76543210
 #define TX_PRIORITY_MAPPING0x33221100
 #define CPDMA_TX_PRIORITY_MAP  0x01234567
 
 #define CPSW_VLAN_AWAREBIT(1)
+#define CPSW_RX_VLAN_ENCAP BIT(2)
 #define CPSW_ALE_VLAN_AWARE1
 
 #define CPSW_FIFO_NORMAL_MODE  (0 << 16)
@@ -148,6 +152,18 @@ do {   
\
 #define CPSW_MAX_QUEUES8
 #define CPSW_CPDMA_DESCS_POOL_SIZE_DEFAULT 256
 
+#define CPSW_RX_VLAN_ENCAP_HDR_PRIO_SHIFT  29
+#define CPSW_RX_VLAN_ENCAP_HDR_PRIO_MSKGENMASK(2, 0)
+#define CPSW_RX_VLAN_ENCAP_HDR_VID_SHIFT   16
+#define CPSW_RX_VLAN_ENCAP_HDR_PKT_TYPE_SHIFT  8
+#define CPSW_RX_VLAN_ENCAP_HDR_PKT_TYPE_MSKGENMASK(1, 0)
+enum {
+   CPSW_RX_VLAN_ENCAP_HDR_PKT_VLAN_TAG = 0,
+   CPSW_RX_VLAN_ENCAP_HDR_PKT_RESERV,
+   CPSW_RX_VLAN_ENCAP_HDR_PKT_PRIO_TAG,
+   CPSW_RX_VLAN_ENCAP_HDR_PKT_UNTAG,
+};
+
 static int debug_level;
 module_param(debug_level, int, 0);
 MODULE_PARM_DESC(debug_level, "cpsw debug level (NETIF_MSG bits)");
@@ -718,6 +734,49 @@ static void cpsw_tx_handler(void *token, int len, int 
status)
dev_kfree_skb_any(skb);
 }
 
+static void cpsw_rx_vlan_encap(struct sk_buff *skb)
+{
+   struct cpsw_priv *priv = netdev_priv(skb->dev);
+   struct cpsw_common *cpsw = priv->cpsw;
+   u32 rx_vlan_encap_hdr = *((u32 *)skb->data);
+   u16 vtag, vid, prio, pkt_type;
+
+   /* Remove VLAN header encapsulation word */
+   skb_pull(skb, CPSW_RX_VLAN_ENCAP_HDR_SIZE);
+
+   pkt_type = (rx_vlan_encap_hdr >>
+   CPSW_RX_VLAN_ENCAP_HDR_PKT_TYPE_SHIFT) &
+   CPSW_RX_VLAN_ENCAP_HDR_PKT_TYPE_MSK;
+   /* Ignore unknown & Priority-tagged packets*/
+   if (pkt_type == CPSW_RX_VLAN_ENCAP_HDR_PKT_RESERV ||
+   pkt_type == CPSW_RX_VLAN_ENCAP_HDR_PKT_PRIO_TAG)
+   return;
+
+   vid = (rx_vlan_encap_hdr >>
+  CPSW_RX_VLAN_ENCAP_HDR_VID_SHIFT) &
+  VLAN_VID_MASK;
+   /* Ignor

Re: [PATCH 0/2] net: phy: relax error checking when creating sysfs link netdev->phydev

2018-03-16 Thread Grygorii Strashko


On 03/16/2018 12:34 PM, Florian Fainelli wrote:
> 
> 
> On 03/16/2018 10:22 AM, Andrew Lunn wrote:
>> On Wed, Mar 14, 2018 at 05:26:22PM -0500, Grygorii Strashko wrote:
>>> Some ethernet drivers (like TI CPSW) may connect and manage >1 Net PHYs per
>>> one netdevice, as result such drivers will produce warning during system
>>> boot and fail to connect second phy to netdevice when PHYLIB framework
>>> will try to create sysfs link netdev->phydev for second PHY
>>> in phy_attach_direct(), because sysfs link with the same name has been
>>> created already for the first PHY.
>>> As result, second CPSW external port will became unusable.
>>> This issue was introduced by commits:
>>> 5568363f0cb3 ("net: phy: Create sysfs reciprocal links for 
>>> attached_dev/phydev"
>>> a3995460491d ("net: phy: Relax error checking on sysfs_create_link()"
>>
>> I wonder if it would be better to add a flag to the phydev that
>> indicates it is the second PHY connected to a MAC? Add a bit to
>> phydrv->mdiodrv.flags. If that bit is set, don't create the sysfs
>> file.
> 
> We could indeed do that, I am fine with Grygorii's approach though in
> making the creation more silent and non fatal.

The link phydev->netdev still can be created. And failure to create links
is non fatal error in my opinion. 

> 
>>
>> For 99% of MAC drivers, having two PHYs is an error, so we want to aid
>> debug by reporting the sysfs error.
> That is true, either way is fine with me, really.
> 

Error still will be reported, just not warning and it will be non-fatal.
So, with this patch set it will be possible now to continue boot (NFS for 
example),
connect to the system and gather logs.


-- 
regards,
-grygorii


Re: [PATCH net-next] net: ethernet: ti: cpsw: enable vlan rx vlan offload

2018-03-16 Thread Grygorii Strashko



On 03/16/2018 01:37 PM, David Miller wrote:

From: Andrew Lunn 
Date: Fri, 16 Mar 2018 01:29:35 +0100


On Thu, Mar 15, 2018 at 03:15:50PM -0500, Grygorii Strashko wrote:

In VLAN_AWARE mode CPSW can insert VLAN header encapsulation word on Host
port 0 egress (RX) before the packet data if RX_VLAN_ENCAP bit is set in
CPSW_CONTROL register. VLAN header encapsulation word has following format:

  HDR_PKT_Priority bits 29-31 - Header Packet VLAN prio (Highest prio: 7)
  HDR_PKT_CFI bits 28 - Header Packet VLAN CFI bit.
  HDR_PKT_Vid bits 27-16 - Header Packet VLAN ID
  PKT_Type bits 8-9 - Packet Type. Indicates whether the packet is
VLAN-tagged, priority-tagged, or non-tagged.
00: VLAN-tagged packet
01: Reserved
10: Priority-tagged packet
11: Non-tagged packet

This feature can be used to implement TX VLAN offload in case of
VLAN-tagged packets and to insert VLAN tag in case Non-tagged packet was
received on port with PVID set. As per documentation, CPSW never modifies
packet data on Host egress (RX) and as result, without this feature
enabled, Host port will not be able to receive properly packets which
entered switch non-tagged through external Port with PVID set (when
non-tagged packet forwarded from external Port with PVID set to another
external Port - packet will be VLAN tagged properly).


So, i think it is time to discuss the future of this driver. It should
really be replaced by a switchdev/DSA driver. There are plenty of
carrots for a new driver: Better statistics, working ethtool support
for all the PHYs, better user experience, etc. But maybe now it is
time for the stick. Should we Maintainers decide that no new features
should be added to the existing drivers, just bug fixes?


Andrew, I totally share your concerns.

However, I think the reality is that at best we can strongly urge
people to do such a large amount of work such as writing a new
switchdev/DSA driver for this cpsw hardware.

We can't really compel them.

And a stick could have the opposite of it's intended effect.  If still
nobody wants to do the switchdev/DSA driver, then this existing one
rots and even worse we can end up with an out-of-tree version of this
driver that has the changes (such as this one) that people want.


Yeh :( This one was created to satisfy real customer use case.
So we'll have to carry it internally any way, but having it in LKML will 
allow to involve broader number of people in review, testing and fixing.
And the same code will have to be part of dsa switch driver also - it 
will be just more stable at time of migration to dsa.




I'd like to see the switchdev/DSA driver for cpsw as much as you do,
but I am not convinced that rejecting patches like this one will
necessarily make that happen.


+1. Hope this work will be started as soon as possible.

--
regards,
-grygorii


Re: [PATCH 0/2] net: phy: relax error checking when creating sysfs link netdev->phydev

2018-03-16 Thread Grygorii Strashko


On 03/16/2018 02:54 PM, Andrew Lunn wrote:
>> The phydrv->mdiodrv.flags can be accessible only after call to 
>> of_phy_connect()/phy_connect(),
> 
> You need to use a function like of_phy_find_device() to get the
> phydev, set the flag, and then call phy_connect_direct().


So, do you propose me to replace direct calls of of_phy_connect()/phy_connect() 
in
CPSW driver with buddies of the same functions? Right?

cpsw_slave_open()
{

if (slave->data->phy_node) {
phy = of_phy_connect(priv->ndev, slave->data->phy_node,
 &cpsw_adjust_link, 0, slave->data->phy_if);
- replace  with below
{
struct phy_device *phy = of_phy_find_device(phy_np);
int ret;

if (!phy)
return NULL;

phy->dev_flags = flags;

-   [set flag in phydrv->mdiodrv.flags]

ret = phy_connect_direct(dev, phy, hndlr, iface);

/* refcount is held by phy_connect_direct() on success */
put_device(&phy->mdio.dev);

return ret ? NULL : phy;
}
-
if (!phy) {
dev_err(priv->dev, "phy \"%pOF\" not found on slave 
%d\n",
slave->data->phy_node,
slave->slave_num);
return;
}
} else {
phy = phy_connect(priv->ndev, slave->data->phy_id,
 &cpsw_adjust_link, slave->data->phy_if);
- replace  with below
{
struct phy_device *phydev;
struct device *d;
int rc;

/* Search the list of PHY devices on the mdio bus for the
 * PHY with the requested name
 */
d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id);
if (!d) {
pr_err("PHY %s not found\n", bus_id);
return ERR_PTR(-ENODEV);
}
phydev = to_phy_device(d);

-   [set flag in phydrv->mdiodrv.flags]

rc = phy_connect_direct(dev, phydev, handler, interface);
put_device(d);
if (rc)
return ERR_PTR(rc);

return phydev;
}
-
if (IS_ERR(phy)) {
dev_err(priv->dev,
"phy \"%s\" not found on slave %d, err %ld\n",
slave->data->phy_id, slave->slave_num,
PTR_ERR(phy));
return;
}
}
}

and all above just to set a flag which will be used by just one driver as of 
now.

Hm. Is this some sort of punishment ;) Sry. I'll probably will take a pause.

-- 
regards,
-grygorii


Re: [PATCH 0/2] net: phy: relax error checking when creating sysfs link netdev->phydev

2018-03-16 Thread Grygorii Strashko


On 03/16/2018 02:11 PM, Florian Fainelli wrote:
> On March 16, 2018 11:42:21 AM PDT, Grygorii Strashko 
>  wrote:
>>
>>
>> On 03/16/2018 12:34 PM, Florian Fainelli wrote:
>>>
>>>
>>> On 03/16/2018 10:22 AM, Andrew Lunn wrote:
>>>> On Wed, Mar 14, 2018 at 05:26:22PM -0500, Grygorii Strashko wrote:
>>>>> Some ethernet drivers (like TI CPSW) may connect and manage >1 Net
>> PHYs per
>>>>> one netdevice, as result such drivers will produce warning during
>> system
>>>>> boot and fail to connect second phy to netdevice when PHYLIB
>> framework
>>>>> will try to create sysfs link netdev->phydev for second PHY
>>>>> in phy_attach_direct(), because sysfs link with the same name has
>> been
>>>>> created already for the first PHY.
>>>>> As result, second CPSW external port will became unusable.
>>>>> This issue was introduced by commits:
>>>>> 5568363f0cb3 ("net: phy: Create sysfs reciprocal links for
>> attached_dev/phydev"
>>>>> a3995460491d ("net: phy: Relax error checking on
>> sysfs_create_link()"
>>>>
>>>> I wonder if it would be better to add a flag to the phydev that
>>>> indicates it is the second PHY connected to a MAC? Add a bit to
>>>> phydrv->mdiodrv.flags. If that bit is set, don't create the sysfs
>>>> file.
>>>
>>> We could indeed do that, I am fine with Grygorii's approach though in
>>> making the creation more silent and non fatal.
>>
>> The link phydev->netdev still can be created. And failure to create
>> links
>> is non fatal error in my opinion.
> 
> They should not be fatal I agree, but it's nice to know when you are doing 
> something wrong anyway.
> 
>>
>>>
>>>>
>>>> For 99% of MAC drivers, having two PHYs is an error, so we want to
>> aid
>>>> debug by reporting the sysfs error.
>>> That is true, either way is fine with me, really.
>>>
>>
>> Error still will be reported, just not warning and it will be
>> non-fatal.
>> So, with this patch set it will be possible now to continue boot (NFS
>> for example),
>> connect to the system and gather logs.
> 
> The point Andrew is trying to make is that you address one particular failure 
> in the PHY creation path when using >
 1 PHY devices with a network device. Using a flag would easily allow us to be 
more future proof with other parts of PHYLIB
  for your particular use case if that becomes necessary. This gives you less 
incentive to fix this use case though.
> 

That's true, I'm fixing use case with >1 and I'll try to re-implement using 
flag as requested.
But note, this patch in its current form fixes 1:1 (phydev:netdev) use case 
also (at least as i understand it),
because current code will just kill net connection if create sysfs link fails, 
so in case of net boot -
failure logs will not be accessible without direct access to the device.

Actually, how can i pass this flag "" from CPSW to 
of_phy_connect()->phy_attach_direct()?
The parameter "flags" == phy_device->dev_flags is used to pass PHY driver's 
specific options, so can't be used.

The phydrv->mdiodrv.flags can be accessible only after call to 
of_phy_connect()/phy_connect(), 
but sysfs links are created inside these functions.

Thanks.
-- 
regards,
-grygorii


[PATCH v2 0/2] net: phy: relax error checking when creating sysfs link netdev->phydev

2018-03-16 Thread Grygorii Strashko
Some ethernet drivers (like TI CPSW) may connect and manage >1 Net PHYs per
one netdevice, as result such drivers will produce warning during system
boot and fail to connect second phy to netdevice when PHYLIB framework
will try to create sysfs link netdev->phydev for second PHY
in phy_attach_direct(), because sysfs link with the same name has been
created already for the first PHY.
As result, second CPSW external port will became unusable.
This regression was introduced by commits:
5568363f0cb3 ("net: phy: Create sysfs reciprocal links for attached_dev/phydev"
a3995460491d ("net: phy: Relax error checking on sysfs_create_link()"

Patch 1: exports sysfs_create_link_nowarn() function as preparation for Patch 2.
Patch 2: relaxes error checking when PHYLIB framework is creating sysfs
link netdev->phydev in phy_attach_direct(), suppresses warning by using
sysfs_create_link_nowarn() and adds error message instead, so links creation
failure is not fatal any more and system can continue working,
which fixes TI CPSW issue and makes boot logs accessible
in case of NFS boot, for example.

This can be stable material 4.13+.

Changes in v2:
- commit messages updated.

v1: 
 https://patchwork.ozlabs.org/cover/886058/

Cc: Florian Fainelli 
Cc: Andrew Lunn 
Grygorii Strashko (2):
  sysfs: symlink: export sysfs_create_link_nowarn()
  net: phy: relax error checking when creating sysfs link netdev->phydev

 drivers/net/phy/phy_device.c | 15 +++
 fs/sysfs/symlink.c   |  1 +
 2 files changed, 12 insertions(+), 4 deletions(-)

-- 
2.10.5



Re: [PATCH 0/2] net: phy: relax error checking when creating sysfs link netdev->phydev

2018-03-16 Thread Grygorii Strashko



On 03/16/2018 04:14 PM, Andrew Lunn wrote:

I agree, let's not have you run into circles, let's just use your
patches as they are since they fix the problem and are not intrusive in
any way.


Agreed, this is too complex, for little gain.



Thanks. v2 posted.

--
regards,
-grygorii


[PATCH v2 1/2] sysfs: symlink: export sysfs_create_link_nowarn()

2018-03-16 Thread Grygorii Strashko
The sysfs_create_link_nowarn() is going to be used in phylib framework in
subsequent patch which can be built as module. Hence, export
sysfs_create_link_nowarn() to avoid build errors.

Cc: Florian Fainelli 
Cc: Andrew Lunn 
Fixes: a3995460491d ("net: phy: Relax error checking on sysfs_create_link()")
Signed-off-by: Grygorii Strashko 
---
"Fixes" added as there is dependency this and subsequent patch.
 fs/sysfs/symlink.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index 8664db2..215c225 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -106,6 +106,7 @@ int sysfs_create_link_nowarn(struct kobject *kobj, struct 
kobject *target,
 {
return sysfs_do_create_link(kobj, target, name, 0);
 }
+EXPORT_SYMBOL_GPL(sysfs_create_link_nowarn);
 
 /**
  * sysfs_delete_link - remove symlink in object's directory.
-- 
2.10.5



[PATCH v2 2/2] net: phy: relax error checking when creating sysfs link netdev->phydev

2018-03-16 Thread Grygorii Strashko
Some ethernet drivers (like TI CPSW) may connect and manage >1 Net PHYs per
one netdevice, as result such drivers will produce warning during system
boot and fail to connect second phy to netdevice when PHYLIB framework
will try to create sysfs link netdev->phydev for second PHY
in phy_attach_direct(), because sysfs link with the same name has been
created already for the first PHY. As result, second CPSW external
port will became unusable.

Fix it by relaxing error checking when PHYLIB framework is creating sysfs
link netdev->phydev in phy_attach_direct(), suppressing warning by using
sysfs_create_link_nowarn() and adding error message instead.
After this change links (phy->netdev and netdev->phy) creation failure is not
fatal any more and system can continue working, which fixes TI CPSW issue.

Cc: Florian Fainelli 
Cc: Andrew Lunn 
Fixes: a3995460491d ("net: phy: Relax error checking on sysfs_create_link()")
Signed-off-by: Grygorii Strashko 
---
 drivers/net/phy/phy_device.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 478405e..fe16f58 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1012,10 +1012,17 @@ int phy_attach_direct(struct net_device *dev, struct 
phy_device *phydev,
err = sysfs_create_link(&phydev->mdio.dev.kobj, &dev->dev.kobj,
"attached_dev");
if (!err) {
-   err = sysfs_create_link(&dev->dev.kobj, &phydev->mdio.dev.kobj,
-   "phydev");
-   if (err)
-   goto error;
+   err = sysfs_create_link_nowarn(&dev->dev.kobj,
+  &phydev->mdio.dev.kobj,
+  "phydev");
+   if (err) {
+   dev_err(&dev->dev, "could not add device link to %s err 
%d\n",
+   kobject_name(&phydev->mdio.dev.kobj),
+   err);
+   /* non-fatal - some net drivers can use one netdevice
+* with more then one phy
+*/
+   }
 
phydev->sysfs_links = true;
}
-- 
2.10.5



Re: [PATCH v2 net-next] net: ethernet: ti: cpdma: correct error handling for chan create

2017-12-12 Thread Grygorii Strashko


On 12/12/2017 10:35 AM, Ivan Khoronzhuk wrote:
> It's not correct to return NULL when that is actually an error and
> function returns errors in any other wrong case. In the same time,
> the cpsw driver and davinci emac doesn't check error case while
> creating channel and it can miss actual error. Also remove WARNs
> duplicated dev_err msgs.
> 
> Signed-off-by: Ivan Khoronzhuk 
> ---
>   drivers/net/ethernet/ti/cpsw.c  | 12 +---
>   drivers/net/ethernet/ti/davinci_cpdma.c |  2 +-
>   drivers/net/ethernet/ti/davinci_emac.c  |  9 +++--
>   3 files changed, 17 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
> index a60a378..3c85a08 100644
> --- a/drivers/net/ethernet/ti/cpsw.c
> +++ b/drivers/net/ethernet/ti/cpsw.c
> @@ -3065,10 +3065,16 @@ static int cpsw_probe(struct platform_device *pdev)
>   }
>   
>   cpsw->txv[0].ch = cpdma_chan_create(cpsw->dma, 0, cpsw_tx_handler, 0);
> + if (IS_ERR(cpsw->txv[0].ch)) {
> + dev_err(priv->dev, "error initializing tx dma channel\n");
> + ret = PTR_ERR(cpsw->txv[0].ch);
> + goto clean_dma_ret;
> + }
> +
>   cpsw->rxv[0].ch = cpdma_chan_create(cpsw->dma, 0, cpsw_rx_handler, 1);
> - if (WARN_ON(!cpsw->rxv[0].ch || !cpsw->txv[0].ch)) {
> - dev_err(priv->dev, "error initializing dma channels\n");
> - ret = -ENOMEM;
> + if (IS_ERR(cpsw->rxv[0].ch)) {
> + dev_err(priv->dev, "error initializing rx dma channel\n");
> + ret = PTR_ERR(cpsw->rxv[0].ch);
>   goto clean_dma_ret;
>   }
>   
> diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c 
> b/drivers/net/ethernet/ti/davinci_cpdma.c
> index e4d6edf..6f9173f 100644
> --- a/drivers/net/ethernet/ti/davinci_cpdma.c
> +++ b/drivers/net/ethernet/ti/davinci_cpdma.c
> @@ -893,7 +893,7 @@ struct cpdma_chan *cpdma_chan_create(struct cpdma_ctlr 
> *ctlr, int chan_num,
>   chan_num = rx_type ? rx_chan_num(chan_num) : tx_chan_num(chan_num);
>   
>   if (__chan_linear(chan_num) >= ctlr->num_chan)
> - return NULL;
> + return ERR_PTR(-EINVAL);
>   
>   chan = devm_kzalloc(ctlr->dev, sizeof(*chan), GFP_KERNEL);
>   if (!chan)
> diff --git a/drivers/net/ethernet/ti/davinci_emac.c 
> b/drivers/net/ethernet/ti/davinci_emac.c
> index f58c0c6..3d4af64 100644
> --- a/drivers/net/ethernet/ti/davinci_emac.c
> +++ b/drivers/net/ethernet/ti/davinci_emac.c
> @@ -1870,10 +1870,15 @@ static int davinci_emac_probe(struct platform_device 
> *pdev)
>   
>   priv->txchan = cpdma_chan_create(priv->dma, EMAC_DEF_TX_CH,
>emac_tx_handler, 0);
> + if (WARN_ON(IS_ERR(priv->txchan))) {

So, logically WARN_ON() should be removed in  davinci_emac.c also. Right?

> + rc = PTR_ERR(priv->txchan);
> + goto no_cpdma_chan;
> + }
> +
>   priv->rxchan = cpdma_chan_create(priv->dma, EMAC_DEF_RX_CH,
>emac_rx_handler, 1);
> - if (WARN_ON(!priv->txchan || !priv->rxchan)) {
> - rc = -ENOMEM;
> + if (WARN_ON(IS_ERR(priv->rxchan))) {
> + rc = PTR_ERR(priv->rxchan);
>   goto no_cpdma_chan;
>   }
>   
> 

-- 
regards,
-grygorii


Re: [PATCH v2 net-next] net: ethernet: ti: cpdma: correct error handling for chan create

2017-12-12 Thread Grygorii Strashko



On 12/12/2017 11:50 AM, Ivan Khoronzhuk wrote:

On Tue, Dec 12, 2017 at 11:08:51AM -0600, Grygorii Strashko wrote:



On 12/12/2017 10:35 AM, Ivan Khoronzhuk wrote:

It's not correct to return NULL when that is actually an error and
function returns errors in any other wrong case. In the same time,
the cpsw driver and davinci emac doesn't check error case while
creating channel and it can miss actual error. Also remove WARNs
duplicated dev_err msgs.

Signed-off-by: Ivan Khoronzhuk 
---
   drivers/net/ethernet/ti/cpsw.c  | 12 +---
   drivers/net/ethernet/ti/davinci_cpdma.c |  2 +-
   drivers/net/ethernet/ti/davinci_emac.c  |  9 +++--
   3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index a60a378..3c85a08 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -3065,10 +3065,16 @@ static int cpsw_probe(struct platform_device *pdev)
}
   
   	cpsw->txv[0].ch = cpdma_chan_create(cpsw->dma, 0, cpsw_tx_handler, 0);

+   if (IS_ERR(cpsw->txv[0].ch)) {
+   dev_err(priv->dev, "error initializing tx dma channel\n");
+   ret = PTR_ERR(cpsw->txv[0].ch);
+   goto clean_dma_ret;
+   }
+
cpsw->rxv[0].ch = cpdma_chan_create(cpsw->dma, 0, cpsw_rx_handler, 1);
-   if (WARN_ON(!cpsw->rxv[0].ch || !cpsw->txv[0].ch)) {
-   dev_err(priv->dev, "error initializing dma channels\n");
-   ret = -ENOMEM;
+   if (IS_ERR(cpsw->rxv[0].ch)) {
+   dev_err(priv->dev, "error initializing rx dma channel\n");
+   ret = PTR_ERR(cpsw->rxv[0].ch);
goto clean_dma_ret;
}
   
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c

index e4d6edf..6f9173f 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.c
+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -893,7 +893,7 @@ struct cpdma_chan *cpdma_chan_create(struct cpdma_ctlr 
*ctlr, int chan_num,
chan_num = rx_type ? rx_chan_num(chan_num) : tx_chan_num(chan_num);
   
   	if (__chan_linear(chan_num) >= ctlr->num_chan)

-   return NULL;
+   return ERR_PTR(-EINVAL);
   
   	chan = devm_kzalloc(ctlr->dev, sizeof(*chan), GFP_KERNEL);

if (!chan)
diff --git a/drivers/net/ethernet/ti/davinci_emac.c 
b/drivers/net/ethernet/ti/davinci_emac.c
index f58c0c6..3d4af64 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -1870,10 +1870,15 @@ static int davinci_emac_probe(struct platform_device 
*pdev)
   
   	priv->txchan = cpdma_chan_create(priv->dma, EMAC_DEF_TX_CH,

 emac_tx_handler, 0);
+   if (WARN_ON(IS_ERR(priv->txchan))) {


So, logically WARN_ON() should be removed in  davinci_emac.c also. Right?

It doesn't have dev_err() duplicate, so not very.
But would be better to replace them on dev_err() if no objection.



right.






+   rc = PTR_ERR(priv->txchan);
+   goto no_cpdma_chan;
+   }
+
priv->rxchan = cpdma_chan_create(priv->dma, EMAC_DEF_RX_CH,
 emac_rx_handler, 1);
-   if (WARN_ON(!priv->txchan || !priv->rxchan)) {
-   rc = -ENOMEM;
+   if (WARN_ON(IS_ERR(priv->rxchan))) {
+   rc = PTR_ERR(priv->rxchan);
goto no_cpdma_chan;
}


--
regards,
-grygorii


Re: [PATCH v3 net-next] net: ethernet: ti: cpdma: correct error handling for chan create

2017-12-12 Thread Grygorii Strashko



On 12/12/2017 03:06 PM, Ivan Khoronzhuk wrote:

It's not correct to return NULL when that is actually an error and
function returns errors in any other wrong case. In the same time,
the cpsw driver and davinci emac doesn't check error case while
creating channel and it can miss actual error. Also remove WARNs
replacing them on dev_err msgs.

Signed-off-by: Ivan Khoronzhuk 


Reviewed-by: Grygorii Strashko 


---
  drivers/net/ethernet/ti/cpsw.c  | 12 +---
  drivers/net/ethernet/ti/davinci_cpdma.c |  2 +-
  drivers/net/ethernet/ti/davinci_emac.c  | 11 +--
  3 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index a60a378..3c85a08 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -3065,10 +3065,16 @@ static int cpsw_probe(struct platform_device *pdev)
}
  
  	cpsw->txv[0].ch = cpdma_chan_create(cpsw->dma, 0, cpsw_tx_handler, 0);

+   if (IS_ERR(cpsw->txv[0].ch)) {
+   dev_err(priv->dev, "error initializing tx dma channel\n");
+   ret = PTR_ERR(cpsw->txv[0].ch);
+   goto clean_dma_ret;
+   }
+
cpsw->rxv[0].ch = cpdma_chan_create(cpsw->dma, 0, cpsw_rx_handler, 1);
-   if (WARN_ON(!cpsw->rxv[0].ch || !cpsw->txv[0].ch)) {
-   dev_err(priv->dev, "error initializing dma channels\n");
-   ret = -ENOMEM;
+   if (IS_ERR(cpsw->rxv[0].ch)) {
+   dev_err(priv->dev, "error initializing rx dma channel\n");
+   ret = PTR_ERR(cpsw->rxv[0].ch);
goto clean_dma_ret;
}
  
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c

index e4d6edf..6f9173f 100644
--- a/drivers/net/ethernet/ti/davinci_cpdma.c
+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -893,7 +893,7 @@ struct cpdma_chan *cpdma_chan_create(struct cpdma_ctlr 
*ctlr, int chan_num,
chan_num = rx_type ? rx_chan_num(chan_num) : tx_chan_num(chan_num);
  
  	if (__chan_linear(chan_num) >= ctlr->num_chan)

-   return NULL;
+   return ERR_PTR(-EINVAL);
  
  	chan = devm_kzalloc(ctlr->dev, sizeof(*chan), GFP_KERNEL);

if (!chan)
diff --git a/drivers/net/ethernet/ti/davinci_emac.c 
b/drivers/net/ethernet/ti/davinci_emac.c
index f58c0c6..abceea8 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -1870,10 +1870,17 @@ static int davinci_emac_probe(struct platform_device 
*pdev)
  
  	priv->txchan = cpdma_chan_create(priv->dma, EMAC_DEF_TX_CH,

 emac_tx_handler, 0);
+   if (IS_ERR(priv->txchan)) {
+   dev_err(&pdev->dev, "error initializing tx dma channel\n");
+   rc = PTR_ERR(priv->txchan);
+   goto no_cpdma_chan;
+   }
+
priv->rxchan = cpdma_chan_create(priv->dma, EMAC_DEF_RX_CH,
 emac_rx_handler, 1);
-   if (WARN_ON(!priv->txchan || !priv->rxchan)) {
-   rc = -ENOMEM;
+   if (IS_ERR(priv->rxchan)) {
+   dev_err(&pdev->dev, "error initializing rx dma channel\n");
+   rc = PTR_ERR(priv->rxchan);
goto no_cpdma_chan;
}
  



--
regards,
-grygorii


regression?: ti: cpsw: warning from phy_connect()->sysfs_create_link()-sysfs_warn_dup()

2018-02-26 Thread Grygorii Strashko
Hi Florian,

The TI CPSW driver produces warning as below when booted in switch mode:
[8.882295] sysfs: cannot create duplicate filename 
'/devices/platform/4400.ocp/48484000.ethernet/net/eth0/phydev'
[8.999859] CPU: 1 PID: 356 Comm: systemd-network Not tainted 
4.16.0-rc3-00010-g6cc3ff6-dirty #225
...
[9.012352] Hardware name: Generic DRA74X (Flattened Device Tree)
[9.018901] Backtrace: 
[9.021376] [] (dump_backtrace) from [] 
(show_stack+0x18/0x1c)
[9.028986]  r7:ed036240 r6:60070013 r5: r4:c0d598a0
[9.034684] [] (show_stack) from [] 
(dump_stack+0x8c/0xa0)
[9.041954] [] (dump_stack) from [] 
(sysfs_warn_dup+0x60/0x6c)
[9.049564]  r7:ed036240 r6:ed036240 r5:c0b579bc r4:ed10c000
[9.055264] [] (sysfs_warn_dup) from [] 
(sysfs_do_create_link_sd+0xbc/0xc4)
[9.064006]  r7:ed036240 r6:ffef r5: r4:ed034660
[9.069701] [] (sysfs_do_create_link_sd) from [] 
(sysfs_create_link+0x30/0x3c)
[9.078706]  r9:0008 r8: r7:ed02f008 r6:ee015ae8 r5:ee015800 
r4:ed02f000
[9.086497] [] (sysfs_create_link) from [] 
(phy_attach_direct+0x180/0x1f4)
[9.095163] [] (phy_attach_direct) from [] 
(phy_connect_direct+0x1c/0x54)
[9.103735]  r10:0001 r9:ee015d0c r8:0008 r7:c062e84c r6:c062e84c 
r5:ed02f000
[9.111609]  r4:ed02f000 r3:0008
[9.115217] [] (phy_connect_direct) from [] 
(phy_connect+0x4c/0x80)
[9.123270]  r7:c062e84c r6:ee015800 r5:ed02f000 r4:ee693664
[9.128969] [] (phy_connect) from [] 
(cpsw_slave_open+0x21c/0x274)
[9.136926]  r9:ee015d0c r8:ee015d00 r7:ed018a10 r6:ee015800 r5:ee015d00 
r4:ed032630
[9.144715] [] (cpsw_slave_open) from [] 
(cpsw_ndo_open+0x158/0x55c)
[9.152860]  r10:0001 r9: r8:ee015d00 r7:c0d04c48 r6:ee015800 
r5:ed018a10
[9.160730]  r4:ed032630
[9.163291] [] (cpsw_ndo_open) from [] 
(__dev_open+0xd4/0x158)
[9.170900]  r10: r9:ec885db4 r8:ee01582c r7:c09a9c00 r6: 
r5:c0d04c48
[9.178768]  r4:ee015800
[9.181326] [] (__dev_open) from [] 
(__dev_change_flags+0x174/0x1c0)

The reason of the warning is that in switch mode CPSW drivers is connecting two 
Net PHYs to 
a single network device (it has been done this way when driver was initially 
introduced), so
now it produces warning during boot because of commits:

5568363f0cb3 ("net: phy: Create sysfs reciprocal links for attached_dev/phydev"
a3995460491d ("net: phy: Relax error checking on sysfs_create_link()"
^ both went in v4.13

Honestly, I'm not sure how to fix it the best way (the simplest fix is below), 
taking into account
that we are not ready to do big reworks in CPSW driver.

Sry, for the late report - in LKML most of dual port TI platforms configured to 
work in
dual mac mode, therefore two network devices are created and warning not 
displayed.

-- 
regards,
-grygorii
--
>From ef2e612652cb7afa844993b23156315f0df7d24f Mon Sep 17 00:00:00 2001
From: Grygorii Strashko 
Date: Mon, 26 Feb 2018 13:53:28 -0600
Subject: [PATCH] [RFC] net: phy: suppress warning when >1 phys connected to one 
netdev

Some ethernet drivers (like TI CPSW) may connect and manage >1 Net PHYs per
one netdevice, as result such drivers will produce warning during system
boot: 'sysfs: cannot create duplicate filename
'/devices/platform/4400.ocp/48484000.ethernet/net/eth0/phydev''.

The code introduced waring was added by commit 5568363f0cb3 ("net: phy:
Create sysfs reciprocal links for attached_dev/phydev").

Fix above, by using sysfs_create_link_nowarn() when "phydev" link from
netdev->phydev is created in phy_attach_direct()

Signed-off-by: Grygorii Strashko 
---
 drivers/net/phy/phy_device.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index d39ae77..7010a92 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1014,8 +1014,9 @@ int phy_attach_direct(struct net_device *dev, struct 
phy_device *phydev,
err = sysfs_create_link(&phydev->mdio.dev.kobj, &dev->dev.kobj,
"attached_dev");
if (!err) {
-   err = sysfs_create_link(&dev->dev.kobj, &phydev->mdio.dev.kobj,
-   "phydev");
+   err = sysfs_create_link_nowarn(&dev->dev.kobj,
+  &phydev->mdio.dev.kobj,
+  "phydev");
if (err)
goto error;
 
-- 
2.10.5


  1   2   3   4   5   6   7   >