--- /dev/null
+From ca7609ff3680c51d6c29897f3117aa2ad904f92a Mon Sep 17 00:00:00 2001
+From: Petr Machata <petrm@mellanox.com>
+Date: Wed, 15 Jan 2020 13:53:48 +0200
+Subject: mlxsw: spectrum: Wipe xstats.backlog of down ports
+
+From: Petr Machata <petrm@mellanox.com>
+
+commit ca7609ff3680c51d6c29897f3117aa2ad904f92a upstream.
+
+Per-port counter cache used by Qdiscs is updated periodically, unless the
+port is down. The fact that the cache is not updated for down ports is no
+problem for most counters, which are relative in nature. However, backlog
+is absolute in nature, and if there is a non-zero value in the cache around
+the time that the port goes down, that value just stays there. This value
+then leaks to offloaded Qdiscs that report non-zero backlog even if
+there (obviously) is no traffic.
+
+The HW does not keep backlog of a downed port, so do likewise: as the port
+goes down, wipe the backlog value from xstats.
+
+Fixes: 075ab8adaf4e ("mlxsw: spectrum: Collect tclass related stats periodically")
+Signed-off-by: Petr Machata <petrm@mellanox.com>
+Acked-by: Jiri Pirko <jiri@mellanox.com>
+Signed-off-by: Ido Schimmel <idosch@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+@@ -1061,6 +1061,9 @@ static void update_stats_cache(struct wo
+ periodic_hw_stats.update_dw.work);
+
+ if (!netif_carrier_ok(mlxsw_sp_port->dev))
++ /* Note: mlxsw_sp_port_down_wipe_counters() clears the cache as
++ * necessary when port goes down.
++ */
+ goto out;
+
+ mlxsw_sp_port_get_hw_stats(mlxsw_sp_port->dev,
+@@ -3309,6 +3312,15 @@ static int mlxsw_sp_port_unsplit(struct
+ return 0;
+ }
+
++static void
++mlxsw_sp_port_down_wipe_counters(struct mlxsw_sp_port *mlxsw_sp_port)
++{
++ int i;
++
++ for (i = 0; i < TC_MAX_QUEUE; i++)
++ mlxsw_sp_port->periodic_hw_stats.xstats.backlog[i] = 0;
++}
++
+ static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg,
+ char *pude_pl, void *priv)
+ {
+@@ -3329,6 +3341,7 @@ static void mlxsw_sp_pude_event_func(con
+ } else {
+ netdev_info(mlxsw_sp_port->dev, "link down\n");
+ netif_carrier_off(mlxsw_sp_port->dev);
++ mlxsw_sp_port_down_wipe_counters(mlxsw_sp_port);
+ }
+ }
+
--- /dev/null
+From 85005b82e59fa7bb7388b12594ab2067bf73d66c Mon Sep 17 00:00:00 2001
+From: Petr Machata <petrm@mellanox.com>
+Date: Wed, 15 Jan 2020 13:53:49 +0200
+Subject: mlxsw: spectrum_qdisc: Include MC TCs in Qdisc counters
+
+From: Petr Machata <petrm@mellanox.com>
+
+commit 85005b82e59fa7bb7388b12594ab2067bf73d66c upstream.
+
+mlxsw configures Spectrum in such a way that BUM traffic is passed not
+through its nominal traffic class TC, but through its MC counterpart TC+8.
+However, when collecting statistics, Qdiscs only look at the nominal TC and
+ignore the MC TC.
+
+Add two helpers to compute the value for logical TC from the constituents,
+one for backlog, the other for tail drops. Use them throughout instead of
+going through the xstats pointer directly.
+
+Counters for TX bytes and packets are deduced from packet priority
+counters, and therefore already include BUM traffic. wred_drop counter is
+irrelevant on MC TCs, because RED is not enabled on them.
+
+Fixes: 7b8195306694 ("mlxsw: spectrum: Configure MC-aware mode on mlxsw ports")
+Signed-off-by: Petr Machata <petrm@mellanox.com>
+Acked-by: Jiri Pirko <jiri@mellanox.com>
+Signed-off-by: Ido Schimmel <idosch@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c | 30 ++++++++++++++-----
+ 1 file changed, 23 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c
+@@ -195,6 +195,20 @@ mlxsw_sp_qdisc_get_xstats(struct mlxsw_s
+ return -EOPNOTSUPP;
+ }
+
++static u64
++mlxsw_sp_xstats_backlog(struct mlxsw_sp_port_xstats *xstats, int tclass_num)
++{
++ return xstats->backlog[tclass_num] +
++ xstats->backlog[tclass_num + 8];
++}
++
++static u64
++mlxsw_sp_xstats_tail_drop(struct mlxsw_sp_port_xstats *xstats, int tclass_num)
++{
++ return xstats->tail_drop[tclass_num] +
++ xstats->tail_drop[tclass_num + 8];
++}
++
+ static void
+ mlxsw_sp_qdisc_bstats_per_priority_get(struct mlxsw_sp_port_xstats *xstats,
+ u8 prio_bitmap, u64 *tx_packets,
+@@ -269,7 +283,7 @@ mlxsw_sp_setup_tc_qdisc_red_clean_stats(
+ &stats_base->tx_bytes);
+ red_base->prob_mark = xstats->ecn;
+ red_base->prob_drop = xstats->wred_drop[tclass_num];
+- red_base->pdrop = xstats->tail_drop[tclass_num];
++ red_base->pdrop = mlxsw_sp_xstats_tail_drop(xstats, tclass_num);
+
+ stats_base->overlimits = red_base->prob_drop + red_base->prob_mark;
+ stats_base->drops = red_base->prob_drop + red_base->pdrop;
+@@ -369,7 +383,8 @@ mlxsw_sp_qdisc_get_red_xstats(struct mlx
+
+ early_drops = xstats->wred_drop[tclass_num] - xstats_base->prob_drop;
+ marks = xstats->ecn - xstats_base->prob_mark;
+- pdrops = xstats->tail_drop[tclass_num] - xstats_base->pdrop;
++ pdrops = mlxsw_sp_xstats_tail_drop(xstats, tclass_num) -
++ xstats_base->pdrop;
+
+ res->pdrop += pdrops;
+ res->prob_drop += early_drops;
+@@ -402,9 +417,10 @@ mlxsw_sp_qdisc_get_red_stats(struct mlxs
+
+ overlimits = xstats->wred_drop[tclass_num] + xstats->ecn -
+ stats_base->overlimits;
+- drops = xstats->wred_drop[tclass_num] + xstats->tail_drop[tclass_num] -
++ drops = xstats->wred_drop[tclass_num] +
++ mlxsw_sp_xstats_tail_drop(xstats, tclass_num) -
+ stats_base->drops;
+- backlog = xstats->backlog[tclass_num];
++ backlog = mlxsw_sp_xstats_backlog(xstats, tclass_num);
+
+ _bstats_update(stats_ptr->bstats, tx_bytes, tx_packets);
+ stats_ptr->qstats->overlimits += overlimits;
+@@ -575,9 +591,9 @@ mlxsw_sp_qdisc_get_prio_stats(struct mlx
+ tx_packets = stats->tx_packets - stats_base->tx_packets;
+
+ for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
+- drops += xstats->tail_drop[i];
++ drops += mlxsw_sp_xstats_tail_drop(xstats, i);
+ drops += xstats->wred_drop[i];
+- backlog += xstats->backlog[i];
++ backlog += mlxsw_sp_xstats_backlog(xstats, i);
+ }
+ drops = drops - stats_base->drops;
+
+@@ -613,7 +629,7 @@ mlxsw_sp_setup_tc_qdisc_prio_clean_stats
+
+ stats_base->drops = 0;
+ for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
+- stats_base->drops += xstats->tail_drop[i];
++ stats_base->drops += mlxsw_sp_xstats_tail_drop(xstats, i);
+ stats_base->drops += xstats->wred_drop[i];
+ }
+
ptp-free-ptp-device-pin-descriptors-properly.patch
r8152-add-missing-endpoint-sanity-check.patch
tcp-fix-marked-lost-packets-not-being-retransmitted.patch
-wimax-i2400-fix-memory-leak.patch
-wimax-i2400-fix-memory-leak-in-i2400m_op_rfkill_sw_toggle.patch
+sh_eth-check-sh_eth_cpu_data-dual_port-when-dumping-registers.patch
+mlxsw-spectrum-wipe-xstats.backlog-of-down-ports.patch
+mlxsw-spectrum_qdisc-include-mc-tcs-in-qdisc-counters.patch
--- /dev/null
+From 3249b1e442a1be1a6b9f1026785b519d1443f807 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Wed, 8 Jan 2020 23:42:42 +0300
+Subject: sh_eth: check sh_eth_cpu_data::dual_port when dumping registers
+
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+
+commit 3249b1e442a1be1a6b9f1026785b519d1443f807 upstream.
+
+When adding the sh_eth_cpu_data::dual_port flag I forgot to add the flag
+checks to __sh_eth_get_regs(), causing the non-existing TSU registers to
+be dumped by 'ethtool' on the single port Ether controllers having TSU...
+
+Fixes: a94cf2a614f8 ("sh_eth: fix TSU init on SH7734/R8A7740")
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/renesas/sh_eth.c | 38 ++++++++++++++++++----------------
+ 1 file changed, 21 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -2184,24 +2184,28 @@ static size_t __sh_eth_get_regs(struct n
+ if (cd->tsu) {
+ add_tsu_reg(ARSTR);
+ add_tsu_reg(TSU_CTRST);
+- add_tsu_reg(TSU_FWEN0);
+- add_tsu_reg(TSU_FWEN1);
+- add_tsu_reg(TSU_FCM);
+- add_tsu_reg(TSU_BSYSL0);
+- add_tsu_reg(TSU_BSYSL1);
+- add_tsu_reg(TSU_PRISL0);
+- add_tsu_reg(TSU_PRISL1);
+- add_tsu_reg(TSU_FWSL0);
+- add_tsu_reg(TSU_FWSL1);
++ if (cd->dual_port) {
++ add_tsu_reg(TSU_FWEN0);
++ add_tsu_reg(TSU_FWEN1);
++ add_tsu_reg(TSU_FCM);
++ add_tsu_reg(TSU_BSYSL0);
++ add_tsu_reg(TSU_BSYSL1);
++ add_tsu_reg(TSU_PRISL0);
++ add_tsu_reg(TSU_PRISL1);
++ add_tsu_reg(TSU_FWSL0);
++ add_tsu_reg(TSU_FWSL1);
++ }
+ add_tsu_reg(TSU_FWSLC);
+- add_tsu_reg(TSU_QTAGM0);
+- add_tsu_reg(TSU_QTAGM1);
+- add_tsu_reg(TSU_FWSR);
+- add_tsu_reg(TSU_FWINMK);
+- add_tsu_reg(TSU_ADQT0);
+- add_tsu_reg(TSU_ADQT1);
+- add_tsu_reg(TSU_VTAG0);
+- add_tsu_reg(TSU_VTAG1);
++ if (cd->dual_port) {
++ add_tsu_reg(TSU_QTAGM0);
++ add_tsu_reg(TSU_QTAGM1);
++ add_tsu_reg(TSU_FWSR);
++ add_tsu_reg(TSU_FWINMK);
++ add_tsu_reg(TSU_ADQT0);
++ add_tsu_reg(TSU_ADQT1);
++ add_tsu_reg(TSU_VTAG0);
++ add_tsu_reg(TSU_VTAG1);
++ }
+ add_tsu_reg(TSU_ADSBSY);
+ add_tsu_reg(TSU_TEN);
+ add_tsu_reg(TSU_POST1);
+++ /dev/null
-From foo@baz Tue 21 Jan 2020 04:28:01 PM CET
-From: Navid Emamdoost <navid.emamdoost@gmail.com>
-Date: Fri, 25 Oct 2019 23:53:30 -0500
-Subject: wimax: i2400: Fix memory leak in i2400m_op_rfkill_sw_toggle
-
-From: Navid Emamdoost <navid.emamdoost@gmail.com>
-
-[ Upstream commit 6f3ef5c25cc762687a7341c18cbea5af54461407 ]
-
-In the implementation of i2400m_op_rfkill_sw_toggle() the allocated
-buffer for cmd should be released before returning. The
-documentation for i2400m_msg_to_dev() says when it returns the buffer
-can be reused. Meaning cmd should be released in either case. Move
-kfree(cmd) before return to be reached by all execution paths.
-
-Fixes: 2507e6ab7a9a ("wimax: i2400: fix memory leak")
-Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/net/wimax/i2400m/op-rfkill.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/wimax/i2400m/op-rfkill.c
-+++ b/drivers/net/wimax/i2400m/op-rfkill.c
-@@ -142,12 +142,12 @@ int i2400m_op_rfkill_sw_toggle(struct wi
- "%d\n", result);
- result = 0;
- error_cmd:
-- kfree(cmd);
- kfree_skb(ack_skb);
- error_msg_to_dev:
- error_alloc:
- d_fnend(4, dev, "(wimax_dev %p state %d) = %d\n",
- wimax_dev, state, result);
-+ kfree(cmd);
- return result;
- }
-
+++ /dev/null
-From foo@baz Tue 21 Jan 2020 04:28:01 PM CET
-From: Navid Emamdoost <navid.emamdoost@gmail.com>
-Date: Tue, 10 Sep 2019 18:01:40 -0500
-Subject: wimax: i2400: fix memory leak
-
-From: Navid Emamdoost <navid.emamdoost@gmail.com>
-
-[ Upstream commit 2507e6ab7a9a440773be476141a255934468c5ef ]
-
-In i2400m_op_rfkill_sw_toggle cmd buffer should be released along with
-skb response.
-
-Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/net/wimax/i2400m/op-rfkill.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/wimax/i2400m/op-rfkill.c
-+++ b/drivers/net/wimax/i2400m/op-rfkill.c
-@@ -142,6 +142,7 @@ int i2400m_op_rfkill_sw_toggle(struct wi
- "%d\n", result);
- result = 0;
- error_cmd:
-+ kfree(cmd);
- kfree_skb(ack_skb);
- error_msg_to_dev:
- error_alloc: