Commit 505bf320 authored by Oleksij Rempel's avatar Oleksij Rempel Committed by David S. Miller

net: dsa: microchip: do per-port Gbit detection instead of per-chip

KSZ8563 has two 100Mbit PHYs and CPU port with RGMII support. Since
1000Mbit configuration for the RGMII capable MAC is present, we should
use per port validation.

As main part of migration to per-port validation we need to rework
ksz9477_switch_init() function. Which is using undocumented
REG_GLOBAL_OPTIONS register to detect per-chip Gbit support. So, it is
related to some sort of risk for regressions.

To reduce this risk I compared the code with publicly available
documentations. This function will executed on following currently
supported chips:
struct ksz_chip_data            OF compatible
KSZ9477				KSZ9477
KSZ9897				KSZ9897
KSZ9893				KSZ9893, KSZ9563
KSZ8563				KSZ8563
KSZ9567				KSZ9567

Only KSZ9893, KSZ9563, KSZ8563 document existence of 0xf ==
REG_GLOBAL_OPTIONS register with bit field description "SKU ID":
KSZ9893 0x0C
KSZ9563 0x1C
KSZ8563 0x3C

The existence of hidden flags is not documented.

KSZ9477, KSZ9897, KSZ9567 do not document this register at all.

Only KSZ8563 is documented as non Gbit chip: 100Mbit PHYs and RGMII CPU
port. So, this change should not introduce a regression for
configurations with properly used OF compatibles.
Signed-off-by: default avatarOleksij Rempel <o.rempel@pengutronix.de>
Reviewed-by: default avatarVladimir Oltean <olteanv@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b4490809
...@@ -320,7 +320,7 @@ void ksz9477_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val) ...@@ -320,7 +320,7 @@ void ksz9477_w_phy(struct ksz_device *dev, u16 addr, u16 reg, u16 val)
return; return;
/* No gigabit support. Do not write to this register. */ /* No gigabit support. Do not write to this register. */
if (!(dev->features & GBIT_SUPPORT) && reg == MII_CTRL1000) if (!dev->info->gbit_capable[addr] && reg == MII_CTRL1000)
return; return;
ksz_pwrite16(dev, addr, 0x100 + (reg << 1), val); ksz_pwrite16(dev, addr, 0x100 + (reg << 1), val);
...@@ -914,7 +914,7 @@ static void ksz9477_phy_errata_setup(struct ksz_device *dev, int port) ...@@ -914,7 +914,7 @@ static void ksz9477_phy_errata_setup(struct ksz_device *dev, int port)
/* Energy Efficient Ethernet (EEE) feature select must /* Energy Efficient Ethernet (EEE) feature select must
* be manually disabled (except on KSZ8565 which is 100Mbit) * be manually disabled (except on KSZ8565 which is 100Mbit)
*/ */
if (dev->features & GBIT_SUPPORT) if (dev->info->gbit_capable[port])
ksz9477_port_mmd_write(dev, port, 0x07, 0x3c, 0x0000); ksz9477_port_mmd_write(dev, port, 0x07, 0x3c, 0x0000);
/* Register settings are required to meet data sheet /* Register settings are required to meet data sheet
...@@ -941,7 +941,7 @@ void ksz9477_get_caps(struct ksz_device *dev, int port, ...@@ -941,7 +941,7 @@ void ksz9477_get_caps(struct ksz_device *dev, int port,
config->mac_capabilities = MAC_10 | MAC_100 | MAC_ASYM_PAUSE | config->mac_capabilities = MAC_10 | MAC_100 | MAC_ASYM_PAUSE |
MAC_SYM_PAUSE; MAC_SYM_PAUSE;
if (dev->features & GBIT_SUPPORT) if (dev->info->gbit_capable[port])
config->mac_capabilities |= MAC_1000FD; config->mac_capabilities |= MAC_1000FD;
} }
...@@ -1158,27 +1158,13 @@ int ksz9477_switch_init(struct ksz_device *dev) ...@@ -1158,27 +1158,13 @@ int ksz9477_switch_init(struct ksz_device *dev)
if (ret) if (ret)
return ret; return ret;
ret = ksz_read8(dev, REG_GLOBAL_OPTIONS, &data8);
if (ret)
return ret;
/* Number of ports can be reduced depending on chip. */ /* Number of ports can be reduced depending on chip. */
dev->phy_port_cnt = 5; dev->phy_port_cnt = 5;
/* Default capability is gigabit capable. */
dev->features = GBIT_SUPPORT;
if (dev->chip_id == KSZ9893_CHIP_ID) { if (dev->chip_id == KSZ9893_CHIP_ID) {
dev->features |= IS_9893; dev->features |= IS_9893;
/* Chip does not support gigabit. */
if (data8 & SW_QW_ABLE)
dev->features &= ~GBIT_SUPPORT;
dev->phy_port_cnt = 2; dev->phy_port_cnt = 2;
} else {
/* Chip does not support gigabit. */
if (!(data8 & SW_GIGABIT_ABLE))
dev->features &= ~GBIT_SUPPORT;
} }
return 0; return 0;
......
...@@ -434,6 +434,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { ...@@ -434,6 +434,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.supports_rmii = {false, false, true}, .supports_rmii = {false, false, true},
.supports_rgmii = {false, false, true}, .supports_rgmii = {false, false, true},
.internal_phy = {true, true, false}, .internal_phy = {true, true, false},
.gbit_capable = {false, false, true},
}, },
[KSZ8795] = { [KSZ8795] = {
...@@ -568,6 +569,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { ...@@ -568,6 +569,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
false, true, false}, false, true, false},
.internal_phy = {true, true, true, true, .internal_phy = {true, true, true, true,
true, false, false}, true, false, false},
.gbit_capable = {true, true, true, true, true, true, true},
}, },
[KSZ9897] = { [KSZ9897] = {
...@@ -596,6 +598,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { ...@@ -596,6 +598,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
false, true, true}, false, true, true},
.internal_phy = {true, true, true, true, .internal_phy = {true, true, true, true,
true, false, false}, true, false, false},
.gbit_capable = {true, true, true, true, true, true, true},
}, },
[KSZ9893] = { [KSZ9893] = {
...@@ -619,6 +622,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { ...@@ -619,6 +622,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
.supports_rmii = {false, false, true}, .supports_rmii = {false, false, true},
.supports_rgmii = {false, false, true}, .supports_rgmii = {false, false, true},
.internal_phy = {true, true, false}, .internal_phy = {true, true, false},
.gbit_capable = {true, true, true},
}, },
[KSZ9567] = { [KSZ9567] = {
...@@ -647,6 +651,7 @@ const struct ksz_chip_data ksz_switch_chips[] = { ...@@ -647,6 +651,7 @@ const struct ksz_chip_data ksz_switch_chips[] = {
false, true, true}, false, true, true},
.internal_phy = {true, true, true, true, .internal_phy = {true, true, true, true,
true, false, false}, true, false, false},
.gbit_capable = {true, true, true, true, true, true, true},
}, },
[LAN9370] = { [LAN9370] = {
......
...@@ -61,6 +61,7 @@ struct ksz_chip_data { ...@@ -61,6 +61,7 @@ struct ksz_chip_data {
bool supports_rmii[KSZ_MAX_NUM_PORTS]; bool supports_rmii[KSZ_MAX_NUM_PORTS];
bool supports_rgmii[KSZ_MAX_NUM_PORTS]; bool supports_rgmii[KSZ_MAX_NUM_PORTS];
bool internal_phy[KSZ_MAX_NUM_PORTS]; bool internal_phy[KSZ_MAX_NUM_PORTS];
bool gbit_capable[KSZ_MAX_NUM_PORTS];
}; };
struct ksz_port { struct ksz_port {
...@@ -504,7 +505,6 @@ static inline int is_lan937x(struct ksz_device *dev) ...@@ -504,7 +505,6 @@ static inline int is_lan937x(struct ksz_device *dev)
#define SW_START 0x01 #define SW_START 0x01
/* Used with variable features to indicate capabilities. */ /* Used with variable features to indicate capabilities. */
#define GBIT_SUPPORT BIT(0)
#define IS_9893 BIT(2) #define IS_9893 BIT(2)
/* xMII configuration */ /* xMII configuration */
......
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