#include "rtl-otto.h"
-struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int port);
+struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int link_idx, int port);
int rtldsa_port_get_stp_state(struct rtl838x_switch_priv *priv, int port)
{
static int rtl83xx_mdio_probe(struct rtl838x_switch_priv *priv)
{
- struct device_node *dn, *phy_node, *pcs_node, *led_node;
+ struct device_node *dn, *phy_node, *led_node;
+ struct of_phandle_args pcs_args;
+ bool has_pcs;
u32 pn;
/* Check if all busses of Realtek mdio controller are registered */
if (of_property_read_u32(dn, "reg", &pn))
continue;
- pcs_node = of_parse_phandle(dn, "pcs-handle", 0);
+ has_pcs = !of_parse_phandle_with_args(dn, "pcs-handle", "#pcs-cells",
+ 0, &pcs_args);
phy_node = of_parse_phandle(dn, "phy-handle", 0);
- if (pn != priv->r->cpu_port && !phy_node && !pcs_node) {
+ if (pn != priv->r->cpu_port && !phy_node && !has_pcs) {
dev_err(priv->dev, "Port node %d has neither pcs-handle nor phy-handle\n", pn);
continue;
}
- if (pcs_node) {
- priv->ports[pn].pcs = rtpcs_create(priv->dev, pcs_node, pn);
+ if (has_pcs) {
+ priv->ports[pn].pcs = rtpcs_create(priv->dev, pcs_args.np,
+ pcs_args.args[0], pn);
+ of_node_put(pcs_args.np);
if (IS_ERR(priv->ports[pn].pcs)) {
dev_err(priv->dev, "port %u failed to create PCS instance: %ld\n",
pn, PTR_ERR(priv->ports[pn].pcs));
#include <linux/regmap.h>
#define RTPCS_SDS_CNT 14
-#define RTPCS_PORT_CNT 57
#define RTPCS_MAX_LINKS_PER_SDS 8
#define RTPCS_SPEED_10 0
struct regmap_field *mac_mode_force; /* nullable, 931x only */
struct regmap_field *usxgmii_submode; /* nullable, 93xx only */
} swcore_regs;
+ struct rtpcs_link *link[RTPCS_MAX_LINKS_PER_SDS];
enum rtpcs_sds_mode hw_mode;
u8 id;
struct mii_bus *bus;
const struct rtpcs_config *cfg;
struct rtpcs_serdes serdes[RTPCS_SDS_CNT];
- struct rtpcs_link *link[RTPCS_PORT_CNT];
struct mutex lock;
/* meaning and source may be family-specific */
return ret;
}
-struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int port);
-struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int port)
+struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int link_idx, int port);
+struct phylink_pcs *rtpcs_create(struct device *dev, struct device_node *np, int link_idx, int port)
{
struct platform_device *pdev;
struct device_node *pcs_np;
if (rtpcs_sds_read(sds, 0, 0) < 0)
return ERR_PTR(-EINVAL);
+ if (link_idx >= RTPCS_MAX_LINKS_PER_SDS) {
+ put_device(&pdev->dev);
+ return ERR_PTR(-EINVAL);
+ }
+ if (sds->link[link_idx]) {
+ put_device(&pdev->dev);
+ return ERR_PTR(-EBUSY);
+ }
+
link = devm_kzalloc(ctrl->dev, sizeof(*link), GFP_KERNEL);
if (!link) {
put_device(&pdev->dev);
link->sds = sds;
link->pcs.ops = ctrl->cfg->pcs_ops;
- ctrl->link[port] = link;
-
- dev_dbg(ctrl->dev, "phylink_pcs created, port %d, sds %d\n", port, sds_id);
+ sds->link[link_idx] = link;
+ dev_dbg(ctrl->dev, "phylink_pcs created, port %d, sds %d, link_idx %d\n",
+ port, sds_id, link_idx);
return &link->pcs;
}
EXPORT_SYMBOL(rtpcs_create);