dts: ksz8974: add support for ksz8863

Add DSA support for KSZ8863 chip.

Signed-off-by: Arvin Farahmand <arvinf@ip-logix.com>
This commit is contained in:
Arvin Farahmand 2021-05-05 17:14:01 -04:00 committed by Christopher Friedt
commit b0e4886dfa
8 changed files with 404 additions and 98 deletions

View file

@ -6,7 +6,7 @@
menuconfig NET_DSA menuconfig NET_DSA
bool "Distributed Switch Architecture support" bool "Distributed Switch Architecture support"
depends on ETH_MCUX depends on ETH_MCUX || ETH_SAM_GMAC
help help
Enable Distributed Switch Architecture support. For now it Enable Distributed Switch Architecture support. For now it
only supports Kinetics ENET driver. only supports Kinetics ENET driver.
@ -18,10 +18,22 @@ config DSA_KSZ8794
help help
Add support for KSZ8794 DSA device driver. Add support for KSZ8794 DSA device driver.
config DSA_KSZ8794_TAIL_TAGGING config DSA_KSZ8863
bool "Enable support for tail tagging on KSZ8794" bool "Enable support for KSZ8863"
help help
Add support for tail tagging on KSZ8794 DSA device. Add support for KSZ8863 DSA device driver.
config DSA_KSZ_TAIL_TAGGING
bool "Enable support for tail tagging"
depends on DSA_KSZ8794 || DSA_KSZ8863
help
Add support for tail tagging on DSA device.
config DSA_SPI
bool "Enable support for PHY SPI interface"
depends on SPI && (DSA_KSZ8794 || DSA_KSZ8863)
help
Use SPI bus to communicate with PHY
module = NET_DSA module = NET_DSA
module-dep = NET_LOG module-dep = NET_LOG

View file

@ -4,8 +4,6 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#define DT_DRV_COMPAT microchip_ksz8794
#define LOG_MODULE_NAME dsa #define LOG_MODULE_NAME dsa
#include <logging/log.h> #include <logging/log.h>
@ -19,14 +17,31 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_ETHERNET_LOG_LEVEL);
#include <net/ethernet.h> #include <net/ethernet.h>
#include <linker/sections.h> #include <linker/sections.h>
#include <drivers/spi.h> #include <drivers/spi.h>
#if defined(CONFIG_DSA_SPI)
#include <drivers/spi.h>
#else
#error "No communication bus defined"
#endif
#if CONFIG_DSA_KSZ8863
#define DT_DRV_COMPAT microchip_ksz8863
#include "dsa_ksz8863.h"
#elif CONFIG_DSA_KSZ8794
#define DT_DRV_COMPAT microchip_ksz8794
#include "dsa_ksz8794.h" #include "dsa_ksz8794.h"
#else
#error "Unsupported KSZ chipset"
#endif
struct ksz8794_data { struct ksz8794_data {
int iface_init_count; int iface_init_count;
bool is_init; bool is_init;
#if defined(CONFIG_DSA_SPI)
const struct device *spi; const struct device *spi;
struct spi_config spi_cfg; struct spi_config spi_cfg;
struct spi_cs_control cs_ctrl; struct spi_cs_control cs_ctrl;
#endif
}; };
static struct ksz8794_data private_data = { static struct ksz8794_data private_data = {
@ -37,9 +52,10 @@ static struct ksz8794_data private_data = {
#define DEV_DATA(dev) ((struct dsa_context *const)(dev)->data) #define DEV_DATA(dev) ((struct dsa_context *const)(dev)->data)
#define PRV_DATA(ctx) ((struct ksz8794_data *const)(ctx)->prv_data) #define PRV_DATA(ctx) ((struct ksz8794_data *const)(ctx)->prv_data)
static void dsa_ksz8794_write_reg(struct ksz8794_data *pdev, static void dsa_ksz8794_write_reg(const struct ksz8794_data *pdev,
uint16_t reg_addr, uint8_t value) uint16_t reg_addr, uint8_t value)
{ {
#if defined(CONFIG_DSA_SPI)
uint8_t buf[3]; uint8_t buf[3];
const struct spi_buf tx_buf = { const struct spi_buf tx_buf = {
@ -51,16 +67,18 @@ static void dsa_ksz8794_write_reg(struct ksz8794_data *pdev,
.count = 1 .count = 1
}; };
buf[0] = KSZ8794_SPI_CMD_WR | ((reg_addr >> 7) & 0x1F); buf[0] = KSZ8XXX_SPI_CMD_WR | ((reg_addr >> 7) & 0x1F);
buf[1] = (reg_addr << 1) & 0xFE; buf[1] = (reg_addr << 1) & 0xFE;
buf[2] = value; buf[2] = value;
spi_write(pdev->spi, &pdev->spi_cfg, &tx); spi_write(pdev->spi, &pdev->spi_cfg, &tx);
#endif
} }
static void dsa_ksz8794_read_reg(struct ksz8794_data *pdev, static void dsa_ksz8794_read_reg(const struct ksz8794_data *pdev,
uint16_t reg_addr, uint8_t *value) uint16_t reg_addr, uint8_t *value)
{ {
#if defined(CONFIG_DSA_SPI)
uint8_t buf[3]; uint8_t buf[3];
const struct spi_buf tx_buf = { const struct spi_buf tx_buf = {
@ -81,7 +99,7 @@ static void dsa_ksz8794_read_reg(struct ksz8794_data *pdev,
.count = 1 .count = 1
}; };
buf[0] = KSZ8794_SPI_CMD_RD | ((reg_addr >> 7) & 0x1F); buf[0] = KSZ8XXX_SPI_CMD_RD | ((reg_addr >> 7) & 0x1F);
buf[1] = (reg_addr << 1) & 0xFE; buf[1] = (reg_addr << 1) & 0xFE;
buf[2] = 0x0; buf[2] = 0x0;
@ -91,6 +109,7 @@ static void dsa_ksz8794_read_reg(struct ksz8794_data *pdev,
LOG_DBG("Failure while reading register 0x%04x", reg_addr); LOG_DBG("Failure while reading register 0x%04x", reg_addr);
*value = 0U; *value = 0U;
} }
#endif
} }
static bool dsa_ksz8794_port_link_status(struct ksz8794_data *pdev, static bool dsa_ksz8794_port_link_status(struct ksz8794_data *pdev,
@ -98,23 +117,24 @@ static bool dsa_ksz8794_port_link_status(struct ksz8794_data *pdev,
{ {
uint8_t tmp; uint8_t tmp;
if (port < KSZ8794_PORT1 || port >= KSZ8794_CPU_PORT) { if (port < KSZ8XXX_FIRST_PORT || port > KSZ8XXX_LAST_PORT ||
port == KSZ8XXX_CPU_PORT) {
return false; return false;
} }
dsa_ksz8794_read_reg(pdev, KSZ8794_STAT2_PORTn(port), &tmp); dsa_ksz8794_read_reg(pdev, KSZ8XXX_STAT2_PORTn(port), &tmp);
return tmp & KSZ8794_STAT2_LINK_GOOD; return tmp & KSZ8XXX_STAT2_LINK_GOOD;
} }
#if !DT_INST_NODE_HAS_PROP(0, reset_gpios) #if !DT_INST_NODE_HAS_PROP(0, reset_gpios)
static void dsa_ksz8794_soft_reset(struct ksz8794_data *pdev) static void dsa_ksz8794_soft_reset(struct ksz8794_data *pdev)
{ {
/* reset switch */ /* reset switch */
dsa_ksz8794_write_reg(pdev, KSZ8794_PD_MGMT_CTRL1, dsa_ksz8794_write_reg(pdev, KSZ8XXX_RESET_REG,
KSZ8794_PWR_MGNT_MODE_SOFT_DOWN); KSZ8XXX_RESET_SET);
k_busy_wait(1000); k_busy_wait(KSZ8XXX_SOFT_RESET_DURATION);
dsa_ksz8794_write_reg(pdev, KSZ8794_PD_MGMT_CTRL1, 0); dsa_ksz8794_write_reg(pdev, KSZ8XXX_RESET_REG, KSZ8XXX_RESET_CLEAR);
} }
#endif #endif
@ -127,8 +147,8 @@ static int dsa_ksz8794_probe(struct ksz8794_data *pdev)
* Wait for SPI of KSZ8794 being fully operational - up to 10 ms * Wait for SPI of KSZ8794 being fully operational - up to 10 ms
*/ */
for (timeout = 100, tmp = 0; for (timeout = 100, tmp = 0;
tmp != KSZ8794_CHIP_ID0_ID_DEFAULT && timeout > 0; timeout--) { tmp != KSZ8XXX_CHIP_ID0_ID_DEFAULT && timeout > 0; timeout--) {
dsa_ksz8794_read_reg(pdev, KSZ8794_CHIP_ID0, &tmp); dsa_ksz8794_read_reg(pdev, KSZ8XXX_CHIP_ID0, &tmp);
k_busy_wait(100); k_busy_wait(100);
} }
@ -137,8 +157,19 @@ static int dsa_ksz8794_probe(struct ksz8794_data *pdev)
return -ENODEV; return -ENODEV;
} }
dsa_ksz8794_read_reg(pdev, KSZ8794_CHIP_ID0, &val[0]); dsa_ksz8794_read_reg(pdev, KSZ8XXX_CHIP_ID0, &val[0]);
dsa_ksz8794_read_reg(pdev, KSZ8794_CHIP_ID1, &val[1]); dsa_ksz8794_read_reg(pdev, KSZ8XXX_CHIP_ID1, &val[1]);
if (val[0] != KSZ8XXX_CHIP_ID0_ID_DEFAULT ||
val[1] != KSZ8XXX_CHIP_ID1_ID_DEFAULT) {
LOG_ERR("Chip ID mismatch. "
"Expected %02x%02x but found %02x%02x",
KSZ8XXX_CHIP_ID0_ID_DEFAULT,
KSZ8XXX_CHIP_ID1_ID_DEFAULT,
val[0],
val[1]);
return -ENODEV;
}
LOG_DBG("KSZ8794: ID0: 0x%x ID1: 0x%x timeout: %d", val[1], val[0], LOG_DBG("KSZ8794: ID0: 0x%x ID1: 0x%x timeout: %d", val[1], val[0],
timeout); timeout);
@ -161,17 +192,17 @@ static int dsa_ksz8794_write_static_mac_table(struct ksz8794_data *pdev,
* Write to Register 111 with 0x0x (trigger the write operation, to * Write to Register 111 with 0x0x (trigger the write operation, to
* table entry x) * table entry x)
*/ */
dsa_ksz8794_write_reg(pdev, KSZ8794_REG_IND_DATA_7, p[7]); dsa_ksz8794_write_reg(pdev, KSZ8XXX_REG_IND_DATA_7, p[7]);
dsa_ksz8794_write_reg(pdev, KSZ8794_REG_IND_DATA_6, p[6]); dsa_ksz8794_write_reg(pdev, KSZ8XXX_REG_IND_DATA_6, p[6]);
dsa_ksz8794_write_reg(pdev, KSZ8794_REG_IND_DATA_5, p[5]); dsa_ksz8794_write_reg(pdev, KSZ8XXX_REG_IND_DATA_5, p[5]);
dsa_ksz8794_write_reg(pdev, KSZ8794_REG_IND_DATA_4, p[4]); dsa_ksz8794_write_reg(pdev, KSZ8XXX_REG_IND_DATA_4, p[4]);
dsa_ksz8794_write_reg(pdev, KSZ8794_REG_IND_DATA_3, p[3]); dsa_ksz8794_write_reg(pdev, KSZ8XXX_REG_IND_DATA_3, p[3]);
dsa_ksz8794_write_reg(pdev, KSZ8794_REG_IND_DATA_2, p[2]); dsa_ksz8794_write_reg(pdev, KSZ8XXX_REG_IND_DATA_2, p[2]);
dsa_ksz8794_write_reg(pdev, KSZ8794_REG_IND_DATA_1, p[1]); dsa_ksz8794_write_reg(pdev, KSZ8XXX_REG_IND_DATA_1, p[1]);
dsa_ksz8794_write_reg(pdev, KSZ8794_REG_IND_DATA_0, p[0]); dsa_ksz8794_write_reg(pdev, KSZ8XXX_REG_IND_DATA_0, p[0]);
dsa_ksz8794_write_reg(pdev, KSZ8794_REG_IND_CTRL_0, 0x00); dsa_ksz8794_write_reg(pdev, KSZ8XXX_REG_IND_CTRL_0, 0x00);
dsa_ksz8794_write_reg(pdev, KSZ8794_REG_IND_CTRL_1, entry_addr); dsa_ksz8794_write_reg(pdev, KSZ8XXX_REG_IND_CTRL_1, entry_addr);
return 0; return 0;
} }
@ -196,8 +227,8 @@ static int dsa_ksz8794_set_static_mac_table(struct ksz8794_data *pdev,
buf[0] = mac[5]; buf[0] = mac[5];
buf[6] = fw_port; buf[6] = fw_port;
buf[6] |= KSZ8794_STATIC_MAC_TABLE_VALID; buf[6] |= KSZ8XXX_STATIC_MAC_TABLE_VALID;
buf[6] |= KSZ8794_STATIC_MAC_TABLE_OVERRIDE; buf[6] |= KSZ8XXX_STATIC_MAC_TABLE_OVRD;
dsa_ksz8794_write_static_mac_table(pdev, entry_idx, buf); dsa_ksz8794_write_static_mac_table(pdev, entry_idx, buf);
@ -222,17 +253,17 @@ static int dsa_ksz8794_read_static_mac_table(struct ksz8794_data *pdev,
* *
*/ */
dsa_ksz8794_write_reg(pdev, KSZ8794_REG_IND_CTRL_0, 0x10); dsa_ksz8794_write_reg(pdev, KSZ8XXX_REG_IND_CTRL_0, 0x10);
dsa_ksz8794_write_reg(pdev, KSZ8794_REG_IND_CTRL_1, entry_addr); dsa_ksz8794_write_reg(pdev, KSZ8XXX_REG_IND_CTRL_1, entry_addr);
dsa_ksz8794_read_reg(pdev, KSZ8794_REG_IND_DATA_7, &p[7]); dsa_ksz8794_read_reg(pdev, KSZ8XXX_REG_IND_DATA_7, &p[7]);
dsa_ksz8794_read_reg(pdev, KSZ8794_REG_IND_DATA_6, &p[6]); dsa_ksz8794_read_reg(pdev, KSZ8XXX_REG_IND_DATA_6, &p[6]);
dsa_ksz8794_read_reg(pdev, KSZ8794_REG_IND_DATA_5, &p[5]); dsa_ksz8794_read_reg(pdev, KSZ8XXX_REG_IND_DATA_5, &p[5]);
dsa_ksz8794_read_reg(pdev, KSZ8794_REG_IND_DATA_4, &p[4]); dsa_ksz8794_read_reg(pdev, KSZ8XXX_REG_IND_DATA_4, &p[4]);
dsa_ksz8794_read_reg(pdev, KSZ8794_REG_IND_DATA_3, &p[3]); dsa_ksz8794_read_reg(pdev, KSZ8XXX_REG_IND_DATA_3, &p[3]);
dsa_ksz8794_read_reg(pdev, KSZ8794_REG_IND_DATA_2, &p[2]); dsa_ksz8794_read_reg(pdev, KSZ8XXX_REG_IND_DATA_2, &p[2]);
dsa_ksz8794_read_reg(pdev, KSZ8794_REG_IND_DATA_1, &p[1]); dsa_ksz8794_read_reg(pdev, KSZ8XXX_REG_IND_DATA_1, &p[1]);
dsa_ksz8794_read_reg(pdev, KSZ8794_REG_IND_DATA_0, &p[0]); dsa_ksz8794_read_reg(pdev, KSZ8XXX_REG_IND_DATA_0, &p[0]);
return 0; return 0;
} }
@ -243,6 +274,46 @@ static int dsa_ksz8794_get_static_mac_table(struct ksz8794_data *pdev,
return dsa_ksz8794_read_static_mac_table(pdev, entry_idx, buf); return dsa_ksz8794_read_static_mac_table(pdev, entry_idx, buf);
} }
#if CONFIG_DSA_KSZ8863
static int dsa_ksz8794_switch_setup(const struct ksz8794_data *pdev)
{
uint8_t tmp, i;
/*
* Loop through ports - The same setup when tail tagging is enabled or
* disabled.
*/
for (i = KSZ8XXX_FIRST_PORT; i <= KSZ8XXX_LAST_PORT; i++) {
/* Enable transmission, reception and switch address learning */
dsa_ksz8794_read_reg(pdev, KSZ8863_CTRL2_PORTn(i), &tmp);
tmp |= KSZ8863_CTRL2_TRANSMIT_EN;
tmp |= KSZ8863_CTRL2_RECEIVE_EN;
tmp &= ~KSZ8863_CTRL2_LEARNING_DIS;
dsa_ksz8794_write_reg(pdev, KSZ8863_CTRL2_PORTn(i), tmp);
}
#if defined(CONFIG_DSA_KSZ_TAIL_TAGGING)
/* Enable tail tag feature */
dsa_ksz8794_read_reg(pdev, KSZ8863_GLOBAL_CTRL10, &tmp);
tmp |= KSZ8863_GLOBAL_CTRL1_TAIL_TAG_EN;
dsa_ksz8794_write_reg(pdev, KSZ8863_GLOBAL_CTRL10, tmp);
#else
/* Disable tail tag feature */
dsa_ksz8794_read_reg(pdev, KSZ8863_GLOBAL_CTRL1, &tmp);
tmp &= ~KSZ8863_GLOBAL_CTRL1_TAIL_TAG_EN;
dsa_ksz8794_write_reg(pdev, KSZ8863_GLOBAL_CTRL1, tmp);
#endif
dsa_ksz8794_read_reg(pdev, KSZ8863_GLOBAL_CTRL2, &tmp);
tmp &= ~KSZ8863_GLOBAL_CTRL2_LEG_MAX_PKT_SIZ_CHK_ENA;
dsa_ksz8794_write_reg(pdev, KSZ8863_GLOBAL_CTRL2, tmp);
return 0;
}
#endif
#if CONFIG_DSA_KSZ8794
static int dsa_ksz8794_switch_setup(struct ksz8794_data *pdev) static int dsa_ksz8794_switch_setup(struct ksz8794_data *pdev)
{ {
uint8_t tmp, i; uint8_t tmp, i;
@ -251,7 +322,12 @@ static int dsa_ksz8794_switch_setup(struct ksz8794_data *pdev)
* Loop through ports - The same setup when tail tagging is enabled or * Loop through ports - The same setup when tail tagging is enabled or
* disabled. * disabled.
*/ */
for (i = KSZ8794_PORT1; i < KSZ8794_CPU_PORT; i++) { for (i = KSZ8XXX_FIRST_PORT; i <= KSZ8XXX_LAST_PORT; i++) {
/* Skip Switch <-> CPU Port */
if (i == KSZ8XXX_CPU_PORT) {
continue;
}
/* Enable transmission, reception and switch address learning */ /* Enable transmission, reception and switch address learning */
dsa_ksz8794_read_reg(pdev, KSZ8794_CTRL2_PORTn(i), &tmp); dsa_ksz8794_read_reg(pdev, KSZ8794_CTRL2_PORTn(i), &tmp);
tmp |= KSZ8794_CTRL2_TRANSMIT_EN; tmp |= KSZ8794_CTRL2_TRANSMIT_EN;
@ -260,7 +336,7 @@ static int dsa_ksz8794_switch_setup(struct ksz8794_data *pdev)
dsa_ksz8794_write_reg(pdev, KSZ8794_CTRL2_PORTn(i), tmp); dsa_ksz8794_write_reg(pdev, KSZ8794_CTRL2_PORTn(i), tmp);
} }
#if defined(CONFIG_DSA_KSZ8794_TAIL_TAGGING) #if defined(DSA_KSZ_TAIL_TAGGING)
/* Enable tail tag feature */ /* Enable tail tag feature */
dsa_ksz8794_read_reg(pdev, KSZ8794_GLOBAL_CTRL10, &tmp); dsa_ksz8794_read_reg(pdev, KSZ8794_GLOBAL_CTRL10, &tmp);
tmp |= KSZ8794_GLOBAL_CTRL10_TAIL_TAG_EN; tmp |= KSZ8794_GLOBAL_CTRL10_TAIL_TAG_EN;
@ -581,6 +657,7 @@ static int dsa_ksz8794_set_lowspeed_drivestrength(struct ksz8794_data *pdev)
return ret; return ret;
} }
#endif #endif
#endif
#if DT_INST_NODE_HAS_PROP(0, reset_gpios) #if DT_INST_NODE_HAS_PROP(0, reset_gpios)
static int dsa_ksz8794_gpio_reset(struct ksz8794_data *pdev) static int dsa_ksz8794_gpio_reset(struct ksz8794_data *pdev)
@ -606,6 +683,7 @@ static int dsa_ksz8794_gpio_reset(struct ksz8794_data *pdev)
static int dsa_ksz8794_configure_bus(struct ksz8794_data *pdev) static int dsa_ksz8794_configure_bus(struct ksz8794_data *pdev)
{ {
#if defined(CONFIG_DSA_SPI)
/* SPI config */ /* SPI config */
pdev->spi_cfg.operation = pdev->spi_cfg.operation =
#if DT_INST_PROP(0, spi_cpol) #if DT_INST_PROP(0, spi_cpol)
@ -632,7 +710,7 @@ static int dsa_ksz8794_configure_bus(struct ksz8794_data *pdev)
if (!pdev->spi) { if (!pdev->spi) {
return -ENODEV; return -ENODEV;
} }
#endif
return 0; return 0;
} }
@ -648,10 +726,10 @@ int dsa_hw_init(struct ksz8794_data *pdev)
/* Hard reset */ /* Hard reset */
#if DT_INST_NODE_HAS_PROP(0, reset_gpios) #if DT_INST_NODE_HAS_PROP(0, reset_gpios)
dsa_ksz8794_gpio_reset(pdev); dsa_ksz8794_gpio_reset(pdev);
#endif
/* Time needed for KSZ8794 to completely power up (100ms) */ /* Time needed for chip to completely power up (100ms) */
k_busy_wait(100000); k_busy_wait(KSZ8XXX_HARD_RESET_WAIT);
#endif
/* Configure communication bus */ /* Configure communication bus */
rc = dsa_ksz8794_configure_bus(pdev); rc = dsa_ksz8794_configure_bus(pdev);
@ -695,7 +773,12 @@ static void dsa_delayed_work(struct k_work *item)
bool link_state; bool link_state;
uint8_t i; uint8_t i;
for (i = KSZ8794_PORT1; i < KSZ8794_CPU_PORT; i++) { for (i = KSZ8XXX_FIRST_PORT; i <= KSZ8XXX_LAST_PORT; i++) {
/* Skip Switch <-> CPU Port */
if (i == KSZ8XXX_CPU_PORT) {
continue;
}
link_state = dsa_ksz8794_port_link_status(pdev, i); link_state = dsa_ksz8794_port_link_status(pdev, i);
if (link_state && !context->link_up[i]) { if (link_state && !context->link_up[i]) {
LOG_INF("DSA port: %d link UP!", i); LOG_INF("DSA port: %d link UP!", i);
@ -712,9 +795,9 @@ static void dsa_delayed_work(struct k_work *item)
int dsa_port_init(const struct device *dev) int dsa_port_init(const struct device *dev)
{ {
struct ksz8794_data *data = PRV_DATA(DEV_DATA(dev)); struct ksz8794_data *pdev = PRV_DATA(DEV_DATA(dev));
dsa_hw_init(data); dsa_hw_init(pdev);
return 0; return 0;
} }
@ -777,8 +860,8 @@ static int dsa_ksz8794_get_mac_table_entry(int switch_id, uint8_t *buf,
return 0; return 0;
} }
#if defined(CONFIG_DSA_KSZ8794_TAIL_TAGGING) #if defined(DSA_KSZ_TAIL_TAGGING)
#define DSA_KSZ8795_TAIL_TAG_OVERRIDE BIT(6) #define DSA_KSZ8795_TAIL_TAG_OVRD BIT(6)
#define DSA_KSZ8795_TAIL_TAG_LOOKUP BIT(7) #define DSA_KSZ8795_TAIL_TAG_LOOKUP BIT(7)
#define DSA_KSZ8794_EGRESS_TAG_LEN 1 #define DSA_KSZ8794_EGRESS_TAG_LEN 1
@ -989,7 +1072,7 @@ static struct dsa_api dsa_api_f = {
.switch_write = dsa_ksz8794_sw_write_reg, .switch_write = dsa_ksz8794_sw_write_reg,
.switch_set_mac_table_entry = dsa_ksz8794_set_mac_table_entry, .switch_set_mac_table_entry = dsa_ksz8794_set_mac_table_entry,
.switch_get_mac_table_entry = dsa_ksz8794_get_mac_table_entry, .switch_get_mac_table_entry = dsa_ksz8794_get_mac_table_entry,
#if defined(CONFIG_DSA_KSZ8794_TAIL_TAGGING) #if defined(DSA_KSZ_TAIL_TAGGING)
.dsa_xmit_pkt = dsa_ksz8794_xmit_pkt, .dsa_xmit_pkt = dsa_ksz8794_xmit_pkt,
.dsa_get_iface = dsa_ksz8794_get_iface, .dsa_get_iface = dsa_ksz8794_get_iface,
#endif #endif

View file

@ -243,6 +243,7 @@
#define KSZ8794_STAT2_LINK_GOOD BIT(5) #define KSZ8794_STAT2_LINK_GOOD BIT(5)
#define KSZ8794_CHIP_ID0_ID_DEFAULT 0x87 #define KSZ8794_CHIP_ID0_ID_DEFAULT 0x87
#define KSZ8794_CHIP_ID1_ID_DEFAULT 0x61
#define KSZ8794_PWR_MGNT_MODE_SOFT_DOWN BIT(4) #define KSZ8794_PWR_MGNT_MODE_SOFT_DOWN BIT(4)
#define KSZ8794_GLOBAL_CTRL20_LOWSPEED_MASK 0x07 #define KSZ8794_GLOBAL_CTRL20_LOWSPEED_MASK 0x07
@ -260,12 +261,11 @@ enum {
KSZ8794_PORT1 = 0, KSZ8794_PORT1 = 0,
KSZ8794_PORT2, KSZ8794_PORT2,
KSZ8794_PORT3, KSZ8794_PORT3,
KSZ8794_PORT4,
/* SWITCH <-> CPU port */ /* SWITCH <-> CPU port */
KSZ8794_PORT4 = 3, KSZ8794_PORT5,
}; };
#define KSZ8794_CPU_PORT KSZ8794_PORT4
#define KSZ8794_REG_IND_DATA_8 0x70 #define KSZ8794_REG_IND_DATA_8 0x70
#define KSZ8794_REG_IND_DATA_7 0x71 #define KSZ8794_REG_IND_DATA_7 0x71
#define KSZ8794_REG_IND_DATA_6 0x72 #define KSZ8794_REG_IND_DATA_6 0x72
@ -280,6 +280,35 @@ enum {
#define KSZ8794_REG_IND_CTRL_1 0x6F #define KSZ8794_REG_IND_CTRL_1 0x6F
#define KSZ8794_STATIC_MAC_TABLE_VALID BIT(5) #define KSZ8794_STATIC_MAC_TABLE_VALID BIT(5)
#define KSZ8794_STATIC_MAC_TABLE_OVERRIDE BIT(6) #define KSZ8794_STATIC_MAC_TABLE_OVRD BIT(6)
#define KSZ8XXX_CHIP_ID0 KSZ8794_CHIP_ID0
#define KSZ8XXX_CHIP_ID1 KSZ8794_CHIP_ID1
#define KSZ8XXX_CHIP_ID0_ID_DEFAULT KSZ8794_CHIP_ID0_ID_DEFAULT
#define KSZ8XXX_CHIP_ID1_ID_DEFAULT KSZ8794_CHIP_ID1_ID_DEFAULT
#define KSZ8XXX_FIRST_PORT KSZ8794_PORT1
#define KSZ8XXX_LAST_PORT KSZ8794_PORT5
#define KSZ8XXX_CPU_PORT KSZ8794_PORT5
#define KSZ8XXX_REG_IND_CTRL_0 KSZ8794_REG_IND_CTRL_0
#define KSZ8XXX_REG_IND_CTRL_1 KSZ8794_REG_IND_CTRL_1
#define KSZ8XXX_REG_IND_DATA_8 KSZ8794_REG_IND_DATA_8
#define KSZ8XXX_REG_IND_DATA_7 KSZ8794_REG_IND_DATA_7
#define KSZ8XXX_REG_IND_DATA_6 KSZ8794_REG_IND_DATA_6
#define KSZ8XXX_REG_IND_DATA_5 KSZ8794_REG_IND_DATA_5
#define KSZ8XXX_REG_IND_DATA_4 KSZ8794_REG_IND_DATA_4
#define KSZ8XXX_REG_IND_DATA_3 KSZ8794_REG_IND_DATA_3
#define KSZ8XXX_REG_IND_DATA_2 KSZ8794_REG_IND_DATA_2
#define KSZ8XXX_REG_IND_DATA_1 KSZ8794_REG_IND_DATA_1
#define KSZ8XXX_REG_IND_DATA_0 KSZ8794_REG_IND_DATA_0
#define KSZ8XXX_STATIC_MAC_TABLE_VALID KSZ8794_STATIC_MAC_TABLE_VALID
#define KSZ8XXX_STATIC_MAC_TABLE_OVRD KSZ8794_STATIC_MAC_TABLE_OVRD
#define KSZ8XXX_STAT2_LINK_GOOD KSZ8794_STAT2_LINK_GOOD
#define KSZ8XXX_RESET_REG KSZ8794_PD_MGMT_CTRL1
#define KSZ8XXX_RESET_SET KSZ8794_PWR_MGNT_MODE_SOFT_DOWN
#define KSZ8XXX_RESET_CLEAR 0
#define KSZ8XXX_STAT2_PORTn KSZ8794_STAT2_PORTn
#define KSZ8XXX_SPI_CMD_RD KSZ8794_SPI_CMD_RD
#define KSZ8XXX_SPI_CMD_WR KSZ8794_SPI_CMD_WR
#define KSZ8XXX_SOFT_RESET_DURATION 1000
#define KSZ8XXX_HARD_RESET_WAIT 10000
#endif /* __DSA_KSZ8794_H__ */ #endif /* __DSA_KSZ8794_H__ */

View file

@ -0,0 +1,165 @@
/*
* Copyright (c) 2021 IP-Logix Inc.
* Arvin Farahmand <arvinf@ip-logix.com>
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DSA_KSZ8863_H__
#define __DSA_KSZ8863_H__
/* SPI commands */
#define KSZ8863_SPI_CMD_WR (BIT(6))
#define KSZ8863_SPI_CMD_RD (BIT(6) | BIT(5))
/* PHY registers */
#define KSZ8863_BMCR 0x00
#define KSZ8863_BMSR 0x01
#define KSZ8863_PHYID1 0x02
#define KSZ8863_PHYID2 0x03
#define KSZ8863_ANAR 0x04
#define KSZ8863_ANLPAR 0x05
#define KSZ8863_LINKMD 0x1D
#define KSZ8863_PHYSCS 0x1F
/* SWITCH registers */
#define KSZ8863_CHIP_ID0 0x00
#define KSZ8863_CHIP_ID1 0x01
#define KSZ8863_GLOBAL_CTRL0 0x02
#define KSZ8863_GLOBAL_CTRL1 0x03
#define KSZ8863_GLOBAL_CTRL2 0x04
#define KSZ8863_GLOBAL_CTRL3 0x05
#define KSZ8863_GLOBAL_CTRL4 0x06
#define KSZ8863_GLOBAL_CTRL5 0x07
#define KSZ8863_GLOBAL_CTRL9 0x0B
#define KSZ8863_GLOBAL_CTRL10 0x0C
#define KSZ8863_GLOBAL_CTRL11 0x0D
#define KSZ8863_GLOBAL_CTRL12 0x0E
#define KSZ8863_GLOBAL_CTRL13 0x0F
#define KSZ8863_PORT1_CTRL0 0x10
#define KSZ8863_PORT1_CTRL1 0x11
#define KSZ8863_PORT1_CTRL2 0x12
#define KSZ8863_PORT1_CTRL3 0x13
#define KSZ8863_PORT1_CTRL4 0x14
#define KSZ8863_PORT1_CTRL5 0x15
#define KSZ8863_PORT1_Q0_IG_LIMIT 0x16
#define KSZ8863_PORT1_Q1_IG_LIMIT 0x17
#define KSZ8863_PORT1_Q2_IG_LIMIT 0x18
#define KSZ8863_PORT1_Q3_IG_LIMIT 0x19
#define KSZ8863_PORT1_PHY_CTRL 0x1A
#define KSZ8863_PORT1_LINKMD 0x1B
#define KSZ8863_PORT1_CTRL12 0x1C
#define KSZ8863_PORT1_CTRL13 0x1D
#define KSZ8863_PORT1_STAT0 0x1E
#define KSZ8863_PORT1_STAT1 0x1F
#define KSZ8863_PORT2_CTRL0 0x20
#define KSZ8863_PORT2_CTRL1 0x21
#define KSZ8863_PORT2_CTRL2 0x22
#define KSZ8863_PORT2_CTRL3 0x23
#define KSZ8863_PORT2_CTRL4 0x24
#define KSZ8863_PORT2_CTRL5 0x25
#define KSZ8863_PORT2_Q0_IG_LIMIT 0x26
#define KSZ8863_PORT2_Q1_IG_LIMIT 0x27
#define KSZ8863_PORT2_Q2_IG_LIMIT 0x28
#define KSZ8863_PORT2_Q3_IG_LIMIT 0x29
#define KSZ8863_PORT2_PHY_CTRL 0x2A
#define KSZ8863_PORT2_LINKMD 0x2B
#define KSZ8863_PORT2_CTRL12 0x2C
#define KSZ8863_PORT2_CTRL13 0x2D
#define KSZ8863_PORT2_STAT0 0x2E
#define KSZ8863_PORT2_STAT1 0x2F
#define KSZ8863_PORT3_CTRL0 0x30
#define KSZ8863_PORT3_CTRL1 0x31
#define KSZ8863_PORT3_CTRL2 0x32
#define KSZ8863_PORT3_CTRL3 0x33
#define KSZ8863_PORT3_CTRL4 0x34
#define KSZ8863_PORT3_CTRL5 0x35
#define KSZ8863_PORT3_Q0_IG_LIMIT 0x36
#define KSZ8863_PORT3_Q1_IG_LIMIT 0x37
#define KSZ8863_PORT3_Q2_IG_LIMIT 0x38
#define KSZ8863_PORT3_Q3_IG_LIMIT 0x39
#define KSZ8863_PORT3_STAT1 0x3F
#define KSZ8863_MAC_ADDR0 0x70
#define KSZ8863_MAC_ADDR1 0x71
#define KSZ8863_MAC_ADDR2 0x72
#define KSZ8863_MAC_ADDR3 0x73
#define KSZ8863_MAC_ADDR4 0x74
#define KSZ8863_MAC_ADDR5 0x75
#define KSZ8863_USER0 0x76
#define KSZ8863_USER1 0x77
#define KSZ8863_USER2 0x78
#define KSZ8863_GLOBAL_CTRL1_TAIL_TAG_EN BIT(6)
#define KSZ8863_GLOBAL_CTRL2_LEG_MAX_PKT_SIZ_CHK_ENA BIT(1)
#define KSZ8863_CTRL2_PORTn(n) (0x12 + ((n) * 0x10))
#define KSZ8863_CTRL2_TRANSMIT_EN BIT(2)
#define KSZ8863_CTRL2_RECEIVE_EN BIT(1)
#define KSZ8863_CTRL2_LEARNING_DIS BIT(0)
#define KSZ8863_STAT2_PORTn(n) (0x1E + ((n) * 0x10))
#define KSZ8863_STAT2_LINK_GOOD BIT(5)
#define KSZ8863_CHIP_ID0_ID_DEFAULT 0x88
#define KSZ8863_CHIP_ID1_ID_DEFAULT 0x31
#define KSZ8863_REGISTER_67 0x43
#define KSZ8863_SOFTWARE_RESET_SET BIT(4)
#define KSZ8863_SOFTWARE_RESET_CLEAR 0
enum {
/* LAN ports for the ksz8863 switch */
KSZ8863_PORT1 = 0,
KSZ8863_PORT2,
/* SWITCH <-> CPU port */
KSZ8863_PORT3,
};
#define KSZ8863_REG_IND_CTRL_0 0x79
#define KSZ8863_REG_IND_CTRL_1 0x7A
#define KSZ8863_REG_IND_DATA_8 0x7B
#define KSZ8863_REG_IND_DATA_7 0x7C
#define KSZ8863_REG_IND_DATA_6 0x7D
#define KSZ8863_REG_IND_DATA_5 0x7E
#define KSZ8863_REG_IND_DATA_4 0x7F
#define KSZ8863_REG_IND_DATA_3 0x80
#define KSZ8863_REG_IND_DATA_2 0x81
#define KSZ8863_REG_IND_DATA_1 0x82
#define KSZ8863_REG_IND_DATA_0 0x83
#define KSZ8863_STATIC_MAC_TABLE_VALID BIT(3)
#define KSZ8863_STATIC_MAC_TABLE_OVRD BIT(4)
#define KSZ8863_STATIC_MAC_TABLE_USE_FID BIT(5)
#define KSZ8XXX_CHIP_ID0 KSZ8863_CHIP_ID0
#define KSZ8XXX_CHIP_ID1 KSZ8863_CHIP_ID1
#define KSZ8XXX_CHIP_ID0_ID_DEFAULT KSZ8863_CHIP_ID0_ID_DEFAULT
#define KSZ8XXX_CHIP_ID1_ID_DEFAULT KSZ8863_CHIP_ID1_ID_DEFAULT
#define KSZ8XXX_FIRST_PORT KSZ8863_PORT1
#define KSZ8XXX_LAST_PORT KSZ8863_PORT3
#define KSZ8XXX_CPU_PORT KSZ8863_PORT3
#define KSZ8XXX_REG_IND_CTRL_0 KSZ8863_REG_IND_CTRL_0
#define KSZ8XXX_REG_IND_CTRL_1 KSZ8863_REG_IND_CTRL_1
#define KSZ8XXX_REG_IND_DATA_8 KSZ8863_REG_IND_DATA_8
#define KSZ8XXX_REG_IND_DATA_7 KSZ8863_REG_IND_DATA_7
#define KSZ8XXX_REG_IND_DATA_6 KSZ8863_REG_IND_DATA_6
#define KSZ8XXX_REG_IND_DATA_5 KSZ8863_REG_IND_DATA_5
#define KSZ8XXX_REG_IND_DATA_4 KSZ8863_REG_IND_DATA_4
#define KSZ8XXX_REG_IND_DATA_3 KSZ8863_REG_IND_DATA_3
#define KSZ8XXX_REG_IND_DATA_2 KSZ8863_REG_IND_DATA_2
#define KSZ8XXX_REG_IND_DATA_1 KSZ8863_REG_IND_DATA_1
#define KSZ8XXX_REG_IND_DATA_0 KSZ8863_REG_IND_DATA_0
#define KSZ8XXX_STATIC_MAC_TABLE_VALID KSZ8863_STATIC_MAC_TABLE_VALID
#define KSZ8XXX_STATIC_MAC_TABLE_OVRD KSZ8863_STATIC_MAC_TABLE_OVRD
#define KSZ8XXX_STAT2_LINK_GOOD KSZ8863_STAT2_LINK_GOOD
#define KSZ8XXX_RESET_REG KSZ8863_REGISTER_67
#define KSZ8XXX_RESET_SET KSZ8863_SOFTWARE_RESET_SET
#define KSZ8XXX_RESET_CLEAR KSZ8863_SOFTWARE_RESET_CLEAR
#define KSZ8XXX_STAT2_PORTn KSZ8863_STAT2_PORTn
#define KSZ8XXX_SPI_CMD_RD KSZ8863_SPI_CMD_RD
#define KSZ8XXX_SPI_CMD_WR KSZ8863_SPI_CMD_WR
#define KSZ8XXX_SOFT_RESET_DURATION 1000
#define KSZ8XXX_HARD_RESET_WAIT 10000
#endif /* __DSA_KSZ8863_H__ */

View file

@ -6,33 +6,8 @@ description: |
compatible: "microchip,ksz8794" compatible: "microchip,ksz8794"
include: [spi-device.yaml] include: [microchip_dsa.yaml]
properties: properties:
dsa-master-port:
type: phandle
required: false
description: Phandle to master port.
dsa-slave-ports:
type: int
required: false
description: Number of slave ports on the switch
spi-cpha:
type: boolean
required: false
description: |
Set to indicate phase starts with asserted half-phase (CPHA=1).
For this driver using this property requires also using cpol.
spi-cpol:
type: boolean
required: false
description: |
Set to indicate clock leading edge is falling (CPOL=1).
For this driver using this property requires also using cpha.
reset-gpios:
type: phandle-array
required: false
description: |
The pin is asserted for 10ms during boot to reset the KSZ8794.
workaround: workaround:
type: int type: int
required: false required: false
@ -58,15 +33,3 @@ properties:
- 20 - 20
- 24 - 24
- 28 - 28
child-binding:
description: Properties of slave port
properties:
label:
type: string
required: true
local-mac-address:
type: uint8-array
required: false
description: |
Specifies the MAC address that was assigned to the port

View file

@ -0,0 +1,9 @@
# Copyright (c) 2021 IP-Logix Inc.
# SPDX-License-Identifier: Apache-2.0
description: |
KSZ8863 ethernet switch
compatible: "microchip,ksz8863"
include: [microchip_dsa.yaml]

View file

@ -0,0 +1,45 @@
# Copyright (c) 2020 DENX Software Engineering GmbH
# SPDX-License-Identifier: Apache-2.0
description: |
DSA Device
include: [spi-device.yaml]
properties:
dsa-master-port:
type: phandle
required: false
description: Phandle to master port.
dsa-slave-ports:
type: int
required: false
description: Number of slave ports on the switch
spi-cpha:
type: boolean
required: false
description: |
Set to indicate phase starts with asserted half-phase (CPHA=1).
For this driver using this property requires also using cpol.
spi-cpol:
type: boolean
required: false
description: |
Set to indicate clock leading edge is falling (CPOL=1).
For this driver using this property requires also using cpha.
reset-gpios:
type: phandle-array
required: false
description: |
The pin is asserted for 10ms during boot to reset the KSZ8794.
child-binding:
description: Properties of slave port
properties:
label:
type: string
required: true
local-mac-address:
type: uint8-array
required: false
description: |
Specifies the MAC address that was assigned to the port

View file

@ -28,7 +28,7 @@
* Size of the DSA TAG: * Size of the DSA TAG:
* - KSZ8794 - 1 byte * - KSZ8794 - 1 byte
*/ */
#if defined(CONFIG_DSA_KSZ8794) && defined(CONFIG_DSA_KSZ8794_TAIL_TAGGING) #if defined(CONFIG_DSA_KSZ8794) && defined(DSA_KSZ_TAIL_TAGGING)
#define DSA_TAG_SIZE 1 #define DSA_TAG_SIZE 1
#else #else
#define DSA_TAG_SIZE 0 #define DSA_TAG_SIZE 0