Skip to content

Commit

Permalink
Merge branch 'part-2-of-sja1105-dsa-driver-preparation-for-new-switch…
Browse files Browse the repository at this point in the history
…-introduction-sja1110'

Vladimir Oltean says:

====================
Part 2 of SJA1105 DSA driver preparation for new switch introduction (SJA1110)

This series is a continuation of:
https://patchwork.kernel.org/project/netdevbpf/cover/[email protected]/

even though it isn't the first time these patches are submitted (they
were part of the group previously called "Add NXP SJA1110 support to the
sja1105 DSA driver"):
https://patchwork.kernel.org/project/netdevbpf/cover/[email protected]/

but I broke that up again since these patches are already reviewed, for
the most part. There are no changes compared to v2 and v1.

This series of patches contains:

- an adaptation of the driver to the new "ethernet-ports" OF node name
- an adaptation of the driver to support more than 1 SGMII port
- a generalization of the supported phy_interface_t values per port
- an adaptation to encode SPEED_10, SPEED_100, SPEED_1000 into the
  hardware registers differently depending on switch revision
- a consolidation of the PHY interface type used for RGMII and another
  one for the API exposed for sja1105_dynamic_config_read()
====================

Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
kuba-moo committed Jun 1, 2021
2 parents 44fdd2e + 96c85f5 commit e3d8178
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 132 deletions.
24 changes: 16 additions & 8 deletions drivers/net/dsa/sja1105/sja1105.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ struct sja1105_regs {
u64 rgu;
u64 vl_status;
u64 config;
u64 sgmii;
u64 rmii_pll1;
u64 ptppinst;
u64 ptppindur;
Expand All @@ -73,6 +72,15 @@ struct sja1105_regs {
u64 stats[__MAX_SJA1105_STATS_AREA][SJA1105_MAX_NUM_PORTS];
};

enum {
SJA1105_SPEED_AUTO,
SJA1105_SPEED_10MBPS,
SJA1105_SPEED_100MBPS,
SJA1105_SPEED_1000MBPS,
SJA1105_SPEED_2500MBPS,
SJA1105_SPEED_MAX,
};

struct sja1105_info {
u64 device_id;
/* Needed for distinction between P and R, and between Q and S
Expand Down Expand Up @@ -112,6 +120,12 @@ struct sja1105_info {
enum packing_op op);
int (*clocking_setup)(struct sja1105_private *priv);
const char *name;
bool supports_mii[SJA1105_MAX_NUM_PORTS];
bool supports_rmii[SJA1105_MAX_NUM_PORTS];
bool supports_rgmii[SJA1105_MAX_NUM_PORTS];
bool supports_sgmii[SJA1105_MAX_NUM_PORTS];
bool supports_2500basex[SJA1105_MAX_NUM_PORTS];
const u64 port_speed[SJA1105_SPEED_MAX];
};

enum sja1105_key_type {
Expand Down Expand Up @@ -211,6 +225,7 @@ struct sja1105_private {
struct sja1105_static_config static_config;
bool rgmii_rx_delay[SJA1105_MAX_NUM_PORTS];
bool rgmii_tx_delay[SJA1105_MAX_NUM_PORTS];
phy_interface_t phy_mode[SJA1105_MAX_NUM_PORTS];
bool best_effort_vlan_filtering;
unsigned long learn_ena;
unsigned long ucast_egress_floods;
Expand Down Expand Up @@ -309,13 +324,6 @@ typedef enum {
XMII_MODE_SGMII = 3,
} sja1105_phy_interface_t;

typedef enum {
SJA1105_SPEED_10MBPS = 3,
SJA1105_SPEED_100MBPS = 2,
SJA1105_SPEED_1000MBPS = 1,
SJA1105_SPEED_AUTO = 0,
} sja1105_speed_t;

int sja1105pqrs_setup_rgmii_delay(const void *ctx, int port);
int sja1105_clocking_setup_port(struct sja1105_private *priv, int port);
int sja1105_clocking_setup(struct sja1105_private *priv);
Expand Down
29 changes: 10 additions & 19 deletions drivers/net/dsa/sja1105/sja1105_clocking.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ sja1105_cgu_pll_control_packing(void *buf, struct sja1105_cgu_pll_ctrl *cmd,
}

static int sja1105_cgu_rgmii_tx_clk_config(struct sja1105_private *priv,
int port, sja1105_speed_t speed)
int port, u64 speed)
{
const struct sja1105_regs *regs = priv->info->regs;
struct sja1105_cgu_mii_ctrl txc;
Expand All @@ -338,7 +338,7 @@ static int sja1105_cgu_rgmii_tx_clk_config(struct sja1105_private *priv,
if (regs->rgmii_tx_clk[port] == SJA1105_RSV_ADDR)
return 0;

if (speed == SJA1105_SPEED_1000MBPS) {
if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) {
clksrc = CLKSRC_PLL0;
} else {
int clk_sources[] = {CLKSRC_IDIV0, CLKSRC_IDIV1, CLKSRC_IDIV2,
Expand Down Expand Up @@ -524,35 +524,31 @@ static int sja1105_rgmii_clocking_setup(struct sja1105_private *priv, int port,
{
struct device *dev = priv->ds->dev;
struct sja1105_mac_config_entry *mac;
sja1105_speed_t speed;
u64 speed;
int rc;

mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries;
speed = mac[port].speed;

dev_dbg(dev, "Configuring port %d RGMII at speed %dMbps\n",
dev_dbg(dev, "Configuring port %d RGMII at speed %lldMbps\n",
port, speed);

switch (speed) {
case SJA1105_SPEED_1000MBPS:
if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) {
/* 1000Mbps, IDIV disabled (125 MHz) */
rc = sja1105_cgu_idiv_config(priv, port, false, 1);
break;
case SJA1105_SPEED_100MBPS:
} else if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS]) {
/* 100Mbps, IDIV enabled, divide by 1 (25 MHz) */
rc = sja1105_cgu_idiv_config(priv, port, true, 1);
break;
case SJA1105_SPEED_10MBPS:
} else if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS]) {
/* 10Mbps, IDIV enabled, divide by 10 (2.5 MHz) */
rc = sja1105_cgu_idiv_config(priv, port, true, 10);
break;
case SJA1105_SPEED_AUTO:
} else if (speed == priv->info->port_speed[SJA1105_SPEED_AUTO]) {
/* Skip CGU configuration if there is no speed available
* (e.g. link is not established yet)
*/
dev_dbg(dev, "Speed not available, skipping CGU config\n");
return 0;
default:
} else {
rc = -EINVAL;
}

Expand All @@ -570,14 +566,9 @@ static int sja1105_rgmii_clocking_setup(struct sja1105_private *priv, int port,
dev_err(dev, "Failed to configure Tx pad registers\n");
return rc;
}

if (!priv->info->setup_rgmii_delay)
return 0;
/* The role has no hardware effect for RGMII. However we use it as
* a proxy for this interface being a MAC-to-MAC connection, with
* the RGMII internal delays needing to be applied by us.
*/
if (role == XMII_MAC)
return 0;

return priv->info->setup_rgmii_delay(priv, port);
}
Expand Down
15 changes: 8 additions & 7 deletions drivers/net/dsa/sja1105/sja1105_dynamic_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
* on its ENTRY portion, as a result of a SPI write command.
* Only the TCAM-based FDB table on SJA1105 P/Q/R/S supports
* this.
* OP_VALID_ANYWAY: Reading some tables through the dynamic config
* interface is possible even if the VALIDENT bit is not
* set in the writeback. So don't error out in that case.
* - .max_entry_count: The number of entries, counting from zero, that can be
* reconfigured through the dynamic interface. If a static
* table can be reconfigured at all dynamically, this
Expand Down Expand Up @@ -651,6 +654,7 @@ static size_t sja1105pqrs_cbs_entry_packing(void *buf, void *entry_ptr,
#define OP_WRITE BIT(1)
#define OP_DEL BIT(2)
#define OP_SEARCH BIT(3)
#define OP_VALID_ANYWAY BIT(4)

/* SJA1105E/T: First generation */
const struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
Expand All @@ -673,7 +677,7 @@ const struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
[BLK_IDX_MGMT_ROUTE] = {
.entry_packing = sja1105et_mgmt_route_entry_packing,
.cmd_packing = sja1105et_mgmt_route_cmd_packing,
.access = (OP_READ | OP_WRITE),
.access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY),
.max_entry_count = SJA1105_NUM_PORTS,
.packed_size = SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD,
.addr = 0x20,
Expand Down Expand Up @@ -757,7 +761,7 @@ const struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {
[BLK_IDX_MGMT_ROUTE] = {
.entry_packing = sja1105pqrs_mgmt_route_entry_packing,
.cmd_packing = sja1105pqrs_mgmt_route_cmd_packing,
.access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH),
.access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH | OP_VALID_ANYWAY),
.max_entry_count = SJA1105_NUM_PORTS,
.packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD,
.addr = 0x24,
Expand Down Expand Up @@ -911,11 +915,8 @@ int sja1105_dynamic_config_read(struct sja1105_private *priv,

cmd = (struct sja1105_dyn_cmd) {0};
ops->cmd_packing(packed_buf, &cmd, UNPACK);
/* UM10944: [valident] will always be found cleared
* during a read access with MGMTROUTE set.
* So don't error out in that case.
*/
if (!cmd.valident && blk_idx != BLK_IDX_MGMT_ROUTE)

if (!cmd.valident && !(ops->access & OP_VALID_ANYWAY))
return -ENOENT;
cpu_relax();
} while (cmd.valid && --retries);
Expand Down
Loading

0 comments on commit e3d8178

Please sign in to comment.