#include <linux/reset.h>
#include <linux/of_mdio.h>
#include "dwmac1000.h"
+#ifdef CONFIG_AMLOGIC_ETH_PRIVE
+#include "stmmac_platform.h"
+#endif
+#ifdef CONFIG_DWMAC_MESON
+#include <phy_debug.h>
+#endif
+
+#include <linux/suspend.h>
+#define PM_SUSPEND_PREPARE 0x0003 /* Going to suspend the system */
#define STMMAC_ALIGN(x) ALIGN(ALIGN(x, SMP_CACHE_BYTES), 16)
#define TSO_MAX_BUFF_SIZE (SZ_16K - 1)
#define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
+/*won't be valid unless enable amlogic priv code*/
+#ifdef CONFIG_AMLOGIC_ETH_PRIVE
+#define TX_MONITOR
+#endif
+
+#ifdef TX_MONITOR
+static struct workqueue_struct *moniter_tx_wq;
+static struct delayed_work moniter_tx_worker;
+#endif
/**
* stmmac_verify_args - verify the driver parameters.
* Description: it checks the driver parameters and set a default in case of
return 0;
}
+#ifdef TX_MONITOR
+static int suspend_pm_notify(struct notifier_block *nb,
+ unsigned long mode, void *_unused)
+{
+ switch (mode) {
+ case PM_SUSPEND_PREPARE:
+ cancel_delayed_work_sync(&moniter_tx_worker);
+ flush_scheduled_work();
+ pr_info("receive suspend notify\n");
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static struct notifier_block suspend_pm_nb = {
+ .notifier_call = suspend_pm_notify,
+};
+#endif
/**
* stmmac_open - open entry point of the driver
* @dev : pointer to the device structure.
napi_enable(&priv->napi);
netif_start_queue(dev);
-
+#ifdef TX_MONITOR
+ queue_delayed_work(moniter_tx_wq, &moniter_tx_worker, HZ);
+#endif
return 0;
lpiirq_error:
* netdev structure and arrange for the device to be reset to a sane state
* in order to transmit a new packet.
*/
+#ifdef TX_MONITOR
+unsigned int timeout_err;
+#endif
static void stmmac_tx_timeout(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
return 0;
}
+#ifdef TX_MONITOR
+struct stmmac_priv *priv_monitor;
+static void moniter_tx_handler(struct work_struct *work)
+{
+ if (priv_monitor) {
+ if (timeout_err) {
+ pr_info("reset eth\n");
+ stmmac_release(priv_monitor->dev);
+ stmmac_open(priv_monitor->dev);
+ timeout_err = 0;
+ }
+ } else {
+ pr_info("device not init yet!\n");
+ }
+// queue_delayed_work(moniter_tx_wq, &moniter_tx_worker, HZ);
+}
+#endif
/**
* stmmac_dvr_probe
* @device: device pointer
struct net_device *ndev = NULL;
struct stmmac_priv *priv;
+#ifdef TX_MONITOR
+ int result = 0;
+ moniter_tx_wq = create_singlethread_workqueue("eth_moniter_tx_wq");
+ INIT_DELAYED_WORK(&moniter_tx_worker, moniter_tx_handler);
+ /*register pm notify callback*/
+ result = register_pm_notifier(&suspend_pm_nb);
+ if (result) {
+ unregister_pm_notifier(&suspend_pm_nb);
+ pr_info("register suspend notifier failed return %d\n", result);
+ }
+#endif
ndev = alloc_etherdev(sizeof(struct stmmac_priv));
if (!ndev)
return -ENOMEM;
goto error_netdev_register;
}
+#ifdef CONFIG_DWMAC_MESON
+ ret = gmac_create_sysfs(
+ mdiobus_get_phy(priv->mii, priv->plat->phy_addr), priv->ioaddr);
+#endif
+#ifdef TX_MONITOR
+ priv_monitor = priv;
+#endif
return ret;
error_netdev_register:
priv->hw->dma->stop_rx(priv->ioaddr);
priv->hw->dma->stop_tx(priv->ioaddr);
+#ifdef CONFIG_DWMAC_MESON
+ gmac_remove_sysfs(priv->phydev);
+#endif
+
stmmac_set_mac(priv->ioaddr, false);
netif_carrier_off(ndev);
unregister_netdev(ndev);
netif_device_detach(ndev);
netif_stop_queue(ndev);
+ /**
+ *napi_disable call might_sleep,if not irq restore
+ *It will warning bug
+ */
+ spin_unlock_irqrestore(&priv->lock, flags);
napi_disable(&priv->napi);
+ spin_lock_irqsave(&priv->lock, flags);
+#ifdef CONFIG_AMLOGIC_ETH_PRIVE
+ del_timer_sync(&priv->txtimer);
+#endif
/* Stop TX/RX DMA */
priv->hw->dma->stop_tx(priv->ioaddr);
priv->hw->dma->stop_rx(priv->ioaddr);
/* Enable Power down mode by programming the PMT regs */
if (device_may_wakeup(priv->device)) {
- priv->hw->mac->pmt(priv->hw, priv->wolopts);
+ //priv->hw->mac->pmt(priv->hw, priv->wolopts);
+ priv->hw->mac->pmt(priv->hw, 0x1 << 5);
priv->irq_wake = 1;
} else {
stmmac_set_mac(priv->ioaddr, false);
stmmac_mdio_reset(priv->mii);
}
+#ifndef CONFIG_AMLOGIC_ETH_PRIVE
netif_device_attach(ndev);
-
+#endif
spin_lock_irqsave(&priv->lock, flags);
priv->cur_rx = 0;
stmmac_clear_descriptors(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
stmmac_hw_setup(ndev, false);
+ spin_lock_irqsave(&priv->lock, flags);
+
stmmac_init_tx_coalesce(priv);
stmmac_set_rx_mode(ndev);
-
+#ifdef CONFIG_AMLOGIC_ETH_PRIVE
+ netif_device_attach(ndev);
+#endif
napi_enable(&priv->napi);
netif_start_queue(ndev);