Commit aba43bdf authored by David S. Miller's avatar David S. Miller

Merge branch 'pcs-xpcs-mmap' into main

Serge Semin <fancer says:

====================
net: pcs: xpcs: Add memory-mapped device support

The main goal of this series is to extend the DW XPCS device support in
the kernel. Particularly the patchset adds a support of the DW XPCS
device with the MCI/APB3 IO interface registered as a platform device. In
order to have them utilized by the DW XPCS core the fwnode-based DW XPCS
descriptor creation procedure has been introduced. Finally the STMMAC
driver has been altered to support the DW XPCS passed via the 'pcs-handle'
property.

Note the series has been significantly re-developed since v1. So I even
had to change the subject. Anyway I've done my best to take all the noted
into account.

The series traditionally starts with a set of the preparation patches.
First one just moves the generic DW XPCS IDs macros from the internal
header file to the external one where some other IDs also reside. Second
patch splits up the xpcs_create() method to a set of the coherent
sub-functions for the sake of the further easier updates and to have it
looking less complicated. The goal of the next three patches is to extend
the DW XPCS ID management code by defining a new dw_xpcs_info structure
with both PCS and PMA IDs.

The next two patches provide the DW XPCS device DT-bindings and the
respective platform-device driver for the memory-mapped DW XPCS devices.
Besides the later patch makes use of the introduced dw_xpcs_info structure
to pre-define the DW XPCS IDs based on the platform-device compatible
string. Thus if there is no way to auto-identify the XPCS device
capabilities it can be done based on the custom device IDs passed via the
MDIO-device platform data.

Final DW XPCS driver change is about adding a new method of the DW XPCS
descriptor creation. The xpcs_create_fwnode() function has been introduced
with the same semantics as a similar method recently added to the Lynx PCS
driver. It's supposed to be called with the fwnode pointing to the DW XPCS
device node, for which the XPCS descriptor will be created.

The series is terminated with two STMMAC driver patches. The former one
simplifies the DW XPCS descriptor registration procedure by dropping the
MDIO-bus scanning and creating the descriptor for the particular device
address. The later patch alters the STMMAC PCS setup method so one would
support the DW XPCS specified via the "pcs-handle" property.

That's it for now. Thanks for review in advance. Any tests are very
welcome. After this series is merged in, I'll submit another one which
adds the generic 10GBase-R and 10GBase-X interfaces support to the STMMAC
and DW XPCS driver with the proper CSRs re-initialization, PMA
initialization and reference clock selection as it's described in the
Synopsys DW XPCS HW manual.

Link: https://lore.kernel.org/netdev/20231205103559.9605-1-fancer.lancer@gmail.com
Changelog v2:
- Drop the patches:
  [PATCH net-next 01/16] net: pcs: xpcs: Drop sentinel entry from 2500basex ifaces list
  [PATCH net-next 02/16] net: pcs: xpcs: Drop redundant workqueue.h include directive
  [PATCH net-next 03/16] net: pcs: xpcs: Return EINVAL in the internal methods
  [PATCH net-next 04/16] net: pcs: xpcs: Explicitly return error on caps validation
  as ones have already been merged into the kernel repo:
Link: https://lore.kernel.org/netdev/20240222175843.26919-1-fancer.lancer@gmail.com/
- Drop the patches:
  [PATCH net-next 14/16] net: stmmac: Pass netdev to XPCS setup function
  [PATCH net-next 15/16] net: stmmac: Add dedicated XPCS cleanup method
  as ones have already been merged into the kernel repo:
Link: https://lore.kernel.org/netdev/20240513-rzn1-gmac1-v7-0-6acf58b5440d@bootlin.com/
- Drop the patch:
  [PATCH net-next 06/16] net: pcs: xpcs: Avoid creating dummy XPCS MDIO device
  [PATCH net-next 09/16] net: mdio: Add Synopsys DW XPCS management interface support
  [PATCH net-next 11/16] net: pcs: xpcs: Change xpcs_create_mdiodev() suffix to "byaddr"
  [PATCH net-next 13/16] net: stmmac: intel: Register generic MDIO device
  as no longer relevant.
- Add new patches:
  [PATCH net-next v2 03/10] net: pcs: xpcs: Convert xpcs_id to dw_xpcs_desc
  [PATCH net-next v2 04/10] net: pcs: xpcs: Convert xpcs_compat to dw_xpcs_compat
  [PATCH net-next v2 05/10] net: pcs: xpcs: Introduce DW XPCS info structure
  [PATCH net-next v2 09/10] net: stmmac: Create DW XPCS device with particular address
- Use the xpcs_create_fwnode() function name and semantics similar to the
  Lynx PCS driver.
- Add kdoc describing the DW XPCS registration functions.
- Convert the memory-mapped DW XPCS device driver to being the
  platform-device driver.
- Convert the DW XPCS DT-bindings to defining both memory-mapped and MDIO
  devices.
- Drop inline'es from the methods statically defined in *.c. (@Maxime)
- Preserve the strict refcount-ing pattern. (@Russell)

Link: https://lore.kernel.org/netdev/20240602143636.5839-1-fancer.lancer@gmail.com/
Changelov v3:
- Implement the ordered clocks constraint. (@Rob)
- Convert xpcs_plat_pm_ops to being defined as static. (@Simon)
- Add the "@interface" argument kdoc to the xpcs_create_mdiodev()
  function. (@Simon)
- Fix the "@fwnode" argument name in the xpcs_create_fwnode() method kdoc.
  (@Simon)
- Move the return value descriptions to the "Return:" section of the
  xpcs_create_mdiodev() and xpcs_create_fwnode() kdoc. (@Simon)
- Drop stmmac_mdio_bus_data::has_xpcs flag and define the PCS-address
  mask with particular XPCS address instead.

Link: https://lore.kernel.org/netdev/20240627004142.8106-1-fancer.lancer@gmail.com/
Changelog v4:
- Make sure the series is applicable to the net-next tree. (@Vladimir)
- Rename entry to desc in the xpcs_init_id() method. (@Andrew)
- Add a comment to the clock-names property constraint about the
  oneOf-subschemas applicability. (@Conor)
- Convert "pclk" clock name to "csr" to match the DW XPCS IP-core
  input signal name. (@Rob)
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 390b14b5 357768c7
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/pcs/snps,dw-xpcs.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Synopsys DesignWare Ethernet PCS
maintainers:
- Serge Semin <fancer.lancer@gmail.com>
description:
Synopsys DesignWare Ethernet Physical Coding Sublayer provides an interface
between Media Access Control and Physical Medium Attachment Sublayer through
the Media Independent Interface (XGMII, USXGMII, XLGMII, GMII, etc)
controlled by means of the IEEE std. Clause 45 registers set. The PCS can be
optionally synthesized with a vendor-specific interface connected to
Synopsys PMA (also called DesignWare Consumer/Enterprise PHY) although in
general it can be used to communicate with any compatible PHY.
The PCS CSRs can be accessible either over the Ethernet MDIO bus or directly
by means of the APB3/MCI interfaces. In the later case the XPCS can be mapped
right to the system IO memory space.
properties:
compatible:
oneOf:
- description: Synopsys DesignWare XPCS with none or unknown PMA
const: snps,dw-xpcs
- description: Synopsys DesignWare XPCS with Consumer Gen1 3G PMA
const: snps,dw-xpcs-gen1-3g
- description: Synopsys DesignWare XPCS with Consumer Gen2 3G PMA
const: snps,dw-xpcs-gen2-3g
- description: Synopsys DesignWare XPCS with Consumer Gen2 6G PMA
const: snps,dw-xpcs-gen2-6g
- description: Synopsys DesignWare XPCS with Consumer Gen4 3G PMA
const: snps,dw-xpcs-gen4-3g
- description: Synopsys DesignWare XPCS with Consumer Gen4 6G PMA
const: snps,dw-xpcs-gen4-6g
- description: Synopsys DesignWare XPCS with Consumer Gen5 10G PMA
const: snps,dw-xpcs-gen5-10g
- description: Synopsys DesignWare XPCS with Consumer Gen5 12G PMA
const: snps,dw-xpcs-gen5-12g
reg:
items:
- description:
In case of the MDIO management interface this just a 5-bits ID
of the MDIO bus device. If DW XPCS CSRs space is accessed over the
MCI or APB3 management interfaces, then the space mapping can be
either 'direct' or 'indirect'. In the former case all Clause 45
registers are contiguously mapped within the address space
MMD '[20:16]', Reg '[15:0]'. In the later case the space is divided
to the multiple 256 register sets. There is a special viewport CSR
which is responsible for the set selection. The upper part of
the CSR address MMD+REG[20:8] is supposed to be written in there
so the corresponding subset would be mapped to the lowest 255 CSRs.
reg-names:
items:
- enum: [ direct, indirect ]
reg-io-width:
description:
The way the CSRs are mapped to the memory is platform depended. Since
each Clause 45 CSR is of 16-bits wide the access instructions must be
two bytes aligned at least.
default: 2
enum: [ 2, 4 ]
interrupts:
description:
System interface interrupt output (sbd_intr_o) indicating Clause 73/37
auto-negotiation events':' Page received, AN is completed or incompatible
link partner.
maxItems: 1
clocks:
description:
The MCI and APB3 interfaces are supposed to be equipped with a clock
source connected to the clk_csr_i line.
PCS/PMA layer can be clocked by an internal reference clock source
(phyN_core_refclk) or by an externally connected (phyN_pad_refclk) clock
generator. Both clocks can be supplied at a time.
minItems: 1
maxItems: 3
clock-names:
oneOf:
- minItems: 1
items: # MDIO
- enum: [core, pad]
- const: pad
- minItems: 1
items: # MCI or APB
- const: csr
- enum: [core, pad]
- const: pad
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
ethernet-pcs@1f05d000 {
compatible = "snps,dw-xpcs";
reg = <0x1f05d000 0x1000>;
reg-names = "indirect";
reg-io-width = <4>;
interrupts = <79 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu_pclk>, <&ccu_core>, <&ccu_pad>;
clock-names = "csr", "core", "pad";
};
- |
mdio-bus {
#address-cells = <1>;
#size-cells = <0>;
ethernet-pcs@0 {
compatible = "snps,dw-xpcs";
reg = <0>;
clocks = <&ccu_core>, <&ccu_pad>;
clock-names = "core", "pad";
};
};
...
......@@ -595,7 +595,7 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
/* Intel mgbe SGMII interface uses pcs-xcps */
if (plat->phy_interface == PHY_INTERFACE_MODE_SGMII ||
plat->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
plat->mdio_bus_data->has_xpcs = true;
plat->mdio_bus_data->pcs_mask = BIT(INTEL_MGBE_XPCS_ADDR);
plat->mdio_bus_data->default_an_inband = true;
plat->select_pcs = intel_mgbe_select_pcs;
}
......
......@@ -497,35 +497,33 @@ int stmmac_mdio_reset(struct mii_bus *bus)
int stmmac_pcs_setup(struct net_device *ndev)
{
struct fwnode_handle *devnode, *pcsnode;
struct dw_xpcs *xpcs = NULL;
struct stmmac_priv *priv;
int ret = -ENODEV;
int mode, addr;
int addr, mode, ret;
priv = netdev_priv(ndev);
mode = priv->plat->phy_interface;
devnode = priv->plat->port_node;
if (priv->plat->pcs_init) {
ret = priv->plat->pcs_init(priv);
} else if (fwnode_property_present(devnode, "pcs-handle")) {
pcsnode = fwnode_find_reference(devnode, "pcs-handle", 0);
xpcs = xpcs_create_fwnode(pcsnode, mode);
fwnode_handle_put(pcsnode);
ret = PTR_ERR_OR_ZERO(xpcs);
} else if (priv->plat->mdio_bus_data &&
priv->plat->mdio_bus_data->has_xpcs) {
/* Try to probe the XPCS by scanning all addresses */
for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
xpcs = xpcs_create_mdiodev(priv->mii, addr, mode);
if (IS_ERR(xpcs))
continue;
ret = 0;
break;
}
priv->plat->mdio_bus_data->pcs_mask) {
addr = ffs(priv->plat->mdio_bus_data->pcs_mask) - 1;
xpcs = xpcs_create_mdiodev(priv->mii, addr, mode);
ret = PTR_ERR_OR_ZERO(xpcs);
} else {
return 0;
}
if (ret) {
dev_warn(priv->device, "No xPCS found\n");
return ret;
}
if (ret)
return dev_err_probe(priv->device, ret, "No xPCS found\n");
priv->hw->xpcs = xpcs;
......@@ -610,7 +608,7 @@ int stmmac_mdio_register(struct net_device *ndev)
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
new_bus->name, priv->plat->bus_id);
new_bus->priv = ndev;
new_bus->phy_mask = mdio_bus_data->phy_mask;
new_bus->phy_mask = mdio_bus_data->phy_mask | mdio_bus_data->pcs_mask;
new_bus->parent = priv->device;
err = of_mdiobus_register(new_bus, mdio_node);
......
......@@ -6,11 +6,11 @@
menu "PCS device drivers"
config PCS_XPCS
tristate
tristate "Synopsys DesignWare Ethernet XPCS"
select PHYLINK
help
This module provides helper functions for Synopsys DesignWare XPCS
controllers.
This module provides a driver and helper functions for Synopsys
DesignWare XPCS controllers.
config PCS_LYNX
tristate
......
# SPDX-License-Identifier: GPL-2.0
# Makefile for Linux PCS drivers
pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.o pcs-xpcs-nxp.o pcs-xpcs-wx.o
pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.o pcs-xpcs-plat.o \
pcs-xpcs-nxp.o pcs-xpcs-wx.o
obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o
obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o
......
This diff is collapsed.
This diff is collapsed.
......@@ -6,8 +6,8 @@
* Author: Jose Abreu <Jose.Abreu@synopsys.com>
*/
#define SYNOPSYS_XPCS_ID 0x7996ced0
#define SYNOPSYS_XPCS_MASK 0xffffffff
#include <linux/bits.h>
#include <linux/pcs/pcs-xpcs.h>
/* Vendor regs access */
#define DW_VENDOR BIT(15)
......@@ -120,6 +120,9 @@
/* VR MII EEE Control 1 defines */
#define DW_VR_MII_EEE_TRN_LPI BIT(0) /* Transparent Mode Enable */
#define DW_XPCS_INFO_DECLARE(_name, _pcs, _pma) \
static const struct dw_xpcs_info _name = { .pcs = _pcs, .pma = _pma }
int xpcs_read(struct dw_xpcs *xpcs, int dev, u32 reg);
int xpcs_write(struct dw_xpcs *xpcs, int dev, u32 reg, u16 val);
int xpcs_read_vpcs(struct dw_xpcs *xpcs, int reg);
......
......@@ -7,11 +7,12 @@
#ifndef __LINUX_PCS_XPCS_H
#define __LINUX_PCS_XPCS_H
#include <linux/clk.h>
#include <linux/fwnode.h>
#include <linux/mdio.h>
#include <linux/phy.h>
#include <linux/phylink.h>
#define NXP_SJA1105_XPCS_ID 0x00000010
#define NXP_SJA1110_XPCS_ID 0x00000020
#include <linux/types.h>
/* AN mode */
#define DW_AN_C73 1
......@@ -20,20 +21,46 @@
#define DW_AN_C37_1000BASEX 4
#define DW_10GBASER 5
/* device vendor OUI */
#define DW_OUI_WX 0x0018fc80
struct dw_xpcs_desc;
enum dw_xpcs_pcs_id {
DW_XPCS_ID_NATIVE = 0,
NXP_SJA1105_XPCS_ID = 0x00000010,
NXP_SJA1110_XPCS_ID = 0x00000020,
DW_XPCS_ID = 0x7996ced0,
DW_XPCS_ID_MASK = 0xffffffff,
};
/* dev_flag */
#define DW_DEV_TXGBE BIT(0)
enum dw_xpcs_pma_id {
DW_XPCS_PMA_ID_NATIVE = 0,
DW_XPCS_PMA_GEN1_3G_ID,
DW_XPCS_PMA_GEN2_3G_ID,
DW_XPCS_PMA_GEN2_6G_ID,
DW_XPCS_PMA_GEN4_3G_ID,
DW_XPCS_PMA_GEN4_6G_ID,
DW_XPCS_PMA_GEN5_10G_ID,
DW_XPCS_PMA_GEN5_12G_ID,
WX_TXGBE_XPCS_PMA_10G_ID = 0x0018fc80,
};
struct xpcs_id;
struct dw_xpcs_info {
u32 pcs;
u32 pma;
};
enum dw_xpcs_clock {
DW_XPCS_CORE_CLK,
DW_XPCS_PAD_CLK,
DW_XPCS_NUM_CLKS,
};
struct dw_xpcs {
struct dw_xpcs_info info;
const struct dw_xpcs_desc *desc;
struct mdio_device *mdiodev;
const struct xpcs_id *id;
struct clk_bulk_data clks[DW_XPCS_NUM_CLKS];
struct phylink_pcs pcs;
phy_interface_t interface;
int dev_flag;
};
int xpcs_get_an_mode(struct dw_xpcs *xpcs, phy_interface_t interface);
......@@ -46,6 +73,8 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
int enable);
struct dw_xpcs *xpcs_create_mdiodev(struct mii_bus *bus, int addr,
phy_interface_t interface);
struct dw_xpcs *xpcs_create_fwnode(struct fwnode_handle *fwnode,
phy_interface_t interface);
void xpcs_destroy(struct dw_xpcs *xpcs);
#endif /* __LINUX_PCS_XPCS_H */
......@@ -82,7 +82,7 @@ struct stmmac_priv;
struct stmmac_mdio_bus_data {
unsigned int phy_mask;
unsigned int has_xpcs;
unsigned int pcs_mask;
unsigned int default_an_inband;
int *irqs;
int probed_phy_irq;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment