aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mediatek/mtk_eth_soc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/mediatek/mtk_eth_soc.c')
-rw-r--r--drivers/net/ethernet/mediatek/mtk_eth_soc.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index c984462fad2a..4763252bbf85 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -133,6 +133,8 @@ static int mtk_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
133static void mtk_phy_link_adjust(struct net_device *dev) 133static void mtk_phy_link_adjust(struct net_device *dev)
134{ 134{
135 struct mtk_mac *mac = netdev_priv(dev); 135 struct mtk_mac *mac = netdev_priv(dev);
136 u16 lcl_adv = 0, rmt_adv = 0;
137 u8 flowctrl;
136 u32 mcr = MAC_MCR_MAX_RX_1536 | MAC_MCR_IPG_CFG | 138 u32 mcr = MAC_MCR_MAX_RX_1536 | MAC_MCR_IPG_CFG |
137 MAC_MCR_FORCE_MODE | MAC_MCR_TX_EN | 139 MAC_MCR_FORCE_MODE | MAC_MCR_TX_EN |
138 MAC_MCR_RX_EN | MAC_MCR_BACKOFF_EN | 140 MAC_MCR_RX_EN | MAC_MCR_BACKOFF_EN |
@@ -150,11 +152,30 @@ static void mtk_phy_link_adjust(struct net_device *dev)
150 if (mac->phy_dev->link) 152 if (mac->phy_dev->link)
151 mcr |= MAC_MCR_FORCE_LINK; 153 mcr |= MAC_MCR_FORCE_LINK;
152 154
153 if (mac->phy_dev->duplex) 155 if (mac->phy_dev->duplex) {
154 mcr |= MAC_MCR_FORCE_DPX; 156 mcr |= MAC_MCR_FORCE_DPX;
155 157
156 if (mac->phy_dev->pause) 158 if (mac->phy_dev->pause)
157 mcr |= MAC_MCR_FORCE_RX_FC | MAC_MCR_FORCE_TX_FC; 159 rmt_adv = LPA_PAUSE_CAP;
160 if (mac->phy_dev->asym_pause)
161 rmt_adv |= LPA_PAUSE_ASYM;
162
163 if (mac->phy_dev->advertising & ADVERTISED_Pause)
164 lcl_adv |= ADVERTISE_PAUSE_CAP;
165 if (mac->phy_dev->advertising & ADVERTISED_Asym_Pause)
166 lcl_adv |= ADVERTISE_PAUSE_ASYM;
167
168 flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
169
170 if (flowctrl & FLOW_CTRL_TX)
171 mcr |= MAC_MCR_FORCE_TX_FC;
172 if (flowctrl & FLOW_CTRL_RX)
173 mcr |= MAC_MCR_FORCE_RX_FC;
174
175 netif_dbg(mac->hw, link, dev, "rx pause %s, tx pause %s\n",
176 flowctrl & FLOW_CTRL_RX ? "enabled" : "disabled",
177 flowctrl & FLOW_CTRL_TX ? "enabled" : "disabled");
178 }
158 179
159 mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id)); 180 mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
160 181
@@ -208,10 +229,16 @@ static int mtk_phy_connect(struct mtk_mac *mac)
208 u32 val, ge_mode; 229 u32 val, ge_mode;
209 230
210 np = of_parse_phandle(mac->of_node, "phy-handle", 0); 231 np = of_parse_phandle(mac->of_node, "phy-handle", 0);
232 if (!np && of_phy_is_fixed_link(mac->of_node))
233 if (!of_phy_register_fixed_link(mac->of_node))
234 np = of_node_get(mac->of_node);
211 if (!np) 235 if (!np)
212 return -ENODEV; 236 return -ENODEV;
213 237
214 switch (of_get_phy_mode(np)) { 238 switch (of_get_phy_mode(np)) {
239 case PHY_INTERFACE_MODE_RGMII_TXID:
240 case PHY_INTERFACE_MODE_RGMII_RXID:
241 case PHY_INTERFACE_MODE_RGMII_ID:
215 case PHY_INTERFACE_MODE_RGMII: 242 case PHY_INTERFACE_MODE_RGMII:
216 ge_mode = 0; 243 ge_mode = 0;
217 break; 244 break;
@@ -236,7 +263,8 @@ static int mtk_phy_connect(struct mtk_mac *mac)
236 mac->phy_dev->autoneg = AUTONEG_ENABLE; 263 mac->phy_dev->autoneg = AUTONEG_ENABLE;
237 mac->phy_dev->speed = 0; 264 mac->phy_dev->speed = 0;
238 mac->phy_dev->duplex = 0; 265 mac->phy_dev->duplex = 0;
239 mac->phy_dev->supported &= PHY_BASIC_FEATURES; 266 mac->phy_dev->supported &= PHY_GBIT_FEATURES | SUPPORTED_Pause |
267 SUPPORTED_Asym_Pause;
240 mac->phy_dev->advertising = mac->phy_dev->supported | 268 mac->phy_dev->advertising = mac->phy_dev->supported |
241 ADVERTISED_Autoneg; 269 ADVERTISED_Autoneg;
242 phy_start_aneg(mac->phy_dev); 270 phy_start_aneg(mac->phy_dev);
@@ -280,7 +308,7 @@ static int mtk_mdio_init(struct mtk_eth *eth)
280 return 0; 308 return 0;
281 309
282err_free_bus: 310err_free_bus:
283 kfree(eth->mii_bus); 311 mdiobus_free(eth->mii_bus);
284 312
285err_put_node: 313err_put_node:
286 of_node_put(mii_np); 314 of_node_put(mii_np);
@@ -295,7 +323,7 @@ static void mtk_mdio_cleanup(struct mtk_eth *eth)
295 323
296 mdiobus_unregister(eth->mii_bus); 324 mdiobus_unregister(eth->mii_bus);
297 of_node_put(eth->mii_bus->dev.of_node); 325 of_node_put(eth->mii_bus->dev.of_node);
298 kfree(eth->mii_bus); 326 mdiobus_free(eth->mii_bus);
299} 327}
300 328
301static inline void mtk_irq_disable(struct mtk_eth *eth, u32 mask) 329static inline void mtk_irq_disable(struct mtk_eth *eth, u32 mask)