|
@@ -100,7 +100,7 @@ static void dsa_port_stop(struct udevice *pdev)
|
|
|
|
|
|
port_pdata = dev_get_parent_plat(pdev);
|
|
|
ops->port_disable(dev, port_pdata->index, port_pdata->phy);
|
|
|
- ops->port_disable(dev, priv->cpu_port, NULL);
|
|
|
+ ops->port_disable(dev, priv->cpu_port, priv->cpu_port_fixed_phy);
|
|
|
}
|
|
|
|
|
|
eth_get_ops(master)->stop(master);
|
|
@@ -199,9 +199,7 @@ static int dsa_port_free_pkt(struct udevice *pdev, uchar *packet, int length)
|
|
|
static int dsa_port_of_to_pdata(struct udevice *pdev)
|
|
|
{
|
|
|
struct dsa_port_pdata *port_pdata;
|
|
|
- struct dsa_pdata *dsa_pdata;
|
|
|
struct eth_pdata *eth_pdata;
|
|
|
- struct udevice *dev;
|
|
|
const char *label;
|
|
|
u32 index;
|
|
|
int err;
|
|
@@ -213,15 +211,12 @@ static int dsa_port_of_to_pdata(struct udevice *pdev)
|
|
|
if (err)
|
|
|
return err;
|
|
|
|
|
|
- dev = dev_get_parent(pdev);
|
|
|
- dsa_pdata = dev_get_uclass_plat(dev);
|
|
|
-
|
|
|
port_pdata = dev_get_parent_plat(pdev);
|
|
|
port_pdata->index = index;
|
|
|
|
|
|
label = ofnode_read_string(dev_ofnode(pdev), "label");
|
|
|
if (label)
|
|
|
- strncpy(port_pdata->name, label, DSA_PORT_NAME_LENGTH);
|
|
|
+ strlcpy(port_pdata->name, label, DSA_PORT_NAME_LENGTH);
|
|
|
|
|
|
eth_pdata = dev_get_plat(pdev);
|
|
|
eth_pdata->priv_pdata = port_pdata;
|
|
@@ -240,18 +235,42 @@ static const struct eth_ops dsa_port_ops = {
|
|
|
.free_pkt = dsa_port_free_pkt,
|
|
|
};
|
|
|
|
|
|
-static int dsa_port_probe(struct udevice *pdev)
|
|
|
+/*
|
|
|
+ * Inherit port's hwaddr from the DSA master, unless the port already has a
|
|
|
+ * unique MAC address specified in the environment.
|
|
|
+ */
|
|
|
+static void dsa_port_set_hwaddr(struct udevice *pdev, struct udevice *master)
|
|
|
{
|
|
|
- struct udevice *dev = dev_get_parent(pdev);
|
|
|
struct eth_pdata *eth_pdata, *master_pdata;
|
|
|
unsigned char env_enetaddr[ARP_HLEN];
|
|
|
+
|
|
|
+ eth_env_get_enetaddr_by_index("eth", dev_seq(pdev), env_enetaddr);
|
|
|
+ if (!is_zero_ethaddr(env_enetaddr)) {
|
|
|
+ /* individual port mac addrs require master to be promisc */
|
|
|
+ struct eth_ops *eth_ops = eth_get_ops(master);
|
|
|
+
|
|
|
+ if (eth_ops->set_promisc)
|
|
|
+ eth_ops->set_promisc(master, 1);
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ master_pdata = dev_get_plat(master);
|
|
|
+ eth_pdata = dev_get_plat(pdev);
|
|
|
+ memcpy(eth_pdata->enetaddr, master_pdata->enetaddr, ARP_HLEN);
|
|
|
+ eth_env_set_enetaddr_by_index("eth", dev_seq(pdev),
|
|
|
+ master_pdata->enetaddr);
|
|
|
+}
|
|
|
+
|
|
|
+static int dsa_port_probe(struct udevice *pdev)
|
|
|
+{
|
|
|
+ struct udevice *dev = dev_get_parent(pdev);
|
|
|
+ struct dsa_ops *ops = dsa_get_ops(dev);
|
|
|
struct dsa_port_pdata *port_pdata;
|
|
|
- struct dsa_priv *dsa_priv;
|
|
|
struct udevice *master;
|
|
|
- int ret;
|
|
|
+ int err;
|
|
|
|
|
|
port_pdata = dev_get_parent_plat(pdev);
|
|
|
- dsa_priv = dev_get_uclass_priv(dev);
|
|
|
|
|
|
port_pdata->phy = dm_eth_phy_connect(pdev);
|
|
|
if (!port_pdata->phy)
|
|
@@ -268,42 +287,25 @@ static int dsa_port_probe(struct udevice *pdev)
|
|
|
* TODO: we assume the master device is always there and doesn't get
|
|
|
* removed during runtime.
|
|
|
*/
|
|
|
- ret = device_probe(master);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
-
|
|
|
- /*
|
|
|
- * Inherit port's hwaddr from the DSA master, unless the port already
|
|
|
- * has a unique MAC address specified in the environment.
|
|
|
- */
|
|
|
- eth_env_get_enetaddr_by_index("eth", dev_seq(pdev), env_enetaddr);
|
|
|
- if (!is_zero_ethaddr(env_enetaddr)) {
|
|
|
- /* individual port mac addrs require master to be promisc */
|
|
|
- struct eth_ops *eth_ops = eth_get_ops(master);
|
|
|
+ err = device_probe(master);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
|
|
|
- if (eth_ops->set_promisc)
|
|
|
- eth_ops->set_promisc(master, 1);
|
|
|
+ dsa_port_set_hwaddr(pdev, master);
|
|
|
|
|
|
- return 0;
|
|
|
+ if (ops->port_probe) {
|
|
|
+ err = ops->port_probe(dev, port_pdata->index,
|
|
|
+ port_pdata->phy);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
}
|
|
|
|
|
|
- master_pdata = dev_get_plat(master);
|
|
|
- eth_pdata = dev_get_plat(pdev);
|
|
|
- memcpy(eth_pdata->enetaddr, master_pdata->enetaddr, ARP_HLEN);
|
|
|
- eth_env_set_enetaddr_by_index("eth", dev_seq(pdev),
|
|
|
- master_pdata->enetaddr);
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static int dsa_port_remove(struct udevice *pdev)
|
|
|
{
|
|
|
- struct udevice *dev = dev_get_parent(pdev);
|
|
|
- struct dsa_port_pdata *port_pdata;
|
|
|
- struct dsa_priv *dsa_priv;
|
|
|
-
|
|
|
- port_pdata = dev_get_parent_plat(pdev);
|
|
|
- dsa_priv = dev_get_uclass_priv(dev);
|
|
|
+ struct dsa_port_pdata *port_pdata = dev_get_parent_plat(pdev);
|
|
|
|
|
|
port_pdata->phy = NULL;
|
|
|
|
|
@@ -419,7 +421,7 @@ static int dsa_post_bind(struct udevice *dev)
|
|
|
struct dsa_port_pdata *port_pdata;
|
|
|
|
|
|
port_pdata = dev_get_parent_plat(pdev);
|
|
|
- strncpy(port_pdata->name, name, DSA_PORT_NAME_LENGTH);
|
|
|
+ strlcpy(port_pdata->name, name, DSA_PORT_NAME_LENGTH);
|
|
|
pdev->name = port_pdata->name;
|
|
|
}
|
|
|
|