blob: 69b6a4c398ee2803e68ccf565b8e3dce77e9bad1 [file] [log] [blame]
Ke Dong32248e72012-09-26 19:22:56 -07001/*******************************************************************************
2Copyright (C) Marvell International Ltd. and its affiliates
3
4This software file (the "File") is owned and distributed by Marvell
5International Ltd. and/or its affiliates ("Marvell") under the following
6alternative licensing terms. Once you have made an election to distribute the
7File under one of the following license alternatives, please (i) delete this
8introductory statement regarding license alternatives, (ii) delete the two
9license alternatives that you have not elected to use and (iii) preserve the
10Marvell copyright notice above.
11
12********************************************************************************
13Marvell Commercial License Option
14
15If you received this File from Marvell and you have entered into a commercial
16license agreement (a "Commercial License") with Marvell, the File is licensed
17to you under the terms of the applicable Commercial License.
18
19********************************************************************************
20Marvell GPL License Option
21
22If you received this File from Marvell, you may opt to use, redistribute and/or
23modify this File in accordance with the terms and conditions of the General
24Public License Version 2, June 1991 (the "GPL License"), a copy of which is
25available along with the File in the license.txt file or by writing to the Free
26Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
27on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
28
29THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
30WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
31DISCLAIMED. The GPL License provides additional details about this warranty
32disclaimer.
33********************************************************************************
34Marvell BSD License Option
35
36If you received this File from Marvell, you may opt to use, redistribute and/or
37modify this File under the following licensing terms.
38Redistribution and use in source and binary forms, with or without modification,
39are permitted provided that the following conditions are met:
40
41 * Redistributions of source code must retain the above copyright notice,
42 this list of conditions and the following disclaimer.
43
44 * Redistributions in binary form must reproduce the above copyright
45 notice, this list of conditions and the following disclaimer in the
46 documentation and/or other materials provided with the distribution.
47
48 * Neither the name of Marvell nor the names of its contributors may be
49 used to endorse or promote products derived from this software without
50 specific prior written permission.
51
52THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
53ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
54WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
56ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
59ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62
63*******************************************************************************/
64
65#include "mvCommon.h" /* Should be included before mvSysHwConfig */
66#include "mvTypes.h"
67#include "mvDebug.h"
68#include "mvOs.h"
69#include "mvNeta.h"
70#include "bm/mvBm.h"
71
72/*#define HWF_DBG mvOsPrintf*/
73#define HWF_DBG(X...)
74
75/*******************************************************************************
76* mvNetaHwfInit - Init HWF registers of the port
77* DESCRIPTION:
78*
79* INPUT:
80* int port - NETA port number
81*
82* RETURN: MV_STATUS
83* MV_OK - Success, Others - Failure
84*
85* NOTE:
86*******************************************************************************/
87MV_STATUS mvNetaHwfInit(int port)
88{
89 int p, txp;
90 MV_U32 regVal;
91 MV_NETA_PORT_CTRL *pPortCtrl;
92
93 if ((port < 0) || (port >= mvNetaHalData.maxPort)) {
94 mvOsPrintf("%s: port %d is out of range\n", __func__, port);
95 return MV_OUT_OF_RANGE;
96 }
97
98 pPortCtrl = mvNetaPortHndlGet(port);
99 if (pPortCtrl == NULL) {
100 mvOsPrintf("%s: port %d is not initialized\n", __func__, port);
101 return MV_FAIL;
102 }
103
104 /* Set TX Port base addresses */
105 for (p = 0; p < mvNetaHalData.maxPort; p++) {
106 pPortCtrl = mvNetaPortHndlGet(p);
107 if (pPortCtrl == NULL)
108 continue;
109
110 for (txp = 0; txp < pPortCtrl->txpNum; txp++) {
111 regVal = MV_REG_READ(NETA_HWF_TXP_CFG_REG(port, (p + txp)));
112 regVal &= ~NETA_TXP_BASE_ADDR_MASK(p + txp);
113 regVal |= ((NETA_TX_REG_BASE(p, txp) >> 10) << NETA_TXP_BASE_ADDR_OFFS(p + txp));
114 MV_REG_WRITE(NETA_HWF_TXP_CFG_REG(port, (p + txp)), regVal);
115 }
116 }
117 /* Init HWF RX Control register */
118 regVal = NETA_GEM_PID_SRC_FLOW_ID;
119 MV_REG_WRITE(NETA_HWF_RX_CTRL_REG(port), regVal);
120
121 /* Set Small TX Gap */
122 MV_REG_WRITE(NETA_HWF_TX_GAP_REG(port), NETA_HWF_SMALL_TX_GAP_MASK);
123
124 return MV_OK;
125}
126
127/*******************************************************************************
128 * mvNetaHwfBmPoolsSet - Set short and long pools to be used by HWF of the port
129 *
130 * INPUT:
131 * int port - port number
132 * int short_pool - BM pool for short buffers
133 * int long_pool - BM pool for long buffers
134 *
135 * RETURN: MV_STATUS
136 * MV_OK - Success, Others - Failure
137 *
138 *******************************************************************************/
139MV_STATUS mvNetaHwfBmPoolsSet(int port, int short_pool, int long_pool)
140{
141 MV_U32 regVal;
142
143 regVal = MV_REG_READ(NETA_HWF_RX_CTRL_REG(port));
144
145 regVal &= ~NETA_HWF_LONG_POOL_MASK;
146 regVal |= NETA_HWF_LONG_POOL_ID(long_pool);
147
148 regVal &= ~NETA_HWF_SHORT_POOL_MASK;
149 regVal |= NETA_HWF_SHORT_POOL_ID(short_pool);
150
151 MV_REG_WRITE(NETA_HWF_RX_CTRL_REG(port), regVal);
152
153 return MV_OK;
154}
155
156/*******************************************************************************
157 * mvNetaHwfEnable - Enable / Disable HWF of the port
158 * DESCRIPTION:
159 *
160 * INPUT:
161 * int port - port number
162 * int enable - 0 - disable, 1 - enable
163 *
164 * RETURN: MV_STATUS
165 * MV_OK - Success, Others - Failure
166 *
167 * NOTE:
168 *******************************************************************************/
169MV_STATUS mvNetaHwfEnable(int port, int enable)
170{
171 MV_U32 regVal;
172
173 regVal = MV_REG_READ(NETA_HWF_RX_CTRL_REG(port));
174 if (enable)
175 regVal |= NETA_HWF_ENABLE_MASK;
176 else
177 regVal &= ~NETA_HWF_ENABLE_MASK;
178
179 MV_REG_WRITE(NETA_HWF_RX_CTRL_REG(port), regVal);
180
181 return MV_OK;
182}
183
184/*******************************************************************************
185 * mvNetaHwfTxqInit - Set TXQ base address and size, set default Drop configuration
186 * DESCRIPTION:
187 *
188 * INPUT:
189 * int rx_port: RX port number
190 * int tx_port, txp, txq: port, TCONT and TXQ numbers
191 *
192 * RETURN: MV_STATUS
193 * MV_OK - Success, Others - Failure
194 *
195 * NOTE:
196 *******************************************************************************/
197MV_STATUS mvNetaHwfTxqInit(int tx_port, int txp, int txq)
198{
199 MV_U32 regVal;
200 MV_NETA_PORT_CTRL *pPortCtrl;
201 MV_NETA_QUEUE_CTRL *pQueueCtrl;
202 int port, dropThresh;
203
204 pPortCtrl = mvNetaPortHndlGet(tx_port);
205 if (pPortCtrl == NULL) {
206 mvOsPrintf("%s: port %d is not initialized\n", __func__, tx_port);
207 return MV_NOT_INITIALIZED;
208 }
209
210 pQueueCtrl = &pPortCtrl->pTxQueue[txp * CONFIG_MV_ETH_TXQ + txq].queueCtrl;
211
212 if (pQueueCtrl->pFirst == NULL) {
213 mvOsPrintf("%s: tx_port=%d, txp=%d, txq=%d is not initialized\n",
214 __func__, tx_port, txp, txq);
215 return MV_NOT_INITIALIZED;
216 }
217
218 for (port = 0; port < mvNetaHalData.maxPort; port++) {
219
220 pPortCtrl = mvNetaPortHndlGet(port);
221 if (pPortCtrl == NULL)
222 continue;
223
224 regVal = NETA_HWF_TX_PORT_MASK(tx_port + txp) | NETA_HWF_TXQ_MASK(txq);
225 MV_REG_WRITE(NETA_HWF_TX_PTR_REG(port), regVal);
226 MV_REG_WRITE(NETA_HWF_TXQ_BASE_REG(port), pQueueCtrl->descBuf.bufPhysAddr);
227 MV_REG_WRITE(NETA_HWF_TXQ_SIZE_REG(port), pQueueCtrl->lastDesc + 1);
228
229 dropThresh = (CONFIG_MV_ETH_HWF_TXQ_DROP * (pQueueCtrl->lastDesc + 1)) / 100;
230 regVal = (dropThresh << NETA_YELLOW_DROP_THRESH_OFFS) |
231 (CONFIG_MV_ETH_HWF_TXQ_DROP_RND << NETA_YELLOW_DROP_RND_GEN_OFFS);
232
233 MV_REG_WRITE(NETA_HWF_DROP_TH_REG(port), regVal);
234 }
235 return MV_OK;
236}
237
John Newlin2e746432013-05-31 10:38:29 -0700238MV_STATUS mvNetaHwfTxqNextIndexGet(int port, int tx_port, int txp, int txq, int *val)
239{
240 MV_U32 regVal;
241
242 regVal = NETA_HWF_TX_PORT_MASK(tx_port + txp) | NETA_HWF_TXQ_MASK(txq) | NETA_HWF_REG_MASK(3);
243 MV_REG_WRITE(NETA_HWF_TX_PTR_REG(port), regVal);
244
245 regVal = MV_REG_READ(NETA_HWF_MEMORY_REG(port));
246 if (val)
247 *val = (int)((regVal >> 16) & 0x3fff);
248
249 return MV_OK;
250}
Ke Dong32248e72012-09-26 19:22:56 -0700251
252/*******************************************************************************
253 * mvNetaHwfTxqEnable - Enable / Disable HWF from the rx_port to tx_port/txp/txq
254 * DESCRIPTION:
255 *
256 * INPUT:
257 * int rx_port: RX port number
258 * int tx_port, txp, txq: port, TCONT and TXQ numbers
259 * int enable: 0 - disable, 1 - enable
260 *
261 * RETURN: MV_STATUS
262 * MV_OK - Success, Others - Failure
263 *
264 * NOTE:
265 *******************************************************************************/
266MV_STATUS mvNetaHwfTxqEnable(int port, int tx_port, int txp, int txq, int enable)
267{
268 MV_U32 regVal;
269
270 /* Enable HWF for each TXQ */
271 regVal = NETA_HWF_TX_PORT_MASK(tx_port + txp) | NETA_HWF_TXQ_MASK(txq);
272 MV_REG_WRITE(NETA_HWF_TX_PTR_REG(port), regVal);
273
274 MV_REG_WRITE(NETA_HWF_TXQ_ENABLE_REG(port), enable << NETA_HWF_TXQ_ENABLE_BIT);
275
276 return MV_OK;
277}
278
279/*******************************************************************************
280 * mvNetaHwfTxqDropSet - Set HWF drop threshold
281 * DESCRIPTION:
282 *
283 * INPUT:
284 * int rx_port: RX port number
285 * int tx_port, txp, txq: port, TCONT and TXQ numbers
286 * int thresh, bits drop configuration
287 *
288 * RETURN: MV_STATUS
289 * MV_OK - Success, Others - Failure
290 *
291 * NOTE:
292 *******************************************************************************/
293MV_STATUS mvNetaHwfTxqDropSet(int port, int tx_port, int txp, int txq, int thresh, int bits)
294{
295 MV_U32 regVal, dropThresh;
296 MV_NETA_PORT_CTRL *pPortCtrl;
297 MV_NETA_QUEUE_CTRL *pQueueCtrl;
298
299 pPortCtrl = mvNetaPortHndlGet(tx_port);
300 if (pPortCtrl == NULL)
301 return MV_FAIL;
302
303 pQueueCtrl = &pPortCtrl->pTxQueue[txp * CONFIG_MV_ETH_TXQ + txq].queueCtrl;
304 if (pQueueCtrl->pFirst == NULL)
305 return MV_FAIL;
306
307 /* Set HWF Drop parameters for specific TXQ */
308 regVal = NETA_HWF_TX_PORT_MASK(tx_port + txp) | NETA_HWF_TXQ_MASK(txq);
309 MV_REG_WRITE(NETA_HWF_TX_PTR_REG(port), regVal);
310
311 dropThresh = (thresh * (pQueueCtrl->lastDesc + 1)) / 100;
312 regVal = (dropThresh << NETA_YELLOW_DROP_THRESH_OFFS) | (bits << NETA_YELLOW_DROP_RND_GEN_OFFS);
313
314 MV_REG_WRITE(NETA_HWF_DROP_TH_REG(port), regVal);
315
316 return MV_OK;
317}
318
319/*******************************************************************************
320 * mvNetaHwfMhSrcSet - Select MH source on TX during HWF (PNC or field in
321 * HWF RX control register.
322 * DESCRIPTION:
323 *
324 * INPUT:
325 * int port; port number
326 * int mh_src; 0 - register field, 1 - PNC result info bits
327 *
328 * RETURN: MV_STATUS
329 * MV_OK - Success, Others - Failure
330 *
331 * NOTE:
332 *******************************************************************************/
333MV_STATUS mvNetaHwfMhSrcSet(int port, MV_NETA_HWF_MH_SRC mh_src)
334{
335 MV_U32 regVal;
336
337 regVal = MV_REG_READ(NETA_HWF_RX_CTRL_REG(port));
338
339 switch (mh_src) {
340
341 case MV_NETA_HWF_MH_REG:
342 regVal &= ~NETA_MH_SRC_PNC_MASK;
343 break;
344
345 case MV_NETA_HWF_MH_PNC:
346 regVal |= NETA_MH_SRC_PNC_MASK;
347 break;
348
349 default:
350 mvOsPrintf("port=%d: Unexpected HWF MH source = %d value\n", port, mh_src);
351 return MV_BAD_PARAM;
352 }
353 MV_REG_WRITE(NETA_HWF_RX_CTRL_REG(port), regVal);
354 return MV_OK;
355
356}
357
358/*******************************************************************************
359 * mvNetaHwfMhSelSet - Set MH value on TX during HWF.
360 *
361 * DESCRIPTION:
362 *
363 * INPUT:
364 * int port; port number
365 * int mh_sel_mask; use the following values as mask
366 * NETA_MH_DONT_CHANGE
367 * NETA_MH_REPLACE_GPON_HDR
368 * NETA_MH_REPLACE_MH_REG(r)
369 * RETURN: MV_STATUS
370 * MV_OK - Success, Others - Failure
371 *
372 * NOTE:
373 *******************************************************************************/
374MV_STATUS mvNetaHwfMhSelSet(int port, MV_U8 mh_sel_mask)
375{
376 MV_U32 regVal;
377
378 regVal = MV_REG_READ(NETA_HWF_RX_CTRL_REG(port));
379 regVal &= ~NETA_MH_SEL_MASK;
380 regVal |= ((mh_sel_mask<<NETA_MH_SEL_OFFS) & NETA_MH_SEL_MASK);
381
382 MV_REG_WRITE(NETA_HWF_RX_CTRL_REG(port), regVal);
383 return MV_OK;
384}