Commit d9d15a66 authored by David S. Miller's avatar David S. Miller

Merge branch 'sja1105-sja1110-prep'

Vladimir Oltean says:

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

This series contains refactoring patches which are necessary before the
support for the new NXP SJA1110 switch can be introduced in this driver.

As far as this series is concerned, here is the list of major changes
introduced with the SJA1110:
- 11 ports vs 5
- port 0 goes to the internal microcontroller, so it is unused as far as
  DSA is concerned
- the Clock Generation Unit does not need any configuration for
  setting up the PLLs for MII/RMII/RGMII
- the L2 Policing Table contains multicast policers too, not just
  broadcast and per-traffic class. These must be minimally initialized.
- more frame buffers
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents feeb3712 1bf658ee
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "sja1105_static_config.h" #include "sja1105_static_config.h"
#define SJA1105_NUM_PORTS 5 #define SJA1105_NUM_PORTS 5
#define SJA1105_MAX_NUM_PORTS SJA1105_NUM_PORTS
#define SJA1105_NUM_TC 8 #define SJA1105_NUM_TC 8
#define SJA1105ET_FDB_BIN_SIZE 4 #define SJA1105ET_FDB_BIN_SIZE 4
/* The hardware value is in multiples of 10 ms. /* The hardware value is in multiples of 10 ms.
...@@ -57,19 +58,19 @@ struct sja1105_regs { ...@@ -57,19 +58,19 @@ struct sja1105_regs {
u64 ptpclkcorp; u64 ptpclkcorp;
u64 ptpsyncts; u64 ptpsyncts;
u64 ptpschtm; u64 ptpschtm;
u64 ptpegr_ts[SJA1105_NUM_PORTS]; u64 ptpegr_ts[SJA1105_MAX_NUM_PORTS];
u64 pad_mii_tx[SJA1105_NUM_PORTS]; u64 pad_mii_tx[SJA1105_MAX_NUM_PORTS];
u64 pad_mii_rx[SJA1105_NUM_PORTS]; u64 pad_mii_rx[SJA1105_MAX_NUM_PORTS];
u64 pad_mii_id[SJA1105_NUM_PORTS]; u64 pad_mii_id[SJA1105_MAX_NUM_PORTS];
u64 cgu_idiv[SJA1105_NUM_PORTS]; u64 cgu_idiv[SJA1105_MAX_NUM_PORTS];
u64 mii_tx_clk[SJA1105_NUM_PORTS]; u64 mii_tx_clk[SJA1105_MAX_NUM_PORTS];
u64 mii_rx_clk[SJA1105_NUM_PORTS]; u64 mii_rx_clk[SJA1105_MAX_NUM_PORTS];
u64 mii_ext_tx_clk[SJA1105_NUM_PORTS]; u64 mii_ext_tx_clk[SJA1105_MAX_NUM_PORTS];
u64 mii_ext_rx_clk[SJA1105_NUM_PORTS]; u64 mii_ext_rx_clk[SJA1105_MAX_NUM_PORTS];
u64 rgmii_tx_clk[SJA1105_NUM_PORTS]; u64 rgmii_tx_clk[SJA1105_MAX_NUM_PORTS];
u64 rmii_ref_clk[SJA1105_NUM_PORTS]; u64 rmii_ref_clk[SJA1105_MAX_NUM_PORTS];
u64 rmii_ext_tx_clk[SJA1105_NUM_PORTS]; u64 rmii_ext_tx_clk[SJA1105_MAX_NUM_PORTS];
u64 stats[__MAX_SJA1105_STATS_AREA][SJA1105_NUM_PORTS]; u64 stats[__MAX_SJA1105_STATS_AREA][SJA1105_MAX_NUM_PORTS];
}; };
struct sja1105_info { struct sja1105_info {
...@@ -89,6 +90,7 @@ struct sja1105_info { ...@@ -89,6 +90,7 @@ struct sja1105_info {
*/ */
int ptpegr_ts_bytes; int ptpegr_ts_bytes;
int num_cbs_shapers; int num_cbs_shapers;
int max_frame_mem;
const struct sja1105_dynamic_table_ops *dyn_ops; const struct sja1105_dynamic_table_ops *dyn_ops;
const struct sja1105_table_ops *static_ops; const struct sja1105_table_ops *static_ops;
const struct sja1105_regs *regs; const struct sja1105_regs *regs;
...@@ -108,6 +110,7 @@ struct sja1105_info { ...@@ -108,6 +110,7 @@ struct sja1105_info {
const unsigned char *addr, u16 vid); const unsigned char *addr, u16 vid);
void (*ptp_cmd_packing)(u8 *buf, struct sja1105_ptp_cmd *cmd, void (*ptp_cmd_packing)(u8 *buf, struct sja1105_ptp_cmd *cmd,
enum packing_op op); enum packing_op op);
int (*clocking_setup)(struct sja1105_private *priv);
const char *name; const char *name;
}; };
...@@ -206,8 +209,8 @@ enum sja1105_vlan_state { ...@@ -206,8 +209,8 @@ enum sja1105_vlan_state {
struct sja1105_private { struct sja1105_private {
struct sja1105_static_config static_config; struct sja1105_static_config static_config;
bool rgmii_rx_delay[SJA1105_NUM_PORTS]; bool rgmii_rx_delay[SJA1105_MAX_NUM_PORTS];
bool rgmii_tx_delay[SJA1105_NUM_PORTS]; bool rgmii_tx_delay[SJA1105_MAX_NUM_PORTS];
bool best_effort_vlan_filtering; bool best_effort_vlan_filtering;
unsigned long learn_ena; unsigned long learn_ena;
unsigned long ucast_egress_floods; unsigned long ucast_egress_floods;
...@@ -220,7 +223,7 @@ struct sja1105_private { ...@@ -220,7 +223,7 @@ struct sja1105_private {
struct list_head dsa_8021q_vlans; struct list_head dsa_8021q_vlans;
struct list_head bridge_vlans; struct list_head bridge_vlans;
struct sja1105_flow_block flow_block; struct sja1105_flow_block flow_block;
struct sja1105_port ports[SJA1105_NUM_PORTS]; struct sja1105_port ports[SJA1105_MAX_NUM_PORTS];
/* Serializes transmission of management frames so that /* Serializes transmission of management frames so that
* the switch doesn't confuse them with one another. * the switch doesn't confuse them with one another.
*/ */
......
...@@ -110,6 +110,9 @@ static int sja1105_cgu_idiv_config(struct sja1105_private *priv, int port, ...@@ -110,6 +110,9 @@ static int sja1105_cgu_idiv_config(struct sja1105_private *priv, int port,
struct sja1105_cgu_idiv idiv; struct sja1105_cgu_idiv idiv;
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0}; u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
if (regs->cgu_idiv[port] == SJA1105_RSV_ADDR)
return 0;
if (enabled && factor != 1 && factor != 10) { if (enabled && factor != 1 && factor != 10) {
dev_err(dev, "idiv factor must be 1 or 10\n"); dev_err(dev, "idiv factor must be 1 or 10\n");
return -ERANGE; return -ERANGE;
...@@ -159,6 +162,9 @@ static int sja1105_cgu_mii_tx_clk_config(struct sja1105_private *priv, ...@@ -159,6 +162,9 @@ static int sja1105_cgu_mii_tx_clk_config(struct sja1105_private *priv,
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0}; u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
int clksrc; int clksrc;
if (regs->mii_tx_clk[port] == SJA1105_RSV_ADDR)
return 0;
if (role == XMII_MAC) if (role == XMII_MAC)
clksrc = mac_clk_sources[port]; clksrc = mac_clk_sources[port];
else else
...@@ -188,6 +194,9 @@ sja1105_cgu_mii_rx_clk_config(struct sja1105_private *priv, int port) ...@@ -188,6 +194,9 @@ sja1105_cgu_mii_rx_clk_config(struct sja1105_private *priv, int port)
CLKSRC_MII4_RX_CLK, CLKSRC_MII4_RX_CLK,
}; };
if (regs->mii_rx_clk[port] == SJA1105_RSV_ADDR)
return 0;
/* Payload for packed_buf */ /* Payload for packed_buf */
mii_rx_clk.clksrc = clk_sources[port]; mii_rx_clk.clksrc = clk_sources[port];
mii_rx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */ mii_rx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
...@@ -212,6 +221,9 @@ sja1105_cgu_mii_ext_tx_clk_config(struct sja1105_private *priv, int port) ...@@ -212,6 +221,9 @@ sja1105_cgu_mii_ext_tx_clk_config(struct sja1105_private *priv, int port)
CLKSRC_IDIV4, CLKSRC_IDIV4,
}; };
if (regs->mii_ext_tx_clk[port] == SJA1105_RSV_ADDR)
return 0;
/* Payload for packed_buf */ /* Payload for packed_buf */
mii_ext_tx_clk.clksrc = clk_sources[port]; mii_ext_tx_clk.clksrc = clk_sources[port];
mii_ext_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */ mii_ext_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
...@@ -236,6 +248,9 @@ sja1105_cgu_mii_ext_rx_clk_config(struct sja1105_private *priv, int port) ...@@ -236,6 +248,9 @@ sja1105_cgu_mii_ext_rx_clk_config(struct sja1105_private *priv, int port)
CLKSRC_IDIV4, CLKSRC_IDIV4,
}; };
if (regs->mii_ext_rx_clk[port] == SJA1105_RSV_ADDR)
return 0;
/* Payload for packed_buf */ /* Payload for packed_buf */
mii_ext_rx_clk.clksrc = clk_sources[port]; mii_ext_rx_clk.clksrc = clk_sources[port];
mii_ext_rx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */ mii_ext_rx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
...@@ -320,6 +335,9 @@ static int sja1105_cgu_rgmii_tx_clk_config(struct sja1105_private *priv, ...@@ -320,6 +335,9 @@ static int sja1105_cgu_rgmii_tx_clk_config(struct sja1105_private *priv,
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0}; u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
int clksrc; int clksrc;
if (regs->rgmii_tx_clk[port] == SJA1105_RSV_ADDR)
return 0;
if (speed == SJA1105_SPEED_1000MBPS) { if (speed == SJA1105_SPEED_1000MBPS) {
clksrc = CLKSRC_PLL0; clksrc = CLKSRC_PLL0;
} else { } else {
...@@ -368,6 +386,9 @@ static int sja1105_rgmii_cfg_pad_tx_config(struct sja1105_private *priv, ...@@ -368,6 +386,9 @@ static int sja1105_rgmii_cfg_pad_tx_config(struct sja1105_private *priv,
struct sja1105_cfg_pad_mii pad_mii_tx = {0}; struct sja1105_cfg_pad_mii pad_mii_tx = {0};
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0}; u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
if (regs->pad_mii_tx[port] == SJA1105_RSV_ADDR)
return 0;
/* Payload */ /* Payload */
pad_mii_tx.d32_os = 3; /* TXD[3:2] output stage: */ pad_mii_tx.d32_os = 3; /* TXD[3:2] output stage: */
/* high noise/high speed */ /* high noise/high speed */
...@@ -394,6 +415,9 @@ static int sja1105_cfg_pad_rx_config(struct sja1105_private *priv, int port) ...@@ -394,6 +415,9 @@ static int sja1105_cfg_pad_rx_config(struct sja1105_private *priv, int port)
struct sja1105_cfg_pad_mii pad_mii_rx = {0}; struct sja1105_cfg_pad_mii pad_mii_rx = {0};
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0}; u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
if (regs->pad_mii_rx[port] == SJA1105_RSV_ADDR)
return 0;
/* Payload */ /* Payload */
pad_mii_rx.d32_ih = 0; /* RXD[3:2] input stage hysteresis: */ pad_mii_rx.d32_ih = 0; /* RXD[3:2] input stage hysteresis: */
/* non-Schmitt (default) */ /* non-Schmitt (default) */
...@@ -572,6 +596,9 @@ static int sja1105_cgu_rmii_ref_clk_config(struct sja1105_private *priv, ...@@ -572,6 +596,9 @@ static int sja1105_cgu_rmii_ref_clk_config(struct sja1105_private *priv,
CLKSRC_MII4_TX_CLK, CLKSRC_MII4_TX_CLK,
}; };
if (regs->rmii_ref_clk[port] == SJA1105_RSV_ADDR)
return 0;
/* Payload for packed_buf */ /* Payload for packed_buf */
ref_clk.clksrc = clk_sources[port]; ref_clk.clksrc = clk_sources[port];
ref_clk.autoblock = 1; /* Autoblock clk while changing clksrc */ ref_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
...@@ -589,6 +616,9 @@ sja1105_cgu_rmii_ext_tx_clk_config(struct sja1105_private *priv, int port) ...@@ -589,6 +616,9 @@ sja1105_cgu_rmii_ext_tx_clk_config(struct sja1105_private *priv, int port)
struct sja1105_cgu_mii_ctrl ext_tx_clk; struct sja1105_cgu_mii_ctrl ext_tx_clk;
u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0}; u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0};
if (regs->rmii_ext_tx_clk[port] == SJA1105_RSV_ADDR)
return 0;
/* Payload for packed_buf */ /* Payload for packed_buf */
ext_tx_clk.clksrc = CLKSRC_PLL1; ext_tx_clk.clksrc = CLKSRC_PLL1;
ext_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */ ext_tx_clk.autoblock = 1; /* Autoblock clk while changing clksrc */
...@@ -607,6 +637,9 @@ static int sja1105_cgu_rmii_pll_config(struct sja1105_private *priv) ...@@ -607,6 +637,9 @@ static int sja1105_cgu_rmii_pll_config(struct sja1105_private *priv)
struct device *dev = priv->ds->dev; struct device *dev = priv->ds->dev;
int rc; int rc;
if (regs->rmii_pll1 == SJA1105_RSV_ADDR)
return 0;
/* PLL1 must be enabled and output 50 Mhz. /* PLL1 must be enabled and output 50 Mhz.
* This is done by writing first 0x0A010941 to * This is done by writing first 0x0A010941 to
* the PLL_1_C register and then deasserting * the PLL_1_C register and then deasserting
...@@ -721,9 +754,10 @@ int sja1105_clocking_setup_port(struct sja1105_private *priv, int port) ...@@ -721,9 +754,10 @@ int sja1105_clocking_setup_port(struct sja1105_private *priv, int port)
int sja1105_clocking_setup(struct sja1105_private *priv) int sja1105_clocking_setup(struct sja1105_private *priv)
{ {
struct dsa_switch *ds = priv->ds;
int port, rc; int port, rc;
for (port = 0; port < SJA1105_NUM_PORTS; port++) { for (port = 0; port < ds->num_ports; port++) {
rc = sja1105_clocking_setup_port(priv, port); rc = sja1105_clocking_setup_port(priv, port);
if (rc < 0) if (rc < 0)
return rc; return rc;
......
...@@ -35,6 +35,7 @@ static int sja1105_setup_bcast_policer(struct sja1105_private *priv, ...@@ -35,6 +35,7 @@ static int sja1105_setup_bcast_policer(struct sja1105_private *priv,
{ {
struct sja1105_rule *rule = sja1105_rule_find(priv, cookie); struct sja1105_rule *rule = sja1105_rule_find(priv, cookie);
struct sja1105_l2_policing_entry *policing; struct sja1105_l2_policing_entry *policing;
struct dsa_switch *ds = priv->ds;
bool new_rule = false; bool new_rule = false;
unsigned long p; unsigned long p;
int rc; int rc;
...@@ -59,7 +60,7 @@ static int sja1105_setup_bcast_policer(struct sja1105_private *priv, ...@@ -59,7 +60,7 @@ static int sja1105_setup_bcast_policer(struct sja1105_private *priv,
policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries; policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries;
if (policing[(SJA1105_NUM_PORTS * SJA1105_NUM_TC) + port].sharindx != port) { if (policing[(ds->num_ports * SJA1105_NUM_TC) + port].sharindx != port) {
NL_SET_ERR_MSG_MOD(extack, NL_SET_ERR_MSG_MOD(extack,
"Port already has a broadcast policer"); "Port already has a broadcast policer");
rc = -EEXIST; rc = -EEXIST;
...@@ -71,8 +72,8 @@ static int sja1105_setup_bcast_policer(struct sja1105_private *priv, ...@@ -71,8 +72,8 @@ static int sja1105_setup_bcast_policer(struct sja1105_private *priv,
/* Make the broadcast policers of all ports attached to this block /* Make the broadcast policers of all ports attached to this block
* point to the newly allocated policer * point to the newly allocated policer
*/ */
for_each_set_bit(p, &rule->port_mask, SJA1105_NUM_PORTS) { for_each_set_bit(p, &rule->port_mask, SJA1105_MAX_NUM_PORTS) {
int bcast = (SJA1105_NUM_PORTS * SJA1105_NUM_TC) + p; int bcast = (ds->num_ports * SJA1105_NUM_TC) + p;
policing[bcast].sharindx = rule->bcast_pol.sharindx; policing[bcast].sharindx = rule->bcast_pol.sharindx;
} }
...@@ -143,7 +144,7 @@ static int sja1105_setup_tc_policer(struct sja1105_private *priv, ...@@ -143,7 +144,7 @@ static int sja1105_setup_tc_policer(struct sja1105_private *priv,
/* Make the policers for traffic class @tc of all ports attached to /* Make the policers for traffic class @tc of all ports attached to
* this block point to the newly allocated policer * this block point to the newly allocated policer
*/ */
for_each_set_bit(p, &rule->port_mask, SJA1105_NUM_PORTS) { for_each_set_bit(p, &rule->port_mask, SJA1105_MAX_NUM_PORTS) {
int index = (p * SJA1105_NUM_TC) + tc; int index = (p * SJA1105_NUM_TC) + tc;
policing[index].sharindx = rule->tc_pol.sharindx; policing[index].sharindx = rule->tc_pol.sharindx;
...@@ -435,7 +436,7 @@ int sja1105_cls_flower_del(struct dsa_switch *ds, int port, ...@@ -435,7 +436,7 @@ int sja1105_cls_flower_del(struct dsa_switch *ds, int port,
policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries; policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries;
if (rule->type == SJA1105_RULE_BCAST_POLICER) { if (rule->type == SJA1105_RULE_BCAST_POLICER) {
int bcast = (SJA1105_NUM_PORTS * SJA1105_NUM_TC) + port; int bcast = (ds->num_ports * SJA1105_NUM_TC) + port;
old_sharindx = policing[bcast].sharindx; old_sharindx = policing[bcast].sharindx;
policing[bcast].sharindx = port; policing[bcast].sharindx = port;
...@@ -486,7 +487,7 @@ void sja1105_flower_setup(struct dsa_switch *ds) ...@@ -486,7 +487,7 @@ void sja1105_flower_setup(struct dsa_switch *ds)
INIT_LIST_HEAD(&priv->flow_block.rules); INIT_LIST_HEAD(&priv->flow_block.rules);
for (port = 0; port < SJA1105_NUM_PORTS; port++) for (port = 0; port < ds->num_ports; port++)
priv->flow_block.l2_policer_used[port] = true; priv->flow_block.l2_policer_used[port] = true;
} }
......
This diff is collapsed.
...@@ -7,8 +7,6 @@ ...@@ -7,8 +7,6 @@
#include <linux/packing.h> #include <linux/packing.h>
#include "sja1105.h" #include "sja1105.h"
#define SJA1105_SIZE_RESET_CMD 4
struct sja1105_chunk { struct sja1105_chunk {
u8 *buf; u8 *buf;
size_t len; size_t len;
...@@ -179,28 +177,20 @@ static int sja1105et_reset_cmd(struct dsa_switch *ds) ...@@ -179,28 +177,20 @@ static int sja1105et_reset_cmd(struct dsa_switch *ds)
{ {
struct sja1105_private *priv = ds->priv; struct sja1105_private *priv = ds->priv;
const struct sja1105_regs *regs = priv->info->regs; const struct sja1105_regs *regs = priv->info->regs;
u8 packed_buf[SJA1105_SIZE_RESET_CMD] = {0}; u32 cold_reset = BIT(3);
const int size = SJA1105_SIZE_RESET_CMD;
u64 cold_rst = 1;
sja1105_pack(packed_buf, &cold_rst, 3, 3, size);
return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgu, packed_buf, /* Cold reset */
SJA1105_SIZE_RESET_CMD); return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &cold_reset, NULL);
} }
static int sja1105pqrs_reset_cmd(struct dsa_switch *ds) static int sja1105pqrs_reset_cmd(struct dsa_switch *ds)
{ {
struct sja1105_private *priv = ds->priv; struct sja1105_private *priv = ds->priv;
const struct sja1105_regs *regs = priv->info->regs; const struct sja1105_regs *regs = priv->info->regs;
u8 packed_buf[SJA1105_SIZE_RESET_CMD] = {0}; u32 cold_reset = BIT(2);
const int size = SJA1105_SIZE_RESET_CMD;
u64 cold_rst = 1;
sja1105_pack(packed_buf, &cold_rst, 2, 2, size);
return sja1105_xfer_buf(priv, SPI_WRITE, regs->rgu, packed_buf, /* Cold reset */
SJA1105_SIZE_RESET_CMD); return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &cold_reset, NULL);
} }
int sja1105_inhibit_tx(const struct sja1105_private *priv, int sja1105_inhibit_tx(const struct sja1105_private *priv,
...@@ -281,7 +271,8 @@ int static_config_buf_prepare_for_upload(struct sja1105_private *priv, ...@@ -281,7 +271,8 @@ int static_config_buf_prepare_for_upload(struct sja1105_private *priv,
char *final_header_ptr; char *final_header_ptr;
int crc_len; int crc_len;
valid = sja1105_static_config_check_valid(config); valid = sja1105_static_config_check_valid(config,
priv->info->max_frame_mem);
if (valid != SJA1105_CONFIG_OK) { if (valid != SJA1105_CONFIG_OK) {
dev_err(&priv->spidev->dev, dev_err(&priv->spidev->dev,
sja1105_static_config_error_msg[valid]); sja1105_static_config_error_msg[valid]);
...@@ -309,10 +300,10 @@ int static_config_buf_prepare_for_upload(struct sja1105_private *priv, ...@@ -309,10 +300,10 @@ int static_config_buf_prepare_for_upload(struct sja1105_private *priv,
int sja1105_static_config_upload(struct sja1105_private *priv) int sja1105_static_config_upload(struct sja1105_private *priv)
{ {
unsigned long port_bitmap = GENMASK_ULL(SJA1105_NUM_PORTS - 1, 0);
struct sja1105_static_config *config = &priv->static_config; struct sja1105_static_config *config = &priv->static_config;
const struct sja1105_regs *regs = priv->info->regs; const struct sja1105_regs *regs = priv->info->regs;
struct device *dev = &priv->spidev->dev; struct device *dev = &priv->spidev->dev;
struct dsa_switch *ds = priv->ds;
struct sja1105_status status; struct sja1105_status status;
int rc, retries = RETRIES; int rc, retries = RETRIES;
u8 *config_buf; u8 *config_buf;
...@@ -333,7 +324,7 @@ int sja1105_static_config_upload(struct sja1105_private *priv) ...@@ -333,7 +324,7 @@ int sja1105_static_config_upload(struct sja1105_private *priv)
* Tx on all ports and waiting for current packet to drain. * Tx on all ports and waiting for current packet to drain.
* Otherwise, the PHY will see an unterminated Ethernet packet. * Otherwise, the PHY will see an unterminated Ethernet packet.
*/ */
rc = sja1105_inhibit_tx(priv, port_bitmap, true); rc = sja1105_inhibit_tx(priv, GENMASK_ULL(ds->num_ports - 1, 0), true);
if (rc < 0) { if (rc < 0) {
dev_err(dev, "Failed to inhibit Tx on ports\n"); dev_err(dev, "Failed to inhibit Tx on ports\n");
rc = -ENXIO; rc = -ENXIO;
...@@ -484,11 +475,13 @@ const struct sja1105_info sja1105e_info = { ...@@ -484,11 +475,13 @@ const struct sja1105_info sja1105e_info = {
.can_limit_mcast_flood = false, .can_limit_mcast_flood = false,
.ptp_ts_bits = 24, .ptp_ts_bits = 24,
.ptpegr_ts_bytes = 4, .ptpegr_ts_bytes = 4,
.max_frame_mem = SJA1105_MAX_FRAME_MEMORY,
.num_cbs_shapers = SJA1105ET_MAX_CBS_COUNT, .num_cbs_shapers = SJA1105ET_MAX_CBS_COUNT,
.reset_cmd = sja1105et_reset_cmd, .reset_cmd = sja1105et_reset_cmd,
.fdb_add_cmd = sja1105et_fdb_add, .fdb_add_cmd = sja1105et_fdb_add,
.fdb_del_cmd = sja1105et_fdb_del, .fdb_del_cmd = sja1105et_fdb_del,
.ptp_cmd_packing = sja1105et_ptp_cmd_packing, .ptp_cmd_packing = sja1105et_ptp_cmd_packing,
.clocking_setup = sja1105_clocking_setup,
.regs = &sja1105et_regs, .regs = &sja1105et_regs,
.name = "SJA1105E", .name = "SJA1105E",
}; };
...@@ -502,11 +495,13 @@ const struct sja1105_info sja1105t_info = { ...@@ -502,11 +495,13 @@ const struct sja1105_info sja1105t_info = {
.can_limit_mcast_flood = false, .can_limit_mcast_flood = false,
.ptp_ts_bits = 24, .ptp_ts_bits = 24,
.ptpegr_ts_bytes = 4, .ptpegr_ts_bytes = 4,
.max_frame_mem = SJA1105_MAX_FRAME_MEMORY,
.num_cbs_shapers = SJA1105ET_MAX_CBS_COUNT, .num_cbs_shapers = SJA1105ET_MAX_CBS_COUNT,
.reset_cmd = sja1105et_reset_cmd, .reset_cmd = sja1105et_reset_cmd,
.fdb_add_cmd = sja1105et_fdb_add, .fdb_add_cmd = sja1105et_fdb_add,
.fdb_del_cmd = sja1105et_fdb_del, .fdb_del_cmd = sja1105et_fdb_del,
.ptp_cmd_packing = sja1105et_ptp_cmd_packing, .ptp_cmd_packing = sja1105et_ptp_cmd_packing,
.clocking_setup = sja1105_clocking_setup,
.regs = &sja1105et_regs, .regs = &sja1105et_regs,
.name = "SJA1105T", .name = "SJA1105T",
}; };
...@@ -520,12 +515,14 @@ const struct sja1105_info sja1105p_info = { ...@@ -520,12 +515,14 @@ const struct sja1105_info sja1105p_info = {
.can_limit_mcast_flood = true, .can_limit_mcast_flood = true,
.ptp_ts_bits = 32, .ptp_ts_bits = 32,
.ptpegr_ts_bytes = 8, .ptpegr_ts_bytes = 8,
.max_frame_mem = SJA1105_MAX_FRAME_MEMORY,
.num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT, .num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT,
.setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay, .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay,
.reset_cmd = sja1105pqrs_reset_cmd, .reset_cmd = sja1105pqrs_reset_cmd,
.fdb_add_cmd = sja1105pqrs_fdb_add, .fdb_add_cmd = sja1105pqrs_fdb_add,
.fdb_del_cmd = sja1105pqrs_fdb_del, .fdb_del_cmd = sja1105pqrs_fdb_del,
.ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing,
.clocking_setup = sja1105_clocking_setup,
.regs = &sja1105pqrs_regs, .regs = &sja1105pqrs_regs,
.name = "SJA1105P", .name = "SJA1105P",
}; };
...@@ -539,12 +536,14 @@ const struct sja1105_info sja1105q_info = { ...@@ -539,12 +536,14 @@ const struct sja1105_info sja1105q_info = {
.can_limit_mcast_flood = true, .can_limit_mcast_flood = true,
.ptp_ts_bits = 32, .ptp_ts_bits = 32,
.ptpegr_ts_bytes = 8, .ptpegr_ts_bytes = 8,
.max_frame_mem = SJA1105_MAX_FRAME_MEMORY,
.num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT, .num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT,
.setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay, .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay,
.reset_cmd = sja1105pqrs_reset_cmd, .reset_cmd = sja1105pqrs_reset_cmd,
.fdb_add_cmd = sja1105pqrs_fdb_add, .fdb_add_cmd = sja1105pqrs_fdb_add,
.fdb_del_cmd = sja1105pqrs_fdb_del, .fdb_del_cmd = sja1105pqrs_fdb_del,
.ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing,
.clocking_setup = sja1105_clocking_setup,
.regs = &sja1105pqrs_regs, .regs = &sja1105pqrs_regs,
.name = "SJA1105Q", .name = "SJA1105Q",
}; };
...@@ -558,12 +557,14 @@ const struct sja1105_info sja1105r_info = { ...@@ -558,12 +557,14 @@ const struct sja1105_info sja1105r_info = {
.can_limit_mcast_flood = true, .can_limit_mcast_flood = true,
.ptp_ts_bits = 32, .ptp_ts_bits = 32,
.ptpegr_ts_bytes = 8, .ptpegr_ts_bytes = 8,
.max_frame_mem = SJA1105_MAX_FRAME_MEMORY,
.num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT, .num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT,
.setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay, .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay,
.reset_cmd = sja1105pqrs_reset_cmd, .reset_cmd = sja1105pqrs_reset_cmd,
.fdb_add_cmd = sja1105pqrs_fdb_add, .fdb_add_cmd = sja1105pqrs_fdb_add,
.fdb_del_cmd = sja1105pqrs_fdb_del, .fdb_del_cmd = sja1105pqrs_fdb_del,
.ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing,
.clocking_setup = sja1105_clocking_setup,
.regs = &sja1105pqrs_regs, .regs = &sja1105pqrs_regs,
.name = "SJA1105R", .name = "SJA1105R",
}; };
...@@ -578,11 +579,13 @@ const struct sja1105_info sja1105s_info = { ...@@ -578,11 +579,13 @@ const struct sja1105_info sja1105s_info = {
.can_limit_mcast_flood = true, .can_limit_mcast_flood = true,
.ptp_ts_bits = 32, .ptp_ts_bits = 32,
.ptpegr_ts_bytes = 8, .ptpegr_ts_bytes = 8,
.max_frame_mem = SJA1105_MAX_FRAME_MEMORY,
.num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT, .num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT,
.setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay, .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay,
.reset_cmd = sja1105pqrs_reset_cmd, .reset_cmd = sja1105pqrs_reset_cmd,
.fdb_add_cmd = sja1105pqrs_fdb_add, .fdb_add_cmd = sja1105pqrs_fdb_add,
.fdb_del_cmd = sja1105pqrs_fdb_del, .fdb_del_cmd = sja1105pqrs_fdb_del,
.ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing,
.clocking_setup = sja1105_clocking_setup,
.name = "SJA1105S", .name = "SJA1105S",
}; };
...@@ -657,11 +657,11 @@ const char *sja1105_static_config_error_msg[] = { ...@@ -657,11 +657,11 @@ const char *sja1105_static_config_error_msg[] = {
}; };
static sja1105_config_valid_t static sja1105_config_valid_t
static_config_check_memory_size(const struct sja1105_table *tables) static_config_check_memory_size(const struct sja1105_table *tables, int max_mem)
{ {
const struct sja1105_l2_forwarding_params_entry *l2_fwd_params; const struct sja1105_l2_forwarding_params_entry *l2_fwd_params;
const struct sja1105_vl_forwarding_params_entry *vl_fwd_params; const struct sja1105_vl_forwarding_params_entry *vl_fwd_params;
int i, max_mem, mem = 0; int i, mem = 0;
l2_fwd_params = tables[BLK_IDX_L2_FORWARDING_PARAMS].entries; l2_fwd_params = tables[BLK_IDX_L2_FORWARDING_PARAMS].entries;
...@@ -675,9 +675,7 @@ static_config_check_memory_size(const struct sja1105_table *tables) ...@@ -675,9 +675,7 @@ static_config_check_memory_size(const struct sja1105_table *tables)
} }
if (tables[BLK_IDX_RETAGGING].entry_count) if (tables[BLK_IDX_RETAGGING].entry_count)
max_mem = SJA1105_MAX_FRAME_MEMORY_RETAGGING; max_mem -= SJA1105_FRAME_MEMORY_RETAGGING_OVERHEAD;
else
max_mem = SJA1105_MAX_FRAME_MEMORY;
if (mem > max_mem) if (mem > max_mem)
return SJA1105_OVERCOMMITTED_FRAME_MEMORY; return SJA1105_OVERCOMMITTED_FRAME_MEMORY;
...@@ -686,7 +684,8 @@ static_config_check_memory_size(const struct sja1105_table *tables) ...@@ -686,7 +684,8 @@ static_config_check_memory_size(const struct sja1105_table *tables)
} }
sja1105_config_valid_t sja1105_config_valid_t
sja1105_static_config_check_valid(const struct sja1105_static_config *config) sja1105_static_config_check_valid(const struct sja1105_static_config *config,
int max_mem)
{ {
const struct sja1105_table *tables = config->tables; const struct sja1105_table *tables = config->tables;
#define IS_FULL(blk_idx) \ #define IS_FULL(blk_idx) \
...@@ -754,7 +753,7 @@ sja1105_static_config_check_valid(const struct sja1105_static_config *config) ...@@ -754,7 +753,7 @@ sja1105_static_config_check_valid(const struct sja1105_static_config *config)
if (!IS_FULL(BLK_IDX_XMII_PARAMS)) if (!IS_FULL(BLK_IDX_XMII_PARAMS))
return SJA1105_MISSING_XMII_TABLE; return SJA1105_MISSING_XMII_TABLE;
return static_config_check_memory_size(tables); return static_config_check_memory_size(tables, max_mem);
#undef IS_FULL #undef IS_FULL
} }
......
...@@ -115,7 +115,7 @@ enum sja1105_blk_idx { ...@@ -115,7 +115,7 @@ enum sja1105_blk_idx {
#define SJA1105PQRS_MAX_CBS_COUNT 16 #define SJA1105PQRS_MAX_CBS_COUNT 16
#define SJA1105_MAX_FRAME_MEMORY 929 #define SJA1105_MAX_FRAME_MEMORY 929
#define SJA1105_MAX_FRAME_MEMORY_RETAGGING 910 #define SJA1105_FRAME_MEMORY_RETAGGING_OVERHEAD 19
#define SJA1105_VL_FRAME_MEMORY 100 #define SJA1105_VL_FRAME_MEMORY 100
#define SJA1105E_DEVICE_ID 0x9C00000Cull #define SJA1105E_DEVICE_ID 0x9C00000Cull
...@@ -129,6 +129,8 @@ enum sja1105_blk_idx { ...@@ -129,6 +129,8 @@ enum sja1105_blk_idx {
#define SJA1105R_PART_NO 0x9A86 #define SJA1105R_PART_NO 0x9A86
#define SJA1105S_PART_NO 0x9A87 #define SJA1105S_PART_NO 0x9A87
#define SJA1105_RSV_ADDR 0xffffffffffffffffull
struct sja1105_schedule_entry { struct sja1105_schedule_entry {
u64 winstindex; u64 winstindex;
u64 winend; u64 winend;
...@@ -414,7 +416,8 @@ typedef enum { ...@@ -414,7 +416,8 @@ typedef enum {
extern const char *sja1105_static_config_error_msg[]; extern const char *sja1105_static_config_error_msg[];
sja1105_config_valid_t sja1105_config_valid_t
sja1105_static_config_check_valid(const struct sja1105_static_config *config); sja1105_static_config_check_valid(const struct sja1105_static_config *config,
int max_mem);
void void
sja1105_static_config_pack(void *buf, struct sja1105_static_config *config); sja1105_static_config_pack(void *buf, struct sja1105_static_config *config);
int sja1105_static_config_init(struct sja1105_static_config *config, int sja1105_static_config_init(struct sja1105_static_config *config,
......
...@@ -27,7 +27,7 @@ static int sja1105_tas_set_runtime_params(struct sja1105_private *priv) ...@@ -27,7 +27,7 @@ static int sja1105_tas_set_runtime_params(struct sja1105_private *priv)
tas_data->enabled = false; tas_data->enabled = false;
for (port = 0; port < SJA1105_NUM_PORTS; port++) { for (port = 0; port < ds->num_ports; port++) {
const struct tc_taprio_qopt_offload *offload; const struct tc_taprio_qopt_offload *offload;
offload = tas_data->offload[port]; offload = tas_data->offload[port];
...@@ -164,6 +164,7 @@ int sja1105_init_scheduling(struct sja1105_private *priv) ...@@ -164,6 +164,7 @@ int sja1105_init_scheduling(struct sja1105_private *priv)
struct sja1105_tas_data *tas_data = &priv->tas_data; struct sja1105_tas_data *tas_data = &priv->tas_data;
struct sja1105_gating_config *gating_cfg = &tas_data->gating_cfg; struct sja1105_gating_config *gating_cfg = &tas_data->gating_cfg;
struct sja1105_schedule_entry *schedule; struct sja1105_schedule_entry *schedule;
struct dsa_switch *ds = priv->ds;
struct sja1105_table *table; struct sja1105_table *table;
int schedule_start_idx; int schedule_start_idx;
s64 entry_point_delta; s64 entry_point_delta;
...@@ -207,7 +208,7 @@ int sja1105_init_scheduling(struct sja1105_private *priv) ...@@ -207,7 +208,7 @@ int sja1105_init_scheduling(struct sja1105_private *priv)
} }
/* Figure out the dimensioning of the problem */ /* Figure out the dimensioning of the problem */
for (port = 0; port < SJA1105_NUM_PORTS; port++) { for (port = 0; port < ds->num_ports; port++) {
if (tas_data->offload[port]) { if (tas_data->offload[port]) {
num_entries += tas_data->offload[port]->num_entries; num_entries += tas_data->offload[port]->num_entries;
num_cycles++; num_cycles++;
...@@ -269,7 +270,7 @@ int sja1105_init_scheduling(struct sja1105_private *priv) ...@@ -269,7 +270,7 @@ int sja1105_init_scheduling(struct sja1105_private *priv)
schedule_entry_points_params->clksrc = SJA1105_TAS_CLKSRC_PTP; schedule_entry_points_params->clksrc = SJA1105_TAS_CLKSRC_PTP;
schedule_entry_points_params->actsubsch = num_cycles - 1; schedule_entry_points_params->actsubsch = num_cycles - 1;
for (port = 0; port < SJA1105_NUM_PORTS; port++) { for (port = 0; port < ds->num_ports; port++) {
const struct tc_taprio_qopt_offload *offload; const struct tc_taprio_qopt_offload *offload;
/* Relative base time */ /* Relative base time */
s64 rbt; s64 rbt;
...@@ -468,6 +469,7 @@ bool sja1105_gating_check_conflicts(struct sja1105_private *priv, int port, ...@@ -468,6 +469,7 @@ bool sja1105_gating_check_conflicts(struct sja1105_private *priv, int port,
struct sja1105_gating_config *gating_cfg = &priv->tas_data.gating_cfg; struct sja1105_gating_config *gating_cfg = &priv->tas_data.gating_cfg;
size_t num_entries = gating_cfg->num_entries; size_t num_entries = gating_cfg->num_entries;
struct tc_taprio_qopt_offload *dummy; struct tc_taprio_qopt_offload *dummy;
struct dsa_switch *ds = priv->ds;
struct sja1105_gate_entry *e; struct sja1105_gate_entry *e;
bool conflict; bool conflict;
int i = 0; int i = 0;
...@@ -491,7 +493,7 @@ bool sja1105_gating_check_conflicts(struct sja1105_private *priv, int port, ...@@ -491,7 +493,7 @@ bool sja1105_gating_check_conflicts(struct sja1105_private *priv, int port,
if (port != -1) { if (port != -1) {
conflict = sja1105_tas_check_conflicts(priv, port, dummy); conflict = sja1105_tas_check_conflicts(priv, port, dummy);
} else { } else {
for (port = 0; port < SJA1105_NUM_PORTS; port++) { for (port = 0; port < ds->num_ports; port++) {
conflict = sja1105_tas_check_conflicts(priv, port, conflict = sja1105_tas_check_conflicts(priv, port,
dummy); dummy);
if (conflict) if (conflict)
...@@ -554,7 +556,7 @@ int sja1105_setup_tc_taprio(struct dsa_switch *ds, int port, ...@@ -554,7 +556,7 @@ int sja1105_setup_tc_taprio(struct dsa_switch *ds, int port,
} }
} }
for (other_port = 0; other_port < SJA1105_NUM_PORTS; other_port++) { for (other_port = 0; other_port < ds->num_ports; other_port++) {
if (other_port == port) if (other_port == port)
continue; continue;
...@@ -885,7 +887,7 @@ void sja1105_tas_teardown(struct dsa_switch *ds) ...@@ -885,7 +887,7 @@ void sja1105_tas_teardown(struct dsa_switch *ds)
cancel_work_sync(&priv->tas_data.tas_work); cancel_work_sync(&priv->tas_data.tas_work);
for (port = 0; port < SJA1105_NUM_PORTS; port++) { for (port = 0; port < ds->num_ports; port++) {
offload = priv->tas_data.offload[port]; offload = priv->tas_data.offload[port];
if (!offload) if (!offload)
continue; continue;
......
...@@ -39,7 +39,7 @@ struct sja1105_gating_config { ...@@ -39,7 +39,7 @@ struct sja1105_gating_config {
}; };
struct sja1105_tas_data { struct sja1105_tas_data {
struct tc_taprio_qopt_offload *offload[SJA1105_NUM_PORTS]; struct tc_taprio_qopt_offload *offload[SJA1105_MAX_NUM_PORTS];
struct sja1105_gating_config gating_cfg; struct sja1105_gating_config gating_cfg;
enum sja1105_tas_state state; enum sja1105_tas_state state;
enum sja1105_ptp_op last_op; enum sja1105_ptp_op last_op;
......
...@@ -386,7 +386,7 @@ static int sja1105_init_virtual_links(struct sja1105_private *priv, ...@@ -386,7 +386,7 @@ static int sja1105_init_virtual_links(struct sja1105_private *priv,
if (rule->type != SJA1105_RULE_VL) if (rule->type != SJA1105_RULE_VL)
continue; continue;
for_each_set_bit(port, &rule->port_mask, SJA1105_NUM_PORTS) { for_each_set_bit(port, &rule->port_mask, SJA1105_MAX_NUM_PORTS) {
vl_lookup[k].format = SJA1105_VL_FORMAT_PSFP; vl_lookup[k].format = SJA1105_VL_FORMAT_PSFP;
vl_lookup[k].port = port; vl_lookup[k].port = port;
vl_lookup[k].macaddr = rule->key.vl.dmac; vl_lookup[k].macaddr = rule->key.vl.dmac;
......
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