switch (ifmode) { case PHY_INTERFACE_MODE_1000BASEX: case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_QSGMII: return lynx_pcs_config_giga(lynx->mdio, ifmode, advertising,
neg_mode); case PHY_INTERFACE_MODE_2500BASEX: if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
dev_err(&lynx->mdio->dev, "AN not supported on 3.125GHz SerDes lane\n"); return -EOPNOTSUPP;
} break; case PHY_INTERFACE_MODE_USXGMII: return lynx_pcs_config_usxgmii(lynx->mdio, advertising,
neg_mode); case PHY_INTERFACE_MODE_10GBASER: /* Nothing to do here for 10GBASER */ break; default: return -EOPNOTSUPP;
}
/* 2500Base-X is SerDes protocol 7 on Felix and 6 on ENETC. It is a SerDes lane * clocked at 3.125 GHz which encodes symbols with 8b/10b and does not have * auto-negotiation of any link parameters. Electrically it is compatible with * a single lane of XAUI. * The hardware reference manual wants to call this mode SGMII, but it isn't * really, since the fundamental features of SGMII: * - Downgrading the link speed by duplicating symbols * - Auto-negotiation * are not there. * The speed is configured at 1000 in the IF_MODE because the clock frequency * is actually given by a PLL configured in the Reset Configuration Word (RCW). * Since there is no difference between fixed speed SGMII w/o AN and 802.3z w/o * AN, we call this PHY interface type 2500Base-X. In case a PHY negotiates a * lower link speed on line side, the system-side interface remains fixed at * 2500 Mbps and we do rate adaptation through pause frames.
*/ staticvoid lynx_pcs_link_up_2500basex(struct mdio_device *pcs, unsignedint neg_mode, int speed, int duplex)
{
u16 if_mode = 0;
if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
dev_err(&pcs->dev, "AN not supported for 2500BaseX\n"); return;
}
if (duplex == DUPLEX_HALF)
if_mode |= IF_MODE_HALF_DUPLEX;
if_mode |= IF_MODE_SPEED(SGMII_SPEED_2500);
staticvoid lynx_pcs_link_up(struct phylink_pcs *pcs, unsignedint neg_mode,
phy_interface_t interface, int speed, int duplex)
{ struct lynx_pcs *lynx = phylink_pcs_to_lynx(pcs);
switch (interface) { case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_QSGMII:
lynx_pcs_link_up_sgmii(lynx->mdio, neg_mode, speed, duplex); break; case PHY_INTERFACE_MODE_2500BASEX:
lynx_pcs_link_up_2500basex(lynx->mdio, neg_mode, speed, duplex); break; case PHY_INTERFACE_MODE_USXGMII: /* At the moment, only in-band AN is supported for USXGMII * so nothing to do in link_up
*/ break; default: break;
}
}
mdio = mdio_device_create(bus, addr); if (IS_ERR(mdio)) return ERR_CAST(mdio);
pcs = lynx_pcs_create(mdio);
/* lynx_create() has taken a refcount on the mdiodev if it was * successful. If lynx_create() fails, this will free the mdio * device here. In any case, we don't need to hold our reference * anymore, and putting it here will allow mdio_device_put() in * lynx_destroy() to automatically free the mdio device.
*/
mdio_device_put(mdio);
/* * lynx_pcs_create_fwnode() creates a lynx PCS instance from the fwnode * device indicated by node. * * Returns: * -ENODEV if the fwnode is marked unavailable * -EPROBE_DEFER if we fail to find the device * -ENOMEM if we fail to allocate memory * pointer to a phylink_pcs on success
*/ struct phylink_pcs *lynx_pcs_create_fwnode(struct fwnode_handle *node)
{ struct mdio_device *mdio; struct phylink_pcs *pcs;
if (!fwnode_device_is_available(node)) return ERR_PTR(-ENODEV);
mdio = fwnode_mdio_find_device(node); if (!mdio) return ERR_PTR(-EPROBE_DEFER);
pcs = lynx_pcs_create(mdio);
/* lynx_create() has taken a refcount on the mdiodev if it was * successful. If lynx_create() fails, this will free the mdio * device here. In any case, we don't need to hold our reference * anymore, and putting it here will allow mdio_device_put() in * lynx_destroy() to automatically free the mdio device.
*/
mdio_device_put(mdio);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.