struct device_node *phy_dn, *port_dn;
bool phy_is_fixed = false;
u32 phy_flags = 0;
- int ret;
+ int mode, ret;
port_dn = cd->port_dn[p->port];
- p->phy_interface = of_get_phy_mode(port_dn);
+ mode = of_get_phy_mode(port_dn);
+ if (mode < 0)
+ mode = PHY_INTERFACE_MODE_NA;
+ p->phy_interface = mode;
phy_dn = of_parse_phandle(port_dn, "phy-handle", 0);
if (of_phy_is_fixed_link(port_dn)) {
if (!p->phy)
return -ENODEV;
+ /* Use already configured phy mode */
+ p->phy_interface = p->phy->interface;
phy_connect_direct(slave_dev, p->phy, dsa_slave_adjust_link,
p->phy_interface);
} else {
return 0;
}
-struct net_device *
-dsa_slave_create(struct dsa_switch *ds, struct device *parent,
- int port, char *name)
+int dsa_slave_create(struct dsa_switch *ds, struct device *parent,
+ int port, char *name)
{
struct net_device *master = ds->dst->master_netdev;
struct net_device *slave_dev;
slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv), name,
NET_NAME_UNKNOWN, ether_setup);
if (slave_dev == NULL)
- return slave_dev;
+ return -ENOMEM;
slave_dev->features = master->vlan_features;
slave_dev->ethtool_ops = &dsa_slave_ethtool_ops;
ret = dsa_slave_phy_setup(p, slave_dev);
if (ret) {
free_netdev(slave_dev);
- return NULL;
+ return ret;
}
+ ds->ports[port] = slave_dev;
ret = register_netdev(slave_dev);
if (ret) {
netdev_err(master, "error %d registering interface %s\n",
ret, slave_dev->name);
phy_disconnect(p->phy);
+ ds->ports[port] = NULL;
free_netdev(slave_dev);
- return NULL;
+ return ret;
}
netif_carrier_off(slave_dev);
- if (p->phy != NULL) {
- if (ds->drv->get_phy_flags)
- p->phy->dev_flags |= ds->drv->get_phy_flags(ds, port);
-
- phy_attach(slave_dev, dev_name(&p->phy->dev),
- PHY_INTERFACE_MODE_GMII);
-
- p->phy->autoneg = AUTONEG_ENABLE;
- p->phy->speed = 0;
- p->phy->duplex = 0;
- p->phy->advertising = p->phy->supported | ADVERTISED_Autoneg;
- }
-
- return slave_dev;
+ return 0;
}