1 /* 10G controller driver for Samsung SoCs
3 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
6 * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16 #include <linux/errno.h>
17 #include <linux/export.h>
18 #include <linux/jiffies.h>
20 #include "sxgbe_mtl.h"
21 #include "sxgbe_reg.h"
23 static void sxgbe_mtl_init(void __iomem
*ioaddr
, unsigned int etsalg
,
28 reg_val
= readl(ioaddr
+ SXGBE_MTL_OP_MODE_REG
);
32 switch (etsalg
& SXGBE_MTL_OPMODE_ESTMASK
) {
43 writel(reg_val
, ioaddr
+ SXGBE_MTL_OP_MODE_REG
);
45 switch (raa
& SXGBE_MTL_OPMODE_RAAMASK
) {
53 writel(reg_val
, ioaddr
+ SXGBE_MTL_OP_MODE_REG
);
56 /* For Dynamic DMA channel mapping for Rx queue */
57 static void sxgbe_mtl_dma_dm_rxqueue(void __iomem
*ioaddr
)
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
);
64 static void sxgbe_mtl_set_txfifosize(void __iomem
*ioaddr
, int queue_num
,
67 u32 fifo_bits
, reg_val
;
69 /* 0 means 256 bytes */
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
));
76 static void sxgbe_mtl_set_rxfifosize(void __iomem
*ioaddr
, int queue_num
,
79 u32 fifo_bits
, reg_val
;
81 /* 0 means 256 bytes */
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
));
88 static void sxgbe_mtl_enable_txqueue(void __iomem
*ioaddr
, int queue_num
)
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
));
97 static void sxgbe_mtl_disable_txqueue(void __iomem
*ioaddr
, int queue_num
)
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
));
106 static void sxgbe_mtl_fc_active(void __iomem
*ioaddr
, int queue_num
,
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
);
115 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
118 static void sxgbe_mtl_fc_enable(void __iomem
*ioaddr
, int queue_num
)
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
));
127 static void sxgbe_mtl_fc_deactive(void __iomem
*ioaddr
, int queue_num
,
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
);
136 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
139 static void sxgbe_mtl_fep_enable(void __iomem
*ioaddr
, int queue_num
)
143 reg_val
= readl(ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
144 reg_val
|= SXGBE_MTL_RXQ_OP_FEP
;
146 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
149 static void sxgbe_mtl_fep_disable(void __iomem
*ioaddr
, int queue_num
)
153 reg_val
= readl(ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
154 reg_val
&= ~(SXGBE_MTL_RXQ_OP_FEP
);
156 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
159 static void sxgbe_mtl_fup_enable(void __iomem
*ioaddr
, int queue_num
)
163 reg_val
= readl(ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
164 reg_val
|= SXGBE_MTL_RXQ_OP_FUP
;
166 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
169 static void sxgbe_mtl_fup_disable(void __iomem
*ioaddr
, int queue_num
)
173 reg_val
= readl(ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
174 reg_val
&= ~(SXGBE_MTL_RXQ_OP_FUP
);
176 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
180 static void sxgbe_set_tx_mtl_mode(void __iomem
*ioaddr
, int queue_num
,
185 reg_val
= readl(ioaddr
+ SXGBE_MTL_TXQ_OPMODE_REG(queue_num
));
186 /* TX specific MTL mode settings */
187 if (tx_mode
== SXGBE_MTL_SFMODE
) {
188 reg_val
|= SXGBE_MTL_SFMODE
;
190 /* set the TTC values */
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
;
204 reg_val
|= MTL_CONTROL_TTC_512
;
207 /* write into TXQ operation register */
208 writel(reg_val
, ioaddr
+ SXGBE_MTL_TXQ_OPMODE_REG(queue_num
));
211 static void sxgbe_set_rx_mtl_mode(void __iomem
*ioaddr
, int queue_num
,
216 reg_val
= readl(ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
217 /* RX specific MTL mode settings */
218 if (rx_mode
== SXGBE_RX_MTL_SFMODE
) {
219 reg_val
|= SXGBE_RX_MTL_SFMODE
;
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
;
229 /* write into RXQ operation register */
230 writel(reg_val
, ioaddr
+ SXGBE_MTL_RXQ_OPMODE_REG(queue_num
));
233 static 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
251 const struct sxgbe_mtl_ops
*sxgbe_get_mtl_ops(void)