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>
This commit is contained in:
commit
f8fdd54ee6
|
@ -132,6 +132,8 @@ struct sja1105_info {
|
|||
int max_frame_mem;
|
||||
int num_ports;
|
||||
bool multiple_cascade_ports;
|
||||
/* Every {port, TXQ} has its own CBS shaper */
|
||||
bool fixed_cbs_mapping;
|
||||
enum dsa_tag_protocol tag_proto;
|
||||
const struct sja1105_dynamic_table_ops *dyn_ops;
|
||||
const struct sja1105_table_ops *static_ops;
|
||||
|
|
|
@ -2115,11 +2115,36 @@ static void sja1105_bridge_leave(struct dsa_switch *ds, int port,
|
|||
}
|
||||
|
||||
#define BYTES_PER_KBIT (1000LL / 8)
|
||||
/* Port 0 (the uC port) does not have CBS shapers */
|
||||
#define SJA1110_FIXED_CBS(port, prio) ((((port) - 1) * SJA1105_NUM_TC) + (prio))
|
||||
|
||||
static int sja1105_find_cbs_shaper(struct sja1105_private *priv,
|
||||
int port, int prio)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (priv->info->fixed_cbs_mapping) {
|
||||
i = SJA1110_FIXED_CBS(port, prio);
|
||||
if (i >= 0 && i < priv->info->num_cbs_shapers)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < priv->info->num_cbs_shapers; i++)
|
||||
if (priv->cbs[i].port == port && priv->cbs[i].prio == prio)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int sja1105_find_unused_cbs_shaper(struct sja1105_private *priv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (priv->info->fixed_cbs_mapping)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < priv->info->num_cbs_shapers; i++)
|
||||
if (!priv->cbs[i].idle_slope && !priv->cbs[i].send_slope)
|
||||
return i;
|
||||
|
@ -2150,14 +2175,20 @@ static int sja1105_setup_tc_cbs(struct dsa_switch *ds, int port,
|
|||
{
|
||||
struct sja1105_private *priv = ds->priv;
|
||||
struct sja1105_cbs_entry *cbs;
|
||||
s64 port_transmit_rate_kbps;
|
||||
int index;
|
||||
|
||||
if (!offload->enable)
|
||||
return sja1105_delete_cbs_shaper(priv, port, offload->queue);
|
||||
|
||||
/* The user may be replacing an existing shaper */
|
||||
index = sja1105_find_cbs_shaper(priv, port, offload->queue);
|
||||
if (index < 0) {
|
||||
/* That isn't the case - see if we can allocate a new one */
|
||||
index = sja1105_find_unused_cbs_shaper(priv);
|
||||
if (index < 0)
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
cbs = &priv->cbs[index];
|
||||
cbs->port = port;
|
||||
|
@ -2167,9 +2198,17 @@ static int sja1105_setup_tc_cbs(struct dsa_switch *ds, int port,
|
|||
*/
|
||||
cbs->credit_hi = offload->hicredit;
|
||||
cbs->credit_lo = abs(offload->locredit);
|
||||
/* User space is in kbits/sec, hardware in bytes/sec */
|
||||
cbs->idle_slope = offload->idleslope * BYTES_PER_KBIT;
|
||||
cbs->send_slope = abs(offload->sendslope * BYTES_PER_KBIT);
|
||||
/* User space is in kbits/sec, while the hardware in bytes/sec times
|
||||
* link speed. Since the given offload->sendslope is good only for the
|
||||
* current link speed anyway, and user space is likely to reprogram it
|
||||
* when that changes, don't even bother to track the port's link speed,
|
||||
* but deduce the port transmit rate from idleslope - sendslope.
|
||||
*/
|
||||
port_transmit_rate_kbps = offload->idleslope - offload->sendslope;
|
||||
cbs->idle_slope = div_s64(offload->idleslope * BYTES_PER_KBIT,
|
||||
port_transmit_rate_kbps);
|
||||
cbs->send_slope = div_s64(abs(offload->sendslope * BYTES_PER_KBIT),
|
||||
port_transmit_rate_kbps);
|
||||
/* Convert the negative values from 64-bit 2's complement
|
||||
* to 32-bit 2's complement (for the case of 0x80000000 whose
|
||||
* negative is still negative).
|
||||
|
|
|
@ -781,6 +781,7 @@ const struct sja1105_info sja1110a_info = {
|
|||
.tag_proto = DSA_TAG_PROTO_SJA1110,
|
||||
.can_limit_mcast_flood = true,
|
||||
.multiple_cascade_ports = true,
|
||||
.fixed_cbs_mapping = true,
|
||||
.ptp_ts_bits = 32,
|
||||
.ptpegr_ts_bytes = 8,
|
||||
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
|
||||
|
@ -831,6 +832,7 @@ const struct sja1105_info sja1110b_info = {
|
|||
.tag_proto = DSA_TAG_PROTO_SJA1110,
|
||||
.can_limit_mcast_flood = true,
|
||||
.multiple_cascade_ports = true,
|
||||
.fixed_cbs_mapping = true,
|
||||
.ptp_ts_bits = 32,
|
||||
.ptpegr_ts_bytes = 8,
|
||||
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
|
||||
|
@ -881,6 +883,7 @@ const struct sja1105_info sja1110c_info = {
|
|||
.tag_proto = DSA_TAG_PROTO_SJA1110,
|
||||
.can_limit_mcast_flood = true,
|
||||
.multiple_cascade_ports = true,
|
||||
.fixed_cbs_mapping = true,
|
||||
.ptp_ts_bits = 32,
|
||||
.ptpegr_ts_bytes = 8,
|
||||
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
|
||||
|
@ -931,6 +934,7 @@ const struct sja1105_info sja1110d_info = {
|
|||
.tag_proto = DSA_TAG_PROTO_SJA1110,
|
||||
.can_limit_mcast_flood = true,
|
||||
.multiple_cascade_ports = true,
|
||||
.fixed_cbs_mapping = true,
|
||||
.ptp_ts_bits = 32,
|
||||
.ptpegr_ts_bytes = 8,
|
||||
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
|
||||
|
|
Loading…
Reference in New Issue