Re: [PATCH] carl9170: remove get_tid_h

2021-04-02 Thread Christian Lamparter

On 02/04/2021 23:31, Christophe JAILLET wrote:

'get_tid_h()' is the same as 'ieee80211_get_tid()'.
So this function can be removed to save a few lines of code.

Signed-off-by: Christophe JAILLET 

Acked-by: Christian Lamparter 


---
  drivers/net/wireless/ath/carl9170/carl9170.h | 7 +--
  drivers/net/wireless/ath/carl9170/tx.c   | 2 +-
  2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h 
b/drivers/net/wireless/ath/carl9170/carl9170.h
index 0d38100d6e4f..84a8ce0784b1 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -631,14 +631,9 @@ static inline u16 carl9170_get_seq(struct sk_buff *skb)
return get_seq_h(carl9170_get_hdr(skb));
  }
  
-static inline u16 get_tid_h(struct ieee80211_hdr *hdr)

-{
-   return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
-}
-
  static inline u16 carl9170_get_tid(struct sk_buff *skb)
  {
-   return get_tid_h(carl9170_get_hdr(skb));
+   return ieee80211_get_tid(carl9170_get_hdr(skb));
  }
  
  static inline struct ieee80211_vif *

diff --git a/drivers/net/wireless/ath/carl9170/tx.c 
b/drivers/net/wireless/ath/carl9170/tx.c
index 6b8446ff48c8..88444fe6d1c6 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -394,7 +394,7 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 
*ar,
if (unlikely(!sta))
goto out_rcu;
  
-	tid = get_tid_h(hdr);

+   tid = ieee80211_get_tid(hdr);
  
  	sta_info = (void *) sta->drv_priv;

tid_info = rcu_dereference(sta_info->agg[tid]);





Re: [PATCH] carl9170: fix struct alignment conflict

2021-02-04 Thread Christian Lamparter

On 04/02/2021 17:29, Arnd Bergmann wrote:

From: Arnd Bergmann 

Multiple structures in the carl9170 driver have alignment
impossible alignment constraints that gcc warns about when
building with 'make W=1':

drivers/net/wireless/ath/carl9170/fwcmd.h:243:2: warning: alignment 1 of 'union 
' is less than 4 [-Wpacked-not-aligned]
drivers/net/wireless/ath/carl9170/wlan.h:373:1: warning: alignment 1 of 'struct 
ar9170_rx_frame_single' is less than 2 [-Wpacked-not-aligned]

In the carl9170_cmd structure, multiple members that have an explicit
alignment requirement of four bytes are added into a union with explicit
byte alignment, but this in turn is part of a structure that also has
four-byte alignment.

In the wlan.h header, multiple structures contain a ieee80211_hdr member
that is required to be two-byte aligned to avoid alignmnet faults when
processing network headers, but all members are forced to be byte-aligned
using the __packed tag at the end of the struct definition.

In both cases, leaving out the packing does not change the internal
layout of the structure but changes the alignment constraint of the
structure itself.

Change all affected structures to only apply packing where it does
not violate the alignment requirement of the contained structure.

Signed-off-by: Arnd Bergmann 


Acked-by: Christian Lamparter 

I've also applied this patch and a previous one dealing with VLAs to the 
firmware
source at <https://github.com/chunkeey/carl9170fw>. I did a quick rebuilt and
the same binary firmware was produced, so I think what's left is to update those
shared firmware/driver headers some day...

Cheers,
Christian


Re: [PATCH] wireless: remove unneeded break

2020-10-19 Thread Christian Lamparter

On 19/10/2020 17:05, t...@redhat.com wrote:

From: Tom Rix 

A break is not needed if it is preceded by a return or goto

Signed-off-by: Tom Rix 



diff --git a/drivers/net/wireless/intersil/p54/eeprom.c 
b/drivers/net/wireless/intersil/p54/eeprom.c
index 5bd35c147e19..3ca9d26df174 100644
--- a/drivers/net/wireless/intersil/p54/eeprom.c
+++ b/drivers/net/wireless/intersil/p54/eeprom.c
@@ -870,7 +870,6 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void 
*eeprom, int len)
} else {
goto good_eeprom;
}
-   break;

Won't the compiler (gcc) now complain about a missing fallthrough annotation?

default:
break;
}


Cheers,
Christian


Re: R: [PATCH 2/2] dt: bindings: ath10k: Document qcom, ath10k-pre-calibration-data-mtd

2020-09-18 Thread Christian Lamparter

On 2020-09-18 20:31, ansuels...@gmail.com wrote:




-Messaggio originale-
Da: Christian Lamparter 
Inviato: venerdì 18 settembre 2020 18:54
A: Ansuel Smith ; Kalle Valo

Cc: devicet...@vger.kernel.org; netdev@vger.kernel.org; linux-
wirel...@vger.kernel.org; linux-ker...@vger.kernel.org;
ath...@lists.infradead.org; David S. Miller ; Rob
Herring ; Jakub Kicinski ; linux-
m...@lists.infradead.org; Srinivas Kandagatla
; Bartosz Golaszewski

Oggetto: Re: [PATCH 2/2] dt: bindings: ath10k: Document qcom, ath10k-
pre-calibration-data-mtd

On 2020-09-18 18:29, Ansuel Smith wrote:

Document use of qcom,ath10k-pre-calibration-data-mtd bindings used to
define from where the driver will load the pre-cal data in the defined
mtd partition.

Signed-off-by: Ansuel Smith 


Q: Doesn't mtd now come with nvmem support from the get go? So
the MAC-Addresses and pre-caldata could be specified as a
nvmem-node in the devicetree? I remember seeing that this was
worked on or was this mtd->nvmem dropped?

Cheers,
Christian


Sorry a lot for the double email... I think I found what you are talking about.
It looks like the code was merged but not the documentation.
Will do some test and check if this works.

This should be the related patch.
https://patchwork.ozlabs.org/project/linux-mtd/patch/1521933899-362-4-git-send-email-al...@free.fr/



Well, I guess the version that was merged:

|commit c4dfa25ab307a277eafa7067cd927fbe4d9be4ba
|Author: Alban Bedel 
|Date:   Tue Nov 13 15:01:10 2018 +0100
|
|mtd: add support for reading MTD devices via the nvmem API
|
|Allow drivers that use the nvmem API to read data stored on MTD devices.
|For this the mtd devices are registered as read-only NVMEM providers.
|
| >>>We don't support device tree systems for now.<<<

answers this. Sorry for the noise. Yee, this likely isn't going to work
as it is still disabled on purpose.

Regards,
Christian


Re: [PATCH 2/2] dt: bindings: ath10k: Document qcom, ath10k-pre-calibration-data-mtd

2020-09-18 Thread Christian Lamparter

On 2020-09-18 18:29, Ansuel Smith wrote:

Document use of qcom,ath10k-pre-calibration-data-mtd bindings used to
define from where the driver will load the pre-cal data in the defined
mtd partition.

Signed-off-by: Ansuel Smith 


Q: Doesn't mtd now come with nvmem support from the get go? So
the MAC-Addresses and pre-caldata could be specified as a
nvmem-node in the devicetree? I remember seeing that this was
worked on or was this mtd->nvmem dropped?

Cheers,
Christian


Re: [PATCH v2 08/30] net: wireless: ath: carl9170: Convert 'ar9170_qmap' to inline function

2020-08-28 Thread Christian Lamparter
On Thursday, 27 August 2020 11:33:51 CEST Lee Jones wrote:
> 'ar9170_qmap' is used in some source files which include carl9170.h,
> but not all of them.  A 'defined but not used' warning is thrown when
> compiling the ones which do not use it.
> 
> Fixes the following W=1 kernel build warning(s)
> 
>  from drivers/net/wireless/ath/carl9170/carl9170.h:57,
>  In file included from drivers/net/wireless/ath/carl9170/carl9170.h:57,
>  drivers/net/wireless/ath/carl9170/carl9170.h:71:17: warning: ‘ar9170_qmap’ 
> defined but not used [-Wunused-const-variable=]
> 
>  NB: Snipped - lots of these repeat
> 
> Cc: Christian Lamparter 
> Cc: Kalle Valo 
> Cc: "David S. Miller" 
> Cc: Jakub Kicinski 
> Cc: Johannes Berg 
> Cc: linux-wirel...@vger.kernel.org
> Cc: netdev@vger.kernel.org
> Suggested-by: Rasmus Villemoes 
> Signed-off-by: Lee Jones 
> ---

For what it's worth:
Acked-by: Christian Lamparter 





Re: [PATCH][next] carl9170: Use fallthrough pseudo-keyword

2020-08-22 Thread Christian Lamparter

On 2020-08-21 08:52, Gustavo A. R. Silva wrote:

Replace the existing /* fall through */ comments and its variants with
the new pseudo-keyword macro fallthrough[1].

[1] 
https://www.kernel.org/doc/html/v5.7/process/deprecated.html?highlight=fallthrough#implicit-switch-case-fall-through

Signed-off-by: Gustavo A. R. Silva 

Acked-by: Christian Lamparter 


Re: [PATCH 00/32] Set 2: Rid W=1 warnings in Wireless

2020-08-22 Thread Christian Lamparter

On 2020-08-21 09:16, Lee Jones wrote:

This set is part of a larger effort attempting to clean-up W=1
kernel builds, which are currently overwhelmingly riddled with
niggly little warnings.


I see that after our discussion about the carl9170 change in this
thread following your patch: 

you decided the best way to address our requirements, was to "drop"
your patch from the series, instead of just implementing the requested 
changes. :(



There are quite a few W=1 warnings in the Wireless.  My plan
is to work through all of them over the next few weeks.
Hopefully it won't be too long before drivers/net/wireless
builds clean with W=1 enabled.


Just a parting note for your consideration:

Since 5.7 [0], it has become rather easy to also compile the linux 
kernel with clang and the LLVM Utilities.



I hope this information can help you to see beyond that one-unamed 
"compiler" bias there... I wish you the best of luck in your endeavors.


Christian

[0] 



Re: [PATCH 03/16] wireless: ath: convert tasklets to use new tasklet_setup() API

2020-08-17 Thread Christian Lamparter

Hello,

looking at the other patches in this series, I think this patch's 
subject "ath:" tag was supposed to be "carl9170:"?


(so the full subject is:
"wireless: carl9170: convert tasklets to use new tasklet_setup() API")

On 2020-08-17 11:06, Allen Pais wrote:

From: Allen Pais 

In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.

Signed-off-by: Romain Perier 
Signed-off-by: Allen Pais 

Seems to work.

Acked-by: Christian Lamparter 


---
  drivers/net/wireless/ath/carl9170/usb.c | 7 +++
  1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/carl9170/usb.c 
b/drivers/net/wireless/ath/carl9170/usb.c
index ead79335823a..e4eb666c6eea 100644
--- a/drivers/net/wireless/ath/carl9170/usb.c
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -377,9 +377,9 @@ void carl9170_usb_handle_tx_err(struct ar9170 *ar)
}
  }
  
-static void carl9170_usb_tasklet(unsigned long data)

+static void carl9170_usb_tasklet(struct tasklet_struct *t)
  {
-   struct ar9170 *ar = (struct ar9170 *) data;
+   struct ar9170 *ar = from_tasklet(ar, t, usb_tasklet);
  
  	if (!IS_INITIALIZED(ar))

return;
@@ -1082,8 +1082,7 @@ static int carl9170_usb_probe(struct usb_interface *intf,
init_completion(&ar->cmd_wait);
init_completion(&ar->fw_boot_wait);
init_completion(&ar->fw_load_wait);
-   tasklet_init(&ar->usb_tasklet, carl9170_usb_tasklet,
-(unsigned long)ar);
+   tasklet_setup(&ar->usb_tasklet, carl9170_usb_tasklet);
  
  	atomic_set(&ar->tx_cmd_urbs, 0);

atomic_set(&ar->tx_anch_urbs, 0);





Re: [PATCH 08/30] net: wireless: ath: carl9170: Mark 'ar9170_qmap' as __maybe_unused

2020-08-17 Thread Christian Lamparter

On 2020-08-17 14:59, Kalle Valo wrote:

Rasmus Villemoes  writes:


On 14/08/2020 17.14, Christian Lamparter wrote:

On 2020-08-14 13:39, Lee Jones wrote:

'ar9170_qmap' is used in some source files which include carl9170.h,
but not all of them.  Mark it as __maybe_unused to show that this is
not only okay, it's expected.

Fixes the following W=1 kernel build warning(s)


Is this W=1 really a "must" requirement? I find it strange having
__maybe_unused in header files as this "suggests" that the
definition is redundant.


In this case it seems one could replace the table lookup with a

static inline u8 ar9170_qmap(u8 idx) { return 3 - idx; }

gcc doesn't warn about unused static inline functions (or one would have
a million warnings to deal with). Just my $0.02.


Yeah, this is much better.


Yes, this is much better than just adding __maybe_unused :).

To be on the safe side (and to get rid of a & in tx.c:666), the "3 - 
idx" should be something like "return (3 - idx) & 
CARL9170_TX_STATUS_QUEUE". I think its also possible to just use clamp_t
(or min_t since the u8 has no negative values) or make use of a switch 
statement [analogues what was done in ath10k commit: 91493e8e10 "ath10k: 
fix recent bandwidth conversion bug" (just to be clear. Yes this ath10k 
commit has nothing to do with queues, but it is a nice, atomic 
switch-case static inline function example).]



And I think that static variables should not even be in the header
files. Doesn't it mean that there's a local copy of the variable
everytime the .h file is included? Sure, in this case the overhead is
small (4 bytes per include) but still it's wrong.

Seems to be "sort of". I compiled both, the current vanilla carl9170 and
with Lee Jones' patch on Debian's current gcc 10.2.0 (Debian 10.2.0-5)
and gnu ld 2.35.

The ar9170_qmap symbol is only present in the object file if ar9170_qmap 
is used by the source. In the final module file (carl9170.ko), there are 
two ar9170_qmap symboles in the module's .rodata section (one is coming 
from main.o code and the other from tx.o).


(The use of __maybe_unused didn't make any difference. Same overall 
section and file sizes).


Cheers,
Christian


Re: [PATCH 08/30] net: wireless: ath: carl9170: Mark 'ar9170_qmap' as __maybe_unused

2020-08-14 Thread Christian Lamparter

On 2020-08-14 18:40, Lee Jones wrote:

On Fri, 14 Aug 2020, Christian Lamparter wrote:


On 2020-08-14 13:39, Lee Jones wrote:

'ar9170_qmap' is used in some source files which include carl9170.h,
but not all of them.  Mark it as __maybe_unused to show that this is
not only okay, it's expected.

Fixes the following W=1 kernel build warning(s)


Is this W=1 really a "must" requirement? I find it strange having


Clean W=1 warnings is the dream, yes.

But is it a requirement?



I would have thought most Maintainers would be on-board with this.
From what I know: It's no changes For changes' sake. Because otherwise 
this would be pretty broken for maintainers. They could just write and 
revert the same code over and over to prob up their LOC and commit 
counter. Wouldn't you agree there?




The ones I've worked with thus far have certainly been thankful.  Many
had this on their own TODO lists.
Question is, do you really want to be just the cleanup crew there? Since 
semantic patches came along and a lot of this has been automated.
I'm of course after something else. Like: "Isn't there a better way than 
manually slapping __maybe_unused there to suppress the warning and call 
it a day?" If you already went down these avenues and can confirm that 
there's no alternative than this, then "fine". But if there is a better

method of doing this, then "let's go with that!".




__maybe_unused in header files as this "suggests" that the
definition is redundant.


Not true.

If it were redundant then we would remove the line entirely.

So, why adding __maybe_unused then? I find it not very helpful to
tell the compiler to "shut up" when you want it's opinion...
This was the vibe I got from gcc's attribute unused help text.

Cheers,
Christian




   from drivers/net/wireless/ath/carl9170/carl9170.h:57,
   In file included from drivers/net/wireless/ath/carl9170/carl9170.h:57,
   drivers/net/wireless/ath/carl9170/carl9170.h:71:17: warning: ‘ar9170_qmap’ 
defined but not used [-Wunused-const-variable=]

Cc: Christian Lamparter 
Cc: Kalle Valo 
Cc: "David S. Miller" 
Cc: Jakub Kicinski 
Cc: Johannes Berg 
Cc: linux-wirel...@vger.kernel.org
Cc: netdev@vger.kernel.org
Signed-off-by: Lee Jones 
---
   drivers/net/wireless/ath/carl9170/carl9170.h | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h 
b/drivers/net/wireless/ath/carl9170/carl9170.h
index 237d0cda1bcb0..9d86253081bce 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -68,7 +68,7 @@
   #define PAYLOAD_MAX  (CARL9170_MAX_CMD_LEN / 4 - 1)
-static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 3, 2, 1, 0 };
+static const u8 __maybe_unused ar9170_qmap[__AR9170_NUM_TXQ] = { 3, 2, 1, 0 };
   #define CARL9170_MAX_RX_BUFFER_SIZE  8192









Re: [PATCH 08/30] net: wireless: ath: carl9170: Mark 'ar9170_qmap' as __maybe_unused

2020-08-14 Thread Christian Lamparter

On 2020-08-14 13:39, Lee Jones wrote:

'ar9170_qmap' is used in some source files which include carl9170.h,
but not all of them.  Mark it as __maybe_unused to show that this is
not only okay, it's expected.

Fixes the following W=1 kernel build warning(s)


Is this W=1 really a "must" requirement? I find it strange having
__maybe_unused in header files as this "suggests" that the
definition is redundant.


  from drivers/net/wireless/ath/carl9170/carl9170.h:57,
  In file included from drivers/net/wireless/ath/carl9170/carl9170.h:57,
  drivers/net/wireless/ath/carl9170/carl9170.h:71:17: warning: ‘ar9170_qmap’ 
defined but not used [-Wunused-const-variable=]






Cc: Christian Lamparter 
Cc: Kalle Valo 
Cc: "David S. Miller" 
Cc: Jakub Kicinski 
Cc: Johannes Berg 
Cc: linux-wirel...@vger.kernel.org
Cc: netdev@vger.kernel.org
Signed-off-by: Lee Jones 
---
  drivers/net/wireless/ath/carl9170/carl9170.h | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h 
b/drivers/net/wireless/ath/carl9170/carl9170.h
index 237d0cda1bcb0..9d86253081bce 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -68,7 +68,7 @@
  
  #define PAYLOAD_MAX	(CARL9170_MAX_CMD_LEN / 4 - 1)
  
-static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 3, 2, 1, 0 };

+static const u8 __maybe_unused ar9170_qmap[__AR9170_NUM_TXQ] = { 3, 2, 1, 0 };
  
  #define CARL9170_MAX_RX_BUFFER_SIZE		8192
  





[PATCH] net: dsa: qca8k: replace legacy gpio include

2019-07-12 Thread Christian Lamparter
This patch replaces the legacy bulk gpio.h include
with the proper gpio/consumer.h variant. This was
caught by the kbuild test robot that was running
into an error because of this.

For more information why linux/gpio.h is bad can be found in:
commit 56a46b6144e7 ("gpio: Clarify that  is legacy")

Reported-by: kbuild test robot 
Link: https://www.spinics.net/lists/netdev/msg584447.html
Fixes: a653f2f538f9 ("net: dsa: qca8k: introduce reset via gpio feature")
Signed-off-by: Christian Lamparter 
---
 drivers/net/dsa/qca8k.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 27709f866c23..232e8cc96f6d 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -14,7 +14,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 
 #include "qca8k.h"
-- 
2.20.1



Re: [net-next:master 342/422] drivers/net/dsa/qca8k.c:1050:21: error: implicit declaration of function 'devm_gpiod_get_optional'; did you mean 'devm_gpio_request_one'?

2019-07-09 Thread Christian Lamparter
(let's hope that the gmail web interface doesn't mangle this too much)

On Mon, Jul 8, 2019 at 10:16 AM kbuild test robot  wrote:
>
> tree:   
> https://kernel.googlesource.com/pub/scm/linux/kernel/git/davem/net-next.git 
> master
> head:   61a582be1a668a0c1407a46f779965bfeff88784
> commit: a653f2f538f9d3e2d1f1445f74a47bfdace85c2e [342/422] net: dsa: qca8k: 
> introduce reset via gpio feature
> config: x86_64-randconfig-s2-07081539 (attached as .config)
> compiler: gcc-7 (Debian 7.4.0-9) 7.4.0
> reproduce:
> git checkout a653f2f538f9d3e2d1f1445f74a47bfdace85c2e
> # save the attached .config to linux build tree
> make ARCH=x86_64
>
> If you fix the issue, kindly add following tag
> Reported-by: kbuild test robot 
>
> All errors (new ones prefixed by >>):
>
>drivers/net/dsa/qca8k.c: In function 'qca8k_sw_probe':
> >> drivers/net/dsa/qca8k.c:1050:21: error: implicit declaration of function 
> >> 'devm_gpiod_get_optional'; did you mean 'devm_gpio_request_one'? 
> >> [-Werror=implicit-function-declaration]
>  priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
> ^~~
> devm_gpio_request_one
> >> drivers/net/dsa/qca8k.c:1051:10: error: 'GPIOD_ASIS' undeclared (first use 
> >> in this function); did you mean 'GPIOF_IN'?
>  GPIOD_ASIS);
>  ^~
>  GPIOF_IN
>drivers/net/dsa/qca8k.c:1051:10: note: each undeclared identifier is 
> reported only once for each function it appears in
> >> drivers/net/dsa/qca8k.c:1056:3: error: implicit declaration of function 
> >> 'gpiod_set_value_cansleep'; did you mean 'gpio_set_value_cansleep'? 
> >> [-Werror=implicit-function-declaration]
>   gpiod_set_value_cansleep(priv->reset_gpio, 1);
>   ^~~~
>   gpio_set_value_cansleep
>cc1: some warnings being treated as errors
>
> vim +1050 drivers/net/dsa/qca8k.c

Ok, I think that just the

#include 

is needed. I can make a patch for this no issue. I'll download
net-next over the next days
(currently I'm just on a 3G/EDGE connection, so the 1.53 GiB will have
to wait until the
weekend.)

Regards,
Christian


[PATCH v1 1/2] dt-bindings: net: dsa: qca8k: document reset-gpios property

2019-06-25 Thread Christian Lamparter
This patch documents the qca8k's reset-gpios property that
can be used if the QCA8337N ends up in a bad state during
reset.

Signed-off-by: Christian Lamparter 
---
 Documentation/devicetree/bindings/net/dsa/qca8k.txt | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/dsa/qca8k.txt 
b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
index 93a7469e70d4..ccbc6d89325d 100644
--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
@@ -9,6 +9,10 @@ Required properties:
 - #size-cells: must be 0
 - #address-cells: must be 1
 
+Optional properties:
+
+- reset-gpios: GPIO to be used to reset the whole device
+
 Subnodes:
 
 The integrated switch subnode should be specified according to the binding
@@ -66,6 +70,7 @@ for the external mdio-bus configuration:
#address-cells = <1>;
#size-cells = <0>;
 
+   reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
reg = <0x10>;
 
ports {
@@ -123,6 +128,7 @@ for the internal master mdio-bus configuration:
#address-cells = <1>;
#size-cells = <0>;
 
+   reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
reg = <0x10>;
 
ports {
-- 
2.20.1



[PATCH v1 2/2] net: dsa: qca8k: introduce reset via gpio feature

2019-06-25 Thread Christian Lamparter
The QCA8337(N) has a RESETn signal on Pin B42 that
triggers a chip reset if the line is pulled low.
The datasheet says that: "The active low duration
must be greater than 10 ms".

This can hopefully fix some of the issues related
to pin strapping in OpenWrt for the EA8500 which
suffers from detection issues after a SoC reset.

Please note that the qca8k_probe() function does
currently require to read the chip's revision
register for identification purposes.

Signed-off-by: Christian Lamparter 
---
 drivers/net/dsa/qca8k.c | 15 +++
 drivers/net/dsa/qca8k.h |  2 ++
 2 files changed, 17 insertions(+)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index c4fa400efdcc..27709f866c23 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "qca8k.h"
@@ -1046,6 +1047,20 @@ qca8k_sw_probe(struct mdio_device *mdiodev)
priv->bus = mdiodev->bus;
priv->dev = &mdiodev->dev;
 
+   priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
+  GPIOD_ASIS);
+   if (IS_ERR(priv->reset_gpio))
+   return PTR_ERR(priv->reset_gpio);
+
+   if (priv->reset_gpio) {
+   gpiod_set_value_cansleep(priv->reset_gpio, 1);
+   /* The active low duration must be greater than 10 ms
+* and checkpatch.pl wants 20 ms.
+*/
+   msleep(20);
+   gpiod_set_value_cansleep(priv->reset_gpio, 0);
+   }
+
/* read the switches ID register */
id = qca8k_read(priv, QCA8K_REG_MASK_CTRL);
id >>= QCA8K_MASK_CTRL_ID_S;
diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h
index 91557433ce2f..42d6ea24eb14 100644
--- a/drivers/net/dsa/qca8k.h
+++ b/drivers/net/dsa/qca8k.h
@@ -10,6 +10,7 @@
 
 #include 
 #include 
+#include 
 
 #define QCA8K_NUM_PORTS7
 
@@ -174,6 +175,7 @@ struct qca8k_priv {
struct mutex reg_mutex;
struct device *dev;
struct dsa_switch_ops ops;
+   struct gpio_desc *reset_gpio;
 };
 
 struct qca8k_mib_desc {
-- 
2.20.1



Re: [PATCH net-next 1/1] net: dsa: qca8k: Fix internal PHY MDIO address

2019-03-25 Thread Christian Lamparter
On Thursday, March 21, 2019 8:55:55 PM CET Marek Behun wrote:
> Hi,
> 
> Oh, I didn't know about Christian's patch.
> 
> I shall test on our device tomorrow. If it works, we will use internal
> PHY access.
> 
> But I think that qca8k_port_to_phy should be used in the external mode
> as well. On our device the PHYs are mapped on 0-4 on the master bus even
> in that mode.

Any news regarding your test?

Here's a direct link to the series:


To test the internal phy you would need 3/4 + 4/4.

Cheers,
Christian




[PATCH v4 3/4] net: dsa: qca8k: remove leftover phy accessors

2019-03-21 Thread Christian Lamparter
This belated patch implements Andrew Lunn's request of
"remove the phy_read() and phy_write() functions."
<https://lore.kernel.org/patchwork/comment/902734/>

While seemingly harmless, this causes the switch's user
port PHYs to get registered twice. This is because the
DSA subsystem will create a slave mdio-bus not knowing
that the qca8k_phy_(read|write) accessors operate on
the external mdio-bus. So the same "bus" gets effectively
duplicated.

Cc: sta...@vger.kernel.org
Fixes: 6b93fb46480a ("net-next: dsa: add new driver for qca8xxx family")
Signed-off-by: Christian Lamparter 
---
This (standalone) patch should be much easier to backport than
the big one.
---
 drivers/net/dsa/qca8k.c | 18 --
 1 file changed, 18 deletions(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 576b37d12a63..14ad78225f07 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -624,22 +624,6 @@ qca8k_adjust_link(struct dsa_switch *ds, int port, struct 
phy_device *phy)
qca8k_port_set_status(priv, port, 1);
 }
 
-static int
-qca8k_phy_read(struct dsa_switch *ds, int phy, int regnum)
-{
-   struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-
-   return mdiobus_read(priv->bus, phy, regnum);
-}
-
-static int
-qca8k_phy_write(struct dsa_switch *ds, int phy, int regnum, u16 val)
-{
-   struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-
-   return mdiobus_write(priv->bus, phy, regnum, val);
-}
-
 static void
 qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t 
*data)
 {
@@ -879,8 +863,6 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
.setup  = qca8k_setup,
.adjust_link= qca8k_adjust_link,
.get_strings= qca8k_get_strings,
-   .phy_read   = qca8k_phy_read,
-   .phy_write  = qca8k_phy_write,
.get_ethtool_stats  = qca8k_get_ethtool_stats,
.get_sset_count = qca8k_get_sset_count,
.get_mac_eee= qca8k_get_mac_eee,
-- 
2.20.1



Re: [PATCH net-next 1/1] net: dsa: qca8k: Fix internal PHY MDIO address

2019-03-21 Thread Christian Lamparter
On Friday, March 22, 2019 12:01:20 AM CET Marek Behun wrote:
> > Hm, it's not really a "external mode". But let's try one more time.
> > The idea is that if an external mdio-bus (from the SoC) has already
> > registered the PHY 0x0 - 0x4 from the QCA8337, the qca8k should not
> > expose the same PHYs as it's own mdio-bus because then the PHYs end
> > up being registered twice.
> 
> Hi,
> yes, I understand this bit. What I was talking about was that the MDIO
> addresses of internal PHYs are 0 to 4, it does not matter if you access
> them via switch or directly. But the current code for direct access is
> using addresses 1 to 5, which does not work at all. It should also
> substract 1 from the port number.
> 
I think you clipped the part that explained what's wrong the code:

|If you look at the mdio-bus communications during boot you can definitly see
|the funkyness: every PHY gets initialized twice. You can also see this
|"duplication" in /sys/class/mdio_bus. In this directory you'll have a mdio-bus
|from the SoC and another one dsa-0:0 from the qca8k. If you look into those
|you'll notice that their both the same.
|
|As for why this happend. I think I found the culprit in a "missed"
|requirement from one of Andrew Lunn's reponses to the initial qca8k patch:
|
|
|In this post, he described the Device-Tree dts configuration we use today.
|But at the end he requests: 
|"and remove the phy_read() and phy_write() functions."

TL;DR: the current qca8k_phy_(read|write) are wrong and need to be
removed. 

But you should be able to test this in V4 easily (CC'd you there).
You only need Patch 3/4 (and keep your dts the way it is). Anyway,
that's it for now until tomorrow. 

Cheers,
Christian




[PATCH v4 1/4] dt-bindings: net: dsa: qca8k: fix example

2019-03-21 Thread Christian Lamparter
In the example, the phy at phy@0 is clashing with
the switch0@0 at the same address. Usually, the switches
are accessible through pseudo PHYs which in case of the
qca8k are located at 0x10 - 0x18.

Reviewed-by: Florian Fainelli 
Signed-off-by: Christian Lamparter 
---
 Documentation/devicetree/bindings/net/dsa/qca8k.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/dsa/qca8k.txt 
b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
index bbcb255c3150..5eda99e6c86e 100644
--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
@@ -55,12 +55,12 @@ Example:
reg = <4>;
};
 
-   switch0@0 {
+   switch@10 {
compatible = "qca,qca8337";
#address-cells = <1>;
#size-cells = <0>;
 
-   reg = <0>;
+   reg = <0x10>;
 
ports {
#address-cells = <1>;
-- 
2.20.1



[PATCH v4 2/4] dt-bindings: net: dsa: qca8k: support internal mdio-bus

2019-03-21 Thread Christian Lamparter
This patch updates the qca8k's binding to document to the
approach for using the internal mdio-bus of the supported
qca8k switches.

Reviewed-by: Florian Fainelli 
Signed-off-by: Christian Lamparter 
---
 .../devicetree/bindings/net/dsa/qca8k.txt | 69 +--
 1 file changed, 64 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/dsa/qca8k.txt 
b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
index 5eda99e6c86e..93a7469e70d4 100644
--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
@@ -12,10 +12,15 @@ Required properties:
 Subnodes:
 
 The integrated switch subnode should be specified according to the binding
-described in dsa/dsa.txt. As the QCA8K switches do not have a N:N mapping of
-port and PHY id, each subnode describing a port needs to have a valid phandle
-referencing the internal PHY connected to it. The CPU port of this switch is
-always port 0.
+described in dsa/dsa.txt. If the QCA8K switch is connect to a SoC's external
+mdio-bus each subnode describing a port needs to have a valid phandle
+referencing the internal PHY it is connected to. This is because there's no
+N:N mapping of port and PHY id.
+
+Don't use mixed external and internal mdio-bus configurations, as this is
+not supported by the hardware.
+
+The CPU port of this switch is always port 0.
 
 A CPU port node has the following optional node:
 
@@ -31,8 +36,9 @@ For QCA8K the 'fixed-link' sub-node supports only the 
following properties:
 - 'full-duplex' (boolean, optional), to indicate that full duplex is
   used. When absent, half duplex is assumed.
 
-Example:
+Examples:
 
+for the external mdio-bus configuration:
 
&mdio0 {
phy_port1: phy@0 {
@@ -108,3 +114,56 @@ Example:
};
};
};
+
+for the internal master mdio-bus configuration:
+
+   &mdio0 {
+   switch@10 {
+   compatible = "qca,qca8337";
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   reg = <0x10>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+   label = "cpu";
+   ethernet = <&gmac1>;
+   phy-mode = "rgmii";
+   fixed-link {
+   speed = 1000;
+   full-duplex;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+   label = "lan1";
+   };
+
+   port@2 {
+   reg = <2>;
+   label = "lan2";
+   };
+
+   port@3 {
+   reg = <3>;
+   label = "lan3";
+   };
+
+   port@4 {
+   reg = <4>;
+   label = "lan4";
+   };
+
+   port@5 {
+   reg = <5>;
+   label = "wan";
+   };
+   };
+   };
+   };
-- 
2.20.1



[PATCH v4 4/4] net: dsa: qca8k: extend slave-bus implementations

2019-03-21 Thread Christian Lamparter
This patch implements accessors for the QCA8337 MDIO access
through the MDIO_MASTER register, which makes it possible to
access the PHYs on slave-bus through the switch. In cases
where the switch ports are already mapped via external
"phy-phandles", the internal mdio-bus is disabled in order to
prevent a duplicated discovery and enumeration of the same
PHYs. Don't use mixed external and internal mdio-bus
configurations, as this is not supported by the hardware.

Signed-off-by: Christian Lamparter 
---
Changes from v3:
 - removed unneccessary PHYAD checks
 - let dsa subsystem setup the slave bus, but only if needed
 - saved an indent level in qca8k_setup_mdio_bus()
 - Reverse XMAS tree-ized

Changes from v2:
 - Make it compatible with existing configurations
 - make it clear that's sadly a either external or
   internal mdio bus access.

Changes from v1:
 - drop DT port <-> phy mapping
 - added register definitions for the MDIO control register
 - implemented new slave-mdio bus accessors
 - DT-binding: fix switch's PSEUDO_PHY address. It's 0x10 not 0.

Old patch (+ discussion) for reference:
<https://patchwork.ozlabs.org/patch/1036309/>

Tested on a Compex WPQ864 (IPQ8064 + QCA8337N)
internal bus:
qca8k 3700.mdio-mii:10 lan1 (uninitialized): PHY [dsa-0.0:01] driver 
[Generic PHY]
qca8k 3700.mdio-mii:10 lan2 (uninitialized): PHY [dsa-0.0:02] driver 
[Generic PHY]
qca8k 3700.mdio-mii:10 lan3 (uninitialized): PHY [dsa-0.0:03] driver 
[Generic PHY]
qca8k 3700.mdio-mii:10 lan4 (uninitialized): PHY [dsa-0.0:04] driver 
[Generic PHY]
qca8k 3700.mdio-mii:10 wan (uninitialized): PHY [dsa-0.0:05] driver 
[Generic PHY]

external bus:
qca8k 3700.mdio-mii:10 lan1 (uninitialized): PHY [3700.mdio-mii:00] 
driver [Generic PHY]
qca8k 3700.mdio-mii:10 lan2 (uninitialized): PHY [3700.mdio-mii:01] 
driver [Generic PHY]
qca8k 3700.mdio-mii:10 lan3 (uninitialized): PHY [3700.mdio-mii:02] 
driver [Generic PHY]
qca8k 3700.mdio-mii:10 lan4 (uninitialized): PHY [3700.mdio-mii:03] 
driver [Generic PHY]
qca8k 3700.mdio-mii:10 wan (uninitialized): PHY [3700.mdio-mii:04] 
driver [Generic PHY]
---
 drivers/net/dsa/qca8k.c | 156 +++-
 drivers/net/dsa/qca8k.h |  13 
 2 files changed, 168 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 14ad78225f07..c4fa400efdcc 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -481,6 +481,155 @@ qca8k_port_set_status(struct qca8k_priv *priv, int port, 
int enable)
qca8k_reg_clear(priv, QCA8K_REG_PORT_STATUS(port), mask);
 }
 
+static u32
+qca8k_port_to_phy(int port)
+{
+   /* From Andrew Lunn:
+* Port 0 has no internal phy.
+* Port 1 has an internal PHY at MDIO address 0.
+* Port 2 has an internal PHY at MDIO address 1.
+* ...
+* Port 5 has an internal PHY at MDIO address 4.
+* Port 6 has no internal PHY.
+*/
+
+   return port - 1;
+}
+
+static int
+qca8k_mdio_write(struct qca8k_priv *priv, int port, u32 regnum, u16 data)
+{
+   u32 phy, val;
+
+   if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
+   return -EINVAL;
+
+   /* callee is responsible for not passing bad ports,
+* but we still would like to make spills impossible.
+*/
+   phy = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
+   val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
+ QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
+ QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
+ QCA8K_MDIO_MASTER_DATA(data);
+
+   qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
+
+   return qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
+   QCA8K_MDIO_MASTER_BUSY);
+}
+
+static int
+qca8k_mdio_read(struct qca8k_priv *priv, int port, u32 regnum)
+{
+   u32 phy, val;
+
+   if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
+   return -EINVAL;
+
+   /* callee is responsible for not passing bad ports,
+* but we still would like to make spills impossible.
+*/
+   phy = qca8k_port_to_phy(port) % PHY_MAX_ADDR;
+   val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
+ QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
+ QCA8K_MDIO_MASTER_REG_ADDR(regnum);
+
+   qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
+
+   if (qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
+   QCA8K_MDIO_MASTER_BUSY))
+   return -ETIMEDOUT;
+
+   val = (qca8k_read(priv, QCA8K_MDIO_MASTER_CTRL) &
+   QCA8K_MDIO_MASTER_DATA_MASK);
+
+   return val;
+}
+
+static int
+qca8k_phy_write(struct dsa_switch *ds, int port, int regnum, u16 data)
+{
+   struct qca8k_priv *priv = ds->priv;
+
+   return qca8k_mdio_write(priv, port, regnum, data);
+}
+
+static int
+qca

Re: [PATCH net-next 1/1] net: dsa: qca8k: Fix internal PHY MDIO address

2019-03-21 Thread Christian Lamparter
(Bottom post?)
On Thursday, March 21, 2019 8:55:55 PM CET Marek Behun wrote:
> Hi,
> 
> Oh, I didn't know about Christian's patch.
> 
> I shall test on our device tomorrow. If it works, we will use internal
> PHY access.
> 
> But I think that qca8k_port_to_phy should be used in the external mode
> as well. On our device the PHYs are mapped on 0-4 on the master bus even
> in that mode.

Hm, it's not really a "external mode". But let's try one more time. The
idea is that if an external mdio-bus (from the SoC) has already registered
the PHY 0x0 - 0x4 from the QCA8337, the qca8k should not expose the same
PHYs as it's own mdio-bus because then the PHYs end up being registered twice.

If you look at the mdio-bus communications during boot you can definitly see
the funkyness: every PHY gets initialized twice. You can also see this
"duplication" in /sys/class/mdio_bus. In this directory you'll have a mdio-bus
from the SoC and another one dsa-0:0 from the qca8k. If you look into those
you'll notice that their both the same.

As for why this happend. I think I found the culprit in a "missed"
requirement from one of Andrew Lunn's reponses to the initial qca8k patch:


In this post, he described the Device-Tree dts configuration we use today.
But at the end he requests: 
"and remove the phy_read() and phy_write() functions."

But from what I can tell, this important bit of information was lost
during the night. Because they show up in v2+:
https://lore.kernel.org/patchwork/patch/716989/

(So I guess I have to add Fixes: to my patch as well)
 
Cheers,
Christian




Re: [PATCH net-next 1/1] net: dsa: qca8k: Fix internal PHY MDIO address

2019-03-21 Thread Christian Lamparter
On Thursday, March 21, 2019 7:26:08 PM CET Florian Fainelli wrote:
> +Christian,
> 
> On 3/21/19 11:23 AM, Marek Behún wrote:
> > The MDIO addresses of the internal PHYs on this switch for ports 1-5
> > have addresses 0-4, not 1-5.
> > 
> 
> Can you provide a Fixes: tag for this? Your change will conflicts with
> Christian's patch series here:
> 
> http://patchwork.ozlabs.org/project/netdev/list/?series=98063
http://patchwork.ozlabs.org/patch/1058655/ (link to the patch)

So, Yes and no ;)

We both have the same idea:

+static int
+qca8k_port_to_phy(int port)
+{
+   if (port < 1 || port > QCA8K_MDIO_MASTER_MAX_PORTS)
+   return -EINVAL;
+
+   return port - 1;
+}

I plan to sent v4 tomorrow, since I need to test it on the device first.

> > Signed-off-by: Marek Behún 
> > Cc: Andrew Lunn 
> > Cc: Florian Fainelli 
> > Cc: Michal Vokáč 
> > Cc: John Crispin 
> > Cc: Wei Yongjun 
> > ---
> >  drivers/net/dsa/qca8k.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
> > index cdcde7f8e0b2..eb199193cc3b 100644
> > --- a/drivers/net/dsa/qca8k.c
> > +++ b/drivers/net/dsa/qca8k.c
> > @@ -625,7 +625,7 @@ qca8k_phy_read(struct dsa_switch *ds, int phy, int 
> > regnum)
> >  {
> > struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
> >  
> > -   return mdiobus_read(priv->bus, phy, regnum);
> > +   return mdiobus_read(priv->bus, phy - 1, regnum);
> >  }
> >  
> >  static int
> > @@ -633,7 +633,7 @@ qca8k_phy_write(struct dsa_switch *ds, int phy, int 
> > regnum, u16 val)
> >  {
> > struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
> >  
> > -   return mdiobus_write(priv->bus, phy, regnum, val);
> > +   return mdiobus_write(priv->bus, phy - 1, regnum, val);
> >  }

Word of Warning: The priv->bus is pointing to the external mdio-bus that
the QCA8337 is connected to, so in my case I noticed that the *same* PHYs
are registered twice. The first time on the external mdio, which is fine
since we need that for the phy-handle of the "ports" node and a s second
time by the slave-mdio that net/dsa/slave.c provides. In my case I found
Florian's explanation in
https://patchwork.ozlabs.org/patch/1036309/#2084184
very useful:

|I don't think you should have to do any of this translation, because you
|can do a couple of things with DSA/Device Tree:
|
|- you can not provide a phy-handle property at all, in which case, the
|core DSA layer assumes that the PHY is part of the switch's internal
|MDIO bus which is implictly created by dsa_slave_mii_bus_create()
|
|- you can specify a phy-handle property and then the PHY device tree
|node can be placed pretty much anywhere in Device Tree, including on a
|separate MDIO bus Device Tre node which is "external" to the switch
|
|In either case, the PHY device's MDIO bus parent and its address are
|taken care of by drivers/of/of_mdio.c. You can look at mx88e6xxx for how
|it deals with its internal vs. external MDIO bus controller and that
|driver is used on a wide variety of configuration.





Re: [PATCH v3 3/3] net: dsa: qca8k: extend slave-bus implementations

2019-03-20 Thread Christian Lamparter
Sorry. I hit Sent by accident and then I had to run...
This is the full response.

On Wednesday, March 20, 2019 7:27:09 PM CET Florian Fainelli wrote:
> On 3/19/19 12:54 PM, Christian Lamparter wrote:
> > This patch implements accessors for the QCA8337 MDIO access
> > through the MDIO_MASTER register, which makes it possible to
> > access the PHYs on slave-bus through the switch. In cases
> > where the switch ports are already mapped via external
> > "phy-phandles", the internal mdio-bus is disabled in order to
> > prevent a duplicated discovery and enumeration of the same
> > PHYs. Don't use mixed external and internal mdio-bus
> > configurations, as this is not supported by the hardware.
> > 
> > Signed-off-by: Christian Lamparter 
> > ---
> > Changes from v2:
> >  - Make it compatible with existing configurations
> >  - make it clear that's sadly a either external or
> >internal mdio bus access.
> > 
> > Changes from v1:
> >  - drop DT port <-> phy mapping
> >  - added register definitions for the MDIO control register
> >  - implemented new slave-mdio bus accessors
> >  - DT-binding: fix switch's PSEUDO_PHY address. It's 0x10 not 0.
> > 
> > Old patch (+ discussion) for reference:
> > <https://patchwork.ozlabs.org/patch/1036309/>
> 
> LGTM, just a few comments/nits below.
> 
> > 
> > Tested on a Compex WPQ864 (IPQ8064 + QCA8337N)
> > internal bus:
> > qca8k 3700.mdio-mii:10 lan1 (uninitialized): PHY 
> > [!mdio@3700!switch@10:01] driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 lan2 (uninitialized): PHY 
> > [!mdio@3700!switch@10:02] driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 lan3 (uninitialized): PHY 
> > [!mdio@3700!switch@10:03] driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 lan4 (uninitialized): PHY 
> > [!mdio@3700!switch@10:04] driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 wan (uninitialized): PHY 
> > [!mdio@3700!switch@10:05] driver [Generic PHY]
> > 
> > external bus:
> > qca8k 3700.mdio-mii:10 lan1 (uninitialized): PHY [3700.mdio-mii:00] 
> > driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 lan2 (uninitialized): PHY [3700.mdio-mii:01] 
> > driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 lan3 (uninitialized): PHY [3700.mdio-mii:02] 
> > driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 lan4 (uninitialized): PHY [3700.mdio-mii:03] 
> > driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 wan (uninitialized): PHY [3700.mdio-mii:04] 
> > driver [Generic PHY]
> > ---
> 
> [snip]
> 
> > +static int
> > +qca8k_mdio_write(struct qca8k_priv *priv, int port, int regnum, u16 data)
> > +{
> > +   u32 val;
> > +   int phy;
> > +
> > +   phy = qca8k_port_to_phy(port);
> > +   if (phy < 0 || (regnum < 0 || regnum >= QCA8K_MDIO_MASTER_MAX_REG))
> > +   return -EINVAL;
> 
> Is not the first condition always true? We should fix the signature of
> phy_{read,write} in dsa.h to match what mdiobus_{read,write} takes,
> which is an u32 regnum.

Yes in that case regnum will never be negative so this check can be
futher simplyfied as dsa_slave_phy_{read|write} checks ds->phy_mii_mask.
So port can't be invalid. In the next version this will be:

if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
return -EINVAL;

Since regnum > 31 will spill into QCA8K_MDIO_MASTER_PHY_ADDR
and the higher control bits.

> > +
> > +   val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
> > + QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
> > + QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
> > + QCA8K_MDIO_MASTER_DATA(data);
> > +
> > +   qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
> > +
> > +   return qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
> > +   QCA8K_MDIO_MASTER_BUSY);
> > +}
> > +
> > +static int
> > +qca8k_mdio_read(struct qca8k_priv *priv, int port, int regnum)
> > +{
> > +   u32 val;
> > +   int phy;
> > +
> > +   phy = qca8k_port_to_phy(port);
> > +   if (phy < 0 || (regnum < 0 || regnum >= QCA8K_MDIO_MASTER_MAX_REG))
> > +   return -EINVAL;
> 
> Likewise.
Yes.
 
> [snip]
> 
> > +static int
> > +qca8k_phy_read(struct dsa_switch *ds, int port, int regnum)
> > +{
> > +   struct qca8k_priv *priv = ds->priv;
> > +   int ret = -EIO;
> > +
> > +   if (ds->slave_mii_bus->phy_mask & BIT(port))
> > +   ret = qca8k_mdio_read(priv, port, r

Re: [PATCH v3 3/3] net: dsa: qca8k: extend slave-bus implementations

2019-03-20 Thread Christian Lamparter
On Wednesday, March 20, 2019 7:27:09 PM CET Florian Fainelli wrote:
> On 3/19/19 12:54 PM, Christian Lamparter wrote:
> > This patch implements accessors for the QCA8337 MDIO access
> > through the MDIO_MASTER register, which makes it possible to
> > access the PHYs on slave-bus through the switch. In cases
> > where the switch ports are already mapped via external
> > "phy-phandles", the internal mdio-bus is disabled in order to
> > prevent a duplicated discovery and enumeration of the same
> > PHYs. Don't use mixed external and internal mdio-bus
> > configurations, as this is not supported by the hardware.
> > 
> > Signed-off-by: Christian Lamparter 
> > ---
> > Changes from v2:
> >  - Make it compatible with existing configurations
> >  - make it clear that's sadly a either external or
> >internal mdio bus access.
> > 
> > Changes from v1:
> >  - drop DT port <-> phy mapping
> >  - added register definitions for the MDIO control register
> >  - implemented new slave-mdio bus accessors
> >  - DT-binding: fix switch's PSEUDO_PHY address. It's 0x10 not 0.
> > 
> > Old patch (+ discussion) for reference:
> > <https://patchwork.ozlabs.org/patch/1036309/>
> 
> LGTM, just a few comments/nits below.
> 
> > 
> > Tested on a Compex WPQ864 (IPQ8064 + QCA8337N)
> > internal bus:
> > qca8k 3700.mdio-mii:10 lan1 (uninitialized): PHY 
> > [!mdio@3700!switch@10:01] driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 lan2 (uninitialized): PHY 
> > [!mdio@3700!switch@10:02] driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 lan3 (uninitialized): PHY 
> > [!mdio@3700!switch@10:03] driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 lan4 (uninitialized): PHY 
> > [!mdio@3700!switch@10:04] driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 wan (uninitialized): PHY 
> > [!mdio@3700!switch@10:05] driver [Generic PHY]
> > 
> > external bus:
> > qca8k 3700.mdio-mii:10 lan1 (uninitialized): PHY [3700.mdio-mii:00] 
> > driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 lan2 (uninitialized): PHY [3700.mdio-mii:01] 
> > driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 lan3 (uninitialized): PHY [3700.mdio-mii:02] 
> > driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 lan4 (uninitialized): PHY [3700.mdio-mii:03] 
> > driver [Generic PHY]
> > qca8k 3700.mdio-mii:10 wan (uninitialized): PHY [3700.mdio-mii:04] 
> > driver [Generic PHY]
> > ---
> 
> [snip]
> 
> > +static int
> > +qca8k_mdio_write(struct qca8k_priv *priv, int port, int regnum, u16 data)
> > +{
> > +   u32 val;
> > +   int phy;
> > +
> > +   phy = qca8k_port_to_phy(port);
> > +   if (phy < 0 || (regnum < 0 || regnum >= QCA8K_MDIO_MASTER_MAX_REG))
> > +   return -EINVAL;
> 
> Is not the first condition always true? We should fix the signature of
> phy_{read,write} in dsa.h to match what mdiobus_{read,write} takes,
> which is an u32 regnum.

I think you are right. As long as 

> 
> > +
> > +   val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
> > + QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
> > + QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
> > + QCA8K_MDIO_MASTER_DATA(data);
> > +
> > +   qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
> > +
> > +   return qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
> > +   QCA8K_MDIO_MASTER_BUSY);
> > +}
> > +
> > +static int
> > +qca8k_mdio_read(struct qca8k_priv *priv, int port, int regnum)
> > +{
> > +   u32 val;
> > +   int phy;
> > +
> > +   phy = qca8k_port_to_phy(port);
> > +   if (phy < 0 || (regnum < 0 || regnum >= QCA8K_MDIO_MASTER_MAX_REG))
> > +   return -EINVAL;
> 
> Likewise.
> 
> [snip]
> 
> > +static int
> > +qca8k_phy_read(struct dsa_switch *ds, int port, int regnum)
> > +{
> > +   struct qca8k_priv *priv = ds->priv;
> > +   int ret = -EIO;
> > +
> > +   if (ds->slave_mii_bus->phy_mask & BIT(port))
> > +   ret = qca8k_mdio_read(priv, port, regnum);
> 
> I suppose in theory you could also look at the external_mdio_mask and do
> something like this:
> 
>   if (ds->slave_mii_bus->phy_mask & BIT(port))
>   ret = qca8k_mdio_read(priv, port, regnum);
>   else
>   ret = mdiobus_read_nested(priv->bus, port, regnum);
> 
> Not strictly necessary for now.
> 
> > +
> >

[PATCH v3 3/3] net: dsa: qca8k: extend slave-bus implementations

2019-03-19 Thread Christian Lamparter
This patch implements accessors for the QCA8337 MDIO access
through the MDIO_MASTER register, which makes it possible to
access the PHYs on slave-bus through the switch. In cases
where the switch ports are already mapped via external
"phy-phandles", the internal mdio-bus is disabled in order to
prevent a duplicated discovery and enumeration of the same
PHYs. Don't use mixed external and internal mdio-bus
configurations, as this is not supported by the hardware.

Signed-off-by: Christian Lamparter 
---
Changes from v2:
 - Make it compatible with existing configurations
 - make it clear that's sadly a either external or
   internal mdio bus access.

Changes from v1:
 - drop DT port <-> phy mapping
 - added register definitions for the MDIO control register
 - implemented new slave-mdio bus accessors
 - DT-binding: fix switch's PSEUDO_PHY address. It's 0x10 not 0.

Old patch (+ discussion) for reference:
<https://patchwork.ozlabs.org/patch/1036309/>

Tested on a Compex WPQ864 (IPQ8064 + QCA8337N)
internal bus:
qca8k 3700.mdio-mii:10 lan1 (uninitialized): PHY 
[!mdio@3700!switch@10:01] driver [Generic PHY]
qca8k 3700.mdio-mii:10 lan2 (uninitialized): PHY 
[!mdio@3700!switch@10:02] driver [Generic PHY]
qca8k 3700.mdio-mii:10 lan3 (uninitialized): PHY 
[!mdio@3700!switch@10:03] driver [Generic PHY]
qca8k 3700.mdio-mii:10 lan4 (uninitialized): PHY 
[!mdio@3700!switch@10:04] driver [Generic PHY]
qca8k 3700.mdio-mii:10 wan (uninitialized): PHY 
[!mdio@3700!switch@10:05] driver [Generic PHY]

external bus:
qca8k 3700.mdio-mii:10 lan1 (uninitialized): PHY [3700.mdio-mii:00] 
driver [Generic PHY]
qca8k 3700.mdio-mii:10 lan2 (uninitialized): PHY [3700.mdio-mii:01] 
driver [Generic PHY]
qca8k 3700.mdio-mii:10 lan3 (uninitialized): PHY [3700.mdio-mii:02] 
driver [Generic PHY]
qca8k 3700.mdio-mii:10 lan4 (uninitialized): PHY [3700.mdio-mii:03] 
driver [Generic PHY]
qca8k 3700.mdio-mii:10 wan (uninitialized): PHY [3700.mdio-mii:04] 
driver [Generic PHY]
---
 drivers/net/dsa/qca8k.c | 203 
 drivers/net/dsa/qca8k.h |  13 +++
 2 files changed, 197 insertions(+), 19 deletions(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 576b37d12a63..26af1036a4ec 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -481,6 +481,184 @@ qca8k_port_set_status(struct qca8k_priv *priv, int port, 
int enable)
qca8k_reg_clear(priv, QCA8K_REG_PORT_STATUS(port), mask);
 }
 
+static int
+qca8k_port_to_phy(int port)
+{
+   if (port < 1 || port > QCA8K_MDIO_MASTER_MAX_PORTS)
+   return -EINVAL;
+
+   return port - 1;
+}
+
+static int
+qca8k_mdio_write(struct qca8k_priv *priv, int port, int regnum, u16 data)
+{
+   u32 val;
+   int phy;
+
+   phy = qca8k_port_to_phy(port);
+   if (phy < 0 || (regnum < 0 || regnum >= QCA8K_MDIO_MASTER_MAX_REG))
+   return -EINVAL;
+
+   val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
+ QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
+ QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
+ QCA8K_MDIO_MASTER_DATA(data);
+
+   qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
+
+   return qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
+   QCA8K_MDIO_MASTER_BUSY);
+}
+
+static int
+qca8k_mdio_read(struct qca8k_priv *priv, int port, int regnum)
+{
+   u32 val;
+   int phy;
+
+   phy = qca8k_port_to_phy(port);
+   if (phy < 0 || (regnum < 0 || regnum >= QCA8K_MDIO_MASTER_MAX_REG))
+   return -EINVAL;
+
+   val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
+ QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
+ QCA8K_MDIO_MASTER_REG_ADDR(regnum);
+
+   qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
+
+   if (qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
+   QCA8K_MDIO_MASTER_BUSY)) {
+   return -ETIMEDOUT;
+   }
+
+   val = (qca8k_read(priv, QCA8K_MDIO_MASTER_CTRL) &
+   QCA8K_MDIO_MASTER_DATA_MASK);
+
+   return val;
+}
+
+static int
+qca8k_slave_phy_read(struct mii_bus *bus, int addr, int reg)
+{
+   struct qca8k_priv *priv = bus->priv;
+
+   if (priv->ds->phys_mii_mask & BIT(addr)) {
+   int ret = qca8k_mdio_read(priv, addr, reg);
+
+   if (ret >= 0)
+   return ret;
+   }
+
+   return 0x;
+}
+
+static int
+qca8k_slave_phy_write(struct mii_bus *bus, int addr, int reg, u16 val)
+{
+   struct qca8k_priv *priv = bus->priv;
+
+   if (priv->ds->phys_mii_mask & BIT(addr))
+   qca8k_mdio_write(priv, addr, reg, val);
+
+   return 0;
+}
+
+static int
+qca8k_phy_write(struct dsa_switch *ds, int port, int regnum, u16 data)
+{
+   st

[PATCH v3 2/3] dt-bindings: net: dsa: qca8k: support internal mdio-bus

2019-03-19 Thread Christian Lamparter
This patch updates the qca8k's binding to document to the
approach for using the internal mdio-bus of the supported
qca8k switches.

Signed-off-by: Christian Lamparter 
---
 .../devicetree/bindings/net/dsa/qca8k.txt | 69 +--
 1 file changed, 64 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/dsa/qca8k.txt 
b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
index 5eda99e6c86e..93a7469e70d4 100644
--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
@@ -12,10 +12,15 @@ Required properties:
 Subnodes:
 
 The integrated switch subnode should be specified according to the binding
-described in dsa/dsa.txt. As the QCA8K switches do not have a N:N mapping of
-port and PHY id, each subnode describing a port needs to have a valid phandle
-referencing the internal PHY connected to it. The CPU port of this switch is
-always port 0.
+described in dsa/dsa.txt. If the QCA8K switch is connect to a SoC's external
+mdio-bus each subnode describing a port needs to have a valid phandle
+referencing the internal PHY it is connected to. This is because there's no
+N:N mapping of port and PHY id.
+
+Don't use mixed external and internal mdio-bus configurations, as this is
+not supported by the hardware.
+
+The CPU port of this switch is always port 0.
 
 A CPU port node has the following optional node:
 
@@ -31,8 +36,9 @@ For QCA8K the 'fixed-link' sub-node supports only the 
following properties:
 - 'full-duplex' (boolean, optional), to indicate that full duplex is
   used. When absent, half duplex is assumed.
 
-Example:
+Examples:
 
+for the external mdio-bus configuration:
 
&mdio0 {
phy_port1: phy@0 {
@@ -108,3 +114,56 @@ Example:
};
};
};
+
+for the internal master mdio-bus configuration:
+
+   &mdio0 {
+   switch@10 {
+   compatible = "qca,qca8337";
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   reg = <0x10>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+   label = "cpu";
+   ethernet = <&gmac1>;
+   phy-mode = "rgmii";
+   fixed-link {
+   speed = 1000;
+   full-duplex;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+   label = "lan1";
+   };
+
+   port@2 {
+   reg = <2>;
+   label = "lan2";
+   };
+
+   port@3 {
+   reg = <3>;
+   label = "lan3";
+   };
+
+   port@4 {
+   reg = <4>;
+   label = "lan4";
+   };
+
+   port@5 {
+   reg = <5>;
+   label = "wan";
+   };
+   };
+   };
+   };
-- 
2.20.1



[PATCH v3 1/3] dt-bindings: net: dsa: qca8k: fix example

2019-03-19 Thread Christian Lamparter
In the example, the phy at phy@0 is clashing with
the switch0@0 at the same address. Usually, the switches
are accessible through pseudo PHYs which in case of the
qca8k are located at 0x10 - 0x18.

Signed-off-by: Christian Lamparter 
---
 Documentation/devicetree/bindings/net/dsa/qca8k.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/dsa/qca8k.txt 
b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
index bbcb255c3150..5eda99e6c86e 100644
--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
@@ -55,12 +55,12 @@ Example:
reg = <4>;
};
 
-   switch0@0 {
+   switch@10 {
compatible = "qca,qca8337";
#address-cells = <1>;
#size-cells = <0>;
 
-   reg = <0>;
+   reg = <0x10>;
 
ports {
#address-cells = <1>;
-- 
2.20.1



Re: [PATCH v1] net: dsa: qca8k: implement DT-based ports <-> phy translation

2019-02-06 Thread Christian Lamparter
On Wednesday, February 6, 2019 11:29:18 PM CET Florian Fainelli wrote:
> On 2/6/19 1:57 PM, Christian Lamparter wrote:
> > On Tuesday, February 5, 2019 11:29:36 PM CET Florian Fainelli wrote:
> >> On 2/5/19 2:12 PM, Christian Lamparter wrote:
> >>> On Tuesday, February 5, 2019 10:29:34 PM CET Andrew Lunn wrote:
> >>>>> For now, I added the DT binding update to the patch as well.
> >>>>> But if this is indeed the way to go, it'll get a separate patch.
> >>>>
> >>>> Hi Christian 
> >>>>
> >>>> You need to be careful with the DT binding. You need to keep backwards
> >>>> compatible with it. An old DT blob needs to keep working. I don't
> >>>> think this is true with this change.
> >>>
> >>> Do you mean because of the 
> >>>
> >>> -   switch0@0 {
> >>> +   switch@10 {
> >>> compatible = "qca,qca8337";
> >>> #address-cells = <1>;
> >>> #size-cells = <0>;
> >>>  
> >>> -   reg = <0>;
> >>> +   reg = <0x10>;
> >>>
> >>> change?
> >>>
> >>> or because I removed the phy-handles?>
> >>> The reg = <0x10>; will be necessary regardless. Because this
> >>> is really a bug in the existing binding example and if it is
> >>> copied it will prevent the qca8k driver from loading. 
> >>> This is due to a resource conflict, because there will be 
> >>> already a "phy_port1: phy@0" registered at reg = <0>;
> >>> So this never worked would have worked.
> >>
> >> That part is fine, it is the removal of the phy-handle properties that
> >> is possibly a problem, but in hindsight, I do not believe it will be a
> >> compatibility issue. Lack of "phy-handle" property within the core DSA
> >> layer means: utilize the switch's internal MDIO bus (ds->slave_mii_bus)
> >> instance, which you are not removing, you are just changing how the PHYs
> >> map to port numbers.
> >>
> > Ok, thanks. 
> > 
> > I think I'm almost ready for v2. I have fully addressed the compatibility
> > issue by forking off the qca8k_switch_ops depending on whenever a phy-handle
> > property on one of the ports was found or not. If there was no phy-handle 
> > the
> > driver adds the slave-bus accessors to the ops which tells DSA to allocate
> > the slave bus and allows the phys can be enumerated. If the phy-handles are
> > found the driver will not have the accessors and DSA will not setup a
> > redundant/fake bus and this prevents the second/double/duplicated discovery
> > and enumeration of the same PHYs again.
> 
> The logic you have sounds a little too broad since it stops as soon as
> one port is found with a 'phy-handle' property and assumes that the
> parent MDIO bus from which qca8k itself is a child device, is the MDIO
> bus to be used. There are possibly 3 cases:
> 
> 1) All ports using internal/build-in PHYs. In that case, you can either
> not specify a 'phy-handle' property and DSA assumes that they are part
> of the switch's internal MDIO bus. You can also specify a 'phy-handle'
> property that references the internal MDIO bus, although then we also
> expect qca8k to register its internal MDIO bus (ala mv88e6xxx)
> 
> 2) Some ports using internal PHYs, some using external PHYs. Similar
> situation again, ports may, or may not specify a 'phy-handle' property,
> so without a 'phy-handle' property that means the port connects to an
> internal PHY, with a 'phy-handle' it could connect to either internal
> PHY or external PHY
> 
> 3) All ports using external PHYs, in that case, we must have a
> 'phy-handle' for each port to specify where and how they connect to
> their external PHYs.

Oh, sadly the mixed configuration you have envisioned will not work really.
The QCA8K_MDIO_MASTER_EN Bit,which grants access to PHYs through the
MDIO_MASTER register also _disconnects_ the external MDC passthrough to
the internal PHYs. So you get garbage like:

[   17.036963] Generic PHY 3700.mdio-mii:01: Master/Slave resolution 
failed, maybe conflicting manual settings?
[   17.116927] Generic PHY 3700.mdio-mii:02: Master/Slave resolution 
failed, maybe conflicting manual settings?
[   17.196894] Generic PHY 3700.mdio-mii:03: Master/Slave resolution 
failed, maybe 

Re: [PATCH v1] net: dsa: qca8k: implement DT-based ports <-> phy translation

2019-02-06 Thread Christian Lamparter
On Tuesday, February 5, 2019 11:29:36 PM CET Florian Fainelli wrote:
> On 2/5/19 2:12 PM, Christian Lamparter wrote:
> > On Tuesday, February 5, 2019 10:29:34 PM CET Andrew Lunn wrote:
> >>> For now, I added the DT binding update to the patch as well.
> >>> But if this is indeed the way to go, it'll get a separate patch.
> >>
> >> Hi Christian 
> >>
> >> You need to be careful with the DT binding. You need to keep backwards
> >> compatible with it. An old DT blob needs to keep working. I don't
> >> think this is true with this change.
> > 
> > Do you mean because of the 
> > 
> > -   switch0@0 {
> > +   switch@10 {
> > compatible = "qca,qca8337";
> > #address-cells = <1>;
> > #size-cells = <0>;
> >  
> > -   reg = <0>;
> > +   reg = <0x10>;
> > 
> > change?
> > 
> > or because I removed the phy-handles?>
> > The reg = <0x10>; will be necessary regardless. Because this
> > is really a bug in the existing binding example and if it is
> > copied it will prevent the qca8k driver from loading. 
> > This is due to a resource conflict, because there will be 
> > already a "phy_port1: phy@0" registered at reg = <0>;
> > So this never worked would have worked.
> 
> That part is fine, it is the removal of the phy-handle properties that
> is possibly a problem, but in hindsight, I do not believe it will be a
> compatibility issue. Lack of "phy-handle" property within the core DSA
> layer means: utilize the switch's internal MDIO bus (ds->slave_mii_bus)
> instance, which you are not removing, you are just changing how the PHYs
> map to port numbers.
> 
Ok, thanks. 

I think I'm almost ready for v2. I have fully addressed the compatibility
issue by forking off the qca8k_switch_ops depending on whenever a phy-handle
property on one of the ports was found or not. If there was no phy-handle the
driver adds the slave-bus accessors to the ops which tells DSA to allocate
the slave bus and allows the phys can be enumerated. If the phy-handles are
found the driver will not have the accessors and DSA will not setup a
redundant/fake bus and this prevents the second/double/duplicated discovery
and enumeration of the same PHYs again.

Cheers,
Christian

Attached is a preview:

---
commit 96bc70b4d6e290c450b9af728d9ca0f6db877f13
Author: Christian Lamparter 
Date:   Fri Feb 1 22:54:32 2019 +0100

net: dsa: qca8k: extend slave-bus implementations

This patch implements accessors for the QCA8337 MDIO access
through the MDIO_MASTER register, which makes it possible to
access the PHYs on slave-bus through the switch. In cases
where the switch ports are already mapped via external
"phy-phandles", the internal mdio-bus is disabled in order to
prevent a duplicated discovery and enumeration of the same
PHYs.

Signed-off-by: Christian Lamparter 
---

Changes from v2:
 - Make it compatible with existing configurations

Changes from v1:
 - drop DT port <-> phy mapping
 - added register definitions for the MDIO control register
 - implemented new slave-mdio bus accessors
 - DT-binding: fix switch's PSEUDO_PHY address. It's 0x10 not 0.

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index a4b6cda38016..2f1b4b0a3507 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -613,19 +613,61 @@ qca8k_adjust_link(struct dsa_switch *ds, int port, struct 
phy_device *phy)
 }
 
 static int
-qca8k_phy_read(struct dsa_switch *ds, int phy, int regnum)
+qca8k_port_to_phy(int port)
+{
+   if (port < 1 || port > QCA8K_MDIO_MASTER_MAX_PORTS)
+   return -EINVAL;
+
+   return port - 1;
+}
+
+static int
+qca8k_phy_write(struct dsa_switch *ds, int port, int regnum, u16 data)
 {
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+   u32 val, phy;
+
+   phy = qca8k_port_to_phy(port);
+   if (phy < 0 || (regnum < 0 || regnum >= QCA8K_MDIO_MASTER_MAX_REG))
+   return -EINVAL;
+
+   val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
+ QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
+ QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
+ QCA8K_MDIO_MASTER_DATA(data);
 
-   return mdiobus_read(priv->bus, phy, regnum);
+   qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
+
+   return qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
+   QCA8K_MDIO_MASTER_BUSY);
 }
 
+
 static int
-qca8k_phy_write(struct dsa_switch *ds, int phy, int r

Re: [PATCH v1] net: dsa: qca8k: implement DT-based ports <-> phy translation

2019-02-05 Thread Christian Lamparter
On Tuesday, February 5, 2019 10:29:34 PM CET Andrew Lunn wrote:
> > For now, I added the DT binding update to the patch as well.
> > But if this is indeed the way to go, it'll get a separate patch.
> 
> Hi Christian 
> 
> You need to be careful with the DT binding. You need to keep backwards
> compatible with it. An old DT blob needs to keep working. I don't
> think this is true with this change.

Do you mean because of the 

-   switch0@0 {
+   switch@10 {
compatible = "qca,qca8337";
#address-cells = <1>;
#size-cells = <0>;
 
-   reg = <0>;
+   reg = <0x10>;

change?

or because I removed the phy-handles?

The reg = <0x10>; will be necessary regardless. Because this
is really a bug in the existing binding example and if it is
copied it will prevent the qca8k driver from loading. 
This is due to a resource conflict, because there will be 
already a "phy_port1: phy@0" registered at reg = <0>;
So this never worked would have worked.

Regards,
Christian




[PATCH v3] net: emac: remove IBM_EMAC_RX_SKB_HEADROOM

2019-02-05 Thread Christian Lamparter
The EMAC driver had a custom IBM_EMAC_RX_SKB_HEADROOM
Kconfig option that reserved additional skb headroom for RX.
This patch removes the option and migrates the code
to use napi_alloc_skb() and netdev_alloc_skb_ip_align()
in its place.

Signed-off-by: Christian Lamparter 
---
 v2 -> v3: drop inlines

 drivers/net/ethernet/ibm/emac/Kconfig | 12 -
 drivers/net/ethernet/ibm/emac/core.c  | 64 ++-
 drivers/net/ethernet/ibm/emac/core.h  | 10 ++---
 3 files changed, 47 insertions(+), 39 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/Kconfig 
b/drivers/net/ethernet/ibm/emac/Kconfig
index 90d49191beb3..eacf7e141fdc 100644
--- a/drivers/net/ethernet/ibm/emac/Kconfig
+++ b/drivers/net/ethernet/ibm/emac/Kconfig
@@ -28,18 +28,6 @@ config IBM_EMAC_RX_COPY_THRESHOLD
depends on IBM_EMAC
default "256"
 
-config IBM_EMAC_RX_SKB_HEADROOM
-   int "Additional RX skb headroom (bytes)"
-   depends on IBM_EMAC
-   default "0"
-   help
- Additional receive skb headroom. Note, that driver
- will always reserve at least 2 bytes to make IP header
- aligned, so usually there is no need to add any additional
- headroom.
-
- If unsure, set to 0.
-
 config IBM_EMAC_DEBUG
bool "Debugging"
depends on IBM_EMAC
diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 209255495bc9..3c2a5759844a 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -1071,7 +1071,9 @@ static int emac_resize_rx_ring(struct emac_instance *dev, 
int new_mtu)
 
/* Second pass, allocate new skbs */
for (i = 0; i < NUM_RX_BUFF; ++i) {
-   struct sk_buff *skb = alloc_skb(rx_skb_size, GFP_ATOMIC);
+   struct sk_buff *skb;
+
+   skb = netdev_alloc_skb_ip_align(dev->ndev, rx_skb_size);
if (!skb) {
ret = -ENOMEM;
goto oom;
@@ -1080,10 +1082,10 @@ static int emac_resize_rx_ring(struct emac_instance 
*dev, int new_mtu)
BUG_ON(!dev->rx_skb[i]);
dev_kfree_skb(dev->rx_skb[i]);
 
-   skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
dev->rx_desc[i].data_ptr =
-   dma_map_single(&dev->ofdev->dev, skb->data - 2, 
rx_sync_size,
-  DMA_FROM_DEVICE) + 2;
+   dma_map_single(&dev->ofdev->dev, skb->data - NET_IP_ALIGN,
+  rx_sync_size, DMA_FROM_DEVICE)
+  + NET_IP_ALIGN;
dev->rx_skb[i] = skb;
}
  skip:
@@ -1174,20 +1176,18 @@ static void emac_clean_rx_ring(struct emac_instance 
*dev)
}
 }
 
-static inline int emac_alloc_rx_skb(struct emac_instance *dev, int slot,
-   gfp_t flags)
+static int
+__emac_prepare_rx_skb(struct sk_buff *skb, struct emac_instance *dev, int slot)
 {
-   struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags);
if (unlikely(!skb))
return -ENOMEM;
 
dev->rx_skb[slot] = skb;
dev->rx_desc[slot].data_len = 0;
 
-   skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
dev->rx_desc[slot].data_ptr =
-   dma_map_single(&dev->ofdev->dev, skb->data - 2, dev->rx_sync_size,
-  DMA_FROM_DEVICE) + 2;
+   dma_map_single(&dev->ofdev->dev, skb->data - NET_IP_ALIGN,
+  dev->rx_sync_size, DMA_FROM_DEVICE) + NET_IP_ALIGN;
wmb();
dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
(slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
@@ -1195,6 +1195,27 @@ static inline int emac_alloc_rx_skb(struct emac_instance 
*dev, int slot,
return 0;
 }
 
+static int
+emac_alloc_rx_skb(struct emac_instance *dev, int slot)
+{
+   struct sk_buff *skb;
+
+   skb = __netdev_alloc_skb_ip_align(dev->ndev, dev->rx_skb_size,
+ GFP_KERNEL);
+
+   return __emac_prepare_rx_skb(skb, dev, slot);
+}
+
+static int
+emac_alloc_rx_skb_napi(struct emac_instance *dev, int slot)
+{
+   struct sk_buff *skb;
+
+   skb = napi_alloc_skb(&dev->mal->napi, dev->rx_skb_size);
+
+   return __emac_prepare_rx_skb(skb, dev, slot);
+}
+
 static void emac_print_link_status(struct emac_instance *dev)
 {
if (netif_carrier_ok(dev->ndev))
@@ -1225,7 +1246,7 @@ static int emac_open(struct net_device *ndev)
 
/* Allocate RX ring */
for (i = 0; i < NUM_RX_BUFF; ++i)
-   if (emac_alloc_rx_skb(dev, i, GFP_KERNEL)) {
+   if (emac_alloc_rx_skb(dev, i)) {
printk(KERN_ERR "%s: failed to allocate RX ring\n",
   ndev-&

Re: [PATCH v1] net: dsa: qca8k: implement DT-based ports <-> phy translation

2019-02-05 Thread Christian Lamparter
On Tuesday, February 5, 2019 2:09:35 PM CET Andrew Lunn wrote:
> > The trick here is that priv->bus is not the internal
> > bus instead it's set to the SoC's (external) mii bus in qca8k_sw_probe()).
> > So this isn't a slave bus! And as stated in the qca8k, the the external
> > and internal PHY bus are not mapped 1:1.
> > 
> > >From what I can tell from the datasheet, the QCA8337N does have
> > dedicated MDIO master control register which is what is
> > needed here.
> 
> Ah, O.K, i was missing that bit. So yes, export an MDIO bus to Linux,
> as the mv88e6xxx does.

I've attached of what I think is needed for this. Can you please take
a quick look and see if this is matches your expecation?

A nice side-effect of adding support for the internal mdio-bus is that
the chip's mdio is now accessible through its UART interface mode or
through data frames (The QCA8337 registers can be accessed
through special data frames from the CPU port).

As for this version, it boots up fine on the WPQ864 with the QCA8337N:

[5.799639] libphy: dsa slave smi: probed
[5.820129] qca8k 3700.mdio-mii:10 lan1 (uninitialized): PHY 
[dsa-0.0:01] driver [Generic PHY]
[5.822418] qca8k 3700.mdio-mii:10 lan2 (uninitialized): PHY 
[dsa-0.0:02] driver [Generic PHY]
[5.830154] qca8k 3700.mdio-mii:10 lan3 (uninitialized): PHY 
[dsa-0.0:03] driver [Generic PHY]
[5.839284] qca8k 3700.mdio-mii:10 lan4 (uninitialized): PHY 
[dsa-0.0:04] driver [Generic PHY]
[5.848048] qca8k 3700.mdio-mii:10 wan (uninitialized): PHY [dsa-0.0:05] 
driver [Generic PHY]
[5.856065] DSA: tree 0 setup

and it works as expected.

For now, I added the DT binding update to the patch as well.
But if this is indeed the way to go, it'll get a separate patch.

Cheers,
Christian

---
>From e4951353e5e25f725a777b3a380c16bf55b2b7c1 Mon Sep 17 00:00:00 2001
From: Christian Lamparter 
Date: Fri, 1 Feb 2019 22:54:32 +0100
Subject: [PATCH v2] net: dsa: qca8k: replace slave-bus implementation

The QCA8337 enumerates 5 PHYs on its internal MDIO access:
on address 0, 1, 2, 3 and 4. Based on the System Block
Diagram in Section 1.2 of the QCA8337's datasheet. These PHYs
connected to MACs of Port 1 to 5.

This version of the patch implements the QCA8337 MDIO
access through the switch's MDIO_MASTER register, which
makes it possible to forgo the current port-mapping in
the DT to map each Port.

Signed-off-by: Christian Lamparter 
---

Changes from v1:
 - drop DT port <-> phy mapping
 - added register definitions for the MDIO control register
 - implemented new slave-mdio bus accessors
 - DT-binding: fix switch's PSEUDO_PHY address. It's 0x10 not 0.
---
 .../devicetree/bindings/net/dsa/qca8k.txt | 35 ++---
 drivers/net/dsa/qca8k.c   | 50 +--
 drivers/net/dsa/qca8k.h   | 12 +
 3 files changed, 62 insertions(+), 35 deletions(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index a4b6cda38016..dfcfb0791965 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -613,19 +613,61 @@ qca8k_adjust_link(struct dsa_switch *ds, int port, struct 
phy_device *phy)
 }
 
 static int
-qca8k_phy_read(struct dsa_switch *ds, int phy, int regnum)
+qca8k_port_to_phy(int port)
+{
+   if (port < 1 || port > QCA8K_MDIO_MASTER_MAX_PORTS)
+   return -EINVAL;
+
+   return port - 1;
+}
+
+static int
+qca8k_phy_write(struct dsa_switch *ds, int port, int regnum, u16 data)
 {
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+   u32 val, phy;
+
+   phy = qca8k_port_to_phy(port);
+   if (phy < 0 || (regnum < 0 || regnum >= QCA8K_MDIO_MASTER_MAX_REG))
+   return -EINVAL;
+
+   val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
+ QCA8K_MDIO_MASTER_WRITE | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
+ QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
+ QCA8K_MDIO_MASTER_DATA(data);
 
-   return mdiobus_read(priv->bus, phy, regnum);
+   qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
+
+   return qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
+   QCA8K_MDIO_MASTER_BUSY);
 }
 
+
 static int
-qca8k_phy_write(struct dsa_switch *ds, int phy, int regnum, u16 val)
+qca8k_phy_read(struct dsa_switch *ds, int port, int regnum)
 {
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+   u32 val, phy;
+
+   phy = qca8k_port_to_phy(port);
+   if (phy < 0 || (regnum < 0 || regnum >= QCA8K_MDIO_MASTER_MAX_REG))
+   return 0x;
+
+   val = QCA8K_MDIO_MASTER_BUSY | QCA8K_MDIO_MASTER_EN |
+ QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
+ QCA8K_MDIO_MASTER_REG_ADDR(regnum);
+
+   qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
 
-   return mdi

Re: [PATCH v1] net: dsa: qca8k: implement DT-based ports <-> phy translation

2019-02-05 Thread Christian Lamparter
On Tuesday, February 5, 2019 3:45:33 AM CET Andrew Lunn wrote:
> On Mon, Feb 04, 2019 at 10:35:55PM +0100, Christian Lamparter wrote:
> > The QCA8337 enumerates 5 PHYs on the MDC/MDIO access: PHY0-PHY4.
> > Based on the System Block Diagram in Section 1.2 of the
> > QCA8337's datasheet. These PHYs are internally connected
> > to MACs of PORT 1 - PORT 5. However, neither qca8k's slave
> > mdio access functions qca8k_phy_read()/qca8k_phy_write()
> > nor the dsa framework is set up for that.
> > 
> > This version of the patch uses the existing phy-handle
> > properties of each specified DSA Port in the DT to map
> > each PORT/MAC to its exposed PHY on the MDIO bus. This
> > is supported by the current binding document qca8k.txt
> > as well.
> 
> Hi Christian
> 
> Looking at Documentation/devicetree/bindings/net/dsa/qca8k.txt 
> 
> I think everything you need is already implemented. What problem do
> you actually have?

Thankfully, Florian's reply answered the question to me. The problem
has to do with the qca8k's slave qca8k_phy_read and qca8k_phy_write.
Here are the functions:

|qca8k_phy_read(struct dsa_switch *ds, int phy, int regnum)
|{
|   struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
|   return mdiobus_read(priv->bus, phy, regnum);
|}
|
|static int
|qca8k_phy_write(struct dsa_switch *ds, int phy, int regnum, u16 val)
|{
|   struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
|   return mdiobus_write(priv->bus, phy, regnum, val);
|}

The trick here is that priv->bus is not the internal
bus instead it's set to the SoC's (external) mii bus in qca8k_sw_probe()).
So this isn't a slave bus! And as stated in the qca8k, the the external
and internal PHY bus are not mapped 1:1.

>From what I can tell from the datasheet, the QCA8337N does have
dedicated MDIO master control register which is what is
needed here. It's at 0x003C. So these mdiobus_read/writes on the
SoCs MDIO bus would either need to be converted to read and write
to 0x003c... Or the qca8k_phy_read() and qca8k_phy_write could be
dropped all together. I've tested it on the WPQ864 and driver
works without since it was never a real slave bus there to begin with.

Thanks,
Christian
---
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 7e97e620bd44..a26850c888cf 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -620,22 +620,6 @@ qca8k_adjust_link(struct dsa_switch *ds, int port, struct 
phy_device *phy)
qca8k_port_set_status(priv, port, 1);
 }
 
-static int
-qca8k_phy_read(struct dsa_switch *ds, int phy, int regnum)
-{
-   struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-
-   return mdiobus_read(priv->bus, phy, regnum);
-}
-
-static int
-qca8k_phy_write(struct dsa_switch *ds, int phy, int regnum, u16 val)
-{
-   struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-
-   return mdiobus_write(priv->bus, phy, regnum, val);
-}
-
 static void
 qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset, uint8_t 
*data)
 {
@@ -876,8 +860,6 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
.setup  = qca8k_setup,
.adjust_link= qca8k_adjust_link,
.get_strings= qca8k_get_strings,
-   .phy_read   = qca8k_phy_read,
-   .phy_write  = qca8k_phy_write,
.get_ethtool_stats  = qca8k_get_ethtool_stats,
.get_sset_count = qca8k_get_sset_count,
.get_mac_eee= qca8k_get_mac_eee,









Re: [PATCH v1] net: dsa: qca8k: implement DT-based ports <-> phy translation

2019-02-04 Thread Christian Lamparter
Hello Andrew and Florian.

I concated both replies into this post.

On Monday, February 4, 2019 11:26:41 PM CET Andrew Lunn wrote:
> On Mon, Feb 04, 2019 at 10:35:55PM +0100, Christian Lamparter wrote:
> > The QCA8337 enumerates 5 PHYs on the MDC/MDIO access: PHY0-PHY4.
> > Based on the System Block Diagram in Section 1.2 of the
> > QCA8337's datasheet. These PHYs are internally connected
> > to MACs of PORT 1 - PORT 5.
> 
> Hi Christian
> 
> Is the off-by-one the problem here?
> 
Yes, this was triggered by a MII_PHYSID1 and MII_PHYSID2 read for a 
non-existent PHY at address >0x5< coming from dsa_register_switch()
during boot.

I added a WARN_ON to qca8k_phy_read() to see from where the reads are
coming from:

[6.218168] WARNING: CPU: 0 PID: 21 at qca8k_phy_read+0x3c/0x68
[6.224062] Modules linked in:
[6.227107] CPU: 0 PID: 21 Comm: kworker/0:1 Tainted: GW 
4.19.16 #0
[6.234732] Workqueue: events deferred_probe_work_func
[6.239849] NIP:  c0308528 LR: c0308528 CTR: c0257d30
[6.244878] REGS: cf485b80 TRAP: 0700   Tainted: GW  
(4.19.16)
[6.252064] MSR:  00029000   CR: 2800  XER: 
[6.258224]
[6.258224] GPR00: c0308528 cf485c30 cf47c000 0005  0215 
c09d61e4 c09d3de0
[6.258224] GPR08: 00021000 c09bfb00 c09bfb00 0007 24002444  
c003f81c cf466060
[6.258224] GPR16:  cf633f60 cf633f6c 0001 cf633f40 c0589f7c 
006080c0 c09bede8
[6.258224] GPR24: cf633f40   f000 0003 cdf21790 
0003 0005
[6.292952] NIP [c0308528] qca8k_phy_read+0x3c/0x68
[6.297808] LR [c0308528] qca8k_phy_read+0x3c/0x68
[6.302574] Call Trace:
[6.305013] [cf485c30] [c0308528] qca8k_phy_read+0x3c/0x68 (unreliable)
[6.311602] [cf485c50] [c0300530] mdiobus_read+0x6c/0x9c
[6.316894] [cf485c70] [c02ffdcc] get_phy_device+0x188/0x204
[6.322527] [cf485cd0] [c0300740] mdiobus_scan+0x20/0x160
[6.327901] [cf485d00] [c0300a3c] __mdiobus_register+0x1bc/0x2a8
[6.333884] [cf485d30] [c047e690] dsa_register_switch+0x6a0/0x904
[6.339954] [cf485db0] [c0300dd8] mdio_probe+0x40/0x88
[6.345070] [cf485dc0] [c026947c] really_probe+0x168/0x300
[6.350530] [cf485df0] [c0269b44] driver_probe_device+0x410/0x460
[6.356594] [cf485e10] [c02672cc] bus_for_each_drv+0x5c/0xc0
[6.362229] [cf485e40] [c0269270] __device_attach+0xa8/0x144
[6.367862] [cf485e70] [c0268430] bus_probe_device+0x3c/0xc0
[6.373495] [cf485e90] [c02689dc] deferred_probe_work_func+0x70/0xac
[6.379821] [cf485eb0] [c003a2c4] process_one_work+0x25c/0x3b0
[6.385633] [cf485ed0] [c003a708] worker_thread+0x2f0/0x434
[6.391180] [cf485f10] [c003f950] kthread+0x134/0x138
[6.396209] [cf485f40] [c000d23c] ret_from_kernel_thread+0x14/0x1c
[6.402357] Instruction dump:
[6.405313] 93c10018 7cbe2b78 93e1001c 7c9f2378 93a10014 83a30018 4bfffe4d 
3d20c058
[6.413027] 7c651b78 7fe4fb78 3869c970 4bd4e35d <0fe0> 80010024 7fc5f378 
807d0004
[6.420916] ---[ end trace 00aeb6767b21cd36 ]---

If I disable port@5 (see qca8k.txt example)
<https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/net/dsa/qca8k.txt#L103>

then problem went away (but of course, this makes the WAN port useless).

When I looked more into it, I started to notice that the mdiobus_scan
started from address >1< (not 0). It was skipping PHY0 (which does exist!)
and then the extract from qca8k.txt suddenly made sense:

|The integrated switch subnode should be specified according to the binding
|described in dsa/dsa.txt. As the QCA8K switches do not have a N:N mapping of
|port and PHY id, each subnode describing a port needs to have a valid phandle
|referencing the internal PHY connected to it. The CPU port of this switch is
|always port 0.

>From what I can tell, the slave mdio port-numbers (i.e 0 - 5/6 on the qca8k)
are being used directly as phy-addresses on the slave-bus. And since the port0
is a cpu port it gets skipped when the ds->phy_mii_mask is created in
dsa_switch_setup():

| ds->phys_mii_mask |= dsa_user_ports(ds);  // 0x3E

<https://elixir.bootlin.com/linux/v5.0-rc5/source/net/dsa/dsa2.c#L350>

However, ds->phys_mii_mask is used to calculate the slave's phy_mask in
dsa_slave_mii_bus_init()

|ds->slave_mii_bus->phy_mask = ~ds->phys_mii_mask; // ~0x3E

<https://github.com/torvalds/linux/blob/master/net/dsa/slave.c#L61>

which is then later used by __mdiobus_register() to scan for the
supposedly existing PHY at 0x1 - 0x5.

|   for (i = 0; i < PHY_MAX_ADDR; i++) {
|   if ((bus->phy_mask & (1 << i)) == 0) {
|   struct phy_device *phydev;
|
|   phydev = mdiobus_scan(bus, i);
|   if (IS_ERR(phydev) && (PTR_ERR(phydev) != -ENODEV)) {
|   err = PTR_ERR(phy

[PATCH v2] net: emac: remove IBM_EMAC_RX_SKB_HEADROOM

2019-02-04 Thread Christian Lamparter
The EMAC driver had a custom IBM_EMAC_RX_SKB_HEADROOM
Kconfig option that reserved additional skb headroom for RX.
This patch removes the option and migrates the code
to use napi_alloc_skb() and netdev_alloc_skb_ip_align()
in its place.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/Kconfig | 12 -
 drivers/net/ethernet/ibm/emac/core.c  | 64 ++-
 drivers/net/ethernet/ibm/emac/core.h  | 10 ++---
 3 files changed, 47 insertions(+), 39 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/Kconfig 
b/drivers/net/ethernet/ibm/emac/Kconfig
index 90d49191beb3..eacf7e141fdc 100644
--- a/drivers/net/ethernet/ibm/emac/Kconfig
+++ b/drivers/net/ethernet/ibm/emac/Kconfig
@@ -28,18 +28,6 @@ config IBM_EMAC_RX_COPY_THRESHOLD
depends on IBM_EMAC
default "256"
 
-config IBM_EMAC_RX_SKB_HEADROOM
-   int "Additional RX skb headroom (bytes)"
-   depends on IBM_EMAC
-   default "0"
-   help
- Additional receive skb headroom. Note, that driver
- will always reserve at least 2 bytes to make IP header
- aligned, so usually there is no need to add any additional
- headroom.
-
- If unsure, set to 0.
-
 config IBM_EMAC_DEBUG
bool "Debugging"
depends on IBM_EMAC
diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 209255495bc9..5fc5fa37d305 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -1071,7 +1071,9 @@ static int emac_resize_rx_ring(struct emac_instance *dev, 
int new_mtu)
 
/* Second pass, allocate new skbs */
for (i = 0; i < NUM_RX_BUFF; ++i) {
-   struct sk_buff *skb = alloc_skb(rx_skb_size, GFP_ATOMIC);
+   struct sk_buff *skb;
+
+   skb = netdev_alloc_skb_ip_align(dev->ndev, rx_skb_size);
if (!skb) {
ret = -ENOMEM;
goto oom;
@@ -1080,10 +1082,10 @@ static int emac_resize_rx_ring(struct emac_instance 
*dev, int new_mtu)
BUG_ON(!dev->rx_skb[i]);
dev_kfree_skb(dev->rx_skb[i]);
 
-   skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
dev->rx_desc[i].data_ptr =
-   dma_map_single(&dev->ofdev->dev, skb->data - 2, 
rx_sync_size,
-  DMA_FROM_DEVICE) + 2;
+   dma_map_single(&dev->ofdev->dev, skb->data - NET_IP_ALIGN,
+  rx_sync_size, DMA_FROM_DEVICE)
+  + NET_IP_ALIGN;
dev->rx_skb[i] = skb;
}
  skip:
@@ -1174,20 +1176,18 @@ static void emac_clean_rx_ring(struct emac_instance 
*dev)
}
 }
 
-static inline int emac_alloc_rx_skb(struct emac_instance *dev, int slot,
-   gfp_t flags)
+static inline int
+__emac_prepare_rx_skb(struct sk_buff *skb, struct emac_instance *dev, int slot)
 {
-   struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags);
if (unlikely(!skb))
return -ENOMEM;
 
dev->rx_skb[slot] = skb;
dev->rx_desc[slot].data_len = 0;
 
-   skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
dev->rx_desc[slot].data_ptr =
-   dma_map_single(&dev->ofdev->dev, skb->data - 2, dev->rx_sync_size,
-  DMA_FROM_DEVICE) + 2;
+   dma_map_single(&dev->ofdev->dev, skb->data - NET_IP_ALIGN,
+  dev->rx_sync_size, DMA_FROM_DEVICE) + NET_IP_ALIGN;
wmb();
dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
(slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
@@ -1195,6 +1195,27 @@ static inline int emac_alloc_rx_skb(struct emac_instance 
*dev, int slot,
return 0;
 }
 
+static inline int
+emac_alloc_rx_skb(struct emac_instance *dev, int slot)
+{
+   struct sk_buff *skb;
+
+   skb = __netdev_alloc_skb_ip_align(dev->ndev, dev->rx_skb_size,
+ GFP_KERNEL);
+
+   return __emac_prepare_rx_skb(skb, dev, slot);
+}
+
+static inline int
+emac_alloc_rx_skb_napi(struct emac_instance *dev, int slot)
+{
+   struct sk_buff *skb;
+
+   skb = napi_alloc_skb(&dev->mal->napi, dev->rx_skb_size);
+
+   return __emac_prepare_rx_skb(skb, dev, slot);
+}
+
 static void emac_print_link_status(struct emac_instance *dev)
 {
if (netif_carrier_ok(dev->ndev))
@@ -1225,7 +1246,7 @@ static int emac_open(struct net_device *ndev)
 
/* Allocate RX ring */
for (i = 0; i < NUM_RX_BUFF; ++i)
-   if (emac_alloc_rx_skb(dev, i, GFP_KERNEL)) {
+   if (emac_alloc_rx_skb(dev, i)) {
printk(KERN_ERR "%s: failed to allocate RX ring\n",
   ndev->nam

[PATCH v1] net: dsa: qca8k: implement DT-based ports <-> phy translation

2019-02-04 Thread Christian Lamparter
The QCA8337 enumerates 5 PHYs on the MDC/MDIO access: PHY0-PHY4.
Based on the System Block Diagram in Section 1.2 of the
QCA8337's datasheet. These PHYs are internally connected
to MACs of PORT 1 - PORT 5. However, neither qca8k's slave
mdio access functions qca8k_phy_read()/qca8k_phy_write()
nor the dsa framework is set up for that.

This version of the patch uses the existing phy-handle
properties of each specified DSA Port in the DT to map
each PORT/MAC to its exposed PHY on the MDIO bus. This
is supported by the current binding document qca8k.txt
as well.

Signed-off-by: Christian Lamparter 
---
 drivers/net/dsa/qca8k.c | 35 +--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index a4b6cda38016..6558b7ed855d 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -612,20 +613,50 @@ qca8k_adjust_link(struct dsa_switch *ds, int port, struct 
phy_device *phy)
qca8k_port_set_status(priv, port, 1);
 }
 
+static int
+qca8k_to_real_phy(struct dsa_switch *ds, int phy)
+{
+   struct device_node *phy_dn, *port_dn;
+   int id;
+
+   if (phy >= ds->num_ports)
+   return -EINVAL;
+
+   port_dn = ds->ports[phy].dn;
+   if (!port_dn)
+   return -EINVAL;
+
+   phy_dn = of_parse_phandle(port_dn, "phy-handle", 0);
+   if (!phy_dn)
+   return phy;
+
+   id = of_mdio_parse_addr(ds->dev, phy_dn);
+   of_node_put(phy_dn);
+   return id;
+}
+
 static int
 qca8k_phy_read(struct dsa_switch *ds, int phy, int regnum)
 {
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+   int realphy = qca8k_to_real_phy(ds, phy);
+
+   if (realphy < 0)
+   return realphy;
 
-   return mdiobus_read(priv->bus, phy, regnum);
+   return mdiobus_read(priv->bus, realphy, regnum);
 }
 
 static int
 qca8k_phy_write(struct dsa_switch *ds, int phy, int regnum, u16 val)
 {
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
+   int realphy = qca8k_to_real_phy(ds, phy);
+
+   if (realphy < 0)
+   return realphy;
 
-   return mdiobus_write(priv->bus, phy, regnum, val);
+   return mdiobus_write(priv->bus, realphy, regnum, val);
 }
 
 static void
-- 
2.20.1



[PATCH v1] net: emac: remove IBM_EMAC_RX_SKB_HEADROOM

2019-01-14 Thread Christian Lamparter
The EMAC driver had a custom IBM_EMAC_RX_SKB_HEADROOM
Kconfig option that reserved additional skb headroom for RX.
This patch removes the option and migrates the code
to use napi_alloc_skb() and netdev_alloc_skb_ip_align()
in its place.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/Kconfig | 12 --
 drivers/net/ethernet/ibm/emac/core.c  | 57 +++
 drivers/net/ethernet/ibm/emac/core.h  | 10 ++---
 3 files changed, 43 insertions(+), 36 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/Kconfig 
b/drivers/net/ethernet/ibm/emac/Kconfig
index 90d49191beb3..eacf7e141fdc 100644
--- a/drivers/net/ethernet/ibm/emac/Kconfig
+++ b/drivers/net/ethernet/ibm/emac/Kconfig
@@ -28,18 +28,6 @@ config IBM_EMAC_RX_COPY_THRESHOLD
depends on IBM_EMAC
default "256"
 
-config IBM_EMAC_RX_SKB_HEADROOM
-   int "Additional RX skb headroom (bytes)"
-   depends on IBM_EMAC
-   default "0"
-   help
- Additional receive skb headroom. Note, that driver
- will always reserve at least 2 bytes to make IP header
- aligned, so usually there is no need to add any additional
- headroom.
-
- If unsure, set to 0.
-
 config IBM_EMAC_DEBUG
bool "Debugging"
depends on IBM_EMAC
diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 209255495bc9..a2ee699ad667 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -1071,7 +1071,9 @@ static int emac_resize_rx_ring(struct emac_instance *dev, 
int new_mtu)
 
/* Second pass, allocate new skbs */
for (i = 0; i < NUM_RX_BUFF; ++i) {
-   struct sk_buff *skb = alloc_skb(rx_skb_size, GFP_ATOMIC);
+   struct sk_buff *skb;
+
+   skb = netdev_alloc_skb_ip_align(dev->ndev, rx_skb_size);
if (!skb) {
ret = -ENOMEM;
goto oom;
@@ -1080,7 +1082,6 @@ static int emac_resize_rx_ring(struct emac_instance *dev, 
int new_mtu)
BUG_ON(!dev->rx_skb[i]);
dev_kfree_skb(dev->rx_skb[i]);
 
-   skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
dev->rx_desc[i].data_ptr =
dma_map_single(&dev->ofdev->dev, skb->data - 2, 
rx_sync_size,
   DMA_FROM_DEVICE) + 2;
@@ -1174,20 +1175,18 @@ static void emac_clean_rx_ring(struct emac_instance 
*dev)
}
 }
 
-static inline int emac_alloc_rx_skb(struct emac_instance *dev, int slot,
-   gfp_t flags)
+static inline int
+__emac_prepare_rx_skb(struct sk_buff *skb, struct emac_instance *dev, int slot)
 {
-   struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags);
if (unlikely(!skb))
return -ENOMEM;
 
dev->rx_skb[slot] = skb;
dev->rx_desc[slot].data_len = 0;
 
-   skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
dev->rx_desc[slot].data_ptr =
-   dma_map_single(&dev->ofdev->dev, skb->data - 2, dev->rx_sync_size,
-  DMA_FROM_DEVICE) + 2;
+   dma_map_single(&dev->ofdev->dev, skb->data - NET_IP_ALIGN,
+  dev->rx_sync_size, DMA_FROM_DEVICE) + NET_IP_ALIGN;
wmb();
dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
(slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
@@ -1195,6 +1194,27 @@ static inline int emac_alloc_rx_skb(struct emac_instance 
*dev, int slot,
return 0;
 }
 
+static inline int
+emac_alloc_rx_skb(struct emac_instance *dev, int slot)
+{
+   struct sk_buff *skb;
+
+   skb = __netdev_alloc_skb_ip_align(dev->ndev, dev->rx_skb_size,
+ GFP_KERNEL);
+
+   return __emac_prepare_rx_skb(skb, dev, slot);
+}
+
+static inline int
+emac_alloc_rx_skb_napi(struct emac_instance *dev, int slot)
+{
+   struct sk_buff *skb;
+
+   skb = napi_alloc_skb(&dev->mal->napi, dev->rx_skb_size);
+
+   return __emac_prepare_rx_skb(skb, dev, slot);
+}
+
 static void emac_print_link_status(struct emac_instance *dev)
 {
if (netif_carrier_ok(dev->ndev))
@@ -1225,7 +1245,7 @@ static int emac_open(struct net_device *ndev)
 
/* Allocate RX ring */
for (i = 0; i < NUM_RX_BUFF; ++i)
-   if (emac_alloc_rx_skb(dev, i, GFP_KERNEL)) {
+   if (emac_alloc_rx_skb(dev, i)) {
printk(KERN_ERR "%s: failed to allocate RX ring\n",
   ndev->name);
goto oom;
@@ -1660,8 +1680,9 @@ static inline void emac_recycle_rx_skb(struct 
emac_instance *dev, int slot,
DBG2(dev, "recycle %d %d" NL, slot, len);
 
if (len)
-   dma_map_single(&dev->ofde

[PATCH v4 1/3] net: emac: implement 802.1Q VLAN TX tagging support

2018-11-06 Thread Christian Lamparter
As per' APM82181 Embedded Processor User Manual 26.1 EMAC Features:
VLAN:
 - Support for VLAN tag ID in compliance with IEEE 802.3ac.
 - VLAN tag insertion or replacement for transmit packets

This patch completes the missing code for the VLAN tx tagging
support, as the the EMAC_MR1_VLE was already enabled.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/core.c | 32 
 drivers/net/ethernet/ibm/emac/core.h |  6 +-
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 760b2ad8e295..be560f9031f4 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -674,7 +675,7 @@ static int emac_configure(struct emac_instance *dev)
 ndev->dev_addr[5]);
 
/* VLAN Tag Protocol ID */
-   out_be32(&p->vtpid, 0x8100);
+   out_be32(&p->vtpid, ETH_P_8021Q);
 
/* Receive mode register */
r = emac_iff2rmr(ndev);
@@ -1435,6 +1436,22 @@ static inline netdev_tx_t emac_xmit_finish(struct 
emac_instance *dev, int len)
return NETDEV_TX_OK;
 }
 
+static inline u16 emac_tx_vlan(struct emac_instance *dev, struct sk_buff *skb)
+{
+   /* Handle VLAN TPID and TCI insert if this is a VLAN skb */
+   if (emac_has_feature(dev, EMAC_FTR_HAS_VLAN_CTAG_TX) &&
+   skb_vlan_tag_present(skb)) {
+   struct emac_regs __iomem *p = dev->emacp;
+
+   /* update the VLAN TCI */
+   out_be32(&p->vtci, (u32)skb_vlan_tag_get(skb));
+
+   /* Insert VLAN tag */
+   return EMAC_TX_CTRL_IVT;
+   }
+   return 0;
+}
+
 /* Tx lock BH */
 static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device 
*ndev)
 {
@@ -1443,7 +1460,7 @@ static netdev_tx_t emac_start_xmit(struct sk_buff *skb, 
struct net_device *ndev)
int slot;
 
u16 ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
-   MAL_TX_CTRL_LAST | emac_tx_csum(dev, skb);
+   MAL_TX_CTRL_LAST | emac_tx_csum(dev, skb) | emac_tx_vlan(dev, skb);
 
slot = dev->tx_slot++;
if (dev->tx_slot == NUM_TX_BUFF) {
@@ -1518,7 +1535,7 @@ emac_start_xmit_sg(struct sk_buff *skb, struct net_device 
*ndev)
goto stop_queue;
 
ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
-   emac_tx_csum(dev, skb);
+   emac_tx_csum(dev, skb) | emac_tx_vlan(dev, skb);
slot = dev->tx_slot;
 
/* skb data */
@@ -2891,7 +2908,8 @@ static int emac_init_config(struct emac_instance *dev)
if (of_device_is_compatible(np, "ibm,emac-apm821xx")) {
dev->features |= (EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE |
  EMAC_FTR_APM821XX_NO_HALF_DUPLEX |
- EMAC_FTR_460EX_PHY_CLK_FIX);
+ EMAC_FTR_460EX_PHY_CLK_FIX |
+ EMAC_FTR_HAS_VLAN_CTAG_TX);
}
} else if (of_device_is_compatible(np, "ibm,emac4")) {
dev->features |= EMAC_FTR_EMAC4;
@@ -3148,6 +3166,12 @@ static int emac_probe(struct platform_device *ofdev)
 
if (dev->tah_dev) {
ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG;
+
+   if (emac_has_feature(dev, EMAC_FTR_HAS_VLAN_CTAG_TX)) {
+   ndev->vlan_features |= ndev->hw_features;
+   ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX;
+   }
+
ndev->features |= ndev->hw_features | NETIF_F_RXCSUM;
}
ndev->watchdog_timeo = 5 * HZ;
diff --git a/drivers/net/ethernet/ibm/emac/core.h 
b/drivers/net/ethernet/ibm/emac/core.h
index 84caa4a3fc52..8d84d439168c 100644
--- a/drivers/net/ethernet/ibm/emac/core.h
+++ b/drivers/net/ethernet/ibm/emac/core.h
@@ -334,6 +334,8 @@ struct emac_instance {
  * APM821xx does not support Half Duplex mode
  */
 #define EMAC_FTR_APM821XX_NO_HALF_DUPLEX   0x1000
+/* EMAC can insert 802.1Q tag */
+#define EMAC_FTR_HAS_VLAN_CTAG_TX  0x2000
 
 /* Right now, we don't quite handle the always/possible masks on the
  * most optimal way as we don't have a way to say something like
@@ -363,7 +365,9 @@ enum {
EMAC_FTR_460EX_PHY_CLK_FIX |
EMAC_FTR_440EP_PHY_CLK_FIX |
EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE |
-   EMAC_FTR_APM821XX_NO_HALF_DUPLEX,
+   EMAC_FTR_APM821XX_NO_HALF_DUPLEX |
+   EMAC_FTR_HAS_VLAN_CTAG_TX |
+   0,
 };
 
 static inline int emac_has_feature(struct emac_instance *dev,
-- 
2.19.1



[PATCH v4 2/3] net: emac: implement TCP segmentation offload (TSO)

2018-11-06 Thread Christian Lamparter
This patch enables TSO(v4) hw feature for emac driver.
As atleast the APM82181's TCP/IP acceleration hardware
controller (TAH) provides TCP segmentation support in
the transmit path.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/core.c | 112 ++-
 drivers/net/ethernet/ibm/emac/core.h |   7 ++
 drivers/net/ethernet/ibm/emac/emac.h |   7 ++
 drivers/net/ethernet/ibm/emac/tah.c  |  22 +-
 drivers/net/ethernet/ibm/emac/tah.h  |   2 +
 5 files changed, 148 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index be560f9031f4..80aafd7552aa 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -38,6 +38,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -1118,6 +1121,32 @@ static int emac_resize_rx_ring(struct emac_instance 
*dev, int new_mtu)
return ret;
 }
 
+/* Restriction applied for the segmentation size
+ * to use HW segmentation offload feature. the size
+ * of the segment must not be less than 168 bytes for
+ * DIX formatted segments, or 176 bytes for
+ * IEEE formatted segments. However based on actual
+ * tests any MTU less than 416 causes excessive retries
+ * due to TX FIFO underruns.
+ */
+const u32 tah_ss[TAH_NO_SSR] = { 1500, 1344, 1152, 960, 768, 416 };
+
+/* look-up matching segment size for the given mtu */
+static void emac_find_tso_ss_for_mtu(struct emac_instance *dev)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(tah_ss); i++) {
+   if (tah_ss[i] <= dev->ndev->mtu)
+   break;
+   }
+   /* if no matching segment size is found, set the tso_ss_mtu_start
+* variable anyway. This will cause the emac_tx_tso to skip straight
+* to the software fallback.
+*/
+   dev->tso_ss_mtu_start = i;
+}
+
 /* Process ctx, rtnl_lock semaphore */
 static int emac_change_mtu(struct net_device *ndev, int new_mtu)
 {
@@ -1134,6 +1163,7 @@ static int emac_change_mtu(struct net_device *ndev, int 
new_mtu)
 
if (!ret) {
ndev->mtu = new_mtu;
+   emac_find_tso_ss_for_mtu(dev);
dev->rx_skb_size = emac_rx_skb_size(new_mtu);
dev->rx_sync_size = emac_rx_sync_size(new_mtu);
}
@@ -1410,6 +1440,33 @@ static inline u16 emac_tx_csum(struct emac_instance *dev,
return 0;
 }
 
+static int emac_tx_tso(struct emac_instance *dev, struct sk_buff *skb,
+  u16 *ctrl)
+{
+   if (emac_has_feature(dev, EMAC_FTR_TAH_HAS_TSO) && skb_is_gso(skb) &&
+   !!(skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) {
+   u32 seg_size = 0, i;
+
+   /* Get the MTU */
+   seg_size = skb_shinfo(skb)->gso_size + tcp_hdrlen(skb) +
+  skb_network_header_len(skb);
+
+   for (i = dev->tso_ss_mtu_start; i < ARRAY_SIZE(tah_ss); i++) {
+   if (tah_ss[i] > seg_size)
+   continue;
+
+   *ctrl |= EMAC_TX_CTRL_TAH_SSR(i);
+   return 0;
+   }
+
+   /* none found fall back to software */
+   return -EINVAL;
+   }
+
+   *ctrl |= emac_tx_csum(dev, skb);
+   return 0;
+}
+
 static inline netdev_tx_t emac_xmit_finish(struct emac_instance *dev, int len)
 {
struct emac_regs __iomem *p = dev->emacp;
@@ -1452,6 +1509,46 @@ static inline u16 emac_tx_vlan(struct emac_instance 
*dev, struct sk_buff *skb)
return 0;
 }
 
+static netdev_tx_t
+emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev);
+
+static int
+emac_sw_tso(struct sk_buff *skb, struct net_device *ndev)
+{
+   struct emac_instance *dev = netdev_priv(ndev);
+   struct sk_buff *segs, *curr;
+   unsigned int i, frag_slots;
+
+   /* make sure to not overflow the tx ring */
+   frag_slots = dev->tx_cnt;
+   for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+   struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
+
+   frag_slots += mal_tx_chunks(skb_frag_size(frag));
+
+   if (frag_slots >= NUM_TX_BUFF)
+   return -ENOSPC;
+   };
+
+   segs = skb_gso_segment(skb, ndev->features &
+   ~(NETIF_F_TSO | NETIF_F_TSO6));
+   if (IS_ERR_OR_NULL(segs)) {
+   ++dev->estats.tx_dropped;
+   dev_kfree_skb_any(skb);
+   } else {
+   while (segs) {
+   curr = segs;
+   segs = curr->next;
+   curr->next = NULL;
+
+   emac_start_xmit_sg(curr, ndev);
+   }
+   dev_consume_skb_any(skb);
+   }
+
+   retur

[PATCH v4 3/3] net: emac: remove IBM_EMAC_RX_SKB_HEADROOM

2018-11-06 Thread Christian Lamparter
The EMAC driver had a custom IBM_EMAC_RX_SKB_HEADROOM
Kconfig option that reserved additional skb headroom for RX.
This patch removes the option and migrates the code
to use napi_alloc_skb() and netdev_alloc_skb_ip_align()
in its place.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/Kconfig | 12 --
 drivers/net/ethernet/ibm/emac/core.c  | 57 +++
 drivers/net/ethernet/ibm/emac/core.h  | 10 ++---
 3 files changed, 43 insertions(+), 36 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/Kconfig 
b/drivers/net/ethernet/ibm/emac/Kconfig
index 90d49191beb3..eacf7e141fdc 100644
--- a/drivers/net/ethernet/ibm/emac/Kconfig
+++ b/drivers/net/ethernet/ibm/emac/Kconfig
@@ -28,18 +28,6 @@ config IBM_EMAC_RX_COPY_THRESHOLD
depends on IBM_EMAC
default "256"
 
-config IBM_EMAC_RX_SKB_HEADROOM
-   int "Additional RX skb headroom (bytes)"
-   depends on IBM_EMAC
-   default "0"
-   help
- Additional receive skb headroom. Note, that driver
- will always reserve at least 2 bytes to make IP header
- aligned, so usually there is no need to add any additional
- headroom.
-
- If unsure, set to 0.
-
 config IBM_EMAC_DEBUG
bool "Debugging"
depends on IBM_EMAC
diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 80aafd7552aa..266b6614125b 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -1075,7 +1075,9 @@ static int emac_resize_rx_ring(struct emac_instance *dev, 
int new_mtu)
 
/* Second pass, allocate new skbs */
for (i = 0; i < NUM_RX_BUFF; ++i) {
-   struct sk_buff *skb = alloc_skb(rx_skb_size, GFP_ATOMIC);
+   struct sk_buff *skb;
+
+   skb = netdev_alloc_skb_ip_align(dev->ndev, rx_skb_size);
if (!skb) {
ret = -ENOMEM;
goto oom;
@@ -1084,7 +1086,6 @@ static int emac_resize_rx_ring(struct emac_instance *dev, 
int new_mtu)
BUG_ON(!dev->rx_skb[i]);
dev_kfree_skb(dev->rx_skb[i]);
 
-   skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
dev->rx_desc[i].data_ptr =
dma_map_single(&dev->ofdev->dev, skb->data - 2, 
rx_sync_size,
   DMA_FROM_DEVICE) + 2;
@@ -1205,20 +1206,18 @@ static void emac_clean_rx_ring(struct emac_instance 
*dev)
}
 }
 
-static inline int emac_alloc_rx_skb(struct emac_instance *dev, int slot,
-   gfp_t flags)
+static inline int
+__emac_prepare_rx_skb(struct sk_buff *skb, struct emac_instance *dev, int slot)
 {
-   struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags);
if (unlikely(!skb))
return -ENOMEM;
 
dev->rx_skb[slot] = skb;
dev->rx_desc[slot].data_len = 0;
 
-   skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
dev->rx_desc[slot].data_ptr =
-   dma_map_single(&dev->ofdev->dev, skb->data - 2, dev->rx_sync_size,
-  DMA_FROM_DEVICE) + 2;
+   dma_map_single(&dev->ofdev->dev, skb->data - NET_IP_ALIGN,
+  dev->rx_sync_size, DMA_FROM_DEVICE) + NET_IP_ALIGN;
wmb();
dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
(slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
@@ -1226,6 +1225,27 @@ static inline int emac_alloc_rx_skb(struct emac_instance 
*dev, int slot,
return 0;
 }
 
+static inline int
+emac_alloc_rx_skb(struct emac_instance *dev, int slot)
+{
+   struct sk_buff *skb;
+
+   skb = __netdev_alloc_skb_ip_align(dev->ndev, dev->rx_skb_size,
+ GFP_KERNEL);
+
+   return __emac_prepare_rx_skb(skb, dev, slot);
+}
+
+static inline int
+emac_alloc_rx_skb_napi(struct emac_instance *dev, int slot)
+{
+   struct sk_buff *skb;
+
+   skb = napi_alloc_skb(&dev->mal->napi, dev->rx_skb_size);
+
+   return __emac_prepare_rx_skb(skb, dev, slot);
+}
+
 static void emac_print_link_status(struct emac_instance *dev)
 {
if (netif_carrier_ok(dev->ndev))
@@ -1256,7 +1276,7 @@ static int emac_open(struct net_device *ndev)
 
/* Allocate RX ring */
for (i = 0; i < NUM_RX_BUFF; ++i)
-   if (emac_alloc_rx_skb(dev, i, GFP_KERNEL)) {
+   if (emac_alloc_rx_skb(dev, i)) {
printk(KERN_ERR "%s: failed to allocate RX ring\n",
   ndev->name);
goto oom;
@@ -1779,8 +1799,9 @@ static inline void emac_recycle_rx_skb(struct 
emac_instance *dev, int slot,
DBG2(dev, "recycle %d %d" NL, slot, len);
 
if (len)
-   dma_map_single(&dev->ofde

[PATCH v3 3/4] net: emac: remove IBM_EMAC_RX_SKB_HEADROOM

2018-10-23 Thread Christian Lamparter
The EMAC driver had a custom IBM_EMAC_RX_SKB_HEADROOM
Kconfig option that reserved additional skb headroom for RX.
This patch removes the option and migrates the code
to use napi_alloc_skb() and netdev_alloc_skb_ip_align()
in its place.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/Kconfig | 12 --
 drivers/net/ethernet/ibm/emac/core.c  | 57 +++
 drivers/net/ethernet/ibm/emac/core.h  | 10 ++---
 3 files changed, 43 insertions(+), 36 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/Kconfig 
b/drivers/net/ethernet/ibm/emac/Kconfig
index 90d49191beb3..eacf7e141fdc 100644
--- a/drivers/net/ethernet/ibm/emac/Kconfig
+++ b/drivers/net/ethernet/ibm/emac/Kconfig
@@ -28,18 +28,6 @@ config IBM_EMAC_RX_COPY_THRESHOLD
depends on IBM_EMAC
default "256"
 
-config IBM_EMAC_RX_SKB_HEADROOM
-   int "Additional RX skb headroom (bytes)"
-   depends on IBM_EMAC
-   default "0"
-   help
- Additional receive skb headroom. Note, that driver
- will always reserve at least 2 bytes to make IP header
- aligned, so usually there is no need to add any additional
- headroom.
-
- If unsure, set to 0.
-
 config IBM_EMAC_DEBUG
bool "Debugging"
depends on IBM_EMAC
diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 80aafd7552aa..266b6614125b 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -1075,7 +1075,9 @@ static int emac_resize_rx_ring(struct emac_instance *dev, 
int new_mtu)
 
/* Second pass, allocate new skbs */
for (i = 0; i < NUM_RX_BUFF; ++i) {
-   struct sk_buff *skb = alloc_skb(rx_skb_size, GFP_ATOMIC);
+   struct sk_buff *skb;
+
+   skb = netdev_alloc_skb_ip_align(dev->ndev, rx_skb_size);
if (!skb) {
ret = -ENOMEM;
goto oom;
@@ -1084,7 +1086,6 @@ static int emac_resize_rx_ring(struct emac_instance *dev, 
int new_mtu)
BUG_ON(!dev->rx_skb[i]);
dev_kfree_skb(dev->rx_skb[i]);
 
-   skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
dev->rx_desc[i].data_ptr =
dma_map_single(&dev->ofdev->dev, skb->data - 2, 
rx_sync_size,
   DMA_FROM_DEVICE) + 2;
@@ -1205,20 +1206,18 @@ static void emac_clean_rx_ring(struct emac_instance 
*dev)
}
 }
 
-static inline int emac_alloc_rx_skb(struct emac_instance *dev, int slot,
-   gfp_t flags)
+static inline int
+__emac_prepare_rx_skb(struct sk_buff *skb, struct emac_instance *dev, int slot)
 {
-   struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags);
if (unlikely(!skb))
return -ENOMEM;
 
dev->rx_skb[slot] = skb;
dev->rx_desc[slot].data_len = 0;
 
-   skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
dev->rx_desc[slot].data_ptr =
-   dma_map_single(&dev->ofdev->dev, skb->data - 2, dev->rx_sync_size,
-  DMA_FROM_DEVICE) + 2;
+   dma_map_single(&dev->ofdev->dev, skb->data - NET_IP_ALIGN,
+  dev->rx_sync_size, DMA_FROM_DEVICE) + NET_IP_ALIGN;
wmb();
dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
(slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
@@ -1226,6 +1225,27 @@ static inline int emac_alloc_rx_skb(struct emac_instance 
*dev, int slot,
return 0;
 }
 
+static inline int
+emac_alloc_rx_skb(struct emac_instance *dev, int slot)
+{
+   struct sk_buff *skb;
+
+   skb = __netdev_alloc_skb_ip_align(dev->ndev, dev->rx_skb_size,
+ GFP_KERNEL);
+
+   return __emac_prepare_rx_skb(skb, dev, slot);
+}
+
+static inline int
+emac_alloc_rx_skb_napi(struct emac_instance *dev, int slot)
+{
+   struct sk_buff *skb;
+
+   skb = napi_alloc_skb(&dev->mal->napi, dev->rx_skb_size);
+
+   return __emac_prepare_rx_skb(skb, dev, slot);
+}
+
 static void emac_print_link_status(struct emac_instance *dev)
 {
if (netif_carrier_ok(dev->ndev))
@@ -1256,7 +1276,7 @@ static int emac_open(struct net_device *ndev)
 
/* Allocate RX ring */
for (i = 0; i < NUM_RX_BUFF; ++i)
-   if (emac_alloc_rx_skb(dev, i, GFP_KERNEL)) {
+   if (emac_alloc_rx_skb(dev, i)) {
printk(KERN_ERR "%s: failed to allocate RX ring\n",
   ndev->name);
goto oom;
@@ -1779,8 +1799,9 @@ static inline void emac_recycle_rx_skb(struct 
emac_instance *dev, int slot,
DBG2(dev, "recycle %d %d" NL, slot, len);
 
if (len)
-   dma_map_single(&dev->ofde

[PATCH v3 2/4] net: emac: implement TCP segmentation offload (TSO)

2018-10-23 Thread Christian Lamparter
This patch enables TSO(v4) hw feature for emac driver.
As atleast the APM82181's TCP/IP acceleration hardware
controller (TAH) provides TCP segmentation support in
the transmit path.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/core.c | 112 ++-
 drivers/net/ethernet/ibm/emac/core.h |   7 ++
 drivers/net/ethernet/ibm/emac/emac.h |   7 ++
 drivers/net/ethernet/ibm/emac/tah.c  |  22 +-
 drivers/net/ethernet/ibm/emac/tah.h  |   2 +
 5 files changed, 148 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index be560f9031f4..80aafd7552aa 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -38,6 +38,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -1118,6 +1121,32 @@ static int emac_resize_rx_ring(struct emac_instance 
*dev, int new_mtu)
return ret;
 }
 
+/* Restriction applied for the segmentation size
+ * to use HW segmentation offload feature. the size
+ * of the segment must not be less than 168 bytes for
+ * DIX formatted segments, or 176 bytes for
+ * IEEE formatted segments. However based on actual
+ * tests any MTU less than 416 causes excessive retries
+ * due to TX FIFO underruns.
+ */
+const u32 tah_ss[TAH_NO_SSR] = { 1500, 1344, 1152, 960, 768, 416 };
+
+/* look-up matching segment size for the given mtu */
+static void emac_find_tso_ss_for_mtu(struct emac_instance *dev)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(tah_ss); i++) {
+   if (tah_ss[i] <= dev->ndev->mtu)
+   break;
+   }
+   /* if no matching segment size is found, set the tso_ss_mtu_start
+* variable anyway. This will cause the emac_tx_tso to skip straight
+* to the software fallback.
+*/
+   dev->tso_ss_mtu_start = i;
+}
+
 /* Process ctx, rtnl_lock semaphore */
 static int emac_change_mtu(struct net_device *ndev, int new_mtu)
 {
@@ -1134,6 +1163,7 @@ static int emac_change_mtu(struct net_device *ndev, int 
new_mtu)
 
if (!ret) {
ndev->mtu = new_mtu;
+   emac_find_tso_ss_for_mtu(dev);
dev->rx_skb_size = emac_rx_skb_size(new_mtu);
dev->rx_sync_size = emac_rx_sync_size(new_mtu);
}
@@ -1410,6 +1440,33 @@ static inline u16 emac_tx_csum(struct emac_instance *dev,
return 0;
 }
 
+static int emac_tx_tso(struct emac_instance *dev, struct sk_buff *skb,
+  u16 *ctrl)
+{
+   if (emac_has_feature(dev, EMAC_FTR_TAH_HAS_TSO) && skb_is_gso(skb) &&
+   !!(skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) {
+   u32 seg_size = 0, i;
+
+   /* Get the MTU */
+   seg_size = skb_shinfo(skb)->gso_size + tcp_hdrlen(skb) +
+  skb_network_header_len(skb);
+
+   for (i = dev->tso_ss_mtu_start; i < ARRAY_SIZE(tah_ss); i++) {
+   if (tah_ss[i] > seg_size)
+   continue;
+
+   *ctrl |= EMAC_TX_CTRL_TAH_SSR(i);
+   return 0;
+   }
+
+   /* none found fall back to software */
+   return -EINVAL;
+   }
+
+   *ctrl |= emac_tx_csum(dev, skb);
+   return 0;
+}
+
 static inline netdev_tx_t emac_xmit_finish(struct emac_instance *dev, int len)
 {
struct emac_regs __iomem *p = dev->emacp;
@@ -1452,6 +1509,46 @@ static inline u16 emac_tx_vlan(struct emac_instance 
*dev, struct sk_buff *skb)
return 0;
 }
 
+static netdev_tx_t
+emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev);
+
+static int
+emac_sw_tso(struct sk_buff *skb, struct net_device *ndev)
+{
+   struct emac_instance *dev = netdev_priv(ndev);
+   struct sk_buff *segs, *curr;
+   unsigned int i, frag_slots;
+
+   /* make sure to not overflow the tx ring */
+   frag_slots = dev->tx_cnt;
+   for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+   struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
+
+   frag_slots += mal_tx_chunks(skb_frag_size(frag));
+
+   if (frag_slots >= NUM_TX_BUFF)
+   return -ENOSPC;
+   };
+
+   segs = skb_gso_segment(skb, ndev->features &
+   ~(NETIF_F_TSO | NETIF_F_TSO6));
+   if (IS_ERR_OR_NULL(segs)) {
+   ++dev->estats.tx_dropped;
+   dev_kfree_skb_any(skb);
+   } else {
+   while (segs) {
+   curr = segs;
+   segs = curr->next;
+   curr->next = NULL;
+
+   emac_start_xmit_sg(curr, ndev);
+   }
+   dev_consume_skb_any(skb);
+   }
+
+   retur

[PATCH v3 4/4] net: emac: add deprecation notice to emac custom phy users

2018-10-23 Thread Christian Lamparter
This patch starts the deprecation process of emac's small library of
supported phys by adding a message to inform all remaining users to
start looking into converting their platform's device-tree to PHYLIB.

EMAC's phy.c support is limited to mostly single ethernet transceivers:
CIS8201, BCM5248, ET1011C, Marvell 88E and 88E1112, AR8035.

And Linux has dedicated PHYLIB drivers for all but the BCM5248 which
can be supported by the generic phy driver.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/phy.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/ibm/emac/phy.c 
b/drivers/net/ethernet/ibm/emac/phy.c
index aa070c063e48..143b4c688ee9 100644
--- a/drivers/net/ethernet/ibm/emac/phy.c
+++ b/drivers/net/ethernet/ibm/emac/phy.c
@@ -496,6 +496,7 @@ static struct mii_phy_def ar8035_phy_def = {
 };
 
 static struct mii_phy_def *mii_phy_table[] = {
+   /* DEPRECATED: Do not add any new PHY drivers to this list. */
&et1011c_phy_def,
&cis8201_phy_def,
&bcm5248_phy_def,
@@ -512,6 +513,9 @@ int emac_mii_phy_probe(struct mii_phy *phy, int address)
int i;
u32 id;
 
+   pr_info("EMAC's custom phy code has been deprecated.\n"
+   "Please convert your EMAC device to PHYLIB.\n");
+
phy->autoneg = AUTONEG_DISABLE;
phy->advertising = 0;
phy->address = address;
-- 
2.19.1



[PATCH v3 1/4] net: emac: implement 802.1Q VLAN TX tagging support

2018-10-23 Thread Christian Lamparter
As per' APM82181 Embedded Processor User Manual 26.1 EMAC Features:
VLAN:
 - Support for VLAN tag ID in compliance with IEEE 802.3ac.
 - VLAN tag insertion or replacement for transmit packets

This patch completes the missing code for the VLAN tx tagging
support, as the the EMAC_MR1_VLE was already enabled.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/core.c | 32 
 drivers/net/ethernet/ibm/emac/core.h |  6 +-
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 760b2ad8e295..be560f9031f4 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -674,7 +675,7 @@ static int emac_configure(struct emac_instance *dev)
 ndev->dev_addr[5]);
 
/* VLAN Tag Protocol ID */
-   out_be32(&p->vtpid, 0x8100);
+   out_be32(&p->vtpid, ETH_P_8021Q);
 
/* Receive mode register */
r = emac_iff2rmr(ndev);
@@ -1435,6 +1436,22 @@ static inline netdev_tx_t emac_xmit_finish(struct 
emac_instance *dev, int len)
return NETDEV_TX_OK;
 }
 
+static inline u16 emac_tx_vlan(struct emac_instance *dev, struct sk_buff *skb)
+{
+   /* Handle VLAN TPID and TCI insert if this is a VLAN skb */
+   if (emac_has_feature(dev, EMAC_FTR_HAS_VLAN_CTAG_TX) &&
+   skb_vlan_tag_present(skb)) {
+   struct emac_regs __iomem *p = dev->emacp;
+
+   /* update the VLAN TCI */
+   out_be32(&p->vtci, (u32)skb_vlan_tag_get(skb));
+
+   /* Insert VLAN tag */
+   return EMAC_TX_CTRL_IVT;
+   }
+   return 0;
+}
+
 /* Tx lock BH */
 static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device 
*ndev)
 {
@@ -1443,7 +1460,7 @@ static netdev_tx_t emac_start_xmit(struct sk_buff *skb, 
struct net_device *ndev)
int slot;
 
u16 ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
-   MAL_TX_CTRL_LAST | emac_tx_csum(dev, skb);
+   MAL_TX_CTRL_LAST | emac_tx_csum(dev, skb) | emac_tx_vlan(dev, skb);
 
slot = dev->tx_slot++;
if (dev->tx_slot == NUM_TX_BUFF) {
@@ -1518,7 +1535,7 @@ emac_start_xmit_sg(struct sk_buff *skb, struct net_device 
*ndev)
goto stop_queue;
 
ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
-   emac_tx_csum(dev, skb);
+   emac_tx_csum(dev, skb) | emac_tx_vlan(dev, skb);
slot = dev->tx_slot;
 
/* skb data */
@@ -2891,7 +2908,8 @@ static int emac_init_config(struct emac_instance *dev)
if (of_device_is_compatible(np, "ibm,emac-apm821xx")) {
dev->features |= (EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE |
  EMAC_FTR_APM821XX_NO_HALF_DUPLEX |
- EMAC_FTR_460EX_PHY_CLK_FIX);
+ EMAC_FTR_460EX_PHY_CLK_FIX |
+ EMAC_FTR_HAS_VLAN_CTAG_TX);
}
} else if (of_device_is_compatible(np, "ibm,emac4")) {
dev->features |= EMAC_FTR_EMAC4;
@@ -3148,6 +3166,12 @@ static int emac_probe(struct platform_device *ofdev)
 
if (dev->tah_dev) {
ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG;
+
+   if (emac_has_feature(dev, EMAC_FTR_HAS_VLAN_CTAG_TX)) {
+   ndev->vlan_features |= ndev->hw_features;
+   ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX;
+   }
+
ndev->features |= ndev->hw_features | NETIF_F_RXCSUM;
}
ndev->watchdog_timeo = 5 * HZ;
diff --git a/drivers/net/ethernet/ibm/emac/core.h 
b/drivers/net/ethernet/ibm/emac/core.h
index 84caa4a3fc52..8d84d439168c 100644
--- a/drivers/net/ethernet/ibm/emac/core.h
+++ b/drivers/net/ethernet/ibm/emac/core.h
@@ -334,6 +334,8 @@ struct emac_instance {
  * APM821xx does not support Half Duplex mode
  */
 #define EMAC_FTR_APM821XX_NO_HALF_DUPLEX   0x1000
+/* EMAC can insert 802.1Q tag */
+#define EMAC_FTR_HAS_VLAN_CTAG_TX  0x2000
 
 /* Right now, we don't quite handle the always/possible masks on the
  * most optimal way as we don't have a way to say something like
@@ -363,7 +365,9 @@ enum {
EMAC_FTR_460EX_PHY_CLK_FIX |
EMAC_FTR_440EP_PHY_CLK_FIX |
EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE |
-   EMAC_FTR_APM821XX_NO_HALF_DUPLEX,
+   EMAC_FTR_APM821XX_NO_HALF_DUPLEX |
+   EMAC_FTR_HAS_VLAN_CTAG_TX |
+   0,
 };
 
 static inline int emac_has_feature(struct emac_instance *dev,
-- 
2.19.1



[PATCH v2 1/4] net: emac: implement 802.1Q VLAN TX tagging support

2018-10-22 Thread Christian Lamparter
As per' APM82181 Embedded Processor User Manual 26.1 EMAC Features:
VLAN:
 - Support for VLAN tag ID in compliance with IEEE 802.3ac.
 - VLAN tag insertion or replacement for transmit packets

This patch completes the missing code for the VLAN tx tagging
support, as the the EMAC_MR1_VLE was already enabled.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/core.c | 32 
 drivers/net/ethernet/ibm/emac/core.h |  6 +-
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 760b2ad8e295..be560f9031f4 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -674,7 +675,7 @@ static int emac_configure(struct emac_instance *dev)
 ndev->dev_addr[5]);
 
/* VLAN Tag Protocol ID */
-   out_be32(&p->vtpid, 0x8100);
+   out_be32(&p->vtpid, ETH_P_8021Q);
 
/* Receive mode register */
r = emac_iff2rmr(ndev);
@@ -1435,6 +1436,22 @@ static inline netdev_tx_t emac_xmit_finish(struct 
emac_instance *dev, int len)
return NETDEV_TX_OK;
 }
 
+static inline u16 emac_tx_vlan(struct emac_instance *dev, struct sk_buff *skb)
+{
+   /* Handle VLAN TPID and TCI insert if this is a VLAN skb */
+   if (emac_has_feature(dev, EMAC_FTR_HAS_VLAN_CTAG_TX) &&
+   skb_vlan_tag_present(skb)) {
+   struct emac_regs __iomem *p = dev->emacp;
+
+   /* update the VLAN TCI */
+   out_be32(&p->vtci, (u32)skb_vlan_tag_get(skb));
+
+   /* Insert VLAN tag */
+   return EMAC_TX_CTRL_IVT;
+   }
+   return 0;
+}
+
 /* Tx lock BH */
 static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device 
*ndev)
 {
@@ -1443,7 +1460,7 @@ static netdev_tx_t emac_start_xmit(struct sk_buff *skb, 
struct net_device *ndev)
int slot;
 
u16 ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
-   MAL_TX_CTRL_LAST | emac_tx_csum(dev, skb);
+   MAL_TX_CTRL_LAST | emac_tx_csum(dev, skb) | emac_tx_vlan(dev, skb);
 
slot = dev->tx_slot++;
if (dev->tx_slot == NUM_TX_BUFF) {
@@ -1518,7 +1535,7 @@ emac_start_xmit_sg(struct sk_buff *skb, struct net_device 
*ndev)
goto stop_queue;
 
ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
-   emac_tx_csum(dev, skb);
+   emac_tx_csum(dev, skb) | emac_tx_vlan(dev, skb);
slot = dev->tx_slot;
 
/* skb data */
@@ -2891,7 +2908,8 @@ static int emac_init_config(struct emac_instance *dev)
if (of_device_is_compatible(np, "ibm,emac-apm821xx")) {
dev->features |= (EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE |
  EMAC_FTR_APM821XX_NO_HALF_DUPLEX |
- EMAC_FTR_460EX_PHY_CLK_FIX);
+ EMAC_FTR_460EX_PHY_CLK_FIX |
+ EMAC_FTR_HAS_VLAN_CTAG_TX);
}
} else if (of_device_is_compatible(np, "ibm,emac4")) {
dev->features |= EMAC_FTR_EMAC4;
@@ -3148,6 +3166,12 @@ static int emac_probe(struct platform_device *ofdev)
 
if (dev->tah_dev) {
ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG;
+
+   if (emac_has_feature(dev, EMAC_FTR_HAS_VLAN_CTAG_TX)) {
+   ndev->vlan_features |= ndev->hw_features;
+   ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX;
+   }
+
ndev->features |= ndev->hw_features | NETIF_F_RXCSUM;
}
ndev->watchdog_timeo = 5 * HZ;
diff --git a/drivers/net/ethernet/ibm/emac/core.h 
b/drivers/net/ethernet/ibm/emac/core.h
index 84caa4a3fc52..8d84d439168c 100644
--- a/drivers/net/ethernet/ibm/emac/core.h
+++ b/drivers/net/ethernet/ibm/emac/core.h
@@ -334,6 +334,8 @@ struct emac_instance {
  * APM821xx does not support Half Duplex mode
  */
 #define EMAC_FTR_APM821XX_NO_HALF_DUPLEX   0x1000
+/* EMAC can insert 802.1Q tag */
+#define EMAC_FTR_HAS_VLAN_CTAG_TX  0x2000
 
 /* Right now, we don't quite handle the always/possible masks on the
  * most optimal way as we don't have a way to say something like
@@ -363,7 +365,9 @@ enum {
EMAC_FTR_460EX_PHY_CLK_FIX |
EMAC_FTR_440EP_PHY_CLK_FIX |
EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE |
-   EMAC_FTR_APM821XX_NO_HALF_DUPLEX,
+   EMAC_FTR_APM821XX_NO_HALF_DUPLEX |
+   EMAC_FTR_HAS_VLAN_CTAG_TX |
+   0,
 };
 
 static inline int emac_has_feature(struct emac_instance *dev,
-- 
2.19.1



[PATCH v2 4/4] net: emac: add deprecation notice to emac custom phy users

2018-10-22 Thread Christian Lamparter
From: Christian Lamparter 

This patch starts the deprecation process of emac's small library of
supported phys by adding a message to inform all remaining users to
start looking into converting their platform's device-tree to PHYLIB.

EMAC's phy.c support is limited to mostly single ethernet transceivers:
CIS8201, BCM5248, ET1011C, Marvell 88E and 88E1112, AR8035.

And Linux has dedicated PHYLIB drivers for all but the BCM5248 which
can be supported by the generic phy driver.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/phy.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/ibm/emac/phy.c 
b/drivers/net/ethernet/ibm/emac/phy.c
index aa070c063e48..143b4c688ee9 100644
--- a/drivers/net/ethernet/ibm/emac/phy.c
+++ b/drivers/net/ethernet/ibm/emac/phy.c
@@ -496,6 +496,7 @@ static struct mii_phy_def ar8035_phy_def = {
 };
 
 static struct mii_phy_def *mii_phy_table[] = {
+   /* DEPRECATED: Do not add any new PHY drivers to this list. */
&et1011c_phy_def,
&cis8201_phy_def,
&bcm5248_phy_def,
@@ -512,6 +513,9 @@ int emac_mii_phy_probe(struct mii_phy *phy, int address)
int i;
u32 id;
 
+   pr_info("EMAC's custom phy code has been deprecated.\n"
+   "Please convert your EMAC device to PHYLIB.\n");
+
phy->autoneg = AUTONEG_DISABLE;
phy->advertising = 0;
phy->address = address;
-- 
2.19.1



[PATCH v2 2/4] net: emac: implement TCP segmentation offload (TSO)

2018-10-22 Thread Christian Lamparter
This patch enables TSO(v4) hw feature for emac driver.
As atleast the APM82181's TCP/IP acceleration hardware
controller (TAH) provides TCP segmentation support in
the transmit path.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/core.c | 113 ++-
 drivers/net/ethernet/ibm/emac/core.h |   7 ++
 drivers/net/ethernet/ibm/emac/emac.h |   7 ++
 drivers/net/ethernet/ibm/emac/tah.c  |  22 +-
 drivers/net/ethernet/ibm/emac/tah.h  |   2 +
 5 files changed, 148 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index be560f9031f4..b5c4b7d3057d 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -38,6 +38,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -1118,6 +1121,32 @@ static int emac_resize_rx_ring(struct emac_instance 
*dev, int new_mtu)
return ret;
 }
 
+/* Restriction applied for the segmentation size
+ * to use HW segmentation offload feature. the size
+ * of the segment must not be less than 168 bytes for
+ * DIX formatted segments, or 176 bytes for
+ * IEEE formatted segments. However based on actual
+ * tests any MTU less than 416 causes excessive retries
+ * due to TX FIFO underruns.
+ */
+const u32 tah_ss[TAH_NO_SSR] = { 1500, 1344, 1152, 960, 768, 416 };
+
+/* look-up matching segment size for the given mtu */
+static void emac_find_tso_ss_for_mtu(struct emac_instance *dev)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(tah_ss); i++) {
+   if (tah_ss[i] <= dev->ndev->mtu)
+   break;
+   }
+   /* if no matching segment size is found, set the tso_ss_mtu_start
+* variable anyway. This will cause the emac_tx_tso to skip straight
+* to the software fallback.
+*/
+   dev->tso_ss_mtu_start = i;
+}
+
 /* Process ctx, rtnl_lock semaphore */
 static int emac_change_mtu(struct net_device *ndev, int new_mtu)
 {
@@ -1134,6 +1163,7 @@ static int emac_change_mtu(struct net_device *ndev, int 
new_mtu)
 
if (!ret) {
ndev->mtu = new_mtu;
+   emac_find_tso_ss_for_mtu(dev);
dev->rx_skb_size = emac_rx_skb_size(new_mtu);
dev->rx_sync_size = emac_rx_sync_size(new_mtu);
}
@@ -1410,6 +1440,33 @@ static inline u16 emac_tx_csum(struct emac_instance *dev,
return 0;
 }
 
+static int emac_tx_tso(struct emac_instance *dev, struct sk_buff *skb,
+  u16 *ctrl)
+{
+   if (emac_has_feature(dev, EMAC_FTR_TAH_HAS_TSO) && skb_is_gso(skb) &&
+   !!(skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) {
+   u32 seg_size = 0, i;
+
+   /* Get the MTU */
+   seg_size = skb_shinfo(skb)->gso_size + tcp_hdrlen(skb) +
+  skb_network_header_len(skb);
+
+   for (i = dev->tso_ss_mtu_start; i < ARRAY_SIZE(tah_ss); i++) {
+   if (tah_ss[i] > seg_size)
+   continue;
+
+   *ctrl |= EMAC_TX_CTRL_TAH_SSR(i);
+   return 0;
+   }
+
+   /* none found fall back to software */
+   return -EINVAL;
+   }
+
+   *ctrl |= emac_tx_csum(dev, skb);
+   return 0;
+}
+
 static inline netdev_tx_t emac_xmit_finish(struct emac_instance *dev, int len)
 {
struct emac_regs __iomem *p = dev->emacp;
@@ -1452,8 +1509,49 @@ static inline u16 emac_tx_vlan(struct emac_instance 
*dev, struct sk_buff *skb)
return 0;
 }
 
+static netdev_tx_t
+emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev);
+
+static netdev_tx_t
+emac_sw_tso(struct sk_buff *skb, struct net_device *ndev)
+{
+   struct emac_instance *dev = netdev_priv(ndev);
+   struct sk_buff *segs, *curr;
+   unsigned int i, frag_slots;
+
+   /* make sure to not overflow the tx ring */
+   frag_slots = dev->tx_cnt;
+   for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+   struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
+
+   frag_slots += mal_tx_chunks(skb_frag_size(frag));
+
+   if (frag_slots >= NUM_TX_BUFF)
+   return NETDEV_TX_BUSY;
+   };
+
+   segs = skb_gso_segment(skb, ndev->features &
+   ~(NETIF_F_TSO | NETIF_F_TSO6));
+   if (IS_ERR_OR_NULL(segs)) {
+   ++dev->estats.tx_dropped;
+   dev_kfree_skb_any(skb);
+   } else {
+   while (segs) {
+   curr = segs;
+   segs = curr->next;
+   curr->next = NULL;
+
+   emac_start_xmit_sg(curr, ndev);
+   }
+   dev_consume_skb_any(skb);
+   }
+

[PATCH v2 3/4] net: emac: remove IBM_EMAC_RX_SKB_HEADROOM

2018-10-22 Thread Christian Lamparter
The EMAC driver had a custom IBM_EMAC_RX_SKB_HEADROOM
Kconfig option that reserved additional skb headroom for RX.
This patch removes the option and migrates the code
to use napi_alloc_skb() and netdev_alloc_skb_ip_align()
in its place.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/Kconfig | 12 --
 drivers/net/ethernet/ibm/emac/core.c  | 57 +++
 drivers/net/ethernet/ibm/emac/core.h  | 10 ++---
 3 files changed, 43 insertions(+), 36 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/Kconfig 
b/drivers/net/ethernet/ibm/emac/Kconfig
index 90d49191beb3..eacf7e141fdc 100644
--- a/drivers/net/ethernet/ibm/emac/Kconfig
+++ b/drivers/net/ethernet/ibm/emac/Kconfig
@@ -28,18 +28,6 @@ config IBM_EMAC_RX_COPY_THRESHOLD
depends on IBM_EMAC
default "256"
 
-config IBM_EMAC_RX_SKB_HEADROOM
-   int "Additional RX skb headroom (bytes)"
-   depends on IBM_EMAC
-   default "0"
-   help
- Additional receive skb headroom. Note, that driver
- will always reserve at least 2 bytes to make IP header
- aligned, so usually there is no need to add any additional
- headroom.
-
- If unsure, set to 0.
-
 config IBM_EMAC_DEBUG
bool "Debugging"
depends on IBM_EMAC
diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index b5c4b7d3057d..388443e08674 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -1075,7 +1075,9 @@ static int emac_resize_rx_ring(struct emac_instance *dev, 
int new_mtu)
 
/* Second pass, allocate new skbs */
for (i = 0; i < NUM_RX_BUFF; ++i) {
-   struct sk_buff *skb = alloc_skb(rx_skb_size, GFP_ATOMIC);
+   struct sk_buff *skb;
+
+   skb = netdev_alloc_skb_ip_align(dev->ndev, rx_skb_size);
if (!skb) {
ret = -ENOMEM;
goto oom;
@@ -1084,7 +1086,6 @@ static int emac_resize_rx_ring(struct emac_instance *dev, 
int new_mtu)
BUG_ON(!dev->rx_skb[i]);
dev_kfree_skb(dev->rx_skb[i]);
 
-   skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
dev->rx_desc[i].data_ptr =
dma_map_single(&dev->ofdev->dev, skb->data - 2, 
rx_sync_size,
   DMA_FROM_DEVICE) + 2;
@@ -1205,20 +1206,18 @@ static void emac_clean_rx_ring(struct emac_instance 
*dev)
}
 }
 
-static inline int emac_alloc_rx_skb(struct emac_instance *dev, int slot,
-   gfp_t flags)
+static inline int
+__emac_prepare_rx_skb(struct sk_buff *skb, struct emac_instance *dev, int slot)
 {
-   struct sk_buff *skb = alloc_skb(dev->rx_skb_size, flags);
if (unlikely(!skb))
return -ENOMEM;
 
dev->rx_skb[slot] = skb;
dev->rx_desc[slot].data_len = 0;
 
-   skb_reserve(skb, EMAC_RX_SKB_HEADROOM + 2);
dev->rx_desc[slot].data_ptr =
-   dma_map_single(&dev->ofdev->dev, skb->data - 2, dev->rx_sync_size,
-  DMA_FROM_DEVICE) + 2;
+   dma_map_single(&dev->ofdev->dev, skb->data - NET_IP_ALIGN,
+  dev->rx_sync_size, DMA_FROM_DEVICE) + NET_IP_ALIGN;
wmb();
dev->rx_desc[slot].ctrl = MAL_RX_CTRL_EMPTY |
(slot == (NUM_RX_BUFF - 1) ? MAL_RX_CTRL_WRAP : 0);
@@ -1226,6 +1225,27 @@ static inline int emac_alloc_rx_skb(struct emac_instance 
*dev, int slot,
return 0;
 }
 
+static inline int
+emac_alloc_rx_skb(struct emac_instance *dev, int slot)
+{
+   struct sk_buff *skb;
+
+   skb = __netdev_alloc_skb_ip_align(dev->ndev, dev->rx_skb_size,
+ GFP_KERNEL);
+
+   return __emac_prepare_rx_skb(skb, dev, slot);
+}
+
+static inline int
+emac_alloc_rx_skb_napi(struct emac_instance *dev, int slot)
+{
+   struct sk_buff *skb;
+
+   skb = napi_alloc_skb(&dev->mal->napi, dev->rx_skb_size);
+
+   return __emac_prepare_rx_skb(skb, dev, slot);
+}
+
 static void emac_print_link_status(struct emac_instance *dev)
 {
if (netif_carrier_ok(dev->ndev))
@@ -1256,7 +1276,7 @@ static int emac_open(struct net_device *ndev)
 
/* Allocate RX ring */
for (i = 0; i < NUM_RX_BUFF; ++i)
-   if (emac_alloc_rx_skb(dev, i, GFP_KERNEL)) {
+   if (emac_alloc_rx_skb(dev, i)) {
printk(KERN_ERR "%s: failed to allocate RX ring\n",
   ndev->name);
goto oom;
@@ -1778,8 +1798,9 @@ static inline void emac_recycle_rx_skb(struct 
emac_instance *dev, int slot,
DBG2(dev, "recycle %d %d" NL, slot, len);
 
if (len)
-   dma_map_single(&dev->ofde

Re: [PATCH 1/2] net: emac: implement 802.1Q VLAN TX tagging support

2018-10-19 Thread Christian Lamparter
On Wednesday, October 17, 2018 10:09:10 PM CEST Florian Fainelli wrote:
> On 10/17/2018 01:08 PM, Florian Fainelli wrote:
> > On 10/17/2018 12:53 PM, Christian Lamparter wrote:
> >> As per' APM82181 Embedded Processor User Manual 26.1 EMAC Features:
> >> VLAN:
> >>  - Support for VLAN tag ID in compliance with IEEE 802.3ac.
> >>  - VLAN tag insertion or replacement for transmit packets
> >>
> >> This patch completes the missing code for the VLAN tx tagging
> >> support, as the the EMAC_MR1_VLE was already enabled.
> >>
> >> Signed-off-by: Christian Lamparter 
> >> ---
> >>  drivers/net/ethernet/ibm/emac/core.c | 32 
> >>  drivers/net/ethernet/ibm/emac/core.h |  6 +-
> >>  2 files changed, 33 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/drivers/net/ethernet/ibm/emac/core.c 
> >> b/drivers/net/ethernet/ibm/emac/core.c
> >> index 760b2ad8e295..be560f9031f4 100644
> >> --- a/drivers/net/ethernet/ibm/emac/core.c
> >> +++ b/drivers/net/ethernet/ibm/emac/core.c
> >> @@ -37,6 +37,7 @@
> >>  #include 
> >>  #include 
> >>  #include 
> >> +#include 
> >>  #include 
> >>  #include 
> >>  #include 
> >> @@ -674,7 +675,7 @@ static int emac_configure(struct emac_instance *dev)
> >> ndev->dev_addr[5]);
> >>  
> >>/* VLAN Tag Protocol ID */
> >> -  out_be32(&p->vtpid, 0x8100);
> >> +  out_be32(&p->vtpid, ETH_P_8021Q);
> >>  
> >>/* Receive mode register */
> >>r = emac_iff2rmr(ndev);
> >> @@ -1435,6 +1436,22 @@ static inline netdev_tx_t emac_xmit_finish(struct 
> >> emac_instance *dev, int len)
> >>return NETDEV_TX_OK;
> >>  }
> >>  
> >> +static inline u16 emac_tx_vlan(struct emac_instance *dev, struct sk_buff 
> >> *skb)
> >> +{
> >> +  /* Handle VLAN TPID and TCI insert if this is a VLAN skb */
> >> +  if (emac_has_feature(dev, EMAC_FTR_HAS_VLAN_CTAG_TX) &&
> >> +  skb_vlan_tag_present(skb)) {
> >> +  struct emac_regs __iomem *p = dev->emacp;
> >> +
> >> +  /* update the VLAN TCI */
> >> +  out_be32(&p->vtci, (u32)skb_vlan_tag_get(skb));
> > 
> > The only case where this is likely not going to be 0x8100/ETH_P_8021Q is
> > if you do 802.1ad (QinQ) and you decided to somehow offload the S-Tag
> > instead of the C-Tag.
> 
> Sorry, looks like I mixed up TCI and TPID here, this looks obviously
> correct ;)

Ok, I wasn't really sure what to write anyway ;).

The hardware documentation mentions that:
"Support for VLAN tag ID in compliance with IEEE Draft 802.3ac/D1.0 standard".
It's too old for offloading any fancy QinQ stuff :(.




Re: [PATCH 2/2] net: emac: implement TCP TSO

2018-10-19 Thread Christian Lamparter
Hello,

On Wednesday, October 17, 2018 10:09:44 PM CEST Florian Fainelli wrote:
> On 10/17/2018 12:53 PM, Christian Lamparter wrote:
> > This patch enables TSO(v4) hw feature for emac driver.
> > As atleast the APM82181's TCP/IP acceleration hardware
> > controller (TAH) provides TCP segmentation support in
> > the transmit path.
> > 
> > Signed-off-by: Christian Lamparter 
> > ---
> > diff --git a/drivers/net/ethernet/ibm/emac/core.c 
> > b/drivers/net/ethernet/ibm/emac/core.c
> > index be560f9031f4..49ffbd6e1707 100644
> > --- a/drivers/net/ethernet/ibm/emac/core.c
> > +++ b/drivers/net/ethernet/ibm/emac/core.c
> > @@ -1410,6 +1413,52 @@ static inline u16 emac_tx_csum(struct emac_instance 
> > *dev,
> > return 0;
> >  }
> >  
> > +const u32 tah_ss[TAH_NO_SSR] = { 9000, 4500, 1500, 1300, 576, 176 };
> > +
> > +static int emac_tx_tso(struct emac_instance *dev, struct sk_buff *skb,
> > +  u16 *ctrl)
> > +{
> > +   if (emac_has_feature(dev, EMAC_FTR_TAH_HAS_TSO) &&
> > +   skb_is_gso(skb) && !!(skb_shinfo(skb)->gso_type &
> > +   (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) {
> > +   u32 seg_size = 0, i;
> > +
> > +   /* Get the MTU */
> > +   seg_size = skb_shinfo(skb)->gso_size + tcp_hdrlen(skb)
> > +   + skb_network_header_len(skb);
> > +
> > +   /* Restriction applied for the segmentation size
> > +* to use HW segmentation offload feature: the size
> > +* of the segment must not be less than 168 bytes for
> > +* DIX formatted segments, or 176 bytes for
> > +* IEEE formatted segments.
> > +*
> > +* I use value 176 to check for the segment size here
> > +* as it can cover both 2 conditions above.
> > +*/
> > +   if (seg_size < 176)
> > +   return -ENODEV;
> > +
> > +   /* Get the best suitable MTU */
> > +   for (i = 0; i < ARRAY_SIZE(tah_ss); i++) {
> > +   u32 curr_seg = tah_ss[i];
> > +
> > +   if (curr_seg > dev->ndev->mtu ||
> > +   curr_seg > seg_size)
> > +   continue;
> > +
> > +   *ctrl &= ~EMAC_TX_CTRL_TAH_CSUM;
> > +   *ctrl |= EMAC_TX_CTRL_TAH_SSR(i);
> > +   return 0;
> 
> This is something that you can possibly take out of your hot path and
> recalculate when the MTU actually changes?

Do you mean the curr_seg > dev->ndev->mtu check? Because from what I
know, the MSS can be manually set by a socket option (TCP_MAXSEG) on a
"per-socket" base.

(Altough, iperf warns that "Setting MSS is very buggy"... Which it is
as I see more way retries with a iperf run with a MSS less than
768-ish. Ideally, the change_mtu could update the TAH_SS register )

> [snip]
> 
> > +static netdev_tx_t emac_sw_tso(struct sk_buff *skb, struct net_device 
> > *ndev)
> > +{
> > +   struct emac_instance *dev = netdev_priv(ndev);
> > +   struct sk_buff *segs, *curr;
> > +
> > +   segs = skb_gso_segment(skb, ndev->features &
> > +   ~(NETIF_F_TSO | NETIF_F_TSO6));
> > +   if (IS_ERR_OR_NULL(segs)) {
> > +   goto drop;
> > +   } else {
> > +   while (segs) {
> > +   /* check for overflow */
> > +   if (dev->tx_cnt >= NUM_TX_BUFF) {
> > +   dev_kfree_skb_any(segs);
> > +   goto drop;
> > +   }
> 
> Would setting dev->max_gso_segs somehow help make sure the stack does
> not feed you oversized GSO'd skbs?
Ok, thanks's for that pointer. I'll look at dev->gso_max_segs and
dev->gso_max_size. The hardware documentation doesn't mention any
hard upper limit for how many segments it can do. What it does tell
is that it just needs an extra 512Bytes in the TX FIFO as a buffer
to store the header template and the calculated checksums and what
not.
 
But this should be no problem because that TX FIFO is 10 KiB. so even
the 9000 Jumbo frames should have plenty of "free real estate".

As for the "overflow" case:

There's a check in emac_start_xmit_sg() before emac_tx_tso() call that
does an *estimation* check and goes to "stop_queue" if it doesn't fit:

|/* Note, this is only an *estimation*, we can still run out of empty
| * slots bec

[PATCH 1/2] net: emac: implement 802.1Q VLAN TX tagging support

2018-10-17 Thread Christian Lamparter
As per' APM82181 Embedded Processor User Manual 26.1 EMAC Features:
VLAN:
 - Support for VLAN tag ID in compliance with IEEE 802.3ac.
 - VLAN tag insertion or replacement for transmit packets

This patch completes the missing code for the VLAN tx tagging
support, as the the EMAC_MR1_VLE was already enabled.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/core.c | 32 
 drivers/net/ethernet/ibm/emac/core.h |  6 +-
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 760b2ad8e295..be560f9031f4 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -674,7 +675,7 @@ static int emac_configure(struct emac_instance *dev)
 ndev->dev_addr[5]);
 
/* VLAN Tag Protocol ID */
-   out_be32(&p->vtpid, 0x8100);
+   out_be32(&p->vtpid, ETH_P_8021Q);
 
/* Receive mode register */
r = emac_iff2rmr(ndev);
@@ -1435,6 +1436,22 @@ static inline netdev_tx_t emac_xmit_finish(struct 
emac_instance *dev, int len)
return NETDEV_TX_OK;
 }
 
+static inline u16 emac_tx_vlan(struct emac_instance *dev, struct sk_buff *skb)
+{
+   /* Handle VLAN TPID and TCI insert if this is a VLAN skb */
+   if (emac_has_feature(dev, EMAC_FTR_HAS_VLAN_CTAG_TX) &&
+   skb_vlan_tag_present(skb)) {
+   struct emac_regs __iomem *p = dev->emacp;
+
+   /* update the VLAN TCI */
+   out_be32(&p->vtci, (u32)skb_vlan_tag_get(skb));
+
+   /* Insert VLAN tag */
+   return EMAC_TX_CTRL_IVT;
+   }
+   return 0;
+}
+
 /* Tx lock BH */
 static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device 
*ndev)
 {
@@ -1443,7 +1460,7 @@ static netdev_tx_t emac_start_xmit(struct sk_buff *skb, 
struct net_device *ndev)
int slot;
 
u16 ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
-   MAL_TX_CTRL_LAST | emac_tx_csum(dev, skb);
+   MAL_TX_CTRL_LAST | emac_tx_csum(dev, skb) | emac_tx_vlan(dev, skb);
 
slot = dev->tx_slot++;
if (dev->tx_slot == NUM_TX_BUFF) {
@@ -1518,7 +1535,7 @@ emac_start_xmit_sg(struct sk_buff *skb, struct net_device 
*ndev)
goto stop_queue;
 
ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
-   emac_tx_csum(dev, skb);
+   emac_tx_csum(dev, skb) | emac_tx_vlan(dev, skb);
slot = dev->tx_slot;
 
/* skb data */
@@ -2891,7 +2908,8 @@ static int emac_init_config(struct emac_instance *dev)
if (of_device_is_compatible(np, "ibm,emac-apm821xx")) {
dev->features |= (EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE |
  EMAC_FTR_APM821XX_NO_HALF_DUPLEX |
- EMAC_FTR_460EX_PHY_CLK_FIX);
+ EMAC_FTR_460EX_PHY_CLK_FIX |
+ EMAC_FTR_HAS_VLAN_CTAG_TX);
}
} else if (of_device_is_compatible(np, "ibm,emac4")) {
dev->features |= EMAC_FTR_EMAC4;
@@ -3148,6 +3166,12 @@ static int emac_probe(struct platform_device *ofdev)
 
if (dev->tah_dev) {
ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG;
+
+   if (emac_has_feature(dev, EMAC_FTR_HAS_VLAN_CTAG_TX)) {
+   ndev->vlan_features |= ndev->hw_features;
+   ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX;
+   }
+
ndev->features |= ndev->hw_features | NETIF_F_RXCSUM;
}
ndev->watchdog_timeo = 5 * HZ;
diff --git a/drivers/net/ethernet/ibm/emac/core.h 
b/drivers/net/ethernet/ibm/emac/core.h
index 84caa4a3fc52..8d84d439168c 100644
--- a/drivers/net/ethernet/ibm/emac/core.h
+++ b/drivers/net/ethernet/ibm/emac/core.h
@@ -334,6 +334,8 @@ struct emac_instance {
  * APM821xx does not support Half Duplex mode
  */
 #define EMAC_FTR_APM821XX_NO_HALF_DUPLEX   0x1000
+/* EMAC can insert 802.1Q tag */
+#define EMAC_FTR_HAS_VLAN_CTAG_TX  0x2000
 
 /* Right now, we don't quite handle the always/possible masks on the
  * most optimal way as we don't have a way to say something like
@@ -363,7 +365,9 @@ enum {
EMAC_FTR_460EX_PHY_CLK_FIX |
EMAC_FTR_440EP_PHY_CLK_FIX |
EMAC_APM821XX_REQ_JUMBO_FRAME_SIZE |
-   EMAC_FTR_APM821XX_NO_HALF_DUPLEX,
+   EMAC_FTR_APM821XX_NO_HALF_DUPLEX |
+   EMAC_FTR_HAS_VLAN_CTAG_TX |
+   0,
 };
 
 static inline int emac_has_feature(struct emac_instance *dev,
-- 
2.19.1



[PATCH 2/2] net: emac: implement TCP TSO

2018-10-17 Thread Christian Lamparter
This patch enables TSO(v4) hw feature for emac driver.
As atleast the APM82181's TCP/IP acceleration hardware
controller (TAH) provides TCP segmentation support in
the transmit path.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/core.c | 101 ++-
 drivers/net/ethernet/ibm/emac/core.h |   4 ++
 drivers/net/ethernet/ibm/emac/emac.h |   7 ++
 drivers/net/ethernet/ibm/emac/tah.c  |  20 ++
 drivers/net/ethernet/ibm/emac/tah.h  |   2 +
 5 files changed, 133 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index be560f9031f4..49ffbd6e1707 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -38,6 +38,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -1410,6 +1413,52 @@ static inline u16 emac_tx_csum(struct emac_instance *dev,
return 0;
 }
 
+const u32 tah_ss[TAH_NO_SSR] = { 9000, 4500, 1500, 1300, 576, 176 };
+
+static int emac_tx_tso(struct emac_instance *dev, struct sk_buff *skb,
+  u16 *ctrl)
+{
+   if (emac_has_feature(dev, EMAC_FTR_TAH_HAS_TSO) &&
+   skb_is_gso(skb) && !!(skb_shinfo(skb)->gso_type &
+   (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) {
+   u32 seg_size = 0, i;
+
+   /* Get the MTU */
+   seg_size = skb_shinfo(skb)->gso_size + tcp_hdrlen(skb)
+   + skb_network_header_len(skb);
+
+   /* Restriction applied for the segmentation size
+* to use HW segmentation offload feature: the size
+* of the segment must not be less than 168 bytes for
+* DIX formatted segments, or 176 bytes for
+* IEEE formatted segments.
+*
+* I use value 176 to check for the segment size here
+* as it can cover both 2 conditions above.
+*/
+   if (seg_size < 176)
+   return -ENODEV;
+
+   /* Get the best suitable MTU */
+   for (i = 0; i < ARRAY_SIZE(tah_ss); i++) {
+   u32 curr_seg = tah_ss[i];
+
+   if (curr_seg > dev->ndev->mtu ||
+   curr_seg > seg_size)
+   continue;
+
+   *ctrl &= ~EMAC_TX_CTRL_TAH_CSUM;
+   *ctrl |= EMAC_TX_CTRL_TAH_SSR(i);
+   return 0;
+   }
+
+   /* none found fall back to software */
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 static inline netdev_tx_t emac_xmit_finish(struct emac_instance *dev, int len)
 {
struct emac_regs __iomem *p = dev->emacp;
@@ -1452,8 +1501,46 @@ static inline u16 emac_tx_vlan(struct emac_instance 
*dev, struct sk_buff *skb)
return 0;
 }
 
+static netdev_tx_t
+emac_start_xmit(struct sk_buff *skb, struct net_device *ndev);
+
+static netdev_tx_t emac_sw_tso(struct sk_buff *skb, struct net_device *ndev)
+{
+   struct emac_instance *dev = netdev_priv(ndev);
+   struct sk_buff *segs, *curr;
+
+   segs = skb_gso_segment(skb, ndev->features &
+   ~(NETIF_F_TSO | NETIF_F_TSO6));
+   if (IS_ERR_OR_NULL(segs)) {
+   goto drop;
+   } else {
+   while (segs) {
+   /* check for overflow */
+   if (dev->tx_cnt >= NUM_TX_BUFF) {
+   dev_kfree_skb_any(segs);
+   goto drop;
+   }
+
+   curr = segs;
+   segs = curr->next;
+   curr->next = NULL;
+
+   emac_start_xmit(curr, ndev);
+   }
+   dev_consume_skb_any(skb);
+   }
+
+   return NETDEV_TX_OK;
+
+drop:
+   ++dev->estats.tx_dropped;
+   dev_kfree_skb_any(skb);
+   return NETDEV_TX_OK;
+}
+
 /* Tx lock BH */
-static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device 
*ndev)
+static netdev_tx_t
+emac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
struct emac_instance *dev = netdev_priv(ndev);
unsigned int len = skb->len;
@@ -1462,6 +1549,9 @@ static netdev_tx_t emac_start_xmit(struct sk_buff *skb, 
struct net_device *ndev)
u16 ctrl = EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP | MAL_TX_CTRL_READY |
MAL_TX_CTRL_LAST | emac_tx_csum(dev, skb) | emac_tx_vlan(dev, skb);
 
+   if (emac_tx_tso(dev, skb, &ctrl))
+   return emac_sw_tso(skb, ndev);
+
slot = dev->tx_slot++;
if (dev->tx_slot == NUM_TX_BUFF) {
dev->tx_slot = 0;
@@ -1536,6 +1626,9 @@ emac_start_xmit_sg(struct sk_buff *skb, stru

[PATCH] net: emac: fix fixed-link setup for the RTL8363SB switch

2018-09-17 Thread Christian Lamparter
On the Netgear WNDAP620, the emac ethernet isn't receiving nor
xmitting any frames from/to the RTL8363SB (identifies itself
as a RTL8367RB).

This is caused by the emac hardware not knowing the forced link
parameters for speed, duplex, pause, etc.

This begs the question, how this was working on the original
driver code, when it was necessary to set the phy_address and
phy_map to 0x. But I guess without access to the old
PPC405/440/460 hardware, it's not possible to know.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/core.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 354c0982847b..3b398ebdb5e6 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -2677,12 +2677,17 @@ static int emac_init_phy(struct emac_instance *dev)
if (of_phy_is_fixed_link(np)) {
int res = emac_dt_mdio_probe(dev);
 
-   if (!res) {
-   res = of_phy_register_fixed_link(np);
-   if (res)
-   mdiobus_unregister(dev->mii_bus);
+   if (res)
+   return res;
+
+   res = of_phy_register_fixed_link(np);
+   dev->phy_dev = of_phy_find_device(np);
+   if (res || !dev->phy_dev) {
+   mdiobus_unregister(dev->mii_bus);
+   return res ? res : -EINVAL;
}
-   return res;
+   emac_adjust_link(dev->ndev);
+   put_device(&dev->phy_dev->mdio.dev);
}
return 0;
}
-- 
2.19.0.rc2



Re: [PATCH 2/2] net/ibm/emac: wrong bit is used for STA control register write

2018-01-22 Thread Christian Lamparter
On Monday, January 22, 2018 8:01:46 PM CET Ivan Mikhaylov wrote:
> >Something looks wrong here?! The commit message talks about bit 18, 19 and 
> >20.
> >However, 0x0800, 0x1000, 0x2000 and are like bit 11, 12 and 13? Furthermore,
> >what about the EMAC_STACR_STAC_MASK? shouldn't it be 0x1800 now (or delete it
> >since it doesn't look like it's used anywhere?).
> Christian, nope, it's all fine there, it's big endian.
Ok Thanks. I think I found the relevant info on Wikipedia:


"Little-endian CPUs usually employ "LSB 0" bit numbering, however both bit
numbering conventions can be seen in big-endian machines. Some architectures
like SPARC and Motorola 68000 use "LSB 0" bit numbering, while S/390, PowerPC
and PA-RISC use "MSB 0"."

But as far as the kernel (code) is concerned, all architectures (big or
little endian) have the same BIT marco:

|#define BIT(nr)(1UL << (nr))
So if someone tries to #define EMAC_STACR_STAC_WRITE BIT(18) it would be
0x4 instead. This is where the confusion is coming from. Can you please
at least mention this somewhere that all the bits in the commit message are
in "MSB 0" format? It's confusing enough as it is ;).

> This commit related only
> to write operation, I'll check MASK and see what I can do with that.
Well, the MASK is not used and it now looks odd. So you might as well
delete it. Maybe as well as all the unused EMACX_STACR_STAC_IND_* macros?

Thanks,
Christian


Re: [PATCH 2/2] net/ibm/emac: wrong bit is used for STA control register write

2018-01-22 Thread Christian Lamparter
On Monday, January 22, 2018 5:00:38 PM CET Ivan Mikhaylov wrote:
> STA control register has areas of mode and opcodes for opeations. 18 bit is
> using for mode selection, where 0 is old MIO/MDIO access method and 1 is
> indirect access mode. 19-20 bits are using for setting up read/write
> operation(STA opcodes). In current state 'read' is set into old MIO/MDIO mode
> with 19 bit and write operation is set into 18 bit which is mode selection,
> not a write operation. To correlate write with read we set it into 20 bit.
> 
> Signed-off-by: Ivan Mikhaylov 
> ---
>  drivers/net/ethernet/ibm/emac/emac.h |2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/net/ethernet/ibm/emac/emac.h 
> b/drivers/net/ethernet/ibm/emac/emac.h
> index d0a0e3b..c26d263 100644
> --- a/drivers/net/ethernet/ibm/emac/emac.h
> +++ b/drivers/net/ethernet/ibm/emac/emac.h
> @@ -244,7 +244,7 @@ struct emac_regs {
>  #define EMAC_STACR_PHYE  0x4000
>  #define EMAC_STACR_STAC_MASK 0x3000
>  #define EMAC_STACR_STAC_READ 0x1000
> -#define EMAC_STACR_STAC_WRITE0x2000
> +#define EMAC_STACR_STAC_WRITE0x0800
>  #define EMAC_STACR_OPBC_MASK 0x0C00
>  #define EMAC_STACR_OPBC_50   0x
>  #define EMAC_STACR_OPBC_66   0x0400
> 

Something looks wrong here?! The commit message talks about bit 18, 19 and 20.
However, 0x0800, 0x1000, 0x2000 and are like bit 11, 12 and 13? Furthermore,
what about the EMAC_STACR_STAC_MASK? shouldn't it be 0x1800 now (or delete it
since it doesn't look like it's used anywhere?).


Re: [PATCH v2 15/19] carl9170: prevent bounds-check bypass via speculative execution

2018-01-12 Thread Christian Lamparter
On Friday, January 12, 2018 7:39:50 PM CET Dan Williams wrote:
> On Fri, Jan 12, 2018 at 6:42 AM, Christian Lamparter  
> wrote:
> > On Friday, January 12, 2018 1:47:46 AM CET Dan Williams wrote:
> >> Static analysis reports that 'queue' may be a user controlled value that
> >> is used as a data dependency to read from the 'ar9170_qmap' array. In
> >> order to avoid potential leaks of kernel memory values, block
> >> speculative execution of the instruction stream that could issue reads
> >> based on an invalid result of 'ar9170_qmap[queue]'. In this case the
> >> value of 'ar9170_qmap[queue]' is immediately reused as an index to the
> >> 'ar->edcf' array.
> >>
> >> Based on an original patch by Elena Reshetova.
> >>
> >> Cc: Christian Lamparter 
> >> Cc: Kalle Valo 
> >> Cc: linux-wirel...@vger.kernel.org
> >> Cc: netdev@vger.kernel.org
> >> Signed-off-by: Elena Reshetova 
> >> Signed-off-by: Dan Williams 
> >> ---
> > This patch (and p54, cw1200) look like the same patch?!
> > Can you tell me what happend to:
> >
> > On Saturday, January 6, 2018 5:34:03 PM CET Dan Williams wrote:
> >> On Sat, Jan 6, 2018 at 6:23 AM, Christian Lamparter  
> >> wrote:
> >> > And Furthermore a invalid queue (param->ac) would cause a crash in
> >> > this line in mac80211 before it even reaches the driver [1]:
> >> > |   sdata->tx_conf[params->ac] = p;
> >> > |   
> >> > |   if (drv_conf_tx(local, sdata, >>>> params->ac <<<<, &p)) {
> >> > |^^ (this is a wrapper for the *_op_conf_tx)
> >> >
> >> > I don't think these chin-up exercises are needed.
> >>
> >> Quite the contrary, you've identified a better place in the call stack
> >> to sanitize the input and disable speculation. Then we can kill the
> >> whole class of the wireless driver reports at once it seems.
> > <https://www.spinics.net/lists/netdev/msg476353.html>
> 
> I didn't see where ac is being validated against the driver specific
> 'queues' value in that earlier patch.
The link to the check is right there in the earlier post. It's in 
parse_txq_params():
<https://github.com/torvalds/linux/blob/master/net/wireless/nl80211.c#L2070>
|   if (txq_params->ac >= NL80211_NUM_ACS)
|   return -EINVAL;

NL80211_NUM_ACS is 4
<http://elixir.free-electrons.com/linux/v4.15-rc7/source/include/uapi/linux/nl80211.h#L3748>

This check was added ever since mac80211's ieee80211_set_txq_params():
| sdata->tx_conf[params->ac] = p;

For cw1200: the driver just sets the dev->queue to 4.
In carl9170 dev->queues is set to __AR9170_NUM_TXQ and
p54 uses P54_QUEUE_AC_NUM.

Both __AR9170_NUM_TXQ and P54_QUEUE_AC_NUM are 4.
And this is not going to change since all drivers
have to follow mac80211's queue API:
<https://wireless.wiki.kernel.org/en/developers/documentation/mac80211/queues>

Some background:
In the old days (linux 2.6 and early 3.x), the parse_txq_params() function did
not verify the "queue" value. That's why these drivers had to do it.

Here's the relevant code from 2.6.39:
<http://elixir.free-electrons.com/linux/v2.6.39/source/net/wireless/nl80211.c#L879>
You'll notice that the check is missing there.
Here's mac80211's ieee80211_set_txq_params for reference:
<http://elixir.free-electrons.com/linux/v2.6.39/source/net/mac80211/cfg.c#L1197>

However over time, the check in the driver has become redundant.

> > Anyway, I think there's an easy way to solve this: remove the
> > "if (queue < ar->hw->queues)" check altogether. It's no longer needed
> > anymore as the "queue" value is validated long before the driver code
> > gets called.
> > 
> > And from my understanding, this will fix the "In this case
> > the value of 'ar9170_qmap[queue]' is immediately reused as an index to
> > the 'ar->edcf' array." gripe your tool complains about.
> >
> > This is here's a quick test-case for carl9170.:
> > ---
> > diff --git a/drivers/net/wireless/ath/carl9170/main.c 
> > b/drivers/net/wireless/ath/carl9170/main.c
> > index 988c8857d78c..2d3afb15bb62 100644
> > --- a/drivers/net/wireless/ath/carl9170/main.c
> > +++ b/drivers/net/wireless/ath/carl9170/main.c
> > @@ -1387,13 +1387,8 @@ static int carl9170_op_conf_tx(struct ieee80211_hw 
> > *hw,
> > int ret;
> >
> >   

Re: [PATCH v2 15/19] carl9170: prevent bounds-check bypass via speculative execution

2018-01-12 Thread Christian Lamparter
On Friday, January 12, 2018 1:47:46 AM CET Dan Williams wrote:
> Static analysis reports that 'queue' may be a user controlled value that
> is used as a data dependency to read from the 'ar9170_qmap' array. In
> order to avoid potential leaks of kernel memory values, block
> speculative execution of the instruction stream that could issue reads
> based on an invalid result of 'ar9170_qmap[queue]'. In this case the
> value of 'ar9170_qmap[queue]' is immediately reused as an index to the
> 'ar->edcf' array.
> 
> Based on an original patch by Elena Reshetova.
> 
> Cc: Christian Lamparter 
> Cc: Kalle Valo 
> Cc: linux-wirel...@vger.kernel.org
> Cc: netdev@vger.kernel.org
> Signed-off-by: Elena Reshetova 
> Signed-off-by: Dan Williams 
> ---
This patch (and p54, cw1200) look like the same patch?! 
Can you tell me what happend to:

On Saturday, January 6, 2018 5:34:03 PM CET Dan Williams wrote:
> On Sat, Jan 6, 2018 at 6:23 AM, Christian Lamparter  
> wrote:
> > And Furthermore a invalid queue (param->ac) would cause a crash in
> > this line in mac80211 before it even reaches the driver [1]:
> > |   sdata->tx_conf[params->ac] = p;
> > |   
> > |   if (drv_conf_tx(local, sdata, >>>> params->ac <<<<, &p)) {
> > |^^ (this is a wrapper for the *_op_conf_tx)
> >
> > I don't think these chin-up exercises are needed.
> 
> Quite the contrary, you've identified a better place in the call stack
> to sanitize the input and disable speculation. Then we can kill the
> whole class of the wireless driver reports at once it seems.
<https://www.spinics.net/lists/netdev/msg476353.html>

Anyway, I think there's an easy way to solve this: remove the 
"if (queue < ar->hw->queues)" check altogether. It's no longer needed
anymore as the "queue" value is validated long before the driver code
gets called. And from my understanding, this will fix the "In this case
the value of 'ar9170_qmap[queue]' is immediately reused as an index to
the 'ar->edcf' array." gripe your tool complains about.

This is here's a quick test-case for carl9170.:
---
diff --git a/drivers/net/wireless/ath/carl9170/main.c 
b/drivers/net/wireless/ath/carl9170/main.c
index 988c8857d78c..2d3afb15bb62 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -1387,13 +1387,8 @@ static int carl9170_op_conf_tx(struct ieee80211_hw *hw,
int ret;
 
mutex_lock(&ar->mutex);
-   if (queue < ar->hw->queues) {
-   memcpy(&ar->edcf[ar9170_qmap[queue]], param, sizeof(*param));
-   ret = carl9170_set_qos(ar);
-   } else {
-   ret = -EINVAL;
-   }
-
+   memcpy(&ar->edcf[ar9170_qmap[queue]], param, sizeof(*param));
+   ret = carl9170_set_qos(ar);
mutex_unlock(&ar->mutex);
return ret;
 }
---
What does your tool say about this? 

(If necessary, the "queue" value could be even sanitized with a
queue %= ARRAY_SIZE(ar9170_qmap); before the mutex_lock.)


Re: [PATCH 08/18] carl9170: prevent bounds-check bypass via speculative execution

2018-01-06 Thread Christian Lamparter
On Saturday, January 6, 2018 4:06:21 PM CET Alan Cox wrote:
> > The only way a user can set this in any meaningful way would be via
> > a NL80211_CMD_SET_WIPHY netlink message. However, the value will get
> > vetted there by cfg80211's parse_txq_params [0]. This is long before
> 
> Far more than a couple of hundred instructions ?
Well, the user would have to send a netlink message each time. So
cfg80211 can parse it (this is where the initial "if queue >= 4 " check
happen). So the CPU would have to continue through and into 
rdev_set_txq_params() to get to mac80211's ieee80211_set_txq_params().
Then pass through that before gets to the driver's op_tx_conf. Once
there the driver code aquires a mutex_lock too before it gets to
check the queue value again.

Is this enough and how would the mutex_lock fit in there? Or can
the CPU skip past this as well? 
> The problem is that the processor will speculate that the parameter
> is valid and continue on that basis until the speculation resolves
> or it hits some other limit that stops it speculating further.
> That can be quite a distance on a modern x86 processor, and for all
> we know could be even more on some of the other CPUs involved.
 
> > it reaches any of the *_op_conf_tx functions.
> > 
> > And Furthermore a invalid queue (param->ac) would cause a crash in 
> > this line in mac80211 before it even reaches the driver [1]:
> > |   sdata->tx_conf[params->ac] = p;
> > |   
> 
> Firstly it might not because the address you get as a result could be
> valid kernel memory. In fact your attackers wants it to be valid kernel
> memory since they are trying to find the value of a piece of that memory.
> 
> Secondly the processor is doing this speculatively so it won't fault. It
> will eventually decide it went the wrong way and throw all the
> speculative work away - leaving footprints. It won't fault unless the
> speculative resolves that was the real path the code took.
> 
> If it's not a performance critical path then it's better to be safe.
Thank you for reading the canary too.

Christian


Re: [PATCH 08/18] carl9170: prevent bounds-check bypass via speculative execution

2018-01-06 Thread Christian Lamparter
On Saturday, January 6, 2018 2:10:37 AM CET Dan Williams wrote:
> Static analysis reports that 'queue' may be a user controlled value that
> is used as a data dependency to read from the 'ar9170_qmap' array. In
> order to avoid potential leaks of kernel memory values, block
> speculative execution of the instruction stream that could issue reads
> based on an invalid result of 'ar9170_qmap[queue]'. In this case the
> value of 'ar9170_qmap[queue]' is immediately reused as an index to the
> 'ar->edcf' array.
> 
> Based on an original patch by Elena Reshetova.
> 
> Cc: Christian Lamparter 
> Cc: Kalle Valo 
> Cc: linux-wirel...@vger.kernel.org
> Cc: netdev@vger.kernel.org
> Signed-off-by: Elena Reshetova 
> Signed-off-by: Dan Williams 
> ---
>  drivers/net/wireless/ath/carl9170/main.c |6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/carl9170/main.c 
> b/drivers/net/wireless/ath/carl9170/main.c
> index 988c8857d78c..0ff34cbe2b62 100644
> --- a/drivers/net/wireless/ath/carl9170/main.c
> +++ b/drivers/net/wireless/ath/carl9170/main.c
> @@ -41,6 +41,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include "hw.h"
> @@ -1384,11 +1385,12 @@ static int carl9170_op_conf_tx(struct ieee80211_hw 
> *hw,
>  const struct ieee80211_tx_queue_params *param)
>  {
>   struct ar9170 *ar = hw->priv;
> + const u8 *elem;
>   int ret;
>  
>   mutex_lock(&ar->mutex);
> - if (queue < ar->hw->queues) {
> - memcpy(&ar->edcf[ar9170_qmap[queue]], param, sizeof(*param));
> + if ((elem = nospec_array_ptr(ar9170_qmap, queue, ar->hw->queues))) {
> + memcpy(&ar->edcf[*elem], param, sizeof(*param));
>   ret = carl9170_set_qos(ar);
>   } else {
>   ret = -EINVAL;
> 
> 
About the "queue" in carl9170_op_conf_tx, p54_conf_tx and cw1200_conf_tx:

The only way a user can set this in any meaningful way would be via
a NL80211_CMD_SET_WIPHY netlink message. However, the value will get
vetted there by cfg80211's parse_txq_params [0]. This is long before
it reaches any of the *_op_conf_tx functions.

And Furthermore a invalid queue (param->ac) would cause a crash in 
this line in mac80211 before it even reaches the driver [1]:
|   sdata->tx_conf[params->ac] = p;
|   
|   if (drv_conf_tx(local, sdata, >>>> params->ac <<<<, &p)) {
|^^ (this is a wrapper for the *_op_conf_tx)

I don't think these chin-up exercises are needed.

[0] <https://github.com/torvalds/linux/blob/master/net/wireless/nl80211.c#L2070>
[1] <https://github.com/torvalds/linux/blob/master/net/mac80211/cfg.c#L2157>



[PATCH v3 2/3] net: ibm: emac: replace custom PHY_MODE_* macros

2017-12-20 Thread Christian Lamparter
The ibm_emac driver predates the PHY_INTERFACE_MODE_*
enums by a few years.

And while the driver has been retrofitted to use the PHYLIB,
the old definitions have stuck around to this day.

This patch replaces all occurences of PHY_MODE_* with
the respective equivalent PHY_INTERFACE_MODE_* enum.
And finally, it purges the old macros for good.

Signed-off-by: Christian Lamparter 

---
Extra change in zmii.c to make checkpatch happy.
---
 drivers/net/ethernet/ibm/emac/core.c  | 20 +-
 drivers/net/ethernet/ibm/emac/emac.h  | 13 
 drivers/net/ethernet/ibm/emac/phy.c   | 10 -
 drivers/net/ethernet/ibm/emac/rgmii.c | 20 +-
 drivers/net/ethernet/ibm/emac/zmii.c  | 38 +--
 5 files changed, 44 insertions(+), 57 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 7feff2450ed6..27f592da7cfc 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -199,18 +199,18 @@ static void __emac_set_multicast_list(struct 
emac_instance *dev);
 
 static inline int emac_phy_supports_gige(int phy_mode)
 {
-   return  phy_mode == PHY_MODE_GMII ||
-   phy_mode == PHY_MODE_RGMII ||
-   phy_mode == PHY_MODE_SGMII ||
-   phy_mode == PHY_MODE_TBI ||
-   phy_mode == PHY_MODE_RTBI;
+   return  phy_mode == PHY_INTERFACE_MODE_GMII ||
+   phy_mode == PHY_INTERFACE_MODE_RGMII ||
+   phy_mode == PHY_INTERFACE_MODE_SGMII ||
+   phy_mode == PHY_INTERFACE_MODE_TBI ||
+   phy_mode == PHY_INTERFACE_MODE_RTBI;
 }
 
 static inline int emac_phy_gpcs(int phy_mode)
 {
-   return  phy_mode == PHY_MODE_SGMII ||
-   phy_mode == PHY_MODE_TBI ||
-   phy_mode == PHY_MODE_RTBI;
+   return  phy_mode == PHY_INTERFACE_MODE_SGMII ||
+   phy_mode == PHY_INTERFACE_MODE_TBI ||
+   phy_mode == PHY_INTERFACE_MODE_RTBI;
 }
 
 static inline void emac_tx_enable(struct emac_instance *dev)
@@ -2865,7 +2865,7 @@ static int emac_init_config(struct emac_instance *dev)
/* PHY mode needs some decoding */
dev->phy_mode = of_get_phy_mode(np);
if (dev->phy_mode < 0)
-   dev->phy_mode = PHY_MODE_NA;
+   dev->phy_mode = PHY_INTERFACE_MODE_NA;
 
/* Check EMAC version */
if (of_device_is_compatible(np, "ibm,emac4sync")) {
@@ -3168,7 +3168,7 @@ static int emac_probe(struct platform_device *ofdev)
printk(KERN_INFO "%s: EMAC-%d %pOF, MAC %pM\n",
   ndev->name, dev->cell_index, np, ndev->dev_addr);
 
-   if (dev->phy_mode == PHY_MODE_SGMII)
+   if (dev->phy_mode == PHY_INTERFACE_MODE_SGMII)
printk(KERN_NOTICE "%s: in SGMII mode\n", ndev->name);
 
if (dev->phy.address >= 0)
diff --git a/drivers/net/ethernet/ibm/emac/emac.h 
b/drivers/net/ethernet/ibm/emac/emac.h
index 5afcc27ceebb..bc14dcf27b6b 100644
--- a/drivers/net/ethernet/ibm/emac/emac.h
+++ b/drivers/net/ethernet/ibm/emac/emac.h
@@ -104,19 +104,6 @@ struct emac_regs {
} u1;
 };
 
-/*
- * PHY mode settings (EMAC <-> ZMII/RGMII bridge <-> PHY)
- */
-#define PHY_MODE_NAPHY_INTERFACE_MODE_NA
-#define PHY_MODE_MII   PHY_INTERFACE_MODE_MII
-#define PHY_MODE_RMII  PHY_INTERFACE_MODE_RMII
-#define PHY_MODE_SMII  PHY_INTERFACE_MODE_SMII
-#define PHY_MODE_RGMII PHY_INTERFACE_MODE_RGMII
-#define PHY_MODE_TBI   PHY_INTERFACE_MODE_TBI
-#define PHY_MODE_GMII  PHY_INTERFACE_MODE_GMII
-#define PHY_MODE_RTBI  PHY_INTERFACE_MODE_RTBI
-#define PHY_MODE_SGMII PHY_INTERFACE_MODE_SGMII
-
 /* EMACx_MR0 */
 #define EMAC_MR0_RXI   0x8000
 #define EMAC_MR0_TXI   0x4000
diff --git a/drivers/net/ethernet/ibm/emac/phy.c 
b/drivers/net/ethernet/ibm/emac/phy.c
index 874949faa424..71ee13c34192 100644
--- a/drivers/net/ethernet/ibm/emac/phy.c
+++ b/drivers/net/ethernet/ibm/emac/phy.c
@@ -96,7 +96,7 @@ int emac_mii_reset_gpcs(struct mii_phy *phy)
if ((val & BMCR_ISOLATE) && limit > 0)
gpcs_phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
 
-   if (limit > 0 && phy->mode == PHY_MODE_SGMII) {
+   if (limit > 0 && phy->mode == PHY_INTERFACE_MODE_SGMII) {
/* Configure GPCS interface to recommended setting for SGMII */
gpcs_phy_write(phy, 0x04, 0x8120); /* AsymPause, FDX */
gpcs_phy_write(phy, 0x07, 0x2801); /* msg_pg, toggle */
@@ -313,16 +313,16 @@ static int cis8201_init(struct mii_phy *phy)
epcr &= ~EPCR_MODE_MASK;
 
switch (phy->mode) {
-   case PHY_MODE_TBI:
+   case PHY_INTERFACE_MODE_TBI:
epcr |= EPCR_TBI_MODE;
break;
-   case PHY_MODE_RTBI:
+   case PHY_INTERFACE_MODE_RTBI:
  

[PATCH v3 3/3] net: ibm: emac: support RGMII-[RX|TX]ID phymode

2017-12-20 Thread Christian Lamparter
The RGMII spec allows compliance for devices that implement an internal
delay on TXC and/or RXC inside the transmitter. This patch adds the
necessary RGMII_[RX|TX]ID mode code to handle such PHYs with the
emac driver.

Signed-off-by: Christian Lamparter 

---
v3: - replace PHY_MODE_* with PHY_INTERFACE_MODE_*
- replace rgmii_mode_name() with phy_modes[]

v2: - utilize phy_interface_mode_is_rgmii()
---
 drivers/net/ethernet/ibm/emac/core.c  | 4 ++--
 drivers/net/ethernet/ibm/emac/rgmii.c | 7 +--
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 27f592da7cfc..71ddad13baf4 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -199,8 +199,8 @@ static void __emac_set_multicast_list(struct emac_instance 
*dev);
 
 static inline int emac_phy_supports_gige(int phy_mode)
 {
-   return  phy_mode == PHY_INTERFACE_MODE_GMII ||
-   phy_mode == PHY_INTERFACE_MODE_RGMII ||
+   return  phy_interface_mode_is_rgmii(phy_mode) ||
+   phy_mode == PHY_INTERFACE_MODE_GMII ||
phy_mode == PHY_INTERFACE_MODE_SGMII ||
phy_mode == PHY_INTERFACE_MODE_TBI ||
phy_mode == PHY_INTERFACE_MODE_RTBI;
diff --git a/drivers/net/ethernet/ibm/emac/rgmii.c 
b/drivers/net/ethernet/ibm/emac/rgmii.c
index 5db225831e81..00f5999de3cf 100644
--- a/drivers/net/ethernet/ibm/emac/rgmii.c
+++ b/drivers/net/ethernet/ibm/emac/rgmii.c
@@ -52,9 +52,9 @@
 /* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */
 static inline int rgmii_valid_mode(int phy_mode)
 {
-   return  phy_mode == PHY_INTERFACE_MODE_GMII ||
+   return  phy_interface_mode_is_rgmii(phy_mode) ||
+   phy_mode == PHY_INTERFACE_MODE_GMII ||
phy_mode == PHY_INTERFACE_MODE_MII ||
-   phy_mode == PHY_INTERFACE_MODE_RGMII ||
phy_mode == PHY_INTERFACE_MODE_TBI ||
phy_mode == PHY_INTERFACE_MODE_RTBI;
 }
@@ -63,6 +63,9 @@ static inline u32 rgmii_mode_mask(int mode, int input)
 {
switch (mode) {
case PHY_INTERFACE_MODE_RGMII:
+   case PHY_INTERFACE_MODE_RGMII_ID:
+   case PHY_INTERFACE_MODE_RGMII_RXID:
+   case PHY_INTERFACE_MODE_RGMII_TXID:
return RGMII_FER_RGMII(input);
case PHY_INTERFACE_MODE_TBI:
return RGMII_FER_TBI(input);
-- 
2.15.1



[PATCH v3 1/3] net: ibm: emac: replace custom rgmii_mode_name with phy_modes

2017-12-20 Thread Christian Lamparter
phy_modes() in the common phy.h already defines the same phy mode
names in lower case. The deleted rgmii_mode_name() is used only
in one place and for a "notice-level" printk. Hence, it will not
be missed.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/rgmii.c | 20 +---
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/rgmii.c 
b/drivers/net/ethernet/ibm/emac/rgmii.c
index c4a1ac38bba8..9a1c06f2471d 100644
--- a/drivers/net/ethernet/ibm/emac/rgmii.c
+++ b/drivers/net/ethernet/ibm/emac/rgmii.c
@@ -59,24 +59,6 @@ static inline int rgmii_valid_mode(int phy_mode)
phy_mode == PHY_MODE_RTBI;
 }
 
-static inline const char *rgmii_mode_name(int mode)
-{
-   switch (mode) {
-   case PHY_MODE_RGMII:
-   return "RGMII";
-   case PHY_MODE_TBI:
-   return "TBI";
-   case PHY_MODE_GMII:
-   return "GMII";
-   case PHY_MODE_MII:
-   return "MII";
-   case PHY_MODE_RTBI:
-   return "RTBI";
-   default:
-   BUG();
-   }
-}
-
 static inline u32 rgmii_mode_mask(int mode, int input)
 {
switch (mode) {
@@ -115,7 +97,7 @@ int rgmii_attach(struct platform_device *ofdev, int input, 
int mode)
out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input));
 
printk(KERN_NOTICE "%pOF: input %d in %s mode\n",
-  ofdev->dev.of_node, input, rgmii_mode_name(mode));
+  ofdev->dev.of_node, input, phy_modes(mode));
 
++dev->users;
 
-- 
2.15.1



Re: [PATCH v2] net: ibm: emac: support RGMII-[RX|TX]ID phymode

2017-12-20 Thread Christian Lamparter
On Wednesday, December 20, 2017 3:10:46 PM CET David Miller wrote:
> From: Christian Lamparter 
> Date: Wed, 20 Dec 2017 17:02:01 +0100
> 
> > diff --git a/drivers/net/ethernet/ibm/emac/emac.h 
> > b/drivers/net/ethernet/ibm/emac/emac.h
> > index 5afcc27ceebb..8c6d2af7281b 100644
> > --- a/drivers/net/ethernet/ibm/emac/emac.h
> > +++ b/drivers/net/ethernet/ibm/emac/emac.h
> > @@ -112,6 +112,9 @@ struct emac_regs {
> >  #define PHY_MODE_RMII  PHY_INTERFACE_MODE_RMII
> >  #define PHY_MODE_SMII  PHY_INTERFACE_MODE_SMII
> >  #define PHY_MODE_RGMII PHY_INTERFACE_MODE_RGMII
> > +#define PHY_MODE_RGMII_ID  PHY_INTERFACE_MODE_RGMII_ID
> > +#define PHY_MODE_RGMII_RXIDPHY_INTERFACE_MODE_RGMII_RXID
> > +#define PHY_MODE_RGMII_TXIDPHY_INTERFACE_MODE_RGMII_TXID
> >  #define PHY_MODE_TBI   PHY_INTERFACE_MODE_TBI
> >  #define PHY_MODE_GMII  PHY_INTERFACE_MODE_GMII
> >  #define PHY_MODE_RTBI  PHY_INTERFACE_MODE_RTBI
> 
> Why does this driver do all of this CPP macro aliasing?
Ah, well the emac driver is almost as old as dirt ;).
I added Benjamin Herrenschmidt since he seems to be the
original author. maybe he can provide some valuable insights
in this archaeological dig.

I don't know when the ibm_emac driver was added, but it does
predate the shared PHY_INTERFACE_MODE_ macros by a few years.

For example 2.6.11 had the driver and the defines.:
<http://elixir.free-electrons.com/linux/v2.6.11/source/drivers/net/ibm_emac/ibm_emac_phy.h#L41>
But there's no PHY_INTERFACE_MODE_* yet.

Fast forward to 2011:
The patch <https://patchwork.kernel.org/patch/945642/> wedded the
PHY_MODE_* macros to the PHY_INTERFACE_MODE_ enums. But this was
not a complete convertion.

So, as far as I can tell, these definitions have been there since
the beginning.
> 
> It's really cruddy because anyone who now reads this code:
> 
> >  static inline int rgmii_valid_mode(int phy_mode)
> >  {
> > -   return  phy_mode == PHY_MODE_GMII ||
> > +   return  phy_interface_mode_is_rgmii(phy_mode) ||
> > +   phy_mode == PHY_MODE_GMII ||
> > phy_mode == PHY_MODE_MII ||
> > -   phy_mode == PHY_MODE_RGMII ||
> > phy_mode == PHY_MODE_TBI ||
> > phy_mode == PHY_MODE_RTBI;
> >  }
> 
> will read this and say "Oh the function tests against these weird
> PHY_MODE_* aliases, but the helper function phy_interface_mode_is_rgmii()
> tests against PHY_INTERFACE_MODE_*, what is going on?"
> 
> I hate to do this to you, but please get rid of these confusing and
> completely unnecessary PHY_MODE_* CPP aliases first, and just use the
> proper PHY_INTERFACE_MODE_* values consistently.

Yeah, I can do that. no problem. 

Question is, should I also replace the rgmii_mode_name() with phy_modes() too?

The only user of rgmii_mode_name() is this notice printk in rgmii_attach():
<http://elixir.free-electrons.com/linux/latest/source/drivers/net/ethernet/ibm/emac/rgmii.c#L117>

Regards,
Christian


[PATCH v2] net: ibm: emac: support RGMII-[RX|TX]ID phymode

2017-12-20 Thread Christian Lamparter
The RGMII spec allows compliance for devices that implement an internal
delay on TXC and/or RXC inside the transmitter. This patch adds the
necessary RGMII_[RX|TX]ID mode code to handle such PHYs with the
emac driver.

Signed-off-by: Christian Lamparter 

---
v2: - utilize phy_interface_mode_is_rgmii()
---
 drivers/net/ethernet/ibm/emac/core.c  |  4 ++--
 drivers/net/ethernet/ibm/emac/emac.h  |  3 +++
 drivers/net/ethernet/ibm/emac/rgmii.c | 10 --
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 7feff2450ed6..043e72e28bba 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -199,8 +199,8 @@ static void __emac_set_multicast_list(struct emac_instance 
*dev);
 
 static inline int emac_phy_supports_gige(int phy_mode)
 {
-   return  phy_mode == PHY_MODE_GMII ||
-   phy_mode == PHY_MODE_RGMII ||
+   return  phy_interface_mode_is_rgmii(phy_mode) ||
+   phy_mode == PHY_MODE_GMII ||
phy_mode == PHY_MODE_SGMII ||
phy_mode == PHY_MODE_TBI ||
phy_mode == PHY_MODE_RTBI;
diff --git a/drivers/net/ethernet/ibm/emac/emac.h 
b/drivers/net/ethernet/ibm/emac/emac.h
index 5afcc27ceebb..8c6d2af7281b 100644
--- a/drivers/net/ethernet/ibm/emac/emac.h
+++ b/drivers/net/ethernet/ibm/emac/emac.h
@@ -112,6 +112,9 @@ struct emac_regs {
 #define PHY_MODE_RMII  PHY_INTERFACE_MODE_RMII
 #define PHY_MODE_SMII  PHY_INTERFACE_MODE_SMII
 #define PHY_MODE_RGMII PHY_INTERFACE_MODE_RGMII
+#define PHY_MODE_RGMII_ID  PHY_INTERFACE_MODE_RGMII_ID
+#define PHY_MODE_RGMII_RXIDPHY_INTERFACE_MODE_RGMII_RXID
+#define PHY_MODE_RGMII_TXIDPHY_INTERFACE_MODE_RGMII_TXID
 #define PHY_MODE_TBI   PHY_INTERFACE_MODE_TBI
 #define PHY_MODE_GMII  PHY_INTERFACE_MODE_GMII
 #define PHY_MODE_RTBI  PHY_INTERFACE_MODE_RTBI
diff --git a/drivers/net/ethernet/ibm/emac/rgmii.c 
b/drivers/net/ethernet/ibm/emac/rgmii.c
index c4a1ac38bba8..124b0473d2b7 100644
--- a/drivers/net/ethernet/ibm/emac/rgmii.c
+++ b/drivers/net/ethernet/ibm/emac/rgmii.c
@@ -52,9 +52,9 @@
 /* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */
 static inline int rgmii_valid_mode(int phy_mode)
 {
-   return  phy_mode == PHY_MODE_GMII ||
+   return  phy_interface_mode_is_rgmii(phy_mode) ||
+   phy_mode == PHY_MODE_GMII ||
phy_mode == PHY_MODE_MII ||
-   phy_mode == PHY_MODE_RGMII ||
phy_mode == PHY_MODE_TBI ||
phy_mode == PHY_MODE_RTBI;
 }
@@ -63,6 +63,9 @@ static inline const char *rgmii_mode_name(int mode)
 {
switch (mode) {
case PHY_MODE_RGMII:
+   case PHY_MODE_RGMII_ID:
+   case PHY_MODE_RGMII_RXID:
+   case PHY_MODE_RGMII_TXID:
return "RGMII";
case PHY_MODE_TBI:
return "TBI";
@@ -81,6 +84,9 @@ static inline u32 rgmii_mode_mask(int mode, int input)
 {
switch (mode) {
case PHY_MODE_RGMII:
+   case PHY_MODE_RGMII_ID:
+   case PHY_MODE_RGMII_RXID:
+   case PHY_MODE_RGMII_TXID:
return RGMII_FER_RGMII(input);
case PHY_MODE_TBI:
return RGMII_FER_TBI(input);
-- 
2.15.1



[PATCH] net: ibm: emac: support RGMII-[RX|TX]ID phymode

2017-12-17 Thread Christian Lamparter
The RGMII spec allows compliance for devices that implement an internal
delay on TXC and/or RXC inside the transmitter. This patch adds the
necessary RGMII_[RX|TX]ID mode code to handle such PHYs with the
emac driver.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/core.c  | 3 +++
 drivers/net/ethernet/ibm/emac/emac.h  | 3 +++
 drivers/net/ethernet/ibm/emac/rgmii.c | 9 +
 3 files changed, 15 insertions(+)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 7feff2450ed6..820173bee168 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -201,6 +201,9 @@ static inline int emac_phy_supports_gige(int phy_mode)
 {
return  phy_mode == PHY_MODE_GMII ||
phy_mode == PHY_MODE_RGMII ||
+   phy_mode == PHY_MODE_RGMII_ID ||
+   phy_mode == PHY_MODE_RGMII_RXID ||
+   phy_mode == PHY_MODE_RGMII_TXID ||
phy_mode == PHY_MODE_SGMII ||
phy_mode == PHY_MODE_TBI ||
phy_mode == PHY_MODE_RTBI;
diff --git a/drivers/net/ethernet/ibm/emac/emac.h 
b/drivers/net/ethernet/ibm/emac/emac.h
index 5afcc27ceebb..8c6d2af7281b 100644
--- a/drivers/net/ethernet/ibm/emac/emac.h
+++ b/drivers/net/ethernet/ibm/emac/emac.h
@@ -112,6 +112,9 @@ struct emac_regs {
 #define PHY_MODE_RMII  PHY_INTERFACE_MODE_RMII
 #define PHY_MODE_SMII  PHY_INTERFACE_MODE_SMII
 #define PHY_MODE_RGMII PHY_INTERFACE_MODE_RGMII
+#define PHY_MODE_RGMII_ID  PHY_INTERFACE_MODE_RGMII_ID
+#define PHY_MODE_RGMII_RXIDPHY_INTERFACE_MODE_RGMII_RXID
+#define PHY_MODE_RGMII_TXIDPHY_INTERFACE_MODE_RGMII_TXID
 #define PHY_MODE_TBI   PHY_INTERFACE_MODE_TBI
 #define PHY_MODE_GMII  PHY_INTERFACE_MODE_GMII
 #define PHY_MODE_RTBI  PHY_INTERFACE_MODE_RTBI
diff --git a/drivers/net/ethernet/ibm/emac/rgmii.c 
b/drivers/net/ethernet/ibm/emac/rgmii.c
index c4a1ac38bba8..7963adffbb1c 100644
--- a/drivers/net/ethernet/ibm/emac/rgmii.c
+++ b/drivers/net/ethernet/ibm/emac/rgmii.c
@@ -55,6 +55,9 @@ static inline int rgmii_valid_mode(int phy_mode)
return  phy_mode == PHY_MODE_GMII ||
phy_mode == PHY_MODE_MII ||
phy_mode == PHY_MODE_RGMII ||
+   phy_mode == PHY_MODE_RGMII_ID ||
+   phy_mode == PHY_MODE_RGMII_RXID ||
+   phy_mode == PHY_MODE_RGMII_TXID ||
phy_mode == PHY_MODE_TBI ||
phy_mode == PHY_MODE_RTBI;
 }
@@ -63,6 +66,9 @@ static inline const char *rgmii_mode_name(int mode)
 {
switch (mode) {
case PHY_MODE_RGMII:
+   case PHY_MODE_RGMII_ID:
+   case PHY_MODE_RGMII_RXID:
+   case PHY_MODE_RGMII_TXID:
return "RGMII";
case PHY_MODE_TBI:
return "TBI";
@@ -81,6 +87,9 @@ static inline u32 rgmii_mode_mask(int mode, int input)
 {
switch (mode) {
case PHY_MODE_RGMII:
+   case PHY_MODE_RGMII_ID:
+   case PHY_MODE_RGMII_RXID:
+   case PHY_MODE_RGMII_TXID:
return RGMII_FER_RGMII(input);
case PHY_MODE_TBI:
return RGMII_FER_TBI(input);
-- 
2.15.1



Re: [PATCH v2] p54: don't unregister leds when they are not initialized

2017-09-26 Thread Christian Lamparter
On Tuesday, September 26, 2017 5:11:33 PM CEST Andrey Konovalov wrote:
> ieee80211_register_hw() in p54_register_common() may fail and leds won't
> get initialized. Currently p54_unregister_common() doesn't check that and
> always calls p54_unregister_leds(). The fix is to check priv->registered
> flag before calling p54_unregister_leds().
> 
> Found by syzkaller.
> 
> [...]
>  process_scheduled_works kernel/workqueue.c:2179
>  worker_thread+0xb2b/0x1850 kernel/workqueue.c:2255
>  kthread+0x3a1/0x470 kernel/kthread.c:231
>  ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431
> 
> Signed-off-by: Andrey Konovalov 
Cc: sta...@vger.kernel.org
Acked-by: Christian Lamparter 

Thanks for making the patch too!



[RESEND] Re: usb/net/p54: trying to register non-static key in p54_unregister_leds

2017-09-23 Thread Christian Lamparter
This got rejected by gmail once. Let's see if it works now.

On Thursday, September 21, 2017 8:22:45 PM CEST Andrey Konovalov wrote:
> On Wed, Sep 20, 2017 at 9:55 PM, Johannes Berg
>  wrote:
> > On Wed, 2017-09-20 at 21:27 +0200, Christian Lamparter wrote:
> >
> >> It seems this is caused as a result of:
> >> -> lock_map_acquire(&work->lockdep_map);
> >>   lock_map_release(&work->lockdep_map);
> >>
> >> in flush_work() [0]
> >
> > Agree.
> >
> >> This was added by:
> >>
> >>   commit 0976dfc1d0cd80a4e9dfaf87bd8744612bde475a
> >>   Author: Stephen Boyd 
> >>   Date:   Fri Apr 20 17:28:50 2012 -0700
> >>
> >>   workqueue: Catch more locking problems with flush_work()
> >
> > Yes, but that doesn't matter.
> >
> >> Looking at the Stephen's patch, it's clear that it was made
> >> with "static DECLARE_WORK(work, my_work)" in mind. However
> >> p54's led_work is "per-device", hence it is stored in the
> >> devices context p54_common, which is dynamically allocated.
> >> So, maybe revert Stephen's patch?
> >
> > I disagree - as the lockdep warning says:
> >
> >> > INFO: trying to register non-static key.
> >> > the code is fine but needs lockdep annotation.
> >> > turning off the locking correctness validator.
> >
> > What it needs is to actually correctly go through initializing the work
> > at least once.
> >
> > Without more information, I can't really say what's going on, but I
> > assume that something is failing and p54_unregister_leds() is getting
> > invoked without p54_init_leds() having been invoked, so essentially
> > it's trying to flush a work that was never initialized?
> >
> > INIT_DELAYED_WORK() does, after all, initialize the lockdep map
> > properly via __INIT_WORK().

Ok, thanks. This does indeed explain it.

But this also begs the question: Is this really working then?
>From what I can tell, if CONFIG_LOCKDEP is not set then there's no BUG
no WARN, no other splat or any other odd system behaviour. Does
[cancel | flush]_[delayed_]work[_sync] really "just work" by *accident*,
as long the delayed_work | work_struct is zeroed out? 
And should it work in the future as well?

> Since I'm able to reproduce this, please let me know if you need me to
> collect some debug traces to help with the triage.

Do you want to take a shot at making a patch too? At a quick glance, it
should be enough to move the [#ifdef CONFIG_P54_LEDS ... #endif] block
in p54_unregister_common() into the if (priv->registered) { block
(preferably before the ieee80211_unregister_hw(dev).

Regards,
Christian


Re: usb/net/p54: trying to register non-static key in p54_unregister_leds

2017-09-20 Thread Christian Lamparter
On Wednesday, September 20, 2017 8:37:08 PM CEST Andrey Konovalov wrote:
> Hi!
> 
> I've got the following report while fuzzing the kernel with syzkaller.
> 
> On commit ebb2c2437d8008d46796902ff390653822af6cc4 (Sep 18).
> 
> INFO: trying to register non-static key.
> the code is fine but needs lockdep annotation.
> turning off the locking correctness validator.
> CPU: 1 PID: 1404 Comm: kworker/1:1 Not tainted
> 4.14.0-rc1-42251-gebb2c2437d80-dirty #205
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
> Workqueue: usb_hub_wq hub_event
> Call Trace:
>  __dump_stack lib/dump_stack.c:16
>  dump_stack+0x292/0x395 lib/dump_stack.c:52
>  register_lock_class+0x6c4/0x1a00 kernel/locking/lockdep.c:769
>  __lock_acquire+0x27e/0x4550 kernel/locking/lockdep.c:3385
>  lock_acquire+0x259/0x620 kernel/locking/lockdep.c:4002
>  flush_work+0xf0/0x8c0 kernel/workqueue.c:2886
>  __cancel_work_timer+0x51d/0x870 kernel/workqueue.c:2961
>  cancel_delayed_work_sync+0x1f/0x30 kernel/workqueue.c:3081
>  p54_unregister_leds+0x6c/0xc0 drivers/net/wireless/intersil/p54/led.c:160
>  p54_unregister_common+0x3d/0xb0 drivers/net/wireless/intersil/p54/main.c:856
>  p54u_disconnect+0x86/0x120 drivers/net/wireless/intersil/p54/p54usb.c:1073
>  usb_unbind_interface+0x21c/0xa90 drivers/usb/core/driver.c:423
>  __device_release_driver drivers/base/dd.c:861
>  device_release_driver_internal+0x4f4/0x5c0 drivers/base/dd.c:893
>  device_release_driver+0x1e/0x30 drivers/base/dd.c:918
>  bus_remove_device+0x2f4/0x4b0 drivers/base/bus.c:565
>  device_del+0x5c4/0xab0 drivers/base/core.c:1985
>  usb_disable_device+0x1e9/0x680 drivers/usb/core/message.c:1170
>  usb_disconnect+0x260/0x7a0 drivers/usb/core/hub.c:2124
>  hub_port_connect drivers/usb/core/hub.c:4754
>  hub_port_connect_change drivers/usb/core/hub.c:5009
>  port_event drivers/usb/core/hub.c:5115
>  hub_event+0x1318/0x3740 drivers/usb/core/hub.c:5195
>  process_one_work+0xc7f/0x1db0 kernel/workqueue.c:2119
>  process_scheduled_works kernel/workqueue.c:2179
>  worker_thread+0xb2b/0x1850 kernel/workqueue.c:2255
>  kthread+0x3a1/0x470 kernel/kthread.c:231
>  ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431
> 

It seems this is caused as a result of:
-> lock_map_acquire(&work->lockdep_map);
lock_map_release(&work->lockdep_map);

in flush_work() [0]

This was added by:

commit 0976dfc1d0cd80a4e9dfaf87bd8744612bde475a
Author: Stephen Boyd 
Date:   Fri Apr 20 17:28:50 2012 -0700

workqueue: Catch more locking problems with flush_work()

Looking at the Stephen's patch, it's clear that it was made
with "static DECLARE_WORK(work, my_work)" in mind. However
p54's led_work is "per-device", hence it is stored in the
devices context p54_common, which is dynamically allocated.
So, maybe revert Stephen's patch?

[0] 




[PATCH] net: emac: Fix napi poll list corruption

2017-09-19 Thread Christian Lamparter
This patch is pretty much a carbon copy of
commit 3079c652141f ("caif: Fix napi poll list corruption")
with "caif" replaced by "emac".

The commit d75b1ade567f ("net: less interrupt masking in NAPI")
breaks emac.

It is now required that if the entire budget is consumed when poll
returns, the napi poll_list must remain empty.  However, like some
other drivers emac tries to do a last-ditch check and if there is
more work it will call napi_reschedule and then immediately process
some of this new work.  Should the entire budget be consumed while
processing such new work then we will violate the new caller
contract.

This patch fixes this by not touching any work when we reschedule
in emac.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/mal.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/mal.c 
b/drivers/net/ethernet/ibm/emac/mal.c
index 2c74baa2398a..fff09dcf9e34 100644
--- a/drivers/net/ethernet/ibm/emac/mal.c
+++ b/drivers/net/ethernet/ibm/emac/mal.c
@@ -402,7 +402,7 @@ static int mal_poll(struct napi_struct *napi, int budget)
unsigned long flags;
 
MAL_DBG2(mal, "poll(%d)" NL, budget);
- again:
+
/* Process TX skbs */
list_for_each(l, &mal->poll_list) {
struct mal_commac *mc =
@@ -451,7 +451,6 @@ static int mal_poll(struct napi_struct *napi, int budget)
spin_lock_irqsave(&mal->lock, flags);
mal_disable_eob_irq(mal);
spin_unlock_irqrestore(&mal->lock, flags);
-   goto again;
}
mc->ops->poll_tx(mc->dev);
}
-- 
2.14.1



Re: hung task in mac80211

2017-09-06 Thread Christian Lamparter
On Wednesday, September 6, 2017 1:57:47 PM CEST Matteo Croce wrote:
> Hi,
> 
> I have an hung task on vanilla 4.13 kernel which I haven't on 4.12.
> The problem is present both on my AP and on my notebook,
> so it seems it affects AP and STA mode as well.
> The generated messages are:
> 
> INFO: task kworker/u16:6:120 blocked for more than 120 seconds.
>   Not tainted 4.13.0 #57
> "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> kworker/u16:6   D0   120  2 0x
> Workqueue: phy0 ieee80211_ba_session_work [mac80211]
> Call Trace:
>  ? __schedule+0x174/0x5b0
>  ? schedule+0x31/0x80
>  ? schedule_preempt_disabled+0x9/0x10
>  ? __mutex_lock.isra.2+0x163/0x480
>  ? select_task_rq_fair+0xb9f/0xc60
>  ? __ieee80211_start_rx_ba_session+0x135/0x4d0 [mac80211]
>  ? __ieee80211_start_rx_ba_session+0x135/0x4d0 [mac80211]
>  ? try_to_wake_up+0x1f1/0x340
>  ? update_curr+0x88/0xd0
>  ? ieee80211_ba_session_work+0x148/0x230 [mac80211]
> 
> I did a bisect and the offending commit is:
> 
> commit 699cb58c8a52ff39bf659bff7971893ebe111bf2
> Author: Johannes Berg 
> Date:   Tue May 30 16:34:46 2017 +0200
> 
> mac80211: manage RX BA session offload without SKB queue

I looked at this briefly:

ieee80211_ba_session_work acquires:
mutex_lock(&sta->ampdu_mlme.mtx) @


But it now also calls
__ieee80211_start_rx_ba_session() @
http://elixir.free-electrons.com/linux/v4.13/source/net/mac80211/ht.c#L336

which also wants to hold mutex_lock(&sta->ampdu_mlme.mtx) in:
http://elixir.free-electrons.com/linux/v4.13/source/net/mac80211/agg-rx.c#L314

I guess this is where it deadlocks?

Regards,
Christian


Re: [PATCH] net: ibm: emac: Fix some error handling path in 'emac_probe()'

2017-08-19 Thread Christian Lamparter
On Saturday, August 19, 2017 1:07:57 AM CEST Christophe JAILLET wrote:
> If 'irq_of_parse_and_map()' or 'of_address_to_resource()' fail, 'err' is
> known to be 0 at this point.
> So return -ENODEV instead in the first case and propagate the error
> returned by 'of_address_to_resource()' in the 2nd case.
> 
> While at it, turn a 'err != 0' test into an equivalent 'err' to be more
> consistent.
> 
> Signed-off-by: Christophe JAILLET 
> ---
>  drivers/net/ethernet/ibm/emac/core.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/ibm/emac/core.c 
> b/drivers/net/ethernet/ibm/emac/core.c
> index 95135d20458f..1af56a97fb47 100644
> --- a/drivers/net/ethernet/ibm/emac/core.c
> +++ b/drivers/net/ethernet/ibm/emac/core.c
> [...]
>   /* Map EMAC regs */
> - if (of_address_to_resource(np, 0, &dev->rsrc_regs)) {
> + err = of_address_to_resource(np, 0, &dev->rsrc_regs);
> + if (err) {
>   printk(KERN_ERR "%pOF: Can't get registers address\n", np);
>   goto err_irq_unmap;
>   }
>  // TODO : request_mem_region
>  dev->emacp = ioremap(dev->rsrc_regs.start,
>   resource_size(&dev->rsrc_regs));
>  ...

If you want to go for 101%: you could get rid of this block
altogether by doing: 
dev->emacp = of_iomap(np, 0);

Note1:
This will also make the rsrc_regs variable in the emac_instance
struct redundant. So simply remove it from the core.h.

Note2: if you want to go for 110%, you could replace this with
platform_get_resource() and devm_ioremap_resource() (if you
are interested, take a look at devm_ioremap_resource's kdoc
it has an example).

Thanks,
Christian


[PATCH v2 1/2] net: emac: fix reset timeout with AR8035 phy

2017-06-07 Thread Christian Lamparter
This patch fixes a problem where the AR8035 PHY can't be
detected on an Cisco Meraki MR24, if the ethernet cable is
not connected on boot.

Russell Senior provided steps to reproduce the issue:
|Disconnect ethernet cable, apply power, wait until device has booted,
|plug in ethernet, check for interfaces, no eth0 is listed.
|
|This appears to be a problem during probing of the AR8035 Phy chip.
|When ethernet has no link, the phy detection fails, and eth0 is not
|created. Plugging ethernet later has no effect, because there is no
|interface as far as the kernel is concerned. The relevant part of
|the boot log looks like this:
|this is the failing case:
|
|[0.876611] /plb/opb/emac-rgmii@ef601500: input 0 in RGMII mode
|[0.882532] /plb/opb/ethernet@ef600c00: reset timeout
|[0.888546] /plb/opb/ethernet@ef600c00: can't find PHY!
|and the succeeding case:
|
|[0.876672] /plb/opb/emac-rgmii@ef601500: input 0 in RGMII mode
|[0.883952] eth0: EMAC-0 /plb/opb/ethernet@ef600c00, MAC 00:01:..
|[0.890822] eth0: found Atheros 8035 Gigabit Ethernet PHY (0x01)

Based on the comment and the commit message of
commit 23fbb5a87c56 ("emac: Fix EMAC soft reset on 460EX/GT").
This is because the AR8035 PHY doesn't provide the TX Clock,
if the ethernet cable is not attached. This causes the reset
to timeout and the PHY detection code in emac_init_phy() is
unable to detect the AR8035 PHY. As a result, the emac driver
bails out early and the user left with no ethernet.

In order to stay compatible with existing configurations, the driver
tries the current reset approach at first. Only if the first attempt
timed out, it does perform one more retry with the clock temporarily
switched to the internal source for just the duration of the reset.

LEDE-Bug: #687 <https://bugs.lede-project.org/index.php?do=details&task_id=687>

Cc: Chris Blake 
Reported-by: Russell Senior 
Fixes: 23fbb5a87c56e98 ("emac: Fix EMAC soft reset on 460EX/GT")
Signed-off-by: Christian Lamparter 
---
v1 -> v2:
- made it clear, that the clock source is only switched
  temporarily.
- fixed missing goto label, if !CONFIG_PPC_DCR_NATIVE
---
 drivers/net/ethernet/ibm/emac/core.c | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 508923f39ccf..b6e871bfb659 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -343,6 +343,7 @@ static int emac_reset(struct emac_instance *dev)
 {
struct emac_regs __iomem *p = dev->emacp;
int n = 20;
+   bool __maybe_unused try_internal_clock = false;
 
DBG(dev, "reset" NL);
 
@@ -355,6 +356,7 @@ static int emac_reset(struct emac_instance *dev)
}
 
 #ifdef CONFIG_PPC_DCR_NATIVE
+do_retry:
/*
 * PPC460EX/GT Embedded Processor Advanced User's Manual
 * section 28.10.1 Mode Register 0 (EMACx_MR0) states:
@@ -362,10 +364,19 @@ static int emac_reset(struct emac_instance *dev)
 * of the EMAC. If none is present, select the internal clock
 * (SDR0_ETH_CFG[EMACx_PHY_CLK] = 1).
 * After a soft reset, select the external clock.
+*
+* The AR8035-A PHY Meraki MR24 does not provide a TX Clk if the
+* ethernet cable is not attached. This causes the reset to timeout
+* and the PHY detection code in emac_init_phy() is unable to
+* communicate and detect the AR8035-A PHY. As a result, the emac
+* driver bails out early and the user has no ethernet.
+* In order to stay compatible with existing configurations, the
+* driver will temporarily switch to the internal clock, after
+* the first reset fails.
 */
if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) {
-   if (dev->phy_address == 0x &&
-   dev->phy_map == 0x) {
+   if (try_internal_clock || (dev->phy_address == 0x &&
+  dev->phy_map == 0x)) {
/* No PHY: select internal loop clock before reset */
dcri_clrset(SDR0, SDR0_ETH_CFG,
0, SDR0_ETH_CFG_ECS << dev->cell_index);
@@ -383,8 +394,15 @@ static int emac_reset(struct emac_instance *dev)
 
 #ifdef CONFIG_PPC_DCR_NATIVE
if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) {
-   if (dev->phy_address == 0x &&
-   dev->phy_map == 0x) {
+   if (!n && !try_internal_clock) {
+   /* first attempt has timed out. */
+   n = 20;
+   try_internal_clock = true;
+   goto do_retry;
+   }
+
+   if (t

[PATCH v2 2/2] net: emac: fix and unify emac_mdio functions

2017-06-07 Thread Christian Lamparter
emac_mdio_read_link() was not copying the requested phy settings
back into the emac driver's own phy api. This has caused a link
speed mismatch issue for the AR8035 as the emac driver kept
trying to connect with 10/100MBps on a 1GBit/s link.

This patch also unifies shared code between emac_setup_aneg()
and emac_mdio_setup_forced(). And furthermore it removes
a chunk of emac_mdio_init_phy(), that was copying the same
data into itself.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/core.c | 41 
 1 file changed, 18 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index b6e871bfb659..259e69a52ec5 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -2478,20 +2478,24 @@ static int emac_mii_bus_reset(struct mii_bus *bus)
return emac_reset(dev);
 }
 
+static int emac_mdio_phy_start_aneg(struct mii_phy *phy,
+   struct phy_device *phy_dev)
+{
+   phy_dev->autoneg = phy->autoneg;
+   phy_dev->speed = phy->speed;
+   phy_dev->duplex = phy->duplex;
+   phy_dev->advertising = phy->advertising;
+   return phy_start_aneg(phy_dev);
+}
+
 static int emac_mdio_setup_aneg(struct mii_phy *phy, u32 advertise)
 {
struct net_device *ndev = phy->dev;
struct emac_instance *dev = netdev_priv(ndev);
 
-   dev->phy.autoneg = AUTONEG_ENABLE;
-   dev->phy.speed = SPEED_1000;
-   dev->phy.duplex = DUPLEX_FULL;
-   dev->phy.advertising = advertise;
phy->autoneg = AUTONEG_ENABLE;
-   phy->speed = dev->phy.speed;
-   phy->duplex = dev->phy.duplex;
phy->advertising = advertise;
-   return phy_start_aneg(dev->phy_dev);
+   return emac_mdio_phy_start_aneg(phy, dev->phy_dev);
 }
 
 static int emac_mdio_setup_forced(struct mii_phy *phy, int speed, int fd)
@@ -2499,13 +2503,10 @@ static int emac_mdio_setup_forced(struct mii_phy *phy, 
int speed, int fd)
struct net_device *ndev = phy->dev;
struct emac_instance *dev = netdev_priv(ndev);
 
-   dev->phy.autoneg =  AUTONEG_DISABLE;
-   dev->phy.speed = speed;
-   dev->phy.duplex = fd;
phy->autoneg = AUTONEG_DISABLE;
phy->speed = speed;
phy->duplex = fd;
-   return phy_start_aneg(dev->phy_dev);
+   return emac_mdio_phy_start_aneg(phy, dev->phy_dev);
 }
 
 static int emac_mdio_poll_link(struct mii_phy *phy)
@@ -2527,16 +2528,17 @@ static int emac_mdio_read_link(struct mii_phy *phy)
 {
struct net_device *ndev = phy->dev;
struct emac_instance *dev = netdev_priv(ndev);
+   struct phy_device *phy_dev = dev->phy_dev;
int res;
 
-   res = phy_read_status(dev->phy_dev);
+   res = phy_read_status(phy_dev);
if (res)
return res;
 
-   dev->phy.speed = phy->speed;
-   dev->phy.duplex = phy->duplex;
-   dev->phy.pause = phy->pause;
-   dev->phy.asym_pause = phy->asym_pause;
+   phy->speed = phy_dev->speed;
+   phy->duplex = phy_dev->duplex;
+   phy->pause = phy_dev->pause;
+   phy->asym_pause = phy_dev->asym_pause;
return 0;
 }
 
@@ -2546,13 +2548,6 @@ static int emac_mdio_init_phy(struct mii_phy *phy)
struct emac_instance *dev = netdev_priv(ndev);
 
phy_start(dev->phy_dev);
-   dev->phy.autoneg = phy->autoneg;
-   dev->phy.speed = phy->speed;
-   dev->phy.duplex = phy->duplex;
-   dev->phy.advertising = phy->advertising;
-   dev->phy.pause = phy->pause;
-   dev->phy.asym_pause = phy->asym_pause;
-
return phy_init_hw(dev->phy_dev);
 }
 
-- 
2.11.0



Re: [PATCH v1 2/2] net: emac: fix and unify emac_mdio functions

2017-06-05 Thread Christian Lamparter
On Monday, June 5, 2017 11:43:33 PM CEST Andrew Lunn wrote:
> On Mon, Jun 05, 2017 at 10:49:40PM +0200, Christian Lamparter wrote:
> > emac_mdio_read_link() was not copying the requested phy settings
> > back into the emac driver's own phy api. This has caused a link
> > speed mismatch issue for the AR8035 as the emac driver kept
> > trying to connect with 10/100MBps on a 1GBit/s link.

> In the long run, you might want to remove the emac phy drivers. 
> Linux has PHYLIB drivers for all but the bcm5248.

Hello Andrew

Back in February I added PHYLIB support to emac.
<https://www.spinics.net/lists/netdev/msg421734.html> ;)

I could add a separate patch that adds a oneliner message like:
pr_info("EMAC supports PHYLIB. Please convert your device to it.\n");
at the right place (emac_mii_phy_probe) to let people know about it.

Is that Ok? If not, please tell me what the appropriate deprecation 
notice should look like.

About the MR24:
I do have a patchset to convert the MR24 to use PHYLIB's at803x as well.
<https://github.com/chunkeey/apm82181-lede/commit/82c50b7f4fca68ce905d4a7a3559700635bf227f>
But because of AT8035 "special tx/rx delay" requirements, this
will need a patched at803x.c driver as well.

Regards,
Christian




Re: [PATCH v1 1/2] net: emac: fix reset timeout with AR8035 phy

2017-06-05 Thread Christian Lamparter
On Monday, June 5, 2017 11:26:17 PM CEST Andrew Lunn wrote:
> > In order to stay compatible with existing configurations, the
> > driver will try the normal reset first and only falls back to
> > to the internal clock, after the first reset fails. If the
> > second reset fails as well, it will give up as before.
> 
> Hi Christian
> 
> This gets things probed correctly. But should you swap back to the PHY
> clock when the PHY declares the link up? Is there code already to do
> this?
> 
>   Andrew
> 
Oh, sorry. I omitted this from the commit message. But the proposed 
emac_reset() code  switched to the internal clock only after the first attempt
has failed AND only for the duration of the reset.

If the reset succeeds or the reset times out, the clock is always switched 
back to the external clock.

Thanks,
Christian



[PATCH v1 1/2] net: emac: fix reset timeout with AR8035 phy

2017-06-05 Thread Christian Lamparter
This patch fixes a problem where the AR8035 PHY can't be
detected on an Cisco Meraki MR24, if the ethernet cable is
not connected on boot.

Russell Senior provided steps to reproduce the issue:
|Disconnect ethernet cable, apply power, wait until device has booted,
|plug in ethernet, check for interfaces, no eth0 is listed.
|
|This appears to be a problem during probing of the AR8035 Phy chip.
|When ethernet has no link, the phy detection fails, and eth0 is not
|created. Plugging ethernet later has no effect, because there is no
|interface as far as the kernel is concerned. The relevant part of
|the boot log looks like this:
|this is the failing case:
|
|[0.876611] /plb/opb/emac-rgmii@ef601500: input 0 in RGMII mode
|[0.882532] /plb/opb/ethernet@ef600c00: reset timeout
|[0.888546] /plb/opb/ethernet@ef600c00: can't find PHY!
|and the succeeding case:
|
|[0.876672] /plb/opb/emac-rgmii@ef601500: input 0 in RGMII mode
|[0.883952] eth0: EMAC-0 /plb/opb/ethernet@ef600c00, MAC 00:01:..
|[0.890822] eth0: found Atheros 8035 Gigabit Ethernet PHY (0x01)

Based on the comment and the commit message of
commit 23fbb5a87c56 ("emac: Fix EMAC soft reset on 460EX/GT").
This is because the AR8035 PHY of the Meraki MR24 does not
provide the TX Clk, if the ethernet cable is not attached.
This causes the reset to timeout and the PHY detection code
in emac_init_phy() is unable to detect the AR8035 PHY.
As a result, the emac driver bails out early and the user
has no ethernet.

In order to stay compatible with existing configurations, the
driver will try the normal reset first and only falls back to
to the internal clock, after the first reset fails. If the
second reset fails as well, it will give up as before.

LEDE-Bug: #687 <https://bugs.lede-project.org/index.php?do=details&task_id=687>

Cc: Chris Blake 
Reported-by: Russell Senior 
Fixes: 23fbb5a87c56e98 ("emac: Fix EMAC soft reset on 460EX/GT")
Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/core.c | 32 +---
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 508923f39ccf..18af1116fa1d 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -343,6 +343,7 @@ static int emac_reset(struct emac_instance *dev)
 {
struct emac_regs __iomem *p = dev->emacp;
int n = 20;
+   bool try_internal_clock = false;
 
DBG(dev, "reset" NL);
 
@@ -355,6 +356,7 @@ static int emac_reset(struct emac_instance *dev)
}
 
 #ifdef CONFIG_PPC_DCR_NATIVE
+do_retry:
/*
 * PPC460EX/GT Embedded Processor Advanced User's Manual
 * section 28.10.1 Mode Register 0 (EMACx_MR0) states:
@@ -362,10 +364,19 @@ static int emac_reset(struct emac_instance *dev)
 * of the EMAC. If none is present, select the internal clock
 * (SDR0_ETH_CFG[EMACx_PHY_CLK] = 1).
 * After a soft reset, select the external clock.
+*
+* The AR8035-A PHY Meraki MR24 does not provide a TX Clk if the
+* ethernet cable is not attached. This causes the reset to timeout
+* and the PHY detection code in emac_init_phy() is unable to
+* communicate and detect the AR8035-A PHY. As a result, the emac
+* driver bails out early and the user has no ethernet.
+* In order to stay compatible with existing configurations, the
+* driver will fall back to and switch to the internal clock, after
+* the first reset fails.
 */
if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) {
-   if (dev->phy_address == 0x &&
-   dev->phy_map == 0x) {
+   if (try_internal_clock || (dev->phy_address == 0x &&
+  dev->phy_map == 0x)) {
/* No PHY: select internal loop clock before reset */
dcri_clrset(SDR0, SDR0_ETH_CFG,
0, SDR0_ETH_CFG_ECS << dev->cell_index);
@@ -383,8 +394,8 @@ static int emac_reset(struct emac_instance *dev)
 
 #ifdef CONFIG_PPC_DCR_NATIVE
if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) {
-   if (dev->phy_address == 0x &&
-   dev->phy_map == 0x) {
+   if (try_internal_clock || (dev->phy_address == 0x &&
+  dev->phy_map == 0x)) {
/* No PHY: restore external clock source after reset */
dcri_clrset(SDR0, SDR0_ETH_CFG,
SDR0_ETH_CFG_ECS << dev->cell_index, 0);
@@ -396,9 +407,16 @@ static int emac_reset(struct emac_instance *dev)
   

[PATCH v1 2/2] net: emac: fix and unify emac_mdio functions

2017-06-05 Thread Christian Lamparter
emac_mdio_read_link() was not copying the requested phy settings
back into the emac driver's own phy api. This has caused a link
speed mismatch issue for the AR8035 as the emac driver kept
trying to connect with 10/100MBps on a 1GBit/s link.

This patch also unifies shared code between emac_setup_aneg()
and emac_mdio_setup_forced(). And furthermore it removes
a chunk of emac_mdio_init_phy(), that was copying the same
data into itself.

Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/core.c | 41 
 1 file changed, 18 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 18af1116fa1d..8cfb148cfdb0 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -2478,20 +2478,24 @@ static int emac_mii_bus_reset(struct mii_bus *bus)
return emac_reset(dev);
 }
 
+static int emac_mdio_phy_start_aneg(struct mii_phy *phy,
+   struct phy_device *phy_dev)
+{
+   phy_dev->autoneg = phy->autoneg;
+   phy_dev->speed = phy->speed;
+   phy_dev->duplex = phy->duplex;
+   phy_dev->advertising = phy->advertising;
+   return phy_start_aneg(phy_dev);
+}
+
 static int emac_mdio_setup_aneg(struct mii_phy *phy, u32 advertise)
 {
struct net_device *ndev = phy->dev;
struct emac_instance *dev = netdev_priv(ndev);
 
-   dev->phy.autoneg = AUTONEG_ENABLE;
-   dev->phy.speed = SPEED_1000;
-   dev->phy.duplex = DUPLEX_FULL;
-   dev->phy.advertising = advertise;
phy->autoneg = AUTONEG_ENABLE;
-   phy->speed = dev->phy.speed;
-   phy->duplex = dev->phy.duplex;
phy->advertising = advertise;
-   return phy_start_aneg(dev->phy_dev);
+   return emac_mdio_phy_start_aneg(phy, dev->phy_dev);
 }
 
 static int emac_mdio_setup_forced(struct mii_phy *phy, int speed, int fd)
@@ -2499,13 +2503,10 @@ static int emac_mdio_setup_forced(struct mii_phy *phy, 
int speed, int fd)
struct net_device *ndev = phy->dev;
struct emac_instance *dev = netdev_priv(ndev);
 
-   dev->phy.autoneg =  AUTONEG_DISABLE;
-   dev->phy.speed = speed;
-   dev->phy.duplex = fd;
phy->autoneg = AUTONEG_DISABLE;
phy->speed = speed;
phy->duplex = fd;
-   return phy_start_aneg(dev->phy_dev);
+   return emac_mdio_phy_start_aneg(phy, dev->phy_dev);
 }
 
 static int emac_mdio_poll_link(struct mii_phy *phy)
@@ -2527,16 +2528,17 @@ static int emac_mdio_read_link(struct mii_phy *phy)
 {
struct net_device *ndev = phy->dev;
struct emac_instance *dev = netdev_priv(ndev);
+   struct phy_device *phy_dev = dev->phy_dev;
int res;
 
-   res = phy_read_status(dev->phy_dev);
+   res = phy_read_status(phy_dev);
if (res)
return res;
 
-   dev->phy.speed = phy->speed;
-   dev->phy.duplex = phy->duplex;
-   dev->phy.pause = phy->pause;
-   dev->phy.asym_pause = phy->asym_pause;
+   phy->speed = phy_dev->speed;
+   phy->duplex = phy_dev->duplex;
+   phy->pause = phy_dev->pause;
+   phy->asym_pause = phy_dev->asym_pause;
return 0;
 }
 
@@ -2546,13 +2548,6 @@ static int emac_mdio_init_phy(struct mii_phy *phy)
struct emac_instance *dev = netdev_priv(ndev);
 
phy_start(dev->phy_dev);
-   dev->phy.autoneg = phy->autoneg;
-   dev->phy.speed = phy->speed;
-   dev->phy.duplex = phy->duplex;
-   dev->phy.advertising = phy->advertising;
-   dev->phy.pause = phy->pause;
-   dev->phy.asym_pause = phy->asym_pause;
-
return phy_init_hw(dev->phy_dev);
 }
 
-- 
2.11.0



Re: [PATCH] p54: add null pointer check before releasing socket buffer

2017-04-10 Thread Christian Lamparter
On Monday, April 10, 2017 1:54:14 PM CEST Myungho Jung wrote:
> On Mon, Apr 10, 2017 at 02:12:54PM +0200, Christian Lamparter wrote:
> > On Sunday, April 9, 2017 10:23:20 PM CEST Myungho Jung wrote:
> > > Kernel panic is caused by trying to dereference null pointer. Check if
> > > the pointer is null before freeing space.
> >  [...]
> > As for adding if (!skb) checks. I think kfree, kfree_skb, dev_kfree_skb 
> > (aka consume_skb) all check for null pointers already. So the logical
> > thing to do would be to make dev_kfree_skb_irq (which would also fix
> > dev_kfree_skb_any) consistent with kfree, kfree_skb, dev_kfree_skb and
> > add the check there.
> > > ---
> > >  drivers/net/wireless/intersil/p54/txrx.c | 8 ++--
> > >  1 file changed, 6 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/net/wireless/intersil/p54/txrx.c 
> > > b/drivers/net/wireless/intersil/p54/txrx.c
> > > index 1af7da0..8956061 100644
> > > --- a/drivers/net/wireless/intersil/p54/txrx.c
> > > +++ b/drivers/net/wireless/intersil/p54/txrx.c
> > > @@ -503,7 +503,9 @@ static void p54_rx_eeprom_readback(struct p54_common 
> > > *priv,
> > >  
> > >   priv->eeprom = NULL;
> > >   tmp = p54_find_and_unlink_skb(priv, hdr->req_id);
> > > - dev_kfree_skb_any(tmp);
> > > + if (unlikely(!tmp))
> > > + dev_kfree_skb_any(tmp);
> > > +
> > >   complete(&priv->eeprom_comp);
> > >  }
> > >  
> > > @@ -597,7 +599,9 @@ static void p54_rx_stats(struct p54_common *priv, 
> > > struct sk_buff *skb)
> > >   }
> > >  
> > >   tmp = p54_find_and_unlink_skb(priv, hdr->req_id);
> > > - dev_kfree_skb_any(tmp);
> > > + if (unlikely(!tmp))
> > > + dev_kfree_skb_any(tmp);
> > > +
> > >   complete(&priv->stat_comp);
> > >  }
> > >  
> > > 
> > 
> > 
> [...] I'm not sure it actually caused kernel panic but guessed from
> a bug report [https://bugzilla.kernel.org/show_bug.cgi?id=195289].
Thank you for bringing this to my attention. Reading the bugreport, it
does sound like there's a bigger issue with the USB Ports. I'll see if
this can be fixed. But it does sound like a hardware issue at this 
point.

> And correct fix will be like this:
>   if (likely(tmp))
>   dev_kfree_skb_any(tmp);
> 
> But, like you said, I think null pointer should be checked in
> dev_kfree_skb_irq although already checking before calling it in many
> other places. I'll try another patch. Thank you for your advice.

Well, the patch could be as simple as this:
---
diff --git a/net/core/dev.c b/net/core/dev.c
index 7869ae3837ca..44f7d5a1c67c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2450,6 +2450,9 @@ void __dev_kfree_skb_irq(struct sk_buff *skb, enum 
skb_free_reason reason)
 {
unsigned long flags;
 
+   if (!skb)
+   return;
+
if (likely(atomic_read(&skb->users) == 1)) {
smp_rmb();
atomic_set(&skb->users, 0);
---

The question is: would David or Eric support the change. Any comments,
what's the prefered solution? Just patch __dev_kfree_skb_irq to make
it consistent with *kfree*, or patch the driver? I'm fine either way,
but I would prefere patching __dev_kfree_skb_irq.

Regards,
Christian


Re: [PATCH] p54: add null pointer check before releasing socket buffer

2017-04-10 Thread Christian Lamparter
(Added linux-wireless, since this is a wireless driver)

On Sunday, April 9, 2017 10:23:20 PM CEST Myungho Jung wrote:
> Kernel panic is caused by trying to dereference null pointer. Check if
> the pointer is null before freeing space.
Do you have the kernel panic somewhere?
I think you have an even bigger problem: You see, in order to get EEPROM
readback and rx_stats feedback you need to sent a request to the firmware
and if the response's req_id cookies don't match, you end up filling up 
the very limited device address space.

As for adding if (!skb) checks. I think kfree, kfree_skb, dev_kfree_skb 
(aka consume_skb) all check for null pointers already. So the logical
thing to do would be to make dev_kfree_skb_irq (which would also fix
dev_kfree_skb_any) consistent with kfree, kfree_skb, dev_kfree_skb and
add the check there.

> Signed-off-by: Myungho Jung 
> ---
>  drivers/net/wireless/intersil/p54/txrx.c | 8 ++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/intersil/p54/txrx.c 
> b/drivers/net/wireless/intersil/p54/txrx.c
> index 1af7da0..8956061 100644
> --- a/drivers/net/wireless/intersil/p54/txrx.c
> +++ b/drivers/net/wireless/intersil/p54/txrx.c
> @@ -503,7 +503,9 @@ static void p54_rx_eeprom_readback(struct p54_common 
> *priv,
>  
>   priv->eeprom = NULL;
>   tmp = p54_find_and_unlink_skb(priv, hdr->req_id);
> - dev_kfree_skb_any(tmp);
> + if (unlikely(!tmp))
> + dev_kfree_skb_any(tmp);
> +
>   complete(&priv->eeprom_comp);
>  }
>  
> @@ -597,7 +599,9 @@ static void p54_rx_stats(struct p54_common *priv, struct 
> sk_buff *skb)
>   }
>  
>   tmp = p54_find_and_unlink_skb(priv, hdr->req_id);
> - dev_kfree_skb_any(tmp);
> + if (unlikely(!tmp))
> + dev_kfree_skb_any(tmp);
> +
>   complete(&priv->stat_comp);
>  }
>  
> 




Re: [PATCH 1/7] Documentation: dt: net: Update the ath9k binding for SoC devices

2017-03-28 Thread Christian Lamparter
On Tuesday, March 28, 2017 6:41:59 PM CEST Andrew Lunn wrote:
> > Oh, in that case you should probably go "all out" and ask on the 
> > LKML to remove all of the ath9k and ath10k ahb work. From what I
> > know all the "users" are running some sort of OpenWRT/LEDE or a 
> > derivative. This is because Atheros/QCA provided a SDK based on
> > OpenWRT.
> > 
> > Alban has been trying to convert the platform to device-tree
> > and add them to the mainline for a while now:
> >  
> > https://patchwork.kernel.org/patch/6514551/
> > 
> > So, you are questioning this work as well.
> 
> Not at all. Ralph Sennhauser has been doing a great job of getting all
> the Marvell devices into Mainline, and i help as much as i can, being
> one of the Marvell SoC Maintainers.
> 
> I'm just saying, get a few boards which require these facilities into
> the mainline, and then you have a much stronger base to argue from.

I was arguing not to deprecate "qca,no-eeprom" property.

based on this quote from Linus' :
|if a new interface is truly more flexible, then it should be able
|to implement the old interface with no changes, so that drivers
|shouldn't need to be changed/upgraded.

what stronger point to do you want?

Thanks,
Christian


Re: [PATCH 1/7] Documentation: dt: net: Update the ath9k binding for SoC devices

2017-03-28 Thread Christian Lamparter
On Tuesday, March 28, 2017 5:18:37 PM CEST Andrew Lunn wrote:
> > But LEDE/OpenWRT rely on the firmware loading API more than ever and 
> > currently there is not a replacement for it.
> 
> 
> 
> 
> > I looked into 10-ath9k-eeprom [0] of LEDE's AR71XX target and I noticed
> > that quite a few devices patch the MACs of the wifi.
> > If you look at the code for the Airtight C-55 and C-60, Meraki MR18,
> > Meraki Z1, you'll notice that each one has to add a fixed value (+1,
> > +2, ...) to the extraced MAC-Address. So how would you replicate this,
> > with "nvmem-cell-names = address" without some sort of 
> > nvmem-provider-processor?
> 
> ...
>  
> > https://github.com/lede-project/source/blob/master/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c#L1204
> > 
> > and grep lists the following devices:
> > mach-dgl-5500-a1.c, mach-dhp-1565-a1.c, mach-dir-505-a1.c, mach-dir-615-c1.c
> > mach-dir-615-i1.c, mach-dir-825-b1.c, mach-dir-825-c1.c, mach-tew-673gru.c
> > mach-tew-712br.c, mach-tew-732br.c, mach-tew-823dru.c
> 
> I would say a big part of the problem is that all of these use cases
> are outside of mainline. Why should mainline support something which
> is not actually used in mainline.
> 
> So i would suggest your first step is to bring some of these devices
> into mainline. Once in mainline, it becomes a mainline issue, and
> people will help get it solved.
>
Oh, in that case you should probably go "all out" and ask on the 
LKML to remove all of the ath9k and ath10k ahb work. From what I
know all the "users" are running some sort of OpenWRT/LEDE or a 
derivative. This is because Atheros/QCA provided a SDK based on
OpenWRT.

Alban has been trying to convert the platform to device-tree
and add them to the mainline for a while now:
 
https://patchwork.kernel.org/patch/6514551/

So, you are questioning this work as well.

Thanks,
Christian


Re: [PATCH 1/7] Documentation: dt: net: Update the ath9k binding for SoC devices

2017-03-28 Thread Christian Lamparter
On Tuesday, March 28, 2017 10:44:41 AM CEST Alban wrote:
> On Mon, 27 Mar 2017 18:11:15 +0200
> Christian Lamparter  wrote:
> 
> > On Monday, March 13, 2017 10:05:09 PM CEST Alban wrote:
> > > The current binding only cover PCI devices so extend it for SoC devices.
> > > 
> > > Most SoC platforms use an MTD partition for the calibration data
> > > instead of an EEPROM. The qca,no-eeprom property was added to allow
> > > loading the EEPROM content using firmware loading. This new binding
> > > replace this hack with NVMEM cells, so we also mark the qca,no-eeprom
> > > property as deprecated in case anyone ever used it.  
> > 
> > Please don't mark "qca,no-eeprom" as deprecated then.
> > If some devices geniously need to rely on userspace for extracting 
> > and processing the calibration data, it should be stay a
> > optional properties.
> 
> Deprecated just mean that it shouldn't be used for new devices. 
> But as it is not used by any board, misuse the firmware loading API and
> firmware loader user helper are deprecated in udev, I find we could also
> just drop it.
But LEDE/OpenWRT rely on the firmware loading API more than ever and 
currently there is not a replacement for it. From what I know, Luis 
tried to replace it with his sysdata approach:

<https://lkml.org/lkml/2016/12/16/204>

however, this was disliked by Greg KH and Linus for the following reasons.
<https://lkml.org/lkml/2016/6/16/995>:

|So I absolutely abhor "changes for changes sake".
|
|If the existing code works for existing drivers, let them keep it.
|
|And if a new interface is truly more flexible, then it should be able
|to implement the old interface with no changes, so that drivers
|shouldn't need to be changed/upgraded.
|
|Then, drivers that actually _want_ new features, or that can take
|advantage of new interfaces to actually make things *simpler*, can
|choose to make those changes. But those changes should have real
|advantages.
|[...]


your nvmem approach would need to be as universal and
powerful as the "qca,no-eeprom" + userspace solutions
in order to deprecate it.
 
> > For example: A device that can't do easily without "qca,no-eeprom" is
> > the AVM FRITZ!WLAN Repeater 300E. For this device, the caldata 
> > is stored in the flash, however for whatever reason the vendor
> > choose to "reverse" it. (like completely back to front, not byteswapped
> > or something). So an extra "unreversing step" is required. So, it would
> > require some sort of a special nvmem-provider-processor as an 
> > alternative.
> 
> Or just handle this special eeprom format in the ath9k driver. I doubt
> that this case is so common that it would justify adding a whole new
> layer to nvmem.
Well, you'll have to deal with it in nvmem, if you want it to deprecate
"qca,no-eeprom".

I looked into 10-ath9k-eeprom [0] of LEDE's AR71XX target and I noticed
that quite a few devices patch the MACs of the wifi.
If you look at the code for the Airtight C-55 and C-60, Meraki MR18,
Meraki Z1, you'll notice that each one has to add a fixed value (+1,
+2, ...) to the extraced MAC-Address. So how would you replicate this,
with "nvmem-cell-names = address" without some sort of 
nvmem-provider-processor?

Also, there's another usecase of a nvmem-provider-processor. 
For example, one could be convert all the different types of
ascii-macs (Either strings like "00:11:22:33:44:55", 
"00.11.22.33..." or "00112233..." ) to their binary representation.
For AR71XX, this is mostly done by ath79_parse_ascii_mac:

https://github.com/lede-project/source/blob/master/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c#L1204

and grep lists the following devices:
mach-dgl-5500-a1.c, mach-dhp-1565-a1.c, mach-dir-505-a1.c, mach-dir-615-c1.c
mach-dir-615-i1.c, mach-dir-825-b1.c, mach-dir-825-c1.c, mach-tew-673gru.c
mach-tew-712br.c, mach-tew-732br.c, mach-tew-823dru.c

I did a quick check: All of them use the extracted MACs for ath9k
and/or ethernet.

Note: I think Ralink/MediaTek will have the same issues.

> > >  Optional properties:
> > > +- mac-address: See ethernet.txt in the parent directory
> > > +- local-mac-address: See ethernet.txt in the parent directory
> > > [...]
> > > +
> > > +Deprecated properties:
> > >  - qca,no-eeprom: Indicates that there is no physical EEPROM
> > > connected to the ath9k wireless chip (in this case the calibration /
> > >   EEPROM data will be loaded from userspace
> > > using the kernel firmware loader).
> > > -- mac-address: See ethernet.txt in the parent directory
> > > -- local-mac

Re: [PATCH 1/7] Documentation: dt: net: Update the ath9k binding for SoC devices

2017-03-27 Thread Christian Lamparter
On Monday, March 13, 2017 10:05:09 PM CEST Alban wrote:
> The current binding only cover PCI devices so extend it for SoC devices.
> 
> Most SoC platforms use an MTD partition for the calibration data
> instead of an EEPROM. The qca,no-eeprom property was added to allow
> loading the EEPROM content using firmware loading. This new binding
> replace this hack with NVMEM cells, so we also mark the qca,no-eeprom
> property as deprecated in case anyone ever used it.

Please don't mark "qca,no-eeprom" as deprecated then.
If some devices geniously need to rely on userspace for extracting 
and processing the calibration data, it should be stay a
optional properties.

For example: A device that can't do easily without "qca,no-eeprom" is
the AVM FRITZ!WLAN Repeater 300E. For this device, the caldata 
is stored in the flash, however for whatever reason the vendor
choose to "reverse" it. (like completely back to front, not byteswapped
or something). So an extra "unreversing step" is required. So, it would
require some sort of a special nvmem-provider-processor as an 
alternative.

> Signed-off-by: Alban 
> ---
> diff --git a/Documentation/devicetree/bindings/net/wireless/qca,ath9k.txt 
> b/Documentation/devicetree/bindings/net/wireless/qca,ath9k.txt
> index b7396c8..61f5f6d 100644
> --- a/Documentation/devicetree/bindings/net/wireless/qca,ath9k.txt
> +++ b/Documentation/devicetree/bindings/net/wireless/qca,ath9k.txt
> @@ -27,16 +27,34 @@ Required properties:
>   - 0034 for AR9462
>   - 0036 for AR9565
>   - 0037 for AR9485
> + For SoC devices the compatible should be "qca,-wmac"
> + and one of the following fallbacks:
> + - "qca,ar9100-wmac"
> + - "qca,ar9330-wmac"
> + - "qca,ar9340-wmac"
> + - "qca,qca9550-wmac"
> + - "qca,qca9530-wmac"
>  - reg: Address and length of the register set for the device.
>  
> +Required properties for SoC devices:
> +- interrupt-parent: phandle of the parent interrupt controller.
> +- interrupts: Interrupt specifier for the controllers interrupt.
> +
>  Optional properties:
> +- mac-address: See ethernet.txt in the parent directory
> +- local-mac-address: See ethernet.txt in the parent directory
> +- clock-names: has to be "ref"
> +- clocks: phandle of the reference clock
> +- resets: phandle of the reset line
> +- nvmem-cell-names: has to be "eeprom" and/or "address"
> +- nvmem-cells: phandle to the eeprom nvmem cell and/or to the mac address
> + nvmem cell.
> +
> +Deprecated properties:
>  - qca,no-eeprom: Indicates that there is no physical EEPROM connected to the
>   ath9k wireless chip (in this case the calibration /
>   EEPROM data will be loaded from userspace using the
>   kernel firmware loader).
> -- mac-address: See ethernet.txt in the parent directory
> -- local-mac-address: See ethernet.txt in the parent directory
> -
It sounds like you want to deprecate mac-address and local-mac-address as well.
If so you sould add this to the commit as well. From my point of view, people
mostly flat-out patched the eeprom-image if they wanted to set the mac-address.
However, this was an extra step, if nvmem does away with it, I'm completely
fine with deprecating these properties.

Thanks,
Christian


Re: [PATCH 3/7] ath9k: Add support for reading the EEPROM data using the nvmem API

2017-03-24 Thread Christian Lamparter
On Thursday, March 23, 2017 3:43:28 PM CET Alban wrote:
> On Tue, 14 Mar 2017 00:53:55 +0100
> Christian Lamparter  wrote:
> 
> > On Monday, March 13, 2017 10:05:11 PM CET Alban wrote:
> > > Currently SoC platforms use a firmware request to get the EEPROM data.
> > > This is mostly a hack and rely on using a user-helper scripts which is
> > > deprecated. A nicer alternative is to use the nvmem API which was
> > > designed for this kind of task.
> > > 
> > > Furthermore we let CONFIG_ATH9K_AHB select CONFIG_NVMEM as such
> > > devices will generally use this method for loading the EEPROM data.
> > > 
> > > Signed-off-by: Alban 
> > > ---
> > > @@ -654,6 +656,25 @@ static int ath9k_init_softc(u16 devid, struct 
> > > ath_softc *sc,
> > >   if (ret)
> > >   return ret;
> > >  
> > > + /* If the EEPROM hasn't been retrieved via firmware request
> > > +  * use the nvmem API insted.
> > > +  */
> > > + if (!ah->eeprom_blob) {
> > > + struct nvmem_cell *eeprom_cell;
> > > +
> > > + eeprom_cell = nvmem_cell_get(ah->dev, "eeprom");
> > > + if (!IS_ERR(eeprom_cell)) {
> > > + ah->eeprom_data = nvmem_cell_read(
> > > + eeprom_cell, &ah->eeprom_size);
> > > + nvmem_cell_put(eeprom_cell);
> > > +
> > > + if (IS_ERR(ah->eeprom_data)) {
> > > + dev_err(ah->dev, "failed to read eeprom");
> > > + return PTR_ERR(ah->eeprom_data);
> > > + }
> > > + }
> > > + }
> > > +
> > >   if (ath9k_led_active_high != -1)
> > >   ah->config.led_active_high = ath9k_led_active_high == 1;
> > >
> > Are you sure this works with AR93XX SoCs that have the calibration data
> > in the OTP?
> 
> I only tested this on an ar9132 platform, so it might well be that a
> few things are missing for the newer SoC. However this shouldn't break
> anything existing as a platform needs to define an nvmem cell on the
> athk9 device for this code to be used a all.

Yes, I looked at it.
+   eeprom_cell = nvmem_cell_get(ah->dev, "eeprom");
+   if (!IS_ERR(eeprom_cell)) {
+   ...
+   }
So if there's a error with the "eeprom" nvmem property,
(i.e.: it's not present) the driver should works as before.

Thanks,
Christian


Re: [PATCH 3/7] ath9k: Add support for reading the EEPROM data using the nvmem API

2017-03-13 Thread Christian Lamparter
On Monday, March 13, 2017 10:05:11 PM CET Alban wrote:
> Currently SoC platforms use a firmware request to get the EEPROM data.
> This is mostly a hack and rely on using a user-helper scripts which is
> deprecated. A nicer alternative is to use the nvmem API which was
> designed for this kind of task.
> 
> Furthermore we let CONFIG_ATH9K_AHB select CONFIG_NVMEM as such
> devices will generally use this method for loading the EEPROM data.
> 
> Signed-off-by: Alban 
> ---
> @@ -654,6 +656,25 @@ static int ath9k_init_softc(u16 devid, struct ath_softc 
> *sc,
>   if (ret)
>   return ret;
>  
> + /* If the EEPROM hasn't been retrieved via firmware request
> +  * use the nvmem API insted.
> +  */
> + if (!ah->eeprom_blob) {
> + struct nvmem_cell *eeprom_cell;
> +
> + eeprom_cell = nvmem_cell_get(ah->dev, "eeprom");
> + if (!IS_ERR(eeprom_cell)) {
> + ah->eeprom_data = nvmem_cell_read(
> + eeprom_cell, &ah->eeprom_size);
> + nvmem_cell_put(eeprom_cell);
> +
> + if (IS_ERR(ah->eeprom_data)) {
> + dev_err(ah->dev, "failed to read eeprom");
> + return PTR_ERR(ah->eeprom_data);
> + }
> + }
> + }
> +
>   if (ath9k_led_active_high != -1)
>   ah->config.led_active_high = ath9k_led_active_high == 1;
>  
Are you sure this works with AR93XX SoCs that have the calibration data
in the OTP?

I've added Chris to the CC, since he has a HiveAP 121 that has this
configuration, so he can test, whenever this is a problem or not.

But from what I can tell, devices with the calibration data in the
OTP would fail now. This is because the OTP is done by ath9k_hw_init()
which hasn't run yet (it's a bit further down the road in the same
function though). 

Note: the OTP doesn't store the whole caldata. Just a few parts.
A temporary "eeprom" gets constructed with the help of the 
ar9300_eep_templates in ar9003_eeprom.c's
ar9300_eeprom_restore_internal(). But from what I don't think, 
that the eeprom_blob is constructed/set by the functions in
ar9003_eeprom.

I think this will require an additional property like
qca,calibration-in-otp. What's your opinion?

Thanks,
Christian


[PATCH] net: ibm: emac: fix regression caused by emac_dt_phy_probe()

2017-03-06 Thread Christian Lamparter
Julian Margetson reported a panic on his SAM460EX with Kernel 4.11-rc1:
| Unable to handle kernel paging request for data at address 0x0014
| Oops: Kernel access of bad area, sig: 11 [#1]
| PREEMPT
| Canyonlands
| Modules linked in:
| CPU: 0 PID: 1 Comm: swapper Not tainted [...]
| task: ea838000 task.stack: ea836000
| NIP: c0599f5c LR: c0599dd8 CTR: 
| REGS: ea837c80 TRAP: 0300   Not tainted [...]
| MSR: 00029000 
|  CR: 24371242  XER: 2000
| DEAR: 0014 ESR: 
| GPR00: c0599ce8 ea837d30 ea838000 c0e52dcc c0d56ffb [...]
| NIP [c0599f5c] emac_probe+0xfb4/0x1304
| LR [c0599dd8] emac_probe+0xe30/0x1304
| Call Trace:
| [ea837d30] [c0599ce8] emac_probe+0xd40/0x1304 (unreliable)
| [ea837d80] [c0533504] platform_drv_probe+0x48/0x90
| [ea837da0] [c0531c14] driver_probe_device+0x15c/0x2c4
| [ea837dd0] [c0531e04] __driver_attach+0x88/0xb0
| ---[ end trace ... ]---

The problem is caused by emac_dt_phy_probe() returing success (0)
for existing device-trees configurations that do not specify a
"phy-handle" property. This caused the code to skip the existing
phy probe and setup. Which led to essential phy related
data-structures being uninitialized.

This patch also removes the unused variable in emac_dt_phy_connect().

Fixes: a577ca6badb5261d ("net: emac: add support for device-tree based PHY 
discovery and setup")
Reported-by: Julian Margetson 
Signed-off-by: Christian Lamparter 
---
 drivers/net/ethernet/ibm/emac/core.c | 25 +
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 275c2e2349ad..c44036d5761a 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -2589,8 +2589,6 @@ static int emac_dt_mdio_probe(struct emac_instance *dev)
 static int emac_dt_phy_connect(struct emac_instance *dev,
   struct device_node *phy_handle)
 {
-   int res;
-
dev->phy.def = devm_kzalloc(&dev->ofdev->dev, sizeof(*dev->phy.def),
GFP_KERNEL);
if (!dev->phy.def)
@@ -2617,7 +2615,7 @@ static int emac_dt_phy_probe(struct emac_instance *dev)
 {
struct device_node *np = dev->ofdev->dev.of_node;
struct device_node *phy_handle;
-   int res = 0;
+   int res = 1;
 
phy_handle = of_parse_phandle(np, "phy-handle", 0);
 
@@ -2714,13 +2712,24 @@ static int emac_init_phy(struct emac_instance *dev)
if (emac_has_feature(dev, EMAC_FTR_HAS_RGMII)) {
int res = emac_dt_phy_probe(dev);
 
-   mutex_unlock(&emac_phy_map_lock);
-   if (!res)
+   switch (res) {
+   case 1:
+   /* No phy-handle property configured.
+* Continue with the existing phy probe
+* and setup code.
+*/
+   break;
+
+   case 0:
+   mutex_unlock(&emac_phy_map_lock);
goto init_phy;
 
-   dev_err(&dev->ofdev->dev, "failed to attach dt phy (%d).\n",
-   res);
-   return res;
+   default:
+   mutex_unlock(&emac_phy_map_lock);
+   dev_err(&dev->ofdev->dev, "failed to attach dt phy 
(%d).\n",
+   res);
+   return res;
+   }
}
 
if (dev->phy_address != 0x)
-- 
2.11.0



[PATCH v1.2] dt: emac: document device-tree based phy discovery and setup

2017-02-27 Thread Christian Lamparter
This patch adds documentation for a new "phy-handle" property,
"fixed-link" and "mdio" sub-node. These allows the enumeration
of PHYs which are supported by the phy library under drivers/net/phy.

The EMAC ethernet controller in IBM and AMCC 4xx chips is
currently stuck with a few privately defined phy
implementations. It has no support for PHYs which
are supported by the generic phylib.

Acked-by: Rob Herring 
Signed-off-by: Christian Lamparter 
---
Fixed: phy node - so it conforms to phy.txt.
---
---
 .../devicetree/bindings/powerpc/4xx/emac.txt   | 61 +-
 1 file changed, 59 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt 
b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
index 712baf6c3e24..2fa861378294 100644
--- a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
+++ b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
@@ -71,6 +71,9 @@
  For Axon it can be absent, though my current driver
  doesn't handle phy-address yet so for now, keep
  0x00ff in it.
+- phy-handle   : Used to describe configurations where a external PHY
+ is used. Please refer to:
+ Documentation/devicetree/bindings/net/ethernet.txt
 - rx-fifo-size-gige : 1 cell, Rx fifo size in bytes for 1000 Mb/sec
  operations (if absent the value is the same as
  rx-fifo-size).  For Axon, either absent or 2048.
@@ -81,8 +84,22 @@
  offload, phandle of the TAH device node.
 - tah-channel   : 1 cell, optional. If appropriate, channel used on the
  TAH engine.
+- fixed-link   : Fixed-link subnode describing a link to a non-MDIO
+ managed entity. See
+ Documentation/devicetree/bindings/net/fixed-link.txt
+ for details.
+- mdio subnode : When the EMAC has a phy connected to its local
+ mdio, which us supported by the kernel's network
+ PHY library in drivers/net/phy, there must be device
+ tree subnode with the following required properties:
+   - #address-cells: Must be <1>.
+   - #size-cells: Must be <0>.
 
-Example:
+ For PHY definitions: Please refer to
+ Documentation/devicetree/bindings/net/phy.txt and
+ Documentation/devicetree/bindings/net/ethernet.txt
+
+Examples:
 
EMAC0: ethernet@4800 {
device_type = "network";
@@ -104,6 +121,47 @@
zmii-channel = <0>;
};
 
+   EMAC1: ethernet@ef600c00 {
+   device_type = "network";
+   compatible = "ibm,emac-apm821xx", "ibm,emac4sync";
+   interrupt-parent = <&EMAC1>;
+   interrupts = <0 1>;
+   #interrupt-cells = <1>;
+   #address-cells = <0>;
+   #size-cells = <0>;
+   interrupt-map = <0 &UIC2 0x10 IRQ_TYPE_LEVEL_HIGH /* Status */
+1 &UIC2 0x14 IRQ_TYPE_LEVEL_HIGH /* Wake */>;
+   reg = <0xef600c00 0x00c4>;
+   local-mac-address = []; /* Filled in by U-Boot */
+   mal-device = <&MAL0>;
+   mal-tx-channel = <0>;
+   mal-rx-channel = <0>;
+   cell-index = <0>;
+   max-frame-size = <9000>;
+   rx-fifo-size = <16384>;
+   tx-fifo-size = <2048>;
+   fifo-entry-size = <10>;
+   phy-mode = "rgmii";
+   phy-handle = <&phy0>;
+   phy-map = <0x>;
+   rgmii-device = <&RGMII0>;
+   rgmii-channel = <0>;
+   tah-device = <&TAH0>;
+   tah-channel = <0>;
+   has-inverted-stacr-oc;
+   has-new-stacr-staopc;
+
+   mdio {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   phy0: ethernet-phy@0 {
+   compatible = "ethernet-phy-ieee802.3-c22";
+   reg = <0>;
+   };
+   };
+
+
   ii) McMAL node
 
 Required properties:
@@ -145,4 +203,3 @@
 - revision   : as provided by the RGMII new version register if
   available.
   For Axon: 0x012a
-
-- 
2.11.0



[PATCH v1.1] dt: emac: document device-tree based phy discovery and setup

2017-02-27 Thread Christian Lamparter
This patch adds documentation for a new "phy-handle" property,
"fixed-link" and "mdio" sub-node. These allows the enumeration
of PHYs which are supported by the phy library under drivers/net/phy.

The EMAC ethernet controller in IBM and AMCC 4xx chips is
currently stuck with a few privately defined phy
implementations. It has no support for PHYs which
are supported by the generic phylib.

Acked-by: Rob Herring 
Signed-off-by: Christian Lamparter 
---
Resent - no changes.
---
 .../devicetree/bindings/powerpc/4xx/emac.txt   | 64 +-
 1 file changed, 62 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt 
b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
index 712baf6c3e24..1893b4c4d93b 100644
--- a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
+++ b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
@@ -71,6 +71,9 @@
  For Axon it can be absent, though my current driver
  doesn't handle phy-address yet so for now, keep
  0x00ff in it.
+- phy-handle   : Used to describe configurations where a external PHY
+ is used. Please refer to:
+ Documentation/devicetree/bindings/net/ethernet.txt
 - rx-fifo-size-gige : 1 cell, Rx fifo size in bytes for 1000 Mb/sec
  operations (if absent the value is the same as
  rx-fifo-size).  For Axon, either absent or 2048.
@@ -81,8 +84,22 @@
  offload, phandle of the TAH device node.
 - tah-channel   : 1 cell, optional. If appropriate, channel used on the
  TAH engine.
+- fixed-link   : Fixed-link subnode describing a link to a non-MDIO
+ managed entity. See
+ Documentation/devicetree/bindings/net/fixed-link.txt
+ for details.
+- mdio subnode : When the EMAC has a phy connected to its local
+ mdio, which us supported by the kernel's network
+ PHY library in drivers/net/phy, there must be device
+ tree subnode with the following required properties:
+   - #address-cells: Must be <1>.
+   - #size-cells: Must be <0>.
 
-Example:
+ For PHY definitions: Please refer to
+ Documentation/devicetree/bindings/net/phy.txt and
+ Documentation/devicetree/bindings/net/ethernet.txt
+
+Examples:
 
EMAC0: ethernet@4800 {
device_type = "network";
@@ -104,6 +121,50 @@
zmii-channel = <0>;
};
 
+   EMAC1: ethernet@ef600c00 {
+   device_type = "network";
+   compatible = "ibm,emac-apm821xx", "ibm,emac4sync";
+   interrupt-parent = <&EMAC1>;
+   interrupts = <0 1>;
+   #interrupt-cells = <1>;
+   #address-cells = <0>;
+   #size-cells = <0>;
+   interrupt-map = <0 &UIC2 0x10 IRQ_TYPE_LEVEL_HIGH /* Status */
+1 &UIC2 0x14 IRQ_TYPE_LEVEL_HIGH /* Wake */>;
+   reg = <0xef600c00 0x00c4>;
+   local-mac-address = []; /* Filled in by U-Boot */
+   mal-device = <&MAL0>;
+   mal-tx-channel = <0>;
+   mal-rx-channel = <0>;
+   cell-index = <0>;
+   max-frame-size = <9000>;
+   rx-fifo-size = <16384>;
+   tx-fifo-size = <2048>;
+   fifo-entry-size = <10>;
+   phy-mode = "rgmii";
+   phy-handle = <&phy0>;
+   phy-map = <0x>;
+   rgmii-device = <&RGMII0>;
+   rgmii-channel = <0>;
+   tah-device = <&TAH0>;
+   tah-channel = <0>;
+   has-inverted-stacr-oc;
+   has-new-stacr-staopc;
+
+   mdio {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   phy0: ethernet-phy@0 {
+   device_type = "ethernet-phy";
+   reg = <0>;
+
+   qca,ar8327-initvals = <
+   0x0010 0x4000>;
+   };
+   };
+
+
   ii) McMAL node
 
 Required properties:
@@ -145,4 +206,3 @@
 - revision   : as provided by the RGMII new version register if
   available.
   For Axon: 0x012a
-
-- 
2.11.0



[PATCH v2] dt: emac: document device-tree based phy discovery and setup

2017-02-27 Thread Christian Lamparter
This patch adds documentation for a new "phy-handle" property,
"fixed-link" and "mdio" sub-node. These allows the enumeration
of PHYs which are supported by the phy library under drivers/net/phy.

The EMAC ethernet controller in IBM and AMCC 4xx chips is
currently stuck with a few privately defined phy
implementations. It has no support for PHYs which
are supported by the generic phylib.

Acked-by: Rob Herring 
Reviewed-by: Florian Fainelli 
Signed-off-by: Christian Lamparter 
---
---
 .../devicetree/bindings/powerpc/4xx/emac.txt   | 62 +-
 1 file changed, 60 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt 
b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
index 712baf6c3e24..44b842b6ca15 100644
--- a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
+++ b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
@@ -71,6 +71,9 @@
  For Axon it can be absent, though my current driver
  doesn't handle phy-address yet so for now, keep
  0x00ff in it.
+- phy-handle   : Used to describe configurations where a external PHY
+ is used. Please refer to:
+ Documentation/devicetree/bindings/net/ethernet.txt
 - rx-fifo-size-gige : 1 cell, Rx fifo size in bytes for 1000 Mb/sec
  operations (if absent the value is the same as
  rx-fifo-size).  For Axon, either absent or 2048.
@@ -81,8 +84,22 @@
  offload, phandle of the TAH device node.
 - tah-channel   : 1 cell, optional. If appropriate, channel used on the
  TAH engine.
+- fixed-link   : Fixed-link subnode describing a link to a non-MDIO
+ managed entity. See
+ Documentation/devicetree/bindings/net/fixed-link.txt
+ for details.
+- mdio subnode : When the EMAC has a phy connected to its local
+ mdio, which us supported by the kernel's network
+ PHY library in drivers/net/phy, there must be device
+ tree subnode with the following required properties:
+   - #address-cells: Must be <1>.
+   - #size-cells: Must be <0>.
 
-Example:
+ For PHY definitions: Please refer to
+ Documentation/devicetree/bindings/net/phy.txt and
+ Documentation/devicetree/bindings/net/ethernet.txt
+
+Examples:
 
EMAC0: ethernet@4800 {
device_type = "network";
@@ -104,6 +121,48 @@
zmii-channel = <0>;
};
 
+   EMAC1: ethernet@ef600c00 {
+   device_type = "network";
+   compatible = "ibm,emac-apm821xx", "ibm,emac4sync";
+   interrupt-parent = <&EMAC1>;
+   interrupts = <0 1>;
+   #interrupt-cells = <1>;
+   #address-cells = <0>;
+   #size-cells = <0>;
+   interrupt-map = <0 &UIC2 0x10 IRQ_TYPE_LEVEL_HIGH /* Status */
+1 &UIC2 0x14 IRQ_TYPE_LEVEL_HIGH /* Wake */>;
+   reg = <0xef600c00 0x00c4>;
+   local-mac-address = []; /* Filled in by U-Boot */
+   mal-device = <&MAL0>;
+   mal-tx-channel = <0>;
+   mal-rx-channel = <0>;
+   cell-index = <0>;
+   max-frame-size = <9000>;
+   rx-fifo-size = <16384>;
+   tx-fifo-size = <2048>;
+   fifo-entry-size = <10>;
+   phy-mode = "rgmii";
+   phy-handle = <&phy0>;
+   phy-map = <0x>;
+   rgmii-device = <&RGMII0>;
+   rgmii-channel = <0>;
+   tah-device = <&TAH0>;
+   tah-channel = <0>;
+   has-inverted-stacr-oc;
+   has-new-stacr-staopc;
+
+   mdio {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   phy0: ethernet-phy@0 {
+   compatible = "ethernet-phy-ieee802.3-c22";
+   reg = <0>;
+   };
+   };
+   };
+
+
   ii) McMAL node
 
 Required properties:
@@ -145,4 +204,3 @@
 - revision   : as provided by the RGMII new version register if
   available.
   For Axon: 0x012a
-
-- 
2.11.0



Re: [PATCH v1.1] net: emac: add support for device-tree based PHY discovery and setup

2017-02-27 Thread Christian Lamparter
On Wednesday, February 22, 2017 3:37:35 PM CET David Miller wrote:
> From: Christian Lamparter 
> Date: Mon, 20 Feb 2017 20:10:58 +0100
> 
> > This patch adds glue-code that allows the EMAC driver to interface
> > with the existing dt-supported PHYs in drivers/net/phy.
> > 
> > Because currently, the emac driver maintains a small library of
> > supported phys for in a private phy.c file located in the drivers
> > directory.
> > 
> > The support is limited to mostly single ethernet transceiver like the:
> > CIS8201, BCM5248, ET1011C, Marvell 88E and 88E1112, AR8035.
> > 
> > However, routers like the Netgear WNDR4700 and Cisco Meraki MX60(W)
> > have a 5-port switch (AR8327N) attached to the EMAC. The switch chip
> > is supported by the qca8k mdio driver, which uses the generic phy
> > library. Another reason is that PHYLIB also supports the BCM54610,
> > which was used for the Western Digital My Book Live.
> > 
> > This will now also make EMAC select PHYLIB.
> > 
> > Signed-off-by: Christian Lamparter 
> 
> Applied, thanks.
> 
Thanks David.

I noticed that the DT Documentation patch:
"[v1,1/2] dt: emac: document device-tree based phy discovery and setup"
is still pending with "Changes Requested":
<https://patchwork.ozlabs.org/patch/729658/>

I think this is because of Florian's comment on patch:
"[v1,2/2] net: emac: add support for device-tree based PHY discovery and setup"
If so, can you please queue this documentation update patch for -next?
(I haven't received any comments or complains. If necessary, I can also
resent it.)

Thanks,
Christian


[PATCH v1.1] net: emac: add support for device-tree based PHY discovery and setup

2017-02-20 Thread Christian Lamparter
This patch adds glue-code that allows the EMAC driver to interface
with the existing dt-supported PHYs in drivers/net/phy.

Because currently, the emac driver maintains a small library of
supported phys for in a private phy.c file located in the drivers
directory.

The support is limited to mostly single ethernet transceiver like the:
CIS8201, BCM5248, ET1011C, Marvell 88E and 88E1112, AR8035.

However, routers like the Netgear WNDR4700 and Cisco Meraki MX60(W)
have a 5-port switch (AR8327N) attached to the EMAC. The switch chip
is supported by the qca8k mdio driver, which uses the generic phy
library. Another reason is that PHYLIB also supports the BCM54610,
which was used for the Western Digital My Book Live.

This will now also make EMAC select PHYLIB.

Signed-off-by: Christian Lamparter 
---
RFC->v1:
- added PHYLIB (fixes kbuild-bot error)
- used the correct version (the working one from LEDE).
- added fixed-link DT support. (This fixes a XXX)
- Added WA for the MX60(W): -EREMOTEIO/-ETIMEDOUT/...
  errors from mdio_read are converted to 0x.
v1->v1.1:
- removed phy_flags
---
 drivers/net/ethernet/ibm/emac/Kconfig |   1 +
 drivers/net/ethernet/ibm/emac/core.c  | 254 +-
 drivers/net/ethernet/ibm/emac/core.h  |   4 +
 3 files changed, 252 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/Kconfig 
b/drivers/net/ethernet/ibm/emac/Kconfig
index 3f44a30e0615..90d49191beb3 100644
--- a/drivers/net/ethernet/ibm/emac/Kconfig
+++ b/drivers/net/ethernet/ibm/emac/Kconfig
@@ -2,6 +2,7 @@ config IBM_EMAC
tristate "IBM EMAC Ethernet support"
depends on PPC_DCR
select CRC32
+   select PHYLIB
help
  This driver supports the IBM EMAC family of Ethernet controllers
  typically found on 4xx embedded PowerPC chips, but also on the
diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 5909615c27f7..c3806679dfa3 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -42,6 +42,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -2410,6 +2411,219 @@ static int emac_read_uint_prop(struct device_node *np, 
const char *name,
return 0;
 }
 
+static void emac_adjust_link(struct net_device *ndev)
+{
+   struct emac_instance *dev = netdev_priv(ndev);
+   struct phy_device *phy = dev->phy_dev;
+
+   dev->phy.autoneg = phy->autoneg;
+   dev->phy.speed = phy->speed;
+   dev->phy.duplex = phy->duplex;
+   dev->phy.pause = phy->pause;
+   dev->phy.asym_pause = phy->asym_pause;
+   dev->phy.advertising = phy->advertising;
+}
+
+static int emac_mii_bus_read(struct mii_bus *bus, int addr, int regnum)
+{
+   int ret = emac_mdio_read(bus->priv, addr, regnum);
+   /* This is a workaround for powered down ports/phys.
+* In the wild, this was seen on the Cisco Meraki MX60(W).
+* This hardware disables ports as part of the handoff
+* procedure. Accessing the ports will lead to errors
+* (-ETIMEDOUT, -EREMOTEIO) that do more harm than good.
+*/
+   return ret < 0 ? 0x : ret;
+}
+
+static int emac_mii_bus_write(struct mii_bus *bus, int addr,
+ int regnum, u16 val)
+{
+   emac_mdio_write(bus->priv, addr, regnum, val);
+   return 0;
+}
+
+static int emac_mii_bus_reset(struct mii_bus *bus)
+{
+   struct emac_instance *dev = netdev_priv(bus->priv);
+
+   return emac_reset(dev);
+}
+
+static int emac_mdio_setup_aneg(struct mii_phy *phy, u32 advertise)
+{
+   struct net_device *ndev = phy->dev;
+   struct emac_instance *dev = netdev_priv(ndev);
+
+   dev->phy.autoneg = AUTONEG_ENABLE;
+   dev->phy.speed = SPEED_1000;
+   dev->phy.duplex = DUPLEX_FULL;
+   dev->phy.advertising = advertise;
+   phy->autoneg = AUTONEG_ENABLE;
+   phy->speed = dev->phy.speed;
+   phy->duplex = dev->phy.duplex;
+   phy->advertising = advertise;
+   return phy_start_aneg(dev->phy_dev);
+}
+
+static int emac_mdio_setup_forced(struct mii_phy *phy, int speed, int fd)
+{
+   struct net_device *ndev = phy->dev;
+   struct emac_instance *dev = netdev_priv(ndev);
+
+   dev->phy.autoneg =  AUTONEG_DISABLE;
+   dev->phy.speed = speed;
+   dev->phy.duplex = fd;
+   phy->autoneg = AUTONEG_DISABLE;
+   phy->speed = speed;
+   phy->duplex = fd;
+   return phy_start_aneg(dev->phy_dev);
+}
+
+static int emac_mdio_poll_link(struct mii_phy *phy)
+{
+   struct net_device *ndev = phy->dev;
+   struct emac_instance *dev = netdev_priv(ndev);
+   int res;
+
+   res = phy_read_status(dev->phy_dev);
+   if (res) {
+   dev_err(&dev->ofdev->dev, &quo

[PATCH v1 2/2] net: emac: add support for device-tree based PHY discovery and setup

2017-02-19 Thread Christian Lamparter
This patch adds glue-code that allows the EMAC driver to interface
with the existing dt-supported PHYs in drivers/net/phy.

Because currently, the emac driver maintains a small library of
supported phys for in a private phy.c file located in the drivers
directory.

The support is limited to mostly single ethernet transceiver like the:
CIS8201, BCM5248, ET1011C, Marvell 88E and 88E1112, AR8035.

However, routers like the Netgear WNDR4700 and Cisco Meraki MX60(W)
have a 5-port switch (AR8327N) attached to the EMAC. The switch chip
is supported by the qca8k mdio driver, which uses the generic phy
library. Another reason is that PHYLIB also supports the BCM54610,
which was used for the Western Digital My Book Live.

This will now also make EMAC select PHYLIB.

Signed-off-by: Christian Lamparter 
---
RFC->v1:
- added PHYLIB (fixes kbuild-bot error)
- used the correct version (the working one from LEDE).
- added fixed-link DT support. (This fixes a XXX)
- Added WA for the MX60(W): -EREMOTEIO/-ETIMEDOUT/...
  errors from mdio_read are converted to 0x.
---
 drivers/net/ethernet/ibm/emac/Kconfig |   1 +
 drivers/net/ethernet/ibm/emac/core.c  | 260 +-
 drivers/net/ethernet/ibm/emac/core.h  |   4 +
 3 files changed, 258 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/ibm/emac/Kconfig 
b/drivers/net/ethernet/ibm/emac/Kconfig
index 3f44a30e0615..90d49191beb3 100644
--- a/drivers/net/ethernet/ibm/emac/Kconfig
+++ b/drivers/net/ethernet/ibm/emac/Kconfig
@@ -2,6 +2,7 @@ config IBM_EMAC
tristate "IBM EMAC Ethernet support"
depends on PPC_DCR
select CRC32
+   select PHYLIB
help
  This driver supports the IBM EMAC family of Ethernet controllers
  typically found on 4xx embedded PowerPC chips, but also on the
diff --git a/drivers/net/ethernet/ibm/emac/core.c 
b/drivers/net/ethernet/ibm/emac/core.c
index 5909615c27f7..11d97971fb28 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -42,6 +42,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -2410,6 +2411,225 @@ static int emac_read_uint_prop(struct device_node *np, 
const char *name,
return 0;
 }
 
+static void emac_adjust_link(struct net_device *ndev)
+{
+   struct emac_instance *dev = netdev_priv(ndev);
+   struct phy_device *phy = dev->phy_dev;
+
+   dev->phy.autoneg = phy->autoneg;
+   dev->phy.speed = phy->speed;
+   dev->phy.duplex = phy->duplex;
+   dev->phy.pause = phy->pause;
+   dev->phy.asym_pause = phy->asym_pause;
+   dev->phy.advertising = phy->advertising;
+}
+
+static int emac_mii_bus_read(struct mii_bus *bus, int addr, int regnum)
+{
+   int ret = emac_mdio_read(bus->priv, addr, regnum);
+   /* This is a workaround for powered down ports/phys.
+* In the wild, this was seen on the Cisco Meraki MX60(W).
+* This hardware disables ports as part of the handoff
+* procedure. Accessing the ports will lead to errors
+* (-ETIMEDOUT, -EREMOTEIO) that do more harm than good.
+*/
+   return ret < 0 ? 0x : ret;
+}
+
+static int emac_mii_bus_write(struct mii_bus *bus, int addr,
+ int regnum, u16 val)
+{
+   emac_mdio_write(bus->priv, addr, regnum, val);
+   return 0;
+}
+
+static int emac_mii_bus_reset(struct mii_bus *bus)
+{
+   struct emac_instance *dev = netdev_priv(bus->priv);
+
+   return emac_reset(dev);
+}
+
+static int emac_mdio_setup_aneg(struct mii_phy *phy, u32 advertise)
+{
+   struct net_device *ndev = phy->dev;
+   struct emac_instance *dev = netdev_priv(ndev);
+
+   dev->phy.autoneg = AUTONEG_ENABLE;
+   dev->phy.speed = SPEED_1000;
+   dev->phy.duplex = DUPLEX_FULL;
+   dev->phy.advertising = advertise;
+   phy->autoneg = AUTONEG_ENABLE;
+   phy->speed = dev->phy.speed;
+   phy->duplex = dev->phy.duplex;
+   phy->advertising = advertise;
+   return phy_start_aneg(dev->phy_dev);
+}
+
+static int emac_mdio_setup_forced(struct mii_phy *phy, int speed, int fd)
+{
+   struct net_device *ndev = phy->dev;
+   struct emac_instance *dev = netdev_priv(ndev);
+
+   dev->phy.autoneg =  AUTONEG_DISABLE;
+   dev->phy.speed = speed;
+   dev->phy.duplex = fd;
+   phy->autoneg = AUTONEG_DISABLE;
+   phy->speed = speed;
+   phy->duplex = fd;
+   return phy_start_aneg(dev->phy_dev);
+}
+
+static int emac_mdio_poll_link(struct mii_phy *phy)
+{
+   struct net_device *ndev = phy->dev;
+   struct emac_instance *dev = netdev_priv(ndev);
+   int res;
+
+   res = phy_read_status(dev->phy_dev);
+   if (res) {
+   dev_err(&dev->ofdev->dev, "link update failed (%d).", res)

[PATCH v1 1/2] dt: emac: document device-tree based phy discovery and setup

2017-02-19 Thread Christian Lamparter
This patch adds documentation for a new "phy-handle" property,
"fixed-link" and "mdio" sub-node. These allows the enumeration
of PHYs which are supported by the phy library under drivers/net/phy.

The EMAC ethernet controller in IBM and AMCC 4xx chips is
currently stuck with a few privately defined phy
implementations. It has no support for PHYs which
are supported by the generic phylib.

Acked-by: Rob Herring 
Signed-off-by: Christian Lamparter 
---
I rewrote the "phy-handle" property in order to make the
links to net/ethernet.txt consistent with the ones in the mdio
subnode. I've also added the "fixed-link" subnode, which I
copied from net/dsa.txt. I hope this doesn't invalidate Rob's
ACK from the RFC (If it does, please tell me, otherwise I
assume everything is still OK).
---
 .../devicetree/bindings/powerpc/4xx/emac.txt   | 64 +-
 1 file changed, 62 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt 
b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
index 712baf6c3e24..1893b4c4d93b 100644
--- a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
+++ b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
@@ -71,6 +71,9 @@
  For Axon it can be absent, though my current driver
  doesn't handle phy-address yet so for now, keep
  0x00ff in it.
+- phy-handle   : Used to describe configurations where a external PHY
+ is used. Please refer to:
+ Documentation/devicetree/bindings/net/ethernet.txt
 - rx-fifo-size-gige : 1 cell, Rx fifo size in bytes for 1000 Mb/sec
  operations (if absent the value is the same as
  rx-fifo-size).  For Axon, either absent or 2048.
@@ -81,8 +84,22 @@
  offload, phandle of the TAH device node.
 - tah-channel   : 1 cell, optional. If appropriate, channel used on the
  TAH engine.
+- fixed-link   : Fixed-link subnode describing a link to a non-MDIO
+ managed entity. See
+ Documentation/devicetree/bindings/net/fixed-link.txt
+ for details.
+- mdio subnode : When the EMAC has a phy connected to its local
+ mdio, which us supported by the kernel's network
+ PHY library in drivers/net/phy, there must be device
+ tree subnode with the following required properties:
+   - #address-cells: Must be <1>.
+   - #size-cells: Must be <0>.
 
-Example:
+ For PHY definitions: Please refer to
+ Documentation/devicetree/bindings/net/phy.txt and
+ Documentation/devicetree/bindings/net/ethernet.txt
+
+Examples:
 
EMAC0: ethernet@4800 {
device_type = "network";
@@ -104,6 +121,50 @@
zmii-channel = <0>;
};
 
+   EMAC1: ethernet@ef600c00 {
+   device_type = "network";
+   compatible = "ibm,emac-apm821xx", "ibm,emac4sync";
+   interrupt-parent = <&EMAC1>;
+   interrupts = <0 1>;
+   #interrupt-cells = <1>;
+   #address-cells = <0>;
+   #size-cells = <0>;
+   interrupt-map = <0 &UIC2 0x10 IRQ_TYPE_LEVEL_HIGH /* Status */
+1 &UIC2 0x14 IRQ_TYPE_LEVEL_HIGH /* Wake */>;
+   reg = <0xef600c00 0x00c4>;
+   local-mac-address = []; /* Filled in by U-Boot */
+   mal-device = <&MAL0>;
+   mal-tx-channel = <0>;
+   mal-rx-channel = <0>;
+   cell-index = <0>;
+   max-frame-size = <9000>;
+   rx-fifo-size = <16384>;
+   tx-fifo-size = <2048>;
+   fifo-entry-size = <10>;
+   phy-mode = "rgmii";
+   phy-handle = <&phy0>;
+   phy-map = <0x>;
+   rgmii-device = <&RGMII0>;
+   rgmii-channel = <0>;
+   tah-device = <&TAH0>;
+   tah-channel = <0>;
+   has-inverted-stacr-oc;
+   has-new-stacr-staopc;
+
+   mdio {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   phy0: ethernet-phy@0 {
+   device_type = "ethernet-phy";
+   reg = <0>;
+
+   

Re: [PATCH][CFT] Saner error handling in skb_copy_datagram_iter() et.al.

2017-02-19 Thread Christian Lamparter
On Saturday, February 18, 2017 12:02:14 AM CET Al Viro wrote:
> On Fri, Feb 17, 2017 at 05:03:15PM +, Al Viro wrote:
> > On Fri, Feb 17, 2017 at 10:54:20AM -0500, David Miller wrote:
> > > From: Al Viro 
> > > Date: Tue, 14 Feb 2017 01:33:06 +
> > > 
> > > > OK...  Remaining interesting question is whether it adds a noticable
> > > > overhead.  Could somebody try it on assorted benchmarks and see if
> > > > it slows the things down?  The patch in question follows:
> > > 
> > > That's about a 40 byte copy onto the stack for each invocation of this
> > > thing.  You can benchmark all you want, but it's clear that this is
> > > non-trivial amount of work and will take some operations from fitting
> > > in the cache to not doing so for sure.
> > 
> > In principle, that could be reduced a bit (32 bytes - ->type is never
> > changed, so we don't need to restore it), but that's not much of 
> > improvement...
> 
> Actually, I've a better solution.  Namely, analogue of iov_iter_advance()
> for going backwards.  The restriction is that you should never unroll
> further than where you've initially started *or* have the iovec, etc.
> array modified under you.  For iovec/kvec/bio_vec it's trivial, for pipe -
> a bit more convoluted, but still doable.  Then net/core/datagram.c stuff
> could simply use iov_iter_unroll() in case of error - all we need to keep
> track of is how much had we copied and that's easy to do.
> 
> The patch below is completely untested, but if it works it should avoid
> buggering the fast paths at all, still giving the same semantics re
> reverting ->msg_iter both on EINVAL and EFAULT.  Comments?
I've tested it. It also fixes the corruption issue I can reproduce
with my setup.:
# tc qdisc add dev eth0 root netem corrupt 0.1%
(and the dlbug code)

So, for what's worth:
Tested-by: Christian Lamparter 

> diff --git a/include/linux/uio.h b/include/linux/uio.h
> index 804e34c6f981..237965348bc2 100644
> --- a/include/linux/uio.h
> +++ b/include/linux/uio.h
> @@ -39,7 +39,10 @@ struct iov_iter {
>   };
>   union {
>   unsigned long nr_segs;
> - int idx;
> + struct {
> + int idx;
> + int start_idx;
> + };
>   };
>  };
>  
> @@ -81,6 +84,7 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long 
> nr_segs, size_t to);
>  size_t iov_iter_copy_from_user_atomic(struct page *page,
>   struct iov_iter *i, unsigned long offset, size_t bytes);
>  void iov_iter_advance(struct iov_iter *i, size_t bytes);
> +void iov_iter_unroll(struct iov_iter *i, size_t bytes);
>  int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes);
>  size_t iov_iter_single_seg_count(const struct iov_iter *i);
>  size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
> diff --git a/lib/iov_iter.c b/lib/iov_iter.c
> index e68604ae3ced..afdaca37f5c9 100644
> --- a/lib/iov_iter.c
> +++ b/lib/iov_iter.c
> @@ -786,6 +786,68 @@ void iov_iter_advance(struct iov_iter *i, size_t size)
>  }
>  EXPORT_SYMBOL(iov_iter_advance);
>  
> +void iov_iter_unroll(struct iov_iter *i, size_t unroll)
> +{
> + if (!unroll)
> + return;
> + i->count += unroll;
> + if (unlikely(i->type & ITER_PIPE)) {
> + struct pipe_inode_info *pipe = i->pipe;
> + int idx = i->idx;
> + size_t off = i->iov_offset;
> + while (1) {
> + size_t n = off - pipe->bufs[idx].offset;
> + if (unroll < n) {
> + off -= (n - unroll);
> + break;
> + }
> + unroll -= n;
> + if (!unroll && idx == i->start_idx) {
> + off = 0;
> + break;
> + }
> + if (!idx--)
> + idx = pipe->buffers - 1;
> + off = pipe->bufs[idx].offset + pipe->bufs[idx].len;
> + }
> + i->iov_offset = off;
> + i->idx = idx;
> + pipe_truncate(i);
> + return;
> + }
> + if (unroll <= i->iov_offset) {
> + i->iov_offset -= unroll;
> + return;
> + }
> + unroll -= i->iov_offset;
> + if (i->type & ITER_BVEC) {
> + const struct bio_vec *bvec = i->bvec;
> + while (1) {
> +  

Re: [RFC 1/2] dt: emac: document device-tree based phy discovery and setup

2017-02-19 Thread Christian Lamparter
On Sunday, February 5, 2017 2:33:44 PM CET Florian Fainelli wrote:
> Le 02/05/17 à 14:25, Christian Lamparter a écrit :
> > This patch adds documentation for a new "phy-handler" property
> > and "mdio" sub-node. These allows the enumeration of PHYs which
> > are supported by the phy library under drivers/net/phy.
> > 
> > The EMAC ethernet controller in IBM and AMCC 4xx chips is
> > currently stuck with a few privately defined phy
> > implementations. It has no support for PHYs which
> > are supported by the generic phylib.
> > 
> > Signed-off-by: Christian Lamparter 
> > ---
> >  .../devicetree/bindings/powerpc/4xx/emac.txt   | 60 
> > +-
> >  1 file changed, 58 insertions(+), 2 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt 
> > b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
> > index 712baf6c3e24..0572d053c35a 100644
> > --- a/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
> > +++ b/Documentation/devicetree/bindings/powerpc/4xx/emac.txt
> > @@ -71,6 +71,8 @@
> >   For Axon it can be absent, though my current driver
> >   doesn't handle phy-address yet so for now, keep
> >   0x00ff in it.
> > +- phy-handle   : See net/ethernet.txt file; used to describe
> > + configurations where a external PHY is used.
> >  - rx-fifo-size-gige : 1 cell, Rx fifo size in bytes for 1000 Mb/sec
> >   operations (if absent the value is the same as
> >   rx-fifo-size).  For Axon, either absent or 2048.
> > @@ -82,7 +84,18 @@
> >  - tah-channel   : 1 cell, optional. If appropriate, channel used 
> > on the
> >   TAH engine.
> >  
> > -Example:
> > +- mdio subnode : When the EMAC has a phy connected to its local
> > + mdio, which us supported by the kernel's network
> > + PHY library in drivers/net/phy, there must be device
> > + tree subnode with the following required properties:
> > +   - #address-cells: Must be <1>.
> > +   - #size-cells: Must be <0>.
> > +
> > + For each phy on the mdio bus, there must be a node
> > + with the following fields:
> > +   - reg: phy id used to communicate to phy.
> > +   - device_type: Must be "ethernet-phy".
> 
> Just provide a reference to
> Documentation/devicetree/bindings/net/phy.txt and
> Documentation/devicetree/bindings/net/ethernet.txt here. device_type is
> not required.

Yes, I added a reference there.
> 
> > +Examples:
> >  
> > EMAC0: ethernet@4800 {
> > device_type = "network";
> > @@ -104,6 +117,50 @@
> > zmii-channel = <0>;
> > };
> >  
> > +   EMAC1: ethernet@ef600c00 {
> > +   device_type = "network";
> > +   compatible = "ibm,emac-apm821xx", "ibm,emac4sync";
> > +   interrupt-parent = <&EMAC1>;
> > +   interrupts = <0 1>;
> > +   #interrupt-cells = <1>;
> > +   #address-cells = <0>;
> > +   #size-cells = <0>;
> > +   interrupt-map = <0 &UIC2 0x10 IRQ_TYPE_LEVEL_HIGH /* Status */
> > +1 &UIC2 0x14 IRQ_TYPE_LEVEL_HIGH /* Wake */>;
> > +   reg = <0xef600c00 0x00c4>;
> > +   local-mac-address = []; /* Filled in by U-Boot */
> > +   mal-device = <&MAL0>;
> > +   mal-tx-channel = <0>;
> > +   mal-rx-channel = <0>;
> > +   cell-index = <0>;
> > +   max-frame-size = <9000>;
> > +   rx-fifo-size = <16384>;
> > +   tx-fifo-size = <2048>;
> > +   fifo-entry-size = <10>;
> > +   phy-mode = "rgmii";
> > +   phy-map = <0x>;
> 
> If you have a proper mdio subnode, this property becomes irrelevant and
> should be unused.
This is emac.c doing. It defaults to 0x... if the property is absent.
<http://lxr.free-electrons.com/source/drivers/net/ethernet/ibm/emac/core.c#L2578>
> > +   phy-handle = <&phy0>;
> > +   rgmii-device = <&RGMII0>;
> > +

Re: [RFC 2/2] net: emac: add support for device-tree based PHY discovery and setup

2017-02-19 Thread Christian Lamparter
On Wednesday, February 15, 2017 3:23:08 PM CET Andrew Lunn wrote:
> > > > Is the PHY just powered down by chance (BMCR_PWRDN set?) and resetting
> > > > it implicitly clears the power down that seems to be what is going on.
> > > 
> > > Yes, the PHY is just in the BMCR_PDOWN state. I can do the same
> > > on the WNDR4700, by messing with u-boot:
> 
> Hi Christian
> 
> What happens if you list the PHYs in the device tree, with their PHY
> ID. That should avoid it looking for the ID and getting 0x
> back. It should just probe the correct PHY driver. If the first thing
> the drivers probe function does it reset the power down bit, it might
> work.

I just tested it. And it didn't work (Same result/error).

It fails because the PHYs on the dsa slave-bus are not detected via the
device tree method. See 


|315 if (!ds->slave_mii_bus && ds->ops->phy_read) {
|316 ds->slave_mii_bus = devm_mdiobus_alloc(ds->dev);
|317 if (!ds->slave_mii_bus)
|318 return -ENOMEM;
|319 
|320 dsa_slave_mii_bus_init(ds);
|321 
|322 err = mdiobus_register(ds->slave_mii_bus);
|323 if (err < 0)
|324 return err;
|325 }

You see that dsa2 just calls mdiobus_register() which will do the
PHY discovery with mdiobus_scan() 

which relys on the values from MII_PHYSID1 and MII_PHYSID2.

In order to get it work, this mdiobus_register would need to be
replaced with of_mdiobus_register().

---
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 737be6470c7f..5a90ec81040f 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "dsa_priv.h"
 
 static LIST_HEAD(dsa_switch_trees);
@@ -288,7 +289,8 @@ static void dsa_user_port_unapply(struct dsa_port *port, 
u32 index,
}
 }
 
-static int dsa_ds_apply(struct dsa_switch_tree *dst, struct dsa_switch *ds)
+static int dsa_ds_apply(struct dsa_switch_tree *dst, struct dsa_switch *ds,
+   struct device_node *ports)
 {
struct dsa_port *port;
u32 index;
@@ -322,7 +324,10 @@ static int dsa_ds_apply(struct dsa_switch_tree *dst, 
struct dsa_switch *ds)
 
dsa_slave_mii_bus_init(ds);
 
-   err = mdiobus_register(ds->slave_mii_bus);
+   if (!ports)
+   err = mdiobus_register(ds->slave_mii_bus);
+   else
+   err = of_mdiobus_register(ds->slave_mii_bus, ports);
if (err < 0)
return err;
}
@@ -383,7 +388,8 @@ static void dsa_ds_unapply(struct dsa_switch_tree *dst, 
struct dsa_switch *ds)
dsa_switch_unregister_notifier(ds);
 }
 
-static int dsa_dst_apply(struct dsa_switch_tree *dst)
+static int dsa_dst_apply(struct dsa_switch_tree *dst,
+struct device_node *ports)
 {
struct dsa_switch *ds;
u32 index;
@@ -394,7 +400,7 @@ static int dsa_dst_apply(struct dsa_switch_tree *dst)
if (!ds)
continue;
 
-   err = dsa_ds_apply(dst, ds);
+   err = dsa_ds_apply(dst, ds, ports);
if (err)
return err;
}
@@ -649,7 +655,7 @@ static int _dsa_register_switch(struct dsa_switch *ds, 
struct device *dev)
struct dsa_chip_data *pdata = dev->platform_data;
struct device_node *np = dev->of_node;
struct dsa_switch_tree *dst;
-   struct device_node *ports;
+   struct device_node *ports = NULL;
u32 tree, index;
int i, err;
 
@@ -722,7 +728,7 @@ static int _dsa_register_switch(struct dsa_switch *ds, 
struct device *dev)
goto out_del_dst;
}
 
-   err = dsa_dst_apply(dst);
+   err = dsa_dst_apply(dst, ports);
if (err) {
dsa_dst_unapply(dst);
goto out_del_dst;
---

With this patch applied, the device discovery works as intended:


| [4.514106] Generic PHY 4ef600c00.ethern:00: attached PHY driver [Generic 
PHY] (mii_bus:phy_addr=4ef600c00.ethern:00, irq=-1)
|[4.525975] Generic PHY dsa-0.0:01: attached PHY driver [Generic PHY] 
(mii_bus:phy_addr=dsa-0.0:01, irq=-1)
|[4.536269] Generic PHY dsa-0.0:02: attached PHY driver [Generic PHY] 
(mii_bus:phy_addr=dsa-0.0:02, irq=-1)
|[4.546562] Generic PHY dsa-0.0:03: attached PHY driver [Generic PHY] 
(mii_bus:phy_addr=dsa-0.0:03, irq=-1)
|[4.556887] Generic PHY dsa-0.0:04: attached PHY driver [Generic PHY] 
(mii_bus:phy_addr=dsa-0.0:04, irq=-1)

>From what I can tell, the PHY works. Although it will ping-pong for a bit:
|[  170.463823] qca8k 4ef600c00.ethern:10 lan1: Link is Down
|[  172.511860] qca8k 4ef600c00.ethern:10 lan1: Link is Up - 1Gbps/Full - flow 
control rx/tx
|[  174.559823] qca8k 4ef600c00.ethern:

Re: [RFC 2/2] net: emac: add support for device-tree based PHY discovery and setup

2017-02-14 Thread Christian Lamparter
On Tuesday, February 14, 2017 12:38:42 AM CET Christian Lamparter wrote:
> > >>> diff --git a/drivers/net/ethernet/ibm/emac/core.c 
> > >>> b/drivers/net/ethernet/ibm/emac/core.c
> > >>> --- a/drivers/net/ethernet/ibm/emac/core.c
> > >>> +++ b/drivers/net/ethernet/ibm/emac/core.c
> > >>> @@ -2420,6 +2421,179 @@ static int emac_read_uint_prop(struct 
> > >>> device_node *np, const char *name,
> > >>> [...] 
> > >>> +static int emac_mii_bus_reset(struct mii_bus *bus)
> > >>> +{
> > >>> +   struct emac_instance *dev = netdev_priv(bus->priv);
> > >>> +
> > >>> +   emac_mii_reset_phy(&dev->phy);
> > >>
> > >> This seems wrong, emac_mii_reset_phy() does a BMCR software reset, which
> > >> PHYLIB is already going to do (phy_init_hw), yet you do this here at the
> > >> MDIO bus level towards a specify PHY, whereas this should be affecting
> > >> the MDIO bus itself (and/or *all* PHY child devices for quirks).
> > > Ah, this is a good point. The emac driver has a emac_reset() function
> > > that does disable and enabled the phy clocks. That said, this is already
> > > done by the emac driver during init too. So if I added it, the bus is
> > > reset twice (since it doesn't hurt - I added it back).
> > > 
> > > The emac_mii_phy_reset() was added because of the Meraki MX60(W).
> > > This is because Cisco's bootloader disables the switch port 
> > > (probably to prevent WAN<->LAN leakage during boot)
> > > 
> > > [bootlog from the MX60(W)]
> > > |Disabling port 0
> > > |Disabling port 1
> > > |Disabling port 2
> > > |Disabling port 3
> > > |ENET Speed is 1000 Mbps - FULL duplex connection (EMAC0)
> > > 
> > > Without emac_mii_reset_phy(), the mdiobus_scan() function, which
> > > is called by mdiobus_register will fail with -ENODEV.
> > > | /plb/opb/ethernet@ef600c00: failed to attach dt phy (-19).
> > > This is because get_phy_id() will "mostly read mostly Fs" and abort.
> > 
> > Is the PHY just powered down by chance (BMCR_PWRDN set?) and resetting
> > it implicitly clears the power down that seems to be what is going on.
> 
> Yes, the PHY is just in the BMCR_PDOWN state. I can do the same
> on the WNDR4700, by messing with u-boot:
> 
> | => mii write 0 0 0x0800
> | => mii dump
> | 0. () -- PHY control register --
> |  (8000:8000) 0.15= 1reset
> |  (4000:4000) 0.14= 1loopback
> |  (2040:2040) 0. 6,13 =   b11speed selection = ??? Mbps
> |  (1000:1000) 0.12= 1A/N enable
> |  (0800:0800) 0.11= 1power-down
> |  (0400:0400) 0.10= 1isolate
> |  (0200:0200) 0. 9= 1restart A/N
> |  (0100:0100) 0. 8= 1duplex = full
> |  (0080:0080) 0. 7= 1collision test enable
> |  (003f:003f) 0. 5- 0 =63(reserved)
> 
> On the Meraki, the port disabled by the bootloader. 
> The reset is still needed.
> 
> > Keep in mind that MDIO address 16 is the switch's pseudo PHY address
> > here, so if you are telling PHYLIB to probe for that address and you
> > don't get the expected MII_PHYSID1/2 value in return, that usually means
> > that there was a PHY fixup registered to intercept these reads and make
> > us return the switch's unique identifier. Reading from the switch's
> > pseudo PHY at address 16 registers 2/3 (MII_PHYSID1/2) is not guaranteed
> > to return the switch's unique identifer.
> > 
> > With a MDIO device driver this won't happen because you will be probed
> > by address, and you can read any switch register you want to and from
> > there move on with the initialization.
> > 
> > > 
> > > 
> > > With emac_mii_reset_phy() in place, it gets detected:
> > > | switch0: Atheros AR8327 rev. 4 switch registered on emac_mdio
> > > 
> > > Furthermore, this is probably not the only device which need it.
> > > Currently, emac's own phy.c code does call emac_mii_reset_phy() 
> > > as well as part of its probe procedure.
> > > <http://lxr.free-electrons.com/source/drivers/net/ethernet/ibm/emac/phy.c#L522>
> > > 
> > > Ideally, we would like to reset only the ports which are registered in 
> > > the DT.
> > 
> > Which you would get for free if you did extend qca8k to support the
> > 8327, because qca8k does implicitly tell the DSA layer to 

Re: [RFC 2/2] net: emac: add support for device-tree based PHY discovery and setup

2017-02-13 Thread Christian Lamparter
On Saturday, February 11, 2017 3:07:04 PM CET Florian Fainelli wrote:
> Le 02/11/17 à 14:45, Christian Lamparter a écrit :
> > On Sunday, February 5, 2017 2:44:54 PM CET Florian Fainelli wrote:
> >> Le 02/05/17 à 14:25, Christian Lamparter a écrit :
> >>> From: Christian Lamparter 
> >>>
> >>> This patch adds glue-code that allows the EMAC driver to interface
> >>> with the existing dt-supported PHYs in drivers/net/phy.
> >>>
> >>> Because currently, the emac driver maintains a small library of
> >>> supported phys for in a private phy.c file located in the drivers
> >>> directory.
> >>>
> >>> The support is limited to mostly single ethernet transceiver like the:
> >>> CIS8201, BCM5248, ET1011C, Marvell 88E and 88E1112, AR8035.
> >>> However, routers like the Netgear WNDR4700 and Cisco Meraki MX60(W)
> >>> have a 5-port switch (QCA8327N) attached to the MDIO of the EMAC.
> >>> The switch chip has already a proper phy-driver (qca8k) that uses
> >>> the generic phy library.
> >>
> >> Technically, it's a mdio_device in the upstream kernel that registers a
> >> switch with DSA (and a PHY device in the OpenWrt/LEDE downstream
> >> kernel). If your goal is to specifically support that device you should
> >> consider making the EMAC interface with a fixed link PHY to properly
> >> initialize the EMAC <=> CPU port of the switch link, and then declare
> >> the qca8k device as a child MDIO device (not a PHY), similar to what is
> >> done in arch/arm/boot/dts/vf610-zii-dev-rev-b.dts for instance.
> > 
> > Ok. I looked what was going on here. As you explained: qca8k is indeed 
> > the wrong driver. We do use the ar8216 with swconfig interface.
> 
> Can you look into adding support for the 8216 into
> drivers/net/dsa/qca8k.c? You don't necessarily need to use QCA tags
> (using DSA_PROTO_NONE works too) and this would be a good way to know
> what could be missing in that driver, you'd also get per-port network
> devices, which could all be driving their built-in PHYs (so ethtool and
> friends work as expected).
Oh, I don't have any devices with an AR8216. Both the Meraki MX60(W) and
the WNDR4700 have the AR8327. I only mentioned AR8216, because that's
the driver module in OpenWRT/LEDE which supports the AR8327 [0], [1].

As for emac and AR8327N: It will come right up, once the QCA8337-only guard 
is removed from qca8k.c [2]. [QCA8K_ID_QCA8337 is 0x13, AR8327N is 0x12]:
|954if (id != QCA8K_ID_QCA8337)
|955return -ENODEV;

[4.250097] libphy: emac_mdio: probed
[4.253789] mdio_bus 4ef600c00.ethern:10: mdio_device_register
[4.346679] eth0: EMAC-0 /plb/opb/ethernet@ef600c00, MAC 10:0d:7f:4e:20:6e
[...]
[4.425333] DSA: switch 0 0 parsed
[4.428751] DSA: tree 0 parsed
[4.496094] libphy: dsa slave smi: probed
[4.513056] Generic PHY 4ef600c00.ethern:00: attached PHY driver [Generic 
PHY] (mii_bus:phy_addr=4ef600c00.ethern:00, irq=-1)
[4.524916] Generic PHY dsa-0.0:01: attached PHY driver [Generic PHY] 
(mii_bus:phy_addr=dsa-0.0:01, irq=-1)
[4.535219] Generic PHY dsa-0.0:02: attached PHY driver [Generic PHY] 
(mii_bus:phy_addr=dsa-0.0:02, irq=-1)
[4.545504] Generic PHY dsa-0.0:03: attached PHY driver [Generic PHY] 
(mii_bus:phy_addr=dsa-0.0:03, irq=-1)
[4.555815] Generic PHY dsa-0.0:04: attached PHY driver [Generic PHY] 
(mii_bus:phy_addr=dsa-0.0:04, irq=-1)

# ip link
2: eth0:  mtu 1500 qdisc fq_codel state UP 
mode DEFAULT group default qlen 1000
link/ether 10:0d:7f:4e:20:6e brd ff:ff:ff:ff:ff:ff
3: lan4@eth0:  mtu 1500 qdisc noqueue switchid 
 state UP mode DEFAULT group default qlen 1000
link/ether 10:0d:7f:4e:20:6e brd ff:ff:ff:ff:ff:ff
4: lan3@eth0:  mtu 1500 qdisc noop switchid  state 
DOWN mode DEFAULT group default qlen 1000
link/ether 10:0d:7f:4e:20:6e brd ff:ff:ff:ff:ff:ff
5: lan2@eth0:  mtu 1500 qdisc noop switchid  state 
DOWN mode DEFAULT group default qlen 1000
link/ether 10:0d:7f:4e:20:6e brd ff:ff:ff:ff:ff:ff
6: lan1@eth0:  mtu 1500 qdisc noop switchid  state 
DOWN mode DEFAULT group default qlen 1000
link/ether 10:0d:7f:4e:20:6e brd ff:ff:ff:ff:ff:ff
7: wan@eth0:  mtu 1500 qdisc noop switchid  state 
DOWN mode DEFAULT group default qlen 1000
link/ether 10:0d:7f:4e:20:6e brd ff:ff:ff:ff:ff:ff
 
> > As for this patch. Currently the apm821xx target in LEDE has two supported
> > routers, on AP and one NAS.
> > 
> > Both routers: The Netgear WNDR4700 and the Cisco MX60(W) use the AR8327N.
> > 
> > The AP: The Cisco Meraki MR24 has a AR8035 PHY. There's the at803x. driver,
> > but David Miller was ni

  1   2   >