Add bcmgenet 5.14.21

This commit is contained in:
Bjarne von Horn
2024-02-02 16:22:54 +01:00
parent 69a8ff515a
commit 1485d78d6a
12 changed files with 12026 additions and 1 deletions

View File

@@ -32,17 +32,29 @@ EXTRA_DIST = \
bcmgenet-5.10-ethercat.h \
bcmgenet-5.10-orig.c \
bcmgenet-5.10-orig.h \
bcmgenet-5.14-ethercat.c \
bcmgenet-5.14-ethercat.h \
bcmgenet-5.14-orig.c \
bcmgenet-5.14-orig.h \
bcmgenet-6.1-ethercat.c \
bcmgenet-6.1-ethercat.h \
bcmgenet-6.1-orig.c \
bcmgenet-6.1-orig.h \
bcmgenet_wol-5.10-ethercat.c \
bcmgenet_wol-5.10-orig.c \
bcmgenet_wol-5.14-ethercat.c \
bcmgenet_wol-5.14-orig.c \
bcmgenet_wol-6.1-ethercat.c \
bcmgenet_wol-6.1-orig.c \
bcmmii-5.14-ethercat.c \
bcmmii-5.14-orig.c \
bcmmii-5.10-ethercat.c \
bcmmii-5.10-orig.c \
bcmmii-6.1-ethercat.c \
bcmmii-6.1-orig.c
bcmmii-6.1-orig.c \
unimac-5.14-ethercat.h \
unimac-5.14-orig.h \
unimac-6.1-ethercat.h \
unimac-6.1-orig.h
#------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1992,6 +1992,7 @@ static struct sk_buff *bcmgenet_add_tsb(struct net_device *dev,
/* If 64 byte status block enabled, must make sure skb has
* enough headroom for us to insert 64B status block.
*/
BUG_ON(priv->ecdev);
new_skb = skb_realloc_headroom(skb, sizeof(*status));
if (!new_skb) {
dev_kfree_skb_any(skb);

View File

@@ -0,0 +1,237 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Broadcom GENET (Gigabit Ethernet) Wake-on-LAN support
*
* Copyright (c) 2014-2020 Broadcom
*/
#define pr_fmt(fmt) "bcmgenet_wol: " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <net/arp.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/phy.h>
#include "bcmgenet-5.14-ethercat.h"
/* ethtool function - get WOL (Wake on LAN) settings, Only Magic Packet
* Detection is supported through ethtool
*/
void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER;
wol->wolopts = priv->wolopts;
memset(wol->sopass, 0, sizeof(wol->sopass));
if (wol->wolopts & WAKE_MAGICSECURE)
memcpy(wol->sopass, priv->sopass, sizeof(priv->sopass));
}
/* ethtool function - set WOL (Wake on LAN) settings.
* Only for magic packet detection mode.
*/
int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
struct device *kdev = &priv->pdev->dev;
if (!device_can_wakeup(kdev))
return -ENOTSUPP;
if (wol->wolopts & ~(WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER))
return -EINVAL;
if (wol->wolopts & WAKE_MAGICSECURE)
memcpy(priv->sopass, wol->sopass, sizeof(priv->sopass));
/* Flag the device and relevant IRQ as wakeup capable */
if (wol->wolopts) {
device_set_wakeup_enable(kdev, 1);
/* Avoid unbalanced enable_irq_wake calls */
if (priv->wol_irq_disabled)
enable_irq_wake(priv->wol_irq);
priv->wol_irq_disabled = false;
} else {
device_set_wakeup_enable(kdev, 0);
/* Avoid unbalanced disable_irq_wake calls */
if (!priv->wol_irq_disabled)
disable_irq_wake(priv->wol_irq);
priv->wol_irq_disabled = true;
}
priv->wolopts = wol->wolopts;
return 0;
}
static int bcmgenet_poll_wol_status(struct bcmgenet_priv *priv)
{
struct net_device *dev = priv->dev;
int retries = 0;
while (!(bcmgenet_rbuf_readl(priv, RBUF_STATUS)
& RBUF_STATUS_WOL)) {
retries++;
if (retries > 5) {
netdev_crit(dev, "polling wol mode timeout\n");
return -ETIMEDOUT;
}
mdelay(1);
}
return retries;
}
static void bcmgenet_set_mpd_password(struct bcmgenet_priv *priv)
{
bcmgenet_umac_writel(priv, get_unaligned_be16(&priv->sopass[0]),
UMAC_MPD_PW_MS);
bcmgenet_umac_writel(priv, get_unaligned_be32(&priv->sopass[2]),
UMAC_MPD_PW_LS);
}
int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
enum bcmgenet_power_mode mode)
{
struct net_device *dev = priv->dev;
struct bcmgenet_rxnfc_rule *rule;
u32 reg, hfb_ctrl_reg, hfb_enable = 0;
int retries = 0;
if (mode != GENET_POWER_WOL_MAGIC) {
netif_err(priv, wol, dev, "unsupported mode: %d\n", mode);
return -EINVAL;
}
/* Can't suspend with WoL if MAC is still in reset */
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
if (reg & CMD_SW_RESET)
reg &= ~CMD_SW_RESET;
/* disable RX */
reg &= ~CMD_RX_EN;
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
mdelay(10);
if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
reg |= MPD_EN;
if (priv->wolopts & WAKE_MAGICSECURE) {
bcmgenet_set_mpd_password(priv);
reg |= MPD_PW_EN;
}
bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
}
hfb_ctrl_reg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL);
if (priv->wolopts & WAKE_FILTER) {
list_for_each_entry(rule, &priv->rxnfc_list, list)
if (rule->fs.ring_cookie == RX_CLS_FLOW_WAKE)
hfb_enable |= (1 << rule->fs.location);
reg = (hfb_ctrl_reg & ~RBUF_HFB_EN) | RBUF_ACPI_EN;
bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL);
}
/* Do not leave UniMAC in MPD mode only */
retries = bcmgenet_poll_wol_status(priv);
if (retries < 0) {
reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
reg &= ~(MPD_EN | MPD_PW_EN);
bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
bcmgenet_hfb_reg_writel(priv, hfb_ctrl_reg, HFB_CTRL);
return retries;
}
netif_dbg(priv, wol, dev, "MPD WOL-ready status set after %d msec\n",
retries);
clk_prepare_enable(priv->clk_wol);
priv->wol_active = 1;
if (hfb_enable) {
bcmgenet_hfb_reg_writel(priv, hfb_enable,
HFB_FLT_ENABLE_V3PLUS + 4);
hfb_ctrl_reg = RBUF_HFB_EN | RBUF_ACPI_EN;
bcmgenet_hfb_reg_writel(priv, hfb_ctrl_reg, HFB_CTRL);
}
/* Enable CRC forward */
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
priv->crc_fwd_en = 1;
reg |= CMD_CRC_FWD;
/* Receiver must be enabled for WOL MP detection */
reg |= CMD_RX_EN;
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
reg = UMAC_IRQ_MPD_R;
if (hfb_enable)
reg |= UMAC_IRQ_HFB_SM | UMAC_IRQ_HFB_MM;
bcmgenet_intrl2_0_writel(priv, reg, INTRL2_CPU_MASK_CLEAR);
return 0;
}
void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
enum bcmgenet_power_mode mode)
{
u32 reg;
if (mode != GENET_POWER_WOL_MAGIC) {
netif_err(priv, wol, priv->dev, "invalid mode: %d\n", mode);
return;
}
if (!priv->wol_active)
return; /* failed to suspend so skip the rest */
priv->wol_active = 0;
clk_disable_unprepare(priv->clk_wol);
priv->crc_fwd_en = 0;
/* Disable Magic Packet Detection */
if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
if (!(reg & MPD_EN))
return; /* already reset so skip the rest */
reg &= ~(MPD_EN | MPD_PW_EN);
bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
}
/* Disable WAKE_FILTER Detection */
if (priv->wolopts & WAKE_FILTER) {
reg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL);
if (!(reg & RBUF_ACPI_EN))
return; /* already reset so skip the rest */
reg &= ~(RBUF_HFB_EN | RBUF_ACPI_EN);
bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL);
}
/* Disable CRC Forward */
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
reg &= ~CMD_CRC_FWD;
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
}

View File

@@ -0,0 +1,237 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Broadcom GENET (Gigabit Ethernet) Wake-on-LAN support
*
* Copyright (c) 2014-2020 Broadcom
*/
#define pr_fmt(fmt) "bcmgenet_wol: " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <net/arp.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/phy.h>
#include "bcmgenet.h"
/* ethtool function - get WOL (Wake on LAN) settings, Only Magic Packet
* Detection is supported through ethtool
*/
void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER;
wol->wolopts = priv->wolopts;
memset(wol->sopass, 0, sizeof(wol->sopass));
if (wol->wolopts & WAKE_MAGICSECURE)
memcpy(wol->sopass, priv->sopass, sizeof(priv->sopass));
}
/* ethtool function - set WOL (Wake on LAN) settings.
* Only for magic packet detection mode.
*/
int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
struct device *kdev = &priv->pdev->dev;
if (!device_can_wakeup(kdev))
return -ENOTSUPP;
if (wol->wolopts & ~(WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER))
return -EINVAL;
if (wol->wolopts & WAKE_MAGICSECURE)
memcpy(priv->sopass, wol->sopass, sizeof(priv->sopass));
/* Flag the device and relevant IRQ as wakeup capable */
if (wol->wolopts) {
device_set_wakeup_enable(kdev, 1);
/* Avoid unbalanced enable_irq_wake calls */
if (priv->wol_irq_disabled)
enable_irq_wake(priv->wol_irq);
priv->wol_irq_disabled = false;
} else {
device_set_wakeup_enable(kdev, 0);
/* Avoid unbalanced disable_irq_wake calls */
if (!priv->wol_irq_disabled)
disable_irq_wake(priv->wol_irq);
priv->wol_irq_disabled = true;
}
priv->wolopts = wol->wolopts;
return 0;
}
static int bcmgenet_poll_wol_status(struct bcmgenet_priv *priv)
{
struct net_device *dev = priv->dev;
int retries = 0;
while (!(bcmgenet_rbuf_readl(priv, RBUF_STATUS)
& RBUF_STATUS_WOL)) {
retries++;
if (retries > 5) {
netdev_crit(dev, "polling wol mode timeout\n");
return -ETIMEDOUT;
}
mdelay(1);
}
return retries;
}
static void bcmgenet_set_mpd_password(struct bcmgenet_priv *priv)
{
bcmgenet_umac_writel(priv, get_unaligned_be16(&priv->sopass[0]),
UMAC_MPD_PW_MS);
bcmgenet_umac_writel(priv, get_unaligned_be32(&priv->sopass[2]),
UMAC_MPD_PW_LS);
}
int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
enum bcmgenet_power_mode mode)
{
struct net_device *dev = priv->dev;
struct bcmgenet_rxnfc_rule *rule;
u32 reg, hfb_ctrl_reg, hfb_enable = 0;
int retries = 0;
if (mode != GENET_POWER_WOL_MAGIC) {
netif_err(priv, wol, dev, "unsupported mode: %d\n", mode);
return -EINVAL;
}
/* Can't suspend with WoL if MAC is still in reset */
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
if (reg & CMD_SW_RESET)
reg &= ~CMD_SW_RESET;
/* disable RX */
reg &= ~CMD_RX_EN;
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
mdelay(10);
if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
reg |= MPD_EN;
if (priv->wolopts & WAKE_MAGICSECURE) {
bcmgenet_set_mpd_password(priv);
reg |= MPD_PW_EN;
}
bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
}
hfb_ctrl_reg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL);
if (priv->wolopts & WAKE_FILTER) {
list_for_each_entry(rule, &priv->rxnfc_list, list)
if (rule->fs.ring_cookie == RX_CLS_FLOW_WAKE)
hfb_enable |= (1 << rule->fs.location);
reg = (hfb_ctrl_reg & ~RBUF_HFB_EN) | RBUF_ACPI_EN;
bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL);
}
/* Do not leave UniMAC in MPD mode only */
retries = bcmgenet_poll_wol_status(priv);
if (retries < 0) {
reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
reg &= ~(MPD_EN | MPD_PW_EN);
bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
bcmgenet_hfb_reg_writel(priv, hfb_ctrl_reg, HFB_CTRL);
return retries;
}
netif_dbg(priv, wol, dev, "MPD WOL-ready status set after %d msec\n",
retries);
clk_prepare_enable(priv->clk_wol);
priv->wol_active = 1;
if (hfb_enable) {
bcmgenet_hfb_reg_writel(priv, hfb_enable,
HFB_FLT_ENABLE_V3PLUS + 4);
hfb_ctrl_reg = RBUF_HFB_EN | RBUF_ACPI_EN;
bcmgenet_hfb_reg_writel(priv, hfb_ctrl_reg, HFB_CTRL);
}
/* Enable CRC forward */
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
priv->crc_fwd_en = 1;
reg |= CMD_CRC_FWD;
/* Receiver must be enabled for WOL MP detection */
reg |= CMD_RX_EN;
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
reg = UMAC_IRQ_MPD_R;
if (hfb_enable)
reg |= UMAC_IRQ_HFB_SM | UMAC_IRQ_HFB_MM;
bcmgenet_intrl2_0_writel(priv, reg, INTRL2_CPU_MASK_CLEAR);
return 0;
}
void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
enum bcmgenet_power_mode mode)
{
u32 reg;
if (mode != GENET_POWER_WOL_MAGIC) {
netif_err(priv, wol, priv->dev, "invalid mode: %d\n", mode);
return;
}
if (!priv->wol_active)
return; /* failed to suspend so skip the rest */
priv->wol_active = 0;
clk_disable_unprepare(priv->clk_wol);
priv->crc_fwd_en = 0;
/* Disable Magic Packet Detection */
if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
if (!(reg & MPD_EN))
return; /* already reset so skip the rest */
reg &= ~(MPD_EN | MPD_PW_EN);
bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
}
/* Disable WAKE_FILTER Detection */
if (priv->wolopts & WAKE_FILTER) {
reg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL);
if (!(reg & RBUF_ACPI_EN))
return; /* already reset so skip the rest */
reg &= ~(RBUF_HFB_EN | RBUF_ACPI_EN);
bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL);
}
/* Disable CRC Forward */
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
reg &= ~CMD_CRC_FWD;
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __UNIMAC_H
#define __UNIMAC_H
#define UMAC_HD_BKP_CTRL 0x004
#define HD_FC_EN (1 << 0)
#define HD_FC_BKOFF_OK (1 << 1)
#define IPG_CONFIG_RX_SHIFT 2
#define IPG_CONFIG_RX_MASK 0x1F
#define UMAC_CMD 0x008
#define CMD_TX_EN (1 << 0)
#define CMD_RX_EN (1 << 1)
#define CMD_SPEED_10 0
#define CMD_SPEED_100 1
#define CMD_SPEED_1000 2
#define CMD_SPEED_2500 3
#define CMD_SPEED_SHIFT 2
#define CMD_SPEED_MASK 3
#define CMD_PROMISC (1 << 4)
#define CMD_PAD_EN (1 << 5)
#define CMD_CRC_FWD (1 << 6)
#define CMD_PAUSE_FWD (1 << 7)
#define CMD_RX_PAUSE_IGNORE (1 << 8)
#define CMD_TX_ADDR_INS (1 << 9)
#define CMD_HD_EN (1 << 10)
#define CMD_SW_RESET_OLD (1 << 11)
#define CMD_SW_RESET (1 << 13)
#define CMD_LCL_LOOP_EN (1 << 15)
#define CMD_AUTO_CONFIG (1 << 22)
#define CMD_CNTL_FRM_EN (1 << 23)
#define CMD_NO_LEN_CHK (1 << 24)
#define CMD_RMT_LOOP_EN (1 << 25)
#define CMD_RX_ERR_DISC (1 << 26)
#define CMD_PRBL_EN (1 << 27)
#define CMD_TX_PAUSE_IGNORE (1 << 28)
#define CMD_TX_RX_EN (1 << 29)
#define CMD_RUNT_FILTER_DIS (1 << 30)
#define UMAC_MAC0 0x00c
#define UMAC_MAC1 0x010
#define UMAC_MAX_FRAME_LEN 0x014
#define UMAC_PAUSE_QUANTA 0x018
#define UMAC_MODE 0x044
#define MODE_LINK_STATUS (1 << 5)
#define UMAC_FRM_TAG0 0x048 /* outer tag */
#define UMAC_FRM_TAG1 0x04c /* inner tag */
#define UMAC_TX_IPG_LEN 0x05c
#define UMAC_EEE_CTRL 0x064
#define EN_LPI_RX_PAUSE (1 << 0)
#define EN_LPI_TX_PFC (1 << 1)
#define EN_LPI_TX_PAUSE (1 << 2)
#define EEE_EN (1 << 3)
#define RX_FIFO_CHECK (1 << 4)
#define EEE_TX_CLK_DIS (1 << 5)
#define DIS_EEE_10M (1 << 6)
#define LP_IDLE_PREDICTION_MODE (1 << 7)
#define UMAC_EEE_LPI_TIMER 0x068
#define UMAC_EEE_WAKE_TIMER 0x06C
#define UMAC_EEE_REF_COUNT 0x070
#define EEE_REFERENCE_COUNT_MASK 0xffff
#define UMAC_RX_IPG_INV 0x078
#define UMAC_MACSEC_PROG_TX_CRC 0x310
#define UMAC_MACSEC_CTRL 0x314
#define UMAC_PAUSE_CTRL 0x330
#define UMAC_TX_FLUSH 0x334
#define UMAC_RX_FIFO_STATUS 0x338
#define UMAC_TX_FIFO_STATUS 0x33c
#endif

View File

@@ -0,0 +1,68 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __UNIMAC_H
#define __UNIMAC_H
#define UMAC_HD_BKP_CTRL 0x004
#define HD_FC_EN (1 << 0)
#define HD_FC_BKOFF_OK (1 << 1)
#define IPG_CONFIG_RX_SHIFT 2
#define IPG_CONFIG_RX_MASK 0x1F
#define UMAC_CMD 0x008
#define CMD_TX_EN (1 << 0)
#define CMD_RX_EN (1 << 1)
#define CMD_SPEED_10 0
#define CMD_SPEED_100 1
#define CMD_SPEED_1000 2
#define CMD_SPEED_2500 3
#define CMD_SPEED_SHIFT 2
#define CMD_SPEED_MASK 3
#define CMD_PROMISC (1 << 4)
#define CMD_PAD_EN (1 << 5)
#define CMD_CRC_FWD (1 << 6)
#define CMD_PAUSE_FWD (1 << 7)
#define CMD_RX_PAUSE_IGNORE (1 << 8)
#define CMD_TX_ADDR_INS (1 << 9)
#define CMD_HD_EN (1 << 10)
#define CMD_SW_RESET_OLD (1 << 11)
#define CMD_SW_RESET (1 << 13)
#define CMD_LCL_LOOP_EN (1 << 15)
#define CMD_AUTO_CONFIG (1 << 22)
#define CMD_CNTL_FRM_EN (1 << 23)
#define CMD_NO_LEN_CHK (1 << 24)
#define CMD_RMT_LOOP_EN (1 << 25)
#define CMD_RX_ERR_DISC (1 << 26)
#define CMD_PRBL_EN (1 << 27)
#define CMD_TX_PAUSE_IGNORE (1 << 28)
#define CMD_TX_RX_EN (1 << 29)
#define CMD_RUNT_FILTER_DIS (1 << 30)
#define UMAC_MAC0 0x00c
#define UMAC_MAC1 0x010
#define UMAC_MAX_FRAME_LEN 0x014
#define UMAC_PAUSE_QUANTA 0x018
#define UMAC_MODE 0x044
#define MODE_LINK_STATUS (1 << 5)
#define UMAC_FRM_TAG0 0x048 /* outer tag */
#define UMAC_FRM_TAG1 0x04c /* inner tag */
#define UMAC_TX_IPG_LEN 0x05c
#define UMAC_EEE_CTRL 0x064
#define EN_LPI_RX_PAUSE (1 << 0)
#define EN_LPI_TX_PFC (1 << 1)
#define EN_LPI_TX_PAUSE (1 << 2)
#define EEE_EN (1 << 3)
#define RX_FIFO_CHECK (1 << 4)
#define EEE_TX_CLK_DIS (1 << 5)
#define DIS_EEE_10M (1 << 6)
#define LP_IDLE_PREDICTION_MODE (1 << 7)
#define UMAC_EEE_LPI_TIMER 0x068
#define UMAC_EEE_WAKE_TIMER 0x06C
#define UMAC_EEE_REF_COUNT 0x070
#define EEE_REFERENCE_COUNT_MASK 0xffff
#define UMAC_RX_IPG_INV 0x078
#define UMAC_MACSEC_PROG_TX_CRC 0x310
#define UMAC_MACSEC_CTRL 0x314
#define UMAC_PAUSE_CTRL 0x330
#define UMAC_TX_FLUSH 0x334
#define UMAC_RX_FIFO_STATUS 0x338
#define UMAC_TX_FIFO_STATUS 0x33c
#endif