1
2
3
4
5
6
7
8
9
10
11
12
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
15#include <linux/io.h>
16#include <linux/errno.h>
17#include <linux/export.h>
18#include <linux/jiffies.h>
19
20#include "sxgbe_mtl.h"
21#include "sxgbe_reg.h"
22
23static void sxgbe_mtl_init(void __iomem *ioaddr, unsigned int etsalg,
24 unsigned int raa)
25{
26 u32 reg_val;
27
28 reg_val = readl(ioaddr + SXGBE_MTL_OP_MODE_REG);
29 reg_val &= ETS_RST;
30
31
32 switch (etsalg & SXGBE_MTL_OPMODE_ESTMASK) {
33 case ETS_WRR:
34 reg_val &= ETS_WRR;
35 break;
36 case ETS_WFQ:
37 reg_val |= ETS_WFQ;
38 break;
39 case ETS_DWRR:
40 reg_val |= ETS_DWRR;
41 break;
42 }
43 writel(reg_val, ioaddr + SXGBE_MTL_OP_MODE_REG);
44
45 switch (raa & SXGBE_MTL_OPMODE_RAAMASK) {
46 case RAA_SP:
47 reg_val &= RAA_SP;
48 break;
49 case RAA_WSP:
50 reg_val |= RAA_WSP;
51 break;
52 }
53 writel(reg_val, ioaddr + SXGBE_MTL_OP_MODE_REG);
54}
55
56
57static void sxgbe_mtl_dma_dm_rxqueue(void __iomem *ioaddr)
58{
59 writel(RX_QUEUE_DYNAMIC, ioaddr + SXGBE_MTL_RXQ_DMAMAP0_REG);
60 writel(RX_QUEUE_DYNAMIC, ioaddr + SXGBE_MTL_RXQ_DMAMAP1_REG);
61 writel(RX_QUEUE_DYNAMIC, ioaddr + SXGBE_MTL_RXQ_DMAMAP2_REG);
62}
63
64static void sxgbe_mtl_set_txfifosize(void __iomem *ioaddr, int queue_num,
65 int queue_fifo)
66{
67 u32 fifo_bits, reg_val;
68
69
70 fifo_bits = (queue_fifo / SXGBE_MTL_TX_FIFO_DIV) - 1;
71 reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
72 reg_val |= (fifo_bits << SXGBE_MTL_FIFO_LSHIFT);
73 writel(reg_val, ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
74}
75
76static void sxgbe_mtl_set_rxfifosize(void __iomem *ioaddr, int queue_num,
77 int queue_fifo)
78{
79 u32 fifo_bits, reg_val;
80
81
82 fifo_bits = (queue_fifo / SXGBE_MTL_RX_FIFO_DIV)-1;
83 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
84 reg_val |= (fifo_bits << SXGBE_MTL_FIFO_LSHIFT);
85 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
86}
87
88static void sxgbe_mtl_enable_txqueue(void __iomem *ioaddr, int queue_num)
89{
90 u32 reg_val;
91
92 reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
93 reg_val |= SXGBE_MTL_ENABLE_QUEUE;
94 writel(reg_val, ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
95}
96
97static void sxgbe_mtl_disable_txqueue(void __iomem *ioaddr, int queue_num)
98{
99 u32 reg_val;
100
101 reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
102 reg_val &= ~SXGBE_MTL_ENABLE_QUEUE;
103 writel(reg_val, ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
104}
105
106static void sxgbe_mtl_fc_active(void __iomem *ioaddr, int queue_num,
107 int threshold)
108{
109 u32 reg_val;
110
111 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
112 reg_val &= ~(SXGBE_MTL_FCMASK << RX_FC_ACTIVE);
113 reg_val |= (threshold << RX_FC_ACTIVE);
114
115 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
116}
117
118static void sxgbe_mtl_fc_enable(void __iomem *ioaddr, int queue_num)
119{
120 u32 reg_val;
121
122 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
123 reg_val |= SXGBE_MTL_ENABLE_FC;
124 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
125}
126
127static void sxgbe_mtl_fc_deactive(void __iomem *ioaddr, int queue_num,
128 int threshold)
129{
130 u32 reg_val;
131
132 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
133 reg_val &= ~(SXGBE_MTL_FCMASK << RX_FC_DEACTIVE);
134 reg_val |= (threshold << RX_FC_DEACTIVE);
135
136 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
137}
138
139static void sxgbe_mtl_fep_enable(void __iomem *ioaddr, int queue_num)
140{
141 u32 reg_val;
142
143 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
144 reg_val |= SXGBE_MTL_RXQ_OP_FEP;
145
146 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
147}
148
149static void sxgbe_mtl_fep_disable(void __iomem *ioaddr, int queue_num)
150{
151 u32 reg_val;
152
153 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
154 reg_val &= ~(SXGBE_MTL_RXQ_OP_FEP);
155
156 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
157}
158
159static void sxgbe_mtl_fup_enable(void __iomem *ioaddr, int queue_num)
160{
161 u32 reg_val;
162
163 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
164 reg_val |= SXGBE_MTL_RXQ_OP_FUP;
165
166 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
167}
168
169static void sxgbe_mtl_fup_disable(void __iomem *ioaddr, int queue_num)
170{
171 u32 reg_val;
172
173 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
174 reg_val &= ~(SXGBE_MTL_RXQ_OP_FUP);
175
176 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
177}
178
179
180static void sxgbe_set_tx_mtl_mode(void __iomem *ioaddr, int queue_num,
181 int tx_mode)
182{
183 u32 reg_val;
184
185 reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
186
187 if (tx_mode == SXGBE_MTL_SFMODE) {
188 reg_val |= SXGBE_MTL_SFMODE;
189 } else {
190
191 if (tx_mode <= 64)
192 reg_val |= MTL_CONTROL_TTC_64;
193 else if (tx_mode <= 96)
194 reg_val |= MTL_CONTROL_TTC_96;
195 else if (tx_mode <= 128)
196 reg_val |= MTL_CONTROL_TTC_128;
197 else if (tx_mode <= 192)
198 reg_val |= MTL_CONTROL_TTC_192;
199 else if (tx_mode <= 256)
200 reg_val |= MTL_CONTROL_TTC_256;
201 else if (tx_mode <= 384)
202 reg_val |= MTL_CONTROL_TTC_384;
203 else
204 reg_val |= MTL_CONTROL_TTC_512;
205 }
206
207
208 writel(reg_val, ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
209}
210
211static void sxgbe_set_rx_mtl_mode(void __iomem *ioaddr, int queue_num,
212 int rx_mode)
213{
214 u32 reg_val;
215
216 reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
217
218 if (rx_mode == SXGBE_RX_MTL_SFMODE) {
219 reg_val |= SXGBE_RX_MTL_SFMODE;
220 } else {
221 if (rx_mode <= 64)
222 reg_val |= MTL_CONTROL_RTC_64;
223 else if (rx_mode <= 96)
224 reg_val |= MTL_CONTROL_RTC_96;
225 else if (rx_mode <= 128)
226 reg_val |= MTL_CONTROL_RTC_128;
227 }
228
229
230 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
231}
232
233static const struct sxgbe_mtl_ops mtl_ops = {
234 .mtl_set_txfifosize = sxgbe_mtl_set_txfifosize,
235 .mtl_set_rxfifosize = sxgbe_mtl_set_rxfifosize,
236 .mtl_enable_txqueue = sxgbe_mtl_enable_txqueue,
237 .mtl_disable_txqueue = sxgbe_mtl_disable_txqueue,
238 .mtl_dynamic_dma_rxqueue = sxgbe_mtl_dma_dm_rxqueue,
239 .set_tx_mtl_mode = sxgbe_set_tx_mtl_mode,
240 .set_rx_mtl_mode = sxgbe_set_rx_mtl_mode,
241 .mtl_init = sxgbe_mtl_init,
242 .mtl_fc_active = sxgbe_mtl_fc_active,
243 .mtl_fc_deactive = sxgbe_mtl_fc_deactive,
244 .mtl_fc_enable = sxgbe_mtl_fc_enable,
245 .mtl_fep_enable = sxgbe_mtl_fep_enable,
246 .mtl_fep_disable = sxgbe_mtl_fep_disable,
247 .mtl_fup_enable = sxgbe_mtl_fup_enable,
248 .mtl_fup_disable = sxgbe_mtl_fup_disable
249};
250
251const struct sxgbe_mtl_ops *sxgbe_get_mtl_ops(void)
252{
253 return &mtl_ops;
254}
255