|
@@ -587,6 +587,47 @@ qca8k_setup(struct dsa_switch *ds)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+qca8k_adjust_link(struct dsa_switch *ds, int port, struct phy_device *phy)
|
|
|
+{
|
|
|
+ struct qca8k_priv *priv = ds->priv;
|
|
|
+ u32 reg;
|
|
|
+
|
|
|
+ /* Force fixed-link setting for CPU port, skip others. */
|
|
|
+ if (!phy_is_pseudo_fixed_link(phy))
|
|
|
+ return;
|
|
|
+
|
|
|
+ /* Set port speed */
|
|
|
+ switch (phy->speed) {
|
|
|
+ case 10:
|
|
|
+ reg = QCA8K_PORT_STATUS_SPEED_10;
|
|
|
+ break;
|
|
|
+ case 100:
|
|
|
+ reg = QCA8K_PORT_STATUS_SPEED_100;
|
|
|
+ break;
|
|
|
+ case 1000:
|
|
|
+ reg = QCA8K_PORT_STATUS_SPEED_1000;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ dev_dbg(priv->dev, "port%d link speed %dMbps not supported.\n",
|
|
|
+ port, phy->speed);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Set duplex mode */
|
|
|
+ if (phy->duplex == DUPLEX_FULL)
|
|
|
+ reg |= QCA8K_PORT_STATUS_DUPLEX;
|
|
|
+
|
|
|
+ /* Force flow control */
|
|
|
+ if (dsa_is_cpu_port(ds, port))
|
|
|
+ reg |= QCA8K_PORT_STATUS_RXFLOW | QCA8K_PORT_STATUS_TXFLOW;
|
|
|
+
|
|
|
+ /* Force link down before changing MAC options */
|
|
|
+ qca8k_port_set_status(priv, port, 0);
|
|
|
+ qca8k_write(priv, QCA8K_REG_PORT_STATUS(port), reg);
|
|
|
+ qca8k_port_set_status(priv, port, 1);
|
|
|
+}
|
|
|
+
|
|
|
static int
|
|
|
qca8k_phy_read(struct dsa_switch *ds, int phy, int regnum)
|
|
|
{
|
|
@@ -841,6 +882,7 @@ qca8k_get_tag_protocol(struct dsa_switch *ds, int port)
|
|
|
static const struct dsa_switch_ops qca8k_switch_ops = {
|
|
|
.get_tag_protocol = qca8k_get_tag_protocol,
|
|
|
.setup = qca8k_setup,
|
|
|
+ .adjust_link = qca8k_adjust_link,
|
|
|
.get_strings = qca8k_get_strings,
|
|
|
.phy_read = qca8k_phy_read,
|
|
|
.phy_write = qca8k_phy_write,
|
|
@@ -872,6 +914,7 @@ qca8k_sw_probe(struct mdio_device *mdiodev)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
priv->bus = mdiodev->bus;
|
|
|
+ priv->dev = &mdiodev->dev;
|
|
|
|
|
|
/* read the switches ID register */
|
|
|
id = qca8k_read(priv, QCA8K_REG_MASK_CTRL);
|