openwrt/target/linux/layerscape/patches-5.4/701-net-0280-net-mscc-ocelot-do-not-force-Felix-MACs-at-lower-spe.patch
Yangbo Lu cddd459140 layerscape: add patches-5.4
Add patches for linux-5.4. The patches are from NXP LSDK-20.04 release
which was tagged LSDK-20.04-V5.4.
https://source.codeaurora.org/external/qoriq/qoriq-components/linux/

For boards LS1021A-IOT, and Traverse-LS1043 which are not involved in
LSDK, port the dts patches from 4.14.

The patches are sorted into the following categories:
  301-arch-xxxx
  302-dts-xxxx
  303-core-xxxx
  701-net-xxxx
  801-audio-xxxx
  802-can-xxxx
  803-clock-xxxx
  804-crypto-xxxx
  805-display-xxxx
  806-dma-xxxx
  807-gpio-xxxx
  808-i2c-xxxx
  809-jailhouse-xxxx
  810-keys-xxxx
  811-kvm-xxxx
  812-pcie-xxxx
  813-pm-xxxx
  814-qe-xxxx
  815-sata-xxxx
  816-sdhc-xxxx
  817-spi-xxxx
  818-thermal-xxxx
  819-uart-xxxx
  820-usb-xxxx
  821-vfio-xxxx

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
2020-05-07 12:53:06 +02:00

155 lines
5.0 KiB
Diff

From 4ba6e00c2f45bf4189ec6a8ef71b45346ae804f2 Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: Thu, 28 Nov 2019 15:36:10 +0200
Subject: [PATCH] net: mscc: ocelot: do not force Felix MACs at lower speeds
than gigabit
In the LS1028A, the VSC9959 switch was integrated with an NXP PCS which
performs SGMII AN and rate adaptation autonomously. The MAC does not
need to know about this, and forcing the MAC speed to something else,
when connected to a 10/100 link partner, actually breaks the GMII
internal link between the MAC and the PCS.
Add a quirk system in the ocelot driver, and a first quirk called "PCS
performs rate adaptation", to distinguish the VSC7514 from the VSC9959
regarding this behavior.
Signed-off-by: Catalin Horghidan <catalin.horghidan@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/dsa/ocelot/felix.c | 1 +
drivers/net/dsa/ocelot/felix.h | 1 +
drivers/net/dsa/ocelot/felix_vsc9959.c | 1 +
drivers/net/ethernet/mscc/ocelot.c | 32 ++++++++++++++++++--------------
include/soc/mscc/ocelot.h | 7 +++++++
5 files changed, 28 insertions(+), 14 deletions(-)
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -249,6 +249,7 @@ static int felix_init_structs(struct fel
ocelot->num_stats = felix->info->num_stats;
ocelot->shared_queue_sz = felix->info->shared_queue_sz;
ocelot->ops = felix->info->ops;
+ ocelot->quirks = felix->info->quirks;
base = pci_resource_start(felix->pdev, felix->info->pci_bar);
--- a/drivers/net/dsa/ocelot/felix.h
+++ b/drivers/net/dsa/ocelot/felix.h
@@ -18,6 +18,7 @@ struct felix_info {
unsigned int num_stats;
int num_ports;
int pci_bar;
+ unsigned long quirks;
};
extern struct felix_info felix_info_vsc9959;
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -584,4 +584,5 @@ struct felix_info felix_info_vsc9959 = {
.shared_queue_sz = 128 * 1024,
.num_ports = 6,
.pci_bar = 4,
+ .quirks = OCELOT_PCS_PERFORMS_RATE_ADAPTATION,
};
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -409,27 +409,32 @@ static u16 ocelot_wm_enc(u16 value)
void ocelot_adjust_link(struct ocelot *ocelot, int port,
struct phy_device *phydev)
{
+ int speed, mac_speed, mac_mode = DEV_MAC_MODE_CFG_FDX_ENA;
struct ocelot_port *ocelot_port = ocelot->ports[port];
- int speed, mode = 0;
- switch (phydev->speed) {
+ if (ocelot->quirks & OCELOT_PCS_PERFORMS_RATE_ADAPTATION)
+ speed = SPEED_1000;
+ else
+ speed = phydev->speed;
+
+ switch (speed) {
case SPEED_10:
- speed = OCELOT_SPEED_10;
+ mac_speed = OCELOT_SPEED_10;
break;
case SPEED_100:
- speed = OCELOT_SPEED_100;
+ mac_speed = OCELOT_SPEED_100;
break;
case SPEED_1000:
- speed = OCELOT_SPEED_1000;
- mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA;
+ mac_speed = OCELOT_SPEED_1000;
+ mac_mode |= DEV_MAC_MODE_CFG_GIGA_MODE_ENA;
break;
case SPEED_2500:
- speed = OCELOT_SPEED_2500;
- mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA;
+ mac_speed = OCELOT_SPEED_2500;
+ mac_mode |= DEV_MAC_MODE_CFG_GIGA_MODE_ENA;
break;
default:
dev_err(ocelot->dev, "Unsupported PHY speed on port %d: %d\n",
- port, phydev->speed);
+ port, speed);
return;
}
@@ -439,8 +444,7 @@ void ocelot_adjust_link(struct ocelot *o
return;
/* Only full duplex supported for now */
- ocelot_port_writel(ocelot_port, DEV_MAC_MODE_CFG_FDX_ENA |
- mode, DEV_MAC_MODE_CFG);
+ ocelot_port_writel(ocelot_port, mac_mode, DEV_MAC_MODE_CFG);
if (ocelot->ops->pcs_init)
ocelot->ops->pcs_init(ocelot, port);
@@ -451,11 +455,11 @@ void ocelot_adjust_link(struct ocelot *o
/* Take MAC, Port, Phy (intern) and PCS (SGMII/Serdes) clock out of
* reset */
- ocelot_port_writel(ocelot_port, DEV_CLOCK_CFG_LINK_SPEED(speed),
+ ocelot_port_writel(ocelot_port, DEV_CLOCK_CFG_LINK_SPEED(mac_speed),
DEV_CLOCK_CFG);
/* No PFC */
- ocelot_write_gix(ocelot, ANA_PFC_PFC_CFG_FC_LINK_SPEED(speed),
+ ocelot_write_gix(ocelot, ANA_PFC_PFC_CFG_FC_LINK_SPEED(mac_speed),
ANA_PFC_PFC_CFG, port);
/* Core: Enable port for frame transfer */
@@ -469,7 +473,7 @@ void ocelot_adjust_link(struct ocelot *o
SYS_MAC_FC_CFG_RX_FC_ENA | SYS_MAC_FC_CFG_TX_FC_ENA |
SYS_MAC_FC_CFG_ZERO_PAUSE_ENA |
SYS_MAC_FC_CFG_FC_LATENCY_CFG(0x7) |
- SYS_MAC_FC_CFG_FC_LINK_SPEED(speed),
+ SYS_MAC_FC_CFG_FC_LINK_SPEED(mac_speed),
SYS_MAC_FC_CFG, port);
ocelot_write_rix(ocelot, 0, ANA_POL_FLOWC, port);
}
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -404,6 +404,11 @@ enum ocelot_tag_prefix {
OCELOT_TAG_PREFIX_LONG,
};
+/* Hardware quirks (differences between switch instantiations) */
+enum {
+ OCELOT_PCS_PERFORMS_RATE_ADAPTATION = BIT(0),
+};
+
struct ocelot;
struct ocelot_ops {
@@ -464,6 +469,8 @@ struct ocelot {
struct delayed_work stats_work;
struct workqueue_struct *stats_queue;
+ unsigned long quirks;
+
u8 ptp:1;
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_info;