On 1/23/2013 1:43 PM, Giuseppe CAVALLARO write:
I modified this part like below
@@ -1044,12 +1046,8 @@ static int stmmac_open(struct net_device *dev)
priv->hw->mac->core_init(priv->ioaddr);
/* Enable auto-negotiation for SGMII, TBI or RTBI */
- if (interface == PHY_INTERFACE_MODE_SGMII ||
- interface == PHY_INTERFACE_MODE_TBI ||
- interface == PHY_INTERFACE_MODE_RTBI) {
- if (priv->phydev->autoneg)
- priv->hw->mac->set_autoneg(priv->ioaddr);
- }
+ if (priv->dma_cap.pcs)
+ priv->hw->mac->ctrl_ane(priv->ioaddr, 0);
/* Request the IRQ lines */
ret = request_irq(dev->irq, stmmac_interrupt,
As you may know, auto-negotiation is essential for SGMII, TBI, or RTBI
interface.
And ctrl_ane funciont is like that
@@ -311,6 +317,18 @@ static void dwmac1000_set_autoneg(void __iomem *ioaddr)
writel(value, ioaddr + GMAC_AN_CTRL);
}
+static void dwmac1000_ctrl_ane(void __iomem *ioaddr, bool restart)
+{
+ u32 value;
+
+ value = readl(ioaddr + GMAC_AN_CTRL);
+ /* auto negotiation enable and External Loopback enable */
+ value = GMAC_AN_CTRL__ANE | GMAC_AN_CTRL__ELE;
+
+ if (restart)
+ value |= GMAC_AN_CTRL_RAN;
+
+ writel(value, ioaddr + GMAC_AN_CTRL);
+}
static const struct stmmac_ops dwmac1000_ops = {
.core_init = dwmac1000_core_init,
I've changed restart AN like below.
@@ -610,6 +607,27 @@ static int stmmac_set_coalesce(struct net_device *dev,
return 0;
}
+static int
+stmmac_nway_reset(struct net_device *netdev)
+{
+ struct stmmac_priv *priv = netdev_priv(netdev);
+ struct phy_device *phy = priv->phydev;
+ int ret = 0;
+
+ spin_lock(&priv->lock);
+
+ if (netif_running(netdev)) {
+ phy_stop(phy);
+ phy_start(phy);
+ ret = phy_start_aneg(phy);
+ if (priv->dma_cap.pcs)
+ priv->hw->mac->ctrl_ane(priv->ioaddr, true);
+ }
+
+ spin_unlock(&priv->lock);
+ return ret;
+}
+
static const struct ethtool_ops stmmac_ethtool_ops = {
.begin = stmmac_check_if_running,
.get_drvinfo = stmmac_ethtool_getdrvinfo,
I think whenever link is changed, phy->state is changed and call
stmmac_adjust_link. It would update gmac's link.
I can get autonegotiation complete and link change irqs if we need something
we can add code in the handler but I'm not sure which one is need yet.
As of now I just added phy_state = PHY_CHANGELINK as a test code in the link
change irq handler.
@@ -1624,8 +1629,43 @@ static irqreturn_t stmmac_interrupt(int irq, void
*dev_id)
priv->xstats.mmc_rx_csum_offload_irq_n++;
if (status & core_irq_receive_pmt_irq)
priv->xstats.irq_receive_pmt_irq_n++;
+ if (status & core_irq_pcs_autoneg_complete)
+ priv->core_pcs_an = true;
+ if (status & core_irq_pcs_link_status_change) {
+ priv->core_pcs_link_change = true;
+ status = readl(priv->ioaddr +
GMAC_AN_STATUS);
+ if (status & GMAC_AN_STATUS_LS)
+ if ((priv->speed != phy->speed) ||
(priv->oldduplex != phy->duplex))
+ phy->state = PHY_CHANGELINK; /* for
test */
+ }
/* For LPI we need to save the tx status */
if (status & core_irq_tx_path_in_lpi_mode) {
I have a question, how to hand over phy's irq number, as I analyzed
phydev->irq is irqlist and irqlist is like below but I can not find a way to
set phy's irq number.
How to register or set priv->mii_irq or mdio_bus_data->irqs.
if (mdio_bus_data->irqs)
irqlist = mdio_bus_data->irqs;
else
irqlist = priv->mii_irq;
I added some defines for AN like below
@@ -97,6 +97,20 @@ enum power_event {
#define GMAC_TBI 0x000000d4 /* TBI extend status */
#define GMAC_GMII_STATUS 0x000000d8 /* S/R-GMII status */
+/* AN Configuration defines */
+#define GMAC_AN_CTRL_RAN 0x00000200 /* Restart Auto-Negotiation
*/
+#define GMAC_AN_CTRL_ANE 0x00001000 /* Auto-Negotiation Enable
*/
+#define GMAC_AN_CTRL_ELE 0x00004000 /* External Loopback Enable
*/
+#define GMAC_AN_CTRL_ECD 0x00010000 /* Enable Comma Detect */
+#define GMAC_AN_CTRL_LR 0x00020000 /* Lock to Reference */
+#define GMAC_AN_CTRL_SGMRAL 0x00040000 /* SGMII RAL Control */
+
+/* AN Status defines */
+#define GMAC_AN_STATUS_LS 0x00000004 /* Link Status 0:down 1:up
*/
+#define GMAC_AN_STATUS_ANA 0x00000008 /* Auto-Negotiation Ability
*/
+#define GMAC_AN_STATUS_ANC 0x00000020 /* Auto-Negotiation Complete
*/
+#define GMAC_AN_STATUS_ES 0x00000100 /* Extended Status */
+
/* GMAC Configuration defines */
#define GMAC_CONTROL_TC 0x01000000 /* Transmit Conf. in
RGMII/SGMII */
#define GMAC_CONTROL_WD 0x00800000 /* Disable Watchdog on
receive */