]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blob - drivers/net/ethernet/samsung/sxgbe/sxgbe_mtl.c
Merge branch 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux...
[mirror_ubuntu-hirsute-kernel.git] / drivers / net / ethernet / samsung / sxgbe / sxgbe_mtl.c
1 /* 10G controller driver for Samsung SoCs
2 *
3 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
7 *
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.
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
23 static 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 /* ETS Algorith */
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 /* For Dynamic DMA channel mapping for Rx queue */
57 static 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
64 static void sxgbe_mtl_set_txfifosize(void __iomem *ioaddr, int queue_num,
65 int queue_fifo)
66 {
67 u32 fifo_bits, reg_val;
68
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));
74 }
75
76 static void sxgbe_mtl_set_rxfifosize(void __iomem *ioaddr, int queue_num,
77 int queue_fifo)
78 {
79 u32 fifo_bits, reg_val;
80
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));
86 }
87
88 static 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
97 static 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
106 static 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
118 static 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
127 static 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
139 static 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
149 static 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
159 static 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
169 static 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
180 static 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 /* TX specific MTL mode settings */
187 if (tx_mode == SXGBE_MTL_SFMODE) {
188 reg_val |= SXGBE_MTL_SFMODE;
189 } else {
190 /* set the TTC values */
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 /* write into TXQ operation register */
208 writel(reg_val, ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
209 }
210
211 static 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 /* RX specific MTL mode settings */
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 /* write into RXQ operation register */
230 writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
231 }
232
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
249 };
250
251 const struct sxgbe_mtl_ops *sxgbe_get_mtl_ops(void)
252 {
253 return &mtl_ops;
254 }