Commit 0419c450 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'stmmac-100GB-Enterprise-MAC-support'



Jose Abreu says:

====================
net: stmmac: 100GB Enterprise MAC support

Adds the support for Enterprise MAC IP version which allows operating
speeds up to 100GB.

Patch 1/4, adds the support in XPCS for XLGMII interface that is used in
this kind of Enterprise MAC IPs.

Patch 2/4, adds the XLGMII interface support in stmmac.

Patch 3/4, adds the HW specific support for Enterprise MAC.

We end in patch 4/4, by updating stmmac documentation to mention the
support for this new IP version.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9f57db9b 2462a82c
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -32,7 +32,8 @@ is also supported.
DesignWare(R) Cores Ethernet MAC 10/100/1000 Universal version 3.70a
(and older) and DesignWare(R) Cores Ethernet Quality-of-Service version 4.0
(and upper) have been used for developing this driver as well as
DesignWare(R) Cores XGMAC - 10G Ethernet MAC.
DesignWare(R) Cores XGMAC - 10G Ethernet MAC and DesignWare(R) Cores
Enterprise MAC - 100G Ethernet MAC.

This driver supports both the platform bus and PCI.

@@ -48,6 +49,8 @@ Cores Ethernet Controllers and corresponding minimum and maximum versions:
+-------------------------------+--------------+--------------+--------------+
| XGMAC - 10G Ethernet MAC      | 2.10a        | N/A          | XGMAC2+      |
+-------------------------------+--------------+--------------+--------------+
| XLGMAC - 100G Ethernet MAC    | 2.00a        | N/A          | XLGMAC2+     |
+-------------------------------+--------------+--------------+--------------+

For questions related to hardware requirements, refer to the documentation
supplied with your Ethernet adapter. All hardware requirements listed apply
@@ -57,7 +60,7 @@ Feature List
============

The following features are available in this driver:
 - GMII/MII/RGMII/SGMII/RMII/XGMII Interface
 - GMII/MII/RGMII/SGMII/RMII/XGMII/XLGMII Interface
 - Half-Duplex / Full-Duplex Operation
 - Energy Efficient Ethernet (EEE)
 - IEEE 802.3x PAUSE Packets (Flow Control)
+13 −0
Original line number Diff line number Diff line
@@ -34,6 +34,11 @@
#define DWMAC_CORE_5_00		0x50
#define DWMAC_CORE_5_10		0x51
#define DWXGMAC_CORE_2_10	0x21
#define DWXLGMAC_CORE_2_00	0x20

/* Device ID */
#define DWXGMAC_ID		0x76
#define DWXLGMAC_ID		0x27

#define STMMAC_CHAN0	0	/* Always supported and default for all chips */

@@ -426,6 +431,12 @@ struct mac_link {
		u32 speed5000;
		u32 speed10000;
	} xgmii;
	struct {
		u32 speed25000;
		u32 speed40000;
		u32 speed50000;
		u32 speed100000;
	} xlgmii;
};

struct mii_regs {
@@ -459,6 +470,7 @@ struct mac_device_info {
	unsigned int pcs;
	unsigned int pmt;
	unsigned int ps;
	unsigned int xlgmac;
};

struct stmmac_rx_routing {
@@ -470,6 +482,7 @@ int dwmac100_setup(struct stmmac_priv *priv);
int dwmac1000_setup(struct stmmac_priv *priv);
int dwmac4_setup(struct stmmac_priv *priv);
int dwxgmac2_setup(struct stmmac_priv *priv);
int dwxlgmac2_setup(struct stmmac_priv *priv);

void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
			 unsigned int high, unsigned int low);
+99 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/iopoll.h>
#include "stmmac.h"
#include "stmmac_ptp.h"
#include "dwxlgmac2.h"
#include "dwxgmac2.h"

static void dwxgmac2_core_init(struct mac_device_info *hw,
@@ -1485,6 +1486,67 @@ const struct stmmac_ops dwxgmac210_ops = {
	.fpe_configure = dwxgmac3_fpe_configure,
};

static void dwxlgmac2_rx_queue_enable(struct mac_device_info *hw, u8 mode,
				      u32 queue)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 value;

	value = readl(ioaddr + XLGMAC_RXQ_ENABLE_CTRL0) & ~XGMAC_RXQEN(queue);
	if (mode == MTL_QUEUE_AVB)
		value |= 0x1 << XGMAC_RXQEN_SHIFT(queue);
	else if (mode == MTL_QUEUE_DCB)
		value |= 0x2 << XGMAC_RXQEN_SHIFT(queue);
	writel(value, ioaddr + XLGMAC_RXQ_ENABLE_CTRL0);
}

const struct stmmac_ops dwxlgmac2_ops = {
	.core_init = dwxgmac2_core_init,
	.set_mac = dwxgmac2_set_mac,
	.rx_ipc = dwxgmac2_rx_ipc,
	.rx_queue_enable = dwxlgmac2_rx_queue_enable,
	.rx_queue_prio = dwxgmac2_rx_queue_prio,
	.tx_queue_prio = dwxgmac2_tx_queue_prio,
	.rx_queue_routing = NULL,
	.prog_mtl_rx_algorithms = dwxgmac2_prog_mtl_rx_algorithms,
	.prog_mtl_tx_algorithms = dwxgmac2_prog_mtl_tx_algorithms,
	.set_mtl_tx_queue_weight = dwxgmac2_set_mtl_tx_queue_weight,
	.map_mtl_to_dma = dwxgmac2_map_mtl_to_dma,
	.config_cbs = dwxgmac2_config_cbs,
	.dump_regs = dwxgmac2_dump_regs,
	.host_irq_status = dwxgmac2_host_irq_status,
	.host_mtl_irq_status = dwxgmac2_host_mtl_irq_status,
	.flow_ctrl = dwxgmac2_flow_ctrl,
	.pmt = dwxgmac2_pmt,
	.set_umac_addr = dwxgmac2_set_umac_addr,
	.get_umac_addr = dwxgmac2_get_umac_addr,
	.set_eee_mode = dwxgmac2_set_eee_mode,
	.reset_eee_mode = dwxgmac2_reset_eee_mode,
	.set_eee_timer = dwxgmac2_set_eee_timer,
	.set_eee_pls = dwxgmac2_set_eee_pls,
	.pcs_ctrl_ane = NULL,
	.pcs_rane = NULL,
	.pcs_get_adv_lp = NULL,
	.debug = NULL,
	.set_filter = dwxgmac2_set_filter,
	.safety_feat_config = dwxgmac3_safety_feat_config,
	.safety_feat_irq_status = dwxgmac3_safety_feat_irq_status,
	.safety_feat_dump = dwxgmac3_safety_feat_dump,
	.set_mac_loopback = dwxgmac2_set_mac_loopback,
	.rss_configure = dwxgmac2_rss_configure,
	.update_vlan_hash = dwxgmac2_update_vlan_hash,
	.rxp_config = dwxgmac3_rxp_config,
	.get_mac_tx_timestamp = dwxgmac2_get_mac_tx_timestamp,
	.flex_pps_config = dwxgmac2_flex_pps_config,
	.sarc_configure = dwxgmac2_sarc_configure,
	.enable_vlan = dwxgmac2_enable_vlan,
	.config_l3_filter = dwxgmac2_config_l3_filter,
	.config_l4_filter = dwxgmac2_config_l4_filter,
	.set_arp_offload = dwxgmac2_set_arp_offload,
	.est_configure = dwxgmac3_est_configure,
	.fpe_configure = dwxgmac3_fpe_configure,
};

int dwxgmac2_setup(struct stmmac_priv *priv)
{
	struct mac_device_info *mac = priv->hw;
@@ -1521,3 +1583,40 @@ int dwxgmac2_setup(struct stmmac_priv *priv)

	return 0;
}

int dwxlgmac2_setup(struct stmmac_priv *priv)
{
	struct mac_device_info *mac = priv->hw;

	dev_info(priv->device, "\tXLGMAC\n");

	priv->dev->priv_flags |= IFF_UNICAST_FLT;
	mac->pcsr = priv->ioaddr;
	mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
	mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
	mac->mcast_bits_log2 = 0;

	if (mac->multicast_filter_bins)
		mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);

	mac->link.duplex = 0;
	mac->link.speed1000 = XLGMAC_CONFIG_SS_1000;
	mac->link.speed2500 = XLGMAC_CONFIG_SS_2500;
	mac->link.xgmii.speed10000 = XLGMAC_CONFIG_SS_10G;
	mac->link.xlgmii.speed25000 = XLGMAC_CONFIG_SS_25G;
	mac->link.xlgmii.speed40000 = XLGMAC_CONFIG_SS_40G;
	mac->link.xlgmii.speed50000 = XLGMAC_CONFIG_SS_50G;
	mac->link.xlgmii.speed100000 = XLGMAC_CONFIG_SS_100G;
	mac->link.speed_mask = XLGMAC_CONFIG_SS;

	mac->mii.addr = XGMAC_MDIO_ADDR;
	mac->mii.data = XGMAC_MDIO_DATA;
	mac->mii.addr_shift = 16;
	mac->mii.addr_mask = GENMASK(20, 16);
	mac->mii.reg_shift = 0;
	mac->mii.reg_mask = GENMASK(15, 0);
	mac->mii.clk_csr_shift = 19;
	mac->mii.clk_csr_mask = GENMASK(21, 19);

	return 0;
}
+22 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2020 Synopsys, Inc. and/or its affiliates.
 * Synopsys DesignWare XLGMAC definitions.
 */

#ifndef __STMMAC_DWXLGMAC2_H__
#define __STMMAC_DWXLGMAC2_H__

/* MAC Registers */
#define XLGMAC_CONFIG_SS		GENMASK(30, 28)
#define XLGMAC_CONFIG_SS_SHIFT		28
#define XLGMAC_CONFIG_SS_40G		(0x0 << XLGMAC_CONFIG_SS_SHIFT)
#define XLGMAC_CONFIG_SS_25G		(0x1 << XLGMAC_CONFIG_SS_SHIFT)
#define XLGMAC_CONFIG_SS_50G		(0x2 << XLGMAC_CONFIG_SS_SHIFT)
#define XLGMAC_CONFIG_SS_100G		(0x3 << XLGMAC_CONFIG_SS_SHIFT)
#define XLGMAC_CONFIG_SS_10G		(0x4 << XLGMAC_CONFIG_SS_SHIFT)
#define XLGMAC_CONFIG_SS_2500		(0x6 << XLGMAC_CONFIG_SS_SHIFT)
#define XLGMAC_CONFIG_SS_1000		(0x7 << XLGMAC_CONFIG_SS_SHIFT)
#define XLGMAC_RXQ_ENABLE_CTRL0		0x00000140

#endif /* __STMMAC_DWXLGMAC2_H__ */
+44 −1
Original line number Diff line number Diff line
@@ -23,6 +23,18 @@ static u32 stmmac_get_id(struct stmmac_priv *priv, u32 id_reg)
	return reg & GENMASK(7, 0);
}

static u32 stmmac_get_dev_id(struct stmmac_priv *priv, u32 id_reg)
{
	u32 reg = readl(priv->ioaddr + id_reg);

	if (!reg) {
		dev_info(priv->device, "Version ID not available\n");
		return 0x0;
	}

	return (reg & GENMASK(15, 8)) >> 8;
}

static void stmmac_dwmac_mode_quirk(struct stmmac_priv *priv)
{
	struct mac_device_info *mac = priv->hw;
@@ -69,11 +81,18 @@ static int stmmac_dwmac4_quirks(struct stmmac_priv *priv)
	return 0;
}

static int stmmac_dwxlgmac_quirks(struct stmmac_priv *priv)
{
	priv->hw->xlgmac = true;
	return 0;
}

static const struct stmmac_hwif_entry {
	bool gmac;
	bool gmac4;
	bool xgmac;
	u32 min_id;
	u32 dev_id;
	const struct stmmac_regs_off regs;
	const void *desc;
	const void *dma;
@@ -199,6 +218,7 @@ static const struct stmmac_hwif_entry {
		.gmac4 = false,
		.xgmac = true,
		.min_id = DWXGMAC_CORE_2_10,
		.dev_id = DWXGMAC_ID,
		.regs = {
			.ptp_off = PTP_XGMAC_OFFSET,
			.mmc_off = MMC_XGMAC_OFFSET,
@@ -212,6 +232,25 @@ static const struct stmmac_hwif_entry {
		.mmc = &dwxgmac_mmc_ops,
		.setup = dwxgmac2_setup,
		.quirks = NULL,
	}, {
		.gmac = false,
		.gmac4 = false,
		.xgmac = true,
		.min_id = DWXLGMAC_CORE_2_00,
		.dev_id = DWXLGMAC_ID,
		.regs = {
			.ptp_off = PTP_XGMAC_OFFSET,
			.mmc_off = MMC_XGMAC_OFFSET,
		},
		.desc = &dwxgmac210_desc_ops,
		.dma = &dwxgmac210_dma_ops,
		.mac = &dwxlgmac2_ops,
		.hwtimestamp = &stmmac_ptp,
		.mode = NULL,
		.tc = &dwmac510_tc_ops,
		.mmc = &dwxgmac_mmc_ops,
		.setup = dwxlgmac2_setup,
		.quirks = stmmac_dwxlgmac_quirks,
	},
};

@@ -223,13 +262,15 @@ int stmmac_hwif_init(struct stmmac_priv *priv)
	const struct stmmac_hwif_entry *entry;
	struct mac_device_info *mac;
	bool needs_setup = true;
	u32 id, dev_id = 0;
	int i, ret;
	u32 id;

	if (needs_gmac) {
		id = stmmac_get_id(priv, GMAC_VERSION);
	} else if (needs_gmac4 || needs_xgmac) {
		id = stmmac_get_id(priv, GMAC4_VERSION);
		if (needs_xgmac)
			dev_id = stmmac_get_dev_id(priv, GMAC4_VERSION);
	} else {
		id = 0;
	}
@@ -267,6 +308,8 @@ int stmmac_hwif_init(struct stmmac_priv *priv)
		/* Use synopsys_id var because some setups can override this */
		if (priv->synopsys_id < entry->min_id)
			continue;
		if (needs_xgmac && (dev_id ^ entry->dev_id))
			continue;

		/* Only use generic HW helpers if needed */
		mac->desc = mac->desc ? : entry->desc;
Loading