From nobody Sat Nov 9 16:29:23 2024 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5051C1AE859; Mon, 9 Sep 2024 08:25:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.154.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870362; cv=none; b=TE+88HJWxuoJYJB4wcsrKWaM/V0ivcN6LDnepO0Zy1phjb5Y9uU7fb1iT1+5438FYBpjF0M6+OMluqwqHP8WJarhgE52ju95LJt9tZLIpBb0q680ix70JFckA5j0t3RSuT3genIxCX/i0emYccnEXZHDFA81J0G9SbrjNNGNA9Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870362; c=relaxed/simple; bh=ZTgoqV7ErDP6UOLCfWyZ+RoAFEMdz+GGegmR+HcE9Sw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Sdgu8+ZUjjdhiv1lAVF1UYyO7VCAp3BAvk46sM75IGWLO6ldzcnnTuXMQC5xlLZ34ohFLvJW3YhorKOtQDyld9yDWEbrhYYdsct5Z3mbXktuB7DwkdaGJikh7aARLQLhzwFvzbImY0LndkqDXQq4KBoXYTEDfLlibXkihGo/HBk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=kRO+psn1; arc=none smtp.client-ip=68.232.154.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="kRO+psn1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1725870360; x=1757406360; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ZTgoqV7ErDP6UOLCfWyZ+RoAFEMdz+GGegmR+HcE9Sw=; b=kRO+psn1khxDrfYwu+1gY5Qgp5a7Na4BmrK/urNfFJnLAVG72DxyHzjn jZBSSsxqk+ss4w1Uz0F8P/rHo7bOberxjUC9kLMxvUjTrMqj6bV7Kymar 4OhZdlmZHZyyzeaA3H9k0tEQUF2ssuGtbxO0g4CaCsGuJZn/u4aJcyBsn 0UkzolDdvbkjn3WjUsA+p0FYoN7+suTkqpX9XpjZFeMpdmgJ6fpqPiOXq qyv8GYtdGi7mYlyM4E2bDVuijq9RsrSS6OIgjGG6cO4apCL37e4UphMdh bjsguQrqrpY3uzCr7skJZ3tKfjq1Oycu9L6FhsL7uxXy4M1YU8ZgwOAVe Q==; X-CSE-ConnectionGUID: i5J4LekxSFeDbUFUX89OIQ== X-CSE-MsgGUID: Z7QGLx3gTKG7gUVm1JIlpg== X-IronPort-AV: E=Sophos;i="6.10,213,1719903600"; d="scan'208";a="31409569" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa4.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 09 Sep 2024 01:25:58 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 9 Sep 2024 01:25:38 -0700 Received: from che-ll-i17164.microchip.com (10.10.85.11) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Mon, 9 Sep 2024 01:25:28 -0700 From: Parthiban Veerasooran To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , , , , , , , , , , , Parthiban Veerasooran Subject: [PATCH net-next v8 01/14] Documentation: networking: add OPEN Alliance 10BASE-T1x MAC-PHY serial interface Date: Mon, 9 Sep 2024 13:55:01 +0530 Message-ID: <20240909082514.262942-2-Parthiban.Veerasooran@microchip.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> References: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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. Reviewed-by: Andrew Lunn Signed-off-by: Parthiban Veerasooran --- Documentation/networking/index.rst | 1 + Documentation/networking/oa-tc6-framework.rst | 497 ++++++++++++++++++ MAINTAINERS | 6 + 3 files changed, 504 insertions(+) create mode 100644 Documentation/networking/oa-tc6-framework.rst diff --git a/Documentation/networking/index.rst b/Documentation/networking/= index.rst index c71b87346178..171bace26c91 100644 --- a/Documentation/networking/index.rst +++ b/Documentation/networking/index.rst @@ -87,6 +87,7 @@ Contents: nexthop-group-resilient nf_conntrack-sysctl nf_flowtable + oa-tc6-framework openvswitch operstates packet_mmap diff --git a/Documentation/networking/oa-tc6-framework.rst b/Documentation/= networking/oa-tc6-framework.rst new file mode 100644 index 000000000000..fe2aabde923a --- /dev/null +++ b/Documentation/networking/oa-tc6-framework.rst @@ -0,0 +1,497 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +OPEN Alliance 10BASE-T1x MAC-PHY Serial Interface (TC6) Framework Support +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +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-PH= Y_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 =E2=80= =991=E2=80=99. + 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 =3D 0 in the footer), indicating that the + host would not process it. Typically, the SPI host should + set NORX =3D 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 =E2=80=980=E2=80= =99. + +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 =E2=80=980=E2=80=99. + +DV (Bit 21) - Data Valid flag. The SPI host uses this bit to indicate + whether the current chunk contains valid transmit frame data + (DV =3D 1) or not (DV =3D 0). When =E2=80=980=E2=80=99, 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 =3D 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 =3D 0. + +RSVD (Bit 15) - Reserved: All reserved bits shall be =E2=80=980=E2=80=99. + +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 =3D 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 =3D 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 =E2=80=980=E2=80=99. + +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=E2=80=99s 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 + =E2=80=980=E2=80=99. + +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 =3D 1) or not (DV =3D 0). When =E2=80= =980=E2=80=99, 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 =3D 1, this field contains t= he + 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 =3D 1) + then SWO points to the most significant byte of the + timestamp. This field will be zero when SV =3D 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D 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 =E2=80= =980=E2=80=99. + 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 +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +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-P= HY. +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-P= HY. +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 throu= gh +the MAC-PHY. + +.. c:function:: int oa_tc6_zero_align_receive_frame_enable(struct oa_tc6 *= tc6); + +Zero align receive frame feature can be enabled to align all receive ether= net +frames data to start at the beginning of any receive data chunk payload wi= th a +start word offset (SWO) of zero. diff --git a/MAINTAINERS b/MAINTAINERS index ca1469d52076..f6daa0cef1a3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17112,6 +17112,12 @@ L: linux-rdma@vger.kernel.org S: Supported F: drivers/infiniband/ulp/opa_vnic =20 +OPEN ALLIANCE 10BASE-T1S MACPHY SERIAL INTERFACE FRAMEWORK +M: Parthiban Veerasooran +L: netdev@vger.kernel.org +S: Maintained +F: Documentation/networking/oa-tc6-framework.rst + OPEN FIRMWARE AND FLATTENED DEVICE TREE M: Rob Herring M: Saravana Kannan --=20 2.34.1 From nobody Sat Nov 9 16:29:23 2024 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0F72D1B2501; Mon, 9 Sep 2024 08:26:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.154.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870365; cv=none; b=NB41a9cOerp/eFAkH03AppE5oQBXwHrDAhi+2yWMHdqNb94gesUkJuJ5lSWdnpyq81JfZIV5YNrRy9UNAz6qN+C+f6D54FxEIa20ywiZNIk/F5u/IW4CWz2CoRxYNWA6Eb/q4gZC5cB2NBEd88p27mAQlm4rrg3HjbIjtpvYQR8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870365; c=relaxed/simple; bh=9Boa9VIjkOMokwi1mDQDM/gRPdkvltGgTP92ZsWMj9s=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=njSqA3uNF/yS3puUiB+zOKT95hGKMnzPOd36T3tuyQRvnHVhm9ym2YruQF+mGyHl/UPyLxt9hHaILZk7/wHtY5horpUnLgkcXh1FUGboKsjEw2WrNWH4tOmKo3zF2xdZHCcpxMjQQXD5c/QBcExAyVMGdI2nQeLxdgFtggmti/k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=q8kXesE/; arc=none smtp.client-ip=68.232.154.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="q8kXesE/" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1725870363; x=1757406363; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=9Boa9VIjkOMokwi1mDQDM/gRPdkvltGgTP92ZsWMj9s=; b=q8kXesE/ZWSznTNRZDunugZAAylDc7KlFF5N+gCjso9IMzgtKarjWju2 C4C9xZy4RWzcXn5Td0/xajfgeZjYUDCWqoeeCZjILpdNAw4YKpyI4MGzB /hu0kva+7KEmZzp+/EAeE8khpu5Z4LrW6yhfRpbIvQu0g4tpA5czB5AZp juwg3g3//gVKW7Dm4PwwLB68I/T9XviYBwVfAkN7HkXiCnr4tvEjNPSih czmVAOz0ez89BNLLlByziwD3m7wwcAt//pP48IhgyMAU/xuu1L0iEPKqh ihOt1M44swYy6EbY+5B10GC/u6Ok4s+yPPHTV5G99Q6sX8dN28K+A2KQh A==; X-CSE-ConnectionGUID: i5J4LekxSFeDbUFUX89OIQ== X-CSE-MsgGUID: TA4TK83RRSeEkKkawvIpbw== X-IronPort-AV: E=Sophos;i="6.10,213,1719903600"; d="scan'208";a="31409572" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa4.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 09 Sep 2024 01:25:59 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 9 Sep 2024 01:25:49 -0700 Received: from che-ll-i17164.microchip.com (10.10.85.11) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Mon, 9 Sep 2024 01:25:38 -0700 From: Parthiban Veerasooran To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , , , , , , , , , , , Parthiban Veerasooran Subject: [PATCH net-next v8 02/14] net: ethernet: oa_tc6: implement register write operation Date: Mon, 9 Sep 2024 13:55:02 +0530 Message-ID: <20240909082514.262942-3-Parthiban.Veerasooran@microchip.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> References: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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. Reviewed-by: Andrew Lunn Signed-off-by: Parthiban Veerasooran --- MAINTAINERS | 2 + drivers/net/ethernet/Kconfig | 11 ++ drivers/net/ethernet/Makefile | 1 + drivers/net/ethernet/oa_tc6.c | 242 ++++++++++++++++++++++++++++++++++ include/linux/oa_tc6.h | 17 +++ 5 files changed, 273 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 f6daa0cef1a3..a8783e6f4e86 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17117,6 +17117,8 @@ M: Parthiban Veerasooran 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 =20 OPEN FIRMWARE AND FLATTENED DEVICE TREE M: Rob Herring diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig index 0baac25db4f8..9a542e3c9b05 100644 --- a/drivers/net/ethernet/Kconfig +++ b/drivers/net/ethernet/Kconfig @@ -158,6 +158,17 @@ config ETHOC help Say Y here if you want to use the OpenCores 10/100 Mbps Ethernet MAC. =20 +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 + . + 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 c03203439c0e..99fa180dedb8 100644 --- a/drivers/net/ethernet/Makefile +++ b/drivers/net/ethernet/Makefile @@ -105,3 +105,4 @@ obj-$(CONFIG_NET_VENDOR_XILINX) +=3D xilinx/ obj-$(CONFIG_NET_VENDOR_XIRCOM) +=3D xircom/ obj-$(CONFIG_NET_VENDOR_SYNOPSYS) +=3D synopsys/ obj-$(CONFIG_NET_VENDOR_PENSANDO) +=3D pensando/ +obj-$(CONFIG_OA_TC6) +=3D 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..24e9fd92d717 --- /dev/null +++ b/drivers/net/ethernet/oa_tc6.c @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * OPEN Alliance 10BASE=E2=80=91T1x MAC=E2=80=91PHY Serial Interface frame= work + * + * Author: Parthiban Veerasooran + */ + +#include +#include + +/* 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 =3D 1, +}; + +static int oa_tc6_spi_transfer(struct oa_tc6 *tc6, + enum oa_tc6_header_type header_type, u16 length) +{ + struct spi_transfer xfer =3D { 0 }; + struct spi_message msg; + + xfer.tx_buf =3D tc6->spi_ctrl_tx_buf; + xfer.rx_buf =3D tc6->spi_ctrl_rx_buf; + xfer.len =3D 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 ^=3D p >> 1; + p ^=3D p >> 2; + p =3D (p & 0x11111111U) * 0x11111111U; + + /* Odd parity is used here */ + return !((p >> 28) & 1); +} + +static __be32 oa_tc6_prepare_ctrl_header(u32 addr, u8 length, + enum oa_tc6_register_op reg_op) +{ + u32 header; + + header =3D 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, addr >> 16) | + FIELD_PREP(OA_TC6_CTRL_HEADER_ADDR, addr) | + FIELD_PREP(OA_TC6_CTRL_HEADER_LENGTH, length - 1); + header |=3D 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 =3D tc6->spi_ctrl_tx_buf + OA_TC6_CTRL_HEADER_SIZE; + + for (int i =3D 0; i < length; i++) + *tx_buf++ =3D 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 =3D tc6->spi_ctrl_tx_buf; + + *tx_buf =3D 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 =3D tc6->spi_ctrl_tx_buf; + u8 *rx_buf =3D tc6->spi_ctrl_rx_buf; + + rx_buf +=3D 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 =3D oa_tc6_calculate_ctrl_buf_size(length); + + /* Perform SPI transfer */ + ret =3D 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 regi= sters. + * @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 @addres= s. + * @length: number of consecutive registers to be written from @address. + * + * Maximum of 128 consecutive registers can be written starting at @addres= s. + * + * Return: 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 =3D 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. + * + * Return: 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. + * + * Return: 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 =3D devm_kzalloc(&spi->dev, sizeof(*tc6), GFP_KERNEL); + if (!tc6) + return NULL; + + tc6->spi =3D spi; + mutex_init(&tc6->spi_ctrl_lock); + + /* Set the SPI controller to pump at realtime priority */ + tc6->spi->rt =3D true; + spi_setup(tc6->spi); + + tc6->spi_ctrl_tx_buf =3D 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 =3D 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=E2=80=91T1x MAC=E2=80=91PHY Seria= l Interface Lib"); +MODULE_AUTHOR("Parthiban Veerasooran = "); +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=E2=80=91T1x MAC=E2=80=91PHY Serial Interface frame= work + * + * Link: https://opensig.org/download/document/OPEN_Alliance_10BASET1x_MAC= -PHY_Serial_Interface_V1.1.pdf + * + * Author: Parthiban Veerasooran + */ + +#include + +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); --=20 2.34.1 From nobody Sat Nov 9 16:29:23 2024 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2DB1F1AF4F8; Mon, 9 Sep 2024 08:26:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.153.233 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870398; cv=none; b=GonvwOjvshNzvIeKJoFh0XzyCSRafsNKjAxea/7VBL6zi7mS4Do2oq5fUKj02jrOvqtdG9pg4SvOWPlsunHeCdHQ495oY/bgCROQVfOaV1nF+1kpznTvFujIEx5q1xXEL9wAWRUXG2kl0M5FfnguYjMbSazGdFoeJA7yn4bdDj0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870398; c=relaxed/simple; bh=5Ze3ak7szOHjF+pnjdFZp69ShAxNT7Poi5W3RGkCbyY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=baaNnfZCJ8pDpN0QHPlZg3x4ek3QgJYZqVoJnbGA0sHkeMC2l/BTZwbTLtUMatmSK1VhPXES5ofqfjYKtm2VJSr5ob4dj5vCno/8KrKKQ3rjnwV9152UqryKl3ccFihvgKsQ7hm7x6eD0SKWgBAvxjyFZ3+TRaDNBjV/4Ea5JFk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=0JzTG8/o; arc=none smtp.client-ip=68.232.153.233 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="0JzTG8/o" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1725870396; x=1757406396; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=5Ze3ak7szOHjF+pnjdFZp69ShAxNT7Poi5W3RGkCbyY=; b=0JzTG8/opgdtWhEhgafJO2QdBqRvt1A5adhmh2aH26zCXMwN/lA8EPxX qC507mPBroJwnfXZdfVZkiUNUcRBLu8le6z8rHqwJ7dCIl0CCQ3tdVUN/ LSKQqGPmyy48872Ar0JKdRGTC8dymGcGD2mox4r0L3ETswuKtUtQoIbuJ x7HRnkDKT1J0Fqc/3+javE44gfdIKVZV7VypPbGs2FKqSkueTJMerg3e1 I07TvtuKndQr3NLkpBV9L8Y2KDukPvKJU5MWIy8vF3trc8WvrF0oZa/WQ ECQ6fFtKLtujZGnE8VhIykoPz3aElDSaTuxgBX0mB5HoXgpk2wSoWFwuC Q==; X-CSE-ConnectionGUID: d/w4Y2PcQAuCOQlGJPomLA== X-CSE-MsgGUID: DOi4i7aFSEC/b0sSq9DYZg== X-IronPort-AV: E=Sophos;i="6.10,213,1719903600"; d="scan'208";a="34622048" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa1.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 09 Sep 2024 01:26:34 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 9 Sep 2024 01:25:59 -0700 Received: from che-ll-i17164.microchip.com (10.10.85.11) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Mon, 9 Sep 2024 01:25:49 -0700 From: Parthiban Veerasooran To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , , , , , , , , , , , Parthiban Veerasooran Subject: [PATCH net-next v8 03/14] net: ethernet: oa_tc6: implement register read operation Date: Mon, 9 Sep 2024 13:55:03 +0530 Message-ID: <20240909082514.262942-4-Parthiban.Veerasooran@microchip.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> References: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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. Reviewed-by: Andrew Lunn Signed-off-by: Parthiban Veerasooran --- 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 24e9fd92d717..72bab9234436 100644 --- a/drivers/net/ethernet/oa_tc6.c +++ b/drivers/net/ethernet/oa_tc6.c @@ -38,6 +38,7 @@ enum oa_tc6_header_type { }; =20 enum oa_tc6_register_op { + OA_TC6_CTRL_REG_READ =3D 0, OA_TC6_CTRL_REG_WRITE =3D 1, }; =20 @@ -113,7 +114,8 @@ static void oa_tc6_prepare_ctrl_spi_buf(struct oa_tc6 *= tc6, u32 address, =20 *tx_buf =3D oa_tc6_prepare_ctrl_header(address, length, reg_op); =20 - oa_tc6_update_ctrl_write_data(tc6, value, length); + if (reg_op =3D=3D OA_TC6_CTRL_REG_WRITE) + oa_tc6_update_ctrl_write_data(tc6, value, length); } =20 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; } =20 +static int oa_tc6_check_ctrl_read_reply(struct oa_tc6 *tc6, u8 size) +{ + u32 *rx_buf =3D tc6->spi_ctrl_rx_buf + OA_TC6_CTRL_IGNORED_SIZE; + u32 *tx_buf =3D tc6->spi_ctrl_tx_buf; + + /* The echoed control read header must match with the one that was + * transmitted. + */ + if (*tx_buf !=3D *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 =3D tc6->spi_ctrl_rx_buf + OA_TC6_CTRL_IGNORED_SIZE + + OA_TC6_CTRL_HEADER_SIZE; + + for (int i =3D 0; i < length; i++) + value[i] =3D 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[], } =20 /* Check echoed/received control write command reply for errors */ - return oa_tc6_check_ctrl_write_reply(tc6, size); + if (reg_op =3D=3D OA_TC6_CTRL_REG_WRITE) + return oa_tc6_check_ctrl_write_reply(tc6, size); + + /* Check echoed/received control read command reply for errors */ + ret =3D 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 regis= ters. + * @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. + * + * Return: 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 =3D 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. + * + * Return: 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); =20 /** * oa_tc6_write_registers - function for writing multiple consecutive regi= sters. 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); --=20 2.34.1 From nobody Sat Nov 9 16:29:23 2024 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7471F1B1506; Mon, 9 Sep 2024 08:26:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.154.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870385; cv=none; b=lUvxahORRhAx0ZpSqll7alFXH2syll+QyudGGktErxI9jEXVI8ADA1axZw5nrQJFdauor7PP7mNesgRtnhL1YJIIq6EjcsZxdQyLfWwv4v/FAMyV8bvQtma45rrNVwPAwr4Ou4cKO5iQmvj0MV/VuDogXKHlbEzPBsn8dY3ry+M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870385; c=relaxed/simple; bh=S7FYudartPoRxv7ei2GeIG0dTCpBW7Lavt39Fq1e7lM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=o9hspb172xmIOsrWCSDBiOR02xAc5LtqjIW5xMRzopFj1Gcn+fM8jcNQYGRsTs92RJC66vcBqw437bwoymjLD+T7Tk8CNxIqTbJkxdY6zN+sS4QRT6uJU42Czkoi1L9vQPteoeo/NUhIWtD9D7wu1Bl/uUIzo+ajDln/fseMl8c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=XMLkG7nv; arc=none smtp.client-ip=68.232.154.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="XMLkG7nv" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1725870383; x=1757406383; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=S7FYudartPoRxv7ei2GeIG0dTCpBW7Lavt39Fq1e7lM=; b=XMLkG7nvmZ3APQIvphsje7TohBgoiFd9q6tGaQlZREEdlY0vF3HzBMAT DI3S1HLN7OX2yu1+J6eWAUWdgQp3U2BeAl4lCI7epAtudE+IgmRHvSU/h i++6gndWd3ELWf+zg48xsqTfP+V1cYpNjHvjUm3rAlKVsLKHwQzWjCJDv BsrFgK4y/1/dUPsBM0H2yrcPgF+dCPsZiZD+eZtr0qu99fz9mbPb1eg73 4a3d10TYrUMKZh+zxw5PZgU+8mUMtKE4d4cS28rls3jZeneODSBIugkfc XEpMmhHBOCOft41wAn7NF5sdgx0lbrTxeD0wL/cmB5pmw7u+BRJPFDhxs Q==; X-CSE-ConnectionGUID: HYDxjUxJQbO7VSKlGAv2ag== X-CSE-MsgGUID: B9mJy37TRKyH1MnoTuHnMw== X-IronPort-AV: E=Sophos;i="6.10,213,1719903600"; d="scan'208";a="198939930" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa6.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 09 Sep 2024 01:26:22 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 9 Sep 2024 01:26:10 -0700 Received: from che-ll-i17164.microchip.com (10.10.85.11) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Mon, 9 Sep 2024 01:26:00 -0700 From: Parthiban Veerasooran To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , , , , , , , , , , , Parthiban Veerasooran Subject: [PATCH net-next v8 04/14] net: ethernet: oa_tc6: implement software reset Date: Mon, 9 Sep 2024 13:55:04 +0530 Message-ID: <20240909082514.262942-5-Parthiban.Veerasooran@microchip.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> References: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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. Reviewed-by: Andrew Lunn Signed-off-by: Parthiban Veerasooran --- drivers/net/ethernet/oa_tc6.c | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c index 72bab9234436..f774ed397213 100644 --- a/drivers/net/ethernet/oa_tc6.c +++ b/drivers/net/ethernet/oa_tc6.c @@ -6,8 +6,18 @@ */ =20 #include +#include #include =20 +/* 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 =20 /* Internal structure for MAC-PHY drivers */ struct oa_tc6 { @@ -279,6 +291,42 @@ int oa_tc6_write_register(struct oa_tc6 *tc6, u32 addr= ess, u32 value) } EXPORT_SYMBOL_GPL(oa_tc6_write_register); =20 +static int oa_tc6_read_status0(struct oa_tc6 *tc6) +{ + u32 regval; + int ret; + + ret =3D oa_tc6_read_register(tc6, OA_TC6_REG_STATUS0, ®val); + if (ret) { + dev_err(&tc6->spi->dev, "STATUS0 register read failed: %d\n", + ret); + return 0; + } + + return regval; +} + +static int oa_tc6_sw_reset_macphy(struct oa_tc6 *tc6) +{ + u32 regval =3D RESET_SWRESET; + int ret; + + ret =3D 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 =3D 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 +337,7 @@ EXPORT_SYMBOL_GPL(oa_tc6_write_register); struct oa_tc6 *oa_tc6_init(struct spi_device *spi) { struct oa_tc6 *tc6; + int ret; =20 tc6 =3D devm_kzalloc(&spi->dev, sizeof(*tc6), GFP_KERNEL); if (!tc6) @@ -313,6 +362,13 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi) if (!tc6->spi_ctrl_rx_buf) return NULL; =20 + ret =3D 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); --=20 2.34.1 From nobody Sat Nov 9 16:29:23 2024 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A497A1AF4FA; Mon, 9 Sep 2024 08:26:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.153.233 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870396; cv=none; b=ro6pxW+Kpamcp1OfQTagkK85t3FgHdHMEjkh92hPFlTg0tgJ4LVyCNvjrA7fzYNSZKgrzmkFqXZFTGdAeTM4zT0hlrzPYLUxHms4JZhlSV4V6q3VH/GsSNq0vR9blTnIV0axBSFYB2UL0S+C7GnNhnlHJesRrtUwaUQL5eqdlM4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870396; c=relaxed/simple; bh=049uuilb9z/YbFT1C82V6wGOnQJt5Pm3yY/25FZjxCQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=gLTCkwnPFEjZ+wRRmt0BfKU+fIAMOvYbFL/klxFmYMdfdx/SqC4LDpFgKOianKGXkPYiy1AYifr8q32uVwZh9MlhYCq//Yts1ZEARHyzmFFve+mW3aDxMOJ41W7TpxCzwNnEIrEqrLeiwg9kLcoSbaB+w1XxAF71IGJU58UVzc0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=U9JqtBSP; arc=none smtp.client-ip=68.232.153.233 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="U9JqtBSP" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1725870394; x=1757406394; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=049uuilb9z/YbFT1C82V6wGOnQJt5Pm3yY/25FZjxCQ=; b=U9JqtBSPPIeA8GtFEckJH/dazR/OCUJgJSC9OQyjgFKCJFFi22G5Qu/q tS23B0mdvfTVqzuJw4tyeAGMECIAoJSoHEHqN6G7eAinuv1kmpDCbJk0q 8rikD1cVvRybDXwizYJNdb3njO+L4sK3B5d51iK9ShRFTOOdPml2prngi Cb2CUyxwLpczxyccb0+pxlDNx1jbaAY2luXRyDa9Q6DPzDUMr+Q0kgD8C QmaWeP9uki1Mr/5fS0ZdvRfVG++/6nmNKjxP0b+2+BE98E7HEKfVWu8lq /jPJlwV2GXElMoyKCidsLNiR5DHDoksajxJHJKCa2AhCydS10gFz13aAH w==; X-CSE-ConnectionGUID: Kn1cgKzKTtGAejKkN2A+wA== X-CSE-MsgGUID: Y7X7t/soSeOJ3oNN1SrKdw== X-IronPort-AV: E=Sophos;i="6.10,213,1719903600"; d="scan'208";a="34622036" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa1.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 09 Sep 2024 01:26:33 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.87.72) by chn-vm-ex02.mchp-main.com (10.10.87.72) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 9 Sep 2024 01:26:21 -0700 Received: from che-ll-i17164.microchip.com (10.10.85.11) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Mon, 9 Sep 2024 01:26:11 -0700 From: Parthiban Veerasooran To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , , , , , , , , , , , Parthiban Veerasooran Subject: [PATCH net-next v8 05/14] net: ethernet: oa_tc6: implement error interrupts unmasking Date: Mon, 9 Sep 2024 13:55:05 +0530 Message-ID: <20240909082514.262942-6-Parthiban.Veerasooran@microchip.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> References: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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. Reviewed-by: Andrew Lunn Signed-off-by: Parthiban Veerasooran --- 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 f774ed397213..86b032cdbee1 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 */ =20 +/* 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) @@ -327,6 +334,23 @@ static int oa_tc6_sw_reset_macphy(struct oa_tc6 *tc6) return oa_tc6_write_register(tc6, OA_TC6_REG_STATUS0, regval); } =20 +static int oa_tc6_unmask_macphy_error_interrupts(struct oa_tc6 *tc6) +{ + u32 regval; + int ret; + + ret =3D oa_tc6_read_register(tc6, OA_TC6_REG_INT_MASK0, ®val); + if (ret) + return ret; + + regval &=3D ~(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. @@ -369,6 +393,13 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi) return NULL; } =20 + ret =3D 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); --=20 2.34.1 From nobody Sat Nov 9 16:29:23 2024 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 791AB1B1506; Mon, 9 Sep 2024 08:26:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.153.233 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870398; cv=none; b=P/j5EKJoibO5Ctkotz9BMcv+rtOv09j74otk+TzMUEKw8/WLoup4JAuobEhnH+x+I3z/hmIpdqLLC2lrYO0jyhkf3pXArWvi4ibHK5NkdY9rZjncwsG+A/wyelKFUl3qB+JFsCh8+pS7/iXFuh4d9v2v4jV/z3NPH3tmwhin9+k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870398; c=relaxed/simple; bh=dLBSNhfXtcYX4kBTM/5pzsARi0SjRQE4zP+21tij2kQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DkNDulLB0AuITbV5R2k4hj/kmAyJdhlkESzEwUh4XcshiUKpJlmMa/N3PDlr2J67JArzgN6D0odztIt+NlYU8RODbwa11hDH0l4uSMzRFcgnh0k+fM4T/G2W+e+eObyNlySMPFKB8suiX+NfETmroOuyH/Oyj3zsAvQAZVG3r08= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=dz3PDcuU; arc=none smtp.client-ip=68.232.153.233 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="dz3PDcuU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1725870396; x=1757406396; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=dLBSNhfXtcYX4kBTM/5pzsARi0SjRQE4zP+21tij2kQ=; b=dz3PDcuUfA9En7UUnhi+R5Bm6OSqowfRnEYKvIAnaStbPjDZZlGAfgUE oxBsfQ5tRPEy2FaNKgi9A+BQ6wZG5YrAdIYN8y25pMXpMxM26enE0KtBd mgf7giOaZHclmpkXMpF8V2vdFTW8TA8BJ0+SSw0xtlnCBeckLUndjpnCI blu/7ytfhi4Hdo+PxVmW9yhL2akAkzw7Xq9NGhAeQ95N7WNuBqc+fosw/ g/cRu1aG2Ph8/qdMZ+NF2Cs40onMl2MbiSt9AQeulzw0TtivZzDkW6QIM lQIsdC9MDyHvxjBFtljz6NDRwryu4zPHvgUaDdQfNFCFckKRHhZcOl6Ci Q==; X-CSE-ConnectionGUID: d/w4Y2PcQAuCOQlGJPomLA== X-CSE-MsgGUID: BSQLloTXQniuFxgAHjR5hA== X-IronPort-AV: E=Sophos;i="6.10,213,1719903600"; d="scan'208";a="34622050" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa1.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 09 Sep 2024 01:26:34 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 9 Sep 2024 01:26:32 -0700 Received: from che-ll-i17164.microchip.com (10.10.85.11) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Mon, 9 Sep 2024 01:26:22 -0700 From: Parthiban Veerasooran To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , , , , , , , , , , , Parthiban Veerasooran Subject: [PATCH net-next v8 06/14] net: ethernet: oa_tc6: implement internal PHY initialization Date: Mon, 9 Sep 2024 13:55:06 +0530 Message-ID: <20240909082514.262942-7-Parthiban.Veerasooran@microchip.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> References: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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. Reviewed-by: Andrew Lunn Signed-off-by: Parthiban Veerasooran --- drivers/net/ethernet/oa_tc6.c | 230 +++++++++++++++++++++++++++++++++- include/linux/oa_tc6.h | 4 +- include/uapi/linux/mdio.h | 1 + 3 files changed, 233 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c index 86b032cdbee1..fc276d881dc9 100644 --- a/drivers/net/ethernet/oa_tc6.c +++ b/drivers/net/ethernet/oa_tc6.c @@ -7,9 +7,15 @@ =20 #include #include +#include +#include #include =20 /* 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) =20 +/* PHY Clause 22 registers base address and mask */ +#define OA_TC6_PHY_STD_REG_ADDR_BASE 0xFF00 +#define OA_TC6_PHY_STD_REG_ADDR_MASK 0x1F + /* 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) =20 +/* PHY =E2=80=93 Clause 45 registers memory map selector (MMS) as per tabl= e 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 @@ =20 /* 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 add= ress, u32 value) } EXPORT_SYMBOL_GPL(oa_tc6_write_register); =20 +static int oa_tc6_check_phy_reg_direct_access_capability(struct oa_tc6 *tc= 6) +{ + u32 regval; + int ret; + + ret =3D oa_tc6_read_register(tc6, OA_TC6_REG_STDCAP, ®val); + 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 =3D bus->priv; + u32 regval; + bool ret; + + ret =3D oa_tc6_read_register(tc6, OA_TC6_PHY_STD_REG_ADDR_BASE | + (regnum & OA_TC6_PHY_STD_REG_ADDR_MASK), + ®val); + if (ret) + return ret; + + return regval; +} + +static int oa_tc6_mdiobus_write(struct mii_bus *bus, int addr, int regnum, + u16 val) +{ + struct oa_tc6 *tc6 =3D 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 devn= um, + int regnum) +{ + struct oa_tc6 *tc6 =3D bus->priv; + u32 regval; + int ret; + + ret =3D oa_tc6_get_phy_c45_mms(devnum); + if (ret < 0) + return ret; + + ret =3D oa_tc6_read_register(tc6, (ret << 16) | regnum, ®val); + if (ret) + return ret; + + return regval; +} + +static int oa_tc6_mdiobus_write_c45(struct mii_bus *bus, int addr, int dev= num, + int regnum, u16 val) +{ + struct oa_tc6 *tc6 =3D bus->priv; + int ret; + + ret =3D 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 =3D mdiobus_alloc(); + if (!tc6->mdiobus) { + netdev_err(tc6->netdev, "MDIO bus alloc failed\n"); + return -ENOMEM; + } + + tc6->mdiobus->priv =3D tc6; + tc6->mdiobus->read =3D oa_tc6_mdiobus_read; + tc6->mdiobus->write =3D 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 =3D oa_tc6_mdiobus_read_c45; + tc6->mdiobus->write_c45 =3D oa_tc6_mdiobus_write_c45; + tc6->mdiobus->name =3D "oa-tc6-mdiobus"; + tc6->mdiobus->parent =3D tc6->dev; + + snprintf(tc6->mdiobus->id, ARRAY_SIZE(tc6->mdiobus->id), "%s", + dev_name(&tc6->spi->dev)); + + ret =3D 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 =3D 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 =3D oa_tc6_mdiobus_register(tc6); + if (ret) + return ret; + + tc6->phydev =3D 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 =3D true; + ret =3D 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; @@ -354,11 +562,12 @@ static int oa_tc6_unmask_macphy_error_interrupts(stru= ct 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. * * Return: 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 *netd= ev) { struct oa_tc6 *tc6; int ret; @@ -368,6 +577,8 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi) return NULL; =20 tc6->spi =3D spi; + tc6->netdev =3D netdev; + SET_NETDEV_DEV(netdev, &spi->dev); mutex_init(&tc6->spi_ctrl_lock); =20 /* Set the SPI controller to pump at realtime priority */ @@ -400,10 +611,27 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi) return NULL; } =20 + ret =3D 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); =20 +/** + * 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=E2=80=91T1x MAC=E2=80=91PHY Seria= l Interface Lib"); MODULE_AUTHOR("Parthiban Veerasooran = "); MODULE_LICENSE("GPL"); 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 */ =20 +#include #include =20 struct oa_tc6; =20 -struct oa_tc6 *oa_tc6_init(struct spi_device *spi); +struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netd= ev); +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 */ --=20 2.34.1 From nobody Sat Nov 9 16:29:23 2024 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D11B71B1D7E; Mon, 9 Sep 2024 08:26:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.153.233 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870413; cv=none; b=LDqwHiTWysXaIJJdp60SPkHcGwcjEq/rIW2kgnJzPWOcvNWeKAR8ojIbrZULsn++CkqqGlF9fEdY1Uca+2TsNqIyvinJ22IthPu9toeGOiflO34eFSU9ONwRl97tOwK854GfCtrU66AanaRbF26Cz8lP1a9Nf64rlv4LnPYSoM8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870413; c=relaxed/simple; bh=6gPhNMCVkjsYb/iNe1vnvKXCmETz6HU3IFpjijceye8=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=GokuYnP7i/SBm9VMkibG0KSAHEQPVo6HbcrCFQ0EugS2lUUdNoXXlNX75tZXHAjwczB1I28L+ZLUa43mbt4ECpc3TcdIbClg0Itt+SdrHc1xt0jJI1OWOCaupZKvqZYLq40nGqBwmwmL4sN531dw4hzmtwzWRF9zP8T4kz/9oSY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=T8K+SztF; arc=none smtp.client-ip=68.232.153.233 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="T8K+SztF" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1725870412; x=1757406412; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=6gPhNMCVkjsYb/iNe1vnvKXCmETz6HU3IFpjijceye8=; b=T8K+SztFncB/ZWn/IhZxA/umkNDSTUK0kJYpqy+YKMkFu/rz7rv/pGGG eX9KlkNSWkviFePtjo5CuWQ+6jim9hIX8mjBpdNUSTz5vcUwlwB1iMXGf qCCzT4Ga3KAFxZVfUyX2RNtE33kB6PnNbmSkR1cNYobzdo6EkoKnl7VPE WQtwoZF8uz1eEpgb0WUNzTLozZSROXRRwbN0sC62DRlGa0LYEPsBfCgJt Uvl2/nsnbt38a3H/dh9Ux92AX+qihqIytF89uOOBU67hRhBm+Nwo2sfKI VOd383i3u7ztjy+UfPN6zQG77m0LiYESqHnzGijF4GsoQ1mGap5PaVSyA Q==; X-CSE-ConnectionGUID: IaT2qUr8REyxuKsTOysLmw== X-CSE-MsgGUID: xMJxFVp+SCm5j6scvTDsYw== X-IronPort-AV: E=Sophos;i="6.10,213,1719903600"; d="scan'208";a="262470616" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa5.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 09 Sep 2024 01:26:51 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 9 Sep 2024 01:26:43 -0700 Received: from che-ll-i17164.microchip.com (10.10.85.11) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Mon, 9 Sep 2024 01:26:33 -0700 From: Parthiban Veerasooran To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , , , , , , , , , , , Parthiban Veerasooran Subject: [PATCH net-next v8 07/14] net: phy: microchip_t1s: add c45 direct access in LAN865x internal PHY Date: Mon, 9 Sep 2024 13:55:07 +0530 Message-ID: <20240909082514.262942-8-Parthiban.Veerasooran@microchip.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> References: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This patch adds c45 registers direct access support in Microchip's LAN865x internal PHY. 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 Reviewed-by: Andrew Lunn Signed-off-by: Parthiban Veerasooran --- drivers/net/phy/microchip_t1s.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/net/phy/microchip_t1s.c b/drivers/net/phy/microchip_t1= s.c index 534ca7d1b061..3614839a8e51 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 *phyd= ev) return 0; } =20 +/* 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 a= ssumes + * it uses C22 protocol and always uses C22 registers indirect access to a= ccess + * 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 C= 45 + * registers direct access can't be used which can save multiple SPI bus a= ccess. + * 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 =3D phydev->mdio.bus; + int addr =3D phydev->mdio.addr; + + return __mdiobus_c45_read(bus, addr, devnum, regnum); +} + +static int lan865x_phy_write_mmd(struct phy_device *phydev, int devnum, + u16 regnum, u16 val) +{ + struct mii_bus *bus =3D phydev->mdio.bus; + int addr =3D phydev->mdio.addr; + + return __mdiobus_c45_write(bus, addr, devnum, regnum, val); +} + static struct phy_driver microchip_t1s_driver[] =3D { { PHY_ID_MATCH_EXACT(PHY_ID_LAN867X_REVB1), @@ -285,6 +313,8 @@ static struct phy_driver microchip_t1s_driver[] =3D { .features =3D PHY_BASIC_T1S_P2MP_FEATURES, .config_init =3D lan865x_revb0_config_init, .read_status =3D lan86xx_read_status, + .read_mmd =3D lan865x_phy_read_mmd, + .write_mmd =3D lan865x_phy_write_mmd, .get_plca_cfg =3D genphy_c45_plca_get_cfg, .set_plca_cfg =3D genphy_c45_plca_set_cfg, .get_plca_status =3D genphy_c45_plca_get_status, --=20 2.34.1 From nobody Sat Nov 9 16:29:23 2024 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A52F31B1D65; Mon, 9 Sep 2024 08:27:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.154.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870442; cv=none; b=AOa/Un8UbgANQCjG7on0Z/rQLp+0T2Cglwq2g3wH0RV803eJsHmn/CmZf3prq+2KDk/uxisBRv1JBUxC6E6xjLydXnTPtI56QrIVnp7xCcF9eoDbqvwzPZMMO5z3R8qZY2KO73N2m5UHZXcJBOVk/21LXurKI4g8dAW7ZjjsB5M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870442; c=relaxed/simple; bh=I5H+DCO9/fGkdq9xMaXHhtiR+lVrD1mPFooeaufi5s0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=NKJIhX/2svN4sYH0+pX5hbuNh9zj+WOkI3lE1tUXteqnDqJz3ZutHcI1ztNzGayoyeVNBi9hhM5q+3BZhT2o92xsKHbShZ0pwJuYSKExnJGxCZAB00kx7ln9LTuuugjIKau4NZsozjkOJGLxT+iHRCwzG2yYUOSqU6HwztLvjBk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=MUp2pJnv; arc=none smtp.client-ip=68.232.154.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="MUp2pJnv" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1725870440; x=1757406440; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=I5H+DCO9/fGkdq9xMaXHhtiR+lVrD1mPFooeaufi5s0=; b=MUp2pJnvFyRv67pPMOjiyw2XsRAtqAHxXQAjO8/zhLfZ6lYTf4Rl3n5A B72Nnsk42q1u09Cm6K5/nZeeAX6SEIFSAgL/UPnjT7vMY/rbiNpOjtno1 Jfb3ugmlBbUvzyaf6wO+EUUYC2JprzfMKzgT/KfwXwgiiGgpjJRG+eD3T ZuS+wozV2Z1nGmCuJCgpge19nZ55XlrvDHhgaUwhmnyhQ9uM9yXKJYTaq UKAfuWigjML3TnFBbe7ftULNOijOWYykirNv6uMHnj3vpIWJjAU9WDb+/ ucXZXjuqSEvpebWQmJSsSiaZvmdQSTbWq/dugMjOBUr14fUI/X9Db6f6H w==; X-CSE-ConnectionGUID: w4Dqm4EATAOwW8L/8a3sNg== X-CSE-MsgGUID: BmAF43ZXTu+ngaw6MfnJQQ== X-IronPort-AV: E=Sophos;i="6.10,213,1719903600"; d="scan'208";a="31409626" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa4.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 09 Sep 2024 01:27:19 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 9 Sep 2024 01:26:54 -0700 Received: from che-ll-i17164.microchip.com (10.10.85.11) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Mon, 9 Sep 2024 01:26:43 -0700 From: Parthiban Veerasooran To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , , , , , , , , , , , Parthiban Veerasooran Subject: [PATCH net-next v8 08/14] net: ethernet: oa_tc6: enable open alliance tc6 data communication Date: Mon, 9 Sep 2024 13:55:08 +0530 Message-ID: <20240909082514.262942-9-Parthiban.Veerasooran@microchip.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> References: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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. Reviewed-by: Andrew Lunn Signed-off-by: Parthiban Veerasooran --- 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 fc276d881dc9..8958af863b6e 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 */ =20 +/* 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 */ @@ -559,6 +563,21 @@ static int oa_tc6_unmask_macphy_error_interrupts(struc= t oa_tc6 *tc6) return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, regval); } =20 +static int oa_tc6_enable_data_transfer(struct oa_tc6 *tc6) +{ + u32 value; + int ret; + + ret =3D oa_tc6_read_register(tc6, OA_TC6_REG_CONFIG0, &value); + if (ret) + return ret; + + /* Enable configuration synchronization for data transfer */ + value |=3D 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. @@ -618,7 +637,18 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi, str= uct net_device *netdev) return NULL; } =20 + ret =3D 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); =20 --=20 2.34.1 From nobody Sat Nov 9 16:29:23 2024 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4B4C31B29CF; Mon, 9 Sep 2024 08:27:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.154.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870444; cv=none; b=oDAXwz1OaZfUgcHvu22LZWhrObBNu9rBB2TK9vnHmWKjnPxj7w3qOuBNZo9clkuMea4idGcYoTqqny5Q3eXfKdy6BbkQ+qz7TVfvL6cnaXVR5OWdSyxPTEAVLP3zUdI3jVDMbSO8GTEBkWemLwTR3VwmzU0I51NSVPcdryTxIIw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870444; c=relaxed/simple; bh=r1uxgoJPoE+8uqH5E+e/fMZqPM3mC7pDOl4tz6skaTg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Y2kgQt5QDw6woUHZowOsPF2OQWqEjhromVWyVwwbCyLwjJfHENU83eD4fljGyLQG24lj4IRUV693/mVyeOv0AQiijAtN30ZpbwfU7FvjN/Tlv9cmh/cEZPGPreSB35Sr3heQufNJ4rbbELNRxJqVoSzst7hmwHDOJ/12fpZ6AEo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=1uON09ww; arc=none smtp.client-ip=68.232.154.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="1uON09ww" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1725870442; x=1757406442; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=r1uxgoJPoE+8uqH5E+e/fMZqPM3mC7pDOl4tz6skaTg=; b=1uON09wwPbGDCBQ0lFI8OxQxK1hRDPzE24ttPGMn/6079j4XqYaWxCqh hoTFOX+dwpo6L5qCCdfEBN2lKPqB8IgAAAg07Z8htnuf7+PPdUuwjXf3U 3Lz+oGh7vAsPyHbOuXxXQm2kz6S86/bLJHl01pIOaUvgXGVibqVMgjNpz w6TGqBf37gvQR7XdA+COMlreKYfGVCA++hLo9w4kuxvlrLZIMeExpzkUb +34T2UFiYpA/YQnHobEigfId71AqQhP6l9pdGdPkFeUKM3HMXwZCyrOI/ q3xoylGUytvzYUC0q/3zf3wNfU9WEJMx4G/DluKgBzuYZZp4flbxguSnU w==; X-CSE-ConnectionGUID: w4Dqm4EATAOwW8L/8a3sNg== X-CSE-MsgGUID: KF2DK5evRoys+CSpqW0ioQ== X-IronPort-AV: E=Sophos;i="6.10,213,1719903600"; d="scan'208";a="31409630" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa4.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 09 Sep 2024 01:27:20 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 9 Sep 2024 01:27:05 -0700 Received: from che-ll-i17164.microchip.com (10.10.85.11) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Mon, 9 Sep 2024 01:26:54 -0700 From: Parthiban Veerasooran To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , , , , , , , , , , , Parthiban Veerasooran Subject: [PATCH net-next v8 09/14] net: ethernet: oa_tc6: implement transmit path to transfer tx ethernet frames Date: Mon, 9 Sep 2024 13:55:09 +0530 Message-ID: <20240909082514.262942-10-Parthiban.Veerasooran@microchip.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> References: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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. Reviewed-by: Andrew Lunn Signed-off-by: Parthiban Veerasooran --- drivers/net/ethernet/oa_tc6.c | 399 +++++++++++++++++++++++++++++++++- include/linux/oa_tc6.h | 1 + 2 files changed, 398 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c index 8958af863b6e..bbc4b7fce64c 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) =20 /* 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) =20 +/* 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 =E2=80=93 Clause 45 registers memory map selector (MMS) as per tabl= e 6 in the * OPEN Alliance specification. */ @@ -64,6 +86,13 @@ (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_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 =20 @@ -77,10 +106,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 *ongoing_tx_skb; + struct sk_buff *waiting_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; }; =20 enum oa_tc6_header_type { OA_TC6_CTRL_HEADER, + OA_TC6_DATA_HEADER, }; =20 enum oa_tc6_register_op { @@ -88,14 +127,34 @@ enum oa_tc6_register_op { OA_TC6_CTRL_REG_WRITE =3D 1, }; =20 +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 =3D { 0 }; struct spi_message msg; =20 - xfer.tx_buf =3D tc6->spi_ctrl_tx_buf; - xfer.rx_buf =3D tc6->spi_ctrl_rx_buf; + if (header_type =3D=3D OA_TC6_DATA_HEADER) { + xfer.tx_buf =3D tc6->spi_data_tx_buf; + xfer.rx_buf =3D tc6->spi_data_rx_buf; + } else { + xfer.tx_buf =3D tc6->spi_ctrl_tx_buf; + xfer.rx_buf =3D tc6->spi_ctrl_rx_buf; + } xfer.len =3D length; =20 spi_message_init(&msg); @@ -578,6 +637,309 @@ static int oa_tc6_enable_data_transfer(struct oa_tc6 = *tc6) return oa_tc6_write_register(tc6, OA_TC6_REG_CONFIG0, value); } =20 +static void oa_tc6_cleanup_ongoing_tx_skb(struct oa_tc6 *tc6) +{ + if (tc6->ongoing_tx_skb) { + tc6->netdev->stats.tx_dropped++; + kfree_skb(tc6->ongoing_tx_skb); + tc6->ongoing_tx_skb =3D NULL; + } +} + +static int oa_tc6_process_extended_status(struct oa_tc6 *tc6) +{ + u32 value; + int ret; + + ret =3D oa_tc6_read_register(tc6, OA_TC6_REG_STATUS0, &value); + if (ret) { + netdev_err(tc6->netdev, "STATUS0 register read failed: %d\n", + ret); + return ret; + } + + /* Clear the error interrupts status */ + ret =3D oa_tc6_write_register(tc6, OA_TC6_REG_STATUS0, value); + if (ret) { + netdev_err(tc6->netdev, "STATUS0 register write failed: %d\n", + ret); + return ret; + } + + 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 =3D FIELD_GET(OA_TC6_DATA_FOOTER_TX_CREDITS, footer); + + if (FIELD_GET(OA_TC6_DATA_FOOTER_EXTENDED_STS, footer)) { + int ret =3D 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_offse= t) +{ + u8 *rx_buf =3D tc6->spi_data_rx_buf; + __be32 footer; + + footer =3D *((__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 =3D 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 =3D 0; i < no_of_rx_chunks; i++) { + /* Last 4 bytes in each received chunk consist footer info */ + footer =3D oa_tc6_get_rx_chunk_footer(tc6, i * OA_TC6_CHUNK_SIZE + + OA_TC6_CHUNK_PAYLOAD_SIZE); + + ret =3D 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 =3D 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 |=3D 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_end_valid_info end_valid =3D OA_TC6_DATA_END_INVALID; + __be32 *tx_buf =3D tc6->spi_data_tx_buf + tc6->spi_data_tx_buf_offset; + u16 remaining_len =3D tc6->ongoing_tx_skb->len - tc6->tx_skb_offset; + u8 *tx_skb_data =3D tc6->ongoing_tx_skb->data + tc6->tx_skb_offset; + enum oa_tc6_data_start_valid_info start_valid; + u8 end_byte_offset =3D 0; + u16 length_to_copy; + + /* Initial value is assigned here to avoid more than 80 characters in + * the declaration place. + */ + start_valid =3D OA_TC6_DATA_START_INVALID; + + /* Set start valid if the current tx chunk contains the start of the tx + * ethernet frame. + */ + if (!tc6->tx_skb_offset) + start_valid =3D 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 =3D min_t(u16, remaining_len, 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 +=3D length_to_copy; + + /* Set end valid if the current tx chunk contains the end of the tx + * ethernet frame. + */ + if (tc6->ongoing_tx_skb->len =3D=3D tc6->tx_skb_offset) { + end_valid =3D OA_TC6_DATA_END_VALID; + end_byte_offset =3D length_to_copy - 1; + tc6->tx_skb_offset =3D 0; + tc6->netdev->stats.tx_bytes +=3D tc6->ongoing_tx_skb->len; + tc6->netdev->stats.tx_packets++; + kfree_skb(tc6->ongoing_tx_skb); + tc6->ongoing_tx_skb =3D NULL; + } + + *tx_buf =3D oa_tc6_prepare_data_header(OA_TC6_DATA_VALID, start_valid, + end_valid, end_byte_offset); + tc6->spi_data_tx_buf_offset +=3D 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 =3D 0; used_tx_credits < tc6->tx_credits; + used_tx_credits++) { + if (!tc6->ongoing_tx_skb) { + tc6->ongoing_tx_skb =3D tc6->waiting_tx_skb; + tc6->waiting_tx_skb =3D NULL; + } + if (!tc6->ongoing_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 =3D 0; + + tc6->spi_data_tx_buf_offset =3D 0; + + if (tc6->ongoing_tx_skb || tc6->waiting_tx_skb) + spi_length =3D oa_tc6_prepare_spi_tx_buf_for_tx_skbs(tc6); + + if (spi_length =3D=3D 0) + break; + + ret =3D 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 =3D 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 (!tc6->waiting_tx_skb && 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 =3D 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, tc6->waiting_tx_skb || + kthread_should_stop()); + + if (kthread_should_stop()) + break; + + ret =3D 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 =3D oa_tc6_read_register(tc6, OA_TC6_REG_BUFFER_STATUS, &value); + if (ret) + return ret; + + tc6->tx_credits =3D FIELD_GET(BUFFER_STATUS_TX_CREDITS_AVAILABLE, value); + + return 0; +} + +/** + * oa_tc6_start_xmit - function for sending the tx skb which consists ethe= rnet + * frame. + * @tc6: oa_tc6 struct. + * @skb: socket buffer in which the ethernet frame is stored. + * + * Return: 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 (tc6->waiting_tx_skb) { + 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; + } + + tc6->waiting_tx_skb =3D 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. @@ -616,6 +978,18 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi, str= uct net_device *netdev) if (!tc6->spi_ctrl_rx_buf) return NULL; =20 + tc6->spi_data_tx_buf =3D 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 =3D devm_kzalloc(&tc6->spi->dev, + OA_TC6_SPI_DATA_BUF_SIZE, + GFP_KERNEL); + if (!tc6->spi_data_rx_buf) + return NULL; + ret =3D oa_tc6_sw_reset_macphy(tc6); if (ret) { dev_err(&tc6->spi->dev, @@ -644,6 +1018,24 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi, st= ruct net_device *netdev) goto phy_exit; } =20 + ret =3D 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; + } + + init_waitqueue_head(&tc6->spi_wq); + + tc6->spi_thread =3D 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; =20 phy_exit: @@ -659,6 +1051,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->ongoing_tx_skb); + dev_kfree_skb_any(tc6->waiting_tx_skb); } EXPORT_SYMBOL_GPL(oa_tc6_exit); =20 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 addres= s, 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); --=20 2.34.1 From nobody Sat Nov 9 16:29:23 2024 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 35F621B14E6; Mon, 9 Sep 2024 08:27:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.153.233 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870469; cv=none; b=oLtmAoe5CxGH/YSu4x8ElAeoTphN78iQTmiYq+NJv2afFAUsvnGJPSOUkx/AoAZb670r+rrWjhRCnDDAEJQzjJ8fK90r3dw5RmRJeA/REKg7/y8Y2ywE84uMv6w+LXle/VSR+R5DoACwnXmV6kGvL3ci1Hequ5cK+ZImlFEjSbg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870469; c=relaxed/simple; bh=+RdObKzoZpW024M+uMLuuV+TUOsyldvW26jLPgr4a3A=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=dJu8uYcKSyVx4ad8GWrVuo0OX0Fo4pHG7XUJcrYqrh2JsZOfODL7fs6BHODHw1XhxyjmCa+eJgCgoqEjKctlOEMzRHH5d+iNM91DUMRIK84iMYXtMhvyxx9WLHHR8OieaXb9xdd9gaxh4/S2y61SXGLYPBoA/JPDiUSMoIh3aVg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=aurWl7ol; arc=none smtp.client-ip=68.232.153.233 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="aurWl7ol" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1725870467; x=1757406467; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+RdObKzoZpW024M+uMLuuV+TUOsyldvW26jLPgr4a3A=; b=aurWl7olJyD1s2OmA7LkxotYJwO5I9fHvEj5n2CxCSoBjEu1KF2jnaAY wBhXztwriyOZ/8d9/YA9Gtdy/MF9DcUOlFS0QhK7u56sCzMguMn79bBk1 WQBLSmui/E6uRXJ6mxchL1+dM47jVyLuH4xyN8ZvR40ue8KWnGjXINYJC p6yKKOCwKRZMiksTSY9LbKVM+4tk8thNUnY42c3q9nhKAWAML0+pYUYYi h0kUNKACOZWuhl/ddAnPSUjHV38Eerx86zco94Nan3skSVSmWTQTOZRZP sTi9LT8ouXbGDe0ghmvmquIu97u8tXsS4uAua08zfzyhBcxFabqMQFqM0 A==; X-CSE-ConnectionGUID: j/68WEKfSwCMycVyn6gidg== X-CSE-MsgGUID: +ZOsFVuWQ3+Gd7Xiq30vkQ== X-IronPort-AV: E=Sophos;i="6.10,213,1719903600"; d="scan'208";a="34622100" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa1.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 09 Sep 2024 01:27:46 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.87.72) by chn-vm-ex02.mchp-main.com (10.10.87.72) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 9 Sep 2024 01:27:16 -0700 Received: from che-ll-i17164.microchip.com (10.10.85.11) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Mon, 9 Sep 2024 01:27:05 -0700 From: Parthiban Veerasooran To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , , , , , , , , , , , Parthiban Veerasooran Subject: [PATCH net-next v8 10/14] net: ethernet: oa_tc6: implement receive path to receive rx ethernet frames Date: Mon, 9 Sep 2024 13:55:10 +0530 Message-ID: <20240909082514.262942-11-Parthiban.Veerasooran@microchip.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> References: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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. Reviewed-by: Andrew Lunn Signed-off-by: Parthiban Veerasooran --- drivers/net/ethernet/oa_tc6.c | 241 ++++++++++++++++++++++++++++++++-- 1 file changed, 233 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c index bbc4b7fce64c..72d95bad669f 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) =20 /* 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) =20 /* 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 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) =20 /* PHY =E2=80=93 Clause 45 registers memory map selector (MMS) as per tabl= e 6 in the @@ -110,11 +118,14 @@ struct oa_tc6 { void *spi_data_rx_buf; struct sk_buff *ongoing_tx_skb; struct sk_buff *waiting_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; }; =20 enum oa_tc6_header_type { @@ -637,6 +648,15 @@ static int oa_tc6_enable_data_transfer(struct oa_tc6 *= tc6) return oa_tc6_write_register(tc6, OA_TC6_REG_CONFIG0, value); } =20 +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 =3D NULL; + } +} + static void oa_tc6_cleanup_ongoing_tx_skb(struct oa_tc6 *tc6) { if (tc6->ongoing_tx_skb) { @@ -666,6 +686,13 @@ static int oa_tc6_process_extended_status(struct oa_tc= 6 *tc6) return ret; } =20 + if (FIELD_GET(STATUS0_RX_BUFFER_OVERFLOW_ERROR, value)) { + tc6->rx_buf_overflow =3D 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; @@ -690,8 +717,11 @@ static int oa_tc6_process_rx_chunk_footer(struct oa_tc= 6 *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 =3D FIELD_GET(OA_TC6_DATA_FOOTER_TX_CREDITS, footer); + tc6->rx_chunks_available =3D FIELD_GET(OA_TC6_DATA_FOOTER_RX_CHUNKS, + footer); =20 if (FIELD_GET(OA_TC6_DATA_FOOTER_EXTENDED_STS, footer)) { int ret =3D oa_tc6_process_extended_status(tc6); @@ -717,6 +747,141 @@ static int oa_tc6_process_rx_chunk_footer(struct oa_t= c6 *tc6, u32 footer) return 0; } =20 +static void oa_tc6_submit_rx_skb(struct oa_tc6 *tc6) +{ + tc6->rx_skb->protocol =3D eth_type_trans(tc6->rx_skb, tc6->netdev); + tc6->netdev->stats.rx_packets++; + tc6->netdev->stats.rx_bytes +=3D tc6->rx_skb->len; + + netif_rx(tc6->rx_skb); + + tc6->rx_skb =3D NULL; +} + +static void oa_tc6_update_rx_skb(struct oa_tc6 *tc6, u8 *payload, u8 lengt= h) +{ + memcpy(skb_put(tc6->rx_skb, length), payload, length); +} + +static int oa_tc6_allocate_rx_skb(struct oa_tc6 *tc6) +{ + tc6->rx_skb =3D netdev_alloc_skb_ip_align(tc6->netdev, tc6->netdev->mtu + + ETH_HLEN + ETH_FCS_LEN); + if (!tc6->rx_skb) { + tc6->netdev->stats.rx_dropped++; + return -ENOMEM; + } + + return 0; +} + +static int oa_tc6_prcs_complete_rx_frame(struct oa_tc6 *tc6, u8 *payload, + u16 size) +{ + int ret; + + ret =3D 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 =3D 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 *data, + u32 footer) +{ + u8 start_byte_offset =3D FIELD_GET(OA_TC6_DATA_FOOTER_START_WORD_OFFSET, + footer) * sizeof(u32); + u8 end_byte_offset =3D FIELD_GET(OA_TC6_DATA_FOOTER_END_BYTE_OFFSET, + footer); + bool start_valid =3D FIELD_GET(OA_TC6_DATA_FOOTER_START_VALID, footer); + bool end_valid =3D 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 =3D 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 =3D end_byte_offset + 1 - start_byte_offset; + return oa_tc6_prcs_complete_rx_frame(tc6, + &data[start_byte_offset], + size); + } + + /* Process the chunk with only rx frame start */ + if (start_valid && !end_valid) { + size =3D OA_TC6_CHUNK_PAYLOAD_SIZE - start_byte_offset; + return oa_tc6_prcs_rx_frame_start(tc6, + &data[start_byte_offset], + size); + } + + /* Process the chunk with only rx frame end */ + if (end_valid && !start_valid) { + size =3D end_byte_offset + 1; + oa_tc6_prcs_rx_frame_end(tc6, data, 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 =3D end_byte_offset + 1; + oa_tc6_prcs_rx_frame_end(tc6, data, size); + } + size =3D OA_TC6_CHUNK_PAYLOAD_SIZE - start_byte_offset; + return oa_tc6_prcs_rx_frame_start(tc6, + &data[start_byte_offset], + size); + } + + /* Process the chunk with ongoing rx frame data */ + oa_tc6_prcs_ongoing_rx_frame(tc6, data, footer); + + return 0; +} + static u32 oa_tc6_get_rx_chunk_footer(struct oa_tc6 *tc6, u16 footer_offse= t) { u8 *rx_buf =3D tc6->spi_data_rx_buf; @@ -742,6 +907,20 @@ static int oa_tc6_process_spi_data_rx_buf(struct oa_tc= 6 *tc6, u16 length) ret =3D 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 =3D tc6->spi_data_rx_buf + i * + OA_TC6_CHUNK_SIZE; + + ret =3D oa_tc6_prcs_rx_chunk_payload(tc6, payload, + footer); + if (ret) + return ret; + } } =20 return 0; @@ -834,31 +1013,74 @@ static u16 oa_tc6_prepare_spi_tx_buf_for_tx_skbs(str= uct oa_tc6 *tc6) return used_tx_credits * OA_TC6_CHUNK_SIZE; } =20 +static void oa_tc6_add_empty_chunks_to_spi_buf(struct oa_tc6 *tc6, + u16 needed_empty_chunks) +{ + __be32 header; + + header =3D 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 =3D tc6->spi_data_tx_buf + + tc6->spi_data_tx_buf_offset; + + *tx_buf =3D header; + tc6->spi_data_tx_buf_offset +=3D OA_TC6_CHUNK_SIZE; + } +} + +static u16 oa_tc6_prepare_spi_tx_buf_for_rx_chunks(struct oa_tc6 *tc6, u16= len) +{ + u16 tx_chunks =3D 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 >=3D tc6->rx_chunks_available) + return len; + + needed_empty_chunks =3D 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; =20 while (true) { - u16 spi_length =3D 0; + u16 spi_len =3D 0; =20 tc6->spi_data_tx_buf_offset =3D 0; =20 if (tc6->ongoing_tx_skb || tc6->waiting_tx_skb) - spi_length =3D oa_tc6_prepare_spi_tx_buf_for_tx_skbs(tc6); + spi_len =3D oa_tc6_prepare_spi_tx_buf_for_tx_skbs(tc6); =20 - if (spi_length =3D=3D 0) + spi_len =3D oa_tc6_prepare_spi_tx_buf_for_rx_chunks(tc6, spi_len); + + if (spi_len =3D=3D 0) break; =20 - ret =3D oa_tc6_spi_transfer(tc6, OA_TC6_DATA_HEADER, spi_length); + ret =3D oa_tc6_spi_transfer(tc6, OA_TC6_DATA_HEADER, spi_len); if (ret) { netdev_err(tc6->netdev, "SPI data transfer failed: %d\n", ret); return ret; } =20 - ret =3D oa_tc6_process_spi_data_rx_buf(tc6, spi_length); + ret =3D oa_tc6_process_spi_data_rx_buf(tc6, spi_len); if (ret) { + if (ret =3D=3D -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; } @@ -896,15 +1118,17 @@ static int oa_tc6_update_buffer_status_from_register= (struct oa_tc6 *tc6) u32 value; int ret; =20 - /* 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 =3D oa_tc6_read_register(tc6, OA_TC6_REG_BUFFER_STATUS, &value); if (ret) return ret; =20 tc6->tx_credits =3D FIELD_GET(BUFFER_STATUS_TX_CREDITS_AVAILABLE, value); + tc6->rx_chunks_available =3D FIELD_GET(BUFFER_STATUS_RX_CHUNKS_AVAILABLE, + value); =20 return 0; } @@ -1054,6 +1278,7 @@ void oa_tc6_exit(struct oa_tc6 *tc6) kthread_stop(tc6->spi_thread); dev_kfree_skb_any(tc6->ongoing_tx_skb); dev_kfree_skb_any(tc6->waiting_tx_skb); + dev_kfree_skb_any(tc6->rx_skb); } EXPORT_SYMBOL_GPL(oa_tc6_exit); =20 --=20 2.34.1 From nobody Sat Nov 9 16:29:23 2024 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 866D41B14FC; Mon, 9 Sep 2024 08:27:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.153.233 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870471; cv=none; b=b+TQ53YSLd40KAWcsvluXr/eB+qAR28jAQnUQvRIl91eezaU21qJbvwpoxrk39H9jeH3euYTcBq9U/ghTQZAh4SNHi5m/5mPNYTB6vy51tLjNJkj/ufbakRRBe2r5vqUVJMxXO3mnvwdv4uADU23587SBiH9eolg9YB+x4JBHfE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870471; c=relaxed/simple; bh=+sI/jz+0k99u+/1sONE4Ydtk43cvotichTjvmCtOzAo=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=bVZgr3lwChONw02N7uOF3gLLjAldmJJY6nBfJhLXN49VIMM5R2/iNVjwh4J++BV80OjPlmkYfHFt72/N84soWXrMCli8FifXxsjH4vqbHhfHLsvUucookfWuI4wCwOtl2/iUR9jDx7w/nqEDSwDscTLuXkooha42Bx3I1+b8iZA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=t+GuVrEh; arc=none smtp.client-ip=68.232.153.233 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="t+GuVrEh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1725870469; x=1757406469; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+sI/jz+0k99u+/1sONE4Ydtk43cvotichTjvmCtOzAo=; b=t+GuVrEhQUIcB/2LHvMoTIT5EGhn1p9WA91eQ4ydIcn5QH3NH9bUUncm iKrjS1tAbyYXyJsRZWdxy4AqcTKffftPa0GALK5NHvy1btJSnC6LJgmN2 wDXk3FII5cz73uAi+QWvwJctJcudlupfzjEcWBCwGR+LLrL4cWllncF81 PDAfT7jZAgBFpO0CVLWRtiMXVj8vyM55hbn70bd6bNgA8jVHMtTHdOo5a C8vc8am2aXWVMUv6qCbSPKF8FK5jJlgNB11UGzeIwILeS5uphEx1IRwDP dIPYjyWYJEPxAWPKOks34DJsJxkWJSsZh1MfRJ4HD/K5UYGo0/FE4meDd g==; X-CSE-ConnectionGUID: j/68WEKfSwCMycVyn6gidg== X-CSE-MsgGUID: V6cS02hrRJqOwjkyBHyt5Q== X-IronPort-AV: E=Sophos;i="6.10,213,1719903600"; d="scan'208";a="34622101" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa1.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 09 Sep 2024 01:27:46 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.87.72) by chn-vm-ex02.mchp-main.com (10.10.87.72) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 9 Sep 2024 01:27:27 -0700 Received: from che-ll-i17164.microchip.com (10.10.85.11) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Mon, 9 Sep 2024 01:27:17 -0700 From: Parthiban Veerasooran To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , , , , , , , , , , , Parthiban Veerasooran Subject: [PATCH net-next v8 11/14] net: ethernet: oa_tc6: implement mac-phy interrupt Date: Mon, 9 Sep 2024 13:55:11 +0530 Message-ID: <20240909082514.262942-12-Parthiban.Veerasooran@microchip.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> References: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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. Reviewed-by: Andrew Lunn Signed-off-by: Parthiban Veerasooran --- drivers/net/ethernet/oa_tc6.c | 52 ++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c index 72d95bad669f..d3510dc19273 100644 --- a/drivers/net/ethernet/oa_tc6.c +++ b/drivers/net/ethernet/oa_tc6.c @@ -126,6 +126,7 @@ struct oa_tc6 { u16 tx_credits; u8 rx_chunks_available; bool rx_buf_overflow; + bool int_flag; }; =20 enum oa_tc6_header_type { @@ -1064,6 +1065,14 @@ static int oa_tc6_try_spi_transfer(struct oa_tc6 *tc= 6) =20 spi_len =3D oa_tc6_prepare_spi_tx_buf_for_rx_chunks(tc6, spi_len); =20 + if (tc6->int_flag) { + tc6->int_flag =3D false; + if (spi_len =3D=3D 0) { + oa_tc6_add_empty_chunks_to_spi_buf(tc6, 1); + spi_len =3D OA_TC6_CHUNK_SIZE; + } + } + if (spi_len =3D=3D 0) break; =20 @@ -1098,8 +1107,11 @@ static int oa_tc6_spi_thread_handler(void *data) int ret; =20 while (likely(!kthread_should_stop())) { - /* This kthread will be waken up if there is a tx skb */ + /* 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->waiting_tx_skb || + tc6->int_flag || kthread_should_stop()); =20 if (kthread_should_stop()) @@ -1133,6 +1145,24 @@ static int oa_tc6_update_buffer_status_from_register= (struct oa_tc6 *tc6) return 0; } =20 +static irqreturn_t oa_tc6_macphy_isr(int irq, void *data) +{ + struct oa_tc6 *tc6 =3D 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 =3D 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 ethe= rnet * frame. @@ -1260,8 +1290,28 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi, s= truct net_device *netdev) =20 sched_set_fifo(tc6->spi_thread); =20 + ret =3D 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 =3D true; + wake_up_interruptible(&tc6->spi_wq); + return tc6; =20 +kthread_stop: + kthread_stop(tc6->spi_thread); phy_exit: oa_tc6_phy_exit(tc6); return NULL; --=20 2.34.1 From nobody Sat Nov 9 16:29:23 2024 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3C7931B141E; Mon, 9 Sep 2024 08:28:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.153.233 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870498; cv=none; b=s00GuMO8bmPnkap6iOS9jF2dg+M0Or1WGNHawIeEuC1ak8qQwCOB0ld4uwdIfwnrTYDnd3pAHYqpnqDyyDgqO7bafa1DUbOy6lRJTXIAxkRP/4DtXQZ4xpJdk1meXlykt7wCwibqjka4gKND86JR8pEkURJkEhtxFuSSFN0Jh/M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870498; c=relaxed/simple; bh=h7a40xJEsSy5K3OxX1zTNWZaRI04YfSGn4CI0EKDF8g=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OoxqihjvjGyQt3Fkc2dWi9xJ7igpYooi/G2xPlWuzf9MG8lWGWkACH4M+CRTXT8BFZFul/0jRFIHKHcf7Xh5vyfQQBd5Pp1ulL8ZITRJ/pFzWWGeEGYBOzZgDIjbeSceVApl02nFo3OrGYYj35LAByyuQbU8tiybEMQt9Cf5mGc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=VPNz+2Dt; arc=none smtp.client-ip=68.232.153.233 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="VPNz+2Dt" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1725870498; x=1757406498; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=h7a40xJEsSy5K3OxX1zTNWZaRI04YfSGn4CI0EKDF8g=; b=VPNz+2Dt7jcPQ+iKLG1x5Ymd2VdijrgOnWzHYGgWBVsQihdXtsJTTxWR o+5KINjaPIYTNlkp8f48c5g52naeAbbC8HhuKKwfDLc76MnR9obuz6Gz1 v8PCXMTo4K8PB0q7VGAkAF8ErcQZOfAhxAm8gAU23wQVBd4ATSWtUZFb1 +isqXALFymMB0av65u7kSdKXcli3s3yBkJJt+f+hIBFG77RUI0IINggno 5C1gnR9Fgs+LlqbJsEgtm0JJcwHEZ5qM27Q8MMYWvZPnZsq6hzJwleshv +IZSM5Y+GGIxora65zS77QQZDQFp+DGnQjf0DxIAMKL2KcYOX5wERIEgE g==; X-CSE-ConnectionGUID: Z/y7ygwVR+qaQBBhmAQUgg== X-CSE-MsgGUID: g6yRFxW9Q3epg1iX8o+ZTw== X-IronPort-AV: E=Sophos;i="6.10,213,1719903600"; d="scan'208";a="31495050" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa3.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 09 Sep 2024 01:28:16 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 9 Sep 2024 01:27:38 -0700 Received: from che-ll-i17164.microchip.com (10.10.85.11) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Mon, 9 Sep 2024 01:27:28 -0700 From: Parthiban Veerasooran To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , , , , , , , , , , , Parthiban Veerasooran Subject: [PATCH net-next v8 12/14] net: ethernet: oa_tc6: add helper function to enable zero align rx frame Date: Mon, 9 Sep 2024 13:55:12 +0530 Message-ID: <20240909082514.262942-13-Parthiban.Veerasooran@microchip.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> References: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Zero align receive frame feature can be enabled to align all receive ethernet frames data to start at the beginning of any receive data chunk payload with a start word offset (SWO) of zero. Receive frames may begin anywhere within the receive data chunk payload when this feature is not enabled. Reviewed-by: Andrew Lunn Signed-off-by: Parthiban Veerasooran --- drivers/net/ethernet/oa_tc6.c | 24 ++++++++++++++++++++++++ include/linux/oa_tc6.h | 1 + 2 files changed, 25 insertions(+) diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c index d3510dc19273..f9c0dcd965c2 100644 --- a/drivers/net/ethernet/oa_tc6.c +++ b/drivers/net/ethernet/oa_tc6.c @@ -23,6 +23,7 @@ /* Configuration Register #0 */ #define OA_TC6_REG_CONFIG0 0x0004 #define CONFIG0_SYNC BIT(15) +#define CONFIG0_ZARFE_ENABLE BIT(12) =20 /* Status Register #0 */ #define OA_TC6_REG_STATUS0 0x0008 @@ -1163,6 +1164,29 @@ static irqreturn_t oa_tc6_macphy_isr(int irq, void *= data) return IRQ_HANDLED; } =20 +/** + * oa_tc6_zero_align_receive_frame_enable - function to enable zero align + * receive frame feature. + * @tc6: oa_tc6 struct. + * + * Return: 0 on success otherwise failed. + */ +int oa_tc6_zero_align_receive_frame_enable(struct oa_tc6 *tc6) +{ + u32 regval; + int ret; + + ret =3D oa_tc6_read_register(tc6, OA_TC6_REG_CONFIG0, ®val); + if (ret) + return ret; + + /* Set Zero-Align Receive Frame Enable */ + regval |=3D CONFIG0_ZARFE_ENABLE; + + return oa_tc6_write_register(tc6, OA_TC6_REG_CONFIG0, regval); +} +EXPORT_SYMBOL_GPL(oa_tc6_zero_align_receive_frame_enable); + /** * oa_tc6_start_xmit - function for sending the tx skb which consists ethe= rnet * frame. diff --git a/include/linux/oa_tc6.h b/include/linux/oa_tc6.h index 5c7811ac9cbe..15f58e3c56c7 100644 --- a/include/linux/oa_tc6.h +++ b/include/linux/oa_tc6.h @@ -21,3 +21,4 @@ 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); +int oa_tc6_zero_align_receive_frame_enable(struct oa_tc6 *tc6); --=20 2.34.1 From nobody Sat Nov 9 16:29:23 2024 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 677011B141E; Mon, 9 Sep 2024 08:28:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.154.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870484; cv=none; b=IgMWyh1C54l64B4kf2tN+uD35BiwLlSle9bp09s5RdfjCjjpLFG23YeurE0WyW08UErFK+O6Rhu4bNtj9wOE6hSkc+kObabbvju3XqLFCpdrQvygTggQOi/UBrVVgvLIez6D7c2NLdtomlL5O48NgQ8qE49HyB5ZbBB99IiC0Bw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870484; c=relaxed/simple; bh=a69kbo3flHjkZqjED3fOdOmSrUgPr+MKjeiDkqwXbNc=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OfzXkgQbBfPgvFfPPn2uBRqb59dIS9H7XRnkGz5mGCl0U+3H30vkYb1Q8ma1nBHxgyV6RVtd3C+Ey9gBiEYzoJUh73cGZ/aZwQdSZjK1MU9j6fbvM/bO4eNSFsp4ZCq26O/YA6/vRBhTP1JduJb9lCJmBytJL48JJ1l39oTlotA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=ZgT5Kdxn; arc=none smtp.client-ip=68.232.154.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="ZgT5Kdxn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1725870482; x=1757406482; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=a69kbo3flHjkZqjED3fOdOmSrUgPr+MKjeiDkqwXbNc=; b=ZgT5Kdxnh+NgnuYpi2CUPvBWtqdRYazuq575b1Tu8wjx4RXG24ToWSJt 1G0VDej3DtBzmbWvFHkg7u8Wut4D2etYzkk2nz7PBDFJZJMak/ZEcaIUv qee1sku0NtYxZ+teuSU71nk8KmPJZ2xPhiw5Latdx5ok4m+lJsISf8llw mLED+yf26of5n3h/DK4h3zCKnw5LErfINtoxFGgRUNYLTVQ7MvCngqmG7 U2L1wY4iZYpWVBNJXR3fyYIvlhB7ec2LXTOWEYfX2aLwXay6KTvacSryY 2Mjaj5RLLMNiaMVZv9GJGoz9TelCWazo3q5tD/YmKp9M5wqrcIfwctxW1 Q==; X-CSE-ConnectionGUID: JiKJu3SpR26ZHEfqOdGNLw== X-CSE-MsgGUID: l5WlzgR5SUiUefdLCTiktA== X-IronPort-AV: E=Sophos;i="6.10,213,1719903600"; d="scan'208";a="198940013" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa6.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 09 Sep 2024 01:28:01 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 9 Sep 2024 01:27:49 -0700 Received: from che-ll-i17164.microchip.com (10.10.85.11) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Mon, 9 Sep 2024 01:27:39 -0700 From: Parthiban Veerasooran To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , , , , , , , , , , , Parthiban Veerasooran Subject: [PATCH net-next v8 13/14] microchip: lan865x: add driver support for Microchip's LAN865X MAC-PHY Date: Mon, 9 Sep 2024 13:55:13 +0530 Message-ID: <20240909082514.262942-14-Parthiban.Veerasooran@microchip.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> References: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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). Reviewed-by: Andrew Lunn Signed-off-by: Parthiban Veerasooran --- 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 | 429 ++++++++++++++++++ 6 files changed, 462 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 a8783e6f4e86..89d038c2e94b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14979,6 +14979,12 @@ L: netdev@vger.kernel.org S: Maintained F: drivers/net/ethernet/microchip/lan743x_* =20 +MICROCHIP LAN8650/1 10BASE-T1S MACPHY ETHERNET DRIVER +M: Parthiban Veerasooran +L: netdev@vger.kernel.org +S: Maintained +F: drivers/net/ethernet/microchip/lan865x/lan865x.c + MICROCHIP LAN87xx/LAN937x T1 PHY DRIVER M: Arun Ramadoss R: UNGLinuxDriver@microchip.com diff --git a/drivers/net/ethernet/microchip/Kconfig b/drivers/net/ethernet/= microchip/Kconfig index ce2435987fb6..99c624755bc4 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. =20 +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 94045537b643..3c65baed9fd8 100644 --- a/drivers/net/ethernet/microchip/Makefile +++ b/drivers/net/ethernet/microchip/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_LAN743X) +=3D lan743x.o =20 lan743x-objs :=3D lan743x_main.o lan743x_ethtool.o lan743x_ptp.o =20 +obj-$(CONFIG_LAN865X) +=3D lan865x/ obj-$(CONFIG_LAN966X_SWITCH) +=3D lan966x/ obj-$(CONFIG_SPARX5_SWITCH) +=3D sparx5/ obj-$(CONFIG_VCAP) +=3D vcap/ diff --git a/drivers/net/ethernet/microchip/lan865x/Kconfig b/drivers/net/e= thernet/microchip/lan865x/Kconfig new file mode 100644 index 000000000000..7f2a4e7e1915 --- /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 + select OA_TC6 + help + Support for the Microchip LAN8650/1 Rev.B0/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) +=3D 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..dd436bdff0f8 --- /dev/null +++ b/drivers/net/ethernet/microchip/lan865x/lan865x.c @@ -0,0 +1,429 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Microchip's LAN865x 10BASE-T1S MAC-PHY driver + * + * Author: Parthiban Veerasooran + */ + +#include +#include +#include +#include + +#define DRV_NAME "lan8650" + +/* 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 */ + +/* MAC Network Configuration Reg */ +#define LAN865X_REG_MAC_NET_CFG 0x00010001 +#define MAC_NET_CFG_PROMISCUOUS_MODE BIT(4) +#define MAC_NET_CFG_MULTICAST_MODE BIT(6) +#define MAC_NET_CFG_UNICAST_MODE BIT(7) + +/* MAC Hash Register Bottom */ +#define LAN865X_REG_MAC_L_HASH 0x00010020 +/* MAC Hash Register Top */ +#define LAN865X_REG_MAC_H_HASH 0x00010021 +/* MAC Specific Addr 1 Bottom Reg */ +#define LAN865X_REG_MAC_L_SADDR1 0x00010022 +/* MAC Specific Addr 1 Top Reg */ +#define LAN865X_REG_MAC_H_SADDR1 0x00010023 + +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 =3D (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 =3D lan865x_set_hw_macaddr_low_bytes(priv->tc6, mac); + if (ret) + return ret; + + /* Prepare and configure MAC address high bytes */ + regval =3D (mac[5] << 8) | mac[4]; + ret =3D 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 =3D lan865x_set_hw_macaddr_low_bytes(priv->tc6, + priv->netdev->dev_addr); + if (restore_ret) + return restore_ret; + + return ret; +} + +static const struct ethtool_ops lan865x_ethtool_ops =3D { + .get_link_ksettings =3D phy_ethtool_get_link_ksettings, + .set_link_ksettings =3D phy_ethtool_set_link_ksettings, +}; + +static int lan865x_set_mac_address(struct net_device *netdev, void *addr) +{ + struct lan865x_priv *priv =3D netdev_priv(netdev); + struct sockaddr *address =3D addr; + int ret; + + ret =3D 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 =3D lan865x_set_hw_macaddr(priv, address->sa_data); + if (ret) + return ret; + + eth_commit_mac_addr_change(netdev, addr); + + return 0; +} + +static u32 get_address_bit(u8 addr[ETH_ALEN], u32 bit) +{ + return ((addr[bit / 8]) >> (bit % 8)) & 1; +} + +static u32 lan865x_hash(u8 addr[ETH_ALEN]) +{ + u32 hash_index =3D 0; + + for (int i =3D 0; i < 6; i++) { + u32 hash =3D 0; + + for (int j =3D 0; j < 8; j++) + hash ^=3D get_address_bit(addr, (j * 6) + i); + + hash_index |=3D (hash << i); + } + + return hash_index; +} + +static int lan865x_set_specific_multicast_addr(struct lan865x_priv *priv) +{ + struct netdev_hw_addr *ha; + u32 hash_lo =3D 0; + u32 hash_hi =3D 0; + int ret; + + netdev_for_each_mc_addr(ha, priv->netdev) { + u32 bit_num =3D lan865x_hash(ha->addr); + + if (bit_num >=3D BIT(5)) + hash_hi |=3D (1 << (bit_num - BIT(5))); + else + hash_lo |=3D (1 << bit_num); + } + + /* Enabling specific multicast addresses */ + ret =3D oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_H_HASH, hash_hi); + if (ret) { + netdev_err(priv->netdev, "Failed to write reg_hashh: %d\n", + ret); + return ret; + } + + ret =3D oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_L_HASH, hash_lo); + if (ret) + netdev_err(priv->netdev, "Failed to write reg_hashl: %d\n", + ret); + + return ret; +} + +static int lan865x_set_all_multicast_addr(struct lan865x_priv *priv) +{ + int ret; + + /* Enabling all multicast addresses */ + ret =3D oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_H_HASH, + 0xffffffff); + if (ret) { + netdev_err(priv->netdev, "Failed to write reg_hashh: %d\n", + ret); + return ret; + } + + ret =3D oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_L_HASH, + 0xffffffff); + if (ret) + netdev_err(priv->netdev, "Failed to write reg_hashl: %d\n", + ret); + + return ret; +} + +static int lan865x_clear_all_multicast_addr(struct lan865x_priv *priv) +{ + int ret; + + ret =3D oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_H_HASH, 0); + if (ret) { + netdev_err(priv->netdev, "Failed to write reg_hashh: %d\n", + ret); + return ret; + } + + ret =3D oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_L_HASH, 0); + if (ret) + netdev_err(priv->netdev, "Failed to write reg_hashl: %d\n", + ret); + + return ret; +} + +static void lan865x_multicast_work_handler(struct work_struct *work) +{ + struct lan865x_priv *priv =3D container_of(work, struct lan865x_priv, + multicast_work); + u32 regval =3D 0; + int ret; + + if (priv->netdev->flags & IFF_PROMISC) { + /* Enabling promiscuous mode */ + regval |=3D MAC_NET_CFG_PROMISCUOUS_MODE; + regval &=3D (~MAC_NET_CFG_MULTICAST_MODE); + regval &=3D (~MAC_NET_CFG_UNICAST_MODE); + } else if (priv->netdev->flags & IFF_ALLMULTI) { + /* Enabling all multicast mode */ + if (lan865x_set_all_multicast_addr(priv)) + return; + + regval &=3D (~MAC_NET_CFG_PROMISCUOUS_MODE); + regval |=3D MAC_NET_CFG_MULTICAST_MODE; + regval &=3D (~MAC_NET_CFG_UNICAST_MODE); + } else if (!netdev_mc_empty(priv->netdev)) { + /* Enabling specific multicast mode */ + if (lan865x_set_specific_multicast_addr(priv)) + return; + + regval &=3D (~MAC_NET_CFG_PROMISCUOUS_MODE); + regval |=3D MAC_NET_CFG_MULTICAST_MODE; + regval &=3D (~MAC_NET_CFG_UNICAST_MODE); + } else { + /* Enabling local mac address only */ + if (lan865x_clear_all_multicast_addr(priv)) + return; + } + ret =3D oa_tc6_write_register(priv->tc6, LAN865X_REG_MAC_NET_CFG, regval); + if (ret) + netdev_err(priv->netdev, "Failed to enable promiscuous/multicast/normal = mode: %d\n", + ret); +} + +static void lan865x_set_multicast_list(struct net_device *netdev) +{ + struct lan865x_priv *priv =3D 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 =3D 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, ®val)) + return -ENODEV; + + regval &=3D ~(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 =3D netdev_priv(netdev); + int ret; + + netif_stop_queue(netdev); + phy_stop(netdev->phydev); + ret =3D 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, ®val)) + return -ENODEV; + + regval |=3D 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 =3D netdev_priv(netdev); + int ret; + + ret =3D 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 =3D { + .ndo_open =3D lan865x_net_open, + .ndo_stop =3D lan865x_net_close, + .ndo_start_xmit =3D lan865x_send_packet, + .ndo_set_rx_mode =3D lan865x_set_multicast_list, + .ndo_set_mac_address =3D lan865x_set_mac_address, +}; + +static int lan865x_probe(struct spi_device *spi) +{ + struct net_device *netdev; + struct lan865x_priv *priv; + int ret; + + netdev =3D alloc_etherdev(sizeof(struct lan865x_priv)); + if (!netdev) + return -ENOMEM; + + priv =3D netdev_priv(netdev); + priv->netdev =3D netdev; + priv->spi =3D spi; + spi_set_drvdata(spi, priv); + INIT_WORK(&priv->multicast_work, lan865x_multicast_work_handler); + + priv->tc6 =3D oa_tc6_init(spi, netdev); + if (!priv->tc6) { + ret =3D -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=3D0). As + * recommended, enable zero align receive frame feature for proper + * operation. + * + * https://ww1.microchip.com/downloads/aemDocuments/documents/AIS/Product= Documents/Errata/LAN8650-1-Errata-80001075.pdf + */ + ret =3D oa_tc6_zero_align_receive_frame_enable(priv->tc6); + 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 =3D 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 =3D IF_PORT_10BASET; + netdev->irq =3D spi->irq; + netdev->netdev_ops =3D &lan865x_netdev_ops; + netdev->ethtool_ops =3D &lan865x_ethtool_ops; + + ret =3D register_netdev(netdev); + if (ret) { + dev_err(&spi->dev, "Register netdev failed (ret =3D %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 =3D 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 spi_device_id spidev_spi_ids[] =3D { + { .name =3D "lan8650" }, + {}, +}; + +static const struct of_device_id lan865x_dt_ids[] =3D { + { .compatible =3D "microchip,lan8650" }, + { /* Sentinel */ } +}; +MODULE_DEVICE_TABLE(of, lan865x_dt_ids); + +static struct spi_driver lan865x_driver =3D { + .driver =3D { + .name =3D DRV_NAME, + .of_match_table =3D lan865x_dt_ids, + }, + .probe =3D lan865x_probe, + .remove =3D lan865x_remove, + .id_table =3D spidev_spi_ids, +}; +module_spi_driver(lan865x_driver); + +MODULE_DESCRIPTION(DRV_NAME " 10Base-T1S MACPHY Ethernet Driver"); +MODULE_AUTHOR("Parthiban Veerasooran = "); +MODULE_LICENSE("GPL"); --=20 2.34.1 From nobody Sat Nov 9 16:29:23 2024 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E08A01B375B; Mon, 9 Sep 2024 08:28:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=68.232.154.123 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870514; cv=none; b=iGnu0zs1rwRMJORrNS70B4lvGkGrKxTTiMM/WxEFWIj2slgArYNGy8Gn1Ep1L+F0GxfoQmgjf5vwld0DewPBFt+XbjbN9qqzZjJHLY/OqbUo4DCOSPa0t+ZAbI+bOEVANmEfd189WbqBWlWrn9zjxwhNhQsbucFb3l7rAGVFOJM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725870514; c=relaxed/simple; bh=sfvsNr5K/hiEOOk8WIX3Bn/QtJvcLwOU4UcxKthOj3c=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OYVqyQqxcKd6KkkoIzR8MEXy74n5a80G3lF+N5lvO1gMElODsNLrvJoACG7G6xOLXHVfJQMaAZFXR9luFi2XWXd7kJq/uy73FniD2igFcjQpxo4t1ehCahSlBVM4v3BjqgcJDB1x3G8cWueKGaXASt4eKV3eeXRC/Pad02ZrJ5o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com; spf=pass smtp.mailfrom=microchip.com; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b=a1L81H8R; arc=none smtp.client-ip=68.232.154.123 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=microchip.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=microchip.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="a1L81H8R" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1725870512; x=1757406512; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=sfvsNr5K/hiEOOk8WIX3Bn/QtJvcLwOU4UcxKthOj3c=; b=a1L81H8RKoARe32cd8Z5Fljkbai8RtsLuJDoGEs2QeXU8bXc7XvCgmOz 4rxPEcIrzC3UW7oIEM1e5SEzUEYd1EhfY5wSqRG1826frH0GPJ0z2rsVy g7HNDY1kd47rA+GCJ23QiVEMTTm5aeqb917badgIpIZIXeh0C1ls+FwIx tENdLdbq8bOk6pOG4HD+gJacpI7Wh17c6ARWTaghUKlz9+9qE6LG6vVqV mn3CDIByPpAQZYqeMr+n8wrtIYv3xpoU15yBAOGdsgW+64ROx+HLdFY6U WEl1EB+xxxjne1S6PRt0YJIdoNluajDNQxteWKFRy0CsfwEQTzPR6DfTT A==; X-CSE-ConnectionGUID: ASzx8kNERhu8wJ4WimobFg== X-CSE-MsgGUID: oQQFZyUeT2esqUXJBqlJJg== X-IronPort-AV: E=Sophos;i="6.10,213,1719903600"; d="scan'208";a="198940031" X-Amp-Result: SKIPPED(no attachment in message) Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa6.microchip.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 09 Sep 2024 01:28:30 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.87.72) by chn-vm-ex02.mchp-main.com (10.10.87.72) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 9 Sep 2024 01:28:00 -0700 Received: from che-ll-i17164.microchip.com (10.10.85.11) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.2507.35 via Frontend Transport; Mon, 9 Sep 2024 01:27:50 -0700 From: Parthiban Veerasooran To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , , , , , , , , , , , Parthiban Veerasooran , Conor Dooley Subject: [PATCH net-next v8 14/14] dt-bindings: net: add Microchip's LAN865X 10BASE-T1S MACPHY Date: Mon, 9 Sep 2024 13:55:14 +0530 Message-ID: <20240909082514.262942-15-Parthiban.Veerasooran@microchip.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> References: <20240909082514.262942-1-Parthiban.Veerasooran@microchip.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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). Reviewed-by: Conor Dooley Reviewed-by: Andrew Lunn Signed-off-by: Parthiban Veerasooran --- .../bindings/net/microchip,lan8650.yaml | 74 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 75 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/microchip,lan8650= .yaml diff --git a/Documentation/devicetree/bindings/net/microchip,lan8650.yaml b= /Documentation/devicetree/bindings/net/microchip,lan8650.yaml new file mode 100644 index 000000000000..61e11d4a07c4 --- /dev/null +++ b/Documentation/devicetree/bindings/net/microchip,lan8650.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/microchip,lan8650.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip LAN8650/1 10BASE-T1S MACPHY Ethernet Controllers + +maintainers: + - Parthiban Veerasooran + +description: + The LAN8650/1 combines a Media Access Controller (MAC) and an Ethernet + PHY to enable 10BASE=E2=80=91T1S networks. The Ethernet Media Access Con= troller + (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: /schemas/net/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 + +required: + - compatible + - reg + - interrupts + - spi-max-frequency + +unevaluatedProperties: false + +examples: + - | + #include + #include + + spi { + #address-cells =3D <1>; + #size-cells =3D <0>; + + ethernet@0 { + compatible =3D "microchip,lan8651", "microchip,lan8650"; + reg =3D <0>; + pinctrl-names =3D "default"; + pinctrl-0 =3D <ð0_pins>; + interrupt-parent =3D <&gpio>; + interrupts =3D <6 IRQ_TYPE_EDGE_FALLING>; + local-mac-address =3D [04 05 06 01 02 03]; + spi-max-frequency =3D <15000000>; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 89d038c2e94b..1dd3347d8f01 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14983,6 +14983,7 @@ MICROCHIP LAN8650/1 10BASE-T1S MACPHY ETHERNET DRIV= ER M: Parthiban Veerasooran L: netdev@vger.kernel.org S: Maintained +F: Documentation/devicetree/bindings/net/microchip,lan8650.yaml F: drivers/net/ethernet/microchip/lan865x/lan865x.c =20 MICROCHIP LAN87xx/LAN937x T1 PHY DRIVER --=20 2.34.1