]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-6.1/net-stmmac-fix-rx-queue-priority-assignment.patch
6.1-stable patches
[thirdparty/kernel/stable-queue.git] / queue-6.1 / net-stmmac-fix-rx-queue-priority-assignment.patch
1 From b3da86d432b7cd65b025a11f68613e333d2483db Mon Sep 17 00:00:00 2001
2 From: Piotr Wejman <piotrwejman90@gmail.com>
3 Date: Mon, 1 Apr 2024 21:22:39 +0200
4 Subject: net: stmmac: fix rx queue priority assignment
5
6 From: Piotr Wejman <piotrwejman90@gmail.com>
7
8 commit b3da86d432b7cd65b025a11f68613e333d2483db upstream.
9
10 The driver should ensure that same priority is not mapped to multiple
11 rx queues. From DesignWare Cores Ethernet Quality-of-Service
12 Databook, section 17.1.29 MAC_RxQ_Ctrl2:
13 "[...]The software must ensure that the content of this field is
14 mutually exclusive to the PSRQ fields for other queues, that is,
15 the same priority is not mapped to multiple Rx queues[...]"
16
17 Previously rx_queue_priority() function was:
18 - clearing all priorities from a queue
19 - adding new priorities to that queue
20 After this patch it will:
21 - first assign new priorities to a queue
22 - then remove those priorities from all other queues
23 - keep other priorities previously assigned to that queue
24
25 Fixes: a8f5102af2a7 ("net: stmmac: TX and RX queue priority configuration")
26 Fixes: 2142754f8b9c ("net: stmmac: Add MAC related callbacks for XGMAC2")
27 Signed-off-by: Piotr Wejman <piotrwejman90@gmail.com>
28 Link: https://lore.kernel.org/r/20240401192239.33942-1-piotrwejman90@gmail.com
29 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
30 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
31 ---
32 drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 40 +++++++++++++++-----
33 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 38 +++++++++++++++----
34 2 files changed, 62 insertions(+), 16 deletions(-)
35
36 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
37 +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
38 @@ -87,19 +87,41 @@ static void dwmac4_rx_queue_priority(str
39 u32 prio, u32 queue)
40 {
41 void __iomem *ioaddr = hw->pcsr;
42 - u32 base_register;
43 - u32 value;
44 + u32 clear_mask = 0;
45 + u32 ctrl2, ctrl3;
46 + int i;
47
48 - base_register = (queue < 4) ? GMAC_RXQ_CTRL2 : GMAC_RXQ_CTRL3;
49 - if (queue >= 4)
50 - queue -= 4;
51 + ctrl2 = readl(ioaddr + GMAC_RXQ_CTRL2);
52 + ctrl3 = readl(ioaddr + GMAC_RXQ_CTRL3);
53 +
54 + /* The software must ensure that the same priority
55 + * is not mapped to multiple Rx queues
56 + */
57 + for (i = 0; i < 4; i++)
58 + clear_mask |= ((prio << GMAC_RXQCTRL_PSRQX_SHIFT(i)) &
59 + GMAC_RXQCTRL_PSRQX_MASK(i));
60
61 - value = readl(ioaddr + base_register);
62 + ctrl2 &= ~clear_mask;
63 + ctrl3 &= ~clear_mask;
64
65 - value &= ~GMAC_RXQCTRL_PSRQX_MASK(queue);
66 - value |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
67 + /* First assign new priorities to a queue, then
68 + * clear them from others queues
69 + */
70 + if (queue < 4) {
71 + ctrl2 |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
72 GMAC_RXQCTRL_PSRQX_MASK(queue);
73 - writel(value, ioaddr + base_register);
74 +
75 + writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2);
76 + writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3);
77 + } else {
78 + queue -= 4;
79 +
80 + ctrl3 |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
81 + GMAC_RXQCTRL_PSRQX_MASK(queue);
82 +
83 + writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3);
84 + writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2);
85 + }
86 }
87
88 static void dwmac4_tx_queue_priority(struct mac_device_info *hw,
89 --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
90 +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
91 @@ -97,17 +97,41 @@ static void dwxgmac2_rx_queue_prio(struc
92 u32 queue)
93 {
94 void __iomem *ioaddr = hw->pcsr;
95 - u32 value, reg;
96 + u32 clear_mask = 0;
97 + u32 ctrl2, ctrl3;
98 + int i;
99
100 - reg = (queue < 4) ? XGMAC_RXQ_CTRL2 : XGMAC_RXQ_CTRL3;
101 - if (queue >= 4)
102 + ctrl2 = readl(ioaddr + XGMAC_RXQ_CTRL2);
103 + ctrl3 = readl(ioaddr + XGMAC_RXQ_CTRL3);
104 +
105 + /* The software must ensure that the same priority
106 + * is not mapped to multiple Rx queues
107 + */
108 + for (i = 0; i < 4; i++)
109 + clear_mask |= ((prio << XGMAC_PSRQ_SHIFT(i)) &
110 + XGMAC_PSRQ(i));
111 +
112 + ctrl2 &= ~clear_mask;
113 + ctrl3 &= ~clear_mask;
114 +
115 + /* First assign new priorities to a queue, then
116 + * clear them from others queues
117 + */
118 + if (queue < 4) {
119 + ctrl2 |= (prio << XGMAC_PSRQ_SHIFT(queue)) &
120 + XGMAC_PSRQ(queue);
121 +
122 + writel(ctrl2, ioaddr + XGMAC_RXQ_CTRL2);
123 + writel(ctrl3, ioaddr + XGMAC_RXQ_CTRL3);
124 + } else {
125 queue -= 4;
126
127 - value = readl(ioaddr + reg);
128 - value &= ~XGMAC_PSRQ(queue);
129 - value |= (prio << XGMAC_PSRQ_SHIFT(queue)) & XGMAC_PSRQ(queue);
130 + ctrl3 |= (prio << XGMAC_PSRQ_SHIFT(queue)) &
131 + XGMAC_PSRQ(queue);
132
133 - writel(value, ioaddr + reg);
134 + writel(ctrl3, ioaddr + XGMAC_RXQ_CTRL3);
135 + writel(ctrl2, ioaddr + XGMAC_RXQ_CTRL2);
136 + }
137 }
138
139 static void dwxgmac2_tx_queue_prio(struct mac_device_info *hw, u32 prio,