struct udevice *current;
};
+/* eth_errno - This stores the most recent failure code from DM functions */
+static int eth_errno;
+
static struct eth_uclass_priv *eth_get_uclass_priv(void)
{
struct uclass *uc;
uclass_first_device(UCLASS_ETH, &uc_priv->current);
}
+/*
+ * Typically this will simply return the active device.
+ * In the case where the most recent active device was unset, this will attempt
+ * to return the first device. If that device doesn't exist or fails to probe,
+ * this function will return NULL.
+ */
struct udevice *eth_get_dev(void)
{
struct eth_uclass_priv *uc_priv;
uc_priv = eth_get_uclass_priv();
if (!uc_priv->current)
- uclass_first_device(UCLASS_ETH,
+ eth_errno = uclass_first_device(UCLASS_ETH,
&uc_priv->current);
return uc_priv->current;
}
+/*
+ * Typically this will just store a device pointer.
+ * In case it was not probed, we will attempt to do so.
+ * dev may be NULL to unset the active device.
+ */
static void eth_set_dev(struct udevice *dev)
{
- device_probe(dev);
+ if (dev && !device_active(dev))
+ eth_errno = device_probe(dev);
eth_get_uclass_priv()->current = dev;
}
uclass_get(UCLASS_ETH, &uc);
uclass_foreach_dev(it, uc) {
- /* We need the seq to be valid, so make sure it's probed */
+ /*
+ * We need the seq to be valid, so try to probe it.
+ * If the probe fails, the seq will not match since it will be
+ * -1 instead of what we are looking for.
+ * We don't care about errors from probe here. Either they won't
+ * match an alias or it will match a literal name and we'll pick
+ * up the error when we try to probe again in eth_set_dev().
+ */
device_probe(it);
/*
* Check for the name or the sequence number to match
{
struct udevice *current;
struct udevice *old_current;
+ int ret = -ENODEV;
current = eth_get_dev();
if (!current) {
else
memset(pdata->enetaddr, 0, 6);
- if (eth_get_ops(current)->start(current) >= 0) {
+ ret = eth_get_ops(current)->start(current);
+ if (ret >= 0) {
struct eth_device_priv *priv =
current->uclass_priv;
priv->state = ETH_STATE_ACTIVE;
return 0;
}
- }
+ } else
+ ret = eth_errno;
+
debug("FAIL\n");
- /* This will ensure the new "current" attempted to probe */
+ /*
+ * If ethrotate is enabled, this will change "current",
+ * otherwise we will drop out of this while loop immediately
+ */
eth_try_another(0);
+ /* This will ensure the new "current" attempted to probe */
current = eth_get_dev();
} while (old_current != current);
- return -ENODEV;
+ return ret;
}
void eth_halt(void)
int eth_send(void *packet, int length)
{
struct udevice *current;
+ int ret;
current = eth_get_dev();
if (!current)
if (!device_active(current))
return -EINVAL;
- return eth_get_ops(current)->send(current, packet, length);
+ ret = eth_get_ops(current)->send(current, packet, length);
+ if (ret < 0) {
+ /* We cannot completely return the error at present */
+ debug("%s: send() returned error %d\n", __func__, ret);
+ }
+ return ret;
}
int eth_rx(void)
}
if (ret == -EAGAIN)
ret = 0;
+ if (ret < 0) {
+ /* We cannot completely return the error at present */
+ debug("%s: recv() returned error %d\n", __func__, ret);
+ }
return ret;
}