static int ate_miibus_readreg(device_t dev, int phy, int reg);
static int ate_miibus_writereg(device_t dev, int phy, int reg, int data);
+
/*
* The AT91 family of products has the ethernet interface called EMAC.
* However, it isn't self identifying. It is anticipated that the parent bus
* code will take care to only add ate devices where they really are. As
* such, we do nothing here to identify the device and just set its name.
+ * However, FDT makes it self-identifying.
*/
static int
ate_probe(device_t dev)
{
#ifdef FDT
- if (!ofw_bus_is_compatible(dev, "cdns,at32ap7000-macb"))
+ if (!ofw_bus_is_compatible(dev, "cdns,at91rm9200-emac") &&
+ !ofw_bus_is_compatible(dev, "cdns,emac") &&
+ !ofw_bus_is_compatible(dev, "cdns,at32ap7000-macb"))
return (ENXIO);
#endif
device_set_desc(dev, "EMAC");
return (0);
}
+#ifdef FDT
+/*
+ * We have to know if we're using MII or RMII attachment
+ * for the MACB to talk to the PHY correctly. With FDT,
+ * we must use rmii if there's a proprety phy-mode
+ * equal to "rmii". Otherwise we MII mode is used.
+ */
+static void
+ate_set_rmii(struct ate_softc *sc)
+{
+ phandle_t node;
+ char prop[10];
+ ssize_t len;
+
+ node = ofw_bus_get_node(sc->dev);
+ memset(prop, 0 ,sizeof(prop));
+ len = OF_getproplen(node, "phy-mode");
+ if (len != 4)
+ return;
+ if (OF_getprop(node, "phy-mode", prop, len) != len)
+ return;
+ if (strncmp(prop, "rmii", 4) == 0)
+ sc->use_rmii = 1;
+}
+
+#else
+/*
+ * We have to know if we're using MII or RMII attachment
+ * for the MACB to talk to the PHY correctly. Without FDT,
+ * there's no good way to do this. So, if the config file
+ * has 'option AT91_ATE_USE_RMII', then we'll force RMII.
+ * Otherwise, we'll use what the bootloader setup. Either
+ * it setup RMII or MII, in which case we'll get it right,
+ * or it did nothing, and we'll fall back to MII and the
+ * option would override if present.
+ */
+static void
+ata_set_rmii(struct ate_softc *sc)
+{
+
+ /* Default to what boot rom did */
+ if (!sc->is_emacb)
+ sc->use_rmii =
+ (RD4(sc, ETH_CFG) & ETH_CFG_RMII) == ETH_CFG_RMII;
+ else
+ sc->use_rmii =
+ (RD4(sc, ETHB_UIO) & ETHB_UIO_RMII) == ETHB_UIO_RMII;
+
+#ifdef AT91_ATE_USE_RMII
+ /* Compile time override */
+ sc->use_rmii = 1;
+#endif
+}
+#endif
+
static int
ate_attach(device_t dev)
{
}
/* New or old version, chooses buffer size. */
+#ifdef FDT
+ sc->is_emacb = ofw_bus_is_compatible(dev, "cdns,at32ap7000-macb");
+#else
sc->is_emacb = at91_is_sam9() || at91_is_sam9xe();
+#endif
sc->rx_buf_size = RX_BUF_SIZE(sc);
err = ate_activate(dev);
if (err)
goto out;
- /* Default to what boot rom did */
- if (!sc->is_emacb)
- sc->use_rmii =
- (RD4(sc, ETH_CFG) & ETH_CFG_RMII) == ETH_CFG_RMII;
- else
- sc->use_rmii =
- (RD4(sc, ETHB_UIO) & ETHB_UIO_RMII) == ETHB_UIO_RMII;
+ ate_set_rmii(sc);
-#ifdef AT91_ATE_USE_RMII
- /* Compile time override */
- sc->use_rmii = 1;
-#endif
/* Sysctls */
sctx = device_get_sysctl_ctx(dev);
soid = device_get_sysctl_tree(dev);
}
+#ifdef FDT
+/*
+ * We have to know if we're using MII or RMII attachment
+ * for the MACB to talk to the PHY correctly. With FDT,
+ * we must use rmii if there's a proprety phy-mode
+ * equal to "rmii". Otherwise we MII mode is used.
+ */
+static void
+macb_set_rmii(struct macb_softc *sc)
+{
+ phandle_t node;
+ char prop[10];
+ ssize_t len;
+
+ node = ofw_bus_get_node(sc->dev);
+ memset(prop, 0 ,sizeof(prop));
+ len = OF_getproplen(node, "phy-mode");
+ if (len != 4)
+ return;
+ if (OF_getprop(node, "phy-mode", prop, len) != len)
+ return;
+ if (strncmp(prop, "rmii", 4) == 0)
+ sc->use_rmii = USRIO_RMII;
+}
+#else
+/*
+ * We have to know if we're using MII or RMII attachment
+ * for the MACB to talk to the PHY correctly. Without FDT,
+ * there's no good way to do this. So, if the config file
+ * has 'option AT91_MACB_USE_RMII', then we'll force RMII.
+ * Otherwise, we'll use what the bootloader setup. Either
+ * it setup RMII or MII, in which case we'll get it right,
+ * or it did nothing, and we'll fall back to MII and the
+ * option would override if present.
+ */
+static void
+macb_set_rmii(struct macb_softc *sc)
+{
+#ifdef AT91_MACB_USE_RMII
+ sc->use_rmii = USRIO_RMII;
+#else
+ sc->use_rmii = read_4(sc, EMAC_USRIO) & USRIO_RMII;
+#endif
+}
+#endif
+
static int
macb_attach(device_t dev)
{
sc->clock = sc->clock << 10;
-#ifdef AT91_MACB_USE_RMII
- sc->use_rmii = USRIO_RMII;
-#else
- sc->use_rmii = read_4(sc, EMAC_USRIO) & USRIO_RMII;
-#endif
-
+ macb_set_rmii(sc);
write_4(sc, EMAC_NCFGR, sc->clock);
write_4(sc, EMAC_USRIO, USRIO_CLOCK | sc->use_rmii); //enable clock