linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface
@ 2024-04-18 12:56 Parthiban Veerasooran
  2024-04-18 12:56 ` [PATCH net-next v4 01/12] Documentation: networking: add OPEN Alliance 10BASE-T1x MAC-PHY serial interface Parthiban Veerasooran
                   ` (15 more replies)
  0 siblings, 16 replies; 96+ messages in thread
From: Parthiban Veerasooran @ 2024-04-18 12:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean
  Cc: UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler,
	Parthiban Veerasooran

This patch series contain the below updates,
- Adds support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface in the
  net/ethernet/oa_tc6.c.
  Link to the spec:
  -----------------
  https://opensig.org/download/document/OPEN_Alliance_10BASET1x_MAC-PHY_Serial_Interface_V1.1.pdf

- Adds driver support for Microchip LAN8650/1 Rev.B1 10BASE-T1S MACPHY
  Ethernet driver in the net/ethernet/microchip/lan865x/lan865x.c.
  Link to the product:
  --------------------
  https://www.microchip.com/en-us/product/lan8650

Testing Details:
----------------
The driver performance was tested using iperf3 in the below two setups
separately.

Setup 1:
--------
Node 0 - Raspberry Pi 4 with LAN8650 MAC-PHY 
Node 1 - Raspberry Pi 4 with EVB-LAN8670-USB USB Stick

Setup 2:
--------
Node 0 - SAMA7G54-EK with LAN8650 MAC-PHY 
Node 1 - Raspberry Pi 4 with EVB-LAN8670-USB USB Stick

Achieved maximum of 9.4 Mbps.

Some systems like Raspberry Pi 4 need performance mode enabled to get the
proper clock speed for SPI. Refer below link for more details.

https://github.com/raspberrypi/linux/issues/3381#issuecomment-1144723750

Changes:
v2:
- Removed RFC tag.
- OA TC6 framework configured in the Kconfig and Makefile to compile as a
  module.
- Kerneldoc headers added for all the API methods exposed to MAC driver.
- Odd parity calculation logic updated from the below link,
  https://elixir.bootlin.com/linux/latest/source/lib/bch.c#L348
- Control buffer memory allocation moved to the initial function.
- struct oa_tc6 implemented as an obaque structure.
- Removed kthread for handling mac-phy interrupt instead threaded irq is
  used.
- Removed interrupt implementation for soft reset handling instead of
  that polling has been implemented.
- Registers name in the defines changed according to the specification
  document.
- Registers defines are arranged in the order of offset and followed by
  register fields.
- oa_tc6_write_register() implemented for writing a single register and
  oa_tc6_write_registers() implemented for writing multiple registers.
- oa_tc6_read_register() implemented for reading a single register and
  oa_tc6_read_registers() implemented for reading multiple registers.
- Removed DRV_VERSION macro as git hash provided by ethtool.
- Moved MDIO bus registration and PHY initialization to the OA TC6 lib.
- Replaced lan865x_set/get_link_ksettings() functions with
  phy_ethtool_ksettings_set/get() functions.
- MAC-PHY's standard capability register values checked against the
  user configured values.
- Removed unnecessary parameters validity check in various places.
- Removed MAC address configuration in the lan865x_net_open() function as
  it is done in the lan865x_probe() function already.
- Moved standard registers and proprietary vendor registers to the
  respective files.
- Added proper subject prefixes for the DT bindings.
- Moved OA specific properties to a separate DT bindings and corrected the
  types & mistakes in the DT bindings.
- Inherited OA specific DT bindings to the LAN865x specific DT bindings.
- Removed sparse warnings in all the places.
- Used net_err_ratelimited() for printing the error messages.
- oa_tc6_process_rx_chunks() function and the content of oa_tc6_handler()
  function are split into small functions.
- Used proper macros provided by network layer for calculating the
  MAX_ETH_LEN.
- Return value of netif_rx() function handled properly.
- Removed unnecessary NULL initialization of skb in the
  oa_tc6_rx_eth_ready() function removed.
- Local variables declaration ordered in reverse xmas tree notation.

v3:
- Completely redesigned all the patches.
- Control and data interface patches are divided into multiple small
  patches.
- Device driver APIs added in the oa-tc6-framework.rst file.
- Code readability improved in all the patches.
- Defined macros wherever is possible.
- Changed RESETC to STATUS0_RESETC for improving the readability.
- Removed OA specific DT bindings.
- Used default configurations defined in the OA spec.
- All variables are named properly as per OA spec for more redability.
- Bigger functions are split into multiple smaller functions.
- DT binding check is done.
- Phy mask is removed in phy scanning.
- Used NET_RX_DROP to compare the rx packet submission status.
- Indentation in the Kconfig file corrected.
- Removed CONFIG_OF and CONFIG_ACPI ifdefs.
- Removed MODULE_ALIAS().

v4:
- Fixed indentation in oa-tc6-framework.rst file.
- Replaced ENODEV error code with EPROTO in the
  oa_tc6_check_ctrl_write_reply and oa_tc6_check_ctrl_read_reply()
  functions.
- Renamed oa_tc6_read_sw_reset_status() function as
  oa_tc6_read_status0().
- Changed software reset polling delay as 1ms and polling timeout as 1s.
- Implemented clause 45 registers direct access.
- Replaced ENODEV error code with ENOMEM in the
  oa_tc6_mdiobus_register() function.
- Changed transmit skbs queue size as 2.
- Added skb_linearize() function to convert contiguous packet data.
- Checked kthread_should_stop() in the oa_tc6_spi_thread_handler()
  function before proceeding for the oa_tc6_try_spi_transfer().
- Removed netdev_err() print in the oa_tc6_allocate_rx_skb() function.
- Added spi-peripheral-props reference in the dt-bindings.
- Changed the fallback order in the dt-bindings.
- Replaced netif_start_queue() with netif_wake_queue().
- Empty data transfer performed in the oa_tc6_init() function to clear
  the reset complete interrupt.
- ZARFE bit in the CONFIG0 register is set to 1 to avoid lan865x halt
  based on the recommendation in the lan865x errata.

Parthiban Veerasooran (12):
  Documentation: networking: add OPEN Alliance 10BASE-T1x MAC-PHY serial
    interface
  net: ethernet: oa_tc6: implement register write operation
  net: ethernet: oa_tc6: implement register read operation
  net: ethernet: oa_tc6: implement software reset
  net: ethernet: oa_tc6: implement error interrupts unmasking
  net: ethernet: oa_tc6: implement internal PHY initialization
  net: ethernet: oa_tc6: enable open alliance tc6 data communication
  net: ethernet: oa_tc6: implement transmit path to transfer tx ethernet
    frames
  net: ethernet: oa_tc6: implement receive path to receive rx ethernet
    frames
  net: ethernet: oa_tc6: implement mac-phy interrupt
  microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  dt-bindings: net: add Microchip's LAN865X 10BASE-T1S MACPHY

 .../bindings/net/microchip,lan865x.yaml       |   80 +
 Documentation/networking/oa-tc6-framework.rst |  491 ++++++
 MAINTAINERS                                   |   15 +
 drivers/net/ethernet/Kconfig                  |   11 +
 drivers/net/ethernet/Makefile                 |    1 +
 drivers/net/ethernet/microchip/Kconfig        |    1 +
 drivers/net/ethernet/microchip/Makefile       |    1 +
 .../net/ethernet/microchip/lan865x/Kconfig    |   19 +
 .../net/ethernet/microchip/lan865x/Makefile   |    6 +
 .../net/ethernet/microchip/lan865x/lan865x.c  |  384 +++++
 drivers/net/ethernet/oa_tc6.c                 | 1321 +++++++++++++++++
 drivers/net/phy/microchip_t1s.c               |   30 +
 include/linux/oa_tc6.h                        |   23 +
 include/uapi/linux/mdio.h                     |    1 +
 14 files changed, 2384 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/microchip,lan865x.yaml
 create mode 100644 Documentation/networking/oa-tc6-framework.rst
 create mode 100644 drivers/net/ethernet/microchip/lan865x/Kconfig
 create mode 100644 drivers/net/ethernet/microchip/lan865x/Makefile
 create mode 100644 drivers/net/ethernet/microchip/lan865x/lan865x.c
 create mode 100644 drivers/net/ethernet/oa_tc6.c
 create mode 100644 include/linux/oa_tc6.h

-- 
2.34.1


^ permalink raw reply	[flat|nested] 96+ messages in thread

* [PATCH net-next v4 01/12] Documentation: networking: add OPEN Alliance 10BASE-T1x MAC-PHY serial interface
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
@ 2024-04-18 12:56 ` Parthiban Veerasooran
  2024-04-28  9:33   ` Bagas Sanjaya
  2024-04-29 16:17   ` Simon Horman
  2024-04-18 12:56 ` [PATCH net-next v4 02/12] net: ethernet: oa_tc6: implement register write operation Parthiban Veerasooran
                   ` (14 subsequent siblings)
  15 siblings, 2 replies; 96+ messages in thread
From: Parthiban Veerasooran @ 2024-04-18 12:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean
  Cc: UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler,
	Parthiban Veerasooran

The IEEE 802.3cg project defines two 10 Mbit/s PHYs operating over a
single pair of conductors. The 10BASE-T1L (Clause 146) is a long reach
PHY supporting full duplex point-to-point operation over 1 km of single
balanced pair of conductors. The 10BASE-T1S (Clause 147) is a short reach
PHY supporting full / half duplex point-to-point operation over 15 m of
single balanced pair of conductors, or half duplex multidrop bus
operation over 25 m of single balanced pair of conductors.

Furthermore, the IEEE 802.3cg project defines the new Physical Layer
Collision Avoidance (PLCA) Reconciliation Sublayer (Clause 148) meant to
provide improved determinism to the CSMA/CD media access method. PLCA
works in conjunction with the 10BASE-T1S PHY operating in multidrop mode.

The aforementioned PHYs are intended to cover the low-speed / low-cost
applications in industrial and automotive environment. The large number
of pins (16) required by the MII interface, which is specified by the
IEEE 802.3 in Clause 22, is one of the major cost factors that need to be
addressed to fulfil this objective.

The MAC-PHY solution integrates an IEEE Clause 4 MAC and a 10BASE-T1x PHY
exposing a low pin count Serial Peripheral Interface (SPI) to the host
microcontroller. This also enables the addition of Ethernet functionality
to existing low-end microcontrollers which do not integrate a MAC
controller.

Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
---
 Documentation/networking/oa-tc6-framework.rst | 491 ++++++++++++++++++
 MAINTAINERS                                   |   6 +
 2 files changed, 497 insertions(+)
 create mode 100644 Documentation/networking/oa-tc6-framework.rst

diff --git a/Documentation/networking/oa-tc6-framework.rst b/Documentation/networking/oa-tc6-framework.rst
new file mode 100644
index 000000000000..35c85676e64a
--- /dev/null
+++ b/Documentation/networking/oa-tc6-framework.rst
@@ -0,0 +1,491 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+=========================================================================
+OPEN Alliance 10BASE-T1x MAC-PHY Serial Interface (TC6) Framework Support
+=========================================================================
+
+Introduction
+------------
+
+The IEEE 802.3cg project defines two 10 Mbit/s PHYs operating over a
+single pair of conductors. The 10BASE-T1L (Clause 146) is a long reach
+PHY supporting full duplex point-to-point operation over 1 km of single
+balanced pair of conductors. The 10BASE-T1S (Clause 147) is a short reach
+PHY supporting full / half duplex point-to-point operation over 15 m of
+single balanced pair of conductors, or half duplex multidrop bus
+operation over 25 m of single balanced pair of conductors.
+
+Furthermore, the IEEE 802.3cg project defines the new Physical Layer
+Collision Avoidance (PLCA) Reconciliation Sublayer (Clause 148) meant to
+provide improved determinism to the CSMA/CD media access method. PLCA
+works in conjunction with the 10BASE-T1S PHY operating in multidrop mode.
+
+The aforementioned PHYs are intended to cover the low-speed / low-cost
+applications in industrial and automotive environment. The large number
+of pins (16) required by the MII interface, which is specified by the
+IEEE 802.3 in Clause 22, is one of the major cost factors that need to be
+addressed to fulfil this objective.
+
+The MAC-PHY solution integrates an IEEE Clause 4 MAC and a 10BASE-T1x PHY
+exposing a low pin count Serial Peripheral Interface (SPI) to the host
+microcontroller. This also enables the addition of Ethernet functionality
+to existing low-end microcontrollers which do not integrate a MAC
+controller.
+
+Overview
+--------
+
+The MAC-PHY is specified to carry both data (Ethernet frames) and control
+(register access) transactions over a single full-duplex serial peripheral
+interface.
+
+Protocol Overview
+-----------------
+
+Two types of transactions are defined in the protocol: data transactions
+for Ethernet frame transfers and control transactions for register
+read/write transfers. A chunk is the basic element of data transactions
+and is composed of 4 bytes of overhead plus 64 bytes of payload size for
+each chunk. Ethernet frames are transferred over one or more data chunks.
+Control transactions consist of one or more register read/write control
+commands.
+
+SPI transactions are initiated by the SPI host with the assertion of CSn
+low to the MAC-PHY and ends with the deassertion of CSn high. In between
+each SPI transaction, the SPI host may need time for additional
+processing and to setup the next SPI data or control transaction.
+
+SPI data transactions consist of an equal number of transmit (TX) and
+receive (RX) chunks. Chunks in both transmit and receive directions may
+or may not contain valid frame data independent from each other, allowing
+for the simultaneous transmission and reception of different length
+frames.
+
+Each transmit data chunk begins with a 32-bit data header followed by a
+data chunk payload on MOSI. The data header indicates whether transmit
+frame data is present and provides the information to determine which
+bytes of the payload contain valid frame data.
+
+In parallel, receive data chunks are received on MISO. Each receive data
+chunk consists of a data chunk payload ending with a 32-bit data footer.
+The data footer indicates if there is receive frame data present within
+the payload or not and provides the information to determine which bytes
+of the payload contain valid frame data.
+
+Reference
+---------
+
+10BASE-T1x MAC-PHY Serial Interface Specification,
+
+Link: https://opensig.org/download/document/OPEN_Alliance_10BASET1x_MAC-PHY_Serial_Interface_V1.1.pdf
+
+Hardware Architecture
+---------------------
+
+.. code-block:: none
+
+  +----------+      +-------------------------------------+
+  |          |      |                MAC-PHY              |
+  |          |<---->| +-----------+  +-------+  +-------+ |
+  | SPI Host |      | | SPI Slave |  |  MAC  |  |  PHY  | |
+  |          |      | +-----------+  +-------+  +-------+ |
+  +----------+      +-------------------------------------+
+
+Software Architecture
+---------------------
+
+.. code-block:: none
+
+  +----------------------------------------------------------+
+  |                 Networking Subsystem                     |
+  +----------------------------------------------------------+
+            / \                             / \
+             |                               |
+             |                               |
+            \ /                              |
+  +----------------------+     +-----------------------------+
+  |     MAC Driver       |<--->| OPEN Alliance TC6 Framework |
+  +----------------------+     +-----------------------------+
+            / \                             / \
+             |                               |
+             |                               |
+             |                              \ /
+  +----------------------------------------------------------+
+  |                    SPI Subsystem                         |
+  +----------------------------------------------------------+
+                          / \
+                           |
+                           |
+                          \ /
+  +----------------------------------------------------------+
+  |                10BASE-T1x MAC-PHY Device                 |
+  +----------------------------------------------------------+
+
+Implementation
+--------------
+
+MAC Driver
+~~~~~~~~~~
+
+- Probed by SPI subsystem.
+
+- Initializes OA TC6 framework for the MAC-PHY.
+
+- Registers and configures the network device.
+
+- Sends the tx ethernet frames from n/w subsystem to OA TC6 framework.
+
+OPEN Alliance TC6 Framework
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- Initializes PHYLIB interface.
+
+- Registers mac-phy interrupt.
+
+- Performs mac-phy register read/write operation using the control
+  transaction protocol specified in the OPEN Alliance 10BASE-T1x MAC-PHY
+  Serial Interface specification.
+
+- Performs Ethernet frames transaction using the data transaction protocol
+  for Ethernet frames specified in the OPEN Alliance 10BASE-T1x MAC-PHY
+  Serial Interface specification.
+
+- Forwards the received Ethernet frame from 10Base-T1x MAC-PHY to n/w
+  subsystem.
+
+Data Transaction
+~~~~~~~~~~~~~~~~
+
+The Ethernet frames that are typically transferred from the SPI host to
+the MAC-PHY will be converted into multiple transmit data chunks. Each
+transmit data chunk will have a 4 bytes header which contains the
+information needed to determine the validity and the location of the
+transmit frame data within the 64 bytes data chunk payload.
+
+.. code-block:: none
+
+  +---------------------------------------------------+
+  |                     Tx Chunk                      |
+  | +---------------------------+  +----------------+ |   MOSI
+  | | 64 bytes chunk payload    |  | 4 bytes header | |------------>
+  | +---------------------------+  +----------------+ |
+  +---------------------------------------------------+
+
+4 bytes header contains the below fields,
+
+DNC (Bit 31) - Data-Not-Control flag. This flag specifies the type of SPI
+               transaction. For TX data chunks, this bit shall be ’1’.
+               0 - Control command
+               1 - Data chunk
+
+SEQ (Bit 30) - Data Chunk Sequence. This bit is used to indicate an
+               even/odd transmit data chunk sequence to the MAC-PHY.
+
+NORX (Bit 29) - No Receive flag. The SPI host may set this bit to prevent
+                the MAC-PHY from conveying RX data on the MISO for the
+                current chunk (DV = 0 in the footer), indicating that the
+                host would not process it. Typically, the SPI host should
+                set NORX = 0 indicating that it will accept and process
+                any receive frame data within the current chunk.
+
+RSVD (Bit 28..24) - Reserved: All reserved bits shall be ‘0’.
+
+VS (Bit 23..22) - Vendor Specific. These bits are implementation specific.
+                  If the MAC-PHY does not implement these bits, the host
+                  shall set them to ‘0’.
+
+DV (Bit 21) - Data Valid flag. The SPI host uses this bit to indicate
+              whether the current chunk contains valid transmit frame data
+              (DV = 1) or not (DV = 0). When ‘0’, the MAC-PHY ignores the
+              chunk payload. Note that the receive path is unaffected by
+              the setting of the DV bit in the data header.
+
+SV (Bit 20) - Start Valid flag. The SPI host shall set this bit when the
+              beginning of an Ethernet frame is present in the current
+              transmit data chunk payload. Otherwise, this bit shall be
+              zero. This bit is not to be confused with the Start-of-Frame
+              Delimiter (SFD) byte described in IEEE 802.3 [2].
+
+SWO (Bit 19..16) - Start Word Offset. When SV = 1, this field shall
+                   contain the 32-bit word offset into the transmit data
+                   chunk payload that points to the start of a new
+                   Ethernet frame to be transmitted. The host shall write
+                   this field as zero when SV = 0.
+
+RSVD (Bit 15) - Reserved: All reserved bits shall be ‘0’.
+
+EV (Bit 14) - End Valid flag. The SPI host shall set this bit when the end
+              of an Ethernet frame is present in the current transmit data
+              chunk payload. Otherwise, this bit shall be zero.
+
+EBO (Bit 13..8) - End Byte Offset. When EV = 1, this field shall contain
+                  the byte offset into the transmit data chunk payload
+                  that points to the last byte of the Ethernet frame to
+                  transmit. This field shall be zero when EV = 0.
+
+TSC (Bit 7..6) - Timestamp Capture. Request a timestamp capture when the
+                 frame is transmitted onto the network.
+                 00 - Do not capture a timestamp
+                 01 - Capture timestamp into timestamp capture register A
+                 10 - Capture timestamp into timestamp capture register B
+                 11 - Capture timestamp into timestamp capture register C
+
+RSVD (Bit 5..1) - Reserved: All reserved bits shall be ‘0’.
+
+P (Bit 0) - Parity. Parity bit calculated over the transmit data header.
+            Method used is odd parity.
+
+The number of buffers available in the MAC-PHY to store the incoming
+transmit data chunk payloads is represented as transmit credits. The
+available transmit credits in the MAC-PHY can be read either from the
+Buffer Status Register or footer (Refer below for the footer info)
+received from the MAC-PHY. The SPI host should not write more data chunks
+than the available transmit credits as this will lead to transmit buffer
+overflow error.
+
+In case the previous data footer had no transmit credits available and
+once the transmit credits become available for transmitting transmit data
+chunks, the MAC-PHY interrupt is asserted to SPI host. On reception of the
+first data header this interrupt will be deasserted and the received
+footer for the first data chunk will have the transmit credits available
+information.
+
+The Ethernet frames that are typically transferred from MAC-PHY to SPI
+host will be sent as multiple receive data chunks. Each receive data
+chunk will have 64 bytes of data chunk payload followed by 4 bytes footer
+which contains the information needed to determine the validity and the
+location of the receive frame data within the 64 bytes data chunk payload.
+
+.. code-block:: none
+
+  +---------------------------------------------------+
+  |                     Rx Chunk                      |
+  | +----------------+  +---------------------------+ |   MISO
+  | | 4 bytes footer |  | 64 bytes chunk payload    | |------------>
+  | +----------------+  +---------------------------+ |
+  +---------------------------------------------------+
+
+4 bytes footer contains the below fields,
+
+EXST (Bit 31) - Extended Status. This bit is set when any bit in the
+                STATUS0 or STATUS1 registers are set and not masked.
+
+HDRB (Bit 30) - Received Header Bad. When set, indicates that the MAC-PHY
+                received a control or data header with a parity error.
+
+SYNC (Bit 29) - Configuration Synchronized flag. This bit reflects the
+                state of the SYNC bit in the CONFIG0 configuration
+                register (see Table 12). A zero indicates that the MAC-PHY
+                configuration may not be as expected by the SPI host.
+                Following configuration, the SPI host sets the
+                corresponding bitin the configuration register which is
+                reflected in this field.
+
+RCA (Bit 28..24) - Receive Chunks Available. The RCA field indicates to
+                   the SPI host the minimum number of additional receive
+                   data chunks of frame data that are available for
+                   reading beyond the current receive data chunk. This
+                   field is zero when there is no receive frame data
+                   pending in the MAC-PHY’s buffer for reading.
+
+VS (Bit 23..22) - Vendor Specific. These bits are implementation specific.
+                  If not implemented, the MAC-PHY shall set these bits to
+                  ‘0’.
+
+DV (Bit 21) - Data Valid flag. The MAC-PHY uses this bit to indicate
+              whether the current receive data chunk contains valid
+              receive frame data (DV = 1) or not (DV = 0). When ‘0’, the
+              SPI host shall ignore the chunk payload.
+
+SV (Bit 20) - Start Valid flag. The MAC-PHY sets this bit when the current
+              chunk payload contains the start of an Ethernet frame.
+              Otherwise, this bit is zero. The SV bit is not to be
+              confused with the Start-of-Frame Delimiter (SFD) byte
+              described in IEEE 802.3 [2].
+
+SWO (Bit 19..16) - Start Word Offset. When SV = 1, this field contains the
+                   32-bit word offset into the receive data chunk payload
+                   containing the first byte of a new received Ethernet
+                   frame. When a receive timestamp has been added to the
+                   beginning of the received Ethernet frame (RTSA = 1)
+                   then SWO points to the most significant byte of the
+                   timestamp. This field will be zero when SV = 0.
+
+FD (Bit 15) - Frame Drop. When set, this bit indicates that the MAC has
+              detected a condition for which the SPI host should drop the
+              received Ethernet frame. This bit is only valid at the end
+              of a received Ethernet frame (EV = 1) and shall be zero at
+              all other times.
+
+EV (Bit 14) - End Valid flag. The MAC-PHY sets this bit when the end of a
+              received Ethernet frame is present in this receive data
+              chunk payload.
+
+EBO (Bit 13..8) - End Byte Offset: When EV = 1, this field contains the
+                  byte offset into the receive data chunk payload that
+                  locates the last byte of the received Ethernet frame.
+                  This field is zero when EV = 0.
+
+RTSA (Bit 7) - Receive Timestamp Added. This bit is set when a 32-bit or
+               64-bit timestamp has been added to the beginning of the
+               received Ethernet frame. The MAC-PHY shall set this bit to
+               zero when SV = 0.
+
+RTSP (Bit 6) - Receive Timestamp Parity. Parity bit calculated over the
+               32-bit/64-bit timestamp added to the beginning of the
+               received Ethernet frame. Method used is odd parity. The
+               MAC-PHY shall set this bit to zero when RTSA = 0.
+
+TXC (Bit 5..1) - Transmit Credits. This field contains the minimum number
+                 of transmit data chunks of frame data that the SPI host
+                 can write in a single transaction without incurring a
+                 transmit buffer overflow error.
+
+P (Bit 0) - Parity. Parity bit calculated over the receive data footer.
+            Method used is odd parity.
+
+SPI host will initiate the data receive transaction based on the receive
+chunks available in the MAC-PHY which is provided in the receive chunk
+footer (RCA - Receive Chunks Available). SPI host will create data invalid
+transmit data chunks (empty chunks) or data valid transmit data chunks in
+case there are valid Ethernet frames to transmit to the MAC-PHY. The
+receive chunks available in MAC-PHY can be read either from the Buffer
+Status Register or footer.
+
+In case the previous data footer had no receive data chunks available and
+once the receive data chunks become available again for reading, the
+MAC-PHY interrupt is asserted to SPI host. On reception of the first data
+header this interrupt will be deasserted and the received footer for the
+first data chunk will have the receive chunks available information.
+
+MAC-PHY Interrupt
+~~~~~~~~~~~~~~~~~
+
+The MAC-PHY interrupt is asserted when the following conditions are met.
+
+Receive chunks available - This interrupt is asserted when the previous
+data footer had no receive data chunks available and once the receive
+data chunks become available for reading. On reception of the first data
+header this interrupt will be deasserted.
+
+Transmit chunk credits available - This interrupt is asserted when the
+previous data footer indicated no transmit credits available and once the
+transmit credits become available for transmitting transmit data chunks.
+On reception of the first data header this interrupt will be deasserted.
+
+Extended status event - This interrupt is asserted when the previous data
+footer indicated no extended status and once the extended event become
+available. In this case the host should read status #0 register to know
+the corresponding error/event. On reception of the first data header this
+interrupt will be deasserted.
+
+Control Transaction
+~~~~~~~~~~~~~~~~~~~
+
+4 bytes control header contains the below fields,
+
+DNC (Bit 31) - Data-Not-Control flag. This flag specifies the type of SPI
+               transaction. For control commands, this bit shall be ‘0’.
+               0 - Control command
+               1 - Data chunk
+
+HDRB (Bit 30) - Received Header Bad. When set by the MAC-PHY, indicates
+                that a header was received with a parity error. The SPI
+                host should always clear this bit. The MAC-PHY ignores the
+                HDRB value sent by the SPI host on MOSI.
+
+WNR (Bit 29) - Write-Not-Read. This bit indicates if data is to be written
+               to registers (when set) or read from registers
+               (when clear).
+
+AID (Bit 28) - Address Increment Disable. When clear, the address will be
+               automatically post-incremented by one following each
+               register read or write. When set, address auto increment is
+               disabled allowing successive reads and writes to occur at
+               the same register address.
+
+MMS (Bit 27..24) - Memory Map Selector. This field selects the specific
+                   register memory map to access.
+
+ADDR (Bit 23..8) - Address. Address of the first register within the
+                   selected memory map to access.
+
+LEN (Bit 7..1) - Length. Specifies the number of registers to read/write.
+                 This field is interpreted as the number of registers
+                 minus 1 allowing for up to 128 consecutive registers read
+                 or written starting at the address specified in ADDR. A
+                 length of zero shall read or write a single register.
+
+P (Bit 0) - Parity. Parity bit calculated over the control command header.
+            Method used is odd parity.
+
+Control transactions consist of one or more control commands. Control
+commands are used by the SPI host to read and write registers within the
+MAC-PHY. Each control commands are composed of a 4 bytes control command
+header followed by register write data in case of control write command.
+
+The MAC-PHY ignores the final 4 bytes of data from the SPI host at the end
+of the control write command. The control write command is also echoed
+from the MAC-PHY back to the SPI host to identify which register write
+failed in case of any bus errors. The echoed Control write command will
+have the first 4 bytes unused value to be ignored by the SPI host
+followed by 4 bytes echoed control header followed by echoed register
+write data. Control write commands can write either a single register or
+multiple consecutive registers. When multiple consecutive registers are
+written, the address is automatically post-incremented by the MAC-PHY.
+Writing to any unimplemented or undefined registers shall be ignored and
+yield no effect.
+
+The MAC-PHY ignores all data from the SPI host following the control
+header for the remainder of the control read command. The control read
+command is also echoed from the MAC-PHY back to the SPI host to identify
+which register read is failed in case of any bus errors. The echoed
+Control read command will have the first 4 bytes of unused value to be
+ignored by the SPI host followed by 4 bytes echoed control header followed
+by register read data. Control read commands can read either a single
+register or multiple consecutive registers. When multiple consecutive
+registers are read, the address is automatically post-incremented by the
+MAC-PHY. Reading any unimplemented or undefined registers shall return
+zero.
+
+Device drivers API
+==================
+
+The include/linux/oa_tc6.h defines the following functions:
+
+.. c:function:: struct oa_tc6 *oa_tc6_init(struct spi_device *spi,
+                                           struct net_device *netdev)
+
+Initialize OA TC6 lib.
+
+.. c:function:: void oa_tc6_exit(struct oa_tc6 *tc6)
+
+Free allocated OA TC6 lib.
+
+.. c:function:: int oa_tc6_write_register(struct oa_tc6 *tc6, u32 address,
+                                          u32 value)
+
+Write a single register in the MAC-PHY.
+
+.. c:function:: int oa_tc6_write_registers(struct oa_tc6 *tc6, u32 address,
+                                           u32 value[], u8 length)
+
+Writing multiple consecutive registers starting from @address in the MAC-PHY.
+Maximum of 128 consecutive registers can be written starting at @address.
+
+.. c:function:: int oa_tc6_read_register(struct oa_tc6 *tc6, u32 address,
+                                         u32 *value)
+
+Read a single register in the MAC-PHY.
+
+.. c:function:: int oa_tc6_read_registers(struct oa_tc6 *tc6, u32 address,
+                                          u32 value[], u8 length)
+
+Reading multiple consecutive registers starting from @address in the MAC-PHY.
+Maximum of 128 consecutive registers can be read starting at @address.
+
+.. c:function:: netdev_tx_t oa_tc6_start_xmit(struct oa_tc6 *tc6,
+                                              struct sk_buff *skb);
+
+The transmit Ethernet frame in the skb is or going to be transmitted through
+the MAC-PHY.
diff --git a/MAINTAINERS b/MAINTAINERS
index 04e5f7c20e30..79fa7abb4ec9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16400,6 +16400,12 @@ L:	linux-rdma@vger.kernel.org
 S:	Supported
 F:	drivers/infiniband/ulp/opa_vnic
 
+OPEN ALLIANCE 10BASE-T1S MACPHY SERIAL INTERFACE FRAMEWORK
+M:	Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
+L:	netdev@vger.kernel.org
+S:	Maintained
+F:	Documentation/networking/oa-tc6-framework.rst
+
 OPEN FIRMWARE AND FLATTENED DEVICE TREE
 M:	Rob Herring <robh+dt@kernel.org>
 M:	Frank Rowand <frowand.list@gmail.com>
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 96+ messages in thread

* [PATCH net-next v4 02/12] net: ethernet: oa_tc6: implement register write operation
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
  2024-04-18 12:56 ` [PATCH net-next v4 01/12] Documentation: networking: add OPEN Alliance 10BASE-T1x MAC-PHY serial interface Parthiban Veerasooran
@ 2024-04-18 12:56 ` Parthiban Veerasooran
  2024-04-22 23:48   ` Andrew Lunn
                     ` (2 more replies)
  2024-04-18 12:56 ` [PATCH net-next v4 03/12] net: ethernet: oa_tc6: implement register read operation Parthiban Veerasooran
                   ` (13 subsequent siblings)
  15 siblings, 3 replies; 96+ messages in thread
From: Parthiban Veerasooran @ 2024-04-18 12:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean
  Cc: UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler,
	Parthiban Veerasooran

Implement register write operation according to the control communication
specified in the OPEN Alliance 10BASE-T1x MACPHY Serial Interface
document. Control write commands are used by the SPI host to write
registers within the MAC-PHY. Each control write commands are composed of
a 32 bits control command header followed by register write data.

The MAC-PHY ignores the final 32 bits of data from the SPI host at the
end of the control write command. The write command and data is also
echoed from the MAC-PHY back to the SPI host to enable the SPI host to
identify which register write failed in the case of any bus errors.
Control write commands can write either a single register or multiple
consecutive registers. When multiple consecutive registers are written,
the address is automatically post-incremented by the MAC-PHY. Writing to
any unimplemented or undefined registers shall be ignored and yield no
effect.

Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
---
 MAINTAINERS                   |   2 +
 drivers/net/ethernet/Kconfig  |  11 ++
 drivers/net/ethernet/Makefile |   1 +
 drivers/net/ethernet/oa_tc6.c | 240 ++++++++++++++++++++++++++++++++++
 include/linux/oa_tc6.h        |  17 +++
 5 files changed, 271 insertions(+)
 create mode 100644 drivers/net/ethernet/oa_tc6.c
 create mode 100644 include/linux/oa_tc6.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 79fa7abb4ec9..603528948f61 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16405,6 +16405,8 @@ M:	Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
 L:	netdev@vger.kernel.org
 S:	Maintained
 F:	Documentation/networking/oa-tc6-framework.rst
+F:	drivers/include/linux/oa_tc6.h
+F:	drivers/net/ethernet/oa_tc6.c
 
 OPEN FIRMWARE AND FLATTENED DEVICE TREE
 M:	Rob Herring <robh+dt@kernel.org>
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index 6a19b5393ed1..eb53372c60b4 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -157,6 +157,17 @@ config ETHOC
 	help
 	  Say Y here if you want to use the OpenCores 10/100 Mbps Ethernet MAC.
 
+config OA_TC6
+	tristate "OPEN Alliance TC6 10BASE-T1x MAC-PHY support"
+	depends on SPI
+	select PHYLIB
+	help
+	  This library implements OPEN Alliance TC6 10BASE-T1x MAC-PHY
+	  Serial Interface protocol for supporting 10BASE-T1x MAC-PHYs.
+
+	  To know the implementation details, refer documentation in
+	  <file:Documentation/networking/oa-tc6-framework.rst>.
+
 source "drivers/net/ethernet/packetengines/Kconfig"
 source "drivers/net/ethernet/pasemi/Kconfig"
 source "drivers/net/ethernet/pensando/Kconfig"
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index 0d872d4efcd1..cf5487fc0761 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -104,3 +104,4 @@ obj-$(CONFIG_NET_VENDOR_XILINX) += xilinx/
 obj-$(CONFIG_NET_VENDOR_XIRCOM) += xircom/
 obj-$(CONFIG_NET_VENDOR_SYNOPSYS) += synopsys/
 obj-$(CONFIG_NET_VENDOR_PENSANDO) += pensando/
+obj-$(CONFIG_OA_TC6) += oa_tc6.o
diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
new file mode 100644
index 000000000000..a92337de4534
--- /dev/null
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * OPEN Alliance 10BASE‑T1x MAC‑PHY Serial Interface framework
+ *
+ * Author: Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/oa_tc6.h>
+
+/* Control command header */
+#define OA_TC6_CTRL_HEADER_DATA_NOT_CTRL	BIT(31)
+#define OA_TC6_CTRL_HEADER_WRITE_NOT_READ	BIT(29)
+#define OA_TC6_CTRL_HEADER_MEM_MAP_SELECTOR	GENMASK(27, 24)
+#define OA_TC6_CTRL_HEADER_ADDR			GENMASK(23, 8)
+#define OA_TC6_CTRL_HEADER_LENGTH		GENMASK(7, 1)
+#define OA_TC6_CTRL_HEADER_PARITY		BIT(0)
+
+#define OA_TC6_CTRL_HEADER_SIZE			4
+#define OA_TC6_CTRL_REG_VALUE_SIZE		4
+#define OA_TC6_CTRL_IGNORED_SIZE		4
+#define OA_TC6_CTRL_MAX_REGISTERS		128
+#define OA_TC6_CTRL_SPI_BUF_SIZE		(OA_TC6_CTRL_HEADER_SIZE +\
+						(OA_TC6_CTRL_MAX_REGISTERS *\
+						OA_TC6_CTRL_REG_VALUE_SIZE) +\
+						OA_TC6_CTRL_IGNORED_SIZE)
+
+/* Internal structure for MAC-PHY drivers */
+struct oa_tc6 {
+	struct spi_device *spi;
+	struct mutex spi_ctrl_lock; /* Protects spi control transfer */
+	void *spi_ctrl_tx_buf;
+	void *spi_ctrl_rx_buf;
+};
+
+enum oa_tc6_header_type {
+	OA_TC6_CTRL_HEADER,
+};
+
+enum oa_tc6_register_op {
+	OA_TC6_CTRL_REG_WRITE = 1,
+};
+
+static int oa_tc6_spi_transfer(struct oa_tc6 *tc6,
+			       enum oa_tc6_header_type header_type, u16 length)
+{
+	struct spi_transfer xfer = { 0 };
+	struct spi_message msg;
+
+	xfer.tx_buf = tc6->spi_ctrl_tx_buf;
+	xfer.rx_buf = tc6->spi_ctrl_rx_buf;
+	xfer.len = length;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+
+	return spi_sync(tc6->spi, &msg);
+}
+
+static int oa_tc6_get_parity(u32 p)
+{
+	/* Public domain code snippet, lifted from
+	 * http://www-graphics.stanford.edu/~seander/bithacks.html
+	 */
+	p ^= p >> 1;
+	p ^= p >> 2;
+	p = (p & 0x11111111U) * 0x11111111U;
+
+	/* Odd parity is used here */
+	return !((p >> 28) & 1);
+}
+
+static __be32 oa_tc6_prepare_ctrl_header(u32 address, u8 length,
+					 enum oa_tc6_register_op reg_op)
+{
+	u32 header;
+
+	header = FIELD_PREP(OA_TC6_CTRL_HEADER_DATA_NOT_CTRL,
+			    OA_TC6_CTRL_HEADER) |
+		 FIELD_PREP(OA_TC6_CTRL_HEADER_WRITE_NOT_READ, reg_op) |
+		 FIELD_PREP(OA_TC6_CTRL_HEADER_MEM_MAP_SELECTOR, address >> 16) |
+		 FIELD_PREP(OA_TC6_CTRL_HEADER_ADDR, address) |
+		 FIELD_PREP(OA_TC6_CTRL_HEADER_LENGTH, length - 1);
+	header |= FIELD_PREP(OA_TC6_CTRL_HEADER_PARITY,
+			     oa_tc6_get_parity(header));
+
+	return cpu_to_be32(header);
+}
+
+static void oa_tc6_update_ctrl_write_data(struct oa_tc6 *tc6, u32 value[],
+					  u8 length)
+{
+	__be32 *tx_buf = tc6->spi_ctrl_tx_buf + OA_TC6_CTRL_HEADER_SIZE;
+
+	for (int i = 0; i < length; i++)
+		*tx_buf++ = cpu_to_be32(value[i]);
+}
+
+static u16 oa_tc6_calculate_ctrl_buf_size(u8 length)
+{
+	/* Control command consists 4 bytes header + 4 bytes register value for
+	 * each register + 4 bytes ignored value.
+	 */
+	return OA_TC6_CTRL_HEADER_SIZE + OA_TC6_CTRL_REG_VALUE_SIZE * length +
+	       OA_TC6_CTRL_IGNORED_SIZE;
+}
+
+static void oa_tc6_prepare_ctrl_spi_buf(struct oa_tc6 *tc6, u32 address,
+					u32 value[], u8 length,
+					enum oa_tc6_register_op reg_op)
+{
+	__be32 *tx_buf = tc6->spi_ctrl_tx_buf;
+
+	*tx_buf = oa_tc6_prepare_ctrl_header(address, length, reg_op);
+
+	oa_tc6_update_ctrl_write_data(tc6, value, length);
+}
+
+static int oa_tc6_check_ctrl_write_reply(struct oa_tc6 *tc6, u8 size)
+{
+	u8 *tx_buf = tc6->spi_ctrl_tx_buf;
+	u8 *rx_buf = tc6->spi_ctrl_rx_buf;
+
+	rx_buf += OA_TC6_CTRL_IGNORED_SIZE;
+
+	/* The echoed control write must match with the one that was
+	 * transmitted.
+	 */
+	if (memcmp(tx_buf, rx_buf, size - OA_TC6_CTRL_IGNORED_SIZE))
+		return -EPROTO;
+
+	return 0;
+}
+
+static int oa_tc6_perform_ctrl(struct oa_tc6 *tc6, u32 address, u32 value[],
+			       u8 length, enum oa_tc6_register_op reg_op)
+{
+	u16 size;
+	int ret;
+
+	/* Prepare control command and copy to SPI control buffer */
+	oa_tc6_prepare_ctrl_spi_buf(tc6, address, value, length, reg_op);
+
+	size = oa_tc6_calculate_ctrl_buf_size(length);
+
+	/* Perform SPI transfer */
+	ret = oa_tc6_spi_transfer(tc6, OA_TC6_CTRL_HEADER, size);
+	if (ret) {
+		dev_err(&tc6->spi->dev, "SPI transfer failed for control: %d\n",
+			ret);
+		return ret;
+	}
+
+	/* Check echoed/received control write command reply for errors */
+	return oa_tc6_check_ctrl_write_reply(tc6, size);
+}
+
+/**
+ * oa_tc6_write_registers - function for writing multiple consecutive registers.
+ * @tc6: oa_tc6 struct.
+ * @address: address of the first register to be written in the MAC-PHY.
+ * @value: values to be written from the starting register address @address.
+ * @length: number of consecutive registers to be written from @address.
+ *
+ * Maximum of 128 consecutive registers can be written starting at @address.
+ *
+ * Returns 0 on success otherwise failed.
+ */
+int oa_tc6_write_registers(struct oa_tc6 *tc6, u32 address, u32 value[],
+			   u8 length)
+{
+	int ret;
+
+	if (!length || length > OA_TC6_CTRL_MAX_REGISTERS) {
+		dev_err(&tc6->spi->dev, "Invalid register length parameter\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&tc6->spi_ctrl_lock);
+	ret = oa_tc6_perform_ctrl(tc6, address, value, length,
+				  OA_TC6_CTRL_REG_WRITE);
+	mutex_unlock(&tc6->spi_ctrl_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(oa_tc6_write_registers);
+
+/**
+ * oa_tc6_write_register - function for writing a MAC-PHY register.
+ * @tc6: oa_tc6 struct.
+ * @address: register address of the MAC-PHY to be written.
+ * @value: value to be written in the @address register address of the MAC-PHY.
+ *
+ * Returns 0 on success otherwise failed.
+ */
+int oa_tc6_write_register(struct oa_tc6 *tc6, u32 address, u32 value)
+{
+	return oa_tc6_write_registers(tc6, address, &value, 1);
+}
+EXPORT_SYMBOL_GPL(oa_tc6_write_register);
+
+/**
+ * oa_tc6_init - allocates and initializes oa_tc6 structure.
+ * @spi: device with which data will be exchanged.
+ *
+ * Returns pointer reference to the oa_tc6 structure if the MAC-PHY
+ * initialization is successful otherwise NULL.
+ */
+struct oa_tc6 *oa_tc6_init(struct spi_device *spi)
+{
+	struct oa_tc6 *tc6;
+
+	tc6 = devm_kzalloc(&spi->dev, sizeof(*tc6), GFP_KERNEL);
+	if (!tc6)
+		return NULL;
+
+	tc6->spi = spi;
+	mutex_init(&tc6->spi_ctrl_lock);
+
+	/* Set the SPI controller to pump at realtime priority */
+	tc6->spi->rt = true;
+	spi_setup(tc6->spi);
+
+	tc6->spi_ctrl_tx_buf = devm_kzalloc(&tc6->spi->dev,
+					    OA_TC6_CTRL_SPI_BUF_SIZE, GFP_KERNEL);
+	if (!tc6->spi_ctrl_tx_buf)
+		return NULL;
+
+	tc6->spi_ctrl_rx_buf = devm_kzalloc(&tc6->spi->dev,
+					    OA_TC6_CTRL_SPI_BUF_SIZE, GFP_KERNEL);
+	if (!tc6->spi_ctrl_rx_buf)
+		return NULL;
+
+	return tc6;
+}
+EXPORT_SYMBOL_GPL(oa_tc6_init);
+
+MODULE_DESCRIPTION("OPEN Alliance 10BASE‑T1x MAC‑PHY Serial Interface Lib");
+MODULE_AUTHOR("Parthiban Veerasooran <parthiban.veerasooran@microchip.com>");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/oa_tc6.h b/include/linux/oa_tc6.h
new file mode 100644
index 000000000000..99c490f1c8a8
--- /dev/null
+++ b/include/linux/oa_tc6.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * OPEN Alliance 10BASE‑T1x MAC‑PHY Serial Interface framework
+ *
+ * Link: https://opensig.org/download/document/OPEN_Alliance_10BASET1x_MAC-PHY_Serial_Interface_V1.1.pdf
+ *
+ * Author: Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
+ */
+
+#include <linux/spi/spi.h>
+
+struct oa_tc6;
+
+struct oa_tc6 *oa_tc6_init(struct spi_device *spi);
+int oa_tc6_write_register(struct oa_tc6 *tc6, u32 address, u32 value);
+int oa_tc6_write_registers(struct oa_tc6 *tc6, u32 address, u32 value[],
+			   u8 length);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 96+ messages in thread

* [PATCH net-next v4 03/12] net: ethernet: oa_tc6: implement register read operation
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
  2024-04-18 12:56 ` [PATCH net-next v4 01/12] Documentation: networking: add OPEN Alliance 10BASE-T1x MAC-PHY serial interface Parthiban Veerasooran
  2024-04-18 12:56 ` [PATCH net-next v4 02/12] net: ethernet: oa_tc6: implement register write operation Parthiban Veerasooran
@ 2024-04-18 12:56 ` Parthiban Veerasooran
  2024-04-23 23:17   ` Andrew Lunn
  2024-04-18 12:56 ` [PATCH net-next v4 04/12] net: ethernet: oa_tc6: implement software reset Parthiban Veerasooran
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 96+ messages in thread
From: Parthiban Veerasooran @ 2024-04-18 12:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean
  Cc: UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler,
	Parthiban Veerasooran

Implement register read operation according to the control communication
specified in the OPEN Alliance 10BASE-T1x MACPHY Serial Interface
document. Control read commands are used by the SPI host to read
registers within the MAC-PHY. Each control read commands are composed of
a 32 bits control command header.

The MAC-PHY ignores all data from the SPI host following the control
header for the remainder of the control read command. Control read
commands can read either a single register or multiple consecutive
registers. When multiple consecutive registers are read, the address is
automatically post-incremented by the MAC-PHY. Reading any unimplemented
or undefined registers shall return zero.

Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
---
 drivers/net/ethernet/oa_tc6.c | 84 ++++++++++++++++++++++++++++++++++-
 include/linux/oa_tc6.h        |  3 ++
 2 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index a92337de4534..f563329912e2 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -38,6 +38,7 @@ enum oa_tc6_header_type {
 };
 
 enum oa_tc6_register_op {
+	OA_TC6_CTRL_REG_READ = 0,
 	OA_TC6_CTRL_REG_WRITE = 1,
 };
 
@@ -113,7 +114,8 @@ static void oa_tc6_prepare_ctrl_spi_buf(struct oa_tc6 *tc6, u32 address,
 
 	*tx_buf = oa_tc6_prepare_ctrl_header(address, length, reg_op);
 
-	oa_tc6_update_ctrl_write_data(tc6, value, length);
+	if (reg_op == OA_TC6_CTRL_REG_WRITE)
+		oa_tc6_update_ctrl_write_data(tc6, value, length);
 }
 
 static int oa_tc6_check_ctrl_write_reply(struct oa_tc6 *tc6, u8 size)
@@ -132,6 +134,30 @@ static int oa_tc6_check_ctrl_write_reply(struct oa_tc6 *tc6, u8 size)
 	return 0;
 }
 
+static int oa_tc6_check_ctrl_read_reply(struct oa_tc6 *tc6, u8 size)
+{
+	u32 *tx_buf = tc6->spi_ctrl_tx_buf;
+	u32 *rx_buf = tc6->spi_ctrl_rx_buf + OA_TC6_CTRL_IGNORED_SIZE;
+
+	/* The echoed control read header must match with the one that was
+	 * transmitted.
+	 */
+	if (*tx_buf != *rx_buf)
+		return -EPROTO;
+
+	return 0;
+}
+
+static void oa_tc6_copy_ctrl_read_data(struct oa_tc6 *tc6, u32 value[],
+				       u8 length)
+{
+	__be32 *rx_buf = tc6->spi_ctrl_rx_buf + OA_TC6_CTRL_IGNORED_SIZE +
+			 OA_TC6_CTRL_HEADER_SIZE;
+
+	for (int i = 0; i < length; i++)
+		value[i] = be32_to_cpu(*rx_buf++);
+}
+
 static int oa_tc6_perform_ctrl(struct oa_tc6 *tc6, u32 address, u32 value[],
 			       u8 length, enum oa_tc6_register_op reg_op)
 {
@@ -152,8 +178,62 @@ static int oa_tc6_perform_ctrl(struct oa_tc6 *tc6, u32 address, u32 value[],
 	}
 
 	/* Check echoed/received control write command reply for errors */
-	return oa_tc6_check_ctrl_write_reply(tc6, size);
+	if (reg_op == OA_TC6_CTRL_REG_WRITE)
+		return oa_tc6_check_ctrl_write_reply(tc6, size);
+
+	/* Check echoed/received control read command reply for errors */
+	ret = oa_tc6_check_ctrl_read_reply(tc6, size);
+	if (ret)
+		return ret;
+
+	oa_tc6_copy_ctrl_read_data(tc6, value, length);
+
+	return 0;
+}
+
+/**
+ * oa_tc6_read_registers - function for reading multiple consecutive registers.
+ * @tc6: oa_tc6 struct.
+ * @address: address of the first register to be read in the MAC-PHY.
+ * @value: values to be read from the starting register address @address.
+ * @length: number of consecutive registers to be read from @address.
+ *
+ * Maximum of 128 consecutive registers can be read starting at @address.
+ *
+ * Returns 0 on success otherwise failed.
+ */
+int oa_tc6_read_registers(struct oa_tc6 *tc6, u32 address, u32 value[],
+			  u8 length)
+{
+	int ret;
+
+	if (!length || length > OA_TC6_CTRL_MAX_REGISTERS) {
+		dev_err(&tc6->spi->dev, "Invalid register length parameter\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&tc6->spi_ctrl_lock);
+	ret = oa_tc6_perform_ctrl(tc6, address, value, length,
+				  OA_TC6_CTRL_REG_READ);
+	mutex_unlock(&tc6->spi_ctrl_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(oa_tc6_read_registers);
+
+/**
+ * oa_tc6_read_register - function for reading a MAC-PHY register.
+ * @tc6: oa_tc6 struct.
+ * @address: register address of the MAC-PHY to be read.
+ * @value: value read from the @address register address of the MAC-PHY.
+ *
+ * Returns 0 on success otherwise failed.
+ */
+int oa_tc6_read_register(struct oa_tc6 *tc6, u32 address, u32 *value)
+{
+	return oa_tc6_read_registers(tc6, address, value, 1);
 }
+EXPORT_SYMBOL_GPL(oa_tc6_read_register);
 
 /**
  * oa_tc6_write_registers - function for writing multiple consecutive registers.
diff --git a/include/linux/oa_tc6.h b/include/linux/oa_tc6.h
index 99c490f1c8a8..85aeecf87306 100644
--- a/include/linux/oa_tc6.h
+++ b/include/linux/oa_tc6.h
@@ -15,3 +15,6 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi);
 int oa_tc6_write_register(struct oa_tc6 *tc6, u32 address, u32 value);
 int oa_tc6_write_registers(struct oa_tc6 *tc6, u32 address, u32 value[],
 			   u8 length);
+int oa_tc6_read_register(struct oa_tc6 *tc6, u32 address, u32 *value);
+int oa_tc6_read_registers(struct oa_tc6 *tc6, u32 address, u32 value[],
+			  u8 length);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 96+ messages in thread

* [PATCH net-next v4 04/12] net: ethernet: oa_tc6: implement software reset
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
                   ` (2 preceding siblings ...)
  2024-04-18 12:56 ` [PATCH net-next v4 03/12] net: ethernet: oa_tc6: implement register read operation Parthiban Veerasooran
@ 2024-04-18 12:56 ` Parthiban Veerasooran
  2024-04-23 23:26   ` Andrew Lunn
  2024-04-18 12:56 ` [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking Parthiban Veerasooran
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 96+ messages in thread
From: Parthiban Veerasooran @ 2024-04-18 12:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean
  Cc: UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler,
	Parthiban Veerasooran

Reset complete bit is set when the MAC-PHY reset completes and ready for
configuration. Additionally reset complete bit in the STS0 register has
to be written by one upon reset complete to clear the interrupt.

Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
---
 drivers/net/ethernet/oa_tc6.c | 53 +++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index f563329912e2..4b0f63c02c35 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -6,8 +6,18 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/iopoll.h>
 #include <linux/oa_tc6.h>
 
+/* OPEN Alliance TC6 registers */
+/* Reset Control and Status Register */
+#define OA_TC6_REG_RESET			0x0003
+#define RESET_SWRESET				BIT(0)	/* Software Reset */
+
+/* Status Register #0 */
+#define OA_TC6_REG_STATUS0			0x0008
+#define STATUS0_RESETC				BIT(6)	/* Reset Complete */
+
 /* Control command header */
 #define OA_TC6_CTRL_HEADER_DATA_NOT_CTRL	BIT(31)
 #define OA_TC6_CTRL_HEADER_WRITE_NOT_READ	BIT(29)
@@ -24,6 +34,8 @@
 						(OA_TC6_CTRL_MAX_REGISTERS *\
 						OA_TC6_CTRL_REG_VALUE_SIZE) +\
 						OA_TC6_CTRL_IGNORED_SIZE)
+#define STATUS0_RESETC_POLL_DELAY		1000
+#define STATUS0_RESETC_POLL_TIMEOUT		1000000
 
 /* Internal structure for MAC-PHY drivers */
 struct oa_tc6 {
@@ -279,6 +291,39 @@ int oa_tc6_write_register(struct oa_tc6 *tc6, u32 address, u32 value)
 }
 EXPORT_SYMBOL_GPL(oa_tc6_write_register);
 
+static int oa_tc6_read_status0(struct oa_tc6 *tc6)
+{
+	u32 regval;
+	int ret;
+
+	ret = oa_tc6_read_register(tc6, OA_TC6_REG_STATUS0, &regval);
+	if (ret)
+		return 0;
+
+	return regval;
+}
+
+static int oa_tc6_sw_reset_macphy(struct oa_tc6 *tc6)
+{
+	u32 regval = RESET_SWRESET;
+	int ret;
+
+	ret = oa_tc6_write_register(tc6, OA_TC6_REG_RESET, regval);
+	if (ret)
+		return ret;
+
+	/* Poll for soft reset complete for every 1ms until 1s timeout */
+	ret = readx_poll_timeout(oa_tc6_read_status0, tc6, regval,
+				 regval & STATUS0_RESETC,
+				 STATUS0_RESETC_POLL_DELAY,
+				 STATUS0_RESETC_POLL_TIMEOUT);
+	if (ret)
+		return -ENODEV;
+
+	/* Clear the reset complete status */
+	return oa_tc6_write_register(tc6, OA_TC6_REG_STATUS0, regval);
+}
+
 /**
  * oa_tc6_init - allocates and initializes oa_tc6 structure.
  * @spi: device with which data will be exchanged.
@@ -289,6 +334,7 @@ EXPORT_SYMBOL_GPL(oa_tc6_write_register);
 struct oa_tc6 *oa_tc6_init(struct spi_device *spi)
 {
 	struct oa_tc6 *tc6;
+	int ret;
 
 	tc6 = devm_kzalloc(&spi->dev, sizeof(*tc6), GFP_KERNEL);
 	if (!tc6)
@@ -311,6 +357,13 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi)
 	if (!tc6->spi_ctrl_rx_buf)
 		return NULL;
 
+	ret = oa_tc6_sw_reset_macphy(tc6);
+	if (ret) {
+		dev_err(&tc6->spi->dev,
+			"MAC-PHY software reset failed: %d\n", ret);
+		return NULL;
+	}
+
 	return tc6;
 }
 EXPORT_SYMBOL_GPL(oa_tc6_init);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 96+ messages in thread

* [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
                   ` (3 preceding siblings ...)
  2024-04-18 12:56 ` [PATCH net-next v4 04/12] net: ethernet: oa_tc6: implement software reset Parthiban Veerasooran
@ 2024-04-18 12:56 ` Parthiban Veerasooran
  2024-04-23 23:27   ` Andrew Lunn
  2024-04-27 19:52   ` Ramón Nordin Rodriguez
  2024-04-18 12:56 ` [PATCH net-next v4 06/12] net: ethernet: oa_tc6: implement internal PHY initialization Parthiban Veerasooran
                   ` (10 subsequent siblings)
  15 siblings, 2 replies; 96+ messages in thread
From: Parthiban Veerasooran @ 2024-04-18 12:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean
  Cc: UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler,
	Parthiban Veerasooran

This will unmask the following error interrupts from the MAC-PHY.
  tx protocol error
  rx buffer overflow error
  loss of framing error
  header error
The MAC-PHY will signal an error by setting the EXST bit in the receive
data footer which will then allow the host to read the STATUS0 register
to find the source of the error.

Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
---
 drivers/net/ethernet/oa_tc6.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index 4b0f63c02c35..850765574d30 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -18,6 +18,13 @@
 #define OA_TC6_REG_STATUS0			0x0008
 #define STATUS0_RESETC				BIT(6)	/* Reset Complete */
 
+/* Interrupt Mask Register #0 */
+#define OA_TC6_REG_INT_MASK0			0x000C
+#define INT_MASK0_HEADER_ERR_MASK		BIT(5)
+#define INT_MASK0_LOSS_OF_FRAME_ERR_MASK	BIT(4)
+#define INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK	BIT(3)
+#define INT_MASK0_TX_PROTOCOL_ERR_MASK		BIT(0)
+
 /* Control command header */
 #define OA_TC6_CTRL_HEADER_DATA_NOT_CTRL	BIT(31)
 #define OA_TC6_CTRL_HEADER_WRITE_NOT_READ	BIT(29)
@@ -324,6 +331,23 @@ static int oa_tc6_sw_reset_macphy(struct oa_tc6 *tc6)
 	return oa_tc6_write_register(tc6, OA_TC6_REG_STATUS0, regval);
 }
 
+static int oa_tc6_unmask_macphy_error_interrupts(struct oa_tc6 *tc6)
+{
+	u32 regval;
+	int ret;
+
+	ret = oa_tc6_read_register(tc6, OA_TC6_REG_INT_MASK0, &regval);
+	if (ret)
+		return ret;
+
+	regval &= ~(INT_MASK0_TX_PROTOCOL_ERR_MASK |
+		    INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK |
+		    INT_MASK0_LOSS_OF_FRAME_ERR_MASK |
+		    INT_MASK0_HEADER_ERR_MASK);
+
+	return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, regval);
+}
+
 /**
  * oa_tc6_init - allocates and initializes oa_tc6 structure.
  * @spi: device with which data will be exchanged.
@@ -364,6 +388,13 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi)
 		return NULL;
 	}
 
+	ret = oa_tc6_unmask_macphy_error_interrupts(tc6);
+	if (ret) {
+		dev_err(&tc6->spi->dev,
+			"MAC-PHY error interrupts unmask failed: %d\n", ret);
+		return NULL;
+	}
+
 	return tc6;
 }
 EXPORT_SYMBOL_GPL(oa_tc6_init);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 96+ messages in thread

* [PATCH net-next v4 06/12] net: ethernet: oa_tc6: implement internal PHY initialization
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
                   ` (4 preceding siblings ...)
  2024-04-18 12:56 ` [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking Parthiban Veerasooran
@ 2024-04-18 12:56 ` Parthiban Veerasooran
  2024-04-23 23:48   ` Andrew Lunn
  2024-04-18 12:56 ` [PATCH net-next v4 07/12] net: ethernet: oa_tc6: enable open alliance tc6 data communication Parthiban Veerasooran
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 96+ messages in thread
From: Parthiban Veerasooran @ 2024-04-18 12:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean
  Cc: UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler,
	Parthiban Veerasooran

Internal PHY is initialized as per the PHY register capability supported
by the MAC-PHY. Direct PHY Register Access Capability indicates if PHY
registers are directly accessible within the SPI register memory space.
Indirect PHY Register Access Capability indicates if PHY registers are
indirectly accessible through the MDIO/MDC registers MDIOACCn defined in
OPEN Alliance specification. Currently the direct register access is only
supported.

Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
---
 drivers/net/ethernet/oa_tc6.c   | 230 +++++++++++++++++++++++++++++++-
 drivers/net/phy/microchip_t1s.c |  30 +++++
 include/linux/oa_tc6.h          |   4 +-
 include/uapi/linux/mdio.h       |   1 +
 4 files changed, 263 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index 850765574d30..f04c4c13e8d3 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -7,9 +7,15 @@
 
 #include <linux/bitfield.h>
 #include <linux/iopoll.h>
+#include <linux/mdio.h>
+#include <linux/phy.h>
 #include <linux/oa_tc6.h>
 
 /* OPEN Alliance TC6 registers */
+/* Standard Capabilities Register */
+#define OA_TC6_REG_STDCAP			0x0002
+#define STDCAP_DIRECT_PHY_REG_ACCESS		BIT(8)
+
 /* Reset Control and Status Register */
 #define OA_TC6_REG_RESET			0x0003
 #define RESET_SWRESET				BIT(0)	/* Software Reset */
@@ -25,6 +31,10 @@
 #define INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK	BIT(3)
 #define INT_MASK0_TX_PROTOCOL_ERR_MASK		BIT(0)
 
+/* PHY Clause 22 and 29 registers base address and mask */
+#define OA_TC6_PHY_STD_REG_ADDR_BASE		0xFF00
+#define OA_TC6_PHY_STD_REG_ADDR_MASK		0x3F
+
 /* Control command header */
 #define OA_TC6_CTRL_HEADER_DATA_NOT_CTRL	BIT(31)
 #define OA_TC6_CTRL_HEADER_WRITE_NOT_READ	BIT(29)
@@ -33,6 +43,15 @@
 #define OA_TC6_CTRL_HEADER_LENGTH		GENMASK(7, 1)
 #define OA_TC6_CTRL_HEADER_PARITY		BIT(0)
 
+/* PHY – Clause 45 registers memory map selector (MMS) as per table 6 in the
+ * OPEN Alliance specification.
+ */
+#define OA_TC6_PHY_C45_PCS_MMS2			2	/* MMD 3 */
+#define OA_TC6_PHY_C45_PMA_PMD_MMS3		3	/* MMD 1 */
+#define OA_TC6_PHY_C45_VS_PLCA_MMS4		4	/* MMD 31 */
+#define OA_TC6_PHY_C45_AUTO_NEG_MMS5		5	/* MMD 7 */
+#define OA_TC6_PHY_C45_POWER_UNIT_MMS6		6	/* MMD 13 */
+
 #define OA_TC6_CTRL_HEADER_SIZE			4
 #define OA_TC6_CTRL_REG_VALUE_SIZE		4
 #define OA_TC6_CTRL_IGNORED_SIZE		4
@@ -46,6 +65,10 @@
 
 /* Internal structure for MAC-PHY drivers */
 struct oa_tc6 {
+	struct device *dev;
+	struct net_device *netdev;
+	struct phy_device *phydev;
+	struct mii_bus *mdiobus;
 	struct spi_device *spi;
 	struct mutex spi_ctrl_lock; /* Protects spi control transfer */
 	void *spi_ctrl_tx_buf;
@@ -298,6 +321,191 @@ int oa_tc6_write_register(struct oa_tc6 *tc6, u32 address, u32 value)
 }
 EXPORT_SYMBOL_GPL(oa_tc6_write_register);
 
+static int oa_tc6_check_phy_reg_direct_access_capability(struct oa_tc6 *tc6)
+{
+	u32 regval;
+	int ret;
+
+	ret = oa_tc6_read_register(tc6, OA_TC6_REG_STDCAP, &regval);
+	if (ret)
+		return ret;
+
+	if (!(regval & STDCAP_DIRECT_PHY_REG_ACCESS))
+		return -ENODEV;
+
+	return 0;
+}
+
+static void oa_tc6_handle_link_change(struct net_device *netdev)
+{
+	phy_print_status(netdev->phydev);
+}
+
+static int oa_tc6_mdiobus_read(struct mii_bus *bus, int addr, int regnum)
+{
+	struct oa_tc6 *tc6 = bus->priv;
+	u32 regval;
+	bool ret;
+
+	ret = oa_tc6_read_register(tc6, OA_TC6_PHY_STD_REG_ADDR_BASE |
+				   (regnum & OA_TC6_PHY_STD_REG_ADDR_MASK),
+				   &regval);
+	if (ret)
+		return -ENODEV;
+
+	return regval;
+}
+
+static int oa_tc6_mdiobus_write(struct mii_bus *bus, int addr, int regnum,
+				u16 val)
+{
+	struct oa_tc6 *tc6 = bus->priv;
+
+	return oa_tc6_write_register(tc6, OA_TC6_PHY_STD_REG_ADDR_BASE |
+				     (regnum & OA_TC6_PHY_STD_REG_ADDR_MASK),
+				     val);
+}
+
+static int oa_tc6_get_phy_c45_mms(int devnum)
+{
+	switch (devnum) {
+	case MDIO_MMD_PCS:
+		return OA_TC6_PHY_C45_PCS_MMS2;
+	case MDIO_MMD_PMAPMD:
+		return OA_TC6_PHY_C45_PMA_PMD_MMS3;
+	case MDIO_MMD_VEND2:
+		return OA_TC6_PHY_C45_VS_PLCA_MMS4;
+	case MDIO_MMD_AN:
+		return OA_TC6_PHY_C45_AUTO_NEG_MMS5;
+	case MDIO_MMD_POWER_UNIT:
+		return OA_TC6_PHY_C45_POWER_UNIT_MMS6;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int oa_tc6_mdiobus_read_c45(struct mii_bus *bus, int addr, int devnum,
+				   int regnum)
+{
+	struct oa_tc6 *tc6 = bus->priv;
+	u32 regval;
+	int ret;
+
+	ret = oa_tc6_get_phy_c45_mms(devnum);
+	if (ret < 0)
+		return ret;
+
+	ret = oa_tc6_read_register(tc6, (ret << 16) | regnum, &regval);
+	if (ret)
+		return ret;
+
+	return regval;
+}
+
+static int oa_tc6_mdiobus_write_c45(struct mii_bus *bus, int addr, int devnum,
+				    int regnum, u16 val)
+{
+	struct oa_tc6 *tc6 = bus->priv;
+	int ret;
+
+	ret = oa_tc6_get_phy_c45_mms(devnum);
+	if (ret < 0)
+		return ret;
+
+	return oa_tc6_write_register(tc6, (ret << 16) | regnum, val);
+}
+
+static int oa_tc6_mdiobus_register(struct oa_tc6 *tc6)
+{
+	int ret;
+
+	tc6->mdiobus = mdiobus_alloc();
+	if (!tc6->mdiobus) {
+		netdev_err(tc6->netdev, "MDIO bus alloc failed\n");
+		return -ENOMEM;
+	}
+
+	tc6->mdiobus->priv = tc6;
+	tc6->mdiobus->read = oa_tc6_mdiobus_read;
+	tc6->mdiobus->write = oa_tc6_mdiobus_write;
+	/* OPEN Alliance 10BASE-T1x compliance MAC-PHYs will have both C22 and
+	 * C45 registers space. If the PHY is discovered via C22 bus protocol it
+	 * assumes it uses C22 protocol and always uses C22 registers indirect
+	 * access to access C45 registers. This is because, we don't have a
+	 * clean separation between C22/C45 register space and C22/C45 MDIO bus
+	 * protocols. Resulting, PHY C45 registers direct access can't be used
+	 * which can save multiple SPI bus access. To support this feature, PHY
+	 * drivers can set .read_mmd/.write_mmd in the PHY driver to call
+	 * .read_c45/.write_c45. Ex: drivers/net/phy/microchip_t1s.c
+	 */
+	tc6->mdiobus->read_c45 = oa_tc6_mdiobus_read_c45;
+	tc6->mdiobus->write_c45 = oa_tc6_mdiobus_write_c45;
+	tc6->mdiobus->name = "oa-tc6-mdiobus";
+	tc6->mdiobus->parent = tc6->dev;
+
+	snprintf(tc6->mdiobus->id, ARRAY_SIZE(tc6->mdiobus->id), "%s",
+		 dev_name(&tc6->spi->dev));
+
+	ret = mdiobus_register(tc6->mdiobus);
+	if (ret) {
+		netdev_err(tc6->netdev, "Could not register MDIO bus\n");
+		mdiobus_free(tc6->mdiobus);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void oa_tc6_mdiobus_unregister(struct oa_tc6 *tc6)
+{
+	mdiobus_unregister(tc6->mdiobus);
+	mdiobus_free(tc6->mdiobus);
+}
+
+static int oa_tc6_phy_init(struct oa_tc6 *tc6)
+{
+	int ret;
+
+	ret = oa_tc6_check_phy_reg_direct_access_capability(tc6);
+	if (ret) {
+		netdev_err(tc6->netdev,
+			   "Direct PHY register access is not supported by the MAC-PHY\n");
+		return ret;
+	}
+
+	ret = oa_tc6_mdiobus_register(tc6);
+	if (ret)
+		return ret;
+
+	tc6->phydev = phy_find_first(tc6->mdiobus);
+	if (!tc6->phydev) {
+		netdev_err(tc6->netdev, "No PHY found\n");
+		oa_tc6_mdiobus_unregister(tc6);
+		return -ENODEV;
+	}
+
+	tc6->phydev->is_internal = true;
+	ret = phy_connect_direct(tc6->netdev, tc6->phydev,
+				 &oa_tc6_handle_link_change,
+				 PHY_INTERFACE_MODE_INTERNAL);
+	if (ret) {
+		netdev_err(tc6->netdev, "Can't attach PHY to %s\n",
+			   tc6->mdiobus->id);
+		oa_tc6_mdiobus_unregister(tc6);
+		return ret;
+	}
+
+	phy_attached_info(tc6->netdev->phydev);
+
+	return 0;
+}
+
+static void oa_tc6_phy_exit(struct oa_tc6 *tc6)
+{
+	phy_disconnect(tc6->phydev);
+	oa_tc6_mdiobus_unregister(tc6);
+}
+
 static int oa_tc6_read_status0(struct oa_tc6 *tc6)
 {
 	u32 regval;
@@ -351,11 +559,12 @@ static int oa_tc6_unmask_macphy_error_interrupts(struct oa_tc6 *tc6)
 /**
  * oa_tc6_init - allocates and initializes oa_tc6 structure.
  * @spi: device with which data will be exchanged.
+ * @netdev: network device interface structure.
  *
  * Returns pointer reference to the oa_tc6 structure if the MAC-PHY
  * initialization is successful otherwise NULL.
  */
-struct oa_tc6 *oa_tc6_init(struct spi_device *spi)
+struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev)
 {
 	struct oa_tc6 *tc6;
 	int ret;
@@ -365,6 +574,8 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi)
 		return NULL;
 
 	tc6->spi = spi;
+	tc6->netdev = netdev;
+	SET_NETDEV_DEV(netdev, &spi->dev);
 	mutex_init(&tc6->spi_ctrl_lock);
 
 	/* Set the SPI controller to pump at realtime priority */
@@ -395,10 +606,27 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi)
 		return NULL;
 	}
 
+	ret = oa_tc6_phy_init(tc6);
+	if (ret) {
+		dev_err(&tc6->spi->dev,
+			"MAC internal PHY initialization failed: %d\n", ret);
+		return NULL;
+	}
+
 	return tc6;
 }
 EXPORT_SYMBOL_GPL(oa_tc6_init);
 
+/**
+ * oa_tc6_exit - exit function.
+ * @tc6: oa_tc6 struct.
+ */
+void oa_tc6_exit(struct oa_tc6 *tc6)
+{
+	oa_tc6_phy_exit(tc6);
+}
+EXPORT_SYMBOL_GPL(oa_tc6_exit);
+
 MODULE_DESCRIPTION("OPEN Alliance 10BASE‑T1x MAC‑PHY Serial Interface Lib");
 MODULE_AUTHOR("Parthiban Veerasooran <parthiban.veerasooran@microchip.com>");
 MODULE_LICENSE("GPL");
diff --git a/drivers/net/phy/microchip_t1s.c b/drivers/net/phy/microchip_t1s.c
index 534ca7d1b061..769a88254285 100644
--- a/drivers/net/phy/microchip_t1s.c
+++ b/drivers/net/phy/microchip_t1s.c
@@ -268,6 +268,34 @@ static int lan86xx_read_status(struct phy_device *phydev)
 	return 0;
 }
 
+/* OPEN Alliance 10BASE-T1x compliance MAC-PHYs will have both C22 and
+ * C45 registers space. If the PHY is discovered via C22 bus protocol it assumes
+ * it uses C22 protocol and always uses C22 registers indirect access to access
+ * C45 registers. This is because, we don't have a clean separation between
+ * C22/C45 register space and C22/C45 MDIO bus protocols. Resulting, PHY C45
+ * registers direct access can't be used which can save multiple SPI bus access.
+ * To support this feature, set .read_mmd/.write_mmd in the PHY driver to call
+ * .read_c45/.write_c45 in the OPEN Alliance framework
+ * drivers/net/ethernet/oa_tc6.c
+ */
+static int lan865x_phy_read_mmd(struct phy_device *phydev, int devnum,
+				u16 regnum)
+{
+	struct mii_bus *bus = phydev->mdio.bus;
+	int addr = phydev->mdio.addr;
+
+	return bus->read_c45(bus, addr, devnum, regnum);
+}
+
+static int lan865x_phy_write_mmd(struct phy_device *phydev, int devnum,
+				 u16 regnum, u16 val)
+{
+	struct mii_bus *bus = phydev->mdio.bus;
+	int addr = phydev->mdio.addr;
+
+	return bus->write_c45(bus, addr, devnum, regnum, val);
+}
+
 static struct phy_driver microchip_t1s_driver[] = {
 	{
 		PHY_ID_MATCH_EXACT(PHY_ID_LAN867X_REVB1),
@@ -285,6 +313,8 @@ static struct phy_driver microchip_t1s_driver[] = {
 		.features           = PHY_BASIC_T1S_P2MP_FEATURES,
 		.config_init        = lan865x_revb0_config_init,
 		.read_status        = lan86xx_read_status,
+		.read_mmd           = lan865x_phy_read_mmd,
+		.write_mmd          = lan865x_phy_write_mmd,
 		.get_plca_cfg	    = genphy_c45_plca_get_cfg,
 		.set_plca_cfg	    = genphy_c45_plca_set_cfg,
 		.get_plca_status    = genphy_c45_plca_get_status,
diff --git a/include/linux/oa_tc6.h b/include/linux/oa_tc6.h
index 85aeecf87306..606ba9f1e663 100644
--- a/include/linux/oa_tc6.h
+++ b/include/linux/oa_tc6.h
@@ -7,11 +7,13 @@
  * Author: Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
  */
 
+#include <linux/etherdevice.h>
 #include <linux/spi/spi.h>
 
 struct oa_tc6;
 
-struct oa_tc6 *oa_tc6_init(struct spi_device *spi);
+struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev);
+void oa_tc6_exit(struct oa_tc6 *tc6);
 int oa_tc6_write_register(struct oa_tc6 *tc6, u32 address, u32 value);
 int oa_tc6_write_registers(struct oa_tc6 *tc6, u32 address, u32 value[],
 			   u8 length);
diff --git a/include/uapi/linux/mdio.h b/include/uapi/linux/mdio.h
index c0c8ec995b06..f0d3f268240d 100644
--- a/include/uapi/linux/mdio.h
+++ b/include/uapi/linux/mdio.h
@@ -23,6 +23,7 @@
 #define MDIO_MMD_DTEXS		5	/* DTE Extender Sublayer */
 #define MDIO_MMD_TC		6	/* Transmission Convergence */
 #define MDIO_MMD_AN		7	/* Auto-Negotiation */
+#define MDIO_MMD_POWER_UNIT	13	/* PHY Power Unit */
 #define MDIO_MMD_C22EXT		29	/* Clause 22 extension */
 #define MDIO_MMD_VEND1		30	/* Vendor specific 1 */
 #define MDIO_MMD_VEND2		31	/* Vendor specific 2 */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 96+ messages in thread

* [PATCH net-next v4 07/12] net: ethernet: oa_tc6: enable open alliance tc6 data communication
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
                   ` (5 preceding siblings ...)
  2024-04-18 12:56 ` [PATCH net-next v4 06/12] net: ethernet: oa_tc6: implement internal PHY initialization Parthiban Veerasooran
@ 2024-04-18 12:56 ` Parthiban Veerasooran
  2024-04-23 23:49   ` Andrew Lunn
  2024-04-18 12:56 ` [PATCH net-next v4 08/12] net: ethernet: oa_tc6: implement transmit path to transfer tx ethernet frames Parthiban Veerasooran
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 96+ messages in thread
From: Parthiban Veerasooran @ 2024-04-18 12:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean
  Cc: UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler,
	Parthiban Veerasooran

Enabling Configuration Synchronization bit (SYNC) in the Configuration
Register #0 enables data communication in the MAC-PHY. The state of this
bit is reflected in the data footer SYNC bit.

Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
---
 drivers/net/ethernet/oa_tc6.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index f04c4c13e8d3..ef7069618319 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -20,6 +20,10 @@
 #define OA_TC6_REG_RESET			0x0003
 #define RESET_SWRESET				BIT(0)	/* Software Reset */
 
+/* Configuration Register #0 */
+#define OA_TC6_REG_CONFIG0			0x0004
+#define CONFIG0_SYNC				BIT(15)
+
 /* Status Register #0 */
 #define OA_TC6_REG_STATUS0			0x0008
 #define STATUS0_RESETC				BIT(6)	/* Reset Complete */
@@ -556,6 +560,21 @@ static int oa_tc6_unmask_macphy_error_interrupts(struct oa_tc6 *tc6)
 	return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, regval);
 }
 
+static int oa_tc6_enable_data_transfer(struct oa_tc6 *tc6)
+{
+	u32 value;
+	int ret;
+
+	ret = oa_tc6_read_register(tc6, OA_TC6_REG_CONFIG0, &value);
+	if (ret)
+		return ret;
+
+	/* Enable configuration synchronization for data transfer */
+	value |= CONFIG0_SYNC;
+
+	return oa_tc6_write_register(tc6, OA_TC6_REG_CONFIG0, value);
+}
+
 /**
  * oa_tc6_init - allocates and initializes oa_tc6 structure.
  * @spi: device with which data will be exchanged.
@@ -613,7 +632,18 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev)
 		return NULL;
 	}
 
+	ret = oa_tc6_enable_data_transfer(tc6);
+	if (ret) {
+		dev_err(&tc6->spi->dev, "Failed to enable data transfer: %d\n",
+			ret);
+		goto phy_exit;
+	}
+
 	return tc6;
+
+phy_exit:
+	oa_tc6_phy_exit(tc6);
+	return NULL;
 }
 EXPORT_SYMBOL_GPL(oa_tc6_init);
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 96+ messages in thread

* [PATCH net-next v4 08/12] net: ethernet: oa_tc6: implement transmit path to transfer tx ethernet frames
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
                   ` (6 preceding siblings ...)
  2024-04-18 12:56 ` [PATCH net-next v4 07/12] net: ethernet: oa_tc6: enable open alliance tc6 data communication Parthiban Veerasooran
@ 2024-04-18 12:56 ` Parthiban Veerasooran
  2024-04-24  0:02   ` Andrew Lunn
  2024-04-18 12:56 ` [PATCH net-next v4 09/12] net: ethernet: oa_tc6: implement receive path to receive rx " Parthiban Veerasooran
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 96+ messages in thread
From: Parthiban Veerasooran @ 2024-04-18 12:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean
  Cc: UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler,
	Parthiban Veerasooran

The transmit ethernet frame will be converted into multiple transmit data
chunks. Each transmit data chunk consists of a 4 bytes header followed by
a 64 bytes transmit data chunk payload. The 4 bytes data header occurs at
the beginning of each transmit data chunk on MOSI. The data header
contains the information needed to determine the validity and location of
the transmit frame data within the data chunk payload. The number of
transmit data chunks transmitted to mac-phy is limited to the number
transmit credits available in the mac-phy. Initially the transmit credits
will be updated from the buffer status register and then it will be
updated from the footer received on each spi data transfer. The received
footer will be examined for the transmit errors if any.

Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
---
 drivers/net/ethernet/oa_tc6.c | 394 +++++++++++++++++++++++++++++++++-
 include/linux/oa_tc6.h        |   1 +
 2 files changed, 393 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index ef7069618319..b43d4cf14ac2 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -27,6 +27,13 @@
 /* Status Register #0 */
 #define OA_TC6_REG_STATUS0			0x0008
 #define STATUS0_RESETC				BIT(6)	/* Reset Complete */
+#define STATUS0_HEADER_ERROR			BIT(5)
+#define STATUS0_LOSS_OF_FRAME_ERROR		BIT(4)
+#define STATUS0_TX_PROTOCOL_ERROR		BIT(0)
+
+/* Buffer Status Register */
+#define OA_TC6_REG_BUFFER_STATUS		0x000B
+#define BUFFER_STATUS_TX_CREDITS_AVAILABLE	GENMASK(15, 8)
 
 /* Interrupt Mask Register #0 */
 #define OA_TC6_REG_INT_MASK0			0x000C
@@ -47,6 +54,21 @@
 #define OA_TC6_CTRL_HEADER_LENGTH		GENMASK(7, 1)
 #define OA_TC6_CTRL_HEADER_PARITY		BIT(0)
 
+/* Data header */
+#define OA_TC6_DATA_HEADER_DATA_NOT_CTRL	BIT(31)
+#define OA_TC6_DATA_HEADER_DATA_VALID		BIT(21)
+#define OA_TC6_DATA_HEADER_START_VALID		BIT(20)
+#define OA_TC6_DATA_HEADER_START_WORD_OFFSET	GENMASK(19, 16)
+#define OA_TC6_DATA_HEADER_END_VALID		BIT(14)
+#define OA_TC6_DATA_HEADER_END_BYTE_OFFSET	GENMASK(13, 8)
+#define OA_TC6_DATA_HEADER_PARITY		BIT(0)
+
+/* Data footer */
+#define OA_TC6_DATA_FOOTER_EXTENDED_STS		BIT(31)
+#define OA_TC6_DATA_FOOTER_RXD_HEADER_BAD	BIT(30)
+#define OA_TC6_DATA_FOOTER_CONFIG_SYNC		BIT(29)
+#define OA_TC6_DATA_FOOTER_TX_CREDITS		GENMASK(5, 1)
+
 /* PHY – Clause 45 registers memory map selector (MMS) as per table 6 in the
  * OPEN Alliance specification.
  */
@@ -64,6 +86,14 @@
 						(OA_TC6_CTRL_MAX_REGISTERS *\
 						OA_TC6_CTRL_REG_VALUE_SIZE) +\
 						OA_TC6_CTRL_IGNORED_SIZE)
+#define OA_TC6_CHUNK_PAYLOAD_SIZE		64
+#define OA_TC6_DATA_HEADER_SIZE			4
+#define OA_TC6_CHUNK_SIZE			(OA_TC6_DATA_HEADER_SIZE +\
+						OA_TC6_CHUNK_PAYLOAD_SIZE)
+#define OA_TC6_TX_SKB_QUEUE_SIZE		2
+#define OA_TC6_MAX_TX_CHUNKS			48
+#define OA_TC6_SPI_DATA_BUF_SIZE		(OA_TC6_MAX_TX_CHUNKS *\
+						OA_TC6_CHUNK_SIZE)
 #define STATUS0_RESETC_POLL_DELAY		1000
 #define STATUS0_RESETC_POLL_TIMEOUT		1000000
 
@@ -77,10 +107,20 @@ struct oa_tc6 {
 	struct mutex spi_ctrl_lock; /* Protects spi control transfer */
 	void *spi_ctrl_tx_buf;
 	void *spi_ctrl_rx_buf;
+	void *spi_data_tx_buf;
+	void *spi_data_rx_buf;
+	struct sk_buff_head tx_skb_q;
+	struct sk_buff *tx_skb;
+	struct task_struct *spi_thread;
+	wait_queue_head_t spi_wq;
+	u16 tx_skb_offset;
+	u16 spi_data_tx_buf_offset;
+	u16 tx_credits;
 };
 
 enum oa_tc6_header_type {
 	OA_TC6_CTRL_HEADER,
+	OA_TC6_DATA_HEADER,
 };
 
 enum oa_tc6_register_op {
@@ -88,14 +128,34 @@ enum oa_tc6_register_op {
 	OA_TC6_CTRL_REG_WRITE = 1,
 };
 
+enum oa_tc6_data_valid_info {
+	OA_TC6_DATA_INVALID,
+	OA_TC6_DATA_VALID,
+};
+
+enum oa_tc6_data_start_valid_info {
+	OA_TC6_DATA_START_INVALID,
+	OA_TC6_DATA_START_VALID,
+};
+
+enum oa_tc6_data_end_valid_info {
+	OA_TC6_DATA_END_INVALID,
+	OA_TC6_DATA_END_VALID,
+};
+
 static int oa_tc6_spi_transfer(struct oa_tc6 *tc6,
 			       enum oa_tc6_header_type header_type, u16 length)
 {
 	struct spi_transfer xfer = { 0 };
 	struct spi_message msg;
 
-	xfer.tx_buf = tc6->spi_ctrl_tx_buf;
-	xfer.rx_buf = tc6->spi_ctrl_rx_buf;
+	if (header_type == OA_TC6_DATA_HEADER) {
+		xfer.tx_buf = tc6->spi_data_tx_buf;
+		xfer.rx_buf = tc6->spi_data_rx_buf;
+	} else {
+		xfer.tx_buf = tc6->spi_ctrl_tx_buf;
+		xfer.rx_buf = tc6->spi_ctrl_rx_buf;
+	}
 	xfer.len = length;
 
 	spi_message_init(&msg);
@@ -575,6 +635,304 @@ static int oa_tc6_enable_data_transfer(struct oa_tc6 *tc6)
 	return oa_tc6_write_register(tc6, OA_TC6_REG_CONFIG0, value);
 }
 
+static void oa_tc6_cleanup_ongoing_tx_skb(struct oa_tc6 *tc6)
+{
+	if (tc6->tx_skb) {
+		tc6->netdev->stats.tx_dropped++;
+		kfree_skb(tc6->tx_skb);
+		tc6->tx_skb = NULL;
+	}
+}
+
+static int oa_tc6_process_extended_status(struct oa_tc6 *tc6)
+{
+	u32 value;
+	int ret;
+
+	ret = oa_tc6_read_register(tc6, OA_TC6_REG_STATUS0, &value);
+	if (ret) {
+		netdev_err(tc6->netdev, "STATUS0 register read failed: %d\n",
+			   ret);
+		return -ENODEV;
+	}
+
+	/* Clear the error interrupts status */
+	ret = oa_tc6_write_register(tc6, OA_TC6_REG_STATUS0, value);
+	if (ret) {
+		netdev_err(tc6->netdev, "STATUS0 register write failed: %d\n",
+			   ret);
+		return -ENODEV;
+	}
+
+	if (FIELD_GET(STATUS0_TX_PROTOCOL_ERROR, value)) {
+		netdev_err(tc6->netdev, "Transmit protocol error\n");
+		return -ENODEV;
+	}
+	/* TODO: Currently loss of frame and header errors are treated as
+	 * non-recoverable errors. They will be handled in the next version.
+	 */
+	if (FIELD_GET(STATUS0_LOSS_OF_FRAME_ERROR, value)) {
+		netdev_err(tc6->netdev, "Loss of frame error\n");
+		return -ENODEV;
+	}
+	if (FIELD_GET(STATUS0_HEADER_ERROR, value)) {
+		netdev_err(tc6->netdev, "Header error\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int oa_tc6_process_rx_chunk_footer(struct oa_tc6 *tc6, u32 footer)
+{
+	/* Process rx chunk footer for the following,
+	 * 1. tx credits
+	 * 2. errors if any from MAC-PHY
+	 */
+	tc6->tx_credits = FIELD_GET(OA_TC6_DATA_FOOTER_TX_CREDITS, footer);
+
+	if (FIELD_GET(OA_TC6_DATA_FOOTER_EXTENDED_STS, footer)) {
+		int ret = oa_tc6_process_extended_status(tc6);
+
+		if (ret)
+			return ret;
+	}
+
+	/* TODO: Currently received header bad and configuration unsync errors
+	 * are treated as non-recoverable errors. They will be handled in the
+	 * next version.
+	 */
+	if (FIELD_GET(OA_TC6_DATA_FOOTER_RXD_HEADER_BAD, footer)) {
+		netdev_err(tc6->netdev, "Rxd header bad error\n");
+		return -ENODEV;
+	}
+
+	if (!FIELD_GET(OA_TC6_DATA_FOOTER_CONFIG_SYNC, footer)) {
+		netdev_err(tc6->netdev, "Config unsync error\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static u32 oa_tc6_get_rx_chunk_footer(struct oa_tc6 *tc6, u16 footer_offset)
+{
+	u8 *rx_buf = tc6->spi_data_rx_buf;
+	__be32 footer;
+
+	footer = *((__be32 *)&rx_buf[footer_offset]);
+
+	return be32_to_cpu(footer);
+}
+
+static int oa_tc6_process_spi_data_rx_buf(struct oa_tc6 *tc6, u16 length)
+{
+	u16 no_of_rx_chunks = length / OA_TC6_CHUNK_SIZE;
+	u32 footer;
+	int ret;
+
+	/* All the rx chunks in the receive SPI data buffer are examined here */
+	for (int i = 0; i < no_of_rx_chunks; i++) {
+		/* Last 4 bytes in each received chunk consist footer info */
+		footer = oa_tc6_get_rx_chunk_footer(tc6, i * OA_TC6_CHUNK_SIZE +
+						    OA_TC6_CHUNK_PAYLOAD_SIZE);
+
+		ret = oa_tc6_process_rx_chunk_footer(tc6, footer);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static __be32 oa_tc6_prepare_data_header(bool data_valid, bool start_valid,
+					 bool end_valid, u8 end_byte_offset)
+{
+	u32 header = FIELD_PREP(OA_TC6_DATA_HEADER_DATA_NOT_CTRL,
+				OA_TC6_DATA_HEADER) |
+		     FIELD_PREP(OA_TC6_DATA_HEADER_DATA_VALID, data_valid) |
+		     FIELD_PREP(OA_TC6_DATA_HEADER_START_VALID, start_valid) |
+		     FIELD_PREP(OA_TC6_DATA_HEADER_END_VALID, end_valid) |
+		     FIELD_PREP(OA_TC6_DATA_HEADER_END_BYTE_OFFSET,
+				end_byte_offset);
+
+	header |= FIELD_PREP(OA_TC6_DATA_HEADER_PARITY,
+			     oa_tc6_get_parity(header));
+
+	return cpu_to_be32(header);
+}
+
+static void oa_tc6_add_tx_skb_to_spi_buf(struct oa_tc6 *tc6)
+{
+	enum oa_tc6_data_start_valid_info start_valid = OA_TC6_DATA_START_INVALID;
+	enum oa_tc6_data_end_valid_info end_valid = OA_TC6_DATA_END_INVALID;
+	__be32 *tx_buf = tc6->spi_data_tx_buf + tc6->spi_data_tx_buf_offset;
+	u16 remaining_length = tc6->tx_skb->len - tc6->tx_skb_offset;
+	u8 *tx_skb_data = tc6->tx_skb->data + tc6->tx_skb_offset;
+	u8 end_byte_offset = 0;
+	u16 length_to_copy;
+
+	/* Set start valid if the current tx chunk contains the start of the tx
+	 * ethernet frame.
+	 */
+	if (!tc6->tx_skb_offset)
+		start_valid = OA_TC6_DATA_START_VALID;
+
+	/* If the remaining tx skb length is more than the chunk payload size of
+	 * 64 bytes then copy only 64 bytes and leave the ongoing tx skb for
+	 * next tx chunk.
+	 */
+	length_to_copy = min_t(u16, remaining_length, OA_TC6_CHUNK_PAYLOAD_SIZE);
+
+	/* Copy the tx skb data to the tx chunk payload buffer */
+	memcpy(tx_buf + 1, tx_skb_data, length_to_copy);
+	tc6->tx_skb_offset += length_to_copy;
+
+	/* Set end valid if the current tx chunk contains the end of the tx
+	 * ethernet frame.
+	 */
+	if (tc6->tx_skb->len == tc6->tx_skb_offset) {
+		end_valid = OA_TC6_DATA_END_VALID;
+		end_byte_offset = length_to_copy - 1;
+		tc6->tx_skb_offset = 0;
+		tc6->netdev->stats.tx_bytes += tc6->tx_skb->len;
+		tc6->netdev->stats.tx_packets++;
+		kfree_skb(tc6->tx_skb);
+		tc6->tx_skb = NULL;
+	}
+
+	*tx_buf = oa_tc6_prepare_data_header(OA_TC6_DATA_VALID, start_valid,
+					     end_valid, end_byte_offset);
+	tc6->spi_data_tx_buf_offset += OA_TC6_CHUNK_SIZE;
+}
+
+static u16 oa_tc6_prepare_spi_tx_buf_for_tx_skbs(struct oa_tc6 *tc6)
+{
+	u16 used_tx_credits;
+
+	/* Get tx skbs and convert them into tx chunks based on the tx credits
+	 * available.
+	 */
+	for (used_tx_credits = 0; used_tx_credits < tc6->tx_credits;
+	     used_tx_credits++) {
+		if (!tc6->tx_skb)
+			tc6->tx_skb = skb_dequeue(&tc6->tx_skb_q);
+		if (!tc6->tx_skb)
+			break;
+		oa_tc6_add_tx_skb_to_spi_buf(tc6);
+	}
+
+	return used_tx_credits * OA_TC6_CHUNK_SIZE;
+}
+
+static int oa_tc6_try_spi_transfer(struct oa_tc6 *tc6)
+{
+	int ret;
+
+	while (true) {
+		u16 spi_length = 0;
+
+		tc6->spi_data_tx_buf_offset = 0;
+
+		if (tc6->tx_skb || !skb_queue_empty(&tc6->tx_skb_q))
+			spi_length = oa_tc6_prepare_spi_tx_buf_for_tx_skbs(tc6);
+
+		if (spi_length == 0)
+			break;
+
+		ret = oa_tc6_spi_transfer(tc6, OA_TC6_DATA_HEADER, spi_length);
+		if (ret) {
+			netdev_err(tc6->netdev, "SPI data transfer failed: %d\n",
+				   ret);
+			return ret;
+		}
+
+		ret = oa_tc6_process_spi_data_rx_buf(tc6, spi_length);
+		if (ret) {
+			oa_tc6_cleanup_ongoing_tx_skb(tc6);
+			netdev_err(tc6->netdev, "Device error: %d\n", ret);
+			return ret;
+		}
+
+		if (skb_queue_len(&tc6->tx_skb_q) < OA_TC6_TX_SKB_QUEUE_SIZE &&
+		    netif_queue_stopped(tc6->netdev))
+			netif_wake_queue(tc6->netdev);
+	}
+
+	return 0;
+}
+
+static int oa_tc6_spi_thread_handler(void *data)
+{
+	struct oa_tc6 *tc6 = data;
+	int ret;
+
+	while (likely(!kthread_should_stop())) {
+		/* This kthread will be waken up if there is a tx skb */
+		wait_event_interruptible(tc6->spi_wq,
+					 !skb_queue_empty(&tc6->tx_skb_q) ||
+					 kthread_should_stop());
+
+		if (kthread_should_stop())
+			break;
+
+		ret = oa_tc6_try_spi_transfer(tc6);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int oa_tc6_update_buffer_status_from_register(struct oa_tc6 *tc6)
+{
+	u32 value;
+	int ret;
+
+	/* Initially tx credits to be updated from the register as there is no
+	 * data transfer performed yet. Later it will be updated from the rx
+	 * footer.
+	 */
+	ret = oa_tc6_read_register(tc6, OA_TC6_REG_BUFFER_STATUS, &value);
+	if (ret)
+		return ret;
+
+	tc6->tx_credits = FIELD_GET(BUFFER_STATUS_TX_CREDITS_AVAILABLE, value);
+
+	return 0;
+}
+
+/**
+ * oa_tc6_start_xmit - function for sending the tx skb which consists ethernet
+ * frame.
+ * @tc6: oa_tc6 struct.
+ * @skb: socket buffer in which the ethernet frame is stored.
+ *
+ * Returns NETDEV_TX_OK if the transmit ethernet frame skb added in the tx_skb_q
+ * otherwise returns NETDEV_TX_BUSY.
+ */
+netdev_tx_t oa_tc6_start_xmit(struct oa_tc6 *tc6, struct sk_buff *skb)
+{
+	if (skb_queue_len(&tc6->tx_skb_q) > OA_TC6_TX_SKB_QUEUE_SIZE) {
+		netif_stop_queue(tc6->netdev);
+		return NETDEV_TX_BUSY;
+	}
+
+	if (skb_linearize(skb)) {
+		dev_kfree_skb_any(skb);
+		tc6->netdev->stats.tx_dropped++;
+		return NETDEV_TX_OK;
+	}
+
+	skb_queue_tail(&tc6->tx_skb_q, skb);
+
+	/* Wake spi kthread to perform spi transfer */
+	wake_up_interruptible(&tc6->spi_wq);
+
+	return NETDEV_TX_OK;
+}
+EXPORT_SYMBOL_GPL(oa_tc6_start_xmit);
+
 /**
  * oa_tc6_init - allocates and initializes oa_tc6 structure.
  * @spi: device with which data will be exchanged.
@@ -611,6 +969,16 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev)
 	if (!tc6->spi_ctrl_rx_buf)
 		return NULL;
 
+	tc6->spi_data_tx_buf = devm_kzalloc(&tc6->spi->dev,
+					    OA_TC6_SPI_DATA_BUF_SIZE, GFP_KERNEL);
+	if (!tc6->spi_data_tx_buf)
+		return NULL;
+
+	tc6->spi_data_rx_buf = devm_kzalloc(&tc6->spi->dev,
+					    OA_TC6_SPI_DATA_BUF_SIZE, GFP_KERNEL);
+	if (!tc6->spi_data_rx_buf)
+		return NULL;
+
 	ret = oa_tc6_sw_reset_macphy(tc6);
 	if (ret) {
 		dev_err(&tc6->spi->dev,
@@ -639,6 +1007,25 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev)
 		goto phy_exit;
 	}
 
+	ret = oa_tc6_update_buffer_status_from_register(tc6);
+	if (ret) {
+		dev_err(&tc6->spi->dev,
+			"Failed to update buffer status: %d\n", ret);
+		goto phy_exit;
+	}
+
+	skb_queue_head_init(&tc6->tx_skb_q);
+	init_waitqueue_head(&tc6->spi_wq);
+
+	tc6->spi_thread = kthread_run(oa_tc6_spi_thread_handler, tc6,
+				      "oa-tc6-spi-thread");
+	if (IS_ERR(tc6->spi_thread)) {
+		dev_err(&tc6->spi->dev, "Failed to create SPI thread\n");
+		goto phy_exit;
+	}
+
+	sched_set_fifo(tc6->spi_thread);
+
 	return tc6;
 
 phy_exit:
@@ -654,6 +1041,9 @@ EXPORT_SYMBOL_GPL(oa_tc6_init);
 void oa_tc6_exit(struct oa_tc6 *tc6)
 {
 	oa_tc6_phy_exit(tc6);
+	kthread_stop(tc6->spi_thread);
+	dev_kfree_skb_any(tc6->tx_skb);
+	skb_queue_purge(&tc6->tx_skb_q);
 }
 EXPORT_SYMBOL_GPL(oa_tc6_exit);
 
diff --git a/include/linux/oa_tc6.h b/include/linux/oa_tc6.h
index 606ba9f1e663..5c7811ac9cbe 100644
--- a/include/linux/oa_tc6.h
+++ b/include/linux/oa_tc6.h
@@ -20,3 +20,4 @@ int oa_tc6_write_registers(struct oa_tc6 *tc6, u32 address, u32 value[],
 int oa_tc6_read_register(struct oa_tc6 *tc6, u32 address, u32 *value);
 int oa_tc6_read_registers(struct oa_tc6 *tc6, u32 address, u32 value[],
 			  u8 length);
+netdev_tx_t oa_tc6_start_xmit(struct oa_tc6 *tc6, struct sk_buff *skb);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 96+ messages in thread

* [PATCH net-next v4 09/12] net: ethernet: oa_tc6: implement receive path to receive rx ethernet frames
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
                   ` (7 preceding siblings ...)
  2024-04-18 12:56 ` [PATCH net-next v4 08/12] net: ethernet: oa_tc6: implement transmit path to transfer tx ethernet frames Parthiban Veerasooran
@ 2024-04-18 12:56 ` Parthiban Veerasooran
  2024-04-24  0:08   ` Andrew Lunn
  2024-04-27 20:02   ` Ramón Nordin Rodriguez
  2024-04-18 12:56 ` [PATCH net-next v4 10/12] net: ethernet: oa_tc6: implement mac-phy interrupt Parthiban Veerasooran
                   ` (6 subsequent siblings)
  15 siblings, 2 replies; 96+ messages in thread
From: Parthiban Veerasooran @ 2024-04-18 12:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean
  Cc: UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler,
	Parthiban Veerasooran

SPI rx data buffer can contain one or more receive data chunks. A receive
data chunk consists a 64 bytes receive data chunk payload followed a
4 bytes data footer at the end. The data footer contains the information
needed to determine the validity and location of the receive frame data
within the receive data chunk payload and the host can use these
information to generate ethernet frame. Initially the receive chunks
available will be updated from the buffer status register and then it
will be updated from the footer received on each spi data transfer. Tx
data valid or empty chunks equal to the number receive chunks available
will be transmitted in the MOSI to receive all the rx chunks.
Additionally the receive data footer contains the below information as
well. The received footer will be examined for the receive errors if any.

Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
---
 drivers/net/ethernet/oa_tc6.c | 226 +++++++++++++++++++++++++++++++++-
 1 file changed, 223 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index b43d4cf14ac2..fa08956a855f 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -29,11 +29,13 @@
 #define STATUS0_RESETC				BIT(6)	/* Reset Complete */
 #define STATUS0_HEADER_ERROR			BIT(5)
 #define STATUS0_LOSS_OF_FRAME_ERROR		BIT(4)
+#define STATUS0_RX_BUFFER_OVERFLOW_ERROR	BIT(3)
 #define STATUS0_TX_PROTOCOL_ERROR		BIT(0)
 
 /* Buffer Status Register */
 #define OA_TC6_REG_BUFFER_STATUS		0x000B
 #define BUFFER_STATUS_TX_CREDITS_AVAILABLE	GENMASK(15, 8)
+#define BUFFER_STATUS_RX_CHUNKS_AVAILABLE	GENMASK(7, 0)
 
 /* Interrupt Mask Register #0 */
 #define OA_TC6_REG_INT_MASK0			0x000C
@@ -67,6 +69,12 @@
 #define OA_TC6_DATA_FOOTER_EXTENDED_STS		BIT(31)
 #define OA_TC6_DATA_FOOTER_RXD_HEADER_BAD	BIT(30)
 #define OA_TC6_DATA_FOOTER_CONFIG_SYNC		BIT(29)
+#define OA_TC6_DATA_FOOTER_RX_CHUNKS_AVAILABLE	GENMASK(28, 24)
+#define OA_TC6_DATA_FOOTER_DATA_VALID		BIT(21)
+#define OA_TC6_DATA_FOOTER_START_VALID		BIT(20)
+#define OA_TC6_DATA_FOOTER_START_WORD_OFFSET	GENMASK(19, 16)
+#define OA_TC6_DATA_FOOTER_END_VALID		BIT(14)
+#define OA_TC6_DATA_FOOTER_END_BYTE_OFFSET	GENMASK(13, 8)
 #define OA_TC6_DATA_FOOTER_TX_CREDITS		GENMASK(5, 1)
 
 /* PHY – Clause 45 registers memory map selector (MMS) as per table 6 in the
@@ -111,11 +119,14 @@ struct oa_tc6 {
 	void *spi_data_rx_buf;
 	struct sk_buff_head tx_skb_q;
 	struct sk_buff *tx_skb;
+	struct sk_buff *rx_skb;
 	struct task_struct *spi_thread;
 	wait_queue_head_t spi_wq;
 	u16 tx_skb_offset;
 	u16 spi_data_tx_buf_offset;
 	u16 tx_credits;
+	u8 rx_chunks_available;
+	bool rx_buf_overflow;
 };
 
 enum oa_tc6_header_type {
@@ -635,6 +646,15 @@ static int oa_tc6_enable_data_transfer(struct oa_tc6 *tc6)
 	return oa_tc6_write_register(tc6, OA_TC6_REG_CONFIG0, value);
 }
 
+static void oa_tc6_cleanup_ongoing_rx_skb(struct oa_tc6 *tc6)
+{
+	if (tc6->rx_skb) {
+		tc6->netdev->stats.rx_dropped++;
+		kfree_skb(tc6->rx_skb);
+		tc6->rx_skb = NULL;
+	}
+}
+
 static void oa_tc6_cleanup_ongoing_tx_skb(struct oa_tc6 *tc6)
 {
 	if (tc6->tx_skb) {
@@ -664,6 +684,13 @@ static int oa_tc6_process_extended_status(struct oa_tc6 *tc6)
 		return -ENODEV;
 	}
 
+	if (FIELD_GET(STATUS0_RX_BUFFER_OVERFLOW_ERROR, value)) {
+		tc6->rx_buf_overflow = true;
+		oa_tc6_cleanup_ongoing_rx_skb(tc6);
+		net_err_ratelimited("%s: Receive buffer overflow error\n",
+				    tc6->netdev->name);
+		return -EAGAIN;
+	}
 	if (FIELD_GET(STATUS0_TX_PROTOCOL_ERROR, value)) {
 		netdev_err(tc6->netdev, "Transmit protocol error\n");
 		return -ENODEV;
@@ -688,8 +715,11 @@ static int oa_tc6_process_rx_chunk_footer(struct oa_tc6 *tc6, u32 footer)
 	/* Process rx chunk footer for the following,
 	 * 1. tx credits
 	 * 2. errors if any from MAC-PHY
+	 * 3. receive chunks available
 	 */
 	tc6->tx_credits = FIELD_GET(OA_TC6_DATA_FOOTER_TX_CREDITS, footer);
+	tc6->rx_chunks_available = FIELD_GET(OA_TC6_DATA_FOOTER_RX_CHUNKS_AVAILABLE,
+					     footer);
 
 	if (FIELD_GET(OA_TC6_DATA_FOOTER_EXTENDED_STS, footer)) {
 		int ret = oa_tc6_process_extended_status(tc6);
@@ -715,6 +745,138 @@ static int oa_tc6_process_rx_chunk_footer(struct oa_tc6 *tc6, u32 footer)
 	return 0;
 }
 
+static void oa_tc6_submit_rx_skb(struct oa_tc6 *tc6)
+{
+	tc6->rx_skb->protocol = eth_type_trans(tc6->rx_skb, tc6->netdev);
+	tc6->netdev->stats.rx_packets++;
+	tc6->netdev->stats.rx_bytes += tc6->rx_skb->len;
+
+	if (netif_rx(tc6->rx_skb) == NET_RX_DROP)
+		tc6->netdev->stats.rx_dropped++;
+
+	tc6->rx_skb = NULL;
+}
+
+static void oa_tc6_update_rx_skb(struct oa_tc6 *tc6, u8 *payload, u8 length)
+{
+	memcpy(skb_put(tc6->rx_skb, length), payload, length);
+}
+
+static int oa_tc6_allocate_rx_skb(struct oa_tc6 *tc6)
+{
+	tc6->rx_skb = netdev_alloc_skb(tc6->netdev, tc6->netdev->mtu + ETH_HLEN +
+				       ETH_FCS_LEN + NET_IP_ALIGN);
+	if (!tc6->rx_skb) {
+		tc6->netdev->stats.rx_dropped++;
+		return -ENOMEM;
+	}
+	skb_reserve(tc6->rx_skb, NET_IP_ALIGN);
+
+	return 0;
+}
+
+static int oa_tc6_prcs_complete_rx_frame(struct oa_tc6 *tc6, u8 *payload,
+					 u16 size)
+{
+	int ret;
+
+	ret = oa_tc6_allocate_rx_skb(tc6);
+	if (ret)
+		return ret;
+
+	oa_tc6_update_rx_skb(tc6, payload, size);
+
+	oa_tc6_submit_rx_skb(tc6);
+
+	return 0;
+}
+
+static int oa_tc6_prcs_rx_frame_start(struct oa_tc6 *tc6, u8 *payload, u16 size)
+{
+	int ret;
+
+	ret = oa_tc6_allocate_rx_skb(tc6);
+	if (ret)
+		return ret;
+
+	oa_tc6_update_rx_skb(tc6, payload, size);
+
+	return 0;
+}
+
+static void oa_tc6_prcs_rx_frame_end(struct oa_tc6 *tc6, u8 *payload, u16 size)
+{
+	oa_tc6_update_rx_skb(tc6, payload, size);
+
+	oa_tc6_submit_rx_skb(tc6);
+}
+
+static void oa_tc6_prcs_ongoing_rx_frame(struct oa_tc6 *tc6, u8 *payload,
+					 u32 footer)
+{
+	oa_tc6_update_rx_skb(tc6, payload, OA_TC6_CHUNK_PAYLOAD_SIZE);
+}
+
+static int oa_tc6_prcs_rx_chunk_payload(struct oa_tc6 *tc6, u8 *payload,
+					u32 footer)
+{
+	u8 start_byte_offset = FIELD_GET(OA_TC6_DATA_FOOTER_START_WORD_OFFSET,
+					 footer) * sizeof(u32);
+	u8 end_byte_offset = FIELD_GET(OA_TC6_DATA_FOOTER_END_BYTE_OFFSET,
+				       footer);
+	bool start_valid = FIELD_GET(OA_TC6_DATA_FOOTER_START_VALID, footer);
+	bool end_valid = FIELD_GET(OA_TC6_DATA_FOOTER_END_VALID, footer);
+	u16 size;
+
+	/* Restart the new rx frame after receiving rx buffer overflow error */
+	if (start_valid && tc6->rx_buf_overflow)
+		tc6->rx_buf_overflow = false;
+
+	if (tc6->rx_buf_overflow)
+		return 0;
+
+	/* Process the chunk with complete rx frame */
+	if (start_valid && end_valid && start_byte_offset < end_byte_offset) {
+		size = end_byte_offset + 1 - start_byte_offset;
+		return oa_tc6_prcs_complete_rx_frame(tc6, &payload[start_byte_offset],
+						     size);
+	}
+
+	/* Process the chunk with only rx frame start */
+	if (start_valid && !end_valid) {
+		size = OA_TC6_CHUNK_PAYLOAD_SIZE - start_byte_offset;
+		return oa_tc6_prcs_rx_frame_start(tc6, &payload[start_byte_offset],
+						  size);
+	}
+
+	/* Process the chunk with only rx frame end */
+	if (end_valid && !start_valid) {
+		size = end_byte_offset + 1;
+		oa_tc6_prcs_rx_frame_end(tc6, payload, size);
+		return 0;
+	}
+
+	/* Process the chunk with previous rx frame end and next rx frame start */
+	if (start_valid && end_valid && start_byte_offset > end_byte_offset) {
+		/* After rx buffer overflow error received, there might be a
+		 * possibility of getting an end valid of a previously
+		 * incomplete rx frame along with the new rx frame start valid.
+		 */
+		if (tc6->rx_skb) {
+			size = end_byte_offset + 1;
+			oa_tc6_prcs_rx_frame_end(tc6, payload, size);
+		}
+		size = OA_TC6_CHUNK_PAYLOAD_SIZE - start_byte_offset;
+		return oa_tc6_prcs_rx_frame_start(tc6, &payload[start_byte_offset],
+						  size);
+	}
+
+	/* Process the chunk with ongoing rx frame data */
+	oa_tc6_prcs_ongoing_rx_frame(tc6, payload, footer);
+
+	return 0;
+}
+
 static u32 oa_tc6_get_rx_chunk_footer(struct oa_tc6 *tc6, u16 footer_offset)
 {
 	u8 *rx_buf = tc6->spi_data_rx_buf;
@@ -740,6 +902,18 @@ static int oa_tc6_process_spi_data_rx_buf(struct oa_tc6 *tc6, u16 length)
 		ret = oa_tc6_process_rx_chunk_footer(tc6, footer);
 		if (ret)
 			return ret;
+
+		/* If there is a data valid chunks then process it for the
+		 * information needed to determine the validity and the location
+		 * of the receive frame data.
+		 */
+		if (FIELD_GET(OA_TC6_DATA_FOOTER_DATA_VALID, footer)) {
+			u8 *payload = tc6->spi_data_rx_buf + i * OA_TC6_CHUNK_SIZE;
+
+			ret = oa_tc6_prcs_rx_chunk_payload(tc6, payload, footer);
+			if (ret)
+				return ret;
+		}
 	}
 
 	return 0;
@@ -825,6 +999,42 @@ static u16 oa_tc6_prepare_spi_tx_buf_for_tx_skbs(struct oa_tc6 *tc6)
 	return used_tx_credits * OA_TC6_CHUNK_SIZE;
 }
 
+static void oa_tc6_add_empty_chunks_to_spi_buf(struct oa_tc6 *tc6,
+					       u16 needed_empty_chunks)
+{
+	__be32 header;
+
+	header = oa_tc6_prepare_data_header(OA_TC6_DATA_INVALID,
+					    OA_TC6_DATA_START_INVALID,
+					    OA_TC6_DATA_END_INVALID, 0);
+
+	while (needed_empty_chunks--) {
+		__be32 *tx_buf = tc6->spi_data_tx_buf + tc6->spi_data_tx_buf_offset;
+
+		*tx_buf = header;
+		tc6->spi_data_tx_buf_offset += OA_TC6_CHUNK_SIZE;
+	}
+}
+
+static u16 oa_tc6_prepare_spi_tx_buf_for_rx_chunks(struct oa_tc6 *tc6, u16 len)
+{
+	u16 tx_chunks = len / OA_TC6_CHUNK_SIZE;
+	u16 needed_empty_chunks;
+
+	/* If there are more chunks to receive than to transmit, we need to add
+	 * enough empty tx chunks to allow the reception of the excess rx
+	 * chunks.
+	 */
+	if (tx_chunks >= tc6->rx_chunks_available)
+		return len;
+
+	needed_empty_chunks = tc6->rx_chunks_available - tx_chunks;
+
+	oa_tc6_add_empty_chunks_to_spi_buf(tc6, needed_empty_chunks);
+
+	return needed_empty_chunks * OA_TC6_CHUNK_SIZE + len;
+}
+
 static int oa_tc6_try_spi_transfer(struct oa_tc6 *tc6)
 {
 	int ret;
@@ -837,6 +1047,9 @@ static int oa_tc6_try_spi_transfer(struct oa_tc6 *tc6)
 		if (tc6->tx_skb || !skb_queue_empty(&tc6->tx_skb_q))
 			spi_length = oa_tc6_prepare_spi_tx_buf_for_tx_skbs(tc6);
 
+		if (tc6->rx_chunks_available)
+			spi_length = oa_tc6_prepare_spi_tx_buf_for_rx_chunks(tc6, spi_length);
+
 		if (spi_length == 0)
 			break;
 
@@ -849,7 +1062,11 @@ static int oa_tc6_try_spi_transfer(struct oa_tc6 *tc6)
 
 		ret = oa_tc6_process_spi_data_rx_buf(tc6, spi_length);
 		if (ret) {
+			if (ret == -EAGAIN)
+				continue;
+
 			oa_tc6_cleanup_ongoing_tx_skb(tc6);
+			oa_tc6_cleanup_ongoing_rx_skb(tc6);
 			netdev_err(tc6->netdev, "Device error: %d\n", ret);
 			return ret;
 		}
@@ -889,15 +1106,17 @@ static int oa_tc6_update_buffer_status_from_register(struct oa_tc6 *tc6)
 	u32 value;
 	int ret;
 
-	/* Initially tx credits to be updated from the register as there is no
-	 * data transfer performed yet. Later it will be updated from the rx
-	 * footer.
+	/* Initially tx credits and rx chunks available to be updated from the
+	 * register as there is no data transfer performed yet. Later they will
+	 * be updated from the rx footer.
 	 */
 	ret = oa_tc6_read_register(tc6, OA_TC6_REG_BUFFER_STATUS, &value);
 	if (ret)
 		return ret;
 
 	tc6->tx_credits = FIELD_GET(BUFFER_STATUS_TX_CREDITS_AVAILABLE, value);
+	tc6->rx_chunks_available = FIELD_GET(BUFFER_STATUS_RX_CHUNKS_AVAILABLE,
+					     value);
 
 	return 0;
 }
@@ -1043,6 +1262,7 @@ void oa_tc6_exit(struct oa_tc6 *tc6)
 	oa_tc6_phy_exit(tc6);
 	kthread_stop(tc6->spi_thread);
 	dev_kfree_skb_any(tc6->tx_skb);
+	dev_kfree_skb_any(tc6->rx_skb);
 	skb_queue_purge(&tc6->tx_skb_q);
 }
 EXPORT_SYMBOL_GPL(oa_tc6_exit);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 96+ messages in thread

* [PATCH net-next v4 10/12] net: ethernet: oa_tc6: implement mac-phy interrupt
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
                   ` (8 preceding siblings ...)
  2024-04-18 12:56 ` [PATCH net-next v4 09/12] net: ethernet: oa_tc6: implement receive path to receive rx " Parthiban Veerasooran
@ 2024-04-18 12:56 ` Parthiban Veerasooran
  2024-04-24  0:10   ` Andrew Lunn
  2024-04-18 12:56 ` [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY Parthiban Veerasooran
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 96+ messages in thread
From: Parthiban Veerasooran @ 2024-04-18 12:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean
  Cc: UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler,
	Parthiban Veerasooran

The MAC-PHY interrupt is asserted when the following conditions are met.

Receive chunks available - This interrupt is asserted when the previous
data footer had no receive data chunks available and once the receive
data chunks become available for reading. On reception of the first data
header this interrupt will be deasserted.

Transmit chunk credits available - This interrupt is asserted when the
previous data footer indicated no transmit credits available and once the
transmit credits become available for transmitting transmit data chunks.
On reception of the first data header this interrupt will be deasserted.

Extended status event - This interrupt is asserted when the previous data
footer indicated no extended status and once the extended event become
available. In this case the host should read status #0 register to know
the corresponding error/event. On reception of the first data header this
interrupt will be deasserted.

Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
---
 drivers/net/ethernet/oa_tc6.c | 53 +++++++++++++++++++++++++++++++++--
 1 file changed, 51 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index fa08956a855f..9f17f3712137 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -127,6 +127,7 @@ struct oa_tc6 {
 	u16 tx_credits;
 	u8 rx_chunks_available;
 	bool rx_buf_overflow;
+	bool int_flag;
 };
 
 enum oa_tc6_header_type {
@@ -1050,6 +1051,14 @@ static int oa_tc6_try_spi_transfer(struct oa_tc6 *tc6)
 		if (tc6->rx_chunks_available)
 			spi_length = oa_tc6_prepare_spi_tx_buf_for_rx_chunks(tc6, spi_length);
 
+		if (tc6->int_flag) {
+			tc6->int_flag = false;
+			if (spi_length == 0) {
+				oa_tc6_add_empty_chunks_to_spi_buf(tc6, 1);
+				spi_length = OA_TC6_CHUNK_SIZE;
+			}
+		}
+
 		if (spi_length == 0)
 			break;
 
@@ -1085,8 +1094,10 @@ static int oa_tc6_spi_thread_handler(void *data)
 	int ret;
 
 	while (likely(!kthread_should_stop())) {
-		/* This kthread will be waken up if there is a tx skb */
-		wait_event_interruptible(tc6->spi_wq,
+		/* This kthread will be waken up if there is a tx skb or mac-phy
+		 * interrupt to perform spi transfer with tx chunks.
+		 */
+		wait_event_interruptible(tc6->spi_wq, tc6->int_flag ||
 					 !skb_queue_empty(&tc6->tx_skb_q) ||
 					 kthread_should_stop());
 
@@ -1121,6 +1132,24 @@ static int oa_tc6_update_buffer_status_from_register(struct oa_tc6 *tc6)
 	return 0;
 }
 
+static irqreturn_t oa_tc6_macphy_isr(int irq, void *data)
+{
+	struct oa_tc6 *tc6 = data;
+
+	/* MAC-PHY interrupt can occur for the following reasons.
+	 * - availability of tx credits if it was 0 before and not reported in
+	 *   the previous rx footer.
+	 * - availability of rx chunks if it was 0 before and not reported in
+	 *   the previous rx footer.
+	 * - extended status event not reported in the previous rx footer.
+	 */
+	tc6->int_flag = true;
+	/* Wake spi kthread to perform spi transfer */
+	wake_up_interruptible(&tc6->spi_wq);
+
+	return IRQ_HANDLED;
+}
+
 /**
  * oa_tc6_start_xmit - function for sending the tx skb which consists ethernet
  * frame.
@@ -1245,8 +1274,28 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev)
 
 	sched_set_fifo(tc6->spi_thread);
 
+	ret = devm_request_irq(&tc6->spi->dev, tc6->spi->irq, oa_tc6_macphy_isr,
+			       IRQF_TRIGGER_FALLING, dev_name(&tc6->spi->dev),
+			       tc6);
+	if (ret) {
+		dev_err(&tc6->spi->dev, "Failed to request macphy isr %d\n",
+			ret);
+		goto kthread_stop;
+	}
+
+	/* oa_tc6_sw_reset_macphy() function resets and clears the MAC-PHY reset
+	 * complete status. IRQ is also asserted on reset completion and it is
+	 * remain asserted until MAC-PHY receives a data chunk. So performing an
+	 * empty data chunk transmission will deassert the IRQ. Refer section
+	 * 7.7 and 9.2.8.8 in the OPEN Alliance specification for more details.
+	 */
+	tc6->int_flag = true;
+	wake_up_interruptible(&tc6->spi_wq);
+
 	return tc6;
 
+kthread_stop:
+	kthread_stop(tc6->spi_thread);
 phy_exit:
 	oa_tc6_phy_exit(tc6);
 	return NULL;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 96+ messages in thread

* [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
                   ` (9 preceding siblings ...)
  2024-04-18 12:56 ` [PATCH net-next v4 10/12] net: ethernet: oa_tc6: implement mac-phy interrupt Parthiban Veerasooran
@ 2024-04-18 12:56 ` Parthiban Veerasooran
  2024-04-24  0:27   ` Andrew Lunn
                     ` (2 more replies)
  2024-04-18 12:56 ` [PATCH net-next v4 12/12] dt-bindings: net: add Microchip's LAN865X 10BASE-T1S MACPHY Parthiban Veerasooran
                   ` (4 subsequent siblings)
  15 siblings, 3 replies; 96+ messages in thread
From: Parthiban Veerasooran @ 2024-04-18 12:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean
  Cc: UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler,
	Parthiban Veerasooran

The LAN8650/1 is designed to conform to the OPEN Alliance 10BASE-T1x
MAC-PHY Serial Interface specification, Version 1.1. The IEEE Clause 4
MAC integration provides the low pin count standard SPI interface to any
microcontroller therefore providing Ethernet functionality without
requiring MAC integration within the microcontroller. The LAN8650/1
operates as an SPI client supporting SCLK clock rates up to a maximum of
25 MHz. This SPI interface supports the transfer of both data (Ethernet
frames) and control (register access).

By default, the chunk data payload is 64 bytes in size. The Ethernet
Media Access Controller (MAC) module implements a 10 Mbps half duplex
Ethernet MAC, compatible with the IEEE 802.3 standard. 10BASE-T1S
physical layer transceiver integrated is into the LAN8650/1. The PHY and
MAC are connected via an internal Media Independent Interface (MII).

Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
---
 MAINTAINERS                                   |   6 +
 drivers/net/ethernet/microchip/Kconfig        |   1 +
 drivers/net/ethernet/microchip/Makefile       |   1 +
 .../net/ethernet/microchip/lan865x/Kconfig    |  19 +
 .../net/ethernet/microchip/lan865x/Makefile   |   6 +
 .../net/ethernet/microchip/lan865x/lan865x.c  | 384 ++++++++++++++++++
 6 files changed, 417 insertions(+)
 create mode 100644 drivers/net/ethernet/microchip/lan865x/Kconfig
 create mode 100644 drivers/net/ethernet/microchip/lan865x/Makefile
 create mode 100644 drivers/net/ethernet/microchip/lan865x/lan865x.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 603528948f61..f41b7f2257d2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14374,6 +14374,12 @@ L:	netdev@vger.kernel.org
 S:	Maintained
 F:	drivers/net/ethernet/microchip/lan743x_*
 
+MICROCHIP LAN8650/1 10BASE-T1S MACPHY ETHERNET DRIVER
+M:	Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
+L:	netdev@vger.kernel.org
+S:	Maintained
+F:	drivers/net/ethernet/microchip/lan865x/lan865x.c
+
 MICROCHIP LAN87xx/LAN937x T1 PHY DRIVER
 M:	Arun Ramadoss <arun.ramadoss@microchip.com>
 R:	UNGLinuxDriver@microchip.com
diff --git a/drivers/net/ethernet/microchip/Kconfig b/drivers/net/ethernet/microchip/Kconfig
index 43ba71e82260..06ca79669053 100644
--- a/drivers/net/ethernet/microchip/Kconfig
+++ b/drivers/net/ethernet/microchip/Kconfig
@@ -56,6 +56,7 @@ config LAN743X
 	  To compile this driver as a module, choose M here. The module will be
 	  called lan743x.
 
+source "drivers/net/ethernet/microchip/lan865x/Kconfig"
 source "drivers/net/ethernet/microchip/lan966x/Kconfig"
 source "drivers/net/ethernet/microchip/sparx5/Kconfig"
 source "drivers/net/ethernet/microchip/vcap/Kconfig"
diff --git a/drivers/net/ethernet/microchip/Makefile b/drivers/net/ethernet/microchip/Makefile
index bbd349264e6f..15dfbb321057 100644
--- a/drivers/net/ethernet/microchip/Makefile
+++ b/drivers/net/ethernet/microchip/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_LAN743X) += lan743x.o
 
 lan743x-objs := lan743x_main.o lan743x_ethtool.o lan743x_ptp.o
 
+obj-$(CONFIG_LAN865X) += lan865x/
 obj-$(CONFIG_LAN966X_SWITCH) += lan966x/
 obj-$(CONFIG_SPARX5_SWITCH) += sparx5/
 obj-$(CONFIG_VCAP) += vcap/
diff --git a/drivers/net/ethernet/microchip/lan865x/Kconfig b/drivers/net/ethernet/microchip/lan865x/Kconfig
new file mode 100644
index 000000000000..f3d60d14e202
--- /dev/null
+++ b/drivers/net/ethernet/microchip/lan865x/Kconfig
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Microchip LAN865x Driver Support
+#
+
+if NET_VENDOR_MICROCHIP
+
+config LAN865X
+	tristate "LAN865x support"
+	depends on SPI
+	depends on OA_TC6
+	help
+	  Support for the Microchip LAN8650/1 Rev.B1 MACPHY Ethernet chip. It
+	  uses OPEN Alliance 10BASE-T1x Serial Interface specification.
+
+	  To compile this driver as a module, choose M here. The module will be
+	  called lan865x.
+
+endif # NET_VENDOR_MICROCHIP
diff --git a/drivers/net/ethernet/microchip/lan865x/Makefile b/drivers/net/ethernet/microchip/lan865x/Makefile
new file mode 100644
index 000000000000..9f5dd89c1eb8
--- /dev/null
+++ b/drivers/net/ethernet/microchip/lan865x/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Makefile for the Microchip LAN865x Driver
+#
+
+obj-$(CONFIG_LAN865X) += lan865x.o
diff --git a/drivers/net/ethernet/microchip/lan865x/lan865x.c b/drivers/net/ethernet/microchip/lan865x/lan865x.c
new file mode 100644
index 000000000000..9abefa8b9d9f
--- /dev/null
+++ b/drivers/net/ethernet/microchip/lan865x/lan865x.c
@@ -0,0 +1,384 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Microchip's LAN865x 10BASE-T1S MAC-PHY driver
+ *
+ * Author: Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/phy.h>
+#include <linux/oa_tc6.h>
+
+#define DRV_NAME			"lan865x"
+
+/* MAC Network Control Register */
+#define LAN865X_REG_MAC_NET_CTL		0x00010000
+#define MAC_NET_CTL_TXEN		BIT(3) /* Transmit Enable */
+#define MAC_NET_CTL_RXEN		BIT(2) /* Receive Enable */
+
+#define LAN865X_REG_MAC_NET_CFG		0x00010001 /* MAC Network Configuration Reg */
+#define MAC_NET_CFG_PROMISCUOUS_MODE	BIT(4)
+#define MAC_NET_CFG_MULTICAST_MODE	BIT(6)
+#define MAC_NET_CFG_UNICAST_MODE	BIT(7)
+
+#define LAN865X_REG_MAC_L_HASH		0x00010020 /* MAC Hash Register Bottom */
+#define LAN865X_REG_MAC_H_HASH		0x00010021 /* MAC Hash Register Top */
+#define LAN865X_REG_MAC_L_SADDR1	0x00010022 /* MAC Specific Addr 1 Bottom Reg */
+#define LAN865X_REG_MAC_H_SADDR1	0x00010023 /* MAC Specific Addr 1 Top Reg */
+
+/* OPEN Alliance Configuration Register #0 */
+#define OA_TC6_REG_CONFIG0		0x0004
+#define CONFIG0_ZARFE_ENABLE		BIT(12)
+
+struct lan865x_priv {
+	struct work_struct multicast_work;
+	struct net_device *netdev;
+	struct spi_device *spi;
+	struct oa_tc6 *tc6;
+};
+
+static int lan865x_set_hw_macaddr_low_bytes(struct oa_tc6 *tc6, const u8 *mac)
+{
+	u32 regval;
+
+	regval = (mac[3] << 24) | (mac[2] << 16) | (mac[1] << 8) | mac[0];
+
+	return oa_tc6_write_register(tc6, LAN865X_REG_MAC_L_SADDR1, regval);
+}
+
+static int lan865x_set_hw_macaddr(struct lan865x_priv *priv, const u8 *mac)
+{
+	int restore_ret;
+	u32 regval;
+	int ret;
+
+	/* Configure MAC address low bytes */
+	ret = lan865x_set_hw_macaddr_low_bytes(priv->tc6, mac);
+	if (ret)
+		return ret;
+
+	/* Prepare and configure MAC address high bytes */
+	regval = (mac[5] << 8) | mac[4];
+	ret = oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_H_SADDR1, regval);
+	if (!ret)
+		return 0;
+
+	/* Restore the old MAC address low bytes from netdev if the new MAC
+	 * address high bytes setting failed.
+	 */
+	restore_ret = lan865x_set_hw_macaddr_low_bytes(priv->tc6,
+						       priv->netdev->dev_addr);
+	if (restore_ret)
+		return restore_ret;
+
+	return ret;
+}
+
+static void
+lan865x_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info)
+{
+	strscpy(info->driver, DRV_NAME, sizeof(info->driver));
+	strscpy(info->bus_info, dev_name(netdev->dev.parent),
+		sizeof(info->bus_info));
+}
+
+static const struct ethtool_ops lan865x_ethtool_ops = {
+	.get_drvinfo        = lan865x_get_drvinfo,
+	.get_link_ksettings = phy_ethtool_get_link_ksettings,
+	.set_link_ksettings = phy_ethtool_set_link_ksettings,
+};
+
+static int lan865x_set_mac_address(struct net_device *netdev, void *addr)
+{
+	struct lan865x_priv *priv = netdev_priv(netdev);
+	struct sockaddr *address = addr;
+	int ret;
+
+	ret = eth_prepare_mac_addr_change(netdev, addr);
+	if (ret < 0)
+		return ret;
+
+	if (ether_addr_equal(address->sa_data, netdev->dev_addr))
+		return 0;
+
+	ret = lan865x_set_hw_macaddr(priv, address->sa_data);
+	if (ret)
+		return ret;
+
+	eth_hw_addr_set(netdev, address->sa_data);
+
+	return 0;
+}
+
+static u32 lan865x_hash(u8 addr[ETH_ALEN])
+{
+	return (ether_crc(ETH_ALEN, addr) >> 26) & GENMASK(5, 0);
+}
+
+static void lan865x_set_specific_multicast_addr(struct net_device *netdev)
+{
+	struct lan865x_priv *priv = netdev_priv(netdev);
+	struct netdev_hw_addr *ha;
+	u32 hash_lo = 0;
+	u32 hash_hi = 0;
+
+	netdev_for_each_mc_addr(ha, netdev) {
+		u32 bit_num = lan865x_hash(ha->addr);
+		u32 mask = BIT(bit_num);
+
+		/* 5th bit of the 6 bits hash value is used to determine which
+		 * bit to set in either a high or low hash register.
+		 */
+		if (bit_num & BIT(5))
+			hash_hi |= mask;
+		else
+			hash_lo |= mask;
+	}
+
+	/* Enabling specific multicast addresses */
+	if (oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_H_HASH, hash_hi)) {
+		netdev_err(netdev, "Failed to write reg_hashh");
+		return;
+	}
+
+	if (oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_L_HASH, hash_lo))
+		netdev_err(netdev, "Failed to write reg_hashl");
+}
+
+static void lan865x_multicast_work_handler(struct work_struct *work)
+{
+	struct lan865x_priv *priv = container_of(work, struct lan865x_priv,
+						 multicast_work);
+	u32 regval = 0;
+
+	if (priv->netdev->flags & IFF_PROMISC) {
+		/* Enabling promiscuous mode */
+		regval |= MAC_NET_CFG_PROMISCUOUS_MODE;
+		regval &= (~MAC_NET_CFG_MULTICAST_MODE);
+		regval &= (~MAC_NET_CFG_UNICAST_MODE);
+	} else if (priv->netdev->flags & IFF_ALLMULTI) {
+		/* Enabling all multicast mode */
+		regval &= (~MAC_NET_CFG_PROMISCUOUS_MODE);
+		regval |= MAC_NET_CFG_MULTICAST_MODE;
+		regval &= (~MAC_NET_CFG_UNICAST_MODE);
+	} else if (!netdev_mc_empty(priv->netdev)) {
+		lan865x_set_specific_multicast_addr(priv->netdev);
+		regval &= (~MAC_NET_CFG_PROMISCUOUS_MODE);
+		regval &= (~MAC_NET_CFG_MULTICAST_MODE);
+		regval |= MAC_NET_CFG_UNICAST_MODE;
+	} else {
+		/* enabling local mac address only */
+		if (oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_H_HASH, 0)) {
+			netdev_err(priv->netdev, "Failed to write reg_hashh");
+			return;
+		}
+		if (oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_L_HASH, 0)) {
+			netdev_err(priv->netdev, "Failed to write reg_hashl");
+			return;
+		}
+	}
+	if (oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_NET_CFG, regval))
+		netdev_err(priv->netdev,
+			   "Failed to enable promiscuous/multicast/normal mode");
+}
+
+static void lan865x_set_multicast_list(struct net_device *netdev)
+{
+	struct lan865x_priv *priv = netdev_priv(netdev);
+
+	schedule_work(&priv->multicast_work);
+}
+
+static netdev_tx_t lan865x_send_packet(struct sk_buff *skb,
+				       struct net_device *netdev)
+{
+	struct lan865x_priv *priv = netdev_priv(netdev);
+
+	return oa_tc6_start_xmit(priv->tc6, skb);
+}
+
+static int lan865x_hw_disable(struct lan865x_priv *priv)
+{
+	u32 regval;
+
+	if (oa_tc6_read_register(priv->tc6, LAN865X_REG_MAC_NET_CTL, &regval))
+		return -ENODEV;
+
+	regval &= ~(MAC_NET_CTL_TXEN | MAC_NET_CTL_RXEN);
+
+	if (oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_NET_CTL, regval))
+		return -ENODEV;
+
+	return 0;
+}
+
+static int lan865x_net_close(struct net_device *netdev)
+{
+	struct lan865x_priv *priv = netdev_priv(netdev);
+	int ret;
+
+	netif_stop_queue(netdev);
+	phy_stop(netdev->phydev);
+	ret = lan865x_hw_disable(priv);
+	if (ret) {
+		netdev_err(netdev, "Failed to disable the hardware: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int lan865x_hw_enable(struct lan865x_priv *priv)
+{
+	u32 regval;
+
+	if (oa_tc6_read_register(priv->tc6, LAN865X_REG_MAC_NET_CTL, &regval))
+		return -ENODEV;
+
+	regval |= MAC_NET_CTL_TXEN | MAC_NET_CTL_RXEN;
+
+	if (oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_NET_CTL, regval))
+		return -ENODEV;
+
+	return 0;
+}
+
+static int lan865x_net_open(struct net_device *netdev)
+{
+	struct lan865x_priv *priv = netdev_priv(netdev);
+	int ret;
+
+	ret = lan865x_hw_enable(priv);
+	if (ret) {
+		netdev_err(netdev, "Failed to enable hardware: %d\n", ret);
+		return ret;
+	}
+
+	phy_start(netdev->phydev);
+
+	return 0;
+}
+
+static const struct net_device_ops lan865x_netdev_ops = {
+	.ndo_open		= lan865x_net_open,
+	.ndo_stop		= lan865x_net_close,
+	.ndo_start_xmit		= lan865x_send_packet,
+	.ndo_set_rx_mode	= lan865x_set_multicast_list,
+	.ndo_set_mac_address	= lan865x_set_mac_address,
+};
+
+static int lan865x_set_zarfe(struct lan865x_priv *priv)
+{
+	u32 regval;
+	int ret;
+
+	ret = oa_tc6_read_register(priv->tc6, OA_TC6_REG_CONFIG0, &regval);
+	if (ret)
+		return ret;
+
+	/* Set Zero-Align Receive Frame Enable */
+	regval |= CONFIG0_ZARFE_ENABLE;
+
+	return oa_tc6_write_register(priv->tc6, OA_TC6_REG_CONFIG0, regval);
+}
+
+static int lan865x_probe(struct spi_device *spi)
+{
+	struct net_device *netdev;
+	struct lan865x_priv *priv;
+	int ret;
+
+	netdev = alloc_etherdev(sizeof(struct lan865x_priv));
+	if (!netdev)
+		return -ENOMEM;
+
+	priv = netdev_priv(netdev);
+	priv->netdev = netdev;
+	priv->spi = spi;
+	spi_set_drvdata(spi, priv);
+	INIT_WORK(&priv->multicast_work, lan865x_multicast_work_handler);
+
+	priv->tc6 = oa_tc6_init(spi, netdev);
+	if (!priv->tc6) {
+		ret = -ENODEV;
+		goto free_netdev;
+	}
+
+	/* As per the point s3 in the below errata, SPI receive Ethernet frame
+	 * transfer may halt when starting the next frame in the same data block
+	 * (chunk) as the end of a previous frame. The RFA field should be
+	 * configured to 01b or 10b for proper operation. In these modes, only
+	 * one receive Ethernet frame will be placed in a single data block.
+	 * When the RFA field is written to 01b, received frames will be forced
+	 * to only start in the first word of the data block payload (SWO=0). As
+	 * recommended, ZARFE bit in the OPEN Alliance CONFIG0 register is set
+	 * to 1 for proper operation.
+	 *
+	 * https://ww1.microchip.com/downloads/aemDocuments/documents/AIS/ProductDocuments/Errata/LAN8650-1-Errata-80001075.pdf
+	 */
+	ret = lan865x_set_zarfe(priv);
+	if (ret) {
+		dev_err(&spi->dev, "Failed to set ZARFE: %d\n", ret);
+		goto oa_tc6_exit;
+	}
+
+	/* Get the MAC address from the SPI device tree node */
+	if (device_get_ethdev_address(&spi->dev, netdev))
+		eth_hw_addr_random(netdev);
+
+	ret = lan865x_set_hw_macaddr(priv, netdev->dev_addr);
+	if (ret) {
+		dev_err(&spi->dev, "Failed to configure MAC: %d\n", ret);
+		goto oa_tc6_exit;
+	}
+
+	netdev->if_port = IF_PORT_10BASET;
+	netdev->irq = spi->irq;
+	netdev->netdev_ops = &lan865x_netdev_ops;
+	netdev->ethtool_ops = &lan865x_ethtool_ops;
+
+	ret = register_netdev(netdev);
+	if (ret) {
+		dev_err(&spi->dev, "Register netdev failed (ret = %d)", ret);
+		goto oa_tc6_exit;
+	}
+
+	return 0;
+
+oa_tc6_exit:
+	oa_tc6_exit(priv->tc6);
+free_netdev:
+	free_netdev(priv->netdev);
+	return ret;
+}
+
+static void lan865x_remove(struct spi_device *spi)
+{
+	struct lan865x_priv *priv = spi_get_drvdata(spi);
+
+	cancel_work_sync(&priv->multicast_work);
+	unregister_netdev(priv->netdev);
+	oa_tc6_exit(priv->tc6);
+	free_netdev(priv->netdev);
+}
+
+static const struct of_device_id lan865x_dt_ids[] = {
+	{ .compatible = "microchip,lan8651", "microchip,lan8650" },
+	{ /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, lan865x_dt_ids);
+
+static struct spi_driver lan865x_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.of_match_table = lan865x_dt_ids,
+	 },
+	.probe = lan865x_probe,
+	.remove = lan865x_remove,
+};
+module_spi_driver(lan865x_driver);
+
+MODULE_DESCRIPTION(DRV_NAME " 10Base-T1S MACPHY Ethernet Driver");
+MODULE_AUTHOR("Parthiban Veerasooran <parthiban.veerasooran@microchip.com>");
+MODULE_LICENSE("GPL");
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 96+ messages in thread

* [PATCH net-next v4 12/12] dt-bindings: net: add Microchip's LAN865X 10BASE-T1S MACPHY
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
                   ` (10 preceding siblings ...)
  2024-04-18 12:56 ` [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY Parthiban Veerasooran
@ 2024-04-18 12:56 ` Parthiban Veerasooran
  2024-04-18 15:39   ` Conor Dooley
  2024-04-22 20:07 ` [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Andrew Lunn
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 96+ messages in thread
From: Parthiban Veerasooran @ 2024-04-18 12:56 UTC (permalink / raw)
  To: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean
  Cc: UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler,
	Parthiban Veerasooran

The LAN8650/1 combines a Media Access Controller (MAC) and an Ethernet
PHY to enable 10BASE-T1S networks. The Ethernet Media Access Controller
(MAC) module implements a 10 Mbps half duplex Ethernet MAC, compatible
with the IEEE 802.3 standard and a 10BASE-T1S physical layer transceiver
integrated into the LAN8650/1. The communication between the Host and the
MAC-PHY is specified in the OPEN Alliance 10BASE-T1x MACPHY Serial
Interface (TC6).

Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
---
 .../bindings/net/microchip,lan865x.yaml       | 80 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 81 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/microchip,lan865x.yaml

diff --git a/Documentation/devicetree/bindings/net/microchip,lan865x.yaml b/Documentation/devicetree/bindings/net/microchip,lan865x.yaml
new file mode 100644
index 000000000000..4fdec0ba3532
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/microchip,lan865x.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/microchip,lan865x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Microchip LAN8650/1 10BASE-T1S MACPHY Ethernet Controllers
+
+maintainers:
+  - Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
+
+description:
+  The LAN8650/1 combines a Media Access Controller (MAC) and an Ethernet
+  PHY to enable 10BASE‑T1S networks. The Ethernet Media Access Controller
+  (MAC) module implements a 10 Mbps half duplex Ethernet MAC, compatible
+  with the IEEE 802.3 standard and a 10BASE-T1S physical layer transceiver
+  integrated into the LAN8650/1. The communication between the Host and
+  the MAC-PHY is specified in the OPEN Alliance 10BASE-T1x MACPHY Serial
+  Interface (TC6).
+
+allOf:
+  - $ref: ethernet-controller.yaml#
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - const: microchip,lan8650
+      - items:
+          - const: microchip,lan8651
+          - const: microchip,lan8650
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    description:
+      Interrupt from MAC-PHY asserted in the event of Receive Chunks
+      Available, Transmit Chunk Credits Available and Extended Status
+      Event.
+    maxItems: 1
+
+  spi-max-frequency:
+    minimum: 15000000
+    maximum: 25000000
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - spi-max-frequency
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/gpio/gpio.h>
+
+    spi {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      ethernet@0 {
+        compatible = "microchip,lan8651", "microchip,lan8650";
+        reg = <0>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&eth0_pins>;
+        interrupt-parent = <&gpio>;
+        interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
+        local-mac-address = [04 05 06 01 02 03];
+        spi-max-frequency = <15000000>;
+      };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index f41b7f2257d2..2172431a1935 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14378,6 +14378,7 @@ MICROCHIP LAN8650/1 10BASE-T1S MACPHY ETHERNET DRIVER
 M:	Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
 L:	netdev@vger.kernel.org
 S:	Maintained
+F:	Documentation/devicetree/bindings/net/microchip,lan865x.yaml
 F:	drivers/net/ethernet/microchip/lan865x/lan865x.c
 
 MICROCHIP LAN87xx/LAN937x T1 PHY DRIVER
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 12/12] dt-bindings: net: add Microchip's LAN865X 10BASE-T1S MACPHY
  2024-04-18 12:56 ` [PATCH net-next v4 12/12] dt-bindings: net: add Microchip's LAN865X 10BASE-T1S MACPHY Parthiban Veerasooran
@ 2024-04-18 15:39   ` Conor Dooley
  2024-04-22  3:59     ` Parthiban.Veerasooran
  0 siblings, 1 reply; 96+ messages in thread
From: Conor Dooley @ 2024-04-18 15:39 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

[-- Attachment #1: Type: text/plain, Size: 4337 bytes --]

On Thu, Apr 18, 2024 at 06:26:48PM +0530, Parthiban Veerasooran wrote:
> The LAN8650/1 combines a Media Access Controller (MAC) and an Ethernet
> PHY to enable 10BASE-T1S networks. The Ethernet Media Access Controller
> (MAC) module implements a 10 Mbps half duplex Ethernet MAC, compatible
> with the IEEE 802.3 standard and a 10BASE-T1S physical layer transceiver
> integrated into the LAN8650/1. The communication between the Host and the
> MAC-PHY is specified in the OPEN Alliance 10BASE-T1x MACPHY Serial
> Interface (TC6).
> 
> Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
> ---
>  .../bindings/net/microchip,lan865x.yaml       | 80 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 81 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/microchip,lan865x.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/microchip,lan865x.yaml b/Documentation/devicetree/bindings/net/microchip,lan865x.yaml
> new file mode 100644
> index 000000000000..4fdec0ba3532
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/microchip,lan865x.yaml

Filename matching a compatible please.


> @@ -0,0 +1,80 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/microchip,lan865x.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Microchip LAN8650/1 10BASE-T1S MACPHY Ethernet Controllers
> +
> +maintainers:
> +  - Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
> +
> +description:
> +  The LAN8650/1 combines a Media Access Controller (MAC) and an Ethernet
> +  PHY to enable 10BASE‑T1S networks. The Ethernet Media Access Controller
> +  (MAC) module implements a 10 Mbps half duplex Ethernet MAC, compatible
> +  with the IEEE 802.3 standard and a 10BASE-T1S physical layer transceiver
> +  integrated into the LAN8650/1. The communication between the Host and
> +  the MAC-PHY is specified in the OPEN Alliance 10BASE-T1x MACPHY Serial
> +  Interface (TC6).
> +
> +allOf:
> +  - $ref: ethernet-controller.yaml#
> +  - $ref: /schemas/spi/spi-peripheral-props.yaml#

Can you use the same referencing style for both elements here please?


Otherwise, looks aight to me, so with those fixed:
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>

Thanks,
Conor.


> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - const: microchip,lan8650
> +      - items:
> +          - const: microchip,lan8651
> +          - const: microchip,lan8650
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    description:
> +      Interrupt from MAC-PHY asserted in the event of Receive Chunks
> +      Available, Transmit Chunk Credits Available and Extended Status
> +      Event.
> +    maxItems: 1
> +
> +  spi-max-frequency:
> +    minimum: 15000000
> +    maximum: 25000000
> +
> +  "#address-cells":
> +    const: 1
> +
> +  "#size-cells":
> +    const: 0
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - spi-max-frequency
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    spi {
> +      #address-cells = <1>;
> +      #size-cells = <0>;
> +
> +      ethernet@0 {
> +        compatible = "microchip,lan8651", "microchip,lan8650";
> +        reg = <0>;
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&eth0_pins>;
> +        interrupt-parent = <&gpio>;
> +        interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
> +        local-mac-address = [04 05 06 01 02 03];
> +        spi-max-frequency = <15000000>;
> +      };
> +    };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index f41b7f2257d2..2172431a1935 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14378,6 +14378,7 @@ MICROCHIP LAN8650/1 10BASE-T1S MACPHY ETHERNET DRIVER
>  M:	Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
>  L:	netdev@vger.kernel.org
>  S:	Maintained
> +F:	Documentation/devicetree/bindings/net/microchip,lan865x.yaml
>  F:	drivers/net/ethernet/microchip/lan865x/lan865x.c
>  
>  MICROCHIP LAN87xx/LAN937x T1 PHY DRIVER
> -- 
> 2.34.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 12/12] dt-bindings: net: add Microchip's LAN865X 10BASE-T1S MACPHY
  2024-04-18 15:39   ` Conor Dooley
@ 2024-04-22  3:59     ` Parthiban.Veerasooran
  2024-04-22 15:50       ` Conor Dooley
  0 siblings, 1 reply; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-22  3:59 UTC (permalink / raw)
  To: conor
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Conor,

On 18/04/24 9:09 pm, Conor Dooley wrote:
> On Thu, Apr 18, 2024 at 06:26:48PM +0530, Parthiban Veerasooran wrote:
>> The LAN8650/1 combines a Media Access Controller (MAC) and an Ethernet
>> PHY to enable 10BASE-T1S networks. The Ethernet Media Access Controller
>> (MAC) module implements a 10 Mbps half duplex Ethernet MAC, compatible
>> with the IEEE 802.3 standard and a 10BASE-T1S physical layer transceiver
>> integrated into the LAN8650/1. The communication between the Host and the
>> MAC-PHY is specified in the OPEN Alliance 10BASE-T1x MACPHY Serial
>> Interface (TC6).
>>
>> Signed-off-by: Parthiban Veerasooran<Parthiban.Veerasooran@microchip.com>
>> ---
>>   .../bindings/net/microchip,lan865x.yaml       | 80 +++++++++++++++++++
>>   MAINTAINERS                                   |  1 +
>>   2 files changed, 81 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/net/microchip,lan865x.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/net/microchip,lan865x.yaml b/Documentation/devicetree/bindings/net/microchip,lan865x.yaml
>> new file mode 100644
>> index 000000000000..4fdec0ba3532
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/net/microchip,lan865x.yaml
> Filename matching a compatible please.
> 
> 
OK. Then I will keep the filename as microchip,lan8650.yaml

>> @@ -0,0 +1,80 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id:http://devicetree.org/schemas/net/microchip,lan865x.yaml#
>> +$schema:http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Microchip LAN8650/1 10BASE-T1S MACPHY Ethernet Controllers
>> +
>> +maintainers:
>> +  - Parthiban Veerasooran<parthiban.veerasooran@microchip.com>
>> +
>> +description:
>> +  The LAN8650/1 combines a Media Access Controller (MAC) and an Ethernet
>> +  PHY to enable 10BASE‑T1S networks. The Ethernet Media Access Controller
>> +  (MAC) module implements a 10 Mbps half duplex Ethernet MAC, compatible
>> +  with the IEEE 802.3 standard and a 10BASE-T1S physical layer transceiver
>> +  integrated into the LAN8650/1. The communication between the Host and
>> +  the MAC-PHY is specified in the OPEN Alliance 10BASE-T1x MACPHY Serial
>> +  Interface (TC6).
>> +
>> +allOf:
>> +  - $ref: ethernet-controller.yaml#
>> +  - $ref: /schemas/spi/spi-peripheral-props.yaml#
> Can you use the same referencing style for both elements here please?
> 
> 
OK. Then I will update this allOf section like below,

allOf:
   - $ref: /schemas/net/ethernet-controller.yaml#
   - $ref: /schemas/spi/spi-peripheral-props.yaml#

> Otherwise, looks aight to me, so with those fixed:
> Reviewed-by: Conor Dooley<conor.dooley@microchip.com>
> 
OK. If you agree with the above changes that you expected then I will 
add the tag in the next version with the proposed changes.

Best regards,
Parthiban V
> Thanks,
> Conor.
> 
> 
>> +
>> +properties:
>> +  compatible:
>> +    oneOf:
>> +      - const: microchip,lan8650
>> +      - items:
>> +          - const: microchip,lan8651
>> +          - const: microchip,lan8650
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  interrupts:
>> +    description:
>> +      Interrupt from MAC-PHY asserted in the event of Receive Chunks
>> +      Available, Transmit Chunk Credits Available and Extended Status
>> +      Event.
>> +    maxItems: 1
>> +
>> +  spi-max-frequency:
>> +    minimum: 15000000
>> +    maximum: 25000000
>> +
>> +  "#address-cells":
>> +    const: 1
>> +
>> +  "#size-cells":
>> +    const: 0
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - interrupts
>> +  - spi-max-frequency
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/interrupt-controller/irq.h>
>> +    #include <dt-bindings/gpio/gpio.h>
>> +
>> +    spi {
>> +      #address-cells = <1>;
>> +      #size-cells = <0>;
>> +
>> +      ethernet@0 {
>> +        compatible = "microchip,lan8651", "microchip,lan8650";
>> +        reg = <0>;
>> +        pinctrl-names = "default";
>> +        pinctrl-0 = <&eth0_pins>;
>> +        interrupt-parent = <&gpio>;
>> +        interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
>> +        local-mac-address = [04 05 06 01 02 03];
>> +        spi-max-frequency = <15000000>;
>> +      };
>> +    };
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index f41b7f2257d2..2172431a1935 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -14378,6 +14378,7 @@ MICROCHIP LAN8650/1 10BASE-T1S MACPHY ETHERNET DRIVER
>>   M:	Parthiban Veerasooran<parthiban.veerasooran@microchip.com>
>>   L:	netdev@vger.kernel.org
>>   S:	Maintained
>> +F:	Documentation/devicetree/bindings/net/microchip,lan865x.yaml
>>   F:	drivers/net/ethernet/microchip/lan865x/lan865x.c
>>   
>>   MICROCHIP LAN87xx/LAN937x T1 PHY DRIVER
>> -- 
>> 2.34.1
>>


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 12/12] dt-bindings: net: add Microchip's LAN865X 10BASE-T1S MACPHY
  2024-04-22  3:59     ` Parthiban.Veerasooran
@ 2024-04-22 15:50       ` Conor Dooley
  2024-04-23  3:27         ` Parthiban.Veerasooran
  0 siblings, 1 reply; 96+ messages in thread
From: Conor Dooley @ 2024-04-22 15:50 UTC (permalink / raw)
  To: Parthiban.Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

[-- Attachment #1: Type: text/plain, Size: 264 bytes --]

On Mon, Apr 22, 2024 at 03:59:31AM +0000, Parthiban.Veerasooran@microchip.com wrote:
> OK. If you agree with the above changes that you expected then I will 
> add the tag in the next version with the proposed changes.

ye, they seem good, you can retain it.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
                   ` (11 preceding siblings ...)
  2024-04-18 12:56 ` [PATCH net-next v4 12/12] dt-bindings: net: add Microchip's LAN865X 10BASE-T1S MACPHY Parthiban Veerasooran
@ 2024-04-22 20:07 ` Andrew Lunn
  2024-04-22 20:08 ` Andrew Lunn
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 96+ messages in thread
From: Andrew Lunn @ 2024-04-22 20:07 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

On Thu, Apr 18, 2024 at 06:26:36PM +0530, Parthiban Veerasooran wrote:
> This patch series contain the below updates,
> - Adds support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface in the
>   net/ethernet/oa_tc6.c.
>   Link to the spec:
>   -----------------
>   https://opensig.org/download/document/OPEN_Alliance_10BASET1x_MAC-PHY_Serial_Interface_V1.1.pdf
> 
> - Adds driver support for Microchip LAN8650/1 Rev.B1 10BASE-T1S MACPHY
>   Ethernet driver in the net/ethernet/microchip/lan865x/lan865x.c.
>   Link to the product:
>   --------------------
>   https://www.microchip.com/en-us/product/lan8650

I will get around to reviewing this soon, i promise.

To the OnSemi people: Have you tried your driver/device using this
framework? It would be good to have a second vendors device using it,
just to show no vendor specific code has slipped into the framework.

Thanks
	Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
                   ` (12 preceding siblings ...)
  2024-04-22 20:07 ` [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Andrew Lunn
@ 2024-04-22 20:08 ` Andrew Lunn
  2024-04-22 23:23   ` Andrew Lunn
  2024-04-22 23:43 ` Andrew Lunn
  2024-04-28 21:16 ` [PATCH net-next v4 13/12] net: lan865x: optional hardware reset Ramón Nordin Rodriguez
  15 siblings, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-22 20:08 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

> Testing Details:
> ----------------
> The driver performance was tested using iperf3 in the below two setups
> separately.
> 
> Setup 1:
> --------
> Node 0 - Raspberry Pi 4 with LAN8650 MAC-PHY 
> Node 1 - Raspberry Pi 4 with EVB-LAN8670-USB USB Stick
> 
> Setup 2:
> --------
> Node 0 - SAMA7G54-EK with LAN8650 MAC-PHY 
> Node 1 - Raspberry Pi 4 with EVB-LAN8670-USB USB Stick

Would it be possible to chain these two setups together by adding two
USB dongles to one of the Ri 4s? If i remember correctly, there were
reports of issues when two devices were using the framework at once.

Thanks
	Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface
  2024-04-22 20:08 ` Andrew Lunn
@ 2024-04-22 23:23   ` Andrew Lunn
  0 siblings, 0 replies; 96+ messages in thread
From: Andrew Lunn @ 2024-04-22 23:23 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

On Mon, Apr 22, 2024 at 10:08:23PM +0200, Andrew Lunn wrote:
> > Testing Details:
> > ----------------
> > The driver performance was tested using iperf3 in the below two setups
> > separately.
> > 
> > Setup 1:
> > --------
> > Node 0 - Raspberry Pi 4 with LAN8650 MAC-PHY 
> > Node 1 - Raspberry Pi 4 with EVB-LAN8670-USB USB Stick
> > 
> > Setup 2:
> > --------
> > Node 0 - SAMA7G54-EK with LAN8650 MAC-PHY 
> > Node 1 - Raspberry Pi 4 with EVB-LAN8670-USB USB Stick
> 
> Would it be possible to chain these two setups together by adding two
> USB dongles to one of the Ri 4s? If i remember correctly, there were
> reports of issues when two devices were using the framework at once.

Sorry, that makes no sense. Your USB device is unlikely to be doing
USB->SPI->MAC-PHY. Do you have two LAN8650 MAC-PHY you can connect to
one host?

    Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
                   ` (13 preceding siblings ...)
  2024-04-22 20:08 ` Andrew Lunn
@ 2024-04-22 23:43 ` Andrew Lunn
  2024-04-28 21:16 ` [PATCH net-next v4 13/12] net: lan865x: optional hardware reset Ramón Nordin Rodriguez
  15 siblings, 0 replies; 96+ messages in thread
From: Andrew Lunn @ 2024-04-22 23:43 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

On Thu, Apr 18, 2024 at 06:26:36PM +0530, Parthiban Veerasooran wrote:
> This patch series contain the below updates,
> - Adds support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface in the
>   net/ethernet/oa_tc6.c.
>   Link to the spec:
>   -----------------
>   https://opensig.org/download/document/OPEN_Alliance_10BASET1x_MAC-PHY_Serial_Interface_V1.1.pdf
> 
> - Adds driver support for Microchip LAN8650/1 Rev.B1 10BASE-T1S MACPHY
>   Ethernet driver in the net/ethernet/microchip/lan865x/lan865x.c.
>   Link to the product:
>   --------------------
>   https://www.microchip.com/en-us/product/lan8650

The patchset did not apply cleanly to net-next:

https://patchwork.kernel.org/project/netdevbpf/list/?series=&submitter=206056&state=*&q=&archive=&delegate=

Which means it did not get any of the standard automatic testing :-(

      Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 02/12] net: ethernet: oa_tc6: implement register write operation
  2024-04-18 12:56 ` [PATCH net-next v4 02/12] net: ethernet: oa_tc6: implement register write operation Parthiban Veerasooran
@ 2024-04-22 23:48   ` Andrew Lunn
  2024-04-23  4:38     ` Parthiban.Veerasooran
  2024-04-23 23:14   ` Andrew Lunn
  2024-04-29 16:36   ` Simon Horman
  2 siblings, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-22 23:48 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

> +/**
> + * oa_tc6_write_registers - function for writing multiple consecutive registers.
> + * @tc6: oa_tc6 struct.
> + * @address: address of the first register to be written in the MAC-PHY.
> + * @value: values to be written from the starting register address @address.
> + * @length: number of consecutive registers to be written from @address.
> + *
> + * Maximum of 128 consecutive registers can be written starting at @address.
> + *
> + * Returns 0 on success otherwise failed.
> + */

I think the static analyser tools are getting more picky, and what
'Return:' .

https://elixir.bootlin.com/linux/latest/source/Documentation/doc-guide/kernel-doc.rst#L86

All the examples use Return:

That document also says:

The documentation format is verified by the kernel build when it is
requested to perform extra gcc checks::

	make W=n

And if patchwork can apply your patches, it also checks for problems
like this.

    Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 12/12] dt-bindings: net: add Microchip's LAN865X 10BASE-T1S MACPHY
  2024-04-22 15:50       ` Conor Dooley
@ 2024-04-23  3:27         ` Parthiban.Veerasooran
  0 siblings, 0 replies; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-23  3:27 UTC (permalink / raw)
  To: conor
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Conor,

On 22/04/24 9:20 pm, Conor Dooley wrote:
> On Mon, Apr 22, 2024 at 03:59:31AM +0000,Parthiban.Veerasooran@microchip.com  wrote:
>> OK. If you agree with the above changes that you expected then I will
>> add the tag in the next version with the proposed changes.
> ye, they seem good, you can retain it.
OK. Thanks for the confirmation.

Best regards,
Parthiban V

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 02/12] net: ethernet: oa_tc6: implement register write operation
  2024-04-22 23:48   ` Andrew Lunn
@ 2024-04-23  4:38     ` Parthiban.Veerasooran
  0 siblings, 0 replies; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-23  4:38 UTC (permalink / raw)
  To: andrew
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Andrew,

On 23/04/24 5:18 am, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
>> +/**
>> + * oa_tc6_write_registers - function for writing multiple consecutive registers.
>> + * @tc6: oa_tc6 struct.
>> + * @address: address of the first register to be written in the MAC-PHY.
>> + * @value: values to be written from the starting register address @address.
>> + * @length: number of consecutive registers to be written from @address.
>> + *
>> + * Maximum of 128 consecutive registers can be written starting at @address.
>> + *
>> + * Returns 0 on success otherwise failed.
>> + */
> 
OK. In this case kernel-doc tool takes it as **Description** that's why 
didn't complaint any error when I run the below command,

$ scripts/kernel-doc -v -none drivers/net/ethernet/oa_tc6.c

drivers/net/ethernet/oa_tc6.c:313: info: Scanning doc for function 
oa_tc6_read_registers
drivers/net/ethernet/oa_tc6.c:343: info: Scanning doc for function 
oa_tc6_read_register
drivers/net/ethernet/oa_tc6.c:357: info: Scanning doc for function 
oa_tc6_write_registers
drivers/net/ethernet/oa_tc6.c:387: info: Scanning doc for function 
oa_tc6_write_register
drivers/net/ethernet/oa_tc6.c:1154: info: Scanning doc for function 
oa_tc6_start_xmit
drivers/net/ethernet/oa_tc6.c:1185: info: Scanning doc for function 
oa_tc6_init
drivers/net/ethernet/oa_tc6.c:1306: info: Scanning doc for function 
oa_tc6_exit

Got this info from below link,

https://elixir.bootlin.com/linux/latest/source/Documentation/doc-guide/kernel-doc.rst#L53

https://elixir.bootlin.com/linux/latest/source/Documentation/doc-guide/kernel-doc.rst#L81

> I think the static analyser tools are getting more picky, and what
> 'Return:' .
> 
> https://elixir.bootlin.com/linux/latest/source/Documentation/doc-guide/kernel-doc.rst#L86
> 
> All the examples use Return:
OK. Thanks for the info. I will change it and also in other APIs as well 
in the next version.

Ex:
Return: 0 on success otherwise failed.
> 
> That document also says:
> 
> The documentation format is verified by the kernel build when it is
> requested to perform extra gcc checks::
> 
>          make W=n
Unfortunately it didn't complaint anything as "Returns" line considered 
as **Description** I guess.
> 
> And if patchwork can apply your patches, it also checks for problems
> like this.
OK. If I understand this correctly the above change will resolve this.

Best regards,
Parthiban V
> 
>      Andrew


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 02/12] net: ethernet: oa_tc6: implement register write operation
  2024-04-18 12:56 ` [PATCH net-next v4 02/12] net: ethernet: oa_tc6: implement register write operation Parthiban Veerasooran
  2024-04-22 23:48   ` Andrew Lunn
@ 2024-04-23 23:14   ` Andrew Lunn
  2024-04-26  5:55     ` Parthiban.Veerasooran
  2024-04-29 16:36   ` Simon Horman
  2 siblings, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-23 23:14 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

On Thu, Apr 18, 2024 at 06:26:38PM +0530, Parthiban Veerasooran wrote:
> Implement register write operation according to the control communication
> specified in the OPEN Alliance 10BASE-T1x MACPHY Serial Interface
> document. Control write commands are used by the SPI host to write
> registers within the MAC-PHY. Each control write commands are composed of
> a 32 bits control command header followed by register write data.
> 
> The MAC-PHY ignores the final 32 bits of data from the SPI host at the
> end of the control write command. The write command and data is also
> echoed from the MAC-PHY back to the SPI host to enable the SPI host to
> identify which register write failed in the case of any bus errors.
> Control write commands can write either a single register or multiple
> consecutive registers. When multiple consecutive registers are written,
> the address is automatically post-incremented by the MAC-PHY. Writing to
> any unimplemented or undefined registers shall be ignored and yield no
> effect.
> 
> Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>

Apart from the Return: issues:

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 03/12] net: ethernet: oa_tc6: implement register read operation
  2024-04-18 12:56 ` [PATCH net-next v4 03/12] net: ethernet: oa_tc6: implement register read operation Parthiban Veerasooran
@ 2024-04-23 23:17   ` Andrew Lunn
  2024-04-26  5:56     ` Parthiban.Veerasooran
  0 siblings, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-23 23:17 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

> +static int oa_tc6_check_ctrl_read_reply(struct oa_tc6 *tc6, u8 size)
> +{
> +	u32 *tx_buf = tc6->spi_ctrl_tx_buf;
> +	u32 *rx_buf = tc6->spi_ctrl_rx_buf + OA_TC6_CTRL_IGNORED_SIZE;

Reverse christmas tree. Those two need swapping around.

	Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 04/12] net: ethernet: oa_tc6: implement software reset
  2024-04-18 12:56 ` [PATCH net-next v4 04/12] net: ethernet: oa_tc6: implement software reset Parthiban Veerasooran
@ 2024-04-23 23:26   ` Andrew Lunn
  2024-04-26  6:38     ` Parthiban.Veerasooran
  0 siblings, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-23 23:26 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

> +static int oa_tc6_read_status0(struct oa_tc6 *tc6)
> +{
> +	u32 regval;
> +	int ret;
> +
> +	ret = oa_tc6_read_register(tc6, OA_TC6_REG_STATUS0, &regval);
> +	if (ret)
> +		return 0;

If there is an error, your throw the error code away?

It is a bit messy, since you are using this inside
readx_poll_timeout(). I would probably do a netdev_warn() or similar,
since it should not happen, and then return 0? I _think_ this is
probably the first bus transaction we do, so if it fails, knowing the
error code will help figuring out what is wrong with the SPI bus
configuration.

	Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking
  2024-04-18 12:56 ` [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking Parthiban Veerasooran
@ 2024-04-23 23:27   ` Andrew Lunn
  2024-04-27 19:52   ` Ramón Nordin Rodriguez
  1 sibling, 0 replies; 96+ messages in thread
From: Andrew Lunn @ 2024-04-23 23:27 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

On Thu, Apr 18, 2024 at 06:26:41PM +0530, Parthiban Veerasooran wrote:
> This will unmask the following error interrupts from the MAC-PHY.
>   tx protocol error
>   rx buffer overflow error
>   loss of framing error
>   header error
> The MAC-PHY will signal an error by setting the EXST bit in the receive
> data footer which will then allow the host to read the STATUS0 register
> to find the source of the error.
> 
> Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 06/12] net: ethernet: oa_tc6: implement internal PHY initialization
  2024-04-18 12:56 ` [PATCH net-next v4 06/12] net: ethernet: oa_tc6: implement internal PHY initialization Parthiban Veerasooran
@ 2024-04-23 23:48   ` Andrew Lunn
  2024-04-26 13:17     ` Parthiban.Veerasooran
  0 siblings, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-23 23:48 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

> +/* PHY Clause 22 and 29 registers base address and mask */
> +#define OA_TC6_PHY_STD_REG_ADDR_BASE		0xFF00
> +#define OA_TC6_PHY_STD_REG_ADDR_MASK		0x3F

Did you every find out why C29 is reference here? From the standard:

29. System considerations for multisegment 100BASE-T networks

NOTE—This clause relates to clauses that are not recommended for new
installations. This clause is not recommended for new
installations. Since March 2012, maintenance changes are no longer
being considered for this clause.

I don't think you should be referencing it in the code.

> +static int oa_tc6_mdiobus_read(struct mii_bus *bus, int addr, int regnum)
> +{
> +	struct oa_tc6 *tc6 = bus->priv;
> +	u32 regval;
> +	bool ret;
> +
> +	ret = oa_tc6_read_register(tc6, OA_TC6_PHY_STD_REG_ADDR_BASE |
> +				   (regnum & OA_TC6_PHY_STD_REG_ADDR_MASK),
> +				   &regval);
> +	if (ret)
> +		return -ENODEV;

In general, you should not replace an error code from a lower level
function with a different error code. If there is a good reason to do
this, please add a comment.

> diff --git a/drivers/net/phy/microchip_t1s.c b/drivers/net/phy/microchip_t1s.c
> index 534ca7d1b061..769a88254285 100644
> --- a/drivers/net/phy/microchip_t1s.c
> +++ b/drivers/net/phy/microchip_t1s.c
> @@ -268,6 +268,34 @@ static int lan86xx_read_status(struct phy_device *phydev)
>  	return 0;
>  }

Please put this into a new patch.

>  
> +/* OPEN Alliance 10BASE-T1x compliance MAC-PHYs will have both C22 and
> + * C45 registers space. If the PHY is discovered via C22 bus protocol it assumes
> + * it uses C22 protocol and always uses C22 registers indirect access to access
> + * C45 registers. This is because, we don't have a clean separation between
> + * C22/C45 register space and C22/C45 MDIO bus protocols. Resulting, PHY C45
> + * registers direct access can't be used which can save multiple SPI bus access.
> + * To support this feature, set .read_mmd/.write_mmd in the PHY driver to call
> + * .read_c45/.write_c45 in the OPEN Alliance framework
> + * drivers/net/ethernet/oa_tc6.c
> + */
> +static int lan865x_phy_read_mmd(struct phy_device *phydev, int devnum,
> +				u16 regnum)
> +{
> +	struct mii_bus *bus = phydev->mdio.bus;
> +	int addr = phydev->mdio.addr;
> +
> +	return bus->read_c45(bus, addr, devnum, regnum);

It is better to use __mdiobus_c45_read(). That will check you have the
lock held, won't jump through a null pointer if the bus does not
implement C45, does tracing, and increments the MDIO statistics.

	  Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 07/12] net: ethernet: oa_tc6: enable open alliance tc6 data communication
  2024-04-18 12:56 ` [PATCH net-next v4 07/12] net: ethernet: oa_tc6: enable open alliance tc6 data communication Parthiban Veerasooran
@ 2024-04-23 23:49   ` Andrew Lunn
  0 siblings, 0 replies; 96+ messages in thread
From: Andrew Lunn @ 2024-04-23 23:49 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

On Thu, Apr 18, 2024 at 06:26:43PM +0530, Parthiban Veerasooran wrote:
> Enabling Configuration Synchronization bit (SYNC) in the Configuration
> Register #0 enables data communication in the MAC-PHY. The state of this
> bit is reflected in the data footer SYNC bit.
> 
> Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 08/12] net: ethernet: oa_tc6: implement transmit path to transfer tx ethernet frames
  2024-04-18 12:56 ` [PATCH net-next v4 08/12] net: ethernet: oa_tc6: implement transmit path to transfer tx ethernet frames Parthiban Veerasooran
@ 2024-04-24  0:02   ` Andrew Lunn
  2024-04-26 13:19     ` Parthiban.Veerasooran
  0 siblings, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-24  0:02 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

> +static int oa_tc6_process_extended_status(struct oa_tc6 *tc6)
> +{
> +	u32 value;
> +	int ret;
> +
> +	ret = oa_tc6_read_register(tc6, OA_TC6_REG_STATUS0, &value);
> +	if (ret) {
> +		netdev_err(tc6->netdev, "STATUS0 register read failed: %d\n",
> +			   ret);
> +		return -ENODEV;
> +	}
> +
> +	/* Clear the error interrupts status */
> +	ret = oa_tc6_write_register(tc6, OA_TC6_REG_STATUS0, value);
> +	if (ret) {
> +		netdev_err(tc6->netdev, "STATUS0 register write failed: %d\n",
> +			   ret);
> +		return -ENODEV;

More examples where you replace one error code with a different one.

     Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 09/12] net: ethernet: oa_tc6: implement receive path to receive rx ethernet frames
  2024-04-18 12:56 ` [PATCH net-next v4 09/12] net: ethernet: oa_tc6: implement receive path to receive rx " Parthiban Veerasooran
@ 2024-04-24  0:08   ` Andrew Lunn
  2024-04-26 13:45     ` Parthiban.Veerasooran
  2024-04-27 20:02   ` Ramón Nordin Rodriguez
  1 sibling, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-24  0:08 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

> +static int oa_tc6_allocate_rx_skb(struct oa_tc6 *tc6)
> +{
> +	tc6->rx_skb = netdev_alloc_skb(tc6->netdev, tc6->netdev->mtu + ETH_HLEN +
> +				       ETH_FCS_LEN + NET_IP_ALIGN);
> +	if (!tc6->rx_skb) {
> +		tc6->netdev->stats.rx_dropped++;
> +		return -ENOMEM;
> +	}
> +	skb_reserve(tc6->rx_skb, NET_IP_ALIGN);

I think you can use netdev_alloc_skb_ip_align() here.


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 10/12] net: ethernet: oa_tc6: implement mac-phy interrupt
  2024-04-18 12:56 ` [PATCH net-next v4 10/12] net: ethernet: oa_tc6: implement mac-phy interrupt Parthiban Veerasooran
@ 2024-04-24  0:10   ` Andrew Lunn
  0 siblings, 0 replies; 96+ messages in thread
From: Andrew Lunn @ 2024-04-24  0:10 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

On Thu, Apr 18, 2024 at 06:26:46PM +0530, Parthiban Veerasooran wrote:
> The MAC-PHY interrupt is asserted when the following conditions are met.
> 
> Receive chunks available - This interrupt is asserted when the previous
> data footer had no receive data chunks available and once the receive
> data chunks become available for reading. On reception of the first data
> header this interrupt will be deasserted.
> 
> Transmit chunk credits available - This interrupt is asserted when the
> previous data footer indicated no transmit credits available and once the
> transmit credits become available for transmitting transmit data chunks.
> On reception of the first data header this interrupt will be deasserted.
> 
> Extended status event - This interrupt is asserted when the previous data
> footer indicated no extended status and once the extended event become
> available. In this case the host should read status #0 register to know
> the corresponding error/event. On reception of the first data header this
> interrupt will be deasserted.
> 
> Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-18 12:56 ` [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY Parthiban Veerasooran
@ 2024-04-24  0:27   ` Andrew Lunn
  2024-04-26 13:32     ` Parthiban.Veerasooran
  2024-04-27 19:19   ` Ramón Nordin Rodriguez
  2024-04-27 19:35   ` Ramón Nordin Rodriguez
  2 siblings, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-24  0:27 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

> +/* OPEN Alliance Configuration Register #0 */
> +#define OA_TC6_REG_CONFIG0		0x0004
> +#define CONFIG0_ZARFE_ENABLE		BIT(12)

If this is a standard register, you should put these defined where
other drivers can use them.

> +static int lan865x_set_mac_address(struct net_device *netdev, void *addr)
> +{
> +	struct lan865x_priv *priv = netdev_priv(netdev);
> +	struct sockaddr *address = addr;
> +	int ret;
> +
> +	ret = eth_prepare_mac_addr_change(netdev, addr);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (ether_addr_equal(address->sa_data, netdev->dev_addr))
> +		return 0;
> +
> +	ret = lan865x_set_hw_macaddr(priv, address->sa_data);
> +	if (ret)
> +		return ret;
> +
> +	eth_hw_addr_set(netdev, address->sa_data);

It seems more normal to call eth_commit_mac_addr_change(), which
better pairs with eth_prepare_mac_addr_change().

> +static int lan865x_set_zarfe(struct lan865x_priv *priv)
> +{
> +	u32 regval;
> +	int ret;
> +
> +	ret = oa_tc6_read_register(priv->tc6, OA_TC6_REG_CONFIG0, &regval);
> +	if (ret)
> +		return ret;
> +
> +	/* Set Zero-Align Receive Frame Enable */
> +	regval |= CONFIG0_ZARFE_ENABLE;
> +
> +	return oa_tc6_write_register(priv->tc6, OA_TC6_REG_CONFIG0, regval);
> +}

There does not appear to be anything specific to your device here. So
please make this a helper in the shared code, so any driver can use
it.

	Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 02/12] net: ethernet: oa_tc6: implement register write operation
  2024-04-23 23:14   ` Andrew Lunn
@ 2024-04-26  5:55     ` Parthiban.Veerasooran
  0 siblings, 0 replies; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-26  5:55 UTC (permalink / raw)
  To: andrew
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Andrew,

On 24/04/24 4:44 am, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Thu, Apr 18, 2024 at 06:26:38PM +0530, Parthiban Veerasooran wrote:
>> Implement register write operation according to the control communication
>> specified in the OPEN Alliance 10BASE-T1x MACPHY Serial Interface
>> document. Control write commands are used by the SPI host to write
>> registers within the MAC-PHY. Each control write commands are composed of
>> a 32 bits control command header followed by register write data.
>>
>> The MAC-PHY ignores the final 32 bits of data from the SPI host at the
>> end of the control write command. The write command and data is also
>> echoed from the MAC-PHY back to the SPI host to enable the SPI host to
>> identify which register write failed in the case of any bus errors.
>> Control write commands can write either a single register or multiple
>> consecutive registers. When multiple consecutive registers are written,
>> the address is automatically post-incremented by the MAC-PHY. Writing to
>> any unimplemented or undefined registers shall be ignored and yield no
>> effect.
>>
>> Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
> 
> Apart from the Return: issues:
OK. Thanks.

Best regards,
Parthiban V
> 
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
> 
>      Andrew
> 


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 03/12] net: ethernet: oa_tc6: implement register read operation
  2024-04-23 23:17   ` Andrew Lunn
@ 2024-04-26  5:56     ` Parthiban.Veerasooran
  0 siblings, 0 replies; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-26  5:56 UTC (permalink / raw)
  To: andrew
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Andrew,

On 24/04/24 4:47 am, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
>> +static int oa_tc6_check_ctrl_read_reply(struct oa_tc6 *tc6, u8 size)
>> +{
>> +     u32 *tx_buf = tc6->spi_ctrl_tx_buf;
>> +     u32 *rx_buf = tc6->spi_ctrl_rx_buf + OA_TC6_CTRL_IGNORED_SIZE;
> 
> Reverse christmas tree. Those two need swapping around.
Ah ok, somehow I missed it. Will correct it in the next version.

Best regards,
Parthiban V
> 
>          Andrew
> 


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 04/12] net: ethernet: oa_tc6: implement software reset
  2024-04-23 23:26   ` Andrew Lunn
@ 2024-04-26  6:38     ` Parthiban.Veerasooran
  0 siblings, 0 replies; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-26  6:38 UTC (permalink / raw)
  To: andrew
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Andrew,

On 24/04/24 4:56 am, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
>> +static int oa_tc6_read_status0(struct oa_tc6 *tc6)
>> +{
>> +     u32 regval;
>> +     int ret;
>> +
>> +     ret = oa_tc6_read_register(tc6, OA_TC6_REG_STATUS0, &regval);
>> +     if (ret)
>> +             return 0;
> 
> If there is an error, your throw the error code away?
> 
> It is a bit messy, since you are using this inside
> readx_poll_timeout(). I would probably do a netdev_warn() or similar,
> since it should not happen, and then return 0? I _think_ this is
> probably the first bus transaction we do, so if it fails, knowing the
> error code will help figuring out what is wrong with the SPI bus
> configuration.
OK, I will add the below print before "return 0;" in the next version.

dev_err(&tc6->spi->dev, "STATUS0 register read failed: %d\n", ret);

Best regards,
Parthiban V
> 
>          Andrew
> 


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 06/12] net: ethernet: oa_tc6: implement internal PHY initialization
  2024-04-23 23:48   ` Andrew Lunn
@ 2024-04-26 13:17     ` Parthiban.Veerasooran
  0 siblings, 0 replies; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-26 13:17 UTC (permalink / raw)
  To: andrew
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Andrew,

On 24/04/24 5:18 am, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
>> +/* PHY Clause 22 and 29 registers base address and mask */
>> +#define OA_TC6_PHY_STD_REG_ADDR_BASE         0xFF00
>> +#define OA_TC6_PHY_STD_REG_ADDR_MASK         0x3F
> 
> Did you every find out why C29 is reference here? From the standard:
> 
> 29. System considerations for multisegment 100BASE-T networks
> 
> NOTE—This clause relates to clauses that are not recommended for new
> installations. This clause is not recommended for new
> installations. Since March 2012, maintenance changes are no longer
> being considered for this clause.
> 
> I don't think you should be referencing it in the code.
Thanks for this detailed explanation. The reason why I considered this 
is, in section 9.2 and table 7 of the OPEN Alliance document shows the 
mapping of standard registers within MMS 0 where clause 29 also listed 
as clause 22 extended registers from 0xFF20 to 0xFF3F.

https://opensig.org/download/document/OPEN_Alliance_10BASET1x_MAC-PHY_Serial_Interface_V1.1.pdf

But by considering the limitations explained by you above, I will change 
the mask as 0x1F to support only for clause 22 registers in the next 
version.
> 
>> +static int oa_tc6_mdiobus_read(struct mii_bus *bus, int addr, int regnum)
>> +{
>> +     struct oa_tc6 *tc6 = bus->priv;
>> +     u32 regval;
>> +     bool ret;
>> +
>> +     ret = oa_tc6_read_register(tc6, OA_TC6_PHY_STD_REG_ADDR_BASE |
>> +                                (regnum & OA_TC6_PHY_STD_REG_ADDR_MASK),
>> +                                &regval);
>> +     if (ret)
>> +             return -ENODEV;
> 
> In general, you should not replace an error code from a lower level
> function with a different error code. If there is a good reason to do
> this, please add a comment.
Ah ok, I will return "ret" in the next version.
> 
>> diff --git a/drivers/net/phy/microchip_t1s.c b/drivers/net/phy/microchip_t1s.c
>> index 534ca7d1b061..769a88254285 100644
>> --- a/drivers/net/phy/microchip_t1s.c
>> +++ b/drivers/net/phy/microchip_t1s.c
>> @@ -268,6 +268,34 @@ static int lan86xx_read_status(struct phy_device *phydev)
>>        return 0;
>>   }
> 
> Please put this into a new patch.
OK, will create as a new patch in the next version.
> 
>>
>> +/* OPEN Alliance 10BASE-T1x compliance MAC-PHYs will have both C22 and
>> + * C45 registers space. If the PHY is discovered via C22 bus protocol it assumes
>> + * it uses C22 protocol and always uses C22 registers indirect access to access
>> + * C45 registers. This is because, we don't have a clean separation between
>> + * C22/C45 register space and C22/C45 MDIO bus protocols. Resulting, PHY C45
>> + * registers direct access can't be used which can save multiple SPI bus access.
>> + * To support this feature, set .read_mmd/.write_mmd in the PHY driver to call
>> + * .read_c45/.write_c45 in the OPEN Alliance framework
>> + * drivers/net/ethernet/oa_tc6.c
>> + */
>> +static int lan865x_phy_read_mmd(struct phy_device *phydev, int devnum,
>> +                             u16 regnum)
>> +{
>> +     struct mii_bus *bus = phydev->mdio.bus;
>> +     int addr = phydev->mdio.addr;
>> +
>> +     return bus->read_c45(bus, addr, devnum, regnum);
> 
> It is better to use __mdiobus_c45_read(). That will check you have the
> lock held, won't jump through a null pointer if the bus does not
> implement C45, does tracing, and increments the MDIO statistics.
OK, sure will do it in the next version. As this is also applicable for 
__mdiobus_c45_write(), I will change this as well.

Best regards,
Parthiban V
> 
>            Andrew
> 


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 08/12] net: ethernet: oa_tc6: implement transmit path to transfer tx ethernet frames
  2024-04-24  0:02   ` Andrew Lunn
@ 2024-04-26 13:19     ` Parthiban.Veerasooran
  0 siblings, 0 replies; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-26 13:19 UTC (permalink / raw)
  To: andrew
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Andrew,

On 24/04/24 5:32 am, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
>> +static int oa_tc6_process_extended_status(struct oa_tc6 *tc6)
>> +{
>> +     u32 value;
>> +     int ret;
>> +
>> +     ret = oa_tc6_read_register(tc6, OA_TC6_REG_STATUS0, &value);
>> +     if (ret) {
>> +             netdev_err(tc6->netdev, "STATUS0 register read failed: %d\n",
>> +                        ret);
>> +             return -ENODEV;
>> +     }
>> +
>> +     /* Clear the error interrupts status */
>> +     ret = oa_tc6_write_register(tc6, OA_TC6_REG_STATUS0, value);
>> +     if (ret) {
>> +             netdev_err(tc6->netdev, "STATUS0 register write failed: %d\n",
>> +                        ret);
>> +             return -ENODEV;
> 
> More examples where you replace one error code with a different one.
Yes I noted. Somehow I messed up with all the -ENODEV. I will take of 
this in all the places in the next version.

Best regards,
Parthiban V
> 
>       Andrew
> 


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-24  0:27   ` Andrew Lunn
@ 2024-04-26 13:32     ` Parthiban.Veerasooran
  2024-04-26 18:14       ` Andrew Lunn
  0 siblings, 1 reply; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-26 13:32 UTC (permalink / raw)
  To: andrew
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Andrew,

On 24/04/24 5:57 am, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
>> +/* OPEN Alliance Configuration Register #0 */
>> +#define OA_TC6_REG_CONFIG0           0x0004
>> +#define CONFIG0_ZARFE_ENABLE         BIT(12)
> 
> If this is a standard register, you should put these defined where
> other drivers can use them.
OK. Will move it to oa_tc6.c in the next version as you have also 
suggested to use this as a helper function in the below comment.
> 
>> +static int lan865x_set_mac_address(struct net_device *netdev, void *addr)
>> +{
>> +     struct lan865x_priv *priv = netdev_priv(netdev);
>> +     struct sockaddr *address = addr;
>> +     int ret;
>> +
>> +     ret = eth_prepare_mac_addr_change(netdev, addr);
>> +     if (ret < 0)
>> +             return ret;
>> +
>> +     if (ether_addr_equal(address->sa_data, netdev->dev_addr))
>> +             return 0;
>> +
>> +     ret = lan865x_set_hw_macaddr(priv, address->sa_data);
>> +     if (ret)
>> +             return ret;
>> +
>> +     eth_hw_addr_set(netdev, address->sa_data);
> 
> It seems more normal to call eth_commit_mac_addr_change(), which
> better pairs with eth_prepare_mac_addr_change().
OK, so I will replace eth_hw_addr_set() with 
eth_prepare_mac_addr_change() in the next version.
> 
>> +static int lan865x_set_zarfe(struct lan865x_priv *priv)
>> +{
>> +     u32 regval;
>> +     int ret;
>> +
>> +     ret = oa_tc6_read_register(priv->tc6, OA_TC6_REG_CONFIG0, &regval);
>> +     if (ret)
>> +             return ret;
>> +
>> +     /* Set Zero-Align Receive Frame Enable */
>> +     regval |= CONFIG0_ZARFE_ENABLE;
>> +
>> +     return oa_tc6_write_register(priv->tc6, OA_TC6_REG_CONFIG0, regval);
>> +}
> 
> There does not appear to be anything specific to your device here. So
> please make this a helper in the shared code, so any driver can use
> it.
OK, I will implement this helper function as oa_tc6_enable_zarfe() in 
the oa_tc6.c. Also do you want me to move this helper function 
implementation to a new patch?

Best regards,
Parthiban V
> 
>          Andrew
> 


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 09/12] net: ethernet: oa_tc6: implement receive path to receive rx ethernet frames
  2024-04-24  0:08   ` Andrew Lunn
@ 2024-04-26 13:45     ` Parthiban.Veerasooran
  2024-04-26 18:13       ` Andrew Lunn
  0 siblings, 1 reply; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-26 13:45 UTC (permalink / raw)
  To: andrew
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Andrew,

On 24/04/24 5:38 am, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
>> +static int oa_tc6_allocate_rx_skb(struct oa_tc6 *tc6)
>> +{
>> +     tc6->rx_skb = netdev_alloc_skb(tc6->netdev, tc6->netdev->mtu + ETH_HLEN +
>> +                                    ETH_FCS_LEN + NET_IP_ALIGN);
>> +     if (!tc6->rx_skb) {
>> +             tc6->netdev->stats.rx_dropped++;
>> +             return -ENOMEM;
>> +     }
>> +     skb_reserve(tc6->rx_skb, NET_IP_ALIGN);
> 
> I think you can use netdev_alloc_skb_ip_align() here.
Ah OK, then do you mean we can rewrite the function 
oa_tc6_allocate_rx_skb() as below?

static int oa_tc6_allocate_rx_skb(struct oa_tc6 *tc6)
{
	tc6->rx_skb = netdev_alloc_skb_ip_align(tc6->netdev, tc6->netdev->mtu + 
ETH_HLEN + ETH_FCS_LEN);
	if (tc6->rx_skb)
		return 0;

	tc6->netdev->stats.rx_dropped++;
	return -ENOMEM;
}

Best regards,
Parthiban V
> 


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 09/12] net: ethernet: oa_tc6: implement receive path to receive rx ethernet frames
  2024-04-26 13:45     ` Parthiban.Veerasooran
@ 2024-04-26 18:13       ` Andrew Lunn
  2024-04-29  6:13         ` Parthiban.Veerasooran
  0 siblings, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-26 18:13 UTC (permalink / raw)
  To: Parthiban.Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

On Fri, Apr 26, 2024 at 01:45:20PM +0000, Parthiban.Veerasooran@microchip.com wrote:
> Hi Andrew,
> 
> On 24/04/24 5:38 am, Andrew Lunn wrote:
> > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> > 
> >> +static int oa_tc6_allocate_rx_skb(struct oa_tc6 *tc6)
> >> +{
> >> +     tc6->rx_skb = netdev_alloc_skb(tc6->netdev, tc6->netdev->mtu + ETH_HLEN +
> >> +                                    ETH_FCS_LEN + NET_IP_ALIGN);
> >> +     if (!tc6->rx_skb) {
> >> +             tc6->netdev->stats.rx_dropped++;
> >> +             return -ENOMEM;
> >> +     }
> >> +     skb_reserve(tc6->rx_skb, NET_IP_ALIGN);
> > 
> > I think you can use netdev_alloc_skb_ip_align() here.
> Ah OK, then do you mean we can rewrite the function 
> oa_tc6_allocate_rx_skb() as below?
> 
> static int oa_tc6_allocate_rx_skb(struct oa_tc6 *tc6)
> {
> 	tc6->rx_skb = netdev_alloc_skb_ip_align(tc6->netdev, tc6->netdev->mtu + 
> ETH_HLEN + ETH_FCS_LEN);
> 	if (tc6->rx_skb)
> 		return 0;
> 
> 	tc6->netdev->stats.rx_dropped++;
> 	return -ENOMEM;
> }

Looks about right. But i did say 'I think', meaning i'm not too sure
about this.

I generally don't review code actually moving packets around. It is
what developers focus on, test heavily, and so is generally O.K. It is
the code around the edges which often needs improvements prompted by
review, ethtool, PHY handling, statistics.

	Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-26 13:32     ` Parthiban.Veerasooran
@ 2024-04-26 18:14       ` Andrew Lunn
  2024-04-29  6:13         ` Parthiban.Veerasooran
  0 siblings, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-26 18:14 UTC (permalink / raw)
  To: Parthiban.Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

> OK, I will implement this helper function as oa_tc6_enable_zarfe() in 
> the oa_tc6.c. Also do you want me to move this helper function 
> implementation to a new patch?

Yes please.

    Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-18 12:56 ` [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY Parthiban Veerasooran
  2024-04-24  0:27   ` Andrew Lunn
@ 2024-04-27 19:19   ` Ramón Nordin Rodriguez
  2024-04-27 19:57     ` Conor Dooley
  2024-04-27 20:40     ` Andrew Lunn
  2024-04-27 19:35   ` Ramón Nordin Rodriguez
  2 siblings, 2 replies; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-27 19:19 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi,

For me the mac driver fails to probe with the following log
[    0.123325] SPI driver lan865x has no spi_device_id for microchip,lan8651

With this change the driver probes

diff --git a/drivers/net/ethernet/microchip/lan865x/lan865x.c b/drivers/net/ethernet/microchip/lan865x/lan865x.c
index 9abefa8b9d9f..72a663f14f50 100644
--- a/drivers/net/ethernet/microchip/lan865x/lan865x.c
+++ b/drivers/net/ethernet/microchip/lan865x/lan865x.c
@@ -364,7 +364,7 @@ static void lan865x_remove(struct spi_device *spi)
 }

 static const struct of_device_id lan865x_dt_ids[] = {
-       { .compatible = "microchip,lan8651", "microchip,lan8650" },
+       { .compatible = "microchip,lan865x", "microchip,lan8650" },
        { /* Sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, lan865x_dt_ids);

Along with compatible = "microchip,lan865x" in the dts

^ permalink raw reply related	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-18 12:56 ` [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY Parthiban Veerasooran
  2024-04-24  0:27   ` Andrew Lunn
  2024-04-27 19:19   ` Ramón Nordin Rodriguez
@ 2024-04-27 19:35   ` Ramón Nordin Rodriguez
  2024-04-27 20:58     ` Andrew Lunn
  2 siblings, 1 reply; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-27 19:35 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

I'm running a dual lan8650 setup, neither IC passed the sw reset in the
oa_tc.c module, I need to pull the reset pin low to reset the pin before
the rest of the init stuff happens.

The datasheet recommends not doing a sw reset, excerpt from section
4.1.1.3 Software Reset
"Note: The SW_RESET bit of the Clause 22 Basic Control register will reset only the internal PHY, not
the entire device. This PHY only reset is not recommended for use. If such a reset is detected, by
reading the RESETC bit of the STS2 register, reset the entire device."

Doing a hw reset followed by a sw reset seems to work fine though. I
added the folloing patch to get things moving.

diff --git a/drivers/net/ethernet/microchip/lan865x/lan865x.c b/drivers/net/ethernet/microchip/lan865x/lan865x.c
index 72a663f14f50..993c4f9dec7e 100644
--- a/drivers/net/ethernet/microchip/lan865x/lan865x.c
+++ b/drivers/net/ethernet/microchip/lan865x/lan865x.c
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/phy.h>
 #include <linux/oa_tc6.h>
+#include <linux/gpio/driver.h>

 #define DRV_NAME                       "lan865x"

@@ -36,6 +37,7 @@ struct lan865x_priv {
        struct net_device *netdev;
        struct spi_device *spi;
        struct oa_tc6 *tc6;
+       struct gpio_desc *reset_gpio;
 };

 static int lan865x_set_hw_macaddr_low_bytes(struct oa_tc6 *tc6, const u8 *mac)
@@ -283,6 +285,29 @@ static int lan865x_set_zarfe(struct lan865x_priv *priv)
        return oa_tc6_write_register(priv->tc6, OA_TC6_REG_CONFIG0, regval);
 }

+static int lan865x_probe_reset_gpio(struct lan865x_priv *priv)
+{
+       priv->reset_gpio = devm_gpiod_get_optional(&priv->spi->dev,
+                                           "reset",
+                                           GPIOD_OUT_HIGH);
+       if (IS_ERR(priv->reset_gpio)) {
+               dev_err(&priv->spi->dev, "failed to parse reset gpio from dt");
+               return PTR_ERR(priv->reset_gpio);
+       }
+
+       return 0;
+}
+
+static void lan865x_hw_reset(struct lan865x_priv *priv)
+{
+       dev_info(&priv->spi->dev, "resetting device");
+       gpiod_set_value(priv->reset_gpio, 1);
+       // the datasheet specifies a minimum 5µs hold time
+       usleep_range(5,10);
+       gpiod_set_value(priv->reset_gpio, 0);
+       dev_info(&priv->spi->dev, "reset completed");
+}
+
 static int lan865x_probe(struct spi_device *spi)
 {
        struct net_device *netdev;
@@ -297,6 +322,9 @@ static int lan865x_probe(struct spi_device *spi)
        priv->netdev = netdev;
        priv->spi = spi;
        spi_set_drvdata(spi, priv);
+       lan865x_probe_reset_gpio(priv);
+       if(priv->reset_gpio)
+               lan865x_hw_reset(priv);
        INIT_WORK(&priv->multicast_work, lan865x_multicast_work_handler);

        priv->tc6 = oa_tc6_init(spi, netdev);

Since the chip does have a HW reset pin I think it would be nice to
at least expose this as an optional dt binding.
Maybe ignore the prints I forgot to remove :)

^ permalink raw reply related	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking
  2024-04-18 12:56 ` [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking Parthiban Veerasooran
  2024-04-23 23:27   ` Andrew Lunn
@ 2024-04-27 19:52   ` Ramón Nordin Rodriguez
  2024-04-27 21:17     ` Andrew Lunn
  1 sibling, 1 reply; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-27 19:52 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

> +static int oa_tc6_unmask_macphy_error_interrupts(struct oa_tc6 *tc6)
> +{
> +	u32 regval;
> +	int ret;
> +
> +	ret = oa_tc6_read_register(tc6, OA_TC6_REG_INT_MASK0, &regval);
> +	if (ret)
> +		return ret;
> +
> +	regval &= ~(INT_MASK0_TX_PROTOCOL_ERR_MASK |
> +		    INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK |
> +		    INT_MASK0_LOSS_OF_FRAME_ERR_MASK |
> +		    INT_MASK0_HEADER_ERR_MASK);
> +
> +	return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, regval);
> +}
> +

This togheter with patch 11 works poorly for me. I get alot of kernel
output, dropped packets and lower performance.
Below is an example for a run when I curl a 10MB blob

time curl 20.0.0.55:8000/rdump -o dump -w '{%speed_download}'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  U[  387.944737] net_ratelimit: 38 callbacks suppressed
pload   Total   Spent    Left  Sp[  387.944755] eth0: Receive buffer overflow error
eed
  0     0    0     0    0     0      0      0 --:--:-- --:-[  387.961424] eth0: Receive buffer overflow error
  0 10.0M    0  2896    0     0  13031      0  0:13:24 --:--:--  0:13:24 12986[  388.204257] eth0: Receive buffer overflow error
[  388.209848] eth0: Receive buffer overflow error
[  388.240705] eth0: Receive buffer overflow error
[  388.246205] eth0: Receive buffer overflow error
[  388.360265] eth0: Receive buffer overflow error
[  388.365755] eth0: Receive buffer overflow error
[  388.371328] eth0: Receive buffer overflow error
[  388.396937] eth0: Receive buffer overflow error
 32 10.0M   32 3362k    0     0   826k      0  0:00:12  0:00:04  0:00:08  826k[  392.950696] net_ratelimit: 84 callbacks suppressed
[  392.950711] eth0: Receive buffer overflow error
 41 10.0M   41 4259k    0     0   840k      0  0:00:12  0:00:05  0:00:07  878k[  393.009785] eth0: Receive buffer overflow error
[  393.016651] eth0: Receive buffer overflow error
[  393.121278] eth0: Receive buffer overflow error
[  393.126876] eth0: Receive buffer overflow error
[  393.204983] eth0: Receive buffer overflow error
[  393.210590] eth0: Receive buffer overflow error
[  393.248977] eth0: Receive buffer overflow error
[  393.254575] eth0: Receive buffer overflow error
[  393.352949] eth0: Receive buffer overflow error
 77 10.0M   77 7903k    0     0   870k      0  0:00:11  0:00:09  0:00:02  906k[  397.956674] net_ratelimit: 88 callbacks suppressed
[  397.956691] eth0: Receive buffer overflow error
[  397.967182] eth0: Receive buffer overflow error
 86 10.0M   86 8837k    0     0   877k      0  0:00:11  0:00:10  0:00:01  915k[  398.048630] eth0: Receive buffer overflow error
[  398.054171] eth0: Receive buffer overflow error
[  398.092858] eth0: Receive buffer overflow error
[  398.113975] eth0: Receive buffer overflow error
[  398.177558] eth0: Receive buffer overflow error
[  398.209782] eth0: Receive buffer overflow error
[  398.272621] eth0: Receive buffer overflow error
[  398.278306] eth0: Receive buffer overflow error
100 10.0M  100 10.0M    0     0   877k      0  0:00:11  0:00:11 --:--:--  921k
{%speed_download}
real    0m11.681s
user    0m0.117s
sys     0m0.226s

I tried this patch

diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index 9f17f3712137..bd7bd3ef6897 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -615,21 +615,9 @@ static int oa_tc6_sw_reset_macphy(struct oa_tc6 *tc6)
        return oa_tc6_write_register(tc6, OA_TC6_REG_STATUS0, regval);
 }

-static int oa_tc6_unmask_macphy_error_interrupts(struct oa_tc6 *tc6)
+static int oa_tc6_disable_imask0_interrupts(struct oa_tc6 *tc6)
 {
-       u32 regval;
-       int ret;
-
-       ret = oa_tc6_read_register(tc6, OA_TC6_REG_INT_MASK0, &regval);
-       if (ret)
-               return ret;
-
-       regval &= ~(INT_MASK0_TX_PROTOCOL_ERR_MASK |
-                   INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK |
-                   INT_MASK0_LOSS_OF_FRAME_ERR_MASK |
-                   INT_MASK0_HEADER_ERR_MASK);
-
-       return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, regval);
+       return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, (u32)-1);
 }

 static int oa_tc6_enable_data_transfer(struct oa_tc6 *tc6)
@@ -1234,7 +1222,7 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev)
                return NULL;
        }

-       ret = oa_tc6_unmask_macphy_error_interrupts(tc6);
+       ret = oa_tc6_disable_imask0_interrupts(tc6);
        if (ret) {
                dev_err(&tc6->spi->dev,
                        "MAC-PHY error interrupts unmask failed: %d\n", ret);

Which results in no log spam, ~5-10% higher throughput and no dropped
packets when I look at /sys/class/net/eth0/statistics/rx_dropped

Wheras when I did an equivalent run with a 100MB file I got 1918
rx_dropped with interrupts enabled.

When I dig through wireshark I can see some retransmissions when
interrupts are disabled, but the network stack seems to handle that with
grace.

Maybe the decision on wheter to enable interrupts or not should be on
the mac driver level, not network framework level?
If this really is preferrable for some reason, could a module option be
added so that it does not require running a fork to disable interrupts?

There is also a interrupt mask 1 register that is not touched in this
patch series, and since things started working better for me with just
touching reg0 I didn't bother tweaking anything int reg1.

BR
Ramón

^ permalink raw reply related	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-27 19:19   ` Ramón Nordin Rodriguez
@ 2024-04-27 19:57     ` Conor Dooley
  2024-04-27 20:13       ` Ramón Nordin Rodriguez
  2024-04-29  9:47       ` Parthiban.Veerasooran
  2024-04-27 20:40     ` Andrew Lunn
  1 sibling, 2 replies; 96+ messages in thread
From: Conor Dooley @ 2024-04-27 19:57 UTC (permalink / raw)
  To: Ramón Nordin Rodriguez
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, andrew, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

[-- Attachment #1: Type: text/plain, Size: 1476 bytes --]

On Sat, Apr 27, 2024 at 09:19:34PM +0200, Ramón Nordin Rodriguez wrote:
> Hi,
> 
> For me the mac driver fails to probe with the following log
> [    0.123325] SPI driver lan865x has no spi_device_id for microchip,lan8651
> 
> With this change the driver probes
> 
> diff --git a/drivers/net/ethernet/microchip/lan865x/lan865x.c b/drivers/net/ethernet/microchip/lan865x/lan865x.c
> index 9abefa8b9d9f..72a663f14f50 100644
> --- a/drivers/net/ethernet/microchip/lan865x/lan865x.c
> +++ b/drivers/net/ethernet/microchip/lan865x/lan865x.c
> @@ -364,7 +364,7 @@ static void lan865x_remove(struct spi_device *spi)
>  }
> 
>  static const struct of_device_id lan865x_dt_ids[] = {
> -       { .compatible = "microchip,lan8651", "microchip,lan8650" },

Huh, that's very strange. I don't see a single instance in the tree of a
of_device_id struct like this with two compatibles like this (at least
with a search of `rg "\.compatible.*\", \"" drivers/`.

Given the fallbacks in the binding, only "microchip,lan8650" actually
needs to be here.

> +       { .compatible = "microchip,lan865x", "microchip,lan8650" },
>         { /* Sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, lan865x_dt_ids);
> 
> Along with compatible = "microchip,lan865x" in the dts

Just to be clear, the compatible w/ an x is unacceptable due to the
wildcard and the binding should stay as-is. Whatever probing bugs
the code has need to be resolved instead :)

Thanks,
Conor.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 09/12] net: ethernet: oa_tc6: implement receive path to receive rx ethernet frames
  2024-04-18 12:56 ` [PATCH net-next v4 09/12] net: ethernet: oa_tc6: implement receive path to receive rx " Parthiban Veerasooran
  2024-04-24  0:08   ` Andrew Lunn
@ 2024-04-27 20:02   ` Ramón Nordin Rodriguez
  2024-04-29  8:32     ` Parthiban.Veerasooran
  1 sibling, 1 reply; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-27 20:02 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Could xfer.rx_buf for the data path point to the currently allocacted socket buff 
	struct spi_transfer xfer = { 0 };
	struct spi_message msg;

	if (header_type == OA_TC6_DATA_HEADER) {
		xfer.tx_buf = tc6->spi_data_tx_buf;
		xfer.rx_buf = tc6->spi_data_rx_buf;
	} else {
		xfer.tx_buf = tc6->spi_ctrl_tx_buf;
		xfer.rx_buf = tc6->spi_ctrl_rx_buf;
	}
	xfer.len = length;

To avoid an additional copy here?

> +static void oa_tc6_update_rx_skb(struct oa_tc6 *tc6, u8 *payload, u8 length)
> +{
> +	memcpy(skb_put(tc6->rx_skb, length), payload, length);
> +}
> 

R

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-27 19:57     ` Conor Dooley
@ 2024-04-27 20:13       ` Ramón Nordin Rodriguez
  2024-04-27 20:22         ` Conor Dooley
  2024-04-29  9:47       ` Parthiban.Veerasooran
  1 sibling, 1 reply; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-27 20:13 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, andrew, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

On Sat, Apr 27, 2024 at 08:57:43PM +0100, Conor Dooley wrote:
> >  static const struct of_device_id lan865x_dt_ids[] = {
> > -       { .compatible = "microchip,lan8651", "microchip,lan8650" },
> 
> Huh, that's very strange. I don't see a single instance in the tree of a
> of_device_id struct like this with two compatibles like this (at least
> with a search of `rg "\.compatible.*\", \"" drivers/`.
> 
> Given the fallbacks in the binding, only "microchip,lan8650" actually
> needs to be here.
> 
> > +       { .compatible = "microchip,lan865x", "microchip,lan8650" },
> >         { /* Sentinel */ }
> >  };
> >  MODULE_DEVICE_TABLE(of, lan865x_dt_ids);
> > 
> > Along with compatible = "microchip,lan865x" in the dts
> 
> Just to be clear, the compatible w/ an x is unacceptable due to the
> wildcard and the binding should stay as-is. Whatever probing bugs
> the code has need to be resolved instead :)
> 

All right, so when I change to

@@ -364,7 +364,7 @@ static void lan865x_remove(struct spi_device *spi)
 }

 static const struct of_device_id lan865x_dt_ids[] = {
-       { .compatible = "microchip,lan8651", "microchip,lan8650" },
+       { .compatible = "microchip,lan8650" },
        { /* Sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, lan865x_dt_ids);

I still get the output
[    0.124266] SPI driver lan865x has no spi_device_id for microchip,lan8650
But the driver does probe and I get a network interface.

If no one beats me to it I'll single step the probe tomorrow.
R

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-27 20:13       ` Ramón Nordin Rodriguez
@ 2024-04-27 20:22         ` Conor Dooley
  2024-04-27 21:09           ` Ramón Nordin Rodriguez
  0 siblings, 1 reply; 96+ messages in thread
From: Conor Dooley @ 2024-04-27 20:22 UTC (permalink / raw)
  To: Ramón Nordin Rodriguez
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, andrew, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

[-- Attachment #1: Type: text/plain, Size: 2100 bytes --]

On Sat, Apr 27, 2024 at 10:13:33PM +0200, Ramón Nordin Rodriguez wrote:
> On Sat, Apr 27, 2024 at 08:57:43PM +0100, Conor Dooley wrote:
> > >  static const struct of_device_id lan865x_dt_ids[] = {
> > > -       { .compatible = "microchip,lan8651", "microchip,lan8650" },
> > 
> > Huh, that's very strange. I don't see a single instance in the tree of a
> > of_device_id struct like this with two compatibles like this (at least
> > with a search of `rg "\.compatible.*\", \"" drivers/`.
> > 
> > Given the fallbacks in the binding, only "microchip,lan8650" actually
> > needs to be here.
> > 
> > > +       { .compatible = "microchip,lan865x", "microchip,lan8650" },
> > >         { /* Sentinel */ }
> > >  };
> > >  MODULE_DEVICE_TABLE(of, lan865x_dt_ids);
> > > 
> > > Along with compatible = "microchip,lan865x" in the dts
> > 
> > Just to be clear, the compatible w/ an x is unacceptable due to the
> > wildcard and the binding should stay as-is. Whatever probing bugs
> > the code has need to be resolved instead :)
> > 
> 
> All right, so when I change to
> 
> @@ -364,7 +364,7 @@ static void lan865x_remove(struct spi_device *spi)
>  }
> 
>  static const struct of_device_id lan865x_dt_ids[] = {
> -       { .compatible = "microchip,lan8651", "microchip,lan8650" },
> +       { .compatible = "microchip,lan8650" },
>         { /* Sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, lan865x_dt_ids);
> 
> I still get the output
> [    0.124266] SPI driver lan865x has no spi_device_id for microchip,lan8650
> But the driver does probe and I get a network interface.
> 
> If no one beats me to it I'll single step the probe tomorrow.

I think the error pretty much is what it says it is, the driver doesn't
appear to have a spi_device_id table containing lan8650. The name of
the driver is lan685x which is used in the fallback clause in
__spi_register_driver(), so it complains as it does not find lan8650 in
either. If my understanding is correct, either a spi_device_id table is
required or the driver needs a rename with s/x/0/.

Cheers,
Conor.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-27 19:19   ` Ramón Nordin Rodriguez
  2024-04-27 19:57     ` Conor Dooley
@ 2024-04-27 20:40     ` Andrew Lunn
  2024-04-27 21:06       ` Ramón Nordin Rodriguez
  1 sibling, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-27 20:40 UTC (permalink / raw)
  To: Ramón Nordin Rodriguez
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

On Sat, Apr 27, 2024 at 09:19:34PM +0200, Ramón Nordin Rodriguez wrote:
> Hi,
> 
> For me the mac driver fails to probe with the following log
> [    0.123325] SPI driver lan865x has no spi_device_id for microchip,lan8651
> 
> With this change the driver probes
> 
> diff --git a/drivers/net/ethernet/microchip/lan865x/lan865x.c b/drivers/net/ethernet/microchip/lan865x/lan865x.c
> index 9abefa8b9d9f..72a663f14f50 100644
> --- a/drivers/net/ethernet/microchip/lan865x/lan865x.c
> +++ b/drivers/net/ethernet/microchip/lan865x/lan865x.c
> @@ -364,7 +364,7 @@ static void lan865x_remove(struct spi_device *spi)
>  }
> 
>  static const struct of_device_id lan865x_dt_ids[] = {
> -       { .compatible = "microchip,lan8651", "microchip,lan8650" },
> +       { .compatible = "microchip,lan865x", "microchip,lan8650" },
>         { /* Sentinel */ }
>  };

The device tree binding says:

+  compatible:
+    oneOf:
+      - const: microchip,lan8650
+      - items:
+          - const: microchip,lan8651
+          - const: microchip,lan8650

So your DT node should either be:

compatible = "microchip,lan8651", "microchip,lan8650";

or

compatible = "microchip,lan8650"

There is no mention of lan865x in the binding, so this patch is
clearly wrong.

What do you have in your DT node?

     Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-27 19:35   ` Ramón Nordin Rodriguez
@ 2024-04-27 20:58     ` Andrew Lunn
  2024-04-27 21:29       ` Ramón Nordin Rodriguez
  0 siblings, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-27 20:58 UTC (permalink / raw)
  To: Ramón Nordin Rodriguez
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

On Sat, Apr 27, 2024 at 09:35:06PM +0200, Ramón Nordin Rodriguez wrote:
> I'm running a dual lan8650 setup, neither IC passed the sw reset in the
> oa_tc.c module, I need to pull the reset pin low to reset the pin before
> the rest of the init stuff happens.
> 
> The datasheet recommends not doing a sw reset, excerpt from section
> 4.1.1.3 Software Reset
> "Note: The SW_RESET bit of the Clause 22 Basic Control register will reset only the internal PHY, not
> the entire device. This PHY only reset is not recommended for use. If such a reset is detected, by
> reading the RESETC bit of the STS2 register, reset the entire device."

That is not so good. The PHY driver does not know the PHY is embedded
within another device. It has no idea of RESETC bit in STS2. Looking
at the phy driver, i don't actually seeing it using
genphy_soft_reset(). Do you see a code path where this could actually
be an issue?

Supporting a hardware reset does however make sense. It would be best
if you submitted a proper clean patch. It can be added to the end of
this series, keeping you as author.

     Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-27 20:40     ` Andrew Lunn
@ 2024-04-27 21:06       ` Ramón Nordin Rodriguez
  2024-04-28 14:18         ` Andrew Lunn
  0 siblings, 1 reply; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-27 21:06 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

Ok this tripped me up.

> The device tree binding says:
> 
> +  compatible:
> +    oneOf:
> +      - const: microchip,lan8650
> +      - items:
> +          - const: microchip,lan8651
> +          - const: microchip,lan8650
> 
> So your DT node should either be:
> 
> compatible = "microchip,lan8651", "microchip,lan8650";
> 
> or
> 
> compatible = "microchip,lan8650"
> 
> There is no mention of lan865x in the binding, so this patch is
> clearly wrong.
> 
> What do you have in your DT node?

Initially I set compatible = "microchip,lan8650", and did not get the
driver to probe, so I got carried away with adding things that were not
necessary.

I dropped my patch and tested again.
What does work is setting:

compatible = "microchip,lan8651"

 - or - 

compatible = "microchip,lan8651", "microchip,lan8650"

but just compatible = "lan8650" does not work.

Also I'm getting the output
[    0.125056] SPI driver lan8650 has no spi_device_id for microchip,lan8651

As Conor pointed out setting the define DRV_NAME to "lan8651" fixes
that.
Setting the define to "lan8650" yet gets the spi module to log the 'no spi_device id..'.

I don't really have an opinion here, but I think there is a risk that
more than one dev might stumble on the same thing as me and expect that
either or should work.

BR
R

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-27 20:22         ` Conor Dooley
@ 2024-04-27 21:09           ` Ramón Nordin Rodriguez
  0 siblings, 0 replies; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-27 21:09 UTC (permalink / raw)
  To: Conor Dooley
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, andrew, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> I think the error pretty much is what it says it is, the driver doesn't
> appear to have a spi_device_id table containing lan8650. The name of
> the driver is lan685x which is used in the fallback clause in
> __spi_register_driver(), so it complains as it does not find lan8650 in
> either. If my understanding is correct, either a spi_device_id table is
> required or the driver needs a rename with s/x/0/.
> 

Right you are, no gdb necessary. With the caveat that I only get it
working when setting DRV_NAME to "lan8651", setting it to "lan8650"
still produces the log

R

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking
  2024-04-27 19:52   ` Ramón Nordin Rodriguez
@ 2024-04-27 21:17     ` Andrew Lunn
  2024-04-27 21:55       ` Ramón Nordin Rodriguez
  2024-04-28  9:54       ` Ramón Nordin Rodriguez
  0 siblings, 2 replies; 96+ messages in thread
From: Andrew Lunn @ 2024-04-27 21:17 UTC (permalink / raw)
  To: Ramón Nordin Rodriguez
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

On Sat, Apr 27, 2024 at 09:52:15PM +0200, Ramón Nordin Rodriguez wrote:
> > +static int oa_tc6_unmask_macphy_error_interrupts(struct oa_tc6 *tc6)
> > +{
> > +	u32 regval;
> > +	int ret;
> > +
> > +	ret = oa_tc6_read_register(tc6, OA_TC6_REG_INT_MASK0, &regval);
> > +	if (ret)
> > +		return ret;
> > +
> > +	regval &= ~(INT_MASK0_TX_PROTOCOL_ERR_MASK |
> > +		    INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK |
> > +		    INT_MASK0_LOSS_OF_FRAME_ERR_MASK |
> > +		    INT_MASK0_HEADER_ERR_MASK);
> > +
> > +	return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, regval);
> > +}
> > +
> 
> This togheter with patch 11 works poorly for me. I get alot of kernel
> output, dropped packets and lower performance.
> Below is an example for a run when I curl a 10MB blob
> 
> time curl 20.0.0.55:8000/rdump -o dump -w '{%speed_download}'
>   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
>                                  Dload  U[  387.944737] net_ratelimit: 38 callbacks suppressed
> pload   Total   Spent    Left  Sp[  387.944755] eth0: Receive buffer overflow error
> eed
>   0     0    0     0    0     0      0      0 --:--:-- --:-[  387.961424] eth0: Receive buffer overflow error
>   0 10.0M    0  2896    0     0  13031      0  0:13:24 --:--:--  0:13:24 12986[  388.204257] eth0: Receive buffer overflow error
> [  388.209848] eth0: Receive buffer overflow error

How fast is your SPI bus? Faster than the link speed? Or slower?

It could be different behaviour is needed depending on the SPI bus
speed. If the SPI bus is faster than the link speed, by some margin,
the receiver buffer should not overflow, since the CPU can empty the
buffer faster than it fills.

If however, the SPI bus is slower than the link speed, there will be
buffer overflows, and a reliance on TCP backing off and slowing down.
The driver should not be spamming the log, since it is going to happen
and there is nothing that can be done about it.

> I tried this patch
> 
> diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
> index 9f17f3712137..bd7bd3ef6897 100644
> --- a/drivers/net/ethernet/oa_tc6.c
> +++ b/drivers/net/ethernet/oa_tc6.c
> @@ -615,21 +615,9 @@ static int oa_tc6_sw_reset_macphy(struct oa_tc6 *tc6)
>         return oa_tc6_write_register(tc6, OA_TC6_REG_STATUS0, regval);
>  }
> 
> -static int oa_tc6_unmask_macphy_error_interrupts(struct oa_tc6 *tc6)
> +static int oa_tc6_disable_imask0_interrupts(struct oa_tc6 *tc6)
>  {
> -       u32 regval;
> -       int ret;
> -
> -       ret = oa_tc6_read_register(tc6, OA_TC6_REG_INT_MASK0, &regval);
> -       if (ret)
> -               return ret;
> -
> -       regval &= ~(INT_MASK0_TX_PROTOCOL_ERR_MASK |
> -                   INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK |
> -                   INT_MASK0_LOSS_OF_FRAME_ERR_MASK |
> -                   INT_MASK0_HEADER_ERR_MASK);
> -
> -       return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, regval);
> +       return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, (u32)-1);

So this appears to be disabling all error interrupts?

This is maybe going too far. Overflow errors are going to happen if
you have a slow SPI bus. So i probably would not enable that. However,
are the other errors actually expected in normal usage? If not, leave
them enabled, because they might indicate real problems.

> Which results in no log spam, ~5-10% higher throughput and no dropped
> packets when I look at /sys/class/net/eth0/statistics/rx_dropped

You cannot trust rx_dropped because you just disabled the code which
increments it! The device is probably still dropping packets, and they
are no longer counted.

It could be the performance increase comes from two places:

1) Spending time and bus bandwidth dealing with the buffer overflow
interrupt

2) Printing out the serial port.

Please could you benchmark a few things:

1) Remove the printk("Receive buffer overflow error"), but otherwise
keep the code the same. That will give us an idea how much the serial
port matters.

2) Disable only the RX buffer overflow interrupt

3) Disable all error interrupts.

   Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-27 20:58     ` Andrew Lunn
@ 2024-04-27 21:29       ` Ramón Nordin Rodriguez
  2024-04-28 14:25         ` Andrew Lunn
  0 siblings, 1 reply; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-27 21:29 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

On Sat, Apr 27, 2024 at 10:58:07PM +0200, Andrew Lunn wrote:
> On Sat, Apr 27, 2024 at 09:35:06PM +0200, Ramón Nordin Rodriguez wrote:
> > I'm running a dual lan8650 setup, neither IC passed the sw reset in the
> > oa_tc.c module, I need to pull the reset pin low to reset the pin before
> > the rest of the init stuff happens.
> > 
> > The datasheet recommends not doing a sw reset, excerpt from section
> > 4.1.1.3 Software Reset
> > "Note: The SW_RESET bit of the Clause 22 Basic Control register will reset only the internal PHY, not
> > the entire device. This PHY only reset is not recommended for use. If such a reset is detected, by
> > reading the RESETC bit of the STS2 register, reset the entire device."
> 
> That is not so good. The PHY driver does not know the PHY is embedded
> within another device. It has no idea of RESETC bit in STS2. Looking
> at the phy driver, i don't actually seeing it using
> genphy_soft_reset(). Do you see a code path where this could actually
> be an issue?
> 

I agree with your assesment, the phy won't reset itself, but maybe we
could add some comment doc about not adding it for the lan8670,
so no one trips over that in the future.
Though the phy does not have to be baked with the lan8650 mac, so that
might be tricky to cover all future bases there. But for now I don't
think it matters.

Then regarding doing the soft reset in the oa_tc6 module, I'm not sure
that it matters, since it seems to work fine for me for as long as I do
the hw reset first.
But I can submit a suggestion for how to deal with reset-quirks if we
want to have the soft reset optional.

I'll run a test with and without the soft reset and see if I can spot
any change in behaviour.

Let me know if I missed any nuance in your question.

> Supporting a hardware reset does however make sense. It would be best
> if you submitted a proper clean patch. It can be added to the end of
> this series, keeping you as author.
> 

I'd be happy to. Getting late in scandinavia so I'll clean it up and
submit tomorrow.

R

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking
  2024-04-27 21:17     ` Andrew Lunn
@ 2024-04-27 21:55       ` Ramón Nordin Rodriguez
  2024-04-28 14:48         ` Andrew Lunn
  2024-04-28  9:54       ` Ramón Nordin Rodriguez
  1 sibling, 1 reply; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-27 21:55 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> How fast is your SPI bus? Faster than the link speed? Or slower?
> 
> It could be different behaviour is needed depending on the SPI bus
> speed. If the SPI bus is faster than the link speed, by some margin,
> the receiver buffer should not overflow, since the CPU can empty the
> buffer faster than it fills.

I'm running at 25MHz, I'm guessing that should translate to fast enough
for the 10MBit half duplex link.
But I'm not sure how the spi clock translates to bps here.

> 
> If however, the SPI bus is slower than the link speed, there will be
> buffer overflows, and a reliance on TCP backing off and slowing down.
> The driver should not be spamming the log, since it is going to happen
> and there is nothing that can be done about it.
> 

I agree, I think the print could be a DBG if deemed necessary, but there
is also the dropped counter to look at.

> > I tried this patch
> > 
> > diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
> > index 9f17f3712137..bd7bd3ef6897 100644
> > --- a/drivers/net/ethernet/oa_tc6.c
> > +++ b/drivers/net/ethernet/oa_tc6.c
> > @@ -615,21 +615,9 @@ static int oa_tc6_sw_reset_macphy(struct oa_tc6 *tc6)
> >         return oa_tc6_write_register(tc6, OA_TC6_REG_STATUS0, regval);
> >  }
> > 
> > -static int oa_tc6_unmask_macphy_error_interrupts(struct oa_tc6 *tc6)
> > +static int oa_tc6_disable_imask0_interrupts(struct oa_tc6 *tc6)
> >  {
> > -       u32 regval;
> > -       int ret;
> > -
> > -       ret = oa_tc6_read_register(tc6, OA_TC6_REG_INT_MASK0, &regval);
> > -       if (ret)
> > -               return ret;
> > -
> > -       regval &= ~(INT_MASK0_TX_PROTOCOL_ERR_MASK |
> > -                   INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK |
> > -                   INT_MASK0_LOSS_OF_FRAME_ERR_MASK |
> > -                   INT_MASK0_HEADER_ERR_MASK);
> > -
> > -       return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, regval);
> > +       return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, (u32)-1);
> 
> So this appears to be disabling all error interrupts?

Yes, and I think you are right in that it's an overcorrection. There is
a secondary interrupt mask register as well that is not touched by the
driver, so that's left at whatever the chip defaults to on reset.

> 
> This is maybe going too far. Overflow errors are going to happen if
> you have a slow SPI bus. So i probably would not enable that. However,
> are the other errors actually expected in normal usage? If not, leave
> them enabled, because they might indicate real problems.

I'm guessing you are right and that the others actually would be
meningful to log.
There is a nested question here as well, and that is wheter to keep or
drop the code that drops the rx buffer on overflow interrupt.
I think not dropping the full buffer could be one of the reasons for the
perf change.

> 
> > Which results in no log spam, ~5-10% higher throughput and no dropped
> > packets when I look at /sys/class/net/eth0/statistics/rx_dropped
> 
> You cannot trust rx_dropped because you just disabled the code which
> increments it! The device is probably still dropping packets, and they
> are no longer counted.

I'll curb my enthusiasm a bit :)

> 
> It could be the performance increase comes from two places:
> 
> 1) Spending time and bus bandwidth dealing with the buffer overflow
> interrupt
> 
> 2) Printing out the serial port.
> 

I think it's possible that the buffer cleanup triggered after the
overflow interrupt hits could be cause 3) here, but just a guess.

> Please could you benchmark a few things:
> 
> 1) Remove the printk("Receive buffer overflow error"), but otherwise
> keep the code the same. That will give us an idea how much the serial
> port matters.
> 
> 2) Disable only the RX buffer overflow interrupt
> 
> 3) Disable all error interrupts.
> 

Thanks for layout it out so clearly. I'll run through the scenarios!

R

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 01/12] Documentation: networking: add OPEN Alliance 10BASE-T1x MAC-PHY serial interface
  2024-04-18 12:56 ` [PATCH net-next v4 01/12] Documentation: networking: add OPEN Alliance 10BASE-T1x MAC-PHY serial interface Parthiban Veerasooran
@ 2024-04-28  9:33   ` Bagas Sanjaya
  2024-04-29 11:31     ` Parthiban.Veerasooran
  2024-04-29 16:17   ` Simon Horman
  1 sibling, 1 reply; 96+ messages in thread
From: Bagas Sanjaya @ 2024-04-28  9:33 UTC (permalink / raw)
  To: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, andrew, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean
  Cc: UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

[-- Attachment #1: Type: text/plain, Size: 1029 bytes --]

On Thu, Apr 18, 2024 at 06:26:37PM +0530, Parthiban Veerasooran wrote:
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 04e5f7c20e30..79fa7abb4ec9 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16400,6 +16400,12 @@ L:	linux-rdma@vger.kernel.org
>  S:	Supported
>  F:	drivers/infiniband/ulp/opa_vnic
>  
> +OPEN ALLIANCE 10BASE-T1S MACPHY SERIAL INTERFACE FRAMEWORK
> +M:	Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
> +L:	netdev@vger.kernel.org
> +S:	Maintained
> +F:	Documentation/networking/oa-tc6-framework.rst
> +
>  OPEN FIRMWARE AND FLATTENED DEVICE TREE
>  M:	Rob Herring <robh+dt@kernel.org>
>  M:	Frank Rowand <frowand.list@gmail.com>

I can't apply this series on top of current net-next due to MAINTAINERS diff
above (on context line 16400 I have Omnivision entries). Care to reroll?
(Hint: also specify --base= to git-send-email(1) so that I and other
reviewers know where to apply this series.)

Confused...

-- 
An old man doll... just what I always wanted! - Clara

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking
  2024-04-27 21:17     ` Andrew Lunn
  2024-04-27 21:55       ` Ramón Nordin Rodriguez
@ 2024-04-28  9:54       ` Ramón Nordin Rodriguez
  2024-04-28 14:59         ` Andrew Lunn
  1 sibling, 1 reply; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-28  9:54 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> It could be the performance increase comes from two places:
> 
> 1) Spending time and bus bandwidth dealing with the buffer overflow
> interrupt
> 
> 2) Printing out the serial port.
> 
> Please could you benchmark a few things:
> 
> 1) Remove the printk("Receive buffer overflow error"), but otherwise
> keep the code the same. That will give us an idea how much the serial
> port matters.
> 
> 2) Disable only the RX buffer overflow interrupt
> 
> 3) Disable all error interrupts.
> 



Test setup
- Server side - 
PC with a lan8670 usb eval board running a http server that serves
a 10MB binary blob. The http server is just python3 -m http.server

- Client side -
iMX8mn board (quad core arm64) with lan8650 mac-phy (25MHz spi)
running curl to download the blob from the server and writing to
a ramfs (ddr4 1.xGHz, so should not be a bottleneck)

Below are a collection of samples of different test runs. All of the
test runs have run a minor patch for hw reset (else nothing works for me).
Using curl is not the most scientific approach here, but iperf has
not exposed any problems for me earlier with overflows.
So sticking with curl since it's easy and definetly gets the overflows.

n  |  name     |  min  |  avg  |  max  |  rx dropped  |  samples
1  |  no mod   |  827K |  846K |  891K |      945     |     5
2  |  no log   |  711K |  726K |  744K |      562     |     5
3  |  less irq |  815K |  833K |  846K |      N/A     |     5
4  |  no irq   |  914K |  924K |  931K |      N/A     |     5
5  |  simple   |  857K |  868K |  879K |      615     |     5

Description of each scenario

1 - no mod
So this just runs a hw reset to get the chip working (described in earlier posts)

2 - no log
This scenario just removes the logging when handling the irq state
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -688,8 +688,6 @@ static int oa_tc6_process_extended_status(struct oa_tc6 *tc6)
        if (FIELD_GET(STATUS0_RX_BUFFER_OVERFLOW_ERROR, value)) {
                tc6->rx_buf_overflow = true;
                oa_tc6_cleanup_ongoing_rx_skb(tc6);
-               net_err_ratelimited("%s: Receive buffer overflow error\n",
-                                   tc6->netdev->name);
                return -EAGAIN;
        }
        if (FIELD_GET(STATUS0_TX_PROTOCOL_ERROR, value)) {

3 - less irq
This scenario disables the overflow interrupt but keeps the others

--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -625,10 +625,10 @@ static int oa_tc6_unmask_macphy_error_interrupts(struct oa_tc6 *tc6)
                return ret;

        regval &= ~(INT_MASK0_TX_PROTOCOL_ERR_MASK |
-                   INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK |
                    INT_MASK0_LOSS_OF_FRAME_ERR_MASK |
                    INT_MASK0_HEADER_ERR_MASK);

+       regval |= INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK;
        return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, regval);
 }

4 - no irq
This scenario disables all imask0 interrupts with the following change

diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index 9f17f3712137..88a9c6ccb37a 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -624,12 +624,7 @@ static int oa_tc6_unmask_macphy_error_interrupts(struct oa_tc6 *tc6)
        if (ret)
                return ret;

-       regval &= ~(INT_MASK0_TX_PROTOCOL_ERR_MASK |
-                   INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK |
-                   INT_MASK0_LOSS_OF_FRAME_ERR_MASK |
-                   INT_MASK0_HEADER_ERR_MASK);
-
-       return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, regval);
+       return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, (u32)-1);
 }

 static int oa_tc6_enable_data_transfer(struct oa_tc6 *tc6)


5 - simple
This keeps the interrupt but does not log or drop the socket buffer on irq
Moving the rx dropped increment here makes it more of a irq counter I guess,
so maybe not relevant.

diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index 9f17f3712137..cbc20a725ad0 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -687,10 +687,7 @@ static int oa_tc6_process_extended_status(struct oa_tc6 *tc6)

        if (FIELD_GET(STATUS0_RX_BUFFER_OVERFLOW_ERROR, value)) {
                tc6->rx_buf_overflow = true;
-               oa_tc6_cleanup_ongoing_rx_skb(tc6);
-               net_err_ratelimited("%s: Receive buffer overflow error\n",
-                                   tc6->netdev->name);
-               return -EAGAIN;
+               tc6->netdev->stats.rx_dropped++;
        }
        if (FIELD_GET(STATUS0_TX_PROTOCOL_ERROR, value)) {
                netdev_err(tc6->netdev, "Transmit protocol error\n");


- postamble -

Removing the logging made things considerably slower which probably
indicates that there is a timing dependent behaviour in the driver.

I have a hard time explaining why there is a throughput difference
between scenario 3 and 4 since I did not get the logs that any of the
other interrupts happened.
Maybe the irq handling adds some unexpected context switching overhead.

My recommendation going forward would be to disable the rx buffer
overlow interrupt and removing any code related to handling of it.

R

^ permalink raw reply related	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-27 21:06       ` Ramón Nordin Rodriguez
@ 2024-04-28 14:18         ` Andrew Lunn
  0 siblings, 0 replies; 96+ messages in thread
From: Andrew Lunn @ 2024-04-28 14:18 UTC (permalink / raw)
  To: Ramón Nordin Rodriguez
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> but just compatible = "lan8650" does not work.

The device tree binding says that is valid, so this needs fixing.

Maybe copy max1111.c in hwmon:

static const struct spi_device_id max1111_ids[] = {
        { "max1110", max1110 },
        { "max1111", max1111 },
        { "max1112", max1112 },
        { "max1113", max1113 },
        { },
};
MODULE_DEVICE_TABLE(spi, max1111_ids);

static struct spi_driver max1111_driver = {
        .driver         = {
                .name   = "max1111",
        },
        .id_table       = max1111_ids,
        .probe          = max1111_probe,
        .remove         = max1111_remove,
};

Interestingly, there is no compatible table. So the device tree
binding probably should change, not require two compatibles for
lan8651.

	Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-27 21:29       ` Ramón Nordin Rodriguez
@ 2024-04-28 14:25         ` Andrew Lunn
  2024-04-28 22:00           ` Ramón Nordin Rodriguez
  0 siblings, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-28 14:25 UTC (permalink / raw)
  To: Ramón Nordin Rodriguez
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> I agree with your assesment, the phy won't reset itself, but maybe we
> could add some comment doc about not adding it for the lan8670,
> so no one trips over that in the future.

In the PHY driver, you can provide your own .soft_reset handler. It
could return -EOPNOTSUPP, or -EINVAL. Maybe check the data sheets for
the standalone devices supported by the driver. Can you limit this to
just the TC6 PHY?

     Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking
  2024-04-27 21:55       ` Ramón Nordin Rodriguez
@ 2024-04-28 14:48         ` Andrew Lunn
  0 siblings, 0 replies; 96+ messages in thread
From: Andrew Lunn @ 2024-04-28 14:48 UTC (permalink / raw)
  To: Ramón Nordin Rodriguez
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

On Sat, Apr 27, 2024 at 11:55:13PM +0200, Ramón Nordin Rodriguez wrote:
> > How fast is your SPI bus? Faster than the link speed? Or slower?
> > 
> > It could be different behaviour is needed depending on the SPI bus
> > speed. If the SPI bus is faster than the link speed, by some margin,
> > the receiver buffer should not overflow, since the CPU can empty the
> > buffer faster than it fills.
> 
> I'm running at 25MHz, I'm guessing that should translate to fast enough
> for the 10MBit half duplex link.
> But I'm not sure how the spi clock translates to bps here.

That seems plenty fast. Maybe you can get a bus pirate or similar
sniffing the bus. Maybe there are big gaps between the transfers for
some reason? Or the interrupt controller is very slow?

> I'm guessing you are right and that the others actually would be
> meningful to log.
> There is a nested question here as well, and that is wheter to keep or
> drop the code that drops the rx buffer on overflow interrupt.
> I think not dropping the full buffer could be one of the reasons for the
> perf change.

You need to look careful at what a buffer overflow means, as written
in the standard. Does it mean a chunk has been dropped from the frame
currently being transferred over the SPI bus? If so, you need to drop
the frame, because it is missing 64 bytes somewhere. That could happen
if the device has very minimal buffering and does cut through. So the
frame goes straight to the SPI bus while it is still being received
from the line. Or the device could have sufficient buffers to hold a
few full frames. It has run out of such buffers while receiving, and
so dropped the frame. You never see that frame over SPI because it has
already been discarded. If so, linux should not be dropping anything,
the device already has.

Given your 25Mhz bus speed, i think there at least two things wrong
here. Dropping frames is too noise, and potentially doing it wrong. I
also think there is something not optimal in your SPI master, because
25MHz should not have trouble with 10Mbps line speed.

	Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking
  2024-04-28  9:54       ` Ramón Nordin Rodriguez
@ 2024-04-28 14:59         ` Andrew Lunn
  2024-04-28 22:04           ` Ramón Nordin Rodriguez
  2024-05-01 18:29           ` Ramón Nordin Rodriguez
  0 siblings, 2 replies; 96+ messages in thread
From: Andrew Lunn @ 2024-04-28 14:59 UTC (permalink / raw)
  To: Ramón Nordin Rodriguez
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> n  |  name     |  min  |  avg  |  max  |  rx dropped  |  samples
> 1  |  no mod   |  827K |  846K |  891K |      945     |     5
> 2  |  no log   |  711K |  726K |  744K |      562     |     5
> 3  |  less irq |  815K |  833K |  846K |      N/A     |     5
> 4  |  no irq   |  914K |  924K |  931K |      N/A     |     5
> 5  |  simple   |  857K |  868K |  879K |      615     |     5

That is odd.

Side question: What CONFIG_HZ= do you have? 100, 250, 1000?  Try
1000. I've seen problems where the driver wants to sleep for a short
time, but the CONFIG_HZ value limits how short a time it can actually
sleep. It ends up sleeping much longer than it wants.

	Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
  2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
                   ` (14 preceding siblings ...)
  2024-04-22 23:43 ` Andrew Lunn
@ 2024-04-28 21:16 ` Ramón Nordin Rodriguez
  2024-04-28 23:17   ` Andrew Lunn
                     ` (2 more replies)
  15 siblings, 3 replies; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-28 21:16 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

From c65e42982684d5fd8b2294eb6acf755aa0fcab83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ram=C3=B3n=20Nordin=20Rodriguez?=
 <ramon.nordin.rodriguez@ferroamp.se>
Date: Sun, 28 Apr 2024 22:25:12 +0200
Subject: [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This commit optionally enables a hardware reset of the lan8650/1
mac-phy. These chips have a software reset that is discourage from use
in the manual since it only resets the internal phy.

Signed-off-by: Ramón Nordin Rodriguez <ramon.nordin.rodriguez@ferroamp.se>
---
 .../bindings/net/microchip,lan865x.yaml       |  4 +++
 .../net/ethernet/microchip/lan865x/lan865x.c  | 28 +++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/microchip,lan865x.yaml b/Documentation/devicetree/bindings/net/microchip,lan865x.yaml
index 4fdec0ba3532..0f11f431df06 100644
--- a/Documentation/devicetree/bindings/net/microchip,lan865x.yaml
+++ b/Documentation/devicetree/bindings/net/microchip,lan865x.yaml
@@ -44,6 +44,9 @@ properties:
     minimum: 15000000
     maximum: 25000000
 
+  reset-gpios:
+    maxItems: 1
+
   "#address-cells":
     const: 1
 
@@ -76,5 +79,6 @@ examples:
         interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
         local-mac-address = [04 05 06 01 02 03];
         spi-max-frequency = <15000000>;
+        reset-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>;
       };
     };
diff --git a/drivers/net/ethernet/microchip/lan865x/lan865x.c b/drivers/net/ethernet/microchip/lan865x/lan865x.c
index 9abefa8b9d9f..bed9033574b2 100644
--- a/drivers/net/ethernet/microchip/lan865x/lan865x.c
+++ b/drivers/net/ethernet/microchip/lan865x/lan865x.c
@@ -9,6 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/phy.h>
 #include <linux/oa_tc6.h>
+#include <linux/gpio/driver.h>
 
 #define DRV_NAME			"lan865x"
 
@@ -33,6 +34,7 @@
 
 struct lan865x_priv {
 	struct work_struct multicast_work;
+	struct gpio_desc *reset_gpio;
 	struct net_device *netdev;
 	struct spi_device *spi;
 	struct oa_tc6 *tc6;
@@ -283,6 +285,24 @@ static int lan865x_set_zarfe(struct lan865x_priv *priv)
 	return oa_tc6_write_register(priv->tc6, OA_TC6_REG_CONFIG0, regval);
 }
 
+static int lan865x_probe_reset_gpio(struct lan865x_priv *priv)
+{
+	priv->reset_gpio = devm_gpiod_get_optional(&priv->spi->dev, "reset",
+						   GPIOD_OUT_HIGH);
+	if (IS_ERR(priv->reset_gpio))
+		return PTR_ERR(priv->reset_gpio);
+
+	return 0;
+}
+
+static void lan865x_hw_reset(struct lan865x_priv *priv)
+{
+	gpiod_set_value_cansleep(priv->reset_gpio, 1);
+	// section 9.6.3 RESET_N Timing specifies a minimum hold of 5us
+	usleep_range(5, 10);
+	gpiod_set_value_cansleep(priv->reset_gpio, 0);
+}
+
 static int lan865x_probe(struct spi_device *spi)
 {
 	struct net_device *netdev;
@@ -297,6 +317,14 @@ static int lan865x_probe(struct spi_device *spi)
 	priv->netdev = netdev;
 	priv->spi = spi;
 	spi_set_drvdata(spi, priv);
+	if (lan865x_probe_reset_gpio(priv)) {
+		dev_err(&spi->dev, "failed to probe reset pin");
+		ret = -ENODEV;
+		goto free_netdev;
+	}
+
+	if (priv->reset_gpio)
+		lan865x_hw_reset(priv);
 	INIT_WORK(&priv->multicast_work, lan865x_multicast_work_handler);
 
 	priv->tc6 = oa_tc6_init(spi, netdev);
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-28 14:25         ` Andrew Lunn
@ 2024-04-28 22:00           ` Ramón Nordin Rodriguez
  0 siblings, 0 replies; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-28 22:00 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

On Sun, Apr 28, 2024 at 04:25:28PM +0200, Andrew Lunn wrote:
> > I agree with your assesment, the phy won't reset itself, but maybe we
> > could add some comment doc about not adding it for the lan8670,
> > so no one trips over that in the future.
> 
> In the PHY driver, you can provide your own .soft_reset handler. It
> could return -EOPNOTSUPP, or -EINVAL. Maybe check the data sheets for
> the standalone devices supported by the driver. Can you limit this to
> just the TC6 PHY?
> 

Gotcha, I think that should be pretty easy to handle then. The
microchip_t1s.c module handles two phy families 
* lan865x - baked in
* lan867x - standalone 

I need to do some thinking and get a bit more oriented. But pretty sure
there is a simple path for this.

R

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking
  2024-04-28 14:59         ` Andrew Lunn
@ 2024-04-28 22:04           ` Ramón Nordin Rodriguez
  2024-05-01 18:29           ` Ramón Nordin Rodriguez
  1 sibling, 0 replies; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-28 22:04 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

On Sun, Apr 28, 2024 at 04:59:40PM +0200, Andrew Lunn wrote:
> > n  |  name     |  min  |  avg  |  max  |  rx dropped  |  samples
> > 1  |  no mod   |  827K |  846K |  891K |      945     |     5
> > 2  |  no log   |  711K |  726K |  744K |      562     |     5
> > 3  |  less irq |  815K |  833K |  846K |      N/A     |     5
> > 4  |  no irq   |  914K |  924K |  931K |      N/A     |     5
> > 5  |  simple   |  857K |  868K |  879K |      615     |     5
> 
> That is odd.
> 
> Side question: What CONFIG_HZ= do you have? 100, 250, 1000?  Try
> 1000. I've seen problems where the driver wants to sleep for a short
> time, but the CONFIG_HZ value limits how short a time it can actually
> sleep. It ends up sleeping much longer than it wants.
> 

Good catch, had it set to 250. I'll rebuild with CONFIG_HZ=1000 and
rerun the tests.

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
  2024-04-28 21:16 ` [PATCH net-next v4 13/12] net: lan865x: optional hardware reset Ramón Nordin Rodriguez
@ 2024-04-28 23:17   ` Andrew Lunn
  2024-04-29 10:42     ` Ramón Nordin Rodriguez
  2024-04-29  6:09   ` Parthiban.Veerasooran
  2024-04-29  6:09   ` Krzysztof Kozlowski
  2 siblings, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-28 23:17 UTC (permalink / raw)
  To: Ramón Nordin Rodriguez
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

On Sun, Apr 28, 2024 at 11:16:32PM +0200, Ramón Nordin Rodriguez wrote:
> >From c65e42982684d5fd8b2294eb6acf755aa0fcab83 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Ram=C3=B3n=20Nordin=20Rodriguez?=
>  <ramon.nordin.rodriguez@ferroamp.se>
> Date: Sun, 28 Apr 2024 22:25:12 +0200
> Subject: [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit

You sent this patch in an odd way. We don't normally see headers like
this. I've been using b4 recently for patch management:

https://b4.docs.kernel.org/en/latest/contributor/prep.html

Using `b4 send` is a good idea. Otherwise git format-patch; git send-email

> index 9abefa8b9d9f..bed9033574b2 100644
> --- a/drivers/net/ethernet/microchip/lan865x/lan865x.c
> +++ b/drivers/net/ethernet/microchip/lan865x/lan865x.c
> @@ -9,6 +9,7 @@
>  #include <linux/kernel.h>
>  #include <linux/phy.h>
>  #include <linux/oa_tc6.h>
> +#include <linux/gpio/driver.h>

This is not a gpio driver, it is a gpio consumer. So you should be
using linux/gpio/consumer.h. Also, i _think_ the includes are sorted,
so it probably should go earlier.

>  
>  #define DRV_NAME			"lan865x"
>  
> @@ -33,6 +34,7 @@
>  
>  struct lan865x_priv {
>  	struct work_struct multicast_work;
> +	struct gpio_desc *reset_gpio;
>  	struct net_device *netdev;
>  	struct spi_device *spi;
>  	struct oa_tc6 *tc6;
> @@ -283,6 +285,24 @@ static int lan865x_set_zarfe(struct lan865x_priv *priv)
>  	return oa_tc6_write_register(priv->tc6, OA_TC6_REG_CONFIG0, regval);
>  }
>  
> +static int lan865x_probe_reset_gpio(struct lan865x_priv *priv)
> +{
> +	priv->reset_gpio = devm_gpiod_get_optional(&priv->spi->dev, "reset",
> +						   GPIOD_OUT_HIGH);
> +	if (IS_ERR(priv->reset_gpio))
> +		return PTR_ERR(priv->reset_gpio);
> +
> +	return 0;
> +}
> +
> +static void lan865x_hw_reset(struct lan865x_priv *priv)
> +{
> +	gpiod_set_value_cansleep(priv->reset_gpio, 1);
> +	// section 9.6.3 RESET_N Timing specifies a minimum hold of 5us
> +	usleep_range(5, 10);
> +	gpiod_set_value_cansleep(priv->reset_gpio, 0);
> +}

Do you see a need to do a reset at any time other than probe? If not,
i would probably combine these two functions into one. Also, since you
pass GPIOD_OUT_HIGH, you have already put it into reset. So setting
the gpio to 1 is pointless.

Does the datasheet say anything about how long you should wait after
releasing the reset?

> +
>  static int lan865x_probe(struct spi_device *spi)
>  {
>  	struct net_device *netdev;
> @@ -297,6 +317,14 @@ static int lan865x_probe(struct spi_device *spi)
>  	priv->netdev = netdev;
>  	priv->spi = spi;
>  	spi_set_drvdata(spi, priv);
> +	if (lan865x_probe_reset_gpio(priv)) {
> +		dev_err(&spi->dev, "failed to probe reset pin");
> +		ret = -ENODEV;

It is normal that a function like lan865x_probe_reset_gpio() would
return an error code. You should then return that error code, rather
than replace it with ENODEV.

     Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
  2024-04-28 21:16 ` [PATCH net-next v4 13/12] net: lan865x: optional hardware reset Ramón Nordin Rodriguez
  2024-04-28 23:17   ` Andrew Lunn
@ 2024-04-29  6:09   ` Parthiban.Veerasooran
  2024-04-29 10:38     ` Ramón Nordin Rodriguez
  2024-04-29  6:09   ` Krzysztof Kozlowski
  2 siblings, 1 reply; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-29  6:09 UTC (permalink / raw)
  To: ramon.nordin.rodriguez, andrew
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Ramon,

On 29/04/24 2:46 am, Ramón Nordin Rodriguez wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
>  From c65e42982684d5fd8b2294eb6acf755aa0fcab83 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Ram=C3=B3n=20Nordin=20Rodriguez?=
>   <ramon.nordin.rodriguez@ferroamp.se>
> Date: Sun, 28 Apr 2024 22:25:12 +0200
> Subject: [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
> 
> This commit optionally enables a hardware reset of the lan8650/1
> mac-phy. These chips have a software reset that is discourage from use
> in the manual since it only resets the internal phy.
The software reset done by the current driver is not only resetting the 
internal PHY, it resets the entire MAC-PHY including the integrated PHY.
The reset bit of the Clause 22 basic control register only will reset 
the internal PHY alone. But oa_tc6_sw_reset_macphy() function is writing 
software reset bit in the Reset Control and Status register which resets 
the entire MAC-PHY including the internal PHY.

OPEN Alliance spec says the following which is done in the 
oa_tc6_sw_reset_macphy().

9.2.4
Reset Control and Status Register (0x0003)
9.2.4.1 RSVD
Reserved for future use. Writing to these bits shall have no effect on 
the MAC-PHY.
9.2.4.2 SWRESET
MAC-PHY Software Reset. The action of writing a ‘1’ to this bit shall 
fully reset the MAC-PHY, including the integrated PHY, to an initial 
state including but not limited to resetting all state machines and 
registers to their default value. When this bit is set, the reset shall 
not occur until CSn is deasserted to allow for the control command write 
to complete. This bit is self-clearing.

LAN8650 spec says the following,

4.1.1.3 Software Reset
A software reset of the LAN8650/1 is available via the Soft Reset 
(SW_RESET) bit in the standard OA_CONFIG0 register.

Note: The SW_RESET bit of the Clause 22 Basic Control register will 
reset only the internal PHY, not the entire device. This PHY only reset 
is not recommended for use. If such a reset is detected, by reading the 
RESETC bit of the STS2 register, reset the entire device.

The above note is given in the lan8650 datasheet to let the user to know 
that clause 22 software reset will reset only internal PHY but I don't 
think they mean it for the MAC-PHY software reset done from Reset 
Control and Status register.

So in my opinion, I don't see the need of external pin reset as the 
existing oa_tc6_sw_reset_macphy() function does the software reset of 
the entire MAC-PHY.

Still if you see a need to have this external pin reset as an optional 
function then it may be needed for all the vendor specific MAC drivers. 
In that case, reset-gpios parameter value alone can be taken from the 
chip specific device tree and the remaining code for operating the reset 
gpio can be moved to oa_tc6.c and the function name can be 
oa_tc6_hw_reset_macphy().

Best regards,
Parthiban V
> 
> Signed-off-by: Ramón Nordin Rodriguez <ramon.nordin.rodriguez@ferroamp.se>
> ---
>   .../bindings/net/microchip,lan865x.yaml       |  4 +++
>   .../net/ethernet/microchip/lan865x/lan865x.c  | 28 +++++++++++++++++++
>   2 files changed, 32 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/net/microchip,lan865x.yaml b/Documentation/devicetree/bindings/net/microchip,lan865x.yaml
> index 4fdec0ba3532..0f11f431df06 100644
> --- a/Documentation/devicetree/bindings/net/microchip,lan865x.yaml
> +++ b/Documentation/devicetree/bindings/net/microchip,lan865x.yaml
> @@ -44,6 +44,9 @@ properties:
>       minimum: 15000000
>       maximum: 25000000
> 
> +  reset-gpios:
> +    maxItems: 1
> +
>     "#address-cells":
>       const: 1
> 
> @@ -76,5 +79,6 @@ examples:
>           interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
>           local-mac-address = [04 05 06 01 02 03];
>           spi-max-frequency = <15000000>;
> +        reset-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>;
>         };
>       };
> diff --git a/drivers/net/ethernet/microchip/lan865x/lan865x.c b/drivers/net/ethernet/microchip/lan865x/lan865x.c
> index 9abefa8b9d9f..bed9033574b2 100644
> --- a/drivers/net/ethernet/microchip/lan865x/lan865x.c
> +++ b/drivers/net/ethernet/microchip/lan865x/lan865x.c
> @@ -9,6 +9,7 @@
>   #include <linux/kernel.h>
>   #include <linux/phy.h>
>   #include <linux/oa_tc6.h>
> +#include <linux/gpio/driver.h>
> 
>   #define DRV_NAME                       "lan865x"
> 
> @@ -33,6 +34,7 @@
> 
>   struct lan865x_priv {
>          struct work_struct multicast_work;
> +       struct gpio_desc *reset_gpio;
>          struct net_device *netdev;
>          struct spi_device *spi;
>          struct oa_tc6 *tc6;
> @@ -283,6 +285,24 @@ static int lan865x_set_zarfe(struct lan865x_priv *priv)
>          return oa_tc6_write_register(priv->tc6, OA_TC6_REG_CONFIG0, regval);
>   }
> 
> +static int lan865x_probe_reset_gpio(struct lan865x_priv *priv)
> +{
> +       priv->reset_gpio = devm_gpiod_get_optional(&priv->spi->dev, "reset",
> +                                                  GPIOD_OUT_HIGH);
> +       if (IS_ERR(priv->reset_gpio))
> +               return PTR_ERR(priv->reset_gpio);
> +
> +       return 0;
> +}
> +
> +static void lan865x_hw_reset(struct lan865x_priv *priv)
> +{
> +       gpiod_set_value_cansleep(priv->reset_gpio, 1);
> +       // section 9.6.3 RESET_N Timing specifies a minimum hold of 5us
> +       usleep_range(5, 10);
> +       gpiod_set_value_cansleep(priv->reset_gpio, 0);
> +}
> +
>   static int lan865x_probe(struct spi_device *spi)
>   {
>          struct net_device *netdev;
> @@ -297,6 +317,14 @@ static int lan865x_probe(struct spi_device *spi)
>          priv->netdev = netdev;
>          priv->spi = spi;
>          spi_set_drvdata(spi, priv);
> +       if (lan865x_probe_reset_gpio(priv)) {
> +               dev_err(&spi->dev, "failed to probe reset pin");
> +               ret = -ENODEV;
> +               goto free_netdev;
> +       }
> +
> +       if (priv->reset_gpio)
> +               lan865x_hw_reset(priv);
>          INIT_WORK(&priv->multicast_work, lan865x_multicast_work_handler);
> 
>          priv->tc6 = oa_tc6_init(spi, netdev);
> --
> 2.43.0
> 
> 


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
  2024-04-28 21:16 ` [PATCH net-next v4 13/12] net: lan865x: optional hardware reset Ramón Nordin Rodriguez
  2024-04-28 23:17   ` Andrew Lunn
  2024-04-29  6:09   ` Parthiban.Veerasooran
@ 2024-04-29  6:09   ` Krzysztof Kozlowski
  2024-04-29 10:44     ` Ramón Nordin Rodriguez
  2 siblings, 1 reply; 96+ messages in thread
From: Krzysztof Kozlowski @ 2024-04-29  6:09 UTC (permalink / raw)
  To: Ramón Nordin Rodriguez, Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

On 28/04/2024 23:16, Ramón Nordin Rodriguez wrote:
> From c65e42982684d5fd8b2294eb6acf755aa0fcab83 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Ram=C3=B3n=20Nordin=20Rodriguez?=
>  <ramon.nordin.rodriguez@ferroamp.se>
> Date: Sun, 28 Apr 2024 22:25:12 +0200
> Subject: [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
> 
> This commit optionally enables a hardware reset of the lan8650/1
> mac-phy. These chips have a software reset that is discourage from use
> in the manual since it only resets the internal phy.
> 
> Signed-off-by: Ramón Nordin Rodriguez <ramon.nordin.rodriguez@ferroamp.se>
> ---
>  .../bindings/net/microchip,lan865x.yaml       |  4 +++
>  .../net/ethernet/microchip/lan865x/lan865x.c  | 28 +++++++++++++++++++

Please run scripts/checkpatch.pl and fix reported warnings. Then please
run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
Some warnings can be ignored, especially from --strict run, but the code
here looks like it needs a fix. Feel free to get in touch if the warning
is not clear.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 09/12] net: ethernet: oa_tc6: implement receive path to receive rx ethernet frames
  2024-04-26 18:13       ` Andrew Lunn
@ 2024-04-29  6:13         ` Parthiban.Veerasooran
  0 siblings, 0 replies; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-29  6:13 UTC (permalink / raw)
  To: andrew
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Andrew,

On 26/04/24 11:43 pm, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Fri, Apr 26, 2024 at 01:45:20PM +0000, Parthiban.Veerasooran@microchip.com wrote:
>> Hi Andrew,
>>
>> On 24/04/24 5:38 am, Andrew Lunn wrote:
>>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>>>
>>>> +static int oa_tc6_allocate_rx_skb(struct oa_tc6 *tc6)
>>>> +{
>>>> +     tc6->rx_skb = netdev_alloc_skb(tc6->netdev, tc6->netdev->mtu + ETH_HLEN +
>>>> +                                    ETH_FCS_LEN + NET_IP_ALIGN);
>>>> +     if (!tc6->rx_skb) {
>>>> +             tc6->netdev->stats.rx_dropped++;
>>>> +             return -ENOMEM;
>>>> +     }
>>>> +     skb_reserve(tc6->rx_skb, NET_IP_ALIGN);
>>>
>>> I think you can use netdev_alloc_skb_ip_align() here.
>> Ah OK, then do you mean we can rewrite the function
>> oa_tc6_allocate_rx_skb() as below?
>>
>> static int oa_tc6_allocate_rx_skb(struct oa_tc6 *tc6)
>> {
>>        tc6->rx_skb = netdev_alloc_skb_ip_align(tc6->netdev, tc6->netdev->mtu +
>> ETH_HLEN + ETH_FCS_LEN);
>>        if (tc6->rx_skb)
>>                return 0;
>>
>>        tc6->netdev->stats.rx_dropped++;
>>        return -ENOMEM;
>> }
> 
> Looks about right. But i did say 'I think', meaning i'm not too sure
> about this.
> 
> I generally don't review code actually moving packets around. It is
> what developers focus on, test heavily, and so is generally O.K. It is
> the code around the edges which often needs improvements prompted by
> review, ethtool, PHY handling, statistics.
You are right. But I tested implementing your proposal with iperf3 and 
it works as expected. So will keep this implementation in the next version.

Best regards,
Parthiban V
> 
>          Andrew


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-26 18:14       ` Andrew Lunn
@ 2024-04-29  6:13         ` Parthiban.Veerasooran
  0 siblings, 0 replies; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-29  6:13 UTC (permalink / raw)
  To: andrew
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Andrew,

On 26/04/24 11:44 pm, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
>> OK, I will implement this helper function as oa_tc6_enable_zarfe() in
>> the oa_tc6.c. Also do you want me to move this helper function
>> implementation to a new patch?
> 
> Yes please.
OK. Thanks.

Best regards,
Parthiban V
> 
>      Andrew


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 09/12] net: ethernet: oa_tc6: implement receive path to receive rx ethernet frames
  2024-04-27 20:02   ` Ramón Nordin Rodriguez
@ 2024-04-29  8:32     ` Parthiban.Veerasooran
  2024-04-29 10:45       ` Ramón Nordin Rodriguez
  0 siblings, 1 reply; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-29  8:32 UTC (permalink / raw)
  To: ramon.nordin.rodriguez
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Ramon,

On 28/04/24 1:32 am, Ramón Nordin Rodriguez wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> Could xfer.rx_buf for the data path point to the currently allocacted socket buff
>          struct spi_transfer xfer = { 0 };
>          struct spi_message msg;
> 
>          if (header_type == OA_TC6_DATA_HEADER) {
>                  xfer.tx_buf = tc6->spi_data_tx_buf;
>                  xfer.rx_buf = tc6->spi_data_rx_buf;
>          } else {
>                  xfer.tx_buf = tc6->spi_ctrl_tx_buf;
>                  xfer.rx_buf = tc6->spi_ctrl_rx_buf;
>          }
>          xfer.len = length;
> 
> To avoid an additional copy here?
I think, this can be done later as part of optimization/improvements. 
Let's keep it simple and optimize it later.

Best regards,
Parthiban V
> 
>> +static void oa_tc6_update_rx_skb(struct oa_tc6 *tc6, u8 *payload, u8 length)
>> +{
>> +     memcpy(skb_put(tc6->rx_skb, length), payload, length);
>> +}
>>
> 
> R
> 


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-27 19:57     ` Conor Dooley
  2024-04-27 20:13       ` Ramón Nordin Rodriguez
@ 2024-04-29  9:47       ` Parthiban.Veerasooran
  2024-04-29 12:09         ` Andrew Lunn
  1 sibling, 1 reply; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-29  9:47 UTC (permalink / raw)
  To: conor, ramon.nordin.rodriguez, andrew
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi All,

On 28/04/24 1:27 am, Conor Dooley wrote:
> On Sat, Apr 27, 2024 at 09:19:34PM +0200, Ramón Nordin Rodriguez wrote:
>> Hi,
>>
>> For me the mac driver fails to probe with the following log
>> [    0.123325] SPI driver lan865x has no spi_device_id for microchip,lan8651
>>
>> With this change the driver probes
>>
>> diff --git a/drivers/net/ethernet/microchip/lan865x/lan865x.c b/drivers/net/ethernet/microchip/lan865x/lan865x.c
>> index 9abefa8b9d9f..72a663f14f50 100644
>> --- a/drivers/net/ethernet/microchip/lan865x/lan865x.c
>> +++ b/drivers/net/ethernet/microchip/lan865x/lan865x.c
>> @@ -364,7 +364,7 @@ static void lan865x_remove(struct spi_device *spi)
>>   }
>>
>>   static const struct of_device_id lan865x_dt_ids[] = {
>> -       { .compatible = "microchip,lan8651", "microchip,lan8650" },
> Huh, that's very strange. I don't see a single instance in the tree of a
> of_device_id struct like this with two compatibles like this (at least
> with a search of `rg "\.compatible.*\", \"" drivers/`.
> 
> Given the fallbacks in the binding, only "microchip,lan8650" actually
> needs to be here.
> 
>> +       { .compatible = "microchip,lan865x", "microchip,lan8650" },
>>          { /* Sentinel */ }
>>   };
>>   MODULE_DEVICE_TABLE(of, lan865x_dt_ids);
>>
>> Along with compatible = "microchip,lan865x" in the dts
> Just to be clear, the compatible w/ an x is unacceptable due to the
> wildcard and the binding should stay as-is. Whatever probing bugs
> the code has need to be resolved instead 🙂
> 
Looks like, the below changes needed to work correctly,

lan865x.c:
- compatible string to be changed like below as it is a fallback for all 
variants,
	.compatible = "microchip,lan8650"
- DRV_NAME to be changed like below,
	#define DRV_NAME                        "lan8650"

microchip,lan865x.example.dts for lan8650:
- compatible string to be changed like below,
	.compatible = "microchip,lan8650";
	OR
microchip,lan865x.example.dts for lan8651:
- compatible string to be changed like below,
	compatible = "microchip,lan8651", "microchip,lan8650";

I tested with the above changes and there was no issues observed. Any 
comments on this? Otherwise we can stick with these changes for the next 
version.

Best regards,
Parthiban V

> Thanks,
> Conor.


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
  2024-04-29  6:09   ` Parthiban.Veerasooran
@ 2024-04-29 10:38     ` Ramón Nordin Rodriguez
  2024-04-29 12:19       ` Andrew Lunn
  0 siblings, 1 reply; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-29 10:38 UTC (permalink / raw)
  To: Parthiban.Veerasooran
  Cc: andrew, davem, edumazet, kuba, pabeni, horms, saeedm,
	anthony.l.nguyen, netdev, linux-kernel, corbet, linux-doc,
	robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	Horatiu.Vultur, ruanjinjie, Steen.Hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> > This commit optionally enables a hardware reset of the lan8650/1
> > mac-phy. These chips have a software reset that is discourage from use
> > in the manual since it only resets the internal phy.
> The software reset done by the current driver is not only resetting the 
> internal PHY, it resets the entire MAC-PHY including the integrated PHY.
> The reset bit of the Clause 22 basic control register only will reset 
> the internal PHY alone. But oa_tc6_sw_reset_macphy() function is writing 
> software reset bit in the Reset Control and Status register which resets 
> the entire MAC-PHY including the internal PHY.

All right, I did not dig deep enough obviously.

> The above note is given in the lan8650 datasheet to let the user to know 
> that clause 22 software reset will reset only internal PHY but I don't 
> think they mean it for the MAC-PHY software reset done from Reset 
> Control and Status register.

Could still be relevant to implement the .soft_reset with -EOPNOTSUPP as
Andrew has suggested in the phy driver.

> 
> So in my opinion, I don't see the need of external pin reset as the 
> existing oa_tc6_sw_reset_macphy() function does the software reset of 
> the entire MAC-PHY.

I agree with your assesment that this invalidates the problem I was
aiming at solving.

Additionally I figured out why my setup did not work without the HW
reset, I had missed a pull resistor in the schematic that held the IC in
reset.

To me it seems more feature complete to have a driver option for the
physical capabilities of the chip, but if it doesn't actually solve a
problem it might just be bloat.

> 
> Still if you see a need to have this external pin reset as an optional 
> function then it may be needed for all the vendor specific MAC drivers. 
> In that case, reset-gpios parameter value alone can be taken from the 
> chip specific device tree and the remaining code for operating the reset 
> gpio can be moved to oa_tc6.c and the function name can be 
> oa_tc6_hw_reset_macphy().
> 

If the consensus is to keep a HW reset I do like this suggestion.

I won't push for this to be included, if it is, I'm happy to address the
feedback of patch 13.

R

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
  2024-04-28 23:17   ` Andrew Lunn
@ 2024-04-29 10:42     ` Ramón Nordin Rodriguez
  0 siblings, 0 replies; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-29 10:42 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> You sent this patch in an odd way. We don't normally see headers like
> this. I've been using b4 recently for patch management:

Sorry about that, I appreciate the suggestion!

You left good comments on the implementation side as well, I'll wait
with addressing these. Parthibans feedback does invalidate the core of
the problem I set out to solve with this patch.

If the patch is not dropped I'll ofc address these points!

R

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
  2024-04-29  6:09   ` Krzysztof Kozlowski
@ 2024-04-29 10:44     ` Ramón Nordin Rodriguez
  0 siblings, 0 replies; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-29 10:44 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, andrew, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> Please run scripts/checkpatch.pl and fix reported warnings. Then please
> run `scripts/checkpatch.pl --strict` and (probably) fix more warnings.
> Some warnings can be ignored, especially from --strict run, but the code
> here looks like it needs a fix. Feel free to get in touch if the warning
> is not clear.
> 

Very much appreciated! I'll hold off on any further submissions for this
patch until it's clear that it's desriable to include.

R

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 09/12] net: ethernet: oa_tc6: implement receive path to receive rx ethernet frames
  2024-04-29  8:32     ` Parthiban.Veerasooran
@ 2024-04-29 10:45       ` Ramón Nordin Rodriguez
  0 siblings, 0 replies; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-29 10:45 UTC (permalink / raw)
  To: Parthiban.Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

> > To avoid an additional copy here?
> I think, this can be done later as part of optimization/improvements. 
> Let's keep it simple and optimize it later.

Sound good to me

R

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 01/12] Documentation: networking: add OPEN Alliance 10BASE-T1x MAC-PHY serial interface
  2024-04-28  9:33   ` Bagas Sanjaya
@ 2024-04-29 11:31     ` Parthiban.Veerasooran
  0 siblings, 0 replies; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-29 11:31 UTC (permalink / raw)
  To: bagasdotme
  Cc: UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler, davem,
	edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen, netdev,
	linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean

Hi,

On 28/04/24 3:03 pm, Bagas Sanjaya wrote:
> On Thu, Apr 18, 2024 at 06:26:37PM +0530, Parthiban Veerasooran wrote:
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 04e5f7c20e30..79fa7abb4ec9 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -16400,6 +16400,12 @@ L:	linux-rdma@vger.kernel.org
>>   S:	Supported
>>   F:	drivers/infiniband/ulp/opa_vnic
>>   
>> +OPEN ALLIANCE 10BASE-T1S MACPHY SERIAL INTERFACE FRAMEWORK
>> +M:	Parthiban Veerasooran<parthiban.veerasooran@microchip.com>
>> +L:	netdev@vger.kernel.org
>> +S:	Maintained
>> +F:	Documentation/networking/oa-tc6-framework.rst
>> +
>>   OPEN FIRMWARE AND FLATTENED DEVICE TREE
>>   M:	Rob Herring<robh+dt@kernel.org>
>>   M:	Frank Rowand<frowand.list@gmail.com>
> I can't apply this series on top of current net-next due to MAINTAINERS diff
> above (on context line 16400 I have Omnivision entries). Care to reroll?
> (Hint: also specify --base= to git-send-email(1) so that I and other
> reviewers know where to apply this series.)
OK. Will add the base commit in the next version.

It is,

base-commit: b307e25d4e6d341ce5af8682d5913c70655d1d36

Best regards,
Parthiban V
> 
> Confused...
> 
> -- An old man doll... just what I always wanted! - Clara


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-29  9:47       ` Parthiban.Veerasooran
@ 2024-04-29 12:09         ` Andrew Lunn
  2024-04-30 13:30           ` Parthiban.Veerasooran
  0 siblings, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-29 12:09 UTC (permalink / raw)
  To: Parthiban.Veerasooran
  Cc: conor, ramon.nordin.rodriguez, davem, edumazet, kuba, pabeni,
	horms, saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	Horatiu.Vultur, ruanjinjie, Steen.Hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> Looks like, the below changes needed to work correctly,
> 
> lan865x.c:
> - compatible string to be changed like below as it is a fallback for all 
> variants,
> 	.compatible = "microchip,lan8650"
> - DRV_NAME to be changed like below,
> 	#define DRV_NAME                        "lan8650"
> 
> microchip,lan865x.example.dts for lan8650:
> - compatible string to be changed like below,
> 	.compatible = "microchip,lan8650";
> 	OR
> microchip,lan865x.example.dts for lan8651:
> - compatible string to be changed like below,
> 	compatible = "microchip,lan8651", "microchip,lan8650";
> 
> I tested with the above changes and there was no issues observed. Any 
> comments on this? Otherwise we can stick with these changes for the next 
> version.

As Conor said, this is probably relying on the fallback
mechanism. Please look at other SPI devices, e.g. hwmon, and see how
they probe for multiple different devices.

	Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
  2024-04-29 10:38     ` Ramón Nordin Rodriguez
@ 2024-04-29 12:19       ` Andrew Lunn
  2024-04-30  8:04         ` Ramón Nordin Rodriguez
  2024-04-30 13:30         ` Parthiban.Veerasooran
  0 siblings, 2 replies; 96+ messages in thread
From: Andrew Lunn @ 2024-04-29 12:19 UTC (permalink / raw)
  To: Ramón Nordin Rodriguez
  Cc: Parthiban.Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	Horatiu.Vultur, ruanjinjie, Steen.Hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> Additionally I figured out why my setup did not work without the HW
> reset, I had missed a pull resistor in the schematic that held the IC in
> reset.

Having a reset controlled by software is a pretty common
design. Something needs to ensure the device is out of reset. It could
be the bootloader, but i don't particularly like that, hiding away
critical things where they are hard to see. So i think having it in
the Linux driver is better.

There is an open question of does the driver need to actually reset
the device, or is it sufficient to ensure it is out of reset? The
wording of the standard suggests a hardware reset cycle is probably
not required, but why did Microchip provide a reset pin?

	Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 01/12] Documentation: networking: add OPEN Alliance 10BASE-T1x MAC-PHY serial interface
  2024-04-18 12:56 ` [PATCH net-next v4 01/12] Documentation: networking: add OPEN Alliance 10BASE-T1x MAC-PHY serial interface Parthiban Veerasooran
  2024-04-28  9:33   ` Bagas Sanjaya
@ 2024-04-29 16:17   ` Simon Horman
  2024-04-30 11:30     ` Parthiban.Veerasooran
  1 sibling, 1 reply; 96+ messages in thread
From: Simon Horman @ 2024-04-29 16:17 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, saeedm, anthony.l.nguyen, netdev,
	linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

On Thu, Apr 18, 2024 at 06:26:37PM +0530, Parthiban Veerasooran wrote:
> The IEEE 802.3cg project defines two 10 Mbit/s PHYs operating over a
> single pair of conductors. The 10BASE-T1L (Clause 146) is a long reach
> PHY supporting full duplex point-to-point operation over 1 km of single
> balanced pair of conductors. The 10BASE-T1S (Clause 147) is a short reach
> PHY supporting full / half duplex point-to-point operation over 15 m of
> single balanced pair of conductors, or half duplex multidrop bus
> operation over 25 m of single balanced pair of conductors.
> 
> Furthermore, the IEEE 802.3cg project defines the new Physical Layer
> Collision Avoidance (PLCA) Reconciliation Sublayer (Clause 148) meant to
> provide improved determinism to the CSMA/CD media access method. PLCA
> works in conjunction with the 10BASE-T1S PHY operating in multidrop mode.
> 
> The aforementioned PHYs are intended to cover the low-speed / low-cost
> applications in industrial and automotive environment. The large number
> of pins (16) required by the MII interface, which is specified by the
> IEEE 802.3 in Clause 22, is one of the major cost factors that need to be
> addressed to fulfil this objective.
> 
> The MAC-PHY solution integrates an IEEE Clause 4 MAC and a 10BASE-T1x PHY
> exposing a low pin count Serial Peripheral Interface (SPI) to the host
> microcontroller. This also enables the addition of Ethernet functionality
> to existing low-end microcontrollers which do not integrate a MAC
> controller.
> 
> Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>

Hi Parthiban,

Some minor feedback from my side.

> ---
>  Documentation/networking/oa-tc6-framework.rst | 491 ++++++++++++++++++

Please add oa-tc6-framework to 

Flagged by: make SPHINXDIRS="networking" htmldocs

>  MAINTAINERS                                   |   6 +
>  2 files changed, 497 insertions(+)
>  create mode 100644 Documentation/networking/oa-tc6-framework.rst
> 
> diff --git a/Documentation/networking/oa-tc6-framework.rst b/Documentation/networking/oa-tc6-framework.rst

...

> +Device drivers API
> +==================
> +
> +The include/linux/oa_tc6.h defines the following functions:
> +
> +.. c:function:: struct oa_tc6 *oa_tc6_init(struct spi_device *spi,
> +                                           struct net_device *netdev)

I think that you need to use a '\' to escape newlines
for a for a multi-line c:function.

e.g.
.. c:function:: struct oa_tc6 *oa_tc6_init(struct spi_device *spi, \
                                           struct net_device *netdev)

Link: https://www.sphinx-doc.org/en/master/usage/domains/index.html

Flagged by make SPHINXDIRS="networking" htmldocs
when using Sphinx 7.2.6

> +
> +Initialize OA TC6 lib.
> +
> +.. c:function:: void oa_tc6_exit(struct oa_tc6 *tc6)
> +
> +Free allocated OA TC6 lib.
> +
> +.. c:function:: int oa_tc6_write_register(struct oa_tc6 *tc6, u32 address,
> +                                          u32 value)
> +
> +Write a single register in the MAC-PHY.
> +
> +.. c:function:: int oa_tc6_write_registers(struct oa_tc6 *tc6, u32 address,
> +                                           u32 value[], u8 length)
> +
> +Writing multiple consecutive registers starting from @address in the MAC-PHY.
> +Maximum of 128 consecutive registers can be written starting at @address.
> +
> +.. c:function:: int oa_tc6_read_register(struct oa_tc6 *tc6, u32 address,
> +                                         u32 *value)
> +
> +Read a single register in the MAC-PHY.
> +
> +.. c:function:: int oa_tc6_read_registers(struct oa_tc6 *tc6, u32 address,
> +                                          u32 value[], u8 length)
> +
> +Reading multiple consecutive registers starting from @address in the MAC-PHY.
> +Maximum of 128 consecutive registers can be read starting at @address.
> +
> +.. c:function:: netdev_tx_t oa_tc6_start_xmit(struct oa_tc6 *tc6,
> +                                              struct sk_buff *skb);
> +
> +The transmit Ethernet frame in the skb is or going to be transmitted through
> +the MAC-PHY.

...

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 02/12] net: ethernet: oa_tc6: implement register write operation
  2024-04-18 12:56 ` [PATCH net-next v4 02/12] net: ethernet: oa_tc6: implement register write operation Parthiban Veerasooran
  2024-04-22 23:48   ` Andrew Lunn
  2024-04-23 23:14   ` Andrew Lunn
@ 2024-04-29 16:36   ` Simon Horman
  2024-04-30  8:14     ` Parthiban.Veerasooran
  2 siblings, 1 reply; 96+ messages in thread
From: Simon Horman @ 2024-04-29 16:36 UTC (permalink / raw)
  To: Parthiban Veerasooran
  Cc: davem, edumazet, kuba, pabeni, saeedm, anthony.l.nguyen, netdev,
	linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, horatiu.vultur,
	ruanjinjie, steen.hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

On Thu, Apr 18, 2024 at 06:26:38PM +0530, Parthiban Veerasooran wrote:
> Implement register write operation according to the control communication
> specified in the OPEN Alliance 10BASE-T1x MACPHY Serial Interface
> document. Control write commands are used by the SPI host to write
> registers within the MAC-PHY. Each control write commands are composed of
> a 32 bits control command header followed by register write data.
> 
> The MAC-PHY ignores the final 32 bits of data from the SPI host at the
> end of the control write command. The write command and data is also
> echoed from the MAC-PHY back to the SPI host to enable the SPI host to
> identify which register write failed in the case of any bus errors.
> Control write commands can write either a single register or multiple
> consecutive registers. When multiple consecutive registers are written,
> the address is automatically post-incremented by the MAC-PHY. Writing to
> any unimplemented or undefined registers shall be ignored and yield no
> effect.
> 
> Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>

...

> diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c

...

> +/**
> + * oa_tc6_write_registers - function for writing multiple consecutive registers.
> + * @tc6: oa_tc6 struct.
> + * @address: address of the first register to be written in the MAC-PHY.
> + * @value: values to be written from the starting register address @address.
> + * @length: number of consecutive registers to be written from @address.
> + *
> + * Maximum of 128 consecutive registers can be written starting at @address.
> + *
> + * Returns 0 on success otherwise failed.

Nit: I think you need a ':' after "Returns" (or "Return")
     in order for kernel-doc -Wall to recognise this as a return section.

Likewise elsewhere in this patch(set).

> + */
> +int oa_tc6_write_registers(struct oa_tc6 *tc6, u32 address, u32 value[],
> +			   u8 length)
> +{

...

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
  2024-04-29 12:19       ` Andrew Lunn
@ 2024-04-30  8:04         ` Ramón Nordin Rodriguez
  2024-04-30 13:30         ` Parthiban.Veerasooran
  1 sibling, 0 replies; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-04-30  8:04 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Parthiban.Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	Horatiu.Vultur, ruanjinjie, Steen.Hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> > Additionally I figured out why my setup did not work without the HW
> > reset, I had missed a pull resistor in the schematic that held the IC in
> > reset.
> 
> Having a reset controlled by software is a pretty common
> design. Something needs to ensure the device is out of reset. It could
> be the bootloader, but i don't particularly like that, hiding away
> critical things where they are hard to see. So i think having it in
> the Linux driver is better.

Wholeheartedly agree, beyond the basics of bringing up ram, cores etc.
it becomes really weird when/if the bootloaders behaviour defines kernel
functionality.

In this case the oa_tc6 module does a soft reset and waits for a status
reg to signal ready.

What seems to be missing here is that the chip signals ready/out of
reset by asserting the irq pin and setting the RESETC bit of ther OA_STATUS0
reg (which is defined behaviour in the OA spec as I understand it).

Neither the lan865x_probe or oa_tc6_init checks for the initial
condition, but I'm guessing it's a fair assumption that the chip is out
of reset by the point when the oa_tc6_sw_reset_machphy function is
invoked.

Far as I can tell no timing information is given in the datasheet.

Might be unecessary but the setup could be made more explicit/clear
with a func such as:

int oa_tc6_out_of_reset(struct oa_tc*);

Which should be invoked before any reg access/modification code in
either oa_tc6 or the mac driver.
If this fails my (opinionated) preferred style would be to do one hw
reset, recheck, and on subsequent failure bail.

Such a change would probably lead to the HW reset being invoked on
reboots (if there is enough capacitors to keep the IC powered) and
definetly as a result of kexec calls.

> 
> There is an open question of does the driver need to actually reset
> the device, or is it sufficient to ensure it is out of reset? The
> wording of the standard suggests a hardware reset cycle is probably
> not required, but why did Microchip provide a reset pin?
> 

This has me tripped up. The lan8650/1 has a configuration write
protection mechanism with an unlock sequence, described in "4.6.3
Configuration Protection" of the datasheet.
The unlocking can be bypassed/simplified with a HW reset, still does
not seem like an explanation for the functionality.

I can't define one scenario where the HW reset is definetly necessary,
but will probably do it anyways on the systems I work on.

Ramón

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 02/12] net: ethernet: oa_tc6: implement register write operation
  2024-04-29 16:36   ` Simon Horman
@ 2024-04-30  8:14     ` Parthiban.Veerasooran
  0 siblings, 0 replies; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-30  8:14 UTC (permalink / raw)
  To: horms
  Cc: davem, edumazet, kuba, pabeni, saeedm, anthony.l.nguyen, netdev,
	linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Simon,

On 29/04/24 10:06 pm, Simon Horman wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Thu, Apr 18, 2024 at 06:26:38PM +0530, Parthiban Veerasooran wrote:
>> Implement register write operation according to the control communication
>> specified in the OPEN Alliance 10BASE-T1x MACPHY Serial Interface
>> document. Control write commands are used by the SPI host to write
>> registers within the MAC-PHY. Each control write commands are composed of
>> a 32 bits control command header followed by register write data.
>>
>> The MAC-PHY ignores the final 32 bits of data from the SPI host at the
>> end of the control write command. The write command and data is also
>> echoed from the MAC-PHY back to the SPI host to enable the SPI host to
>> identify which register write failed in the case of any bus errors.
>> Control write commands can write either a single register or multiple
>> consecutive registers. When multiple consecutive registers are written,
>> the address is automatically post-incremented by the MAC-PHY. Writing to
>> any unimplemented or undefined registers shall be ignored and yield no
>> effect.
>>
>> Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
> 
> ...
> 
>> diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
> 
> ...
> 
>> +/**
>> + * oa_tc6_write_registers - function for writing multiple consecutive registers.
>> + * @tc6: oa_tc6 struct.
>> + * @address: address of the first register to be written in the MAC-PHY.
>> + * @value: values to be written from the starting register address @address.
>> + * @length: number of consecutive registers to be written from @address.
>> + *
>> + * Maximum of 128 consecutive registers can be written starting at @address.
>> + *
>> + * Returns 0 on success otherwise failed.
> 
> Nit: I think you need a ':' after "Returns" (or "Return")
>       in order for kernel-doc -Wall to recognise this as a return section.
> 
> Likewise elsewhere in this patch(set).
OK. Thanks for the hint. Yes I noticed some warnings on this "Returns" 
area while running the below command,

./scripts/kernel-doc -Wall -v -none drivers/net/ethernet/oa_tc6.c

Will fix it in the next version.

Best regards,
Parthiban V
> 
>> + */
>> +int oa_tc6_write_registers(struct oa_tc6 *tc6, u32 address, u32 value[],
>> +                        u8 length)
>> +{
> 
> ...


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 01/12] Documentation: networking: add OPEN Alliance 10BASE-T1x MAC-PHY serial interface
  2024-04-29 16:17   ` Simon Horman
@ 2024-04-30 11:30     ` Parthiban.Veerasooran
  0 siblings, 0 replies; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-30 11:30 UTC (permalink / raw)
  To: horms
  Cc: davem, edumazet, kuba, pabeni, saeedm, anthony.l.nguyen, netdev,
	linux-kernel, andrew, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Simon,

On 29/04/24 9:47 pm, Simon Horman wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On Thu, Apr 18, 2024 at 06:26:37PM +0530, Parthiban Veerasooran wrote:
>> The IEEE 802.3cg project defines two 10 Mbit/s PHYs operating over a
>> single pair of conductors. The 10BASE-T1L (Clause 146) is a long reach
>> PHY supporting full duplex point-to-point operation over 1 km of single
>> balanced pair of conductors. The 10BASE-T1S (Clause 147) is a short reach
>> PHY supporting full / half duplex point-to-point operation over 15 m of
>> single balanced pair of conductors, or half duplex multidrop bus
>> operation over 25 m of single balanced pair of conductors.
>>
>> Furthermore, the IEEE 802.3cg project defines the new Physical Layer
>> Collision Avoidance (PLCA) Reconciliation Sublayer (Clause 148) meant to
>> provide improved determinism to the CSMA/CD media access method. PLCA
>> works in conjunction with the 10BASE-T1S PHY operating in multidrop mode.
>>
>> The aforementioned PHYs are intended to cover the low-speed / low-cost
>> applications in industrial and automotive environment. The large number
>> of pins (16) required by the MII interface, which is specified by the
>> IEEE 802.3 in Clause 22, is one of the major cost factors that need to be
>> addressed to fulfil this objective.
>>
>> The MAC-PHY solution integrates an IEEE Clause 4 MAC and a 10BASE-T1x PHY
>> exposing a low pin count Serial Peripheral Interface (SPI) to the host
>> microcontroller. This also enables the addition of Ethernet functionality
>> to existing low-end microcontrollers which do not integrate a MAC
>> controller.
>>
>> Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
> 
> Hi Parthiban,
> 
> Some minor feedback from my side.
> 
>> ---
>>   Documentation/networking/oa-tc6-framework.rst | 491 ++++++++++++++++++
> 
> Please add oa-tc6-framework to
> 
> Flagged by: make SPHINXDIRS="networking" htmldocs
OK. Thanks for pointing this. Will correct it in the next version.
> 
>>   MAINTAINERS                                   |   6 +
>>   2 files changed, 497 insertions(+)
>>   create mode 100644 Documentation/networking/oa-tc6-framework.rst
>>
>> diff --git a/Documentation/networking/oa-tc6-framework.rst b/Documentation/networking/oa-tc6-framework.rst
> 
> ...
> 
>> +Device drivers API
>> +==================
>> +
>> +The include/linux/oa_tc6.h defines the following functions:
>> +
>> +.. c:function:: struct oa_tc6 *oa_tc6_init(struct spi_device *spi,
>> +                                           struct net_device *netdev)
> 
> I think that you need to use a '\' to escape newlines
> for a for a multi-line c:function.
> 
> e.g.
> .. c:function:: struct oa_tc6 *oa_tc6_init(struct spi_device *spi, \
>                                             struct net_device *netdev)
> 
> Link: https://www.sphinx-doc.org/en/master/usage/domains/index.html
> 
> Flagged by make SPHINXDIRS="networking" htmldocs
> when using Sphinx 7.2.6
Yes noted. Will correct it in the next version.

Best regards,
Parthiban V
> 
>> +
>> +Initialize OA TC6 lib.
>> +
>> +.. c:function:: void oa_tc6_exit(struct oa_tc6 *tc6)
>> +
>> +Free allocated OA TC6 lib.
>> +
>> +.. c:function:: int oa_tc6_write_register(struct oa_tc6 *tc6, u32 address,
>> +                                          u32 value)
>> +
>> +Write a single register in the MAC-PHY.
>> +
>> +.. c:function:: int oa_tc6_write_registers(struct oa_tc6 *tc6, u32 address,
>> +                                           u32 value[], u8 length)
>> +
>> +Writing multiple consecutive registers starting from @address in the MAC-PHY.
>> +Maximum of 128 consecutive registers can be written starting at @address.
>> +
>> +.. c:function:: int oa_tc6_read_register(struct oa_tc6 *tc6, u32 address,
>> +                                         u32 *value)
>> +
>> +Read a single register in the MAC-PHY.
>> +
>> +.. c:function:: int oa_tc6_read_registers(struct oa_tc6 *tc6, u32 address,
>> +                                          u32 value[], u8 length)
>> +
>> +Reading multiple consecutive registers starting from @address in the MAC-PHY.
>> +Maximum of 128 consecutive registers can be read starting at @address.
>> +
>> +.. c:function:: netdev_tx_t oa_tc6_start_xmit(struct oa_tc6 *tc6,
>> +                                              struct sk_buff *skb);
>> +
>> +The transmit Ethernet frame in the skb is or going to be transmitted through
>> +the MAC-PHY.
> 
> ...


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-29 12:09         ` Andrew Lunn
@ 2024-04-30 13:30           ` Parthiban.Veerasooran
  2024-04-30 16:55             ` Conor Dooley
  0 siblings, 1 reply; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-30 13:30 UTC (permalink / raw)
  To: andrew
  Cc: conor, ramon.nordin.rodriguez, davem, edumazet, kuba, pabeni,
	horms, saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	Horatiu.Vultur, ruanjinjie, Steen.Hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

Hi Andrew,

On 29/04/24 5:39 pm, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
>> Looks like, the below changes needed to work correctly,
>>
>> lan865x.c:
>> - compatible string to be changed like below as it is a fallback for all
>> variants,
>>        .compatible = "microchip,lan8650"
>> - DRV_NAME to be changed like below,
>>        #define DRV_NAME                        "lan8650"
>>
>> microchip,lan865x.example.dts for lan8650:
>> - compatible string to be changed like below,
>>        .compatible = "microchip,lan8650";
>>        OR
>> microchip,lan865x.example.dts for lan8651:
>> - compatible string to be changed like below,
>>        compatible = "microchip,lan8651", "microchip,lan8650";
>>
>> I tested with the above changes and there was no issues observed. Any
>> comments on this? Otherwise we can stick with these changes for the next
>> version.
> 
> As Conor said, this is probably relying on the fallback
> mechanism. Please look at other SPI devices, e.g. hwmon, and see how
> they probe for multiple different devices.
I just referred the below drivers for the spi devices handling along 
with the compatible,

https://elixir.bootlin.com/linux/latest/source/drivers/net/ethernet/davicom/dm9051.c#L1239

https://elixir.bootlin.com/linux/latest/source/drivers/net/ethernet/adi/adin1110.c#L1644

lan8650 - MAC-PHY chip
lan8651 - ETH Click-Mikroe with MAC-PHY chip

So, they are different in interface but not in functionality. There is 
no difference in the configuration. So let's consider lan8650 is the 
fallback option for lan8651.

By referring the above links, I have restructured the code like below to 
support with lan8651 fallback. Still there is no change in the existing 
device tree binding. This is the only change in lan865x.c.

static const struct spi_device_id spidev_spi_ids[] = {
         { .name = "lan8650" },
         {},
};

static const struct of_device_id lan865x_dt_ids[] = {
         { .compatible = "microchip,lan8650" },
         { /* Sentinel */ }
};
MODULE_DEVICE_TABLE(of, lan865x_dt_ids);

static struct spi_driver lan865x_driver = {
         .driver = {
                 .name = DRV_NAME,
                 .of_match_table = lan865x_dt_ids,
          },
         .probe = lan865x_probe,
         .remove = lan865x_remove,
         .id_table = spidev_spi_ids,
};

I also referred the below two links for the device tree binding and 
driver in case of fallback.

https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/net/smsc,lan9115.yaml#L18

https://elixir.bootlin.com/linux/latest/source/Documentation/devicetree/bindings/net/smsc,lan9115.yaml#L102

https://elixir.bootlin.com/linux/latest/source/drivers/net/ethernet/smsc/smsc911x.c#L2652

Best regards,
Parthiban V
> 
>          Andrew


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
  2024-04-29 12:19       ` Andrew Lunn
  2024-04-30  8:04         ` Ramón Nordin Rodriguez
@ 2024-04-30 13:30         ` Parthiban.Veerasooran
  2024-04-30 14:14           ` Andrew Lunn
  1 sibling, 1 reply; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-04-30 13:30 UTC (permalink / raw)
  To: andrew
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler, ramon.nordin.rodriguez

On 29/04/24 5:49 pm, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
>> Additionally I figured out why my setup did not work without the HW
>> reset, I had missed a pull resistor in the schematic that held the IC in
>> reset.
> 
> Having a reset controlled by software is a pretty common
> design. Something needs to ensure the device is out of reset. It could
> be the bootloader, but i don't particularly like that, hiding away
> critical things where they are hard to see. So i think having it in
> the Linux driver is better.
> 
> There is an open question of does the driver need to actually reset
> the device, or is it sufficient to ensure it is out of reset? The
> wording of the standard suggests a hardware reset cycle is probably
> not required, but why did Microchip provide a reset pin?
There are three resets mentioned,

1. Power ON reset - A Power-On Reset occurs when power is initially 
applied to the device. Once the reset completes, the IRQ_N pin will be 
asserted and the RESETC (Reset Completed) bit of the OA_STATUS0 Register 
will be set to 1, as specified by the Open Alliance. This indicates to 
the driver that the device has been reset and ready to configure. For a 
pre configured system this is enough to start the configuration.

2. Software reset - This reset can be done from software. In the driver, 
it is done as part of initialization. Actually it may not be needed if 
we are not going to reload the driver, as the Power ON reset does the 
same job for us. But if we compiled the driver as a loadable module and 
out of tree then it is needed for each time when we reload the driver 
without power reset.

3. Ext pin reset - A hardware reset will occur when the RESET_N pin is 
asserted. Once the RESET_N input is deasserted, the LAN8650/1 will 
restart operation. The device will indicate to the station's controller
that it has been reset and must be configured in the same way as if a 
Power-On Reset had occurred: the IRQ_N pin will be asserted and the 
RESETC (Reset Completed) bit of the OA_STATUS Register will be set to 1.

This is also basically does the same job but it may be useful when the 
chip gets into a situation where it can't perform SPI anymore to do a 
software reset. This may be needed in the initial phase testing. But 
once the development is completed and the chip is ready to use then 
there will not be any possibility to get into the above situation unless 
there is a permanent hardware failure where this reset also will not 
make any sense.

OPEN Alliance spec says the following in the section 8.2 Variables

reset
	This variable reflects the logical-OR of all reset sources of the 
MAC-PHY and is TRUE when any of the reset sources are asserted. Reset 
sources include power-on reset (POR), software reset (see Section 
9.2.4.2), and an external RESET pin (if implemented).

In the spec, external RESET pin is mentioned as "if implemented", in my 
understanding it is MAC-PHY vendors choice of implementing it where 
Microchip is implemented it. Using this reset, can be a application 
requirement/decision. It can be controlled from an external application 
where it is not needed SPI to operate.

Best regards,
Parthiban V
> 
>          Andrew


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
  2024-04-30 13:30         ` Parthiban.Veerasooran
@ 2024-04-30 14:14           ` Andrew Lunn
  2024-05-02 10:10             ` Parthiban.Veerasooran
  0 siblings, 1 reply; 96+ messages in thread
From: Andrew Lunn @ 2024-04-30 14:14 UTC (permalink / raw)
  To: Parthiban.Veerasooran
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler, ramon.nordin.rodriguez

> In the spec, external RESET pin is mentioned as "if implemented", in my 
> understanding it is MAC-PHY vendors choice of implementing it where 
> Microchip is implemented it. Using this reset, can be a application 
> requirement/decision. It can be controlled from an external application 
> where it is not needed SPI to operate.

Since it is optional, controlling the reset pin is clearly not
something for the TC6 core.

However, i doubt having an external application controlling the reset
is a good idea. You don't want to reset during operation. So to me,
this reset should be controlled by the driver. I tend to agree, that
actually performing a reset is optional, but i would expect the driver
to ensure the device is taken out of reset during probe, if the power
on default of the board is to hold it in reset.

   Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-30 13:30           ` Parthiban.Veerasooran
@ 2024-04-30 16:55             ` Conor Dooley
  2024-05-02  5:56               ` Parthiban.Veerasooran
  0 siblings, 1 reply; 96+ messages in thread
From: Conor Dooley @ 2024-04-30 16:55 UTC (permalink / raw)
  To: Parthiban.Veerasooran
  Cc: andrew, ramon.nordin.rodriguez, davem, edumazet, kuba, pabeni,
	horms, saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	Horatiu.Vultur, ruanjinjie, Steen.Hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

[-- Attachment #1: Type: text/plain, Size: 2929 bytes --]

On Tue, Apr 30, 2024 at 01:30:22PM +0000, Parthiban.Veerasooran@microchip.com wrote:
> Hi Andrew,
> 
> On 29/04/24 5:39 pm, Andrew Lunn wrote:
> > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> > 
> >> Looks like, the below changes needed to work correctly,
> >>
> >> lan865x.c:
> >> - compatible string to be changed like below as it is a fallback for all
> >> variants,
> >>        .compatible = "microchip,lan8650"
> >> - DRV_NAME to be changed like below,
> >>        #define DRV_NAME                        "lan8650"
> >>
> >> microchip,lan865x.example.dts for lan8650:
> >> - compatible string to be changed like below,
> >>        .compatible = "microchip,lan8650";
> >>        OR
> >> microchip,lan865x.example.dts for lan8651:
> >> - compatible string to be changed like below,
> >>        compatible = "microchip,lan8651", "microchip,lan8650";
> >>
> >> I tested with the above changes and there was no issues observed. Any
> >> comments on this? Otherwise we can stick with these changes for the next
> >> version.
> > 
> > As Conor said, this is probably relying on the fallback
> > mechanism. Please look at other SPI devices, e.g. hwmon, and see how
> > they probe for multiple different devices.
> I just referred the below drivers for the spi devices handling along 
> with the compatible,
> 
> https://elixir.bootlin.com/linux/latest/source/drivers/net/ethernet/davicom/dm9051.c#L1239
> 
> https://elixir.bootlin.com/linux/latest/source/drivers/net/ethernet/adi/adin1110.c#L1644
> 
> lan8650 - MAC-PHY chip
> lan8651 - ETH Click-Mikroe with MAC-PHY chip
> 
> So, they are different in interface but not in functionality. There is 
> no difference in the configuration. So let's consider lan8650 is the 
> fallback option for lan8651.
> 
> By referring the above links, I have restructured the code like below to 
> support with lan8651 fallback. Still there is no change in the existing 
> device tree binding. This is the only change in lan865x.c.
> 
> static const struct spi_device_id spidev_spi_ids[] = {
>          { .name = "lan8650" },
>          {},
> };
> 
> static const struct of_device_id lan865x_dt_ids[] = {
>          { .compatible = "microchip,lan8650" },
>          { /* Sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, lan865x_dt_ids);
> 
> static struct spi_driver lan865x_driver = {
>          .driver = {
>                  .name = DRV_NAME,
>                  .of_match_table = lan865x_dt_ids,
>           },
>          .probe = lan865x_probe,
>          .remove = lan865x_remove,
>          .id_table = spidev_spi_ids,
> };
> 
> I also referred the below two links for the device tree binding and 
> driver in case of fallback.

Did you also verify that the warning from the spi core is no longer
generated when using compatible = "microchip,lan8651", "microchip,lan8650"?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking
  2024-04-28 14:59         ` Andrew Lunn
  2024-04-28 22:04           ` Ramón Nordin Rodriguez
@ 2024-05-01 18:29           ` Ramón Nordin Rodriguez
  2024-05-01 19:58             ` Andrew Lunn
                               ` (2 more replies)
  1 sibling, 3 replies; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-05-01 18:29 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> > n  |  name     |  min  |  avg  |  max  |  rx dropped  |  samples
> > 1  |  no mod   |  827K |  846K |  891K |      945     |     5
> > 2  |  no log   |  711K |  726K |  744K |      562     |     5
> > 3  |  less irq |  815K |  833K |  846K |      N/A     |     5
> > 4  |  no irq   |  914K |  924K |  931K |      N/A     |     5
> > 5  |  simple   |  857K |  868K |  879K |      615     |     5
> 
> That is odd.
> 
> Side question: What CONFIG_HZ= do you have? 100, 250, 1000?  Try
> 1000. I've seen problems where the driver wants to sleep for a short
> time, but the CONFIG_HZ value limits how short a time it can actually
> sleep. It ends up sleeping much longer than it wants.
> 

I have been doing my best to abuse the link some more. In brief tweaking
CONFIG_HZ has some but limited effect. 
Saturating the link with the rx buffer interrupt enabled breaks the driver.
Saturating the link with the rx buffer interrupt disabled has poor
performance.

The following scenario has been tested. Both ends of the link run:
* server.py
* client.py

One end is an arm64 quad core running at 1.2GHz with the lan8650 macphy.
The other end is an amd 3950x running the lan8670 usb eval board.
Both systems should be fast enough that running python should not be a
limiting factor.

-- The test code --
server.py
#!/bin/env python3
import socket

def serve(sock: socket.socket):
    while True:
        client, addr = sock.accept()
        print(f'connection from: {addr}')
        while len(client.recv(2048)) > 0:
            pass
        print('client disconnected')
        client.close()

if __name__ == '__main__':
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind(('0.0.0.0', 4040))
    sock.listen(1)
    serve(sock)
    print("something went wrong")

client.py
#!/bin/env python3
import socket
import sys

if __name__ == '__main__':
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect((sys.argv[1], 4040))

    while True:
        sock.sendall(b'0'*2048)

-- test runs --
run 1 - all interrupts enabled
Time to failure:
1 min or less

Kernel output:
[   94.361312] sched: RT throttling activated

top output:
 PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 145 root     -51   0       0      0      0 R  95.5   0.0   1:11.22 oa-tc6-spi-thread

link stats:
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 32:c2:7e:22:93:99 brd ff:ff:ff:ff:ff:ff
    RX:  bytes packets errors dropped  missed   mcast
       3371902    7186      0      48       0       0
    RX errors:  length    crc   frame    fifo overrun
                     0      0       0       0       0
    TX:  bytes packets errors dropped carrier collsns
      10341438    8071      0       0       0       0
    TX errors: aborted   fifo  window heartbt transns
                     0      0       0       0       1
state:
Completly borked, can't ping in or out, bringing the interface down then up
has no effect.
There is no SPI clock and no interrupts generated by the mac-phy.
The worker thread seems to have live locked.

-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
run 2 - RX_BUFFER_OVERLOW interrupt disabled

state:
Runs just fine but the oa-tc6-spi-thread is consuming 10-20% cpu
Ping times have increased from 1-2ms to 8-35ms


-- additional notes --
When tweaking CONFIG_HZ I do get some changes in behaviour, the cpu
consumption stays stable at 20%+-2 with CONFIG_HZ=250, when increased to
CONFIG_HZ=1000 it jumps up and down between 10-20%.

I don't have access to a logic analyzer but my old oscilloscope is
almost reliable. I could confirm that the spi clock is indeed running at
the expected 25MHz, but I could observe some gaps of up to 320µs so
that's 8k spi cycles spent doing something else.
These gaps were observed on the SPI clock and the macphy interrupt was
active for the same ammount of time(though this was measured independently
and not on the same trigger).
I've been drinking way to much coffe, so soldering is not gonna happen
today (shaky hands), but if it helps I can solder wires to attach both
probes to confirm that the gap in the SPI clock happens at the same time
or not as the interrupt is active.

I'd be keen on hearing what Microchips plans to address. If tracking
down performance issues is a priority I'll probably not spend any time
on it, if not then I'll definetly dig into it more.

Let me know if anything is unclear or if I can help out with anything
specific.

R

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking
  2024-05-01 18:29           ` Ramón Nordin Rodriguez
@ 2024-05-01 19:58             ` Andrew Lunn
  2024-05-01 20:07             ` Andrew Lunn
  2024-05-02 10:10             ` Parthiban.Veerasooran
  2 siblings, 0 replies; 96+ messages in thread
From: Andrew Lunn @ 2024-05-01 19:58 UTC (permalink / raw)
  To: Ramón Nordin Rodriguez
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> Kernel output:
> [   94.361312] sched: RT throttling activated
> 
> top output:
>  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
>  145 root     -51   0       0      0      0 R  95.5   0.0   1:11.22 oa-tc6-spi-thread
> 
> link stats:
> 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
>     link/ether 32:c2:7e:22:93:99 brd ff:ff:ff:ff:ff:ff
>     RX:  bytes packets errors dropped  missed   mcast
>        3371902    7186      0      48       0       0
>     RX errors:  length    crc   frame    fifo overrun
>                      0      0       0       0       0
>     TX:  bytes packets errors dropped carrier collsns
>       10341438    8071      0       0       0       0
>     TX errors: aborted   fifo  window heartbt transns
>                      0      0       0       0       1
> state:
> Completly borked, can't ping in or out, bringing the interface down then up
> has no effect.

Completely borked is not good. 

> I'd be keen on hearing what Microchips plans to address. If tracking
> down performance issues is a priority I'll probably not spend any time
> on it, if not then I'll definetly dig into it more.

Borked ! = performance issue. This should be addressed. Lets see if
the python scripts are enough to be able to reproduce it.

We should not rule out differences in SPI drivers. So it might be you
need to debug this, if Microchip cannot reproduce it.

I would also suggest you enable the "kernel hacking" debug features
for finding deadlocks, bad spinlocks, stuck RT tasks etc. That might
give some clues.

	Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking
  2024-05-01 18:29           ` Ramón Nordin Rodriguez
  2024-05-01 19:58             ` Andrew Lunn
@ 2024-05-01 20:07             ` Andrew Lunn
  2024-05-02 10:10             ` Parthiban.Veerasooran
  2 siblings, 0 replies; 96+ messages in thread
From: Andrew Lunn @ 2024-05-01 20:07 UTC (permalink / raw)
  To: Ramón Nordin Rodriguez
  Cc: Parthiban Veerasooran, davem, edumazet, kuba, pabeni, horms,
	saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	horatiu.vultur, ruanjinjie, steen.hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> I don't have access to a logic analyzer but my old oscilloscope is
> almost reliable. I could confirm that the spi clock is indeed running at
> the expected 25MHz, but I could observe some gaps of up to 320µs so
> that's 8k spi cycles spent doing something else.
> These gaps were observed on the SPI clock and the macphy interrupt was
> active for the same ammount of time(though this was measured independently
> and not on the same trigger).
> I've been drinking way to much coffe, so soldering is not gonna happen
> today (shaky hands), but if it helps I can solder wires to attach both
> probes to confirm that the gap in the SPI clock happens at the same time
> or not as the interrupt is active.

What i expect you will see is that the interrupt line goes active. A
while later there is an SPI bus transfer to fetch the interrupt
status, and when that transfer completes the interrupt should go
inactive. But you will need your second channel to confirm this.

One question would be, is 320µs reasonable for an interrupt, and one
SPI transfer?

I would then expect a number of back to back transfers, each around 64
bytes in size, as it gets the received frame. The gaps between those
transfers will be interesting.

	Andrew

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY
  2024-04-30 16:55             ` Conor Dooley
@ 2024-05-02  5:56               ` Parthiban.Veerasooran
  0 siblings, 0 replies; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-05-02  5:56 UTC (permalink / raw)
  To: conor
  Cc: andrew, ramon.nordin.rodriguez, davem, edumazet, kuba, pabeni,
	horms, saeedm, anthony.l.nguyen, netdev, linux-kernel, corbet,
	linux-doc, robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	Horatiu.Vultur, ruanjinjie, Steen.Hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

Hi Conor,

On 30/04/24 10:25 pm, Conor Dooley wrote:
> On Tue, Apr 30, 2024 at 01:30:22PM +0000,Parthiban.Veerasooran@microchip.com  wrote:
>> Hi Andrew,
>>
>> On 29/04/24 5:39 pm, Andrew Lunn wrote:
>>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>>>
>>>> Looks like, the below changes needed to work correctly,
>>>>
>>>> lan865x.c:
>>>> - compatible string to be changed like below as it is a fallback for all
>>>> variants,
>>>>         .compatible = "microchip,lan8650"
>>>> - DRV_NAME to be changed like below,
>>>>         #define DRV_NAME                        "lan8650"
>>>>
>>>> microchip,lan865x.example.dts for lan8650:
>>>> - compatible string to be changed like below,
>>>>         .compatible = "microchip,lan8650";
>>>>         OR
>>>> microchip,lan865x.example.dts for lan8651:
>>>> - compatible string to be changed like below,
>>>>         compatible = "microchip,lan8651", "microchip,lan8650";
>>>>
>>>> I tested with the above changes and there was no issues observed. Any
>>>> comments on this? Otherwise we can stick with these changes for the next
>>>> version.
>>> As Conor said, this is probably relying on the fallback
>>> mechanism. Please look at other SPI devices, e.g. hwmon, and see how
>>> they probe for multiple different devices.
>> I just referred the below drivers for the spi devices handling along
>> with the compatible,
>>
>> https://elixir.bootlin.com/linux/latest/source/drivers/net/ethernet/davicom/dm9051.c#L1239
>>
>> https://elixir.bootlin.com/linux/latest/source/drivers/net/ethernet/adi/adin1110.c#L1644
>>
>> lan8650 - MAC-PHY chip
>> lan8651 - ETH Click-Mikroe with MAC-PHY chip
>>
>> So, they are different in interface but not in functionality. There is
>> no difference in the configuration. So let's consider lan8650 is the
>> fallback option for lan8651.
>>
>> By referring the above links, I have restructured the code like below to
>> support with lan8651 fallback. Still there is no change in the existing
>> device tree binding. This is the only change in lan865x.c.
>>
>> static const struct spi_device_id spidev_spi_ids[] = {
>>           { .name = "lan8650" },
>>           {},
>> };
>>
>> static const struct of_device_id lan865x_dt_ids[] = {
>>           { .compatible = "microchip,lan8650" },
>>           { /* Sentinel */ }
>> };
>> MODULE_DEVICE_TABLE(of, lan865x_dt_ids);
>>
>> static struct spi_driver lan865x_driver = {
>>           .driver = {
>>                   .name = DRV_NAME,
>>                   .of_match_table = lan865x_dt_ids,
>>            },
>>           .probe = lan865x_probe,
>>           .remove = lan865x_remove,
>>           .id_table = spidev_spi_ids,
>> };
>>
>> I also referred the below two links for the device tree binding and
>> driver in case of fallback.
> Did you also verify that the warning from the spi core is no longer
> generated when using compatible = "microchip,lan8651", "microchip,lan8650"?
Do you mean changing in the lan865x.c file? if yes then I got the 
warning "SPI driver lan865x has no spi_device_id for microchip,lan8651"

But after updating the lan865x.c like below, the warning disappeared.

static const struct spi_device_id spidev_spi_ids[] = {
         { .name = "lan8650" },
         { .name = "lan8651" },
         {},
};

Note: In both the above two cases compatible in the dts is
compatible = "microchip,lan8651", "microchip,lan8650";

Best regards,
Parthiban V

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking
  2024-05-01 18:29           ` Ramón Nordin Rodriguez
  2024-05-01 19:58             ` Andrew Lunn
  2024-05-01 20:07             ` Andrew Lunn
@ 2024-05-02 10:10             ` Parthiban.Veerasooran
  2024-05-02 10:19               ` Ramón Nordin Rodriguez
  2 siblings, 1 reply; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-05-02 10:10 UTC (permalink / raw)
  To: ramon.nordin.rodriguez, andrew
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler

Hi Ramon,

On 01/05/24 11:59 pm, Ramón Nordin Rodriguez wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
>>> n  |  name     |  min  |  avg  |  max  |  rx dropped  |  samples
>>> 1  |  no mod   |  827K |  846K |  891K |      945     |     5
>>> 2  |  no log   |  711K |  726K |  744K |      562     |     5
>>> 3  |  less irq |  815K |  833K |  846K |      N/A     |     5
>>> 4  |  no irq   |  914K |  924K |  931K |      N/A     |     5
>>> 5  |  simple   |  857K |  868K |  879K |      615     |     5
>>
>> That is odd.
>>
>> Side question: What CONFIG_HZ= do you have? 100, 250, 1000?  Try
>> 1000. I've seen problems where the driver wants to sleep for a short
>> time, but the CONFIG_HZ value limits how short a time it can actually
>> sleep. It ends up sleeping much longer than it wants.
>>
> 
> I have been doing my best to abuse the link some more. In brief tweaking
> CONFIG_HZ has some but limited effect.
> Saturating the link with the rx buffer interrupt enabled breaks the driver.
> Saturating the link with the rx buffer interrupt disabled has poor
> performance.
> 
> The following scenario has been tested. Both ends of the link run:
> * server.py
> * client.py
> 
> One end is an arm64 quad core running at 1.2GHz with the lan8650 macphy.
> The other end is an amd 3950x running the lan8670 usb eval board.
> Both systems should be fast enough that running python should not be a
> limiting factor.
> 
> -- The test code --
> server.py
> #!/bin/env python3
> import socket
> 
> def serve(sock: socket.socket):
>      while True:
>          client, addr = sock.accept()
>          print(f'connection from: {addr}')
>          while len(client.recv(2048)) > 0:
>              pass
>          print('client disconnected')
>          client.close()
> 
> if __name__ == '__main__':
>      sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>      sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
>      sock.bind(('0.0.0.0', 4040))
>      sock.listen(1)
>      serve(sock)
>      print("something went wrong")
> 
> client.py
> #!/bin/env python3
> import socket
> import sys
> 
> if __name__ == '__main__':
>      sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>      sock.connect((sys.argv[1], 4040))
> 
>      while True:
>          sock.sendall(b'0'*2048)
> 
> -- test runs --
> run 1 - all interrupts enabled
> Time to failure:
> 1 min or less
> 
> Kernel output:
> [   94.361312] sched: RT throttling activated
> 
> top output:
>   PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
>   145 root     -51   0       0      0      0 R  95.5   0.0   1:11.22 oa-tc6-spi-thread
> 
> link stats:
> 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
>      link/ether 32:c2:7e:22:93:99 brd ff:ff:ff:ff:ff:ff
>      RX:  bytes packets errors dropped  missed   mcast
>         3371902    7186      0      48       0       0
>      RX errors:  length    crc   frame    fifo overrun
>                       0      0       0       0       0
>      TX:  bytes packets errors dropped carrier collsns
>        10341438    8071      0       0       0       0
>      TX errors: aborted   fifo  window heartbt transns
>                       0      0       0       0       1
> state:
> Completly borked, can't ping in or out, bringing the interface down then up
> has no effect.
> There is no SPI clock and no interrupts generated by the mac-phy.
> The worker thread seems to have live locked.
> 
> -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
> run 2 - RX_BUFFER_OVERLOW interrupt disabled
> 
> state:
> Runs just fine but the oa-tc6-spi-thread is consuming 10-20% cpu
> Ping times have increased from 1-2ms to 8-35ms
> 
> 
> -- additional notes --
> When tweaking CONFIG_HZ I do get some changes in behaviour, the cpu
> consumption stays stable at 20%+-2 with CONFIG_HZ=250, when increased to
> CONFIG_HZ=1000 it jumps up and down between 10-20%.
> 
> I don't have access to a logic analyzer but my old oscilloscope is
> almost reliable. I could confirm that the spi clock is indeed running at
> the expected 25MHz, but I could observe some gaps of up to 320µs so
> that's 8k spi cycles spent doing something else.
> These gaps were observed on the SPI clock and the macphy interrupt was
> active for the same ammount of time(though this was measured independently
> and not on the same trigger).
> I've been drinking way to much coffe, so soldering is not gonna happen
> today (shaky hands), but if it helps I can solder wires to attach both
> probes to confirm that the gap in the SPI clock happens at the same time
> or not as the interrupt is active.
> 
> I'd be keen on hearing what Microchips plans to address. If tracking
> down performance issues is a priority I'll probably not spend any time
> on it, if not then I'll definetly dig into it more.
I tried to reproduce the issue in my setup with your above applications.
But surprisingly I couldn't reproduce the issue you are facing.

One end is Raspberry Pi 4 with lan8651 MAC-PHY and the other end is 
Raspberry Pi 4 with EVB-LAN8670-USB Stick.

lan8651 MAC-PHY side:
---------------------

pi@raspberrypi:~/lan865x/v4_mainline $ python3 server.py
connection from: ('192.168.5.101', 46608)

Top output:
-----------
top - 14:28:14 up  1:14,  4 users,  load average: 0.68, 0.67, 0.63
Tasks: 201 total,   1 running, 200 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.2 us,  1.1 sy,  0.0 ni, 98.7 id,  0.0 wa,  0.0 hi,  0.1 si, 
0.0 st
MiB Mem :   7810.0 total,   7110.5 free,    392.3 used,    432.4 
buff/cache
MiB Swap:    100.0 total,    100.0 free,      0.0 used.   7417.7 avail Mem

     PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ 
COMMAND 

    7219 root     -51   0       0      0      0 S   2.7   0.0   1:13.11 
oa-tc6-spi-thread 

   35307 pi        20   0   16280   9216   5248 S   0.7   0.1   0:16.53 
python3 

   88831 pi        20   0   11728   4864   2816 R   0.3   0.1   0:00.22 
top 

   89819 vnc       20   0    2320    384    384 S   0.3   0.0   0:00.04 
sh 

       1 root      20   0  168652  11580   8436 S   0.0   0.1   0:03.85 
systemd 

       2 root      20   0       0      0      0 S   0.0   0.0   0:00.01 
kthreadd 

       3 root      20   0       0      0      0 S   0.0   0.0   0:00.00 
pool_workqueue_release 

       4 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 
kworker/R-rcu_g 

       5 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 
kworker/R-rcu_p 

       6 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 
kworker/R-slub_ 

       7 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 
kworker/R-netns 

      11 root      20   0       0      0      0 I   0.0   0.0   0:00.03 
kworker/u8:0-ext4-rsv-conversion 

      12 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 
kworker/R-mm_pe

ifconfig output:
----------------
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
         inet 192.168.5.100  netmask 255.255.255.0  broadcast 0.0.0.0
         ether 04:05:06:01:02:03  txqueuelen 1000  (Ethernet)
         RX packets 1589879  bytes 2391045582 (2.2 GiB)
         RX errors 0  dropped 0  overruns 0  frame 0
         TX packets 1022419  bytes 71954905 (68.6 MiB)
         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
         device interrupt 55

dmesg output:
-------------
pi@raspberrypi:~/lan865x/v4_mainline $ dmesg
[  234.019968] LAN865X Rev.B0 Internal Phy spi0.0:00: attached PHY 
driver (mii_bus:phy_addr=spi0.0:00, irq=POLL)
[  234.069387] lan865x spi0.0 eth1: Link is Up - 10Mbps/Half - flow 
control off

EVB-LAN8670-USB stick side:
---------------------------
pi@pv-rpi-tp2:~/microchip/t1s-usb $ python3 client.py 192.168.5.100

ifconfig output:
----------------
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
         inet 192.168.5.101  netmask 255.255.255.0  broadcast 192.168.5.255
         ether 00:1e:c0:d1:ca:39  txqueuelen 1000  (Ethernet)
         RX packets 1034606  bytes 58330335 (55.6 MiB)
         RX errors 0  dropped 0  overruns 0  frame 0
         TX packets 1722400  bytes 2628199197 (2.4 GiB)
         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Let me know if you want to try anything more.

Best regards,
Parthiban V
> 
> Let me know if anything is unclear or if I can help out with anything
> specific.
> 
> R


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 13/12] net: lan865x: optional hardware reset
  2024-04-30 14:14           ` Andrew Lunn
@ 2024-05-02 10:10             ` Parthiban.Veerasooran
  0 siblings, 0 replies; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-05-02 10:10 UTC (permalink / raw)
  To: andrew
  Cc: davem, edumazet, kuba, pabeni, horms, saeedm, anthony.l.nguyen,
	netdev, linux-kernel, corbet, linux-doc, robh+dt,
	krzysztof.kozlowski+dt, conor+dt, devicetree, Horatiu.Vultur,
	ruanjinjie, Steen.Hegelund, vladimir.oltean, UNGLinuxDriver,
	Thorsten.Kummermehr, Pier.Beruto, Selvamani.Rajagopal,
	Nicolas.Ferre, benjamin.bigler, ramon.nordin.rodriguez

Hi Andrew,

On 30/04/24 7:44 pm, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
>> In the spec, external RESET pin is mentioned as "if implemented", in my
>> understanding it is MAC-PHY vendors choice of implementing it where
>> Microchip is implemented it. Using this reset, can be a application
>> requirement/decision. It can be controlled from an external application
>> where it is not needed SPI to operate.
> 
> Since it is optional, controlling the reset pin is clearly not
> something for the TC6 core.
> 
> However, i doubt having an external application controlling the reset
> is a good idea. You don't want to reset during operation. So to me,
> this reset should be controlled by the driver. I tend to agree, that
> actually performing a reset is optional, but i would expect the driver
> to ensure the device is taken out of reset during probe, if the power
> on default of the board is to hold it in reset.
POR - Power ON Reset.

If I understand you correctly, we need to ensure that whether the 
MAC-PHY is out of POR before doing any SPI operation right? so you 
expect oa_tc6_sw_reset_macphy() also may fail as the SWRESET bit write 
may fail if the device is still in POR.

Basically oa_tc6_sw_reset_macphy() does the following,
  - Writes 1 to SWRESET bit in the Reset Control and Status Register to 
trigger software reset.
  - Polls for software reset complete for every 1ms until 1s timeout.
  - Clears reset status complete status.

Can we rename the function like oa_tc6_check_power_on_reset_complete()
and the definition like below?
  - Poll for software reset complete for every 1ms until 1s timeout. The 
return value of oa_tc6_read_register() may not be needed to check for 
error as it might fail if the POR is taking place right?
  - Clear reset complete status.

But this case will work fine with initial power ON but after that if we 
are only reloading the driver for next time without powering OFF and ON 
then it will fail.

I am just thinking from TC6 framework point of view. Controlling from 
ext reset pin will not be an option as it is mentioned like an optional 
implementation in the OPEN Alliance. So some MAC-PHY vendors might not 
implement this.

Just an open question, after powering ON the Linux system, there are 
different stages are involved in the booting sequence of a system before 
kernel driver loads. A device like MAC-PHY which takes hardly around 5 
to 10us will complete the POR before that? OR is my understanding here 
is wrong?

Best regards,
Parthiban V
> 
>     Andrew


^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking
  2024-05-02 10:10             ` Parthiban.Veerasooran
@ 2024-05-02 10:19               ` Ramón Nordin Rodriguez
  2024-05-03  7:10                 ` Parthiban.Veerasooran
  0 siblings, 1 reply; 96+ messages in thread
From: Ramón Nordin Rodriguez @ 2024-05-02 10:19 UTC (permalink / raw)
  To: Parthiban.Veerasooran
  Cc: andrew, davem, edumazet, kuba, pabeni, horms, saeedm,
	anthony.l.nguyen, netdev, linux-kernel, corbet, linux-doc,
	robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	Horatiu.Vultur, ruanjinjie, Steen.Hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

> I tried to reproduce the issue in my setup with your above applications.
> But surprisingly I couldn't reproduce the issue you are facing.
> 
> One end is Raspberry Pi 4 with lan8651 MAC-PHY and the other end is 
> Raspberry Pi 4 with EVB-LAN8670-USB Stick.
> 
> lan8651 MAC-PHY side:
> ---------------------
> 

Did you run both client and server on both ends? The previous tests I
have done have only sent traffic in one direction, which did not lead to
a live lock.
But both sending and receiving as fast as possible in both directions
trigger the problems on my end.
R

^ permalink raw reply	[flat|nested] 96+ messages in thread

* Re: [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking
  2024-05-02 10:19               ` Ramón Nordin Rodriguez
@ 2024-05-03  7:10                 ` Parthiban.Veerasooran
  0 siblings, 0 replies; 96+ messages in thread
From: Parthiban.Veerasooran @ 2024-05-03  7:10 UTC (permalink / raw)
  To: ramon.nordin.rodriguez
  Cc: andrew, davem, edumazet, kuba, pabeni, horms, saeedm,
	anthony.l.nguyen, netdev, linux-kernel, corbet, linux-doc,
	robh+dt, krzysztof.kozlowski+dt, conor+dt, devicetree,
	Horatiu.Vultur, ruanjinjie, Steen.Hegelund, vladimir.oltean,
	UNGLinuxDriver, Thorsten.Kummermehr, Pier.Beruto,
	Selvamani.Rajagopal, Nicolas.Ferre, benjamin.bigler

On 02/05/24 3:49 pm, Ramón Nordin Rodriguez wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
>> I tried to reproduce the issue in my setup with your above applications.
>> But surprisingly I couldn't reproduce the issue you are facing.
>>
>> One end is Raspberry Pi 4 with lan8651 MAC-PHY and the other end is
>> Raspberry Pi 4 with EVB-LAN8670-USB Stick.
>>
>> lan8651 MAC-PHY side:
>> ---------------------
>>
> 
> Did you run both client and server on both ends? The previous tests I
> have done have only sent traffic in one direction, which did not lead to
> a live lock.
> But both sending and receiving as fast as possible in both directions
> trigger the problems on my end.
OK, today I executed both the client and server on both the sides. It is 
running more than an hour, it didn't crash. But there are some "Receive 
buffer overflow error" time to time in the dmesg. I don't know whether 
this is an expected behavior with this type of stress test.

top output:
-----------

pi@raspberrypi:~/lan865x/v4_mainline $ top

top - 19:47:07 up 54 min,  5 users,  load average: 1.23, 1.20, 1.14
Tasks: 205 total,   1 running, 204 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  7.5 sy,  0.0 ni, 92.1 id,  0.0 wa,  0.0 hi,  0.2 si, 
0.0 st
MiB Mem :   7810.0 total,   7013.5 free,    402.6 used,    518.0 
buff/cache
MiB Swap:    100.0 total,    100.0 free,      0.0 used.   7407.5 avail Mem

     PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ 
COMMAND 

    7218 root     -51   0       0      0      0 D  28.6   0.0  13:51.12 
oa-tc6-spi-thread 

   63853 vnc       20   0    2320    384    384 S   0.7   0.0   0:00.23 
sh 

   65090 pi        20   0   11728   4992   2816 R   0.7   0.1   0:00.04 
top 

      17 root      20   0       0      0      0 I   0.3   0.0   0:01.74 
rcu_preempt 

      27 root      20   0       0      0      0 S   0.3   0.0   0:16.67 
ksoftirqd/2 

     268 root      20   0   50024  16132  15108 S   0.3   0.2   0:02.02 
systemd-journal 

     956 pi        20   0  699196  37896  29160 S   0.3   0.5   0:03.60 
wireplumber 

    7328 pi        20   0   16280   9216   5248 S   0.3   0.1   0:07.61 
python3 

       1 root      20   0  168692  11340   8320 S   0.0   0.1   0:03.67 
systemd 

       2 root      20   0       0      0      0 S   0.0   0.0   0:00.01 
kthreadd

ifconfig output:
----------------

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
         inet 192.168.5.100  netmask 255.255.255.0  broadcast 0.0.0.0
         ether 04:05:06:01:02:03  txqueuelen 1000  (Ethernet)
         RX packets 1944541  bytes 909191168 (867.0 MiB)
         RX errors 0  dropped 2  overruns 0  frame 0
         TX packets 2402855  bytes 3129162624 (2.9 GiB)
         TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
         device interrupt 55

dmesg output:
-------------

[  285.482275] LAN865X Rev.B0 Internal Phy spi0.0:00: attached PHY 
driver (mii_bus:phy_addr=spi0.0:00, irq=POLL)
[  285.534760] lan865x spi0.0 eth1: Link is Up - 10Mbps/Half - flow 
control off
[  341.466221] eth1: Receive buffer overflow error
[  345.730222] eth1: Receive buffer overflow error
[  345.891126] eth1: Receive buffer overflow error
[  346.074220] eth1: Receive buffer overflow error
[  354.374223] eth1: Receive buffer overflow error
[  354.375422] eth1: Receive buffer overflow error
[  355.786219] eth1: Receive buffer overflow error
[  356.898221] eth1: Receive buffer overflow error
[  357.782219] eth1: Receive buffer overflow error
[  357.783194] eth1: Receive buffer overflow error
[  365.446224] eth1: Receive buffer overflow error
[  387.722221] eth1: Receive buffer overflow error
[  387.790218] eth1: Receive buffer overflow error
[  387.950224] eth1: Receive buffer overflow error
[  387.951199] eth1: Receive buffer overflow error
[  388.790219] eth1: Receive buffer overflow error
[  389.010220] eth1: Receive buffer overflow error
[  391.066221] eth1: Receive buffer overflow error
[  409.746225] eth1: Receive buffer overflow error
[  442.835278] eth1: Receive buffer overflow error
[  447.410222] eth1: Receive buffer overflow error
[  447.510220] eth1: Receive buffer overflow error
[  447.758219] eth1: Receive buffer overflow error
[  448.066221] eth1: Receive buffer overflow error
[  449.590220] eth1: Receive buffer overflow error
[  450.686221] eth1: Receive buffer overflow error
[  451.238222] eth1: Receive buffer overflow error
[  451.490220] eth1: Receive buffer overflow error
[  472.254221] eth1: Receive buffer overflow error
[  473.302222] eth1: Receive buffer overflow error
[  474.070220] eth1: Receive buffer overflow error
[  475.262220] eth1: Receive buffer overflow error
[  475.362223] eth1: Receive buffer overflow error
[  477.362224] eth1: Receive buffer overflow error
[  501.918221] eth1: Receive buffer overflow error
[  505.510219] eth1: Receive buffer overflow error
[  516.466220] eth1: Receive buffer overflow error
[  600.830221] eth1: Receive buffer overflow error
[  675.614219] eth1: Receive buffer overflow error
[  676.318223] eth1: Receive buffer overflow error
[  676.594223] eth1: Receive buffer overflow error
[  678.702219] eth1: Receive buffer overflow error
[  679.102219] eth1: Receive buffer overflow error
[  679.642218] eth1: Receive buffer overflow error
[  679.894218] eth1: Receive buffer overflow error
[  679.906224] eth1: Receive buffer overflow error
[  682.529386] eth1: Receive buffer overflow error
[  682.786221] eth1: Receive buffer overflow error
[  703.374220] eth1: Receive buffer overflow error
[  703.462219] eth1: Receive buffer overflow error
[  716.606222] eth1: Receive buffer overflow error
[  717.134219] eth1: Receive buffer overflow error
[  722.838219] eth1: Receive buffer overflow error
[  801.522220] eth1: Receive buffer overflow error
[  871.946226] eth1: Receive buffer overflow error
[ 1304.190220] eth1: Receive buffer overflow error
[ 1307.734221] eth1: Receive buffer overflow error
[ 1309.738224] eth1: Receive buffer overflow error
[ 1605.222219] eth1: Receive buffer overflow error
[ 1739.927121] eth1: Receive buffer overflow error
[ 2240.002213] eth1: Receive buffer overflow error
[ 2241.355378] eth1: Receive buffer overflow error
[ 2300.374218] eth1: Receive buffer overflow error
[ 2332.850214] eth1: Receive buffer overflow error
[ 2347.322215] eth1: Receive buffer overflow error
[ 2377.702216] eth1: Receive buffer overflow error
[ 2393.942214] eth1: Receive buffer overflow error
[ 2404.986214] eth1: Receive buffer overflow error
[ 2407.538216] eth1: Receive buffer overflow error
[ 2407.539190] eth1: Receive buffer overflow error
[ 2411.266213] eth1: Receive buffer overflow error
[ 2421.542220] eth1: Receive buffer overflow error
[ 2713.142214] eth1: Receive buffer overflow error
[ 3401.226215] eth1: Receive buffer overflow error
[ 3494.394214] eth1: Receive buffer overflow error
[ 3511.850214] eth1: Receive buffer overflow error


Best regards,
Parthiban V
> R
> 


^ permalink raw reply	[flat|nested] 96+ messages in thread

end of thread, other threads:[~2024-05-03  7:10 UTC | newest]

Thread overview: 96+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-18 12:56 [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Parthiban Veerasooran
2024-04-18 12:56 ` [PATCH net-next v4 01/12] Documentation: networking: add OPEN Alliance 10BASE-T1x MAC-PHY serial interface Parthiban Veerasooran
2024-04-28  9:33   ` Bagas Sanjaya
2024-04-29 11:31     ` Parthiban.Veerasooran
2024-04-29 16:17   ` Simon Horman
2024-04-30 11:30     ` Parthiban.Veerasooran
2024-04-18 12:56 ` [PATCH net-next v4 02/12] net: ethernet: oa_tc6: implement register write operation Parthiban Veerasooran
2024-04-22 23:48   ` Andrew Lunn
2024-04-23  4:38     ` Parthiban.Veerasooran
2024-04-23 23:14   ` Andrew Lunn
2024-04-26  5:55     ` Parthiban.Veerasooran
2024-04-29 16:36   ` Simon Horman
2024-04-30  8:14     ` Parthiban.Veerasooran
2024-04-18 12:56 ` [PATCH net-next v4 03/12] net: ethernet: oa_tc6: implement register read operation Parthiban Veerasooran
2024-04-23 23:17   ` Andrew Lunn
2024-04-26  5:56     ` Parthiban.Veerasooran
2024-04-18 12:56 ` [PATCH net-next v4 04/12] net: ethernet: oa_tc6: implement software reset Parthiban Veerasooran
2024-04-23 23:26   ` Andrew Lunn
2024-04-26  6:38     ` Parthiban.Veerasooran
2024-04-18 12:56 ` [PATCH net-next v4 05/12] net: ethernet: oa_tc6: implement error interrupts unmasking Parthiban Veerasooran
2024-04-23 23:27   ` Andrew Lunn
2024-04-27 19:52   ` Ramón Nordin Rodriguez
2024-04-27 21:17     ` Andrew Lunn
2024-04-27 21:55       ` Ramón Nordin Rodriguez
2024-04-28 14:48         ` Andrew Lunn
2024-04-28  9:54       ` Ramón Nordin Rodriguez
2024-04-28 14:59         ` Andrew Lunn
2024-04-28 22:04           ` Ramón Nordin Rodriguez
2024-05-01 18:29           ` Ramón Nordin Rodriguez
2024-05-01 19:58             ` Andrew Lunn
2024-05-01 20:07             ` Andrew Lunn
2024-05-02 10:10             ` Parthiban.Veerasooran
2024-05-02 10:19               ` Ramón Nordin Rodriguez
2024-05-03  7:10                 ` Parthiban.Veerasooran
2024-04-18 12:56 ` [PATCH net-next v4 06/12] net: ethernet: oa_tc6: implement internal PHY initialization Parthiban Veerasooran
2024-04-23 23:48   ` Andrew Lunn
2024-04-26 13:17     ` Parthiban.Veerasooran
2024-04-18 12:56 ` [PATCH net-next v4 07/12] net: ethernet: oa_tc6: enable open alliance tc6 data communication Parthiban Veerasooran
2024-04-23 23:49   ` Andrew Lunn
2024-04-18 12:56 ` [PATCH net-next v4 08/12] net: ethernet: oa_tc6: implement transmit path to transfer tx ethernet frames Parthiban Veerasooran
2024-04-24  0:02   ` Andrew Lunn
2024-04-26 13:19     ` Parthiban.Veerasooran
2024-04-18 12:56 ` [PATCH net-next v4 09/12] net: ethernet: oa_tc6: implement receive path to receive rx " Parthiban Veerasooran
2024-04-24  0:08   ` Andrew Lunn
2024-04-26 13:45     ` Parthiban.Veerasooran
2024-04-26 18:13       ` Andrew Lunn
2024-04-29  6:13         ` Parthiban.Veerasooran
2024-04-27 20:02   ` Ramón Nordin Rodriguez
2024-04-29  8:32     ` Parthiban.Veerasooran
2024-04-29 10:45       ` Ramón Nordin Rodriguez
2024-04-18 12:56 ` [PATCH net-next v4 10/12] net: ethernet: oa_tc6: implement mac-phy interrupt Parthiban Veerasooran
2024-04-24  0:10   ` Andrew Lunn
2024-04-18 12:56 ` [PATCH net-next v4 11/12] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY Parthiban Veerasooran
2024-04-24  0:27   ` Andrew Lunn
2024-04-26 13:32     ` Parthiban.Veerasooran
2024-04-26 18:14       ` Andrew Lunn
2024-04-29  6:13         ` Parthiban.Veerasooran
2024-04-27 19:19   ` Ramón Nordin Rodriguez
2024-04-27 19:57     ` Conor Dooley
2024-04-27 20:13       ` Ramón Nordin Rodriguez
2024-04-27 20:22         ` Conor Dooley
2024-04-27 21:09           ` Ramón Nordin Rodriguez
2024-04-29  9:47       ` Parthiban.Veerasooran
2024-04-29 12:09         ` Andrew Lunn
2024-04-30 13:30           ` Parthiban.Veerasooran
2024-04-30 16:55             ` Conor Dooley
2024-05-02  5:56               ` Parthiban.Veerasooran
2024-04-27 20:40     ` Andrew Lunn
2024-04-27 21:06       ` Ramón Nordin Rodriguez
2024-04-28 14:18         ` Andrew Lunn
2024-04-27 19:35   ` Ramón Nordin Rodriguez
2024-04-27 20:58     ` Andrew Lunn
2024-04-27 21:29       ` Ramón Nordin Rodriguez
2024-04-28 14:25         ` Andrew Lunn
2024-04-28 22:00           ` Ramón Nordin Rodriguez
2024-04-18 12:56 ` [PATCH net-next v4 12/12] dt-bindings: net: add Microchip's LAN865X 10BASE-T1S MACPHY Parthiban Veerasooran
2024-04-18 15:39   ` Conor Dooley
2024-04-22  3:59     ` Parthiban.Veerasooran
2024-04-22 15:50       ` Conor Dooley
2024-04-23  3:27         ` Parthiban.Veerasooran
2024-04-22 20:07 ` [PATCH net-next v4 00/12] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface Andrew Lunn
2024-04-22 20:08 ` Andrew Lunn
2024-04-22 23:23   ` Andrew Lunn
2024-04-22 23:43 ` Andrew Lunn
2024-04-28 21:16 ` [PATCH net-next v4 13/12] net: lan865x: optional hardware reset Ramón Nordin Rodriguez
2024-04-28 23:17   ` Andrew Lunn
2024-04-29 10:42     ` Ramón Nordin Rodriguez
2024-04-29  6:09   ` Parthiban.Veerasooran
2024-04-29 10:38     ` Ramón Nordin Rodriguez
2024-04-29 12:19       ` Andrew Lunn
2024-04-30  8:04         ` Ramón Nordin Rodriguez
2024-04-30 13:30         ` Parthiban.Veerasooran
2024-04-30 14:14           ` Andrew Lunn
2024-05-02 10:10             ` Parthiban.Veerasooran
2024-04-29  6:09   ` Krzysztof Kozlowski
2024-04-29 10:44     ` Ramón Nordin Rodriguez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).