From nobody Thu Sep 24 23:33:31 2026 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D90502C15A0; Fri, 18 Sep 2026 15:14:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.193 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789744451; cv=none; b=Pi3bk48ehR5gGnEJZQHuNVPLzep8qdhO3s8Rw3tkbDQ/aZ3CfkErWnVc7/TJVEy71F9ebs1LDda+A4Qht2KAgGZD7IjYOprpo/VfKR+L9xSN1tcxY0qtscBOs/Ut6y1nj299xYFsHlxXmZHopldqhCxM7WfT+Rai9k57Az9XfEs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789744451; c=relaxed/simple; bh=+I/qTNy5wusN95y1K2LBqQCJN0koBjQAqT3LQ6kFPIg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GtAwFp7KaKDYyArgfgwGzm/iWOu45TCxj8pl5tGshmUIwtu7tVxNwYItVLndCfd5aBMXtk6w6N5VFvS4J8FErypA6GcbetB+nRMdHqGZxnfiQNEestnEPyjKGdXHK0KfDlvRCt+PqmMT0g20TnvAT/BiW2UUFxjsq6DLNNi85/M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marmottus.net; spf=pass smtp.mailfrom=marmottus.net; dkim=pass (2048-bit key) header.d=marmottus.net header.i=@marmottus.net header.b=UGxZM9PI; arc=none smtp.client-ip=217.70.183.193 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marmottus.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marmottus.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marmottus.net header.i=@marmottus.net header.b="UGxZM9PI" Received: by mail.gandi.net (Postfix) with ESMTPSA id 04A443E972; Fri, 18 Sep 2026 15:14:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marmottus.net; s=gm1; t=1789744446; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AZmcxDmxZ4YT2+eMBhUSakgSgo7dVh5HubdgLZqcTjk=; b=UGxZM9PIiDqhTlOwRtzWIhd9F55HbbfXJADH20VwkPoRk1aelbq5QpjutTcrmFgak0CNOX sQPRUCNsGiT0YzvEfaZj9z2dRLge4CbrziaSLzKi7QY/vjYwKVOUkXWFswtFGzCVxm2x93 Yb7b3qsDuDHKEST8pxR+lfvF5LMyyInuioM4lb4hylankrdS24kaoqhhexuDEzvXTjEV8T RXwnwKwshxiuWa8eSArm3i126ccEmslhBjPmIZnSiC7bPIzXXbrlKnAX0S3seZs6MHKSAm OWvs1f62KrJUkgFICOYORBi0gqNuQnWUe58D1S/SQ8hc1cWGTJDQdeAwXklDQg== From: Arthur Crepin Leblond Date: Fri, 18 Sep 2026 17:13:53 +0200 Subject: [PATCH net-next v9 1/3] dt-bindings: net: wiznet,w5100: convert to DT schema Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260918-wiznet-link-gpio-v9-1-5536f24d8d6d@marmottus.net> References: <20260918-wiznet-link-gpio-v9-0-5536f24d8d6d@marmottus.net> In-Reply-To: <20260918-wiznet-link-gpio-v9-0-5536f24d8d6d@marmottus.net> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Arnd Bergmann , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Arthur Crepin Leblond , Krzysztof Kozlowski X-Mailer: b4 0.15.2 X-GND-Sasl: arthur@marmottus.net X-GND-State: clean X-GND-Score: -100 X-GND-Cause: dmFkZTFls0bAkj+Lr/fwGgGfgvHYiZxHxyuqL7P2PAjM38fI0GNXj5eI3EaGB+AqFjIi7VCzMNZYffuM2Jel6uAhYS7P0LtOFv4ncQJbGiWNX8NQpMMeoN8xTh0nNgIwhMQxPYTlm7kpfNZxj4knydSL+h8Ubuui6rzCtYhTBYcZwUV9E8qGGZfwXAnypky3sTb2r7Q4taHlZBJDKJpU6JrkQNvzeHoJ5cIKKftUaKtgVcBz3zb3zyQ5fLOAz8/DbS/G7Qzun9kfUvjSjekMcxk4Fefo65U0Dju07CqUEKzKQo6Vz1h0W8Dgqhr86b59NI/gFMC2IOOYt9mpMCQ7H4kxtu9ybuW71WqH78nqlOsy9hhofCxEXEIib7ZQUcO4MVrr1RLXjgdXyQHW3fR2A8SCBIJipQxZmhk5/gyfSVGgbBlpqognT8KUSiITw78/8nDKnygRuY68eZdrfFXqiGmEOeys/ErFBBW3DuIYORnicXRpo2FnM75AGHv86XxRK8wXXqslLkWfjOGKKGSxOu/zOOU8lNP2chZA3kI8wJEyXxRbaXk9ZzxNzrisIyeNEjD7gYLR1kQD8Blsg3L/hy3QDsv/bMOIhHM/UflTMKi+JE+uHmfMlPyKzKm5bJbolvfxevOhkYBa26jjmG1z6ieQeqBvhScCNAMXS4kaPjq+Kw2QLA Convert the Wiznet w5x00 SPI Ethernet controller binding from plain text to DT schema. Change the trigger type from edge-falling to low to match the driver implementation. Signed-off-by: Arthur Crepin Leblond Reviewed-by: Krzysztof Kozlowski --- v9: - Add edge-falling->low in commit message v8: - Add a myself in MAINTAINERS - Address Sashiko reviews - Change edge-falling to level-low - Clarify the spi max frequency for all devices - Add main interrupt description v7: - No changes v6: - Put back the reviewed by tag from Krzysztof Kozlowski from v4 v5: - Remove gpio/gpio.h include from DT example - Fix DT bindings errors v4: - Update interrupts in DT bindings v3: - Fix DT binding errors v2: - Convert device tree binding to YAML --- .../devicetree/bindings/net/wiznet,w5100.yaml | 68 ++++++++++++++++++= ++++ .../devicetree/bindings/net/wiznet,w5x00.txt | 50 ---------------- MAINTAINERS | 6 ++ 3 files changed, 74 insertions(+), 50 deletions(-) diff --git a/Documentation/devicetree/bindings/net/wiznet,w5100.yaml b/Docu= mentation/devicetree/bindings/net/wiznet,w5100.yaml new file mode 100644 index 000000000000..25098308eb6e --- /dev/null +++ b/Documentation/devicetree/bindings/net/wiznet,w5100.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/wiznet,w5100.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Wiznet w5100/w5200/w5500 SPI Ethernet Controller + +maintainers: + - Arthur Crepin Leblond + +description: | + This is a standalone 10/100 MBit Ethernet controller with SPI interface. + +allOf: + - $ref: /schemas/net/ethernet-controller.yaml# + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +properties: + compatible: + enum: + - wiznet,w5100 + - wiznet,w5200 + - wiznet,w5500 + + interrupts: + maxItems: 1 + description: Main interrupt (INT pin on the device). + + reg: + maxItems: 1 + + spi-max-frequency: + description: + According to the datasheets, w5500 and w5200 allow a maximum of 80 M= Hz + while w5100 is reported by users to allow a maximum of 14 MHz. Howev= er, + board designs may need to limit this value. + maximum: 80000000 + +required: + - compatible + - reg + - interrupts + +unevaluatedProperties: false + +examples: + - | + /* Example (for Raspberry Pi with pin control stuff for GPIO irq) */ + + #include + + spi { + #address-cells =3D <1>; + #size-cells =3D <0>; + + ethernet@0 { + compatible =3D "wiznet,w5500"; + reg =3D <0>; + pinctrl-names =3D "default"; + pinctrl-0 =3D <ð1_pins>; + interrupt-parent =3D <&gpio>; + interrupts =3D <25 IRQ_TYPE_LEVEL_LOW>; + spi-max-frequency =3D <30000000>; + local-mac-address =3D [ a0 b0 c0 d0 e0 f0 ]; + }; + }; +... diff --git a/Documentation/devicetree/bindings/net/wiznet,w5x00.txt b/Docum= entation/devicetree/bindings/net/wiznet,w5x00.txt deleted file mode 100644 index e9665798c4be..000000000000 --- a/Documentation/devicetree/bindings/net/wiznet,w5x00.txt +++ /dev/null @@ -1,50 +0,0 @@ -* Wiznet w5x00 - -This is a standalone 10/100 MBit Ethernet controller with SPI interface. - -For each device connected to a SPI bus, define a child node within -the SPI master node. - -Required properties: -- compatible: Should be one of the following strings: - "wiznet,w5100" - "wiznet,w5200" - "wiznet,w5500" -- reg: Specify the SPI chip select the chip is wired to. -- interrupts: Specify the interrupt index within the interrupt controller = (referred - to above in interrupt-parent) and interrupt type. w5x00 nati= vely - generates falling edge interrupts, however, additional board= logic - might invert the signal. -- pinctrl-names: List of assigned state names, see pinctrl binding documen= tation. -- pinctrl-0: List of phandles to configure the GPIO pin used as interrupt = line, - see also generic and your platform specific pinctrl binding - documentation. - -Optional properties: -- spi-max-frequency: Maximum frequency of the SPI bus when accessing the w= 5500. - According to the w5500 datasheet, the chip allows a maximum of 80 MHz, h= owever, - board designs may need to limit this value. -- local-mac-address: See ethernet.txt in the same directory. - - -Example (for Raspberry Pi with pin control stuff for GPIO irq): - -&spi { - ethernet@0: w5500@0 { - compatible =3D "wiznet,w5500"; - reg =3D <0>; - pinctrl-names =3D "default"; - pinctrl-0 =3D <ð1_pins>; - interrupt-parent =3D <&gpio>; - interrupts =3D <25 IRQ_TYPE_EDGE_FALLING>; - spi-max-frequency =3D <30000000>; - }; -}; - -&gpio { - eth1_pins: eth1_pins { - brcm,pins =3D <25>; - brcm,function =3D <0>; /* in */ - brcm,pull =3D <0>; /* none */ - }; -}; diff --git a/MAINTAINERS b/MAINTAINERS index cae5962045dd..e6a5a4e245a0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -29439,6 +29439,12 @@ M: Miloslav Trmac S: Maintained F: drivers/input/misc/wistron_btns.c =20 +WIZNET W5100 ETHERNET DRIVER +M: Arthur Crepin Leblond +L: netdev@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/net/wiznet,w5100.yaml + WMI BINARY MOF DRIVER M: Armin Wolf R: Thomas Wei=C3=9Fschuh --=20 2.55.0 From nobody Thu Sep 24 23:33:31 2026 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 839304FDA7C; Fri, 18 Sep 2026 15:14:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.193 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789744452; cv=none; b=TJjI5ozMZoXew/Foeg/iQzdLsY/XoQQI8WlM2+6MVdX1BhlT60Le0LxQXXWtyzCpZ58MtGyiQJnuy3Wv11ws1j1wrkoYX7gg4OE/bwKFTf66/H8McktgnUfmvRVSZck29pSgymlnkWLEclc+wqwRqn+vqUdPuPSyS1cMk1jf5Wo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789744452; c=relaxed/simple; bh=P6hoLnRrxNgZe/hOkFs0XcLZKF4rcsUXbUU0x4k1rZY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=RbMQlTIt336l6hhtvhv9ozLVlWUEWmZJdT7avpSwVbItqF18Vr4czzT1UA9MT2K1NNt0aeK/TeyyriNMsv7vjuaISSovPknmC/SdCNwgWu4Di9KApYY2RhWkPYy5+8+7pcQgNRIhepXTtmfDn6DqvNgCvFeb7TOLvph9CIk9Rnc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marmottus.net; spf=pass smtp.mailfrom=marmottus.net; dkim=pass (2048-bit key) header.d=marmottus.net header.i=@marmottus.net header.b=XqnzOqhM; arc=none smtp.client-ip=217.70.183.193 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marmottus.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marmottus.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marmottus.net header.i=@marmottus.net header.b="XqnzOqhM" Received: by mail.gandi.net (Postfix) with ESMTPSA id 1291B3E994; Fri, 18 Sep 2026 15:14:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marmottus.net; s=gm1; t=1789744448; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nJD01rN5UEa3pjfOwFaAzn/OShX3dU5FY+R3aedzBzo=; b=XqnzOqhMWivqqI7W9QTW3hpBr1wvFfcMYDKluK1Vyy2vrJXi4x7jbs8KsSTEV1ycSx6GZR XkJeSsaB+8GLb0uzu19jxzO1vYoSRpywHlprGMsKJBAw5+Z8CK2QWFziq9vfrdWE/e9d87 l8SA7XAY1L8pPW/EH9P4yCbKnzPQLyH2Sxkzw2NI1iQOuaF76nsorxjmBvVRo4jfP4EVJ6 fuEheebvRPLOisWr4xmi8ZePtyGYHRqYQMzbxoV6ZTToF1kDbngFSVUg2rgB04ERRbrMeK abw33LEpkvEGzRK4f43Sll33ma30HsqaeZDJk1NNGF3aTSGQONzpqPUac6ILYw== From: Arthur Crepin Leblond Date: Fri, 18 Sep 2026 17:13:54 +0200 Subject: [PATCH net-next v9 2/3] dt-bindings: net: wiznet,w5100: add link status interrupt Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260918-wiznet-link-gpio-v9-2-5536f24d8d6d@marmottus.net> References: <20260918-wiznet-link-gpio-v9-0-5536f24d8d6d@marmottus.net> In-Reply-To: <20260918-wiznet-link-gpio-v9-0-5536f24d8d6d@marmottus.net> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Arnd Bergmann , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Arthur Crepin Leblond X-Mailer: b4 0.15.2 X-GND-Sasl: arthur@marmottus.net X-GND-State: clean X-GND-Score: -100 X-GND-Cause: dmFkZTFS2sth9ps5Z787jmCwf5jUB4saRsy3OjoHb9M4YNA5CDF7I2Mi7BiMfC9+pXRW620mnrspKoKpuOc0KfwAyeWCVCbV9ihLJRxo8ERcxkmdm2DobYI3tVzkDTrt9anaHq9cTSwZq2hofIYHMnYhpdKVL/i+8qiX3vs6lJPcKpu1NGUXorkAEbog0SmgQ04AmGgqICTJVuJmwGqWEHBDoO6GwMfFN2nybgVOhoOZt9dogl9n011JuRx7lK1oLSNPM1QpWV+kQddhVCNqhKijs6Cz5AK23nglakh+K2j6VL4/OavLC4HjoRLI2pYkHkstuapRWIfXpBsbycJgXrXKqb1fICiVbX3hIeWoBrAIvlvPunwgVKS69+SFpGCPYaUI1ORnDunXpySvmZnCsRfNYdLQiIStrBSmZIqZAzDJH09gSwLBkD1iYAUpcWqJXFVdAtp//7HNia5PYeCf65xal76SwalU5NCx2xJNOxXrC35hshGc59TSM9FlHIkUpXQA/M1ICsgzv3aCd73DJGEBsfe7TasM80sgYlDMUYxL6bujpSL0FOY72dE6hFsoJTKJnKDqvo3tvww1EhnXI1J9Yt/ghAsh+Xvd9DyDvNSIxdbNZoJzZQ1QhcDrlUnKvunIFYwFgVrmXTkyTBj23m6eiVaMUg1GeJGOBDm3VX0imeHU/Q Add an optional link status interrupt which can be connected to the LINKLED pin on the device to detect link status changes. This second interrupt is only supported on wiznet,w5500. Signed-off-by: Arthur Crepin Leblond --- v9: - Simplify the interrupts description: - Describe the 2 interrupts in the top-level properties - Limit the maximum number to 1 on non-w5500 with a condition - Somehow only adding minItems in the top-level and then describing 2 items in the if block led to dt checks errors. v8: - Remove Krzysztof Kozlowski reviewed-by tag after Sashiko review changes - Make the interrupts property conditional v7: - No changes v6: - Fix DT error: use minItems - Remove conditional properties v5: - Make the DT interrupts property dynamic from the compatible one - Fix DT bindings errors v4: - Update interrupts in DT bindings v3: - Fix DT binding errors v2: - Convert device tree binding to YAML --- .../devicetree/bindings/net/wiznet,w5100.yaml | 34 +++++++++++++++++-= ---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/net/wiznet,w5100.yaml b/Docu= mentation/devicetree/bindings/net/wiznet,w5100.yaml index 25098308eb6e..ac2ee725af5d 100644 --- a/Documentation/devicetree/bindings/net/wiznet,w5100.yaml +++ b/Documentation/devicetree/bindings/net/wiznet,w5100.yaml @@ -12,10 +12,6 @@ maintainers: description: | This is a standalone 10/100 MBit Ethernet controller with SPI interface. =20 -allOf: - - $ref: /schemas/net/ethernet-controller.yaml# - - $ref: /schemas/spi/spi-peripheral-props.yaml# - properties: compatible: enum: @@ -24,8 +20,16 @@ properties: - wiznet,w5500 =20 interrupts: - maxItems: 1 - description: Main interrupt (INT pin on the device). + minItems: 1 + description: + The main interrupt (INT pin) is mandatory on all devices. The w5500 + additionally supports an optional second interrupt for link status c= hanges + (LINKLED pin). If it is not specified, link state changes will not be + reported. + items: + - description: Main interrupt (INT pin on the device). + - description: + Optional interrupt for link status changes (LINKLED pin on w5500= ). =20 reg: maxItems: 1 @@ -42,6 +46,21 @@ required: - reg - interrupts =20 +allOf: + - $ref: /schemas/net/ethernet-controller.yaml# + - $ref: /schemas/spi/spi-peripheral-props.yaml# + - if: + not: + properties: + compatible: + contains: + enum: + - wiznet,w5500 + then: + properties: + interrupts: + maxItems: 1 + unevaluatedProperties: false =20 examples: @@ -60,7 +79,8 @@ examples: pinctrl-names =3D "default"; pinctrl-0 =3D <ð1_pins>; interrupt-parent =3D <&gpio>; - interrupts =3D <25 IRQ_TYPE_LEVEL_LOW>; + interrupts =3D <25 IRQ_TYPE_LEVEL_LOW>, + <24 IRQ_TYPE_EDGE_BOTH>; spi-max-frequency =3D <30000000>; local-mac-address =3D [ a0 b0 c0 d0 e0 f0 ]; }; --=20 2.55.0 From nobody Thu Sep 24 23:33:31 2026 Received: from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net [217.70.183.193]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B9EFF5013C4; Fri, 18 Sep 2026 15:14:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.193 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789744455; cv=none; b=StOzroYxlubhKso++iOUZNayeC1nm90EUMifp6k1Nx5rc5qhlKon713zFvb5iE6k+MfJgHTcVJWN22wnsDXJiKezax0CJUkUkRe+ImkEYN//S7cBbUO1qVMjdhPNlI810EFDfL/5rrkewmBPHoDBZDkhB7x6eyhfLHOpjGtc9p8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789744455; c=relaxed/simple; bh=U17uwyjqWSLUicsyQbJaDeASIbAWpfb0sKzKv2PO+3U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=JPaAQrGNWmZqT/2gilfV1RHWlFfONg0juI6fyF0yF1OESttoMdcjGPDO2Vh4i7pfIbdoeTqDEhMo9EY2c06vtBtTfK2AgVrN+orW9JypsnNeLOUedOdPgaJL1bZhlTwwFzRMmuQg982N07pig5ISotAjbj5sZN3EyhDVZjT8Ucg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marmottus.net; spf=pass smtp.mailfrom=marmottus.net; dkim=pass (2048-bit key) header.d=marmottus.net header.i=@marmottus.net header.b=bbYJIqwO; arc=none smtp.client-ip=217.70.183.193 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marmottus.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marmottus.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marmottus.net header.i=@marmottus.net header.b="bbYJIqwO" Received: by mail.gandi.net (Postfix) with ESMTPSA id 04F823EF93; Fri, 18 Sep 2026 15:14:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marmottus.net; s=gm1; t=1789744450; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=o4FDHcN0dBTzUzRdscUDZpmj3PQrCRMpKATUEGZvSTM=; b=bbYJIqwOw50NENBnZL7IhK4hQrCzMtWIkMxYP6nIP9as10GynmjRjFNwVapGn8jNUl8QfZ 8u4o5baFObwPvmVxGm5cXDTUTXMZ35yw4PVVElJ81QmTbSVY/3yZcJ1GAFNfK18j7OS0xS pxvB0qx2WFPNU1sWgBWEUG7aEcpNGzVTaaxy3bY0JbRSDCXysd8qaGHvOwK7HL6wbhkSoD eoDSOoyTWylg4vCX5PEG0xBTJF0gx+jiNH1v37iK/ukZcO7oESgh5ntLH5G40GR8e6oV2A AU4/nZNccFhmHxo7fzDZ3fgoVFUpKiS4gpzGuEQZCudORe3igi4F48zjsYBV/w== From: Arthur Crepin Leblond Date: Fri, 18 Sep 2026 17:13:55 +0200 Subject: [PATCH net-next v9 3/3] w5100: detect carrier state using link status bit and optional interrupt Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260918-wiznet-link-gpio-v9-3-5536f24d8d6d@marmottus.net> References: <20260918-wiznet-link-gpio-v9-0-5536f24d8d6d@marmottus.net> In-Reply-To: <20260918-wiznet-link-gpio-v9-0-5536f24d8d6d@marmottus.net> To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Arnd Bergmann , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Arthur Crepin Leblond X-Mailer: b4 0.15.2 X-GND-Sasl: arthur@marmottus.net X-GND-State: clean X-GND-Score: -100 X-GND-Cause: dmFkZTFS2sth9ps5Z787jmCwf5jUB4saRsy3OjoHb9M4YNA5CDF7I2Mi7BiMfC9+pXRW620mnrspKoKpuOc0KfwAyeWCVCbV9ihLJRxo8ERcxkmdm2DobYI3tVzkDTrt9anaHq9cTSwZq2hofIYHMnYhpdKVL/i+8qiX3vs6lJPcKpu1NGUXorkAEbog0SmgQ04AmGgqICTJVuJmwGqWEHBDoO6GwMfFN2nybgVOhoOZt9dogl9n011JuRx7lK1oLSNPM1QpWV+kQddhVCNqhKijs6Cz5AK23nglakh+K2j6VL4/OavLC4HjoRLI2pYkHkstuapRWIfXpBsbycJgXrXKqb1fnLtMNxiMlsN8wNwQd+4AiJMrDLqv/r+BH1Z4J1l0TxGfSjPvrFgQ2R/luXHauQ8dDnb/COH1AQPsnGuLO2BKzvT02FVOqMXX4Pxj4dEWVA+gNnYE9ryst4TCqatEoiinwiKoP2ipdz78PLHuD6wgImEQ7E6XuNcs88IZ5CsXc73NB7hmgfJ949XFiO5m15aqsS9IdAfXxNEueER0wkAMv3Q9kaUl2WWqgwWqwXa1DmhnqYSQo3vdpqXIckRZy/DoQU1orp5CwsBxTxk8+r8/T+LkeFF9wZmedd+KM/fx36mRHMwXOT2x2WInC3RDye48VmUlTItdkMI5A99h1DcoQg Detect the carrier state on the w5500 Ethernet controller using the Link Status bit from the PHY Configuration register (PHYCFGR). On w5100/w5200, which lack this register, .get_link() is not implemented and the carrier state is not reported. The carrier state is also not reported using netif_carrier_on|off(). For the w5500, add an optional interrupt, wired to the LINKLED pin of the device, to detect link status changes with a read of the PHYCFGR register and update of the carrier state with netif_carrier_on|off(). If this interrupt is not set in the DT binding, only .get_link() can be used to get the carrier state, netif_carrier_on|off() is not called. The interrupt handler and the PHYCFGR register read are synchronized using a mutex. A few changes are brought to the bring-up teardown: - The net device is registered last in the probe() function so no operation can be performed before the probing is finished - the net device is unregistered first in remove() - dev_name is now used instead of netdev_name - w5100_remove(), w5100_stop() and w5100_suspend() call cancel_work_sync()/flush_work() to make sure there is no pending work - the main irq is enabled/disabled in open()/stop() and suspend()/resume() - enable the link irq after checking PHYCFGR Commit dacf281771a9 ("w5100: remove unused gpio link detection") dropped the link_gpio/link_irq handling on the grounds that no devicetree user passed a "link" gpio at the time and that it used the old gpio interface. This isn't a plain revert of that removal: link detection is now done using a second interrupt rather than a gpio with a documented DT binding. Signed-off-by: Arthur Crepin Leblond --- v9: - Address Sashiko review - Rework commit message - Disable the link irq first in w5100_stop() - Call w5100_hw_close earlier in w5100_stop() - Flush rx/tx work and cancel restart in w5100_stop() - Call cancel_work_sync() after unregister_netdev in w5100_remove() - Call cancel_work_sync before netif_carrier_off in w5100_suspend() - Enable/Disable main irq in open()/stop() and suspend()/resume() - Check the number of irqs defined in DT - Ignore fwnode_irq_get errors other than EPROBE_DEFER v8: - Add myself in the MAINTAINERS file - Address Sashiko reviews from online bot and locally run - Add a mutex to synchronize the link state read and interrupt - Return last known carrier state (netif_carrier_ok()) in w5500_get_link on SPI error or if the device is not present - Only set ops .get_link on w5500 - Check the netif state, disable/enable the irq and re-check the carrier state in w5100_restart - Cancel the restart work on stop/suspend - Only set carrier state to off in w5100_stop/suspend when a link irq is present - Warn on fwnode_irq_get errors for the link irq - Free the main irq and flush queues before resetting the hardware in w5100_remove v7: - Address Sashiko reviews - Propagate spi read error to the caller - Do not change the state of the carrier on SPI read error - Enable the link IRQ before reading the PHYCFGR bit - Call unregister_netdev before reset - Update commit message v6: - Revert to the reviewed v4 version by Arnd Bergmann with a few changes based on Sashiko's review - Address Sashiko reviews - call netif_carrier_off in open if there is no link_irq or get_link returns false - call register_netdev at the very end of probe - call unregister_netdev before destroying work queue - handle link irq probe defer error - call netif_device_attach in resume before re enabling the link irq - disable the link irq first in suspend - log netif_err when PHYCFGR cannot be read - enable link irq in open - disable link irq in stop - free irq and invalidate it in remove v5: - Address Sashiko review - Read the link status register only on w5500 instead of checking link_irq - call netif_carrier_off on w5500 link status off in open - enable/disable the link irq in open/stop - enable/disable the link irq in resume/suspend - handle link irq probe defer error - register the netdev last v4: - Use directly an interrupt line instead of gpio -> irq - Address Sashiko reviews - drop devm_ on request_threaded_irq to avoid use after free - disable/enable the link_irq in the suspend/resume - only call netif_carrier_on|off if the link interrupt is present v3: - Use the Link Status bit of the PHY Configuration Register - Use the LINKLED gpio binding for change detection only v2: - Use devm_request_threaded_irq instead of request_any_context_irq - Use devm_gpiod_get_optional instead of gpiod_get_optional - Call dev_err_probe on gpiod_to_irq failure - Remove link_irq from priv - Use a fixed string for the IRQ name - Remove empty new lines --- MAINTAINERS | 1 + drivers/net/ethernet/wiznet/w5100.c | 220 ++++++++++++++++++++++++++++++++= ---- 2 files changed, 199 insertions(+), 22 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index e6a5a4e245a0..7e6f7a95a341 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -29444,6 +29444,7 @@ M: Arthur Crepin Leblond L: netdev@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/net/wiznet,w5100.yaml +F: drivers/net/ethernet/wiznet/ =20 WMI BINARY MOF DRIVER M: Armin Wolf diff --git a/drivers/net/ethernet/wiznet/w5100.c b/drivers/net/ethernet/wiz= net/w5100.c index 53d8dc642fbd..e6dc5fe7c088 100644 --- a/drivers/net/ethernet/wiznet/w5100.c +++ b/drivers/net/ethernet/wiznet/w5100.c @@ -18,9 +18,11 @@ #include #include #include +#include #include #include #include +#include #include =20 #include "w5100.h" @@ -124,6 +126,8 @@ MODULE_LICENSE("GPL"); */ #define W5500_SIMR 0x0018 /* Socket Interrupt Mask Register */ #define W5500_RTR 0x0019 /* Retry Time-value Register */ +#define W5500_PHYCFGR 0x002e /* PHY Configuration Register */ +#define PHYCFGR_LNK 0x01 /* Link status */ =20 #define W5500_S0_REGS 0x10000 =20 @@ -154,6 +158,9 @@ struct w5100_priv { u16 s0_rx_buf_size; =20 int irq; + int link_irq; + /* Protects link state and carrier updates */ + struct mutex link_lock; =20 struct napi_struct napi; struct net_device *ndev; @@ -345,6 +352,77 @@ static void w5500_memory_configure(struct w5100_priv *= priv) } } =20 +static int w5500_get_phycfgr_lnk(struct net_device *ndev) +{ + struct w5100_priv *priv =3D netdev_priv(ndev); + int ret =3D w5100_read(priv, W5500_PHYCFGR); + + if (ret < 0) { + netif_err(priv, link, ndev, + "failed to read link status: %d\n", ret); + return ret; + } + + return ret & PHYCFGR_LNK; +} + +static void w5500_report_carrier_state(struct net_device *ndev) +{ + struct w5100_priv *priv =3D netdev_priv(ndev); + int state; + + mutex_lock(&priv->link_lock); + + state =3D w5500_get_phycfgr_lnk(ndev); + if (state > 0) { + netif_info(priv, link, ndev, "link is up\n"); + netif_carrier_on(ndev); + } else if (state =3D=3D 0) { + netif_info(priv, link, ndev, "link is down\n"); + netif_carrier_off(ndev); + } + + mutex_unlock(&priv->link_lock); +} + +static irqreturn_t w5500_detect_link_interrupt(int irq, void *ndev_instanc= e) +{ + struct net_device *ndev =3D ndev_instance; + + if (netif_running(ndev)) + w5500_report_carrier_state(ndev); + + return IRQ_HANDLED; +} + +static u32 w5500_get_link(struct net_device *ndev) +{ + struct w5100_priv *priv =3D netdev_priv(ndev); + int state; + bool link; + + mutex_lock(&priv->link_lock); + + if (!netif_device_present(ndev)) { + link =3D netif_carrier_ok(ndev); + goto out; + } + + state =3D w5500_get_phycfgr_lnk(ndev); + + if (state < 0) { + link =3D netif_carrier_ok(ndev); + goto out; + } + + link =3D state > 0; + +out: + mutex_unlock(&priv->link_lock); + + return link; +} + static int w5100_hw_reset(struct w5100_priv *priv) { u32 rtr; @@ -448,12 +526,25 @@ static void w5100_restart(struct net_device *ndev) { struct w5100_priv *priv =3D netdev_priv(ndev); =20 + if (!netif_running(ndev) || !netif_device_present(ndev)) + return; + + disable_irq(priv->irq); + if (priv->link_irq > 0) + disable_irq(priv->link_irq); + netif_stop_queue(ndev); w5100_hw_reset(priv); + enable_irq(priv->irq); w5100_hw_start(priv); ndev->stats.tx_errors++; netif_trans_update(ndev); netif_wake_queue(ndev); + + if (priv->link_irq > 0) { + w5500_report_carrier_state(ndev); + enable_irq(priv->link_irq); + } } =20 static void w5100_restart_work(struct work_struct *work) @@ -656,9 +747,16 @@ static int w5100_open(struct net_device *ndev) struct w5100_priv *priv =3D netdev_priv(ndev); =20 netif_info(priv, ifup, ndev, "enabling\n"); - w5100_hw_start(priv); napi_enable(&priv->napi); + enable_irq(priv->irq); + w5100_hw_start(priv); netif_start_queue(ndev); + + if (priv->link_irq > 0) { + w5500_report_carrier_state(ndev); + enable_irq(priv->link_irq); + } + return 0; } =20 @@ -667,13 +765,38 @@ static int w5100_stop(struct net_device *ndev) struct w5100_priv *priv =3D netdev_priv(ndev); =20 netif_info(priv, ifdown, ndev, "shutting down\n"); + + disable_irq(priv->irq); + if (priv->link_irq > 0) + disable_irq(priv->link_irq); + + cancel_work_sync(&priv->restart_work); + cancel_work_sync(&priv->setrx_work); + flush_work(&priv->rx_work); + flush_work(&priv->tx_work); + w5100_hw_close(priv); - netif_carrier_off(ndev); + + if (priv->link_irq > 0) { + mutex_lock(&priv->link_lock); + netif_carrier_off(ndev); + mutex_unlock(&priv->link_lock); + } + netif_stop_queue(ndev); napi_disable(&priv->napi); return 0; } =20 +static const struct ethtool_ops w5500_ethtool_ops =3D { + .get_drvinfo =3D w5100_get_drvinfo, + .get_msglevel =3D w5100_get_msglevel, + .set_msglevel =3D w5100_set_msglevel, + .get_link =3D w5500_get_link, + .get_regs_len =3D w5100_get_regs_len, + .get_regs =3D w5100_get_regs, +}; + static const struct ethtool_ops w5100_ethtool_ops =3D { .get_drvinfo =3D w5100_get_drvinfo, .get_msglevel =3D w5100_get_msglevel, @@ -721,6 +844,8 @@ int w5100_probe(struct device *dev, const struct w5100_= ops *ops, dev_set_drvdata(dev, ndev); priv =3D netdev_priv(ndev); =20 + mutex_init(&priv->link_lock); + switch (ops->chip_id) { case W5100: priv->s0_regs =3D W5100_S0_REGS; @@ -745,15 +870,26 @@ int w5100_probe(struct device *dev, const struct w510= 0_ops *ops, break; default: err =3D -EINVAL; - goto err_register; + goto err_mutex; } =20 priv->ndev =3D ndev; priv->ops =3D ops; priv->irq =3D irq; =20 + priv->link_irq =3D -EINVAL; + if (ops->chip_id =3D=3D W5500) { + priv->link_irq =3D fwnode_irq_get(dev_fwnode(dev), 1); + if (priv->link_irq =3D=3D -EPROBE_DEFER) { + err =3D dev_err_probe(dev, priv->link_irq, + "failed to get link irq\n"); + goto err_mutex; + } + } + ndev->netdev_ops =3D &w5100_netdev_ops; - ndev->ethtool_ops =3D &w5100_ethtool_ops; + ndev->ethtool_ops =3D ops->chip_id =3D=3D W5500 ? &w5500_ethtool_ops : + &w5100_ethtool_ops; netif_napi_add_weight(ndev, &priv->napi, w5100_napi_poll, 16); =20 /* This chip doesn't support VLAN packets with normal MTU, @@ -761,15 +897,11 @@ int w5100_probe(struct device *dev, const struct w510= 0_ops *ops, */ ndev->features |=3D NETIF_F_VLAN_CHALLENGED; =20 - err =3D register_netdev(ndev); - if (err < 0) - goto err_register; - priv->xfer_wq =3D alloc_workqueue("%s", WQ_MEM_RECLAIM | WQ_PERCPU, 0, - netdev_name(ndev)); + dev_name(dev)); if (!priv->xfer_wq) { err =3D -ENOMEM; - goto err_wq; + goto err_mutex; } =20 INIT_WORK(&priv->rx_work, w5100_rx_work); @@ -794,22 +926,44 @@ int w5100_probe(struct device *dev, const struct w510= 0_ops *ops, =20 if (ops->may_sleep) { err =3D request_threaded_irq(priv->irq, NULL, w5100_interrupt, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - netdev_name(ndev), ndev); + IRQF_TRIGGER_LOW | IRQF_ONESHOT | + IRQF_NO_AUTOEN, + dev_name(dev), ndev); } else { err =3D request_irq(priv->irq, w5100_interrupt, - IRQF_TRIGGER_LOW, netdev_name(ndev), ndev); + IRQF_TRIGGER_LOW | IRQF_NO_AUTOEN, dev_name(dev), ndev); } if (err) goto err_hw; =20 + if (priv->link_irq > 0) { + err =3D request_threaded_irq(priv->link_irq, NULL, + w5500_detect_link_interrupt, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT | IRQF_NO_AUTOEN, + "w5100-link", ndev); + if (err < 0) + goto err_irq; + + netif_carrier_off(ndev); + } + + err =3D register_netdev(ndev); + if (err < 0) + goto err_link_irq; + return 0; =20 +err_link_irq: + if (priv->link_irq > 0) + free_irq(priv->link_irq, ndev); +err_irq: + free_irq(priv->irq, ndev); err_hw: destroy_workqueue(priv->xfer_wq); -err_wq: - unregister_netdev(ndev); -err_register: +err_mutex: + mutex_destroy(&priv->link_lock); free_netdev(ndev); return err; } @@ -820,14 +974,19 @@ void w5100_remove(struct device *dev) struct net_device *ndev =3D dev_get_drvdata(dev); struct w5100_priv *priv =3D netdev_priv(ndev); =20 - w5100_hw_reset(priv); + unregister_netdev(ndev); + + if (priv->link_irq > 0) + free_irq(priv->link_irq, ndev); free_irq(priv->irq, ndev); =20 - flush_work(&priv->setrx_work); - flush_work(&priv->restart_work); - destroy_workqueue(priv->xfer_wq); + w5100_hw_reset(priv); =20 - unregister_netdev(ndev); + cancel_work_sync(&priv->setrx_work); + cancel_work_sync(&priv->restart_work); + + destroy_workqueue(priv->xfer_wq); + mutex_destroy(&priv->link_lock); free_netdev(ndev); } EXPORT_SYMBOL_GPL(w5100_remove); @@ -839,7 +998,18 @@ static int w5100_suspend(struct device *dev) struct w5100_priv *priv =3D netdev_priv(ndev); =20 if (netif_running(ndev)) { - netif_carrier_off(ndev); + disable_irq(priv->irq); + if (priv->link_irq > 0) + disable_irq(priv->link_irq); + + cancel_work_sync(&priv->restart_work); + + if (priv->link_irq > 0) { + mutex_lock(&priv->link_lock); + netif_carrier_off(ndev); + mutex_unlock(&priv->link_lock); + } + netif_device_detach(ndev); =20 w5100_hw_close(priv); @@ -854,9 +1024,15 @@ static int w5100_resume(struct device *dev) =20 if (netif_running(ndev)) { w5100_hw_reset(priv); + enable_irq(priv->irq); w5100_hw_start(priv); =20 netif_device_attach(ndev); + + if (priv->link_irq > 0) { + w5500_report_carrier_state(ndev); + enable_irq(priv->link_irq); + } } return 0; } --=20 2.55.0