mirror of
https://github.com/lkl/linux.git
synced 2025-12-19 16:13:19 +09:00
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:
@@ -132,6 +132,8 @@ struct sja1105_info {
|
|||||||
int max_frame_mem;
|
int max_frame_mem;
|
||||||
int num_ports;
|
int num_ports;
|
||||||
bool multiple_cascade_ports;
|
bool multiple_cascade_ports;
|
||||||
|
/* Every {port, TXQ} has its own CBS shaper */
|
||||||
|
bool fixed_cbs_mapping;
|
||||||
enum dsa_tag_protocol tag_proto;
|
enum dsa_tag_protocol tag_proto;
|
||||||
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;
|
||||||
|
|||||||
@@ -2115,11 +2115,36 @@ static void sja1105_bridge_leave(struct dsa_switch *ds, int port,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define BYTES_PER_KBIT (1000LL / 8)
|
#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)
|
static int sja1105_find_unused_cbs_shaper(struct sja1105_private *priv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (priv->info->fixed_cbs_mapping)
|
||||||
|
return -1;
|
||||||
|
|
||||||
for (i = 0; i < priv->info->num_cbs_shapers; i++)
|
for (i = 0; i < priv->info->num_cbs_shapers; i++)
|
||||||
if (!priv->cbs[i].idle_slope && !priv->cbs[i].send_slope)
|
if (!priv->cbs[i].idle_slope && !priv->cbs[i].send_slope)
|
||||||
return i;
|
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_private *priv = ds->priv;
|
||||||
struct sja1105_cbs_entry *cbs;
|
struct sja1105_cbs_entry *cbs;
|
||||||
|
s64 port_transmit_rate_kbps;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
if (!offload->enable)
|
if (!offload->enable)
|
||||||
return sja1105_delete_cbs_shaper(priv, port, offload->queue);
|
return sja1105_delete_cbs_shaper(priv, port, offload->queue);
|
||||||
|
|
||||||
index = sja1105_find_unused_cbs_shaper(priv);
|
/* The user may be replacing an existing shaper */
|
||||||
if (index < 0)
|
index = sja1105_find_cbs_shaper(priv, port, offload->queue);
|
||||||
return -ENOSPC;
|
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 = &priv->cbs[index];
|
||||||
cbs->port = port;
|
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_hi = offload->hicredit;
|
||||||
cbs->credit_lo = abs(offload->locredit);
|
cbs->credit_lo = abs(offload->locredit);
|
||||||
/* User space is in kbits/sec, hardware in bytes/sec */
|
/* User space is in kbits/sec, while the hardware in bytes/sec times
|
||||||
cbs->idle_slope = offload->idleslope * BYTES_PER_KBIT;
|
* link speed. Since the given offload->sendslope is good only for the
|
||||||
cbs->send_slope = abs(offload->sendslope * BYTES_PER_KBIT);
|
* 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
|
/* Convert the negative values from 64-bit 2's complement
|
||||||
* to 32-bit 2's complement (for the case of 0x80000000 whose
|
* to 32-bit 2's complement (for the case of 0x80000000 whose
|
||||||
* negative is still negative).
|
* negative is still negative).
|
||||||
|
|||||||
@@ -781,6 +781,7 @@ const struct sja1105_info sja1110a_info = {
|
|||||||
.tag_proto = DSA_TAG_PROTO_SJA1110,
|
.tag_proto = DSA_TAG_PROTO_SJA1110,
|
||||||
.can_limit_mcast_flood = true,
|
.can_limit_mcast_flood = true,
|
||||||
.multiple_cascade_ports = true,
|
.multiple_cascade_ports = true,
|
||||||
|
.fixed_cbs_mapping = true,
|
||||||
.ptp_ts_bits = 32,
|
.ptp_ts_bits = 32,
|
||||||
.ptpegr_ts_bytes = 8,
|
.ptpegr_ts_bytes = 8,
|
||||||
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
|
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
|
||||||
@@ -831,6 +832,7 @@ const struct sja1105_info sja1110b_info = {
|
|||||||
.tag_proto = DSA_TAG_PROTO_SJA1110,
|
.tag_proto = DSA_TAG_PROTO_SJA1110,
|
||||||
.can_limit_mcast_flood = true,
|
.can_limit_mcast_flood = true,
|
||||||
.multiple_cascade_ports = true,
|
.multiple_cascade_ports = true,
|
||||||
|
.fixed_cbs_mapping = true,
|
||||||
.ptp_ts_bits = 32,
|
.ptp_ts_bits = 32,
|
||||||
.ptpegr_ts_bytes = 8,
|
.ptpegr_ts_bytes = 8,
|
||||||
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
|
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
|
||||||
@@ -881,6 +883,7 @@ const struct sja1105_info sja1110c_info = {
|
|||||||
.tag_proto = DSA_TAG_PROTO_SJA1110,
|
.tag_proto = DSA_TAG_PROTO_SJA1110,
|
||||||
.can_limit_mcast_flood = true,
|
.can_limit_mcast_flood = true,
|
||||||
.multiple_cascade_ports = true,
|
.multiple_cascade_ports = true,
|
||||||
|
.fixed_cbs_mapping = true,
|
||||||
.ptp_ts_bits = 32,
|
.ptp_ts_bits = 32,
|
||||||
.ptpegr_ts_bytes = 8,
|
.ptpegr_ts_bytes = 8,
|
||||||
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
|
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
|
||||||
@@ -931,6 +934,7 @@ const struct sja1105_info sja1110d_info = {
|
|||||||
.tag_proto = DSA_TAG_PROTO_SJA1110,
|
.tag_proto = DSA_TAG_PROTO_SJA1110,
|
||||||
.can_limit_mcast_flood = true,
|
.can_limit_mcast_flood = true,
|
||||||
.multiple_cascade_ports = true,
|
.multiple_cascade_ports = true,
|
||||||
|
.fixed_cbs_mapping = true,
|
||||||
.ptp_ts_bits = 32,
|
.ptp_ts_bits = 32,
|
||||||
.ptpegr_ts_bytes = 8,
|
.ptpegr_ts_bytes = 8,
|
||||||
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
|
.max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
|
||||||
|
|||||||
Reference in New Issue
Block a user