Skip to content

Commit f8fdd54

Browse files
committed
Merge branch 'sja1105-fixes'
Vladimir Oltean says: ==================== tc-cbs offload fixes for SJA1105 DSA Yanan Yang has pointed out to me that certain tc-cbs offloaded configurations do not appear to do any shaping on the LS1021A-TSN board (SJA1105T). This is due to an apparent documentation error that also made its way into the driver, which patch 1/3 now fixes. While investigating and then testing, I've found 2 more bugs, which are patches 2/3 and 3/3. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents ca7cfd7 + 180a741 commit f8fdd54

File tree

3 files changed

+51
-6
lines changed

3 files changed

+51
-6
lines changed

drivers/net/dsa/sja1105/sja1105.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ struct sja1105_info {
132132
int max_frame_mem;
133133
int num_ports;
134134
bool multiple_cascade_ports;
135+
/* Every {port, TXQ} has its own CBS shaper */
136+
bool fixed_cbs_mapping;
135137
enum dsa_tag_protocol tag_proto;
136138
const struct sja1105_dynamic_table_ops *dyn_ops;
137139
const struct sja1105_table_ops *static_ops;

drivers/net/dsa/sja1105/sja1105_main.c

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,11 +2115,36 @@ static void sja1105_bridge_leave(struct dsa_switch *ds, int port,
21152115
}
21162116

21172117
#define BYTES_PER_KBIT (1000LL / 8)
2118+
/* Port 0 (the uC port) does not have CBS shapers */
2119+
#define SJA1110_FIXED_CBS(port, prio) ((((port) - 1) * SJA1105_NUM_TC) + (prio))
2120+
2121+
static int sja1105_find_cbs_shaper(struct sja1105_private *priv,
2122+
int port, int prio)
2123+
{
2124+
int i;
2125+
2126+
if (priv->info->fixed_cbs_mapping) {
2127+
i = SJA1110_FIXED_CBS(port, prio);
2128+
if (i >= 0 && i < priv->info->num_cbs_shapers)
2129+
return i;
2130+
2131+
return -1;
2132+
}
2133+
2134+
for (i = 0; i < priv->info->num_cbs_shapers; i++)
2135+
if (priv->cbs[i].port == port && priv->cbs[i].prio == prio)
2136+
return i;
2137+
2138+
return -1;
2139+
}
21182140

21192141
static int sja1105_find_unused_cbs_shaper(struct sja1105_private *priv)
21202142
{
21212143
int i;
21222144

2145+
if (priv->info->fixed_cbs_mapping)
2146+
return -1;
2147+
21232148
for (i = 0; i < priv->info->num_cbs_shapers; i++)
21242149
if (!priv->cbs[i].idle_slope && !priv->cbs[i].send_slope)
21252150
return i;
@@ -2150,14 +2175,20 @@ static int sja1105_setup_tc_cbs(struct dsa_switch *ds, int port,
21502175
{
21512176
struct sja1105_private *priv = ds->priv;
21522177
struct sja1105_cbs_entry *cbs;
2178+
s64 port_transmit_rate_kbps;
21532179
int index;
21542180

21552181
if (!offload->enable)
21562182
return sja1105_delete_cbs_shaper(priv, port, offload->queue);
21572183

2158-
index = sja1105_find_unused_cbs_shaper(priv);
2159-
if (index < 0)
2160-
return -ENOSPC;
2184+
/* The user may be replacing an existing shaper */
2185+
index = sja1105_find_cbs_shaper(priv, port, offload->queue);
2186+
if (index < 0) {
2187+
/* That isn't the case - see if we can allocate a new one */
2188+
index = sja1105_find_unused_cbs_shaper(priv);
2189+
if (index < 0)
2190+
return -ENOSPC;
2191+
}
21612192

21622193
cbs = &priv->cbs[index];
21632194
cbs->port = port;
@@ -2167,9 +2198,17 @@ static int sja1105_setup_tc_cbs(struct dsa_switch *ds, int port,
21672198
*/
21682199
cbs->credit_hi = offload->hicredit;
21692200
cbs->credit_lo = abs(offload->locredit);
2170-
/* User space is in kbits/sec, hardware in bytes/sec */
2171-
cbs->idle_slope = offload->idleslope * BYTES_PER_KBIT;
2172-
cbs->send_slope = abs(offload->sendslope * BYTES_PER_KBIT);
2201+
/* User space is in kbits/sec, while the hardware in bytes/sec times
2202+
* link speed. Since the given offload->sendslope is good only for the
2203+
* current link speed anyway, and user space is likely to reprogram it
2204+
* when that changes, don't even bother to track the port's link speed,
2205+
* but deduce the port transmit rate from idleslope - sendslope.
2206+
*/
2207+
port_transmit_rate_kbps = offload->idleslope - offload->sendslope;
2208+
cbs->idle_slope = div_s64(offload->idleslope * BYTES_PER_KBIT,
2209+
port_transmit_rate_kbps);
2210+
cbs->send_slope = div_s64(abs(offload->sendslope * BYTES_PER_KBIT),
2211+
port_transmit_rate_kbps);
21732212
/* Convert the negative values from 64-bit 2's complement
21742213
* to 32-bit 2's complement (for the case of 0x80000000 whose
21752214
* negative is still negative).

drivers/net/dsa/sja1105/sja1105_spi.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,7 @@ const struct sja1105_info sja1110a_info = {
781781
.tag_proto = DSA_TAG_PROTO_SJA1110,
782782
.can_limit_mcast_flood = true,
783783
.multiple_cascade_ports = true,
784+
.fixed_cbs_mapping = true,
784785
.ptp_ts_bits = 32,
785786
.ptpegr_ts_bytes = 8,
786787
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
@@ -831,6 +832,7 @@ const struct sja1105_info sja1110b_info = {
831832
.tag_proto = DSA_TAG_PROTO_SJA1110,
832833
.can_limit_mcast_flood = true,
833834
.multiple_cascade_ports = true,
835+
.fixed_cbs_mapping = true,
834836
.ptp_ts_bits = 32,
835837
.ptpegr_ts_bytes = 8,
836838
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
@@ -881,6 +883,7 @@ const struct sja1105_info sja1110c_info = {
881883
.tag_proto = DSA_TAG_PROTO_SJA1110,
882884
.can_limit_mcast_flood = true,
883885
.multiple_cascade_ports = true,
886+
.fixed_cbs_mapping = true,
884887
.ptp_ts_bits = 32,
885888
.ptpegr_ts_bytes = 8,
886889
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
@@ -931,6 +934,7 @@ const struct sja1105_info sja1110d_info = {
931934
.tag_proto = DSA_TAG_PROTO_SJA1110,
932935
.can_limit_mcast_flood = true,
933936
.multiple_cascade_ports = true,
937+
.fixed_cbs_mapping = true,
934938
.ptp_ts_bits = 32,
935939
.ptpegr_ts_bytes = 8,
936940
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,

0 commit comments

Comments
 (0)