- Various DSA additions
- bootp: fix for VCI string
- tsec: support for promiscuous mode
- add Aspeed MDIO driver
This commit is contained in:
Tom Rini 2021-11-23 07:43:50 -05:00
commit 5a24e12f13
22 changed files with 3854 additions and 52 deletions

View File

@ -14,6 +14,81 @@
enet1-sgmii-phy = &sgmii_phy1;
spi0 = &qspi;
spi1 = &dspi1;
ethernet0 = &enet0;
ethernet1 = &enet1;
ethernet2 = &enet2;
ethernet3 = &swp2;
ethernet4 = &swp3;
ethernet5 = &swp4;
ethernet6 = &swp5;
};
};
&dspi0 {
bus-num = <0>;
status = "okay";
sja1105: ethernet-switch@1 {
reg = <0x1>;
#address-cells = <1>;
#size-cells = <0>;
compatible = "nxp,sja1105t";
/* 12 MHz */
spi-max-frequency = <12000000>;
/* Sample data on trailing clock edge */
spi-cpha;
/* SPI controller settings for SJA1105 timing requirements */
fsl,spi-cs-sck-delay = <1000>;
fsl,spi-sck-cs-delay = <1000>;
ports {
#address-cells = <1>;
#size-cells = <0>;
swp5: port@0 {
/* ETH5 written on chassis */
label = "swp5";
phy-handle = <&rgmii_phy6>;
phy-mode = "rgmii-id";
reg = <0>;
};
swp2: port@1 {
/* ETH2 written on chassis */
label = "swp2";
phy-handle = <&rgmii_phy3>;
phy-mode = "rgmii-id";
reg = <1>;
};
swp3: port@2 {
/* ETH3 written on chassis */
label = "swp3";
phy-handle = <&rgmii_phy4>;
phy-mode = "rgmii-id";
reg = <2>;
};
swp4: port@3 {
/* ETH4 written on chassis */
label = "swp4";
phy-handle = <&rgmii_phy5>;
phy-mode = "rgmii-id";
reg = <3>;
};
port@4 {
/* Internal port connected to eth2 */
ethernet = <&enet2>;
phy-mode = "rgmii";
reg = <4>;
fixed-link {
speed = <1000>;
full-duplex;
};
};
};
};
};
@ -31,6 +106,17 @@
status = "okay";
};
/* RGMII delays added via PCB traces */
&enet2 {
phy-mode = "rgmii";
status = "okay";
fixed-link {
speed = <1000>;
full-duplex;
};
};
&i2c0 {
status = "okay";
};
@ -46,6 +132,23 @@
reg = <0x2>;
};
/* BCM5464 quad PHY */
rgmii_phy3: ethernet-phy@3 {
reg = <0x3>;
};
rgmii_phy4: ethernet-phy@4 {
reg = <0x4>;
};
rgmii_phy5: ethernet-phy@5 {
reg = <0x5>;
};
rgmii_phy6: ethernet-phy@6 {
reg = <0x6>;
};
/* SGMII PCS for enet0 */
tbi0: tbi-phy@1f {
reg = <0x1f>;

View File

@ -550,7 +550,10 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
* Scenario 2: If there is an fdt_addr specified, pass it along to
* bootm, and adjust argc appropriately.
*
* Scenario 3: fdt blob is not available.
* Scenario 3: If there is an fdtcontroladdr specified, pass it along to
* bootm, and adjust argc appropriately.
*
* Scenario 4: fdt blob is not available.
*/
bootm_argv[3] = env_get("fdt_addr_r");
@ -652,6 +655,9 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
if (!bootm_argv[3])
bootm_argv[3] = env_get("fdt_addr");
if (!bootm_argv[3])
bootm_argv[3] = env_get("fdtcontroladdr");
if (bootm_argv[3]) {
if (!bootm_argv[2])
bootm_argv[2] = "-";

View File

@ -51,8 +51,11 @@ CONFIG_SPI_FLASH_DATAFLASH=y
CONFIG_PHY_ATHEROS=y
CONFIG_PHY_BROADCOM=y
CONFIG_PHY_FIXED=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DM_ETH=y
CONFIG_DM_MDIO=y
CONFIG_DM_DSA=y
CONFIG_SJA1105=y
CONFIG_PHY_GIGE=y
CONFIG_MII=y
CONFIG_TSEC_ENET=y

View File

@ -66,8 +66,11 @@ CONFIG_SPI_FLASH_DATAFLASH=y
CONFIG_PHY_ATHEROS=y
CONFIG_PHY_BROADCOM=y
CONFIG_PHY_FIXED=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DM_ETH=y
CONFIG_DM_MDIO=y
CONFIG_DM_DSA=y
CONFIG_SJA1105=y
CONFIG_PHY_GIGE=y
CONFIG_MII=y
CONFIG_TSEC_ENET=y

View File

@ -8,7 +8,6 @@ CONFIG_PINE64_DT_SELECTION=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_OF_LIST="sun50i-a64-pine64 sun50i-a64-pine64-plus"
CONFIG_PHY_REALTEK=y
CONFIG_RTL8211E_PINE64_GIGABIT_FIX=y
CONFIG_SUN8I_EMAC=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y

View File

@ -155,3 +155,15 @@ bool ofnode_phy_is_fixed_link(ofnode eth_node, ofnode *phy_node)
return true;
}
bool ofnode_eth_uses_inband_aneg(ofnode eth_node)
{
bool inband_aneg = false;
const char *managed;
managed = ofnode_read_string(eth_node, "managed");
if (managed && !strcmp(managed, "in-band-status"))
inband_aneg = true;
return inband_aneg;
}

View File

@ -554,6 +554,22 @@ config RTL8169
This driver supports Realtek 8169 series gigabit ethernet family of
PCI/PCIe chipsets/adapters.
config SJA1105
bool "NXP SJA1105 Ethernet switch family driver"
depends on DM_DSA && DM_SPI
select BITREVERSE
help
This is the driver for the NXP SJA1105 automotive Ethernet switch
family. These are 5-port devices and are managed over an SPI
interface. Probing is handled based on OF bindings. The driver
supports the following revisions:
- SJA1105E (Gen. 1, No TT-Ethernet)
- SJA1105T (Gen. 1, TT-Ethernet)
- SJA1105P (Gen. 2, No SGMII, No TT-Ethernet)
- SJA1105Q (Gen. 2, No SGMII, TT-Ethernet)
- SJA1105R (Gen. 2, SGMII, No TT-Ethernet)
- SJA1105S (Gen. 2, SGMII, TT-Ethernet)
config SMC911X
bool "SMSC LAN911x and LAN921x controller driver"
@ -835,6 +851,13 @@ config FSL_LS_MDIO
This driver supports the MDIO bus found on the Fman 10G Ethernet MACs and
on the mEMAC (which supports both Clauses 22 and 45).
config ASPEED_MDIO
bool "Aspeed MDIO interface support"
depends on DM_MDIO
help
This driver supports the MDIO bus of Aspeed AST2600 SOC. The driver
currently supports Clause 22.
config MDIO_MUX_MMIOREG
bool "MDIO MUX accessed as a MMIO register access"
depends on DM_MDIO_MUX

View File

@ -29,6 +29,7 @@ obj-$(CONFIG_DM_ETH_PHY) += eth-phy-uclass.o
obj-$(CONFIG_E1000) += e1000.o
obj-$(CONFIG_E1000_SPI) += e1000_spi.o
obj-$(CONFIG_EEPRO100) += eepro100.o
obj-$(CONFIG_SJA1105) += sja1105.o
obj-$(CONFIG_SUN4I_EMAC) += sunxi_emac.o
obj-$(CONFIG_SUN8I_EMAC) += sun8i_emac.o
obj-$(CONFIG_EP93XX) += ep93xx_eth.o
@ -101,3 +102,4 @@ obj-$(CONFIG_HIGMACV300_ETH) += higmacv300.o
obj-$(CONFIG_MDIO_SANDBOX) += mdio_sandbox.o
obj-$(CONFIG_FSL_ENETC) += fsl_enetc.o fsl_enetc_mdio.o
obj-$(CONFIG_FSL_LS_MDIO) += fsl_ls_mdio.o
obj-$(CONFIG_ASPEED_MDIO) += aspeed_mdio.o

128
drivers/net/aspeed_mdio.c Normal file
View File

@ -0,0 +1,128 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Aspeed MDIO driver
*
* (C) Copyright 2021 Aspeed Technology Inc.
*
* This file is inspired from the Linux kernel driver drivers/net/phy/mdio-aspeed.c
*/
#include <common.h>
#include <dm.h>
#include <log.h>
#include <miiphy.h>
#include <net.h>
#include <reset.h>
#include <linux/bitops.h>
#include <linux/bitfield.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#define ASPEED_MDIO_CTRL 0x0
#define ASPEED_MDIO_CTRL_FIRE BIT(31)
#define ASPEED_MDIO_CTRL_ST BIT(28)
#define ASPEED_MDIO_CTRL_ST_C45 0
#define ASPEED_MDIO_CTRL_ST_C22 1
#define ASPEED_MDIO_CTRL_OP GENMASK(27, 26)
#define MDIO_C22_OP_WRITE 0b01
#define MDIO_C22_OP_READ 0b10
#define ASPEED_MDIO_CTRL_PHYAD GENMASK(25, 21)
#define ASPEED_MDIO_CTRL_REGAD GENMASK(20, 16)
#define ASPEED_MDIO_CTRL_MIIWDATA GENMASK(15, 0)
#define ASPEED_MDIO_DATA 0x4
#define ASPEED_MDIO_DATA_MDC_THRES GENMASK(31, 24)
#define ASPEED_MDIO_DATA_MDIO_EDGE BIT(23)
#define ASPEED_MDIO_DATA_MDIO_LATCH GENMASK(22, 20)
#define ASPEED_MDIO_DATA_IDLE BIT(16)
#define ASPEED_MDIO_DATA_MIIRDATA GENMASK(15, 0)
#define ASPEED_MDIO_TIMEOUT_US 1000
struct aspeed_mdio_priv {
void *base;
};
static int aspeed_mdio_read(struct udevice *mdio_dev, int addr, int devad, int reg)
{
struct aspeed_mdio_priv *priv = dev_get_priv(mdio_dev);
u32 ctrl;
u32 data;
int rc;
if (devad != MDIO_DEVAD_NONE)
return -EOPNOTSUPP;
ctrl = ASPEED_MDIO_CTRL_FIRE
| FIELD_PREP(ASPEED_MDIO_CTRL_ST, ASPEED_MDIO_CTRL_ST_C22)
| FIELD_PREP(ASPEED_MDIO_CTRL_OP, MDIO_C22_OP_READ)
| FIELD_PREP(ASPEED_MDIO_CTRL_PHYAD, addr)
| FIELD_PREP(ASPEED_MDIO_CTRL_REGAD, reg);
writel(ctrl, priv->base + ASPEED_MDIO_CTRL);
rc = readl_poll_timeout(priv->base + ASPEED_MDIO_DATA, data,
data & ASPEED_MDIO_DATA_IDLE,
ASPEED_MDIO_TIMEOUT_US);
if (rc < 0)
return rc;
return FIELD_GET(ASPEED_MDIO_DATA_MIIRDATA, data);
}
static int aspeed_mdio_write(struct udevice *mdio_dev, int addr, int devad, int reg, u16 val)
{
struct aspeed_mdio_priv *priv = dev_get_priv(mdio_dev);
u32 ctrl;
if (devad != MDIO_DEVAD_NONE)
return -EOPNOTSUPP;
ctrl = ASPEED_MDIO_CTRL_FIRE
| FIELD_PREP(ASPEED_MDIO_CTRL_ST, ASPEED_MDIO_CTRL_ST_C22)
| FIELD_PREP(ASPEED_MDIO_CTRL_OP, MDIO_C22_OP_WRITE)
| FIELD_PREP(ASPEED_MDIO_CTRL_PHYAD, addr)
| FIELD_PREP(ASPEED_MDIO_CTRL_REGAD, reg)
| FIELD_PREP(ASPEED_MDIO_CTRL_MIIWDATA, val);
writel(ctrl, priv->base + ASPEED_MDIO_CTRL);
return readl_poll_timeout(priv->base + ASPEED_MDIO_CTRL, ctrl,
!(ctrl & ASPEED_MDIO_CTRL_FIRE),
ASPEED_MDIO_TIMEOUT_US);
}
static const struct mdio_ops aspeed_mdio_ops = {
.read = aspeed_mdio_read,
.write = aspeed_mdio_write,
};
static int aspeed_mdio_probe(struct udevice *dev)
{
struct aspeed_mdio_priv *priv = dev_get_priv(dev);
struct reset_ctl reset_ctl;
int ret = 0;
priv->base = dev_read_addr_ptr(dev);
ret = reset_get_by_index(dev, 0, &reset_ctl);
reset_deassert(&reset_ctl);
return 0;
}
static const struct udevice_id aspeed_mdio_ids[] = {
{ .compatible = "aspeed,ast2600-mdio" },
{ }
};
U_BOOT_DRIVER(aspeed_mdio) = {
.name = "aspeed_mdio",
.id = UCLASS_MDIO,
.of_match = aspeed_mdio_ids,
.probe = aspeed_mdio_probe,
.ops = &aspeed_mdio_ops,
.plat_auto = sizeof(struct mdio_perdev_priv),
.priv_auto = sizeof(struct aspeed_mdio_priv),
};

View File

@ -272,7 +272,7 @@ struct fec_priv {
struct clk clk_ref;
struct clk clk_ptp;
u32 clk_rate;
char promisc;
bool promisc;
};
/**

View File

@ -16,6 +16,7 @@
*/
#include <dm/device_compat.h>
#include <dm/of_extra.h>
#include <linux/delay.h>
#include <net/dsa.h>
#include <asm/io.h>
@ -210,17 +211,14 @@ static int felix_init_sxgmii(struct mii_dev *imdio, int pidx)
static void felix_start_pcs(struct udevice *dev, int port,
struct phy_device *phy, struct mii_dev *imdio)
{
bool autoneg = true;
if (phy->phy_id == PHY_FIXED_ID ||
phy->interface == PHY_INTERFACE_MODE_2500BASEX)
autoneg = false;
ofnode node = dsa_port_get_ofnode(dev, port);
bool inband_an = ofnode_eth_uses_inband_aneg(node);
switch (phy->interface) {
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_2500BASEX:
case PHY_INTERFACE_MODE_QSGMII:
felix_init_sgmii(imdio, port, autoneg);
felix_init_sgmii(imdio, port, inband_an);
break;
case PHY_INTERFACE_MODE_10GBASER:
case PHY_INTERFACE_MODE_USXGMII:

View File

@ -214,16 +214,6 @@ config PHY_NXP_C45_TJA11XX
config PHY_REALTEK
bool "Realtek Ethernet PHYs support"
config RTL8211E_PINE64_GIGABIT_FIX
bool "Fix gigabit throughput on some Pine64+ models"
depends on PHY_REALTEK
help
Configure the Realtek RTL8211E found on some Pine64+ models differently to
fix throughput on Gigabit links, turning off all internal delays in the
process. The settings that this touches are not documented in the CONFREG
section of the RTL8211E datasheet, but come from Realtek by way of the
Pine64 engineering team.
config RTL8211X_PHY_FORCE_MASTER
bool "Ethernet PHY RTL8211x: force 1000BASE-T master mode"
depends on PHY_REALTEK

View File

@ -19,6 +19,7 @@
/* Microsemi PHY ID's */
#define PHY_ID_VSC8530 0x00070560
#define PHY_ID_VSC8531 0x00070570
#define PHY_ID_VSC8502 0x00070630
#define PHY_ID_VSC8540 0x00070760
#define PHY_ID_VSC8541 0x00070770
#define PHY_ID_VSC8574 0x000704a0
@ -1513,6 +1514,50 @@ static int vsc8584_config(struct phy_device *phydev)
return vsc8584_config_init(phydev);
}
static int vsc8502_config(struct phy_device *phydev)
{
bool rgmii_rx_delay = false, rgmii_tx_delay = false;
u16 reg = 0;
int ret;
/* Assume nothing needs to be done for the default GMII/MII mode */
if (!phy_interface_is_rgmii(phydev))
return 0;
/* Set Extended PHY Control 1 register to RGMII */
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_EXT_PHY_CNTL_1_REG,
BIT(13) | BIT(12));
/* Soft reset required after changing PHY mode from the default
* of GMII/MII
*/
ret = mscc_phy_soft_reset(phydev);
if (ret)
return ret;
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
rgmii_rx_delay = true;
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
rgmii_tx_delay = true;
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_EXT2);
if (rgmii_rx_delay)
reg |= VSC_PHY_RGMII_DELAY_2000_PS << RGMII_RX_CLK_DELAY_POS;
if (rgmii_tx_delay)
reg |= VSC_PHY_RGMII_DELAY_2000_PS << RGMII_TX_CLK_DELAY_POS;
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_STD);
return 0;
}
static struct phy_driver VSC8530_driver = {
.name = "Microsemi VSC8530",
.uid = PHY_ID_VSC8530,
@ -1533,6 +1578,16 @@ static struct phy_driver VSC8531_driver = {
.shutdown = &genphy_shutdown,
};
static struct phy_driver VSC8502_driver = {
.name = "Microsemi VSC8502",
.uid = PHY_ID_VSC8502,
.mask = 0x000ffff0,
.features = PHY_GBIT_FEATURES,
.config = &vsc8502_config,
.startup = &mscc_startup,
.shutdown = &genphy_shutdown,
};
static struct phy_driver VSC8540_driver = {
.name = "Microsemi VSC8540",
.uid = PHY_ID_VSC8540,
@ -1577,6 +1632,7 @@ int phy_mscc_init(void)
{
phy_register(&VSC8530_driver);
phy_register(&VSC8531_driver);
phy_register(&VSC8502_driver);
phy_register(&VSC8540_driver);
phy_register(&VSC8541_driver);
phy_register(&VSC8574_driver);

View File

@ -12,7 +12,6 @@
#include <linux/delay.h>
#define PHY_RTL8211x_FORCE_MASTER BIT(1)
#define PHY_RTL8211E_PINE64_GIGABIT_FIX BIT(2)
#define PHY_RTL8211F_FORCE_EEE_RXC_ON BIT(3)
#define PHY_RTL8201F_S700_RMII_TIMINGS BIT(4)
@ -49,10 +48,10 @@
#define MIIM_RTL8211F_PHYSTAT_SPDDONE 0x0800
#define MIIM_RTL8211F_PHYSTAT_LINK 0x0004
#define MIIM_RTL8211E_CONFREG 0x1c
#define MIIM_RTL8211E_CONFREG_TXD 0x0002
#define MIIM_RTL8211E_CONFREG_RXD 0x0004
#define MIIM_RTL8211E_CONFREG_MAGIC 0xb400 /* Undocumented */
#define MIIM_RTL8211E_CONFREG 0x1c
#define MIIM_RTL8211E_CTRL_DELAY BIT(13)
#define MIIM_RTL8211E_TX_DELAY BIT(12)
#define MIIM_RTL8211E_RX_DELAY BIT(11)
#define MIIM_RTL8211E_EXT_PAGE_SELECT 0x1e
@ -108,10 +107,6 @@ static int rtl8211b_probe(struct phy_device *phydev)
static int rtl8211e_probe(struct phy_device *phydev)
{
#ifdef CONFIG_RTL8211E_PINE64_GIGABIT_FIX
phydev->flags |= PHY_RTL8211E_PINE64_GIGABIT_FIX;
#endif
return 0;
}
@ -154,22 +149,6 @@ static int rtl8211x_config(struct phy_device *phydev)
reg |= MIIM_RTL8211x_CTRL1000T_MASTER;
phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, reg);
}
if (phydev->flags & PHY_RTL8211E_PINE64_GIGABIT_FIX) {
unsigned int reg;
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT,
7);
phy_write(phydev, MDIO_DEVAD_NONE,
MIIM_RTL8211E_EXT_PAGE_SELECT, 0xa4);
reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG);
/* Ensure both internal delays are turned off */
reg &= ~(MIIM_RTL8211E_CONFREG_TXD | MIIM_RTL8211E_CONFREG_RXD);
/* Flip the magic undocumented bits */
reg |= MIIM_RTL8211E_CONFREG_MAGIC;
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG, reg);
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT,
0);
}
/* read interrupt status just to clear it */
phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER);
@ -201,6 +180,44 @@ static int rtl8201f_config(struct phy_device *phydev)
return 0;
}
static int rtl8211e_config(struct phy_device *phydev)
{
int reg, val;
/* enable TX/RX delay for rgmii-* modes, and disable them for rgmii. */
switch (phydev->interface) {
case PHY_INTERFACE_MODE_RGMII:
val = MIIM_RTL8211E_CTRL_DELAY;
break;
case PHY_INTERFACE_MODE_RGMII_ID:
val = MIIM_RTL8211E_CTRL_DELAY | MIIM_RTL8211E_TX_DELAY |
MIIM_RTL8211E_RX_DELAY;
break;
case PHY_INTERFACE_MODE_RGMII_RXID:
val = MIIM_RTL8211E_CTRL_DELAY | MIIM_RTL8211E_RX_DELAY;
break;
case PHY_INTERFACE_MODE_RGMII_TXID:
val = MIIM_RTL8211E_CTRL_DELAY | MIIM_RTL8211E_TX_DELAY;
break;
default: /* the rest of the modes imply leaving delays as is. */
goto default_delay;
}
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 7);
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_EXT_PAGE_SELECT, 0xa4);
reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG);
reg &= ~(MIIM_RTL8211E_TX_DELAY | MIIM_RTL8211E_RX_DELAY);
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG, reg | val);
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 0);
default_delay:
genphy_config_aneg(phydev);
return 0;
}
static int rtl8211f_config(struct phy_device *phydev)
{
u16 reg;
@ -410,7 +427,7 @@ static struct phy_driver RTL8211E_driver = {
.mask = 0xffffff,
.features = PHY_GBIT_FEATURES,
.probe = &rtl8211e_probe,
.config = &rtl8211x_config,
.config = &rtl8211e_config,
.startup = &rtl8211e_startup,
.shutdown = &genphy_shutdown,
};

3376
drivers/net/sja1105.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -156,6 +156,19 @@ static int tsec_mcast_addr(struct udevice *dev, const u8 *mcast_mac, int join)
return 0;
}
static int __maybe_unused tsec_set_promisc(struct udevice *dev, bool enable)
{
struct tsec_private *priv = dev_get_priv(dev);
struct tsec __iomem *regs = priv->regs;
if (enable)
setbits_be32(&regs->rctrl, RCTRL_PROM);
else
clrbits_be32(&regs->rctrl, RCTRL_PROM);
return 0;
}
/*
* Initialized required registers to appropriate values, zeroing
* those we don't care about (unless zero is bad, in which case,
@ -186,8 +199,6 @@ static void init_registers(struct tsec __iomem *regs)
out_be32(&regs->hash.gaddr6, 0);
out_be32(&regs->hash.gaddr7, 0);
out_be32(&regs->rctrl, 0x00000000);
/* Init RMON mib registers */
memset((void *)&regs->rmon, 0, sizeof(regs->rmon));
@ -432,7 +443,7 @@ static void tsec_halt(struct udevice *dev)
* of the eTSEC port initialization sequence,
* the eTSEC Rx logic may not be properly initialized.
*/
void redundant_init(struct tsec_private *priv)
static void redundant_init(struct tsec_private *priv)
{
struct tsec __iomem *regs = priv->regs;
uint t, count = 0;
@ -454,7 +465,7 @@ void redundant_init(struct tsec_private *priv)
0x71, 0x72};
/* Enable promiscuous mode */
setbits_be32(&regs->rctrl, 0x8);
setbits_be32(&regs->rctrl, RCTRL_PROM);
/* Enable loopback mode */
setbits_be32(&regs->maccfg1, MACCFG1_LOOPBACK);
/* Enable transmit and receive */
@ -506,7 +517,7 @@ void redundant_init(struct tsec_private *priv)
if (fail)
panic("eTSEC init fail!\n");
/* Disable promiscuous mode */
clrbits_be32(&regs->rctrl, 0x8);
clrbits_be32(&regs->rctrl, RCTRL_PROM);
/* Disable loopback mode */
clrbits_be32(&regs->maccfg1, MACCFG1_LOOPBACK);
}
@ -932,6 +943,7 @@ static const struct eth_ops tsec_ops = {
.free_pkt = tsec_free_pkt,
.stop = tsec_halt,
.mcast = tsec_mcast_addr,
.set_promisc = tsec_set_promisc,
};
static struct tsec_data etsec2_data = {

View File

@ -114,4 +114,18 @@ int ofnode_decode_memory_region(ofnode config_node, const char *mem_type,
*/
bool ofnode_phy_is_fixed_link(ofnode eth_node, ofnode *phy_node);
/**
* ofnode_eth_uses_inband_aneg() - Detect whether MAC should use in-band autoneg
*
* This function detects whether the Ethernet controller should use IEEE 802.3
* clause 37 in-band autonegotiation for serial protocols such as 1000base-x,
* SGMII, USXGMII, etc. The property is relevant when the Ethernet controller
* is connected to an on-board PHY or an SFP cage, and is not relevant when it
* has a fixed link (in that case, in-band autoneg should not be used).
*
* @param eth_node ofnode belonging to the Ethernet controller
* @return true if in-band autoneg should be used, false otherwise
*/
bool ofnode_eth_uses_inband_aneg(ofnode eth_node);
#endif

26
include/linux/if_vlan.h Normal file
View File

@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* VLAN An implementation of 802.1Q VLAN tagging.
*
* Authors: Ben Greear <greearb@candelatech.com>
*/
#ifndef _LINUX_IF_VLAN_H_
#define _LINUX_IF_VLAN_H_
/**
* struct vlan_ethhdr - vlan ethernet header (ethhdr + vlan_hdr)
* @h_dest: destination ethernet address
* @h_source: source ethernet address
* @h_vlan_proto: ethernet protocol
* @h_vlan_TCI: priority and VLAN ID
* @h_vlan_encapsulated_proto: packet type ID or len
*/
struct vlan_ethhdr {
unsigned char h_dest[ETH_ALEN];
unsigned char h_source[ETH_ALEN];
__be16 h_vlan_proto;
__be16 h_vlan_TCI;
__be16 h_vlan_encapsulated_proto;
};
#endif /* !(_LINUX_IF_VLAN_H_) */

View File

@ -6,6 +6,7 @@
#ifndef __DSA_H__
#define __DSA_H__
#include <dm/ofnode.h>
#include <phy.h>
#include <net.h>
@ -145,6 +146,17 @@ int dsa_set_tagging(struct udevice *dev, ushort headroom, ushort tailroom);
*/
struct udevice *dsa_get_master(struct udevice *dev);
/**
* dsa_port_get_ofnode() - Return a reference to the given port's OF node
*
* Can be called at driver probe time or later.
*
* @dev: DSA switch udevice pointer
* @port: Port index
* @return OF node reference if OK, NULL on error
*/
ofnode dsa_port_get_ofnode(struct udevice *dev, int port);
/**
* dsa_port_get_pdata() - Helper that returns the platdata of an active
* (non-CPU) DSA port device.

View File

@ -122,6 +122,8 @@
#define ECNTRL_REDUCED_MII_MODE 0x00000004
#define ECNTRL_SGMII_MODE 0x00000002
#define RCTRL_PROM 0x00000008
#ifndef CONFIG_SYS_TBIPA_VALUE
# define CONFIG_SYS_TBIPA_VALUE 0x1f
#endif

View File

@ -647,7 +647,7 @@ static int bootp_extended(u8 *e)
*e++ = (576 - 312 + OPT_FIELD_SIZE) & 0xff;
#endif
add_vci(e);
e = add_vci(e);
#if defined(CONFIG_BOOTP_SUBNETMASK)
*e++ = 1; /* Subnet mask request */

View File

@ -44,6 +44,26 @@ int dsa_set_tagging(struct udevice *dev, ushort headroom, ushort tailroom)
return 0;
}
ofnode dsa_port_get_ofnode(struct udevice *dev, int port)
{
struct dsa_pdata *pdata = dev_get_uclass_plat(dev);
struct dsa_port_pdata *port_pdata;
struct udevice *pdev;
if (port == pdata->cpu_port)
return pdata->cpu_port_node;
for (device_find_first_child(dev, &pdev);
pdev;
device_find_next_child(&pdev)) {
port_pdata = dev_get_parent_plat(pdev);
if (port_pdata->index == port)
return dev_ofnode(pdev);
}
return ofnode_null();
}
/* returns the DSA master Ethernet device */
struct udevice *dsa_get_master(struct udevice *dev)
{
@ -250,7 +270,7 @@ static void dsa_port_set_hwaddr(struct udevice *pdev, struct udevice *master)
struct eth_ops *eth_ops = eth_get_ops(master);
if (eth_ops->set_promisc)
eth_ops->set_promisc(master, 1);
eth_ops->set_promisc(master, true);
return;
}