Commit 50b70845 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'add-ethernet-driver-for-tehuti-networks-tn40xx-chips'

FUJITA Tomonori says:

====================
add ethernet driver for Tehuti Networks TN40xx chips

This patchset adds a new 10G ethernet driver for Tehuti Networks
TN40xx chips. Note in mainline, there is a driver for Tehuti Networks
(drivers/net/ethernet/tehuti/tehuti.[hc]), which supports TN30xx
chips.

Multiple vendors (DLink, Asus, Edimax, QNAP, etc) developed adapters
based on TN40xx chips. Tehuti Networks went out of business but the
drivers are still distributed under GPL2 with some of the hardware
(and also available on some sites). With some changes, I try to
upstream this driver with a new PHY driver in Rust.

The major change is replacing the PHY abstraction layer in the original
driver with phylink. TN40xx chips are used with various PHY hardware
(AMCC QT2025, TI TLK10232, Aqrate AQR105, and Marvell MV88X3120,
MV88X3310, and MV88E2010).

I've also been working on a new PHY driver for QT2025 in Rust [1]. For
now, I enable only adapters using QT2025 PHY in the PCI ID table of
this driver. I've tested this driver and the QT2025 PHY driver with
Edimax EN-9320 10G adapter and 10G-SR SFP+. In mainline, there are PHY
drivers for AQR105 and Marvell PHYs, which could work for some TN40xx
adapters with this driver.

To make reviewing easier, this patchset has only basic functions. Once
merged, I'll submit features like ethtool support.

v11: https://lore.kernel.org/netdev/20240618051608.95208-7-fujita.tomonori@gmail.com/
v10: https://lore.kernel.org/netdev/20240611045217.78529-7-fujita.tomonori@gmail.com/
v9: https://lore.kernel.org/netdev/20240605232608.65471-1-fujita.tomonori@gmail.com/
v8: https://lore.kernel.org/netdev/20240603064955.58327-1-fujita.tomonori@gmail.com/
v7: https://lore.kernel.org/netdev/20240527203928.38206-7-fujita.tomonori@gmail.com/
v6: https://lore.kernel.org/netdev/20240512085611.79747-2-fujita.tomonori@gmail.com/
v5: https://lore.kernel.org/netdev/20240508113947.68530-1-fujita.tomonori@gmail.com/
v4: https://lore.kernel.org/netdev/20240501230552.53185-1-fujita.tomonori@gmail.com/
v3: https://lore.kernel.org/netdev/20240429043827.44407-1-fujita.tomonori@gmail.com/
v2: https://lore.kernel.org/netdev/20240425010354.32605-1-fujita.tomonori@gmail.com/
v1: https://lore.kernel.org/netdev/20240415104352.4685-1-fujita.tomonori@gmail.com/

[1] https://lore.kernel.org/netdev/20240415104701.4772-1-fujita.tomonori@gmail.com/
====================

Link: https://patch.msgid.link/20240623235507.108147-1-fujita.tomonori@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents c0c68e4d 30824122
......@@ -22148,7 +22148,13 @@ TEHUTI ETHERNET DRIVER
M: Andy Gospodarek <andy@greyhouse.net>
L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/tehuti/*
F: drivers/net/ethernet/tehuti/tehuti.*
TEHUTI TN40XX ETHERNET DRIVER
M: FUJITA Tomonori <fujita.tomonori@gmail.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/tehuti/tn40*
TELECOM CLOCK DRIVER FOR MCPL0010
M: Mark Gross <markgross@kernel.org>
......
......@@ -23,4 +23,19 @@ config TEHUTI
help
Tehuti Networks 10G Ethernet NIC
config TEHUTI_TN40
tristate "Tehuti Networks TN40xx 10G Ethernet adapters"
depends on PCI
select PAGE_POOL
select FW_LOADER
select PHYLINK
help
This driver supports 10G Ethernet adapters using Tehuti Networks
TN40xx chips. Currently, adapters with Applied Micro Circuits
Corporation QT2025 are supported; Tehuti Networks TN9310,
DLink DXE-810S, ASUS XG-C100F, and Edimax EN-9320.
To compile this driver as a module, choose M here: the module
will be called tn40xx.
endif # NET_VENDOR_TEHUTI
......@@ -4,3 +4,6 @@
#
obj-$(CONFIG_TEHUTI) += tehuti.o
tn40xx-y := tn40.o tn40_mdio.o tn40_phy.o
obj-$(CONFIG_TEHUTI_TN40) += tn40xx.o
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) Tehuti Networks Ltd. */
#ifndef _TN40_H_
#define _TN40_H_
#include "tn40_regs.h"
#define TN40_DRV_NAME "tn40xx"
#define TN40_MDIO_SPEED_1MHZ (1)
#define TN40_MDIO_SPEED_6MHZ (6)
/* netdev tx queue len for Luxor. The default value is 1000.
* ifconfig eth1 txqueuelen 3000 - to change it at runtime.
*/
#define TN40_NDEV_TXQ_LEN 1000
#define TN40_FIFO_SIZE 4096
#define TN40_FIFO_EXTRA_SPACE 1024
#define TN40_TXF_DESC_SZ 16
#define TN40_MAX_TX_LEVEL (priv->txd_fifo0.m.memsz - 16)
#define TN40_MIN_TX_LEVEL 256
#define TN40_NO_UPD_PACKETS 40
#define TN40_MAX_MTU BIT(14)
#define TN40_PCK_TH_MULT 128
#define TN40_INT_COAL_MULT 2
#define TN40_INT_REG_VAL(coal, coal_rc, rxf_th, pck_th) ( \
FIELD_PREP(GENMASK(14, 0), (coal)) | \
FIELD_PREP(BIT(15), (coal_rc)) | \
FIELD_PREP(GENMASK(19, 16), (rxf_th)) | \
FIELD_PREP(GENMASK(31, 20), (pck_th)) \
)
struct tn40_fifo {
dma_addr_t da; /* Physical address of fifo (used by HW) */
char *va; /* Virtual address of fifo (used by SW) */
u32 rptr, wptr;
/* Cached values of RPTR and WPTR registers,
* they're 32 bits on both 32 and 64 archs.
*/
u16 reg_cfg0;
u16 reg_cfg1;
u16 reg_rptr;
u16 reg_wptr;
u16 memsz; /* Memory size allocated for fifo */
u16 size_mask;
u16 pktsz; /* Skb packet size to allocate */
u16 rcvno; /* Number of buffers that come from this RXF */
};
struct tn40_txf_fifo {
struct tn40_fifo m; /* The minimal set of variables used by all fifos */
};
struct tn40_txd_fifo {
struct tn40_fifo m; /* The minimal set of variables used by all fifos */
};
struct tn40_rxf_fifo {
struct tn40_fifo m; /* The minimal set of variables used by all fifos */
};
struct tn40_rxd_fifo {
struct tn40_fifo m; /* The minimal set of variables used by all fifos */
};
struct tn40_rx_map {
struct page *page;
};
struct tn40_rxdb {
unsigned int *stack;
struct tn40_rx_map *elems;
unsigned int nelem;
unsigned int top;
};
union tn40_tx_dma_addr {
dma_addr_t dma;
struct sk_buff *skb;
};
/* Entry in the db.
* if len == 0 addr is dma
* if len != 0 addr is skb
*/
struct tn40_tx_map {
union tn40_tx_dma_addr addr;
int len;
};
/* tx database - implemented as circular fifo buffer */
struct tn40_txdb {
struct tn40_tx_map *start; /* Points to the first element */
struct tn40_tx_map *end; /* Points just AFTER the last element */
struct tn40_tx_map *rptr; /* Points to the next element to read */
struct tn40_tx_map *wptr; /* Points to the next element to write */
int size; /* Number of elements in the db */
};
struct tn40_priv {
struct net_device *ndev;
struct pci_dev *pdev;
struct napi_struct napi;
/* RX FIFOs: 1 for data (full) descs, and 2 for free descs */
struct tn40_rxd_fifo rxd_fifo0;
struct tn40_rxf_fifo rxf_fifo0;
struct tn40_rxdb *rxdb0; /* Rx dbs to store skb pointers */
struct page_pool *page_pool;
/* Tx FIFOs: 1 for data desc, 1 for empty (acks) desc */
struct tn40_txd_fifo txd_fifo0;
struct tn40_txf_fifo txf_fifo0;
struct tn40_txdb txdb;
int tx_level;
int tx_update_mark;
int tx_noupd;
int stats_flag;
struct rtnl_link_stats64 stats;
struct u64_stats_sync syncp;
u8 txd_size;
u8 txf_size;
u8 rxd_size;
u8 rxf_size;
u32 rdintcm;
u32 tdintcm;
u32 isr_mask;
void __iomem *regs;
/* SHORT_PKT_FIX */
u32 b0_len;
dma_addr_t b0_dma; /* Physical address of buffer */
char *b0_va; /* Virtual address of buffer */
struct mii_bus *mdio;
struct phy_device *phydev;
struct phylink *phylink;
struct phylink_config phylink_config;
};
/* RX FREE descriptor - 64bit */
struct tn40_rxf_desc {
__le32 info; /* Buffer Count + Info - described below */
__le32 va_lo; /* VAdr[31:0] */
__le32 va_hi; /* VAdr[63:32] */
__le32 pa_lo; /* PAdr[31:0] */
__le32 pa_hi; /* PAdr[63:32] */
__le32 len; /* Buffer Length */
};
#define TN40_GET_RXD_BC(x) FIELD_GET(GENMASK(4, 0), (x))
#define TN40_GET_RXD_ERR(x) FIELD_GET(GENMASK(26, 21), (x))
#define TN40_GET_RXD_PKT_ID(x) FIELD_GET(GENMASK(30, 28), (x))
#define TN40_GET_RXD_VTAG(x) FIELD_GET(BIT(31), (x))
#define TN40_GET_RXD_VLAN_TCI(x) FIELD_GET(GENMASK(15, 0), (x))
struct tn40_rxd_desc {
__le32 rxd_val1;
__le16 len;
__le16 rxd_vlan;
__le32 va_lo;
__le32 va_hi;
__le32 rss_lo;
__le32 rss_hash;
};
#define TN40_MAX_PBL (19)
/* PBL describes each virtual buffer to be transmitted from the host. */
struct tn40_pbl {
__le32 pa_lo;
__le32 pa_hi;
__le32 len;
};
/* First word for TXD descriptor. It means: type = 3 for regular Tx packet,
* hw_csum = 7 for IP+UDP+TCP HW checksums.
*/
#define TN40_TXD_W1_VAL(bc, checksum, vtag, lgsnd, vlan_id) ( \
GENMASK(17, 16) | \
FIELD_PREP(GENMASK(4, 0), (bc)) | \
FIELD_PREP(GENMASK(7, 5), (checksum)) | \
FIELD_PREP(BIT(8), (vtag)) | \
FIELD_PREP(GENMASK(12, 9), (lgsnd)) | \
FIELD_PREP(GENMASK(15, 13), \
FIELD_GET(GENMASK(15, 13), (vlan_id))) | \
FIELD_PREP(GENMASK(31, 20), \
FIELD_GET(GENMASK(11, 0), (vlan_id))) \
)
struct tn40_txd_desc {
__le32 txd_val1;
__le16 mss;
__le16 length;
__le32 va_lo;
__le32 va_hi;
struct tn40_pbl pbl[]; /* Fragments */
};
struct tn40_txf_desc {
u32 status;
u32 va_lo; /* VAdr[31:0] */
u32 va_hi; /* VAdr[63:32] */
u32 pad;
};
static inline u32 tn40_read_reg(struct tn40_priv *priv, u32 reg)
{
return readl(priv->regs + reg);
}
static inline void tn40_write_reg(struct tn40_priv *priv, u32 reg, u32 val)
{
writel(val, priv->regs + reg);
}
int tn40_set_link_speed(struct tn40_priv *priv, u32 speed);
int tn40_mdiobus_init(struct tn40_priv *priv);
int tn40_phy_register(struct tn40_priv *priv);
void tn40_phy_unregister(struct tn40_priv *priv);
#endif /* _TN40XX_H */
// SPDX-License-Identifier: GPL-2.0+
/* Copyright (c) Tehuti Networks Ltd. */
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/phylink.h>
#include "tn40.h"
#define TN40_MDIO_DEVAD_MASK GENMASK(4, 0)
#define TN40_MDIO_PRTAD_MASK GENMASK(9, 5)
#define TN40_MDIO_CMD_VAL(device, port) \
(FIELD_PREP(TN40_MDIO_DEVAD_MASK, (device)) | \
(FIELD_PREP(TN40_MDIO_PRTAD_MASK, (port))))
#define TN40_MDIO_CMD_READ BIT(15)
static void tn40_mdio_set_speed(struct tn40_priv *priv, u32 speed)
{
void __iomem *regs = priv->regs;
int mdio_cfg;
if (speed == TN40_MDIO_SPEED_1MHZ)
mdio_cfg = (0x7d << 7) | 0x08; /* 1MHz */
else
mdio_cfg = 0xA08; /* 6MHz */
mdio_cfg |= (1 << 6);
writel(mdio_cfg, regs + TN40_REG_MDIO_CMD_STAT);
msleep(100);
}
static u32 tn40_mdio_stat(struct tn40_priv *priv)
{
void __iomem *regs = priv->regs;
return readl(regs + TN40_REG_MDIO_CMD_STAT);
}
static int tn40_mdio_wait_nobusy(struct tn40_priv *priv, u32 *val)
{
u32 stat;
int ret;
ret = readx_poll_timeout_atomic(tn40_mdio_stat, priv, stat,
TN40_GET_MDIO_BUSY(stat) == 0, 10,
10000);
if (val)
*val = stat;
return ret;
}
static int tn40_mdio_read(struct tn40_priv *priv, int port, int device,
u16 regnum)
{
void __iomem *regs = priv->regs;
u32 i;
/* wait until MDIO is not busy */
if (tn40_mdio_wait_nobusy(priv, NULL))
return -EIO;
i = TN40_MDIO_CMD_VAL(device, port);
writel(i, regs + TN40_REG_MDIO_CMD);
writel((u32)regnum, regs + TN40_REG_MDIO_ADDR);
if (tn40_mdio_wait_nobusy(priv, NULL))
return -EIO;
writel(TN40_MDIO_CMD_READ | i, regs + TN40_REG_MDIO_CMD);
/* read CMD_STAT until not busy */
if (tn40_mdio_wait_nobusy(priv, NULL))
return -EIO;
return lower_16_bits(readl(regs + TN40_REG_MDIO_DATA));
}
static int tn40_mdio_write(struct tn40_priv *priv, int port, int device,
u16 regnum, u16 data)
{
void __iomem *regs = priv->regs;
u32 tmp_reg = 0;
int ret;
/* wait until MDIO is not busy */
if (tn40_mdio_wait_nobusy(priv, NULL))
return -EIO;
writel(TN40_MDIO_CMD_VAL(device, port), regs + TN40_REG_MDIO_CMD);
writel((u32)regnum, regs + TN40_REG_MDIO_ADDR);
if (tn40_mdio_wait_nobusy(priv, NULL))
return -EIO;
writel((u32)data, regs + TN40_REG_MDIO_DATA);
/* read CMD_STAT until not busy */
ret = tn40_mdio_wait_nobusy(priv, &tmp_reg);
if (ret)
return -EIO;
if (TN40_GET_MDIO_RD_ERR(tmp_reg)) {
dev_err(&priv->pdev->dev, "MDIO error after write command\n");
return -EIO;
}
return 0;
}
static int tn40_mdio_read_c45(struct mii_bus *mii_bus, int addr, int devnum,
int regnum)
{
return tn40_mdio_read(mii_bus->priv, addr, devnum, regnum);
}
static int tn40_mdio_write_c45(struct mii_bus *mii_bus, int addr, int devnum,
int regnum, u16 val)
{
return tn40_mdio_write(mii_bus->priv, addr, devnum, regnum, val);
}
int tn40_mdiobus_init(struct tn40_priv *priv)
{
struct pci_dev *pdev = priv->pdev;
struct mii_bus *bus;
int ret;
bus = devm_mdiobus_alloc(&pdev->dev);
if (!bus)
return -ENOMEM;
bus->name = TN40_DRV_NAME;
bus->parent = &pdev->dev;
snprintf(bus->id, MII_BUS_ID_SIZE, "tn40xx-%x-%x",
pci_domain_nr(pdev->bus), pci_dev_id(pdev));
bus->priv = priv;
bus->read_c45 = tn40_mdio_read_c45;
bus->write_c45 = tn40_mdio_write_c45;
ret = devm_mdiobus_register(&pdev->dev, bus);
if (ret) {
dev_err(&pdev->dev, "failed to register mdiobus %d %u %u\n",
ret, bus->state, MDIOBUS_UNREGISTERED);
return ret;
}
tn40_mdio_set_speed(priv, TN40_MDIO_SPEED_6MHZ);
priv->mdio = bus;
return 0;
}
// SPDX-License-Identifier: GPL-2.0+
/* Copyright (c) Tehuti Networks Ltd. */
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/phylink.h>
#include "tn40.h"
static struct tn40_priv *tn40_config_to_priv(struct phylink_config *config)
{
return container_of(config, struct tn40_priv, phylink_config);
}
static void tn40_link_up(struct phylink_config *config, struct phy_device *phy,
unsigned int mode, phy_interface_t interface,
int speed, int duplex, bool tx_pause, bool rx_pause)
{
struct tn40_priv *priv = tn40_config_to_priv(config);
tn40_set_link_speed(priv, speed);
netif_wake_queue(priv->ndev);
}
static void tn40_link_down(struct phylink_config *config, unsigned int mode,
phy_interface_t interface)
{
struct tn40_priv *priv = tn40_config_to_priv(config);
netif_stop_queue(priv->ndev);
tn40_set_link_speed(priv, 0);
}
static void tn40_mac_config(struct phylink_config *config, unsigned int mode,
const struct phylink_link_state *state)
{
}
static const struct phylink_mac_ops tn40_mac_ops = {
.mac_config = tn40_mac_config,
.mac_link_up = tn40_link_up,
.mac_link_down = tn40_link_down,
};
int tn40_phy_register(struct tn40_priv *priv)
{
struct phylink_config *config;
struct phy_device *phydev;
struct phylink *phylink;
phydev = phy_find_first(priv->mdio);
if (!phydev) {
dev_err(&priv->pdev->dev, "PHY isn't found\n");
return -ENODEV;
}
config = &priv->phylink_config;
config->dev = &priv->ndev->dev;
config->type = PHYLINK_NETDEV;
config->mac_capabilities = MAC_10000FD;
__set_bit(PHY_INTERFACE_MODE_XAUI, config->supported_interfaces);
phylink = phylink_create(config, NULL, PHY_INTERFACE_MODE_XAUI,
&tn40_mac_ops);
if (IS_ERR(phylink))
return PTR_ERR(phylink);
priv->phydev = phydev;
priv->phylink = phylink;
return 0;
}
void tn40_phy_unregister(struct tn40_priv *priv)
{
phylink_destroy(priv->phylink);
}
/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (c) Tehuti Networks Ltd. */
#ifndef _TN40_REGS_H_
#define _TN40_REGS_H_
/* Register region size */
#define TN40_REGS_SIZE 0x10000
/* Registers from 0x0000-0x00fc were remapped to 0x4000-0x40fc */
#define TN40_REG_TXD_CFG1_0 0x4000
#define TN40_REG_TXD_CFG1_1 0x4004
#define TN40_REG_TXD_CFG1_2 0x4008
#define TN40_REG_TXD_CFG1_3 0x400C
#define TN40_REG_RXF_CFG1_0 0x4010
#define TN40_REG_RXF_CFG1_1 0x4014
#define TN40_REG_RXF_CFG1_2 0x4018
#define TN40_REG_RXF_CFG1_3 0x401C
#define TN40_REG_RXD_CFG1_0 0x4020
#define TN40_REG_RXD_CFG1_1 0x4024
#define TN40_REG_RXD_CFG1_2 0x4028
#define TN40_REG_RXD_CFG1_3 0x402C
#define TN40_REG_TXF_CFG1_0 0x4030
#define TN40_REG_TXF_CFG1_1 0x4034
#define TN40_REG_TXF_CFG1_2 0x4038
#define TN40_REG_TXF_CFG1_3 0x403C
#define TN40_REG_TXD_CFG0_0 0x4040
#define TN40_REG_TXD_CFG0_1 0x4044
#define TN40_REG_TXD_CFG0_2 0x4048
#define TN40_REG_TXD_CFG0_3 0x404C
#define TN40_REG_RXF_CFG0_0 0x4050
#define TN40_REG_RXF_CFG0_1 0x4054
#define TN40_REG_RXF_CFG0_2 0x4058
#define TN40_REG_RXF_CFG0_3 0x405C
#define TN40_REG_RXD_CFG0_0 0x4060
#define TN40_REG_RXD_CFG0_1 0x4064
#define TN40_REG_RXD_CFG0_2 0x4068
#define TN40_REG_RXD_CFG0_3 0x406C
#define TN40_REG_TXF_CFG0_0 0x4070
#define TN40_REG_TXF_CFG0_1 0x4074
#define TN40_REG_TXF_CFG0_2 0x4078
#define TN40_REG_TXF_CFG0_3 0x407C
#define TN40_REG_TXD_WPTR_0 0x4080
#define TN40_REG_TXD_WPTR_1 0x4084
#define TN40_REG_TXD_WPTR_2 0x4088
#define TN40_REG_TXD_WPTR_3 0x408C
#define TN40_REG_RXF_WPTR_0 0x4090
#define TN40_REG_RXF_WPTR_1 0x4094
#define TN40_REG_RXF_WPTR_2 0x4098
#define TN40_REG_RXF_WPTR_3 0x409C
#define TN40_REG_RXD_WPTR_0 0x40A0
#define TN40_REG_RXD_WPTR_1 0x40A4
#define TN40_REG_RXD_WPTR_2 0x40A8
#define TN40_REG_RXD_WPTR_3 0x40AC
#define TN40_REG_TXF_WPTR_0 0x40B0
#define TN40_REG_TXF_WPTR_1 0x40B4
#define TN40_REG_TXF_WPTR_2 0x40B8
#define TN40_REG_TXF_WPTR_3 0x40BC
#define TN40_REG_TXD_RPTR_0 0x40C0
#define TN40_REG_TXD_RPTR_1 0x40C4
#define TN40_REG_TXD_RPTR_2 0x40C8
#define TN40_REG_TXD_RPTR_3 0x40CC
#define TN40_REG_RXF_RPTR_0 0x40D0
#define TN40_REG_RXF_RPTR_1 0x40D4
#define TN40_REG_RXF_RPTR_2 0x40D8
#define TN40_REG_RXF_RPTR_3 0x40DC
#define TN40_REG_RXD_RPTR_0 0x40E0
#define TN40_REG_RXD_RPTR_1 0x40E4
#define TN40_REG_RXD_RPTR_2 0x40E8
#define TN40_REG_RXD_RPTR_3 0x40EC
#define TN40_REG_TXF_RPTR_0 0x40F0
#define TN40_REG_TXF_RPTR_1 0x40F4
#define TN40_REG_TXF_RPTR_2 0x40F8
#define TN40_REG_TXF_RPTR_3 0x40FC
/* Hardware versioning */
#define TN40_FPGA_VER 0x5030
/* Registers from 0x0100-0x0150 were remapped to 0x5100-0x5150 */
#define TN40_REG_ISR TN40_REG_ISR0
#define TN40_REG_ISR0 0x5100
#define TN40_REG_IMR TN40_REG_IMR0
#define TN40_REG_IMR0 0x5110
#define TN40_REG_RDINTCM0 0x5120
#define TN40_REG_RDINTCM2 0x5128
#define TN40_REG_TDINTCM0 0x5130
#define TN40_REG_ISR_MSK0 0x5140
#define TN40_REG_INIT_SEMAPHORE 0x5170
#define TN40_REG_INIT_STATUS 0x5180
#define TN40_REG_MAC_LNK_STAT 0x0200
#define TN40_MAC_LINK_STAT 0x0004 /* Link state */
#define TN40_REG_BLNK_LED 0x0210
#define TN40_REG_GMAC_RXF_A 0x1240
#define TN40_REG_UNC_MAC0_A 0x1250
#define TN40_REG_UNC_MAC1_A 0x1260
#define TN40_REG_UNC_MAC2_A 0x1270
#define TN40_REG_VLAN_0 0x1800
#define TN40_REG_MAX_FRAME_A 0x12C0
#define TN40_REG_RX_MAC_MCST0 0x1A80
#define TN40_REG_RX_MAC_MCST1 0x1A84
#define TN40_MAC_MCST_NUM 15
#define TN40_REG_RX_MCST_HASH0 0x1A00
#define TN40_MAC_MCST_HASH_NUM 8
#define TN40_REG_VPC 0x2300
#define TN40_REG_VIC 0x2320
#define TN40_REG_VGLB 0x2340
#define TN40_REG_CLKPLL 0x5000
/* MDIO interface */
#define TN40_REG_MDIO_CMD_STAT 0x6030
#define TN40_REG_MDIO_CMD 0x6034
#define TN40_REG_MDIO_DATA 0x6038
#define TN40_REG_MDIO_ADDR 0x603C
#define TN40_GET_MDIO_BUSY(x) FIELD_GET(GENMASK(0, 0), (x))
#define TN40_GET_MDIO_RD_ERR(x) FIELD_GET(GENMASK(1, 1), (x))
#define TN40_REG_REVISION 0x6000
#define TN40_REG_SCRATCH 0x6004
#define TN40_REG_CTRLST 0x6008
#define TN40_REG_MAC_ADDR_0 0x600C
#define TN40_REG_MAC_ADDR_1 0x6010
#define TN40_REG_FRM_LENGTH 0x6014
#define TN40_REG_PAUSE_QUANT 0x6054
#define TN40_REG_RX_FIFO_SECTION 0x601C
#define TN40_REG_TX_FIFO_SECTION 0x6020
#define TN40_REG_RX_FULLNESS 0x6024
#define TN40_REG_TX_FULLNESS 0x6028
#define TN40_REG_HASHTABLE 0x602C
#define TN40_REG_RST_PORT 0x7000
#define TN40_REG_DIS_PORT 0x7010
#define TN40_REG_RST_QU 0x7020
#define TN40_REG_DIS_QU 0x7030
#define TN40_REG_CTRLST_TX_ENA 0x0001
#define TN40_REG_CTRLST_RX_ENA 0x0002
#define TN40_REG_CTRLST_PRM_ENA 0x0010
#define TN40_REG_CTRLST_PAD_ENA 0x0020
#define TN40_REG_CTRLST_BASE (TN40_REG_CTRLST_PAD_ENA | REG_CTRLST_PRM_ENA)
/* TXD TXF RXF RXD CONFIG 0x0000 --- 0x007c */
#define TN40_TX_RX_CFG1_BASE 0xffffffff /*0-31 */
#define TN40_TX_RX_CFG0_BASE 0xfffff000 /*31:12 */
#define TN40_TX_RX_CFG0_RSVD 0x00000ffc /*11:2 */
#define TN40_TX_RX_CFG0_SIZE 0x00000003 /*1:0 */
/* TXD TXF RXF RXD WRITE 0x0080 --- 0x00BC */
#define TN40_TXF_WPTR_WR_PTR 0x00007ff8 /*14:3 */
/* TXD TXF RXF RXD READ 0x00CO --- 0x00FC */
#define TN40_TXF_RPTR_RD_PTR 0x00007ff8 /*14:3 */
/* The last 4 bits are dropped size is rounded to 16 */
#define TN40_TXF_WPTR_MASK 0x7ff0
/* regISR 0x0100 */
/* regIMR 0x0110 */
#define TN40_IMR_INPROG 0x80000000 /*31 */
#define TN40_IR_LNKCHG1 0x10000000 /*28 */
#define TN40_IR_LNKCHG0 0x08000000 /*27 */
#define TN40_IR_GPIO 0x04000000 /*26 */
#define TN40_IR_RFRSH 0x02000000 /*25 */
#define TN40_IR_RSVD 0x01000000 /*24 */
#define TN40_IR_SWI 0x00800000 /*23 */
#define TN40_IR_RX_FREE_3 0x00400000 /*22 */
#define TN40_IR_RX_FREE_2 0x00200000 /*21 */
#define TN40_IR_RX_FREE_1 0x00100000 /*20 */
#define TN40_IR_RX_FREE_0 0x00080000 /*19 */
#define TN40_IR_TX_FREE_3 0x00040000 /*18 */
#define TN40_IR_TX_FREE_2 0x00020000 /*17 */
#define TN40_IR_TX_FREE_1 0x00010000 /*16 */
#define TN40_IR_TX_FREE_0 0x00008000 /*15 */
#define TN40_IR_RX_DESC_3 0x00004000 /*14 */
#define TN40_IR_RX_DESC_2 0x00002000 /*13 */
#define TN40_IR_RX_DESC_1 0x00001000 /*12 */
#define TN40_IR_RX_DESC_0 0x00000800 /*11 */
#define TN40_IR_PSE 0x00000400 /*10 */
#define TN40_IR_TMR3 0x00000200 /* 9 */
#define TN40_IR_TMR2 0x00000100 /* 8 */
#define TN40_IR_TMR1 0x00000080 /* 7 */
#define TN40_IR_TMR0 0x00000040 /* 6 */
#define TN40_IR_VNT 0x00000020 /* 5 */
#define TN40_IR_RxFL 0x00000010 /* 4 */
#define TN40_IR_SDPERR 0x00000008 /* 3 */
#define TN40_IR_TR 0x00000004 /* 2 */
#define TN40_IR_PCIE_LINK 0x00000002 /* 1 */
#define TN40_IR_PCIE_TOUT 0x00000001 /* 0 */
#define TN40_IR_EXTRA \
(TN40_IR_RX_FREE_0 | TN40_IR_LNKCHG0 | TN40_IR_LNKCHG1 |\
TN40_IR_PSE | TN40_IR_TMR0 | TN40_IR_PCIE_LINK | \
TN40_IR_PCIE_TOUT)
#define TN40_GMAC_RX_FILTER_OSEN 0x1000 /* shared OS enable */
#define TN40_GMAC_RX_FILTER_TXFC 0x0400 /* Tx flow control */
#define TN40_GMAC_RX_FILTER_RSV0 0x0200 /* reserved */
#define TN40_GMAC_RX_FILTER_FDA 0x0100 /* filter out direct address */
#define TN40_GMAC_RX_FILTER_AOF 0x0080 /* accept over run */
#define TN40_GMAC_RX_FILTER_ACF 0x0040 /* accept control frames */
#define TN40_GMAC_RX_FILTER_ARUNT 0x0020 /* accept under run */
#define TN40_GMAC_RX_FILTER_ACRC 0x0010 /* accept crc error */
#define TN40_GMAC_RX_FILTER_AM 0x0008 /* accept multicast */
#define TN40_GMAC_RX_FILTER_AB 0x0004 /* accept broadcast */
#define TN40_GMAC_RX_FILTER_PRM 0x0001 /* [0:1] promiscuous mode */
#define TN40_MAX_FRAME_AB_VAL 0x3fff /* 13:0 */
#define TN40_CLKPLL_PLLLKD 0x0200 /* 9 */
#define TN40_CLKPLL_RSTEND 0x0100 /* 8 */
#define TN40_CLKPLL_SFTRST 0x0001 /* 0 */
#define TN40_CLKPLL_LKD (TN40_CLKPLL_PLLLKD | TN40_CLKPLL_RSTEND)
#endif
......@@ -2126,6 +2126,8 @@
#define PCI_VENDOR_ID_CHELSIO 0x1425
#define PCI_VENDOR_ID_EDIMAX 0x1432
#define PCI_VENDOR_ID_ADLINK 0x144a
#define PCI_VENDOR_ID_SAMSUNG 0x144d
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment