1 // SPDX-License-Identifier: GPL-2.0-only
2 /* 10G controller driver for Samsung SoCs
4 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
7 * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 #include <linux/errno.h>
14 #include <linux/export.h>
15 #include <linux/jiffies.h>
17 #include "sxgbe_mtl.h"
18 #include "sxgbe_reg.h"
20 static void sxgbe_mtl_init(void __iomem
*ioaddr
, unsigned int etsalg
,
25 reg_val
= readl(ioaddr
+ SXGBE_MTL_OP_MODE_REG
);
29 switch (etsalg
& SXGBE_MTL_OPMODE_ESTMASK
) {
40 writel(reg_val
, ioaddr
+ SXGBE_MTL_OP_MODE_REG
);
42 switch (raa
& SXGBE_MTL_OPMODE_RAAMASK
) {
50 writel(reg_val
, ioaddr
+ SXGBE_MTL_OP_MODE_REG
);
53 /* For Dynamic DMA channel mapping for Rx queue */
54 static void sxgbe_mtl_dma_dm_rxqueue(void __iomem
*ioaddr
)
56 writel(RX_QUEUE_DYNAMIC
, ioaddr
+ SXGBE_MTL_RXQ_DMAMAP0_REG
);
57 writel(RX_QUEUE_DYNAMIC
, ioaddr
+ SXGBE_MTL_RXQ_DMAMAP1_REG
);
58 writel(RX_QUEUE_DYNAMIC
, ioaddr
+ SXGBE_MTL_RXQ_DMAMAP2_REG
);
61 static void sxgbe_mtl_set_txfifosize(void __iomem
*ioaddr
, int queue_num
,
64 u32 fifo_bits
, reg_val
;
66 /* 0 means 256 bytes */
67 fifo_bits
= (queue_fifo
/ SXGBE_MTL_TX_FIFO_DIV
) - 1;
68 reg_val
= readl(ioaddr
+ SXGBE_MTL_TXQ_OPMODE_REG(queue_num
));
69 reg_val
|= (fifo_bits
<< SXGBE_MTL_FIFO_LSHIFT
);
70 writel(reg_val
, ioaddr
+ SXGBE_MTL_TXQ_OPMODE_REG(queue_num
));
73 static void sxgbe_mtl_set_rxfifosize(void __iomem
*ioaddr
, int queue_num
,
76 u32 fifo_bits
, reg_val
;
78 /* 0 means 256 bytes */
79 fifo_bits
= (queue_fifo
/ SXGBE_MTL_RX_FIFO_DIV
)-1;
80 reg_val
= readl(ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
81 reg_val
|= (fifo_bits
<< SXGBE_MTL_FIFO_LSHIFT
);
82 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
85 static void sxgbe_mtl_enable_txqueue(void __iomem
*ioaddr
, int queue_num
)
89 reg_val
= readl(ioaddr
+ SXGBE_MTL_TXQ_OPMODE_REG(queue_num
));
90 reg_val
|= SXGBE_MTL_ENABLE_QUEUE
;
91 writel(reg_val
, ioaddr
+ SXGBE_MTL_TXQ_OPMODE_REG(queue_num
));
94 static void sxgbe_mtl_disable_txqueue(void __iomem
*ioaddr
, int queue_num
)
98 reg_val
= readl(ioaddr
+ SXGBE_MTL_TXQ_OPMODE_REG(queue_num
));
99 reg_val
&= ~SXGBE_MTL_ENABLE_QUEUE
;
100 writel(reg_val
, ioaddr
+ SXGBE_MTL_TXQ_OPMODE_REG(queue_num
));
103 static void sxgbe_mtl_fc_active(void __iomem
*ioaddr
, int queue_num
,
108 reg_val
= readl(ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
109 reg_val
&= ~(SXGBE_MTL_FCMASK
<< RX_FC_ACTIVE
);
110 reg_val
|= (threshold
<< RX_FC_ACTIVE
);
112 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
115 static void sxgbe_mtl_fc_enable(void __iomem
*ioaddr
, int queue_num
)
119 reg_val
= readl(ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
120 reg_val
|= SXGBE_MTL_ENABLE_FC
;
121 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
124 static void sxgbe_mtl_fc_deactive(void __iomem
*ioaddr
, int queue_num
,
129 reg_val
= readl(ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
130 reg_val
&= ~(SXGBE_MTL_FCMASK
<< RX_FC_DEACTIVE
);
131 reg_val
|= (threshold
<< RX_FC_DEACTIVE
);
133 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
136 static void sxgbe_mtl_fep_enable(void __iomem
*ioaddr
, int queue_num
)
140 reg_val
= readl(ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
141 reg_val
|= SXGBE_MTL_RXQ_OP_FEP
;
143 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
146 static void sxgbe_mtl_fep_disable(void __iomem
*ioaddr
, int queue_num
)
150 reg_val
= readl(ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
151 reg_val
&= ~(SXGBE_MTL_RXQ_OP_FEP
);
153 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
156 static void sxgbe_mtl_fup_enable(void __iomem
*ioaddr
, int queue_num
)
160 reg_val
= readl(ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
161 reg_val
|= SXGBE_MTL_RXQ_OP_FUP
;
163 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
166 static void sxgbe_mtl_fup_disable(void __iomem
*ioaddr
, int queue_num
)
170 reg_val
= readl(ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
171 reg_val
&= ~(SXGBE_MTL_RXQ_OP_FUP
);
173 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
177 static void sxgbe_set_tx_mtl_mode(void __iomem
*ioaddr
, int queue_num
,
182 reg_val
= readl(ioaddr
+ SXGBE_MTL_TXQ_OPMODE_REG(queue_num
));
183 /* TX specific MTL mode settings */
184 if (tx_mode
== SXGBE_MTL_SFMODE
) {
185 reg_val
|= SXGBE_MTL_SFMODE
;
187 /* set the TTC values */
189 reg_val
|= MTL_CONTROL_TTC_64
;
190 else if (tx_mode
<= 96)
191 reg_val
|= MTL_CONTROL_TTC_96
;
192 else if (tx_mode
<= 128)
193 reg_val
|= MTL_CONTROL_TTC_128
;
194 else if (tx_mode
<= 192)
195 reg_val
|= MTL_CONTROL_TTC_192
;
196 else if (tx_mode
<= 256)
197 reg_val
|= MTL_CONTROL_TTC_256
;
198 else if (tx_mode
<= 384)
199 reg_val
|= MTL_CONTROL_TTC_384
;
201 reg_val
|= MTL_CONTROL_TTC_512
;
204 /* write into TXQ operation register */
205 writel(reg_val
, ioaddr
+ SXGBE_MTL_TXQ_OPMODE_REG(queue_num
));
208 static void sxgbe_set_rx_mtl_mode(void __iomem
*ioaddr
, int queue_num
,
213 reg_val
= readl(ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
214 /* RX specific MTL mode settings */
215 if (rx_mode
== SXGBE_RX_MTL_SFMODE
) {
216 reg_val
|= SXGBE_RX_MTL_SFMODE
;
219 reg_val
|= MTL_CONTROL_RTC_64
;
220 else if (rx_mode
<= 96)
221 reg_val
|= MTL_CONTROL_RTC_96
;
222 else if (rx_mode
<= 128)
223 reg_val
|= MTL_CONTROL_RTC_128
;
226 /* write into RXQ operation register */
227 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
230 static const struct sxgbe_mtl_ops mtl_ops
= {
231 .mtl_set_txfifosize
= sxgbe_mtl_set_txfifosize
,
232 .mtl_set_rxfifosize
= sxgbe_mtl_set_rxfifosize
,
233 .mtl_enable_txqueue
= sxgbe_mtl_enable_txqueue
,
234 .mtl_disable_txqueue
= sxgbe_mtl_disable_txqueue
,
235 .mtl_dynamic_dma_rxqueue
= sxgbe_mtl_dma_dm_rxqueue
,
236 .set_tx_mtl_mode
= sxgbe_set_tx_mtl_mode
,
237 .set_rx_mtl_mode
= sxgbe_set_rx_mtl_mode
,
238 .mtl_init
= sxgbe_mtl_init
,
239 .mtl_fc_active
= sxgbe_mtl_fc_active
,
240 .mtl_fc_deactive
= sxgbe_mtl_fc_deactive
,
241 .mtl_fc_enable
= sxgbe_mtl_fc_enable
,
242 .mtl_fep_enable
= sxgbe_mtl_fep_enable
,
243 .mtl_fep_disable
= sxgbe_mtl_fep_disable
,
244 .mtl_fup_enable
= sxgbe_mtl_fup_enable
,
245 .mtl_fup_disable
= sxgbe_mtl_fup_disable
248 const struct sxgbe_mtl_ops
*sxgbe_get_mtl_ops(void)