Lines Matching +full:mode +full:- +full:reg

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Broadcom GENET (Gigabit Ethernet) Wake-on-LAN support
5 * Copyright (c) 2014-2024 Broadcom
37 /* ethtool function - get WOL (Wake on LAN) settings, Only Magic Packet
43 struct device *kdev = &priv->pdev->dev; in bcmgenet_get_wol()
45 if (dev->phydev) in bcmgenet_get_wol()
46 phy_ethtool_get_wol(dev->phydev, wol); in bcmgenet_get_wol()
48 /* MAC is not wake-up capable, return what the PHY does */ in bcmgenet_get_wol()
53 wol->supported |= WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER; in bcmgenet_get_wol()
54 wol->wolopts = priv->wolopts; in bcmgenet_get_wol()
55 memset(wol->sopass, 0, sizeof(wol->sopass)); in bcmgenet_get_wol()
57 if (wol->wolopts & WAKE_MAGICSECURE) in bcmgenet_get_wol()
58 memcpy(wol->sopass, priv->sopass, sizeof(priv->sopass)); in bcmgenet_get_wol()
61 /* ethtool function - set WOL (Wake on LAN) settings.
62 * Only for magic packet detection mode.
67 struct device *kdev = &priv->pdev->dev; in bcmgenet_set_wol()
70 /* Try Wake-on-LAN from the PHY first */ in bcmgenet_set_wol()
71 if (dev->phydev) { in bcmgenet_set_wol()
72 ret = phy_ethtool_set_wol(dev->phydev, wol); in bcmgenet_set_wol()
73 if (ret != -EOPNOTSUPP) in bcmgenet_set_wol()
78 return -ENOTSUPP; in bcmgenet_set_wol()
80 if (wol->wolopts & ~(WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER)) in bcmgenet_set_wol()
81 return -EINVAL; in bcmgenet_set_wol()
83 if (wol->wolopts & WAKE_MAGICSECURE) in bcmgenet_set_wol()
84 memcpy(priv->sopass, wol->sopass, sizeof(priv->sopass)); in bcmgenet_set_wol()
87 if (wol->wolopts) { in bcmgenet_set_wol()
90 if (priv->wol_irq_disabled) { in bcmgenet_set_wol()
91 enable_irq_wake(priv->wol_irq); in bcmgenet_set_wol()
92 enable_irq_wake(priv->irq0); in bcmgenet_set_wol()
94 priv->wol_irq_disabled = false; in bcmgenet_set_wol()
98 if (!priv->wol_irq_disabled) { in bcmgenet_set_wol()
99 disable_irq_wake(priv->wol_irq); in bcmgenet_set_wol()
100 disable_irq_wake(priv->irq0); in bcmgenet_set_wol()
102 priv->wol_irq_disabled = true; in bcmgenet_set_wol()
105 priv->wolopts = wol->wolopts; in bcmgenet_set_wol()
112 struct net_device *dev = priv->dev; in bcmgenet_poll_wol_status()
119 netdev_crit(dev, "polling wol mode timeout\n"); in bcmgenet_poll_wol_status()
120 return -ETIMEDOUT; in bcmgenet_poll_wol_status()
130 bcmgenet_umac_writel(priv, get_unaligned_be16(&priv->sopass[0]), in bcmgenet_set_mpd_password()
132 bcmgenet_umac_writel(priv, get_unaligned_be32(&priv->sopass[2]), in bcmgenet_set_mpd_password()
137 enum bcmgenet_power_mode mode) in bcmgenet_wol_power_down_cfg() argument
139 struct net_device *dev = priv->dev; in bcmgenet_wol_power_down_cfg()
141 u32 reg, hfb_ctrl_reg, hfb_enable = 0; in bcmgenet_wol_power_down_cfg() local
144 if (mode != GENET_POWER_WOL_MAGIC) { in bcmgenet_wol_power_down_cfg()
145 netif_err(priv, wol, dev, "unsupported mode: %d\n", mode); in bcmgenet_wol_power_down_cfg()
146 return -EINVAL; in bcmgenet_wol_power_down_cfg()
150 spin_lock_bh(&priv->reg_lock); in bcmgenet_wol_power_down_cfg()
151 reg = bcmgenet_umac_readl(priv, UMAC_CMD); in bcmgenet_wol_power_down_cfg()
152 if (reg & CMD_SW_RESET) in bcmgenet_wol_power_down_cfg()
153 reg &= ~CMD_SW_RESET; in bcmgenet_wol_power_down_cfg()
156 reg &= ~CMD_RX_EN; in bcmgenet_wol_power_down_cfg()
157 bcmgenet_umac_writel(priv, reg, UMAC_CMD); in bcmgenet_wol_power_down_cfg()
158 spin_unlock_bh(&priv->reg_lock); in bcmgenet_wol_power_down_cfg()
161 if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) { in bcmgenet_wol_power_down_cfg()
162 reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); in bcmgenet_wol_power_down_cfg()
163 reg |= MPD_EN; in bcmgenet_wol_power_down_cfg()
164 if (priv->wolopts & WAKE_MAGICSECURE) { in bcmgenet_wol_power_down_cfg()
166 reg |= MPD_PW_EN; in bcmgenet_wol_power_down_cfg()
168 bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); in bcmgenet_wol_power_down_cfg()
172 if (priv->wolopts & WAKE_FILTER) { in bcmgenet_wol_power_down_cfg()
173 list_for_each_entry(rule, &priv->rxnfc_list, list) in bcmgenet_wol_power_down_cfg()
174 if (rule->fs.ring_cookie == RX_CLS_FLOW_WAKE) in bcmgenet_wol_power_down_cfg()
175 hfb_enable |= (1 << rule->fs.location); in bcmgenet_wol_power_down_cfg()
176 reg = (hfb_ctrl_reg & ~RBUF_HFB_EN) | RBUF_ACPI_EN; in bcmgenet_wol_power_down_cfg()
177 bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL); in bcmgenet_wol_power_down_cfg()
180 /* Do not leave UniMAC in MPD mode only */ in bcmgenet_wol_power_down_cfg()
183 reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); in bcmgenet_wol_power_down_cfg()
184 reg &= ~(MPD_EN | MPD_PW_EN); in bcmgenet_wol_power_down_cfg()
185 bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); in bcmgenet_wol_power_down_cfg()
190 netif_dbg(priv, wol, dev, "MPD WOL-ready status set after %d msec\n", in bcmgenet_wol_power_down_cfg()
193 clk_prepare_enable(priv->clk_wol); in bcmgenet_wol_power_down_cfg()
194 priv->wol_active = 1; in bcmgenet_wol_power_down_cfg()
204 spin_lock_bh(&priv->reg_lock); in bcmgenet_wol_power_down_cfg()
205 reg = bcmgenet_umac_readl(priv, UMAC_CMD); in bcmgenet_wol_power_down_cfg()
206 priv->crc_fwd_en = 1; in bcmgenet_wol_power_down_cfg()
207 reg |= CMD_CRC_FWD; in bcmgenet_wol_power_down_cfg()
210 reg |= CMD_RX_EN; in bcmgenet_wol_power_down_cfg()
211 bcmgenet_umac_writel(priv, reg, UMAC_CMD); in bcmgenet_wol_power_down_cfg()
212 spin_unlock_bh(&priv->reg_lock); in bcmgenet_wol_power_down_cfg()
214 reg = UMAC_IRQ_MPD_R; in bcmgenet_wol_power_down_cfg()
216 reg |= UMAC_IRQ_HFB_SM | UMAC_IRQ_HFB_MM; in bcmgenet_wol_power_down_cfg()
218 bcmgenet_intrl2_0_writel(priv, reg, INTRL2_CPU_MASK_CLEAR); in bcmgenet_wol_power_down_cfg()
224 enum bcmgenet_power_mode mode) in bcmgenet_wol_power_up_cfg() argument
226 u32 reg; in bcmgenet_wol_power_up_cfg() local
228 if (mode != GENET_POWER_WOL_MAGIC) { in bcmgenet_wol_power_up_cfg()
229 netif_err(priv, wol, priv->dev, "invalid mode: %d\n", mode); in bcmgenet_wol_power_up_cfg()
233 if (!priv->wol_active) in bcmgenet_wol_power_up_cfg()
236 priv->wol_active = 0; in bcmgenet_wol_power_up_cfg()
237 clk_disable_unprepare(priv->clk_wol); in bcmgenet_wol_power_up_cfg()
238 priv->crc_fwd_en = 0; in bcmgenet_wol_power_up_cfg()
241 if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) { in bcmgenet_wol_power_up_cfg()
242 reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); in bcmgenet_wol_power_up_cfg()
243 if (!(reg & MPD_EN)) in bcmgenet_wol_power_up_cfg()
245 reg &= ~(MPD_EN | MPD_PW_EN); in bcmgenet_wol_power_up_cfg()
246 bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); in bcmgenet_wol_power_up_cfg()
250 if (priv->wolopts & WAKE_FILTER) { in bcmgenet_wol_power_up_cfg()
251 reg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL); in bcmgenet_wol_power_up_cfg()
252 if (!(reg & RBUF_ACPI_EN)) in bcmgenet_wol_power_up_cfg()
254 reg &= ~(RBUF_HFB_EN | RBUF_ACPI_EN); in bcmgenet_wol_power_up_cfg()
255 bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL); in bcmgenet_wol_power_up_cfg()
259 spin_lock_bh(&priv->reg_lock); in bcmgenet_wol_power_up_cfg()
260 reg = bcmgenet_umac_readl(priv, UMAC_CMD); in bcmgenet_wol_power_up_cfg()
261 reg &= ~CMD_CRC_FWD; in bcmgenet_wol_power_up_cfg()
262 bcmgenet_umac_writel(priv, reg, UMAC_CMD); in bcmgenet_wol_power_up_cfg()
263 spin_unlock_bh(&priv->reg_lock); in bcmgenet_wol_power_up_cfg()