aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/dsa/microchip
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/dsa/microchip')
-rw-r--r--drivers/net/dsa/microchip/ksz8795.c29
-rw-r--r--drivers/net/dsa/microchip/ksz8795_reg.h3
-rw-r--r--drivers/net/dsa/microchip/ksz_common.c39
-rw-r--r--drivers/net/dsa/microchip/ksz_common.h20
4 files changed, 53 insertions, 38 deletions
diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c
index ec1ddfcf7473..61b71bcfe396 100644
--- a/drivers/net/dsa/microchip/ksz8795.c
+++ b/drivers/net/dsa/microchip/ksz8795.c
@@ -1358,6 +1358,9 @@ static void ksz8795_cpu_interface_select(struct ksz_device *dev, int port)
{
struct ksz_port *p = &dev->ports[port];
+ if (!ksz_is_ksz87xx(dev))
+ return;
+
if (!p->interface && dev->compat_interface) {
dev_warn(dev->dev,
"Using legacy switch \"phy-mode\" property, because it is missing on port %d node. "
@@ -1391,18 +1394,29 @@ void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port)
/* enable 802.1p priority */
ksz_port_cfg(dev, port, P_PRIO_CTRL, PORT_802_1P_ENABLE, true);
- if (cpu_port) {
- if (!ksz_is_ksz88x3(dev))
- ksz8795_cpu_interface_select(dev, port);
-
+ if (cpu_port)
member = dsa_user_ports(ds);
- } else {
+ else
member = BIT(dsa_upstream_port(ds, port));
- }
ksz8_cfg_port_member(dev, port, member);
}
+static void ksz88x3_config_rmii_clk(struct ksz_device *dev)
+{
+ struct dsa_port *cpu_dp = dsa_to_port(dev->ds, dev->cpu_port);
+ bool rmii_clk_internal;
+
+ if (!ksz_is_ksz88x3(dev))
+ return;
+
+ rmii_clk_internal = of_property_read_bool(cpu_dp->dn,
+ "microchip,rmii-clk-internal");
+
+ ksz_cfg(dev, KSZ88X3_REG_FVID_AND_HOST_MODE,
+ KSZ88X3_PORT3_RMII_CLK_INTERNAL, rmii_clk_internal);
+}
+
void ksz8_config_cpu_port(struct dsa_switch *ds)
{
struct ksz_device *dev = ds->priv;
@@ -1419,6 +1433,9 @@ void ksz8_config_cpu_port(struct dsa_switch *ds)
ksz8_port_setup(dev, dev->cpu_port, true);
+ ksz8795_cpu_interface_select(dev, dev->cpu_port);
+ ksz88x3_config_rmii_clk(dev);
+
for (i = 0; i < dev->phy_port_cnt; i++) {
ksz_port_stp_state_set(ds, i, BR_STATE_DISABLED);
}
diff --git a/drivers/net/dsa/microchip/ksz8795_reg.h b/drivers/net/dsa/microchip/ksz8795_reg.h
index 3c9dae53e4d8..beca974e0171 100644
--- a/drivers/net/dsa/microchip/ksz8795_reg.h
+++ b/drivers/net/dsa/microchip/ksz8795_reg.h
@@ -22,6 +22,9 @@
#define KSZ8863_GLOBAL_SOFTWARE_RESET BIT(4)
#define KSZ8863_PCS_RESET BIT(0)
+#define KSZ88X3_REG_FVID_AND_HOST_MODE 0xC6
+#define KSZ88X3_PORT3_RMII_CLK_INTERNAL BIT(3)
+
#define REG_SW_CTRL_0 0x02
#define SW_NEW_BACKOFF BIT(7)
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 9545aed905f5..245dfb7a7a31 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -1673,15 +1673,23 @@ static const struct ksz_chip_data *ksz_lookup_info(unsigned int prod_num)
static int ksz_check_device_id(struct ksz_device *dev)
{
- const struct ksz_chip_data *dt_chip_data;
+ const struct ksz_chip_data *expected_chip_data;
+ u32 expected_chip_id;
- dt_chip_data = of_device_get_match_data(dev->dev);
+ if (dev->pdata) {
+ expected_chip_id = dev->pdata->chip_id;
+ expected_chip_data = ksz_lookup_info(expected_chip_id);
+ if (WARN_ON(!expected_chip_data))
+ return -ENODEV;
+ } else {
+ expected_chip_data = of_device_get_match_data(dev->dev);
+ expected_chip_id = expected_chip_data->chip_id;
+ }
- /* Check for Device Tree and Chip ID */
- if (dt_chip_data->chip_id != dev->chip_id) {
+ if (expected_chip_id != dev->chip_id) {
dev_err(dev->dev,
"Device tree specifies chip %s but found %s, please fix it!\n",
- dt_chip_data->dev_name, dev->info->dev_name);
+ expected_chip_data->dev_name, dev->info->dev_name);
return -ENODEV;
}
@@ -2704,7 +2712,7 @@ static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds,
proto = DSA_TAG_PROTO_KSZ9477;
if (is_lan937x(dev))
- proto = DSA_TAG_PROTO_LAN937X_VALUE;
+ proto = DSA_TAG_PROTO_LAN937X;
return proto;
}
@@ -2714,10 +2722,18 @@ static int ksz_connect_tag_protocol(struct dsa_switch *ds,
{
struct ksz_tagger_data *tagger_data;
- tagger_data = ksz_tagger_data(ds);
- tagger_data->xmit_work_fn = ksz_port_deferred_xmit;
-
- return 0;
+ switch (proto) {
+ case DSA_TAG_PROTO_KSZ8795:
+ return 0;
+ case DSA_TAG_PROTO_KSZ9893:
+ case DSA_TAG_PROTO_KSZ9477:
+ case DSA_TAG_PROTO_LAN937X:
+ tagger_data = ksz_tagger_data(ds);
+ tagger_data->xmit_work_fn = ksz_port_deferred_xmit;
+ return 0;
+ default:
+ return -EPROTONOSUPPORT;
+ }
}
static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port,
@@ -4156,9 +4172,6 @@ int ksz_switch_register(struct ksz_device *dev)
int ret;
int i;
- if (dev->pdata)
- dev->chip_id = dev->pdata->chip_id;
-
dev->reset_gpio = devm_gpiod_get_optional(dev->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(dev->reset_gpio))
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index d1a1c876ba0d..15612101a155 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -14,6 +14,7 @@
#include <linux/regmap.h>
#include <net/dsa.h>
#include <linux/irq.h>
+#include <linux/platform_data/microchip-ksz.h>
#include "ksz_ptp.h"
@@ -203,25 +204,6 @@ enum ksz_model {
LAN9374,
};
-enum ksz_chip_id {
- KSZ8563_CHIP_ID = 0x8563,
- KSZ8795_CHIP_ID = 0x8795,
- KSZ8794_CHIP_ID = 0x8794,
- KSZ8765_CHIP_ID = 0x8765,
- KSZ8830_CHIP_ID = 0x8830,
- KSZ9477_CHIP_ID = 0x00947700,
- KSZ9896_CHIP_ID = 0x00989600,
- KSZ9897_CHIP_ID = 0x00989700,
- KSZ9893_CHIP_ID = 0x00989300,
- KSZ9563_CHIP_ID = 0x00956300,
- KSZ9567_CHIP_ID = 0x00956700,
- LAN9370_CHIP_ID = 0x00937000,
- LAN9371_CHIP_ID = 0x00937100,
- LAN9372_CHIP_ID = 0x00937200,
- LAN9373_CHIP_ID = 0x00937300,
- LAN9374_CHIP_ID = 0x00937400,
-};
-
enum ksz_regs {
REG_SW_MAC_ADDR,
REG_IND_CTRL_0,