File Index
Files and directories
Sign in
FILE

sxgbe_mtl.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/samsung/sxgbe/sxgbe_mtl.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/* 10G controller driver for Samsung SoCs
  3 *
  4 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
  5 *		http://www.samsung.com
  6 *
  7 * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
  8 */
  9
 10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 11
 12#include <linux/io.h>
 13#include <linux/errno.h>
 14#include <linux/export.h>
 15#include <linux/jiffies.h>
 16
 17#include "sxgbe_mtl.h"
 18#include "sxgbe_reg.h"
 19
 20static void sxgbe_mtl_init(void __iomem *ioaddr, unsigned int etsalg,
 21			   unsigned int raa)
 22{
 23	u32 reg_val;
 24
 25	reg_val = readl(ioaddr + SXGBE_MTL_OP_MODE_REG);
 26	reg_val &= ETS_RST;
 27
 28	/* ETS Algorith */
 29	switch (etsalg & SXGBE_MTL_OPMODE_ESTMASK) {
 30	case ETS_WRR:
 31		reg_val &= ETS_WRR;
 32		break;
 33	case ETS_WFQ:
 34		reg_val |= ETS_WFQ;
 35		break;
 36	case ETS_DWRR:
 37		reg_val |= ETS_DWRR;
 38		break;
 39	}
 40	writel(reg_val, ioaddr + SXGBE_MTL_OP_MODE_REG);
 41
 42	switch (raa & SXGBE_MTL_OPMODE_RAAMASK) {
 43	case RAA_SP:
 44		reg_val &= RAA_SP;
 45		break;
 46	case RAA_WSP:
 47		reg_val |= RAA_WSP;
 48		break;
 49	}
 50	writel(reg_val, ioaddr + SXGBE_MTL_OP_MODE_REG);
 51}
 52
 53/* For Dynamic DMA channel mapping for Rx queue */
 54static void sxgbe_mtl_dma_dm_rxqueue(void __iomem *ioaddr)
 55{
 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);
 59}
 60
 61static void sxgbe_mtl_set_txfifosize(void __iomem *ioaddr, int queue_num,
 62				     int queue_fifo)
 63{
 64	u32 fifo_bits, reg_val;
 65
 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));
 71}
 72
 73static void sxgbe_mtl_set_rxfifosize(void __iomem *ioaddr, int queue_num,
 74				     int queue_fifo)
 75{
 76	u32 fifo_bits, reg_val;
 77
 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));
 83}
 84
 85static void sxgbe_mtl_enable_txqueue(void __iomem *ioaddr, int queue_num)
 86{
 87	u32 reg_val;
 88
 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));
 92}
 93
 94static void sxgbe_mtl_disable_txqueue(void __iomem *ioaddr, int queue_num)
 95{
 96	u32 reg_val;
 97
 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));
101}
102
103static void sxgbe_mtl_fc_active(void __iomem *ioaddr, int queue_num,
104				int threshold)
105{
106	u32 reg_val;
107
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);
111
112	writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
113}
114
115static void sxgbe_mtl_fc_enable(void __iomem *ioaddr, int queue_num)
116{
117	u32 reg_val;
118
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));
122}
123
124static void sxgbe_mtl_fc_deactive(void __iomem *ioaddr, int queue_num,
125				  int threshold)
126{
127	u32 reg_val;
128
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);
132
133	writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
134}
135
136static void sxgbe_mtl_fep_enable(void __iomem *ioaddr, int queue_num)
137{
138	u32 reg_val;
139
140	reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
141	reg_val |= SXGBE_MTL_RXQ_OP_FEP;
142
143	writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
144}
145
146static void sxgbe_mtl_fep_disable(void __iomem *ioaddr, int queue_num)
147{
148	u32 reg_val;
149
150	reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
151	reg_val &= ~(SXGBE_MTL_RXQ_OP_FEP);
152
153	writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
154}
155
156static void sxgbe_mtl_fup_enable(void __iomem *ioaddr, int queue_num)
157{
158	u32 reg_val;
159
160	reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
161	reg_val |= SXGBE_MTL_RXQ_OP_FUP;
162
163	writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
164}
165
166static void sxgbe_mtl_fup_disable(void __iomem *ioaddr, int queue_num)
167{
168	u32 reg_val;
169
170	reg_val = readl(ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
171	reg_val &= ~(SXGBE_MTL_RXQ_OP_FUP);
172
173	writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
174}
175
176
177static void sxgbe_set_tx_mtl_mode(void __iomem *ioaddr, int queue_num,
178				  int tx_mode)
179{
180	u32 reg_val;
181
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;
186	} else {
187		/* set the TTC values */
188		if (tx_mode <= 64)
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;
200		else
201			reg_val |= MTL_CONTROL_TTC_512;
202	}
203
204	/* write into TXQ operation register */
205	writel(reg_val, ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num));
206}
207
208static void sxgbe_set_rx_mtl_mode(void __iomem *ioaddr, int queue_num,
209				  int rx_mode)
210{
211	u32 reg_val;
212
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;
217	} else {
218		if (rx_mode <= 64)
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;
224	}
225
226	/* write into RXQ operation register */
227	writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num));
228}
229
230static 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
246};
247
248const struct sxgbe_mtl_ops *sxgbe_get_mtl_ops(void)
249{
250	return &mtl_ops;
251}
~/ Read-only file preview.