The mt7628 has an embedded ethernet switch (5 phy ports + 1 cpu port).
Although in IOT mode only port0 is usable, the phy0 is still connected
to the switch, not the ethernet gmac directly.
This patch rewrites it and makes it optional. It can be turned on by adding
mediatek,poll-link-phy = <?> explicitly into the eth node. By default the
driver is switch mode with all 5 phy ports working without link detection.
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
config MT7628_ETH
bool "MediaTek MT7628 Ethernet Interface"
depends on SOC_MT7628
config MT7628_ETH
bool "MediaTek MT7628 Ethernet Interface"
depends on SOC_MT7628
help
The MediaTek MT7628 ethernet interface is used on MT7628 and
MT7688 based boards.
help
The MediaTek MT7628 ethernet interface is used on MT7628 and
MT7688 based boards.
#define NUM_RX_DESC 256
#define NUM_TX_DESC 4
#define NUM_RX_DESC 256
#define NUM_TX_DESC 4
#define PADDING_LENGTH 60
#define PADDING_LENGTH 60
#define CONFIG_DMA_STOP_TIMEOUT 100
#define CONFIG_TX_DMA_TIMEOUT 100
#define CONFIG_DMA_STOP_TIMEOUT 100
#define CONFIG_TX_DMA_TIMEOUT 100
-#define LINK_DELAY_TIME 500 /* 500 ms */
-#define LINK_TIMEOUT 10000 /* 10 seconds */
-
struct mt7628_eth_dev {
void __iomem *base; /* frame engine base address */
void __iomem *eth_sw_base; /* switch base address */
struct mt7628_eth_dev {
void __iomem *base; /* frame engine base address */
void __iomem *eth_sw_base; /* switch base address */
int tx_dma_idx;
struct reset_ctl rst_ephy;
int tx_dma_idx;
struct reset_ctl rst_ephy;
+
+ struct phy_device *phy;
};
static int mdio_wait_read(struct mt7628_eth_dev *priv, u32 mask, bool mask_set)
};
static int mdio_wait_read(struct mt7628_eth_dev *priv, u32 mask, bool mask_set)
-static int phy_link_up(struct mt7628_eth_dev *priv)
-{
- u32 val;
-
- mii_mgr_read(priv, 0x00, MII_BMSR, &val);
- return !!(val & BMSR_LSTATUS);
-}
-
static int mt7628_eth_start(struct udevice *dev)
{
struct mt7628_eth_dev *priv = dev_get_priv(dev);
void __iomem *base = priv->base;
uchar packet[MTK_QDMA_PAGE_SIZE];
uchar *packetp;
static int mt7628_eth_start(struct udevice *dev)
{
struct mt7628_eth_dev *priv = dev_get_priv(dev);
void __iomem *base = priv->base;
uchar packet[MTK_QDMA_PAGE_SIZE];
uchar *packetp;
int i;
for (i = 0; i < NUM_RX_DESC; i++) {
int i;
for (i = 0; i < NUM_RX_DESC; i++) {
wmb();
eth_dma_start(priv);
wmb();
eth_dma_start(priv);
- /* Check if link is not up yet */
- if (!phy_link_up(priv)) {
- /* Wait for link to come up */
-
- printf("Waiting for link to come up .");
- for (i = 0; i < (LINK_TIMEOUT / LINK_DELAY_TIME); i++) {
- mdelay(LINK_DELAY_TIME);
- if (phy_link_up(priv)) {
- mdelay(100); /* Ensure all is ready */
- break;
- }
+ if (priv->phy) {
+ ret = phy_startup(priv->phy);
+ if (ret)
+ return ret;
- printf(".");
- }
-
- if (phy_link_up(priv))
- printf(" done\n");
- else
- printf(" timeout! Trying anyways\n");
+ if (!priv->phy->link)
+ return -EAGAIN;
{
struct mt7628_eth_dev *priv = dev_get_priv(dev);
struct mii_dev *bus;
{
struct mt7628_eth_dev *priv = dev_get_priv(dev);
struct mii_dev *bus;
+ poll_link_phy = dev_read_u32_default(dev, "mediatek,poll-link-phy", -1);
+ if (poll_link_phy >= 0) {
+ if (poll_link_phy >= NUM_PHYS) {
+ pr_err("invalid phy %d for poll-link-phy\n",
+ poll_link_phy);
+ return ret;
+ }
+
+ priv->phy = phy_connect(bus, poll_link_phy, dev,
+ PHY_INTERFACE_MODE_MII);
+ if (!priv->phy) {
+ pr_err("failed to probe phy %d\n", poll_link_phy);
+ return -ENODEV;
+ }
+
+ priv->phy->advertising = priv->phy->supported;
+ phy_config(priv->phy);
+ }
+
/* Switch configuration */
rt305x_esw_init(priv);
/* Switch configuration */
rt305x_esw_init(priv);