Re: [PATCH] drm/rockchip: Cope with endpoints that haven't been registered yet

2021-04-16 Thread Jonathan McDowell
On Sun, Mar 21, 2021 at 07:58:13PM +0100, Heiko Stuebner wrote:
> Am Dienstag, 16. März 2021, 19:27:53 CET schrieb Jonathan McDowell:
> > The Rockchip RGB CRTC output driver attempts to avoid probing Rockchip
> > subdrivers to see if they're a connected panel or bridge. However part
> > of its checks assumes that if no OF platform device is found then it
> > can't be a valid bridge or panel. This causes issues with I2C controlled
> > bridges that have not yet been registered to the point they can be
> > found.
> > 
> > Change this to return EPROBE_DEFER instead of ENODEV and don't ignore
> > such devices. The subsequent call to drm_of_find_panel_or_bridge() will
> > return EPROBE_DEFER as well if there's actually a valid device we should
> > wait for.
> > 
> > Signed-off-by: Jonathan McDowell 
> > ---
> >  drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 8 ++--
> >  drivers/gpu/drm/rockchip/rockchip_rgb.c | 7 ---
> >  2 files changed, 10 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
> > b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> > index 212bd87c0c4a..b0d63a566501 100644
> > --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> > @@ -270,11 +270,15 @@ int rockchip_drm_endpoint_is_subdriver(struct 
> > device_node *ep)
> > if (!node)
> > return -ENODEV;
> >  
> > -   /* status disabled will prevent creation of platform-devices */
> > +   /*
> > +* status disabled will prevent creation of platform-devices,
> > +* but equally we can't rely on the driver having been registered
> > +* yet (e.g. I2C bridges).
> > +*/
> > pdev = of_find_device_by_node(node);
> > of_node_put(node);
> > if (!pdev)
> > -   return -ENODEV;
> > +   return -EPROBE_DEFER;
> 
> In general, how does that relate to i2c-bridge-drivers, as
> of_find_device_by_node supposedly only acts on platform-devices?

I think the problem here is that not finding the device node means we
return an error here, which means it's not actually possible to attach
an i2c bridge driver to the Rockchip RGB interface at present.

> Also if that points to a disabled bridge (hdmi, etc) that would likely make
> it probe-defer indefinitly, as that device will never become available?
> 
> Maybe we could do something like of_device_is_available() which checks
> the status property of the node. So something like:
> 
>   pdev = of_find_device_by_node(node);
>   if (!pdev) {
>   bool avail = of_device_is_available(node);
> 
>   of_node_put(node);
> 
>   /* if disabled
>   if (!avail)
>   return -ENODEV;
>   else
>   return -EPROBE_DEFER;
>   }
>   of_node_put(node);
> 
> Though I still do not understand how that should actually pick up on
> i2c devices at all.

of_find_device_by_node will fail here, as it's not a platform device,
but then of_device_is_available should return true so I think I can
actually just return false here rather than EPROBE_DEFER - because if
it's not a platform device then it's not a subdriver, which is what
we're checking for.

I'll re-roll and test this weekend and post an updated revision. Thanks
for the pointers.

J.

-- 
101 things you can't have too much of : 3 - Sleep.


[PATCH] drm/rockchip: Cope with endpoints that haven't been registered yet

2021-03-16 Thread Jonathan McDowell
The Rockchip RGB CRTC output driver attempts to avoid probing Rockchip
subdrivers to see if they're a connected panel or bridge. However part
of its checks assumes that if no OF platform device is found then it
can't be a valid bridge or panel. This causes issues with I2C controlled
bridges that have not yet been registered to the point they can be
found.

Change this to return EPROBE_DEFER instead of ENODEV and don't ignore
such devices. The subsequent call to drm_of_find_panel_or_bridge() will
return EPROBE_DEFER as well if there's actually a valid device we should
wait for.

Signed-off-by: Jonathan McDowell 
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 8 ++--
 drivers/gpu/drm/rockchip/rockchip_rgb.c | 7 ---
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 212bd87c0c4a..b0d63a566501 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -270,11 +270,15 @@ int rockchip_drm_endpoint_is_subdriver(struct device_node 
*ep)
if (!node)
return -ENODEV;
 
-   /* status disabled will prevent creation of platform-devices */
+   /*
+* status disabled will prevent creation of platform-devices,
+* but equally we can't rely on the driver having been registered
+* yet (e.g. I2C bridges).
+*/
pdev = of_find_device_by_node(node);
of_node_put(node);
if (!pdev)
-   return -ENODEV;
+   return -EPROBE_DEFER;
 
/*
 * All rockchip subdrivers have probed at this point, so
diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c 
b/drivers/gpu/drm/rockchip/rockchip_rgb.c
index c079714477d8..989595087397 100644
--- a/drivers/gpu/drm/rockchip/rockchip_rgb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c
@@ -77,7 +77,7 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
struct drm_encoder *encoder;
struct device_node *port, *endpoint;
u32 endpoint_id;
-   int ret = 0, child_count = 0;
+   int subret, ret = 0, child_count = 0;
struct drm_panel *panel;
struct drm_bridge *bridge;
 
@@ -96,8 +96,9 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
if (of_property_read_u32(endpoint, "reg", _id))
endpoint_id = 0;
 
-   /* if subdriver (> 0) or error case (< 0), ignore entry */
-   if (rockchip_drm_endpoint_is_subdriver(endpoint) != 0)
+   /* if subdriver (> 0) or non-defer error case (< 0), ignore 
entry */
+   subret = rockchip_drm_endpoint_is_subdriver(endpoint);
+   if (subret != 0 && subret != -EPROBE_DEFER)
continue;
 
child_count++;
-- 
2.20.1



[PATCH net-next] net: stmmac: Set FIFO sizes for ipq806x

2021-03-13 Thread Jonathan McDowell
Commit eaf4fac47807 ("net: stmmac: Do not accept invalid MTU values")
started using the TX FIFO size to verify what counts as a valid MTU
request for the stmmac driver.  This is unset for the ipq806x variant.
Looking at older patches for this it seems the RX + TXs buffers can be
up to 8k, so set appropriately.

(I sent this as an RFC patch in June last year, but received no replies.
I've been running with this on my hardware (a MikroTik RB3011) since
then with larger MTUs to support both the internal qca8k switch and
VLANs with no problems. Without the patch it's impossible to set the
larger MTU required to support this.)

Signed-off-by: Jonathan McDowell 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
index bf3250e0e59c..749585fe6fc9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
@@ -352,6 +352,8 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
plat_dat->bsp_priv = gmac;
plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed;
plat_dat->multicast_filter_bins = 0;
+   plat_dat->tx_fifo_size = 8192;
+   plat_dat->rx_fifo_size = 8192;
 
err = stmmac_dvr_probe(>dev, plat_dat, _res);
if (err)
-- 
2.30.1



Re: PGP pathfinder service is no longer maintained

2020-12-17 Thread Jonathan McDowell


In article <20201216224344.h3r7wbo7fgatupm5@chatter.i7.local> 
(earth.lists.linux-kernel) you wrote:
> On Wed, Dec 16, 2020 at 10:20:18PM +, Matthew Wilcox wrote:
> > > Unfortunately the site https://pgp.cs.uu.nl/ is not maintained 
> > > anymore
> > > and the "Finding paths to Linus" link in the Kernel Maintainer PGP guide
> > > is dead. Is there any alternative sites to find a way through the web of
> > > trust?
> > 
> > Several.  Konstantin has a local one: https://github.com/mricon/wotmate

> This is how we generate these:
> https://git.kernel.org/pub/scm/docs/kernel/pgpkeys.git/tree/graphs

> > and if you want a web service, I like this one:
> > https://the.earth.li/~noodles/pathfind.html

> FYI, it says "The pathfinder is currently out of action due to queries 
> taking far too long to respond. It may return in the future when I find 
> enough time to optimize it." :)

I've re-enabled it for the moment; the keyserver now only holds keys it
has paths to so hopefully it'll be a bit better behaved now.

J.

-- 
Give me liberty or I will cut you.


Re: [PATCH] dt-bindings: dmaengine: Convert Qualcomm ADM bindings to yaml

2020-12-10 Thread Jonathan McDowell
On Mon, Dec 07, 2020 at 01:12:22PM -0600, Rob Herring wrote:
> On Sun, Nov 15, 2020 at 06:12:42PM +0000, Jonathan McDowell wrote:
> > Converts the device tree bindings for the Qualcomm Application Data
> > Mover (ADM) DMA controller over to YAML schemas.
> > 
> > Signed-off-by: Jonathan McDowell 
> > ---
> >  .../devicetree/bindings/dma/qcom,adm.yaml | 102 ++
> >  .../devicetree/bindings/dma/qcom_adm.txt  |  61 ---
> >  2 files changed, 102 insertions(+), 61 deletions(-)
> >  create mode 100644 Documentation/devicetree/bindings/dma/qcom,adm.yaml
> >  delete mode 100644 Documentation/devicetree/bindings/dma/qcom_adm.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/dma/qcom,adm.yaml 
> > b/Documentation/devicetree/bindings/dma/qcom,adm.yaml
> > new file mode 100644
> > index ..353d85d3326d
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/dma/qcom,adm.yaml
> > @@ -0,0 +1,102 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/dma/qcom,adm.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: QCOM ADM DMA Controller
> > +
> > +maintainers:
> > +  - Jonathan McDowell 
> > +
> > +description: |
> > +  QCOM Application Data Mover (ADM) DMA controller found in the MSM8x60
> > +  and IPQ/APQ8064 platforms.
> > +
> > +properties:
> > +  compatible:
> > +oneOf:
> > +  - const: qcom,adm
> 
> Needs SoC specific compatible(s).

It's not clear would actually make sense that's more specific than this;
adding a version was discussed but it does not appear more recent chips
use the adm block and so qcom,adm was seen to be sufficient (as well as
matching what's already in tree).

> > +
> > +  reg:
> > +maxItems: 1
> > +description:
> > +  Address range for DMA registers
> 
> Drop description. Doesn't really add anything specific to this binding.

Ok.

> > +
> > +  interrupts:
> > +maxItems: 1
> > +description:
> > +  Should contain one interrupt shared by all channels
> 
> Drop.

Ok.

> > +
> > +  "#dma-cells":
> > +const: 2
> > +description:
> > +  First cell denotes the channel number.  Second cell denotes CRCI
> > +  (client rate control interface) flow control assignment. If no
> > +  flow control is required, use 0.
> > +
> > +  clocks:
> > +maxItems: 2
> > +description:
> > +  Should contain the core clock and interface clock.
> > +
> > +  clock-names:
> > +items:
> > +  - const: core
> > +  - const: iface
> > +
> > +  resets:
> > +maxItems: 4
> > +description:
> > +  Must contain an entry for each entry in reset names.
> > +
> > +  reset-names:
> > +items:
> > +  - const: clk
> > +  - const: c0
> > +  - const: c1
> > +  - const: c2
> > +
> > +  qcom,ee:
> > +maxItems: 1
> 
> maxItems is for arrays and this is a scalar.

So it should be:

  $ref: /schemas/types.yaml#/definitions/uint32

?

> > +description:
> > +  Indicates the security domain identifier used in the secure world.
> 
> How do I get 'ee' from this? Is this something other QCom blocks need?

Apparently it stands for "Execution Environment". It's used for other
QCom blocks as well (I see at least qcom,bam and qcom,spmi-pmic-arb
already in tree). I'll expand the comment to include the Execution
Environment string.

> > +$ref: /schemas/types.yaml#/definitions/uint32
> > +
> > +required:
> > +  - "#dma-cells"
> > +  - compatible
> > +  - reg
> > +  - clocks
> > +  - clock-names
> > +  - interrupts
> > +  - qcom,ee
> > +  - resets
> > +  - reset-names
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +#include 
> > +#include 
> > +#include 
> > +
> > +adm_dma: dma@1830 {
> 
> Drop unused labels.

Ok.

> 
> > + compatible = "qcom,adm";
> > + reg = <0x1830 0x10>;
> > + interrupts = ;
> > + #dma-cells = <2>;
> > +
> > + clocks = < ADM0_CLK>, < ADM0_PBUS_CLK>;
> > + clock-names = "core", "iface";
> > +
> > + resets = < ADM0_RESET>,
> > 

Re: [PATCH] ARM: dts: qcom: add prng definition to ipq806x

2020-11-29 Thread Jonathan McDowell
Gentle poke; did this just get missed or is there some reason not to
apply it?

On Sun, Jul 05, 2020 at 03:25:44PM +0100, Jonathan McDowell wrote:
> Add missing prng definition for ipq806x SoC
> 
> Signed-off-by: Jonathan McDowell 
> ---
>  arch/arm/boot/dts/qcom-ipq8064.dtsi | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi 
> b/arch/arm/boot/dts/qcom-ipq8064.dtsi
> index b912da9a3ff3..22e0669b9133 100644
> --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
> +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
> @@ -386,6 +386,13 @@ gsbi7_serial: serial@1664 {
>   };
>   };
>  
> + rng@1a50 {
> + compatible = "qcom,prng";
> + reg = <0x1a50 0x200>;
> + clocks = < PRNG_CLK>;
> + clock-names = "core";
> + };
> +
>   sata_phy: sata-phy@1b40 {
>   compatible = "qcom,ipq806x-sata-phy";
>   reg = <0x1b40 0x200>;
> -- 
> 2.27.0
> 

J.

-- 
Revd Jonathan McDowell, ULC | Hail Eris. All hail Discordia. Fnord?


[PATCH] dmaengine: qcom: Fix ADM driver kerneldoc markup

2020-11-26 Thread Jonathan McDowell
Update the kerneldoc function headers to fix build warnings:

drivers/dma/qcom/qcom_adm.c:180: warning: Function parameter or member 'chan' 
not described in 'adm_free_chan'
drivers/dma/qcom/qcom_adm.c:190: warning: Function parameter or member 'burst' 
not described in 'adm_get_blksize'
drivers/dma/qcom/qcom_adm.c:466: warning: Function parameter or member 'chan' 
not described in 'adm_terminate_all'
drivers/dma/qcom/qcom_adm.c:466: warning: Excess function parameter 'achan' 
description in 'adm_terminate_all'
drivers/dma/qcom/qcom_adm.c:503: warning: Function parameter or member 'achan' 
not described in 'adm_start_dma'

Signed-off-by: Jonathan McDowell 
---
 drivers/dma/qcom/qcom_adm.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/qcom/qcom_adm.c b/drivers/dma/qcom/qcom_adm.c
index 9b6f8e050ecc..ee78bed8d60d 100644
--- a/drivers/dma/qcom/qcom_adm.c
+++ b/drivers/dma/qcom/qcom_adm.c
@@ -173,8 +173,9 @@ struct adm_device {
 /**
  * adm_free_chan - Frees dma resources associated with the specific channel
  *
- * Free all allocated descriptors associated with this channel
+ * @chan: dma channel
  *
+ * Free all allocated descriptors associated with this channel
  */
 static void adm_free_chan(struct dma_chan *chan)
 {
@@ -185,6 +186,7 @@ static void adm_free_chan(struct dma_chan *chan)
 /**
  * adm_get_blksize - Get block size from burst value
  *
+ * @burst: Burst size of transaction
  */
 static int adm_get_blksize(unsigned int burst)
 {
@@ -456,7 +458,7 @@ static struct dma_async_tx_descriptor 
*adm_prep_slave_sg(struct dma_chan *chan,
 
 /**
  * adm_terminate_all - terminate all transactions on a channel
- * @achan: adm dma channel
+ * @chan: dma channel
  *
  * Dequeues and frees all transactions, aborts current transaction
  * No callbacks are done
@@ -497,7 +499,7 @@ static int adm_slave_config(struct dma_chan *chan, struct 
dma_slave_config *cfg)
 
 /**
  * adm_start_dma - start next transaction
- * @achan - ADM dma channel
+ * @achan: ADM dma channel
  */
 static void adm_start_dma(struct adm_chan *achan)
 {
-- 
2.20.1



[PATCH] dt-bindings: dmaengine: Convert Qualcomm ADM bindings to yaml

2020-11-15 Thread Jonathan McDowell
Converts the device tree bindings for the Qualcomm Application Data
Mover (ADM) DMA controller over to YAML schemas.

Signed-off-by: Jonathan McDowell 
---
 .../devicetree/bindings/dma/qcom,adm.yaml | 102 ++
 .../devicetree/bindings/dma/qcom_adm.txt  |  61 ---
 2 files changed, 102 insertions(+), 61 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/qcom,adm.yaml
 delete mode 100644 Documentation/devicetree/bindings/dma/qcom_adm.txt

diff --git a/Documentation/devicetree/bindings/dma/qcom,adm.yaml 
b/Documentation/devicetree/bindings/dma/qcom,adm.yaml
new file mode 100644
index ..353d85d3326d
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/qcom,adm.yaml
@@ -0,0 +1,102 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/qcom,adm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: QCOM ADM DMA Controller
+
+maintainers:
+  - Jonathan McDowell 
+
+description: |
+  QCOM Application Data Mover (ADM) DMA controller found in the MSM8x60
+  and IPQ/APQ8064 platforms.
+
+properties:
+  compatible:
+oneOf:
+  - const: qcom,adm
+
+  reg:
+maxItems: 1
+description:
+  Address range for DMA registers
+
+  interrupts:
+maxItems: 1
+description:
+  Should contain one interrupt shared by all channels
+
+  "#dma-cells":
+const: 2
+description:
+  First cell denotes the channel number.  Second cell denotes CRCI
+  (client rate control interface) flow control assignment. If no
+  flow control is required, use 0.
+
+  clocks:
+maxItems: 2
+description:
+  Should contain the core clock and interface clock.
+
+  clock-names:
+items:
+  - const: core
+  - const: iface
+
+  resets:
+maxItems: 4
+description:
+  Must contain an entry for each entry in reset names.
+
+  reset-names:
+items:
+  - const: clk
+  - const: c0
+  - const: c1
+  - const: c2
+
+  qcom,ee:
+maxItems: 1
+description:
+  Indicates the security domain identifier used in the secure world.
+$ref: /schemas/types.yaml#/definitions/uint32
+
+required:
+  - "#dma-cells"
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - qcom,ee
+  - resets
+  - reset-names
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+
+adm_dma: dma@1830 {
+ compatible = "qcom,adm";
+ reg = <0x1830 0x10>;
+ interrupts = ;
+ #dma-cells = <2>;
+
+ clocks = < ADM0_CLK>, < ADM0_PBUS_CLK>;
+ clock-names = "core", "iface";
+
+ resets = < ADM0_RESET>,
+  < ADM0_C0_RESET>,
+  < ADM0_C1_RESET>,
+  < ADM0_C2_RESET>;
+ reset-names = "clk", "c0", "c1", "c2";
+ qcom,ee = <0>;
+};
+
+...
diff --git a/Documentation/devicetree/bindings/dma/qcom_adm.txt 
b/Documentation/devicetree/bindings/dma/qcom_adm.txt
deleted file mode 100644
index 9d3b2f917b7b..
--- a/Documentation/devicetree/bindings/dma/qcom_adm.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-QCOM ADM DMA Controller
-
-Required properties:
-- compatible: must contain "qcom,adm" for IPQ/APQ8064 and MSM8960
-- reg: Address range for DMA registers
-- interrupts: Should contain one interrupt shared by all channels
-- #dma-cells: must be <2>.  First cell denotes the channel number.  Second cell
-  denotes CRCI (client rate control interface) flow control assignment.
-- clocks: Should contain the core clock and interface clock.
-- clock-names: Must contain "core" for the core clock and "iface" for the
-  interface clock.
-- resets: Must contain an entry for each entry in reset names.
-- reset-names: Must include the following entries:
-  - clk
-  - c0
-  - c1
-  - c2
-- qcom,ee: indicates the security domain identifier used in the secure world.
-
-Example:
-   adm_dma: dma@1830 {
-   compatible = "qcom,adm";
-   reg = <0x1830 0x10>;
-   interrupts = <0 170 0>;
-   #dma-cells = <2>;
-
-   clocks = < ADM0_CLK>, < ADM0_PBUS_CLK>;
-   clock-names = "core", "iface";
-
-   resets = < ADM0_RESET>,
-   < ADM0_C0_RESET>,
-   < ADM0_C1_RESET>,
-   < ADM0_C2_RESET>;
-   reset-names = "clk", "c0", "c1", "c2";
-   qcom,ee = <0>;
-  

[PATCH v5] dmaengine: qcom: Add ADM driver

2020-11-14 Thread Jonathan McDowell
Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA
controller found in the MSM8x60 and IPQ/APQ8064 platforms.

The ADM supports both memory to memory transactions and memory
to/from peripheral device transactions.  The controller also provides
flow control capabilities for transactions to/from peripheral devices.

The initial release of this driver supports slave transfers to/from
peripherals and also incorporates CRCI (client rate control interface)
flow control.

The hardware only supports a 32 bit physical address, so specifying
!PHYS_ADDR_T_64BIT gives maximum COMPILE_TEST coverage without having to
spend effort on kludging things in the code that will never actually be
needed on real hardware.

Signed-off-by: Andy Gross 
Signed-off-by: Thomas Pedersen 
Signed-off-by: Jonathan McDowell 

(I'm not sure how best to attribute this. It's originally from Andy
Gross, the version I picked up was a later version from Thomas Pedersen,
and I can't find clear indication of why the latest version wasn't
applied. The device tree details were added back in September 2014. The
driver is the missing piece in mainline for IPQ8064 NAND support and
I've been using it successfully with my RB3011 device on 5.8+)

v5:
- Clarify the reason for !PHYS_ADDR_T_64BIT
v4:
- Reorder probe function to acquire resources before enabling anything
v3:
- Depend on !PHYS_ADDR_T_64BIT rather than !64BIT as reported by kernel
  test robot 
v2:
- Address Vinod's review comments
  - GFP_NOWAIT instead of GFP_ATOMIC
  - Use devm_platform_ioremap_resource()
  - Call tasklet_kill on remove
  - Sort Kconfig/Makefile entries
  - SPDX identifier
  - Formatting fixes for checkpatch --strict
---
 drivers/dma/qcom/Kconfig|  11 +
 drivers/dma/qcom/Makefile   |   1 +
 drivers/dma/qcom/qcom_adm.c | 903 
 3 files changed, 915 insertions(+)
 create mode 100644 drivers/dma/qcom/qcom_adm.c

diff --git a/drivers/dma/qcom/Kconfig b/drivers/dma/qcom/Kconfig
index 3bcb689162c6..0389d60d2604 100644
--- a/drivers/dma/qcom/Kconfig
+++ b/drivers/dma/qcom/Kconfig
@@ -1,4 +1,15 @@
 # SPDX-License-Identifier: GPL-2.0-only
+config QCOM_ADM
+   tristate "Qualcomm ADM support"
+   depends on (ARCH_QCOM || COMPILE_TEST) && !PHYS_ADDR_T_64BIT
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Enable support for the Qualcomm Application Data Mover (ADM) DMA
+ controller, as present on MSM8x60, APQ8064, and IPQ8064 devices.
+ This controller provides DMA capabilities for both general purpose
+ and on-chip peripheral devices.
+
 config QCOM_BAM_DMA
tristate "QCOM BAM DMA support"
depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
diff --git a/drivers/dma/qcom/Makefile b/drivers/dma/qcom/Makefile
index 1ae92da88b0c..346e643fbb6d 100644
--- a/drivers/dma/qcom/Makefile
+++ b/drivers/dma/qcom/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
 obj-$(CONFIG_QCOM_BAM_DMA) += bam_dma.o
 obj-$(CONFIG_QCOM_HIDMA_MGMT) += hdma_mgmt.o
 hdma_mgmt-objs  := hidma_mgmt.o hidma_mgmt_sys.o
diff --git a/drivers/dma/qcom/qcom_adm.c b/drivers/dma/qcom/qcom_adm.c
new file mode 100644
index ..9b6f8e050ecc
--- /dev/null
+++ b/drivers/dma/qcom/qcom_adm.c
@@ -0,0 +1,903 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../dmaengine.h"
+#include "../virt-dma.h"
+
+/* ADM registers - calculated from channel number and security domain */
+#define ADM_CHAN_MULTI 0x4
+#define ADM_CI_MULTI   0x4
+#define ADM_CRCI_MULTI 0x4
+#define ADM_EE_MULTI   0x800
+#define ADM_CHAN_OFFS(chan)(ADM_CHAN_MULTI * (chan))
+#define ADM_EE_OFFS(ee)(ADM_EE_MULTI * (ee))
+#define ADM_CHAN_EE_OFFS(chan, ee) (ADM_CHAN_OFFS(chan) + ADM_EE_OFFS(ee))
+#define ADM_CHAN_OFFS(chan)(ADM_CHAN_MULTI * (chan))
+#define ADM_CI_OFFS(ci)(ADM_CHAN_OFF(ci))
+#define ADM_CH_CMD_PTR(chan, ee)   (ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_RSLT(chan, ee)  (0x40 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_FLUSH_STATE0(chan, ee)  (0x80 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_STATUS_SD(chan, ee) (0x200 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_CONF(chan)  (0x240 + ADM_CHAN_OFFS(chan))
+#define ADM_CH_RSLT_CONF(chan, ee) (0x300 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_SEC_DOMAIN_IRQ_STATUS(ee)  (0x380 + ADM_EE_OFFS(ee))
+#define ADM_CI_CONF(ci)(0x390 + (ci) * ADM_CI_MULTI)
+#define ADM

Re: [PATCH v4] dmaengine: qcom: Add ADM driver

2020-11-09 Thread Jonathan McDowell
On Mon, Nov 09, 2020 at 05:11:21PM +0530, Vinod Koul wrote:
> HI Jonathan,
> 
> On 23-09-20, 20:40, Jonathan McDowell wrote:
> > Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA
> > controller found in the MSM8x60 and IPQ/APQ8064 platforms.
> 
> Mostly it looks good, some nitpicks
> 
> > The ADM supports both memory to memory transactions and memory
> > to/from peripheral device transactions.  The controller also provides
> > flow control capabilities for transactions to/from peripheral devices.
> > 
> > The initial release of this driver supports slave transfers to/from
> > peripherals and also incorporates CRCI (client rate control interface)
> > flow control.
> 
> Can you also convert the binding from txt to yaml?

Seems like that can be a separate patch, but sure, I'll give it a whirl.

> > diff --git a/drivers/dma/qcom/Kconfig b/drivers/dma/qcom/Kconfig
> > index 3bcb689162c6..0389d60d2604 100644
> > --- a/drivers/dma/qcom/Kconfig
> > +++ b/drivers/dma/qcom/Kconfig
> > @@ -1,4 +1,15 @@
> >  # SPDX-License-Identifier: GPL-2.0-only
> > +config QCOM_ADM
> > +   tristate "Qualcomm ADM support"
> > +   depends on (ARCH_QCOM || COMPILE_TEST) && !PHYS_ADDR_T_64BIT
> 
> why !PHYS_ADDR_T_64BIT ..?

The hardware only supports a 32 bit physical address, so specifying
!PHYS_ADDR_T_64BIT gives maximum COMPILE_TEST coverage without having to
spend effort on kludging things in the code that will never actually be
needed on real hardware.

> > +   select DMA_ENGINE
> > +   select DMA_VIRTUAL_CHANNELS
> > +   help
> > + Enable support for the Qualcomm Application Data Mover (ADM) DMA
> > + controller, as present on MSM8x60, APQ8064, and IPQ8064 devices.
> > + This controller provides DMA capabilities for both general purpose
> > + and on-chip peripheral devices.
> 
> > +static const struct of_device_id adm_of_match[] = {
> > +   { .compatible = "qcom,adm", },
> 
> I know we have merged the binding, but should we not have a soc specific
> compatible?

Which soc? Looking at the other QCOM DMA drivers they mostly have
versioned compatibles and I can't find any indication there are multiple
variants of this block out there.

J.

-- 
Web [ Every program is either trivial or it contains at least one  ]
site: https:// [   bug.   ]  Made by
www.earth.li/~noodles/  [  ] HuggieTag 0.0.24


[PATCH net] net: dsa: qca8k: Fix port MTU setting

2020-10-30 Thread Jonathan McDowell
The qca8k only supports a switch-wide MTU setting, and the code to take
the max of all ports was only looking at the port currently being set.
Fix to examine all ports.

Reported-by: DENG Qingfang 
Fixes: f58d2598cf70 ("net: dsa: qca8k: implement the port MTU callbacks")
Cc: sta...@vger.kernel.org
Signed-off-by: Jonathan McDowell 
---
 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 53064e0e1618..5bdac669a339 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -1219,8 +1219,8 @@ qca8k_port_change_mtu(struct dsa_switch *ds, int port, 
int new_mtu)
priv->port_mtu[port] = new_mtu;
 
for (i = 0; i < QCA8K_NUM_PORTS; i++)
-   if (priv->port_mtu[port] > mtu)
-   mtu = priv->port_mtu[port];
+   if (priv->port_mtu[i] > mtu)
+   mtu = priv->port_mtu[i];
 
/* Include L2 header / FCS length */
qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
-- 
2.20.1



Re: [PATCH v4] dmaengine: qcom: Add ADM driver

2020-10-25 Thread Jonathan McDowell
Gentle ping on this one; looks like I missed the window for 5.10, but is
there anything outstanding for it to hit 5.11 or should I just have
patience?

On Wed, Sep 23, 2020 at 08:40:56PM +0100, Jonathan McDowell wrote:
> Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA
> controller found in the MSM8x60 and IPQ/APQ8064 platforms.
> 
> The ADM supports both memory to memory transactions and memory
> to/from peripheral device transactions.  The controller also provides
> flow control capabilities for transactions to/from peripheral devices.
> 
> The initial release of this driver supports slave transfers to/from
> peripherals and also incorporates CRCI (client rate control interface)
> flow control.
> 
> Signed-off-by: Andy Gross 
> Signed-off-by: Thomas Pedersen 
> Signed-off-by: Jonathan McDowell 
> 
> (I'm not sure how best to attribute this. It's originally from Andy
> Gross, the version I picked up was a later version from Thomas Pedersen,
> and I can't find clear indication of why the latest version wasn't
> applied. The device tree details were added back in September 2014. The
> driver is the missing piece in mainline for IPQ8064 NAND support and
> I've been using it successfully with my RB3011 device on 5.8+)
> 
> v4:
> - Reorder probe function to acquire resources before enabling anything
> v3:
> - Depend on !PHYS_ADDR_T_64BIT rather than !64BIT as reported by kernel
>   test robot 
> v2:
> - Address Vinod's review comments
>   - GFP_NOWAIT instead of GFP_ATOMIC
>   - Use devm_platform_ioremap_resource()
>   - Call tasklet_kill on remove
>   - Sort Kconfig/Makefile entries
>   - SPDX identifier
>   - Formatting fixes for checkpatch --strict
> ---
>  drivers/dma/qcom/Kconfig|  11 +
>  drivers/dma/qcom/Makefile   |   1 +
>  drivers/dma/qcom/qcom_adm.c | 903 
>  3 files changed, 915 insertions(+)
>  create mode 100644 drivers/dma/qcom/qcom_adm.c
> 
> diff --git a/drivers/dma/qcom/Kconfig b/drivers/dma/qcom/Kconfig
> index 3bcb689162c6..0389d60d2604 100644
> --- a/drivers/dma/qcom/Kconfig
> +++ b/drivers/dma/qcom/Kconfig
> @@ -1,4 +1,15 @@
>  # SPDX-License-Identifier: GPL-2.0-only
> +config QCOM_ADM
> + tristate "Qualcomm ADM support"
> + depends on (ARCH_QCOM || COMPILE_TEST) && !PHYS_ADDR_T_64BIT
> + select DMA_ENGINE
> + select DMA_VIRTUAL_CHANNELS
> + help
> +   Enable support for the Qualcomm Application Data Mover (ADM) DMA
> +   controller, as present on MSM8x60, APQ8064, and IPQ8064 devices.
> +   This controller provides DMA capabilities for both general purpose
> +   and on-chip peripheral devices.
> +
>  config QCOM_BAM_DMA
>   tristate "QCOM BAM DMA support"
>   depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
> diff --git a/drivers/dma/qcom/Makefile b/drivers/dma/qcom/Makefile
> index 1ae92da88b0c..346e643fbb6d 100644
> --- a/drivers/dma/qcom/Makefile
> +++ b/drivers/dma/qcom/Makefile
> @@ -1,4 +1,5 @@
>  # SPDX-License-Identifier: GPL-2.0
> +obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
>  obj-$(CONFIG_QCOM_BAM_DMA) += bam_dma.o
>  obj-$(CONFIG_QCOM_HIDMA_MGMT) += hdma_mgmt.o
>  hdma_mgmt-objs:= hidma_mgmt.o hidma_mgmt_sys.o
> diff --git a/drivers/dma/qcom/qcom_adm.c b/drivers/dma/qcom/qcom_adm.c
> new file mode 100644
> index ..9b6f8e050ecc
> --- /dev/null
> +++ b/drivers/dma/qcom/qcom_adm.c
> @@ -0,0 +1,903 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "../dmaengine.h"
> +#include "../virt-dma.h"
> +
> +/* ADM registers - calculated from channel number and security domain */
> +#define ADM_CHAN_MULTI   0x4
> +#define ADM_CI_MULTI 0x4
> +#define ADM_CRCI_MULTI   0x4
> +#define ADM_EE_MULTI 0x800
> +#define ADM_CHAN_OFFS(chan)  (ADM_CHAN_MULTI * (chan))
> +#define ADM_EE_OFFS(ee)  (ADM_EE_MULTI * (ee))
> +#define ADM_CHAN_EE_OFFS(chan, ee)   (ADM_CHAN_OFFS(chan) + ADM_EE_OFFS(ee))
> +#define ADM_CHAN_OFFS(chan)  (ADM_CHAN_MULTI * (chan))
> +#define ADM_CI_OFFS(ci)  (ADM_CHAN_OFF(ci))
> +#define ADM_CH_CMD_PTR(chan, ee) (ADM_CHAN_EE_OFFS(chan, ee))
> +#define ADM_CH_RSLT(chan, ee) 

[PATCH v4] dmaengine: qcom: Add ADM driver

2020-09-23 Thread Jonathan McDowell
Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA
controller found in the MSM8x60 and IPQ/APQ8064 platforms.

The ADM supports both memory to memory transactions and memory
to/from peripheral device transactions.  The controller also provides
flow control capabilities for transactions to/from peripheral devices.

The initial release of this driver supports slave transfers to/from
peripherals and also incorporates CRCI (client rate control interface)
flow control.

Signed-off-by: Andy Gross 
Signed-off-by: Thomas Pedersen 
Signed-off-by: Jonathan McDowell 

(I'm not sure how best to attribute this. It's originally from Andy
Gross, the version I picked up was a later version from Thomas Pedersen,
and I can't find clear indication of why the latest version wasn't
applied. The device tree details were added back in September 2014. The
driver is the missing piece in mainline for IPQ8064 NAND support and
I've been using it successfully with my RB3011 device on 5.8+)

v4:
- Reorder probe function to acquire resources before enabling anything
v3:
- Depend on !PHYS_ADDR_T_64BIT rather than !64BIT as reported by kernel
  test robot 
v2:
- Address Vinod's review comments
  - GFP_NOWAIT instead of GFP_ATOMIC
  - Use devm_platform_ioremap_resource()
  - Call tasklet_kill on remove
  - Sort Kconfig/Makefile entries
  - SPDX identifier
  - Formatting fixes for checkpatch --strict
---
 drivers/dma/qcom/Kconfig|  11 +
 drivers/dma/qcom/Makefile   |   1 +
 drivers/dma/qcom/qcom_adm.c | 903 
 3 files changed, 915 insertions(+)
 create mode 100644 drivers/dma/qcom/qcom_adm.c

diff --git a/drivers/dma/qcom/Kconfig b/drivers/dma/qcom/Kconfig
index 3bcb689162c6..0389d60d2604 100644
--- a/drivers/dma/qcom/Kconfig
+++ b/drivers/dma/qcom/Kconfig
@@ -1,4 +1,15 @@
 # SPDX-License-Identifier: GPL-2.0-only
+config QCOM_ADM
+   tristate "Qualcomm ADM support"
+   depends on (ARCH_QCOM || COMPILE_TEST) && !PHYS_ADDR_T_64BIT
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Enable support for the Qualcomm Application Data Mover (ADM) DMA
+ controller, as present on MSM8x60, APQ8064, and IPQ8064 devices.
+ This controller provides DMA capabilities for both general purpose
+ and on-chip peripheral devices.
+
 config QCOM_BAM_DMA
tristate "QCOM BAM DMA support"
depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
diff --git a/drivers/dma/qcom/Makefile b/drivers/dma/qcom/Makefile
index 1ae92da88b0c..346e643fbb6d 100644
--- a/drivers/dma/qcom/Makefile
+++ b/drivers/dma/qcom/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
 obj-$(CONFIG_QCOM_BAM_DMA) += bam_dma.o
 obj-$(CONFIG_QCOM_HIDMA_MGMT) += hdma_mgmt.o
 hdma_mgmt-objs  := hidma_mgmt.o hidma_mgmt_sys.o
diff --git a/drivers/dma/qcom/qcom_adm.c b/drivers/dma/qcom/qcom_adm.c
new file mode 100644
index ..9b6f8e050ecc
--- /dev/null
+++ b/drivers/dma/qcom/qcom_adm.c
@@ -0,0 +1,903 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../dmaengine.h"
+#include "../virt-dma.h"
+
+/* ADM registers - calculated from channel number and security domain */
+#define ADM_CHAN_MULTI 0x4
+#define ADM_CI_MULTI   0x4
+#define ADM_CRCI_MULTI 0x4
+#define ADM_EE_MULTI   0x800
+#define ADM_CHAN_OFFS(chan)(ADM_CHAN_MULTI * (chan))
+#define ADM_EE_OFFS(ee)(ADM_EE_MULTI * (ee))
+#define ADM_CHAN_EE_OFFS(chan, ee) (ADM_CHAN_OFFS(chan) + ADM_EE_OFFS(ee))
+#define ADM_CHAN_OFFS(chan)(ADM_CHAN_MULTI * (chan))
+#define ADM_CI_OFFS(ci)(ADM_CHAN_OFF(ci))
+#define ADM_CH_CMD_PTR(chan, ee)   (ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_RSLT(chan, ee)  (0x40 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_FLUSH_STATE0(chan, ee)  (0x80 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_STATUS_SD(chan, ee) (0x200 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_CONF(chan)  (0x240 + ADM_CHAN_OFFS(chan))
+#define ADM_CH_RSLT_CONF(chan, ee) (0x300 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_SEC_DOMAIN_IRQ_STATUS(ee)  (0x380 + ADM_EE_OFFS(ee))
+#define ADM_CI_CONF(ci)(0x390 + (ci) * ADM_CI_MULTI)
+#define ADM_GP_CTL 0x3d8
+#define ADM_CRCI_CTL(crci, ee) (0x400 + (crci) * ADM_CRCI_MULTI + \
+   ADM_EE_OFFS(ee))
+
+/* channel status */
+#define ADM_CH_STATUS_VALIDBIT(1)
+
+/* channel result */
+#define

[PATCH v3] dmaengine: qcom: Add ADM driver

2020-09-20 Thread Jonathan McDowell
Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA
controller found in the MSM8x60 and IPQ/APQ8064 platforms.

The ADM supports both memory to memory transactions and memory
to/from peripheral device transactions.  The controller also provides
flow control capabilities for transactions to/from peripheral devices.

The initial release of this driver supports slave transfers to/from
peripherals and also incorporates CRCI (client rate control interface)
flow control.

Signed-off-by: Andy Gross 
Signed-off-by: Thomas Pedersen 
Signed-off-by: Jonathan McDowell 

(I'm not sure how best to attribute this. It's originally from Andy
Gross, the version I picked up was a later version from Thomas Pedersen,
and I can't find clear indication of why the latest version wasn't
applied. The device tree details were added back in September 2014. The
driver is the missing piece in mainline for IPQ8064 NAND support and
I've been using it successfully with my RB3011 device on 5.8+)

v3:
- Depend on !PHYS_ADDR_T_64BIT rather than !64BIT as reported by kernel
  test robot 
v2:
- Address Vinod's review comments
  - GFP_NOWAIT instead of GFP_ATOMIC
  - Use devm_platform_ioremap_resource()
  - Call tasklet_kill on remove
  - Sort Kconfig/Makefile entries
  - SPDX identifier
  - Formatting fixes for checkpatch --strict
---
 drivers/dma/qcom/Kconfig|  11 +
 drivers/dma/qcom/Makefile   |   1 +
 drivers/dma/qcom/qcom_adm.c | 909 
 3 files changed, 921 insertions(+)
 create mode 100644 drivers/dma/qcom/qcom_adm.c

diff --git a/drivers/dma/qcom/Kconfig b/drivers/dma/qcom/Kconfig
index 3bcb689162c6..c78e8dfd0c2d 100644
--- a/drivers/dma/qcom/Kconfig
+++ b/drivers/dma/qcom/Kconfig
@@ -1,4 +1,15 @@
 # SPDX-License-Identifier: GPL-2.0-only
+config QCOM_ADM
+   tristate "Qualcomm ADM support"
+   depends on (ARCH_QCOM || COMPILE_TEST) && !PHYS_ADDR_T_64BIT
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Enable support for the Qualcomm Application Data Mover (ADM) DMA
+ controller, as present on MSM8x60, APQ8064, and IPQ8064 devices.
+ This controller provides DMA capabilities for both general purpose
+ and on-chip peripheral devices.
+
 config QCOM_BAM_DMA
tristate "QCOM BAM DMA support"
depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
diff --git a/drivers/dma/qcom/Makefile b/drivers/dma/qcom/Makefile
index 1ae92da88b0c..346e643fbb6d 100644
--- a/drivers/dma/qcom/Makefile
+++ b/drivers/dma/qcom/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
 obj-$(CONFIG_QCOM_BAM_DMA) += bam_dma.o
 obj-$(CONFIG_QCOM_HIDMA_MGMT) += hdma_mgmt.o
 hdma_mgmt-objs  := hidma_mgmt.o hidma_mgmt_sys.o
diff --git a/drivers/dma/qcom/qcom_adm.c b/drivers/dma/qcom/qcom_adm.c
new file mode 100644
index ..a5672039fc6b
--- /dev/null
+++ b/drivers/dma/qcom/qcom_adm.c
@@ -0,0 +1,909 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../dmaengine.h"
+#include "../virt-dma.h"
+
+/* ADM registers - calculated from channel number and security domain */
+#define ADM_CHAN_MULTI 0x4
+#define ADM_CI_MULTI   0x4
+#define ADM_CRCI_MULTI 0x4
+#define ADM_EE_MULTI   0x800
+#define ADM_CHAN_OFFS(chan)(ADM_CHAN_MULTI * (chan))
+#define ADM_EE_OFFS(ee)(ADM_EE_MULTI * (ee))
+#define ADM_CHAN_EE_OFFS(chan, ee) (ADM_CHAN_OFFS(chan) + ADM_EE_OFFS(ee))
+#define ADM_CHAN_OFFS(chan)(ADM_CHAN_MULTI * (chan))
+#define ADM_CI_OFFS(ci)(ADM_CHAN_OFF(ci))
+#define ADM_CH_CMD_PTR(chan, ee)   (ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_RSLT(chan, ee)  (0x40 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_FLUSH_STATE0(chan, ee)  (0x80 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_STATUS_SD(chan, ee) (0x200 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_CONF(chan)  (0x240 + ADM_CHAN_OFFS(chan))
+#define ADM_CH_RSLT_CONF(chan, ee) (0x300 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_SEC_DOMAIN_IRQ_STATUS(ee)  (0x380 + ADM_EE_OFFS(ee))
+#define ADM_CI_CONF(ci)(0x390 + (ci) * ADM_CI_MULTI)
+#define ADM_GP_CTL 0x3d8
+#define ADM_CRCI_CTL(crci, ee) (0x400 + (crci) * ADM_CRCI_MULTI + \
+   ADM_EE_OFFS(ee))
+
+/* channel status */
+#define ADM_CH_STATUS_VALIDBIT(1)
+
+/* channel result */
+#define ADM_CH_RSLT_VALID  BIT(31)
+#define ADM_CH_RSLT_ERR  

[PATCH v2] dmaengine: qcom: Add ADM driver

2020-09-19 Thread Jonathan McDowell
Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA
controller found in the MSM8x60 and IPQ/APQ8064 platforms.

The ADM supports both memory to memory transactions and memory
to/from peripheral device transactions.  The controller also provides
flow control capabilities for transactions to/from peripheral devices.

The initial release of this driver supports slave transfers to/from
peripherals and also incorporates CRCI (client rate control interface)
flow control.

Signed-off-by: Andy Gross 
Signed-off-by: Thomas Pedersen 
Signed-off-by: Jonathan McDowell 

(I'm not sure how best to attribute this. It's originally from Andy
Gross, the version I picked up was a later version from Thomas Pedersen,
and I can't find clear indication of why the latest version wasn't
applied. The device tree details were added back in September 2014. The
driver is the missing piece in mainline for IPQ8064 NAND support and
I've been using it successfully with my RB3011 device on 5.8+)

v2:
- Address Vinod's review comments
  - GFP_NOWAIT instead of GFP_ATOMIC
  - Use devm_platform_ioremap_resource()
  - Call tasklet_kill on remove
  - Sort Kconfig/Makefile entries
  - SPDX identifier
  - Formatting fixes for checkpatch --strict
---
 drivers/dma/qcom/Kconfig|  11 +
 drivers/dma/qcom/Makefile   |   1 +
 drivers/dma/qcom/qcom_adm.c | 909 
 3 files changed, 921 insertions(+)
 create mode 100644 drivers/dma/qcom/qcom_adm.c

diff --git a/drivers/dma/qcom/Kconfig b/drivers/dma/qcom/Kconfig
index 3bcb689162c6..c78e8dfd0c2d 100644
--- a/drivers/dma/qcom/Kconfig
+++ b/drivers/dma/qcom/Kconfig
@@ -1,4 +1,15 @@
 # SPDX-License-Identifier: GPL-2.0-only
+config QCOM_ADM
+   tristate "Qualcomm ADM support"
+   depends on (ARCH_QCOM || COMPILE_TEST) && !64BIT
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Enable support for the Qualcomm Application Data Mover (ADM) DMA
+ controller, as present on MSM8x60, APQ8064, and IPQ8064 devices.
+ This controller provides DMA capabilities for both general purpose
+ and on-chip peripheral devices.
+
 config QCOM_BAM_DMA
tristate "QCOM BAM DMA support"
depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
diff --git a/drivers/dma/qcom/Makefile b/drivers/dma/qcom/Makefile
index 1ae92da88b0c..346e643fbb6d 100644
--- a/drivers/dma/qcom/Makefile
+++ b/drivers/dma/qcom/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
 obj-$(CONFIG_QCOM_BAM_DMA) += bam_dma.o
 obj-$(CONFIG_QCOM_HIDMA_MGMT) += hdma_mgmt.o
 hdma_mgmt-objs  := hidma_mgmt.o hidma_mgmt_sys.o
diff --git a/drivers/dma/qcom/qcom_adm.c b/drivers/dma/qcom/qcom_adm.c
new file mode 100644
index ..a5672039fc6b
--- /dev/null
+++ b/drivers/dma/qcom/qcom_adm.c
@@ -0,0 +1,909 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../dmaengine.h"
+#include "../virt-dma.h"
+
+/* ADM registers - calculated from channel number and security domain */
+#define ADM_CHAN_MULTI 0x4
+#define ADM_CI_MULTI   0x4
+#define ADM_CRCI_MULTI 0x4
+#define ADM_EE_MULTI   0x800
+#define ADM_CHAN_OFFS(chan)(ADM_CHAN_MULTI * (chan))
+#define ADM_EE_OFFS(ee)(ADM_EE_MULTI * (ee))
+#define ADM_CHAN_EE_OFFS(chan, ee) (ADM_CHAN_OFFS(chan) + ADM_EE_OFFS(ee))
+#define ADM_CHAN_OFFS(chan)(ADM_CHAN_MULTI * (chan))
+#define ADM_CI_OFFS(ci)(ADM_CHAN_OFF(ci))
+#define ADM_CH_CMD_PTR(chan, ee)   (ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_RSLT(chan, ee)  (0x40 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_FLUSH_STATE0(chan, ee)  (0x80 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_STATUS_SD(chan, ee) (0x200 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_CONF(chan)  (0x240 + ADM_CHAN_OFFS(chan))
+#define ADM_CH_RSLT_CONF(chan, ee) (0x300 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_SEC_DOMAIN_IRQ_STATUS(ee)  (0x380 + ADM_EE_OFFS(ee))
+#define ADM_CI_CONF(ci)(0x390 + (ci) * ADM_CI_MULTI)
+#define ADM_GP_CTL 0x3d8
+#define ADM_CRCI_CTL(crci, ee) (0x400 + (crci) * ADM_CRCI_MULTI + \
+   ADM_EE_OFFS(ee))
+
+/* channel status */
+#define ADM_CH_STATUS_VALIDBIT(1)
+
+/* channel result */
+#define ADM_CH_RSLT_VALID  BIT(31)
+#define ADM_CH_RSLT_ERRBIT(3)
+#define ADM_CH_RSLT_FLUSH  BIT(2)
+#define ADM_CH_RSLT_TPDBIT(1)
+

Re: [PATCH] dmaengine: qcom: Add ADM driver

2020-09-18 Thread Jonathan McDowell
On Fri, Sep 18, 2020 at 05:04:43PM +0530, Vinod Koul wrote:
> Hello Jonathan
> 
> On 16-09-20, 07:43, Jonathan McDowell wrote:
> > From: Andy Gross 
> > 
> > (I'm not sure how best to attribute this. It's originally from Andy
> > Gross, the version I picked up was a later version from Thomas Pedersen,
> > and I can't find clear indication of why the latest version wasn't
> > applied. The device tree details were added back in September 2014. The
> > driver is the missing piece in mainline for IPQ8064 NAND support and
> > I've been using it successfully with my RB3011 device on 5.8+)
> 
> Yeah not sure why the driver was missed :(
> Btw this note is helpful but not great for log, you should add it after
> sob lines.

Noted, I'll move it for v2.

> > diff --git a/drivers/dma/qcom/Kconfig b/drivers/dma/qcom/Kconfig
> > index 3bcb689162c6..75ee112ccea9 100644
> > --- a/drivers/dma/qcom/Kconfig
> > +++ b/drivers/dma/qcom/Kconfig
> > @@ -28,3 +28,13 @@ config QCOM_HIDMA
> >   (user to kernel, kernel to kernel, etc.).  It only supports
> >   memcpy interface. The core is not intended for general
> >   purpose slave DMA.
> > +
> > +config QCOM_ADM
> 
> alphabetical sort please

Ok.

> > +   tristate "Qualcomm ADM support"
> > +   depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
> 
> Why COMPILE_TEST && OF? just COMPILE_TEST should be fine

Turns out (ARCH_QCOM || COMPILE_TEST) && !64BIT is sufficient.

> > +   select DMA_ENGINE
> > +   select DMA_VIRTUAL_CHANNELS
> > +   ---help---
> > + Enable support for the Qualcomm ADM DMA controller.  This controller
> > + provides DMA capabilities for both general purpose and on-chip
> > + peripheral devices.
> > diff --git a/drivers/dma/qcom/Makefile b/drivers/dma/qcom/Makefile
> > index 1ae92da88b0c..98a021fc6fe5 100644
> > --- a/drivers/dma/qcom/Makefile
> > +++ b/drivers/dma/qcom/Makefile
> > @@ -4,3 +4,4 @@ obj-$(CONFIG_QCOM_HIDMA_MGMT) += hdma_mgmt.o
> >  hdma_mgmt-objs  := hidma_mgmt.o hidma_mgmt_sys.o
> >  obj-$(CONFIG_QCOM_HIDMA) +=  hdma.o
> >  hdma-objs:= hidma_ll.o hidma.o hidma_dbg.o
> > +obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
> 
> alphabetical sort please

Ok.

> > +/* channel conf */
> > +#define ADM_CH_CONF_SHADOW_EN  BIT(12)
> > +#define ADM_CH_CONF_MPU_DISABLEBIT(11)
> > +#define ADM_CH_CONF_PERM_MPU_CONF  BIT(9)
> > +#define ADM_CH_CONF_FORCE_RSLT_EN  BIT(7)
> > +#define ADM_CH_CONF_SEC_DOMAIN(ee) (((ee & 0x3) << 4) | ((ee & 0x4) << 11))
> 
> USE FIELD_PREP for this?

I can't see a way to neatly use FIELD_PREP for a split field; am I
missing something?

(other pieces fixed up for v2 as well; I'd run checkpatch but not with
--strict. Will post once I've actually tested it.)

J.

-- 
 Minorities are the foundation of  |  .''`.  Debian GNU/Linux Developer
 society.  | : :' :  Happy to accept PGP signed
   | `. `'   or encrypted mail - RSA
   |   `-key on the keyservers.


[PATCH] dmaengine: qcom: Add ADM driver

2020-09-16 Thread Jonathan McDowell
From: Andy Gross 

(I'm not sure how best to attribute this. It's originally from Andy
Gross, the version I picked up was a later version from Thomas Pedersen,
and I can't find clear indication of why the latest version wasn't
applied. The device tree details were added back in September 2014. The
driver is the missing piece in mainline for IPQ8064 NAND support and
I've been using it successfully with my RB3011 device on 5.8+)

Add the DMA engine driver for the QCOM Application Data Mover (ADM) DMA
controller found in the MSM8x60 and IPQ/APQ8064 platforms.

The ADM supports both memory to memory transactions and memory
to/from peripheral device transactions.  The controller also provides
flow control capabilities for transactions to/from peripheral devices.

The initial release of this driver supports slave transfers to/from
peripherals and also incorporates CRCI (client rate control interface)
flow control.

Signed-off-by: Andy Gross 
Signed-off-by: Thomas Pedersen 
Signed-off-by: Jonathan McDowell 

diff --git a/drivers/dma/qcom/Kconfig b/drivers/dma/qcom/Kconfig
index 3bcb689162c6..75ee112ccea9 100644
--- a/drivers/dma/qcom/Kconfig
+++ b/drivers/dma/qcom/Kconfig
@@ -28,3 +28,13 @@ config QCOM_HIDMA
  (user to kernel, kernel to kernel, etc.).  It only supports
  memcpy interface. The core is not intended for general
  purpose slave DMA.
+
+config QCOM_ADM
+   tristate "Qualcomm ADM support"
+   depends on ARCH_QCOM || (COMPILE_TEST && OF && ARM)
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   ---help---
+ Enable support for the Qualcomm ADM DMA controller.  This controller
+ provides DMA capabilities for both general purpose and on-chip
+ peripheral devices.
diff --git a/drivers/dma/qcom/Makefile b/drivers/dma/qcom/Makefile
index 1ae92da88b0c..98a021fc6fe5 100644
--- a/drivers/dma/qcom/Makefile
+++ b/drivers/dma/qcom/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_QCOM_HIDMA_MGMT) += hdma_mgmt.o
 hdma_mgmt-objs  := hidma_mgmt.o hidma_mgmt_sys.o
 obj-$(CONFIG_QCOM_HIDMA) +=  hdma.o
 hdma-objs:= hidma_ll.o hidma.o hidma_dbg.o
+obj-$(CONFIG_QCOM_ADM) += qcom_adm.o
diff --git a/drivers/dma/qcom/qcom_adm.c b/drivers/dma/qcom/qcom_adm.c
new file mode 100644
index ..36d16c5e1515
--- /dev/null
+++ b/drivers/dma/qcom/qcom_adm.c
@@ -0,0 +1,914 @@
+/*
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../dmaengine.h"
+#include "../virt-dma.h"
+
+/* ADM registers - calculated from channel number and security domain */
+#define ADM_CHAN_MULTI 0x4
+#define ADM_CI_MULTI   0x4
+#define ADM_CRCI_MULTI 0x4
+#define ADM_EE_MULTI   0x800
+#define ADM_CHAN_OFFS(chan)(ADM_CHAN_MULTI * chan)
+#define ADM_EE_OFFS(ee)(ADM_EE_MULTI * ee)
+#define ADM_CHAN_EE_OFFS(chan, ee) (ADM_CHAN_OFFS(chan) + ADM_EE_OFFS(ee))
+#define ADM_CHAN_OFFS(chan)(ADM_CHAN_MULTI * chan)
+#define ADM_CI_OFFS(ci)(ADM_CHAN_OFF(ci))
+#define ADM_CH_CMD_PTR(chan, ee)   (ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_RSLT(chan, ee)  (0x40 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_FLUSH_STATE0(chan, ee)  (0x80 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_STATUS_SD(chan, ee) (0x200 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_CH_CONF(chan)  (0x240 + ADM_CHAN_OFFS(chan))
+#define ADM_CH_RSLT_CONF(chan, ee) (0x300 + ADM_CHAN_EE_OFFS(chan, ee))
+#define ADM_SEC_DOMAIN_IRQ_STATUS(ee)  (0x380 + ADM_EE_OFFS(ee))
+#define ADM_CI_CONF(ci)(0x390 + ci * ADM_CI_MULTI)
+#define ADM_GP_CTL 0x3d8
+#define ADM_CRCI_CTL(crci, ee) (0x400 + crci * ADM_CRCI_MULTI + \
+   ADM_EE_OFFS(ee))
+
+/* channel status */
+#define ADM_CH_STATUS_VALIDBIT(1)
+
+/* channel result */
+#define ADM_CH_RSLT_VALID  BIT(31)
+#define ADM_CH_RSLT_ERRBIT(3)
+#define ADM_CH_RSLT_FLUSH  BIT(2)
+#define ADM_CH_RSLT_TPDBIT(1)
+
+/* channel conf */
+#define ADM_CH_CONF_SHADOW_EN  BIT(12)
+#define ADM_CH_CONF_MPU_DISABLEBIT(11)
+#define 

Re: [net-next v4 1/6] net: marvell: prestera: Add driver for Prestera family ASIC devices

2020-08-14 Thread Jonathan McDowell
On Fri, Aug 14, 2020 at 11:20:54AM +0300, Vadym Kochan wrote:
> On Thu, Aug 13, 2020 at 09:03:22AM +0100, Jonathan McDowell wrote:
> > On Mon, Jul 27, 2020 at 03:22:37PM +0300, Vadym Kochan wrote:
> > > Marvell Prestera 98DX326x integrates up to 24 ports of 1GbE with 8
> > > ports of 10GbE uplinks or 2 ports of 40Gbps stacking for a largely
> > > wireless SMB deployment.
> > > 
> > > The current implementation supports only boards designed for the Marvell
> > > Switchdev solution and requires special firmware.
> > > 
> > > The core Prestera switching logic is implemented in prestera_main.c,
> > > there is an intermediate hw layer between core logic and firmware. It is
> > > implemented in prestera_hw.c, the purpose of it is to encapsulate hw
> > > related logic, in future there is a plan to support more devices with
> > > different HW related configurations.
> > 
> > The Prestera range covers a lot of different silicon. 98DX326x appears
> > to be AlleyCat3; does this driver definitely support all previous
> > revisions too? I've started looking at some 98DX4122 (BobCat+) hardware
> > and while some of the register mappings seem to match up it looks like
> > the DSA tagging has some extra information at least.
> > 
> > Worth making it clear exactly what this driver is expected to support,
> > and possibly fix up the naming/device tree compatibles as a result.
> > 
> Regarding "naming/device tree compatibles", do you mean to add
> compatible matching for particular ASIC and also for common ? 
> 
> Currently 
> 
> compatible = "marvell,prestera"
> 
> is used as default, so may be
> 
> you mean to support few matching including particular silicon too, like ?
> 
> 
> compatible = "marvell,prestera"
> compatible = "marvell,prestera-ac3x"
> 
> Would you please give an example ?

AFAICT "Prestera" is the general name for the Marvell
enterprise/data-centre silicon, comparable to the "LinkStreet"
designation for their lower end switching. The mv88e* drivers do not
mention LinkStreet in their compatible strings at all, choosing instead
to refer to chip IDs (I see mv88e6085, mv88e6190 + mv88e6250).

I do not have enough familiarity with the Prestera range to be able to
tell what commonality there is between the different versions (it
appears you need an NDA to get hold of the programming references), but
even just looking at your driver and the vendor code for the BobCat it
seems that AlleyCat3 uses an extended DSA header format, and requires a
firmware with message based access, in comparison to the BobCat which
uses register poking.

Based on that I'd recommend not using the bare "marvell,prestera"
compatible string, but instead something more specific.
"marvell,prestera-ac3x" seems like a suitable choice, assuming that's
how these chips are named/generally referred to.

Also I'd expand your Kconfig information to actually include "Marvell
Prestera 98DX326x" as that's the only supported chip range at present.

J.

-- 
... "'And the beast shall come forth surrounded by a roiling cloud of
vengeance. The house of the unbelievers shall be razed and they shall
be scorched to the earth. Their tags shall blink until the end of
days.' from The Book of Mozilla, 12:10" -- about:mozilla


Re: [net-next v4 1/6] net: marvell: prestera: Add driver for Prestera family ASIC devices

2020-08-13 Thread Jonathan McDowell
On Mon, Jul 27, 2020 at 03:22:37PM +0300, Vadym Kochan wrote:
> Marvell Prestera 98DX326x integrates up to 24 ports of 1GbE with 8
> ports of 10GbE uplinks or 2 ports of 40Gbps stacking for a largely
> wireless SMB deployment.
> 
> The current implementation supports only boards designed for the Marvell
> Switchdev solution and requires special firmware.
> 
> The core Prestera switching logic is implemented in prestera_main.c,
> there is an intermediate hw layer between core logic and firmware. It is
> implemented in prestera_hw.c, the purpose of it is to encapsulate hw
> related logic, in future there is a plan to support more devices with
> different HW related configurations.

The Prestera range covers a lot of different silicon. 98DX326x appears
to be AlleyCat3; does this driver definitely support all previous
revisions too? I've started looking at some 98DX4122 (BobCat+) hardware
and while some of the register mappings seem to match up it looks like
the DSA tagging has some extra information at least.

Worth making it clear exactly what this driver is expected to support,
and possibly fix up the naming/device tree compatibles as a result.

J.

-- 
... Nice world. Let's make it weirder.


[PATCH net 2/2] net: ethernet: stmmac: Disable hardware multicast filter

2020-08-12 Thread Jonathan McDowell
The IPQ806x does not appear to have a functional multicast ethernet
address filter. This was observed as a failure to correctly receive IPv6
packets on a LAN to the all stations address. Checking the vendor driver
shows that it does not attempt to enable the multicast filter and
instead falls back to receiving all multicast packets, internally
setting ALLMULTI.

Use the new fallback support in the dwmac1000 driver to correctly
achieve the same with the mainline IPQ806x driver. Confirmed to fix IPv6
functionality on an RB3011 router.

Cc: sta...@vger.kernel.org
Signed-off-by: Jonathan McDowell 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
index 02102c781a8c..bf3250e0e59c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
@@ -351,6 +351,7 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
plat_dat->has_gmac = true;
plat_dat->bsp_priv = gmac;
plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed;
+   plat_dat->multicast_filter_bins = 0;
 
err = stmmac_dvr_probe(>dev, plat_dat, _res);
if (err)
-- 
2.20.1



[PATCH net 1/2] net: stmmac: dwmac1000: provide multicast filter fallback

2020-08-12 Thread Jonathan McDowell
If we don't have a hardware multicast filter available then instead of
silently failing to listen for the requested ethernet broadcast
addresses fall back to receiving all multicast packets, in a similar
fashion to other drivers with no multicast filter.

Cc: sta...@vger.kernel.org
Signed-off-by: Jonathan McDowell 
---
 drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index efc6ec1b8027..fc8759f146c7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -164,6 +164,9 @@ static void dwmac1000_set_filter(struct mac_device_info *hw,
value = GMAC_FRAME_FILTER_PR | GMAC_FRAME_FILTER_PCF;
} else if (dev->flags & IFF_ALLMULTI) {
value = GMAC_FRAME_FILTER_PM;   /* pass all multi */
+   } else if (!netdev_mc_empty(dev) && (mcbitslog2 == 0)) {
+   /* Fall back to all multicast if we've no filter */
+   value = GMAC_FRAME_FILTER_PM;
} else if (!netdev_mc_empty(dev)) {
struct netdev_hw_addr *ha;
 
-- 
2.20.1



[PATCH net 0/2] net: stmmac: Fix multicast filter on IPQ806x

2020-08-12 Thread Jonathan McDowell
This pair of patches are the result of discovering a failure to
correctly receive IPv6 multicast packets on such a device (in particular
DHCPv6 requests and RA solicitations). Putting the device into
promiscuous mode, or allmulti, both resulted in such packets correctly
being received. Examination of the vendor driver (nss-gmac from the
qsdk) shows that it does not enable the multicast filter and instead
falls back to allmulti.

Extend the base dwmac1000 driver to fall back when there's no suitable
hardware filter, and update the ipq806x platform to request this.

Jonathan McDowell (2):
  net: stmmac: dwmac1000: provide multicast filter fallback
  net: ethernet: stmmac: Disable hardware multicast filter

 drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c  | 1 +
 drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 3 +++
 2 files changed, 4 insertions(+)

-- 
2.20.1



[PATCH net-next v3 2/2] net: dsa: qca8k: Add 802.1q VLAN support

2020-08-01 Thread Jonathan McDowell
This adds full 802.1q VLAN support to the qca8k, allowing the use of
vlan_filtering and more complicated bridging setups than allowed by
basic port VLAN support.

Tested with a number of untagged ports with separate VLANs and then a
trunk port with all the VLANs tagged on it.

v3:
- Pull QCA8K_PORT_VID_DEF changes into separate cleanup patch
- Reverse Christmas tree notation for variable definitions
- Use untagged instead of tagged for consistency
v2:
- Return sensible errnos on failure rather than -1 (rmk)
- Style cleanups based on Florian's feedback
- Silently allow VLAN 0 as device correctly treats this as no tag

Signed-off-by: Jonathan McDowell 
---
 drivers/net/dsa/qca8k.c | 181 
 drivers/net/dsa/qca8k.h |  27 ++
 2 files changed, 208 insertions(+)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 3ebc4da63074..f1e484477e35 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -408,6 +408,112 @@ qca8k_fdb_flush(struct qca8k_priv *priv)
mutex_unlock(>reg_mutex);
 }
 
+static int
+qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
+{
+   u32 reg;
+
+   /* Set the command and VLAN index */
+   reg = QCA8K_VTU_FUNC1_BUSY;
+   reg |= cmd;
+   reg |= vid << QCA8K_VTU_FUNC1_VID_S;
+
+   /* Write the function register triggering the table access */
+   qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
+
+   /* wait for completion */
+   if (qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY))
+   return -ETIMEDOUT;
+
+   /* Check for table full violation when adding an entry */
+   if (cmd == QCA8K_VLAN_LOAD) {
+   reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC1);
+   if (reg & QCA8K_VTU_FUNC1_FULL)
+   return -ENOMEM;
+   }
+
+   return 0;
+}
+
+static int
+qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool untagged)
+{
+   u32 reg;
+   int ret;
+
+   /*
+  We do the right thing with VLAN 0 and treat it as untagged while
+  preserving the tag on egress.
+*/
+   if (vid == 0)
+   return 0;
+
+   mutex_lock(>reg_mutex);
+   ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
+   if (ret < 0)
+   goto out;
+
+   reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
+   reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
+   reg &= ~(QCA8K_VTU_FUNC0_EG_MODE_MASK << 
QCA8K_VTU_FUNC0_EG_MODE_S(port));
+   if (untagged)
+   reg |= QCA8K_VTU_FUNC0_EG_MODE_UNTAG <<
+   QCA8K_VTU_FUNC0_EG_MODE_S(port);
+   else
+   reg |= QCA8K_VTU_FUNC0_EG_MODE_TAG <<
+   QCA8K_VTU_FUNC0_EG_MODE_S(port);
+
+   qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
+   ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
+
+out:
+   mutex_unlock(>reg_mutex);
+
+   return ret;
+}
+
+static int
+qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
+{
+   u32 reg, mask;
+   int ret, i;
+   bool del;
+
+   mutex_lock(>reg_mutex);
+   ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
+   if (ret < 0)
+   goto out;
+
+   reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
+   reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
+   reg |= QCA8K_VTU_FUNC0_EG_MODE_NOT <<
+   QCA8K_VTU_FUNC0_EG_MODE_S(port);
+
+   /* Check if we're the last member to be removed */
+   del = true;
+   for (i = 0; i < QCA8K_NUM_PORTS; i++) {
+   mask = QCA8K_VTU_FUNC0_EG_MODE_NOT;
+   mask <<= QCA8K_VTU_FUNC0_EG_MODE_S(i);
+
+   if ((reg & mask) != mask) {
+   del = false;
+   break;
+   }
+   }
+
+   if (del) {
+   ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
+   } else {
+   qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
+   ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
+   }
+
+out:
+   mutex_unlock(>reg_mutex);
+
+   return ret;
+}
+
 static void
 qca8k_mib_init(struct qca8k_priv *priv)
 {
@@ -1187,6 +1293,76 @@ qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
return 0;
 }
 
+static int
+qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering)
+{
+   struct qca8k_priv *priv = ds->priv;
+
+   if (vlan_filtering) {
+   qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
+ QCA8K_PORT_LOOKUP_VLAN_MODE,
+ QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE);
+   } else {
+   qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
+ QCA8K_PORT_LOOKUP_VLAN_MODE,
+ QCA8K_PORT_LOOKUP_VLAN_MODE_NONE);
+   

[PATCH net-next v3 1/2] net: dsa: qca8k: Add define for port VID

2020-08-01 Thread Jonathan McDowell
Rather than using a magic value of 1 when configuring the port VIDs add
a QCA8K_PORT_VID_DEF define and use that instead. Also fix up the
bitmask in the process; the top 4 bits are reserved so this wasn't a
problem, but only masking 12 bits is the correct approach.

Signed-off-by: Jonathan McDowell 
---
 drivers/net/dsa/qca8k.c | 11 ++-
 drivers/net/dsa/qca8k.h |  2 ++
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index a5566de82853..3ebc4da63074 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -663,10 +663,11 @@ qca8k_setup(struct dsa_switch *ds)
 * default egress vid
 */
qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
- 0x << shift, 1 << shift);
+ 0xfff << shift,
+ QCA8K_PORT_VID_DEF << shift);
qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
-   QCA8K_PORT_VLAN_CVID(1) |
-   QCA8K_PORT_VLAN_SVID(1));
+   QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
+   QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
}
}
 
@@ -1133,7 +1134,7 @@ qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 
*addr,
 {
/* Set the vid to the port vlan id if no vid is set */
if (!vid)
-   vid = 1;
+   vid = QCA8K_PORT_VID_DEF;
 
return qca8k_fdb_add(priv, addr, port_mask, vid,
 QCA8K_ATU_STATUS_STATIC);
@@ -1157,7 +1158,7 @@ qca8k_port_fdb_del(struct dsa_switch *ds, int port,
u16 port_mask = BIT(port);
 
if (!vid)
-   vid = 1;
+   vid = QCA8K_PORT_VID_DEF;
 
return qca8k_fdb_del(priv, addr, port_mask, vid);
 }
diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h
index 31439396401c..92216a52daa5 100644
--- a/drivers/net/dsa/qca8k.h
+++ b/drivers/net/dsa/qca8k.h
@@ -22,6 +22,8 @@
 
 #define QCA8K_CPU_PORT 0
 
+#define QCA8K_PORT_VID_DEF 1
+
 /* Global control registers */
 #define QCA8K_REG_MASK_CTRL0x000
 #define   QCA8K_MASK_CTRL_ID_M 0xff
-- 
2.20.1



Re: [PATCH net-next v2] net: dsa: qca8k: Add 802.1q VLAN support

2020-07-30 Thread Jonathan McDowell
On Tue, Jul 28, 2020 at 07:34:57PM +0300, Vladimir Oltean wrote:
> Hi Jonathan,
> 
> On Sun, Jul 26, 2020 at 03:56:11PM +0100, Jonathan McDowell wrote:
> > This adds full 802.1q VLAN support to the qca8k, allowing the use of
> > vlan_filtering and more complicated bridging setups than allowed by
> > basic port VLAN support.
> > 
> > Tested with a number of untagged ports with separate VLANs and then a
> > trunk port with all the VLANs tagged on it.
> > 
> > v2:
> > - Return sensible errnos on failure rather than -1 (rmk)
> > - Style cleanups based on Florian's feedback
> > - Silently allow VLAN 0 as device correctly treats this as no tag
> > 
> > Signed-off-by: Jonathan McDowell 
> > ---
> 
> This generally looks ok. The integration with the APIs is fine.
> Some comments below.
> 
> >  drivers/net/dsa/qca8k.c | 191 ++--
> >  drivers/net/dsa/qca8k.h |  28 ++
> >  2 files changed, 214 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
> > index a5566de82853..1cc61bc8929f 100644
> > --- a/drivers/net/dsa/qca8k.c
> > +++ b/drivers/net/dsa/qca8k.c
> > @@ -408,6 +408,111 @@ qca8k_fdb_flush(struct qca8k_priv *priv)
> > mutex_unlock(>reg_mutex);
> >  }
> >  
> > +static int
> > +qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 
> > vid)
> > +{
> > +   u32 reg;
> > +
> > +   /* Set the command and VLAN index */
> > +   reg = QCA8K_VTU_FUNC1_BUSY;
> > +   reg |= cmd;
> > +   reg |= vid << QCA8K_VTU_FUNC1_VID_S;
> > +
> > +   /* Write the function register triggering the table access */
> > +   qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
> > +
> > +   /* wait for completion */
> > +   if (qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY))
> > +   return -ETIMEDOUT;
> > +
> > +   /* Check for table full violation when adding an entry */
> > +   if (cmd == QCA8K_VLAN_LOAD) {
> > +   reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC1);
> > +   if (reg & QCA8K_VTU_FUNC1_FULL)
> > +   return -ENOMEM;
> > +   }
> > +
> > +   return 0;
> > +}
> > +
> > +static int
> > +qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool tagged)
> 
> It is customary to keep referring to this bool as 'untagged' for
> consistency with many other parts of the kernel.

Ok, changed.

> > +{
> > +   u32 reg;
> > +   int ret;
> > +
> > +   /* We do the right thing with VLAN 0 and treat it as untagged */
> 
> ...while also preserving the tag on egress.
> 
> > +   if (vid == 0)
> > +   return 0;
> > +
> > +   mutex_lock(>reg_mutex);
> 
> Unrelated, but what's the purpose of this mutex?

The access to the VLAN configuration is a set of writes to multiple
registers, so the mutex is to avoid trying to do 2 updates at the same
time. Same principle as is applied for the existing FDB accesses.

> > +   ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
> > +   if (ret < 0)
> > +   goto out;
> > +
> > +   reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
> > +   reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
> > +   reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
> > +   if (tagged)
> > +   reg |= QCA8K_VTU_FUNC0_EG_MODE_TAG <<
> > +   QCA8K_VTU_FUNC0_EG_MODE_S(port);
> > +   else
> > +   reg |= QCA8K_VTU_FUNC0_EG_MODE_UNTAG <<
> > +   QCA8K_VTU_FUNC0_EG_MODE_S(port);
> > +
> 
> Not thrilled about the "3 <<" thing, maybe a definition like the one
> below would look better:
> 
> #define QCA8K_VTU_FUNC_REG0_EG_VLAN_MODE_MASK(port) \
>   GENMASK(5 + (port) * 2, 4 + (port) * 2)
> 
> ...
> 
>   int eg_vlan_mode = QCA8K_VTU_FUNC_REG0_EG_MODE_TAG;
> 
>   reg &= ~QCA8K_VTU_FUNC_REG0_EG_VLAN_MODE_MASK(port);
>   if (tagged)
>   eg_vlan_mode = QCA8K_VTU_FUNC_REG0_EG_MODE_UNTAG;
>   reg |= QCA8K_VTU_FUNC_REG0_EG_MODE(eg_vlan_mode, port);
> 
> Your call if you want to change this, though.

I've added QCA8K_VTU_FUNC_REG0_EG_MODE_MASK instead of using the hard
coded 3, I think it's clearer when the mask + the values are both
getting the shift in the same manner.

> > +   qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
> > +   ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
> > +
> > +out:
> > +   mutex_unlock(>reg_m

[PATCH net-next v2] net: dsa: qca8k: Add 802.1q VLAN support

2020-07-26 Thread Jonathan McDowell
This adds full 802.1q VLAN support to the qca8k, allowing the use of
vlan_filtering and more complicated bridging setups than allowed by
basic port VLAN support.

Tested with a number of untagged ports with separate VLANs and then a
trunk port with all the VLANs tagged on it.

v2:
- Return sensible errnos on failure rather than -1 (rmk)
- Style cleanups based on Florian's feedback
- Silently allow VLAN 0 as device correctly treats this as no tag

Signed-off-by: Jonathan McDowell 
---
 drivers/net/dsa/qca8k.c | 191 ++--
 drivers/net/dsa/qca8k.h |  28 ++
 2 files changed, 214 insertions(+), 5 deletions(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index a5566de82853..1cc61bc8929f 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -408,6 +408,111 @@ qca8k_fdb_flush(struct qca8k_priv *priv)
mutex_unlock(>reg_mutex);
 }
 
+static int
+qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
+{
+   u32 reg;
+
+   /* Set the command and VLAN index */
+   reg = QCA8K_VTU_FUNC1_BUSY;
+   reg |= cmd;
+   reg |= vid << QCA8K_VTU_FUNC1_VID_S;
+
+   /* Write the function register triggering the table access */
+   qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
+
+   /* wait for completion */
+   if (qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY))
+   return -ETIMEDOUT;
+
+   /* Check for table full violation when adding an entry */
+   if (cmd == QCA8K_VLAN_LOAD) {
+   reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC1);
+   if (reg & QCA8K_VTU_FUNC1_FULL)
+   return -ENOMEM;
+   }
+
+   return 0;
+}
+
+static int
+qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool tagged)
+{
+   u32 reg;
+   int ret;
+
+   /* We do the right thing with VLAN 0 and treat it as untagged */
+   if (vid == 0)
+   return 0;
+
+   mutex_lock(>reg_mutex);
+   ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
+   if (ret < 0)
+   goto out;
+
+   reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
+   reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
+   reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
+   if (tagged)
+   reg |= QCA8K_VTU_FUNC0_EG_MODE_TAG <<
+   QCA8K_VTU_FUNC0_EG_MODE_S(port);
+   else
+   reg |= QCA8K_VTU_FUNC0_EG_MODE_UNTAG <<
+   QCA8K_VTU_FUNC0_EG_MODE_S(port);
+
+   qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
+   ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
+
+out:
+   mutex_unlock(>reg_mutex);
+
+   return ret;
+}
+
+static int
+qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
+{
+   u32 reg;
+   u32 mask;
+   int ret;
+   int i;
+   bool del;
+
+   mutex_lock(>reg_mutex);
+   ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
+   if (ret < 0)
+   goto out;
+
+   reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
+   reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
+   reg |= QCA8K_VTU_FUNC0_EG_MODE_NOT <<
+   QCA8K_VTU_FUNC0_EG_MODE_S(port);
+
+   /* Check if we're the last member to be removed */
+   del = true;
+   for (i = 0; i < QCA8K_NUM_PORTS; i++) {
+   mask = QCA8K_VTU_FUNC0_EG_MODE_NOT;
+   mask <<= QCA8K_VTU_FUNC0_EG_MODE_S(i);
+
+   if ((reg & mask) != mask) {
+   del = false;
+   break;
+   }
+   }
+
+   if (del) {
+   ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
+   } else {
+   qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
+   ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
+   }
+
+out:
+   mutex_unlock(>reg_mutex);
+
+   return ret;
+}
+
 static void
 qca8k_mib_init(struct qca8k_priv *priv)
 {
@@ -663,10 +768,11 @@ qca8k_setup(struct dsa_switch *ds)
 * default egress vid
 */
qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
- 0x << shift, 1 << shift);
+ 0x << shift,
+ QCA8K_PORT_VID_DEF << shift);
qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
-   QCA8K_PORT_VLAN_CVID(1) |
-   QCA8K_PORT_VLAN_SVID(1));
+   QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
+   QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
}
}
 
@@ -1133,7 +1239,7 @@ qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 
*addr,
 {
/* Set the 

Re: [RFC PATCH] net: dsa: qca8k: Add 802.1q VLAN support

2020-07-25 Thread Jonathan McDowell
On Thu, Jul 23, 2020 at 01:58:47AM +0300, Vladimir Oltean wrote:
> On Wed, Jul 22, 2020 at 03:36:38PM -0700, Florian Fainelli wrote:
> > On 7/22/20 12:38 PM, Jonathan McDowell wrote:
> > > On Tue, Jul 21, 2020 at 10:26:07AM -0700, Florian Fainelli wrote:
> > >> On 7/21/20 10:16 AM, Jonathan McDowell wrote:
> > >>> This adds full 802.1q VLAN support to the qca8k, allowing the use of
> > >>> vlan_filtering and more complicated bridging setups than allowed by
> > >>> basic port VLAN support.
> > >>>
> > >>> Tested with a number of untagged ports with separate VLANs and then a
> > >>> trunk port with all the VLANs tagged on it.
> > >>
> > >> This looks good to me at first glance, at least not seeing obvious
> > >> issue, however below are a few questions:
> > > 
> > > Thanks for the comments.
> > > 
> > >> - vid == 0 appears to be unsupported according to your port_vlan_prepare
> > >> callback, is this really the case, or is it more a case of VID 0 should
> > >> be pvid untagged, which is what dsa_slave_vlan_rx_add_vid() would
> > >> attempt to program
> > > 
> > > I don't quite follow you here. VID 0 doesn't appear to be supported by
> > > the hardware (and several other DSA drivers don't seem to like it
> > > either), hence the check; I'm not clear if there's something alternate I
> > > should be doing in that case instead?
> > 
> > Is it really that the hardware does not support it, or is it that it was
> > not tried or poorly handled before? If the switch supports programming
> > the VID 0 entry as PVID egress untagged, which is what
> > dsa_slave_vlan_rx_add_vid() requests, then this is great, because you
> > have almost nothing to do.
> > 
> > If not, what you are doing is definitively okay, because you have a
> > port_bridge_join that ensures that the port matrix gets configured
> > correctly for bridging, if that was not supported we would be in trouble.
> 
> Things added by dsa_slave_vlan_rx_add_vid() are definitely not "pvid
> untagged", they are installed with flags=0 which means "non-pvid,
> egress-tagged", aka a simple vlan with tagged ingress and egress.
> 
> The case of VLAN 0 is special because according to 802.1Q it is "not a
> VLAN", but simply a way to transmit the other stuff in a VLAN header,
> namely a class of service (VLAN PCP). The VLAN ID should not be used for
> segregation of forwarding domains, should not be assigned as port-based
> VLAN to untagged traffic (from what I recall from the 802.1Q standard)
> and should always be sent as egress-tagged.
...
> So maybe it's worth checking what is your switch's behavior with regard
> to VLAN 0. If it already does what's supposed to, then you might just as
> well stop fighting the system and silently accept the configuration
> while not doing anything.  As Russell implied, the bridge can't add a
> VLAN of 0. It is just the 8021q module that does it.  The fact that we
> have the same callbacks being used for both in DSA is merely an artefact
> of implementation.

Ok, thanks for the clarification, that helps a lot.

I've done some experimentation injecting packets on untagged ports with
VLAN 0 headers. It looks like it's doing the right thing; the intact
VLAN 0 / classification comes through to the CPU port, and the packet is
also correctly sent out tagged with the correct VLAN (from the untagged
port configuration) on a trunk port. So I think I can just silently drop
the request for VLAN 0 configuration rather than returning an error.

> > >> - since we have a qca8k_port_bridge_join() callback which programs the
> > >> port lookup control register, putting all ports by default in VID==1
> > >> does not break per-port isolation between non-bridged and bridged ports,
> > >> right?
> > > 
> > > VLAN_MODE_NONE (set when we don't have VLAN filtering enabled)
> > > configures us for port filtering, ignoring the VLAN info, so I think
> > > we're good here.
> > 
> > OK, good, so just to be sure, there is no cross talk between non-bridged
> > ports and bridged ports even when VLAN filtering is not enabled on the
> > bridge, right?

Yup. When VLAN filtering is off off we only allow ports to talk to each
other that we get bridge_join calls for (that's the way the device is
currently supported by the kernel).

J.

-- 
/-\ |  Be Ye Not Lost Among Precepts of
|@/  Debian GNU/Linux Developer |Order
\-  |


Re: [RFC PATCH] net: dsa: qca8k: Add 802.1q VLAN support

2020-07-22 Thread Jonathan McDowell
On Tue, Jul 21, 2020 at 10:26:07AM -0700, Florian Fainelli wrote:
> On 7/21/20 10:16 AM, Jonathan McDowell wrote:
> > This adds full 802.1q VLAN support to the qca8k, allowing the use of
> > vlan_filtering and more complicated bridging setups than allowed by
> > basic port VLAN support.
> > 
> > Tested with a number of untagged ports with separate VLANs and then a
> > trunk port with all the VLANs tagged on it.
> 
> This looks good to me at first glance, at least not seeing obvious
> issue, however below are a few questions:

Thanks for the comments.

> - vid == 0 appears to be unsupported according to your port_vlan_prepare
> callback, is this really the case, or is it more a case of VID 0 should
> be pvid untagged, which is what dsa_slave_vlan_rx_add_vid() would
> attempt to program

I don't quite follow you here. VID 0 doesn't appear to be supported by
the hardware (and several other DSA drivers don't seem to like it
either), hence the check; I'm not clear if there's something alternate I
should be doing in that case instead?

> - since we have a qca8k_port_bridge_join() callback which programs the
> port lookup control register, putting all ports by default in VID==1
> does not break per-port isolation between non-bridged and bridged ports,
> right?

VLAN_MODE_NONE (set when we don't have VLAN filtering enabled)
configures us for port filtering, ignoring the VLAN info, so I think
we're good here.

> - since you program the ports with a default VLAN ID upon startup of the
> switch driver should not you also set
> dsa_switch::configure_vlan_while_not_filtering to indicate to the DSA
> layer that there is a VLAN table programmed regardless of VLAN filtering
> being enabled in the bridge or not?

Yup, this should be set. I'd seen the vlan_bridge_vtu patch from
December but not noticed it had been renamed, just assumed it hadn't
been applied.

> See some nitpicks below:
> 
> > 
> > Signed-off-by: Jonathan McDowell 
> > 
> > diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
> > index a5566de82853..cce05493075f 100644
> > --- a/drivers/net/dsa/qca8k.c
> > +++ b/drivers/net/dsa/qca8k.c
> > @@ -408,6 +408,104 @@ qca8k_fdb_flush(struct qca8k_priv *priv)
> > mutex_unlock(>reg_mutex);
> >  }
> >  
> > +static int
> > +qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 
> > vid)
> > +{
> > +   u32 reg;
> > +
> > +   /* Set the command and VLAN index */
> > +   reg = QCA8K_VTU_FUNC1_BUSY;> +  reg |= cmd;
> > +   reg |= vid << QCA8K_VTU_FUNC1_VID_S;
> > +
> > +   /* Write the function register triggering the table access */
> > +   qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
> > +
> > +   /* wait for completion */
> > +   if (qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY))
> > +   return -1;
> 
> Can you propagate the return value from qca8k_busy_wait() directly?

It just returns a boolean. rmk makes a valid point about a sensible
errno instead, so I'll switch to ETIMEDOUT in v2 (and ENOMEM when the
VLAN table is full below).

> > +
> > +   /* Check for table full violation when adding an entry */
> > +   if (cmd == QCA8K_VLAN_LOAD) {
> > +   reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC1);
> > +   if (reg & QCA8K_VTU_FUNC1_FULL)
> > +   return -1;
> > +   }
> > +
> > +   return 0;
> > +}
> > +
> > +static int
> > +qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool tagged)
> > +{
> > +   u32 reg;
> > +   int ret;
> > +
> > +   if (!vid)
> > +   return -EOPNOTSUPP;
> > +
> > +   mutex_lock(>reg_mutex);
> > +   ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
> > +   if (ret >= 0) {
> 
> Do an early return upon negative error code instead of reidenting the
> code block?

I'll switch over to a goto for cleanup (unlocking the mutex) to avoid
the extra indentation (and below).

> > +   reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
> > +   reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
> > +   reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
> > +   if (tagged)
> > +   reg |= QCA8K_VTU_FUNC0_EG_MODE_TAG <<
> > +   QCA8K_VTU_FUNC0_EG_MODE_S(port);
> > +   else
> > +   reg |= QCA8K_VTU_FUNC0_EG_MODE_UNTAG <<
> > +   QCA8K_VTU_FUNC0_EG_MODE_S(port);
> > +
> > +   qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
> > +   ret = qca8k_vlan_acc

Re: [RFC PATCH] net: dsa: qca8k: Add 802.1q VLAN support

2020-07-22 Thread Jonathan McDowell
On Tue, Jul 21, 2020 at 09:48:18PM +0100, Russell King - ARM Linux admin wrote:
> On Tue, Jul 21, 2020 at 06:16:24PM +0100, Jonathan McDowell wrote:
> > This adds full 802.1q VLAN support to the qca8k, allowing the use of
> > vlan_filtering and more complicated bridging setups than allowed by
> > basic port VLAN support.
> > 
> > Tested with a number of untagged ports with separate VLANs and then a
> > trunk port with all the VLANs tagged on it.
> > 
> > Signed-off-by: Jonathan McDowell 
> > 
> > diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
> > index a5566de82853..cce05493075f 100644
> > --- a/drivers/net/dsa/qca8k.c
> > +++ b/drivers/net/dsa/qca8k.c
> > @@ -408,6 +408,104 @@ qca8k_fdb_flush(struct qca8k_priv *priv)
> > mutex_unlock(>reg_mutex);
> >  }
> >  
> > +static int
> > +qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 
> > vid)
> > +{
> > +   u32 reg;
> > +
> > +   /* Set the command and VLAN index */
> > +   reg = QCA8K_VTU_FUNC1_BUSY;
> > +   reg |= cmd;
> > +   reg |= vid << QCA8K_VTU_FUNC1_VID_S;
> > +
> > +   /* Write the function register triggering the table access */
> > +   qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
> > +
> > +   /* wait for completion */
> > +   if (qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY))
> > +   return -1;
> 
> You return -1 here.  Personally, I don't like this in the kernel, as
> convention is for functions returning "int" to return negative errno
> values, and this risks returning -1 (-EPERM) being returned to userspace
> if someone decides to propagate the "error code".

Reasonable. I based this code off the qca8k_fdb_access code, but I'll
switch over to more sensible returns (and clean the fdb stuff up in a
separate patch).

> > +
> > +   /* Check for table full violation when adding an entry */
> > +   if (cmd == QCA8K_VLAN_LOAD) {
> > +   reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC1);
> > +   if (reg & QCA8K_VTU_FUNC1_FULL)
> > +   return -1;
> 
> ... and here.
> 
> > +   }
> > +
> > +   return 0;
> > +}
> > +
> > +static int
> > +qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool tagged)
> > +{
> > +   u32 reg;
> > +   int ret;
> > +
> > +   if (!vid)
> > +   return -EOPNOTSUPP;
> 
> Have you checked whether this can be called with vid=0 ?

It's called at startup with VID 0 (part of setting up the HW filter
according to the log message?) and the hardware isn't happy with that.

...
> > +
> > +static int
> > +qca8k_port_vlan_prepare(struct dsa_switch *ds, int port,
> > +   const struct switchdev_obj_port_vlan *vlan)
> > +{
> > +   if (!vlan->vid_begin)
> > +   return -EOPNOTSUPP;
> > +
> > +   return 0;
> > +}
> > +
> > +static void
> > +qca8k_port_vlan_add(struct dsa_switch *ds, int port,
> > +   const struct switchdev_obj_port_vlan *vlan)
> > +{
> > +   struct qca8k_priv *priv = ds->priv;
> > +   bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
> > +   bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
> > +   u16 vid;
> > +
> > +   for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid)
> > +   qca8k_vlan_add(priv, port, vid, !untagged);
> 
> The and ignored here, so is there any point qca8k_vlan_add() returning
> an error?  If it fails, we'll never know... there even seems to be no
> diagnostic gets logged in the kernel message log.
> 
> If you decide to add some logging, be careful how you do it - userspace
> could ask for vids 1..4095 to be added, and we wouldn't want the
> possibility of 4094 error messages.
> 
> Another issue may be the time taken to process 4094 VIDs if
> qca8k_busy_wait() has to wait for every one.

I'll add a break out on error (and a dev_err) for this and the del case
in v2.

J.

-- 
   Hell is other people.   |  .''`.  Debian GNU/Linux Developer
   | : :' :  Happy to accept PGP signed
   | `. `'   or encrypted mail - RSA
   |   `-key on the keyservers.


[RFC PATCH] net: dsa: qca8k: Add 802.1q VLAN support

2020-07-21 Thread Jonathan McDowell
This adds full 802.1q VLAN support to the qca8k, allowing the use of
vlan_filtering and more complicated bridging setups than allowed by
basic port VLAN support.

Tested with a number of untagged ports with separate VLANs and then a
trunk port with all the VLANs tagged on it.

Signed-off-by: Jonathan McDowell 

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index a5566de82853..cce05493075f 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -408,6 +408,104 @@ qca8k_fdb_flush(struct qca8k_priv *priv)
mutex_unlock(>reg_mutex);
 }
 
+static int
+qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
+{
+   u32 reg;
+
+   /* Set the command and VLAN index */
+   reg = QCA8K_VTU_FUNC1_BUSY;
+   reg |= cmd;
+   reg |= vid << QCA8K_VTU_FUNC1_VID_S;
+
+   /* Write the function register triggering the table access */
+   qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
+
+   /* wait for completion */
+   if (qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY))
+   return -1;
+
+   /* Check for table full violation when adding an entry */
+   if (cmd == QCA8K_VLAN_LOAD) {
+   reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC1);
+   if (reg & QCA8K_VTU_FUNC1_FULL)
+   return -1;
+   }
+
+   return 0;
+}
+
+static int
+qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid, bool tagged)
+{
+   u32 reg;
+   int ret;
+
+   if (!vid)
+   return -EOPNOTSUPP;
+
+   mutex_lock(>reg_mutex);
+   ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
+   if (ret >= 0) {
+   reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
+   reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
+   reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
+   if (tagged)
+   reg |= QCA8K_VTU_FUNC0_EG_MODE_TAG <<
+   QCA8K_VTU_FUNC0_EG_MODE_S(port);
+   else
+   reg |= QCA8K_VTU_FUNC0_EG_MODE_UNTAG <<
+   QCA8K_VTU_FUNC0_EG_MODE_S(port);
+
+   qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
+   ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
+   }
+   mutex_unlock(>reg_mutex);
+
+   return ret;
+}
+
+static int
+qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
+{
+   u32 reg;
+   u32 mask;
+   int ret;
+   int i;
+   bool del;
+
+   mutex_lock(>reg_mutex);
+   ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
+   if (ret >= 0) {
+   reg = qca8k_read(priv, QCA8K_REG_VTU_FUNC0);
+   reg &= ~(3 << QCA8K_VTU_FUNC0_EG_MODE_S(port));
+   reg |= QCA8K_VTU_FUNC0_EG_MODE_NOT <<
+   QCA8K_VTU_FUNC0_EG_MODE_S(port);
+
+   /* Check if we're the last member to be removed */
+   del = true;
+   for (i = 0; i < QCA8K_NUM_PORTS; i++) {
+   mask = QCA8K_VTU_FUNC0_EG_MODE_NOT;
+   mask <<= QCA8K_VTU_FUNC0_EG_MODE_S(i);
+
+   if ((reg & mask) != mask) {
+   del = false;
+   break;
+   }
+   }
+
+   if (del) {
+   ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
+   } else {
+   qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
+   ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
+   }
+   }
+   mutex_unlock(>reg_mutex);
+
+   return ret;
+}
+
 static void
 qca8k_mib_init(struct qca8k_priv *priv)
 {
@@ -663,10 +761,11 @@ qca8k_setup(struct dsa_switch *ds)
 * default egress vid
 */
qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
- 0x << shift, 1 << shift);
+ 0x << shift,
+ QCA8K_PORT_VID_DEF << shift);
qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
-   QCA8K_PORT_VLAN_CVID(1) |
-   QCA8K_PORT_VLAN_SVID(1));
+   QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
+   QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
}
}
 
@@ -1133,7 +1232,7 @@ qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 
*addr,
 {
/* Set the vid to the port vlan id if no vid is set */
if (!vid)
-   vid = 1;
+   vid = QCA8K_PORT_VID_DEF;
 
return qca8k_fdb_add(priv, addr, port_mask, vid,
 

[PATCH v2] net: dsa: qca8k: implement the port MTU callbacks

2020-07-18 Thread Jonathan McDowell
This switch has a single max frame size configuration register, so we
track the requested MTU for each port and apply the largest.

v2:
- Address review feedback from Vladimir Oltean

Signed-off-by: Jonathan McDowell 
---
 drivers/net/dsa/qca8k.c | 31 +++
 drivers/net/dsa/qca8k.h |  3 +++
 2 files changed, 34 insertions(+)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 4acad5fa0c84..a5566de82853 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -670,6 +670,11 @@ qca8k_setup(struct dsa_switch *ds)
}
}
 
+   /* Setup our port MTUs to match power on defaults */
+   for (i = 0; i < QCA8K_NUM_PORTS; i++)
+   priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
+   qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
+
/* Flush the FDB table */
qca8k_fdb_flush(priv);
 
@@ -1098,6 +1103,30 @@ qca8k_port_disable(struct dsa_switch *ds, int port)
priv->port_sts[port].enabled = 0;
 }
 
+static int
+qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
+{
+   struct qca8k_priv *priv = ds->priv;
+   int i, mtu = 0;
+
+   priv->port_mtu[port] = new_mtu;
+
+   for (i = 0; i < QCA8K_NUM_PORTS; i++)
+   if (priv->port_mtu[port] > mtu)
+   mtu = priv->port_mtu[port];
+
+   /* Include L2 header / FCS length */
+   qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
+
+   return 0;
+}
+
+static int
+qca8k_port_max_mtu(struct dsa_switch *ds, int port)
+{
+   return QCA8K_MAX_MTU;
+}
+
 static int
 qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
  u16 port_mask, u16 vid)
@@ -1174,6 +1203,8 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
.set_mac_eee= qca8k_set_mac_eee,
.port_enable= qca8k_port_enable,
.port_disable   = qca8k_port_disable,
+   .port_change_mtu= qca8k_port_change_mtu,
+   .port_max_mtu   = qca8k_port_max_mtu,
.port_stp_state_set = qca8k_port_stp_state_set,
.port_bridge_join   = qca8k_port_bridge_join,
.port_bridge_leave  = qca8k_port_bridge_leave,
diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h
index 10ef2bca2cde..31439396401c 100644
--- a/drivers/net/dsa/qca8k.h
+++ b/drivers/net/dsa/qca8k.h
@@ -13,6 +13,7 @@
 #include 
 
 #define QCA8K_NUM_PORTS7
+#define QCA8K_MAX_MTU  9000
 
 #define PHY_ID_QCA8337 0x004dd036
 #define QCA8K_ID_QCA8337   0x13
@@ -58,6 +59,7 @@
 #define   QCA8K_MDIO_MASTER_MAX_REG32
 #define QCA8K_GOL_MAC_ADDR00x60
 #define QCA8K_GOL_MAC_ADDR10x64
+#define QCA8K_MAX_FRAME_SIZE   0x78
 #define QCA8K_REG_PORT_STATUS(_i)  (0x07c + (_i) * 4)
 #define   QCA8K_PORT_STATUS_SPEED  GENMASK(1, 0)
 #define   QCA8K_PORT_STATUS_SPEED_10   0
@@ -189,6 +191,7 @@ struct qca8k_priv {
struct device *dev;
struct dsa_switch_ops ops;
struct gpio_desc *reset_gpio;
+   unsigned int port_mtu[QCA8K_NUM_PORTS];
 };
 
 struct qca8k_mib_desc {
-- 
2.27.0



Re: [PATCH] net: dsa: qca8k: implement the port MTU callbacks

2020-07-18 Thread Jonathan McDowell
On Sat, Jul 18, 2020 at 01:38:08PM +0300, Vladimir Oltean wrote:
> On Sat, Jul 18, 2020 at 10:35:55AM +0100, Jonathan McDowell wrote:
> > This switch has a single max frame size configuration register, so we
> > track the requested MTU for each port and apply the largest.
> > 
> > Signed-off-by: Jonathan McDowell 
> > ---
> >  drivers/net/dsa/qca8k.c | 38 ++
> >  drivers/net/dsa/qca8k.h |  3 +++
> >  2 files changed, 41 insertions(+)
> > 
> > diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
> > index 4acad5fa0c84..3690f02aea3a 100644
> > --- a/drivers/net/dsa/qca8k.c
> > +++ b/drivers/net/dsa/qca8k.c
> > @@ -670,6 +670,12 @@ qca8k_setup(struct dsa_switch *ds)
> > }
> > }
> >  
> > +   /* Setup our port MTUs to match power on defaults */
> > +   for (i = 0; i < QCA8K_NUM_PORTS; i++) {
> > +   priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
> > +   }
> 
> I am not quite sure the curly brackets are needed. And nowhere else in
> qca8k.c is this convention being used.

Good point; force of habit from coding standards elsewhere. Fixed (and
also the instance below).

> > +   qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
> > +
> > /* Flush the FDB table */
> > qca8k_fdb_flush(priv);
> >  
> > @@ -1098,6 +1104,36 @@ qca8k_port_disable(struct dsa_switch *ds, int port)
> > priv->port_sts[port].enabled = 0;
> >  }
> >  
> > +static int
> > +qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
> > +{
> > +   struct qca8k_priv *priv = ds->priv;
> > +   int i, mtu;
> > +
> > +   if ((new_mtu < ETH_MIN_MTU) || (new_mtu > QCA8K_MAX_MTU)) {
> > +   return -EINVAL;
> > +   }
> 
> I'm pretty sure this check should not be needed.
> The only reason why slave_dev->min_mtu is 0 seems to be:
> 
> commit 8b1efc0f83f1f75b8f85c70d2211007de8fd7633
> Author: Jarod Wilson 
> Date:   Thu Oct 20 23:25:27 2016 -0400
> 
> net: remove MTU limits on a few ether_setup callers
> 
> These few drivers call ether_setup(), but have no ndo_change_mtu, and thus
> were overlooked for changes to MTU range checking behavior. They
> previously had no range checks, so for feature-parity, set their min_mtu
> to 0 and max_mtu to ETH_MAX_MTU (65535), instead of the 68 and 1500
> inherited from the ether_setup() changes. Fine-tuning can come after we 
> get
> back to full feature-parity here.
> 
> CC: net...@vger.kernel.org
> Reported-by: Asbjoern Sloth Toennesen 
> CC: Asbjoern Sloth Toennesen 
> CC: R Parameswaran 
> Signed-off-by: Jarod Wilson 
> Signed-off-by: David S. Miller 
> 
> which is an oversight on my part. Since now DSA supports
> ndo_change_mtu(), the "slave_dev->min_mtu = 0;" line in net/dsa/slave.c
> can be removed and so can this check.

Ok.

> > +
> > +   priv->port_mtu[port] = new_mtu;
> > +
> > +   mtu = 0;
> 
> I think it's more typical to initialize mtu to 0 at declaration time.

Sure, fixed.

> > +   for (i = 0; i < QCA8K_NUM_PORTS; i++) {
> > +   if (priv->port_mtu[port] > mtu)
> > +   mtu = priv->port_mtu[port];
> > +   }
> 
> Again, curly brackets are not needed here, although some might feel it
> aids readability.
> 
> > +
> > +   /* Include L2 header / FCS length */
> > +   qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
> > +
> > +   return 0;
> > +}
> > +
> > +static int
> > +qca8k_port_max_mtu(struct dsa_switch *ds, int port)
> > +{
> > +   return QCA8K_MAX_MTU;
> 
> So what is the maximum value that you can write into
> QCA8K_MAX_FRAME_SIZE? 9000 or 9018? If it's 9000, you should report a
> max MTU of 8982, and let the network stack do the range check for you,
> that's why this callback exists in the first place.

9018 (including header + fcs), hence returning QCA8K_MAX_MTU here.

> Do you know how are VLAN tags accounted for (i.e. does iperf3 TCP work
> over a VLAN sub-interface after your patch)? There are 2 options:
> - The ports automatically increase the maximum accepted frame size by 4
>   (or 8, in case of double tag) bytes if they see VLAN tagged traffic.
>   Case in which you don't need to do anything.
> - You need to manually account for the possibility that VLAN-tagged
>   traffic will be received, since the 802.1Q header is not part of the
>   SDU whose max length is measured by the MTU. So you might want to
>   write a value to QCA8K_MAX_FRA

[PATCH] net: dsa: qca8k: implement the port MTU callbacks

2020-07-18 Thread Jonathan McDowell
This switch has a single max frame size configuration register, so we
track the requested MTU for each port and apply the largest.

Signed-off-by: Jonathan McDowell 
---
 drivers/net/dsa/qca8k.c | 38 ++
 drivers/net/dsa/qca8k.h |  3 +++
 2 files changed, 41 insertions(+)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 4acad5fa0c84..3690f02aea3a 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -670,6 +670,12 @@ qca8k_setup(struct dsa_switch *ds)
}
}
 
+   /* Setup our port MTUs to match power on defaults */
+   for (i = 0; i < QCA8K_NUM_PORTS; i++) {
+   priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
+   }
+   qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
+
/* Flush the FDB table */
qca8k_fdb_flush(priv);
 
@@ -1098,6 +1104,36 @@ qca8k_port_disable(struct dsa_switch *ds, int port)
priv->port_sts[port].enabled = 0;
 }
 
+static int
+qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
+{
+   struct qca8k_priv *priv = ds->priv;
+   int i, mtu;
+
+   if ((new_mtu < ETH_MIN_MTU) || (new_mtu > QCA8K_MAX_MTU)) {
+   return -EINVAL;
+   }
+
+   priv->port_mtu[port] = new_mtu;
+
+   mtu = 0;
+   for (i = 0; i < QCA8K_NUM_PORTS; i++) {
+   if (priv->port_mtu[port] > mtu)
+   mtu = priv->port_mtu[port];
+   }
+
+   /* Include L2 header / FCS length */
+   qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
+
+   return 0;
+}
+
+static int
+qca8k_port_max_mtu(struct dsa_switch *ds, int port)
+{
+   return QCA8K_MAX_MTU;
+}
+
 static int
 qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
  u16 port_mask, u16 vid)
@@ -1174,6 +1210,8 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
.set_mac_eee= qca8k_set_mac_eee,
.port_enable= qca8k_port_enable,
.port_disable   = qca8k_port_disable,
+   .port_change_mtu= qca8k_port_change_mtu,
+   .port_max_mtu   = qca8k_port_max_mtu,
.port_stp_state_set = qca8k_port_stp_state_set,
.port_bridge_join   = qca8k_port_bridge_join,
.port_bridge_leave  = qca8k_port_bridge_leave,
diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h
index 10ef2bca2cde..31439396401c 100644
--- a/drivers/net/dsa/qca8k.h
+++ b/drivers/net/dsa/qca8k.h
@@ -13,6 +13,7 @@
 #include 
 
 #define QCA8K_NUM_PORTS7
+#define QCA8K_MAX_MTU  9000
 
 #define PHY_ID_QCA8337 0x004dd036
 #define QCA8K_ID_QCA8337   0x13
@@ -58,6 +59,7 @@
 #define   QCA8K_MDIO_MASTER_MAX_REG32
 #define QCA8K_GOL_MAC_ADDR00x60
 #define QCA8K_GOL_MAC_ADDR10x64
+#define QCA8K_MAX_FRAME_SIZE   0x78
 #define QCA8K_REG_PORT_STATUS(_i)  (0x07c + (_i) * 4)
 #define   QCA8K_PORT_STATUS_SPEED  GENMASK(1, 0)
 #define   QCA8K_PORT_STATUS_SPEED_10   0
@@ -189,6 +191,7 @@ struct qca8k_priv {
struct device *dev;
struct dsa_switch_ops ops;
struct gpio_desc *reset_gpio;
+   unsigned int port_mtu[QCA8K_NUM_PORTS];
 };
 
 struct qca8k_mib_desc {
-- 
2.27.0



Re: [PATCH 2/2] dt-bindings: net: dsa: qca8k: Add PORT0_PAD_CTRL properties

2020-07-17 Thread Jonathan McDowell
On Fri, Jul 17, 2020 at 01:38:22AM +0300, Vladimir Oltean wrote:
> On Thu, Jul 16, 2020 at 03:09:25PM -0700, Jakub Kicinski wrote:
> > On Mon, 13 Jul 2020 21:50:26 +0100 Matthew Hagan wrote:
> > > +- qca,sgmii-rxclk-falling-edge:  If present, sets receive clock phase to
> > > + falling edge.
> > > +- qca,sgmii-txclk-falling-edge:  If present, sets transmit clock phase to
> > > + falling edge.
> > 
> > These are not something that other vendors may implement and therefore
> > something we may want to make generic? Andrew?
> > 
> 
> It was asked before whether this device uses source-synchronous clock
> for SGMII or if it recovers the clock from the data stream. Just "pass"
> was given for a response.
> 
> https://patchwork.ozlabs.org/project/netdev/patch/8ddd76e484e1bedd12c87ea0810826b60e004a65.1591380105.git.nood...@earth.li/
> 
> One can, in principle, tell easily by examining schematics. If the SGMII
> is only connected via RX_P, RX_N, TX_P, TX_N (and optionally there might
> be external reference clocks for the SERDES lanes, but these are not
> part of the data connection itself), then the clock is recovered from
> the serial data stream, and we have no idea what "SGMII delays" are.
> 
> If the schematic shows 2 extra clock signals, one in each transmit
> direction, then this is, in Russell King's words, "a new world of RGMII
> delay pain but for SGMII". In principle I would fully expect clock skews
> to be necessary for any high-speed protocol with source-synchronous
> clocking. The problem, really, is that we aren't ready to deal with this
> properly. We aren't distinguishing "SGMII with clock" from "SGMII
> without clock" in any way. We have no idea who else is using such a
> thing. Depending on the magnitude of this new world, it may be wise to
> let these bindings go in as-is, or do something more kernel-wide...

I don't have the schematic for the device I've been working with, but
the switch data sheet just shows 2 differential pairs (input/output) for
the SerDes Interface (whereas the RGMII interfaces *are* listed with
their clocks).

J.

-- 
I just Fedexed my soul to hell. I'm *real* clever.


[PATCH] ARM: dts: qcom: add prng definition to ipq806x

2020-07-05 Thread Jonathan McDowell
Add missing prng definition for ipq806x SoC

Signed-off-by: Jonathan McDowell 
---
 arch/arm/boot/dts/qcom-ipq8064.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi 
b/arch/arm/boot/dts/qcom-ipq8064.dtsi
index b912da9a3ff3..22e0669b9133 100644
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -386,6 +386,13 @@ gsbi7_serial: serial@1664 {
};
};
 
+   rng@1a50 {
+   compatible = "qcom,prng";
+   reg = <0x1a50 0x200>;
+   clocks = < PRNG_CLK>;
+   clock-names = "core";
+   };
+
sata_phy: sata-phy@1b40 {
compatible = "qcom,ipq806x-sata-phy";
reg = <0x1b40 0x200>;
-- 
2.27.0



[PATCH] firmware: qcom_scm: Fix legacy convention SCM accessors

2020-07-04 Thread Jonathan McDowell
The move to a combined driver for the QCOM SCM hardware changed the
io_writel and io_readl helpers to use non-atomic calls, despite the
commit message saying that atomic was a better option. This breaks these
helpers on hardware that uses the old legacy convention (access fails
with a -95 return code). Switch back to using the atomic calls.

Observed as a failure routing GPIO interrupts to the Apps processor on
an IPQ8064; fix is confirmed as correctly allowing the interrupts to be
routed and observed.

Fixes: 57d3b816718c ("firmware: qcom_scm: Remove thin wrappers")
Cc: sta...@vger.kernel.org
Signed-off-by: Jonathan McDowell 
---
 drivers/firmware/qcom_scm.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index 0e7233a20f34..d4fda210adfe 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -391,7 +391,7 @@ static int __qcom_scm_set_dload_mode(struct device *dev, 
bool enable)
 
desc.args[1] = enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0;
 
-   return qcom_scm_call(__scm->dev, , NULL);
+   return qcom_scm_call_atomic(__scm->dev, , NULL);
 }
 
 static void qcom_scm_set_download_mode(bool enable)
@@ -650,7 +650,7 @@ int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val)
int ret;
 
 
-   ret = qcom_scm_call(__scm->dev, , );
+   ret = qcom_scm_call_atomic(__scm->dev, , );
if (ret >= 0)
*val = res.result[0];
 
@@ -669,8 +669,7 @@ int qcom_scm_io_writel(phys_addr_t addr, unsigned int val)
.owner = ARM_SMCCC_OWNER_SIP,
};
 
-
-   return qcom_scm_call(__scm->dev, , NULL);
+   return qcom_scm_call_atomic(__scm->dev, , NULL);
 }
 EXPORT_SYMBOL(qcom_scm_io_writel);
 
-- 
2.20.1



[PATCH net-next v5 2/3] net: dsa: qca8k: Improve SGMII interface handling

2020-06-20 Thread Jonathan McDowell
This patch improves the handling of the SGMII interface on the QCA8K
devices. Previously the driver did no configuration of the port, even if
it was selected. We now configure it up in the appropriate
PHY/MAC/Base-X mode depending on what phylink tells us we are connected
to and ensure it is enabled.

Tested with a device where the CPU connection is RGMII (i.e. the common
current use case) + one where the CPU connection is SGMII. I don't have
any devices where the SGMII interface is brought out to something other
than the CPU.

Signed-off-by: Jonathan McDowell 
---
 drivers/net/dsa/qca8k.c | 33 -
 drivers/net/dsa/qca8k.h | 13 +
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 63b84789f16b..11d1c290d90f 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -673,6 +673,9 @@ qca8k_setup(struct dsa_switch *ds)
/* Flush the FDB table */
qca8k_fdb_flush(priv);
 
+   /* We don't have interrupts for link changes, so we need to poll */
+   ds->pcs_poll = true;
+
return 0;
 }
 
@@ -681,7 +684,7 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, 
unsigned int mode,
 const struct phylink_link_state *state)
 {
struct qca8k_priv *priv = ds->priv;
-   u32 reg;
+   u32 reg, val;
 
switch (port) {
case 0: /* 1st CPU port */
@@ -740,6 +743,34 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, 
unsigned int mode,
case PHY_INTERFACE_MODE_1000BASEX:
/* Enable SGMII on the port */
qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
+
+   /* Enable/disable SerDes auto-negotiation as necessary */
+   val = qca8k_read(priv, QCA8K_REG_PWS);
+   if (phylink_autoneg_inband(mode))
+   val &= ~QCA8K_PWS_SERDES_AEN_DIS;
+   else
+   val |= QCA8K_PWS_SERDES_AEN_DIS;
+   qca8k_write(priv, QCA8K_REG_PWS, val);
+
+   /* Configure the SGMII parameters */
+   val = qca8k_read(priv, QCA8K_REG_SGMII_CTRL);
+
+   val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
+   QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
+
+   if (dsa_is_cpu_port(ds, port)) {
+   /* CPU port, we're talking to the CPU MAC, be a PHY */
+   val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
+   val |= QCA8K_SGMII_MODE_CTRL_PHY;
+   } else if (state->interface == PHY_INTERFACE_MODE_SGMII) {
+   val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
+   val |= QCA8K_SGMII_MODE_CTRL_MAC;
+   } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
+   val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
+   val |= QCA8K_SGMII_MODE_CTRL_BASEX;
+   }
+
+   qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
break;
default:
dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h
index 42d6ea24eb14..10ef2bca2cde 100644
--- a/drivers/net/dsa/qca8k.h
+++ b/drivers/net/dsa/qca8k.h
@@ -36,6 +36,8 @@
 #define   QCA8K_MAX_DELAY  3
 #define   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24)
 #define   QCA8K_PORT_PAD_SGMII_EN  BIT(7)
+#define QCA8K_REG_PWS  0x010
+#define   QCA8K_PWS_SERDES_AEN_DIS BIT(7)
 #define QCA8K_REG_MODULE_EN0x030
 #define   QCA8K_MODULE_EN_MIB  BIT(0)
 #define QCA8K_REG_MIB  0x034
@@ -69,6 +71,7 @@
 #define   QCA8K_PORT_STATUS_LINK_UPBIT(8)
 #define   QCA8K_PORT_STATUS_LINK_AUTO  BIT(9)
 #define   QCA8K_PORT_STATUS_LINK_PAUSE BIT(10)
+#define   QCA8K_PORT_STATUS_FLOW_AUTO  BIT(12)
 #define QCA8K_REG_PORT_HDR_CTRL(_i)(0x9c + (_i * 4))
 #define   QCA8K_PORT_HDR_CTRL_RX_MASK  GENMASK(3, 2)
 #define   QCA8K_PORT_HDR_CTRL_RX_S 2
@@ -77,6 +80,16 @@
 #define   QCA8K_PORT_HDR_CTRL_ALL  2
 #define   QCA8K_PORT_HDR_CTRL_MGMT 1
 #define   QCA8K_PORT_HDR_CTRL_NONE 0
+#define QCA8K_REG_SGMII_CTRL   0x0e0
+#define   QCA8K_SGMII_EN_PLL   BIT(1)
+#define   QCA8K_SGMII_EN_RXBIT(2)
+#define   QCA8K_SGMII_EN_TXBIT(3)
+#define   QCA8K_SGMII_EN_SDBIT(4)
+#define   QCA8K_SGMII_CLK125M_DELAYBIT(7)
+#define   QCA8K_SGMII_MODE_CTRL_MASK  

[PATCH net-next v5 3/3] net: dsa: qca8k: Minor comment spelling fix

2020-06-20 Thread Jonathan McDowell
Signed-off-by: Jonathan McDowell 
---
 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 11d1c290d90f..4acad5fa0c84 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -647,7 +647,7 @@ qca8k_setup(struct dsa_switch *ds)
  QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
}
 
-   /* Invividual user ports get connected to CPU port only */
+   /* Individual user ports get connected to CPU port only */
if (dsa_is_user_port(ds, i)) {
int shift = 16 * (i % 2);
 
-- 
2.20.1



[PATCH net-next v5 1/3] net: dsa: qca8k: Switch to PHYLINK instead of PHYLIB

2020-06-20 Thread Jonathan McDowell
Update the driver to use the new PHYLINK callbacks, removing the
legacy adjust_link callback.

Signed-off-by: Jonathan McDowell 
---
 drivers/net/dsa/qca8k.c | 306 +++-
 1 file changed, 210 insertions(+), 96 deletions(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index d2b5ab403e06..63b84789f16b 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -418,55 +419,6 @@ qca8k_mib_init(struct qca8k_priv *priv)
mutex_unlock(>reg_mutex);
 }
 
-static int
-qca8k_set_pad_ctrl(struct qca8k_priv *priv, int port, int mode)
-{
-   u32 reg, val;
-
-   switch (port) {
-   case 0:
-   reg = QCA8K_REG_PORT0_PAD_CTRL;
-   break;
-   case 6:
-   reg = QCA8K_REG_PORT6_PAD_CTRL;
-   break;
-   default:
-   pr_err("Can't set PAD_CTRL on port %d\n", port);
-   return -EINVAL;
-   }
-
-   /* Configure a port to be directly connected to an external
-* PHY or MAC.
-*/
-   switch (mode) {
-   case PHY_INTERFACE_MODE_RGMII:
-   /* RGMII mode means no delay so don't enable the delay */
-   val = QCA8K_PORT_PAD_RGMII_EN;
-   qca8k_write(priv, reg, val);
-   break;
-   case PHY_INTERFACE_MODE_RGMII_ID:
-   /* RGMII_ID needs internal delay. This is enabled through
-* PORT5_PAD_CTRL for all ports, rather than individual port
-* registers
-*/
-   qca8k_write(priv, reg,
-   QCA8K_PORT_PAD_RGMII_EN |
-   QCA8K_PORT_PAD_RGMII_TX_DELAY(QCA8K_MAX_DELAY) |
-   QCA8K_PORT_PAD_RGMII_RX_DELAY(QCA8K_MAX_DELAY));
-   qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
-   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
-   break;
-   case PHY_INTERFACE_MODE_SGMII:
-   qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
-   break;
-   default:
-   pr_err("xMII mode %d not supported\n", mode);
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
 static void
 qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
 {
@@ -639,9 +591,7 @@ static int
 qca8k_setup(struct dsa_switch *ds)
 {
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-   phy_interface_t phy_mode = PHY_INTERFACE_MODE_NA;
int ret, i;
-   u32 mask;
 
/* Make sure that port 0 is the cpu port */
if (!dsa_is_cpu_port(ds, 0)) {
@@ -661,24 +611,9 @@ qca8k_setup(struct dsa_switch *ds)
if (ret)
return ret;
 
-   /* Initialize CPU port pad mode (xMII type, delays...) */
-   ret = of_get_phy_mode(dsa_to_port(ds, QCA8K_CPU_PORT)->dn, _mode);
-   if (ret) {
-   pr_err("Can't find phy-mode for master device\n");
-   return ret;
-   }
-   ret = qca8k_set_pad_ctrl(priv, QCA8K_CPU_PORT, phy_mode);
-   if (ret < 0)
-   return ret;
-
-   /* Enable CPU Port, force it to maximum bandwidth and full-duplex */
-   mask = QCA8K_PORT_STATUS_SPEED_1000 | QCA8K_PORT_STATUS_TXFLOW |
-  QCA8K_PORT_STATUS_RXFLOW | QCA8K_PORT_STATUS_DUPLEX;
-   qca8k_write(priv, QCA8K_REG_PORT_STATUS(QCA8K_CPU_PORT), mask);
+   /* Enable CPU Port */
qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
  QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
-   qca8k_port_set_status(priv, QCA8K_CPU_PORT, 1);
-   priv->port_sts[QCA8K_CPU_PORT].enabled = 1;
 
/* Enable MIB counters */
qca8k_mib_init(priv);
@@ -693,10 +628,9 @@ qca8k_setup(struct dsa_switch *ds)
qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
  QCA8K_PORT_LOOKUP_MEMBER, 0);
 
-   /* Disable MAC by default on all user ports */
+   /* Disable MAC by default on all ports */
for (i = 1; i < QCA8K_NUM_PORTS; i++)
-   if (dsa_is_user_port(ds, i))
-   qca8k_port_set_status(priv, i, 0);
+   qca8k_port_set_status(priv, i, 0);
 
/* Forward all unknown frames to CPU port for Linux processing */
qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
@@ -743,44 +677,222 @@ qca8k_setup(struct dsa_switch *ds)
 }
 
 static void
-qca8k_adjust_link(struct dsa_switch *ds, int port, struct phy_device *phy)
+qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
+const struct phylink_link_state *state)
 {
struct qca8k_priv *priv = ds->priv;
u32 reg;
 
-   /* Force fixed-link setting for CPU port, skip others. */
-   if (!phy_is_pseudo_fixed_link(phy))
+   switch (port) {
+   case 0: /* 1

[PATCH net-next v5 0/3] net: dsa: qca8k: Improve SGMII interface handling

2020-06-20 Thread Jonathan McDowell
This 3 patch series migrates the qca8k switch driver over to PHYLINK,
and then adds the SGMII clean-ups (i.e. the missing initialisation) on
top of that as a second patch. The final patch is a simple spelling fix
in a comment.

As before, tested with a device where the CPU connection is RGMII (i.e.
the common current use case) + one where the CPU connection is SGMII. I
don't have any devices where the SGMII interface is brought out to
something other than the CPU.

v5:
- Move spelling fix to separate patch
- Use ds directly rather than ds->priv
v4:
- Enable pcs_poll so we keep phylink updated when doing in-band
  negotiation
- Explicitly check for PHY_INTERFACE_MODE_1000BASEX when setting SGMII
  port mode.
- Address Vladimir's review comments
v3:
- Move phylink changes to separate patch
- Address rmk review comments
v2:
- Switch to phylink
- Avoid need for device tree configuration options

Jonathan McDowell (3):
  net: dsa: qca8k: Switch to PHYLINK instead of PHYLIB
  net: dsa: qca8k: Improve SGMII interface handling
  net: dsa: qca8k: Minor comment spelling fix

 drivers/net/dsa/qca8k.c | 341 
 drivers/net/dsa/qca8k.h |  13 ++
 2 files changed, 256 insertions(+), 98 deletions(-)

-- 
2.20.1



[PATCH] ARM: dts: qcom: add qfprom definition to ipq806x

2020-06-16 Thread Jonathan McDowell
Add missing qfprom definition for ipq806x SoC

Signed-off-by: Jonathan McDowell 
---
 arch/arm/boot/dts/qcom-ipq8064.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi 
b/arch/arm/boot/dts/qcom-ipq8064.dtsi
index b912da9a3ff3..8f299cae2628 100644
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -425,6 +425,13 @@
qcom,controller-type = "pmic-arbiter";
};
 
+   qfprom: qfprom@70 {
+   compatible = "qcom,qfprom";
+   reg = <0x0070 0x1000>;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   };
+
gcc: clock-controller@90 {
compatible = "qcom,gcc-ipq8064";
reg = <0x0090 0x4000>;
-- 
2.20.1



Re: [PATCH 1/2] dt-bindings: net: dsa: qca8k: document SGMII properties

2020-06-15 Thread Jonathan McDowell
On Mon, Jun 15, 2020 at 11:45:16AM -0600, Rob Herring wrote:
> On Fri, Jun 05, 2020 at 07:10:02PM +0100, Jonathan McDowell wrote:
> > This patch documents the qca8k's SGMII related properties that allow
> > configuration of the SGMII port.
> > 
> > Signed-off-by: Jonathan McDowell 
> > ---
> >  Documentation/devicetree/bindings/net/dsa/qca8k.txt | 4 
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/net/dsa/qca8k.txt 
> > b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
> > index ccbc6d89325d..9e7d74a248ad 100644
> > --- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
> > +++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
> > @@ -11,7 +11,11 @@ Required properties:
> >  
> >  Optional properties:
> >  
> > +- disable-serdes-autoneg: Boolean, disables auto-negotiation on the SerDes
> >  - reset-gpios: GPIO to be used to reset the whole device
> > +- sgmii-delay: Boolean, presence delays SGMII clock by 2ns
> > +- sgmii-mode: String, operation mode of the SGMII interface.
> > +  Supported values are: "basex", "mac", "phy".
> 
> Either these should be common properties and documented in a common 
> spot or they need vendor prefixes. They seem like they former to me 
> (though 'sgmii-delay' would need to be more general and take a time).

I've managed to spin a subsequent revision which avoids the need for a
device tree change, based on comments similar to yours. I'll keep them
in mind should it become necessary to re-introduce the DT options.

J.

-- 
] https://www.earth.li/~noodles/ []  I'm a creep, I'm a weirdo, what   [
]  PGP/GPG Key @ the.earth.li[] the hell am I doing here?  [
] via keyserver, web or email.   [][
] RSA: 4096/0x94FA372B2DA8B985   [][


Re: [RFC PATCH v4 2/2] net: dsa: qca8k: Improve SGMII interface handling

2020-06-14 Thread Jonathan McDowell
On Sat, Jun 13, 2020 at 11:10:49PM +0300, Vladimir Oltean wrote:
> On Sat, 13 Jun 2020 at 14:32, Jonathan McDowell  wrote:
> >
> > This patch improves the handling of the SGMII interface on the QCA8K
> > devices. Previously the driver did no configuration of the port, even if
> > it was selected. We now configure it up in the appropriate
> > PHY/MAC/Base-X mode depending on what phylink tells us we are connected
> > to and ensure it is enabled.
> >
> > Tested with a device where the CPU connection is RGMII (i.e. the common
> > current use case) + one where the CPU connection is SGMII. I don't have
> > any devices where the SGMII interface is brought out to something other
> > than the CPU.
> >
> > Signed-off-by: Jonathan McDowell 
> > ---
> >  drivers/net/dsa/qca8k.c | 33 -
> >  drivers/net/dsa/qca8k.h | 13 +
> >  2 files changed, 45 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
> > index dadf9ab2c14a..da7d2b92ed3e 100644
> > --- a/drivers/net/dsa/qca8k.c
> > +++ b/drivers/net/dsa/qca8k.c
> > @@ -673,6 +673,9 @@ qca8k_setup(struct dsa_switch *ds)
> > /* Flush the FDB table */
> > qca8k_fdb_flush(priv);
> >
> > +   /* We don't have interrupts for link changes, so we need to poll */
> > +   priv->ds->pcs_poll = true;
> > +
> 
> You can access ds directly here.

Good point, thanks.

> > return 0;
> >  }
> >
> > @@ -681,7 +684,7 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int 
> > port, unsigned int mode,
> >  const struct phylink_link_state *state)
> >  {
> > struct qca8k_priv *priv = ds->priv;
> > -   u32 reg;
> > +   u32 reg, val;
> >
> > switch (port) {
> > case 0: /* 1st CPU port */
> > @@ -740,6 +743,34 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int 
> > port, unsigned int mode,
> > case PHY_INTERFACE_MODE_1000BASEX:
> > /* Enable SGMII on the port */
> > qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
> > +
> > +   /* Enable/disable SerDes auto-negotiation as necessary */
> > +   val = qca8k_read(priv, QCA8K_REG_PWS);
> > +   if (phylink_autoneg_inband(mode))
> > +   val &= ~QCA8K_PWS_SERDES_AEN_DIS;
> > +   else
> > +   val |= QCA8K_PWS_SERDES_AEN_DIS;
> > +   qca8k_write(priv, QCA8K_REG_PWS, val);
> > +
> > +   /* Configure the SGMII parameters */
> > +   val = qca8k_read(priv, QCA8K_REG_SGMII_CTRL);
> > +
> > +   val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
> > +   QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
> > +
> > +   if (dsa_is_cpu_port(ds, port)) {

> I don't see any device tree in mainline for qca,qca8334 that uses
> SGMII on the CPU port, but there are some assumptions being made here,
> and there are also going to be some assumptions made in the MAC
> driver, and I just want to make sure that those assumptions are not
> going to be incompatible, so I would like you to make some
> clarifications.

FWIW I have a DTS for the MikroTik RB3011 that should hopefully make it
to 5.9 via the linux-msm tree, which has 2 qca,qca8337 devices, one
connected via rgmii, one connected via sgmii. Sadly not chained to each
other, instead connected to different CPU ethernet ports.

> So there's a single SGMII interface which can go to port 0 (the CPU
> port) or to port 6, right? The SGMII port can behave as an AN master
> or as an AN slave, depending on whether MODE_CTRL is 1 or 2, or can
> have a forced speed (if SERDES_AEN is disabled)?

Yes.

> We don't have a standard way to describe an SGMII AN master that is
> not a PHY in the device tree, because I don't think anybody needed to
> do that so far.
>
> Typically a MAC would describe the link towards the CPU port of the
> switch as a fixed-link. In that case, if the phy-mode is sgmii, it
> would disable in-band autoneg, because there's nothing really to
> negotiate (the link speed and duplex is fixed). For these, I think the
> expectation is that the switch does not enable in-band autoneg either,
> and has a fixed-link too. Per your configuration, you would disable
> SerDes AN, and you would configure the port as SGMII AN master (PHY),
> but that setting would be ignored because AN is disabled.

Right; this is the situation with my device. There's a fixed-link stanza
in the DT.

> In other conf

[RFC PATCH v4 2/2] net: dsa: qca8k: Improve SGMII interface handling

2020-06-13 Thread Jonathan McDowell
This patch improves the handling of the SGMII interface on the QCA8K
devices. Previously the driver did no configuration of the port, even if
it was selected. We now configure it up in the appropriate
PHY/MAC/Base-X mode depending on what phylink tells us we are connected
to and ensure it is enabled.

Tested with a device where the CPU connection is RGMII (i.e. the common
current use case) + one where the CPU connection is SGMII. I don't have
any devices where the SGMII interface is brought out to something other
than the CPU.

Signed-off-by: Jonathan McDowell 
---
 drivers/net/dsa/qca8k.c | 33 -
 drivers/net/dsa/qca8k.h | 13 +
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index dadf9ab2c14a..da7d2b92ed3e 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -673,6 +673,9 @@ qca8k_setup(struct dsa_switch *ds)
/* Flush the FDB table */
qca8k_fdb_flush(priv);
 
+   /* We don't have interrupts for link changes, so we need to poll */
+   priv->ds->pcs_poll = true;
+
return 0;
 }
 
@@ -681,7 +684,7 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, 
unsigned int mode,
 const struct phylink_link_state *state)
 {
struct qca8k_priv *priv = ds->priv;
-   u32 reg;
+   u32 reg, val;
 
switch (port) {
case 0: /* 1st CPU port */
@@ -740,6 +743,34 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, 
unsigned int mode,
case PHY_INTERFACE_MODE_1000BASEX:
/* Enable SGMII on the port */
qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
+
+   /* Enable/disable SerDes auto-negotiation as necessary */
+   val = qca8k_read(priv, QCA8K_REG_PWS);
+   if (phylink_autoneg_inband(mode))
+   val &= ~QCA8K_PWS_SERDES_AEN_DIS;
+   else
+   val |= QCA8K_PWS_SERDES_AEN_DIS;
+   qca8k_write(priv, QCA8K_REG_PWS, val);
+
+   /* Configure the SGMII parameters */
+   val = qca8k_read(priv, QCA8K_REG_SGMII_CTRL);
+
+   val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
+   QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
+
+   if (dsa_is_cpu_port(ds, port)) {
+   /* CPU port, we're talking to the CPU MAC, be a PHY */
+   val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
+   val |= QCA8K_SGMII_MODE_CTRL_PHY;
+   } else if (state->interface == PHY_INTERFACE_MODE_SGMII) {
+   val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
+   val |= QCA8K_SGMII_MODE_CTRL_MAC;
+   } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
+   val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
+   val |= QCA8K_SGMII_MODE_CTRL_BASEX;
+   }
+
+   qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
break;
default:
dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h
index 42d6ea24eb14..10ef2bca2cde 100644
--- a/drivers/net/dsa/qca8k.h
+++ b/drivers/net/dsa/qca8k.h
@@ -36,6 +36,8 @@
 #define   QCA8K_MAX_DELAY  3
 #define   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24)
 #define   QCA8K_PORT_PAD_SGMII_EN  BIT(7)
+#define QCA8K_REG_PWS  0x010
+#define   QCA8K_PWS_SERDES_AEN_DIS BIT(7)
 #define QCA8K_REG_MODULE_EN0x030
 #define   QCA8K_MODULE_EN_MIB  BIT(0)
 #define QCA8K_REG_MIB  0x034
@@ -69,6 +71,7 @@
 #define   QCA8K_PORT_STATUS_LINK_UPBIT(8)
 #define   QCA8K_PORT_STATUS_LINK_AUTO  BIT(9)
 #define   QCA8K_PORT_STATUS_LINK_PAUSE BIT(10)
+#define   QCA8K_PORT_STATUS_FLOW_AUTO  BIT(12)
 #define QCA8K_REG_PORT_HDR_CTRL(_i)(0x9c + (_i * 4))
 #define   QCA8K_PORT_HDR_CTRL_RX_MASK  GENMASK(3, 2)
 #define   QCA8K_PORT_HDR_CTRL_RX_S 2
@@ -77,6 +80,16 @@
 #define   QCA8K_PORT_HDR_CTRL_ALL  2
 #define   QCA8K_PORT_HDR_CTRL_MGMT 1
 #define   QCA8K_PORT_HDR_CTRL_NONE 0
+#define QCA8K_REG_SGMII_CTRL   0x0e0
+#define   QCA8K_SGMII_EN_PLL   BIT(1)
+#define   QCA8K_SGMII_EN_RXBIT(2)
+#define   QCA8K_SGMII_EN_TXBIT(3)
+#define   QCA8K_SGMII_EN_SDBIT(4)
+#define   QCA8K_SGMII_CLK125M_DELAYBIT(7)
+#define   QCA8K_SGMII_MODE_CTRL_MASK   

[RFC PATCH v4 0/2] net: dsa: qca8k: Improve SGMII interface handling

2020-06-13 Thread Jonathan McDowell
Hopefully getting there, thanks for all the review comments.

This 2 patch series migrates the qca8k switch driver over to PHYLINK,
and then adds the SGMII clean-ups (i.e. the missing initialisation) on
top of that as a second patch.

As before, tested with a device where the CPU connection is RGMII (i.e.
the common current use case) + one where the CPU connection is SGMII. I
don't have any devices where the SGMII interface is brought out to
something other than the CPU.

v4:
- Enable pcs_poll so we keep phylink updated when doing in-band
  negotiation
- Explicitly check for PHY_INTERFACE_MODE_1000BASEX when setting SGMII
  port mode.
- Address Vladimir's review comments
v3:
- Move phylink changes to separate patch
- Address rmk review comments
v2:
- Switch to phylink
- Avoid need for device tree configuration options

Jonathan McDowell (2):
  net: dsa: qca8k: Switch to PHYLINK instead of PHYLIB
  net: dsa: qca8k: Improve SGMII interface handling

 drivers/net/dsa/qca8k.c | 341 
 drivers/net/dsa/qca8k.h |  13 ++
 2 files changed, 256 insertions(+), 98 deletions(-)

-- 
2.20.1



[RFC PATCH v4 1/2] net: dsa: qca8k: Switch to PHYLINK instead of PHYLIB

2020-06-13 Thread Jonathan McDowell
Update the driver to use the new PHYLINK callbacks, removing the
legacy adjust_link callback.

Signed-off-by: Jonathan McDowell 
---
 drivers/net/dsa/qca8k.c | 308 +++-
 1 file changed, 211 insertions(+), 97 deletions(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index d2b5ab403e06..dadf9ab2c14a 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -418,55 +419,6 @@ qca8k_mib_init(struct qca8k_priv *priv)
mutex_unlock(>reg_mutex);
 }
 
-static int
-qca8k_set_pad_ctrl(struct qca8k_priv *priv, int port, int mode)
-{
-   u32 reg, val;
-
-   switch (port) {
-   case 0:
-   reg = QCA8K_REG_PORT0_PAD_CTRL;
-   break;
-   case 6:
-   reg = QCA8K_REG_PORT6_PAD_CTRL;
-   break;
-   default:
-   pr_err("Can't set PAD_CTRL on port %d\n", port);
-   return -EINVAL;
-   }
-
-   /* Configure a port to be directly connected to an external
-* PHY or MAC.
-*/
-   switch (mode) {
-   case PHY_INTERFACE_MODE_RGMII:
-   /* RGMII mode means no delay so don't enable the delay */
-   val = QCA8K_PORT_PAD_RGMII_EN;
-   qca8k_write(priv, reg, val);
-   break;
-   case PHY_INTERFACE_MODE_RGMII_ID:
-   /* RGMII_ID needs internal delay. This is enabled through
-* PORT5_PAD_CTRL for all ports, rather than individual port
-* registers
-*/
-   qca8k_write(priv, reg,
-   QCA8K_PORT_PAD_RGMII_EN |
-   QCA8K_PORT_PAD_RGMII_TX_DELAY(QCA8K_MAX_DELAY) |
-   QCA8K_PORT_PAD_RGMII_RX_DELAY(QCA8K_MAX_DELAY));
-   qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
-   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
-   break;
-   case PHY_INTERFACE_MODE_SGMII:
-   qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
-   break;
-   default:
-   pr_err("xMII mode %d not supported\n", mode);
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
 static void
 qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
 {
@@ -639,9 +591,7 @@ static int
 qca8k_setup(struct dsa_switch *ds)
 {
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-   phy_interface_t phy_mode = PHY_INTERFACE_MODE_NA;
int ret, i;
-   u32 mask;
 
/* Make sure that port 0 is the cpu port */
if (!dsa_is_cpu_port(ds, 0)) {
@@ -661,24 +611,9 @@ qca8k_setup(struct dsa_switch *ds)
if (ret)
return ret;
 
-   /* Initialize CPU port pad mode (xMII type, delays...) */
-   ret = of_get_phy_mode(dsa_to_port(ds, QCA8K_CPU_PORT)->dn, _mode);
-   if (ret) {
-   pr_err("Can't find phy-mode for master device\n");
-   return ret;
-   }
-   ret = qca8k_set_pad_ctrl(priv, QCA8K_CPU_PORT, phy_mode);
-   if (ret < 0)
-   return ret;
-
-   /* Enable CPU Port, force it to maximum bandwidth and full-duplex */
-   mask = QCA8K_PORT_STATUS_SPEED_1000 | QCA8K_PORT_STATUS_TXFLOW |
-  QCA8K_PORT_STATUS_RXFLOW | QCA8K_PORT_STATUS_DUPLEX;
-   qca8k_write(priv, QCA8K_REG_PORT_STATUS(QCA8K_CPU_PORT), mask);
+   /* Enable CPU Port */
qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
  QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
-   qca8k_port_set_status(priv, QCA8K_CPU_PORT, 1);
-   priv->port_sts[QCA8K_CPU_PORT].enabled = 1;
 
/* Enable MIB counters */
qca8k_mib_init(priv);
@@ -693,10 +628,9 @@ qca8k_setup(struct dsa_switch *ds)
qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
  QCA8K_PORT_LOOKUP_MEMBER, 0);
 
-   /* Disable MAC by default on all user ports */
+   /* Disable MAC by default on all ports */
for (i = 1; i < QCA8K_NUM_PORTS; i++)
-   if (dsa_is_user_port(ds, i))
-   qca8k_port_set_status(priv, i, 0);
+   qca8k_port_set_status(priv, i, 0);
 
/* Forward all unknown frames to CPU port for Linux processing */
qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
@@ -713,7 +647,7 @@ qca8k_setup(struct dsa_switch *ds)
  QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
}
 
-   /* Invividual user ports get connected to CPU port only */
+   /* Individual user ports get connected to CPU port only */
if (dsa_is_user_port(ds, i)) {
int shift = 16 * (i % 2);
 
@@ -743,44 +677,222 @@ qca8k_setup(struct dsa_switch *ds)
 }
 
 static void
-qca8k_adjust_link(struct dsa_switch *ds, int port, struct p

Re: [PATCH 1/2] net: dsa: qca8k: Switch to PHYLINK instead of PHYLIB

2020-06-12 Thread Jonathan McDowell
On Thu, Jun 11, 2020 at 09:55:23AM +0100, Russell King - ARM Linux admin wrote:
> On Wed, Jun 10, 2020 at 08:14:03PM +0100, Jonathan McDowell wrote:
> > Update the driver to use the new PHYLINK callbacks, removing the
> > legacy adjust_link callback.
> 
> Looks good, there's a couple of issues / questions
> 
> >  static void
> > +qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int 
> > mode,
> > +const struct phylink_link_state *state)
> >  {
> > struct qca8k_priv *priv = ds->priv;
> > u32 reg;
> >  
> > +   switch (port) {
> ...
> > +   case 6: /* 2nd CPU port / external PHY */
> > +   if (state->interface != PHY_INTERFACE_MODE_RGMII &&
> > +   state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
> > +   state->interface != PHY_INTERFACE_MODE_SGMII &&
> > +   state->interface != PHY_INTERFACE_MODE_1000BASEX)
> > +   return;
> > +
> > +   reg = QCA8K_REG_PORT6_PAD_CTRL;
> > +   break;
> ...
> > +   }
> > +
> > +   if (port != 6 && phylink_autoneg_inband(mode)) {
> > +   dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
> > +   __func__);
> > +   return;
> > +   }
> > +
> > +   switch (state->interface) {
> ...
> > +   case PHY_INTERFACE_MODE_SGMII:
> > +   case PHY_INTERFACE_MODE_1000BASEX:
> > +   /* Enable SGMII on the port */
> > +   qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
> > +   break;
> 
> Is inband mode configurable?  What if the link partner does/doesn't
> send the configuration word?  How is the link state communicated to
> the MAC?

I moved those over to the second patch on the request of Andrew Lunn,
who wanted the phylink change to be separate from the addition of the
SGMII changes. This first patch should result in no change of behaviour,
just the move to phylink.

> > +static int
> > +qca8k_phylink_mac_link_state(struct dsa_switch *ds, int port,
> > +struct phylink_link_state *state)
> > +{
> > +   struct qca8k_priv *priv = ds->priv;
> > +   u32 reg;
> >  
> > +   reg = qca8k_read(priv, QCA8K_REG_PORT_STATUS(port));
> > +
> > +   state->link = !!(reg & QCA8K_PORT_STATUS_LINK_UP);
> > +   state->an_complete = state->link;
> > +   state->an_enabled = !!(reg & QCA8K_PORT_STATUS_LINK_AUTO);
> > +   state->duplex = (reg & QCA8K_PORT_STATUS_DUPLEX) ? DUPLEX_FULL :
> > +  DUPLEX_HALF;
> > +
> > +   switch (reg & QCA8K_PORT_STATUS_SPEED) {
> > +   case QCA8K_PORT_STATUS_SPEED_10:
> > +   state->speed = SPEED_10;
> > +   break;
> > +   case QCA8K_PORT_STATUS_SPEED_100:
> > +   state->speed = SPEED_100;
> > +   break;
> > +   case QCA8K_PORT_STATUS_SPEED_1000:
> > +   state->speed = SPEED_1000;
> > +   break;
> > +   default:
> > +   state->speed = SPEED_UNKNOWN;
> 
> Maybe also force the link down in this case, since the state is invalid?
> 
> Do you have access to the link partner's configuration word?  If you do,
> you should use that to fill in state->lp_advertising.

It doesn't seem to be available from my reading of the data sheet.

> > +   break;
> > +   }
> > +
> > +   state->pause = MLO_PAUSE_NONE;
> > +   if (reg & QCA8K_PORT_STATUS_RXFLOW)
> > +   state->pause |= MLO_PAUSE_RX;
> > +   if (reg & QCA8K_PORT_STATUS_TXFLOW)
> > +   state->pause |= MLO_PAUSE_TX;
> > +
> > +   return 1;
> > +}
> > +
> > +static void
> > +qca8k_phylink_mac_link_down(struct dsa_switch *ds, int port, unsigned int 
> > mode,
> > +   phy_interface_t interface)
> > +{
> > +   struct qca8k_priv *priv = ds->priv;
> >  
> > qca8k_port_set_status(priv, port, 0);
> 
> If operating in in-band mode, forcing the link down unconditionally
> will prevent the link coming up if the SGMII/1000base-X block
> automatically updates the MAC, and if this takes precedence.
> 
> When using in-band mode, you need to call dsa_port_phylink_mac_change()
> to keep phylink updated with the link status.
> 
> Alternatively, phylink supports polling mode, but due to the layered
> way DSA is written, DSA drivers don't have access to that as that is
> in the DSA upper levels in net/dsa/slave.c (dsa_slave_phy_setup(),
> it would be dp->pl_config.pcs_poll).

My reading of Vladimir's mail is I can set pcs_poll to get that
functionality, and from the data sheet the link detection is keyed off a
separate bit than the mac link down piece so I think I'm ok there.

> Apart from those points, I think it looks fine, thanks.

Thanks for the review. I'll get a new version out soon.

J.

-- 
If a program is useless, it must be documented.


Re: [PATCH 2/2] net: dsa: qca8k: Improve SGMII interface handling

2020-06-11 Thread Jonathan McDowell
On Wed, Jun 10, 2020 at 08:31:11PM -0700, Florian Fainelli wrote:
> On 6/10/2020 12:15 PM, Jonathan McDowell wrote:
> > This patch improves the handling of the SGMII interface on the QCA8K
> > devices. Previously the driver did no configuration of the port, even if
> > it was selected. We now configure it up in the appropriate
> > PHY/MAC/Base-X mode depending on what phylink tells us we are connected
> > to and ensure it is enabled.
> > 
> > Tested with a device where the CPU connection is RGMII (i.e. the common
> > current use case) + one where the CPU connection is SGMII. I don't have
> > any devices where the SGMII interface is brought out to something other
> > than the CPU.
> > 
> > Signed-off-by: Jonathan McDowell 
> > ---
> >  drivers/net/dsa/qca8k.c | 28 +++-
> >  drivers/net/dsa/qca8k.h | 13 +
> >  2 files changed, 40 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
> > index dcd9e8fa99b6..33e62598289e 100644
> > --- a/drivers/net/dsa/qca8k.c
> > +++ b/drivers/net/dsa/qca8k.c
> > @@ -681,7 +681,7 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int 
> > port, unsigned int mode,
> >  const struct phylink_link_state *state)
> >  {
> > struct qca8k_priv *priv = ds->priv;
> > -   u32 reg;
> > +   u32 reg, val;
> >  
> > switch (port) {
> > case 0: /* 1st CPU port */
> > @@ -740,6 +740,32 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int 
> > port, unsigned int mode,
> > case PHY_INTERFACE_MODE_1000BASEX:
> > /* Enable SGMII on the port */
> > qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
> > +
> > +   /* Enable/disable SerDes auto-negotiation as necessary */
> > +   val = qca8k_read(priv, QCA8K_REG_PWS);
> > +   if (phylink_autoneg_inband(mode))
> > +   val &= ~QCA8K_PWS_SERDES_AEN_DIS;
> > +   else
> > +   val |= QCA8K_PWS_SERDES_AEN_DIS;
> > +   qca8k_write(priv, QCA8K_REG_PWS, val);
> > +
> > +   /* Configure the SGMII parameters */
> > +   val = qca8k_read(priv, QCA8K_REG_SGMII_CTRL);
> > +
> > +   val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
> > +   QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
> > +
> > +   val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
> > +   if (dsa_is_cpu_port(ds, port)) {
> > +   /* CPU port, we're talking to the CPU MAC, be a PHY */
> > +   val |= QCA8K_SGMII_MODE_CTRL_PHY;
> 
> Since port 6 can be interfaced to an external PHY, do not you have to
> differentiate here whether this port is connected to an actual PHY,
> versus connected to a MAC? You should be able to use mode == MLO_AN_PHY
> to differentiate that case from the others.

I don't think MLO_AN_PHY is sufficient? If it's a fixed link we'll have
MLO_AN_FIXED and that could be talking to a PHY?

The logic I've gone for is assuming that a port hooked up to the CPU
should look like a PHY, and otherwise we're hooked up to a PHY so we're
acting as a MAC. That means we don't cope with the situation that we're
hooked up to something that isn't the CPU but wants us to look like a
PHY, but I don't think we have any current way to describe that.

> > +   } else if (state->interface == PHY_INTERFACE_MODE_SGMII) {
> > +   val |= QCA8K_SGMII_MODE_CTRL_MAC;
> > +   } else {
> > +   val |= QCA8K_SGMII_MODE_CTRL_BASEX;
> 
> Better make this explicit and check for PHY_INTERFACE_MODE_1000BASEX,
> even if those are the only two possible values covered by this part of
> the case statement.

Sure. I'll move the mask inside the if block too in that case, so we
don't change the setting if we get fed something invalid.

J.

-- 
Beware of programmers carrying screwdrivers.


Re: [PATCH 1/2] net: dsa: qca8k: Switch to PHYLINK instead of PHYLIB

2020-06-11 Thread Jonathan McDowell
On Thu, Jun 11, 2020 at 11:58:43AM +0300, Vladimir Oltean wrote:
> Hi Jonathan,
> 
> On Wed, 10 Jun 2020 at 23:19, Jonathan McDowell  wrote:
> >
> > Update the driver to use the new PHYLINK callbacks, removing the
> > legacy adjust_link callback.
> >
> > Signed-off-by: Jonathan McDowell 
...
> >  static void
> > -qca8k_adjust_link(struct dsa_switch *ds, int port, struct phy_device *phy)
> > +qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int 
> > mode,
> > +const struct phylink_link_state *state)
> >  {
> > struct qca8k_priv *priv = ds->priv;
> > u32 reg;
> >
> > -   /* Force fixed-link setting for CPU port, skip others. */
> > -   if (!phy_is_pseudo_fixed_link(phy))
> > +   switch (port) {
> > +   case 0: /* 1st CPU port */
> > +   if (state->interface != PHY_INTERFACE_MODE_RGMII &&
> > +   state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
> > +   state->interface != PHY_INTERFACE_MODE_SGMII)
> > +   return;
> > +
> > +   reg = QCA8K_REG_PORT0_PAD_CTRL;
> > +   break;
> > +   case 1:
> > +   case 2:
> > +   case 3:
> > +   case 4:
> > +   case 5:
> > +   /* Internal PHY, nothing to do */
> > +   return;
> > +   case 6: /* 2nd CPU port / external PHY */
> > +   if (state->interface != PHY_INTERFACE_MODE_RGMII &&
> > +   state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
> > +   state->interface != PHY_INTERFACE_MODE_SGMII &&
> > +   state->interface != PHY_INTERFACE_MODE_1000BASEX)
> > +   return;
> > +
> > +   reg = QCA8K_REG_PORT6_PAD_CTRL;
> > +   break;
> > +   default:
> > +   dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, 
> > port);
> > +   return;
> > +   }
> > +
> > +   if (port != 6 && phylink_autoneg_inband(mode)) {
> > +   dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
> > +   __func__);
> > +   return;
> > +   }
> > +
> > +   switch (state->interface) {
> > +   case PHY_INTERFACE_MODE_RGMII:
> > +   /* RGMII mode means no delay so don't enable the delay */
> > +   qca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);
> > +   break;
> > +   case PHY_INTERFACE_MODE_RGMII_ID:
> > +   /* RGMII_ID needs internal delay. This is enabled through
> > +* PORT5_PAD_CTRL for all ports, rather than individual port
> > +* registers
> > +*/
> > +   qca8k_write(priv, reg,
> > +   QCA8K_PORT_PAD_RGMII_EN |
> > +   QCA8K_PORT_PAD_RGMII_TX_DELAY(QCA8K_MAX_DELAY) |
> > +   QCA8K_PORT_PAD_RGMII_RX_DELAY(QCA8K_MAX_DELAY));
> 
> 3 points here:
> - Should you prevalidate the device tree bindings that in case rgmii*
> mode are used, same delay settings are applied to all ports?
> - Can any RGMII port be connected to a PHY? If it can, won't the PHY
> enable delays too for RGMII_ID? Will the link work in that case?
> - Should you treat RGMII_TX_DELAY and RGMII_RX_DELAY independently for
> the case where there may be PCB traces?

The intent with this patch was to pull out the conversion to PHYLINK to
be stand-alone, with no functional changes, as request by Andrew. I
think there's room for some future clean-up here around the RGMII
options, but my main purpose in this patch set is to improve the SGMII
portion which my hardware uses that doesn't work with mainline.

> > +static void
> > +qca8k_phylink_validate(struct dsa_switch *ds, int port,
> > +  unsigned long *supported,
> > +  struct phylink_link_state *state)
> > +{
> > +   __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
> > +
> > +   switch (port) {
> > +   case 0: /* 1st CPU port */
> > +   if (state->interface != PHY_INTERFACE_MODE_NA &&
> > +   state->interface != PHY_INTERFACE_MODE_RGMII &&
> > +   state->interface != PHY_INTERFACE_MODE_RGMII_ID &&
> > +   state->interface != PHY_INTERFACE_MODE_SGMII)
> > + 

[PATCH 2/2] net: dsa: qca8k: Improve SGMII interface handling

2020-06-10 Thread Jonathan McDowell
This patch improves the handling of the SGMII interface on the QCA8K
devices. Previously the driver did no configuration of the port, even if
it was selected. We now configure it up in the appropriate
PHY/MAC/Base-X mode depending on what phylink tells us we are connected
to and ensure it is enabled.

Tested with a device where the CPU connection is RGMII (i.e. the common
current use case) + one where the CPU connection is SGMII. I don't have
any devices where the SGMII interface is brought out to something other
than the CPU.

Signed-off-by: Jonathan McDowell 
---
 drivers/net/dsa/qca8k.c | 28 +++-
 drivers/net/dsa/qca8k.h | 13 +
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index dcd9e8fa99b6..33e62598289e 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -681,7 +681,7 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, 
unsigned int mode,
 const struct phylink_link_state *state)
 {
struct qca8k_priv *priv = ds->priv;
-   u32 reg;
+   u32 reg, val;
 
switch (port) {
case 0: /* 1st CPU port */
@@ -740,6 +740,32 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, 
unsigned int mode,
case PHY_INTERFACE_MODE_1000BASEX:
/* Enable SGMII on the port */
qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
+
+   /* Enable/disable SerDes auto-negotiation as necessary */
+   val = qca8k_read(priv, QCA8K_REG_PWS);
+   if (phylink_autoneg_inband(mode))
+   val &= ~QCA8K_PWS_SERDES_AEN_DIS;
+   else
+   val |= QCA8K_PWS_SERDES_AEN_DIS;
+   qca8k_write(priv, QCA8K_REG_PWS, val);
+
+   /* Configure the SGMII parameters */
+   val = qca8k_read(priv, QCA8K_REG_SGMII_CTRL);
+
+   val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
+   QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
+
+   val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
+   if (dsa_is_cpu_port(ds, port)) {
+   /* CPU port, we're talking to the CPU MAC, be a PHY */
+   val |= QCA8K_SGMII_MODE_CTRL_PHY;
+   } else if (state->interface == PHY_INTERFACE_MODE_SGMII) {
+   val |= QCA8K_SGMII_MODE_CTRL_MAC;
+   } else {
+   val |= QCA8K_SGMII_MODE_CTRL_BASEX;
+   }
+
+   qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
break;
default:
dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h
index 42d6ea24eb14..10ef2bca2cde 100644
--- a/drivers/net/dsa/qca8k.h
+++ b/drivers/net/dsa/qca8k.h
@@ -36,6 +36,8 @@
 #define   QCA8K_MAX_DELAY  3
 #define   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24)
 #define   QCA8K_PORT_PAD_SGMII_EN  BIT(7)
+#define QCA8K_REG_PWS  0x010
+#define   QCA8K_PWS_SERDES_AEN_DIS BIT(7)
 #define QCA8K_REG_MODULE_EN0x030
 #define   QCA8K_MODULE_EN_MIB  BIT(0)
 #define QCA8K_REG_MIB  0x034
@@ -69,6 +71,7 @@
 #define   QCA8K_PORT_STATUS_LINK_UPBIT(8)
 #define   QCA8K_PORT_STATUS_LINK_AUTO  BIT(9)
 #define   QCA8K_PORT_STATUS_LINK_PAUSE BIT(10)
+#define   QCA8K_PORT_STATUS_FLOW_AUTO  BIT(12)
 #define QCA8K_REG_PORT_HDR_CTRL(_i)(0x9c + (_i * 4))
 #define   QCA8K_PORT_HDR_CTRL_RX_MASK  GENMASK(3, 2)
 #define   QCA8K_PORT_HDR_CTRL_RX_S 2
@@ -77,6 +80,16 @@
 #define   QCA8K_PORT_HDR_CTRL_ALL  2
 #define   QCA8K_PORT_HDR_CTRL_MGMT 1
 #define   QCA8K_PORT_HDR_CTRL_NONE 0
+#define QCA8K_REG_SGMII_CTRL   0x0e0
+#define   QCA8K_SGMII_EN_PLL   BIT(1)
+#define   QCA8K_SGMII_EN_RXBIT(2)
+#define   QCA8K_SGMII_EN_TXBIT(3)
+#define   QCA8K_SGMII_EN_SDBIT(4)
+#define   QCA8K_SGMII_CLK125M_DELAYBIT(7)
+#define   QCA8K_SGMII_MODE_CTRL_MASK   (BIT(22) | BIT(23))
+#define   QCA8K_SGMII_MODE_CTRL_BASEX  (0 << 22)
+#define   QCA8K_SGMII_MODE_CTRL_PHY(1 << 22)
+#define   QCA8K_SGMII_MODE_CTRL_MAC(2 << 22)
 
 /* EEE control registers */
 #define QCA8K_REG_EEE_CTRL 0x100
-- 
2.20.1



[RFC PATCH v3 0/2] net: dsa: qca8k: Improve SGMII interface handling

2020-06-10 Thread Jonathan McDowell
Ok, take 3. This splits out the PHYLINK change to a separate patch which
should have no effect on functionality, and then adds the SGMII clean-ups
(i.e. the missing initialisation) on top of that as a second patch.

As before, tested with a device where the CPU connection is RGMII (i.e.
the common current use case) + one where the CPU connection is SGMII. I
don't have any devices where the SGMII interface is brought out to
something other than the CPU.


v3:
- Move phylink changes to separate patch
- Address rmk review comments
v2:
- Switch to phylink
- Avoid need for device tree configuration options

Jonathan McDowell (2):
  net: dsa: qca8k: Switch to PHYLINK instead of PHYLIB
  net: dsa: qca8k: Improve SGMII interface handling

 drivers/net/dsa/qca8k.c | 337 
 drivers/net/dsa/qca8k.h |  13 ++
 2 files changed, 252 insertions(+), 98 deletions(-)

-- 
2.20.1



[PATCH 1/2] net: dsa: qca8k: Switch to PHYLINK instead of PHYLIB

2020-06-10 Thread Jonathan McDowell
Update the driver to use the new PHYLINK callbacks, removing the
legacy adjust_link callback.

Signed-off-by: Jonathan McDowell 
---
 drivers/net/dsa/qca8k.c | 309 +++-
 1 file changed, 212 insertions(+), 97 deletions(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index d2b5ab403e06..dcd9e8fa99b6 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -418,55 +419,6 @@ qca8k_mib_init(struct qca8k_priv *priv)
mutex_unlock(>reg_mutex);
 }
 
-static int
-qca8k_set_pad_ctrl(struct qca8k_priv *priv, int port, int mode)
-{
-   u32 reg, val;
-
-   switch (port) {
-   case 0:
-   reg = QCA8K_REG_PORT0_PAD_CTRL;
-   break;
-   case 6:
-   reg = QCA8K_REG_PORT6_PAD_CTRL;
-   break;
-   default:
-   pr_err("Can't set PAD_CTRL on port %d\n", port);
-   return -EINVAL;
-   }
-
-   /* Configure a port to be directly connected to an external
-* PHY or MAC.
-*/
-   switch (mode) {
-   case PHY_INTERFACE_MODE_RGMII:
-   /* RGMII mode means no delay so don't enable the delay */
-   val = QCA8K_PORT_PAD_RGMII_EN;
-   qca8k_write(priv, reg, val);
-   break;
-   case PHY_INTERFACE_MODE_RGMII_ID:
-   /* RGMII_ID needs internal delay. This is enabled through
-* PORT5_PAD_CTRL for all ports, rather than individual port
-* registers
-*/
-   qca8k_write(priv, reg,
-   QCA8K_PORT_PAD_RGMII_EN |
-   QCA8K_PORT_PAD_RGMII_TX_DELAY(QCA8K_MAX_DELAY) |
-   QCA8K_PORT_PAD_RGMII_RX_DELAY(QCA8K_MAX_DELAY));
-   qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
-   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
-   break;
-   case PHY_INTERFACE_MODE_SGMII:
-   qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
-   break;
-   default:
-   pr_err("xMII mode %d not supported\n", mode);
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
 static void
 qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
 {
@@ -639,9 +591,7 @@ static int
 qca8k_setup(struct dsa_switch *ds)
 {
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-   phy_interface_t phy_mode = PHY_INTERFACE_MODE_NA;
int ret, i;
-   u32 mask;
 
/* Make sure that port 0 is the cpu port */
if (!dsa_is_cpu_port(ds, 0)) {
@@ -661,24 +611,9 @@ qca8k_setup(struct dsa_switch *ds)
if (ret)
return ret;
 
-   /* Initialize CPU port pad mode (xMII type, delays...) */
-   ret = of_get_phy_mode(dsa_to_port(ds, QCA8K_CPU_PORT)->dn, _mode);
-   if (ret) {
-   pr_err("Can't find phy-mode for master device\n");
-   return ret;
-   }
-   ret = qca8k_set_pad_ctrl(priv, QCA8K_CPU_PORT, phy_mode);
-   if (ret < 0)
-   return ret;
-
-   /* Enable CPU Port, force it to maximum bandwidth and full-duplex */
-   mask = QCA8K_PORT_STATUS_SPEED_1000 | QCA8K_PORT_STATUS_TXFLOW |
-  QCA8K_PORT_STATUS_RXFLOW | QCA8K_PORT_STATUS_DUPLEX;
-   qca8k_write(priv, QCA8K_REG_PORT_STATUS(QCA8K_CPU_PORT), mask);
+   /* Enable CPU Port */
qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
  QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
-   qca8k_port_set_status(priv, QCA8K_CPU_PORT, 1);
-   priv->port_sts[QCA8K_CPU_PORT].enabled = 1;
 
/* Enable MIB counters */
qca8k_mib_init(priv);
@@ -693,10 +628,9 @@ qca8k_setup(struct dsa_switch *ds)
qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
  QCA8K_PORT_LOOKUP_MEMBER, 0);
 
-   /* Disable MAC by default on all user ports */
+   /* Disable MAC by default on all ports */
for (i = 1; i < QCA8K_NUM_PORTS; i++)
-   if (dsa_is_user_port(ds, i))
-   qca8k_port_set_status(priv, i, 0);
+   qca8k_port_set_status(priv, i, 0);
 
/* Forward all unknown frames to CPU port for Linux processing */
qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
@@ -713,7 +647,7 @@ qca8k_setup(struct dsa_switch *ds)
  QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
}
 
-   /* Invividual user ports get connected to CPU port only */
+   /* Individual user ports get connected to CPU port only */
if (dsa_is_user_port(ds, i)) {
int shift = 16 * (i % 2);
 
@@ -743,44 +677,223 @@ qca8k_setup(struct dsa_switch *ds)
 }
 
 static void
-qca8k_adjust_link(struct dsa_switch *ds, int port, struct p

Re: R: [PATCH v6 1/2] phy: qualcomm: add qcom ipq806x dwc usb phy driver

2020-06-09 Thread Jonathan McDowell
On Fri, Jun 05, 2020 at 07:00:04PM +0200, ansuels...@gmail.com wrote:
> > On Wed, Jun 03, 2020 at 03:22:34PM +0200, Ansuel Smith wrote:
> > > This has lost in the original push for the dwc3 qcom driver.
> > > This is needed for ipq806x SoC as without this the usb ports
> > > doesn't work at all.
> > 
> > FWIW I tested this on my RB3011 so feel free to add:
> > 
> > Tested-by: Jonathan McDowell 
> > 
> > One minor comment; would PHY_QCOM_USB_IPQ806X not be a better
> > choice than PHY_QCOM_IPQ806X_USB given the existing naming?
> > 
>
> Thanks for the feedback. About naming I'm following the sata ipq806x
> naming.  I really hope someone gets this and reviews it since usb is
> broken for a long time now.

Doesn't seem to have made the 5.8 merge window; I note Vinod has done a
bunch of the recent commits to phy/qualcomm/ so adding him to the CC in
addition to Kishon.

> > > Signed-off-by: Andy Gross 
> > > Signed-off-by: Ansuel Smith 
> > > ---
> > > v6:
> > > * Use GENMASK instead of hex value
> > > v4:
> > > * Add qcom to specific bindings
> > > v3:
> > > * Use reg instead of regmap phandle
> > > v2:
> > > * Renamed config from PHY_QCOM_DWC3 to PHY_QCOM_IPQ806X_USB
> > > * Rename inline function to generic name to reduce length
> > > * Fix check reported by checkpatch --strict
> > > * Rename compatible to qcom,ipq806x-usb-phy-(hs/ss)
> > >
> > >  drivers/phy/qualcomm/Kconfig|  12 +
> > >  drivers/phy/qualcomm/Makefile   |   1 +
> > >  drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c | 593
> > 
> > >  3 files changed, 606 insertions(+)
> > >  create mode 100644 drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
> > >
> > > diff --git a/drivers/phy/qualcomm/Kconfig
> > b/drivers/phy/qualcomm/Kconfig
> > > index e46824da29f6..9d41c3d12800 100644
> > > --- a/drivers/phy/qualcomm/Kconfig
> > > +++ b/drivers/phy/qualcomm/Kconfig
> > > @@ -91,3 +91,15 @@ config PHY_QCOM_USB_HSIC
> > >   select GENERIC_PHY
> > >   help
> > > Support for the USB HSIC ULPI compliant PHY on QCOM chipsets.
> > > +
> > > +config PHY_QCOM_IPQ806X_USB
> > > + tristate "Qualcomm IPQ806x DWC3 USB PHY driver"
> > > + depends on ARCH_QCOM
> > > + depends on HAS_IOMEM
> > > + depends on OF
> > > + select GENERIC_PHY
> > > + help
> > > +   This option enables support for the Synopsis PHYs present inside
> > the
> > > +   Qualcomm USB3.0 DWC3 controller on ipq806x SoC. This driver
> > supports
> > > +   both HS and SS PHY controllers.
> > > +
> > > diff --git a/drivers/phy/qualcomm/Makefile
> > b/drivers/phy/qualcomm/Makefile
> > > index 283251d6a5d9..8629299c1495 100644
> > > --- a/drivers/phy/qualcomm/Makefile
> > > +++ b/drivers/phy/qualcomm/Makefile
> > > @@ -10,3 +10,4 @@ obj-$(CONFIG_PHY_QCOM_UFS_14NM)
> > += phy-qcom-ufs-qmp-14nm.o
> > >  obj-$(CONFIG_PHY_QCOM_UFS_20NM)  += phy-qcom-ufs-
> > qmp-20nm.o
> > >  obj-$(CONFIG_PHY_QCOM_USB_HS)+= phy-qcom-usb-hs.o
> > >  obj-$(CONFIG_PHY_QCOM_USB_HSIC)  += phy-qcom-usb-hsic.o
> > > +obj-$(CONFIG_PHY_QCOM_IPQ806X_USB)   += phy-qcom-
> > ipq806x-usb.o
> > > diff --git a/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
> > b/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
> > > new file mode 100644
> > > index ..f37cd8760118
> > > --- /dev/null
> > > +++ b/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
> > > @@ -0,0 +1,593 @@
> > > +// SPDX-License-Identifier: GPL-2.0-only
> > > +/* Copyright (c) 2014-2015, Code Aurora Forum. All rights reserved.
> > > + *
> > > + * This program is free software; you can redistribute it and/or modify
> > > + * it under the terms of the GNU General Public License version 2 and
> > > + * only version 2 as published by the Free Software Foundation.
> > > + *
> > > + * This program is distributed in the hope that it will be useful,
> > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > > + * GNU General Public License for more details.
> > > + */
> > > +
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 

[RFC PATCH v2] net: dsa: qca8k: Improve SGMII interface handling

2020-06-08 Thread Jonathan McDowell
On Sat, Jun 06, 2020 at 11:59:09AM +0100, Jonathan McDowell wrote:
> I'll go away and roll a v2 moving qca8k over to phylink and then using
> that to auto select the appropriate SGMII mode. Thanks for the feedback.

Ok, take 2. I've switched the driver over to phylink which has let me
drop the need for any device tree configuration; if we're a CPU port
then we're in SGMII-PHY mode, otherwise we choose between SGMII-MAC +
Base-X on what phylink tells us.



This patch improves the handling of the SGMII interface on the QCA8K
devices. Previously the driver did no configuration of the port, even if
it was selected. We now configure it up in the appropriate
PHY/MAC/Base-X mode depending on what phylink tells us we are connected
to and ensure it is enabled.

Tested with a device where the CPU connection is RGMII (i.e. the common
current use case) + one where the CPU connection is SGMII. I don't have
any devices where the SGMII interface is brought out to something other
than the CPU.

v2:
- Switch to phylink
- Avoid need for device tree configuration options

Signed-off-by: Jonathan McDowell 

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index d2b5ab403e06..62f609ea0e49 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -418,55 +419,6 @@ qca8k_mib_init(struct qca8k_priv *priv)
mutex_unlock(>reg_mutex);
 }
 
-static int
-qca8k_set_pad_ctrl(struct qca8k_priv *priv, int port, int mode)
-{
-   u32 reg, val;
-
-   switch (port) {
-   case 0:
-   reg = QCA8K_REG_PORT0_PAD_CTRL;
-   break;
-   case 6:
-   reg = QCA8K_REG_PORT6_PAD_CTRL;
-   break;
-   default:
-   pr_err("Can't set PAD_CTRL on port %d\n", port);
-   return -EINVAL;
-   }
-
-   /* Configure a port to be directly connected to an external
-* PHY or MAC.
-*/
-   switch (mode) {
-   case PHY_INTERFACE_MODE_RGMII:
-   /* RGMII mode means no delay so don't enable the delay */
-   val = QCA8K_PORT_PAD_RGMII_EN;
-   qca8k_write(priv, reg, val);
-   break;
-   case PHY_INTERFACE_MODE_RGMII_ID:
-   /* RGMII_ID needs internal delay. This is enabled through
-* PORT5_PAD_CTRL for all ports, rather than individual port
-* registers
-*/
-   qca8k_write(priv, reg,
-   QCA8K_PORT_PAD_RGMII_EN |
-   QCA8K_PORT_PAD_RGMII_TX_DELAY(QCA8K_MAX_DELAY) |
-   QCA8K_PORT_PAD_RGMII_RX_DELAY(QCA8K_MAX_DELAY));
-   qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,
-   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
-   break;
-   case PHY_INTERFACE_MODE_SGMII:
-   qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
-   break;
-   default:
-   pr_err("xMII mode %d not supported\n", mode);
-   return -EINVAL;
-   }
-
-   return 0;
-}
-
 static void
 qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
 {
@@ -639,9 +591,7 @@ static int
 qca8k_setup(struct dsa_switch *ds)
 {
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
-   phy_interface_t phy_mode = PHY_INTERFACE_MODE_NA;
int ret, i;
-   u32 mask;
 
/* Make sure that port 0 is the cpu port */
if (!dsa_is_cpu_port(ds, 0)) {
@@ -661,24 +611,9 @@ qca8k_setup(struct dsa_switch *ds)
if (ret)
return ret;
 
-   /* Initialize CPU port pad mode (xMII type, delays...) */
-   ret = of_get_phy_mode(dsa_to_port(ds, QCA8K_CPU_PORT)->dn, _mode);
-   if (ret) {
-   pr_err("Can't find phy-mode for master device\n");
-   return ret;
-   }
-   ret = qca8k_set_pad_ctrl(priv, QCA8K_CPU_PORT, phy_mode);
-   if (ret < 0)
-   return ret;
-
-   /* Enable CPU Port, force it to maximum bandwidth and full-duplex */
-   mask = QCA8K_PORT_STATUS_SPEED_1000 | QCA8K_PORT_STATUS_TXFLOW |
-  QCA8K_PORT_STATUS_RXFLOW | QCA8K_PORT_STATUS_DUPLEX;
-   qca8k_write(priv, QCA8K_REG_PORT_STATUS(QCA8K_CPU_PORT), mask);
+   /* Enable CPU Port */
qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0,
  QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
-   qca8k_port_set_status(priv, QCA8K_CPU_PORT, 1);
-   priv->port_sts[QCA8K_CPU_PORT].enabled = 1;
 
/* Enable MIB counters */
qca8k_mib_init(priv);
@@ -693,10 +628,9 @@ qca8k_setup(struct dsa_switch *ds)
qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i),
  QCA8K_PORT_LOOKUP_MEMBER, 0);
 
-   /* Disable MAC by default on all user ports */
+   /* Disable MAC by default on all 

Re: [PATCH 2/2] net: dsa: qca8k: introduce SGMII configuration options

2020-06-06 Thread Jonathan McDowell
On Sat, Jun 06, 2020 at 02:43:56PM +0100, Russell King - ARM Linux admin wrote:
> On Sat, Jun 06, 2020 at 11:59:09AM +0100, Jonathan McDowell wrote:
> > So the device in question is a 7 port stand alone switch chip. There's a
> > single SGMII port which is configurable between port 0 + 6 (they can
> > also be configure up as RGMII, while the remaining 5 ports have their
> > own phys).
> > 
> > It sounds like there's a strong preference to try and auto configure
> > things as much as possible, so I should assume the CPU port is in MAC
> > mode, and anything not tagged as a CPU port is talking to a PHY/BASEX.
> > 
> > I assume I can use PHY_INTERFACE_MODE_1000BASEX on the
> > phylink_mac_config call to choose BASEX?
> 
> Yes, but from what you've mentioned above, I think I need to ensure that
> there's a proper understanding here.
> 
> 1000BASE-X is the IEEE 802.3 defined 1G single lane Serdes protocol.
> SGMII is different; it's a vendor derivative of 1000BASE-X which has
> become a de-facto standard.
> 
> Both are somewhat compatible with each other; SGMII brings with it
> additional data replication to achieve 100M and 10M speeds, while
> keeping the link running at 1.25Gbaud.  In both cases, there is a
> 16-bit "configuration" word that is passed between the partners.
> 
> 1000BASE-X uses this configuration word to advertise the abilities of
> each end, which is limited to duplex and pause modes only.  This you
> get by specifying the phy-mode="1000base-x" and
> managed="in-band-status" in DT.
> 
> SGMII uses this configuration word for the media side to inform the
> system side which mode it wishes to operate the link: the speed and
> duplex.  Some vendors extend it to include EEE parameters as well,
> or pause modes.  You get this via phy-mode="sgmii" and
> managed="in-band-status" in DT.
> 
> Then there are variants where the configuration word is not present.
> In this case, the link has to be manually configured, and without the
> configuration word, SGMII operating at 1G is compatible with
> 1000base-X operating at 1G.  Fixed-link can be used for this, although
> fixed-link will always report that the link is up at the moment; that
> may change in the future, it's something that is being looked into at
> the moment.

The hardware I'm using has the switch connected to the CPU via the SGMII
link, and all instances I can find completely disable inband
configuration for that case. However the data sheet has an SGMII control
register which allows configuration of the various auto-negotiation
parameters (as well as whether we're base-x or sgmii) so I think the
full flexibility is there.

I've got an initial port over to using phylink and picking up the
parameters that way (avoiding any device tree option changes) that seems
to be working, but I'll do a bit more testing before sending out a v2
RFC.

J.

-- 
/-\ | There are always at least two ways
|@/  Debian GNU/Linux Developer | to program the same thing.
\-  |


Re: [PATCH 2/2] net: dsa: qca8k: introduce SGMII configuration options

2020-06-06 Thread Jonathan McDowell
On Sat, Jun 06, 2020 at 09:37:41AM +0100, Russell King - ARM Linux admin wrote:
> On Sat, Jun 06, 2020 at 08:49:16AM +0100, Jonathan McDowell wrote:
> > On Fri, Jun 05, 2020 at 08:38:43PM +0200, Andrew Lunn wrote:
> > > On Fri, Jun 05, 2020 at 07:10:58PM +0100, Jonathan McDowell wrote:
> > > > The QCA8337(N) has an SGMII port which can operate in MAC, PHY or BASE-X
> > > > mode depending on what it's connected to (e.g. CPU vs external PHY or
> > > > SFP). At present the driver does no configuration of this port even if
> > > > it is selected.
> > > > 
> > > > Add support for making sure the SGMII is enabled if it's in use, and
> > > > device tree support for configuring the connection details.
> > > 
> > > It is good to include Russell King in Cc: for patches like this.
> > 
> > No problem, I can keep him in the thread; I used get_maintainer for the
> > initial set of people/lists to copy.
> 
> get_maintainer is not always "good" at selecting the right people,
> especially when your patches don't match the criteria; MAINTAINERS
> contains everything that is sensible, but Andrew is suggesting that
> you copy me because in his opinion, you should be using phylink -
> and that's something that you can't encode into a program.

Sure, and I appreciate the pointer to appropriate people who might
provide helpful comments.

> Note that I haven't seen your patches.

I'll make sure to copy you on v2.

> > > Also, netdev is closed at the moment, so please post patches as RFC.
> > 
> > "closed"? If you mean this won't get into 5.8 then I wasn't expecting it
> > to, I'm aware the merge window for that is already open.
> 
> See https://www.kernel.org/doc/Documentation/networking/netdev-FAQ.txt
> "How often do changes from these trees make it to the mainline Linus
> tree?"

Ta. I'll hold off on a v2 until after -rc1 drops.

> > > It sounds like the hardware has a PCS which can support SGMII or
> > > 1000BaseX. phylink will tell you what mode to configure it to. e.g. A
> > > fibre SFP module will want 1000BaseX. A copper SFP module will want
> > > SGMII. A switch is likely to want 1000BaseX. A PHY is likely to want
> > > SGMII. So remove the "sgmii-mode" property and configure it as phylink
> > > is requesting.
> > 
> > It's more than SGMII or 1000BaseX as I read it. The port can act as if
> > it's talking to an SGMII MAC, i.e. a CPU, or an SGMII PHY, i.e. an
> > external PHY, or in BaseX mode for an SFP. I couldn't figure out a way
> > in the current framework to automatically work out if I wanted PHY or
> > MAC mode. For the port tagged CPU I can assume MAC mode, but a port that
> > doesn't have that might still be attached to the CPU rather than an
> > external PHY.
> 
> That depends what you're connected to. Some people call the two sides
> of SGMII "System side" and "Media side". System side is where you're
> receiving the results of AN from a PHY. Media side is where you're
> telling the partner what you want it to do.
> 
> Media side is only useful if you're connected to another MAC, and
> unless you have a requirement for it, I would suggest not implementing
> that - you could come up with something using fixed-link, or it may
> need some other model if the settings need to change.  That depends on
> the application.

So the device in question is a 7 port stand alone switch chip. There's a
single SGMII port which is configurable between port 0 + 6 (they can
also be configure up as RGMII, while the remaining 5 ports have their
own phys).

It sounds like there's a strong preference to try and auto configure
things as much as possible, so I should assume the CPU port is in MAC
mode, and anything not tagged as a CPU port is talking to a PHY/BASEX.

I assume I can use PHY_INTERFACE_MODE_1000BASEX on the
phylink_mac_config call to choose BASEX?

> > > What exactly does sgmii-delay do?
> > 
> > As per the device tree documentation update I sent it delays the SGMII
> > clock by 2ns. From the data sheet:
> > 
> > SGMII_SEL_CLK125M   sgmii_clk125m_rx_delay is delayed by 2ns
> 
> This sounds like a new world of RGMII delay pain but for SGMII. There
> is no mention of "delay" in the SGMII v1.8 specification, so I guess
> it's something the vendor is doing. Is this device capable of
> recovering the clock from a single serdes pair carrying the data,
> or does it always require the separate clock?

Pass, but I think I might be able to get away without having to
configure that for the moment.

I'll go away and roll a v2 moving qca8k over to phylink and then using
that to auto select the appropriate SGMII mode. Thanks for the feedback.

J.

-- 
I started out with nothing & still have most of it left.


Re: [PATCH 2/2] net: dsa: qca8k: introduce SGMII configuration options

2020-06-06 Thread Jonathan McDowell
On Fri, Jun 05, 2020 at 08:38:43PM +0200, Andrew Lunn wrote:
> On Fri, Jun 05, 2020 at 07:10:58PM +0100, Jonathan McDowell wrote:
> > The QCA8337(N) has an SGMII port which can operate in MAC, PHY or BASE-X
> > mode depending on what it's connected to (e.g. CPU vs external PHY or
> > SFP). At present the driver does no configuration of this port even if
> > it is selected.
> > 
> > Add support for making sure the SGMII is enabled if it's in use, and
> > device tree support for configuring the connection details.
> 
> It is good to include Russell King in Cc: for patches like this.

No problem, I can keep him in the thread; I used get_maintainer for the
initial set of people/lists to copy.

> Also, netdev is closed at the moment, so please post patches as RFC.

"closed"? If you mean this won't get into 5.8 then I wasn't expecting it
to, I'm aware the merge window for that is already open.

> It sounds like the hardware has a PCS which can support SGMII or
> 1000BaseX. phylink will tell you what mode to configure it to. e.g. A
> fibre SFP module will want 1000BaseX. A copper SFP module will want
> SGMII. A switch is likely to want 1000BaseX. A PHY is likely to want
> SGMII. So remove the "sgmii-mode" property and configure it as phylink
> is requesting.

It's more than SGMII or 1000BaseX as I read it. The port can act as if
it's talking to an SGMII MAC, i.e. a CPU, or an SGMII PHY, i.e. an
external PHY, or in BaseX mode for an SFP. I couldn't figure out a way
in the current framework to automatically work out if I wanted PHY or
MAC mode. For the port tagged CPU I can assume MAC mode, but a port that
doesn't have that might still be attached to the CPU rather than an
external PHY.

> What exactly does sgmii-delay do?

As per the device tree documentation update I sent it delays the SGMII
clock by 2ns. From the data sheet:

SGMII_SEL_CLK125M   sgmii_clk125m_rx_delay is delayed by 2ns

> > +#define QCA8K_REG_SGMII_CTRL   0x0e0
> > +#define   QCA8K_SGMII_EN_PLL   BIT(1)
> > +#define   QCA8K_SGMII_EN_RXBIT(2)
> > +#define   QCA8K_SGMII_EN_TXBIT(3)
> > +#define   QCA8K_SGMII_EN_SDBIT(4)
> > +#define   QCA8K_SGMII_CLK125M_DELAYBIT(7)
> > +#define   QCA8K_SGMII_MODE_CTRL_MASK   (BIT(22) | 
> > BIT(23))
> > +#define   QCA8K_SGMII_MODE_CTRL_BASEX  0
> > +#define   QCA8K_SGMII_MODE_CTRL_PHYBIT(22)
> > +#define   QCA8K_SGMII_MODE_CTRL_MACBIT(23)
> 
> I guess these are not really bits. You cannot combine
> QCA8K_SGMII_MODE_CTRL_MAC and QCA8K_SGMII_MODE_CTRL_PHY. So it makes
> more sense to have:
> 
> #define   QCA8K_SGMII_MODE_CTRL_BASEX (0x0 << 22)
> #define   QCA8K_SGMII_MODE_CTRL_PHY   (0x1 << 22)
> #define   QCA8K_SGMII_MODE_CTRL_MAC   (0x2 << 22)

Sure; given there's no 0x3 choice I just went for the bits that need
set, but that works too.

J.

-- 
Mistakes aren't always regrets.


[PATCH 2/2] net: dsa: qca8k: introduce SGMII configuration options

2020-06-05 Thread Jonathan McDowell
The QCA8337(N) has an SGMII port which can operate in MAC, PHY or BASE-X
mode depending on what it's connected to (e.g. CPU vs external PHY or
SFP). At present the driver does no configuration of this port even if
it is selected.

Add support for making sure the SGMII is enabled if it's in use, and
device tree support for configuring the connection details.

Signed-off-by: Jonathan McDowell 
---
 drivers/net/dsa/qca8k.c | 44 -
 drivers/net/dsa/qca8k.h | 12 +++
 2 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 9f4205b4439b..5b7979aca9b9 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -418,6 +418,40 @@ qca8k_mib_init(struct qca8k_priv *priv)
mutex_unlock(>reg_mutex);
 }
 
+static int
+qca8k_setup_sgmii(struct qca8k_priv *priv)
+{
+   const char *mode;
+   u32 val;
+
+   val = qca8k_read(priv, QCA8K_REG_SGMII_CTRL);
+
+   val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
+   QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
+
+   if (of_property_read_bool(priv->dev->of_node, "sgmii-delay"))
+   val |= QCA8K_SGMII_CLK125M_DELAY;
+
+   if (of_property_read_string(priv->dev->of_node, "sgmii-mode", )) {
+   val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
+
+   if (!strcasecmp(mode, "basex")) {
+   val |= QCA8K_SGMII_MODE_CTRL_BASEX;
+   } else if (!strcasecmp(mode, "mac")) {
+   val |= QCA8K_SGMII_MODE_CTRL_MAC;
+   } else if (!strcasecmp(mode, "phy")) {
+   val |= QCA8K_SGMII_MODE_CTRL_PHY;
+   } else {
+   pr_err("Unrecognised SGMII mode %s\n", mode);
+   return -EINVAL;
+   }
+   }
+
+   qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
+
+   return 0;
+}
+
 static int
 qca8k_set_pad_ctrl(struct qca8k_priv *priv, int port, int mode)
 {
@@ -458,7 +492,8 @@ qca8k_set_pad_ctrl(struct qca8k_priv *priv, int port, int 
mode)
break;
case PHY_INTERFACE_MODE_SGMII:
qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
-   break;
+
+   return qca8k_setup_sgmii(priv);
default:
pr_err("xMII mode %d not supported\n", mode);
return -EINVAL;
@@ -661,6 +696,13 @@ qca8k_setup(struct dsa_switch *ds)
if (ret)
return ret;
 
+   if (of_property_read_bool(priv->dev->of_node,
+ "disable-serdes-autoneg")) {
+   mask = qca8k_read(priv, QCA8K_REG_PWS) |
+  QCA8K_PWS_SERDES_AEN_DIS;
+   qca8k_write(priv, QCA8K_REG_PWS, mask);
+   }
+
/* Initialize CPU port pad mode (xMII type, delays...) */
ret = of_get_phy_mode(dsa_to_port(ds, QCA8K_CPU_PORT)->dn, _mode);
if (ret) {
diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h
index 42d6ea24eb14..cd97c212f3f8 100644
--- a/drivers/net/dsa/qca8k.h
+++ b/drivers/net/dsa/qca8k.h
@@ -36,6 +36,8 @@
 #define   QCA8K_MAX_DELAY  3
 #define   QCA8K_PORT_PAD_RGMII_RX_DELAY_EN BIT(24)
 #define   QCA8K_PORT_PAD_SGMII_EN  BIT(7)
+#define QCA8K_REG_PWS  0x010
+#define   QCA8K_PWS_SERDES_AEN_DIS BIT(7)
 #define QCA8K_REG_MODULE_EN0x030
 #define   QCA8K_MODULE_EN_MIB  BIT(0)
 #define QCA8K_REG_MIB  0x034
@@ -77,6 +79,16 @@
 #define   QCA8K_PORT_HDR_CTRL_ALL  2
 #define   QCA8K_PORT_HDR_CTRL_MGMT 1
 #define   QCA8K_PORT_HDR_CTRL_NONE 0
+#define QCA8K_REG_SGMII_CTRL   0x0e0
+#define   QCA8K_SGMII_EN_PLL   BIT(1)
+#define   QCA8K_SGMII_EN_RXBIT(2)
+#define   QCA8K_SGMII_EN_TXBIT(3)
+#define   QCA8K_SGMII_EN_SDBIT(4)
+#define   QCA8K_SGMII_CLK125M_DELAYBIT(7)
+#define   QCA8K_SGMII_MODE_CTRL_MASK   (BIT(22) | BIT(23))
+#define   QCA8K_SGMII_MODE_CTRL_BASEX  0
+#define   QCA8K_SGMII_MODE_CTRL_PHYBIT(22)
+#define   QCA8K_SGMII_MODE_CTRL_MACBIT(23)
 
 /* EEE control registers */
 #define QCA8K_REG_EEE_CTRL 0x100
-- 
2.20.1



[PATCH 1/2] dt-bindings: net: dsa: qca8k: document SGMII properties

2020-06-05 Thread Jonathan McDowell
This patch documents the qca8k's SGMII related properties that allow
configuration of the SGMII port.

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

diff --git a/Documentation/devicetree/bindings/net/dsa/qca8k.txt 
b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
index ccbc6d89325d..9e7d74a248ad 100644
--- a/Documentation/devicetree/bindings/net/dsa/qca8k.txt
+++ b/Documentation/devicetree/bindings/net/dsa/qca8k.txt
@@ -11,7 +11,11 @@ Required properties:
 
 Optional properties:
 
+- disable-serdes-autoneg: Boolean, disables auto-negotiation on the SerDes
 - reset-gpios: GPIO to be used to reset the whole device
+- sgmii-delay: Boolean, presence delays SGMII clock by 2ns
+- sgmii-mode: String, operation mode of the SGMII interface.
+  Supported values are: "basex", "mac", "phy".
 
 Subnodes:
 
-- 
2.20.1



[PATCH 0/2] net: dsa: qca8k: Add SGMII configuration options

2020-06-05 Thread Jonathan McDowell
This pair of patches adds some SGMII device tree configuration options
for the QCA8K switch driver, and the associated documentation.

At present the driver does no configuration of the SGMII port, even if
it is selected. These changes allow configuration of how it is connected
up (i.e. connected to an external phy, or to a CPU, or to an SFP cage)
as well as allowing for autonegotiation to be disabled and a delay
configured.

Tested on a MikroTik RB3011; the second switch is connected to the CPU
via SGMII.

Jonathan McDowell (2):
  dt-bindings: net: dsa: qca8k: document SGMII properties
  net: dsa: qca8k: introduce SGMII configuration options

 .../devicetree/bindings/net/dsa/qca8k.txt |  4 ++
 drivers/net/dsa/qca8k.c   | 44 ++-
 drivers/net/dsa/qca8k.h   | 12 +
 3 files changed, 59 insertions(+), 1 deletion(-)

-- 
2.20.1



Re: [PATCH v6 1/2] phy: qualcomm: add qcom ipq806x dwc usb phy driver

2020-06-04 Thread Jonathan McDowell
On Wed, Jun 03, 2020 at 03:22:34PM +0200, Ansuel Smith wrote:
> This has lost in the original push for the dwc3 qcom driver.
> This is needed for ipq806x SoC as without this the usb ports
> doesn't work at all.

FWIW I tested this on my RB3011 so feel free to add:

Tested-by: Jonathan McDowell 

One minor comment; would PHY_QCOM_USB_IPQ806X not be a better choice
than PHY_QCOM_IPQ806X_USB given the existing naming?

> Signed-off-by: Andy Gross 
> Signed-off-by: Ansuel Smith 
> ---
> v6:
> * Use GENMASK instead of hex value
> v4:
> * Add qcom to specific bindings
> v3:
> * Use reg instead of regmap phandle
> v2:
> * Renamed config from PHY_QCOM_DWC3 to PHY_QCOM_IPQ806X_USB
> * Rename inline function to generic name to reduce length
> * Fix check reported by checkpatch --strict
> * Rename compatible to qcom,ipq806x-usb-phy-(hs/ss)
> 
>  drivers/phy/qualcomm/Kconfig|  12 +
>  drivers/phy/qualcomm/Makefile   |   1 +
>  drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c | 593 
>  3 files changed, 606 insertions(+)
>  create mode 100644 drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
> 
> diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig
> index e46824da29f6..9d41c3d12800 100644
> --- a/drivers/phy/qualcomm/Kconfig
> +++ b/drivers/phy/qualcomm/Kconfig
> @@ -91,3 +91,15 @@ config PHY_QCOM_USB_HSIC
>   select GENERIC_PHY
>   help
> Support for the USB HSIC ULPI compliant PHY on QCOM chipsets.
> +
> +config PHY_QCOM_IPQ806X_USB
> + tristate "Qualcomm IPQ806x DWC3 USB PHY driver"
> + depends on ARCH_QCOM
> + depends on HAS_IOMEM
> + depends on OF
> + select GENERIC_PHY
> + help
> +   This option enables support for the Synopsis PHYs present inside the
> +   Qualcomm USB3.0 DWC3 controller on ipq806x SoC. This driver supports
> +   both HS and SS PHY controllers.
> +
> diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile
> index 283251d6a5d9..8629299c1495 100644
> --- a/drivers/phy/qualcomm/Makefile
> +++ b/drivers/phy/qualcomm/Makefile
> @@ -10,3 +10,4 @@ obj-$(CONFIG_PHY_QCOM_UFS_14NM) += 
> phy-qcom-ufs-qmp-14nm.o
>  obj-$(CONFIG_PHY_QCOM_UFS_20NM)  += phy-qcom-ufs-qmp-20nm.o
>  obj-$(CONFIG_PHY_QCOM_USB_HS)+= phy-qcom-usb-hs.o
>  obj-$(CONFIG_PHY_QCOM_USB_HSIC)  += phy-qcom-usb-hsic.o
> +obj-$(CONFIG_PHY_QCOM_IPQ806X_USB)   += phy-qcom-ipq806x-usb.o
> diff --git a/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c 
> b/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
> new file mode 100644
> index ..f37cd8760118
> --- /dev/null
> +++ b/drivers/phy/qualcomm/phy-qcom-ipq806x-usb.c
> @@ -0,0 +1,593 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/* Copyright (c) 2014-2015, Code Aurora Forum. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +/* USB QSCRATCH Hardware registers */
> +#define QSCRATCH_GENERAL_CFG (0x08)
> +#define HSUSB_PHY_CTRL_REG   (0x10)
> +
> +/* PHY_CTRL_REG */
> +#define HSUSB_CTRL_DMSEHV_CLAMP  BIT(24)
> +#define HSUSB_CTRL_USB2_SUSPEND  BIT(23)
> +#define HSUSB_CTRL_UTMI_CLK_EN   BIT(21)
> +#define HSUSB_CTRL_UTMI_OTG_VBUS_VALID   BIT(20)
> +#define HSUSB_CTRL_USE_CLKCORE   BIT(18)
> +#define HSUSB_CTRL_DPSEHV_CLAMP  BIT(17)
> +#define HSUSB_CTRL_COMMONONN BIT(11)
> +#define HSUSB_CTRL_ID_HV_CLAMP   BIT(9)
> +#define HSUSB_CTRL_OTGSESSVLD_CLAMP  BIT(8)
> +#define HSUSB_CTRL_CLAMP_EN  BIT(7)
> +#define HSUSB_CTRL_RETENABLENBIT(1)
> +#define HSUSB_CTRL_POR   BIT(0)
> +
> +/* QSCRATCH_GENERAL_CFG */
> +#define HSUSB_GCFG_XHCI_REV  BIT(2)
> +
> +/* USB QSCRATCH Hardware registers */
> +#define SSUSB_PHY_CTRL_REG   (0x00)
> +#define SSUSB_PHY_PARAM_CTRL_1   (0x04)
> +#define SSUSB_PHY_PARAM_CTRL_2   (0x08)
> +#define CR_PROTOCOL_DATA_IN_REG  (0x0c)
> +#define CR_PROTOCOL_DATA_OUT_REG  

[PATCH] net: ethernet: stmmac: Enable interface clocks on probe for IPQ806x

2020-05-21 Thread Jonathan McDowell
The ipq806x_gmac_probe() function enables the PTP clock but not the
appropriate interface clocks. This means that if the bootloader hasn't
done so attempting to bring up the interface will fail with an error
like:

[   59.028131] ipq806x-gmac-dwmac 3760.ethernet: Failed to reset the dma
[   59.028196] ipq806x-gmac-dwmac 3760.ethernet eth1: stmmac_hw_setup: DMA 
engine initialization failed
[   59.034056] ipq806x-gmac-dwmac 3760.ethernet eth1: stmmac_open: Hw setup 
failed

This patch, a slightly cleaned up version of one posted by Sergey
Sergeev in:

https://forum.openwrt.org/t/support-for-mikrotik-rb3011uias-rm/4064/257

correctly enables the clock; we have already configured the source just
before this.

Tested on a MikroTik RB3011.

Signed-off-by: Jonathan McDowell 

---

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
index 6ae13dc19510..02102c781a8c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
@@ -319,6 +319,19 @@ static int ipq806x_gmac_probe(struct platform_device *pdev)
/* Enable PTP clock */
regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, );
val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id);
+   switch (gmac->phy_mode) {
+   case PHY_INTERFACE_MODE_RGMII:
+   val |= NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
+   NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
+   break;
+   case PHY_INTERFACE_MODE_SGMII:
+   val |= NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) |
+   NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
+   break;
+   default:
+   /* We don't get here; the switch above will have errored out */
+   unreachable();
+   }
regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
 
if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) {


[PATCH 1/3] dt-bindings: vendor-prefixes: Add MikroTik

2020-05-18 Thread Jonathan McDowell
MikroTik (SIA Mikrotīkls) is a Latvian company who develop routers and
wireless ISP systems.

Signed-off-by: Jonathan McDowell 
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml 
b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index d3891386d671..d3277fe6640b 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -633,6 +633,8 @@ patternProperties:
 description: Microsoft Corporation
   "^mikroe,.*":
 description: MikroElektronika d.o.o.
+  "^mikrotik,.*":
+description: MikroTik
   "^miniand,.*":
 description: Miniand Tech
   "^minix,.*":
-- 
2.20.1



[PATCH 2/3] ARM: dts: qcom: add ethernet definitions to ipq8064

2020-05-18 Thread Jonathan McDowell
Plumb in the 4 IPQ8064 stmmac based ethernet interfaces.

Signed-off-by: Jonathan McDowell 
---
 arch/arm/boot/dts/qcom-ipq8064.dtsi | 108 
 1 file changed, 108 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi 
b/arch/arm/boot/dts/qcom-ipq8064.dtsi
index b912da9a3ff3..9c0d5510c805 100644
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -597,6 +597,114 @@
perst-gpio = <_pinmux 63 GPIO_ACTIVE_LOW>;
};
 
+   nss_common: syscon@0300 {
+   compatible = "syscon";
+   reg = <0x0300 0x>;
+   };
+
+   qsgmii_csr: syscon@1bb0 {
+   compatible = "syscon";
+   reg = <0x1bb0 0x01FF>;
+   };
+
+   stmmac_axi_setup: stmmac-axi-config {
+   snps,wr_osr_lmt = <7>;
+   snps,rd_osr_lmt = <7>;
+   snps,blen = <16 0 0 0 0 0 0>;
+   };
+
+   gmac0: ethernet@3700 {
+   device_type = "network";
+   compatible = "qcom,ipq806x-gmac";
+   reg = <0x3700 0x20>;
+   interrupts = ;
+   interrupt-names = "macirq";
+
+   snps,axi-config = <_axi_setup>;
+   snps,pbl = <32>;
+   snps,aal = <1>;
+
+   qcom,nss-common = <_common>;
+   qcom,qsgmii-csr = <_csr>;
+
+   clocks = < GMAC_CORE1_CLK>;
+   clock-names = "stmmaceth";
+
+   resets = < GMAC_CORE1_RESET>;
+   reset-names = "stmmaceth";
+
+   status = "disabled";
+   };
+
+   gmac1: ethernet@3720 {
+   device_type = "network";
+   compatible = "qcom,ipq806x-gmac";
+   reg = <0x3720 0x20>;
+   interrupts = ;
+   interrupt-names = "macirq";
+
+   snps,axi-config = <_axi_setup>;
+   snps,pbl = <32>;
+   snps,aal = <1>;
+
+   qcom,nss-common = <_common>;
+   qcom,qsgmii-csr = <_csr>;
+
+   clocks = < GMAC_CORE2_CLK>;
+   clock-names = "stmmaceth";
+
+   resets = < GMAC_CORE2_RESET>;
+   reset-names = "stmmaceth";
+
+   status = "disabled";
+   };
+
+   gmac2: ethernet@3740 {
+   device_type = "network";
+   compatible = "qcom,ipq806x-gmac";
+   reg = <0x3740 0x20>;
+   interrupts = ;
+   interrupt-names = "macirq";
+
+   snps,axi-config = <_axi_setup>;
+   snps,pbl = <32>;
+   snps,aal = <1>;
+
+   qcom,nss-common = <_common>;
+   qcom,qsgmii-csr = <_csr>;
+
+   clocks = < GMAC_CORE3_CLK>;
+   clock-names = "stmmaceth";
+
+   resets = < GMAC_CORE3_RESET>;
+   reset-names = "stmmaceth";
+
+   status = "disabled";
+   };
+
+   gmac3: ethernet@3760 {
+   device_type = "network";
+   compatible = "qcom,ipq806x-gmac";
+   reg = <0x3760 0x20>;
+   interrupts = ;
+   interrupt-names = "macirq";
+
+   snps,axi-config = <_axi_setup>;
+   snps,pbl = <32>;
+   snps,aal = <1>;
+
+   qcom,nss-common = <_common>;
+   qcom,qsgmii-csr = <_csr>;
+
+   clocks = < GMAC_CORE4_CLK>;
+   clock-names = "stmmaceth";
+
+   resets = < GMAC_CORE4_RESET>;
+   reset-names = "stmmaceth";
+
+   status = "disabled";
+   };
+
vsdcc_fixed: vsdcc-regulator {
compatible = "regulator-fixed";
regulator-name = "SDCC Power";
-- 
2.20.1



[PATCH 0/3] Add initial support for MikroTik RB3011

2020-05-18 Thread Jonathan McDowell
This patches do some prep (device tree vendor addition, missing ethernet
definitions for IPQ8064 dts) and then add an initial device tree for the
MikroTik RB3011 1U router, which is an IPQ8064 device with 1G RAM. They
are sufficient to boot with an initrd, the serial console and the first
5 switch ports fully functional (the second bank of 5 require some extra
patches to the QCA8K driver which will follow later). The bootloader NOR
is also supported, but the 128MB NAND is not yet enabled.

Jonathan McDowell (3):
  dt-bindings: vendor-prefixes: Add MikroTik
  ARM: dts: qcom: add ethernet definitions to ipq8064
  ARM: dts: qcom: Add MikroTik RB3011

 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 arch/arm/boot/dts/Makefile|   1 +
 arch/arm/boot/dts/qcom-ipq8064-rb3011.dts | 308 ++
 arch/arm/boot/dts/qcom-ipq8064.dtsi   | 108 ++
 4 files changed, 419 insertions(+)
 create mode 100644 arch/arm/boot/dts/qcom-ipq8064-rb3011.dts

-- 
2.20.1



[PATCH 3/3] ARM: dts: qcom: Add MikroTik RB3011

2020-05-18 Thread Jonathan McDowell
This patch adds a DTS file for the MikroTik RouterBoard 3011, which is a
1U rackmount router based on the IPQ8064, supporting the serial UART,
dual QCA8337 Gigabit ethernet switches, boot loader NOR and user LED
device.

Signed-off-by: Jonathan McDowell 
---
 arch/arm/boot/dts/Makefile|   1 +
 arch/arm/boot/dts/qcom-ipq8064-rb3011.dts | 308 ++
 2 files changed, 309 insertions(+)
 create mode 100644 arch/arm/boot/dts/qcom-ipq8064-rb3011.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index e8dd99201397..e697a4bd7426 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -884,6 +884,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
qcom-ipq4019-ap.dk07.1-c1.dtb \
qcom-ipq4019-ap.dk07.1-c2.dtb \
qcom-ipq8064-ap148.dtb \
+   qcom-ipq8064-rb3011.dtb \
qcom-msm8660-surf.dtb \
qcom-msm8960-cdp.dtb \
qcom-msm8974-fairphone-fp2.dtb \
diff --git a/arch/arm/boot/dts/qcom-ipq8064-rb3011.dts 
b/arch/arm/boot/dts/qcom-ipq8064-rb3011.dts
new file mode 100644
index ..282b89ce3d45
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-ipq8064-rb3011.dts
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "qcom-ipq8064.dtsi"
+#include 
+
+/ {
+   model = "MikroTik RB3011UiAS-RM";
+   compatible = "mikrotik,rb3011";
+
+   aliases {
+   serial0 = _serial;
+   ethernet0 = 
+   ethernet1 = 
+   mdio-gpio0 = 
+   mdio-gpio1 = 
+   };
+
+   chosen {
+   bootargs = "loglevel=8 console=ttyMSM0,115200";
+   stdout-path = "serial0:115200n8";
+   };
+
+   memory@0 {
+   reg = <0x4200 0x3e00>;
+   device_type = "memory";
+   };
+
+   mdio0: mdio@0 {
+   status = "okay";
+   compatible = "virtual,mdio-gpio";
+   gpios = <_pinmux 1 GPIO_ACTIVE_HIGH>,
+   <_pinmux 0 GPIO_ACTIVE_HIGH>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   pinctrl-0 = <_pins>;
+   pinctrl-names = "default";
+
+   switch0: switch@10 {
+   compatible = "qca,qca8337";
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   dsa,member = <0 0>;
+
+   pinctrl-0 = <_reset_pin>;
+   pinctrl-names = "default";
+
+   reset-gpios = <_pinmux 16 GPIO_ACTIVE_LOW>;
+   reg = <0x10>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   switch0cpu: port@0 {
+   reg = <0>;
+   label = "cpu";
+   ethernet = <>;
+   phy-mode = "rgmii-id";
+   fixed-link {
+   speed = <1000>;
+   full-duplex;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+   label = "sw1";
+   };
+
+   port@2 {
+   reg = <2>;
+   label = "sw2";
+   };
+
+   port@3 {
+   reg = <3>;
+   label = "sw3";
+   };
+
+   port@4 {
+   reg = <4>;
+   label = "sw4";
+   };
+
+   port@5 {
+   reg = <5>;
+   label = "sw5";
+   };
+   };
+   };
+   };
+
+   mdio1: mdio@1 {
+   status = "okay";
+   compatible = "virtual,mdio-gpio";
+   gpios = <_pinmux 11 GPIO_ACTIVE_HIGH>,
+   <_pinmux 10 GPIO_ACTIVE_HIGH>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   pinctrl-0 = <_pins>;
+   pinctrl-names = "def

[PATCHv2] ARM: dts: sun8i-h3: Add dts for the Mapleboard MP130

2018-10-30 Thread Jonathan McDowell
The Mapleboard MP130 is a single board computer based on the Allwinner
H3 SoC, with all schematics freely available. The Lite version includes
1GB main memory and 8GB eMMC.

https://www.mapleboard.org/en (still mostly in Chinese even when English
is selected)

This DTS is based upon the DTS shipped with the board which uses
mapleboard,mp130- prefixes instead of the allwinner,sun8i variants.

v2: Fold in review comments from Maxime Ripard

Signed-off-by: Jonathan McDowell 
---
 arch/arm/boot/dts/Makefile|   1 +
 .../boot/dts/sun8i-h3-mapleboard-mp130.dts| 174 ++
 2 files changed, 175 insertions(+)
 create mode 100644 arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b5bd3de87c33..dcf1b9e7f71e 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1035,6 +1035,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
sun8i-h3-bananapi-m2-plus.dtb \
sun8i-h3-beelink-x2.dtb \
sun8i-h3-libretech-all-h3-cc.dtb \
+   sun8i-h3-mapleboard-mp130.dtb \
sun8i-h3-nanopi-m1.dtb  \
sun8i-h3-nanopi-m1-plus.dtb \
sun8i-h3-nanopi-neo.dtb \
diff --git a/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts 
b/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts
new file mode 100644
index ..13ad55be4454
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 Centrum Embedded Systems, Jia-Bin Huang 
+ * Copyright (C) 2018 Jonathan McDowell 
+ */
+
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include 
+#include 
+
+/ {
+   model = "MapleBoard MP130";
+   compatible = "mapleboard,mp130", "allwinner,sun8i-h3";
+
+   aliases {
+   ethernet0 = 
+   serial0 = 
+   };
+
+   chosen {
+   stdout-path = "serial0:115200n8";
+   };
+
+   leds {
+   compatible = "gpio-leds";
+   pinctrl-names = "default";
+
+   pwr_led {
+   label = "mp130:orange:pwr";
+   gpios = <_pio 0 10 GPIO_ACTIVE_HIGH>;
+   default-state = "on";
+   };
+
+   status_led {
+   label = "mp130:orange:status";
+   gpios = < 0 10 GPIO_ACTIVE_HIGH>;
+   };
+   };
+
+   r_gpio_keys {
+   compatible = "gpio-keys";
+   pinctrl-names = "default";
+
+   power {
+   label = "mp130:power";
+   linux,code = ;
+   gpios = <_pio 0 3 GPIO_ACTIVE_LOW>; /* PL3 */
+   };
+
+   user {
+   label = "mp130:user";
+   linux,code = ;
+   gpios = <_pio 0 4 GPIO_ACTIVE_LOW>;
+   };
+   };
+};
+
+ {
+   allwinner,audio-routing =
+   "Line Out", "LINEOUT",
+   "LINEIN", "Line In";
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   phy-handle = <_mii_phy>;
+   phy-mode = "mii";
+   allwinner,leds-active-low;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   cd-gpios = < 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
+   cd-inverted;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_8bit_pins>;
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <8>;
+   non-removable;
+   cap-mmc-hw-reset;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   leds_pio: led_pins {
+   pins = "PA15";
+   function = "gpio_out";
+   };
+};
+
+_pio {
+   leds_r_pio: led_pins {
+   pins = "PL10";
+   function = "gpio_out";
+   };
+
+   sw_r_pio: key_pins {
+   pins = "PL3", "PL4";
+   function = "gpio_in";
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+_otg {
+   dr_mode = "peripheral";
+   status = "okay";
+};
+
+ {
+   /* USB VBUS is always on */
+   status = "okay";
+};
-- 
2.19.1



[PATCHv2] ARM: dts: sun8i-h3: Add dts for the Mapleboard MP130

2018-10-30 Thread Jonathan McDowell
The Mapleboard MP130 is a single board computer based on the Allwinner
H3 SoC, with all schematics freely available. The Lite version includes
1GB main memory and 8GB eMMC.

https://www.mapleboard.org/en (still mostly in Chinese even when English
is selected)

This DTS is based upon the DTS shipped with the board which uses
mapleboard,mp130- prefixes instead of the allwinner,sun8i variants.

v2: Fold in review comments from Maxime Ripard

Signed-off-by: Jonathan McDowell 
---
 arch/arm/boot/dts/Makefile|   1 +
 .../boot/dts/sun8i-h3-mapleboard-mp130.dts| 174 ++
 2 files changed, 175 insertions(+)
 create mode 100644 arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b5bd3de87c33..dcf1b9e7f71e 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1035,6 +1035,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
sun8i-h3-bananapi-m2-plus.dtb \
sun8i-h3-beelink-x2.dtb \
sun8i-h3-libretech-all-h3-cc.dtb \
+   sun8i-h3-mapleboard-mp130.dtb \
sun8i-h3-nanopi-m1.dtb  \
sun8i-h3-nanopi-m1-plus.dtb \
sun8i-h3-nanopi-neo.dtb \
diff --git a/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts 
b/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts
new file mode 100644
index ..13ad55be4454
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 Centrum Embedded Systems, Jia-Bin Huang 
+ * Copyright (C) 2018 Jonathan McDowell 
+ */
+
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include 
+#include 
+
+/ {
+   model = "MapleBoard MP130";
+   compatible = "mapleboard,mp130", "allwinner,sun8i-h3";
+
+   aliases {
+   ethernet0 = 
+   serial0 = 
+   };
+
+   chosen {
+   stdout-path = "serial0:115200n8";
+   };
+
+   leds {
+   compatible = "gpio-leds";
+   pinctrl-names = "default";
+
+   pwr_led {
+   label = "mp130:orange:pwr";
+   gpios = <_pio 0 10 GPIO_ACTIVE_HIGH>;
+   default-state = "on";
+   };
+
+   status_led {
+   label = "mp130:orange:status";
+   gpios = < 0 10 GPIO_ACTIVE_HIGH>;
+   };
+   };
+
+   r_gpio_keys {
+   compatible = "gpio-keys";
+   pinctrl-names = "default";
+
+   power {
+   label = "mp130:power";
+   linux,code = ;
+   gpios = <_pio 0 3 GPIO_ACTIVE_LOW>; /* PL3 */
+   };
+
+   user {
+   label = "mp130:user";
+   linux,code = ;
+   gpios = <_pio 0 4 GPIO_ACTIVE_LOW>;
+   };
+   };
+};
+
+ {
+   allwinner,audio-routing =
+   "Line Out", "LINEOUT",
+   "LINEIN", "Line In";
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   phy-handle = <_mii_phy>;
+   phy-mode = "mii";
+   allwinner,leds-active-low;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   cd-gpios = < 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
+   cd-inverted;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_8bit_pins>;
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <8>;
+   non-removable;
+   cap-mmc-hw-reset;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   leds_pio: led_pins {
+   pins = "PA15";
+   function = "gpio_out";
+   };
+};
+
+_pio {
+   leds_r_pio: led_pins {
+   pins = "PL10";
+   function = "gpio_out";
+   };
+
+   sw_r_pio: key_pins {
+   pins = "PL3", "PL4";
+   function = "gpio_in";
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+_otg {
+   dr_mode = "peripheral";
+   status = "okay";
+};
+
+ {
+   /* USB VBUS is always on */
+   status = "okay";
+};
-- 
2.19.1



Re: [PATCH] dts: sun8i-h3: Add DTS for Mapleboard MP130

2018-10-30 Thread Jonathan McDowell
On Mon, Oct 29, 2018 at 04:20:52PM +0100, Maxime Ripard wrote:
> Thanks for your patch.

Thanks for the comments.

> On Thu, Oct 25, 2018 at 08:55:19PM +0100, Jonathan McDowell wrote:
...
> The prefix of your patch should be "ARM: dts: sun8i-h3: ..."

Ok.

> > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > index b5bd3de87c33..dcf1b9e7f71e 100644
> > --- a/arch/arm/boot/dts/Makefile
> > +++ b/arch/arm/boot/dts/Makefile
> > @@ -1035,6 +1035,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
> > sun8i-h3-bananapi-m2-plus.dtb \
> > sun8i-h3-beelink-x2.dtb \
> > sun8i-h3-libretech-all-h3-cc.dtb \
> > +   sun8i-h3-mapleboard-mp130.dtb \
> > sun8i-h3-nanopi-m1.dtb  \
> > sun8i-h3-nanopi-m1-plus.dtb \
> > sun8i-h3-nanopi-neo.dtb \
> > diff --git a/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts 
> > b/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts
> > new file mode 100644
> > index ..bf948128af94
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts
> > @@ -0,0 +1,179 @@
> > +/*
> > + * Copyright (C) 2017 Centrum Embedded Systems, Jia-Bin Huang 
> > 
> > + * Copyright (C) 2018 Jonathan McDowell 
> > + *
> > + * This file is licensed under the terms of the GNU General Public
> > + * License version 2. This program is licensed "as is" without any
> > + * warranty of any kind, whether express or implied.
> 
> You should add a SPDX tag instead of the license.

Done.

> We're also trying to license the DT under a dual GPL/MIT license,
> since they can be used by projects under a license that is not the
> GPL. But that's your call, obviously.

I'm building on top of Jia-Bin Huang's work, which was GPL only, so I'll
stick with that for the moment.

> > + */
> > +
> > +/dts-v1/;
> > +#include "sun8i-h3.dtsi"
> > +#include "sunxi-common-regulators.dtsi"
> > +
> > +#include 
> > +#include 
> > +
> > +/ {
> > +   model = "MapleBoard MP130 Board";
> > +   compatible = "mapleboard,mp130_board", "allwinner,sun8i-h3";
> 
> The "board" in both the model and compatible is redundant.

Ok.

> > +
> > +   aliases {
> > +   ethernet0 = 
> > +   serial0 = 
> > +   };
> > +
> > +   chosen {
> > +   stdout-path = "serial0:115200n8";
> > +   };
> > +
> > +   leds {
> > +   compatible = "gpio-leds";
> > +   pinctrl-names = "default";
> > +   pinctrl-0 = <_pio>, <_r_pio>;
> 
> You can drop those pinctrl nodes

Done.

> > +   pwr_led {
> > +   label = "mp130_board:orange:pwr";
> > +   gpios = <_pio 0 10 GPIO_ACTIVE_HIGH>;
> > +   default-state = "on";
> > +   };
> 
> A new line here would be nice

Ok.

> > +   status_led {
> > +   label = "mp130_board:orange:status";
> > +   gpios = < 0 10 GPIO_ACTIVE_HIGH>;
> > +   };
> > +   };
> > +
> > +   r_gpio_keys {
> > +   compatible = "gpio-keys";
> > +   pinctrl-names = "default";
> > +   pinctrl-0 = <_r_pio>;
> 
> Samething the pinctrl reference can be dropped

Ok.

> > +   power {
> > +   label = "power";
> > +   linux,code = ;
> > +   gpios = <_pio 0 3 GPIO_ACTIVE_LOW>; /* PL3 */
> > +   };
> > +
> > +   user {
> > +   label = "user";
> > +   linux,code = ;
> > +   gpios = <_pio 0 4 GPIO_ACTIVE_LOW>;
> > +   };
> 
> The labels should be under the form "board:color:function"

These are GPIO buttons, not LEDs, so I think you mean "board:function".
Will change.

> > +   };
> > +};
> > +
> > + {
> > +   allwinner,audio-routing =
> > +   "Line Out", "LINEOUT",
> > +   "LINEIN", "Line In";
> > +   status = "okay";
> > +};
> > +
> > + {
> > +   status = "okay";
> > +};
> > +
> > + {
> > +   status = "okay";
> > +};
> > +
> > + {
> > +   status = "okay";
> > +};
> > +
> > + {
> > +   pinctrl-na

Re: [PATCH] dts: sun8i-h3: Add DTS for Mapleboard MP130

2018-10-30 Thread Jonathan McDowell
On Mon, Oct 29, 2018 at 04:20:52PM +0100, Maxime Ripard wrote:
> Thanks for your patch.

Thanks for the comments.

> On Thu, Oct 25, 2018 at 08:55:19PM +0100, Jonathan McDowell wrote:
...
> The prefix of your patch should be "ARM: dts: sun8i-h3: ..."

Ok.

> > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > index b5bd3de87c33..dcf1b9e7f71e 100644
> > --- a/arch/arm/boot/dts/Makefile
> > +++ b/arch/arm/boot/dts/Makefile
> > @@ -1035,6 +1035,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
> > sun8i-h3-bananapi-m2-plus.dtb \
> > sun8i-h3-beelink-x2.dtb \
> > sun8i-h3-libretech-all-h3-cc.dtb \
> > +   sun8i-h3-mapleboard-mp130.dtb \
> > sun8i-h3-nanopi-m1.dtb  \
> > sun8i-h3-nanopi-m1-plus.dtb \
> > sun8i-h3-nanopi-neo.dtb \
> > diff --git a/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts 
> > b/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts
> > new file mode 100644
> > index ..bf948128af94
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts
> > @@ -0,0 +1,179 @@
> > +/*
> > + * Copyright (C) 2017 Centrum Embedded Systems, Jia-Bin Huang 
> > 
> > + * Copyright (C) 2018 Jonathan McDowell 
> > + *
> > + * This file is licensed under the terms of the GNU General Public
> > + * License version 2. This program is licensed "as is" without any
> > + * warranty of any kind, whether express or implied.
> 
> You should add a SPDX tag instead of the license.

Done.

> We're also trying to license the DT under a dual GPL/MIT license,
> since they can be used by projects under a license that is not the
> GPL. But that's your call, obviously.

I'm building on top of Jia-Bin Huang's work, which was GPL only, so I'll
stick with that for the moment.

> > + */
> > +
> > +/dts-v1/;
> > +#include "sun8i-h3.dtsi"
> > +#include "sunxi-common-regulators.dtsi"
> > +
> > +#include 
> > +#include 
> > +
> > +/ {
> > +   model = "MapleBoard MP130 Board";
> > +   compatible = "mapleboard,mp130_board", "allwinner,sun8i-h3";
> 
> The "board" in both the model and compatible is redundant.

Ok.

> > +
> > +   aliases {
> > +   ethernet0 = 
> > +   serial0 = 
> > +   };
> > +
> > +   chosen {
> > +   stdout-path = "serial0:115200n8";
> > +   };
> > +
> > +   leds {
> > +   compatible = "gpio-leds";
> > +   pinctrl-names = "default";
> > +   pinctrl-0 = <_pio>, <_r_pio>;
> 
> You can drop those pinctrl nodes

Done.

> > +   pwr_led {
> > +   label = "mp130_board:orange:pwr";
> > +   gpios = <_pio 0 10 GPIO_ACTIVE_HIGH>;
> > +   default-state = "on";
> > +   };
> 
> A new line here would be nice

Ok.

> > +   status_led {
> > +   label = "mp130_board:orange:status";
> > +   gpios = < 0 10 GPIO_ACTIVE_HIGH>;
> > +   };
> > +   };
> > +
> > +   r_gpio_keys {
> > +   compatible = "gpio-keys";
> > +   pinctrl-names = "default";
> > +   pinctrl-0 = <_r_pio>;
> 
> Samething the pinctrl reference can be dropped

Ok.

> > +   power {
> > +   label = "power";
> > +   linux,code = ;
> > +   gpios = <_pio 0 3 GPIO_ACTIVE_LOW>; /* PL3 */
> > +   };
> > +
> > +   user {
> > +   label = "user";
> > +   linux,code = ;
> > +   gpios = <_pio 0 4 GPIO_ACTIVE_LOW>;
> > +   };
> 
> The labels should be under the form "board:color:function"

These are GPIO buttons, not LEDs, so I think you mean "board:function".
Will change.

> > +   };
> > +};
> > +
> > + {
> > +   allwinner,audio-routing =
> > +   "Line Out", "LINEOUT",
> > +   "LINEIN", "Line In";
> > +   status = "okay";
> > +};
> > +
> > + {
> > +   status = "okay";
> > +};
> > +
> > + {
> > +   status = "okay";
> > +};
> > +
> > + {
> > +   status = "okay";
> > +};
> > +
> > + {
> > +   pinctrl-na

[PATCH] dts: sun8i-h3: Add DTS for Mapleboard MP130

2018-10-25 Thread Jonathan McDowell


The Mapleboard MP130 is a single board computer based on the Allwinner
H3 SoC, with all schematics freely available. The Lite version includes
1GB main memory and 8GB eMMC.

https://www.mapleboard.org/en (still mostly in Chinese even when English
is selected)

This DTS is based upon the DTS shipped with the board which uses
mapleboard,mp130- prefixes instead of the allwinner,sun8i variants.

Signed-off-by: Jonathan McDowell 

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b5bd3de87c33..dcf1b9e7f71e 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1035,6 +1035,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
sun8i-h3-bananapi-m2-plus.dtb \
sun8i-h3-beelink-x2.dtb \
sun8i-h3-libretech-all-h3-cc.dtb \
+   sun8i-h3-mapleboard-mp130.dtb \
sun8i-h3-nanopi-m1.dtb  \
sun8i-h3-nanopi-m1-plus.dtb \
sun8i-h3-nanopi-neo.dtb \
diff --git a/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts 
b/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts
new file mode 100644
index ..bf948128af94
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2017 Centrum Embedded Systems, Jia-Bin Huang 
+ * Copyright (C) 2018 Jonathan McDowell 
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include 
+#include 
+
+/ {
+   model = "MapleBoard MP130 Board";
+   compatible = "mapleboard,mp130_board", "allwinner,sun8i-h3";
+
+   aliases {
+   ethernet0 = 
+   serial0 = 
+   };
+
+   chosen {
+   stdout-path = "serial0:115200n8";
+   };
+
+   leds {
+   compatible = "gpio-leds";
+   pinctrl-names = "default";
+   pinctrl-0 = <_pio>, <_r_pio>;
+
+   pwr_led {
+   label = "mp130_board:orange:pwr";
+   gpios = <_pio 0 10 GPIO_ACTIVE_HIGH>;
+   default-state = "on";
+   };
+   status_led {
+   label = "mp130_board:orange:status";
+   gpios = < 0 10 GPIO_ACTIVE_HIGH>;
+   };
+   };
+
+   r_gpio_keys {
+   compatible = "gpio-keys";
+   pinctrl-names = "default";
+   pinctrl-0 = <_r_pio>;
+
+   power {
+   label = "power";
+   linux,code = ;
+   gpios = <_pio 0 3 GPIO_ACTIVE_LOW>; /* PL3 */
+   };
+
+   user {
+   label = "user";
+   linux,code = ;
+   gpios = <_pio 0 4 GPIO_ACTIVE_LOW>;
+   };
+   };
+};
+
+ {
+   allwinner,audio-routing =
+   "Line Out", "LINEOUT",
+   "LINEIN", "Line In";
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   cd-gpios = < 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
+   cd-inverted;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_8bit_pins>;
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <8>;
+   non-removable;
+   cap-mmc-hw-reset;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   leds_pio: led_pins {
+   pins = "PA15";
+   function = "gpio_out";
+   };
+};
+
+_pio {
+   leds_r_pio: led_pins {
+   pins = "PL10";
+   function = "gpio_out";
+   };
+
+   sw_r_pio: key_pins {
+   pins = "PL3", "PL4";
+   function = "gpio_in";
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+_otg {
+   dr_mode = "peripheral";
+   status = "okay";
+};
+
+ {
+   /* USB VBUS is always on */
+   status = "okay";
+};
+
+ {
+   phy-handle = <_mii_phy>;
+   phy-mode = "mii";
+   allwinner,leds-active-low;
+   status = "okay";
+};
+

J.

-- 
Revd Jonathan McDowell, ULC | Do you believe in happy endings?


[PATCH] dts: sun8i-h3: Add DTS for Mapleboard MP130

2018-10-25 Thread Jonathan McDowell


The Mapleboard MP130 is a single board computer based on the Allwinner
H3 SoC, with all schematics freely available. The Lite version includes
1GB main memory and 8GB eMMC.

https://www.mapleboard.org/en (still mostly in Chinese even when English
is selected)

This DTS is based upon the DTS shipped with the board which uses
mapleboard,mp130- prefixes instead of the allwinner,sun8i variants.

Signed-off-by: Jonathan McDowell 

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b5bd3de87c33..dcf1b9e7f71e 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1035,6 +1035,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
sun8i-h3-bananapi-m2-plus.dtb \
sun8i-h3-beelink-x2.dtb \
sun8i-h3-libretech-all-h3-cc.dtb \
+   sun8i-h3-mapleboard-mp130.dtb \
sun8i-h3-nanopi-m1.dtb  \
sun8i-h3-nanopi-m1-plus.dtb \
sun8i-h3-nanopi-neo.dtb \
diff --git a/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts 
b/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts
new file mode 100644
index ..bf948128af94
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-h3-mapleboard-mp130.dts
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2017 Centrum Embedded Systems, Jia-Bin Huang 
+ * Copyright (C) 2018 Jonathan McDowell 
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "sun8i-h3.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include 
+#include 
+
+/ {
+   model = "MapleBoard MP130 Board";
+   compatible = "mapleboard,mp130_board", "allwinner,sun8i-h3";
+
+   aliases {
+   ethernet0 = 
+   serial0 = 
+   };
+
+   chosen {
+   stdout-path = "serial0:115200n8";
+   };
+
+   leds {
+   compatible = "gpio-leds";
+   pinctrl-names = "default";
+   pinctrl-0 = <_pio>, <_r_pio>;
+
+   pwr_led {
+   label = "mp130_board:orange:pwr";
+   gpios = <_pio 0 10 GPIO_ACTIVE_HIGH>;
+   default-state = "on";
+   };
+   status_led {
+   label = "mp130_board:orange:status";
+   gpios = < 0 10 GPIO_ACTIVE_HIGH>;
+   };
+   };
+
+   r_gpio_keys {
+   compatible = "gpio-keys";
+   pinctrl-names = "default";
+   pinctrl-0 = <_r_pio>;
+
+   power {
+   label = "power";
+   linux,code = ;
+   gpios = <_pio 0 3 GPIO_ACTIVE_LOW>; /* PL3 */
+   };
+
+   user {
+   label = "user";
+   linux,code = ;
+   gpios = <_pio 0 4 GPIO_ACTIVE_LOW>;
+   };
+   };
+};
+
+ {
+   allwinner,audio-routing =
+   "Line Out", "LINEOUT",
+   "LINEIN", "Line In";
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <4>;
+   cd-gpios = < 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */
+   cd-inverted;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_8bit_pins>;
+   vmmc-supply = <_vcc3v3>;
+   bus-width = <8>;
+   non-removable;
+   cap-mmc-hw-reset;
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   status = "okay";
+};
+
+ {
+   leds_pio: led_pins {
+   pins = "PA15";
+   function = "gpio_out";
+   };
+};
+
+_pio {
+   leds_r_pio: led_pins {
+   pins = "PL10";
+   function = "gpio_out";
+   };
+
+   sw_r_pio: key_pins {
+   pins = "PL3", "PL4";
+   function = "gpio_in";
+   };
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   status = "disabled";
+};
+
+_otg {
+   dr_mode = "peripheral";
+   status = "okay";
+};
+
+ {
+   /* USB VBUS is always on */
+   status = "okay";
+};
+
+ {
+   phy-handle = <_mii_phy>;
+   phy-mode = "mii";
+   allwinner,leds-active-low;
+   status = "okay";
+};
+

J.

-- 
Revd Jonathan McDowell, ULC | Do you believe in happy endings?


Re: [PATCH] ACPI / WMI: Call acpi_wmi_init() later

2018-01-06 Thread Jonathan McDowell
On Sat, Jan 06, 2018 at 12:30:23AM +0100, Rafael J. Wysocki wrote:
> On Wed, Jan 3, 2018 at 12:49 PM, Rafael J. Wysocki <r...@rjwysocki.net> wrote:
> > From: Rafael J. Wysocki <rafael.j.wyso...@intel.com>
> >
> > Calling acpi_wmi_init() at the subsys_initcall() level causes ordering
> > issues to appear on some systems and they are difficult to reproduce,
> > because there is no guaranteed ordering between subsys_initcall()
> > calls, so they may occur in different orders on different systems.
> >
> > In particular, commit 86d9f48534e8 (mm/slab: fix kmemcg cache
> > creation delayed issue) exposed one of these issues where genl_init()
> > and acpi_wmi_init() are both called at the same initcall level, but
> > the former must run before the latter so as to avoid a NULL pointer
> > dereference.
> >
> > For this reason, move the acpi_wmi_init() invocation to the
> > initcall_sync level which should still be early enough for things
> > to work correctly in the WMI land.
> >
> > Link: https://marc.info/?t=15127459672=1=2
> > Reported-by: Jonathan McDowell <nood...@earth.li>
> > Reported-by: Joonsoo Kim <iamjoonsoo@lge.com>
> > Tested-by: Jonathan McDowell <nood...@earth.li>
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wyso...@intel.com>
> 
> Guys, this fixes a crash on boot.
> 
> If there are no concerns/objections I will just take it through the ACPI tree.

Note that I first started seeing it in v4.9 so would ideally hit the
appropriate stable trees too.

> > ---
> >  drivers/platform/x86/wmi.c |2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > Index: linux-pm/drivers/platform/x86/wmi.c
> > ===
> > --- linux-pm.orig/drivers/platform/x86/wmi.c
> > +++ linux-pm/drivers/platform/x86/wmi.c
> > @@ -1458,5 +1458,5 @@ static void __exit acpi_wmi_exit(void)
> > class_unregister(_bus_class);
> >  }
> >
> > -subsys_initcall(acpi_wmi_init);
> > +subsys_initcall_sync(acpi_wmi_init);
> >  module_exit(acpi_wmi_exit);
> >
> > --

J.

-- 
/-\ | 101 things you can't have too much
|@/  Debian GNU/Linux Developer |of : 36 - Spare video tapes.
\-  |


Re: [PATCH] ACPI / WMI: Call acpi_wmi_init() later

2018-01-06 Thread Jonathan McDowell
On Sat, Jan 06, 2018 at 12:30:23AM +0100, Rafael J. Wysocki wrote:
> On Wed, Jan 3, 2018 at 12:49 PM, Rafael J. Wysocki  wrote:
> > From: Rafael J. Wysocki 
> >
> > Calling acpi_wmi_init() at the subsys_initcall() level causes ordering
> > issues to appear on some systems and they are difficult to reproduce,
> > because there is no guaranteed ordering between subsys_initcall()
> > calls, so they may occur in different orders on different systems.
> >
> > In particular, commit 86d9f48534e8 (mm/slab: fix kmemcg cache
> > creation delayed issue) exposed one of these issues where genl_init()
> > and acpi_wmi_init() are both called at the same initcall level, but
> > the former must run before the latter so as to avoid a NULL pointer
> > dereference.
> >
> > For this reason, move the acpi_wmi_init() invocation to the
> > initcall_sync level which should still be early enough for things
> > to work correctly in the WMI land.
> >
> > Link: https://marc.info/?t=15127459672=1=2
> > Reported-by: Jonathan McDowell 
> > Reported-by: Joonsoo Kim 
> > Tested-by: Jonathan McDowell 
> > Signed-off-by: Rafael J. Wysocki 
> 
> Guys, this fixes a crash on boot.
> 
> If there are no concerns/objections I will just take it through the ACPI tree.

Note that I first started seeing it in v4.9 so would ideally hit the
appropriate stable trees too.

> > ---
> >  drivers/platform/x86/wmi.c |2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > Index: linux-pm/drivers/platform/x86/wmi.c
> > ===
> > --- linux-pm.orig/drivers/platform/x86/wmi.c
> > +++ linux-pm/drivers/platform/x86/wmi.c
> > @@ -1458,5 +1458,5 @@ static void __exit acpi_wmi_exit(void)
> > class_unregister(_bus_class);
> >  }
> >
> > -subsys_initcall(acpi_wmi_init);
> > +subsys_initcall_sync(acpi_wmi_init);
> >  module_exit(acpi_wmi_exit);
> >
> > --

J.

-- 
/-\ | 101 things you can't have too much
|@/  Debian GNU/Linux Developer |of : 36 - Spare video tapes.
\-  |


Re: ACPI issues on cold power on [bisected]

2018-01-03 Thread Jonathan McDowell
On Wed, Jan 03, 2018 at 11:11:29AM +0900, Joonsoo Kim wrote:
> On Tue, Jan 02, 2018 at 11:25:01AM +0100, Rafael J. Wysocki wrote:
> > On Tue, Jan 2, 2018 at 3:54 AM, Joonsoo Kim <iamjoonsoo@lge.com> wrote:
> > > On Fri, Dec 29, 2017 at 04:36:59PM +, Jonathan McDowell wrote:
> > >> On Fri, Dec 22, 2017 at 09:21:09AM +0900, Joonsoo Kim wrote:
> > >> > On Fri, Dec 08, 2017 at 03:11:59PM +, Jonathan McDowell wrote:
> > >> > > I've been sitting on this for a while and should have spent time to
> > >> > > investigate sooner, but it's been an odd failure mode that wasn't 
> > >> > > quite
> > >> > > obvious.
> > >> > >
> > >> > > In 4.9 if I cold power on my laptop (Dell E7240) it fails to boot - I
> > >> > > don't see anything after grub says its booting. In 4.10 onwards the
> > >> > > laptop boots, but I get an Oops as part of the boot and ACPI is 
> > >> > > unhappy
> > >> > > (no suspend, no clean poweroff, no ACPI buttons). The Oops is below;
> > >> > > taken from 4.12 as that's the most recent error dmesg I have saved 
> > >> > > but
> > >> > > also seen back in 4.10. It's always address 0x30 for the dereference.
> > >> > >
> > >> > > Rebooting the laptop does not lead to these problems; it's *only* 
> > >> > > from a
> > >> > > complete cold boot that they arise (which didn't help me in terms of
> > >> > > being able to reliably bisect). Once I realised that I was able to
> > >> > > bisect, but it leads me to an odd commit:
> > >> > >
> > >> > > 86d9f48534e800e4d62cdc1b5aaf539f4c1d47d6
> > >> > > (mm/slab: fix kmemcg cache creation delayed issue)
> > >> > >
> > >> > > If I revert this then I can cold boot without problems.
> > >> > >
> > >> > > Also I don't see the problem with a stock Debian kernel, I think 
> > >> > > because
> > >> > > the ACPI support is modularised.
> > >> >
> > >> > Sorry for late response. I was on a long vacation.
> > >>
> > >> No problem. I've been trying to get around to diagnosing this for a
> > >> while now anyway and this isn't a great time of year for fast responses.
> > >>
> > >> > I have tried to solve the problem however I don't find any clue yet.
> > >> >
> > >> > >From my analysis, oops report shows that 'struct sock *ssk' passed to
> > >> > netlink_broadcast_filtered() is NULL. It means that some of
> > >> > netlink_kernel_create() returns NULL. Maybe, it is due to slab
> > >> > allocation failure. Could you check it by inserting some log on that
> > >> > part? The issue cannot be reproducible in my side so I need your help.
> > >>
> > >> I've added some debug in acpi_bus_generate_netlink_event +
> > >> genlmsg_multicast and the problem seems to be that genlmsg_multicast is
> > >> getting called when init_net.genl_sock has not yet been initialised,
> > >> leading to the NULL deference.
> > >>
> > >> Full dmesg output from a cold 4.14.8 boot at:
> > >>
> > >> https://the.earth.li/~noodles/acpi-problem/dmesg-4.14.8-broken
> > >>
> > >> And the same kernel after a reboot ("shutdown -r now"):
> > >>
> > >> https://the.earth.li/~noodles/acpi-problem/dmesg-4.14.8-working
> > >>
> > >> Patch that I've applied is at
> > >>
> > >> https://the.earth.li/~noodles/acpi-problem/debug-acpi.diff
> > >>
> > >
> > > Thanks for testing! It's very helpful.
> > >
> > >> The interesting difference seems to be:
> > >>
> > >>  PCI: Using ACPI for IRQ routing
> > >> +ACPI: Generating event type 208 (:9DBB5994-A997-11DA-B012-B622A1EF5492)
> > >> +ERROR: init_net.genl_sock is NULL
> > >> +BUG: unable to handle kernel NULL pointer dereference at 
> > >> 0030
> > >> +IP: netlink_broadcast_filtered+0x20/0x3d0
> > >> +PGD 0 P4D 0
> > >> +Oops:  [#1] SMP
> > >> +Modules linked in:
> > >> +CPU: 0 PID: 29 Comm: kworker/0:1 Not tainted 4.14.8+ #1
> > >> +Hardware name: Dell Inc. Latitude E7240/07RPNV, BIOS A22 10/18/2017
> > >> +Workq

Re: ACPI issues on cold power on [bisected]

2018-01-03 Thread Jonathan McDowell
On Wed, Jan 03, 2018 at 11:11:29AM +0900, Joonsoo Kim wrote:
> On Tue, Jan 02, 2018 at 11:25:01AM +0100, Rafael J. Wysocki wrote:
> > On Tue, Jan 2, 2018 at 3:54 AM, Joonsoo Kim  wrote:
> > > On Fri, Dec 29, 2017 at 04:36:59PM +, Jonathan McDowell wrote:
> > >> On Fri, Dec 22, 2017 at 09:21:09AM +0900, Joonsoo Kim wrote:
> > >> > On Fri, Dec 08, 2017 at 03:11:59PM +, Jonathan McDowell wrote:
> > >> > > I've been sitting on this for a while and should have spent time to
> > >> > > investigate sooner, but it's been an odd failure mode that wasn't 
> > >> > > quite
> > >> > > obvious.
> > >> > >
> > >> > > In 4.9 if I cold power on my laptop (Dell E7240) it fails to boot - I
> > >> > > don't see anything after grub says its booting. In 4.10 onwards the
> > >> > > laptop boots, but I get an Oops as part of the boot and ACPI is 
> > >> > > unhappy
> > >> > > (no suspend, no clean poweroff, no ACPI buttons). The Oops is below;
> > >> > > taken from 4.12 as that's the most recent error dmesg I have saved 
> > >> > > but
> > >> > > also seen back in 4.10. It's always address 0x30 for the dereference.
> > >> > >
> > >> > > Rebooting the laptop does not lead to these problems; it's *only* 
> > >> > > from a
> > >> > > complete cold boot that they arise (which didn't help me in terms of
> > >> > > being able to reliably bisect). Once I realised that I was able to
> > >> > > bisect, but it leads me to an odd commit:
> > >> > >
> > >> > > 86d9f48534e800e4d62cdc1b5aaf539f4c1d47d6
> > >> > > (mm/slab: fix kmemcg cache creation delayed issue)
> > >> > >
> > >> > > If I revert this then I can cold boot without problems.
> > >> > >
> > >> > > Also I don't see the problem with a stock Debian kernel, I think 
> > >> > > because
> > >> > > the ACPI support is modularised.
> > >> >
> > >> > Sorry for late response. I was on a long vacation.
> > >>
> > >> No problem. I've been trying to get around to diagnosing this for a
> > >> while now anyway and this isn't a great time of year for fast responses.
> > >>
> > >> > I have tried to solve the problem however I don't find any clue yet.
> > >> >
> > >> > >From my analysis, oops report shows that 'struct sock *ssk' passed to
> > >> > netlink_broadcast_filtered() is NULL. It means that some of
> > >> > netlink_kernel_create() returns NULL. Maybe, it is due to slab
> > >> > allocation failure. Could you check it by inserting some log on that
> > >> > part? The issue cannot be reproducible in my side so I need your help.
> > >>
> > >> I've added some debug in acpi_bus_generate_netlink_event +
> > >> genlmsg_multicast and the problem seems to be that genlmsg_multicast is
> > >> getting called when init_net.genl_sock has not yet been initialised,
> > >> leading to the NULL deference.
> > >>
> > >> Full dmesg output from a cold 4.14.8 boot at:
> > >>
> > >> https://the.earth.li/~noodles/acpi-problem/dmesg-4.14.8-broken
> > >>
> > >> And the same kernel after a reboot ("shutdown -r now"):
> > >>
> > >> https://the.earth.li/~noodles/acpi-problem/dmesg-4.14.8-working
> > >>
> > >> Patch that I've applied is at
> > >>
> > >> https://the.earth.li/~noodles/acpi-problem/debug-acpi.diff
> > >>
> > >
> > > Thanks for testing! It's very helpful.
> > >
> > >> The interesting difference seems to be:
> > >>
> > >>  PCI: Using ACPI for IRQ routing
> > >> +ACPI: Generating event type 208 (:9DBB5994-A997-11DA-B012-B622A1EF5492)
> > >> +ERROR: init_net.genl_sock is NULL
> > >> +BUG: unable to handle kernel NULL pointer dereference at 
> > >> 0030
> > >> +IP: netlink_broadcast_filtered+0x20/0x3d0
> > >> +PGD 0 P4D 0
> > >> +Oops:  [#1] SMP
> > >> +Modules linked in:
> > >> +CPU: 0 PID: 29 Comm: kworker/0:1 Not tainted 4.14.8+ #1
> > >> +Hardware name: Dell Inc. Latitude E7240/07RPNV, BIOS A22 10/18/2017
> > >> +Workqueue: kacpi_notify ac

Re: ACPI issues on cold power on [bisected]

2017-12-29 Thread Jonathan McDowell
On Fri, Dec 22, 2017 at 09:21:09AM +0900, Joonsoo Kim wrote:
> On Fri, Dec 08, 2017 at 03:11:59PM +0000, Jonathan McDowell wrote:
> > I've been sitting on this for a while and should have spent time to
> > investigate sooner, but it's been an odd failure mode that wasn't quite
> > obvious.
> > 
> > In 4.9 if I cold power on my laptop (Dell E7240) it fails to boot - I
> > don't see anything after grub says its booting. In 4.10 onwards the
> > laptop boots, but I get an Oops as part of the boot and ACPI is unhappy
> > (no suspend, no clean poweroff, no ACPI buttons). The Oops is below;
> > taken from 4.12 as that's the most recent error dmesg I have saved but
> > also seen back in 4.10. It's always address 0x30 for the dereference.
> > 
> > Rebooting the laptop does not lead to these problems; it's *only* from a
> > complete cold boot that they arise (which didn't help me in terms of
> > being able to reliably bisect). Once I realised that I was able to
> > bisect, but it leads me to an odd commit:
> > 
> > 86d9f48534e800e4d62cdc1b5aaf539f4c1d47d6
> > (mm/slab: fix kmemcg cache creation delayed issue)
> > 
> > If I revert this then I can cold boot without problems.
> > 
> > Also I don't see the problem with a stock Debian kernel, I think because
> > the ACPI support is modularised.
> 
> Sorry for late response. I was on a long vacation.

No problem. I've been trying to get around to diagnosing this for a
while now anyway and this isn't a great time of year for fast responses.

> I have tried to solve the problem however I don't find any clue yet.
> 
> >From my analysis, oops report shows that 'struct sock *ssk' passed to
> netlink_broadcast_filtered() is NULL. It means that some of
> netlink_kernel_create() returns NULL. Maybe, it is due to slab
> allocation failure. Could you check it by inserting some log on that
> part? The issue cannot be reproducible in my side so I need your help.

I've added some debug in acpi_bus_generate_netlink_event +
genlmsg_multicast and the problem seems to be that genlmsg_multicast is
getting called when init_net.genl_sock has not yet been initialised,
leading to the NULL deference.

Full dmesg output from a cold 4.14.8 boot at:

https://the.earth.li/~noodles/acpi-problem/dmesg-4.14.8-broken

And the same kernel after a reboot ("shutdown -r now"):

https://the.earth.li/~noodles/acpi-problem/dmesg-4.14.8-working

Patch that I've applied is at

https://the.earth.li/~noodles/acpi-problem/debug-acpi.diff

The interesting difference seems to be:

 PCI: Using ACPI for IRQ routing
+ACPI: Generating event type 208 (:9DBB5994-A997-11DA-B012-B622A1EF5492)
+ERROR: init_net.genl_sock is NULL
+BUG: unable to handle kernel NULL pointer dereference at 0030
+IP: netlink_broadcast_filtered+0x20/0x3d0
+PGD 0 P4D 0 
+Oops:  [#1] SMP
+Modules linked in:
+CPU: 0 PID: 29 Comm: kworker/0:1 Not tainted 4.14.8+ #1
+Hardware name: Dell Inc. Latitude E7240/07RPNV, BIOS A22 10/18/2017
+Workqueue: kacpi_notify acpi_os_execute_deferred

9DBB5994-A997-11DA-B012-B622A1EF5492 is the Dell WMI event GUID and
there's no visible event for it on a reboot, just on a cold power on.
Some sort of ordering issues such that genl_sock is being initialised
later with the slab change?

J.

-- 
  Hail Eris. All hail Discordia.   |  .''`.  Debian GNU/Linux Developer
  Fnord?   | : :' :  Happy to accept PGP signed
   | `. `'   or encrypted mail - RSA
   |   `-key on the keyservers.


Re: ACPI issues on cold power on [bisected]

2017-12-29 Thread Jonathan McDowell
On Fri, Dec 22, 2017 at 09:21:09AM +0900, Joonsoo Kim wrote:
> On Fri, Dec 08, 2017 at 03:11:59PM +0000, Jonathan McDowell wrote:
> > I've been sitting on this for a while and should have spent time to
> > investigate sooner, but it's been an odd failure mode that wasn't quite
> > obvious.
> > 
> > In 4.9 if I cold power on my laptop (Dell E7240) it fails to boot - I
> > don't see anything after grub says its booting. In 4.10 onwards the
> > laptop boots, but I get an Oops as part of the boot and ACPI is unhappy
> > (no suspend, no clean poweroff, no ACPI buttons). The Oops is below;
> > taken from 4.12 as that's the most recent error dmesg I have saved but
> > also seen back in 4.10. It's always address 0x30 for the dereference.
> > 
> > Rebooting the laptop does not lead to these problems; it's *only* from a
> > complete cold boot that they arise (which didn't help me in terms of
> > being able to reliably bisect). Once I realised that I was able to
> > bisect, but it leads me to an odd commit:
> > 
> > 86d9f48534e800e4d62cdc1b5aaf539f4c1d47d6
> > (mm/slab: fix kmemcg cache creation delayed issue)
> > 
> > If I revert this then I can cold boot without problems.
> > 
> > Also I don't see the problem with a stock Debian kernel, I think because
> > the ACPI support is modularised.
> 
> Sorry for late response. I was on a long vacation.

No problem. I've been trying to get around to diagnosing this for a
while now anyway and this isn't a great time of year for fast responses.

> I have tried to solve the problem however I don't find any clue yet.
> 
> >From my analysis, oops report shows that 'struct sock *ssk' passed to
> netlink_broadcast_filtered() is NULL. It means that some of
> netlink_kernel_create() returns NULL. Maybe, it is due to slab
> allocation failure. Could you check it by inserting some log on that
> part? The issue cannot be reproducible in my side so I need your help.

I've added some debug in acpi_bus_generate_netlink_event +
genlmsg_multicast and the problem seems to be that genlmsg_multicast is
getting called when init_net.genl_sock has not yet been initialised,
leading to the NULL deference.

Full dmesg output from a cold 4.14.8 boot at:

https://the.earth.li/~noodles/acpi-problem/dmesg-4.14.8-broken

And the same kernel after a reboot ("shutdown -r now"):

https://the.earth.li/~noodles/acpi-problem/dmesg-4.14.8-working

Patch that I've applied is at

https://the.earth.li/~noodles/acpi-problem/debug-acpi.diff

The interesting difference seems to be:

 PCI: Using ACPI for IRQ routing
+ACPI: Generating event type 208 (:9DBB5994-A997-11DA-B012-B622A1EF5492)
+ERROR: init_net.genl_sock is NULL
+BUG: unable to handle kernel NULL pointer dereference at 0030
+IP: netlink_broadcast_filtered+0x20/0x3d0
+PGD 0 P4D 0 
+Oops:  [#1] SMP
+Modules linked in:
+CPU: 0 PID: 29 Comm: kworker/0:1 Not tainted 4.14.8+ #1
+Hardware name: Dell Inc. Latitude E7240/07RPNV, BIOS A22 10/18/2017
+Workqueue: kacpi_notify acpi_os_execute_deferred

9DBB5994-A997-11DA-B012-B622A1EF5492 is the Dell WMI event GUID and
there's no visible event for it on a reboot, just on a cold power on.
Some sort of ordering issues such that genl_sock is being initialised
later with the slab change?

J.

-- 
  Hail Eris. All hail Discordia.   |  .''`.  Debian GNU/Linux Developer
  Fnord?   | : :' :  Happy to accept PGP signed
   | `. `'   or encrypted mail - RSA
   |   `-key on the keyservers.


ACPI issues on cold power on [bisected]

2017-12-08 Thread Jonathan McDowell
I've been sitting on this for a while and should have spent time to
investigate sooner, but it's been an odd failure mode that wasn't quite
obvious.

In 4.9 if I cold power on my laptop (Dell E7240) it fails to boot - I
don't see anything after grub says its booting. In 4.10 onwards the
laptop boots, but I get an Oops as part of the boot and ACPI is unhappy
(no suspend, no clean poweroff, no ACPI buttons). The Oops is below;
taken from 4.12 as that's the most recent error dmesg I have saved but
also seen back in 4.10. It's always address 0x30 for the dereference.

Rebooting the laptop does not lead to these problems; it's *only* from a
complete cold boot that they arise (which didn't help me in terms of
being able to reliably bisect). Once I realised that I was able to
bisect, but it leads me to an odd commit:

86d9f48534e800e4d62cdc1b5aaf539f4c1d47d6
(mm/slab: fix kmemcg cache creation delayed issue)

If I revert this then I can cold boot without problems.

Also I don't see the problem with a stock Debian kernel, I think because
the ACPI support is modularised.

Config, dmesg + bisect log at:

https://the.earth.li/~noodles/acpi-problem/

---
BUG: unable to handle kernel NULL pointer dereference at 0030
IP: netlink_broadcast_filtered+0x1d/0x3e0
PGD 0 
P4D 0 

Oops:  [#1] SMP
Modules linked in:
CPU: 0 PID: 41 Comm: kworker/0:1 Not tainted 4.12.0 #1
Hardware name: Dell Inc. Latitude E7240/07RPNV, BIOS A21 05/08/2017
Workqueue: kacpi_notify acpi_os_execute_deferred
task: 914e4c321240 task.stack: a3bd4017c000
RIP: 0010:netlink_broadcast_filtered+0x1d/0x3e0
RSP: :a3bd4017fd90 EFLAGS: 00010286
RAX: 0001 RBX: 914e4c82b300 RCX: 
RDX:  RSI: 01080020 RDI: 914e4c82b300
RBP: 914e4c305614 R08: 01080020 R09: 
R10: 0014 R11: b8a31d40 R12: 
R13:  R14: 914e4c305614 R15: 
FS:  () GS:914e5ea0() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 0030 CR3: 000236c09000 CR4: 001406f0
Call Trace:
 ? __kmalloc_reserve.isra.37+0x24/0x70
 ? __nlmsg_put+0x63/0x80
 ? netlink_broadcast+0xa/0x10
 ? acpi_bus_generate_netlink_event+0x10d/0x150
 ? acpi_ev_notify_dispatch+0x37/0x4c
 ? acpi_os_execute_deferred+0xb/0x20
 ? process_one_work+0x1cf/0x3c0
 ? worker_thread+0x42/0x3c0
 ? __schedule+0x26c/0x660
 ? kthread+0xf7/0x130
 ? create_worker+0x190/0x190
 ? kthread_create_on_node+0x40/0x40
 ? ret_from_fork+0x22/0x30
Code: c8 c3 66 90 66 2e 0f 1f 84 00 00 00 00 00 41 57 41 89 cf 41 56 41 55 49 
89 fd 48 89 f7 44 89 c6 41 54 41 89 d4 55 53 48 83 ec 38 <49> 8b 6d 30 44 89 44 
24 24 4c 89 4c 24 28 e8 a0 ec ff ff 48 c7 
RIP: netlink_broadcast_filtered+0x1d/0x3e0 RSP: a3bd4017fd90
CR2: 0030
---[ end trace f8e25281792d4743 ]---

J.

-- 
/-\ | 101 things you can't have too much
|@/  Debian GNU/Linux Developer |   of : 47 - More coffee.
\-  |


ACPI issues on cold power on [bisected]

2017-12-08 Thread Jonathan McDowell
I've been sitting on this for a while and should have spent time to
investigate sooner, but it's been an odd failure mode that wasn't quite
obvious.

In 4.9 if I cold power on my laptop (Dell E7240) it fails to boot - I
don't see anything after grub says its booting. In 4.10 onwards the
laptop boots, but I get an Oops as part of the boot and ACPI is unhappy
(no suspend, no clean poweroff, no ACPI buttons). The Oops is below;
taken from 4.12 as that's the most recent error dmesg I have saved but
also seen back in 4.10. It's always address 0x30 for the dereference.

Rebooting the laptop does not lead to these problems; it's *only* from a
complete cold boot that they arise (which didn't help me in terms of
being able to reliably bisect). Once I realised that I was able to
bisect, but it leads me to an odd commit:

86d9f48534e800e4d62cdc1b5aaf539f4c1d47d6
(mm/slab: fix kmemcg cache creation delayed issue)

If I revert this then I can cold boot without problems.

Also I don't see the problem with a stock Debian kernel, I think because
the ACPI support is modularised.

Config, dmesg + bisect log at:

https://the.earth.li/~noodles/acpi-problem/

---
BUG: unable to handle kernel NULL pointer dereference at 0030
IP: netlink_broadcast_filtered+0x1d/0x3e0
PGD 0 
P4D 0 

Oops:  [#1] SMP
Modules linked in:
CPU: 0 PID: 41 Comm: kworker/0:1 Not tainted 4.12.0 #1
Hardware name: Dell Inc. Latitude E7240/07RPNV, BIOS A21 05/08/2017
Workqueue: kacpi_notify acpi_os_execute_deferred
task: 914e4c321240 task.stack: a3bd4017c000
RIP: 0010:netlink_broadcast_filtered+0x1d/0x3e0
RSP: :a3bd4017fd90 EFLAGS: 00010286
RAX: 0001 RBX: 914e4c82b300 RCX: 
RDX:  RSI: 01080020 RDI: 914e4c82b300
RBP: 914e4c305614 R08: 01080020 R09: 
R10: 0014 R11: b8a31d40 R12: 
R13:  R14: 914e4c305614 R15: 
FS:  () GS:914e5ea0() knlGS:
CS:  0010 DS:  ES:  CR0: 80050033
CR2: 0030 CR3: 000236c09000 CR4: 001406f0
Call Trace:
 ? __kmalloc_reserve.isra.37+0x24/0x70
 ? __nlmsg_put+0x63/0x80
 ? netlink_broadcast+0xa/0x10
 ? acpi_bus_generate_netlink_event+0x10d/0x150
 ? acpi_ev_notify_dispatch+0x37/0x4c
 ? acpi_os_execute_deferred+0xb/0x20
 ? process_one_work+0x1cf/0x3c0
 ? worker_thread+0x42/0x3c0
 ? __schedule+0x26c/0x660
 ? kthread+0xf7/0x130
 ? create_worker+0x190/0x190
 ? kthread_create_on_node+0x40/0x40
 ? ret_from_fork+0x22/0x30
Code: c8 c3 66 90 66 2e 0f 1f 84 00 00 00 00 00 41 57 41 89 cf 41 56 41 55 49 
89 fd 48 89 f7 44 89 c6 41 54 41 89 d4 55 53 48 83 ec 38 <49> 8b 6d 30 44 89 44 
24 24 4c 89 4c 24 28 e8 a0 ec ff ff 48 c7 
RIP: netlink_broadcast_filtered+0x1d/0x3e0 RSP: a3bd4017fd90
CR2: 0030
---[ end trace f8e25281792d4743 ]---

J.

-- 
/-\ | 101 things you can't have too much
|@/  Debian GNU/Linux Developer |   of : 47 - More coffee.
\-  |


Re: [PATCH 2/5] x86/cpuid: Add generic table for cpuid dependencies

2017-06-22 Thread Jonathan McDowell
In article <20170621234106.16548-3-a...@firstfloor.org> you wrote:

> Some CPUID features depend on other features. Currently it's
> possible to to clear dependent features, but not clear the base features,
> which can cause various interesting problems.

> This patch implements a generic table to describe dependencies
> between CPUID features, to be used by all code that clears
> CPUID.

> Some subsystems (like XSAVE) had an own implementation of this,
> but it's better to do it all in a single place for everyone.

> Then clear_cpu_cap and setup_clear_cpu_cap always look up
> this table and clear all dependencies too.

> This is intended to be a practical table: only for features
> that make sense to clear. If someone for example clears FPU,
> or other features that are essentially part of the required
> base feature set, not much is going to work. Handling
> that is right now out of scope. We're only handling
> features which can be usefully cleared.

> v2: Add EXPORT_SYMBOL for clear_cpu_id for lguest
> Signed-off-by: Andi Kleen 
> ---
>  arch/x86/include/asm/cpufeature.h  |  8 +++-
>  arch/x86/include/asm/cpufeatures.h |  5 +++
>  arch/x86/kernel/cpu/Makefile   |  1 +
>  arch/x86/kernel/cpu/cpuid-deps.c   | 92 
> ++
>  4 files changed, 104 insertions(+), 2 deletions(-)
>  create mode 100644 arch/x86/kernel/cpu/cpuid-deps.c

> diff --git a/arch/x86/include/asm/cpufeature.h 
> b/arch/x86/include/asm/cpufeature.h
> index d59c15c3defd..e6145f383ff8 100644
> --- a/arch/x86/include/asm/cpufeature.h
> +++ b/arch/x86/include/asm/cpufeature.h
> @@ -125,8 +125,12 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
>  #define boot_cpu_has(bit)  cpu_has(_cpu_data, bit)
>  
>  #define set_cpu_cap(c, bit)set_bit(bit, (unsigned long 
> *)((c)->x86_capability))
> -#define clear_cpu_cap(c, bit)  clear_bit(bit, (unsigned long 
> *)((c)->x86_capability))
> -#define setup_clear_cpu_cap(bit) do { \
> +#define __clear_cpu_cap(c, bit)clear_bit(bit, (unsigned long 
> *)((c)->x86_capability))
> +
> +extern void setup_clear_cpu_cap(int bit);
> +extern void clear_cpu_cap(struct cpuinfo_x86 *cpu, int bit);
> +
> +#define __setup_clear_cpu_cap(bit) do { \
> clear_cpu_cap(_cpu_data, bit); \
> set_bit(bit, (unsigned long *)cpu_caps_cleared); \
>  } while (0)
> diff --git a/arch/x86/include/asm/cpufeatures.h 
> b/arch/x86/include/asm/cpufeatures.h
> index 2701e5f8145b..8f371a5966e7 100644
> --- a/arch/x86/include/asm/cpufeatures.h
> +++ b/arch/x86/include/asm/cpufeatures.h
> @@ -21,6 +21,11 @@
>   * this feature bit is not displayed in /proc/cpuinfo at all.
>   */
>  
> +/*
> + * When adding new features here that depend on other features,
> + * please update the table in kernel/cpu/cpuid-deps.c
> + */
> +
>  /* Intel-defined CPU features, CPUID level 0x0001 (edx), word 0 */
>  #define X86_FEATURE_FPU( 0*32+ 0) /* Onboard FPU */
>  #define X86_FEATURE_VME( 0*32+ 1) /* Virtual Mode Extensions 
> */
> diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
> index 5210c62e..274fc0fee1e1 100644
> --- a/arch/x86/kernel/cpu/Makefile
> +++ b/arch/x86/kernel/cpu/Makefile
> @@ -21,6 +21,7 @@ obj-y += common.o
>  obj-y  += rdrand.o
>  obj-y  += match.o
>  obj-y  += bugs.o
> +obj-y  += cpuid-deps.o
>  
>  obj-$(CONFIG_PROC_FS)  += proc.o
>  obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o
> diff --git a/arch/x86/kernel/cpu/cpuid-deps.c 
> b/arch/x86/kernel/cpu/cpuid-deps.c
> new file mode 100644
> index ..08aff02cf2ff
> --- /dev/null
> +++ b/arch/x86/kernel/cpu/cpuid-deps.c
> @@ -0,0 +1,92 @@
> +/* Declare dependencies between CPUIDs */
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +struct cpuid_dep {
> +   int feature;
> +   int dep;
> +};

This seems a little confusing; I had to read through a couple of times
to understand that "dep" represents the feature that needs to be
disabled if "feature" is disabled, rather than dep being a dependency
of feature.

> +
> +/*
> + * Table of CPUID features that depend on others.
> + *
> + * This only includes dependencies that can be usefully disabled, not
> + * features part of the base set (like FPU).
> + */
> +const static struct cpuid_dep cpuid_deps[] = {
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_XSAVEOPT },
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_XSAVEC },
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_XSAVES },
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_AVX },
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_AVX512F },
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_PKU },
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_MPX },
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_XGETBV1 },
> +   { X86_FEATURE_XMM, X86_FEATURE_XMM2 },
> +   { X86_FEATURE_XMM2,X86_FEATURE_XMM3 },
> +   { X86_FEATURE_XMM2,

Re: [PATCH 2/5] x86/cpuid: Add generic table for cpuid dependencies

2017-06-22 Thread Jonathan McDowell
In article <20170621234106.16548-3-a...@firstfloor.org> you wrote:

> Some CPUID features depend on other features. Currently it's
> possible to to clear dependent features, but not clear the base features,
> which can cause various interesting problems.

> This patch implements a generic table to describe dependencies
> between CPUID features, to be used by all code that clears
> CPUID.

> Some subsystems (like XSAVE) had an own implementation of this,
> but it's better to do it all in a single place for everyone.

> Then clear_cpu_cap and setup_clear_cpu_cap always look up
> this table and clear all dependencies too.

> This is intended to be a practical table: only for features
> that make sense to clear. If someone for example clears FPU,
> or other features that are essentially part of the required
> base feature set, not much is going to work. Handling
> that is right now out of scope. We're only handling
> features which can be usefully cleared.

> v2: Add EXPORT_SYMBOL for clear_cpu_id for lguest
> Signed-off-by: Andi Kleen 
> ---
>  arch/x86/include/asm/cpufeature.h  |  8 +++-
>  arch/x86/include/asm/cpufeatures.h |  5 +++
>  arch/x86/kernel/cpu/Makefile   |  1 +
>  arch/x86/kernel/cpu/cpuid-deps.c   | 92 
> ++
>  4 files changed, 104 insertions(+), 2 deletions(-)
>  create mode 100644 arch/x86/kernel/cpu/cpuid-deps.c

> diff --git a/arch/x86/include/asm/cpufeature.h 
> b/arch/x86/include/asm/cpufeature.h
> index d59c15c3defd..e6145f383ff8 100644
> --- a/arch/x86/include/asm/cpufeature.h
> +++ b/arch/x86/include/asm/cpufeature.h
> @@ -125,8 +125,12 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
>  #define boot_cpu_has(bit)  cpu_has(_cpu_data, bit)
>  
>  #define set_cpu_cap(c, bit)set_bit(bit, (unsigned long 
> *)((c)->x86_capability))
> -#define clear_cpu_cap(c, bit)  clear_bit(bit, (unsigned long 
> *)((c)->x86_capability))
> -#define setup_clear_cpu_cap(bit) do { \
> +#define __clear_cpu_cap(c, bit)clear_bit(bit, (unsigned long 
> *)((c)->x86_capability))
> +
> +extern void setup_clear_cpu_cap(int bit);
> +extern void clear_cpu_cap(struct cpuinfo_x86 *cpu, int bit);
> +
> +#define __setup_clear_cpu_cap(bit) do { \
> clear_cpu_cap(_cpu_data, bit); \
> set_bit(bit, (unsigned long *)cpu_caps_cleared); \
>  } while (0)
> diff --git a/arch/x86/include/asm/cpufeatures.h 
> b/arch/x86/include/asm/cpufeatures.h
> index 2701e5f8145b..8f371a5966e7 100644
> --- a/arch/x86/include/asm/cpufeatures.h
> +++ b/arch/x86/include/asm/cpufeatures.h
> @@ -21,6 +21,11 @@
>   * this feature bit is not displayed in /proc/cpuinfo at all.
>   */
>  
> +/*
> + * When adding new features here that depend on other features,
> + * please update the table in kernel/cpu/cpuid-deps.c
> + */
> +
>  /* Intel-defined CPU features, CPUID level 0x0001 (edx), word 0 */
>  #define X86_FEATURE_FPU( 0*32+ 0) /* Onboard FPU */
>  #define X86_FEATURE_VME( 0*32+ 1) /* Virtual Mode Extensions 
> */
> diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
> index 5210c62e..274fc0fee1e1 100644
> --- a/arch/x86/kernel/cpu/Makefile
> +++ b/arch/x86/kernel/cpu/Makefile
> @@ -21,6 +21,7 @@ obj-y += common.o
>  obj-y  += rdrand.o
>  obj-y  += match.o
>  obj-y  += bugs.o
> +obj-y  += cpuid-deps.o
>  
>  obj-$(CONFIG_PROC_FS)  += proc.o
>  obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o
> diff --git a/arch/x86/kernel/cpu/cpuid-deps.c 
> b/arch/x86/kernel/cpu/cpuid-deps.c
> new file mode 100644
> index ..08aff02cf2ff
> --- /dev/null
> +++ b/arch/x86/kernel/cpu/cpuid-deps.c
> @@ -0,0 +1,92 @@
> +/* Declare dependencies between CPUIDs */
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +struct cpuid_dep {
> +   int feature;
> +   int dep;
> +};

This seems a little confusing; I had to read through a couple of times
to understand that "dep" represents the feature that needs to be
disabled if "feature" is disabled, rather than dep being a dependency
of feature.

> +
> +/*
> + * Table of CPUID features that depend on others.
> + *
> + * This only includes dependencies that can be usefully disabled, not
> + * features part of the base set (like FPU).
> + */
> +const static struct cpuid_dep cpuid_deps[] = {
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_XSAVEOPT },
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_XSAVEC },
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_XSAVES },
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_AVX },
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_AVX512F },
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_PKU },
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_MPX },
> +   { X86_FEATURE_XSAVE,   X86_FEATURE_XGETBV1 },
> +   { X86_FEATURE_XMM, X86_FEATURE_XMM2 },
> +   { X86_FEATURE_XMM2,X86_FEATURE_XMM3 },
> +   { X86_FEATURE_XMM2,X86_FEATURE_XMM4_1 },
> +  

[PATCH v2] [media] dw2102: don't do DMA on stack

2017-02-15 Thread Jonathan McDowell
(Apologies, the original version of this patch had a stray, unused,
"buf_mutex" definition left over from an earlier version before I
switched to the existing data_mutex.)

I upgraded my media box today from 4.4.48 to 4.9.10 and hit WARNINGs in
the dw2102 driver for my TechnoTrend TT-connect S2-4600, one in
su3000_power_ctrl() and the other in tt_s2_4600_frontend_attach(). Both
were due to the use of buffers on the stack as parameters to
dvb_usb_generic_rw() and the resulting attempt to do DMA with them. The
device was non-functional as a result.

Patch below switches this driver over to using a buffer within the
device state structure, as has been done with other DVB-USB drivers.
Tested against 4.9.10 but applies to Linus' master cleanly.

Signed-off-by: Jonathan McDowell <nood...@earth.li>
Cc: <sta...@vger.kernel.org>

-
diff --git a/drivers/media/usb/dvb-usb/dw2102.c 
b/drivers/media/usb/dvb-usb/dw2102.c
index 2c720cb..861c15a 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -68,6 +68,7 @@
 struct dw2102_state {
u8 initialized;
u8 last_lock;
+   u8 data[MAX_XFER_SIZE + 4];
struct i2c_client *i2c_client_demod;
struct i2c_client *i2c_client_tuner;
 
@@ -662,62 +663,69 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, 
struct i2c_msg msg[],
int num)
 {
struct dvb_usb_device *d = i2c_get_adapdata(adap);
-   u8 obuf[0x40], ibuf[0x40];
+   struct dw2102_state *state = (struct dw2102_state *)d->priv;
 
if (!d)
return -ENODEV;
if (mutex_lock_interruptible(>i2c_mutex) < 0)
return -EAGAIN;
+   if (mutex_lock_interruptible(>data_mutex) < 0) {
+   mutex_unlock(>i2c_mutex);
+   return -EAGAIN;
+   }
 
switch (num) {
case 1:
switch (msg[0].addr) {
case SU3000_STREAM_CTRL:
-   obuf[0] = msg[0].buf[0] + 0x36;
-   obuf[1] = 3;
-   obuf[2] = 0;
-   if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
+   state->data[0] = msg[0].buf[0] + 0x36;
+   state->data[1] = 3;
+   state->data[2] = 0;
+   if (dvb_usb_generic_rw(d, state->data, 3,
+   state->data, 0, 0) < 0)
err("i2c transfer failed.");
break;
case DW2102_RC_QUERY:
-   obuf[0] = 0x10;
-   if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
+   state->data[0] = 0x10;
+   if (dvb_usb_generic_rw(d, state->data, 1,
+   state->data, 2, 0) < 0)
err("i2c transfer failed.");
-   msg[0].buf[1] = ibuf[0];
-   msg[0].buf[0] = ibuf[1];
+   msg[0].buf[1] = state->data[0];
+   msg[0].buf[0] = state->data[1];
break;
default:
/* always i2c write*/
-   obuf[0] = 0x08;
-   obuf[1] = msg[0].addr;
-   obuf[2] = msg[0].len;
+   state->data[0] = 0x08;
+   state->data[1] = msg[0].addr;
+   state->data[2] = msg[0].len;
 
-   memcpy([3], msg[0].buf, msg[0].len);
+   memcpy(>data[3], msg[0].buf, msg[0].len);
 
-   if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
-   ibuf, 1, 0) < 0)
+   if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3,
+   state->data, 1, 0) < 0)
err("i2c transfer failed.");
 
}
break;
case 2:
/* always i2c read */
-   obuf[0] = 0x09;
-   obuf[1] = msg[0].len;
-   obuf[2] = msg[1].len;
-   obuf[3] = msg[0].addr;
-   memcpy([4], msg[0].buf, msg[0].len);
-
-   if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
-   ibuf, msg[1].len + 1, 0) < 0)
+   state->data[0] = 0x09;
+   state->data[1] = msg[0].len;
+   state->data[2] = msg[1].len;
+   state->data[3] = msg[0].addr;
+   memcpy(>data[4], msg[0].buf, msg[0].len);
+
+   if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4,
+   state->data, msg[1

[PATCH v2] [media] dw2102: don't do DMA on stack

2017-02-15 Thread Jonathan McDowell
(Apologies, the original version of this patch had a stray, unused,
"buf_mutex" definition left over from an earlier version before I
switched to the existing data_mutex.)

I upgraded my media box today from 4.4.48 to 4.9.10 and hit WARNINGs in
the dw2102 driver for my TechnoTrend TT-connect S2-4600, one in
su3000_power_ctrl() and the other in tt_s2_4600_frontend_attach(). Both
were due to the use of buffers on the stack as parameters to
dvb_usb_generic_rw() and the resulting attempt to do DMA with them. The
device was non-functional as a result.

Patch below switches this driver over to using a buffer within the
device state structure, as has been done with other DVB-USB drivers.
Tested against 4.9.10 but applies to Linus' master cleanly.

Signed-off-by: Jonathan McDowell 
Cc: 

-
diff --git a/drivers/media/usb/dvb-usb/dw2102.c 
b/drivers/media/usb/dvb-usb/dw2102.c
index 2c720cb..861c15a 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -68,6 +68,7 @@
 struct dw2102_state {
u8 initialized;
u8 last_lock;
+   u8 data[MAX_XFER_SIZE + 4];
struct i2c_client *i2c_client_demod;
struct i2c_client *i2c_client_tuner;
 
@@ -662,62 +663,69 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, 
struct i2c_msg msg[],
int num)
 {
struct dvb_usb_device *d = i2c_get_adapdata(adap);
-   u8 obuf[0x40], ibuf[0x40];
+   struct dw2102_state *state = (struct dw2102_state *)d->priv;
 
if (!d)
return -ENODEV;
if (mutex_lock_interruptible(>i2c_mutex) < 0)
return -EAGAIN;
+   if (mutex_lock_interruptible(>data_mutex) < 0) {
+   mutex_unlock(>i2c_mutex);
+   return -EAGAIN;
+   }
 
switch (num) {
case 1:
switch (msg[0].addr) {
case SU3000_STREAM_CTRL:
-   obuf[0] = msg[0].buf[0] + 0x36;
-   obuf[1] = 3;
-   obuf[2] = 0;
-   if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
+   state->data[0] = msg[0].buf[0] + 0x36;
+   state->data[1] = 3;
+   state->data[2] = 0;
+   if (dvb_usb_generic_rw(d, state->data, 3,
+   state->data, 0, 0) < 0)
err("i2c transfer failed.");
break;
case DW2102_RC_QUERY:
-   obuf[0] = 0x10;
-   if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
+   state->data[0] = 0x10;
+   if (dvb_usb_generic_rw(d, state->data, 1,
+   state->data, 2, 0) < 0)
err("i2c transfer failed.");
-   msg[0].buf[1] = ibuf[0];
-   msg[0].buf[0] = ibuf[1];
+   msg[0].buf[1] = state->data[0];
+   msg[0].buf[0] = state->data[1];
break;
default:
/* always i2c write*/
-   obuf[0] = 0x08;
-   obuf[1] = msg[0].addr;
-   obuf[2] = msg[0].len;
+   state->data[0] = 0x08;
+   state->data[1] = msg[0].addr;
+   state->data[2] = msg[0].len;
 
-   memcpy([3], msg[0].buf, msg[0].len);
+   memcpy(>data[3], msg[0].buf, msg[0].len);
 
-   if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
-   ibuf, 1, 0) < 0)
+   if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3,
+   state->data, 1, 0) < 0)
err("i2c transfer failed.");
 
}
break;
case 2:
/* always i2c read */
-   obuf[0] = 0x09;
-   obuf[1] = msg[0].len;
-   obuf[2] = msg[1].len;
-   obuf[3] = msg[0].addr;
-   memcpy([4], msg[0].buf, msg[0].len);
-
-   if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
-   ibuf, msg[1].len + 1, 0) < 0)
+   state->data[0] = 0x09;
+   state->data[1] = msg[0].len;
+   state->data[2] = msg[1].len;
+   state->data[3] = msg[0].addr;
+   memcpy(>data[4], msg[0].buf, msg[0].len);
+
+   if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4,
+   state->data, msg[1].len + 1, 0) < 0)

[PATCH] [media] dw2102: don't do DMA on stack

2017-02-15 Thread Jonathan McDowell
I upgraded my media box today from 4.4.48 to 4.9.10 and hit WARNINGs in
the dw2102 driver for my TechnoTrend TT-connect S2-4600, one in
su3000_power_ctrl() and the other in tt_s2_4600_frontend_attach(). Both
were due to the use of buffers on the stack as parameters to
dvb_usb_generic_rw() and the resulting attempt to do DMA with them.

Patch below switches this driver over to using a buffer within the
device state structure, as has been done with other DVB-USB drivers.
Tested against 4.9.10 but applies to Linus' master cleanly.

Signed-off-by: Jonathan McDowell <nood...@earth.li>
Cc: <sta...@vger.kernel.org>

-
diff --git a/drivers/media/usb/dvb-usb/dw2102.c 
b/drivers/media/usb/dvb-usb/dw2102.c
index 2c720cb..1dde34f 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -68,6 +68,8 @@
 struct dw2102_state {
u8 initialized;
u8 last_lock;
+   u8 data[MAX_XFER_SIZE + 4];
+   struct mutex buf_mutex;
struct i2c_client *i2c_client_demod;
struct i2c_client *i2c_client_tuner;
 
@@ -662,62 +664,69 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, 
struct i2c_msg msg[],
int num)
 {
struct dvb_usb_device *d = i2c_get_adapdata(adap);
-   u8 obuf[0x40], ibuf[0x40];
+   struct dw2102_state *state = (struct dw2102_state *)d->priv;
 
if (!d)
return -ENODEV;
if (mutex_lock_interruptible(>i2c_mutex) < 0)
return -EAGAIN;
+   if (mutex_lock_interruptible(>data_mutex) < 0) {
+   mutex_unlock(>i2c_mutex);
+   return -EAGAIN;
+   }
 
switch (num) {
case 1:
switch (msg[0].addr) {
case SU3000_STREAM_CTRL:
-   obuf[0] = msg[0].buf[0] + 0x36;
-   obuf[1] = 3;
-   obuf[2] = 0;
-   if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
+   state->data[0] = msg[0].buf[0] + 0x36;
+   state->data[1] = 3;
+   state->data[2] = 0;
+   if (dvb_usb_generic_rw(d, state->data, 3,
+   state->data, 0, 0) < 0)
err("i2c transfer failed.");
break;
case DW2102_RC_QUERY:
-   obuf[0] = 0x10;
-   if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
+   state->data[0] = 0x10;
+   if (dvb_usb_generic_rw(d, state->data, 1,
+   state->data, 2, 0) < 0)
err("i2c transfer failed.");
-   msg[0].buf[1] = ibuf[0];
-   msg[0].buf[0] = ibuf[1];
+   msg[0].buf[1] = state->data[0];
+   msg[0].buf[0] = state->data[1];
break;
default:
/* always i2c write*/
-   obuf[0] = 0x08;
-   obuf[1] = msg[0].addr;
-   obuf[2] = msg[0].len;
+   state->data[0] = 0x08;
+   state->data[1] = msg[0].addr;
+   state->data[2] = msg[0].len;
 
-   memcpy([3], msg[0].buf, msg[0].len);
+   memcpy(>data[3], msg[0].buf, msg[0].len);
 
-   if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
-   ibuf, 1, 0) < 0)
+   if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3,
+   state->data, 1, 0) < 0)
err("i2c transfer failed.");
 
}
break;
case 2:
/* always i2c read */
-   obuf[0] = 0x09;
-   obuf[1] = msg[0].len;
-   obuf[2] = msg[1].len;
-   obuf[3] = msg[0].addr;
-   memcpy([4], msg[0].buf, msg[0].len);
-
-   if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
-   ibuf, msg[1].len + 1, 0) < 0)
+   state->data[0] = 0x09;
+   state->data[1] = msg[0].len;
+   state->data[2] = msg[1].len;
+   state->data[3] = msg[0].addr;
+   memcpy(>data[4], msg[0].buf, msg[0].len);
+
+   if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4,
+   state->data, msg[1].len + 1, 0) < 0)
err("i2c transfer failed.");
 
-   memcpy(msg[1].buf, [1], msg[1].len);
+   memcpy(msg[1].buf, &

[PATCH] [media] dw2102: don't do DMA on stack

2017-02-15 Thread Jonathan McDowell
I upgraded my media box today from 4.4.48 to 4.9.10 and hit WARNINGs in
the dw2102 driver for my TechnoTrend TT-connect S2-4600, one in
su3000_power_ctrl() and the other in tt_s2_4600_frontend_attach(). Both
were due to the use of buffers on the stack as parameters to
dvb_usb_generic_rw() and the resulting attempt to do DMA with them.

Patch below switches this driver over to using a buffer within the
device state structure, as has been done with other DVB-USB drivers.
Tested against 4.9.10 but applies to Linus' master cleanly.

Signed-off-by: Jonathan McDowell 
Cc: 

-
diff --git a/drivers/media/usb/dvb-usb/dw2102.c 
b/drivers/media/usb/dvb-usb/dw2102.c
index 2c720cb..1dde34f 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -68,6 +68,8 @@
 struct dw2102_state {
u8 initialized;
u8 last_lock;
+   u8 data[MAX_XFER_SIZE + 4];
+   struct mutex buf_mutex;
struct i2c_client *i2c_client_demod;
struct i2c_client *i2c_client_tuner;
 
@@ -662,62 +664,69 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, 
struct i2c_msg msg[],
int num)
 {
struct dvb_usb_device *d = i2c_get_adapdata(adap);
-   u8 obuf[0x40], ibuf[0x40];
+   struct dw2102_state *state = (struct dw2102_state *)d->priv;
 
if (!d)
return -ENODEV;
if (mutex_lock_interruptible(>i2c_mutex) < 0)
return -EAGAIN;
+   if (mutex_lock_interruptible(>data_mutex) < 0) {
+   mutex_unlock(>i2c_mutex);
+   return -EAGAIN;
+   }
 
switch (num) {
case 1:
switch (msg[0].addr) {
case SU3000_STREAM_CTRL:
-   obuf[0] = msg[0].buf[0] + 0x36;
-   obuf[1] = 3;
-   obuf[2] = 0;
-   if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
+   state->data[0] = msg[0].buf[0] + 0x36;
+   state->data[1] = 3;
+   state->data[2] = 0;
+   if (dvb_usb_generic_rw(d, state->data, 3,
+   state->data, 0, 0) < 0)
err("i2c transfer failed.");
break;
case DW2102_RC_QUERY:
-   obuf[0] = 0x10;
-   if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
+   state->data[0] = 0x10;
+   if (dvb_usb_generic_rw(d, state->data, 1,
+   state->data, 2, 0) < 0)
err("i2c transfer failed.");
-   msg[0].buf[1] = ibuf[0];
-   msg[0].buf[0] = ibuf[1];
+   msg[0].buf[1] = state->data[0];
+   msg[0].buf[0] = state->data[1];
break;
default:
/* always i2c write*/
-   obuf[0] = 0x08;
-   obuf[1] = msg[0].addr;
-   obuf[2] = msg[0].len;
+   state->data[0] = 0x08;
+   state->data[1] = msg[0].addr;
+   state->data[2] = msg[0].len;
 
-   memcpy([3], msg[0].buf, msg[0].len);
+   memcpy(>data[3], msg[0].buf, msg[0].len);
 
-   if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
-   ibuf, 1, 0) < 0)
+   if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3,
+   state->data, 1, 0) < 0)
err("i2c transfer failed.");
 
}
break;
case 2:
/* always i2c read */
-   obuf[0] = 0x09;
-   obuf[1] = msg[0].len;
-   obuf[2] = msg[1].len;
-   obuf[3] = msg[0].addr;
-   memcpy([4], msg[0].buf, msg[0].len);
-
-   if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
-   ibuf, msg[1].len + 1, 0) < 0)
+   state->data[0] = 0x09;
+   state->data[1] = msg[0].len;
+   state->data[2] = msg[1].len;
+   state->data[3] = msg[0].addr;
+   memcpy(>data[4], msg[0].buf, msg[0].len);
+
+   if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4,
+   state->data, msg[1].len + 1, 0) < 0)
err("i2c transfer failed.");
 
-   memcpy(msg[1].buf, [1], msg[1].len);
+   memcpy(msg[1].buf, >data[1], msg[1].len);
break;

[PATCH] Remove spurious blank lines in dw2101 kernel messages

2016-06-06 Thread Jonathan McDowell
The DW2102 DVB-S/S2 driver uses the info() logging function from
dvb-usb.h. This function already appends a newline to the provided log
message, causing the dmesg output from DW2102 to include blank lines.
Fix this by removing the newline in the calls to info().

Signed-off-by: Jonathan McDowell <nood...@earth.li>

-
diff --git a/drivers/media/usb/dvb-usb/dw2102.c 
b/drivers/media/usb/dvb-usb/dw2102.c
index 14ef25d..687f740 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -896,7 +896,7 @@ static int su3000_power_ctrl(struct dvb_usb_device *d, int 
i)
struct dw2102_state *state = (struct dw2102_state *)d->priv;
u8 obuf[] = {0xde, 0};
 
-   info("%s: %d, initialized %d\n", __func__, i, state->initialized);
+   info("%s: %d, initialized %d", __func__, i, state->initialized);
 
if (i && !state->initialized) {
state->initialized = 1;
@@ -943,7 +943,7 @@ static int su3000_identify_state(struct usb_device *udev,
 struct dvb_usb_device_description **desc,
 int *cold)
 {
-   info("%s\n", __func__);
+   info("%s", __func__);
 
*cold = 0;
return 0;
@@ -1197,7 +1197,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter 
*d)
tuner_ops->set_bandwidth = stb6100_set_bandw;
tuner_ops->get_bandwidth = stb6100_get_bandw;
d->fe_adap[0].fe->ops.set_voltage = 
dw210x_set_voltage;
-   info("Attached STV0900+STB6100!\n");
+   info("Attached STV0900+STB6100!");
return 0;
}
}
@@ -1211,7 +1211,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter 
*d)
_stv6110_config,
>dev->i2c_adap)) {
d->fe_adap[0].fe->ops.set_voltage = 
dw210x_set_voltage;
-   info("Attached STV0900+STV6110A!\n");
+   info("Attached STV0900+STV6110A!");
return 0;
}
}
@@ -1222,7 +1222,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter 
*d)
>dev->i2c_adap);
if (d->fe_adap[0].fe != NULL) {
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-   info("Attached cx24116!\n");
+   info("Attached cx24116!");
return 0;
}
}
@@ -1233,7 +1233,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter 
*d)
dvb_attach(ts2020_attach, d->fe_adap[0].fe,
_ts2020_config, >dev->i2c_adap);
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-   info("Attached DS3000!\n");
+   info("Attached DS3000!");
return 0;
}
 
@@ -1252,7 +1252,7 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter 
*d)
>dev->i2c_adap);
if (d->fe_adap[0].fe != NULL) {
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-   info("Attached si21xx!\n");
+   info("Attached si21xx!");
return 0;
}
}
@@ -1264,7 +1264,7 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter 
*d)
if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61,
>dev->i2c_adap)) {
d->fe_adap[0].fe->ops.set_voltage = 
dw210x_set_voltage;
-   info("Attached stv0288!\n");
+   info("Attached stv0288!");
return 0;
}
}
@@ -1276,7 +1276,7 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter 
*d)
>dev->i2c_adap);
if (d->fe_adap[0].fe != NULL) {
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-   info("Attached stv0299!\n");
+   info("Attached stv0299!");
return 0;
}
}
@@ -1288,7 +1288,7 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter 
*d)
d->fe_adap[0].fe = dvb_attach(tda10023_attach, _tda10023_config,
   

[PATCH] Remove spurious blank lines in dw2101 kernel messages

2016-06-06 Thread Jonathan McDowell
The DW2102 DVB-S/S2 driver uses the info() logging function from
dvb-usb.h. This function already appends a newline to the provided log
message, causing the dmesg output from DW2102 to include blank lines.
Fix this by removing the newline in the calls to info().

Signed-off-by: Jonathan McDowell 

-
diff --git a/drivers/media/usb/dvb-usb/dw2102.c 
b/drivers/media/usb/dvb-usb/dw2102.c
index 14ef25d..687f740 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -896,7 +896,7 @@ static int su3000_power_ctrl(struct dvb_usb_device *d, int 
i)
struct dw2102_state *state = (struct dw2102_state *)d->priv;
u8 obuf[] = {0xde, 0};
 
-   info("%s: %d, initialized %d\n", __func__, i, state->initialized);
+   info("%s: %d, initialized %d", __func__, i, state->initialized);
 
if (i && !state->initialized) {
state->initialized = 1;
@@ -943,7 +943,7 @@ static int su3000_identify_state(struct usb_device *udev,
 struct dvb_usb_device_description **desc,
 int *cold)
 {
-   info("%s\n", __func__);
+   info("%s", __func__);
 
*cold = 0;
return 0;
@@ -1197,7 +1197,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter 
*d)
tuner_ops->set_bandwidth = stb6100_set_bandw;
tuner_ops->get_bandwidth = stb6100_get_bandw;
d->fe_adap[0].fe->ops.set_voltage = 
dw210x_set_voltage;
-   info("Attached STV0900+STB6100!\n");
+   info("Attached STV0900+STB6100!");
return 0;
}
}
@@ -1211,7 +1211,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter 
*d)
_stv6110_config,
>dev->i2c_adap)) {
d->fe_adap[0].fe->ops.set_voltage = 
dw210x_set_voltage;
-   info("Attached STV0900+STV6110A!\n");
+   info("Attached STV0900+STV6110A!");
return 0;
}
}
@@ -1222,7 +1222,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter 
*d)
>dev->i2c_adap);
if (d->fe_adap[0].fe != NULL) {
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-   info("Attached cx24116!\n");
+   info("Attached cx24116!");
return 0;
}
}
@@ -1233,7 +1233,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter 
*d)
dvb_attach(ts2020_attach, d->fe_adap[0].fe,
_ts2020_config, >dev->i2c_adap);
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-   info("Attached DS3000!\n");
+   info("Attached DS3000!");
return 0;
}
 
@@ -1252,7 +1252,7 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter 
*d)
>dev->i2c_adap);
if (d->fe_adap[0].fe != NULL) {
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-   info("Attached si21xx!\n");
+   info("Attached si21xx!");
return 0;
}
}
@@ -1264,7 +1264,7 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter 
*d)
if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61,
>dev->i2c_adap)) {
d->fe_adap[0].fe->ops.set_voltage = 
dw210x_set_voltage;
-   info("Attached stv0288!\n");
+   info("Attached stv0288!");
return 0;
}
}
@@ -1276,7 +1276,7 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter 
*d)
>dev->i2c_adap);
if (d->fe_adap[0].fe != NULL) {
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
-   info("Attached stv0299!\n");
+   info("Attached stv0299!");
return 0;
}
}
@@ -1288,7 +1288,7 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter 
*d)
d->fe_adap[0].fe = dvb_attach(tda10023_attach, _tda10023_config,
 

[PATCH] Convert Wideview WT220 DVB USB driver to rc-core

2016-05-20 Thread Jonathan McDowell
(I don't know if this sort of patch is welcome, but if it is I have a
couple of other USB DVB sticks I will convert over as well. My main
motivation was to be able to easily use a better remote than the mini
one that comes with these devices.)

This patch converts the dtt200u DVB USB driver over to the rc-core
infrastructure for its handling of IR remotes. This device can receive
generic NEC / NEC Extended signals and the switch to the newer core
enables the easy use of tools such as ir-keytable to modify the active
key map.

Signed-off-by: Jonathan McDowell <nood...@earth.li>

-
diff --git a/drivers/media/rc/keymaps/Makefile 
b/drivers/media/rc/keymaps/Makefile
index fbbd3bb..3bc5714 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-dm1105-nec.o \
rc-dntv-live-dvb-t.o \
rc-dntv-live-dvbt-pro.o \
+   rc-dtt200u.o \
rc-dvbsky.o \
rc-em-terratec.o \
rc-encore-enltv2.o \
diff --git a/drivers/media/rc/keymaps/rc-dtt200u.c 
b/drivers/media/rc/keymaps/rc-dtt200u.c
new file mode 100644
index 000..25650e9
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-dtt200u.c
@@ -0,0 +1,59 @@
+/* Keytable for Wideview WT-220U.
+ *
+ * Copyright (c) 2016 Jonathan McDowell <nood...@earth.li>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+
+/* key list for the tiny remote control (Yakumo, don't know about the others) 
*/
+static struct rc_map_table dtt200u_table[] = {
+   { 0x8001, KEY_MUTE },
+   { 0x8002, KEY_CHANNELDOWN },
+   { 0x8003, KEY_VOLUMEDOWN },
+   { 0x8004, KEY_1 },
+   { 0x8005, KEY_2 },
+   { 0x8006, KEY_3 },
+   { 0x8007, KEY_4 },
+   { 0x8008, KEY_5 },
+   { 0x8009, KEY_6 },
+   { 0x800a, KEY_7 },
+   { 0x800c, KEY_ZOOM },
+   { 0x800d, KEY_0 },
+   { 0x800e, KEY_SELECT },
+   { 0x8012, KEY_POWER },
+   { 0x801a, KEY_CHANNELUP },
+   { 0x801b, KEY_8 },
+   { 0x801e, KEY_VOLUMEUP },
+   { 0x801f, KEY_9 },
+};
+
+static struct rc_map_list dtt200u_map = {
+   .map = {
+   .scan= dtt200u_table,
+   .size= ARRAY_SIZE(dtt200u_table),
+   .rc_type = RC_TYPE_NEC,
+   .name= RC_MAP_DTT200U,
+   }
+};
+
+static int __init init_rc_map_dtt200u(void)
+{
+   return rc_map_register(_map);
+}
+
+static void __exit exit_rc_map_dtt200u(void)
+{
+   rc_map_unregister(_map);
+}
+
+module_init(init_rc_map_dtt200u)
+module_exit(exit_rc_map_dtt200u)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jonathan McDowell <nood...@earth.li>");
diff --git a/drivers/media/usb/dvb-usb/dtt200u.c 
b/drivers/media/usb/dvb-usb/dtt200u.c
index ca3b69a..be633ec 100644
--- a/drivers/media/usb/dvb-usb/dtt200u.c
+++ b/drivers/media/usb/dvb-usb/dtt200u.c
@@ -55,36 +55,36 @@ static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, 
int index, u16 pid,
return dvb_usb_generic_write(adap->dev, b_pid, 4);
 }
 
-/* remote control */
-/* key list for the tiny remote control (Yakumo, don't know about the others) 
*/
-static struct rc_map_table rc_map_dtt200u_table[] = {
-   { 0x8001, KEY_MUTE },
-   { 0x8002, KEY_CHANNELDOWN },
-   { 0x8003, KEY_VOLUMEDOWN },
-   { 0x8004, KEY_1 },
-   { 0x8005, KEY_2 },
-   { 0x8006, KEY_3 },
-   { 0x8007, KEY_4 },
-   { 0x8008, KEY_5 },
-   { 0x8009, KEY_6 },
-   { 0x800a, KEY_7 },
-   { 0x800c, KEY_ZOOM },
-   { 0x800d, KEY_0 },
-   { 0x800e, KEY_SELECT },
-   { 0x8012, KEY_POWER },
-   { 0x801a, KEY_CHANNELUP },
-   { 0x801b, KEY_8 },
-   { 0x801e, KEY_VOLUMEUP },
-   { 0x801f, KEY_9 },
-};
-
-static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+static int dtt200u_rc_query(struct dvb_usb_device *d)
 {
u8 key[5],cmd = GET_RC_CODE;
+   u32 scancode;
+
dvb_usb_generic_rw(d,,1,key,5,0);
-   dvb_usb_nec_rc_key_to_event(d,key,event,state);
+   if (key[0] == 1) {
+   scancode = key[1];
+   if ((u8) ~key[1] != key[2]) {
+   /* Extended NEC */
+   scancode = scancode << 8;
+   scancode |= key[2];
+   }
+   scancode = scancode << 8;
+   scancode |= key[3];
+
+   /* Check command checksum is ok */
+   if ((u8) ~key[3] == key[4])
+   rc_keydown(d->rc_dev, RC_TYPE_NEC, scancode, 0);
+   else
+  

[PATCH] Convert Wideview WT220 DVB USB driver to rc-core

2016-05-20 Thread Jonathan McDowell
(I don't know if this sort of patch is welcome, but if it is I have a
couple of other USB DVB sticks I will convert over as well. My main
motivation was to be able to easily use a better remote than the mini
one that comes with these devices.)

This patch converts the dtt200u DVB USB driver over to the rc-core
infrastructure for its handling of IR remotes. This device can receive
generic NEC / NEC Extended signals and the switch to the newer core
enables the easy use of tools such as ir-keytable to modify the active
key map.

Signed-off-by: Jonathan McDowell 

-
diff --git a/drivers/media/rc/keymaps/Makefile 
b/drivers/media/rc/keymaps/Makefile
index fbbd3bb..3bc5714 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-dm1105-nec.o \
rc-dntv-live-dvb-t.o \
rc-dntv-live-dvbt-pro.o \
+   rc-dtt200u.o \
rc-dvbsky.o \
rc-em-terratec.o \
rc-encore-enltv2.o \
diff --git a/drivers/media/rc/keymaps/rc-dtt200u.c 
b/drivers/media/rc/keymaps/rc-dtt200u.c
new file mode 100644
index 000..25650e9
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-dtt200u.c
@@ -0,0 +1,59 @@
+/* Keytable for Wideview WT-220U.
+ *
+ * Copyright (c) 2016 Jonathan McDowell 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+
+/* key list for the tiny remote control (Yakumo, don't know about the others) 
*/
+static struct rc_map_table dtt200u_table[] = {
+   { 0x8001, KEY_MUTE },
+   { 0x8002, KEY_CHANNELDOWN },
+   { 0x8003, KEY_VOLUMEDOWN },
+   { 0x8004, KEY_1 },
+   { 0x8005, KEY_2 },
+   { 0x8006, KEY_3 },
+   { 0x8007, KEY_4 },
+   { 0x8008, KEY_5 },
+   { 0x8009, KEY_6 },
+   { 0x800a, KEY_7 },
+   { 0x800c, KEY_ZOOM },
+   { 0x800d, KEY_0 },
+   { 0x800e, KEY_SELECT },
+   { 0x8012, KEY_POWER },
+   { 0x801a, KEY_CHANNELUP },
+   { 0x801b, KEY_8 },
+   { 0x801e, KEY_VOLUMEUP },
+   { 0x801f, KEY_9 },
+};
+
+static struct rc_map_list dtt200u_map = {
+   .map = {
+   .scan= dtt200u_table,
+   .size= ARRAY_SIZE(dtt200u_table),
+   .rc_type = RC_TYPE_NEC,
+   .name= RC_MAP_DTT200U,
+   }
+};
+
+static int __init init_rc_map_dtt200u(void)
+{
+   return rc_map_register(_map);
+}
+
+static void __exit exit_rc_map_dtt200u(void)
+{
+   rc_map_unregister(_map);
+}
+
+module_init(init_rc_map_dtt200u)
+module_exit(exit_rc_map_dtt200u)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jonathan McDowell ");
diff --git a/drivers/media/usb/dvb-usb/dtt200u.c 
b/drivers/media/usb/dvb-usb/dtt200u.c
index ca3b69a..be633ec 100644
--- a/drivers/media/usb/dvb-usb/dtt200u.c
+++ b/drivers/media/usb/dvb-usb/dtt200u.c
@@ -55,36 +55,36 @@ static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, 
int index, u16 pid,
return dvb_usb_generic_write(adap->dev, b_pid, 4);
 }
 
-/* remote control */
-/* key list for the tiny remote control (Yakumo, don't know about the others) 
*/
-static struct rc_map_table rc_map_dtt200u_table[] = {
-   { 0x8001, KEY_MUTE },
-   { 0x8002, KEY_CHANNELDOWN },
-   { 0x8003, KEY_VOLUMEDOWN },
-   { 0x8004, KEY_1 },
-   { 0x8005, KEY_2 },
-   { 0x8006, KEY_3 },
-   { 0x8007, KEY_4 },
-   { 0x8008, KEY_5 },
-   { 0x8009, KEY_6 },
-   { 0x800a, KEY_7 },
-   { 0x800c, KEY_ZOOM },
-   { 0x800d, KEY_0 },
-   { 0x800e, KEY_SELECT },
-   { 0x8012, KEY_POWER },
-   { 0x801a, KEY_CHANNELUP },
-   { 0x801b, KEY_8 },
-   { 0x801e, KEY_VOLUMEUP },
-   { 0x801f, KEY_9 },
-};
-
-static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+static int dtt200u_rc_query(struct dvb_usb_device *d)
 {
u8 key[5],cmd = GET_RC_CODE;
+   u32 scancode;
+
dvb_usb_generic_rw(d,,1,key,5,0);
-   dvb_usb_nec_rc_key_to_event(d,key,event,state);
+   if (key[0] == 1) {
+   scancode = key[1];
+   if ((u8) ~key[1] != key[2]) {
+   /* Extended NEC */
+   scancode = scancode << 8;
+   scancode |= key[2];
+   }
+   scancode = scancode << 8;
+   scancode |= key[3];
+
+   /* Check command checksum is ok */
+   if ((u8) ~key[3] == key[4])
+   rc_keydown(d->rc_dev, RC_TYPE_NEC, scancode, 0);
+   else
+   rc_keyup(d->rc_dev);
+   } else if (key[0] == 2) {
+  

[PATCH] Fix RC5 decoding with Fintek CIR chipset

2016-05-14 Thread Jonathan McDowell
Fix RC5 decoding with Fintek CIR chipset

Commit e87b540be2dd02552fb9244d50ae8b4e4619a34b tightened up the RC5
decoding by adding a check for trailing silence to ensure a valid RC5
command had been received. Unfortunately the trailer length checked was
10 units and the Fintek CIR device does not want to provide details of a
space longer than 6350us. This meant that RC5 remotes working on a
Fintek setup on 3.16 failed on 3.17 and later. Fix this by shortening
the trailer check to 6 units (allowing for a previous space in the
received remote command).

Signed-off-by: Jonathan McDowell <nood...@earth.li>
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=117221
Cc: sta...@vger.kernel.org

-
diff --git a/drivers/media/rc/ir-rc5-decoder.c 
b/drivers/media/rc/ir-rc5-decoder.c
index 6ffe776..a0fd4e6 100644
--- a/drivers/media/rc/ir-rc5-decoder.c
+++ b/drivers/media/rc/ir-rc5-decoder.c
@@ -29,7 +29,7 @@
 #define RC5_BIT_START  (1 * RC5_UNIT)
 #define RC5_BIT_END(1 * RC5_UNIT)
 #define RC5X_SPACE (4 * RC5_UNIT)
-#define RC5_TRAILER(10 * RC5_UNIT) /* In reality, approx 100 */
+#define RC5_TRAILER(6 * RC5_UNIT) /* In reality, approx 100 */
 
 enum rc5_state {
STATE_INACTIVE,
-

J.

-- 
What did the first punk rock girl wear to your school?


[PATCH] Fix RC5 decoding with Fintek CIR chipset

2016-05-14 Thread Jonathan McDowell
Fix RC5 decoding with Fintek CIR chipset

Commit e87b540be2dd02552fb9244d50ae8b4e4619a34b tightened up the RC5
decoding by adding a check for trailing silence to ensure a valid RC5
command had been received. Unfortunately the trailer length checked was
10 units and the Fintek CIR device does not want to provide details of a
space longer than 6350us. This meant that RC5 remotes working on a
Fintek setup on 3.16 failed on 3.17 and later. Fix this by shortening
the trailer check to 6 units (allowing for a previous space in the
received remote command).

Signed-off-by: Jonathan McDowell 
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=117221
Cc: sta...@vger.kernel.org

-
diff --git a/drivers/media/rc/ir-rc5-decoder.c 
b/drivers/media/rc/ir-rc5-decoder.c
index 6ffe776..a0fd4e6 100644
--- a/drivers/media/rc/ir-rc5-decoder.c
+++ b/drivers/media/rc/ir-rc5-decoder.c
@@ -29,7 +29,7 @@
 #define RC5_BIT_START  (1 * RC5_UNIT)
 #define RC5_BIT_END(1 * RC5_UNIT)
 #define RC5X_SPACE (4 * RC5_UNIT)
-#define RC5_TRAILER(10 * RC5_UNIT) /* In reality, approx 100 */
+#define RC5_TRAILER(6 * RC5_UNIT) /* In reality, approx 100 */
 
 enum rc5_state {
STATE_INACTIVE,
-

J.

-- 
What did the first punk rock girl wear to your school?


[PATCH] Re: [4.3-rc1 regression] modular 8250 doesn't load

2015-09-21 Thread Jonathan McDowell

In article <20150914211827.ga3...@kroah.com> (earth.lists.linux-kernel)
you wrote:
> On Mon, Sep 14, 2015 at 02:12:43PM -0700, Greg Kroah-Hartman wrote:
> > On Mon, Sep 14, 2015 at 10:42:24PM +0200, Mikael Pettersson wrote:
> > > Greg Kroah-Hartman writes: uart_insert_char is EXPORT_SYMBOL_GPL,
> > > so could the missing license tag be preventing 8250_core from
> > > binding to it?  (I haven't checked the other symbols but I assume
> > > they are also _GPL.)
> > 
> > Ah, crap, yes, you are right.  You can test this with a simple:
> > MODULE_LICENSE("GPL"); line added to the 8250_base file.

> Wait, 8250_base.c has a module license line.

8250_base.c doesn't exist; it is built from 8250_port.c and 8250_dma.c,
neither of which have a MODULE_LICENSE line. Adding
MODULE_LICENSE("GPL") as per below fixes the issue for me (on 4.3-rc2):

-
Author: Jonathan McDowell 
Date:   Mon Sep 21 21:20:53 2015 +0100

Add missing module license for 8250_base.ko

The split of the 8250 driver into a 8250_base/8250.ko resulted in a
lack of a license for the 8250_base.ko module. This caused the module
to fail to load and the kernel to be tainted. Add the appropriate
MODULE_LICENSE to 8250_port.c, which is always compiled into
8250_base.ko

Signed-off-by: Jonathan McDowell 

diff --git a/drivers/tty/serial/8250/8250_port.c 
b/drivers/tty/serial/8250/8250_port.c
index 54e6c8d..b1e0ba3 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -2910,3 +2910,5 @@ int serial8250_console_setup(struct uart_port *port, char 
*options, bool probe)
 }
 
 #endif /* CONFIG_SERIAL_8250_CONSOLE */
+
+MODULE_LICENSE("GPL");
-

J.

-- 
Even the Evening Herald slags me off.
This .sig brought to you by the letter U and the number 21
Product of the Republic of HuggieTag
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] Re: [4.3-rc1 regression] modular 8250 doesn't load

2015-09-21 Thread Jonathan McDowell

In article <20150914211827.ga3...@kroah.com> (earth.lists.linux-kernel)
you wrote:
> On Mon, Sep 14, 2015 at 02:12:43PM -0700, Greg Kroah-Hartman wrote:
> > On Mon, Sep 14, 2015 at 10:42:24PM +0200, Mikael Pettersson wrote:
> > > Greg Kroah-Hartman writes: uart_insert_char is EXPORT_SYMBOL_GPL,
> > > so could the missing license tag be preventing 8250_core from
> > > binding to it?  (I haven't checked the other symbols but I assume
> > > they are also _GPL.)
> > 
> > Ah, crap, yes, you are right.  You can test this with a simple:
> > MODULE_LICENSE("GPL"); line added to the 8250_base file.

> Wait, 8250_base.c has a module license line.

8250_base.c doesn't exist; it is built from 8250_port.c and 8250_dma.c,
neither of which have a MODULE_LICENSE line. Adding
MODULE_LICENSE("GPL") as per below fixes the issue for me (on 4.3-rc2):

-
Author: Jonathan McDowell <nood...@earth.li>
Date:   Mon Sep 21 21:20:53 2015 +0100

Add missing module license for 8250_base.ko

The split of the 8250 driver into a 8250_base/8250.ko resulted in a
lack of a license for the 8250_base.ko module. This caused the module
to fail to load and the kernel to be tainted. Add the appropriate
MODULE_LICENSE to 8250_port.c, which is always compiled into
8250_base.ko

Signed-off-by: Jonathan McDowell <nood...@earth.li>

diff --git a/drivers/tty/serial/8250/8250_port.c 
b/drivers/tty/serial/8250/8250_port.c
index 54e6c8d..b1e0ba3 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -2910,3 +2910,5 @@ int serial8250_console_setup(struct uart_port *port, char 
*options, bool probe)
 }
 
 #endif /* CONFIG_SERIAL_8250_CONSOLE */
+
+MODULE_LICENSE("GPL");
-

J.

-- 
Even the Evening Herald slags me off.
This .sig brought to you by the letter U and the number 21
Product of the Republic of HuggieTag
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Audio crackles with 4.1-rc1

2015-06-14 Thread Jonathan McDowell
On Fri, Jun 12, 2015 at 04:13:16PM +0200, Takashi Iwai wrote:
> At Fri, 12 Jun 2015 12:09:55 +0200,
> Takashi Iwai wrote:
> > At Fri, 12 Jun 2015 12:45:23 +0300,
> > Mihai Donțu wrote:
> > > Nice shot! It appears to work. :-) No clicks, no static.
> > 
> > Good to hear!
> > 
> > > I had to apply it by hand over 4.1-rc7, because the first two arrays
> > > look different in both it and -master. Anyway, I will play with it some
> > > more today see if anything else is broken.
> > 
> > While we are at it: could you try to enable codec->power_save_node in
> > patch_alc269() (while keeping the new patch)?
> > 
> > --- a/sound/pci/hda/patch_realtek.c
> > +++ b/sound/pci/hda/patch_realtek.c
> > @@ -5671,8 +5671,7 @@ static int patch_alc269(struct hda_codec *codec)
> >  
> > spec = codec->spec;
> > spec->gen.shared_mic_vref_pin = 0x18;
> > -   if (codec->core.vendor_id != 0x10ec0292)
> > -   codec->power_save_node = 1;
> > +   codec->power_save_node = 1;
> >  
> >  #ifdef CONFIG_PM
> > codec->patch_ops.suspend = alc269_suspend;
> 
> For your convenience, below is the combined patch for 4.1.
> 
> Jonathan, could you also try this patch and see whether you still get
> the noise?

Applying the combined patch to 4.1-rc7 I'm not getting any noise on the
transition from suspended to active.

J.

-- 
   101 things you can't have too   |  .''`.  Debian GNU/Linux Developer
much of : 47 - More coffee.| : :' :  Happy to accept PGP signed
   | `. `'   or encrypted mail - RSA
   |   `-key on the keyservers.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Audio crackles with 4.1-rc1

2015-06-14 Thread Jonathan McDowell
On Fri, Jun 12, 2015 at 04:13:16PM +0200, Takashi Iwai wrote:
 At Fri, 12 Jun 2015 12:09:55 +0200,
 Takashi Iwai wrote:
  At Fri, 12 Jun 2015 12:45:23 +0300,
  Mihai Donțu wrote:
   Nice shot! It appears to work. :-) No clicks, no static.
  
  Good to hear!
  
   I had to apply it by hand over 4.1-rc7, because the first two arrays
   look different in both it and -master. Anyway, I will play with it some
   more today see if anything else is broken.
  
  While we are at it: could you try to enable codec-power_save_node in
  patch_alc269() (while keeping the new patch)?
  
  --- a/sound/pci/hda/patch_realtek.c
  +++ b/sound/pci/hda/patch_realtek.c
  @@ -5671,8 +5671,7 @@ static int patch_alc269(struct hda_codec *codec)
   
  spec = codec-spec;
  spec-gen.shared_mic_vref_pin = 0x18;
  -   if (codec-core.vendor_id != 0x10ec0292)
  -   codec-power_save_node = 1;
  +   codec-power_save_node = 1;
   
   #ifdef CONFIG_PM
  codec-patch_ops.suspend = alc269_suspend;
 
 For your convenience, below is the combined patch for 4.1.
 
 Jonathan, could you also try this patch and see whether you still get
 the noise?

Applying the combined patch to 4.1-rc7 I'm not getting any noise on the
transition from suspended to active.

J.

-- 
   101 things you can't have too   |  .''`.  Debian GNU/Linux Developer
much of : 47 - More coffee.| : :' :  Happy to accept PGP signed
   | `. `'   or encrypted mail - RSA
   |   `-key on the keyservers.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Audio crackles with 4.1-rc1

2015-05-20 Thread Jonathan McDowell
On Wed, May 20, 2015 at 07:01:12AM +0200, Takashi Iwai wrote:
> At Tue, 19 May 2015 22:53:10 +0100,
> Jonathan McDowell wrote:
> > 
> > On Tue, May 19, 2015 at 07:09:12PM +0200, Takashi Iwai wrote:
> > > At Tue, 19 May 2015 17:19:11 +0100,
> > > Jonathan McDowell wrote:
> > > > 
> > > > On Tue, May 19, 2015 at 08:15:32AM +0200, Takashi Iwai wrote:
> > > > > Does the patch below have any improvement?
> > > > 
> > > > I still get a clicking on the standby -> active transition with the
> > > > patch provided on top of 4.1-rc4.
> > > 
> > > OK, just to be sure, could you check whether changing msleep(10) to
> > > msleep(100) makes no difference?  Also put a line like
> > >   pr_info("XXX power up %x\n", nid);
> > > after msleep() call to see which nodes are powered up dynamically.
> > 
> > Increasing the delay, if anything, makes the crackle when powering up
> > seem a little longer. dmesg log looks like:
> > 
> > [ 4206.075557] XXX power up 2
> > [ 4206.179671] XXX power up 14
> > [ 4206.291758] XXX power up 3
> 
> OK, so everything looks correct, but the codec (or the machine) seems
> leading to the noise when a branched path is activated while the pin
> was already powered up.  Then let's disable the widget power-saving
> for these codecs.
> 
> Could you confirm that the patch below works?

4.1-rc4 + patch below running all day without hearing any crackles.
Sounds good to me.

> -- 8< --
> From: Takashi Iwai 
> Subject: [PATCH] ALSA: hda - Disable widget power-saving for ALC292 & co
> 
> We've got reports that ALC3226 (a Dell variant of ALC292) gives click
> noises at transition from D3 to D0 when the widget power-saving is
> enabled.  Further debugging session showed that avoiding it isn't
> trivial, unfortunately, since paths are basically activated
> dynamically while the pins have been already enabled.
> 
> This patch disables the widget power-saving for such codecs.
> 
> Reported-by: Jonathan McDowell 
> Signed-off-by: Takashi Iwai 
> ---
>  sound/pci/hda/patch_realtek.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
> index 2e246fe495f6..31f8f13be907 100644
> --- a/sound/pci/hda/patch_realtek.c
> +++ b/sound/pci/hda/patch_realtek.c
> @@ -5623,7 +5623,8 @@ static int patch_alc269(struct hda_codec *codec)
>  
>   spec = codec->spec;
>   spec->gen.shared_mic_vref_pin = 0x18;
> - codec->power_save_node = 1;
> + if (codec->core.vendor_id != 0x10ec0292)
> + codec->power_save_node = 1;
>  
>   snd_hda_pick_fixup(codec, alc269_fixup_models,
>  alc269_fixup_tbl, alc269_fixups);
> -- 

J.

-- 
] http://www.earth.li/~noodles/ [] Sex, truth and jellibabies. [
]  PGP/GPG Key @ the.earth.li   [] [
] via keyserver, web or email.  [] [
] RSA: 4096/2DA8B985[] [
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Audio crackles with 4.1-rc1

2015-05-20 Thread Jonathan McDowell
On Wed, May 20, 2015 at 07:01:12AM +0200, Takashi Iwai wrote:
 At Tue, 19 May 2015 22:53:10 +0100,
 Jonathan McDowell wrote:
  
  On Tue, May 19, 2015 at 07:09:12PM +0200, Takashi Iwai wrote:
   At Tue, 19 May 2015 17:19:11 +0100,
   Jonathan McDowell wrote:

On Tue, May 19, 2015 at 08:15:32AM +0200, Takashi Iwai wrote:
 Does the patch below have any improvement?

I still get a clicking on the standby - active transition with the
patch provided on top of 4.1-rc4.
   
   OK, just to be sure, could you check whether changing msleep(10) to
   msleep(100) makes no difference?  Also put a line like
 pr_info(XXX power up %x\n, nid);
   after msleep() call to see which nodes are powered up dynamically.
  
  Increasing the delay, if anything, makes the crackle when powering up
  seem a little longer. dmesg log looks like:
  
  [ 4206.075557] XXX power up 2
  [ 4206.179671] XXX power up 14
  [ 4206.291758] XXX power up 3
 
 OK, so everything looks correct, but the codec (or the machine) seems
 leading to the noise when a branched path is activated while the pin
 was already powered up.  Then let's disable the widget power-saving
 for these codecs.
 
 Could you confirm that the patch below works?

4.1-rc4 + patch below running all day without hearing any crackles.
Sounds good to me.

 -- 8 --
 From: Takashi Iwai ti...@suse.de
 Subject: [PATCH] ALSA: hda - Disable widget power-saving for ALC292  co
 
 We've got reports that ALC3226 (a Dell variant of ALC292) gives click
 noises at transition from D3 to D0 when the widget power-saving is
 enabled.  Further debugging session showed that avoiding it isn't
 trivial, unfortunately, since paths are basically activated
 dynamically while the pins have been already enabled.
 
 This patch disables the widget power-saving for such codecs.
 
 Reported-by: Jonathan McDowell nood...@earth.li
 Signed-off-by: Takashi Iwai ti...@suse.de
 ---
  sound/pci/hda/patch_realtek.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
 index 2e246fe495f6..31f8f13be907 100644
 --- a/sound/pci/hda/patch_realtek.c
 +++ b/sound/pci/hda/patch_realtek.c
 @@ -5623,7 +5623,8 @@ static int patch_alc269(struct hda_codec *codec)
  
   spec = codec-spec;
   spec-gen.shared_mic_vref_pin = 0x18;
 - codec-power_save_node = 1;
 + if (codec-core.vendor_id != 0x10ec0292)
 + codec-power_save_node = 1;
  
   snd_hda_pick_fixup(codec, alc269_fixup_models,
  alc269_fixup_tbl, alc269_fixups);
 -- 

J.

-- 
] http://www.earth.li/~noodles/ [] Sex, truth and jellibabies. [
]  PGP/GPG Key @ the.earth.li   [] [
] via keyserver, web or email.  [] [
] RSA: 4096/2DA8B985[] [
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Audio crackles with 4.1-rc1

2015-05-19 Thread Jonathan McDowell
On Tue, May 19, 2015 at 07:09:12PM +0200, Takashi Iwai wrote:
> At Tue, 19 May 2015 17:19:11 +0100,
> Jonathan McDowell wrote:
> > 
> > On Tue, May 19, 2015 at 08:15:32AM +0200, Takashi Iwai wrote:
> > > Does the patch below have any improvement?
> > 
> > I still get a clicking on the standby -> active transition with the
> > patch provided on top of 4.1-rc4.
> 
> OK, just to be sure, could you check whether changing msleep(10) to
> msleep(100) makes no difference?  Also put a line like
>   pr_info("XXX power up %x\n", nid);
> after msleep() call to see which nodes are powered up dynamically.

Increasing the delay, if anything, makes the crackle when powering up
seem a little longer. dmesg log looks like:

[ 4206.075557] XXX power up 2
[ 4206.179671] XXX power up 14
[ 4206.291758] XXX power up 3

J.

-- 
xmpp:nood...@earth.li
"f u cn rd ths, u cn gt a gd jb n cmptr
prgrmmng." -- Simon
Cozens, ox.os.linux
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Audio crackles with 4.1-rc1

2015-05-19 Thread Jonathan McDowell
On Tue, May 19, 2015 at 08:15:32AM +0200, Takashi Iwai wrote:
> At Sat, 2 May 2015 16:05:13 +0100,
> Jonathan McDowell wrote:
> > 
> > On Thu, Apr 30, 2015 at 07:06:31PM +0200, Takashi Iwai wrote:
> > > At Thu, 30 Apr 2015 16:01:31 +0100, Jonathan McDowell wrote:
> > > > 
> > > > On Wed, Apr 29, 2015 at 01:54:57PM +0200, Takashi Iwai wrote:
> > > > > 
> > > > > One patch you can try (with or without power_save_node
> > > > > disablement) is below, it squashes the verb sequences at (runtime)
> > > > > PM resume as we did for 4.0.  Let me know if this changes the
> > > > > behavior.
> > > > 
> > > > Patch alone has no effect. Patch with power_save_node disablement
> > > > solves the problem. Didn't try power_save_node disablement without
> > > > the patch.
> > > 
> > > Then please confirm that only power_save_node disablement suffices.
> > > This can be considered as the least change that can be put to 4.1-rc
> > > if no better fix is found.
> > 
> > Setting codec->power_save_node to 0 in patch_alc269 is sufficient; no
> > noticeable cracking occurring.
> 
> Does the patch below have any improvement?

I still get a clicking on the standby -> active transition with the
patch provided on top of 4.1-rc4.

J.

-- 
   101 things you can't have too   |  .''`.  Debian GNU/Linux Developer
  much of : 9 - Processing power.  | : :' :  Happy to accept PGP signed
   | `. `'   or encrypted mail - RSA
   |   `-key on the keyservers.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


  1   2   >