From 1543e317f1da31b75942316931e8f491a8920811 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 04 Jan 2024 10:08:02 +0000
Subject: [PATCH] disable FB
---
kernel/drivers/net/ethernet/socionext/sni_ave.c | 176 +++++++++++++++++++++++++++++++++++++---------------------
1 files changed, 112 insertions(+), 64 deletions(-)
diff --git a/kernel/drivers/net/ethernet/socionext/sni_ave.c b/kernel/drivers/net/ethernet/socionext/sni_ave.c
index 01cde5f..501b9c7 100644
--- a/kernel/drivers/net/ethernet/socionext/sni_ave.c
+++ b/kernel/drivers/net/ethernet/socionext/sni_ave.c
@@ -185,8 +185,8 @@
NETIF_MSG_TX_ERR)
/* Parameter for descriptor */
-#define AVE_NR_TXDESC 32 /* Tx descriptor */
-#define AVE_NR_RXDESC 64 /* Rx descriptor */
+#define AVE_NR_TXDESC 64 /* Tx descriptor */
+#define AVE_NR_RXDESC 256 /* Rx descriptor */
#define AVE_DESC_OFS_CMDSTS 0
#define AVE_DESC_OFS_ADDRL 4
@@ -262,6 +262,7 @@
struct regmap *regmap;
unsigned int pinmode_mask;
unsigned int pinmode_val;
+ u32 wolopts;
/* stats */
struct ave_stats stats_rx;
@@ -423,16 +424,22 @@
phy_ethtool_get_wol(ndev->phydev, wol);
}
+static int __ave_ethtool_set_wol(struct net_device *ndev,
+ struct ethtool_wolinfo *wol)
+{
+ if (!ndev->phydev ||
+ (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE)))
+ return -EOPNOTSUPP;
+
+ return phy_ethtool_set_wol(ndev->phydev, wol);
+}
+
static int ave_ethtool_set_wol(struct net_device *ndev,
struct ethtool_wolinfo *wol)
{
int ret;
- if (!ndev->phydev ||
- (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE)))
- return -EOPNOTSUPP;
-
- ret = phy_ethtool_set_wol(ndev->phydev, wol);
+ ret = __ave_ethtool_set_wol(ndev, wol);
if (!ret)
device_set_wakeup_enable(&ndev->dev, !!wol->wolopts);
@@ -462,16 +469,7 @@
priv->pause_rx = pause->rx_pause;
priv->pause_tx = pause->tx_pause;
- phydev->advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
- if (pause->rx_pause)
- phydev->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
- if (pause->tx_pause)
- phydev->advertising ^= ADVERTISED_Asym_Pause;
-
- if (pause->autoneg) {
- if (netif_running(ndev))
- phy_start_aneg(phydev);
- }
+ phy_set_asym_pause(phydev, pause->rx_pause, pause->tx_pause);
return 0;
}
@@ -1127,11 +1125,8 @@
rmt_adv |= LPA_PAUSE_CAP;
if (phydev->asym_pause)
rmt_adv |= LPA_PAUSE_ASYM;
- if (phydev->advertising & ADVERTISED_Pause)
- lcl_adv |= ADVERTISE_PAUSE_CAP;
- if (phydev->advertising & ADVERTISED_Asym_Pause)
- lcl_adv |= ADVERTISE_PAUSE_ASYM;
+ lcl_adv = linkmode_adv_to_lcl_adv_t(phydev->advertising);
cap = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
if (cap & FLOW_CTRL_TX)
txcr |= AVE_TXCR_FLOCTR;
@@ -1222,14 +1217,17 @@
priv->phydev = phydev;
- phy_ethtool_get_wol(phydev, &wol);
+ ave_ethtool_get_wol(ndev, &wol);
device_set_wakeup_capable(&ndev->dev, !!wol.supported);
- if (!phy_interface_is_rgmii(phydev)) {
- phydev->supported &= ~PHY_GBIT_FEATURES;
- phydev->supported |= PHY_BASIC_FEATURES;
- }
- phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+ /* set wol initial state disabled */
+ wol.wolopts = 0;
+ __ave_ethtool_set_wol(ndev, &wol);
+
+ if (!phy_interface_is_rgmii(phydev))
+ phy_set_max_speed(phydev, SPEED_100);
+
+ phy_support_asym_pause(phydev);
phy_attached_info(phydev);
@@ -1396,7 +1394,7 @@
return 0;
}
-static int ave_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t ave_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
struct ave_private *priv = netdev_priv(ndev);
u32 proc_idx, done_idx, ndesc, cmdsts;
@@ -1561,7 +1559,6 @@
struct ave_private *priv;
struct net_device *ndev;
struct device_node *np;
- struct resource *res;
const void *mac_addr;
void __iomem *base;
const char *name;
@@ -1574,24 +1571,21 @@
return -EINVAL;
np = dev->of_node;
- phy_mode = of_get_phy_mode(np);
- if ((int)phy_mode < 0) {
+ ret = of_get_phy_mode(np, &phy_mode);
+ if (ret) {
dev_err(dev, "phy-mode not found\n");
- return -EINVAL;
+ return ret;
}
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(dev, "IRQ not found\n");
+ if (irq < 0)
return irq;
- }
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- base = devm_ioremap_resource(dev, res);
+ base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
- ndev = alloc_etherdev(sizeof(struct ave_private));
+ ndev = devm_alloc_etherdev(dev, sizeof(struct ave_private));
if (!ndev) {
dev_err(dev, "can't allocate ethernet device\n");
return -ENOMEM;
@@ -1607,7 +1601,7 @@
ndev->max_mtu = AVE_MAX_ETHFRAME - (ETH_HLEN + ETH_FCS_LEN);
mac_addr = of_get_mac_address(np);
- if (mac_addr)
+ if (!IS_ERR(mac_addr))
ether_addr_copy(ndev->dev_addr, mac_addr);
/* if the mac address is invalid, use random mac address */
@@ -1638,7 +1632,7 @@
}
ret = dma_set_mask(dev, dma_mask);
if (ret)
- goto out_free_netdev;
+ return ret;
priv->tx.ndesc = AVE_NR_TXDESC;
priv->rx.ndesc = AVE_NR_RXDESC;
@@ -1651,10 +1645,8 @@
if (!name)
break;
priv->clk[i] = devm_clk_get(dev, name);
- if (IS_ERR(priv->clk[i])) {
- ret = PTR_ERR(priv->clk[i]);
- goto out_free_netdev;
- }
+ if (IS_ERR(priv->clk[i]))
+ return PTR_ERR(priv->clk[i]);
priv->nclks++;
}
@@ -1663,10 +1655,8 @@
if (!name)
break;
priv->rst[i] = devm_reset_control_get_shared(dev, name);
- if (IS_ERR(priv->rst[i])) {
- ret = PTR_ERR(priv->rst[i]);
- goto out_free_netdev;
- }
+ if (IS_ERR(priv->rst[i]))
+ return PTR_ERR(priv->rst[i]);
priv->nrsts++;
}
@@ -1674,27 +1664,24 @@
"socionext,syscon-phy-mode",
1, 0, &args);
if (ret) {
- netdev_err(ndev, "can't get syscon-phy-mode property\n");
- goto out_free_netdev;
+ dev_err(dev, "can't get syscon-phy-mode property\n");
+ return ret;
}
priv->regmap = syscon_node_to_regmap(args.np);
of_node_put(args.np);
if (IS_ERR(priv->regmap)) {
- netdev_err(ndev, "can't map syscon-phy-mode\n");
- ret = PTR_ERR(priv->regmap);
- goto out_free_netdev;
+ dev_err(dev, "can't map syscon-phy-mode\n");
+ return PTR_ERR(priv->regmap);
}
ret = priv->data->get_pinmode(priv, phy_mode, args.args[0]);
if (ret) {
- netdev_err(ndev, "invalid phy-mode setting\n");
- goto out_free_netdev;
+ dev_err(dev, "invalid phy-mode setting\n");
+ return ret;
}
priv->mdio = devm_mdiobus_alloc(dev);
- if (!priv->mdio) {
- ret = -ENOMEM;
- goto out_free_netdev;
- }
+ if (!priv->mdio)
+ return -ENOMEM;
priv->mdio->priv = ndev;
priv->mdio->parent = dev;
priv->mdio->read = ave_mdiobus_read;
@@ -1704,9 +1691,10 @@
pdev->name, pdev->id);
/* Register as a NAPI supported driver */
- netif_napi_add(ndev, &priv->napi_rx, ave_napi_poll_rx, priv->rx.ndesc);
+ netif_napi_add(ndev, &priv->napi_rx, ave_napi_poll_rx,
+ NAPI_POLL_WEIGHT);
netif_tx_napi_add(ndev, &priv->napi_tx, ave_napi_poll_tx,
- priv->tx.ndesc);
+ NAPI_POLL_WEIGHT);
platform_set_drvdata(pdev, ndev);
@@ -1730,8 +1718,6 @@
out_del_napi:
netif_napi_del(&priv->napi_rx);
netif_napi_del(&priv->napi_tx);
-out_free_netdev:
- free_netdev(ndev);
return ret;
}
@@ -1744,10 +1730,61 @@
unregister_netdev(ndev);
netif_napi_del(&priv->napi_rx);
netif_napi_del(&priv->napi_tx);
- free_netdev(ndev);
return 0;
}
+
+#ifdef CONFIG_PM_SLEEP
+static int ave_suspend(struct device *dev)
+{
+ struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct ave_private *priv = netdev_priv(ndev);
+ int ret = 0;
+
+ if (netif_running(ndev)) {
+ ret = ave_stop(ndev);
+ netif_device_detach(ndev);
+ }
+
+ ave_ethtool_get_wol(ndev, &wol);
+ priv->wolopts = wol.wolopts;
+
+ return ret;
+}
+
+static int ave_resume(struct device *dev)
+{
+ struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct ave_private *priv = netdev_priv(ndev);
+ int ret = 0;
+
+ ave_global_reset(ndev);
+
+ ave_ethtool_get_wol(ndev, &wol);
+ wol.wolopts = priv->wolopts;
+ __ave_ethtool_set_wol(ndev, &wol);
+
+ if (ndev->phydev) {
+ ret = phy_resume(ndev->phydev);
+ if (ret)
+ return ret;
+ }
+
+ if (netif_running(ndev)) {
+ ret = ave_open(ndev);
+ netif_device_attach(ndev);
+ }
+
+ return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(ave_pm_ops, ave_suspend, ave_resume);
+#define AVE_PM_OPS (&ave_pm_ops)
+#else
+#define AVE_PM_OPS NULL
+#endif
static int ave_pro4_get_pinmode(struct ave_private *priv,
phy_interface_t phy_mode, u32 arg)
@@ -1763,6 +1800,9 @@
break;
case PHY_INTERFACE_MODE_MII:
case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
priv->pinmode_val = 0;
break;
default:
@@ -1807,6 +1847,9 @@
priv->pinmode_val = SG_ETPINMODE_RMII(0);
break;
case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
priv->pinmode_val = 0;
break;
default:
@@ -1829,6 +1872,9 @@
priv->pinmode_val = SG_ETPINMODE_RMII(arg);
break;
case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
priv->pinmode_val = 0;
break;
default:
@@ -1923,10 +1969,12 @@
.remove = ave_remove,
.driver = {
.name = "ave",
+ .pm = AVE_PM_OPS,
.of_match_table = of_ave_match,
},
};
module_platform_driver(ave_driver);
+MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>");
MODULE_DESCRIPTION("Socionext UniPhier AVE ethernet driver");
MODULE_LICENSE("GPL v2");
--
Gitblit v1.6.2