[PATCH net-next v2] net: phy: Also request modules for C45 IDs

2018-12-02 Thread Jose Abreu
Logic of phy_device_create() requests PHY modules according to PHY ID
but for C45 PHYs we use different field for the IDs.

Let's also request the modules for these IDs.

Changes from v1:
- Only request C22 modules if C45 are not present (Andrew)

Signed-off-by: Jose Abreu 
Cc: Andrew Lunn 
Cc: Florian Fainelli 
Cc: "David S. Miller" 
Cc: Joao Pinto 
---
 drivers/net/phy/phy_device.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 0904002b19a2..1569db7480af 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -605,7 +605,21 @@ struct phy_device *phy_device_create(struct mii_bus *bus, 
int addr, int phy_id,
 * driver will get bored and give up as soon as it finds that
 * there's no driver _already_ loaded.
 */
-   request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, MDIO_ID_ARGS(phy_id));
+   if (is_c45 && c45_ids) {
+   const int num_ids = ARRAY_SIZE(c45_ids->device_ids);
+   int i;
+
+   for (i = 1; i < num_ids; i++) {
+   if (!(c45_ids->devices_in_package & (1 << i)))
+   continue;
+
+   request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT,
+  MDIO_ID_ARGS(c45_ids->device_ids[i]));
+   }
+   } else {
+   request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT,
+  MDIO_ID_ARGS(phy_id));
+   }
 
device_initialize(>dev);
 
-- 
2.7.4



[PATCH net-next] net: phy: Also request modules for C45 IDs

2018-11-30 Thread Jose Abreu
Logic of phy_device_create() requests PHY modules according to PHY ID
but for C45 PHYs we use different field for the IDs.

Let's also request the modules for these IDs.

Signed-off-by: Jose Abreu 
Cc: Andrew Lunn 
Cc: Florian Fainelli 
Cc: "David S. Miller" 
Cc: Joao Pinto 
---
 drivers/net/phy/phy_device.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 0904002b19a2..d0f6edfd3381 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -606,6 +606,18 @@ struct phy_device *phy_device_create(struct mii_bus *bus, 
int addr, int phy_id,
 * there's no driver _already_ loaded.
 */
request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, MDIO_ID_ARGS(phy_id));
+   if (c45_ids) {
+   const int num_ids = ARRAY_SIZE(c45_ids->device_ids);
+   int i;
+
+   for (i = 1; i < num_ids; i++) {
+   if (!(c45_ids->devices_in_package & (1 << i)))
+   continue;
+
+   request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT,
+  MDIO_ID_ARGS(c45_ids->device_ids[i]));
+   }
+   }
 
device_initialize(>dev);
 
-- 
2.7.4




Re: [PATCH 00/12 net-next,v2] add flow_rule infrastructure

2018-11-19 Thread Jose Abreu
Hello Pablo,

On 19-11-2018 00:15, Pablo Neira Ayuso wrote:
> Hi,
>
> This patchset introduces a kernel intermediate representation (IR) to
> express ACL hardware offloads, as already described in previous RFC and
> v1 patchset [1] [2]. The idea is to normalize the frontend U/APIs to use
> the flow dissectors and the flow actions so drivers can reuse the
> existing TC offload driver codebase - that has been converted to use the
> flow_rule infrastructure.
>
> After this patch, as Or previously described, there is one extra layer:
>
> kernel frontend U/API X --> kernel parser Y --> IR --> driver --> HW API
> kernel frontend U/API Z --> kernel parser W --> IR --> driver --> HW API
>
> However, cost of this layer is very small, adding 1 million rules via
> tc -batch, perf shows:
>
>  0.06%  tc   [kernel.vmlinux][k] tc_setup_flow_action
>
> at position 187 in the call graph, far from the top ten. The flow_match
> representation uses the flow dissector infrastructure, just like
> cls_flower, therefore, there is no need for conversion of the rule match
> side.
>
> The flow_action representation is very similar to the TC action plus
> this includes wake-up-on-lan and queue to CPU actions that are needed
> for the ethtool_rx_flow_spec interface in the bcm_sf2 driver, that is
> converted in this patchset to use it. It is now possible to add tc
> cls_flower support for bcm_sf2 and reuse the existing parser that was
> originally designed for the ethtool_rx_flow_spec interface.
>
> As requested, this new patchset also converts qlogic/qede to use this
> new infrastructure (see patch 12/12). This driver currently has two
> parsers, one for ethtool_rx_flow_spec and another for tc cls_flower.
> This driver supports for simple 5-tuple matching and available actions
> are packet drop and queue. This patch updates the driver code to use one
> single parser to populate HW IR.
>
> Thanks.
>
> [1] 
> https://urldefense.proofpoint.com/v2/url?u=https-3A__lwn.net_Articles_766695_=DwIBAg=DPL6_X_6JkXFx7AXWqB0tg=yaVFU4TjGY0gVF8El1uKcisy6TPsyCl9uN7Wsis-qhY=tB4p4lWxJv3Np8Tg05scy415_MEU7RQO3Q6KGdcTMCg=EUCsiqp58Et5K2u9hHsxXyF6ep1yfhnASEBdXur33oQ=
> [2] 
> https://urldefense.proofpoint.com/v2/url?u=https-3A__marc.info_-3Fl-3Dlinux-2Dnetdev-26m-3D154233253114506-26w-3D2=DwIBAg=DPL6_X_6JkXFx7AXWqB0tg=yaVFU4TjGY0gVF8El1uKcisy6TPsyCl9uN7Wsis-qhY=tB4p4lWxJv3Np8Tg05scy415_MEU7RQO3Q6KGdcTMCg=1XOZeTYyELUCyM8yS76_bRQOVGOy19pnV9cH937FjkY=
>
> Pablo Neira Ayuso (12):
>   flow_dissector: add flow_rule and flow_match structures and use them
>   net/mlx5e: support for two independent packet edit actions
>   flow_dissector: add flow action infrastructure
>   cls_api: add translator to flow_action representation
>   cls_flower: add statistics retrieval infrastructure and use it
>   drivers: net: use flow action infrastructure
>   cls_flower: don't expose TC actions to drivers anymore
>   flow_dissector: add wake-up-on-lan and queue to flow_action
>   flow_dissector: add basic ethtool_rx_flow_spec to flow_rule structure
> translator
>   dsa: bcm_sf2: use flow_rule infrastructure
>   qede: place ethtool_rx_flow_spec after code after TC flower codebase
>   qede: use ethtool_rx_flow_rule() to remove duplicated parser code
>
>  drivers/net/dsa/bcm_sf2_cfp.c  | 108 +--
>  drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c   | 252 +++
>  .../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c   | 450 ++---
>  drivers/net/ethernet/intel/i40e/i40e_main.c| 178 ++---
>  drivers/net/ethernet/intel/iavf/iavf_main.c| 195 +++---
>  drivers/net/ethernet/intel/igb/igb_main.c  |  64 +-
>  drivers/net/ethernet/mellanox/mlx5/core/en_tc.c| 743 
> ++---
>  drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c |   2 +-
>  .../net/ethernet/mellanox/mlxsw/spectrum_flower.c  | 259 ---
>  drivers/net/ethernet/netronome/nfp/flower/action.c | 196 +++---
>  drivers/net/ethernet/netronome/nfp/flower/match.c  | 417 ++--
>  .../net/ethernet/netronome/nfp/flower/offload.c| 151 ++---
>  drivers/net/ethernet/qlogic/qede/qede_filter.c | 537 ++-
>  include/net/flow_dissector.h   | 185 +
>  include/net/pkt_cls.h  |  29 +-
>  net/core/flow_dissector.c  | 341 ++
>  net/sched/cls_api.c| 113 
>  net/sched/cls_flower.c |  42 +-
>  18 files changed, 2279 insertions(+), 1983 deletions(-)
>

Although I was cc'ed in the thread I'm not seeing stmmac driver
in this conversion. Can you please add it ?

Thanks and Best Regards,
Jose Miguel Abreu


Re: [RFC] net: stmmac: RX Jumbo packet size > 8191 problem

2018-10-26 Thread Jose Abreu



On 25-10-2018 21:41, Thor Thayer wrote:
> Hi,
>
> I'm running into a weird issue at the DMA boundary for large
> packets (>8192) that I can't explain.  I'm hoping someone here
> has an idea on why I'm seeing this issue.
>
> This is the Synopsys DesignWare Ethernet GMAC core (3.74) using
> the stmmac driver found at drivers/net/ethernet/stmicro/stmmac.
>
> If I ping with data sizes that exceed the first DMA buffer size
> (size set to 8191), ping reports a data mismatch as follows at
> byte #8144:
>
> $ ping -c 1 -M do -s 8150 192.168.1.99
> PING 192.168.1.99 (192.168.1.99) 8150(8178) bytes of data.
> 8158 bytes from 192.168.1.99: icmp_seq=1 ttl=64 time=0.669 ms
> wrong data byte #8144 should be 0xd0 but was 0x0
> #1610 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22
> 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
> %< ---snip--
> #8112b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1
> c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf
> #81440 0 0 0 d0 d1
> ^^^
> Notice the 4 bytes of 0 there before the expected byte of d0. I
> confirmed the on-wire result with wireshark - same data packet
> as shown above.
>
> Looking at the queue, I'm seeing these values in the RX
> descriptors (I'm using ring mode, enhanced descriptors).
> 0xa0040320 0x9fff1fff 0x7a358042 0x7a35a042
>  ^des0  ^des1  ^des2  ^desc3
>
> desc0 => 8196 bytes, OWN, First & Last Descriptor, Frame type =
> Eth
> desc1 => Disable IRQ on done, Rx Buffer2 sz = 8191, Rx Buffer1
> sz = 8191
> desc2 => Buffer 1 Addr Pointer
> desc3 => Buffer 2 Addr Pointer
>
> If I adjust init_desc3() and refill_desc3() to initialize desc3
> to desc2+BUF_SIZE_8KiB-4, I get a descriptor as show below and
> ping completes successfully.
> 0xa0040320 0x9fff1fff 0x77df8042 0x77dfa03e
>   ^ this is now different
>
> But I'm not sure why the -4 works because desc3 overlaps into
> the end of the first DMA buffer area (des2) which is
> counterintuitive.

By databook you have to set buffer size as multiple of bus width
but you are setting 8191 so this is not correct.

Can you try changing ehn_desc_rx_set_on_ring() and remove the
subtraction, as well as in enh_desc_init_rx_desc() ?

Thanks and Best Regards,
Jose Miguel Abreu


Re: [PATCH net-next 3/4] net: phy-c45: Implement reset/suspend/resume callbacks

2018-10-24 Thread Jose Abreu



On 23-10-2018 11:58, Russell King - ARM Linux wrote:
> On Tue, Oct 23, 2018 at 11:28:09AM +0100, Jose Abreu wrote:
>> On 23-10-2018 11:20, Russell King - ARM Linux wrote:
>>> I have no idea what you're proposing there - your patches weren't copied
>>> to me.
>> They just set / unset  MDIO_CTRL1_LPOWER bit in PCS. I find that
>> without this remote end doesn't detect link is down ...
>>
>> If it's okay for Generic 10G driver I can submit only this and
>> manually reset PHY in stmmac driver so that I don't need to
>> implement custom PHY driver ...
>
>
>> BTW, I just found out currently Generic 10G Driver is broken
>> without patch 4/4 of this series [1]
>>
>> [1] 
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__patchwork.ozlabs.org_patch_987570_=DwIBAg=DPL6_X_6JkXFx7AXWqB0tg=WHDsc6kcWAl4i96Vm5hJ_19IJiuxx_p_Rzo2g-uHDKw=zYEDSMZPTCHiPc_3B8buyu0kXnlIEYawnHWAxPrsoSU=MlF6I2cBSYkGxgEwNV-hXpXJIvXv_gRYXP-CazjkUSw=
> How is it broken - what are the symptoms?
>
> The generic 10G driver is bound not via the normal bus matching and
> phy_bus_match(), but via a manual bind in phy_attach_direct().  This
> calls the probe function, which is phy_probe(), which initialises
> the supported/advertising to the driver's features (which as you note
> are zero.)

Since 719655a14971 ("net: phy: Replace phy driver features u32
with link_mode bitmap"), phy_probe() calls
ethtool_convert_link_mode_to_legacy_u32() with phydrv->features
as argument. Since features are NULL, we will get NULL pointer
dereference.

I guess Generic 10G driver was forgotten in the conversion.

Thanks and Best Regards,
Jose Miguel Abreu

>
> However, phy_attach_direct() goes on to call phy_init_hw(), which
> calls the config_init() method.  The config_init() method initialises
> the supported/advertising masks to 10GbaseT.  This is (partly) what
> I refer to when I say that the generic 10G support is crippled - it
> only supports this single speed and media.
>
> So the supported/advertising masks should be forced to only 10GbaseT
> at the completion of phy_attach_direct().
>
> The "generic 10G" support doesn't do autonegotiation, configuration
> or link mode forcing.  It only assumes 10GbaseT is supported, and
> only checks for the "link up" bits.
>
> It isn't like the non-10G generic PHY support due to history - it
> was added in 2014 by Andy Fleming (see 124059fd53af).
>
> BTW, your patch 1 is wrong as well (introducing phy_update_link()).
> You don't take account that a 10G phy may have alternative ways of
> reading the link (like 88x3310 does, because it has multiple
> instances of AN/PCS/PHYXS at 1k offsets.)  All the gen10g_*
> functions are legacy functions for the crippled "generic" 10G
> support.
>



Re: [PATCH net-next 3/4] net: phy-c45: Implement reset/suspend/resume callbacks

2018-10-23 Thread Jose Abreu
On 23-10-2018 11:20, Russell King - ARM Linux wrote:
> On Tue, Oct 23, 2018 at 11:17:50AM +0100, Jose Abreu wrote:
>> On 22-10-2018 18:13, Florian Fainelli wrote:
>>> On 10/22/18 8:48 AM, Russell King - ARM Linux wrote:
>>>> On Mon, Oct 22, 2018 at 01:47:48PM +0100, Jose Abreu wrote:
>>>>> Hello,
>>>>>
>>>>> On 22-10-2018 13:28, Andrew Lunn wrote:
>>>>>>>  EXPORT_SYMBOL_GPL(gen10g_resume);
>>>>>>> @@ -327,7 +381,7 @@ struct phy_driver genphy_10g_driver = {
>>>>>>> .phy_id = 0x,
>>>>>>> .phy_id_mask= 0x,
>>>>>>> .name   = "Generic 10G PHY",
>>>>>>> -   .soft_reset = gen10g_no_soft_reset,
>>>>>>> +   .soft_reset = gen10g_soft_reset,
>>>>>>> .config_init= gen10g_config_init,
>>>>>>> .features   = 0,
>>>>>>> .aneg_done  = genphy_c45_aneg_done,
>>>>>> Hi Jose
>>>>>>
>>>>>> You need to be careful here. There is a reason this is called
>>>>>> gen10g_no_soft_reset, rather than having an empty
>>>>>> gen10g_soft_reset. Some PHYs break when you do a reset.  So adding a
>>>>>> gen10g_soft_reset is fine, but don't change this here, without first
>>>>>> understanding the history, and talking to Russell King.
>>>>> Hmm, the reset function only interacts with standard PCS
>>>>> registers, which should always be available ...
>>>>>
>>>>> >From my tests I need to do at least 1 reset during power-up so in
>>>>> ultimate case I can add a feature quirk or similar.
>>>>>
>>>>> Russell, can you please comment ?
>>>> Setting the reset bit on 88x3310 causes the entire device to become
>>>> completely inaccessible until hardware reset.  Therefore, this bit
>>>> must _never_ be set for these devices.  That said, we have a separate
>>>> driver for these PHYs, but that will only be used for them if it's
>>>> present in the kernel.  If we accidentally fall back to the generic
>>>> driver, then we'll screw the 88x3310 until a full hardware reset.
>>>>
>>>> We also have a bunch of net devices that make use of this crippled
>>>> "generic" 10G support - we don't know whether resetting the PHY
>>>> for those systems will cause a regression - maybe board firmware
>>>> already configured the PHY?  I can't say either way on that, except
>>>> that we've had crippled 10G support in PHYLIB for a number of years
>>>> now _with_ users, and adding reset support drastically changes the
>>>> subsystem's behaviour for these users.
>>>>
>>>> I would recommend not touching the generic 10G driver, but instead
>>>> implement your own driver for your PHY to avoid causing regressions.
>>>>
>>> Agreed.
>> What about .suspend / .resume ?
> I have no idea what you're proposing there - your patches weren't copied
> to me.
>

They just set / unset  MDIO_CTRL1_LPOWER bit in PCS. I find that
without this remote end doesn't detect link is down ...

If it's okay for Generic 10G driver I can submit only this and
manually reset PHY in stmmac driver so that I don't need to
implement custom PHY driver ...

BTW, I just found out currently Generic 10G Driver is broken
without patch 4/4 of this series [1]

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

Thanks and Best Regards,
Jose Miguel Abreu


Re: [PATCH net-next 1/4] net: phy: Use C45 Helpers when forcing PHY

2018-10-23 Thread Jose Abreu
On 22-10-2018 18:11, Florian Fainelli wrote:
> On 10/22/18 3:32 AM, Jose Abreu wrote:
>> If PHY is in force state and we have a C45 phy we need to use the
>> standard C45 helpers and not the C22 ones.
>>
>> Signed-off-by: Jose Abreu 
>> Cc: Andrew Lunn 
>> Cc: Florian Fainelli 
>> Cc: "David S. Miller" 
>> Cc: Joao Pinto 
>> ---
>>  drivers/net/phy/phy.c | 2 +-
>>  include/linux/phy.h   | 8 
>>  2 files changed, 9 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
>> index 1d73ac3309ce..0ff4946e208e 100644
>> --- a/drivers/net/phy/phy.c
>> +++ b/drivers/net/phy/phy.c
>> @@ -995,7 +995,7 @@ void phy_state_machine(struct work_struct *work)
>>  }
>>  break;
>>  case PHY_FORCING:
>> -err = genphy_update_link(phydev);
>> +err = phy_update_link(phydev);
>>  if (err)
>>  break;
>>  
>> diff --git a/include/linux/phy.h b/include/linux/phy.h
>> index 3ea87f774a76..02c2ee8bc05b 100644
>> --- a/include/linux/phy.h
>> +++ b/include/linux/phy.h
>> @@ -1044,6 +1044,14 @@ static inline int phy_read_status(struct phy_device 
>> *phydev)
>>  return genphy_read_status(phydev);
>>  }
>>  
>> +static inline int phy_update_link(struct phy_device *phydev)
>> +{
>> +if (phydev->is_c45)
>> +return gen10g_read_status(phydev);
> Should not this be genphy_c45_read_link() for symmetry with
> genphy_update_link() which only updates phydev->link?

Hmmm, genphy_c45_read_link() does not update phydev->link ... I
can create a new gen10g_update_link() that wraps around
genphy_c45_read_link() and updates link ...

Thanks and Best Regards,
Jose Miguel Abreu


Re: [PATCH net-next 3/4] net: phy-c45: Implement reset/suspend/resume callbacks

2018-10-23 Thread Jose Abreu
On 22-10-2018 18:13, Florian Fainelli wrote:
> On 10/22/18 8:48 AM, Russell King - ARM Linux wrote:
>> On Mon, Oct 22, 2018 at 01:47:48PM +0100, Jose Abreu wrote:
>>> Hello,
>>>
>>> On 22-10-2018 13:28, Andrew Lunn wrote:
>>>>>  EXPORT_SYMBOL_GPL(gen10g_resume);
>>>>> @@ -327,7 +381,7 @@ struct phy_driver genphy_10g_driver = {
>>>>>   .phy_id = 0x,
>>>>>   .phy_id_mask= 0x,
>>>>>   .name   = "Generic 10G PHY",
>>>>> - .soft_reset = gen10g_no_soft_reset,
>>>>> + .soft_reset = gen10g_soft_reset,
>>>>>   .config_init= gen10g_config_init,
>>>>>   .features   = 0,
>>>>>   .aneg_done  = genphy_c45_aneg_done,
>>>> Hi Jose
>>>>
>>>> You need to be careful here. There is a reason this is called
>>>> gen10g_no_soft_reset, rather than having an empty
>>>> gen10g_soft_reset. Some PHYs break when you do a reset.  So adding a
>>>> gen10g_soft_reset is fine, but don't change this here, without first
>>>> understanding the history, and talking to Russell King.
>>> Hmm, the reset function only interacts with standard PCS
>>> registers, which should always be available ...
>>>
>>> >From my tests I need to do at least 1 reset during power-up so in
>>> ultimate case I can add a feature quirk or similar.
>>>
>>> Russell, can you please comment ?
>> Setting the reset bit on 88x3310 causes the entire device to become
>> completely inaccessible until hardware reset.  Therefore, this bit
>> must _never_ be set for these devices.  That said, we have a separate
>> driver for these PHYs, but that will only be used for them if it's
>> present in the kernel.  If we accidentally fall back to the generic
>> driver, then we'll screw the 88x3310 until a full hardware reset.
>>
>> We also have a bunch of net devices that make use of this crippled
>> "generic" 10G support - we don't know whether resetting the PHY
>> for those systems will cause a regression - maybe board firmware
>> already configured the PHY?  I can't say either way on that, except
>> that we've had crippled 10G support in PHYLIB for a number of years
>> now _with_ users, and adding reset support drastically changes the
>> subsystem's behaviour for these users.
>>
>> I would recommend not touching the generic 10G driver, but instead
>> implement your own driver for your PHY to avoid causing regressions.
>>
> Agreed.

What about .suspend / .resume ?

Thanks and Best Regards,
Jose Miguel Abreu


Re: [PATCH net-next 3/4] net: phy-c45: Implement reset/suspend/resume callbacks

2018-10-22 Thread Jose Abreu
Hello,

On 22-10-2018 13:28, Andrew Lunn wrote:
>>  EXPORT_SYMBOL_GPL(gen10g_resume);
>> @@ -327,7 +381,7 @@ struct phy_driver genphy_10g_driver = {
>>  .phy_id = 0x,
>>  .phy_id_mask= 0x,
>>  .name   = "Generic 10G PHY",
>> -.soft_reset = gen10g_no_soft_reset,
>> +.soft_reset = gen10g_soft_reset,
>>  .config_init= gen10g_config_init,
>>  .features   = 0,
>>  .aneg_done  = genphy_c45_aneg_done,
> Hi Jose
>
> You need to be careful here. There is a reason this is called
> gen10g_no_soft_reset, rather than having an empty
> gen10g_soft_reset. Some PHYs break when you do a reset.  So adding a
> gen10g_soft_reset is fine, but don't change this here, without first
> understanding the history, and talking to Russell King.

Hmm, the reset function only interacts with standard PCS
registers, which should always be available ...

>From my tests I need to do at least 1 reset during power-up so in
ultimate case I can add a feature quirk or similar.

Russell, can you please comment ?

Thanks and Best Regards,
Jose Miguel Abreu

>
> Andrew



[PATCH net-next 2/4] net: phy-c45: Populate autoneg_done callback

2018-10-22 Thread Jose Abreu
We already have this callback implemented. Use it in driver structure.

Signed-off-by: Jose Abreu 
Cc: Andrew Lunn 
Cc: Florian Fainelli 
Cc: "David S. Miller" 
Cc: Joao Pinto 
---
 drivers/net/phy/phy-c45.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c
index e1225545362d..c0135217b81f 100644
--- a/drivers/net/phy/phy-c45.c
+++ b/drivers/net/phy/phy-c45.c
@@ -330,6 +330,7 @@ struct phy_driver genphy_10g_driver = {
.soft_reset = gen10g_no_soft_reset,
.config_init= gen10g_config_init,
.features   = 0,
+   .aneg_done  = genphy_c45_aneg_done,
.config_aneg= gen10g_config_aneg,
.read_status= gen10g_read_status,
.suspend= gen10g_suspend,
-- 
2.7.4




[PATCH net-next 3/4] net: phy-c45: Implement reset/suspend/resume callbacks

2018-10-22 Thread Jose Abreu
Implement the missing callbacks for Generic 10G PHY. Tested using XGMAC
with a C45 PHY working at 10G Link.

Signed-off-by: Jose Abreu 
Cc: Andrew Lunn 
Cc: Florian Fainelli 
Cc: "David S. Miller" 
Cc: Joao Pinto 
---
 drivers/net/phy/phy-c45.c | 56 ++-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c
index c0135217b81f..7e62bd7795a3 100644
--- a/drivers/net/phy/phy-c45.c
+++ b/drivers/net/phy/phy-c45.c
@@ -1,6 +1,7 @@
 /*
  * Clause 45 PHY support
  */
+#include 
 #include 
 #include 
 #include 
@@ -294,6 +295,35 @@ int gen10g_read_status(struct phy_device *phydev)
 }
 EXPORT_SYMBOL_GPL(gen10g_read_status);
 
+static int gen10g_poll_reset(struct phy_device *phydev)
+{
+   /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
+   unsigned int retries = 12;
+   int ret;
+
+   do {
+   msleep(50);
+   ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
+   if (ret < 0)
+   return ret;
+   } while (ret & MDIO_CTRL1_RESET && --retries);
+   if (ret & MDIO_CTRL1_RESET)
+   return -ETIMEDOUT;
+
+   return 0;
+}
+
+static int gen10g_soft_reset(struct phy_device *phydev)
+{
+   int val;
+
+   val = phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, MDIO_CTRL1_RESET);
+   if (val < 0)
+   return val;
+
+   return gen10g_poll_reset(phydev);
+}
+
 int gen10g_no_soft_reset(struct phy_device *phydev)
 {
/* Do nothing for now */
@@ -313,12 +343,36 @@ EXPORT_SYMBOL_GPL(gen10g_config_init);
 
 int gen10g_suspend(struct phy_device *phydev)
 {
+   int val;
+
+   val = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
+   if (val < 0)
+   return val;
+
+   val |= MDIO_CTRL1_LPOWER;
+
+   val = phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, val);
+   if (val < 0)
+   return val;
+
return 0;
 }
 EXPORT_SYMBOL_GPL(gen10g_suspend);
 
 int gen10g_resume(struct phy_device *phydev)
 {
+   int val;
+
+   val = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1);
+   if (val < 0)
+   return val;
+
+   val &= ~MDIO_CTRL1_LPOWER;
+
+   val = phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_CTRL1, val);
+   if (val < 0)
+   return val;
+
return 0;
 }
 EXPORT_SYMBOL_GPL(gen10g_resume);
@@ -327,7 +381,7 @@ struct phy_driver genphy_10g_driver = {
.phy_id = 0x,
.phy_id_mask= 0x,
.name   = "Generic 10G PHY",
-   .soft_reset = gen10g_no_soft_reset,
+   .soft_reset = gen10g_soft_reset,
.config_init= gen10g_config_init,
.features   = 0,
.aneg_done  = genphy_c45_aneg_done,
-- 
2.7.4




[PATCH net-next 4/4] net: phy-c45: Populate missing features

2018-10-22 Thread Jose Abreu
Populate the missing features field of Generic 10G PHY Driver. This will
be overwritten in .config_init callback so we can just set basic 10G
funcionalities in the field.

Signed-off-by: Jose Abreu 
Cc: Andrew Lunn 
Cc: Florian Fainelli 
Cc: "David S. Miller" 
Cc: Joao Pinto 
---
 drivers/net/phy/phy-c45.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c
index 7e62bd7795a3..99c66b452af9 100644
--- a/drivers/net/phy/phy-c45.c
+++ b/drivers/net/phy/phy-c45.c
@@ -383,7 +383,7 @@ struct phy_driver genphy_10g_driver = {
.name   = "Generic 10G PHY",
.soft_reset = gen10g_soft_reset,
.config_init= gen10g_config_init,
-   .features   = 0,
+   .features   = PHY_10GBIT_FEATURES,
.aneg_done  = genphy_c45_aneg_done,
.config_aneg= gen10g_config_aneg,
.read_status= gen10g_read_status,
-- 
2.7.4




[PATCH net-next 0/4] net: phy: Misc improvements for Generic 10G PHY

2018-10-22 Thread Jose Abreu
Set of improvements for Generic 10G PHY. All of them tested using stmmac with
XGMAC2 IP working at 10G Link with a C45 PHY.

Cc: Andrew Lunn 
Cc: Florian Fainelli 
Cc: "David S. Miller" 
Cc: Joao Pinto 

Jose Abreu (4):
  net: phy: Use C45 Helpers when forcing PHY
  net: phy-c45: Populate autoneg_done callback
  net: phy-c45: Implement reset/suspend/resume callbacks
  net: phy-c45: Populate missing features

 drivers/net/phy/phy-c45.c | 59 +--
 drivers/net/phy/phy.c |  2 +-
 include/linux/phy.h   |  8 +++
 3 files changed, 66 insertions(+), 3 deletions(-)

-- 
2.7.4




[PATCH net-next 1/4] net: phy: Use C45 Helpers when forcing PHY

2018-10-22 Thread Jose Abreu
If PHY is in force state and we have a C45 phy we need to use the
standard C45 helpers and not the C22 ones.

Signed-off-by: Jose Abreu 
Cc: Andrew Lunn 
Cc: Florian Fainelli 
Cc: "David S. Miller" 
Cc: Joao Pinto 
---
 drivers/net/phy/phy.c | 2 +-
 include/linux/phy.h   | 8 
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 1d73ac3309ce..0ff4946e208e 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -995,7 +995,7 @@ void phy_state_machine(struct work_struct *work)
}
break;
case PHY_FORCING:
-   err = genphy_update_link(phydev);
+   err = phy_update_link(phydev);
if (err)
break;
 
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 3ea87f774a76..02c2ee8bc05b 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1044,6 +1044,14 @@ static inline int phy_read_status(struct phy_device 
*phydev)
return genphy_read_status(phydev);
 }
 
+static inline int phy_update_link(struct phy_device *phydev)
+{
+   if (phydev->is_c45)
+   return gen10g_read_status(phydev);
+   else
+   return genphy_update_link(phydev);
+}
+
 void phy_driver_unregister(struct phy_driver *drv);
 void phy_drivers_unregister(struct phy_driver *drv, int n);
 int phy_driver_register(struct phy_driver *new_driver, struct module *owner);
-- 
2.7.4




C45 Phys and PHY_FORCING state

2018-10-19 Thread Jose Abreu
Hello Andrew and Florian,

Currently I have a 10G C45 phy that is fixed at 10G link. This
version does not support auto negotiation so I'm turning off the
feature in phydev struct field. I found out that when I do this
phylib is not composing C45 frames and is instead using C22. This
is due to call to genphy_udpate_link() which doesn't work on my
phy because it doesn't support C22.

If I apply attached patch then things work perfectly fine. Can
you please review it ?

Thanks and Best Regards,
Jose Miguel Abreu
>From cccf07f4d7335cbc36f3856da6d368cb01570760 Mon Sep 17 00:00:00 2001
Message-Id: 
In-Reply-To: 
References: 
From: Jose Abreu 
Date: Thu, 18 Oct 2018 17:36:21 +0200
Subject: [PATCH 5/8] net: phy: Use C45 Helpers when forcing PHY

If PHY is in force state and we have a C45 phy we need to use the
standard C45 helpers and not the C22 ones.

Signed-off-by: Jose Abreu 
---
 drivers/net/phy/phy.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 1ee25877c4d1..28ed957bc0f6 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1007,7 +1007,11 @@ void phy_state_machine(struct work_struct *work)
 		}
 		break;
 	case PHY_FORCING:
-		err = genphy_update_link(phydev);
+		if (phydev->is_c45)
+			err = gen10g_read_status(phydev);
+		else
+			err = genphy_update_link(phydev);
+
 		if (err)
 			break;
 
-- 
2.7.4



stmmac: Race in coalesce timer and NAPI

2018-09-21 Thread Jose Abreu
Hello,

I'm getting a race in stmmac coalesce timer and the
napi_schedule() interrupt and I'm asking for advice. Currently,
we are scheduling NAPI in coalesce timer but this leads to
stmmac_tx_clean() deadlock because this function tries to acquire
queue lock.

I find that this is not expected because only one instance of
NAPI should run at same time so I was wondering if it is possible
that xmit() callback is causing the deadlock ?

BTW, this is solved by:
- Directly call stmmac_tx_clean() in timer function AND
- Use netif_tx_trylock() in stmmac_tx_clean(). Then, if queue
is already locked we re-arm coalesce timer or reschedule NAPI.

This is easily reproducible in an ARM board with 8 core running
at 100MHz each.

Thanks and Best Regards,
Jose Miguel Abreu


Re: [PATCH net-next v3 0/2] net: stmmac: Coalesce and tail addr fixes

2018-09-17 Thread Jose Abreu
Hi Jerome,

On 14-09-2018 16:06, Jerome Brunet wrote:
>
> Looks better this time. Stable so far, with even a small throughput 
> improvement
> on the Tx path.
>
> so for the a113 s400 board (single queue)
> Tested-by: Jerome Brunet 
>

Thanks for testing! I sent out a rebased version against net.

Can you share what's the throughput improvement in % ?

Do you still see the performance drop when tx/rx work at same
time ? I remember that was another issue ...

Thanks and Best Regards,
Jose Miguel Abreu


[PATCH net 0/2] net: stmmac: Coalesce and tail addr fixes

2018-09-17 Thread Jose Abreu
The fix for coalesce timer and a fix in tail address setting that impacts
XGMAC2 operation.

The series is:
Tested-by: Jerome Brunet 
on a113 s400 board (single queue)

Cc: Florian Fainelli 
Cc: Neil Armstrong 
Cc: Jerome Brunet 
Cc: Martin Blumenstingl 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 

Jose Abreu (2):
  net: stmmac: Rework coalesce timer and fix multi-queue races
  net: stmmac: Fixup the tail addr setting in xmit path

 drivers/net/ethernet/stmicro/stmmac/common.h  |   4 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  14 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 238 --
 include/linux/stmmac.h|   1 +
 4 files changed, 149 insertions(+), 108 deletions(-)

-- 
2.7.4




[PATCH net 2/2] net: stmmac: Fixup the tail addr setting in xmit path

2018-09-17 Thread Jose Abreu
Currently we are always setting the tail address of descriptor list to
the end of the pre-allocated list.

According to databook this is not correct. Tail address should point to
the last available descriptor + 1, which means we have to update the
tail address everytime we call the xmit function.

This should make no impact in older versions of MAC but in newer
versions there are some DMA features which allows the IP to fetch
descriptors in advance and in a non sequential order so its critical
that we set the tail address correctly.

Signed-off-by: Jose Abreu 
Fixes: f748be531d70 ("stmmac: support new GMAC4")
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ab9cc0143ff2..75896d6ba6e2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2213,8 +2213,7 @@ static int stmmac_init_dma_engine(struct stmmac_priv 
*priv)
stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
tx_q->dma_tx_phy, chan);
 
-   tx_q->tx_tail_addr = tx_q->dma_tx_phy +
-   (DMA_TX_SIZE * sizeof(struct dma_desc));
+   tx_q->tx_tail_addr = tx_q->dma_tx_phy;
stmmac_set_tx_tail_ptr(priv, priv->ioaddr,
   tx_q->tx_tail_addr, chan);
}
@@ -3003,6 +3002,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, 
struct net_device *dev)
 
netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len);
 
+   tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc));
stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);
 
return NETDEV_TX_OK;
@@ -3210,6 +3210,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, 
struct net_device *dev)
 
stmmac_enable_dma_transmission(priv, priv->ioaddr);
 
+   tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc));
stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);
 
return NETDEV_TX_OK;
-- 
2.7.4




[PATCH net 1/2] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-17 Thread Jose Abreu
This follows David Miller advice and tries to fix coalesce timer in
multi-queue scenarios.

We are now using per-queue coalesce values and per-queue TX timer.

Coalesce timer default values was changed to 1ms and the coalesce frames
to 25.

Tested in B2B setup between XGMAC2 and GMAC5.

Signed-off-by: Jose Abreu 
Fixes:  ce736788e8a ("net: stmmac: adding multiple buffers for TX")
Cc: Florian Fainelli 
Cc: Neil Armstrong 
Cc: Jerome Brunet 
Cc: Martin Blumenstingl 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/common.h  |   4 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  14 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 233 --
 include/linux/stmmac.h|   1 +
 4 files changed, 146 insertions(+), 106 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
b/drivers/net/ethernet/stmicro/stmmac/common.h
index 1854f270ad66..b1b305f8f414 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -258,10 +258,10 @@ struct stmmac_safety_stats {
 #define MAX_DMA_RIWT   0xff
 #define MIN_DMA_RIWT   0x20
 /* Tx coalesce parameters */
-#define STMMAC_COAL_TX_TIMER   4
+#define STMMAC_COAL_TX_TIMER   1000
 #define STMMAC_MAX_COAL_TX_TICK10
 #define STMMAC_TX_MAX_FRAMES   256
-#define STMMAC_TX_FRAMES   64
+#define STMMAC_TX_FRAMES   25
 
 /* Packets types */
 enum packets_types {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h 
b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index c0a855b7ab3b..63e1064b27a2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -48,6 +48,8 @@ struct stmmac_tx_info {
 
 /* Frequently used values are kept adjacent for cache effect */
 struct stmmac_tx_queue {
+   u32 tx_count_frames;
+   struct timer_list txtimer;
u32 queue_index;
struct stmmac_priv *priv_data;
struct dma_extended_desc *dma_etx cacheline_aligned_in_smp;
@@ -73,7 +75,14 @@ struct stmmac_rx_queue {
u32 rx_zeroc_thresh;
dma_addr_t dma_rx_phy;
u32 rx_tail_addr;
+};
+
+struct stmmac_channel {
struct napi_struct napi cacheline_aligned_in_smp;
+   struct stmmac_priv *priv_data;
+   u32 index;
+   int has_rx;
+   int has_tx;
 };
 
 struct stmmac_tc_entry {
@@ -109,14 +118,12 @@ struct stmmac_pps_cfg {
 
 struct stmmac_priv {
/* Frequently used values are kept adjacent for cache effect */
-   u32 tx_count_frames;
u32 tx_coal_frames;
u32 tx_coal_timer;
 
int tx_coalesce;
int hwts_tx_en;
bool tx_path_in_lpi_mode;
-   struct timer_list txtimer;
bool tso;
 
unsigned int dma_buf_sz;
@@ -137,6 +144,9 @@ struct stmmac_priv {
/* TX Queue */
struct stmmac_tx_queue tx_queue[MTL_MAX_TX_QUEUES];
 
+   /* Generic channel for NAPI */
+   struct stmmac_channel channel[STMMAC_CH_MAX];
+
bool oldlink;
int speed;
int oldduplex;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9f458bb16f2a..ab9cc0143ff2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -148,12 +148,14 @@ static void stmmac_verify_args(void)
 static void stmmac_disable_all_queues(struct stmmac_priv *priv)
 {
u32 rx_queues_cnt = priv->plat->rx_queues_to_use;
+   u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
+   u32 maxq = max(rx_queues_cnt, tx_queues_cnt);
u32 queue;
 
-   for (queue = 0; queue < rx_queues_cnt; queue++) {
-   struct stmmac_rx_queue *rx_q = >rx_queue[queue];
+   for (queue = 0; queue < maxq; queue++) {
+   struct stmmac_channel *ch = >channel[queue];
 
-   napi_disable(_q->napi);
+   napi_disable(>napi);
}
 }
 
@@ -164,12 +166,14 @@ static void stmmac_disable_all_queues(struct stmmac_priv 
*priv)
 static void stmmac_enable_all_queues(struct stmmac_priv *priv)
 {
u32 rx_queues_cnt = priv->plat->rx_queues_to_use;
+   u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
+   u32 maxq = max(rx_queues_cnt, tx_queues_cnt);
u32 queue;
 
-   for (queue = 0; queue < rx_queues_cnt; queue++) {
-   struct stmmac_rx_queue *rx_q = >rx_queue[queue];
+   for (queue = 0; queue < maxq; queue++) {
+   struct stmmac_channel *ch = >channel[queue];
 
-   napi_enable(_q->napi);
+   napi_enable(>napi);
}
 }
 
@@ -1843,18 +1847,18 @@ static void stmmac_dma_operation_mode(struct 
stmmac_priv *priv)
  * @queue: TX queue index
  * Description: it reclaims the transmit resources a

[PATCH net-next v3 1/2] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-13 Thread Jose Abreu
This follows David Miller advice and tries to fix coalesce timer in
multi-queue scenarios.

We are now using per-queue coalesce values and per-queue TX timer.

Coalesce timer default values was changed to 1ms and the coalesce frames
to 25.

Tested in B2B setup between XGMAC2 and GMAC5.

Signed-off-by: Jose Abreu 
Cc: Florian Fainelli 
Cc: Neil Armstrong 
Cc: Jerome Brunet 
Cc: Martin Blumenstingl 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/common.h  |   4 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  14 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 233 --
 include/linux/stmmac.h|   1 +
 4 files changed, 146 insertions(+), 106 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
b/drivers/net/ethernet/stmicro/stmmac/common.h
index 1854f270ad66..b1b305f8f414 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -258,10 +258,10 @@ struct stmmac_safety_stats {
 #define MAX_DMA_RIWT   0xff
 #define MIN_DMA_RIWT   0x20
 /* Tx coalesce parameters */
-#define STMMAC_COAL_TX_TIMER   4
+#define STMMAC_COAL_TX_TIMER   1000
 #define STMMAC_MAX_COAL_TX_TICK10
 #define STMMAC_TX_MAX_FRAMES   256
-#define STMMAC_TX_FRAMES   64
+#define STMMAC_TX_FRAMES   25
 
 /* Packets types */
 enum packets_types {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h 
b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index c0a855b7ab3b..63e1064b27a2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -48,6 +48,8 @@ struct stmmac_tx_info {
 
 /* Frequently used values are kept adjacent for cache effect */
 struct stmmac_tx_queue {
+   u32 tx_count_frames;
+   struct timer_list txtimer;
u32 queue_index;
struct stmmac_priv *priv_data;
struct dma_extended_desc *dma_etx cacheline_aligned_in_smp;
@@ -73,7 +75,14 @@ struct stmmac_rx_queue {
u32 rx_zeroc_thresh;
dma_addr_t dma_rx_phy;
u32 rx_tail_addr;
+};
+
+struct stmmac_channel {
struct napi_struct napi cacheline_aligned_in_smp;
+   struct stmmac_priv *priv_data;
+   u32 index;
+   int has_rx;
+   int has_tx;
 };
 
 struct stmmac_tc_entry {
@@ -109,14 +118,12 @@ struct stmmac_pps_cfg {
 
 struct stmmac_priv {
/* Frequently used values are kept adjacent for cache effect */
-   u32 tx_count_frames;
u32 tx_coal_frames;
u32 tx_coal_timer;
 
int tx_coalesce;
int hwts_tx_en;
bool tx_path_in_lpi_mode;
-   struct timer_list txtimer;
bool tso;
 
unsigned int dma_buf_sz;
@@ -137,6 +144,9 @@ struct stmmac_priv {
/* TX Queue */
struct stmmac_tx_queue tx_queue[MTL_MAX_TX_QUEUES];
 
+   /* Generic channel for NAPI */
+   struct stmmac_channel channel[STMMAC_CH_MAX];
+
bool oldlink;
int speed;
int oldduplex;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9f458bb16f2a..ab9cc0143ff2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -148,12 +148,14 @@ static void stmmac_verify_args(void)
 static void stmmac_disable_all_queues(struct stmmac_priv *priv)
 {
u32 rx_queues_cnt = priv->plat->rx_queues_to_use;
+   u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
+   u32 maxq = max(rx_queues_cnt, tx_queues_cnt);
u32 queue;
 
-   for (queue = 0; queue < rx_queues_cnt; queue++) {
-   struct stmmac_rx_queue *rx_q = >rx_queue[queue];
+   for (queue = 0; queue < maxq; queue++) {
+   struct stmmac_channel *ch = >channel[queue];
 
-   napi_disable(_q->napi);
+   napi_disable(>napi);
}
 }
 
@@ -164,12 +166,14 @@ static void stmmac_disable_all_queues(struct stmmac_priv 
*priv)
 static void stmmac_enable_all_queues(struct stmmac_priv *priv)
 {
u32 rx_queues_cnt = priv->plat->rx_queues_to_use;
+   u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
+   u32 maxq = max(rx_queues_cnt, tx_queues_cnt);
u32 queue;
 
-   for (queue = 0; queue < rx_queues_cnt; queue++) {
-   struct stmmac_rx_queue *rx_q = >rx_queue[queue];
+   for (queue = 0; queue < maxq; queue++) {
+   struct stmmac_channel *ch = >channel[queue];
 
-   napi_enable(_q->napi);
+   napi_enable(>napi);
}
 }
 
@@ -1843,18 +1847,18 @@ static void stmmac_dma_operation_mode(struct 
stmmac_priv *priv)
  * @queue: TX queue index
  * Description: it reclaims the transmit resources after transmission 
completes.
  */
-static void stmmac_tx_clean(struct stmmac_priv *pri

[PATCH net-next v3 2/2] net: stmmac: Fixup the tail addr setting in xmit path

2018-09-13 Thread Jose Abreu
Currently we are always setting the tail address of descriptor list to
the end of the pre-allocated list.

According to databook this is not correct. Tail address should point to
the last available descriptor + 1, which means we have to update the
tail address everytime we call the xmit function.

This should make no impact in older versions of MAC but in newer
versions there are some DMA features which allows the IP to fetch
descriptors in advance and in a non sequential order so its critical
that we set the tail address correctly.

Signed-off-by: Jose Abreu 
Fixes: f748be531d70 ("stmmac: support new GMAC4")
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
Cc: Florian Fainelli 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ab9cc0143ff2..75896d6ba6e2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2213,8 +2213,7 @@ static int stmmac_init_dma_engine(struct stmmac_priv 
*priv)
stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
tx_q->dma_tx_phy, chan);
 
-   tx_q->tx_tail_addr = tx_q->dma_tx_phy +
-   (DMA_TX_SIZE * sizeof(struct dma_desc));
+   tx_q->tx_tail_addr = tx_q->dma_tx_phy;
stmmac_set_tx_tail_ptr(priv, priv->ioaddr,
   tx_q->tx_tail_addr, chan);
}
@@ -3003,6 +3002,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, 
struct net_device *dev)
 
netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len);
 
+   tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc));
stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);
 
return NETDEV_TX_OK;
@@ -3210,6 +3210,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, 
struct net_device *dev)
 
stmmac_enable_dma_transmission(priv, priv->ioaddr);
 
+   tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc));
stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);
 
return NETDEV_TX_OK;
-- 
2.7.4




[PATCH net-next v3 0/2] net: stmmac: Coalesce and tail addr fixes

2018-09-13 Thread Jose Abreu
The fix for coalesce timer and a fix in tail address setting that impacts
XGMAC2 operation.

Cc: Florian Fainelli 
Cc: Neil Armstrong 
Cc: Jerome Brunet 
Cc: Martin Blumenstingl 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 

Jose Abreu (2):
  net: stmmac: Rework coalesce timer and fix multi-queue races
  net: stmmac: Fixup the tail addr setting in xmit path

 drivers/net/ethernet/stmicro/stmmac/common.h  |   4 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  14 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 238 --
 include/linux/stmmac.h|   1 +
 4 files changed, 149 insertions(+), 108 deletions(-)

-- 
2.7.4




Re: [net-next, v2, 1/2] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-12 Thread Jose Abreu
Hi Neil,

On 12-09-2018 14:50, Neil Armstrong wrote:
> Hi Jose,
>
> On 11/09/2018 10:17, Jose Abreu wrote:
>> On 10-09-2018 19:15, Neil Armstrong wrote:
>>> RX is still ok but now TX fails almost immediately...
>>>
>>> With 100ms report :
>>>
>>> $ iperf3 -c 192.168.1.47 -t 0 -p 5202 -R -i 0.1
>>> Connecting to host 192.168.1.47, port 5202
>>> Reverse mode, remote host 192.168.1.47 is sending
>>> [  4] local 192.168.1.45 port 45900 connected to 192.168.1.47 port 5202
>>> [ ID] Interval   Transfer Bandwidth
>>> [  4]   0.00-0.10   sec  10.9 MBytes   913 Mbits/sec
>>> [  4]   0.10-0.20   sec  11.0 MBytes   923 Mbits/sec
>>> [  4]   0.20-0.30   sec  6.34 MBytes   532 Mbits/sec
>>> [  4]   0.30-0.40   sec  0.00 Bytes  0.00 bits/sec
>>> [  4]   0.40-0.50   sec  0.00 Bytes  0.00 bits/sec
>>> [  4]   0.50-0.60   sec  0.00 Bytes  0.00 bits/sec
>>> [  4]   0.60-0.70   sec  0.00 Bytes  0.00 bits/sec
>>> [  4]   0.70-0.80   sec  0.00 Bytes  0.00 bits/sec
>>> [  4]   0.80-0.90   sec  0.00 Bytes  0.00 bits/sec
>>> [  4]   0.90-1.00   sec  0.00 Bytes  0.00 bits/sec
>>> [  4]   1.00-1.10   sec  0.00 Bytes  0.00 bits/sec
>>> ^C[  4]   1.10-1.10   sec  0.00 Bytes  0.00 bits/sec
>>> - - - - - - - - - - - - - - - - - - - - - - - - -
>>> [ ID] Interval   Transfer Bandwidth
>>> [  4]   0.00-1.10   sec  0.00 Bytes  0.00 bits/sec  sender
>>> [  4]   0.00-1.10   sec  28.2 MBytes   214 Mbits/sec  
>>> receiver
>>> iperf3: interrupt - the client has terminated
>>>
>>> Neil
>> Ok, here goes another incremental patch. If this doesn't work can
>> you please send me a link to the spec of the board you are using ?
> Sorry for the delay...
>
> Not better, sorry.
>
> $ iperf3 -c 10.1.3.201 -p 5202 -R -t 0
> Connecting to host 10.1.3.201, port 5202
> Reverse mode, remote host 10.1.3.201 is sending
> [  4] local 10.1.2.12 port 60612 connected to 10.1.3.201 port 5202
> [ ID] Interval   Transfer Bandwidth
> [  4]   0.00-1.00   sec   110 MBytes   920 Mbits/sec
> [  4]   1.00-2.00   sec   110 MBytes   926 Mbits/sec
> [  4]   2.00-3.00   sec  1.94 MBytes  16.3 Mbits/sec
> [  4]   3.00-4.00   sec  0.00 Bytes  0.00 bits/sec
> ^C[  4]   4.00-4.76   sec  0.00 Bytes  0.00 bits/sec
> - - - - - - - - - - - - - - - - - - - - - - - - -
> [ ID] Interval   Transfer Bandwidth
> [  4]   0.00-4.76   sec  0.00 Bytes  0.00 bits/sec  sender
> [  4]   0.00-4.76   sec   222 MBytes   391 Mbits/sec  receiver
> iperf3: interrupt - the client has terminated
>
> The board is the Amlogic S400 with the A113D SoC, sorry there is no public 
> spec for this board and for this SoC.

Thanks for testing. I will send a new version with major
differences, if you could validate it it would be great.

Thanks and Best Regards,
Jose Miguel Abreu

>
> Neil
>
>> Thanks and Best Regards,
>> Jose Miguel Abreu
>>



Re: [PATCH net-next v2 1/2] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-12 Thread Jose Abreu
Hi Florian,

Thanks for your input.

On 10-09-2018 20:22, Florian Fainelli wrote:
> On 09/10/2018 02:14 AM, Jose Abreu wrote:
>> This follows David Miller advice and tries to fix coalesce timer in
>> multi-queue scenarios.
>>
>> We are now using per-queue coalesce values and per-queue TX timer.
>>
>> Coalesce timer default values was changed to 1ms and the coalesce frames
>> to 25.
>>
>> Tested in B2B setup between XGMAC2 and GMAC5.
> Why not revert the entire features for this merge window and work on
> getting it to work over the next weeks/merge windows?

It was already reverted but the performance drops a little bit
(not that much but I'm trying to fix it).

>
> The idea of using a timer to coalesce TX path when there is not a HW
> timer is a good idea and if this is made robust enough, you could even
> promote that as being a network stack library/feature that could be used
> by other drivers. In fact, this could be a great addition to the net DIM
> library (Tal, what do you think?)
>
> Here's a quick drive by review of things that appear wrong in the
> current driver (without your patches):
>
> - in stmmac_xmit(), in case we hit the !is_jumbo branch and we fail the
> DMA mapping, there is no timer cancellation, don't we want to abort the
> whole transmission?

I don't think this is needed because then tx pointer will not
advance and in stmmac_tx_clean we just won't perform any work.
Besides, we can have a pending timer from previous packets
running so canceling it can cause some problems.

>
> - stmmac_tx_clean() should probably use netif_lock_bh() to guard against
> the timer (soft IRQ context) and the the NAPI context (also soft IRQ)
> running in parallel on two different CPUs. This may not explain all
> problems, but these two things are fundamentally exclusive, because the
> timer is meant to emulate the interrupt after N packets, while NAPI
> executes when such a thing did actually occur

Ok, and now I'm also using __netif_tx_lock_bh(queue) to just lock
per queue instead of the whole TX.

>
> - stmmac_poll() should cancel pending timer(s) if it was able to reclaim
> packets, likewise stmmac_tx_timer() should re-enable TX interrupts if it
> reclaimed packets, since TX interrupts could have been left disabled
> from a prior NAPI run. These could be considered optimizations, since
> you could leave the TX timer running all the time, just adjust the
> deadline (based on line rate, MTU, IPG, number of fragments and their
> respective length), worst case, both NAPI and the timer clean up your TX
> ring, so you should always have room to push more packets

In next version I'm dropping the direct call to stmmac_tx_clean()
in the timer function and just scheduling NAPI instead.

Thanks and Best Regards,
Jose Miguel Abreu


Re: [PATCH net-next v2 2/2] net: stmmac: Fixup the tail addr setting in xmit path

2018-09-12 Thread Jose Abreu
Hi Florian,

On 10-09-2018 19:46, Florian Fainelli wrote:
>
> Can you include the appropriate Fixes tag here so this can easily be
> backported to relevant stable branches?

Well I guess it goes since forever but it can only cause a major
impact in xgmac2 operation, remaining shall be okay.

I didn't add a Fixes tag because xgmac2 was merged quite recently
... Will add in next version.

Thanks and Best Regards,
Jose Miguel Abreu


Re: [net-next, v2, 1/2] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-11 Thread Jose Abreu
On 10-09-2018 19:15, Neil Armstrong wrote:
>
> RX is still ok but now TX fails almost immediately...
>
> With 100ms report :
>
> $ iperf3 -c 192.168.1.47 -t 0 -p 5202 -R -i 0.1
> Connecting to host 192.168.1.47, port 5202
> Reverse mode, remote host 192.168.1.47 is sending
> [  4] local 192.168.1.45 port 45900 connected to 192.168.1.47 port 5202
> [ ID] Interval   Transfer Bandwidth
> [  4]   0.00-0.10   sec  10.9 MBytes   913 Mbits/sec
> [  4]   0.10-0.20   sec  11.0 MBytes   923 Mbits/sec
> [  4]   0.20-0.30   sec  6.34 MBytes   532 Mbits/sec
> [  4]   0.30-0.40   sec  0.00 Bytes  0.00 bits/sec
> [  4]   0.40-0.50   sec  0.00 Bytes  0.00 bits/sec
> [  4]   0.50-0.60   sec  0.00 Bytes  0.00 bits/sec
> [  4]   0.60-0.70   sec  0.00 Bytes  0.00 bits/sec
> [  4]   0.70-0.80   sec  0.00 Bytes  0.00 bits/sec
> [  4]   0.80-0.90   sec  0.00 Bytes  0.00 bits/sec
> [  4]   0.90-1.00   sec  0.00 Bytes  0.00 bits/sec
> [  4]   1.00-1.10   sec  0.00 Bytes  0.00 bits/sec
> ^C[  4]   1.10-1.10   sec  0.00 Bytes  0.00 bits/sec
> - - - - - - - - - - - - - - - - - - - - - - - - -
> [ ID] Interval   Transfer Bandwidth
> [  4]   0.00-1.10   sec  0.00 Bytes  0.00 bits/sec  sender
> [  4]   0.00-1.10   sec  28.2 MBytes   214 Mbits/sec  receiver
> iperf3: interrupt - the client has terminated
>
> Neil

Ok, here goes another incremental patch. If this doesn't work can
you please send me a link to the spec of the board you are using ?

Thanks and Best Regards,
Jose Miguel Abreu

>From d6c3bc9c282eadfa754bd78e7c7447a200dd1737 Mon Sep 17 00:00:00 2001
Message-Id: 
From: Jose Abreu 
Date: Tue, 11 Sep 2018 10:15:31 +0200
Subject: [PATCH] fixup_coalesce_4

Signed-off-by: Jose Abreu 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 31 ++-
 1 file changed, 13 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index f6587ee372ab..b6d661f17bd7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1857,17 +1857,14 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
  * @queue: TX queue index
  * Description: it reclaims the transmit resources after transmission completes.
  */
-static int stmmac_tx_clean(struct stmmac_priv *priv, int limit, u32 queue,
-			   bool *more)
+static bool stmmac_tx_clean(struct stmmac_priv *priv, u32 queue)
 {
 	struct stmmac_tx_queue *tx_q = >tx_queue[queue];
 	unsigned int bytes_compl = 0, pkts_compl = 0;
+	bool has_more = false;
 	unsigned int entry;
 
-	netif_tx_lock(priv->dev);
-
-	if (more)
-		*more = false;
+	netif_tx_lock_bh(priv->dev);
 
 	priv->xstats.tx_clean++;
 
@@ -1956,12 +1953,12 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int limit, u32 queue,
 		mod_timer(>eee_ctrl_timer, STMMAC_LPI_T(eee_timer));
 	}
 
-	if (more && (tx_q->dirty_tx != tx_q->cur_tx))
-		*more = true;
+	if (tx_q->dirty_tx != tx_q->cur_tx)
+		has_more = true;
 
-	netif_tx_unlock(priv->dev);
+	netif_tx_unlock_bh(priv->dev);
 
-	return pkts_compl;
+	return has_more;
 }
 
 /**
@@ -2257,10 +2254,9 @@ static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue)
 static void stmmac_tx_timer(struct timer_list *t)
 {
 	struct stmmac_tx_queue *tx_q = from_timer(tx_q, t, txtimer);
-	struct stmmac_priv *priv = tx_q->priv_data;
-	bool more;
 
-	stmmac_tx_clean(priv, ~0, tx_q->queue_index, );
+	if (likely(napi_schedule_prep(_q->napi)))
+		__napi_schedule(_q->napi);
 }
 
 /**
@@ -3562,15 +3558,14 @@ static int stmmac_tx_poll(struct napi_struct *napi, int budget)
 		container_of(napi, struct stmmac_tx_queue, napi);
 	struct stmmac_priv *priv = tx_q->priv_data;
 	u32 chan = tx_q->queue_index;
-	int work_done = 0;
 
 	priv->xstats.napi_poll++;
 
-	work_done = stmmac_tx_clean(priv, budget, chan, NULL);
-	if (work_done < budget)
-		napi_complete_done(napi, work_done);
+	if (stmmac_tx_clean(priv, chan))
+		return budget;
 
-	return min(work_done, budget);
+	napi_complete_done(napi, 0);
+	return 0;
 }
 
 /**
-- 
2.7.4



Re: [net-next, v2, 1/2] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-10 Thread Jose Abreu
On 10-09-2018 16:49, Neil Armstrong wrote:
> Hi Jose,
>
> On 10/09/2018 16:44, Jose Abreu wrote:
>> On 10-09-2018 14:46, Neil Armstrong wrote:
>>> hi Jose,
>>>
>>> On 10/09/2018 14:55, Jose Abreu wrote:
>>>> On 10-09-2018 13:52, Jose Abreu wrote:
>>>>> Can you please try attached follow-up patch ? 
>>>> Oh, please apply the whole series otherwise this will not apply
>>>> cleanly.
>>> Indeed, it helps!
>>>
>>> With the fixups, it fails later, around 15s instead of 3, in RX and TX.
>> Thanks for testing Neil. What if we keep rearming the timer
>> whilst there are pending packets ? Something like in the attach.
>> (applies on top of previous one).
> It fixes RX, but TX fails after ~13s.

Ok :(

Can you please try attached follow-up patch ?

I'm so sorry about this back and forth and I appreciate all your
help .

Thanks and Best Regards,
Jose Miguel Abreu


>
> Neil
>
>> Thanks and Best Regards,
>> Jose Miguel Abreu
>>

>From 4f2ba5fca6c8858cfe640f3d466fd01904c451e3 Mon Sep 17 00:00:00 2001
Message-Id: <4f2ba5fca6c8858cfe640f3d466fd01904c451e3.1536596296.git.joab...@synopsys.com>
From: Jose Abreu 
Date: Mon, 10 Sep 2018 18:18:10 +0200
Subject: [PATCH] fixup_coalesce_3

Signed-off-by: Jose Abreu 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 25 ++-
 1 file changed, 6 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 76a6196b3263..f6587ee372ab 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2245,11 +2245,7 @@ static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue)
 {
 	struct stmmac_tx_queue *tx_q = >tx_queue[queue];
 
-	if (tx_q->tx_timer_active)
-		return;
-
 	mod_timer(_q->txtimer, STMMAC_COAL_TIMER(priv->tx_coal_timer));
-	tx_q->tx_timer_active = true;
 }
 
 /**
@@ -2264,10 +2260,7 @@ static void stmmac_tx_timer(struct timer_list *t)
 	struct stmmac_priv *priv = tx_q->priv_data;
 	bool more;
 
-	tx_q->tx_timer_active = false;
 	stmmac_tx_clean(priv, ~0, tx_q->queue_index, );
-	if (more)
-		stmmac_tx_timer_arm(priv, tx_q->queue_index);
 }
 
 /**
@@ -2866,9 +2859,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* Compute header lengths */
 	proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
 
-	/* Start coalesce timer earlier in case TX Queue is stopped */
-	stmmac_tx_timer_arm(priv, queue);
-
 	/* Desc availability based on threshold should be enough safe */
 	if (unlikely(stmmac_tx_avail(priv, queue) <
 		(((skb->len - proto_hdr_len) / TSO_MAX_BUFF_SIZE + 1 {
@@ -2975,6 +2965,8 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 		stmmac_set_tx_ic(priv, desc);
 		priv->xstats.tx_set_ic_bit++;
 		tx_q->tx_count_frames = 0;
+	} else {
+		stmmac_tx_timer_arm(priv, queue);
 	}
 
 	skb_tx_timestamp(skb);
@@ -3065,9 +3057,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
 			return stmmac_tso_xmit(skb, dev);
 	}
 
-	/* Start coalesce timer earlier in case TX Queue is stopped */
-	stmmac_tx_timer_arm(priv, queue);
-
 	if (unlikely(stmmac_tx_avail(priv, queue) < nfrags + 1)) {
 		if (!netif_tx_queue_stopped(netdev_get_tx_queue(dev, queue))) {
 			netif_tx_stop_queue(netdev_get_tx_queue(priv->dev,
@@ -3186,6 +3175,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
 		stmmac_set_tx_ic(priv, desc);
 		priv->xstats.tx_set_ic_bit++;
 		tx_q->tx_count_frames = 0;
+	} else {
+		stmmac_tx_timer_arm(priv, queue);
 	}
 
 	skb_tx_timestamp(skb);
@@ -3572,16 +3563,12 @@ static int stmmac_tx_poll(struct napi_struct *napi, int budget)
 	struct stmmac_priv *priv = tx_q->priv_data;
 	u32 chan = tx_q->queue_index;
 	int work_done = 0;
-	bool more;
 
 	priv->xstats.napi_poll++;
 
-	work_done = stmmac_tx_clean(priv, budget, chan, );
-	if (work_done < budget) {
+	work_done = stmmac_tx_clean(priv, budget, chan, NULL);
+	if (work_done < budget)
 		napi_complete_done(napi, work_done);
-		if (more)
-			napi_reschedule(napi);
-	}
 
 	return min(work_done, budget);
 }
-- 
2.7.4



Re: [net-next, v2, 1/2] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-10 Thread Jose Abreu
On 10-09-2018 14:46, Neil Armstrong wrote:
> hi Jose,
>
> On 10/09/2018 14:55, Jose Abreu wrote:
>> On 10-09-2018 13:52, Jose Abreu wrote:
>>> Can you please try attached follow-up patch ? 
>> Oh, please apply the whole series otherwise this will not apply
>> cleanly.
> Indeed, it helps!
>
> With the fixups, it fails later, around 15s instead of 3, in RX and TX.

Thanks for testing Neil. What if we keep rearming the timer
whilst there are pending packets ? Something like in the attach.
(applies on top of previous one).

Thanks and Best Regards,
Jose Miguel Abreu
>From 5d5a6bd882006f14c59b351f4324160115f818c0 Mon Sep 17 00:00:00 2001
Message-Id: <5d5a6bd882006f14c59b351f4324160115f818c0.1536590220.git.joab...@synopsys.com>
From: Jose Abreu 
Date: Mon, 10 Sep 2018 16:36:37 +0200
Subject: [PATCH] fixup_coalesce_2

Signed-off-by: Jose Abreu 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 7875e81966fb..76a6196b3263 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2262,9 +2262,12 @@ static void stmmac_tx_timer(struct timer_list *t)
 {
 	struct stmmac_tx_queue *tx_q = from_timer(tx_q, t, txtimer);
 	struct stmmac_priv *priv = tx_q->priv_data;
+	bool more;
 
-	stmmac_tx_clean(priv, ~0, tx_q->queue_index, NULL);
 	tx_q->tx_timer_active = false;
+	stmmac_tx_clean(priv, ~0, tx_q->queue_index, );
+	if (more)
+		stmmac_tx_timer_arm(priv, tx_q->queue_index);
 }
 
 /**
-- 
2.7.4



Re: [net-next, v2, 1/2] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-10 Thread Jose Abreu
On 10-09-2018 13:52, Jose Abreu wrote:
>
> Can you please try attached follow-up patch ? 

Oh, please apply the whole series otherwise this will not apply
cleanly.

Thanks and Best Regards,
Jose Miguel Abreu




Re: [net-next, v2, 1/2] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-10 Thread Jose Abreu
Hi Neil,

On 10-09-2018 12:43, Neil Armstrong wrote:
> Hi Jose,
>
> On 10/09/2018 11:14, Jose Abreu wrote:
>> This follows David Miller advice and tries to fix coalesce timer in
>> multi-queue scenarios.
>>
>> We are now using per-queue coalesce values and per-queue TX timer.
>>
>> Coalesce timer default values was changed to 1ms and the coalesce frames
>> to 25.
>>
>> Tested in B2B setup between XGMAC2 and GMAC5.
>>
>> Signed-off-by: Jose Abreu 
>> Cc: Jerome Brunet 
>> Cc: Martin Blumenstingl 
>> Cc: David S. Miller 
>> Cc: Joao Pinto 
>> Cc: Giuseppe Cavallaro 
>> Cc: Alexandre Torgue 
>> ---
>> Jerome,
> Jerome is in holidays...
>
>> Can you please test if this one is okay ?
>
> I tested this patch on top of 4.18.7 with the previous patch (4ae0169fd1b3) 
> reverted.
>
> The TX or RX stopped a few seconds after iperf3 started :
> (iperf3 is running in server mode on the Amlogic A113D board)
>
> $ iperf3 -c 10.1.4.95
> Connecting to host 10.1.4.95, port 5201
> [  4] local 10.1.2.12 port 39906 connected to 10.1.4.95 port 5201
> [ ID] Interval   Transfer Bandwidth   Retr  Cwnd
> [  4]   0.00-1.00   sec  56.2 MBytes   472 Mbits/sec0660 KBytes
> [  4]   1.00-2.00   sec  56.2 MBytes   472 Mbits/sec0660 KBytes
> [  4]   2.00-3.00   sec  38.8 MBytes   325 Mbits/sec1   1.41 KBytes
> [  4]   3.00-4.00   sec  0.00 Bytes  0.00 bits/sec1   1.41 KBytes
> [  4]   4.00-5.00   sec  0.00 Bytes  0.00 bits/sec1   1.41 KBytes
> ^C[  4]   5.00-5.61   sec  0.00 Bytes  0.00 bits/sec0   1.41 KBytes
> - - - - - - - - - - - - - - - - - - - - - - - - -
> [ ID] Interval   Transfer Bandwidth   Retr
> [  4]   0.00-5.61   sec   151 MBytes   226 Mbits/sec3 sender
> [  4]   0.00-5.61   sec  0.00 Bytes  0.00 bits/sec  receiver
> iperf3: interrupt - the client has terminated
>
> $ iperf3 -c 10.1.4.95 -R
> Connecting to host 10.1.4.95, port 5201
> Reverse mode, remote host 10.1.4.95 is sending
> [  4] local 10.1.2.12 port 39894 connected to 10.1.4.95 port 5201
> [ ID] Interval   Transfer Bandwidth
> [  4]   0.00-1.00   sec  82.2 MBytes   690 Mbits/sec
> [  4]   1.00-2.00   sec  82.6 MBytes   693 Mbits/sec
> [  4]   2.00-3.00   sec  24.2 MBytes   203 Mbits/sec
> [  4]   3.00-4.00   sec  0.00 Bytes  0.00 bits/sec
> [  4]   4.00-5.00   sec  0.00 Bytes  0.00 bits/sec
> ^C[  4]   5.00-5.53   sec  0.00 Bytes  0.00 bits/sec
> - - - - - - - - - - - - - - - - - - - - - - - - -
> [ ID] Interval   Transfer Bandwidth
> [  4]   0.00-5.53   sec  0.00 Bytes  0.00 bits/sec  sender
> [  4]   0.00-5.53   sec   189 MBytes   287 Mbits/sec  receiver
> iperf3: interrupt - the client has terminated
>
> These works for hours without this patch applied.

Damn... I'm able to replicate the issue if I turn SMP off but
it's not consistent ...

Can you please try attached follow-up patch ? It's been running
for 10min now and I'm getting ~700Mbps on the same GMAC as you
have (3.71).

Thanks and Best Regards,
Jose Miguel Abreu

>
> Neil
>
>> Thanks and Best Regards,
>> Jose Miguel Abreu
>> ---
>>  drivers/net/ethernet/stmicro/stmmac/common.h  |   4 +-
>>  drivers/net/ethernet/stmicro/stmmac/stmmac.h  |   6 +-
>>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 207 
>> ++
>>  3 files changed, 135 insertions(+), 82 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
>> b/drivers/net/ethernet/stmicro/stmmac/common.h
>> index 1854f270ad66..b1b305f8f414 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
>> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
>> @@ -258,10 +258,10 @@ struct stmmac_safety_stats {
>>  #define MAX_DMA_RIWT0xff
>>  #define MIN_DMA_RIWT0x20
>>  /* Tx coalesce parameters */
>> -#define STMMAC_COAL_TX_TIMER4
>> +#define STMMAC_COAL_TX_TIMER1000
>>  #define STMMAC_MAX_COAL_TX_TICK 10
>>  #define STMMAC_TX_MAX_FRAMES256
>> -#define STMMAC_TX_FRAMES64
>> +#define STMMAC_TX_FRAMES25
>>  
>>  /* Packets types */
>>  enum packets_types {
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h 
>> b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
>> index c0a855b7ab3b..957030cfb833 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
>> @@ -48,6 +48,9 @@ struct stmmac_tx_info {
>>  
>>  /* Frequently used values are kept adjacent for c

[PATCH net-next v2 1/2] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-10 Thread Jose Abreu
This follows David Miller advice and tries to fix coalesce timer in
multi-queue scenarios.

We are now using per-queue coalesce values and per-queue TX timer.

Coalesce timer default values was changed to 1ms and the coalesce frames
to 25.

Tested in B2B setup between XGMAC2 and GMAC5.

Signed-off-by: Jose Abreu 
Cc: Jerome Brunet 
Cc: Martin Blumenstingl 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
Jerome,

Can you please test if this one is okay ?

Thanks and Best Regards,
Jose Miguel Abreu
---
 drivers/net/ethernet/stmicro/stmmac/common.h  |   4 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |   6 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 207 ++
 3 files changed, 135 insertions(+), 82 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
b/drivers/net/ethernet/stmicro/stmmac/common.h
index 1854f270ad66..b1b305f8f414 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -258,10 +258,10 @@ struct stmmac_safety_stats {
 #define MAX_DMA_RIWT   0xff
 #define MIN_DMA_RIWT   0x20
 /* Tx coalesce parameters */
-#define STMMAC_COAL_TX_TIMER   4
+#define STMMAC_COAL_TX_TIMER   1000
 #define STMMAC_MAX_COAL_TX_TICK10
 #define STMMAC_TX_MAX_FRAMES   256
-#define STMMAC_TX_FRAMES   64
+#define STMMAC_TX_FRAMES   25
 
 /* Packets types */
 enum packets_types {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h 
b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index c0a855b7ab3b..957030cfb833 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -48,6 +48,9 @@ struct stmmac_tx_info {
 
 /* Frequently used values are kept adjacent for cache effect */
 struct stmmac_tx_queue {
+   u32 tx_count_frames;
+   int tx_timer_active;
+   struct timer_list txtimer;
u32 queue_index;
struct stmmac_priv *priv_data;
struct dma_extended_desc *dma_etx cacheline_aligned_in_smp;
@@ -59,6 +62,7 @@ struct stmmac_tx_queue {
dma_addr_t dma_tx_phy;
u32 tx_tail_addr;
u32 mss;
+   struct napi_struct napi cacheline_aligned_in_smp;
 };
 
 struct stmmac_rx_queue {
@@ -109,14 +113,12 @@ struct stmmac_pps_cfg {
 
 struct stmmac_priv {
/* Frequently used values are kept adjacent for cache effect */
-   u32 tx_count_frames;
u32 tx_coal_frames;
u32 tx_coal_timer;
 
int tx_coalesce;
int hwts_tx_en;
bool tx_path_in_lpi_mode;
-   struct timer_list txtimer;
bool tso;
 
unsigned int dma_buf_sz;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9f458bb16f2a..9809c2b319fe 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -148,6 +148,7 @@ static void stmmac_verify_args(void)
 static void stmmac_disable_all_queues(struct stmmac_priv *priv)
 {
u32 rx_queues_cnt = priv->plat->rx_queues_to_use;
+   u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
u32 queue;
 
for (queue = 0; queue < rx_queues_cnt; queue++) {
@@ -155,6 +156,12 @@ static void stmmac_disable_all_queues(struct stmmac_priv 
*priv)
 
napi_disable(_q->napi);
}
+
+   for (queue = 0; queue < tx_queues_cnt; queue++) {
+   struct stmmac_tx_queue *tx_q = >tx_queue[queue];
+
+   napi_disable(_q->napi);
+   }
 }
 
 /**
@@ -164,6 +171,7 @@ static void stmmac_disable_all_queues(struct stmmac_priv 
*priv)
 static void stmmac_enable_all_queues(struct stmmac_priv *priv)
 {
u32 rx_queues_cnt = priv->plat->rx_queues_to_use;
+   u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
u32 queue;
 
for (queue = 0; queue < rx_queues_cnt; queue++) {
@@ -171,6 +179,12 @@ static void stmmac_enable_all_queues(struct stmmac_priv 
*priv)
 
napi_enable(_q->napi);
}
+
+   for (queue = 0; queue < tx_queues_cnt; queue++) {
+   struct stmmac_tx_queue *tx_q = >tx_queue[queue];
+
+   napi_enable(_q->napi);
+   }
 }
 
 /**
@@ -1843,7 +1857,8 @@ static void stmmac_dma_operation_mode(struct stmmac_priv 
*priv)
  * @queue: TX queue index
  * Description: it reclaims the transmit resources after transmission 
completes.
  */
-static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue)
+static int stmmac_tx_clean(struct stmmac_priv *priv, int limit, u32 queue,
+  bool *more)
 {
struct stmmac_tx_queue *tx_q = >tx_queue[queue];
unsigned int bytes_compl = 0, pkts_compl = 0;
@@ -1851,10 +1866,13 @@ static void stmmac_tx_clean(struct stmmac_priv *priv, 
u32 queue)
 
netif_tx_lock(priv->dev);
 
+   if (more)
+ 

[PATCH net-next v2 0/2] net: stmmac: Coalesce and tail addr fixes

2018-09-10 Thread Jose Abreu
The fix for coalesce timer and a fix in tail address setting that impacts
XGMAC2 operation.

Cc: Jerome Brunet 
Cc: Martin Blumenstingl 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 

Jose Abreu (2):
  net: stmmac: Rework coalesce timer and fix multi-queue races
  net: stmmac: Fixup the tail addr setting in xmit path

 drivers/net/ethernet/stmicro/stmmac/common.h  |   4 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |   6 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 212 ++
 3 files changed, 138 insertions(+), 84 deletions(-)

-- 
2.7.4




[PATCH net-next v2 2/2] net: stmmac: Fixup the tail addr setting in xmit path

2018-09-10 Thread Jose Abreu
Currently we are always setting the tail address of descriptor list to
the end of the pre-allocated list.

According to databook this is not correct. Tail address should point to
the last available descriptor + 1, which means we have to update the
tail address everytime we call the xmit function.

This should make no impact in older versions of MAC but in newer
versions there are some DMA features which allows the IP to fetch
descriptors in advance and in a non sequential order so its critical
that we set the tail address correctly.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9809c2b319fe..97268769186e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2229,8 +2229,7 @@ static int stmmac_init_dma_engine(struct stmmac_priv 
*priv)
stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
tx_q->dma_tx_phy, chan);
 
-   tx_q->tx_tail_addr = tx_q->dma_tx_phy +
-   (DMA_TX_SIZE * sizeof(struct dma_desc));
+   tx_q->tx_tail_addr = tx_q->dma_tx_phy;
stmmac_set_tx_tail_ptr(priv, priv->ioaddr,
   tx_q->tx_tail_addr, chan);
}
@@ -3007,6 +3006,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, 
struct net_device *dev)
 
netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len);
 
+   tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc));
stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);
 
if (priv->tx_coal_timer && !tx_q->tx_timer_active) {
@@ -3218,6 +3218,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, 
struct net_device *dev)
 
stmmac_enable_dma_transmission(priv, priv->ioaddr);
 
+   tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc));
stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);
 
if (priv->tx_coal_timer && !tx_q->tx_timer_active) {
-- 
2.7.4




[PATCH net-next] net: stmmac: Enable TC Ops for GMAC >= 4

2018-09-06 Thread Jose Abreu
GMAC >= 4 also supports CBS. Lets enable the TC Ops for these versions.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/hwif.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c 
b/drivers/net/ethernet/stmicro/stmmac/hwif.c
index d9a34a4d08b3..81b966a8261b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
@@ -133,7 +133,7 @@ static const struct stmmac_hwif_entry {
.mac = _ops,
.hwtimestamp = _ptp,
.mode = NULL,
-   .tc = NULL,
+   .tc = _tc_ops,
.setup = dwmac4_setup,
.quirks = stmmac_dwmac4_quirks,
}, {
@@ -150,7 +150,7 @@ static const struct stmmac_hwif_entry {
.mac = _ops,
.hwtimestamp = _ptp,
.mode = _ring_mode_ops,
-   .tc = NULL,
+   .tc = _tc_ops,
.setup = dwmac4_setup,
.quirks = NULL,
}, {
@@ -167,7 +167,7 @@ static const struct stmmac_hwif_entry {
.mac = _ops,
.hwtimestamp = _ptp,
.mode = _ring_mode_ops,
-   .tc = NULL,
+   .tc = _tc_ops,
.setup = dwmac4_setup,
.quirks = NULL,
}, {
-- 
2.7.4




Re: [PATCH net-next 1/2] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-04 Thread Jose Abreu
Hi Jerome,

On 04-09-2018 13:27, Jerome Brunet wrote:
> On Tue, 2018-09-04 at 10:57 +0100, Jose Abreu wrote:
>> Hi Jerome,
>>
>> On 03-09-2018 17:22, Jerome Brunet wrote:
>>> Situation is even worse with this.
>>> I'm using an NFS root filesystem. With your fixup, I'm not reaching the 
>>> prompt
>>> anymore. Looks like a the same kind of network breakdown we had previously
>>>
>> I was able to reproduce your problem and the attached fixup patch
>> fixed it up for me. Can you please try?
> I suppose this applies on top the initial patch, not the previous fixup
> (judging from the rejection) Could you details the baseline for each
> patch you send, its not easy to follow.
>
> BTW, there something weird (at least for me) with the patch you attach.
> git always refuse to apply them and even patch complains:
>
> git apply fixup2.patch
> error: patch failed: drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:1861
> error: drivers/net/ethernet/stmicro/stmmac/stmmac_main.c: patch does not apply
>
> patch -p1 < fixup2.patch
> (Stripping trailing CRs from patch; use --binary to disable.)
> patching file drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> Hunk #6 succeeded at 2252 (offset 1 line).   
> patch unexpectedly ends in middle of line
> patch unexpectedly ends in middle of line

I just do "git diff  > out.patch". Maybe not the best thing
to do then.

>
> Anyway, with this second fixup, I'm back to square one:
> I can boot but iperf3 won't hold for long
>
>
> # iperf3 -c 10.1.2.124 -p 12345 -t 600
> Connecting to host 10.1.2.124, port 12345
> [  4] local 10.1.4.59 port 38650 connected to 10.1.2.124 port 12345
> [ ID] Interval   Transfer Bandwidth   Retr  Cwnd
> [  4]   0.00-1.00   sec  80.8 MBytes   678 Mbits/sec1300 KBytes
> [  4]   1.00-2.00   sec  81.1 MBytes   680 Mbits/sec0329 KBytes
> [  4]   2.00-3.00   sec  80.7 MBytes   677 Mbits/sec0335 KBytes
> [  4]   3.00-4.00   sec  81.7 MBytes   685 Mbits/sec0337 KBytes
> [  4]   4.00-5.00   sec  81.0 MBytes   680 Mbits/sec0341 KBytes
> [  4]   5.00-6.00   sec  81.0 MBytes   680 Mbits/sec0344 KBytes
> [  4]   6.00-7.00   sec  80.7 MBytes   677 Mbits/sec0345 KBytes
> [  4]   7.00-8.00   sec  81.5 MBytes   684 Mbits/sec0346 KBytes
> [  4]   8.00-9.00   sec  81.2 MBytes   680 Mbits/sec0348 KBytes
> [  4]   9.00-10.00  sec  5.59 MBytes  46.9 Mbits/sec2   1.41 KBytes
> [  4]  10.00-11.00  sec  0.00 Bytes  0.00 bits/sec1   1.41 KBytes
> [  4]  11.00-12.00  sec  0.00 Bytes  0.00 bits/sec0   1.41 KBytes
> [  4]  12.00-13.00  sec  0.00 Bytes  0.00 bits/sec1   1.41 KBytes
> [  4]  13.00-14.00  sec  0.00 Bytes  0.00 bits/sec0   1.41 KBytes

Okay, so this is odd because I now have a similar setup as yours
and is working perfectly fine:

---
# dmesg | grep -i stmmac
stmmaceth f0008000.ethernet: PTP uses main clock
stmmaceth f0008000.ethernet: User ID: 0x10, Synopsys ID: 0x37
stmmaceth f0008000.ethernet:DWMAC1000
stmmaceth f0008000.ethernet: DMA HW capability register supported
stmmaceth f0008000.ethernet: RX Checksum Offload Engine supported
stmmaceth f0008000.ethernet: COE Type 2
stmmaceth f0008000.ethernet: TX Checksum insertion supported
stmmaceth f0008000.ethernet: Normal descriptors
stmmaceth f0008000.ethernet: Ring mode enabled
stmmaceth f0008000.ethernet: Enable RX Mitigation via HW Watchdog
Timer
libphy: stmmac: probed
stmmaceth f0008000.ethernet eth0: device MAC address
0e:67:f6:6c:59:c6
Micrel KSZ9031 Gigabit PHY stmmac-0:00: attached PHY driver
[Micrel KSZ9031 Gigabit PHY] (mii_bus:phy_addr=stmmac-0:00, irq=POLL)
stmmaceth f0008000.ethernet eth0: No Safety Features support found
stmmaceth f0008000.ethernet eth0: PTP not supported by HW
stmmaceth f0008000.ethernet eth0: Link is Up - 1Gbps/Full - flow
control off
stmmaceth f0008000.ethernet eth0: Link is Down
stmmaceth f0008000.ethernet eth0: Link is Up - 1Gbps/Full - flow
control off

---
# iperf3 -c 192.168.0.3 -t 600
Connecting to host 192.168.0.3, port 5201
[  4] local 192.168.0.1 port 46796 connected to 192.168.0.3 port 5201
[ ID] Interval   Transfer Bandwidth   Retr  Cwnd
[  4]   0.00-1.01   sec   101 MBytes   841 Mbits/sec1467
KBytes
[  4]   1.01-2.00   sec   112 MBytes   945 Mbits/sec0475
KBytes
[  4]   2.00-3.01   sec   114 MBytes   947 Mbits/sec0481
KBytes
[  4]   3.01-4.00   sec   112 MBytes   945 Mbits/sec0486
KBytes
[  4]   4.00-5.00   sec   113 MBytes   947 Mbits/sec0506
KBytes
[  4]   5.00-6.01   sec   113 MBytes   947 Mbits/sec0520
KBytes
[  4]   6.01-7.00   sec   112 MBytes   950 Mbits/sec0625
KBytes
[  4]   7.00-8.01   sec   114 MBytes   948 Mbits/sec0625
KBytes
[  4] 

Re: [RFT net-next] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-04 Thread Jose Abreu



On 04-09-2018 10:16, Jerome Brunet wrote:
> On Mon, 2018-09-03 at 16:47 +0100, Jose Abreu wrote:
>> On 03-09-2018 16:38, Jerome Brunet wrote:
>>> On Mon, 2018-09-03 at 16:22 +0100, Jose Abreu wrote:
>>>> On 03-09-2018 15:10, Jerome Brunet wrote:
>>>>> On Mon, 2018-09-03 at 12:47 +0100, Jose Abreu wrote:
>>>>>> On 03-09-2018 11:16, Jerome Brunet wrote:
>>>>>>> No notable change. Rx is fine but Tx:
>>>>>>> [  5]   3.00-4.00   sec  3.55 MBytes  29.8 Mbits/sec   51   12.7 KBytes
>>>>>>>
>>>>>>> I suppose the problem as something to do with the retries. When doing 
>>>>>>> Tx test
>>>>>>> alone, we don't have such a things a throughput where we expect it to 
>>>>>>> be.
>>>>>> Yeah, I just remembered you are not using GMAC4 so it wouldn't
>>>>>> make a difference. Is your version 3.710? If so please try adding
>>>>>> the following compatible to your DT bindings "snps,dwmac-3.710".
>>>>> According to the documentation, it is a 3.70a but I learn (the hard way) 
>>>>> not to
>>>>> trust the documentation too much. Is there anyway to make sure which 
>>>>> version we
>>>>> have. Like a register to read ?
>>>> It should be dumped at probe by a string like this one:
>>>>
>>>> "User ID: 0xXY, Synopsys ID: 0xXZ"
>>> User ID: 0x11, Synopsys ID: 0x37 ? What to does it map to ?
>> Its 3.7. As for the User ID this can be changed by final HW team
>> so I can't confirm what it means.
>>
> Is there anyway to know if it is a 3.70a or 3.71 ?

If the user ID wasn't changed from default then its 3.71.

>
>>>>> Out of curiosity, I changed the compatible to "snps,dwmac-3.710" anyway. 
>>>>> For
>>>>> some reason, the MDIO bus failed to register with this. Since it is not 
>>>>> the
>>>>> documented version, I did not check why.
>>>> No you can't change. You need to add it. So it should stay like this:
>>>>
>>>> compatible = "amlogic,meson-gxbb-dwmac", "snps,dwmac",
>>>> "snps,dwmac-3.710";
>>> Adding "snps,dwmac-3.710" does not change anything for me.
>>> Having both Tx and Rx at the same time still wreck Tx throughput 
>>> unfortunately 
>> Okay, so you said that there are lots of retries: can you disable
>> COE at all ? (it should be something like: ethtool -K eth0 rx off
>> tx off).
> Done but no change.

Ok. Are you able to analyze the sent / received packets using
pcap so that we can understand why there are lots of retries ?

Thanks and Best Regards,
Jose Miguel Abreu

>
>> Thanks and Best Regards,
>> Jose Miguel Abreu
>>
>>>> Thanks and Best Regards,
>>>> Jose Miguel Abreu
>>>>
>>>>>>> By the way, your mailer (and its auto 80 column rule I suppose) made 
>>>>>>> the patch
>>>>>>> below a bit harder to apply
>>>>>> Sorry. Next time I will send as attachment.
>>>>> No worries
>>>>>
>>>>>> Thanks and Best Regards,
>>>>>> Jose Miguel Abreu
>>
>



Re: [PATCH net-next 1/2] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-04 Thread Jose Abreu
Hi Jerome,

On 03-09-2018 17:22, Jerome Brunet wrote:
>
> Situation is even worse with this.
> I'm using an NFS root filesystem. With your fixup, I'm not reaching the prompt
> anymore. Looks like a the same kind of network breakdown we had previously
>

I was able to reproduce your problem and the attached fixup patch
fixed it up for me. Can you please try?

Thanks and Best Regards,
Jose Miguel Abreu
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 14f890f2a970..2cf927ccb409 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1861,14 +1861,14 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int limit, u32 queue)
 {
 	struct stmmac_tx_queue *tx_q = >tx_queue[queue];
 	unsigned int bytes_compl = 0, pkts_compl = 0;
-	unsigned int entry, count = 0;
+	unsigned int entry;
 
 	netif_tx_lock(priv->dev);
 
 	priv->xstats.tx_clean++;
 
 	entry = tx_q->dirty_tx;
-	while ((entry != tx_q->cur_tx) && (count < limit)) {
+	while ((entry != tx_q->cur_tx) && (pkts_compl < limit)) {
 		struct sk_buff *skb = tx_q->tx_skbuff[entry];
 		struct dma_desc *p;
 		int status;
@@ -1884,8 +1884,6 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int limit, u32 queue)
 		if (unlikely(status & tx_dma_own))
 			break;
 
-		count++;
-
 		/* Make sure descriptor fields are read after reading
 		 * the own bit.
 		 */
@@ -1955,7 +1953,7 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int limit, u32 queue)
 	}
 	netif_tx_unlock(priv->dev);
 
-	return count;
+	return pkts_compl;
 }
 
 /**
@@ -2072,8 +2070,11 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
 		if (likely(status[chan] & handle_rx)) {
 			struct stmmac_rx_queue *rx_q = >rx_queue[chan];
 
-			if (likely(napi_schedule_prep(_q->napi)))
+			if (likely(napi_schedule_prep(_q->napi))) {
+stmmac_disable_dma_irq(priv, priv->ioaddr,
+		   rx_q->queue_index);
 __napi_schedule(_q->napi);
+			}
 		}
 	}
 
@@ -2085,8 +2086,11 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
 		if (status[chan] & handle_tx) {
 			struct stmmac_tx_queue *tx_q = >tx_queue[chan];
 
-			if (likely(napi_schedule_prep(_q->napi)))
+			if (likely(napi_schedule_prep(_q->napi))) {
+stmmac_disable_dma_irq(priv, priv->ioaddr,
+		   tx_q->queue_index);
 __napi_schedule(_q->napi);
+			}
 		}
 	}
 
@@ -2247,11 +2251,7 @@ static void stmmac_tx_timer(struct timer_list *t)
 	struct stmmac_tx_queue *tx_q = from_timer(tx_q, t, txtimer);
 	struct stmmac_priv *priv = tx_q->priv_data;
 
-	if (napi_schedule_prep(_q->napi)) {
-		stmmac_disable_dma_irq(priv, priv->ioaddr, tx_q->queue_index);
-		__napi_schedule(_q->napi);
-	}
-
+	stmmac_tx_clean(priv, ~0, tx_q->queue_index);
 	tx_q->tx_timer_active = 0;
 }
 


Re: [RFT net-next] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-03 Thread Jose Abreu
On 03-09-2018 16:38, Jerome Brunet wrote:
> On Mon, 2018-09-03 at 16:22 +0100, Jose Abreu wrote:
>> On 03-09-2018 15:10, Jerome Brunet wrote:
>>> On Mon, 2018-09-03 at 12:47 +0100, Jose Abreu wrote:
>>>> On 03-09-2018 11:16, Jerome Brunet wrote:
>>>>> No notable change. Rx is fine but Tx:
>>>>> [  5]   3.00-4.00   sec  3.55 MBytes  29.8 Mbits/sec   51   12.7 KBytes
>>>>>
>>>>> I suppose the problem as something to do with the retries. When doing Tx 
>>>>> test
>>>>> alone, we don't have such a things a throughput where we expect it to be.
>>>> Yeah, I just remembered you are not using GMAC4 so it wouldn't
>>>> make a difference. Is your version 3.710? If so please try adding
>>>> the following compatible to your DT bindings "snps,dwmac-3.710".
>>> According to the documentation, it is a 3.70a but I learn (the hard way) 
>>> not to
>>> trust the documentation too much. Is there anyway to make sure which 
>>> version we
>>> have. Like a register to read ?
>> It should be dumped at probe by a string like this one:
>>
>> "User ID: 0xXY, Synopsys ID: 0xXZ"
> User ID: 0x11, Synopsys ID: 0x37 ? What to does it map to ?

Its 3.7. As for the User ID this can be changed by final HW team
so I can't confirm what it means.

>
>>> Out of curiosity, I changed the compatible to "snps,dwmac-3.710" anyway. For
>>> some reason, the MDIO bus failed to register with this. Since it is not the
>>> documented version, I did not check why.
>> No you can't change. You need to add it. So it should stay like this:
>>
>> compatible = "amlogic,meson-gxbb-dwmac", "snps,dwmac",
>> "snps,dwmac-3.710";
> Adding "snps,dwmac-3.710" does not change anything for me.
> Having both Tx and Rx at the same time still wreck Tx throughput 
> unfortunately 

Okay, so you said that there are lots of retries: can you disable
COE at all ? (it should be something like: ethtool -K eth0 rx off
tx off).

Thanks and Best Regards,
Jose Miguel Abreu

>
>> Thanks and Best Regards,
>> Jose Miguel Abreu
>>
>>>>> By the way, your mailer (and its auto 80 column rule I suppose) made the 
>>>>> patch
>>>>> below a bit harder to apply
>>>> Sorry. Next time I will send as attachment.
>>> No worries
>>>
>>>> Thanks and Best Regards,
>>>> Jose Miguel Abreu
>>
>



Re: [RFT net-next] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-03 Thread Jose Abreu
On 03-09-2018 15:10, Jerome Brunet wrote:
> On Mon, 2018-09-03 at 12:47 +0100, Jose Abreu wrote:
>> On 03-09-2018 11:16, Jerome Brunet wrote:
>>> No notable change. Rx is fine but Tx:
>>> [  5]   3.00-4.00   sec  3.55 MBytes  29.8 Mbits/sec   51   12.7 KBytes
>>>
>>> I suppose the problem as something to do with the retries. When doing Tx 
>>> test
>>> alone, we don't have such a things a throughput where we expect it to be.
>> Yeah, I just remembered you are not using GMAC4 so it wouldn't
>> make a difference. Is your version 3.710? If so please try adding
>> the following compatible to your DT bindings "snps,dwmac-3.710".
> According to the documentation, it is a 3.70a but I learn (the hard way) not 
> to
> trust the documentation too much. Is there anyway to make sure which version 
> we
> have. Like a register to read ?

It should be dumped at probe by a string like this one:

"User ID: 0xXY, Synopsys ID: 0xXZ"

>
> Out of curiosity, I changed the compatible to "snps,dwmac-3.710" anyway. For
> some reason, the MDIO bus failed to register with this. Since it is not the
> documented version, I did not check why.

No you can't change. You need to add it. So it should stay like this:

compatible = "amlogic,meson-gxbb-dwmac", "snps,dwmac",
"snps,dwmac-3.710";

Thanks and Best Regards,
Jose Miguel Abreu

>
>>> By the way, your mailer (and its auto 80 column rule I suppose) made the 
>>> patch
>>> below a bit harder to apply
>> Sorry. Next time I will send as attachment.
> No worries
>
>> Thanks and Best Regards,
>> Jose Miguel Abreu
>



Re: [PATCH net-next 1/2] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-03 Thread Jose Abreu
On 03-09-2018 15:07, Jerome Brunet wrote:
>
> You had it on what you sent in the RFT, but this different.

Yeah, I had to fix the logic where tx queues != rx queues...

>
> Like with the RFT, the network breakdown we had is no longer reproduced.
> However this patch wreck the Rx throughput (680MBps -> 35MBps)

Damn, thats low. And I cant reproduce it here :/

Strange because I barely messed around with RX path...

Can you try attached patch in top of this one please?

>
> BTW, this patch and the RFT assume that 4ae0169fd1b3 ("net: stmmac: Do not 
> keep
> rearming the coalesce timer in stmmac_xmit") is still applied but I believe
> David reverted the patch.
>
> If you still need this change, you should include it back in your changeset.

Yes I know it was reverted but -net was not merged into -next yet...

Thanks and Best Regards,
Jose Miguel Abreu

>
>> Thanks and Best Regards,
>> Jose Miguel Abreu
>> ---
>>  drivers/net/ethernet/stmicro/stmmac/common.h  |   4 +-
>>  drivers/net/ethernet/stmicro/stmmac/stmmac.h  |   7 +-
>>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 177 
>> +++---
>>  3 files changed, 126 insertions(+), 62 deletions(-)
>

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 14f890f2a970..3c7cfda80433 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2247,10 +2247,8 @@ static void stmmac_tx_timer(struct timer_list *t)
 	struct stmmac_tx_queue *tx_q = from_timer(tx_q, t, txtimer);
 	struct stmmac_priv *priv = tx_q->priv_data;
 
-	if (napi_schedule_prep(_q->napi)) {
-		stmmac_disable_dma_irq(priv, priv->ioaddr, tx_q->queue_index);
+	if (napi_schedule_prep(_q->napi))
 		__napi_schedule(_q->napi);
-	}
 
 	tx_q->tx_timer_active = 0;
 }


[PATCH net-next 0/2] net: stmmac: Coalesce and tail addr fixes

2018-09-03 Thread Jose Abreu
The fix for coalesce timer and a fix in tail address setting that impacts
XGMAC2 operation.

Cc: Jerome Brunet 
Cc: Martin Blumenstingl 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 

Jose Abreu (2):
  net: stmmac: Rework coalesce timer and fix multi-queue races
  net: stmmac: Fixup the tail addr setting in xmit path

 drivers/net/ethernet/stmicro/stmmac/common.h  |   4 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |   7 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 182 +++---
 3 files changed, 129 insertions(+), 64 deletions(-)

-- 
2.7.4




[PATCH net-next 2/2] net: stmmac: Fixup the tail addr setting in xmit path

2018-09-03 Thread Jose Abreu
Currently we are always setting the tail address of descriptor list to
the end of the pre-allocated list.

According to databook this is not correct. Tail address should point to
the last available descriptor + 1, which means we have to update the
tail address everytime we call the xmit function.

This should make no impact in older versions of MAC but in newer
versions there are some DMA features which allows the IP to fetch
descriptors in advance and in a non sequential order so its critical
that we set the tail address correctly.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 1fca66ad6b17..14f890f2a970 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2224,8 +2224,7 @@ static int stmmac_init_dma_engine(struct stmmac_priv 
*priv)
stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
tx_q->dma_tx_phy, chan);
 
-   tx_q->tx_tail_addr = tx_q->dma_tx_phy +
-   (DMA_TX_SIZE * sizeof(struct dma_desc));
+   tx_q->tx_tail_addr = tx_q->dma_tx_phy;
stmmac_set_tx_tail_ptr(priv, priv->ioaddr,
   tx_q->tx_tail_addr, chan);
}
@@ -3015,6 +3014,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, 
struct net_device *dev)
 
netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len);
 
+   tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc));
stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);
 
if (priv->tx_coal_timer && !tx_q->tx_timer_active) {
@@ -3235,6 +3235,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, 
struct net_device *dev)
 
stmmac_enable_dma_transmission(priv, priv->ioaddr);
 
+   tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc));
stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);
 
if (priv->tx_coal_timer && !tx_q->tx_timer_active) {
-- 
2.7.4




[PATCH net-next 1/2] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-03 Thread Jose Abreu
This follows David Miller advice and tries to fix coalesce timer in
multi-queue scenarios.

We are now using per-queue coalesce values and per-queue TX timer.

Coalesce timer default values was changed to 1ms and the coalesce frames
to 25.

Tested in B2B setup between XGMAC2 and GMAC5.

Signed-off-by: Jose Abreu 
Cc: Jerome Brunet 
Cc: Martin Blumenstingl 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
Jerome,

Can I have your Tested-by in this patch?

Thanks and Best Regards,
Jose Miguel Abreu
---
 drivers/net/ethernet/stmicro/stmmac/common.h  |   4 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |   7 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 177 +++---
 3 files changed, 126 insertions(+), 62 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
b/drivers/net/ethernet/stmicro/stmmac/common.h
index 1854f270ad66..b1b305f8f414 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -258,10 +258,10 @@ struct stmmac_safety_stats {
 #define MAX_DMA_RIWT   0xff
 #define MIN_DMA_RIWT   0x20
 /* Tx coalesce parameters */
-#define STMMAC_COAL_TX_TIMER   4
+#define STMMAC_COAL_TX_TIMER   1000
 #define STMMAC_MAX_COAL_TX_TICK10
 #define STMMAC_TX_MAX_FRAMES   256
-#define STMMAC_TX_FRAMES   64
+#define STMMAC_TX_FRAMES   25
 
 /* Packets types */
 enum packets_types {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h 
b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 76649adf8fb0..957030cfb833 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -48,6 +48,9 @@ struct stmmac_tx_info {
 
 /* Frequently used values are kept adjacent for cache effect */
 struct stmmac_tx_queue {
+   u32 tx_count_frames;
+   int tx_timer_active;
+   struct timer_list txtimer;
u32 queue_index;
struct stmmac_priv *priv_data;
struct dma_extended_desc *dma_etx cacheline_aligned_in_smp;
@@ -59,6 +62,7 @@ struct stmmac_tx_queue {
dma_addr_t dma_tx_phy;
u32 tx_tail_addr;
u32 mss;
+   struct napi_struct napi cacheline_aligned_in_smp;
 };
 
 struct stmmac_rx_queue {
@@ -109,15 +113,12 @@ struct stmmac_pps_cfg {
 
 struct stmmac_priv {
/* Frequently used values are kept adjacent for cache effect */
-   u32 tx_count_frames;
u32 tx_coal_frames;
u32 tx_coal_timer;
-   bool tx_timer_armed;
 
int tx_coalesce;
int hwts_tx_en;
bool tx_path_in_lpi_mode;
-   struct timer_list txtimer;
bool tso;
 
unsigned int dma_buf_sz;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ff1ffb46198a..1fca66ad6b17 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -148,6 +148,7 @@ static void stmmac_verify_args(void)
 static void stmmac_disable_all_queues(struct stmmac_priv *priv)
 {
u32 rx_queues_cnt = priv->plat->rx_queues_to_use;
+   u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
u32 queue;
 
for (queue = 0; queue < rx_queues_cnt; queue++) {
@@ -155,6 +156,12 @@ static void stmmac_disable_all_queues(struct stmmac_priv 
*priv)
 
napi_disable(_q->napi);
}
+
+   for (queue = 0; queue < tx_queues_cnt; queue++) {
+   struct stmmac_tx_queue *tx_q = >tx_queue[queue];
+
+   napi_disable(_q->napi);
+   }
 }
 
 /**
@@ -164,6 +171,7 @@ static void stmmac_disable_all_queues(struct stmmac_priv 
*priv)
 static void stmmac_enable_all_queues(struct stmmac_priv *priv)
 {
u32 rx_queues_cnt = priv->plat->rx_queues_to_use;
+   u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
u32 queue;
 
for (queue = 0; queue < rx_queues_cnt; queue++) {
@@ -171,6 +179,12 @@ static void stmmac_enable_all_queues(struct stmmac_priv 
*priv)
 
napi_enable(_q->napi);
}
+
+   for (queue = 0; queue < tx_queues_cnt; queue++) {
+   struct stmmac_tx_queue *tx_q = >tx_queue[queue];
+
+   napi_enable(_q->napi);
+   }
 }
 
 /**
@@ -1843,18 +1857,18 @@ static void stmmac_dma_operation_mode(struct 
stmmac_priv *priv)
  * @queue: TX queue index
  * Description: it reclaims the transmit resources after transmission 
completes.
  */
-static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue)
+static int stmmac_tx_clean(struct stmmac_priv *priv, int limit, u32 queue)
 {
struct stmmac_tx_queue *tx_q = >tx_queue[queue];
unsigned int bytes_compl = 0, pkts_compl = 0;
-   unsigned int entry;
+   unsigned int entry, count = 0;
 
netif_tx_lock(priv->dev);
 
priv->xstats.tx_clean++;
 
entry = tx_q-&

Re: [RFT net-next] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-03 Thread Jose Abreu
On 03-09-2018 11:16, Jerome Brunet wrote:
> No notable change. Rx is fine but Tx:
> [  5]   3.00-4.00   sec  3.55 MBytes  29.8 Mbits/sec   51   12.7 KBytes
>
> I suppose the problem as something to do with the retries. When doing Tx test
> alone, we don't have such a things a throughput where we expect it to be.

Yeah, I just remembered you are not using GMAC4 so it wouldn't
make a difference. Is your version 3.710? If so please try adding
the following compatible to your DT bindings "snps,dwmac-3.710".

>
> By the way, your mailer (and its auto 80 column rule I suppose) made the patch
> below a bit harder to apply

Sorry. Next time I will send as attachment.

Thanks and Best Regards,
Jose Miguel Abreu


Re: [RFT net-next] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-09-03 Thread Jose Abreu
Hi Jerome,

On 03-09-2018 09:56, Jerome Brunet wrote:
> On Thu, 2018-08-30 at 11:37 +0100, Jose Abreu wrote:
>> [ As for now this is only for testing! ]
>>
>> This follows David Miller advice and tries to fix coalesce timer in
>> multi-queue scenarios.
>>
>> We are now using per-queue coalesce values and per-queue TX timer. This
>> assumes that tx_queues == rx_queues, which can not be necessarly true.
>> Official patch will need to have this fixed.
>>
>> Coalesce timer default values was changed to 1ms and the coalesce frames
>> to 25.
>>
>> Tested in B2B setup between XGMAC2 and GMAC5.
> Tested on Amlogic meson-axg-s400. No regression seen so far.
> (arch/arm64/boot/dts/amlogic/meson-axg-s400.dts)
>
> As far as I understand from the device tree parsing, this platform (and all
> other amlogic platforms) use single queue.

Thanks for testing! I will send a formal patch once I get around
the problem of rx queues != tx queues.

>
> ---
>
> Jose,
>
> On another topic doing iperf3 test on amlogic's devices we seen a strange
> behavior.
>
> Doing Tx or Rx test usually works fine (700MBps to 900MBps depending on the
> platform). However, when doing both Rx and Tx at the same time, We see the Tx
> throughput dropping significantly (~30MBps) and lot of TCP retries.
>
> Would you any idea what might be our problem ? or how to start investigating
> this ?
>

I'm not able to reproduce this here but I'm using multiple queue.
I will try with single queue. In the meantime please try this
patch (it shall be applied directly on top of this RFT):


--->8
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ae26a6e8608e..1407975320aa 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2210,8 +2210,7 @@ static int stmmac_init_dma_engine(struct
stmmac_priv *priv)
stmmac_init_tx_chan(priv, priv->ioaddr,
priv->plat->dma_cfg,
tx_q->dma_tx_phy, chan);
 
-   tx_q->tx_tail_addr = tx_q->dma_tx_phy +
-   (DMA_TX_SIZE * sizeof(struct dma_desc));
+   tx_q->tx_tail_addr = tx_q->dma_tx_phy;
stmmac_set_tx_tail_ptr(priv, priv->ioaddr,
   tx_q->tx_tail_addr, chan);
}
@@ -3004,6 +3003,7 @@ static netdev_tx_t stmmac_tso_xmit(struct
sk_buff *skb, struct net_device *dev)
 
netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue),
skb->len);
 
+   tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx *
sizeof(*desc));
stmmac_set_tx_tail_ptr(priv, priv->ioaddr,
tx_q->tx_tail_addr, queue);
 
if (priv->tx_coal_timer && !tx_q->tx_timer_active) {
@@ -3223,6 +3223,8 @@ static netdev_tx_t stmmac_xmit(struct
sk_buff *skb, struct net_device *dev)
netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue),
skb->len);
 
stmmac_enable_dma_transmission(priv, priv->ioaddr);
+
+   tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx *
sizeof(*desc));
stmmac_set_tx_tail_ptr(priv, priv->ioaddr,
tx_q->tx_tail_addr, queue);
 
if (priv->tx_coal_timer && !tx_q->tx_timer_active) {
--->8

Thanks and Best Regards,
Jose Miguel Abreu


[PATCH net-next] net: stmmac: Add CBS support in XGMAC2

2018-08-30 Thread Jose Abreu
XGMAC2 uses the same CBS mechanism as GMAC5, only registers offset
changes. Lets use the same TC callbacks and implement the .config_cbs
callback in XGMAC2 core.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h  | 12 
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 19 ++-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c  | 19 +++
 drivers/net/ethernet/stmicro/stmmac/hwif.c  |  2 +-
 4 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index 0a80fa25afe3..d6bb953685fa 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -119,11 +119,23 @@
 #define XGMAC_MTL_TXQ_OPMODE(x)(0x1100 + (0x80 * (x)))
 #define XGMAC_TQS  GENMASK(25, 16)
 #define XGMAC_TQS_SHIFT16
+#define XGMAC_Q2TCMAP  GENMASK(10, 8)
+#define XGMAC_Q2TCMAP_SHIFT8
 #define XGMAC_TTC  GENMASK(6, 4)
 #define XGMAC_TTC_SHIFT4
 #define XGMAC_TXQENGENMASK(3, 2)
 #define XGMAC_TXQEN_SHIFT  2
 #define XGMAC_TSF  BIT(1)
+#define XGMAC_MTL_TCx_ETS_CONTROL(x)   (0x1110 + (0x80 * (x)))
+#define XGMAC_MTL_TCx_QUANTUM_WEIGHT(x)(0x1118 + (0x80 * (x)))
+#define XGMAC_MTL_TCx_SENDSLOPE(x) (0x111c + (0x80 * (x)))
+#define XGMAC_MTL_TCx_HICREDIT(x)  (0x1120 + (0x80 * (x)))
+#define XGMAC_MTL_TCx_LOCREDIT(x)  (0x1124 + (0x80 * (x)))
+#define XGMAC_CC   BIT(3)
+#define XGMAC_TSA  GENMASK(1, 0)
+#define XGMAC_SP   (0x0 << 0)
+#define XGMAC_CBS  (0x1 << 0)
+#define XGMAC_ETS  (0x2 << 0)
 #define XGMAC_MTL_RXQ_OPMODE(x)(0x1140 + (0x80 * (x)))
 #define XGMAC_RQS  GENMASK(25, 16)
 #define XGMAC_RQS_SHIFT16
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index d182f82f7b58..64b8cb88ea45 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -177,6 +177,23 @@ static void dwxgmac2_map_mtl_to_dma(struct mac_device_info 
*hw, u32 queue,
writel(value, ioaddr + reg);
 }
 
+static void dwxgmac2_config_cbs(struct mac_device_info *hw,
+   u32 send_slope, u32 idle_slope,
+   u32 high_credit, u32 low_credit, u32 queue)
+{
+   void __iomem *ioaddr = hw->pcsr;
+   u32 value;
+
+   writel(send_slope, ioaddr + XGMAC_MTL_TCx_SENDSLOPE(queue));
+   writel(idle_slope, ioaddr + XGMAC_MTL_TCx_QUANTUM_WEIGHT(queue));
+   writel(high_credit, ioaddr + XGMAC_MTL_TCx_HICREDIT(queue));
+   writel(low_credit, ioaddr + XGMAC_MTL_TCx_LOCREDIT(queue));
+
+   value = readl(ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue));
+   value |= XGMAC_CC | XGMAC_CBS;
+   writel(value, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue));
+}
+
 static int dwxgmac2_host_irq_status(struct mac_device_info *hw,
struct stmmac_extra_stats *x)
 {
@@ -316,7 +333,7 @@ const struct stmmac_ops dwxgmac210_ops = {
.prog_mtl_tx_algorithms = dwxgmac2_prog_mtl_tx_algorithms,
.set_mtl_tx_queue_weight = NULL,
.map_mtl_to_dma = dwxgmac2_map_mtl_to_dma,
-   .config_cbs = NULL,
+   .config_cbs = dwxgmac2_config_cbs,
.dump_regs = NULL,
.host_irq_status = dwxgmac2_host_irq_status,
.host_mtl_irq_status = dwxgmac2_host_mtl_irq_status,
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
index 20909036e002..6c5092e7771c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
@@ -182,6 +182,9 @@ static void dwxgmac2_dma_tx_mode(void __iomem *ioaddr, int 
mode,
value |= 0x7 << XGMAC_TTC_SHIFT;
}
 
+   /* Use static TC to Queue mapping */
+   value |= (channel << XGMAC_Q2TCMAP_SHIFT) & XGMAC_Q2TCMAP;
+
value &= ~XGMAC_TXQEN;
if (qmode != MTL_QUEUE_AVB)
value |= 0x2 << XGMAC_TXQEN_SHIFT;
@@ -374,6 +377,21 @@ static void dwxgmac2_enable_tso(void __iomem *ioaddr, bool 
en, u32 chan)
writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
 }
 
+static void dwxgmac2_qmode(void __iomem *ioaddr, u32 channel, u8 qmode)
+{
+   u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(channel));
+
+   value &= ~XGMAC_TXQEN;
+   if (qmo

[RFT net-next] net: stmmac: Rework coalesce timer and fix multi-queue races

2018-08-30 Thread Jose Abreu
[ As for now this is only for testing! ]

This follows David Miller advice and tries to fix coalesce timer in
multi-queue scenarios.

We are now using per-queue coalesce values and per-queue TX timer. This
assumes that tx_queues == rx_queues, which can not be necessarly true.
Official patch will need to have this fixed.

Coalesce timer default values was changed to 1ms and the coalesce frames
to 25.

Tested in B2B setup between XGMAC2 and GMAC5.

Signed-off-by: Jose Abreu 
Cc: Jerome Brunet 
Cc: Martin Blumenstingl 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/common.h  |   4 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |   6 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 117 +-
 3 files changed, 75 insertions(+), 52 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
b/drivers/net/ethernet/stmicro/stmmac/common.h
index 1854f270ad66..b1b305f8f414 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -258,10 +258,10 @@ struct stmmac_safety_stats {
 #define MAX_DMA_RIWT   0xff
 #define MIN_DMA_RIWT   0x20
 /* Tx coalesce parameters */
-#define STMMAC_COAL_TX_TIMER   4
+#define STMMAC_COAL_TX_TIMER   1000
 #define STMMAC_MAX_COAL_TX_TICK10
 #define STMMAC_TX_MAX_FRAMES   256
-#define STMMAC_TX_FRAMES   64
+#define STMMAC_TX_FRAMES   25
 
 /* Packets types */
 enum packets_types {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h 
b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 76649adf8fb0..db42a5f03a5f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -48,6 +48,9 @@ struct stmmac_tx_info {
 
 /* Frequently used values are kept adjacent for cache effect */
 struct stmmac_tx_queue {
+   u32 tx_count_frames;
+   int tx_timer_active;
+   struct timer_list txtimer;
u32 queue_index;
struct stmmac_priv *priv_data;
struct dma_extended_desc *dma_etx cacheline_aligned_in_smp;
@@ -109,15 +112,12 @@ struct stmmac_pps_cfg {
 
 struct stmmac_priv {
/* Frequently used values are kept adjacent for cache effect */
-   u32 tx_count_frames;
u32 tx_coal_frames;
u32 tx_coal_timer;
-   bool tx_timer_armed;
 
int tx_coalesce;
int hwts_tx_en;
bool tx_path_in_lpi_mode;
-   struct timer_list txtimer;
bool tso;
 
unsigned int dma_buf_sz;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ff1ffb46198a..ae26a6e8608e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2034,7 +2034,6 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
u32 channels_to_check = tx_channel_count > rx_channel_count ?
tx_channel_count : rx_channel_count;
u32 chan;
-   bool poll_scheduled = false;
int status[max_t(u32, MTL_MAX_TX_QUEUES, MTL_MAX_RX_QUEUES)];
 
/* Make sure we never check beyond our status buffer. */
@@ -2058,7 +2057,6 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
if (likely(napi_schedule_prep(_q->napi))) {
stmmac_disable_dma_irq(priv, priv->ioaddr, 
chan);
__napi_schedule(_q->napi);
-   poll_scheduled = true;
}
}
}
@@ -2067,21 +2065,13 @@ static void stmmac_dma_interrupt(struct stmmac_priv 
*priv)
 * If we didn't schedule poll, see if any DMA channel (used by tx) has a
 * completed transmission, if so, call stmmac_poll (once).
 */
-   if (!poll_scheduled) {
-   for (chan = 0; chan < tx_channel_count; chan++) {
-   if (status[chan] & handle_tx) {
-   /* It doesn't matter what rx queue we choose
-* here. We use 0 since it always exists.
-*/
-   struct stmmac_rx_queue *rx_q =
-   >rx_queue[0];
+   for (chan = 0; chan < tx_channel_count; chan++) {
+   if (status[chan] & handle_tx) {
+   struct stmmac_rx_queue *rx_q = >rx_queue[chan];
 
-   if (likely(napi_schedule_prep(_q->napi))) {
-   stmmac_disable_dma_irq(priv,
-   priv->ioaddr, chan);
-   __napi_schedule(_q->napi);
-   }
-   break;
+

Re: C45 support and mdiobus_scan

2018-08-09 Thread Jose Abreu
Hi Andrew,

Thanks for your answer :)

On 09-08-2018 16:03, Andrew Lunn wrote:
> On Thu, Aug 09, 2018 at 02:54:11PM +0100, Jose Abreu wrote:
>> Hi All,
>>
>> I'm preparing to add support for 10G in stmmac and I noticed that
>> Generic 10G PHY needs C45 support. Digging through the
>> registration callbacks for phy that are used in stmmac I reached
>> to mdiobus_scan() and the following call:
>>
>> phydev = get_phy_device(bus, addr, false);
>>
>> The last parameter is "is_c45", and is always being set to false ...
>>
>> Does this mean that I can't use the Generic 10G PHY in stmmac? I
>> don't mind link being fixed for 10G for now.
> Hi Jose
>
> So far, all MACs which support 10G have used phy-handle to point to a
> PHY on am MDIO bus, and that PHY uses .compatible =
> "ethernet-phy-ieee802.3-c45". of_mdiobus_register() will then find the
> PHY and register it. You really should try to follow this, if you can.
>
>> (Notice I'm using a PCI based setup so no DT bindings can help me
>> for this).
> That is not necessarily true. Take a look at:
>
> arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi
>
>  {
> pinctrl-names = "default";
> pinctrl-0 = <_pcie>;
> reset-gpio = < 12 GPIO_ACTIVE_LOW>;
> status = "okay";
>
> host@0 {
> reg = <0 0 0 0 0>;
>
> #address-cells = <3>;
> #size-cells = <2>;
>
> i210: i210@0 {
> reg = <0 0 0 0 0>;
> };
> };
> };
>
> The PCIe core will look in the device tree and when it creates the
> platform device for the i210 on the pcie bus, it points
> pdev->dev.of_node at this node. So long as you are using a platform
> with DT, you can do this. I hope you are not using x86..

Yes I am :( Any possible solution for this?

I guess in ultimate case I will have to switch to ARM based setup.

Thanks and Best Regards,
Jose Miguel Abreu

>
>  Andrew



C45 support and mdiobus_scan

2018-08-09 Thread Jose Abreu
Hi All,

I'm preparing to add support for 10G in stmmac and I noticed that
Generic 10G PHY needs C45 support. Digging through the
registration callbacks for phy that are used in stmmac I reached
to mdiobus_scan() and the following call:

phydev = get_phy_device(bus, addr, false);

The last parameter is "is_c45", and is always being set to false ...

Does this mean that I can't use the Generic 10G PHY in stmmac? I
don't mind link being fixed for 10G for now.

(Notice I'm using a PCI based setup so no DT bindings can help me
for this).

Thanks and Best Regards,
Jose Miguel Abreu


[PATCH v4 net-next 9/9] dt-bindings: net: stmmac: Add the bindings documentation for XGMAC2.

2018-08-08 Thread Jose Abreu
Adds the documentation for XGMAC2 DT bindings.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
Cc: Sergei Shtylyov 
Cc: devicet...@vger.kernel.org
Cc: Rob Herring 
---
Changes from v3:
- Remove driver mention (Rob)
Changes from v1:
- Correct header, now we also support 2.5/10G.
- Add missing '>' (Sergei)
---
 Documentation/devicetree/bindings/net/stmmac.txt | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/stmmac.txt 
b/Documentation/devicetree/bindings/net/stmmac.txt
index 3a28a5d8857d..7f1385c4643d 100644
--- a/Documentation/devicetree/bindings/net/stmmac.txt
+++ b/Documentation/devicetree/bindings/net/stmmac.txt
@@ -1,7 +1,8 @@
-* STMicroelectronics 10/100/1000 Ethernet driver (GMAC)
+* STMicroelectronics 10/100/1000/2500/1 Ethernet (GMAC/XGMAC)
 
 Required properties:
-- compatible: Should be "snps,dwmac-", "snps,dwmac"
+- compatible: Should be "snps,dwmac-", "snps,dwmac" or
+   "snps,dwxgmac-", "snps,dwxgmac".
For backwards compatibility: "st,spear600-gmac" is also supported.
 - reg: Address and length of the register set for the device
 - interrupt-parent: Should be the phandle for the interrupt controller
-- 
2.7.4




[PATCH v4 net-next 2/9] net: stmmac: Add MAC related callbacks for XGMAC2

2018-08-08 Thread Jose Abreu
Add the MAC related callbacks for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   2 +-
 drivers/net/ethernet/stmicro/stmmac/common.h   |   3 +
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 141 
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c| 371 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |   4 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   1 +
 6 files changed, 519 insertions(+), 3 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile 
b/drivers/net/ethernet/stmicro/stmmac/Makefile
index 68e9e2640c62..a6cf632c9592 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o 
ring_mode.o  \
  dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
  mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o  \
  dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
- stmmac_tc.o $(stmmac-y)
+ stmmac_tc.o dwxgmac2_core.o $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)  += stmmac-platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
b/drivers/net/ethernet/stmicro/stmmac/common.h
index 3fb81acbd274..1854f270ad66 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -400,6 +400,8 @@ struct mac_link {
u32 speed10;
u32 speed100;
u32 speed1000;
+   u32 speed2500;
+   u32 speed1;
u32 duplex;
 };
 
@@ -441,6 +443,7 @@ struct stmmac_rx_routing {
 int dwmac100_setup(struct stmmac_priv *priv);
 int dwmac1000_setup(struct stmmac_priv *priv);
 int dwmac4_setup(struct stmmac_priv *priv);
+int dwxgmac2_setup(struct stmmac_priv *priv);
 
 void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
 unsigned int high, unsigned int low);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
new file mode 100644
index ..7832571f791f
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
+ * stmmac XGMAC definitions.
+ */
+
+#ifndef __STMMAC_DWXGMAC2_H__
+#define __STMMAC_DWXGMAC2_H__
+
+#include "common.h"
+
+/* Misc */
+#define XGMAC_JUMBO_LEN16368
+
+/* MAC Registers */
+#define XGMAC_TX_CONFIG0x
+#define XGMAC_CONFIG_SS_OFF29
+#define XGMAC_CONFIG_SS_MASK   GENMASK(30, 29)
+#define XGMAC_CONFIG_SS_1  (0x0 << XGMAC_CONFIG_SS_OFF)
+#define XGMAC_CONFIG_SS_2500   (0x2 << XGMAC_CONFIG_SS_OFF)
+#define XGMAC_CONFIG_SS_1000   (0x3 << XGMAC_CONFIG_SS_OFF)
+#define XGMAC_CONFIG_SARC  GENMASK(22, 20)
+#define XGMAC_CONFIG_SARC_SHIFT20
+#define XGMAC_CONFIG_JDBIT(16)
+#define XGMAC_CONFIG_TEBIT(0)
+#define XGMAC_CORE_INIT_TX (XGMAC_CONFIG_JD)
+#define XGMAC_RX_CONFIG0x0004
+#define XGMAC_CONFIG_ARPEN BIT(31)
+#define XGMAC_CONFIG_GPSL  GENMASK(29, 16)
+#define XGMAC_CONFIG_GPSL_SHIFT16
+#define XGMAC_CONFIG_S2KP  BIT(11)
+#define XGMAC_CONFIG_IPC   BIT(9)
+#define XGMAC_CONFIG_JEBIT(8)
+#define XGMAC_CONFIG_WDBIT(7)
+#define XGMAC_CONFIG_GPSLCEBIT(6)
+#define XGMAC_CONFIG_CST   BIT(2)
+#define XGMAC_CONFIG_ACS   BIT(1)
+#define XGMAC_CONFIG_REBIT(0)
+#define XGMAC_CORE_INIT_RX 0
+#define XGMAC_PACKET_FILTER0x0008
+#define XGMAC_FILTER_RABIT(31)
+#define XGMAC_FILTER_PMBIT(4)
+#define XGMAC_FILTER_HMC   BIT(2)
+#define XGMAC_FILTER_PRBIT(0)
+#define XGMAC_HASH_TABLE(x)(0x0010 + (x) * 4)
+#define XGMAC_RXQ_CTRL00x00a0
+#define XGMAC_RXQEN(x) GENMASK((x) * 2 + 1, (x) * 2)
+#define XGMAC_RXQEN_SHIFT(x)   ((x) * 2)
+#define XGMAC_RXQ_CTRL20x00a8
+#define XGMAC_RXQ_CTRL30x00ac
+#define XGMAC_PSRQ(x)  GENMASK((x) * 8 + 7, (x) * 8)
+#define XGMAC_PSRQ_SHIFT(x)((x) * 8)
+#define XGMAC_INT_STATUS   0x0

[PATCH v4 net-next 1/9] net: stmmac: Add XGMAC 2.10 HWIF entry

2018-08-08 Thread Jose Abreu
Add a new entry to HWIF table for XGMAC 2.10. For now we fill it with
empty callbacks which will be added in posterior patches.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/common.h | 14 +++--
 drivers/net/ethernet/stmicro/stmmac/hwif.c   | 31 ++--
 include/linux/stmmac.h   |  1 +
 3 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
b/drivers/net/ethernet/stmicro/stmmac/common.h
index 78fd0f8b8e81..3fb81acbd274 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -36,12 +36,14 @@
 #include "mmc.h"
 
 /* Synopsys Core versions */
-#defineDWMAC_CORE_3_40 0x34
-#defineDWMAC_CORE_3_50 0x35
-#defineDWMAC_CORE_4_00 0x40
-#define DWMAC_CORE_4_100x41
-#define DWMAC_CORE_5_00 0x50
-#define DWMAC_CORE_5_10 0x51
+#defineDWMAC_CORE_3_40 0x34
+#defineDWMAC_CORE_3_50 0x35
+#defineDWMAC_CORE_4_00 0x40
+#define DWMAC_CORE_4_100x41
+#define DWMAC_CORE_5_000x50
+#define DWMAC_CORE_5_100x51
+#define DWXGMAC_CORE_2_10  0x21
+
 #define STMMAC_CHAN0   0   /* Always supported and default for all chips */
 
 /* These need to be power of two, and >= 4 */
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c 
b/drivers/net/ethernet/stmicro/stmmac/hwif.c
index 1f50e83cafb2..24f5ff175aa4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
@@ -72,6 +72,7 @@ static int stmmac_dwmac4_quirks(struct stmmac_priv *priv)
 static const struct stmmac_hwif_entry {
bool gmac;
bool gmac4;
+   bool xgmac;
u32 min_id;
const struct stmmac_regs_off regs;
const void *desc;
@@ -87,6 +88,7 @@ static const struct stmmac_hwif_entry {
{
.gmac = false,
.gmac4 = false,
+   .xgmac = false,
.min_id = 0,
.regs = {
.ptp_off = PTP_GMAC3_X_OFFSET,
@@ -103,6 +105,7 @@ static const struct stmmac_hwif_entry {
}, {
.gmac = true,
.gmac4 = false,
+   .xgmac = false,
.min_id = 0,
.regs = {
.ptp_off = PTP_GMAC3_X_OFFSET,
@@ -119,6 +122,7 @@ static const struct stmmac_hwif_entry {
}, {
.gmac = false,
.gmac4 = true,
+   .xgmac = false,
.min_id = 0,
.regs = {
.ptp_off = PTP_GMAC4_OFFSET,
@@ -135,6 +139,7 @@ static const struct stmmac_hwif_entry {
}, {
.gmac = false,
.gmac4 = true,
+   .xgmac = false,
.min_id = DWMAC_CORE_4_00,
.regs = {
.ptp_off = PTP_GMAC4_OFFSET,
@@ -151,6 +156,7 @@ static const struct stmmac_hwif_entry {
}, {
.gmac = false,
.gmac4 = true,
+   .xgmac = false,
.min_id = DWMAC_CORE_4_10,
.regs = {
.ptp_off = PTP_GMAC4_OFFSET,
@@ -167,6 +173,7 @@ static const struct stmmac_hwif_entry {
}, {
.gmac = false,
.gmac4 = true,
+   .xgmac = false,
.min_id = DWMAC_CORE_5_10,
.regs = {
.ptp_off = PTP_GMAC4_OFFSET,
@@ -180,11 +187,29 @@ static const struct stmmac_hwif_entry {
.tc = _tc_ops,
.setup = dwmac4_setup,
.quirks = NULL,
-   }
+   }, {
+   .gmac = false,
+   .gmac4 = false,
+   .xgmac = true,
+   .min_id = DWXGMAC_CORE_2_10,
+   .regs = {
+   .ptp_off = 0,
+   .mmc_off = 0,
+   },
+   .desc = NULL,
+   .dma = NULL,
+   .mac = NULL,
+   .hwtimestamp = NULL,
+   .mode = NULL,
+   .tc = NULL,
+   .setup = NULL,
+   .quirks = NULL,
+   },
 };
 
 int stmmac_hwif_init(struct stmmac_priv *priv)
 {
+   bool needs_xgmac = priv->plat->has_xgmac;
bool needs_gmac4 = priv->plat->has_gmac4;
bool needs_gmac = priv->plat->has_gmac;
const struct stmmac_hwif_entry *entry;
@@ -195,7 +220,7 @@ int stmmac_hwif_init(struct stmmac_priv *priv)
 
if (needs_gmac) {
id = stmmac_get_id(priv, GMAC_VERSION);
-   } else if (needs_gmac4) {
+   } else if (needs_gmac4 || needs_xgmac) {
id = stmmac_get_id(priv, GMAC4_VERSION);
} else {
id = 0;
@@ -229,6 +254,8

[PATCH v4 net-next 7/9] net: stmmac: Integrate XGMAC into main driver flow

2018-08-08 Thread Jose Abreu
Now that we have all the XGMAC related callbacks, lets start integrating
this IP block into main driver.

Also, we corrected the initialization flow to only start DMA after
setting descriptors length.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
Cc: Andrew Lunn 
---
Changes from v1:
- Correct flow of initialization
- Remove 2.5G/10G support (Andrew)
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 67 ---
 1 file changed, 48 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9d104a05044d..ff1ffb46198a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -51,6 +51,7 @@
 #include 
 #include 
 #include "dwmac1000.h"
+#include "dwxgmac2.h"
 #include "hwif.h"
 
 #defineSTMMAC_ALIGN(x) __ALIGN_KERNEL(x, SMP_CACHE_BYTES)
@@ -262,6 +263,21 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv)
else
priv->clk_csr = 0;
}
+
+   if (priv->plat->has_xgmac) {
+   if (clk_rate > 4)
+   priv->clk_csr = 0x5;
+   else if (clk_rate > 35000)
+   priv->clk_csr = 0x4;
+   else if (clk_rate > 3)
+   priv->clk_csr = 0x3;
+   else if (clk_rate > 25000)
+   priv->clk_csr = 0x2;
+   else if (clk_rate > 15000)
+   priv->clk_csr = 0x1;
+   else
+   priv->clk_csr = 0x0;
+   }
 }
 
 static void print_pkt(unsigned char *buf, int len)
@@ -498,7 +514,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv 
*priv, struct dma_desc *p,
if (!priv->hwts_rx_en)
return;
/* For GMAC4, the valid timestamp is from CTX next desc. */
-   if (priv->plat->has_gmac4)
+   if (priv->plat->has_gmac4 || priv->plat->has_xgmac)
desc = np;
 
/* Check if timestamp is available */
@@ -540,6 +556,9 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
u32 ts_event_en = 0;
u32 value = 0;
u32 sec_inc;
+   bool xmac;
+
+   xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 
if (!(priv->dma_cap.time_stamp || priv->adv_ts)) {
netdev_alert(priv->dev, "No support for HW time stamping\n");
@@ -575,7 +594,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
/* PTP v1, UDP, any kind of event packet */
config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
/* take time stamp for all event messages */
-   if (priv->plat->has_gmac4)
+   if (xmac)
snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
else
snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
@@ -610,7 +629,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
ptp_v2 = PTP_TCR_TSVER2ENA;
/* take time stamp for all event messages */
-   if (priv->plat->has_gmac4)
+   if (xmac)
snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
else
snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
@@ -647,7 +666,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
ptp_v2 = PTP_TCR_TSVER2ENA;
/* take time stamp for all event messages */
-   if (priv->plat->has_gmac4)
+   if (xmac)
snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
else
snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
@@ -718,7 +737,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
/* program Sub Second Increment reg */
stmmac_config_sub_second_increment(priv,
priv->ptpaddr, priv->plat->clk_ptp_rate,
-   priv->plat->has_gmac4, _inc);
+   xmac, _inc);
temp = div_u64(10ULL, sec_inc);
 
/* Store sub second increment and flags for later use */
@@ -755,12 +774,14 @@ static int stmmac_hwtstamp_ioct

[PATCH v4 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2

2018-08-08 Thread Jose Abreu
Add the MDIO related funcionalities for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
Cc: Andrew Lunn 
Cc: Florian Fainelli 
---
Changes from v3:
- Check if unsupported phy_addr was specified in DT
- Clear C22 reg before setting the bit (Florian)
- Limit the number of possible phys to 4 (for now) (Florian)
Changes from v2:
- Use helper to set C22 (Andrew)
- Wait for bus free before setting C22 reg (Andrew)
Changes from v1:
- Remove C45 support (Andrew)
- Add define for bits (Andrew)
- Remove uneeded cast (Andrew)
- Use different callbacks instead of if's (Andrew)
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 133 +-
 1 file changed, 129 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index 5df1a608e566..b72ef171477e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 
+#include "dwxgmac2.h"
 #include "stmmac.h"
 
 #define MII_BUSY 0x0001
@@ -39,6 +40,115 @@
 #define MII_GMAC4_WRITE(1 << MII_GMAC4_GOC_SHIFT)
 #define MII_GMAC4_READ (3 << MII_GMAC4_GOC_SHIFT)
 
+/* XGMAC defines */
+#define MII_XGMAC_SADDRBIT(18)
+#define MII_XGMAC_CMD_SHIFT16
+#define MII_XGMAC_WRITE(1 << MII_XGMAC_CMD_SHIFT)
+#define MII_XGMAC_READ (3 << MII_XGMAC_CMD_SHIFT)
+#define MII_XGMAC_BUSY BIT(22)
+#define MII_XGMAC_MAX_C22ADDR  3
+#define MII_XGMAC_C22P_MASKGENMASK(MII_XGMAC_MAX_C22ADDR, 0)
+
+static int stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int phyaddr,
+   int phyreg, u32 *hw_addr)
+{
+   unsigned int mii_data = priv->hw->mii.data;
+   u32 tmp;
+
+   /* HW does not support C22 addr >= 4 */
+   if (phyaddr > MII_XGMAC_MAX_C22ADDR)
+   return -ENODEV;
+   /* Wait until any existing MII operation is complete */
+   if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+  !(tmp & MII_XGMAC_BUSY), 100, 1))
+   return -EBUSY;
+
+   /* Set port as Clause 22 */
+   tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
+   tmp &= ~MII_XGMAC_C22P_MASK;
+   tmp |= BIT(phyaddr);
+   writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
+
+   *hw_addr = (phyaddr << 16) | (phyreg & 0x1f);
+   return 0;
+}
+
+static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int 
phyreg)
+{
+   struct net_device *ndev = bus->priv;
+   struct stmmac_priv *priv = netdev_priv(ndev);
+   unsigned int mii_address = priv->hw->mii.addr;
+   unsigned int mii_data = priv->hw->mii.data;
+   u32 tmp, addr, value = MII_XGMAC_BUSY;
+   int ret;
+
+   if (phyreg & MII_ADDR_C45) {
+   return -EOPNOTSUPP;
+   } else {
+   ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, );
+   if (ret)
+   return ret;
+   }
+
+   value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
+   & priv->hw->mii.clk_csr_mask;
+   value |= MII_XGMAC_SADDR | MII_XGMAC_READ;
+
+   /* Wait until any existing MII operation is complete */
+   if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+  !(tmp & MII_XGMAC_BUSY), 100, 1))
+   return -EBUSY;
+
+   /* Set the MII address register to read */
+   writel(addr, priv->ioaddr + mii_address);
+   writel(value, priv->ioaddr + mii_data);
+
+   /* Wait until any existing MII operation is complete */
+   if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+  !(tmp & MII_XGMAC_BUSY), 100, 1))
+   return -EBUSY;
+
+   /* Read the data from the MII data register */
+   return readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
+}
+
+static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr,
+   int phyreg, u16 phydata)
+{
+   struct net_device *ndev = bus->priv;
+   struct stmmac_priv *priv = netdev_priv(ndev);
+   unsigned int mii_address = priv->hw->mii.addr;
+   unsigned int mii_data = priv->hw->mii.data;
+   u32 addr, tmp, value = MII_XGMAC_BUSY;
+   int ret;
+
+   if (phyreg & MII_ADDR_C45) {
+   return -EOPNOTSUPP;
+   } else {
+   ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, );
+   if (ret)
+   return ret;
+ 

[PATCH v4 net-next 8/9] net: stmmac: Add the bindings parsing for XGMAC2

2018-08-08 Thread Jose Abreu
Add the bindings parsing for XGMAC2 IP block.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c   | 2 ++
 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
index 3304095c934c..fad503820e04 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
@@ -78,6 +78,8 @@ static const struct of_device_id dwmac_generic_match[] = {
{ .compatible = "snps,dwmac-4.00"},
{ .compatible = "snps,dwmac-4.10a"},
{ .compatible = "snps,dwmac"},
+   { .compatible = "snps,dwxgmac-2.10"},
+   { .compatible = "snps,dwxgmac"},
{ }
 };
 MODULE_DEVICE_TABLE(of, dwmac_generic_match);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 72da77b94ecd..3609c7b696c7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -486,6 +486,12 @@ stmmac_probe_config_dt(struct platform_device *pdev, const 
char **mac)
plat->force_sf_dma_mode = 1;
}
 
+   if (of_device_is_compatible(np, "snps,dwxgmac")) {
+   plat->has_xgmac = 1;
+   plat->pmt = 1;
+   plat->tso_en = of_property_read_bool(np, "snps,tso");
+   }
+
dma_cfg = devm_kzalloc(>dev, sizeof(*dma_cfg),
   GFP_KERNEL);
if (!dma_cfg) {
-- 
2.7.4




[PATCH v4 net-next 0/9] Add support for XGMAC2 in stmmac

2018-08-08 Thread Jose Abreu
This series adds support for 10Gigabit IP in stmmac. The IP is called XGMAC2
and has many similarities with GMAC4. Due to this, its relatively easy to
incorporate this new IP into stmmac driver by adding a new block and
filling the necessary callbacks.

The functionality added by this series is still reduced but its only a
starting point which will later be expanded.

I splitted the patches into funcionality and to ease the review. Only the
patch 8/9 really enables the XGMAC2 block by adding a new compatible string.

Version 4 addresses review comments of Florian Fainelli and Rob Herring.

NOTE: Although the IP supports 10G, for now it was only possible to test it
at 1G speed due to 10G PHY HW shipping problems. Here follows iperf3
results at 1G:

---
# iperf3 -c 192.168.0.10
Connecting to host 192.168.0.10, port 5201
[  4] local 192.168.0.3 port 39178 connected to 192.168.0.10 port 5201
[ ID] Interval   Transfer Bandwidth   Retr  Cwnd
[  4]   0.00-1.00   sec   110 MBytes   920 Mbits/sec0482 KBytes
[  4]   1.00-2.00   sec   113 MBytes   946 Mbits/sec0482 KBytes
[  4]   2.00-3.00   sec   112 MBytes   937 Mbits/sec0482 KBytes
[  4]   3.00-4.00   sec   113 MBytes   946 Mbits/sec0482 KBytes
[  4]   4.00-5.00   sec   112 MBytes   935 Mbits/sec0482 KBytes
[  4]   5.00-6.00   sec   113 MBytes   946 Mbits/sec0482 KBytes
[  4]   6.00-7.00   sec   112 MBytes   937 Mbits/sec0482 KBytes
[  4]   7.00-8.00   sec   113 MBytes   946 Mbits/sec0482 KBytes
[  4]   8.00-9.00   sec   112 MBytes   937 Mbits/sec0482 KBytes
[  4]   9.00-10.00  sec   113 MBytes   946 Mbits/sec0482 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   Retr
[  4]   0.00-10.00  sec  1.09 GBytes   940 Mbits/sec0 sender
[  4]   0.00-10.00  sec  1.09 GBytes   938 Mbits/sec  receiver
---

Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
Cc: Andrew Lunn 
Cc: Florian Fainelli 

Jose Abreu (9):
  net: stmmac: Add XGMAC 2.10 HWIF entry
  net: stmmac: Add MAC related callbacks for XGMAC2
  net: stmmac: Add DMA related callbacks for XGMAC2
  net: stmmac: Add descriptor related callbacks for XGMAC2
  net: stmmac: Add MDIO related functions for XGMAC2
  net: stmmac: Add PTP support for XGMAC2
  net: stmmac: Integrate XGMAC into main driver flow
  net: stmmac: Add the bindings parsing for XGMAC2
  dt-bindings: net: stmmac: Add the bindings documentation for XGMAC2.

 Documentation/devicetree/bindings/net/stmmac.txt   |   5 +-
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   3 +-
 drivers/net/ethernet/stmicro/stmmac/common.h   |  17 +-
 .../net/ethernet/stmicro/stmmac/dwmac-generic.c|   2 +
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 228 
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c| 371 +++
 .../net/ethernet/stmicro/stmmac/dwxgmac2_descs.c   | 280 ++
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 411 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |  31 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   3 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  67 +++-
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c  | 133 ++-
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   6 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c   |   6 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h   |   1 +
 include/linux/stmmac.h |   1 +
 16 files changed, 1529 insertions(+), 36 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c

-- 
2.7.4




[PATCH v4 net-next 3/9] net: stmmac: Add DMA related callbacks for XGMAC2

2018-08-08 Thread Jose Abreu
Add the DMA related callbacks for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
Cc: Florian Fainelli 
---
Changes from v3:
- Clear previous BLEN values (Florian)
---
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   2 +-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h |  57 +++
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 411 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |   2 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   1 +
 5 files changed, 471 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile 
b/drivers/net/ethernet/stmicro/stmmac/Makefile
index a6cf632c9592..da40d3bba037 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o 
ring_mode.o  \
  dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
  mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o  \
  dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
- stmmac_tc.o dwxgmac2_core.o $(stmmac-y)
+ stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)  += stmmac-platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index 7832571f791f..a6992332f801 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -138,4 +138,61 @@
 #define XGMAC_ABPSIS   BIT(1)
 #define XGMAC_TXUNFIS  BIT(0)
 
+/* DMA Registers */
+#define XGMAC_DMA_MODE 0x3000
+#define XGMAC_SWR  BIT(0)
+#define XGMAC_DMA_SYSBUS_MODE  0x3004
+#define XGMAC_WR_OSR_LMT   GENMASK(29, 24)
+#define XGMAC_WR_OSR_LMT_SHIFT 24
+#define XGMAC_RD_OSR_LMT   GENMASK(21, 16)
+#define XGMAC_RD_OSR_LMT_SHIFT 16
+#define XGMAC_EN_LPI   BIT(15)
+#define XGMAC_LPI_XIT_PKT  BIT(14)
+#define XGMAC_AAL  BIT(12)
+#define XGMAC_BLEN GENMASK(7, 1)
+#define XGMAC_BLEN256  BIT(7)
+#define XGMAC_BLEN128  BIT(6)
+#define XGMAC_BLEN64   BIT(5)
+#define XGMAC_BLEN32   BIT(4)
+#define XGMAC_BLEN16   BIT(3)
+#define XGMAC_BLEN8BIT(2)
+#define XGMAC_BLEN4BIT(1)
+#define XGMAC_UNDEFBIT(0)
+#define XGMAC_DMA_CH_CONTROL(x)(0x3100 + (0x80 * (x)))
+#define XGMAC_PBLx8BIT(16)
+#define XGMAC_DMA_CH_TX_CONTROL(x) (0x3104 + (0x80 * (x)))
+#define XGMAC_TxPBLGENMASK(21, 16)
+#define XGMAC_TxPBL_SHIFT  16
+#define XGMAC_TSE  BIT(12)
+#define XGMAC_OSP  BIT(4)
+#define XGMAC_TXST BIT(0)
+#define XGMAC_DMA_CH_RX_CONTROL(x) (0x3108 + (0x80 * (x)))
+#define XGMAC_RxPBLGENMASK(21, 16)
+#define XGMAC_RxPBL_SHIFT  16
+#define XGMAC_RXST BIT(0)
+#define XGMAC_DMA_CH_TxDESC_LADDR(x)   (0x3114 + (0x80 * (x)))
+#define XGMAC_DMA_CH_RxDESC_LADDR(x)   (0x311c + (0x80 * (x)))
+#define XGMAC_DMA_CH_TxDESC_TAIL_LPTR(x)   (0x3124 + (0x80 * (x)))
+#define XGMAC_DMA_CH_RxDESC_TAIL_LPTR(x)   (0x312c + (0x80 * (x)))
+#define XGMAC_DMA_CH_TxDESC_RING_LEN(x)(0x3130 + (0x80 * 
(x)))
+#define XGMAC_DMA_CH_RxDESC_RING_LEN(x)(0x3134 + (0x80 * 
(x)))
+#define XGMAC_DMA_CH_INT_EN(x) (0x3138 + (0x80 * (x)))
+#define XGMAC_NIE  BIT(15)
+#define XGMAC_AIE  BIT(14)
+#define XGMAC_RBUE BIT(7)
+#define XGMAC_RIE  BIT(6)
+#define XGMAC_TIE  BIT(0)
+#define XGMAC_DMA_INT_DEFAULT_EN   (XGMAC_NIE | XGMAC_AIE | XGMAC_RBUE | \
+   XGMAC_RIE | XGMAC_TIE)
+#define XGMAC_DMA_CH_Rx_WATCHDOG(x)(0x313c + (0x80 * (x)))
+#define XGMAC_RWT  GENMASK(7, 0)
+#define XGMAC_DMA_CH_STATUS(x) (0x3160 + (0x80 * (x)))
+#define XGMAC_NIS  BIT(15)
+#define XGMAC_AIS  BIT(14)
+#define XGMAC_FBE  BIT(12)
+#define XGMAC_RBU  BIT(7)
+#define XGMAC_RI   BIT(6)
+#define XGMAC_TPS  BIT(1)
+#define XGMAC_TI   BIT(0)
+
 #endif /* __STMMAC_DWXGMAC2_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c 
b

[PATCH v4 net-next 4/9] net: stmmac: Add descriptor related callbacks for XGMAC2

2018-08-08 Thread Jose Abreu
Add the descriptor related callbacks for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   3 +-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h |  30 +++
 .../net/ethernet/stmicro/stmmac/dwxgmac2_descs.c   | 280 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |   2 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   1 +
 5 files changed, 314 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile 
b/drivers/net/ethernet/stmicro/stmmac/Makefile
index da40d3bba037..99967a80a8c8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -5,7 +5,8 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o 
ring_mode.o  \
  dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
  mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o  \
  dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
- stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o $(stmmac-y)
+ stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o dwxgmac2_descs.o \
+ $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)  += stmmac-platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index a6992332f801..0a80fa25afe3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -195,4 +195,34 @@
 #define XGMAC_TPS  BIT(1)
 #define XGMAC_TI   BIT(0)
 
+/* Descriptors */
+#define XGMAC_TDES2_IOCBIT(31)
+#define XGMAC_TDES2_TTSE   BIT(30)
+#define XGMAC_TDES2_B2LGENMASK(29, 16)
+#define XGMAC_TDES2_B2L_SHIFT  16
+#define XGMAC_TDES2_B1LGENMASK(13, 0)
+#define XGMAC_TDES3_OWNBIT(31)
+#define XGMAC_TDES3_CTXT   BIT(30)
+#define XGMAC_TDES3_FD BIT(29)
+#define XGMAC_TDES3_LD BIT(28)
+#define XGMAC_TDES3_CPCGENMASK(27, 26)
+#define XGMAC_TDES3_CPC_SHIFT  26
+#define XGMAC_TDES3_TCMSSV BIT(26)
+#define XGMAC_TDES3_THLGENMASK(22, 19)
+#define XGMAC_TDES3_THL_SHIFT  19
+#define XGMAC_TDES3_TSEBIT(18)
+#define XGMAC_TDES3_CICGENMASK(17, 16)
+#define XGMAC_TDES3_CIC_SHIFT  16
+#define XGMAC_TDES3_TPLGENMASK(17, 0)
+#define XGMAC_TDES3_FL GENMASK(14, 0)
+#define XGMAC_RDES3_OWNBIT(31)
+#define XGMAC_RDES3_CTXT   BIT(30)
+#define XGMAC_RDES3_IOCBIT(30)
+#define XGMAC_RDES3_LD BIT(28)
+#define XGMAC_RDES3_CDABIT(27)
+#define XGMAC_RDES3_ES BIT(15)
+#define XGMAC_RDES3_PL GENMASK(13, 0)
+#define XGMAC_RDES3_TSDBIT(6)
+#define XGMAC_RDES3_TSABIT(4)
+
 #endif /* __STMMAC_DWXGMAC2_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
new file mode 100644
index ..1d858fdec997
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
+ * stmmac XGMAC support.
+ */
+
+#include 
+#include "common.h"
+#include "dwxgmac2.h"
+
+static int dwxgmac2_get_tx_status(void *data, struct stmmac_extra_stats *x,
+ struct dma_desc *p, void __iomem *ioaddr)
+{
+   unsigned int tdes3 = le32_to_cpu(p->des3);
+   int ret = tx_done;
+
+   if (unlikely(tdes3 & XGMAC_TDES3_OWN))
+   return tx_dma_own;
+   if (likely(!(tdes3 & XGMAC_TDES3_LD)))
+   return tx_not_ls;
+
+   return ret;
+}
+
+static int dwxgmac2_get_rx_status(void *data, struct stmmac_extra_stats *x,
+ struct dma_desc *p)
+{
+   unsigned int rdes3 = le32_to_cpu(p->des3);
+   int ret = good_frame;
+
+   if (unlikely(rdes3 & XGMAC_RDES3_OWN))
+   return dma_own;
+   if (likely(!(rdes3 & XGMAC_RDES3_LD)))
+   return discard_frame;
+   if (unlikely(rdes3 & XGMAC_RDES3_ES))
+   ret = discard_frame;
+
+   return ret;
+}
+
+static int dwxgmac2_get_tx_len(struct dma_desc *p)
+{
+   return (le32_to_cpu(p->des2) & XGMAC_TDES2_B1L);
+}
+
+static int dwxgmac2_get_tx_owner(struc

[PATCH v4 net-next 6/9] net: stmmac: Add PTP support for XGMAC2

2018-08-08 Thread Jose Abreu
XGMAC2 uses the same engine of timestamping as GMAC4. Let's use the same
callbacks.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/hwif.c   | 4 ++--
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 6 --
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h | 1 +
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c 
b/drivers/net/ethernet/stmicro/stmmac/hwif.c
index 4b4ba1c8bad5..357309a6d6a5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
@@ -193,13 +193,13 @@ static const struct stmmac_hwif_entry {
.xgmac = true,
.min_id = DWXGMAC_CORE_2_10,
.regs = {
-   .ptp_off = 0,
+   .ptp_off = PTP_XGMAC_OFFSET,
.mmc_off = 0,
},
.desc = _desc_ops,
.dma = _dma_ops,
.mac = _ops,
-   .hwtimestamp = NULL,
+   .hwtimestamp = _ptp,
.mode = NULL,
.tc = NULL,
.setup = dwxgmac2_setup,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
index 0cb0e39a2be9..2293e21f789f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
@@ -71,6 +71,9 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 
delta)
u32 sec, nsec;
u32 quotient, reminder;
int neg_adj = 0;
+   bool xmac;
+
+   xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 
if (delta < 0) {
neg_adj = 1;
@@ -82,8 +85,7 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 
delta)
nsec = reminder;
 
spin_lock_irqsave(>ptp_lock, flags);
-   stmmac_adjust_systime(priv, priv->ptpaddr, sec, nsec, neg_adj,
-   priv->plat->has_gmac4);
+   stmmac_adjust_systime(priv, priv->ptpaddr, sec, nsec, neg_adj, xmac);
spin_unlock_irqrestore(>ptp_lock, flags);
 
return 0;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
index f4b31d69f60e..ecccf895fd7e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
@@ -21,6 +21,7 @@
 #ifndef__STMMAC_PTP_H__
 #define__STMMAC_PTP_H__
 
+#define PTP_XGMAC_OFFSET   0xd00
 #definePTP_GMAC4_OFFSET0xb00
 #definePTP_GMAC3_X_OFFSET  0x700
 
-- 
2.7.4




Re: [PATCH v3 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2

2018-08-07 Thread Jose Abreu
On 07-08-2018 14:35, Jose Abreu wrote:
> Hi Florian,
>
> On 06-08-2018 16:25, Florian Fainelli wrote:
>> On August 6, 2018 12:59:54 AM PDT, Jose Abreu  
>> wrote:
>>> On 03-08-2018 20:06, Florian Fainelli wrote:
>>>> On 08/03/2018 08:50 AM, Jose Abreu wrote:
>>>>> Add the MDIO related funcionalities for the new IP block XGMAC2.
>>>>>
>>>>> Signed-off-by: Jose Abreu 
>>>>> Cc: David S. Miller 
>>>>> Cc: Joao Pinto 
>>>>> Cc: Giuseppe Cavallaro 
>>>>> Cc: Alexandre Torgue 
>>>>> Cc: Andrew Lunn 
>>>>> ---
>>>>> +satic int stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int
>>> phyaddr,
>>>>> + int phyreg, u32 *hw_addr)
>>>>> +{
>>>>> + unsigned int mii_data = priv->hw->mii.data;
>>>>> + u32 tmp;
>>>>> +
>>>>> + /* HW does not support C22 addr >= 4 */
>>>>> + if (phyaddr >= 4)
>>>>> + return -ENODEV;
>>>> It would be nice if this could be moved at probe time so you don't
>>> have
>>>> to wait until you connect to the PHY, read its PHY OUI and find out
>>> it
>>>> has a MDIO address >= 4. Not a blocker, but something that could be
>>>> improved further on.
>>>>
>>>> In premise you could even scan the MDIO bus' device tree node, and
>>> find
>>>> that out ahead of time.
>>> Oh, but I use phylib ... I only provide the read/write callbacks
>>> so I think we should avoid duplicating the code that's already in
>>> the phylib ... No?
>> You can always extract the code that scans a MDIO bus into a helper function 
>> and make it parametrized with a callback of some kind. In that case I would 
>> be fine with you open coding the MDIO bus scan to find out if there is an 
>> address >= 4.
> Sorry but I dont' think thats the best solution because
> of_mdiobus_register() already scans the bus. 

My mistake. Its stmmac thats scanning the bus. See this:

359 for (addr = 0; addr < PHY_MAX_ADDR; addr++)
{  
360 struct phy_device *phydev =
mdiobus_get_phy(new_bus, addr);
361 
   

362 if
(!phydev)   
363
continue;  

So, its just cycling through all possible phys (0..31) ... Do you
think it would be okay if I just limit the cycle max to 4 for
this xgmac2 for now ? I would maintain the if in  the
stmmac_xgmac2_c22_format though, as safe-guard.

Thanks and Best Regards,
Jose Miguel Abreu

> Duplicating this
> should be avoided, no?
>
> Note all of this is probably never needed because stmmac just
> picks the first phy it finds, if phy_addr is not specified ...
>
>>>>> + /* Wait until any existing MII operation is complete */
>>>>> + if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
>>>>> +!(tmp & MII_XGMAC_BUSY), 100, 1))
>>>>> + return -EBUSY;
>>>>> +
>>>>> + /* Set port as Clause 22 */
>>>>> + tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
>>>>> + tmp |= BIT(phyaddr);
>>>> Since the registers are being Read/Modify/Write here, don't you need
>>> to
>>>> clear the previous address bits as well?
>>>>
>>>> You probably did not encounter any problems in your testing if you
>>> had
>>>> only one PHY on the MDIO bus, but this is not something that is
>>>> necessarily true, e.g: if you have an Ethernet switch, several MDIO
>>> bus
>>>> addresses are going to be responding.
>>>>
>>>> Your MDIO bus implementation must be able to support one transaction
>>>> with one PHY address and the next transaction with another PHY
>>> address ,
>>>> etc...
>>>>
>>>> That is something that should be easy to fix and be resubmitted as
>>> part
>>>> of v4.
>>> I'm not following you here... I only set/unset the bit for the
>>> corresponding phyaddr that phylib wants to read/write. Why would
>>> I clear the remaining addresses?
>> Because this is all about transactions, the HW must be in a state that it 
>> will be able to perform that transaction correctly. So here for instance if 
>> you needed to support a C45 transaction you would have to clear that bit for 
>> that particular PHY address. Since you don't appear to support those yet 
>> then yes the code appears fine though it would not hurt if you did clear all 
>> other PHY's c22 bits to make it clear what this does.
> I can't test C45 right now but I will in a near future. In that
> case then we will need to support C22 and C45 so I may want to
> only set one bit for a specific phy that only supports c22.
>
> Thanks and Best Regards,
> Jose Miguel Abreu
>



Re: [PATCH v3 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2

2018-08-07 Thread Jose Abreu
Hi Florian,

On 06-08-2018 16:25, Florian Fainelli wrote:
> On August 6, 2018 12:59:54 AM PDT, Jose Abreu  wrote:
>> On 03-08-2018 20:06, Florian Fainelli wrote:
>>> On 08/03/2018 08:50 AM, Jose Abreu wrote:
>>>> Add the MDIO related funcionalities for the new IP block XGMAC2.
>>>>
>>>> Signed-off-by: Jose Abreu 
>>>> Cc: David S. Miller 
>>>> Cc: Joao Pinto 
>>>> Cc: Giuseppe Cavallaro 
>>>> Cc: Alexandre Torgue 
>>>> Cc: Andrew Lunn 
>>>> ---
>>>> +satic int stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int
>> phyaddr,
>>>> +  int phyreg, u32 *hw_addr)
>>>> +{
>>>> +  unsigned int mii_data = priv->hw->mii.data;
>>>> +  u32 tmp;
>>>> +
>>>> +  /* HW does not support C22 addr >= 4 */
>>>> +  if (phyaddr >= 4)
>>>> +  return -ENODEV;
>>> It would be nice if this could be moved at probe time so you don't
>> have
>>> to wait until you connect to the PHY, read its PHY OUI and find out
>> it
>>> has a MDIO address >= 4. Not a blocker, but something that could be
>>> improved further on.
>>>
>>> In premise you could even scan the MDIO bus' device tree node, and
>> find
>>> that out ahead of time.
>> Oh, but I use phylib ... I only provide the read/write callbacks
>> so I think we should avoid duplicating the code that's already in
>> the phylib ... No?
> You can always extract the code that scans a MDIO bus into a helper function 
> and make it parametrized with a callback of some kind. In that case I would 
> be fine with you open coding the MDIO bus scan to find out if there is an 
> address >= 4.

Sorry but I dont' think thats the best solution because
of_mdiobus_register() already scans the bus. Duplicating this
should be avoided, no?

Note all of this is probably never needed because stmmac just
picks the first phy it finds, if phy_addr is not specified ...

>
>>>> +  /* Wait until any existing MII operation is complete */
>>>> +  if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
>>>> + !(tmp & MII_XGMAC_BUSY), 100, 1))
>>>> +  return -EBUSY;
>>>> +
>>>> +  /* Set port as Clause 22 */
>>>> +  tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
>>>> +  tmp |= BIT(phyaddr);
>>> Since the registers are being Read/Modify/Write here, don't you need
>> to
>>> clear the previous address bits as well?
>>>
>>> You probably did not encounter any problems in your testing if you
>> had
>>> only one PHY on the MDIO bus, but this is not something that is
>>> necessarily true, e.g: if you have an Ethernet switch, several MDIO
>> bus
>>> addresses are going to be responding.
>>>
>>> Your MDIO bus implementation must be able to support one transaction
>>> with one PHY address and the next transaction with another PHY
>> address ,
>>> etc...
>>>
>>> That is something that should be easy to fix and be resubmitted as
>> part
>>> of v4.
>> I'm not following you here... I only set/unset the bit for the
>> corresponding phyaddr that phylib wants to read/write. Why would
>> I clear the remaining addresses?
> Because this is all about transactions, the HW must be in a state that it 
> will be able to perform that transaction correctly. So here for instance if 
> you needed to support a C45 transaction you would have to clear that bit for 
> that particular PHY address. Since you don't appear to support those yet then 
> yes the code appears fine though it would not hurt if you did clear all other 
> PHY's c22 bits to make it clear what this does.

I can't test C45 right now but I will in a near future. In that
case then we will need to support C22 and C45 so I may want to
only set one bit for a specific phy that only supports c22.

Thanks and Best Regards,
Jose Miguel Abreu

>



Re: [stmmac][bug?] endianness of Flexible RX Parser code

2018-08-06 Thread Jose Abreu
Hi Al,

On 04-08-2018 02:19, Al Viro wrote:
>   The values passed in struct tc_u32_sel ->mask and ->val are
> 32bit net-endian.  Your tc_fill_entry() does this:
>
> data = sel->keys[0].val;
> mask = sel->keys[0].mask;
>
> ...
> entry->frag_ptr = frag;
> entry->val.match_en = (mask << (rem * 8)) &
> GENMASK(31, rem * 8);
> entry->val.match_data = (data << (rem * 8)) &
> GENMASK(31, rem * 8);
> entry->val.frame_offset = real_off;
> entry->prio = prio;
>
> frag->val.match_en = (mask >> (rem * 8)) &
> GENMASK(rem * 8 - 1, 0);
> frag->val.match_data = (data >> (rem * 8)) &
> GENMASK(rem * 8 - 1, 0);
> frag->val.frame_offset = real_off + 1;
> frag->prio = prio;
> frag->is_frag = true;
>
> and that looks very odd.  rem here is offset modulo 4.  Suppose offset is
> equal to 5, val contains {V0, V1, V2, V3} and mask - {M0, M1, M2, M3}.
> Then on little-endian host we get
> entry->val.match_en:  {0, M0, M1, M2}
> entry->val.match_data:{0, V0, V1, V2}
> entry->val.frame_offset = 1;
> frag->val.match_en:   {M3, 0, 0, 0}
> frag->val.match_data: {V3, 0, 0, 0}
> frag->val.frame_offset = 2;
> and on big-endian
> entry->val.match_en:  {M1, M2, M3, 0}
> entry->val.match_data:{V1, V2, V3, 0}
> entry->val.frame_offset = 1;
> frag->val.match_en:   {0, 0, 0, M0}
> frag->val.match_data: {0, 0, 0, V0}
> frag->val.frame_offset = 2;
>
> Little-endian variant looks like we mask octets 5, 6, 7 and 8 with
> M0..M3 resp. and want V0..V3 in those.  On big-endian, though, we
> look at the octets 11, 4, 5 and 6 instead.
>
> I don't know the hardware (and it might be pulling any kind of weird
> endianness-dependent stunts), but that really smells like a bug.

There is a feature in HW that supports Byte-Invariant Big-Endian
data transfer. It's not activated by default though ...

> It looks like that code is trying to do something like
>
> data = ntohl(sel->keys[0].val);
> mask = ntohl(sel->keys[0].mask);
>   shift = rem * 8;
>
>   entry->val.match_en = htonl(mask >> shift);
>   entry->val.match_data = htonl(data >> shift);
>   entry->val.frame_offset = real_off;
>   ...
>   frag->val.match_en = htonl(mask << (32 - shift));
>   frag->val.match_data = htonl(data << (32 - shift));
>   entry->val.frame_offset = real_off + 1;
>
> Comments?

Looks good. Can you send a formal patch and a simple command that
I can use to validate this situation?

I used at the time at least two commands: one for validating
simple match by using 1 entry (i.e. plain match) and another to
validate 2 entries (i.e. two matches) and did not encounter any
problem ...

Thanks and Best Regards,
Jose Miguel Abreu


Re: [PATCH v3 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2

2018-08-06 Thread Jose Abreu
On 03-08-2018 20:06, Florian Fainelli wrote:
> On 08/03/2018 08:50 AM, Jose Abreu wrote:
>> Add the MDIO related funcionalities for the new IP block XGMAC2.
>>
>> Signed-off-by: Jose Abreu 
>> Cc: David S. Miller 
>> Cc: Joao Pinto 
>> Cc: Giuseppe Cavallaro 
>> Cc: Alexandre Torgue 
>> Cc: Andrew Lunn 
>> ---
>> +satic int stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int phyaddr,
>> +int phyreg, u32 *hw_addr)
>> +{
>> +unsigned int mii_data = priv->hw->mii.data;
>> +u32 tmp;
>> +
>> +/* HW does not support C22 addr >= 4 */
>> +if (phyaddr >= 4)
>> +return -ENODEV;
> It would be nice if this could be moved at probe time so you don't have
> to wait until you connect to the PHY, read its PHY OUI and find out it
> has a MDIO address >= 4. Not a blocker, but something that could be
> improved further on.
>
> In premise you could even scan the MDIO bus' device tree node, and find
> that out ahead of time.

Oh, but I use phylib ... I only provide the read/write callbacks
so I think we should avoid duplicating the code that's already in
the phylib ... No?

>
>> +/* Wait until any existing MII operation is complete */
>> +if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
>> +   !(tmp & MII_XGMAC_BUSY), 100, 1))
>> +return -EBUSY;
>> +
>> +/* Set port as Clause 22 */
>> +tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
>> +tmp |= BIT(phyaddr);
> Since the registers are being Read/Modify/Write here, don't you need to
> clear the previous address bits as well?
>
> You probably did not encounter any problems in your testing if you had
> only one PHY on the MDIO bus, but this is not something that is
> necessarily true, e.g: if you have an Ethernet switch, several MDIO bus
> addresses are going to be responding.
>
> Your MDIO bus implementation must be able to support one transaction
> with one PHY address and the next transaction with another PHY address ,
> etc...
>
> That is something that should be easy to fix and be resubmitted as part
> of v4.

I'm not following you here... I only set/unset the bit for the
corresponding phyaddr that phylib wants to read/write. Why would
I clear the remaining addresses?

Thanks and Best Regards,
Jose Miguel Abreu


Re: [PATCH v3 net-next 3/9] net: stmmac: Add DMA related callbacks for XGMAC2

2018-08-06 Thread Jose Abreu
On 03-08-2018 19:58, Florian Fainelli wrote:
> On 08/03/2018 08:50 AM, Jose Abreu wrote:
>> Add the DMA related callbacks for the new IP block XGMAC2.
>>
>> Signed-off-by: Jose Abreu 
>> Cc: David S. Miller 
>> Cc: Joao Pinto 
>> Cc: Giuseppe Cavallaro 
>> Cc: Alexandre Torgue 
>> ---
>> +value &= ~XGMAC_RD_OSR_LMT;
>> +value |= (axi->axi_rd_osr_lmt << XGMAC_RD_OSR_LMT_SHIFT) &
>> +XGMAC_RD_OSR_LMT;
>> +
>> +for (i = 0; i < AXI_BLEN; i++) {
>> +if (axi->axi_blen[i])
>> +value &= ~XGMAC_UNDEF;
> Should not you be you clearing all XGMAC_BLEN* values since you do a
> logical or here? I am assuming this is not something that would likely
> change from one open/close but still?

Yeah, this won't change between open/close but I will add the
mask anyway.

Thanks and Best Regards,
Jose Miguel Abreu


Re: [PATCH v3 net-next 1/9] net: stmmac: Add XGMAC 2.10 HWIF entry

2018-08-06 Thread Jose Abreu
Hi Florian,

On 03-08-2018 19:54, Florian Fainelli wrote:
> On 08/03/2018 08:50 AM, Jose Abreu wrote:
>> @@ -87,6 +88,7 @@ static const struct stmmac_hwif_entry {
>>  {
>>  .gmac = false,
>>  .gmac4 = false,
>> +.xgmac = false,
> In a future clean-up you would like want to remove this and replace this
> an enumeration which is less error prone than having to define a boolean
> for each of these previous generations only to say "this is not an xgmac".

Its a good idea! I really don't like the pattern of "if
(priv->plat->has_something)" in the code. I will think about
adding this but for now let's merge xgmac2 and I will try to
refactor the code later because I will need to change many files
and the patchset would be bigger.

Thanks and Best Regards,
Jose Miguel Abreu


[PATCH v3 net-next 9/9] dt-bindings: net: stmmac: Add the bindings documentation for XGMAC2.

2018-08-03 Thread Jose Abreu
Adds the documentation for XGMAC2 DT bindings.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
Cc: Sergei Shtylyov 
Cc: devicet...@vger.kernel.org
Cc: Rob Herring 
---
Changes from v1:
- Correct header, now we also support 2.5/10G.
- Add missing '>' (Sergei)
---
 Documentation/devicetree/bindings/net/stmmac.txt | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/stmmac.txt 
b/Documentation/devicetree/bindings/net/stmmac.txt
index 3a28a5d8857d..a32fd590ce8f 100644
--- a/Documentation/devicetree/bindings/net/stmmac.txt
+++ b/Documentation/devicetree/bindings/net/stmmac.txt
@@ -1,7 +1,8 @@
-* STMicroelectronics 10/100/1000 Ethernet driver (GMAC)
+* STMicroelectronics 10/100/1000/2500/1 Ethernet driver (GMAC/XGMAC)
 
 Required properties:
-- compatible: Should be "snps,dwmac-", "snps,dwmac"
+- compatible: Should be "snps,dwmac-", "snps,dwmac" or
+   "snps,dwxgmac-", "snps,dwxgmac".
For backwards compatibility: "st,spear600-gmac" is also supported.
 - reg: Address and length of the register set for the device
 - interrupt-parent: Should be the phandle for the interrupt controller
-- 
2.7.4




[PATCH v3 net-next 8/9] net: stmmac: Add the bindings parsing for XGMAC2

2018-08-03 Thread Jose Abreu
Add the bindings parsing for XGMAC2 IP block.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c   | 2 ++
 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
index 3304095c934c..fad503820e04 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
@@ -78,6 +78,8 @@ static const struct of_device_id dwmac_generic_match[] = {
{ .compatible = "snps,dwmac-4.00"},
{ .compatible = "snps,dwmac-4.10a"},
{ .compatible = "snps,dwmac"},
+   { .compatible = "snps,dwxgmac-2.10"},
+   { .compatible = "snps,dwxgmac"},
{ }
 };
 MODULE_DEVICE_TABLE(of, dwmac_generic_match);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 72da77b94ecd..3609c7b696c7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -486,6 +486,12 @@ stmmac_probe_config_dt(struct platform_device *pdev, const 
char **mac)
plat->force_sf_dma_mode = 1;
}
 
+   if (of_device_is_compatible(np, "snps,dwxgmac")) {
+   plat->has_xgmac = 1;
+   plat->pmt = 1;
+   plat->tso_en = of_property_read_bool(np, "snps,tso");
+   }
+
dma_cfg = devm_kzalloc(>dev, sizeof(*dma_cfg),
   GFP_KERNEL);
if (!dma_cfg) {
-- 
2.7.4




[PATCH v3 net-next 7/9] net: stmmac: Integrate XGMAC into main driver flow

2018-08-03 Thread Jose Abreu
Now that we have all the XGMAC related callbacks, lets start integrating
this IP block into main driver.

Also, we corrected the initialization flow to only start DMA after
setting descriptors length.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
Cc: Andrew Lunn 
---
Changes from v1:
- Correct flow of initialization
- Remove 2.5G/10G support (Andrew)
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 67 ---
 1 file changed, 48 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9d104a05044d..ff1ffb46198a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -51,6 +51,7 @@
 #include 
 #include 
 #include "dwmac1000.h"
+#include "dwxgmac2.h"
 #include "hwif.h"
 
 #defineSTMMAC_ALIGN(x) __ALIGN_KERNEL(x, SMP_CACHE_BYTES)
@@ -262,6 +263,21 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv)
else
priv->clk_csr = 0;
}
+
+   if (priv->plat->has_xgmac) {
+   if (clk_rate > 4)
+   priv->clk_csr = 0x5;
+   else if (clk_rate > 35000)
+   priv->clk_csr = 0x4;
+   else if (clk_rate > 3)
+   priv->clk_csr = 0x3;
+   else if (clk_rate > 25000)
+   priv->clk_csr = 0x2;
+   else if (clk_rate > 15000)
+   priv->clk_csr = 0x1;
+   else
+   priv->clk_csr = 0x0;
+   }
 }
 
 static void print_pkt(unsigned char *buf, int len)
@@ -498,7 +514,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv 
*priv, struct dma_desc *p,
if (!priv->hwts_rx_en)
return;
/* For GMAC4, the valid timestamp is from CTX next desc. */
-   if (priv->plat->has_gmac4)
+   if (priv->plat->has_gmac4 || priv->plat->has_xgmac)
desc = np;
 
/* Check if timestamp is available */
@@ -540,6 +556,9 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
u32 ts_event_en = 0;
u32 value = 0;
u32 sec_inc;
+   bool xmac;
+
+   xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 
if (!(priv->dma_cap.time_stamp || priv->adv_ts)) {
netdev_alert(priv->dev, "No support for HW time stamping\n");
@@ -575,7 +594,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
/* PTP v1, UDP, any kind of event packet */
config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
/* take time stamp for all event messages */
-   if (priv->plat->has_gmac4)
+   if (xmac)
snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
else
snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
@@ -610,7 +629,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
ptp_v2 = PTP_TCR_TSVER2ENA;
/* take time stamp for all event messages */
-   if (priv->plat->has_gmac4)
+   if (xmac)
snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
else
snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
@@ -647,7 +666,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
ptp_v2 = PTP_TCR_TSVER2ENA;
/* take time stamp for all event messages */
-   if (priv->plat->has_gmac4)
+   if (xmac)
snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
else
snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
@@ -718,7 +737,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
/* program Sub Second Increment reg */
stmmac_config_sub_second_increment(priv,
priv->ptpaddr, priv->plat->clk_ptp_rate,
-   priv->plat->has_gmac4, _inc);
+   xmac, _inc);
temp = div_u64(10ULL, sec_inc);
 
/* Store sub second increment and flags for later use */
@@ -755,12 +774,14 @@ static int stmmac_hwtstamp_ioct

[PATCH v3 net-next 6/9] net: stmmac: Add PTP support for XGMAC2

2018-08-03 Thread Jose Abreu
XGMAC2 uses the same engine of timestamping as GMAC4. Let's use the same
callbacks.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/hwif.c   | 4 ++--
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 6 --
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h | 1 +
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c 
b/drivers/net/ethernet/stmicro/stmmac/hwif.c
index 4b4ba1c8bad5..357309a6d6a5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
@@ -193,13 +193,13 @@ static const struct stmmac_hwif_entry {
.xgmac = true,
.min_id = DWXGMAC_CORE_2_10,
.regs = {
-   .ptp_off = 0,
+   .ptp_off = PTP_XGMAC_OFFSET,
.mmc_off = 0,
},
.desc = _desc_ops,
.dma = _dma_ops,
.mac = _ops,
-   .hwtimestamp = NULL,
+   .hwtimestamp = _ptp,
.mode = NULL,
.tc = NULL,
.setup = dwxgmac2_setup,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
index 0cb0e39a2be9..2293e21f789f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
@@ -71,6 +71,9 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 
delta)
u32 sec, nsec;
u32 quotient, reminder;
int neg_adj = 0;
+   bool xmac;
+
+   xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 
if (delta < 0) {
neg_adj = 1;
@@ -82,8 +85,7 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 
delta)
nsec = reminder;
 
spin_lock_irqsave(>ptp_lock, flags);
-   stmmac_adjust_systime(priv, priv->ptpaddr, sec, nsec, neg_adj,
-   priv->plat->has_gmac4);
+   stmmac_adjust_systime(priv, priv->ptpaddr, sec, nsec, neg_adj, xmac);
spin_unlock_irqrestore(>ptp_lock, flags);
 
return 0;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
index f4b31d69f60e..ecccf895fd7e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
@@ -21,6 +21,7 @@
 #ifndef__STMMAC_PTP_H__
 #define__STMMAC_PTP_H__
 
+#define PTP_XGMAC_OFFSET   0xd00
 #definePTP_GMAC4_OFFSET0xb00
 #definePTP_GMAC3_X_OFFSET  0x700
 
-- 
2.7.4




[PATCH v3 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2

2018-08-03 Thread Jose Abreu
Add the MDIO related funcionalities for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
Cc: Andrew Lunn 
---
Changes from v2:
- Use helper to set C22 (Andrew)
- Wait for bus free before setting C22 reg (Andrew)
Changes from v1:
- Remove C45 support (Andrew)
- Add define for bits (Andrew)
- Remove uneeded cast (Andrew)
- Use different callbacks instead of if's (Andrew)
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 117 +-
 1 file changed, 115 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index 5df1a608e566..7b0167059bd2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 
+#include "dwxgmac2.h"
 #include "stmmac.h"
 
 #define MII_BUSY 0x0001
@@ -39,6 +40,112 @@
 #define MII_GMAC4_WRITE(1 << MII_GMAC4_GOC_SHIFT)
 #define MII_GMAC4_READ (3 << MII_GMAC4_GOC_SHIFT)
 
+/* XGMAC defines */
+#define MII_XGMAC_SADDRBIT(18)
+#define MII_XGMAC_CMD_SHIFT16
+#define MII_XGMAC_WRITE(1 << MII_XGMAC_CMD_SHIFT)
+#define MII_XGMAC_READ (3 << MII_XGMAC_CMD_SHIFT)
+#define MII_XGMAC_BUSY BIT(22)
+
+static int stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int phyaddr,
+   int phyreg, u32 *hw_addr)
+{
+   unsigned int mii_data = priv->hw->mii.data;
+   u32 tmp;
+
+   /* HW does not support C22 addr >= 4 */
+   if (phyaddr >= 4)
+   return -ENODEV;
+   /* Wait until any existing MII operation is complete */
+   if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+  !(tmp & MII_XGMAC_BUSY), 100, 1))
+   return -EBUSY;
+
+   /* Set port as Clause 22 */
+   tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
+   tmp |= BIT(phyaddr);
+   writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
+
+   *hw_addr = (phyaddr << 16) | (phyreg & 0x1f);
+   return 0;
+}
+
+static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int 
phyreg)
+{
+   struct net_device *ndev = bus->priv;
+   struct stmmac_priv *priv = netdev_priv(ndev);
+   unsigned int mii_address = priv->hw->mii.addr;
+   unsigned int mii_data = priv->hw->mii.data;
+   u32 tmp, addr, value = MII_XGMAC_BUSY;
+   int ret;
+
+   if (phyreg & MII_ADDR_C45) {
+   return -EOPNOTSUPP;
+   } else {
+   ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, );
+   if (ret)
+   return ret;
+   }
+
+   value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
+   & priv->hw->mii.clk_csr_mask;
+   value |= MII_XGMAC_SADDR | MII_XGMAC_READ;
+
+   /* Wait until any existing MII operation is complete */
+   if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+  !(tmp & MII_XGMAC_BUSY), 100, 1))
+   return -EBUSY;
+
+   /* Set the MII address register to read */
+   writel(addr, priv->ioaddr + mii_address);
+   writel(value, priv->ioaddr + mii_data);
+
+   /* Wait until any existing MII operation is complete */
+   if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+  !(tmp & MII_XGMAC_BUSY), 100, 1))
+   return -EBUSY;
+
+   /* Read the data from the MII data register */
+   return readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
+}
+
+static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr,
+   int phyreg, u16 phydata)
+{
+   struct net_device *ndev = bus->priv;
+   struct stmmac_priv *priv = netdev_priv(ndev);
+   unsigned int mii_address = priv->hw->mii.addr;
+   unsigned int mii_data = priv->hw->mii.data;
+   u32 addr, tmp, value = MII_XGMAC_BUSY;
+   int ret;
+
+   if (phyreg & MII_ADDR_C45) {
+   return -EOPNOTSUPP;
+   } else {
+   ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, );
+   if (ret)
+   return ret;
+   }
+
+   value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
+   & priv->hw->mii.clk_csr_mask;
+   value |= phydata | MII_XGMAC_SADDR;
+   value |= MII_XGMAC_WRITE;
+
+   /* Wait until any existing MII operation is complete */
+   if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+  !(tmp & MII_XGMAC

[PATCH v3 net-next 3/9] net: stmmac: Add DMA related callbacks for XGMAC2

2018-08-03 Thread Jose Abreu
Add the DMA related callbacks for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   2 +-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h |  56 +++
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 410 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |   2 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   1 +
 5 files changed, 469 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile 
b/drivers/net/ethernet/stmicro/stmmac/Makefile
index a6cf632c9592..da40d3bba037 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o 
ring_mode.o  \
  dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
  mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o  \
  dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
- stmmac_tc.o dwxgmac2_core.o $(stmmac-y)
+ stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)  += stmmac-platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index 7832571f791f..ddd23f8559df 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -138,4 +138,60 @@
 #define XGMAC_ABPSIS   BIT(1)
 #define XGMAC_TXUNFIS  BIT(0)
 
+/* DMA Registers */
+#define XGMAC_DMA_MODE 0x3000
+#define XGMAC_SWR  BIT(0)
+#define XGMAC_DMA_SYSBUS_MODE  0x3004
+#define XGMAC_WR_OSR_LMT   GENMASK(29, 24)
+#define XGMAC_WR_OSR_LMT_SHIFT 24
+#define XGMAC_RD_OSR_LMT   GENMASK(21, 16)
+#define XGMAC_RD_OSR_LMT_SHIFT 16
+#define XGMAC_EN_LPI   BIT(15)
+#define XGMAC_LPI_XIT_PKT  BIT(14)
+#define XGMAC_AAL  BIT(12)
+#define XGMAC_BLEN256  BIT(7)
+#define XGMAC_BLEN128  BIT(6)
+#define XGMAC_BLEN64   BIT(5)
+#define XGMAC_BLEN32   BIT(4)
+#define XGMAC_BLEN16   BIT(3)
+#define XGMAC_BLEN8BIT(2)
+#define XGMAC_BLEN4BIT(1)
+#define XGMAC_UNDEFBIT(0)
+#define XGMAC_DMA_CH_CONTROL(x)(0x3100 + (0x80 * (x)))
+#define XGMAC_PBLx8BIT(16)
+#define XGMAC_DMA_CH_TX_CONTROL(x) (0x3104 + (0x80 * (x)))
+#define XGMAC_TxPBLGENMASK(21, 16)
+#define XGMAC_TxPBL_SHIFT  16
+#define XGMAC_TSE  BIT(12)
+#define XGMAC_OSP  BIT(4)
+#define XGMAC_TXST BIT(0)
+#define XGMAC_DMA_CH_RX_CONTROL(x) (0x3108 + (0x80 * (x)))
+#define XGMAC_RxPBLGENMASK(21, 16)
+#define XGMAC_RxPBL_SHIFT  16
+#define XGMAC_RXST BIT(0)
+#define XGMAC_DMA_CH_TxDESC_LADDR(x)   (0x3114 + (0x80 * (x)))
+#define XGMAC_DMA_CH_RxDESC_LADDR(x)   (0x311c + (0x80 * (x)))
+#define XGMAC_DMA_CH_TxDESC_TAIL_LPTR(x)   (0x3124 + (0x80 * (x)))
+#define XGMAC_DMA_CH_RxDESC_TAIL_LPTR(x)   (0x312c + (0x80 * (x)))
+#define XGMAC_DMA_CH_TxDESC_RING_LEN(x)(0x3130 + (0x80 * 
(x)))
+#define XGMAC_DMA_CH_RxDESC_RING_LEN(x)(0x3134 + (0x80 * 
(x)))
+#define XGMAC_DMA_CH_INT_EN(x) (0x3138 + (0x80 * (x)))
+#define XGMAC_NIE  BIT(15)
+#define XGMAC_AIE  BIT(14)
+#define XGMAC_RBUE BIT(7)
+#define XGMAC_RIE  BIT(6)
+#define XGMAC_TIE  BIT(0)
+#define XGMAC_DMA_INT_DEFAULT_EN   (XGMAC_NIE | XGMAC_AIE | XGMAC_RBUE | \
+   XGMAC_RIE | XGMAC_TIE)
+#define XGMAC_DMA_CH_Rx_WATCHDOG(x)(0x313c + (0x80 * (x)))
+#define XGMAC_RWT  GENMASK(7, 0)
+#define XGMAC_DMA_CH_STATUS(x) (0x3160 + (0x80 * (x)))
+#define XGMAC_NIS  BIT(15)
+#define XGMAC_AIS  BIT(14)
+#define XGMAC_FBE  BIT(12)
+#define XGMAC_RBU  BIT(7)
+#define XGMAC_RI   BIT(6)
+#define XGMAC_TPS  BIT(1)
+#define XGMAC_TI   BIT(0)
+
 #endif /* __STMMAC_DWXGMAC2_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
new file mode 100644
index ..50d9fffc32b5
--- /dev/null
+++ b/drivers/net/ethernet

[PATCH v3 net-next 4/9] net: stmmac: Add descriptor related callbacks for XGMAC2

2018-08-03 Thread Jose Abreu
Add the descriptor related callbacks for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   3 +-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h |  30 +++
 .../net/ethernet/stmicro/stmmac/dwxgmac2_descs.c   | 280 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |   2 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   1 +
 5 files changed, 314 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile 
b/drivers/net/ethernet/stmicro/stmmac/Makefile
index da40d3bba037..99967a80a8c8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -5,7 +5,8 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o 
ring_mode.o  \
  dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
  mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o  \
  dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
- stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o $(stmmac-y)
+ stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o dwxgmac2_descs.o \
+ $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)  += stmmac-platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index ddd23f8559df..d090cbb501f2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -194,4 +194,34 @@
 #define XGMAC_TPS  BIT(1)
 #define XGMAC_TI   BIT(0)
 
+/* Descriptors */
+#define XGMAC_TDES2_IOCBIT(31)
+#define XGMAC_TDES2_TTSE   BIT(30)
+#define XGMAC_TDES2_B2LGENMASK(29, 16)
+#define XGMAC_TDES2_B2L_SHIFT  16
+#define XGMAC_TDES2_B1LGENMASK(13, 0)
+#define XGMAC_TDES3_OWNBIT(31)
+#define XGMAC_TDES3_CTXT   BIT(30)
+#define XGMAC_TDES3_FD BIT(29)
+#define XGMAC_TDES3_LD BIT(28)
+#define XGMAC_TDES3_CPCGENMASK(27, 26)
+#define XGMAC_TDES3_CPC_SHIFT  26
+#define XGMAC_TDES3_TCMSSV BIT(26)
+#define XGMAC_TDES3_THLGENMASK(22, 19)
+#define XGMAC_TDES3_THL_SHIFT  19
+#define XGMAC_TDES3_TSEBIT(18)
+#define XGMAC_TDES3_CICGENMASK(17, 16)
+#define XGMAC_TDES3_CIC_SHIFT  16
+#define XGMAC_TDES3_TPLGENMASK(17, 0)
+#define XGMAC_TDES3_FL GENMASK(14, 0)
+#define XGMAC_RDES3_OWNBIT(31)
+#define XGMAC_RDES3_CTXT   BIT(30)
+#define XGMAC_RDES3_IOCBIT(30)
+#define XGMAC_RDES3_LD BIT(28)
+#define XGMAC_RDES3_CDABIT(27)
+#define XGMAC_RDES3_ES BIT(15)
+#define XGMAC_RDES3_PL GENMASK(13, 0)
+#define XGMAC_RDES3_TSDBIT(6)
+#define XGMAC_RDES3_TSABIT(4)
+
 #endif /* __STMMAC_DWXGMAC2_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
new file mode 100644
index ..1d858fdec997
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
+ * stmmac XGMAC support.
+ */
+
+#include 
+#include "common.h"
+#include "dwxgmac2.h"
+
+static int dwxgmac2_get_tx_status(void *data, struct stmmac_extra_stats *x,
+ struct dma_desc *p, void __iomem *ioaddr)
+{
+   unsigned int tdes3 = le32_to_cpu(p->des3);
+   int ret = tx_done;
+
+   if (unlikely(tdes3 & XGMAC_TDES3_OWN))
+   return tx_dma_own;
+   if (likely(!(tdes3 & XGMAC_TDES3_LD)))
+   return tx_not_ls;
+
+   return ret;
+}
+
+static int dwxgmac2_get_rx_status(void *data, struct stmmac_extra_stats *x,
+ struct dma_desc *p)
+{
+   unsigned int rdes3 = le32_to_cpu(p->des3);
+   int ret = good_frame;
+
+   if (unlikely(rdes3 & XGMAC_RDES3_OWN))
+   return dma_own;
+   if (likely(!(rdes3 & XGMAC_RDES3_LD)))
+   return discard_frame;
+   if (unlikely(rdes3 & XGMAC_RDES3_ES))
+   ret = discard_frame;
+
+   return ret;
+}
+
+static int dwxgmac2_get_tx_len(struct dma_desc *p)
+{
+   return (le32_to_cpu(p->des2) & XGMAC_TDES2_B1L);
+}
+
+static int dwxgmac2_get_tx_owner(struc

[PATCH v3 net-next 1/9] net: stmmac: Add XGMAC 2.10 HWIF entry

2018-08-03 Thread Jose Abreu
Add a new entry to HWIF table for XGMAC 2.10. For now we fill it with
empty callbacks which will be added in posterior patches.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/common.h | 14 +++--
 drivers/net/ethernet/stmicro/stmmac/hwif.c   | 31 ++--
 include/linux/stmmac.h   |  1 +
 3 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
b/drivers/net/ethernet/stmicro/stmmac/common.h
index 78fd0f8b8e81..3fb81acbd274 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -36,12 +36,14 @@
 #include "mmc.h"
 
 /* Synopsys Core versions */
-#defineDWMAC_CORE_3_40 0x34
-#defineDWMAC_CORE_3_50 0x35
-#defineDWMAC_CORE_4_00 0x40
-#define DWMAC_CORE_4_100x41
-#define DWMAC_CORE_5_00 0x50
-#define DWMAC_CORE_5_10 0x51
+#defineDWMAC_CORE_3_40 0x34
+#defineDWMAC_CORE_3_50 0x35
+#defineDWMAC_CORE_4_00 0x40
+#define DWMAC_CORE_4_100x41
+#define DWMAC_CORE_5_000x50
+#define DWMAC_CORE_5_100x51
+#define DWXGMAC_CORE_2_10  0x21
+
 #define STMMAC_CHAN0   0   /* Always supported and default for all chips */
 
 /* These need to be power of two, and >= 4 */
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c 
b/drivers/net/ethernet/stmicro/stmmac/hwif.c
index 1f50e83cafb2..24f5ff175aa4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
@@ -72,6 +72,7 @@ static int stmmac_dwmac4_quirks(struct stmmac_priv *priv)
 static const struct stmmac_hwif_entry {
bool gmac;
bool gmac4;
+   bool xgmac;
u32 min_id;
const struct stmmac_regs_off regs;
const void *desc;
@@ -87,6 +88,7 @@ static const struct stmmac_hwif_entry {
{
.gmac = false,
.gmac4 = false,
+   .xgmac = false,
.min_id = 0,
.regs = {
.ptp_off = PTP_GMAC3_X_OFFSET,
@@ -103,6 +105,7 @@ static const struct stmmac_hwif_entry {
}, {
.gmac = true,
.gmac4 = false,
+   .xgmac = false,
.min_id = 0,
.regs = {
.ptp_off = PTP_GMAC3_X_OFFSET,
@@ -119,6 +122,7 @@ static const struct stmmac_hwif_entry {
}, {
.gmac = false,
.gmac4 = true,
+   .xgmac = false,
.min_id = 0,
.regs = {
.ptp_off = PTP_GMAC4_OFFSET,
@@ -135,6 +139,7 @@ static const struct stmmac_hwif_entry {
}, {
.gmac = false,
.gmac4 = true,
+   .xgmac = false,
.min_id = DWMAC_CORE_4_00,
.regs = {
.ptp_off = PTP_GMAC4_OFFSET,
@@ -151,6 +156,7 @@ static const struct stmmac_hwif_entry {
}, {
.gmac = false,
.gmac4 = true,
+   .xgmac = false,
.min_id = DWMAC_CORE_4_10,
.regs = {
.ptp_off = PTP_GMAC4_OFFSET,
@@ -167,6 +173,7 @@ static const struct stmmac_hwif_entry {
}, {
.gmac = false,
.gmac4 = true,
+   .xgmac = false,
.min_id = DWMAC_CORE_5_10,
.regs = {
.ptp_off = PTP_GMAC4_OFFSET,
@@ -180,11 +187,29 @@ static const struct stmmac_hwif_entry {
.tc = _tc_ops,
.setup = dwmac4_setup,
.quirks = NULL,
-   }
+   }, {
+   .gmac = false,
+   .gmac4 = false,
+   .xgmac = true,
+   .min_id = DWXGMAC_CORE_2_10,
+   .regs = {
+   .ptp_off = 0,
+   .mmc_off = 0,
+   },
+   .desc = NULL,
+   .dma = NULL,
+   .mac = NULL,
+   .hwtimestamp = NULL,
+   .mode = NULL,
+   .tc = NULL,
+   .setup = NULL,
+   .quirks = NULL,
+   },
 };
 
 int stmmac_hwif_init(struct stmmac_priv *priv)
 {
+   bool needs_xgmac = priv->plat->has_xgmac;
bool needs_gmac4 = priv->plat->has_gmac4;
bool needs_gmac = priv->plat->has_gmac;
const struct stmmac_hwif_entry *entry;
@@ -195,7 +220,7 @@ int stmmac_hwif_init(struct stmmac_priv *priv)
 
if (needs_gmac) {
id = stmmac_get_id(priv, GMAC_VERSION);
-   } else if (needs_gmac4) {
+   } else if (needs_gmac4 || needs_xgmac) {
id = stmmac_get_id(priv, GMAC4_VERSION);
} else {
id = 0;
@@ -229,6 +254,8

[PATCH v3 net-next 0/9] Add support for XGMAC2 in stmmac

2018-08-03 Thread Jose Abreu
This series adds support for 10Gigabit IP in stmmac. The IP is called XGMAC2
and has many similarities with GMAC4. Due to this, its relatively easy to
incorporate this new IP into stmmac driver by adding a new block and
filling the necessary callbacks.

The functionality added by this series is still reduced but its only a
starting point which will later be expanded.

I splitted the patches into funcionality and to ease the review. Only the
patch 8/9 really enables the XGMAC2 block by adding a new compatible string.

Version 3 addresses review comments of Andrew Lunn.

NOTE: Although the IP supports 10G, for now it was only possible to test it
at 1G speed due to 10G PHY HW shipping problems. Here follows iperf3
results at 1G:

---
# iperf3 -c 192.168.0.10
Connecting to host 192.168.0.10, port 5201
[  4] local 192.168.0.3 port 39178 connected to 192.168.0.10 port 5201
[ ID] Interval   Transfer Bandwidth   Retr  Cwnd
[  4]   0.00-1.00   sec   110 MBytes   920 Mbits/sec0482 KBytes
[  4]   1.00-2.00   sec   113 MBytes   946 Mbits/sec0482 KBytes
[  4]   2.00-3.00   sec   112 MBytes   937 Mbits/sec0482 KBytes
[  4]   3.00-4.00   sec   113 MBytes   946 Mbits/sec0482 KBytes
[  4]   4.00-5.00   sec   112 MBytes   935 Mbits/sec0482 KBytes
[  4]   5.00-6.00   sec   113 MBytes   946 Mbits/sec0482 KBytes
[  4]   6.00-7.00   sec   112 MBytes   937 Mbits/sec0482 KBytes
[  4]   7.00-8.00   sec   113 MBytes   946 Mbits/sec0482 KBytes
[  4]   8.00-9.00   sec   112 MBytes   937 Mbits/sec0482 KBytes
[  4]   9.00-10.00  sec   113 MBytes   946 Mbits/sec0482 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   Retr
[  4]   0.00-10.00  sec  1.09 GBytes   940 Mbits/sec0 sender
[  4]   0.00-10.00  sec  1.09 GBytes   938 Mbits/sec  receiver
---

Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
Cc: Andrew Lunn 

Jose Abreu (9):
  net: stmmac: Add XGMAC 2.10 HWIF entry
  net: stmmac: Add MAC related callbacks for XGMAC2
  net: stmmac: Add DMA related callbacks for XGMAC2
  net: stmmac: Add descriptor related callbacks for XGMAC2
  net: stmmac: Add MDIO related functions for XGMAC2
  net: stmmac: Add PTP support for XGMAC2
  net: stmmac: Integrate XGMAC into main driver flow
  net: stmmac: Add the bindings parsing for XGMAC2
  dt-bindings: net: stmmac: Add the bindings documentation for XGMAC2.

 Documentation/devicetree/bindings/net/stmmac.txt   |   5 +-
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   3 +-
 drivers/net/ethernet/stmicro/stmmac/common.h   |  17 +-
 .../net/ethernet/stmicro/stmmac/dwmac-generic.c|   2 +
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 227 
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c| 371 +++
 .../net/ethernet/stmicro/stmmac/dwxgmac2_descs.c   | 280 ++
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 410 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |  31 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   3 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  67 +++-
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c  | 117 +-
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   6 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c   |   6 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h   |   1 +
 include/linux/stmmac.h |   1 +
 16 files changed, 1513 insertions(+), 34 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c

-- 
2.7.4




[PATCH v3 net-next 2/9] net: stmmac: Add MAC related callbacks for XGMAC2

2018-08-03 Thread Jose Abreu
Add the MAC related callbacks for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   2 +-
 drivers/net/ethernet/stmicro/stmmac/common.h   |   3 +
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 141 
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c| 371 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |   4 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   1 +
 6 files changed, 519 insertions(+), 3 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile 
b/drivers/net/ethernet/stmicro/stmmac/Makefile
index 68e9e2640c62..a6cf632c9592 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o 
ring_mode.o  \
  dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
  mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o  \
  dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
- stmmac_tc.o $(stmmac-y)
+ stmmac_tc.o dwxgmac2_core.o $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)  += stmmac-platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
b/drivers/net/ethernet/stmicro/stmmac/common.h
index 3fb81acbd274..1854f270ad66 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -400,6 +400,8 @@ struct mac_link {
u32 speed10;
u32 speed100;
u32 speed1000;
+   u32 speed2500;
+   u32 speed1;
u32 duplex;
 };
 
@@ -441,6 +443,7 @@ struct stmmac_rx_routing {
 int dwmac100_setup(struct stmmac_priv *priv);
 int dwmac1000_setup(struct stmmac_priv *priv);
 int dwmac4_setup(struct stmmac_priv *priv);
+int dwxgmac2_setup(struct stmmac_priv *priv);
 
 void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
 unsigned int high, unsigned int low);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
new file mode 100644
index ..7832571f791f
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
+ * stmmac XGMAC definitions.
+ */
+
+#ifndef __STMMAC_DWXGMAC2_H__
+#define __STMMAC_DWXGMAC2_H__
+
+#include "common.h"
+
+/* Misc */
+#define XGMAC_JUMBO_LEN16368
+
+/* MAC Registers */
+#define XGMAC_TX_CONFIG0x
+#define XGMAC_CONFIG_SS_OFF29
+#define XGMAC_CONFIG_SS_MASK   GENMASK(30, 29)
+#define XGMAC_CONFIG_SS_1  (0x0 << XGMAC_CONFIG_SS_OFF)
+#define XGMAC_CONFIG_SS_2500   (0x2 << XGMAC_CONFIG_SS_OFF)
+#define XGMAC_CONFIG_SS_1000   (0x3 << XGMAC_CONFIG_SS_OFF)
+#define XGMAC_CONFIG_SARC  GENMASK(22, 20)
+#define XGMAC_CONFIG_SARC_SHIFT20
+#define XGMAC_CONFIG_JDBIT(16)
+#define XGMAC_CONFIG_TEBIT(0)
+#define XGMAC_CORE_INIT_TX (XGMAC_CONFIG_JD)
+#define XGMAC_RX_CONFIG0x0004
+#define XGMAC_CONFIG_ARPEN BIT(31)
+#define XGMAC_CONFIG_GPSL  GENMASK(29, 16)
+#define XGMAC_CONFIG_GPSL_SHIFT16
+#define XGMAC_CONFIG_S2KP  BIT(11)
+#define XGMAC_CONFIG_IPC   BIT(9)
+#define XGMAC_CONFIG_JEBIT(8)
+#define XGMAC_CONFIG_WDBIT(7)
+#define XGMAC_CONFIG_GPSLCEBIT(6)
+#define XGMAC_CONFIG_CST   BIT(2)
+#define XGMAC_CONFIG_ACS   BIT(1)
+#define XGMAC_CONFIG_REBIT(0)
+#define XGMAC_CORE_INIT_RX 0
+#define XGMAC_PACKET_FILTER0x0008
+#define XGMAC_FILTER_RABIT(31)
+#define XGMAC_FILTER_PMBIT(4)
+#define XGMAC_FILTER_HMC   BIT(2)
+#define XGMAC_FILTER_PRBIT(0)
+#define XGMAC_HASH_TABLE(x)(0x0010 + (x) * 4)
+#define XGMAC_RXQ_CTRL00x00a0
+#define XGMAC_RXQEN(x) GENMASK((x) * 2 + 1, (x) * 2)
+#define XGMAC_RXQEN_SHIFT(x)   ((x) * 2)
+#define XGMAC_RXQ_CTRL20x00a8
+#define XGMAC_RXQ_CTRL30x00ac
+#define XGMAC_PSRQ(x)  GENMASK((x) * 8 + 7, (x) * 8)
+#define XGMAC_PSRQ_SHIFT(x)((x) * 8)
+#define XGMAC_INT_STATUS   0x0

Re: [PATCH v2 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2

2018-08-03 Thread Jose Abreu
Hi Andrew,

On 03-08-2018 16:20, Andrew Lunn wrote:
> On Fri, Aug 03, 2018 at 03:56:07PM +0100, Jose Abreu wrote:
>> Add the MDIO related funcionalities for the new IP block XGMAC2.
>>
>> Signed-off-by: Jose Abreu 
>> Cc: David S. Miller 
>> Cc: Joao Pinto 
>> Cc: Giuseppe Cavallaro 
>> Cc: Alexandre Torgue 
>> Cc: Andrew Lunn 
>> ---
>> Changes from v1:
>>  - Remove C45 support (Andrew)
>>  - Add define for bits (Andrew)
>>  - Remove uneeded cast (Andrew)
>>  - Use different callbacks instead of if's (Andrew)
>> ---
>>  drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 101 
>> +-
>>  1 file changed, 99 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c 
>> b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
>> index 5df1a608e566..9bbdb78d3315 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
>> @@ -29,6 +29,7 @@
>>  #include 
>>  #include 
>>  
>> +#include "dwxgmac2.h"
>>  #include "stmmac.h"
>>  
>>  #define MII_BUSY 0x0001
>> @@ -39,6 +40,96 @@
>>  #define MII_GMAC4_WRITE (1 << MII_GMAC4_GOC_SHIFT)
>>  #define MII_GMAC4_READ  (3 << MII_GMAC4_GOC_SHIFT)
>>  
>> +/* XGMAC defines */
>> +#define MII_XGMAC_SADDR BIT(18)
>> +#define MII_XGMAC_CMD_SHIFT 16
>> +#define MII_XGMAC_WRITE (1 << MII_XGMAC_CMD_SHIFT)
>> +#define MII_XGMAC_READ  (3 << MII_XGMAC_CMD_SHIFT)
>> +#define MII_XGMAC_BUSY  BIT(22)
>> +
>> +static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int 
>> phyreg)
>> +{
>> +struct net_device *ndev = bus->priv;
>> +struct stmmac_priv *priv = netdev_priv(ndev);
>> +unsigned int mii_address = priv->hw->mii.addr;
>> +unsigned int mii_data = priv->hw->mii.data;
>> +u32 tmp, addr, value = MII_XGMAC_BUSY;
>> +
>> +if (phyreg & MII_ADDR_C45) {
>> +return -EOPNOTSUPP;
>> +} else {
>> +if (phyaddr >= 4)
>> +return -ENODEV;
>> +
>> +/* Set port as Clause 22 */
>> +tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
>> +tmp |= BIT(phyaddr);
>> +writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
> Hi Jose
>
> Maybe put this into a helper? You do repeat it twice.

Yes, makes sense.

>
>> +
>> +addr = (phyaddr << 16) | (phyreg & 0x1f);
> You could use GENMASK(4, 0) here. That was the point i was trying to
> make earlier. But i actually find 0x1f, and 0x easier to read.

Less typing :D

>
>> +}
>> +
>> +value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
>> +& priv->hw->mii.clk_csr_mask;
>> +value |= MII_XGMAC_SADDR | MII_XGMAC_READ;
>> +
>> +if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
>> +   !(tmp & MII_XGMAC_BUSY), 100, 1))
>> +return -EBUSY;
> Probably you want to wait for the bus to be idle before you change the
> mode to C22. Some PHYs can do both C22 and C45, e.g. EEE registers can
> be in C45 space, while the rest are in C22.

Ok but I can't test C45 right now so maybe leave that change to
when I can test it ?

Thanks and Best Regards,
Jose Miguel Abreu

>
>> +
>> +writel(addr, priv->ioaddr + mii_address);
>> +writel(value, priv->ioaddr + mii_data);
>> +
>> +if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
>> +   !(tmp & MII_XGMAC_BUSY), 100, 1))
>> +return -EBUSY;
>> +
>> +/* Read the data from the MII data register */
>> +return readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
>> +}
>   Andrew



[PATCH v2 net-next 7/9] net: stmmac: Integrate XGMAC into main driver flow

2018-08-03 Thread Jose Abreu
Now that we have all the XGMAC related callbacks, lets start integrating
this IP block into main driver.

Also, we corrected the initialization flow to only start DMA after
setting descriptors length.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
Cc: Andrew Lunn 
---
Changes from v1:
- Correct flow of initialization
- Remove 2.5G/10G support (Andrew)
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 67 ---
 1 file changed, 48 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9d104a05044d..ff1ffb46198a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -51,6 +51,7 @@
 #include 
 #include 
 #include "dwmac1000.h"
+#include "dwxgmac2.h"
 #include "hwif.h"
 
 #defineSTMMAC_ALIGN(x) __ALIGN_KERNEL(x, SMP_CACHE_BYTES)
@@ -262,6 +263,21 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv)
else
priv->clk_csr = 0;
}
+
+   if (priv->plat->has_xgmac) {
+   if (clk_rate > 4)
+   priv->clk_csr = 0x5;
+   else if (clk_rate > 35000)
+   priv->clk_csr = 0x4;
+   else if (clk_rate > 3)
+   priv->clk_csr = 0x3;
+   else if (clk_rate > 25000)
+   priv->clk_csr = 0x2;
+   else if (clk_rate > 15000)
+   priv->clk_csr = 0x1;
+   else
+   priv->clk_csr = 0x0;
+   }
 }
 
 static void print_pkt(unsigned char *buf, int len)
@@ -498,7 +514,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv 
*priv, struct dma_desc *p,
if (!priv->hwts_rx_en)
return;
/* For GMAC4, the valid timestamp is from CTX next desc. */
-   if (priv->plat->has_gmac4)
+   if (priv->plat->has_gmac4 || priv->plat->has_xgmac)
desc = np;
 
/* Check if timestamp is available */
@@ -540,6 +556,9 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
u32 ts_event_en = 0;
u32 value = 0;
u32 sec_inc;
+   bool xmac;
+
+   xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 
if (!(priv->dma_cap.time_stamp || priv->adv_ts)) {
netdev_alert(priv->dev, "No support for HW time stamping\n");
@@ -575,7 +594,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
/* PTP v1, UDP, any kind of event packet */
config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
/* take time stamp for all event messages */
-   if (priv->plat->has_gmac4)
+   if (xmac)
snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
else
snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
@@ -610,7 +629,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
ptp_v2 = PTP_TCR_TSVER2ENA;
/* take time stamp for all event messages */
-   if (priv->plat->has_gmac4)
+   if (xmac)
snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
else
snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
@@ -647,7 +666,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
ptp_v2 = PTP_TCR_TSVER2ENA;
/* take time stamp for all event messages */
-   if (priv->plat->has_gmac4)
+   if (xmac)
snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
else
snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
@@ -718,7 +737,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
/* program Sub Second Increment reg */
stmmac_config_sub_second_increment(priv,
priv->ptpaddr, priv->plat->clk_ptp_rate,
-   priv->plat->has_gmac4, _inc);
+   xmac, _inc);
temp = div_u64(10ULL, sec_inc);
 
/* Store sub second increment and flags for later use */
@@ -755,12 +774,14 @@ static int stmmac_hwtstamp_ioct

[PATCH v2 net-next 9/9] dt-bindings: net: stmmac: Add the bindings documentation for XGMAC2.

2018-08-03 Thread Jose Abreu
Adds the documentation for XGMAC2 DT bindings.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
Cc: Sergei Shtylyov 
Cc: devicet...@vger.kernel.org
Cc: Rob Herring 
---
Changes from v1:
- Correct header, now we also support 2.5/10G.
- Add missing '>' (Sergei)
---
 Documentation/devicetree/bindings/net/stmmac.txt | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/stmmac.txt 
b/Documentation/devicetree/bindings/net/stmmac.txt
index 3a28a5d8857d..a32fd590ce8f 100644
--- a/Documentation/devicetree/bindings/net/stmmac.txt
+++ b/Documentation/devicetree/bindings/net/stmmac.txt
@@ -1,7 +1,8 @@
-* STMicroelectronics 10/100/1000 Ethernet driver (GMAC)
+* STMicroelectronics 10/100/1000/2500/1 Ethernet driver (GMAC/XGMAC)
 
 Required properties:
-- compatible: Should be "snps,dwmac-", "snps,dwmac"
+- compatible: Should be "snps,dwmac-", "snps,dwmac" or
+   "snps,dwxgmac-", "snps,dwxgmac".
For backwards compatibility: "st,spear600-gmac" is also supported.
 - reg: Address and length of the register set for the device
 - interrupt-parent: Should be the phandle for the interrupt controller
-- 
2.7.4




[PATCH v2 net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2

2018-08-03 Thread Jose Abreu
Add the MDIO related funcionalities for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
Cc: Andrew Lunn 
---
Changes from v1:
- Remove C45 support (Andrew)
- Add define for bits (Andrew)
- Remove uneeded cast (Andrew)
- Use different callbacks instead of if's (Andrew)
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 101 +-
 1 file changed, 99 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index 5df1a608e566..9bbdb78d3315 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 
+#include "dwxgmac2.h"
 #include "stmmac.h"
 
 #define MII_BUSY 0x0001
@@ -39,6 +40,96 @@
 #define MII_GMAC4_WRITE(1 << MII_GMAC4_GOC_SHIFT)
 #define MII_GMAC4_READ (3 << MII_GMAC4_GOC_SHIFT)
 
+/* XGMAC defines */
+#define MII_XGMAC_SADDRBIT(18)
+#define MII_XGMAC_CMD_SHIFT16
+#define MII_XGMAC_WRITE(1 << MII_XGMAC_CMD_SHIFT)
+#define MII_XGMAC_READ (3 << MII_XGMAC_CMD_SHIFT)
+#define MII_XGMAC_BUSY BIT(22)
+
+static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int 
phyreg)
+{
+   struct net_device *ndev = bus->priv;
+   struct stmmac_priv *priv = netdev_priv(ndev);
+   unsigned int mii_address = priv->hw->mii.addr;
+   unsigned int mii_data = priv->hw->mii.data;
+   u32 tmp, addr, value = MII_XGMAC_BUSY;
+
+   if (phyreg & MII_ADDR_C45) {
+   return -EOPNOTSUPP;
+   } else {
+   if (phyaddr >= 4)
+   return -ENODEV;
+
+   /* Set port as Clause 22 */
+   tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
+   tmp |= BIT(phyaddr);
+   writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
+
+   addr = (phyaddr << 16) | (phyreg & 0x1f);
+   }
+
+   value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
+   & priv->hw->mii.clk_csr_mask;
+   value |= MII_XGMAC_SADDR | MII_XGMAC_READ;
+
+   if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+  !(tmp & MII_XGMAC_BUSY), 100, 1))
+   return -EBUSY;
+
+   writel(addr, priv->ioaddr + mii_address);
+   writel(value, priv->ioaddr + mii_data);
+
+   if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+  !(tmp & MII_XGMAC_BUSY), 100, 1))
+   return -EBUSY;
+
+   /* Read the data from the MII data register */
+   return readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
+}
+
+static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr,
+   int phyreg, u16 phydata)
+{
+   struct net_device *ndev = bus->priv;
+   struct stmmac_priv *priv = netdev_priv(ndev);
+   unsigned int mii_address = priv->hw->mii.addr;
+   unsigned int mii_data = priv->hw->mii.data;
+   u32 addr, tmp, value = MII_XGMAC_BUSY;
+
+   if (phyreg & MII_ADDR_C45) {
+   return -EOPNOTSUPP;
+   } else {
+   if (phyaddr >= 4)
+   return -ENODEV;
+
+   /* Set port as Clause 22 */
+   tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
+   tmp |= BIT(phyaddr);
+   writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
+
+   addr = (phyaddr << 16) | (phyreg & 0x1f);
+   }
+
+   value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
+   & priv->hw->mii.clk_csr_mask;
+   value |= phydata | MII_XGMAC_SADDR;
+   value |= MII_XGMAC_WRITE;
+
+   /* Wait until any existing MII operation is complete */
+   if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+  !(tmp & MII_XGMAC_BUSY), 100, 1))
+   return -EBUSY;
+
+   /* Set the MII address register to write */
+   writel(addr, priv->ioaddr + mii_address);
+   writel(value, priv->ioaddr + mii_data);
+
+   /* Wait until any existing MII operation is complete */
+   return readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+ !(tmp & MII_XGMAC_BUSY), 100, 1);
+}
+
 /**
  * stmmac_mdio_read
  * @bus: points to the mii_bus structure
@@ -223,8 +314,14 @@ int stmmac_mdio_register(struct net_device *ndev)
 #endif
 
new_bus->name = "stmmac";
-   new_bus->read = _mdio_read;
-   new_bus->write = _mdio_write;
+
+   if

[PATCH v2 net-next 4/9] net: stmmac: Add descriptor related callbacks for XGMAC2

2018-08-03 Thread Jose Abreu
Add the descriptor related callbacks for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   3 +-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h |  30 +++
 .../net/ethernet/stmicro/stmmac/dwxgmac2_descs.c   | 280 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |   2 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   1 +
 5 files changed, 314 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile 
b/drivers/net/ethernet/stmicro/stmmac/Makefile
index da40d3bba037..99967a80a8c8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -5,7 +5,8 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o 
ring_mode.o  \
  dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
  mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o  \
  dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
- stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o $(stmmac-y)
+ stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o dwxgmac2_descs.o \
+ $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)  += stmmac-platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index ddd23f8559df..d090cbb501f2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -194,4 +194,34 @@
 #define XGMAC_TPS  BIT(1)
 #define XGMAC_TI   BIT(0)
 
+/* Descriptors */
+#define XGMAC_TDES2_IOCBIT(31)
+#define XGMAC_TDES2_TTSE   BIT(30)
+#define XGMAC_TDES2_B2LGENMASK(29, 16)
+#define XGMAC_TDES2_B2L_SHIFT  16
+#define XGMAC_TDES2_B1LGENMASK(13, 0)
+#define XGMAC_TDES3_OWNBIT(31)
+#define XGMAC_TDES3_CTXT   BIT(30)
+#define XGMAC_TDES3_FD BIT(29)
+#define XGMAC_TDES3_LD BIT(28)
+#define XGMAC_TDES3_CPCGENMASK(27, 26)
+#define XGMAC_TDES3_CPC_SHIFT  26
+#define XGMAC_TDES3_TCMSSV BIT(26)
+#define XGMAC_TDES3_THLGENMASK(22, 19)
+#define XGMAC_TDES3_THL_SHIFT  19
+#define XGMAC_TDES3_TSEBIT(18)
+#define XGMAC_TDES3_CICGENMASK(17, 16)
+#define XGMAC_TDES3_CIC_SHIFT  16
+#define XGMAC_TDES3_TPLGENMASK(17, 0)
+#define XGMAC_TDES3_FL GENMASK(14, 0)
+#define XGMAC_RDES3_OWNBIT(31)
+#define XGMAC_RDES3_CTXT   BIT(30)
+#define XGMAC_RDES3_IOCBIT(30)
+#define XGMAC_RDES3_LD BIT(28)
+#define XGMAC_RDES3_CDABIT(27)
+#define XGMAC_RDES3_ES BIT(15)
+#define XGMAC_RDES3_PL GENMASK(13, 0)
+#define XGMAC_RDES3_TSDBIT(6)
+#define XGMAC_RDES3_TSABIT(4)
+
 #endif /* __STMMAC_DWXGMAC2_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
new file mode 100644
index ..1d858fdec997
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
+ * stmmac XGMAC support.
+ */
+
+#include 
+#include "common.h"
+#include "dwxgmac2.h"
+
+static int dwxgmac2_get_tx_status(void *data, struct stmmac_extra_stats *x,
+ struct dma_desc *p, void __iomem *ioaddr)
+{
+   unsigned int tdes3 = le32_to_cpu(p->des3);
+   int ret = tx_done;
+
+   if (unlikely(tdes3 & XGMAC_TDES3_OWN))
+   return tx_dma_own;
+   if (likely(!(tdes3 & XGMAC_TDES3_LD)))
+   return tx_not_ls;
+
+   return ret;
+}
+
+static int dwxgmac2_get_rx_status(void *data, struct stmmac_extra_stats *x,
+ struct dma_desc *p)
+{
+   unsigned int rdes3 = le32_to_cpu(p->des3);
+   int ret = good_frame;
+
+   if (unlikely(rdes3 & XGMAC_RDES3_OWN))
+   return dma_own;
+   if (likely(!(rdes3 & XGMAC_RDES3_LD)))
+   return discard_frame;
+   if (unlikely(rdes3 & XGMAC_RDES3_ES))
+   ret = discard_frame;
+
+   return ret;
+}
+
+static int dwxgmac2_get_tx_len(struct dma_desc *p)
+{
+   return (le32_to_cpu(p->des2) & XGMAC_TDES2_B1L);
+}
+
+static int dwxgmac2_get_tx_owner(struc

[PATCH v2 net-next 1/9] net: stmmac: Add XGMAC 2.10 HWIF entry

2018-08-03 Thread Jose Abreu
Add a new entry to HWIF table for XGMAC 2.10. For now we fill it with
empty callbacks which will be added in posterior patches.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/common.h | 14 +++--
 drivers/net/ethernet/stmicro/stmmac/hwif.c   | 31 ++--
 include/linux/stmmac.h   |  1 +
 3 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
b/drivers/net/ethernet/stmicro/stmmac/common.h
index 78fd0f8b8e81..3fb81acbd274 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -36,12 +36,14 @@
 #include "mmc.h"
 
 /* Synopsys Core versions */
-#defineDWMAC_CORE_3_40 0x34
-#defineDWMAC_CORE_3_50 0x35
-#defineDWMAC_CORE_4_00 0x40
-#define DWMAC_CORE_4_100x41
-#define DWMAC_CORE_5_00 0x50
-#define DWMAC_CORE_5_10 0x51
+#defineDWMAC_CORE_3_40 0x34
+#defineDWMAC_CORE_3_50 0x35
+#defineDWMAC_CORE_4_00 0x40
+#define DWMAC_CORE_4_100x41
+#define DWMAC_CORE_5_000x50
+#define DWMAC_CORE_5_100x51
+#define DWXGMAC_CORE_2_10  0x21
+
 #define STMMAC_CHAN0   0   /* Always supported and default for all chips */
 
 /* These need to be power of two, and >= 4 */
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c 
b/drivers/net/ethernet/stmicro/stmmac/hwif.c
index 1f50e83cafb2..24f5ff175aa4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
@@ -72,6 +72,7 @@ static int stmmac_dwmac4_quirks(struct stmmac_priv *priv)
 static const struct stmmac_hwif_entry {
bool gmac;
bool gmac4;
+   bool xgmac;
u32 min_id;
const struct stmmac_regs_off regs;
const void *desc;
@@ -87,6 +88,7 @@ static const struct stmmac_hwif_entry {
{
.gmac = false,
.gmac4 = false,
+   .xgmac = false,
.min_id = 0,
.regs = {
.ptp_off = PTP_GMAC3_X_OFFSET,
@@ -103,6 +105,7 @@ static const struct stmmac_hwif_entry {
}, {
.gmac = true,
.gmac4 = false,
+   .xgmac = false,
.min_id = 0,
.regs = {
.ptp_off = PTP_GMAC3_X_OFFSET,
@@ -119,6 +122,7 @@ static const struct stmmac_hwif_entry {
}, {
.gmac = false,
.gmac4 = true,
+   .xgmac = false,
.min_id = 0,
.regs = {
.ptp_off = PTP_GMAC4_OFFSET,
@@ -135,6 +139,7 @@ static const struct stmmac_hwif_entry {
}, {
.gmac = false,
.gmac4 = true,
+   .xgmac = false,
.min_id = DWMAC_CORE_4_00,
.regs = {
.ptp_off = PTP_GMAC4_OFFSET,
@@ -151,6 +156,7 @@ static const struct stmmac_hwif_entry {
}, {
.gmac = false,
.gmac4 = true,
+   .xgmac = false,
.min_id = DWMAC_CORE_4_10,
.regs = {
.ptp_off = PTP_GMAC4_OFFSET,
@@ -167,6 +173,7 @@ static const struct stmmac_hwif_entry {
}, {
.gmac = false,
.gmac4 = true,
+   .xgmac = false,
.min_id = DWMAC_CORE_5_10,
.regs = {
.ptp_off = PTP_GMAC4_OFFSET,
@@ -180,11 +187,29 @@ static const struct stmmac_hwif_entry {
.tc = _tc_ops,
.setup = dwmac4_setup,
.quirks = NULL,
-   }
+   }, {
+   .gmac = false,
+   .gmac4 = false,
+   .xgmac = true,
+   .min_id = DWXGMAC_CORE_2_10,
+   .regs = {
+   .ptp_off = 0,
+   .mmc_off = 0,
+   },
+   .desc = NULL,
+   .dma = NULL,
+   .mac = NULL,
+   .hwtimestamp = NULL,
+   .mode = NULL,
+   .tc = NULL,
+   .setup = NULL,
+   .quirks = NULL,
+   },
 };
 
 int stmmac_hwif_init(struct stmmac_priv *priv)
 {
+   bool needs_xgmac = priv->plat->has_xgmac;
bool needs_gmac4 = priv->plat->has_gmac4;
bool needs_gmac = priv->plat->has_gmac;
const struct stmmac_hwif_entry *entry;
@@ -195,7 +220,7 @@ int stmmac_hwif_init(struct stmmac_priv *priv)
 
if (needs_gmac) {
id = stmmac_get_id(priv, GMAC_VERSION);
-   } else if (needs_gmac4) {
+   } else if (needs_gmac4 || needs_xgmac) {
id = stmmac_get_id(priv, GMAC4_VERSION);
} else {
id = 0;
@@ -229,6 +254,8

[PATCH v2 net-next 8/9] net: stmmac: Add the bindings parsing for XGMAC2

2018-08-03 Thread Jose Abreu
Add the bindings parsing for XGMAC2 IP block.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c   | 2 ++
 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
index 3304095c934c..fad503820e04 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
@@ -78,6 +78,8 @@ static const struct of_device_id dwmac_generic_match[] = {
{ .compatible = "snps,dwmac-4.00"},
{ .compatible = "snps,dwmac-4.10a"},
{ .compatible = "snps,dwmac"},
+   { .compatible = "snps,dwxgmac-2.10"},
+   { .compatible = "snps,dwxgmac"},
{ }
 };
 MODULE_DEVICE_TABLE(of, dwmac_generic_match);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 72da77b94ecd..3609c7b696c7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -486,6 +486,12 @@ stmmac_probe_config_dt(struct platform_device *pdev, const 
char **mac)
plat->force_sf_dma_mode = 1;
}
 
+   if (of_device_is_compatible(np, "snps,dwxgmac")) {
+   plat->has_xgmac = 1;
+   plat->pmt = 1;
+   plat->tso_en = of_property_read_bool(np, "snps,tso");
+   }
+
dma_cfg = devm_kzalloc(>dev, sizeof(*dma_cfg),
   GFP_KERNEL);
if (!dma_cfg) {
-- 
2.7.4




[PATCH v2 net-next 0/9] Add support for XGMAC2 in stmmac

2018-08-03 Thread Jose Abreu
This series adds support for 10Gigabit IP in stmmac. The IP is called XGMAC2
and has many similarities with GMAC4. Due to this, its relatively easy to
incorporate this new IP into stmmac driver by adding a new block and
filling the necessary callbacks.

The functionality added by this series is still reduced but its only a
starting point which will later be expanded.

I splitted the patches into funcionality and to ease the review. Only the
patch 8/9 really enables the XGMAC2 block by adding a new compatible string.

Version 2 addresses review comments of Andrew Lunn.

NOTE: Although the IP supports 10G, for now it was only possible to test it
at 1G speed due to 10G PHY HW shipping problems. Here follows iperf3
results at 1G:

---
# iperf3 -c 192.168.0.10
Connecting to host 192.168.0.10, port 5201
[  4] local 192.168.0.3 port 39178 connected to 192.168.0.10 port 5201
[ ID] Interval   Transfer Bandwidth   Retr  Cwnd
[  4]   0.00-1.00   sec   110 MBytes   920 Mbits/sec0482 KBytes
[  4]   1.00-2.00   sec   113 MBytes   946 Mbits/sec0482 KBytes
[  4]   2.00-3.00   sec   112 MBytes   937 Mbits/sec0482 KBytes
[  4]   3.00-4.00   sec   113 MBytes   946 Mbits/sec0482 KBytes
[  4]   4.00-5.00   sec   112 MBytes   935 Mbits/sec0482 KBytes
[  4]   5.00-6.00   sec   113 MBytes   946 Mbits/sec0482 KBytes
[  4]   6.00-7.00   sec   112 MBytes   937 Mbits/sec0482 KBytes
[  4]   7.00-8.00   sec   113 MBytes   946 Mbits/sec0482 KBytes
[  4]   8.00-9.00   sec   112 MBytes   937 Mbits/sec0482 KBytes
[  4]   9.00-10.00  sec   113 MBytes   946 Mbits/sec0482 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval   Transfer Bandwidth   Retr
[  4]   0.00-10.00  sec  1.09 GBytes   940 Mbits/sec0 sender
[  4]   0.00-10.00  sec  1.09 GBytes   938 Mbits/sec  receiver
---

Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
Cc: Andrew Lunn 

Jose Abreu (9):
  net: stmmac: Add XGMAC 2.10 HWIF entry
  net: stmmac: Add MAC related callbacks for XGMAC2
  net: stmmac: Add DMA related callbacks for XGMAC2
  net: stmmac: Add descriptor related callbacks for XGMAC2
  net: stmmac: Add MDIO related functions for XGMAC2
  net: stmmac: Add PTP support for XGMAC2
  net: stmmac: Integrate XGMAC into main driver flow
  net: stmmac: Add the bindings parsing for XGMAC2
  dt-bindings: net: stmmac: Add the bindings documentation for XGMAC2.

 Documentation/devicetree/bindings/net/stmmac.txt   |   5 +-
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   3 +-
 drivers/net/ethernet/stmicro/stmmac/common.h   |  17 +-
 .../net/ethernet/stmicro/stmmac/dwmac-generic.c|   2 +
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 227 
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c| 371 +++
 .../net/ethernet/stmicro/stmmac/dwxgmac2_descs.c   | 280 ++
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 410 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |  31 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   3 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  67 +++-
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c  | 101 -
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   6 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c   |   6 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h   |   1 +
 include/linux/stmmac.h |   1 +
 16 files changed, 1497 insertions(+), 34 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c

-- 
2.7.4




[PATCH v2 net-next 3/9] net: stmmac: Add DMA related callbacks for XGMAC2

2018-08-03 Thread Jose Abreu
Add the DMA related callbacks for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   2 +-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h |  56 +++
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 410 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |   2 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   1 +
 5 files changed, 469 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile 
b/drivers/net/ethernet/stmicro/stmmac/Makefile
index a6cf632c9592..da40d3bba037 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o 
ring_mode.o  \
  dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
  mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o  \
  dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
- stmmac_tc.o dwxgmac2_core.o $(stmmac-y)
+ stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)  += stmmac-platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index 7832571f791f..ddd23f8559df 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -138,4 +138,60 @@
 #define XGMAC_ABPSIS   BIT(1)
 #define XGMAC_TXUNFIS  BIT(0)
 
+/* DMA Registers */
+#define XGMAC_DMA_MODE 0x3000
+#define XGMAC_SWR  BIT(0)
+#define XGMAC_DMA_SYSBUS_MODE  0x3004
+#define XGMAC_WR_OSR_LMT   GENMASK(29, 24)
+#define XGMAC_WR_OSR_LMT_SHIFT 24
+#define XGMAC_RD_OSR_LMT   GENMASK(21, 16)
+#define XGMAC_RD_OSR_LMT_SHIFT 16
+#define XGMAC_EN_LPI   BIT(15)
+#define XGMAC_LPI_XIT_PKT  BIT(14)
+#define XGMAC_AAL  BIT(12)
+#define XGMAC_BLEN256  BIT(7)
+#define XGMAC_BLEN128  BIT(6)
+#define XGMAC_BLEN64   BIT(5)
+#define XGMAC_BLEN32   BIT(4)
+#define XGMAC_BLEN16   BIT(3)
+#define XGMAC_BLEN8BIT(2)
+#define XGMAC_BLEN4BIT(1)
+#define XGMAC_UNDEFBIT(0)
+#define XGMAC_DMA_CH_CONTROL(x)(0x3100 + (0x80 * (x)))
+#define XGMAC_PBLx8BIT(16)
+#define XGMAC_DMA_CH_TX_CONTROL(x) (0x3104 + (0x80 * (x)))
+#define XGMAC_TxPBLGENMASK(21, 16)
+#define XGMAC_TxPBL_SHIFT  16
+#define XGMAC_TSE  BIT(12)
+#define XGMAC_OSP  BIT(4)
+#define XGMAC_TXST BIT(0)
+#define XGMAC_DMA_CH_RX_CONTROL(x) (0x3108 + (0x80 * (x)))
+#define XGMAC_RxPBLGENMASK(21, 16)
+#define XGMAC_RxPBL_SHIFT  16
+#define XGMAC_RXST BIT(0)
+#define XGMAC_DMA_CH_TxDESC_LADDR(x)   (0x3114 + (0x80 * (x)))
+#define XGMAC_DMA_CH_RxDESC_LADDR(x)   (0x311c + (0x80 * (x)))
+#define XGMAC_DMA_CH_TxDESC_TAIL_LPTR(x)   (0x3124 + (0x80 * (x)))
+#define XGMAC_DMA_CH_RxDESC_TAIL_LPTR(x)   (0x312c + (0x80 * (x)))
+#define XGMAC_DMA_CH_TxDESC_RING_LEN(x)(0x3130 + (0x80 * 
(x)))
+#define XGMAC_DMA_CH_RxDESC_RING_LEN(x)(0x3134 + (0x80 * 
(x)))
+#define XGMAC_DMA_CH_INT_EN(x) (0x3138 + (0x80 * (x)))
+#define XGMAC_NIE  BIT(15)
+#define XGMAC_AIE  BIT(14)
+#define XGMAC_RBUE BIT(7)
+#define XGMAC_RIE  BIT(6)
+#define XGMAC_TIE  BIT(0)
+#define XGMAC_DMA_INT_DEFAULT_EN   (XGMAC_NIE | XGMAC_AIE | XGMAC_RBUE | \
+   XGMAC_RIE | XGMAC_TIE)
+#define XGMAC_DMA_CH_Rx_WATCHDOG(x)(0x313c + (0x80 * (x)))
+#define XGMAC_RWT  GENMASK(7, 0)
+#define XGMAC_DMA_CH_STATUS(x) (0x3160 + (0x80 * (x)))
+#define XGMAC_NIS  BIT(15)
+#define XGMAC_AIS  BIT(14)
+#define XGMAC_FBE  BIT(12)
+#define XGMAC_RBU  BIT(7)
+#define XGMAC_RI   BIT(6)
+#define XGMAC_TPS  BIT(1)
+#define XGMAC_TI   BIT(0)
+
 #endif /* __STMMAC_DWXGMAC2_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
new file mode 100644
index ..50d9fffc32b5
--- /dev/null
+++ b/drivers/net/ethernet

[PATCH v2 net-next 2/9] net: stmmac: Add MAC related callbacks for XGMAC2

2018-08-03 Thread Jose Abreu
Add the MAC related callbacks for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   2 +-
 drivers/net/ethernet/stmicro/stmmac/common.h   |   3 +
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 141 
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c| 371 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |   4 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   1 +
 6 files changed, 519 insertions(+), 3 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile 
b/drivers/net/ethernet/stmicro/stmmac/Makefile
index 68e9e2640c62..a6cf632c9592 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o 
ring_mode.o  \
  dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
  mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o  \
  dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
- stmmac_tc.o $(stmmac-y)
+ stmmac_tc.o dwxgmac2_core.o $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)  += stmmac-platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
b/drivers/net/ethernet/stmicro/stmmac/common.h
index 3fb81acbd274..1854f270ad66 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -400,6 +400,8 @@ struct mac_link {
u32 speed10;
u32 speed100;
u32 speed1000;
+   u32 speed2500;
+   u32 speed1;
u32 duplex;
 };
 
@@ -441,6 +443,7 @@ struct stmmac_rx_routing {
 int dwmac100_setup(struct stmmac_priv *priv);
 int dwmac1000_setup(struct stmmac_priv *priv);
 int dwmac4_setup(struct stmmac_priv *priv);
+int dwxgmac2_setup(struct stmmac_priv *priv);
 
 void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
 unsigned int high, unsigned int low);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
new file mode 100644
index ..7832571f791f
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
+ * stmmac XGMAC definitions.
+ */
+
+#ifndef __STMMAC_DWXGMAC2_H__
+#define __STMMAC_DWXGMAC2_H__
+
+#include "common.h"
+
+/* Misc */
+#define XGMAC_JUMBO_LEN16368
+
+/* MAC Registers */
+#define XGMAC_TX_CONFIG0x
+#define XGMAC_CONFIG_SS_OFF29
+#define XGMAC_CONFIG_SS_MASK   GENMASK(30, 29)
+#define XGMAC_CONFIG_SS_1  (0x0 << XGMAC_CONFIG_SS_OFF)
+#define XGMAC_CONFIG_SS_2500   (0x2 << XGMAC_CONFIG_SS_OFF)
+#define XGMAC_CONFIG_SS_1000   (0x3 << XGMAC_CONFIG_SS_OFF)
+#define XGMAC_CONFIG_SARC  GENMASK(22, 20)
+#define XGMAC_CONFIG_SARC_SHIFT20
+#define XGMAC_CONFIG_JDBIT(16)
+#define XGMAC_CONFIG_TEBIT(0)
+#define XGMAC_CORE_INIT_TX (XGMAC_CONFIG_JD)
+#define XGMAC_RX_CONFIG0x0004
+#define XGMAC_CONFIG_ARPEN BIT(31)
+#define XGMAC_CONFIG_GPSL  GENMASK(29, 16)
+#define XGMAC_CONFIG_GPSL_SHIFT16
+#define XGMAC_CONFIG_S2KP  BIT(11)
+#define XGMAC_CONFIG_IPC   BIT(9)
+#define XGMAC_CONFIG_JEBIT(8)
+#define XGMAC_CONFIG_WDBIT(7)
+#define XGMAC_CONFIG_GPSLCEBIT(6)
+#define XGMAC_CONFIG_CST   BIT(2)
+#define XGMAC_CONFIG_ACS   BIT(1)
+#define XGMAC_CONFIG_REBIT(0)
+#define XGMAC_CORE_INIT_RX 0
+#define XGMAC_PACKET_FILTER0x0008
+#define XGMAC_FILTER_RABIT(31)
+#define XGMAC_FILTER_PMBIT(4)
+#define XGMAC_FILTER_HMC   BIT(2)
+#define XGMAC_FILTER_PRBIT(0)
+#define XGMAC_HASH_TABLE(x)(0x0010 + (x) * 4)
+#define XGMAC_RXQ_CTRL00x00a0
+#define XGMAC_RXQEN(x) GENMASK((x) * 2 + 1, (x) * 2)
+#define XGMAC_RXQEN_SHIFT(x)   ((x) * 2)
+#define XGMAC_RXQ_CTRL20x00a8
+#define XGMAC_RXQ_CTRL30x00ac
+#define XGMAC_PSRQ(x)  GENMASK((x) * 8 + 7, (x) * 8)
+#define XGMAC_PSRQ_SHIFT(x)((x) * 8)
+#define XGMAC_INT_STATUS   0x0

[PATCH v2 net-next 6/9] net: stmmac: Add PTP support for XGMAC2

2018-08-03 Thread Jose Abreu
XGMAC2 uses the same engine of timestamping as GMAC4. Let's use the same
callbacks.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/hwif.c   | 4 ++--
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 6 --
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h | 1 +
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c 
b/drivers/net/ethernet/stmicro/stmmac/hwif.c
index 4b4ba1c8bad5..357309a6d6a5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
@@ -193,13 +193,13 @@ static const struct stmmac_hwif_entry {
.xgmac = true,
.min_id = DWXGMAC_CORE_2_10,
.regs = {
-   .ptp_off = 0,
+   .ptp_off = PTP_XGMAC_OFFSET,
.mmc_off = 0,
},
.desc = _desc_ops,
.dma = _dma_ops,
.mac = _ops,
-   .hwtimestamp = NULL,
+   .hwtimestamp = _ptp,
.mode = NULL,
.tc = NULL,
.setup = dwxgmac2_setup,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
index 0cb0e39a2be9..2293e21f789f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
@@ -71,6 +71,9 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 
delta)
u32 sec, nsec;
u32 quotient, reminder;
int neg_adj = 0;
+   bool xmac;
+
+   xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 
if (delta < 0) {
neg_adj = 1;
@@ -82,8 +85,7 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 
delta)
nsec = reminder;
 
spin_lock_irqsave(>ptp_lock, flags);
-   stmmac_adjust_systime(priv, priv->ptpaddr, sec, nsec, neg_adj,
-   priv->plat->has_gmac4);
+   stmmac_adjust_systime(priv, priv->ptpaddr, sec, nsec, neg_adj, xmac);
spin_unlock_irqrestore(>ptp_lock, flags);
 
return 0;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
index f4b31d69f60e..ecccf895fd7e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
@@ -21,6 +21,7 @@
 #ifndef__STMMAC_PTP_H__
 #define__STMMAC_PTP_H__
 
+#define PTP_XGMAC_OFFSET   0xd00
 #definePTP_GMAC4_OFFSET0xb00
 #definePTP_GMAC3_X_OFFSET  0x700
 
-- 
2.7.4




Re: [PATCH net-next 7/9] net: stmmac: Integrate XGMAC into main driver flow

2018-08-02 Thread Jose Abreu
On 02-08-2018 15:36, Andrew Lunn wrote:
>> Sorry, I made a mistake. Where it reads SGMII in my reply I was
>> referring to XGMII.
> So you have XGMII between the MAC and the PHY. That should support
> 2.5G, 5G and 10G. What i don't know is if you can also do 10/100/1000
> over XGMII?

Acording to databook I can only do 1G/2.5G and 10G.

>
> How are you currently connecting your 1G PHY to the MAC? XGMII is a
> big parallel bus, where as SGMII is a small serial bus.

I will check with HW team because I've no idea how is this
connected ...

>
> I would say, before this patchset goes anywhere, you need to test
> 10/100/1000/2.5G/10G, with at least one PHY.
>
> Alternatively, take out support for 2.5G/10G and C45, and post patches
> for just > 1G and C22. That you can test and you know works. You can
> add the rest later.

Looks like a plan. So, I will remove the adjust_link speed
selection for > 1g and the C45 support. I will leave the SS
selection in dwxgmac2_core_init (patch 2/9) as this makes no
difference because only 1g will be selected for now. I will also
clearly refer in cover letter the BW results for 1g tests.

Later on I will add support for 10g once shipping arrives.

Looks okay?

Thanks and Best Regards,
Jose Miguel Abreu

>
>   Andrew



Re: [PATCH net-next 7/9] net: stmmac: Integrate XGMAC into main driver flow

2018-08-02 Thread Jose Abreu
Hi Andrew,

On 02-08-2018 15:03, Andrew Lunn wrote:
> On Thu, Aug 02, 2018 at 09:26:28AM +0100, Jose Abreu wrote:
>> Hi Andrew,
>>
>> Thanks for the review!
>>
>> On 01-08-2018 16:23, Andrew Lunn wrote:
>>>> @@ -842,6 +863,12 @@ static void stmmac_adjust_link(struct net_device *dev)
>>>>new_state = true;
>>>>ctrl &= ~priv->hw->link.speed_mask;
>>>>switch (phydev->speed) {
>>>> +  case SPEED_1:
>>>> +  ctrl |= priv->hw->link.speed1;
>>>> +  break;
>>>> +  case SPEED_2500:
>>>> +  ctrl |= priv->hw->link.speed2500;
>>>> +  break;
>>>>case SPEED_1000:
>>>>ctrl |= priv->hw->link.speed1000;
>>>>break;
>>> Hi Jose
>>>
>>> What PHY did you test this with?
>> We had some shipping issues with the 10G phy so right now I'm
>> using a 1G phy ...
> Please add that to the commit message. It is useful for people to know
> this is untested above 1G, and so probably broken

Ok, will do.

>
>> I would expect that as MDIO is used in both
>> phys then phylib would take care of everything as long as I
>> specify in the DT the right interface (SGMII) ... Am I making a
>> wrong assumption?
>>
>>> 10G phys change the interface mode when the speed change. In general,
>>> 10/100/1000G copper uses SGMII. A 1G SFP optical module generally
>>> wants 1000Base-X. 2.5G wants 2500Base-X, 10G copper wants 10GKR, etc.
>>>
>>> So your adjust link callback needs to look at phydev->interface and
>>> reconfigure the MAC as requested.
>> Sorry, I'm not a phy expert but as long as I use MDIO shouldn't
>> this be transparent to MAC? I mean, there are no registers about
>> the interface to use in XGMAC2, there is only this speed
>> selection register that its implemented already in the
>> stmmac_adjust_link.
> MDIO is the control plane used to manage the PHY. But here we are
> talking about the data plane. As i said, the link between the MAC and
> PHY will need to change depending on what the PHY is doing. SGMII will
> work for 10/100/1000, but nothing above that. 

Sorry, I made a mistake. Where it reads SGMII in my reply I was
referring to XGMII.

> It could be this speed
> register also changes the SERDES configuration, but you really should
> confirm this and find out exactly what it is doing. There can be
> multiple ways of doing one speed, e.g. SGMII at 1G. So if the PHY
> wants you to do 1000Base-X and the MAC can only do SGMII, you need to
> be raising an error. phylink makes this simpler. It ask the MAC driver
> for all the modes it supports. It will then not ask the MAC to swap to
> something it does not support.

Ok. XGMII support is optional in the MAC so I will need to add a
check for that.

Thanks and Best Regards,
Jose Miguel Abreu

>
> I suggest you get the datasheet for the PHY you are expecting to get,
> once shipping is fixed. See what it says about its MAC side interface.
> You can also look at the Marvell 10G driver, e.g.
> mv3310_update_interface().
>
>   Andrew



Re: [PATCH net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2

2018-08-02 Thread Jose Abreu
Hi Andrew,

On 01-08-2018 16:08, Andrew Lunn wrote:
> Hi Jose
>
>> +static int stmmac_xgmac2_mdio_read(struct stmmac_priv *priv, int phyaddr,
>> +   int phyreg)
>> +{
>> +unsigned int mii_address = priv->hw->mii.addr;
>> +unsigned int mii_data = priv->hw->mii.data;
>> +u32 tmp, addr, value = MII_XGMAC_BUSY;
>> +int data;
>> +
>> +if (phyreg & MII_ADDR_C45) {
>> +addr = ((phyreg >> 16) & 0x1f) << 21;
>> +addr |= (phyaddr << 16) | (phyreg & 0x);
> Do you need to tell the hardware this is a C45 transfer? Normally an
> extra bit needs setting somewhere.

The organization of addr reg is the following:
DA [25:21] | PA [20:16] | RA [15:0]

DA is Device Address, PA is Port Address and RA is Register Address.

>
>> +} else {
>> +if (phyaddr >= 4)
>> +return -ENODEV;
> Can the MDIO bus be external? If so, is there a reason why there
> cannot be a PHY at addresses > 4. So maybe there is an Ethernet
> switch, which needs lots of addresses? And C45 can have devices > 4
> but C22 cannot?

Only ports 0 to 3 can be configured as C22 ports, according to
databook. This for MDIO bus trough controller.

>
>> +writel(~0x0, priv->ioaddr + 0x220);
>> +addr = (phyaddr << 16) | (phyreg & 0x1f);
>> +}
>> +
>> +value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
>> +& priv->hw->mii.clk_csr_mask;
>> +value |= BIT(18);
> Please add a #define for this bit.

Ok.

>
>> +value |= MII_XGMAC_READ;
>> +
>> +if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
>> +   !(tmp & MII_XGMAC_BUSY), 100, 1))
>> +return -EBUSY;
>> +
>> +writel(addr, priv->ioaddr + mii_address);
>> +writel(value, priv->ioaddr + mii_data);
>> +
>> +if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
>> +   !(tmp & MII_XGMAC_BUSY), 100, 1))
>> +return -EBUSY;
>> +
>> +/* Read the data from the MII data register */
>> +data = (int)readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
> Is the cast needed? And why use GENMASK here, but not in all the other
> places you have masks in this code?

The GENMASK is needed, notice how we set more values into
mii_data (clk_csr, bit(18), cmd), this is not cleared by XGMAC2
upon the completion of the operation ...

>
>>  /**
>>   * stmmac_mdio_read
>>   * @bus: points to the mii_bus structure
>> @@ -59,6 +141,9 @@ static int stmmac_mdio_read(struct mii_bus *bus, int 
>> phyaddr, int phyreg)
>>  int data;
>>  u32 value = MII_BUSY;
>>  
>> +if (priv->plat->has_xgmac)
>> +return stmmac_xgmac2_mdio_read(priv, phyaddr, phyreg);
> It would be cleaner to instead do this in stmmac_mdio_register() when
> setting new_bus->read.

Makes sense! Thanks!

Thanks and Best Regards,
Jose Miguel Abreu

>
>   Andrew



Re: [PATCH net-next 7/9] net: stmmac: Integrate XGMAC into main driver flow

2018-08-02 Thread Jose Abreu
Hi Andrew,

Thanks for the review!

On 01-08-2018 16:23, Andrew Lunn wrote:
>> @@ -842,6 +863,12 @@ static void stmmac_adjust_link(struct net_device *dev)
>>  new_state = true;
>>  ctrl &= ~priv->hw->link.speed_mask;
>>  switch (phydev->speed) {
>> +case SPEED_1:
>> +ctrl |= priv->hw->link.speed1;
>> +break;
>> +case SPEED_2500:
>> +ctrl |= priv->hw->link.speed2500;
>> +break;
>>  case SPEED_1000:
>>  ctrl |= priv->hw->link.speed1000;
>>  break;
> Hi Jose
>
> What PHY did you test this with?

We had some shipping issues with the 10G phy so right now I'm
using a 1G phy ... I would expect that as MDIO is used in both
phys then phylib would take care of everything as long as I
specify in the DT the right interface (SGMII) ... Am I making a
wrong assumption?

>
> 10G phys change the interface mode when the speed change. In general,
> 10/100/1000G copper uses SGMII. A 1G SFP optical module generally
> wants 1000Base-X. 2.5G wants 2500Base-X, 10G copper wants 10GKR, etc.
>
> So your adjust link callback needs to look at phydev->interface and
> reconfigure the MAC as requested.

Sorry, I'm not a phy expert but as long as I use MDIO shouldn't
this be transparent to MAC? I mean, there are no registers about
the interface to use in XGMAC2, there is only this speed
selection register that its implemented already in the
stmmac_adjust_link.

>
> You might also want to consider moving from phylib to phylink. It has
> a better interface for things like this, and makes support for SFP
> interfaces much easier. A MAC which supports 10G is likely to be used
> with SFPs...

Ok, I will take a look into it.

Thanks and Best Regards,
Jose Miguel Abreu

>
>  Andrew



[PATCH net-next 6/9] net: stmmac: Add PTP support for XGMAC2

2018-08-01 Thread Jose Abreu
XGMAC2 uses the same engine of timestamping as GMAC4. Let's use the same
callbacks.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/hwif.c   | 4 ++--
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 6 --
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h | 1 +
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c 
b/drivers/net/ethernet/stmicro/stmmac/hwif.c
index 4b4ba1c8bad5..357309a6d6a5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
@@ -193,13 +193,13 @@ static const struct stmmac_hwif_entry {
.xgmac = true,
.min_id = DWXGMAC_CORE_2_10,
.regs = {
-   .ptp_off = 0,
+   .ptp_off = PTP_XGMAC_OFFSET,
.mmc_off = 0,
},
.desc = _desc_ops,
.dma = _dma_ops,
.mac = _ops,
-   .hwtimestamp = NULL,
+   .hwtimestamp = _ptp,
.mode = NULL,
.tc = NULL,
.setup = dwxgmac2_setup,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
index 0cb0e39a2be9..2293e21f789f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
@@ -71,6 +71,9 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 
delta)
u32 sec, nsec;
u32 quotient, reminder;
int neg_adj = 0;
+   bool xmac;
+
+   xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 
if (delta < 0) {
neg_adj = 1;
@@ -82,8 +85,7 @@ static int stmmac_adjust_time(struct ptp_clock_info *ptp, s64 
delta)
nsec = reminder;
 
spin_lock_irqsave(>ptp_lock, flags);
-   stmmac_adjust_systime(priv, priv->ptpaddr, sec, nsec, neg_adj,
-   priv->plat->has_gmac4);
+   stmmac_adjust_systime(priv, priv->ptpaddr, sec, nsec, neg_adj, xmac);
spin_unlock_irqrestore(>ptp_lock, flags);
 
return 0;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
index f4b31d69f60e..ecccf895fd7e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
@@ -21,6 +21,7 @@
 #ifndef__STMMAC_PTP_H__
 #define__STMMAC_PTP_H__
 
+#define PTP_XGMAC_OFFSET   0xd00
 #definePTP_GMAC4_OFFSET0xb00
 #definePTP_GMAC3_X_OFFSET  0x700
 
-- 
2.7.4




[PATCH net-next 7/9] net: stmmac: Integrate XGMAC into main driver flow

2018-08-01 Thread Jose Abreu
Now that we have all the XGMAC related callbacks, lets start integrating
this IP block into main driver.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 55 ++-
 1 file changed, 45 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index d9e60cfd8a85..2c7a571140bb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -51,6 +51,7 @@
 #include 
 #include 
 #include "dwmac1000.h"
+#include "dwxgmac2.h"
 #include "hwif.h"
 
 #define STMMAC_ALIGN(x)L1_CACHE_ALIGN(x)
@@ -262,6 +263,21 @@ static void stmmac_clk_csr_set(struct stmmac_priv *priv)
else
priv->clk_csr = 0;
}
+
+   if (priv->plat->has_xgmac) {
+   if (clk_rate > 4)
+   priv->clk_csr = 0x5;
+   else if (clk_rate > 35000)
+   priv->clk_csr = 0x4;
+   else if (clk_rate > 3)
+   priv->clk_csr = 0x3;
+   else if (clk_rate > 25000)
+   priv->clk_csr = 0x2;
+   else if (clk_rate > 15000)
+   priv->clk_csr = 0x1;
+   else
+   priv->clk_csr = 0x0;
+   }
 }
 
 static void print_pkt(unsigned char *buf, int len)
@@ -498,7 +514,7 @@ static void stmmac_get_rx_hwtstamp(struct stmmac_priv 
*priv, struct dma_desc *p,
if (!priv->hwts_rx_en)
return;
/* For GMAC4, the valid timestamp is from CTX next desc. */
-   if (priv->plat->has_gmac4)
+   if (priv->plat->has_gmac4 || priv->plat->has_xgmac)
desc = np;
 
/* Check if timestamp is available */
@@ -540,6 +556,9 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
u32 ts_event_en = 0;
u32 value = 0;
u32 sec_inc;
+   bool xmac;
+
+   xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 
if (!(priv->dma_cap.time_stamp || priv->adv_ts)) {
netdev_alert(priv->dev, "No support for HW time stamping\n");
@@ -575,7 +594,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
/* PTP v1, UDP, any kind of event packet */
config.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
/* take time stamp for all event messages */
-   if (priv->plat->has_gmac4)
+   if (xmac)
snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
else
snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
@@ -610,7 +629,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
ptp_v2 = PTP_TCR_TSVER2ENA;
/* take time stamp for all event messages */
-   if (priv->plat->has_gmac4)
+   if (xmac)
snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
else
snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
@@ -647,7 +666,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
ptp_v2 = PTP_TCR_TSVER2ENA;
/* take time stamp for all event messages */
-   if (priv->plat->has_gmac4)
+   if (xmac)
snap_type_sel = PTP_GMAC4_TCR_SNAPTYPSEL_1;
else
snap_type_sel = PTP_TCR_SNAPTYPSEL_1;
@@ -718,7 +737,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
/* program Sub Second Increment reg */
stmmac_config_sub_second_increment(priv,
priv->ptpaddr, priv->plat->clk_ptp_rate,
-   priv->plat->has_gmac4, _inc);
+   xmac, _inc);
temp = div_u64(10ULL, sec_inc);
 
/* Store sub second increment and flags for later use */
@@ -755,12 +774,14 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, 
struct ifreq *ifr)
  */
 static int stmmac_init_ptp(struct stmmac_priv *priv)
 {
+   bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
+
if (!(priv->dma_cap.time_stamp || priv-&

[PATCH net-next 9/9] bindings: net: stmmac: Add the bindings documentation for XGMAC2.

2018-08-01 Thread Jose Abreu
Adds the documentation for XGMAC2 DT bindings.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 Documentation/devicetree/bindings/net/stmmac.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/stmmac.txt 
b/Documentation/devicetree/bindings/net/stmmac.txt
index 3a28a5d8857d..525425beb6e7 100644
--- a/Documentation/devicetree/bindings/net/stmmac.txt
+++ b/Documentation/devicetree/bindings/net/stmmac.txt
@@ -1,7 +1,8 @@
 * STMicroelectronics 10/100/1000 Ethernet driver (GMAC)
 
 Required properties:
-- compatible: Should be "snps,dwmac-", "snps,dwmac"
+- compatible: Should be "snps,dwmac-", "snps,dwmac" or
+   "snps,dwxgmac-

[PATCH net-next 8/9] net: stmmac: Add the bindings parsing for XGMAC2

2018-08-01 Thread Jose Abreu
Add the bindings parsing for XGMAC2 IP block.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c   | 2 ++
 drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 6 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
index 3304095c934c..fad503820e04 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c
@@ -78,6 +78,8 @@ static const struct of_device_id dwmac_generic_match[] = {
{ .compatible = "snps,dwmac-4.00"},
{ .compatible = "snps,dwmac-4.10a"},
{ .compatible = "snps,dwmac"},
+   { .compatible = "snps,dwxgmac-2.10"},
+   { .compatible = "snps,dwxgmac"},
{ }
 };
 MODULE_DEVICE_TABLE(of, dwmac_generic_match);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 72da77b94ecd..3609c7b696c7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -486,6 +486,12 @@ stmmac_probe_config_dt(struct platform_device *pdev, const 
char **mac)
plat->force_sf_dma_mode = 1;
}
 
+   if (of_device_is_compatible(np, "snps,dwxgmac")) {
+   plat->has_xgmac = 1;
+   plat->pmt = 1;
+   plat->tso_en = of_property_read_bool(np, "snps,tso");
+   }
+
dma_cfg = devm_kzalloc(>dev, sizeof(*dma_cfg),
   GFP_KERNEL);
if (!dma_cfg) {
-- 
2.7.4




[PATCH net-next 3/9] net: stmmac: Add DMA related callbacks for XGMAC2

2018-08-01 Thread Jose Abreu
Add the DMA related callbacks for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   2 +-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h |  56 +++
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 410 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |   2 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   1 +
 5 files changed, 469 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile 
b/drivers/net/ethernet/stmicro/stmmac/Makefile
index a6cf632c9592..da40d3bba037 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o 
ring_mode.o  \
  dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
  mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o  \
  dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
- stmmac_tc.o dwxgmac2_core.o $(stmmac-y)
+ stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)  += stmmac-platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index ef63a62a699d..69d225a9c890 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -137,4 +137,60 @@
 #define XGMAC_ABPSIS   BIT(1)
 #define XGMAC_TXUNFIS  BIT(0)
 
+/* DMA Registers */
+#define XGMAC_DMA_MODE 0x3000
+#define XGMAC_SWR  BIT(0)
+#define XGMAC_DMA_SYSBUS_MODE  0x3004
+#define XGMAC_WR_OSR_LMT   GENMASK(29, 24)
+#define XGMAC_WR_OSR_LMT_SHIFT 24
+#define XGMAC_RD_OSR_LMT   GENMASK(21, 16)
+#define XGMAC_RD_OSR_LMT_SHIFT 16
+#define XGMAC_EN_LPI   BIT(15)
+#define XGMAC_LPI_XIT_PKT  BIT(14)
+#define XGMAC_AAL  BIT(12)
+#define XGMAC_BLEN256  BIT(7)
+#define XGMAC_BLEN128  BIT(6)
+#define XGMAC_BLEN64   BIT(5)
+#define XGMAC_BLEN32   BIT(4)
+#define XGMAC_BLEN16   BIT(3)
+#define XGMAC_BLEN8BIT(2)
+#define XGMAC_BLEN4BIT(1)
+#define XGMAC_UNDEFBIT(0)
+#define XGMAC_DMA_CH_CONTROL(x)(0x3100 + (0x80 * (x)))
+#define XGMAC_PBLx8BIT(16)
+#define XGMAC_DMA_CH_TX_CONTROL(x) (0x3104 + (0x80 * (x)))
+#define XGMAC_TxPBLGENMASK(21, 16)
+#define XGMAC_TxPBL_SHIFT  16
+#define XGMAC_TSE  BIT(12)
+#define XGMAC_OSP  BIT(4)
+#define XGMAC_TXST BIT(0)
+#define XGMAC_DMA_CH_RX_CONTROL(x) (0x3108 + (0x80 * (x)))
+#define XGMAC_RxPBLGENMASK(21, 16)
+#define XGMAC_RxPBL_SHIFT  16
+#define XGMAC_RXST BIT(0)
+#define XGMAC_DMA_CH_TxDESC_LADDR(x)   (0x3114 + (0x80 * (x)))
+#define XGMAC_DMA_CH_RxDESC_LADDR(x)   (0x311c + (0x80 * (x)))
+#define XGMAC_DMA_CH_TxDESC_TAIL_LPTR(x)   (0x3124 + (0x80 * (x)))
+#define XGMAC_DMA_CH_RxDESC_TAIL_LPTR(x)   (0x312c + (0x80 * (x)))
+#define XGMAC_DMA_CH_TxDESC_RING_LEN(x)(0x3130 + (0x80 * 
(x)))
+#define XGMAC_DMA_CH_RxDESC_RING_LEN(x)(0x3134 + (0x80 * 
(x)))
+#define XGMAC_DMA_CH_INT_EN(x) (0x3138 + (0x80 * (x)))
+#define XGMAC_NIE  BIT(15)
+#define XGMAC_AIE  BIT(14)
+#define XGMAC_RBUE BIT(7)
+#define XGMAC_RIE  BIT(6)
+#define XGMAC_TIE  BIT(0)
+#define XGMAC_DMA_INT_DEFAULT_EN   (XGMAC_NIE | XGMAC_AIE | XGMAC_RBUE | \
+   XGMAC_RIE | XGMAC_TIE)
+#define XGMAC_DMA_CH_Rx_WATCHDOG(x)(0x313c + (0x80 * (x)))
+#define XGMAC_RWT  GENMASK(7, 0)
+#define XGMAC_DMA_CH_STATUS(x) (0x3160 + (0x80 * (x)))
+#define XGMAC_NIS  BIT(15)
+#define XGMAC_AIS  BIT(14)
+#define XGMAC_FBE  BIT(12)
+#define XGMAC_RBU  BIT(7)
+#define XGMAC_RI   BIT(6)
+#define XGMAC_TPS  BIT(1)
+#define XGMAC_TI   BIT(0)
+
 #endif /* __STMMAC_DWXGMAC2_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
new file mode 100644
index ..50d9fffc32b5
--- /dev/null
+++ b/drivers/net/ethernet

[PATCH net-next 5/9] net: stmmac: Add MDIO related functions for XGMAC2

2018-08-01 Thread Jose Abreu
Add the MDIO related funcionalities for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 88 +++
 1 file changed, 88 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c 
b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index 5df1a608e566..e6bf86dc14eb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -39,6 +39,88 @@
 #define MII_GMAC4_WRITE(1 << MII_GMAC4_GOC_SHIFT)
 #define MII_GMAC4_READ (3 << MII_GMAC4_GOC_SHIFT)
 
+/* XGMAC defines */
+#define MII_XGMAC_CMD_SHIFT16
+#define MII_XGMAC_WRITE(1 << MII_XGMAC_CMD_SHIFT)
+#define MII_XGMAC_READ (3 << MII_XGMAC_CMD_SHIFT)
+#define MII_XGMAC_BUSY BIT(22)
+
+static int stmmac_xgmac2_mdio_read(struct stmmac_priv *priv, int phyaddr,
+  int phyreg)
+{
+   unsigned int mii_address = priv->hw->mii.addr;
+   unsigned int mii_data = priv->hw->mii.data;
+   u32 tmp, addr, value = MII_XGMAC_BUSY;
+   int data;
+
+   if (phyreg & MII_ADDR_C45) {
+   addr = ((phyreg >> 16) & 0x1f) << 21;
+   addr |= (phyaddr << 16) | (phyreg & 0x);
+   } else {
+   if (phyaddr >= 4)
+   return -ENODEV;
+   writel(~0x0, priv->ioaddr + 0x220);
+   addr = (phyaddr << 16) | (phyreg & 0x1f);
+   }
+
+   value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
+   & priv->hw->mii.clk_csr_mask;
+   value |= BIT(18);
+   value |= MII_XGMAC_READ;
+
+   if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+  !(tmp & MII_XGMAC_BUSY), 100, 1))
+   return -EBUSY;
+
+   writel(addr, priv->ioaddr + mii_address);
+   writel(value, priv->ioaddr + mii_data);
+
+   if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+  !(tmp & MII_XGMAC_BUSY), 100, 1))
+   return -EBUSY;
+
+   /* Read the data from the MII data register */
+   data = (int)readl(priv->ioaddr + mii_data) & GENMASK(15, 0);
+
+   return data;
+}
+
+static int stmmac_xgmac2_mdio_write(struct stmmac_priv *priv, int phyaddr,
+   int phyreg, u16 phydata)
+{
+   unsigned int mii_address = priv->hw->mii.addr;
+   unsigned int mii_data = priv->hw->mii.data;
+   u32 addr, tmp, value = MII_XGMAC_BUSY;
+
+   if (phyreg & MII_ADDR_C45) {
+   addr = ((phyreg >> 16) & 0x1f) << 21;
+   addr |= (phyaddr << 16) | (phyreg & 0x);
+   } else {
+   if (phyaddr >= 4)
+   return -ENODEV;
+   writel(~0x0, priv->ioaddr + 0x220);
+   addr = (phyaddr << 16) | (phyreg & 0x1f);
+   }
+
+   value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
+   & priv->hw->mii.clk_csr_mask;
+   value |= phydata | BIT(18);
+   value |= MII_XGMAC_WRITE;
+
+   /* Wait until any existing MII operation is complete */
+   if (readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+  !(tmp & MII_XGMAC_BUSY), 100, 1))
+   return -EBUSY;
+
+   /* Set the MII address register to write */
+   writel(addr, priv->ioaddr + mii_address);
+   writel(value, priv->ioaddr + mii_data);
+
+   /* Wait until any existing MII operation is complete */
+   return readl_poll_timeout(priv->ioaddr + mii_data, tmp,
+ !(tmp & MII_XGMAC_BUSY), 100, 1);
+}
+
 /**
  * stmmac_mdio_read
  * @bus: points to the mii_bus structure
@@ -59,6 +141,9 @@ static int stmmac_mdio_read(struct mii_bus *bus, int 
phyaddr, int phyreg)
int data;
u32 value = MII_BUSY;
 
+   if (priv->plat->has_xgmac)
+   return stmmac_xgmac2_mdio_read(priv, phyaddr, phyreg);
+
value |= (phyaddr << priv->hw->mii.addr_shift)
& priv->hw->mii.addr_mask;
value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
@@ -101,6 +186,9 @@ static int stmmac_mdio_write(struct mii_bus *bus, int 
phyaddr, int phyreg,
u32 v;
u32 value = MII_BUSY;
 
+   if (priv->plat->has_xgmac)
+   return stmmac_xgmac2_mdio_write(priv, phyaddr, phyreg, phydata);
+
value |= (phyaddr << priv->hw->mii.addr_shift)
& priv->hw->mii.addr_mask;
value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
-- 
2.7.4




[PATCH net-next 4/9] net: stmmac: Add descriptor related callbacks for XGMAC2

2018-08-01 Thread Jose Abreu
Add the descriptor related callbacks for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   3 +-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h |  30 +++
 .../net/ethernet/stmicro/stmmac/dwxgmac2_descs.c   | 280 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |   2 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   1 +
 5 files changed, 314 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile 
b/drivers/net/ethernet/stmicro/stmmac/Makefile
index da40d3bba037..99967a80a8c8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -5,7 +5,8 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o 
ring_mode.o  \
  dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
  mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o  \
  dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
- stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o $(stmmac-y)
+ stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o dwxgmac2_descs.o \
+ $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)  += stmmac-platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index 69d225a9c890..7d9f4428d8d5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -193,4 +193,34 @@
 #define XGMAC_TPS  BIT(1)
 #define XGMAC_TI   BIT(0)
 
+/* Descriptors */
+#define XGMAC_TDES2_IOCBIT(31)
+#define XGMAC_TDES2_TTSE   BIT(30)
+#define XGMAC_TDES2_B2LGENMASK(29, 16)
+#define XGMAC_TDES2_B2L_SHIFT  16
+#define XGMAC_TDES2_B1LGENMASK(13, 0)
+#define XGMAC_TDES3_OWNBIT(31)
+#define XGMAC_TDES3_CTXT   BIT(30)
+#define XGMAC_TDES3_FD BIT(29)
+#define XGMAC_TDES3_LD BIT(28)
+#define XGMAC_TDES3_CPCGENMASK(27, 26)
+#define XGMAC_TDES3_CPC_SHIFT  26
+#define XGMAC_TDES3_TCMSSV BIT(26)
+#define XGMAC_TDES3_THLGENMASK(22, 19)
+#define XGMAC_TDES3_THL_SHIFT  19
+#define XGMAC_TDES3_TSEBIT(18)
+#define XGMAC_TDES3_CICGENMASK(17, 16)
+#define XGMAC_TDES3_CIC_SHIFT  16
+#define XGMAC_TDES3_TPLGENMASK(17, 0)
+#define XGMAC_TDES3_FL GENMASK(14, 0)
+#define XGMAC_RDES3_OWNBIT(31)
+#define XGMAC_RDES3_CTXT   BIT(30)
+#define XGMAC_RDES3_IOCBIT(30)
+#define XGMAC_RDES3_LD BIT(28)
+#define XGMAC_RDES3_CDABIT(27)
+#define XGMAC_RDES3_ES BIT(15)
+#define XGMAC_RDES3_PL GENMASK(13, 0)
+#define XGMAC_RDES3_TSDBIT(6)
+#define XGMAC_RDES3_TSABIT(4)
+
 #endif /* __STMMAC_DWXGMAC2_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
new file mode 100644
index ..1d858fdec997
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
+ * stmmac XGMAC support.
+ */
+
+#include 
+#include "common.h"
+#include "dwxgmac2.h"
+
+static int dwxgmac2_get_tx_status(void *data, struct stmmac_extra_stats *x,
+ struct dma_desc *p, void __iomem *ioaddr)
+{
+   unsigned int tdes3 = le32_to_cpu(p->des3);
+   int ret = tx_done;
+
+   if (unlikely(tdes3 & XGMAC_TDES3_OWN))
+   return tx_dma_own;
+   if (likely(!(tdes3 & XGMAC_TDES3_LD)))
+   return tx_not_ls;
+
+   return ret;
+}
+
+static int dwxgmac2_get_rx_status(void *data, struct stmmac_extra_stats *x,
+ struct dma_desc *p)
+{
+   unsigned int rdes3 = le32_to_cpu(p->des3);
+   int ret = good_frame;
+
+   if (unlikely(rdes3 & XGMAC_RDES3_OWN))
+   return dma_own;
+   if (likely(!(rdes3 & XGMAC_RDES3_LD)))
+   return discard_frame;
+   if (unlikely(rdes3 & XGMAC_RDES3_ES))
+   ret = discard_frame;
+
+   return ret;
+}
+
+static int dwxgmac2_get_tx_len(struct dma_desc *p)
+{
+   return (le32_to_cpu(p->des2) & XGMAC_TDES2_B1L);
+}
+
+static int dwxgmac2_get_tx_owner(struc

[PATCH net-next 2/9] net: stmmac: Add MAC related callbacks for XGMAC2

2018-08-01 Thread Jose Abreu
Add the MAC related callbacks for the new IP block XGMAC2.

Signed-off-by: Jose Abreu 
Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 
---
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   2 +-
 drivers/net/ethernet/stmicro/stmmac/common.h   |   3 +
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 140 
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c| 371 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |   4 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   1 +
 6 files changed, 518 insertions(+), 3 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile 
b/drivers/net/ethernet/stmicro/stmmac/Makefile
index 68e9e2640c62..a6cf632c9592 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o 
ring_mode.o  \
  dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
  mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o  \
  dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
- stmmac_tc.o $(stmmac-y)
+ stmmac_tc.o dwxgmac2_core.o $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)  += stmmac-platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h 
b/drivers/net/ethernet/stmicro/stmmac/common.h
index 3fb81acbd274..1854f270ad66 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -400,6 +400,8 @@ struct mac_link {
u32 speed10;
u32 speed100;
u32 speed1000;
+   u32 speed2500;
+   u32 speed1;
u32 duplex;
 };
 
@@ -441,6 +443,7 @@ struct stmmac_rx_routing {
 int dwmac100_setup(struct stmmac_priv *priv);
 int dwmac1000_setup(struct stmmac_priv *priv);
 int dwmac4_setup(struct stmmac_priv *priv);
+int dwxgmac2_setup(struct stmmac_priv *priv);
 
 void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
 unsigned int high, unsigned int low);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h 
b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
new file mode 100644
index ..ef63a62a699d
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
+ * stmmac XGMAC definitions.
+ */
+
+#ifndef __STMMAC_DWXGMAC2_H__
+#define __STMMAC_DWXGMAC2_H__
+
+#include "common.h"
+
+/* Misc */
+#define XGMAC_JUMBO_LEN16368
+
+/* MAC Registers */
+#define XGMAC_TX_CONFIG0x
+#define XGMAC_CONFIG_SS_OFF29
+#define XGMAC_CONFIG_SS_MASK   GENMASK(30, 29)
+#define XGMAC_CONFIG_SS_1  (0x0 << XGMAC_CONFIG_SS_OFF)
+#define XGMAC_CONFIG_SS_2500   (0x2 << XGMAC_CONFIG_SS_OFF)
+#define XGMAC_CONFIG_SS_1000   (0x3 << XGMAC_CONFIG_SS_OFF)
+#define XGMAC_CONFIG_SARC  GENMASK(22, 20)
+#define XGMAC_CONFIG_SARC_SHIFT20
+#define XGMAC_CONFIG_JDBIT(16)
+#define XGMAC_CONFIG_TEBIT(0)
+#define XGMAC_CORE_INIT_TX (XGMAC_CONFIG_JD)
+#define XGMAC_RX_CONFIG0x0004
+#define XGMAC_CONFIG_ARPEN BIT(31)
+#define XGMAC_CONFIG_GPSL  GENMASK(29, 16)
+#define XGMAC_CONFIG_GPSL_SHIFT16
+#define XGMAC_CONFIG_S2KP  BIT(11)
+#define XGMAC_CONFIG_IPC   BIT(9)
+#define XGMAC_CONFIG_JEBIT(8)
+#define XGMAC_CONFIG_WDBIT(7)
+#define XGMAC_CONFIG_GPSLCEBIT(6)
+#define XGMAC_CONFIG_CST   BIT(2)
+#define XGMAC_CONFIG_ACS   BIT(1)
+#define XGMAC_CONFIG_REBIT(0)
+#define XGMAC_CORE_INIT_RX 0
+#define XGMAC_PACKET_FILTER0x0008
+#define XGMAC_FILTER_RABIT(31)
+#define XGMAC_FILTER_PMBIT(4)
+#define XGMAC_FILTER_HMC   BIT(2)
+#define XGMAC_FILTER_PRBIT(0)
+#define XGMAC_HASH_TABLE(x)(0x0010 + (x) * 4)
+#define XGMAC_RXQ_CTRL00x00a0
+#define XGMAC_RXQEN(x) GENMASK((x) * 2 + 1, (x) * 2)
+#define XGMAC_RXQEN_SHIFT(x)   ((x) * 2)
+#define XGMAC_RXQ_CTRL20x00a8
+#define XGMAC_RXQ_CTRL30x00ac
+#define XGMAC_PSRQ(x)  GENMASK((x) * 8 + 7, (x) * 8)
+#define XGMAC_PSRQ_SHIFT(x)((x) * 8)
+#define XGMAC_INT_STATUS   0x0

[PATCH net-next 0/9] Add 10GbE support in stmmac using XGMAC2

2018-08-01 Thread Jose Abreu
This series adds support for 10Gigabit IP in stmmac. The IP is called XGMAC2
and has many similarities with GMAC4. Due to this, its relatively easy to
incorporate this new IP into stmmac driver by adding a new block and
filling the necessary callbacks.

The functionality added by this series is still reduced but its only a
starting point which will later be expanded.

I splitted the patches into funcionality and to ease the review. Only the
patch 8/9 really enables the XGMAC2 block by adding a new compatible string.

Cc: David S. Miller 
Cc: Joao Pinto 
Cc: Giuseppe Cavallaro 
Cc: Alexandre Torgue 

Jose Abreu (9):
  net: stmmac: Add XGMAC 2.10 HWIF entry
  net: stmmac: Add MAC related callbacks for XGMAC2
  net: stmmac: Add DMA related callbacks for XGMAC2
  net: stmmac: Add descriptor related callbacks for XGMAC2
  net: stmmac: Add MDIO related functions for XGMAC2
  net: stmmac: Add PTP support for XGMAC2
  net: stmmac: Integrate XGMAC into main driver flow
  net: stmmac: Add the bindings parsing for XGMAC2
  bindings: net: stmmac: Add the bindings documentation for XGMAC2.

 Documentation/devicetree/bindings/net/stmmac.txt   |   3 +-
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   3 +-
 drivers/net/ethernet/stmicro/stmmac/common.h   |  17 +-
 .../net/ethernet/stmicro/stmmac/dwmac-generic.c|   2 +
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 226 
 .../net/ethernet/stmicro/stmmac/dwxgmac2_core.c| 371 +++
 .../net/ethernet/stmicro/stmmac/dwxgmac2_descs.c   | 280 ++
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 410 +
 drivers/net/ethernet/stmicro/stmmac/hwif.c |  31 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h |   3 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |  55 ++-
 drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c  |  88 +
 .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |   6 +
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c   |   6 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h   |   1 +
 include/linux/stmmac.h |   1 +
 16 files changed, 1481 insertions(+), 22 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c

-- 
2.7.4




  1   2   3   >