diff mbox series

[net-next,1/2,v9] net: ethernet: Add DT bindings for the Gemini ethernet

Message ID 20171216193911.6938-1-linus.walleij@linaro.org
State New
Headers show
Series [net-next,1/2,v9] net: ethernet: Add DT bindings for the Gemini ethernet | expand

Commit Message

Linus Walleij Dec. 16, 2017, 7:39 p.m. UTC
This adds the device tree bindings for the Gemini ethernet
controller. It is pretty straight-forward, using standard
bindings and modelling the two child ports as child devices
under the parent ethernet controller device.

Cc: devicetree@vger.kernel.org
Cc: Tobias Waldvogel <tobias.waldvogel@gmail.com>
Cc: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v8->v9:
- Collect Rob's ACK.
ChangeLog v7->v8:
- Use ethernet-port@0 and ethernet-port@1 with unit names
  and following OF graph requirements.
---
 .../bindings/net/cortina,gemini-ethernet.txt       | 92 ++++++++++++++++++++++
 1 file changed, 92 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt

Comments

Linus Walleij Dec. 18, 2017, 1:57 p.m. UTC | #1
On Sat, Dec 16, 2017 at 8:39 PM, Linus Walleij <linus.walleij@linaro.org> wrote:

> The Gemini ethernet has been around for years as an out-of-tree
> patch used with the NAS boxen and routers built on StorLink
> SL3512 and SL3516, later Storm Semiconductor, later Cortina
> Systems. These ASICs are still being deployed and brand new
> off-the-shelf systems using it can easily be acquired.
>
> The full name of the IP block is "Net Engine and Gigabit
> Ethernet MAC" commonly just called "GMAC".
>
> The hardware block contains a common TCP Offload Enginer (TOE)
> that can be used by both MACs. The current driver does not use
> it.
>
> Cc: Tobias Waldvogel <tobias.waldvogel@gmail.com>
> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> Changes from v8:
> - Remove dependency guards in Kconfig to get a wider compile
>   coverage for the driver to detect broken APIs etc.

I guess we need to hold this off for a while, the code does
some weird stuff using the ARM-internal page DMA mapping
API.

I *think* what happens is that the driver allocates a global queue
used for RX and TX on both interfaces, then initializes that with
page pointers and gives that to the hardware to play with.

When an RX packet comes in, the RX routine needs to figure
out from the DMA (physical) address which remapped
page/address this random physical address pointer
corresponds to.

The Linux DMA API assumption is that the driver keeps track
of this mapping, not the hardware. So we need to figure out
a way to reverse-map this. Preferably quickly, and without
using any ARM-internal mapping APIs.

Yours,
Linus Walleij
Michał Mirosław Dec. 18, 2017, 2:48 p.m. UTC | #2
On Mon, Dec 18, 2017 at 02:57:37PM +0100, Linus Walleij wrote:
> On Sat, Dec 16, 2017 at 8:39 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
> 
> > The Gemini ethernet has been around for years as an out-of-tree
> > patch used with the NAS boxen and routers built on StorLink
> > SL3512 and SL3516, later Storm Semiconductor, later Cortina
> > Systems. These ASICs are still being deployed and brand new
> > off-the-shelf systems using it can easily be acquired.
[...]
> > ---
> > Changes from v8:
> > - Remove dependency guards in Kconfig to get a wider compile
> >   coverage for the driver to detect broken APIs etc.
> 
> I guess we need to hold this off for a while, the code does
> some weird stuff using the ARM-internal page DMA mapping
> API.
> 
> I *think* what happens is that the driver allocates a global queue
> used for RX and TX on both interfaces, then initializes that with
> page pointers and gives that to the hardware to play with.
> 
> When an RX packet comes in, the RX routine needs to figure
> out from the DMA (physical) address which remapped
> page/address this random physical address pointer
> corresponds to.
> 
> The Linux DMA API assumption is that the driver keeps track
> of this mapping, not the hardware. So we need to figure out
> a way to reverse-map this. Preferably quickly, and without
> using any ARM-internal mapping APIs.

IIRC, the hardware copies descriptors from free queue (FREEQ)
to RX queues. FREEQ is shared among the two ethernet ports.

This platform is CPU bound, so every additional lookup will
hit performance here. In my version I had an #ifdef for
COMPILE_TEST that replaced ARM-specific calls with stubs.
Since the driver is not expected to work on other platforms,
this seemed like the best workaround to make it compile
on other arches.

Best Regards,
Michał Mirosław
Russell King (Oracle) Dec. 18, 2017, 2:54 p.m. UTC | #3
On Mon, Dec 18, 2017 at 03:48:17PM +0100, Michał Mirosław wrote:
> On Mon, Dec 18, 2017 at 02:57:37PM +0100, Linus Walleij wrote:
> > On Sat, Dec 16, 2017 at 8:39 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
> > 
> > > The Gemini ethernet has been around for years as an out-of-tree
> > > patch used with the NAS boxen and routers built on StorLink
> > > SL3512 and SL3516, later Storm Semiconductor, later Cortina
> > > Systems. These ASICs are still being deployed and brand new
> > > off-the-shelf systems using it can easily be acquired.
> [...]
> > > ---
> > > Changes from v8:
> > > - Remove dependency guards in Kconfig to get a wider compile
> > >   coverage for the driver to detect broken APIs etc.
> > 
> > I guess we need to hold this off for a while, the code does
> > some weird stuff using the ARM-internal page DMA mapping
> > API.
> > 
> > I *think* what happens is that the driver allocates a global queue
> > used for RX and TX on both interfaces, then initializes that with
> > page pointers and gives that to the hardware to play with.
> > 
> > When an RX packet comes in, the RX routine needs to figure
> > out from the DMA (physical) address which remapped
> > page/address this random physical address pointer
> > corresponds to.
> > 
> > The Linux DMA API assumption is that the driver keeps track
> > of this mapping, not the hardware. So we need to figure out
> > a way to reverse-map this. Preferably quickly, and without
> > using any ARM-internal mapping APIs.
> 
> IIRC, the hardware copies descriptors from free queue (FREEQ)
> to RX queues. FREEQ is shared among the two ethernet ports.
> 
> This platform is CPU bound, so every additional lookup will
> hit performance here. In my version I had an #ifdef for
> COMPILE_TEST that replaced ARM-specific calls with stubs.
> Since the driver is not expected to work on other platforms,
> this seemed like the best workaround to make it compile
> on other arches.

Really.  No.  Stop going beneath the covers and using ARM private
implementation APIs in drivers.

Take that as a big NAK to that.

(I don't seem have the patch in question here to look at though.)
Linus Walleij Dec. 18, 2017, 8:55 p.m. UTC | #4
On Mon, Dec 18, 2017 at 3:54 PM, Russell King - ARM Linux
<linux@armlinux.org.uk> wrote:
> On Mon, Dec 18, 2017 at 03:48:17PM +0100, Michał Mirosław wrote:
>> On Mon, Dec 18, 2017 at 02:57:37PM +0100, Linus Walleij wrote:
>> > On Sat, Dec 16, 2017 at 8:39 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
>> >
>> > > The Gemini ethernet has been around for years as an out-of-tree
>> > > patch used with the NAS boxen and routers built on StorLink
>> > > SL3512 and SL3516, later Storm Semiconductor, later Cortina
>> > > Systems. These ASICs are still being deployed and brand new
>> > > off-the-shelf systems using it can easily be acquired.
>> [...]
>> > > ---
>> > > Changes from v8:
>> > > - Remove dependency guards in Kconfig to get a wider compile
>> > >   coverage for the driver to detect broken APIs etc.
>> >
>> > I guess we need to hold this off for a while, the code does
>> > some weird stuff using the ARM-internal page DMA mapping
>> > API.
>> >
>> > I *think* what happens is that the driver allocates a global queue
>> > used for RX and TX on both interfaces, then initializes that with
>> > page pointers and gives that to the hardware to play with.
>> >
>> > When an RX packet comes in, the RX routine needs to figure
>> > out from the DMA (physical) address which remapped
>> > page/address this random physical address pointer
>> > corresponds to.
>> >
>> > The Linux DMA API assumption is that the driver keeps track
>> > of this mapping, not the hardware. So we need to figure out
>> > a way to reverse-map this. Preferably quickly, and without
>> > using any ARM-internal mapping APIs.
>>
>> IIRC, the hardware copies descriptors from free queue (FREEQ)
>> to RX queues. FREEQ is shared among the two ethernet ports.

Seems like that to me too. I will try to refactor and break it
apart a bit.

The way freeq works is undocumented, even in the official
datasheet for CS3516 (the memory area is just "reserved"),
so the code is the only documentation of it.

>> This platform is CPU bound, so every additional lookup will
>> hit performance here. In my version I had an #ifdef for
>> COMPILE_TEST that replaced ARM-specific calls with stubs.
>> Since the driver is not expected to work on other platforms,
>> this seemed like the best workaround to make it compile
>> on other arches.
>
> Really.  No.  Stop going beneath the covers and using ARM private
> implementation APIs in drivers.
>
> Take that as a big NAK to that.

Don't worry, it won't happen. I am already thinking about better
approaches that stay with the public DMA-API.

> (I don't seem have the patch in question here to look at though.)

I'll put you on CC in future postings.

Yours,
Linus Walleij
diff mbox series

Patch

diff --git a/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt b/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt
new file mode 100644
index 000000000000..6c559981d110
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt
@@ -0,0 +1,92 @@ 
+Cortina Systems Gemini Ethernet Controller
+==========================================
+
+This ethernet controller is found in the Gemini SoC family:
+StorLink SL3512 and SL3516, also known as Cortina Systems
+CS3512 and CS3516.
+
+Required properties:
+- compatible: must be "cortina,gemini-ethernet"
+- reg: must contain the global registers and the V-bit and A-bit
+  memory areas, in total three register sets.
+- syscon: a phandle to the system controller
+- #address-cells: must be specified, must be <1>
+- #size-cells: must be specified, must be <1>
+- ranges: should be state like this giving a 1:1 address translation
+  for the subnodes
+
+The subnodes represents the two ethernet ports in this device.
+They are not independent of each other since they share resources
+in the parent node, and are thus children.
+
+Required subnodes:
+- port0: contains the resources for ethernet port 0
+- port1: contains the resources for ethernet port 1
+
+Required subnode properties:
+- compatible: must be "cortina,gemini-ethernet-port"
+- reg: must contain two register areas: the DMA/TOE memory and
+  the GMAC memory area of the port
+- interrupts: should contain the interrupt line of the port.
+  this is nominally a level interrupt active high.
+- resets: this must provide an SoC-integrated reset line for
+  the port.
+- clocks: this should contain a handle to the PCLK clock for
+  clocking the silicon in this port
+- clock-names: must be "PCLK"
+
+Optional subnode properties:
+- phy-mode: see ethernet.txt
+- phy-handle: see ethernet.txt
+
+Example:
+
+mdio-bus {
+	(...)
+	phy0: ethernet-phy@1 {
+		reg = <1>;
+		device_type = "ethernet-phy";
+	};
+	phy1: ethernet-phy@3 {
+		reg = <3>;
+		device_type = "ethernet-phy";
+	};
+};
+
+
+ethernet@60000000 {
+	compatible = "cortina,gemini-ethernet";
+	reg = <0x60000000 0x4000>, /* Global registers, queue */
+	      <0x60004000 0x2000>, /* V-bit */
+	      <0x60006000 0x2000>; /* A-bit */
+	syscon = <&syscon>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges;
+
+	gmac0: ethernet-port@0 {
+		compatible = "cortina,gemini-ethernet-port";
+		reg = <0x60008000 0x2000>, /* Port 0 DMA/TOE */
+		      <0x6000a000 0x2000>; /* Port 0 GMAC */
+		interrupt-parent = <&intcon>;
+		interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
+		resets = <&syscon GEMINI_RESET_GMAC0>;
+		clocks = <&syscon GEMINI_CLK_GATE_GMAC0>;
+		clock-names = "PCLK";
+		phy-mode = "rgmii";
+		phy-handle = <&phy0>;
+	};
+
+	gmac1: ethernet-port@1 {
+		compatible = "cortina,gemini-ethernet-port";
+		reg = <0x6000c000 0x2000>, /* Port 1 DMA/TOE */
+		      <0x6000e000 0x2000>; /* Port 1 GMAC */
+		interrupt-parent = <&intcon>;
+		interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
+		resets = <&syscon GEMINI_RESET_GMAC1>;
+		clocks = <&syscon GEMINI_CLK_GATE_GMAC1>;
+		clock-names = "PCLK";
+		phy-mode = "rgmii";
+		phy-handle = <&phy1>;
+	};
+};