• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /********************************************************************************
2 Copyright (C) 2016 Marvell International Ltd.
3 
4 Marvell BSD License Option
5 
6 If you received this File from Marvell, you may opt to use, redistribute and/or
7 modify this File under the following licensing terms.
8 Redistribution and use in source and binary forms, with or without modification,
9 are permitted provided that the following conditions are met:
10 
11   * Redistributions of source code must retain the above copyright notice,
12     this list of conditions and the following disclaimer.
13 
14   * Redistributions in binary form must reproduce the above copyright
15     notice, this list of conditions and the following disclaimer in the
16     documentation and/or other materials provided with the distribution.
17 
18   * Neither the name of Marvell nor the names of its contributors may be
19     used to endorse or promote products derived from this software without
20     specific prior written permission.
21 
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
26 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 *******************************************************************************/
34 
35 #include "Mvpp2Lib.h"
36 #include "Mvpp2LibHw.h"
37 #include "Pp2Dxe.h"
38 
39 /* Parser configuration routines */
40 
41 /* Update parser Tcam and Sram hw entries */
42 STATIC
43 INT32
Mvpp2PrsHwWrite(IN MVPP2_SHARED * Priv,IN OUT MVPP2_PRS_ENTRY * Pe)44 Mvpp2PrsHwWrite (
45   IN MVPP2_SHARED *Priv,
46   IN OUT MVPP2_PRS_ENTRY *Pe
47   )
48 {
49   INT32 i;
50 
51   if (Pe->Index > MVPP2_PRS_TCAM_SRAM_SIZE - 1) {
52     return MVPP2_EINVAL;
53   }
54 
55   /* Clear entry invalidation bit */
56   Pe->Tcam.Word[MVPP2_PRS_TCAM_INV_WORD] &= ~MVPP2_PRS_TCAM_INV_MASK;
57 
58   /* Write Tcam Index - indirect access */
59   Mvpp2Write (Priv, MVPP2_PRS_TCAM_IDX_REG, Pe->Index);
60   for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++) {
61     Mvpp2Write (Priv, MVPP2_PRS_TCAM_DATA_REG(i), Pe->Tcam.Word[i]);
62   }
63 
64   /* Write Sram Index - indirect access */
65   Mvpp2Write (Priv, MVPP2_PRS_SRAM_IDX_REG, Pe->Index);
66   for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++) {
67     Mvpp2Write (Priv, MVPP2_PRS_SRAM_DATA_REG(i), Pe->Sram.Word[i]);
68   }
69 
70   return 0;
71 }
72 
73 /* Read Tcam entry from hw */
74 STATIC
75 INT32
Mvpp2PrsHwRead(IN MVPP2_SHARED * Priv,IN OUT MVPP2_PRS_ENTRY * Pe)76 Mvpp2PrsHwRead (
77   IN MVPP2_SHARED *Priv,
78   IN OUT MVPP2_PRS_ENTRY *Pe
79   )
80 {
81   INT32 i;
82 
83   if (Pe->Index > MVPP2_PRS_TCAM_SRAM_SIZE - 1) {
84     return MVPP2_EINVAL;
85   }
86 
87   /* Write Tcam Index - indirect access */
88   Mvpp2Write (Priv, MVPP2_PRS_TCAM_IDX_REG, Pe->Index);
89 
90   Pe->Tcam.Word[MVPP2_PRS_TCAM_INV_WORD] =
91     Mvpp2Read (Priv, MVPP2_PRS_TCAM_DATA_REG(MVPP2_PRS_TCAM_INV_WORD));
92   if (Pe->Tcam.Word[MVPP2_PRS_TCAM_INV_WORD] & MVPP2_PRS_TCAM_INV_MASK) {
93     return MVPP2_PRS_TCAM_ENTRY_INVALID;
94   }
95 
96   for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++) {
97     Pe->Tcam.Word[i] = Mvpp2Read (Priv, MVPP2_PRS_TCAM_DATA_REG(i));
98   }
99 
100   /* Write Sram Index - indirect access */
101   Mvpp2Write (Priv, MVPP2_PRS_SRAM_IDX_REG, Pe->Index);
102   for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++) {
103     Pe->Sram.Word[i] = Mvpp2Read (Priv, MVPP2_PRS_SRAM_DATA_REG(i));
104   }
105 
106   return 0;
107 }
108 
109 /* Invalidate Tcam hw entry */
110 STATIC
111 VOID
Mvpp2PrsHwInv(IN MVPP2_SHARED * Priv,IN INT32 Index)112 Mvpp2PrsHwInv (
113   IN MVPP2_SHARED *Priv,
114   IN INT32 Index
115   )
116 {
117   /* Write Index - indirect access */
118   Mvpp2Write (Priv, MVPP2_PRS_TCAM_IDX_REG, Index);
119   Mvpp2Write (Priv, MVPP2_PRS_TCAM_DATA_REG(MVPP2_PRS_TCAM_INV_WORD),
120         MVPP2_PRS_TCAM_INV_MASK);
121 }
122 
123 /* Enable shadow table entry and set its lookup ID */
124 STATIC
125 VOID
Mvpp2PrsShadowSet(IN MVPP2_SHARED * Priv,IN INT32 Index,IN INT32 Lu)126 Mvpp2PrsShadowSet (
127   IN MVPP2_SHARED *Priv,
128   IN INT32 Index,
129   IN INT32 Lu
130   )
131 {
132   Priv->PrsShadow[Index].Valid = TRUE;
133   Priv->PrsShadow[Index].Lu = Lu;
134 }
135 
136 /* Update Ri fields in shadow table entry */
137 STATIC
138 VOID
Mvpp2PrsShadowRiSet(IN MVPP2_SHARED * Priv,IN INT32 Index,IN UINT32 Ri,IN UINT32 RiMask)139 Mvpp2PrsShadowRiSet (
140   IN MVPP2_SHARED *Priv,
141   IN INT32 Index,
142   IN UINT32 Ri,
143   IN UINT32 RiMask
144   )
145 {
146   Priv->PrsShadow[Index].RiMask = RiMask;
147   Priv->PrsShadow[Index].Ri = Ri;
148 }
149 
150 /* Update lookup field in Tcam sw entry */
151 STATIC
152 VOID
Mvpp2PrsTcamLuSet(IN OUT MVPP2_PRS_ENTRY * Pe,IN UINT32 Lu)153 Mvpp2PrsTcamLuSet (
154   IN OUT MVPP2_PRS_ENTRY *Pe,
155   IN UINT32 Lu
156   )
157 {
158   INT32 EnableOff = MVPP2_PRS_TCAM_EN_OFFS (MVPP2_PRS_TCAM_LU_BYTE);
159 
160   Pe->Tcam.Byte[MVPP2_PRS_TCAM_LU_BYTE] = Lu;
161   Pe->Tcam.Byte[EnableOff] = MVPP2_PRS_LU_MASK;
162 }
163 
164 /* Update Mask for single Port in Tcam sw entry */
165 STATIC
166 VOID
Mvpp2PrsTcamPortSet(IN OUT MVPP2_PRS_ENTRY * Pe,IN UINT32 PortId,IN BOOLEAN Add)167 Mvpp2PrsTcamPortSet (
168   IN OUT MVPP2_PRS_ENTRY *Pe,
169   IN UINT32 PortId,
170   IN BOOLEAN Add
171   )
172 {
173   INT32 EnableOff = MVPP2_PRS_TCAM_EN_OFFS (MVPP2_PRS_TCAM_PORT_BYTE);
174 
175   if (Add) {
176     Pe->Tcam.Byte[EnableOff] &= ~(1 << PortId);
177   } else {
178     Pe->Tcam.Byte[EnableOff] |= 1 << PortId;
179   }
180 }
181 
182 /* Update Port map in Tcam sw entry */
183 STATIC
184 VOID
Mvpp2PrsTcamPortMapSet(IN OUT MVPP2_PRS_ENTRY * Pe,IN UINT32 PortMask)185 Mvpp2PrsTcamPortMapSet (
186   IN OUT MVPP2_PRS_ENTRY *Pe,
187   IN UINT32 PortMask
188   )
189 {
190   INT32 EnableOff = MVPP2_PRS_TCAM_EN_OFFS (MVPP2_PRS_TCAM_PORT_BYTE);
191   UINT8 Mask = MVPP2_PRS_PORT_MASK;
192 
193   Pe->Tcam.Byte[MVPP2_PRS_TCAM_PORT_BYTE] = 0;
194   Pe->Tcam.Byte[EnableOff] &= ~Mask;
195   Pe->Tcam.Byte[EnableOff] |= ~PortMask & MVPP2_PRS_PORT_MASK;
196 }
197 
198 /* Obtain Port map from Tcam sw entry */
199 STATIC
200 UINT32
Mvpp2PrsTcamPortMapGet(IN MVPP2_PRS_ENTRY * Pe)201 Mvpp2PrsTcamPortMapGet (
202   IN MVPP2_PRS_ENTRY *Pe
203   )
204 {
205   INT32 EnableOff = MVPP2_PRS_TCAM_EN_OFFS (MVPP2_PRS_TCAM_PORT_BYTE);
206 
207   return ~(Pe->Tcam.Byte[EnableOff]) & MVPP2_PRS_PORT_MASK;
208 }
209 
210 /* Set Byte of data and its enable bits in Tcam sw entry */
211 STATIC
212 VOID
Mvpp2PrsTcamDataByteSet(IN OUT MVPP2_PRS_ENTRY * Pe,IN UINT32 Offs,IN UINT8 Byte,IN UINT8 Enable)213 Mvpp2PrsTcamDataByteSet (
214   IN OUT MVPP2_PRS_ENTRY *Pe,
215   IN UINT32 Offs,
216   IN UINT8 Byte,
217   IN UINT8 Enable
218   )
219 {
220   Pe->Tcam.Byte[MVPP2_PRS_TCAM_DATA_BYTE(Offs)] = Byte;
221   Pe->Tcam.Byte[MVPP2_PRS_TCAM_DATA_BYTE_EN(Offs)] = Enable;
222 }
223 
224 /* Get Byte of data and its enable bits from Tcam sw entry */
225 STATIC
226 VOID
Mvpp2PrsTcamDataByteGet(IN MVPP2_PRS_ENTRY * Pe,IN UINT32 Offs,OUT UINT8 * Byte,OUT UINT8 * Enable)227 Mvpp2PrsTcamDataByteGet (
228   IN MVPP2_PRS_ENTRY *Pe,
229   IN UINT32 Offs,
230   OUT UINT8 *Byte,
231   OUT UINT8 *Enable
232   )
233 {
234   *Byte = Pe->Tcam.Byte[MVPP2_PRS_TCAM_DATA_BYTE(Offs)];
235   *Enable = Pe->Tcam.Byte[MVPP2_PRS_TCAM_DATA_BYTE_EN(Offs)];
236 }
237 
238 /* Compare Tcam data bytes with a pattern */
239 STATIC
240 BOOLEAN
Mvpp2PrsTcamDataCmp(IN MVPP2_PRS_ENTRY * Pe,IN INT32 Offset,IN UINT16 Data)241 Mvpp2PrsTcamDataCmp (
242   IN MVPP2_PRS_ENTRY *Pe,
243   IN INT32 Offset,
244   IN UINT16 Data
245   )
246 {
247   INT32 ByteOffset = MVPP2_PRS_TCAM_DATA_BYTE(Offset);
248   UINT16 TcamData;
249 
250   TcamData = (Pe->Tcam.Byte[ByteOffset + 1] << 8) | Pe->Tcam.Byte[ByteOffset];
251   if (TcamData != Data) {
252     return FALSE;
253   }
254 
255   return TRUE;
256 }
257 
258 /* Update ai bits in Tcam sw entry */
259 STATIC
260 VOID
Mvpp2PrsTcamAiUpdate(IN OUT MVPP2_PRS_ENTRY * Pe,IN UINT32 Bits,IN UINT32 Enable)261 Mvpp2PrsTcamAiUpdate (
262   IN OUT MVPP2_PRS_ENTRY *Pe,
263   IN UINT32 Bits,
264   IN UINT32 Enable
265   )
266 {
267   INT32 i, AiIdx = MVPP2_PRS_TCAM_AI_BYTE;
268 
269   for (i = 0; i < MVPP2_PRS_AI_BITS; i++) {
270 
271     if (!(Enable & BIT (i))) {
272       continue;
273     }
274 
275     if (Bits & BIT (i)) {
276       Pe->Tcam.Byte[AiIdx] |= 1 << i;
277     } else {
278       Pe->Tcam.Byte[AiIdx] &= ~(1 << i);
279     }
280   }
281 
282   Pe->Tcam.Byte[MVPP2_PRS_TCAM_EN_OFFS (AiIdx)] |= Enable;
283 }
284 
285 /* Get ai bits from Tcam sw entry */
286 STATIC
287 INT32
Mvpp2PrsTcamAiGet(IN MVPP2_PRS_ENTRY * Pe)288 Mvpp2PrsTcamAiGet (
289   IN MVPP2_PRS_ENTRY *Pe
290   )
291 {
292   return Pe->Tcam.Byte[MVPP2_PRS_TCAM_AI_BYTE];
293 }
294 
295 /* Get word of data and its enable bits from Tcam sw entry */
296 STATIC
297 VOID
Mvpp2PrsTcamDataWordGet(IN MVPP2_PRS_ENTRY * Pe,IN UINT32 DataOffset,OUT UINT32 * Word,OUT UINT32 * Enable)298 Mvpp2PrsTcamDataWordGet (
299   IN MVPP2_PRS_ENTRY *Pe,
300   IN UINT32 DataOffset,
301   OUT UINT32 *Word,
302   OUT UINT32 *Enable
303   )
304 {
305   INT32 Index, Position;
306   UINT8 Byte, Mask;
307 
308   for (Index = 0; Index < 4; Index++) {
309     Position = (DataOffset * sizeof (INT32)) + Index;
310     Mvpp2PrsTcamDataByteGet (Pe, Position, &Byte, &Mask);
311     ((UINT8 *)Word)[Index] = Byte;
312     ((UINT8 *)Enable)[Index] = Mask;
313   }
314 }
315 
316 /* Set ethertype in Tcam sw entry */
317 STATIC
318 VOID
Mvpp2PrsMatchEtype(IN OUT MVPP2_PRS_ENTRY * Pe,IN INT32 Offset,IN UINT16 EtherType)319 Mvpp2PrsMatchEtype (
320   IN OUT MVPP2_PRS_ENTRY *Pe,
321   IN INT32 Offset,
322   IN UINT16 EtherType
323   )
324 {
325   Mvpp2PrsTcamDataByteSet (Pe, Offset + 0, EtherType >> 8, 0xff);
326   Mvpp2PrsTcamDataByteSet (Pe, Offset + 1, EtherType & 0xff, 0xff);
327 }
328 
329 /* Set bits in Sram sw entry */
330 STATIC
331 VOID
Mvpp2PrsSramBitsSet(IN OUT MVPP2_PRS_ENTRY * Pe,IN INT32 BitNum,IN INT32 Val)332 Mvpp2PrsSramBitsSet (
333   IN OUT MVPP2_PRS_ENTRY *Pe,
334   IN INT32 BitNum,
335   IN INT32 Val
336   )
337 {
338   Pe->Sram.Byte[MVPP2_BIT_TO_BYTE(BitNum)] |= (Val << (BitNum % 8));
339 }
340 
341 /* Clear bits in Sram sw entry */
342 STATIC
343 VOID
Mvpp2PrsSramBitsClear(IN OUT MVPP2_PRS_ENTRY * Pe,IN INT32 BitNum,IN INT32 Val)344 Mvpp2PrsSramBitsClear (
345   IN OUT MVPP2_PRS_ENTRY *Pe,
346   IN INT32 BitNum,
347   IN INT32 Val
348   )
349 {
350   Pe->Sram.Byte[MVPP2_BIT_TO_BYTE(BitNum)] &= ~(Val << (BitNum % 8));
351 }
352 
353 /* Update Ri bits in Sram sw entry */
354 STATIC
355 VOID
Mvpp2PrsSramRiUpdate(IN OUT MVPP2_PRS_ENTRY * Pe,IN UINT32 bits,IN UINT32 Mask)356 Mvpp2PrsSramRiUpdate (
357   IN OUT MVPP2_PRS_ENTRY *Pe,
358   IN UINT32 bits,
359   IN UINT32 Mask
360   )
361 {
362   UINT32 i;
363 
364   for (i = 0; i < MVPP2_PRS_SRAM_RI_CTRL_BITS; i++) {
365     INT32 RiOff = MVPP2_PRS_SRAM_RI_OFFS;
366 
367     if (!(Mask & BIT (i))) {
368       continue;
369     }
370 
371     if (bits & BIT (i)) {
372       Mvpp2PrsSramBitsSet (Pe, RiOff + i, 1);
373     } else {
374       Mvpp2PrsSramBitsClear (Pe, RiOff + i, 1);
375     }
376 
377     Mvpp2PrsSramBitsSet (Pe, MVPP2_PRS_SRAM_RI_CTRL_OFFS + i, 1);
378   }
379 }
380 
381 /* Obtain Ri bits from Sram sw entry */
382 STATIC
383 INT32
Mvpp2PrsSramRiGet(IN MVPP2_PRS_ENTRY * Pe)384 Mvpp2PrsSramRiGet (
385   IN MVPP2_PRS_ENTRY *Pe
386   )
387 {
388   return Pe->Sram.Word[MVPP2_PRS_SRAM_RI_WORD];
389 }
390 
391 /* Update ai bits in Sram sw entry */
392 STATIC
393 VOID
Mvpp2PrsSramAiUpdate(IN OUT MVPP2_PRS_ENTRY * Pe,IN UINT32 Bits,UINT32 Mask)394 Mvpp2PrsSramAiUpdate (
395   IN OUT MVPP2_PRS_ENTRY *Pe,
396   IN UINT32 Bits,
397   UINT32 Mask
398   )
399 {
400   UINT32 i;
401   INT32 AiOff = MVPP2_PRS_SRAM_AI_OFFS;
402 
403   for (i = 0; i < MVPP2_PRS_SRAM_AI_CTRL_BITS; i++) {
404 
405     if (!(Mask & BIT (i))) {
406       continue;
407     }
408 
409     if (Bits & BIT (i)) {
410       Mvpp2PrsSramBitsSet (Pe, AiOff + i, 1);
411     } else {
412       Mvpp2PrsSramBitsClear (Pe, AiOff + i, 1);
413     }
414 
415     Mvpp2PrsSramBitsSet (Pe, MVPP2_PRS_SRAM_AI_CTRL_OFFS + i, 1);
416   }
417 }
418 
419 /* Read ai bits from Sram sw entry */
420 STATIC
421 INT32
Mvpp2PrsSramAiGet(IN MVPP2_PRS_ENTRY * Pe)422 Mvpp2PrsSramAiGet (
423   IN MVPP2_PRS_ENTRY *Pe
424   )
425 {
426   UINT8 bits;
427   INT32 AiOff = MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_AI_OFFS);
428   INT32 AiEnOff = AiOff + 1;
429   INT32 AiShift = MVPP2_PRS_SRAM_AI_OFFS % 8;
430 
431   bits = (Pe->Sram.Byte[AiOff] >> AiShift) |
432          (Pe->Sram.Byte[AiEnOff] << (8 - AiShift));
433 
434   return bits;
435 }
436 
437 /*
438  * In Sram sw entry set lookup ID field of the
439  * Tcam key to be used in the next lookup iteration
440  */
441 STATIC
442 VOID
Mvpp2PrsSramNextLuSet(IN OUT MVPP2_PRS_ENTRY * Pe,IN UINT32 Lu)443 Mvpp2PrsSramNextLuSet (
444   IN OUT MVPP2_PRS_ENTRY *Pe,
445   IN UINT32 Lu
446   )
447 {
448   INT32 SramNextOff = MVPP2_PRS_SRAM_NEXT_LU_OFFS;
449 
450   Mvpp2PrsSramBitsClear (Pe, SramNextOff, MVPP2_PRS_SRAM_NEXT_LU_MASK);
451   Mvpp2PrsSramBitsSet (Pe, SramNextOff, Lu);
452 }
453 
454 /*
455  * In the Sram sw entry set sign and value of the next lookup Offset
456  * and the Offset value generated to the classifier
457  */
458 STATIC
459 VOID
Mvpp2PrsSramShiftSet(IN OUT MVPP2_PRS_ENTRY * Pe,IN INT32 Shift,IN UINT32 Op)460 Mvpp2PrsSramShiftSet (
461   IN OUT MVPP2_PRS_ENTRY *Pe,
462   IN INT32 Shift,
463   IN UINT32 Op
464   )
465 {
466   /* Set sign */
467   if (Shift < 0) {
468     Mvpp2PrsSramBitsSet (Pe, MVPP2_PRS_SRAM_SHIFT_SIGN_BIT, 1);
469     Shift = -Shift;
470   } else {
471     Mvpp2PrsSramBitsClear (Pe, MVPP2_PRS_SRAM_SHIFT_SIGN_BIT, 1);
472   }
473 
474   /* Set value */
475   Pe->Sram.Byte[MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_SHIFT_OFFS)] = (UINT8)Shift;
476 
477   /* Reset and set operation */
478   Mvpp2PrsSramBitsClear (Pe, MVPP2_PRS_SRAM_OP_SEL_SHIFT_OFFS, MVPP2_PRS_SRAM_OP_SEL_SHIFT_MASK);
479   Mvpp2PrsSramBitsSet (Pe, MVPP2_PRS_SRAM_OP_SEL_SHIFT_OFFS, Op);
480 
481   /* Set base Offset as current */
482   Mvpp2PrsSramBitsClear (Pe, MVPP2_PRS_SRAM_OP_SEL_BASE_OFFS, 1);
483 }
484 
485 /*
486  * In the Sram sw entry set sign and value of the user defined offset
487  * generated for the classifier
488  */
489 STATIC
490 VOID
Mvpp2PrsSramOffsetSet(IN OUT MVPP2_PRS_ENTRY * Pe,IN UINT32 Type,IN INT32 Offset,IN UINT32 Op)491 Mvpp2PrsSramOffsetSet (
492   IN OUT MVPP2_PRS_ENTRY *Pe,
493   IN UINT32 Type,
494   IN INT32 Offset,
495   IN UINT32 Op
496   )
497 {
498   UINT8 UdfByte = MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_UDF_OFFS + MVPP2_PRS_SRAM_UDF_BITS);
499   UINT8 UdfByteOffset = (8 - (MVPP2_PRS_SRAM_UDF_OFFS % 8));
500   UINT8 OpSelUdfByte = MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS + MVPP2_PRS_SRAM_OP_SEL_UDF_BITS);
501   UINT8 OpSelUdfByteOffset = (8 - (MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS % 8));
502 
503   /* Set sign */
504   if (Offset < 0) {
505     Mvpp2PrsSramBitsSet (Pe, MVPP2_PRS_SRAM_UDF_SIGN_BIT, 1);
506     Offset = -Offset;
507   } else {
508     Mvpp2PrsSramBitsClear (Pe, MVPP2_PRS_SRAM_UDF_SIGN_BIT, 1);
509   }
510 
511   /* Set value */
512   Mvpp2PrsSramBitsClear (Pe, MVPP2_PRS_SRAM_UDF_OFFS, MVPP2_PRS_SRAM_UDF_MASK);
513   Mvpp2PrsSramBitsSet (Pe, MVPP2_PRS_SRAM_UDF_OFFS, Offset);
514 
515   Pe->Sram.Byte[UdfByte] &= ~(MVPP2_PRS_SRAM_UDF_MASK >> UdfByteOffset);
516   Pe->Sram.Byte[UdfByte] |= (Offset >> UdfByteOffset);
517 
518   /* Set Offset Type */
519   Mvpp2PrsSramBitsClear (Pe, MVPP2_PRS_SRAM_UDF_TYPE_OFFS, MVPP2_PRS_SRAM_UDF_TYPE_MASK);
520   Mvpp2PrsSramBitsSet (Pe, MVPP2_PRS_SRAM_UDF_TYPE_OFFS, Type);
521 
522   /* Set Offset operation */
523   Mvpp2PrsSramBitsClear (Pe, MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS, MVPP2_PRS_SRAM_OP_SEL_UDF_MASK);
524   Mvpp2PrsSramBitsSet (Pe, MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS, Op);
525 
526   Pe->Sram.Byte[OpSelUdfByte] &= ~(MVPP2_PRS_SRAM_OP_SEL_UDF_MASK >> OpSelUdfByteOffset);
527   Pe->Sram.Byte[OpSelUdfByte] |= (Op >> OpSelUdfByteOffset);
528 
529   /* Set base Offset as current */
530   Mvpp2PrsSramBitsClear (Pe, MVPP2_PRS_SRAM_OP_SEL_BASE_OFFS, 1);
531 }
532 
533 /* Find parser Flow entry */
534 STATIC
535 MVPP2_PRS_ENTRY *
Mvpp2PrsFlowFind(IN MVPP2_SHARED * Priv,IN INT32 Flow)536 Mvpp2PrsFlowFind (
537   IN MVPP2_SHARED *Priv,
538   IN INT32 Flow
539   )
540 {
541   MVPP2_PRS_ENTRY *Pe;
542   INT32 Tid;
543   UINT32 Word, Enable;
544 
545   Pe = Mvpp2Alloc (sizeof (*Pe));
546   if (Pe == NULL) {
547     return NULL;
548   }
549 
550   Mvpp2PrsTcamLuSet (Pe, MVPP2_PRS_LU_FLOWS);
551 
552   /* Go through the all entires with MVPP2_PRS_LU_FLOWS */
553   for (Tid = MVPP2_PRS_TCAM_SRAM_SIZE - 1; Tid >= 0; Tid--) {
554     UINT8 Bits;
555 
556     if (!Priv->PrsShadow[Tid].Valid || Priv->PrsShadow[Tid].Lu != MVPP2_PRS_LU_FLOWS) {
557       continue;
558     }
559 
560     Pe->Index = Tid;
561     Mvpp2PrsHwRead (Priv, Pe);
562 
563     /*
564      * Check result info, because there maybe
565      * several TCAM lines to generate the same Flow
566      */
567     Mvpp2PrsTcamDataWordGet (Pe, 0, &Word, &Enable);
568     if ((Word != 0) || (Enable != 0)) {
569       continue;
570     }
571 
572     Bits = Mvpp2PrsSramAiGet (Pe);
573 
574     /* Sram store classification lookup ID in AI Bits [5:0] */
575     if ((Bits & MVPP2_PRS_FLOW_ID_MASK) == Flow) {
576       return Pe;
577     }
578   }
579 
580   Mvpp2Free (Pe);
581 
582   return NULL;
583 }
584 
585 /* Return first free Tcam Index, seeking from start to end */
586 STATIC
587 INT32
Mvpp2PrsTcamFirstFree(IN MVPP2_SHARED * Priv,IN UINT8 Start,IN UINT8 End)588 Mvpp2PrsTcamFirstFree (
589   IN MVPP2_SHARED *Priv,
590   IN UINT8 Start,
591   IN UINT8 End
592   )
593 {
594   INT32 Tid;
595 
596   if (Start > End) {
597     Mvpp2SwapVariables (Start, End);
598   }
599 
600   if (End >= MVPP2_PRS_TCAM_SRAM_SIZE) {
601     End = MVPP2_PRS_TCAM_SRAM_SIZE - 1;
602   }
603 
604   for (Tid = Start; Tid <= End; Tid++) {
605     if (!Priv->PrsShadow[Tid].Valid) {
606       return Tid;
607     }
608   }
609 
610   return MVPP2_EINVAL;
611 }
612 
613 /* Enable/disable dropping all mac Da's */
614 STATIC
615 VOID
Mvpp2PrsMacDropAllSet(IN MVPP2_SHARED * Priv,IN INT32 PortId,IN BOOLEAN Add)616 Mvpp2PrsMacDropAllSet (
617   IN MVPP2_SHARED *Priv,
618   IN INT32 PortId,
619   IN BOOLEAN Add
620   )
621 {
622   MVPP2_PRS_ENTRY Pe;
623 
624   if (Priv->PrsShadow[MVPP2_PE_DROP_ALL].Valid) {
625     /* Entry exist - update PortId only */
626     Pe.Index = MVPP2_PE_DROP_ALL;
627     Mvpp2PrsHwRead (Priv, &Pe);
628   } else {
629     /* Entry doesn't exist - create new */
630     Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
631     Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_MAC);
632     Pe.Index = MVPP2_PE_DROP_ALL;
633 
634     /* Non-promiscuous mode for all Ports - DROP unknown packets */
635     Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_DROP_MASK, MVPP2_PRS_RI_DROP_MASK);
636 
637     Mvpp2PrsSramBitsSet (&Pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
638     Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_FLOWS);
639 
640     /* Update shadow table */
641     Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_MAC);
642 
643     /* Mask all Ports */
644     Mvpp2PrsTcamPortMapSet (&Pe, 0);
645   }
646 
647   /* Update PortId Mask */
648   Mvpp2PrsTcamPortSet (&Pe, PortId, Add);
649 
650   Mvpp2PrsHwWrite (Priv, &Pe);
651 }
652 
653 /* Set port to promiscuous mode */
654 VOID
Mvpp2PrsMacPromiscSet(IN MVPP2_SHARED * Priv,IN INT32 PortId,IN BOOLEAN Add)655 Mvpp2PrsMacPromiscSet (
656   IN MVPP2_SHARED *Priv,
657   IN INT32 PortId,
658   IN BOOLEAN Add
659   )
660 {
661   MVPP2_PRS_ENTRY Pe;
662 
663   /* Promiscuous mode - Accept unknown packets */
664 
665   if (Priv->PrsShadow[MVPP2_PE_MAC_PROMISCUOUS].Valid) {
666     /* Entry exist - update port only */
667     Pe.Index = MVPP2_PE_MAC_PROMISCUOUS;
668     Mvpp2PrsHwRead (Priv, &Pe);
669   } else {
670     /* Entry doesn't exist - create new */
671     Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
672     Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_MAC);
673     Pe.Index = MVPP2_PE_MAC_PROMISCUOUS;
674 
675     /* Continue - set next lookup */
676     Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_DSA);
677 
678     /* Set result info bits */
679     Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L2_UCAST, MVPP2_PRS_RI_L2_CAST_MASK);
680 
681     /* Shift to ethertype with 2 of MAC Address length */
682     Mvpp2PrsSramShiftSet (&Pe, 2 * MV_ETH_ALEN, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
683 
684     /* Mask all Ports */
685     Mvpp2PrsTcamPortMapSet (&Pe, 0);
686 
687     /* Update shadow table */
688     Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_MAC);
689   }
690 
691   /* Update port Mask */
692   Mvpp2PrsTcamPortSet (&Pe, PortId, Add);
693 
694   Mvpp2PrsHwWrite (Priv, &Pe);
695 }
696 
697 /* Accept multicast */
698 VOID
Mvpp2PrsMacMultiSet(IN MVPP2_SHARED * Priv,IN INT32 PortId,IN INT32 Index,IN BOOLEAN Add)699 Mvpp2PrsMacMultiSet (
700   IN MVPP2_SHARED *Priv,
701   IN INT32 PortId,
702   IN INT32 Index,
703   IN BOOLEAN Add
704   )
705 {
706   MVPP2_PRS_ENTRY Pe;
707   UINT8 DaMc;
708 
709   /*
710    * Ethernet multicast Address first Byte is
711    * 0x01 for IPv4 and 0x33 for IPv6
712    */
713   DaMc = (Index == MVPP2_PE_MAC_MC_ALL) ? 0x01 : 0x33;
714 
715   if (Priv->PrsShadow[Index].Valid) {
716     /* Entry exist - update port only */
717     Pe.Index = Index;
718     Mvpp2PrsHwRead (Priv, &Pe);
719   } else {
720     /* Entry doesn't exist - create new */
721     Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
722     Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_MAC);
723     Pe.Index = Index;
724 
725     /* Continue - set next lookup */
726     Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_DSA);
727 
728     /* Set result info bits */
729     Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L2_MCAST, MVPP2_PRS_RI_L2_CAST_MASK);
730 
731     /* Update Tcam entry data first Byte */
732     Mvpp2PrsTcamDataByteSet (&Pe, 0, DaMc, 0xff);
733 
734     /* Shift to ethertype */
735     Mvpp2PrsSramShiftSet (&Pe, 2 * MV_ETH_ALEN, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
736 
737     /* Mask all ports */
738     Mvpp2PrsTcamPortMapSet (&Pe, 0);
739 
740     /* Update shadow table */
741     Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_MAC);
742   }
743 
744   /* Update port Mask */
745   Mvpp2PrsTcamPortSet (&Pe, PortId, Add);
746 
747   Mvpp2PrsHwWrite (Priv, &Pe);
748 }
749 
750 /* Set entry for dsa packets */
751 STATIC
752 VOID
Mvpp2PrsDsaTagSet(IN MVPP2_SHARED * Priv,IN INT32 PortId,IN BOOLEAN Add,IN BOOLEAN Tagged,IN BOOLEAN Extend)753 Mvpp2PrsDsaTagSet (
754   IN MVPP2_SHARED *Priv,
755   IN INT32 PortId,
756   IN BOOLEAN Add,
757   IN BOOLEAN Tagged,
758   IN BOOLEAN Extend
759   )
760 {
761   MVPP2_PRS_ENTRY Pe;
762   INT32 Tid, Shift;
763 
764   if (Extend) {
765     Tid = Tagged ? MVPP2_PE_EDSA_TAGGED : MVPP2_PE_EDSA_UNTAGGED;
766     Shift = 8;
767   } else {
768     Tid = Tagged ? MVPP2_PE_DSA_TAGGED : MVPP2_PE_DSA_UNTAGGED;
769     Shift = 4;
770   }
771 
772   if (Priv->PrsShadow[Tid].Valid) {
773     /* Entry exist - update port only */
774     Pe.Index = Tid;
775     Mvpp2PrsHwRead (Priv, &Pe);
776   } else {
777     /* Entry doesn't exist - create new */
778     Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
779     Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_DSA);
780     Pe.Index = Tid;
781 
782     /* Shift 4 bytes if DSA tag or 8 bytes in case of EDSA tag*/
783     Mvpp2PrsSramShiftSet (&Pe, Shift, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
784 
785     /* Update shadow table */
786     Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_DSA);
787 
788     if (Tagged) {
789       /* Set Tagged bit in DSA tag */
790       Mvpp2PrsTcamDataByteSet (&Pe, 0, MVPP2_PRS_TCAM_DSA_TAGGED_BIT, MVPP2_PRS_TCAM_DSA_TAGGED_BIT);
791 
792       /* Clear all ai bits for next iteration */
793       Mvpp2PrsSramAiUpdate (&Pe, 0, MVPP2_PRS_SRAM_AI_MASK);
794 
795       /* If packet is Tagged continue check vlans */
796       Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_VLAN);
797     } else {
798       /* Set result info bits to 'no vlans' */
799       Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_VLAN_NONE, MVPP2_PRS_RI_VLAN_MASK);
800       Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_L2);
801     }
802 
803     /* Mask all Ports */
804     Mvpp2PrsTcamPortMapSet (&Pe, 0);
805   }
806 
807   /* Update port Mask */
808   Mvpp2PrsTcamPortSet (&Pe, PortId, Add);
809 
810   Mvpp2PrsHwWrite (Priv, &Pe);
811 }
812 
813 /* Set entry for dsa ethertype */
814 STATIC
815 VOID
Mvpp2PrsDsaTagEthertypeSet(IN MVPP2_SHARED * Priv,IN INT32 PortId,IN BOOLEAN Add,IN BOOLEAN Tagged,IN BOOLEAN Extend)816 Mvpp2PrsDsaTagEthertypeSet (
817   IN MVPP2_SHARED *Priv,
818   IN INT32 PortId,
819   IN BOOLEAN Add,
820   IN BOOLEAN Tagged,
821   IN BOOLEAN Extend
822   )
823 {
824   MVPP2_PRS_ENTRY Pe;
825   INT32 Tid, Shift, PortMask;
826 
827   if (Extend) {
828     Tid = Tagged ? MVPP2_PE_ETYPE_EDSA_TAGGED : MVPP2_PE_ETYPE_EDSA_UNTAGGED;
829     PortMask = 0;
830     Shift = 8;
831   } else {
832     Tid = Tagged ? MVPP2_PE_ETYPE_DSA_TAGGED : MVPP2_PE_ETYPE_DSA_UNTAGGED;
833     PortMask = MVPP2_PRS_PORT_MASK;
834     Shift = 4;
835   }
836 
837   if (Priv->PrsShadow[Tid].Valid) {
838     /* Entry exist - update PortId only */
839     Pe.Index = Tid;
840     Mvpp2PrsHwRead (Priv, &Pe);
841   } else {
842     /* Entry doesn't exist - create new */
843     Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
844     Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_DSA);
845     Pe.Index = Tid;
846 
847     /*
848      * Set ethertype at offset 0 for DSA and
849      * clear it at offset 2 - obtained from Marvell.
850      */
851     Mvpp2PrsMatchEtype (&Pe, 0, MV_ETH_P_EDSA);
852     Mvpp2PrsMatchEtype (&Pe, 2, 0);
853 
854     Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_DSA_MASK,
855            MVPP2_PRS_RI_DSA_MASK);
856 
857     /* Shift ethertype + 2 Byte reserved + tag */
858     Mvpp2PrsSramShiftSet (&Pe, 2 + MVPP2_ETH_TYPE_LEN + Shift,
859            MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
860 
861     /* Update shadow table */
862     Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_DSA);
863 
864     if (Tagged) {
865       /* Set Tagged bit in DSA tag */
866       Mvpp2PrsTcamDataByteSet (
867                       &Pe,
868                       MVPP2_ETH_TYPE_LEN + 2 + 3,
869                       MVPP2_PRS_TCAM_DSA_TAGGED_BIT,
870                       MVPP2_PRS_TCAM_DSA_TAGGED_BIT
871                     );
872 
873       /* Clear all ai bits for next iteration */
874       Mvpp2PrsSramAiUpdate (&Pe, 0, MVPP2_PRS_SRAM_AI_MASK);
875 
876       /* If packet is Tagged continue check vlans */
877       Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_VLAN);
878     } else {
879       /* Set result info bits to 'no vlans' */
880       Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_VLAN_NONE, MVPP2_PRS_RI_VLAN_MASK);
881       Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_L2);
882     }
883 
884     /* Mask/unmask all ports, depending on dsa type */
885     Mvpp2PrsTcamPortMapSet (&Pe, PortMask);
886   }
887 
888   /* Update port Mask */
889   Mvpp2PrsTcamPortSet (&Pe, PortId, Add);
890 
891   Mvpp2PrsHwWrite (Priv, &Pe);
892 }
893 
894 /* Search for existing single/triple vlan entry */
895 STATIC
896 MVPP2_PRS_ENTRY *
Mvpp2PrsVlanFind(IN MVPP2_SHARED * Priv,IN UINT16 Tpid,IN INT32 Ai)897 Mvpp2PrsVlanFind (
898   IN MVPP2_SHARED *Priv,
899   IN UINT16 Tpid,
900   IN INT32 Ai
901   )
902 {
903   MVPP2_PRS_ENTRY *Pe;
904   INT32 Tid;
905 
906   Pe = Mvpp2Alloc (sizeof (*Pe));
907   if (Pe == NULL) {
908     return NULL;
909   }
910 
911   Mvpp2PrsTcamLuSet (Pe, MVPP2_PRS_LU_VLAN);
912 
913   /* Go through the all entries with MVPP2_PRS_LU_VLAN */
914   for (Tid = MVPP2_PE_FIRST_FREE_TID; Tid <= MVPP2_PE_LAST_FREE_TID; Tid++) {
915     UINT32 RiBits, AiBits;
916     BOOLEAN match;
917 
918     if (!Priv->PrsShadow[Tid].Valid || Priv->PrsShadow[Tid].Lu != MVPP2_PRS_LU_VLAN) {
919       continue;
920     }
921 
922     Pe->Index = Tid;
923 
924     Mvpp2PrsHwRead (Priv, Pe);
925     match = Mvpp2PrsTcamDataCmp (Pe, 0, Mvpp2SwapBytes16 (Tpid));
926     if (!match) {
927       continue;
928     }
929 
930     /* Get vlan type */
931     RiBits = Mvpp2PrsSramRiGet (Pe);
932     RiBits &= MVPP2_PRS_RI_VLAN_MASK;
933 
934     /* Get current Ai value from Tcam */
935     AiBits = Mvpp2PrsTcamAiGet (Pe);
936 
937     /* Clear double vlan bit */
938     AiBits &= ~MVPP2_PRS_DBL_VLAN_AI_BIT;
939 
940     if (Ai != AiBits) {
941       continue;
942     }
943 
944     if (RiBits == MVPP2_PRS_RI_VLAN_SINGLE || RiBits == MVPP2_PRS_RI_VLAN_TRIPLE) {
945       return Pe;
946     }
947   }
948 
949   Mvpp2Free (Pe);
950 
951   return NULL;
952 }
953 
954 /* Add/update single/triple vlan entry */
955 INT32
Mvpp2PrsVlanAdd(IN MVPP2_SHARED * Priv,IN UINT16 Tpid,IN INT32 Ai,IN UINT32 PortMap)956 Mvpp2PrsVlanAdd (
957   IN MVPP2_SHARED *Priv,
958   IN UINT16 Tpid,
959   IN INT32 Ai,
960   IN UINT32 PortMap
961   )
962 {
963   MVPP2_PRS_ENTRY *Pe;
964   INT32 TidAux, Tid;
965   INT32 Ret = 0;
966 
967   Pe = Mvpp2PrsVlanFind (Priv, Tpid, Ai);
968 
969   if (!Pe) {
970     /* Create new Tcam entry */
971     Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_LAST_FREE_TID, MVPP2_PE_FIRST_FREE_TID);
972     if (Tid < 0) {
973       return Tid;
974     }
975 
976     Pe = Mvpp2Alloc (sizeof (*Pe));
977     if (Pe == NULL) {
978       return MVPP2_ENOMEM;
979     }
980 
981     /* Get last double vlan Tid */
982     for (TidAux = MVPP2_PE_LAST_FREE_TID; TidAux >= MVPP2_PE_FIRST_FREE_TID; TidAux--) {
983       UINT32 RiBits;
984 
985       if (!Priv->PrsShadow[TidAux].Valid || Priv->PrsShadow[TidAux].Lu != MVPP2_PRS_LU_VLAN) {
986         continue;
987       }
988 
989       Pe->Index = TidAux;
990       Mvpp2PrsHwRead (Priv, Pe);
991       RiBits = Mvpp2PrsSramRiGet (Pe);
992       if ((RiBits & MVPP2_PRS_RI_VLAN_MASK) == MVPP2_PRS_RI_VLAN_DOUBLE) {
993         break;
994       }
995     }
996 
997     if (Tid <= TidAux) {
998       Ret = MVPP2_EINVAL;
999       goto error;
1000     }
1001 
1002     Mvpp2Memset (Pe, 0 , sizeof (MVPP2_PRS_ENTRY));
1003     Mvpp2PrsTcamLuSet (Pe, MVPP2_PRS_LU_VLAN);
1004     Pe->Index = Tid;
1005 
1006     /* Set VLAN type's offset to 0 bytes - obtained from Marvell */
1007     Mvpp2PrsMatchEtype (Pe, 0, Tpid);
1008 
1009     Mvpp2PrsSramNextLuSet (Pe, MVPP2_PRS_LU_L2);
1010 
1011     /* Shift 4 bytes - skip 1 vlan tag */
1012     Mvpp2PrsSramShiftSet (Pe, MVPP2_VLAN_TAG_LEN,
1013            MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
1014 
1015     /* Clear all Ai bits for next iteration */
1016     Mvpp2PrsSramAiUpdate (Pe, 0, MVPP2_PRS_SRAM_AI_MASK);
1017 
1018     if (Ai == MVPP2_PRS_SINGLE_VLAN_AI) {
1019       Mvpp2PrsSramRiUpdate (Pe, MVPP2_PRS_RI_VLAN_SINGLE, MVPP2_PRS_RI_VLAN_MASK);
1020     } else {
1021       Ai |= MVPP2_PRS_DBL_VLAN_AI_BIT;
1022       Mvpp2PrsSramRiUpdate (Pe, MVPP2_PRS_RI_VLAN_TRIPLE, MVPP2_PRS_RI_VLAN_MASK);
1023     }
1024 
1025     Mvpp2PrsTcamAiUpdate (Pe, Ai, MVPP2_PRS_SRAM_AI_MASK);
1026 
1027     Mvpp2PrsShadowSet (Priv, Pe->Index, MVPP2_PRS_LU_VLAN);
1028   }
1029 
1030   /* Update Ports' Mask */
1031   Mvpp2PrsTcamPortMapSet (Pe, PortMap);
1032   Mvpp2PrsHwWrite (Priv, Pe);
1033 
1034 error:
1035   Mvpp2Free (Pe);
1036 
1037   return Ret;
1038 }
1039 
1040 /* Get first free double vlan ai number */
1041 INT32
Mvpp2PrsDoubleVlanAiFreeGet(IN MVPP2_SHARED * Priv)1042 Mvpp2PrsDoubleVlanAiFreeGet (
1043   IN MVPP2_SHARED *Priv
1044   )
1045 {
1046   INT32 i;
1047 
1048   for (i = 1; i < MVPP2_PRS_DBL_VLANS_MAX; i++) {
1049     if (!Priv->PrsDoubleVlans[i]) {
1050       return i;
1051     }
1052   }
1053 
1054   return MVPP2_EINVAL;
1055 }
1056 
1057 /* Search for existing double vlan entry */
Mvpp2PrsDoubleVlanFind(IN MVPP2_SHARED * Priv,IN UINT16 Tpid1,IN UINT16 Tpid2)1058 MVPP2_PRS_ENTRY *Mvpp2PrsDoubleVlanFind (
1059   IN MVPP2_SHARED *Priv,
1060   IN UINT16 Tpid1,
1061   IN UINT16 Tpid2
1062   )
1063 {
1064   MVPP2_PRS_ENTRY *Pe;
1065   INT32 Tid;
1066 
1067   Pe = Mvpp2Alloc (sizeof (*Pe));
1068   if (Pe == NULL) {
1069     return NULL;
1070   }
1071 
1072   Mvpp2PrsTcamLuSet (Pe, MVPP2_PRS_LU_VLAN);
1073 
1074   /* Go through the all entries with MVPP2_PRS_LU_VLAN */
1075   for (Tid = MVPP2_PE_FIRST_FREE_TID; Tid <= MVPP2_PE_LAST_FREE_TID; Tid++) {
1076     UINT32 RiMask;
1077     BOOLEAN match;
1078 
1079     if (!Priv->PrsShadow[Tid].Valid || Priv->PrsShadow[Tid].Lu != MVPP2_PRS_LU_VLAN) {
1080       continue;
1081     }
1082 
1083     Pe->Index = Tid;
1084     Mvpp2PrsHwRead (Priv, Pe);
1085 
1086     match = Mvpp2PrsTcamDataCmp (Pe, 0, Mvpp2SwapBytes16 (Tpid1)) &&
1087             Mvpp2PrsTcamDataCmp (Pe, 4, Mvpp2SwapBytes16 (Tpid2));
1088 
1089     if (!match) {
1090       continue;
1091     }
1092 
1093     RiMask = Mvpp2PrsSramRiGet (Pe) & MVPP2_PRS_RI_VLAN_MASK;
1094     if (RiMask == MVPP2_PRS_RI_VLAN_DOUBLE) {
1095       return Pe;
1096     }
1097   }
1098 
1099   Mvpp2Free (Pe);
1100 
1101   return NULL;
1102 }
1103 
1104 /* Add or update double vlan entry */
1105 INT32
Mvpp2PrsDoubleVlanAdd(IN MVPP2_SHARED * Priv,IN UINT16 Tpid1,IN UINT16 Tpid2,IN UINT32 PortMap)1106 Mvpp2PrsDoubleVlanAdd (
1107   IN MVPP2_SHARED *Priv,
1108   IN UINT16 Tpid1,
1109   IN UINT16 Tpid2,
1110   IN UINT32 PortMap
1111   )
1112 {
1113   MVPP2_PRS_ENTRY *Pe;
1114   INT32 TidAux, Tid, Ai, Ret = 0;
1115 
1116   Pe = Mvpp2PrsDoubleVlanFind (Priv, Tpid1, Tpid2);
1117 
1118   if (!Pe) {
1119     /* Create new Tcam entry */
1120     Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1121     if (Tid < 0) {
1122       return Tid;
1123     }
1124 
1125     Pe = Mvpp2Alloc (sizeof (*Pe));
1126     if (Pe == NULL) {
1127       return MVPP2_ENOMEM;
1128     }
1129 
1130     /* Set Ai value for new double vlan entry */
1131     Ai = Mvpp2PrsDoubleVlanAiFreeGet (Priv);
1132     if (Ai < 0) {
1133       Ret = Ai;
1134       goto error;
1135     }
1136 
1137     /* Get first single/triple vlan Tid */
1138     for (TidAux = MVPP2_PE_FIRST_FREE_TID; TidAux <= MVPP2_PE_LAST_FREE_TID; TidAux++) {
1139       UINT32 RiBits;
1140 
1141       if (!Priv->PrsShadow[TidAux].Valid || Priv->PrsShadow[TidAux].Lu != MVPP2_PRS_LU_VLAN) {
1142         continue;
1143       }
1144 
1145       Pe->Index = TidAux;
1146       Mvpp2PrsHwRead (Priv, Pe);
1147       RiBits = Mvpp2PrsSramRiGet (Pe);
1148       RiBits &= MVPP2_PRS_RI_VLAN_MASK;
1149 
1150       if (RiBits == MVPP2_PRS_RI_VLAN_SINGLE || RiBits == MVPP2_PRS_RI_VLAN_TRIPLE) {
1151         break;
1152       }
1153     }
1154 
1155     if (Tid >= TidAux) {
1156       Ret = MVPP2_ERANGE;
1157       goto error;
1158     }
1159 
1160     Mvpp2Memset (Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1161     Mvpp2PrsTcamLuSet (Pe, MVPP2_PRS_LU_VLAN);
1162     Pe->Index = Tid;
1163 
1164     Priv->PrsDoubleVlans[Ai] = TRUE;
1165 
1166     /* Set both VLAN types' offsets to 0 and 4 bytes - obtained from Marvell */
1167     Mvpp2PrsMatchEtype (Pe, 0, Tpid1);
1168     Mvpp2PrsMatchEtype (Pe, 4, Tpid2);
1169 
1170     Mvpp2PrsSramNextLuSet (Pe, MVPP2_PRS_LU_VLAN);
1171 
1172     /* Shift 8 bytes - skip 2 vlan tags */
1173     Mvpp2PrsSramShiftSet (Pe, 2 * MVPP2_VLAN_TAG_LEN, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
1174     Mvpp2PrsSramRiUpdate (Pe, MVPP2_PRS_RI_VLAN_DOUBLE, MVPP2_PRS_RI_VLAN_MASK);
1175     Mvpp2PrsSramAiUpdate (Pe, Ai | MVPP2_PRS_DBL_VLAN_AI_BIT, MVPP2_PRS_SRAM_AI_MASK);
1176 
1177     Mvpp2PrsShadowSet (Priv, Pe->Index, MVPP2_PRS_LU_VLAN);
1178   }
1179 
1180   /* Update Ports' Mask */
1181   Mvpp2PrsTcamPortMapSet (Pe, PortMap);
1182   Mvpp2PrsHwWrite (Priv, Pe);
1183 
1184 error:
1185   Mvpp2Free (Pe);
1186   return Ret;
1187 }
1188 
1189 /* IPv4 header parsing for fragmentation and L4 Offset */
1190 STATIC
1191 INT32
Mvpp2PrsIp4Proto(IN MVPP2_SHARED * Priv,IN UINT16 Proto,IN UINT32 Ri,IN UINT32 RiMask)1192 Mvpp2PrsIp4Proto (
1193   IN MVPP2_SHARED *Priv,
1194   IN UINT16 Proto,
1195   IN UINT32 Ri,
1196   IN UINT32 RiMask
1197   )
1198 {
1199   MVPP2_PRS_ENTRY Pe;
1200   INT32 Tid;
1201 
1202   if ((Proto != MV_IPPR_TCP) && (Proto != MV_IPPR_UDP) && (Proto != MV_IPPR_IGMP)) {
1203     return MVPP2_EINVAL;
1204   }
1205 
1206   /* Fragmented packet */
1207   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1208   if (Tid < 0) {
1209     return Tid;
1210   }
1211 
1212   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1213   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_IP4);
1214   Pe.Index = Tid;
1215 
1216   /* Set next Lu to IPv4 - 12 bytes shift */
1217   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_IP4);
1218   Mvpp2PrsSramShiftSet (&Pe, 12, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
1219 
1220   /* Set L4 offset 4 bytes relative IPv4 header size (current position) */
1221   Mvpp2PrsSramOffsetSet (
1222                   &Pe,
1223                   MVPP2_PRS_SRAM_UDF_TYPE_L4,
1224                   sizeof (Mvpp2Iphdr) - 4,
1225                   MVPP2_PRS_SRAM_OP_SEL_UDF_ADD
1226                 );
1227 
1228   Mvpp2PrsSramAiUpdate (&Pe, MVPP2_PRS_IPV4_DIP_AI_BIT, MVPP2_PRS_IPV4_DIP_AI_BIT);
1229   Mvpp2PrsSramRiUpdate (&Pe, Ri | MVPP2_PRS_RI_IP_FRAG_MASK, RiMask | MVPP2_PRS_RI_IP_FRAG_MASK);
1230 
1231   Mvpp2PrsTcamDataByteSet (&Pe, 5, Proto, MVPP2_PRS_TCAM_PROTO_MASK);
1232   Mvpp2PrsTcamAiUpdate (&Pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT);
1233 
1234   /* Unmask all Ports */
1235   Mvpp2PrsTcamPortMapSet (&Pe, MVPP2_PRS_PORT_MASK);
1236 
1237   /* Update shadow table and hw entry */
1238   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_IP4);
1239   Mvpp2PrsHwWrite (Priv, &Pe);
1240 
1241   /* Not fragmented packet */
1242   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1243   if (Tid < 0) {
1244     return Tid;
1245   }
1246 
1247   Pe.Index = Tid;
1248 
1249   /* Clear Ri before updating */
1250   Pe.Sram.Word[MVPP2_PRS_SRAM_RI_WORD] = 0x0;
1251   Pe.Sram.Word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0;
1252   Mvpp2PrsSramRiUpdate (&Pe, Ri, RiMask);
1253 
1254   Mvpp2PrsTcamDataByteSet (&Pe, 2, 0x00, MVPP2_PRS_TCAM_PROTO_MASK_L);
1255   Mvpp2PrsTcamDataByteSet (&Pe, 3, 0x00, MVPP2_PRS_TCAM_PROTO_MASK);
1256 
1257   /* Update shadow table and hw entry */
1258   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_IP4);
1259   Mvpp2PrsHwWrite (Priv, &Pe);
1260 
1261   return 0;
1262 }
1263 
1264 /* IPv4 L3 multicast or broadcast */
1265 STATIC
1266 INT32
Mvpp2PrsIp4Cast(IN MVPP2_SHARED * Priv,IN UINT16 L3Cast)1267 Mvpp2PrsIp4Cast (
1268   IN MVPP2_SHARED *Priv,
1269   IN UINT16 L3Cast
1270   )
1271 {
1272   MVPP2_PRS_ENTRY Pe;
1273   INT32 Mask, Tid;
1274 
1275   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1276   if (Tid < 0) {
1277     return Tid;
1278   }
1279 
1280   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1281   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_IP4);
1282   Pe.Index = Tid;
1283 
1284   switch (L3Cast) {
1285   case MVPP2_PRS_L3_MULTI_CAST:
1286     Mvpp2PrsTcamDataByteSet (&Pe, 0, MVPP2_PRS_IPV4_MC, MVPP2_PRS_IPV4_MC_MASK);
1287     Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L3_MCAST, MVPP2_PRS_RI_L3_ADDR_MASK);
1288     break;
1289   case  MVPP2_PRS_L3_BROAD_CAST:
1290     Mask = MVPP2_PRS_IPV4_BC_MASK;
1291     Mvpp2PrsTcamDataByteSet (&Pe, 0, Mask, Mask);
1292     Mvpp2PrsTcamDataByteSet (&Pe, 1, Mask, Mask);
1293     Mvpp2PrsTcamDataByteSet (&Pe, 2, Mask, Mask);
1294     Mvpp2PrsTcamDataByteSet (&Pe, 3, Mask, Mask);
1295     Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L3_BCAST, MVPP2_PRS_RI_L3_ADDR_MASK);
1296     break;
1297   default:
1298     return MVPP2_EINVAL;
1299   }
1300 
1301   /* Finished: go to Flowid generation */
1302   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_FLOWS);
1303   Mvpp2PrsSramBitsSet (&Pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
1304 
1305   Mvpp2PrsTcamAiUpdate (&Pe, MVPP2_PRS_IPV4_DIP_AI_BIT, MVPP2_PRS_IPV4_DIP_AI_BIT);
1306 
1307   /* Unmask all Ports */
1308   Mvpp2PrsTcamPortMapSet (&Pe, MVPP2_PRS_PORT_MASK);
1309 
1310   /* Update shadow table and hw entry */
1311   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_IP4);
1312   Mvpp2PrsHwWrite (Priv, &Pe);
1313 
1314   return 0;
1315 }
1316 
1317 /* Set entries for protocols over IPv6  */
1318 STATIC
1319 INT32
Mvpp2PrsIp6Proto(IN MVPP2_SHARED * Priv,IN UINT16 Proto,IN UINT32 Ri,IN UINT32 RiMask)1320 Mvpp2PrsIp6Proto (
1321   IN MVPP2_SHARED *Priv,
1322   IN UINT16 Proto,
1323   IN UINT32 Ri,
1324   IN UINT32 RiMask
1325   )
1326 {
1327   MVPP2_PRS_ENTRY Pe;
1328   INT32 Tid;
1329 
1330   if ((Proto != MV_IPPR_TCP) && (Proto != MV_IPPR_UDP) &&
1331       (Proto != MV_IPPR_ICMPV6) && (Proto != MV_IPPR_IPIP))
1332   {
1333     return MVPP2_EINVAL;
1334   }
1335 
1336   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1337   if (Tid < 0) {
1338     return Tid;
1339   }
1340 
1341   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1342   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_IP6);
1343   Pe.Index = Tid;
1344 
1345   /* Finished: go to Flowid generation */
1346   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_FLOWS);
1347   Mvpp2PrsSramBitsSet (&Pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
1348   Mvpp2PrsSramRiUpdate (&Pe, Ri, RiMask);
1349 
1350   /* Set offset for protocol 6 bytes relative to IPv6 header size */
1351   Mvpp2PrsSramOffsetSet (
1352                   &Pe,
1353                   MVPP2_PRS_SRAM_UDF_TYPE_L4,
1354                   sizeof (Mvpp2Ipv6hdr) - 6,
1355                   MVPP2_PRS_SRAM_OP_SEL_UDF_ADD
1356                 );
1357 
1358   Mvpp2PrsTcamDataByteSet (&Pe, 0, Proto, MVPP2_PRS_TCAM_PROTO_MASK);
1359   Mvpp2PrsTcamAiUpdate (&Pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT, MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
1360 
1361   /* Unmask all Ports */
1362   Mvpp2PrsTcamPortMapSet (&Pe, MVPP2_PRS_PORT_MASK);
1363 
1364   /* Write HW */
1365   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_IP6);
1366   Mvpp2PrsHwWrite (Priv, &Pe);
1367 
1368   return 0;
1369 }
1370 
1371 /* IPv6 L3 multicast entry */
1372 STATIC
1373 INT32
Mvpp2PrsIp6Cast(IN MVPP2_SHARED * Priv,IN UINT16 L3Cast)1374 Mvpp2PrsIp6Cast (
1375   IN MVPP2_SHARED *Priv,
1376   IN UINT16 L3Cast
1377   )
1378 {
1379   MVPP2_PRS_ENTRY Pe;
1380   INT32 Tid;
1381 
1382   if (L3Cast != MVPP2_PRS_L3_MULTI_CAST) {
1383     return MVPP2_EINVAL;
1384   }
1385 
1386   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1387   if (Tid < 0) {
1388     return Tid;
1389   }
1390 
1391   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1392   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_IP6);
1393   Pe.Index = Tid;
1394 
1395   /* Finished: go to Flowid generation */
1396   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_IP6);
1397   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L3_MCAST, MVPP2_PRS_RI_L3_ADDR_MASK);
1398   Mvpp2PrsSramAiUpdate (&Pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT, MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
1399 
1400   /* Shift back to IPv6 by 18 bytes - byte count provided by Marvell */
1401   Mvpp2PrsSramShiftSet (&Pe, -18, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
1402 
1403   Mvpp2PrsTcamDataByteSet (&Pe, 0, MVPP2_PRS_IPV6_MC, MVPP2_PRS_IPV6_MC_MASK);
1404   Mvpp2PrsTcamAiUpdate (&Pe, 0, MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
1405 
1406   /* Unmask all Ports */
1407   Mvpp2PrsTcamPortMapSet (&Pe, MVPP2_PRS_PORT_MASK);
1408 
1409   /* Update shadow table and hw entry */
1410   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_IP6);
1411   Mvpp2PrsHwWrite (Priv, &Pe);
1412 
1413   return 0;
1414 }
1415 
1416 /* Parser per-Port initialization */
1417 STATIC
1418 VOID
Mvpp2PrsHwPortInit(IN MVPP2_SHARED * Priv,IN INT32 PortId,IN INT32 LuFirst,IN INT32 LuMax,IN INT32 Offset)1419 Mvpp2PrsHwPortInit (
1420   IN MVPP2_SHARED *Priv,
1421   IN INT32 PortId,
1422   IN INT32 LuFirst,
1423   IN INT32 LuMax,
1424   IN INT32 Offset
1425   )
1426 {
1427   UINT32 Val;
1428 
1429   /* Set lookup ID */
1430   Val = Mvpp2Read (Priv, MVPP2_PRS_INIT_LOOKUP_REG);
1431   Val &= ~MVPP2_PRS_PORT_LU_MASK (PortId);
1432   Val |=  MVPP2_PRS_PORT_LU_VAL (PortId, LuFirst);
1433   Mvpp2Write (Priv, MVPP2_PRS_INIT_LOOKUP_REG, Val);
1434 
1435   /* Set maximum number of loops for packet received from PortId */
1436   Val = Mvpp2Read (Priv, MVPP2_PRS_MAX_LOOP_REG(PortId));
1437   Val &= ~MVPP2_PRS_MAX_LOOP_MASK (PortId);
1438   Val |= MVPP2_PRS_MAX_LOOP_VAL (PortId, LuMax);
1439   Mvpp2Write (Priv, MVPP2_PRS_MAX_LOOP_REG(PortId), Val);
1440 
1441   /*
1442    * Set initial Offset for packet header extraction for the first
1443    * searching loop
1444    */
1445   Val = Mvpp2Read (Priv, MVPP2_PRS_INIT_OFFS_REG(PortId));
1446   Val &= ~MVPP2_PRS_INIT_OFF_MASK (PortId);
1447   Val |= MVPP2_PRS_INIT_OFF_VAL (PortId, Offset);
1448   Mvpp2Write (Priv, MVPP2_PRS_INIT_OFFS_REG(PortId), Val);
1449 }
1450 
1451 /* Default Flow entries initialization for all Ports */
1452 STATIC
1453 VOID
Mvpp2PrsDefFlowInit(IN MVPP2_SHARED * Priv)1454 Mvpp2PrsDefFlowInit (
1455   IN MVPP2_SHARED *Priv
1456   )
1457 {
1458   MVPP2_PRS_ENTRY Pe;
1459   INT32 PortId;
1460 
1461   for (PortId = 0; PortId < MVPP2_MAX_PORTS; PortId++) {
1462     Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1463     Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_FLOWS);
1464     Pe.Index = MVPP2_PE_FIRST_DEFAULT_FLOW - PortId;
1465 
1466     /* Mask all Ports */
1467     Mvpp2PrsTcamPortMapSet (&Pe, 0);
1468 
1469     /* Set Flow ID*/
1470     Mvpp2PrsSramAiUpdate (&Pe, PortId, MVPP2_PRS_FLOW_ID_MASK);
1471     Mvpp2PrsSramBitsSet (&Pe, MVPP2_PRS_SRAM_LU_DONE_BIT, 1);
1472 
1473     /* Update shadow table and hw entry */
1474     Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_FLOWS);
1475     Mvpp2PrsHwWrite (Priv, &Pe);
1476   }
1477 }
1478 
1479 /* Set default entry for Marvell Header field */
1480 STATIC
1481 VOID
Mvpp2PrsMhInit(IN MVPP2_SHARED * Priv)1482 Mvpp2PrsMhInit (
1483   IN MVPP2_SHARED *Priv
1484   )
1485 {
1486   MVPP2_PRS_ENTRY Pe;
1487 
1488   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1489 
1490   Pe.Index = MVPP2_PE_MH_DEFAULT;
1491   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_MH);
1492   Mvpp2PrsSramShiftSet (&Pe, MVPP2_MH_SIZE, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
1493   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_MAC);
1494 
1495   /* Unmask all Ports */
1496   Mvpp2PrsTcamPortMapSet (&Pe, MVPP2_PRS_PORT_MASK);
1497 
1498   /* Update shadow table and hw entry */
1499   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_MH);
1500   Mvpp2PrsHwWrite (Priv, &Pe);
1501 }
1502 
1503 /*
1504  * Set default entires (place holder) for promiscuous, non-promiscuous and
1505  * multicast MAC Addresses
1506  */
1507 STATIC
1508 VOID
Mvpp2PrsMacInit(IN MVPP2_SHARED * Priv)1509 Mvpp2PrsMacInit (
1510   IN MVPP2_SHARED *Priv
1511   )
1512 {
1513   MVPP2_PRS_ENTRY Pe;
1514 
1515   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1516 
1517   /* Non-promiscuous mode for all Ports - DROP unknown packets */
1518   Pe.Index = MVPP2_PE_MAC_NON_PROMISCUOUS;
1519   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_MAC);
1520 
1521   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_DROP_MASK, MVPP2_PRS_RI_DROP_MASK);
1522   Mvpp2PrsSramBitsSet (&Pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
1523   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_FLOWS);
1524 
1525   /* Unmask all Ports */
1526   Mvpp2PrsTcamPortMapSet (&Pe, MVPP2_PRS_PORT_MASK);
1527 
1528   /* Update shadow table and hw entry */
1529   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_MAC);
1530   Mvpp2PrsHwWrite (Priv, &Pe);
1531 
1532   /* Place holders only - no Ports */
1533   Mvpp2PrsMacDropAllSet (Priv, 0, FALSE);
1534   Mvpp2PrsMacPromiscSet (Priv, 0, FALSE);
1535   Mvpp2PrsMacMultiSet (Priv, MVPP2_PE_MAC_MC_ALL, 0, FALSE);
1536   Mvpp2PrsMacMultiSet (Priv, MVPP2_PE_MAC_MC_IP6, 0, FALSE);
1537 }
1538 
1539 /* Set default entries for various types of dsa packets */
1540 STATIC
1541 VOID
Mvpp2PrsDsaInit(IN MVPP2_SHARED * Priv)1542 Mvpp2PrsDsaInit (
1543   IN MVPP2_SHARED *Priv
1544   )
1545 {
1546   MVPP2_PRS_ENTRY Pe;
1547 
1548   /* None tagged EDSA entry - place holder */
1549   Mvpp2PrsDsaTagSet (Priv, 0, FALSE, MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
1550 
1551   /* Tagged EDSA entry - place holder */
1552   Mvpp2PrsDsaTagSet (Priv, 0, FALSE, MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
1553 
1554   /* None tagged DSA entry - place holder */
1555   Mvpp2PrsDsaTagSet (Priv, 0, FALSE, MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);
1556 
1557   /* Tagged DSA entry - place holder */
1558   Mvpp2PrsDsaTagSet (Priv, 0, FALSE, MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
1559 
1560   /* None tagged EDSA ethertype entry - place holder*/
1561   Mvpp2PrsDsaTagEthertypeSet (Priv, 0, FALSE, MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
1562 
1563   /* Tagged EDSA ethertype entry - place holder*/
1564   Mvpp2PrsDsaTagEthertypeSet (Priv, 0, FALSE, MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
1565 
1566   /* None tagged DSA ethertype entry */
1567   Mvpp2PrsDsaTagEthertypeSet (Priv, 0, TRUE, MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);
1568 
1569   /* Tagged DSA ethertype entry */
1570   Mvpp2PrsDsaTagEthertypeSet (Priv, 0, TRUE, MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
1571 
1572   /* Set default entry, in case DSA or EDSA tag not found */
1573   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1574   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_DSA);
1575   Pe.Index = MVPP2_PE_DSA_DEFAULT;
1576   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_VLAN);
1577 
1578   /* Shift 0 bytes */
1579   Mvpp2PrsSramShiftSet (&Pe, 0, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
1580   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_MAC);
1581 
1582   /* Clear all Sram ai bits for next iteration */
1583   Mvpp2PrsSramAiUpdate (&Pe, 0, MVPP2_PRS_SRAM_AI_MASK);
1584 
1585   /* Unmask all Ports */
1586   Mvpp2PrsTcamPortMapSet (&Pe, MVPP2_PRS_PORT_MASK);
1587 
1588   Mvpp2PrsHwWrite (Priv, &Pe);
1589 }
1590 
1591 /* Match basic ethertypes */
1592 STATIC
1593 INT32
Mvpp2PrsEtypeInit(IN MVPP2_SHARED * Priv)1594 Mvpp2PrsEtypeInit (
1595   IN MVPP2_SHARED *Priv
1596   )
1597 {
1598   MVPP2_PRS_ENTRY Pe;
1599   INT32 Tid;
1600 
1601   /* Ethertype: PPPoE */
1602   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1603   if (Tid < 0) {
1604     return Tid;
1605   }
1606 
1607   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1608   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_L2);
1609   Pe.Index = Tid;
1610 
1611   /* Set PPPoE type offset to 0 - obtained from Marvell */
1612   Mvpp2PrsMatchEtype (&Pe, 0, MV_ETH_P_PPP_SES);
1613 
1614   Mvpp2PrsSramShiftSet (&Pe, MVPP2_PPPOE_HDR_SIZE, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
1615   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_PPPOE);
1616   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_PPPOE_MASK, MVPP2_PRS_RI_PPPOE_MASK);
1617 
1618   /* Update shadow table and hw entry */
1619   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_L2);
1620   Priv->PrsShadow[Pe.Index].Udf = MVPP2_PRS_UDF_L2_DEF;
1621   Priv->PrsShadow[Pe.Index].Finish = FALSE;
1622   Mvpp2PrsShadowRiSet (Priv, Pe.Index, MVPP2_PRS_RI_PPPOE_MASK, MVPP2_PRS_RI_PPPOE_MASK);
1623   Mvpp2PrsHwWrite (Priv, &Pe);
1624 
1625   /* Ethertype: ARP */
1626   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1627   if (Tid < 0) {
1628     return Tid;
1629   }
1630 
1631   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1632   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_L2);
1633   Pe.Index = Tid;
1634 
1635   /* Set ARP type offset to 0 - obtained from Marvell */
1636   Mvpp2PrsMatchEtype (&Pe, 0, MV_ETH_P_ARP);
1637 
1638   /* Generate Flow in the next iteration*/
1639   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_FLOWS);
1640   Mvpp2PrsSramBitsSet (&Pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
1641   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L3_ARP, MVPP2_PRS_RI_L3_PROTO_MASK);
1642 
1643   /* Set L3 Offset */
1644   Mvpp2PrsSramOffsetSet (&Pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
1645 
1646   /* Update shadow table and hw entry */
1647   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_L2);
1648   Priv->PrsShadow[Pe.Index].Udf = MVPP2_PRS_UDF_L2_DEF;
1649   Priv->PrsShadow[Pe.Index].Finish = TRUE;
1650   Mvpp2PrsShadowRiSet (Priv, Pe.Index, MVPP2_PRS_RI_L3_ARP, MVPP2_PRS_RI_L3_PROTO_MASK);
1651   Mvpp2PrsHwWrite (Priv, &Pe);
1652 
1653   /* Ethertype: LBTD */
1654   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1655   if (Tid < 0) {
1656     return Tid;
1657   }
1658 
1659   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1660   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_L2);
1661   Pe.Index = Tid;
1662 
1663   /* Set LBTD type offset to 0 - obtained from Marvell */
1664   Mvpp2PrsMatchEtype (&Pe, 0, MVPP2_IP_LBDT_TYPE);
1665 
1666   /* Generate Flow in the next iteration*/
1667   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_FLOWS);
1668   Mvpp2PrsSramBitsSet (&Pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
1669   Mvpp2PrsSramRiUpdate (
1670                   &Pe,
1671                   MVPP2_PRS_RI_CPU_CODE_RX_SPEC | MVPP2_PRS_RI_UDF3_RX_SPECIAL,
1672                   MVPP2_PRS_RI_CPU_CODE_MASK | MVPP2_PRS_RI_UDF3_MASK
1673                 );
1674 
1675   /* Set L3 Offset */
1676   Mvpp2PrsSramOffsetSet (&Pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
1677 
1678   /* Update shadow table and hw entry */
1679   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_L2);
1680   Priv->PrsShadow[Pe.Index].Udf = MVPP2_PRS_UDF_L2_DEF;
1681   Priv->PrsShadow[Pe.Index].Finish = TRUE;
1682   Mvpp2PrsShadowRiSet (
1683                   Priv,
1684                   Pe.Index,
1685                   MVPP2_PRS_RI_CPU_CODE_RX_SPEC | MVPP2_PRS_RI_UDF3_RX_SPECIAL,
1686                   MVPP2_PRS_RI_CPU_CODE_MASK | MVPP2_PRS_RI_UDF3_MASK
1687                 );
1688 
1689   Mvpp2PrsHwWrite (Priv, &Pe);
1690 
1691   /* Ethertype: IPv4 without options */
1692   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1693   if (Tid < 0) {
1694     return Tid;
1695   }
1696 
1697   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1698   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_L2);
1699   Pe.Index = Tid;
1700 
1701   /* Set IPv4 type offset to 0 - obtained from Marvell */
1702   Mvpp2PrsMatchEtype (&Pe, 0, MV_ETH_P_IP);
1703   Mvpp2PrsTcamDataByteSet (
1704                   &Pe,
1705                   MVPP2_ETH_TYPE_LEN,
1706                   MVPP2_PRS_IPV4_HEAD | MVPP2_PRS_IPV4_IHL,
1707                   MVPP2_PRS_IPV4_HEAD_MASK | MVPP2_PRS_IPV4_IHL_MASK
1708                 );
1709 
1710   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_IP4);
1711   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L3_IP4, MVPP2_PRS_RI_L3_PROTO_MASK);
1712 
1713   /* Skip EthType + 4 bytes of IP header */
1714   Mvpp2PrsSramShiftSet (&Pe, MVPP2_ETH_TYPE_LEN + 4, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
1715 
1716   /* Set L3 Offset */
1717   Mvpp2PrsSramOffsetSet (&Pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
1718 
1719   /* Update shadow table and hw entry */
1720   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_L2);
1721   Priv->PrsShadow[Pe.Index].Udf = MVPP2_PRS_UDF_L2_DEF;
1722   Priv->PrsShadow[Pe.Index].Finish = FALSE;
1723   Mvpp2PrsShadowRiSet (Priv, Pe.Index, MVPP2_PRS_RI_L3_IP4, MVPP2_PRS_RI_L3_PROTO_MASK);
1724   Mvpp2PrsHwWrite (Priv, &Pe);
1725 
1726   /* Ethertype: IPv4 with options */
1727   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1728   if (Tid < 0) {
1729     return Tid;
1730   }
1731 
1732   Pe.Index = Tid;
1733 
1734   /* Clear Tcam data before updating */
1735   Pe.Tcam.Byte[MVPP2_PRS_TCAM_DATA_BYTE(MVPP2_ETH_TYPE_LEN)] = 0x0;
1736   Pe.Tcam.Byte[MVPP2_PRS_TCAM_DATA_BYTE_EN(MVPP2_ETH_TYPE_LEN)] = 0x0;
1737 
1738   Mvpp2PrsTcamDataByteSet (&Pe, MVPP2_ETH_TYPE_LEN, MVPP2_PRS_IPV4_HEAD, MVPP2_PRS_IPV4_HEAD_MASK);
1739 
1740   /* Clear Ri before updating */
1741   Pe.Sram.Word[MVPP2_PRS_SRAM_RI_WORD] = 0x0;
1742   Pe.Sram.Word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0;
1743   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L3_IP4_OPT, MVPP2_PRS_RI_L3_PROTO_MASK);
1744 
1745   /* Update shadow table and hw entry */
1746   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_L2);
1747   Priv->PrsShadow[Pe.Index].Udf = MVPP2_PRS_UDF_L2_DEF;
1748   Priv->PrsShadow[Pe.Index].Finish = FALSE;
1749   Mvpp2PrsShadowRiSet (Priv, Pe.Index, MVPP2_PRS_RI_L3_IP4_OPT, MVPP2_PRS_RI_L3_PROTO_MASK);
1750   Mvpp2PrsHwWrite (Priv, &Pe);
1751 
1752   /* Ethertype: IPv6 without options */
1753   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1754   if (Tid < 0) {
1755     return Tid;
1756   }
1757 
1758   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1759   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_L2);
1760   Pe.Index = Tid;
1761 
1762   /* Set IPv6 type offset to 0 - obtained from Marvell */
1763   Mvpp2PrsMatchEtype (&Pe, 0, MV_ETH_P_IPV6);
1764 
1765   /* Skip DIP of IPV6 header - value provided by Marvell */
1766   Mvpp2PrsSramShiftSet (&Pe, MVPP2_ETH_TYPE_LEN + 8 + MVPP2_MAX_L3_ADDR_SIZE, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
1767   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_IP6);
1768   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L3_IP6, MVPP2_PRS_RI_L3_PROTO_MASK);
1769 
1770   /* Set L3 Offset */
1771   Mvpp2PrsSramOffsetSet (&Pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
1772 
1773   /* Update shadow table and hw entry */
1774   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_L2);
1775   Priv->PrsShadow[Pe.Index].Udf = MVPP2_PRS_UDF_L2_DEF;
1776   Priv->PrsShadow[Pe.Index].Finish = FALSE;
1777   Mvpp2PrsShadowRiSet (Priv, Pe.Index, MVPP2_PRS_RI_L3_IP6, MVPP2_PRS_RI_L3_PROTO_MASK);
1778   Mvpp2PrsHwWrite (Priv, &Pe);
1779 
1780   /* Default entry for MVPP2_PRS_LU_L2 - Unknown ethtype */
1781   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1782   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_L2);
1783   Pe.Index = MVPP2_PE_ETH_TYPE_UN;
1784 
1785   /* Unmask all Ports */
1786   Mvpp2PrsTcamPortMapSet (&Pe, MVPP2_PRS_PORT_MASK);
1787 
1788   /* Generate Flow in the next iteration*/
1789   Mvpp2PrsSramBitsSet (&Pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
1790   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_FLOWS);
1791   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L3_UN, MVPP2_PRS_RI_L3_PROTO_MASK);
1792 
1793   /* Set L3 Offset even it's unknown L3 */
1794   Mvpp2PrsSramOffsetSet (&Pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
1795 
1796   /* Update shadow table and hw entry */
1797   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_L2);
1798   Priv->PrsShadow[Pe.Index].Udf = MVPP2_PRS_UDF_L2_DEF;
1799   Priv->PrsShadow[Pe.Index].Finish = TRUE;
1800   Mvpp2PrsShadowRiSet (Priv, Pe.Index, MVPP2_PRS_RI_L3_UN, MVPP2_PRS_RI_L3_PROTO_MASK);
1801   Mvpp2PrsHwWrite (Priv, &Pe);
1802 
1803   return 0;
1804 }
1805 
1806 /*
1807  * Configure vlan entries and detect up to 2 successive VLAN tags.
1808  * Possible options:
1809  * 0x8100, 0x88A8
1810  * 0x8100, 0x8100
1811  * 0x8100, 0x88A8
1812  */
1813 STATIC
1814 INT32
Mvpp2PrsVlanInit(IN MVPP2_SHARED * Priv)1815 Mvpp2PrsVlanInit (
1816   IN MVPP2_SHARED *Priv
1817   )
1818 {
1819   MVPP2_PRS_ENTRY Pe;
1820   INT32 Err;
1821 
1822   /* Double VLAN: 0x8100, 0x88A8 */
1823   Err = Mvpp2PrsDoubleVlanAdd (Priv, MV_ETH_P_8021Q, MV_ETH_P_8021AD, MVPP2_PRS_PORT_MASK);
1824   if (Err != 0) {
1825     return Err;
1826   }
1827 
1828   /* Double VLAN: 0x8100, 0x8100 */
1829   Err = Mvpp2PrsDoubleVlanAdd (Priv, MV_ETH_P_8021Q, MV_ETH_P_8021Q, MVPP2_PRS_PORT_MASK);
1830   if (Err != 0) {
1831     return Err;
1832   }
1833 
1834   /* Single VLAN: 0x88a8 */
1835   Err = Mvpp2PrsVlanAdd (Priv, MV_ETH_P_8021AD, MVPP2_PRS_SINGLE_VLAN_AI, MVPP2_PRS_PORT_MASK);
1836   if (Err != 0) {
1837     return Err;
1838   }
1839 
1840   /* Single VLAN: 0x8100 */
1841   Err = Mvpp2PrsVlanAdd (Priv, MV_ETH_P_8021Q, MVPP2_PRS_SINGLE_VLAN_AI, MVPP2_PRS_PORT_MASK);
1842   if (Err != 0) {
1843     return Err;
1844   }
1845 
1846   /* Set default double vlan entry */
1847   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1848   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_VLAN);
1849   Pe.Index = MVPP2_PE_VLAN_DBL;
1850 
1851   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_L2);
1852 
1853   /* Clear ai for next iterations */
1854   Mvpp2PrsSramAiUpdate (&Pe, 0, MVPP2_PRS_SRAM_AI_MASK);
1855   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_VLAN_DOUBLE, MVPP2_PRS_RI_VLAN_MASK);
1856 
1857   Mvpp2PrsTcamAiUpdate (&Pe, MVPP2_PRS_DBL_VLAN_AI_BIT, MVPP2_PRS_DBL_VLAN_AI_BIT);
1858 
1859   /* Unmask all Ports */
1860   Mvpp2PrsTcamPortMapSet (&Pe, MVPP2_PRS_PORT_MASK);
1861 
1862   /* Update shadow table and hw entry */
1863   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_VLAN);
1864   Mvpp2PrsHwWrite (Priv, &Pe);
1865 
1866   /* Set default vlan none entry */
1867   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1868   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_VLAN);
1869   Pe.Index = MVPP2_PE_VLAN_NONE;
1870 
1871   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_L2);
1872   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_VLAN_NONE, MVPP2_PRS_RI_VLAN_MASK);
1873 
1874   /* Unmask all Ports */
1875   Mvpp2PrsTcamPortMapSet (&Pe, MVPP2_PRS_PORT_MASK);
1876 
1877   /* Update shadow table and hw entry */
1878   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_VLAN);
1879   Mvpp2PrsHwWrite (Priv, &Pe);
1880 
1881   return 0;
1882 }
1883 
1884 /* Set entries for PPPoE ethertype */
1885 STATIC
1886 INT32
Mvpp2PrsPppoeInit(IN MVPP2_SHARED * Priv)1887 Mvpp2PrsPppoeInit (
1888   IN MVPP2_SHARED *Priv
1889   )
1890 {
1891   MVPP2_PRS_ENTRY Pe;
1892   INT32 Tid;
1893 
1894   /* IPv4 over PPPoE with options */
1895   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1896   if (Tid < 0) {
1897     return Tid;
1898   }
1899 
1900   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1901   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_PPPOE);
1902   Pe.Index = Tid;
1903 
1904   /* Set IPv4 over PPPoE type offset to 0 - obtained from Marvell */
1905   Mvpp2PrsMatchEtype (&Pe, 0, MV_PPP_IP);
1906 
1907   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_IP4);
1908   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L3_IP4_OPT, MVPP2_PRS_RI_L3_PROTO_MASK);
1909 
1910   /* Skip EthType + 4 bytes of IP header */
1911   Mvpp2PrsSramShiftSet (&Pe, MVPP2_ETH_TYPE_LEN + 4, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
1912 
1913   /* Set L3 Offset */
1914   Mvpp2PrsSramOffsetSet (&Pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
1915 
1916   /* Update shadow table and hw entry */
1917   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_PPPOE);
1918   Mvpp2PrsHwWrite (Priv, &Pe);
1919 
1920   /* IPv4 over PPPoE without options */
1921   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1922   if (Tid < 0) {
1923     return Tid;
1924   }
1925 
1926   Pe.Index = Tid;
1927 
1928   Mvpp2PrsTcamDataByteSet (
1929                   &Pe,
1930                   MVPP2_ETH_TYPE_LEN,
1931                   MVPP2_PRS_IPV4_HEAD | MVPP2_PRS_IPV4_IHL,
1932                   MVPP2_PRS_IPV4_HEAD_MASK | MVPP2_PRS_IPV4_IHL_MASK
1933                 );
1934 
1935   /* Clear Ri before updating */
1936   Pe.Sram.Word[MVPP2_PRS_SRAM_RI_WORD] = 0x0;
1937   Pe.Sram.Word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0;
1938   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L3_IP4, MVPP2_PRS_RI_L3_PROTO_MASK);
1939 
1940   /* Update shadow table and hw entry */
1941   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_PPPOE);
1942   Mvpp2PrsHwWrite (Priv, &Pe);
1943 
1944   /* IPv6 over PPPoE */
1945   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1946   if (Tid < 0) {
1947     return Tid;
1948   }
1949 
1950   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1951   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_PPPOE);
1952   Pe.Index = Tid;
1953 
1954   /* Set IPv6 over PPPoE type offset to 0 - obtained from Marvell */
1955   Mvpp2PrsMatchEtype (&Pe, 0, MV_PPP_IPV6);
1956 
1957   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_IP6);
1958   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L3_IP6, MVPP2_PRS_RI_L3_PROTO_MASK);
1959 
1960   /* Skip EthType + 4 bytes of IPv6 header */
1961   Mvpp2PrsSramShiftSet (&Pe, MVPP2_ETH_TYPE_LEN + 4, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
1962 
1963   /* Set L3 Offset */
1964   Mvpp2PrsSramOffsetSet (&Pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
1965 
1966   /* Update shadow table and hw entry */
1967   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_PPPOE);
1968   Mvpp2PrsHwWrite (Priv, &Pe);
1969 
1970   /* Non-IP over PPPoE */
1971   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
1972   if (Tid < 0) {
1973     return Tid;
1974   }
1975 
1976   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
1977   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_PPPOE);
1978   Pe.Index = Tid;
1979 
1980   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L3_UN, MVPP2_PRS_RI_L3_PROTO_MASK);
1981 
1982   /* Finished: go to Flowid generation */
1983   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_FLOWS);
1984   Mvpp2PrsSramBitsSet (&Pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
1985 
1986   /* Set L3 Offset even if it's unknown L3 */
1987   Mvpp2PrsSramOffsetSet (&Pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);
1988 
1989   /* Update shadow table and hw entry */
1990   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_PPPOE);
1991   Mvpp2PrsHwWrite (Priv, &Pe);
1992 
1993   return 0;
1994 }
1995 
1996 /* Initialize entries for IPv4 */
1997 STATIC
1998 INT32
Mvpp2PrsIp4Init(IN MVPP2_SHARED * Priv)1999 Mvpp2PrsIp4Init (
2000   IN MVPP2_SHARED *Priv
2001   )
2002 {
2003   MVPP2_PRS_ENTRY Pe;
2004   INT32 Err;
2005 
2006   /* Set entries for TCP, UDP and IGMP over IPv4 */
2007   Err = Mvpp2PrsIp4Proto (Priv, MV_IPPR_TCP, MVPP2_PRS_RI_L4_TCP, MVPP2_PRS_RI_L4_PROTO_MASK);
2008   if (Err != 0) {
2009     return Err;
2010   }
2011 
2012   Err = Mvpp2PrsIp4Proto (Priv, MV_IPPR_UDP, MVPP2_PRS_RI_L4_UDP, MVPP2_PRS_RI_L4_PROTO_MASK);
2013   if (Err != 0) {
2014     return Err;
2015   }
2016 
2017   Err = Mvpp2PrsIp4Proto (
2018                   Priv,
2019                   MV_IPPR_IGMP,
2020                   MVPP2_PRS_RI_CPU_CODE_RX_SPEC | MVPP2_PRS_RI_UDF3_RX_SPECIAL,
2021                   MVPP2_PRS_RI_CPU_CODE_MASK | MVPP2_PRS_RI_UDF3_MASK
2022                 );
2023 
2024   if (Err != 0) {
2025     return Err;
2026   }
2027 
2028   /* IPv4 Broadcast */
2029   Err = Mvpp2PrsIp4Cast (Priv, MVPP2_PRS_L3_BROAD_CAST);
2030   if (Err != 0) {
2031     return Err;
2032   }
2033 
2034   /* IPv4 Multicast */
2035   Err = Mvpp2PrsIp4Cast (Priv, MVPP2_PRS_L3_MULTI_CAST);
2036   if (Err != 0) {
2037     return Err;
2038   }
2039 
2040   /* Default IPv4 entry for unknown protocols */
2041   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
2042   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_IP4);
2043   Pe.Index = MVPP2_PE_IP4_PROTO_UN;
2044 
2045   /* Set next Lu to IPv4 and shift by 12 bytes - obtained from Marvell*/
2046   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_IP4);
2047   Mvpp2PrsSramShiftSet (&Pe, 12, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
2048 
2049   /* Set L4 offset 4 bytes relative IPv4 header size (current position) */
2050   Mvpp2PrsSramOffsetSet (
2051                   &Pe,
2052                   MVPP2_PRS_SRAM_UDF_TYPE_L4,
2053                   sizeof (Mvpp2Iphdr) - 4,
2054                   MVPP2_PRS_SRAM_OP_SEL_UDF_ADD
2055                 );
2056 
2057   Mvpp2PrsSramAiUpdate (&Pe, MVPP2_PRS_IPV4_DIP_AI_BIT, MVPP2_PRS_IPV4_DIP_AI_BIT);
2058   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L4_OTHER, MVPP2_PRS_RI_L4_PROTO_MASK);
2059 
2060   Mvpp2PrsTcamAiUpdate (&Pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT);
2061 
2062   /* Unmask all Ports */
2063   Mvpp2PrsTcamPortMapSet (&Pe, MVPP2_PRS_PORT_MASK);
2064 
2065   /* Update shadow table and hw entry */
2066   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_IP4);
2067   Mvpp2PrsHwWrite (Priv, &Pe);
2068 
2069   /* Default IPv4 entry for unicast Address */
2070   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
2071   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_IP4);
2072   Pe.Index = MVPP2_PE_IP4_ADDR_UN;
2073 
2074   /* Finished: go to Flowid generation */
2075   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_FLOWS);
2076   Mvpp2PrsSramBitsSet (&Pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
2077   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L3_UCAST, MVPP2_PRS_RI_L3_ADDR_MASK);
2078 
2079   Mvpp2PrsTcamAiUpdate (&Pe, MVPP2_PRS_IPV4_DIP_AI_BIT, MVPP2_PRS_IPV4_DIP_AI_BIT);
2080 
2081   /* Unmask all Ports */
2082   Mvpp2PrsTcamPortMapSet (&Pe, MVPP2_PRS_PORT_MASK);
2083 
2084   /* Update shadow table and hw entry */
2085   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_IP4);
2086   Mvpp2PrsHwWrite (Priv, &Pe);
2087 
2088   return 0;
2089 }
2090 
2091 /* Initialize entries for IPv6 */
2092 STATIC
2093 INT32
Mvpp2PrsIp6Init(IN MVPP2_SHARED * Priv)2094 Mvpp2PrsIp6Init (
2095   IN MVPP2_SHARED *Priv
2096   )
2097 {
2098   MVPP2_PRS_ENTRY Pe;
2099   INT32 Tid, Err;
2100 
2101   /* Set entries for TCP, UDP and ICMP over IPv6 */
2102   Err = Mvpp2PrsIp6Proto (Priv, MV_IPPR_TCP, MVPP2_PRS_RI_L4_TCP, MVPP2_PRS_RI_L4_PROTO_MASK);
2103   if (Err != 0) {
2104     return Err;
2105   }
2106 
2107   Err = Mvpp2PrsIp6Proto (Priv, MV_IPPR_UDP, MVPP2_PRS_RI_L4_UDP, MVPP2_PRS_RI_L4_PROTO_MASK);
2108   if (Err != 0) {
2109     return Err;
2110   }
2111 
2112   Err = Mvpp2PrsIp6Proto (
2113                   Priv,
2114                   MV_IPPR_ICMPV6,
2115                   MVPP2_PRS_RI_CPU_CODE_RX_SPEC | MVPP2_PRS_RI_UDF3_RX_SPECIAL,
2116                   MVPP2_PRS_RI_CPU_CODE_MASK | MVPP2_PRS_RI_UDF3_MASK
2117                 );
2118 
2119   if (Err != 0) {
2120     return Err;
2121   }
2122 
2123   /*
2124    * IPv4 is the last header. This is similar case as 6-TCP or 17-UDP
2125    * Result Info: UDF7=1, DS lite
2126    */
2127   Err = Mvpp2PrsIp6Proto (Priv, MV_IPPR_IPIP, MVPP2_PRS_RI_UDF7_IP6_LITE, MVPP2_PRS_RI_UDF7_MASK);
2128   if (Err != 0) {
2129     return Err;
2130   }
2131 
2132   /* IPv6 multicast */
2133   Err = Mvpp2PrsIp6Cast (Priv, MVPP2_PRS_L3_MULTI_CAST);
2134   if (Err != 0) {
2135     return Err;
2136   }
2137 
2138   /* Entry for checking hop limit */
2139   Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, MVPP2_PE_LAST_FREE_TID);
2140   if (Tid < 0) {
2141     return Tid;
2142   }
2143 
2144   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
2145   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_IP6);
2146   Pe.Index = Tid;
2147 
2148   /* Finished: go to Flowid generation */
2149   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_FLOWS);
2150   Mvpp2PrsSramBitsSet (&Pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
2151   Mvpp2PrsSramRiUpdate (
2152                   &Pe,
2153                   MVPP2_PRS_RI_L3_UN | MVPP2_PRS_RI_DROP_MASK,
2154                   MVPP2_PRS_RI_L3_PROTO_MASK | MVPP2_PRS_RI_DROP_MASK
2155                 );
2156 
2157   Mvpp2PrsTcamDataByteSet (&Pe, 1, 0x00, MVPP2_PRS_IPV6_HOP_MASK);
2158   Mvpp2PrsTcamAiUpdate (&Pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT, MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
2159 
2160   /* Update shadow table and hw entry */
2161   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_IP4);
2162   Mvpp2PrsHwWrite (Priv, &Pe);
2163 
2164   /* Default IPv6 entry for unknown protocols */
2165   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
2166   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_IP6);
2167   Pe.Index = MVPP2_PE_IP6_PROTO_UN;
2168 
2169   /* Finished: go to Flowid generation */
2170   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_FLOWS);
2171   Mvpp2PrsSramBitsSet (&Pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
2172   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L4_OTHER, MVPP2_PRS_RI_L4_PROTO_MASK);
2173 
2174   /* Set L4 offset 6 bytes relative IPv6 header size (current position) */
2175   Mvpp2PrsSramOffsetSet (
2176                   &Pe,
2177                   MVPP2_PRS_SRAM_UDF_TYPE_L4,
2178                   sizeof (Mvpp2Ipv6hdr) - 6,
2179                   MVPP2_PRS_SRAM_OP_SEL_UDF_ADD
2180                 );
2181 
2182   Mvpp2PrsTcamAiUpdate (&Pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT, MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
2183 
2184   /* Unmask all Ports */
2185   Mvpp2PrsTcamPortMapSet (&Pe, MVPP2_PRS_PORT_MASK);
2186 
2187   /* Update shadow table and hw entry */
2188   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_IP4);
2189   Mvpp2PrsHwWrite (Priv, &Pe);
2190 
2191   /* Default IPv6 entry for unknown ext protocols */
2192   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
2193   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_IP6);
2194   Pe.Index = MVPP2_PE_IP6_EXT_PROTO_UN;
2195 
2196   /* Finished: go to Flowid generation */
2197   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_FLOWS);
2198   Mvpp2PrsSramBitsSet (&Pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);
2199   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L4_OTHER, MVPP2_PRS_RI_L4_PROTO_MASK);
2200 
2201   Mvpp2PrsTcamAiUpdate (&Pe, MVPP2_PRS_IPV6_EXT_AI_BIT, MVPP2_PRS_IPV6_EXT_AI_BIT);
2202 
2203   /* Unmask all Ports */
2204   Mvpp2PrsTcamPortMapSet (&Pe, MVPP2_PRS_PORT_MASK);
2205 
2206   /* Update shadow table and hw entry */
2207   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_IP4);
2208   Mvpp2PrsHwWrite (Priv, &Pe);
2209 
2210   /* Default IPv6 entry for unicast Address */
2211   Mvpp2Memset (&Pe, 0, sizeof (MVPP2_PRS_ENTRY));
2212   Mvpp2PrsTcamLuSet (&Pe, MVPP2_PRS_LU_IP6);
2213   Pe.Index = MVPP2_PE_IP6_ADDR_UN;
2214 
2215   /* Finished: go to IPv6 again */
2216   Mvpp2PrsSramNextLuSet (&Pe, MVPP2_PRS_LU_IP6);
2217   Mvpp2PrsSramRiUpdate (&Pe, MVPP2_PRS_RI_L3_UCAST, MVPP2_PRS_RI_L3_ADDR_MASK);
2218   Mvpp2PrsSramAiUpdate (&Pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT, MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
2219 
2220   /* Shift back to IPv6 by 18 bytes - byte count provided by Marvell */
2221   Mvpp2PrsSramShiftSet (&Pe, -18, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
2222   Mvpp2PrsTcamAiUpdate (&Pe, 0, MVPP2_PRS_IPV6_NO_EXT_AI_BIT);
2223 
2224   /* Unmask all Ports */
2225   Mvpp2PrsTcamPortMapSet (&Pe, MVPP2_PRS_PORT_MASK);
2226 
2227   /* Update shadow table and hw entry */
2228   Mvpp2PrsShadowSet (Priv, Pe.Index, MVPP2_PRS_LU_IP6);
2229   Mvpp2PrsHwWrite (Priv, &Pe);
2230 
2231   return 0;
2232 }
2233 
2234 /* Parser default initialization */
2235 INT32
Mvpp2PrsDefaultInit(IN MVPP2_SHARED * Priv)2236 Mvpp2PrsDefaultInit (
2237   IN MVPP2_SHARED *Priv
2238   )
2239 {
2240   INT32 Err, Index, i;
2241 
2242   /* Enable Tcam table */
2243   Mvpp2Write (Priv, MVPP2_PRS_TCAM_CTRL_REG, MVPP2_PRS_TCAM_EN_MASK);
2244 
2245   /* Clear all Tcam and Sram entries */
2246   for (Index = 0; Index < MVPP2_PRS_TCAM_SRAM_SIZE; Index++) {
2247     Mvpp2Write (Priv, MVPP2_PRS_TCAM_IDX_REG, Index);
2248     for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++) {
2249       Mvpp2Write (Priv, MVPP2_PRS_TCAM_DATA_REG(i), 0);
2250     }
2251 
2252     Mvpp2Write (Priv, MVPP2_PRS_SRAM_IDX_REG, Index);
2253     for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++) {
2254       Mvpp2Write (Priv, MVPP2_PRS_SRAM_DATA_REG(i), 0);
2255     }
2256   }
2257 
2258   /* Invalidate all Tcam entries */
2259   for (Index = 0; Index < MVPP2_PRS_TCAM_SRAM_SIZE; Index++) {
2260     Mvpp2PrsHwInv (Priv, Index);
2261   }
2262 
2263   /* Always start from lookup = 0 */
2264   for (Index = 0; Index < MVPP2_MAX_PORTS; Index++) {
2265     Mvpp2PrsHwPortInit (Priv, Index, MVPP2_PRS_LU_MH, MVPP2_PRS_PORT_LU_MAX, 0);
2266   }
2267 
2268   Mvpp2PrsDefFlowInit (Priv);
2269 
2270   Mvpp2PrsMhInit (Priv);
2271 
2272   Mvpp2PrsMacInit (Priv);
2273 
2274   Mvpp2PrsDsaInit (Priv);
2275 
2276   Err = Mvpp2PrsEtypeInit (Priv);
2277   if (Err != 0) {
2278     return Err;
2279   }
2280 
2281   Err = Mvpp2PrsVlanInit (Priv);
2282   if (Err != 0) {
2283     return Err;
2284   }
2285 
2286   Err = Mvpp2PrsPppoeInit (Priv);
2287   if (Err != 0) {
2288     return Err;
2289   }
2290 
2291   Err = Mvpp2PrsIp6Init (Priv);
2292   if (Err != 0) {
2293     return Err;
2294   }
2295 
2296   Err = Mvpp2PrsIp4Init (Priv);
2297   if (Err != 0) {
2298     return Err;
2299   }
2300 
2301   return 0;
2302 }
2303 
2304 /* Compare MAC DA with Tcam entry data */
2305 STATIC
2306 BOOLEAN
Mvpp2PrsMacRangeEquals(IN MVPP2_PRS_ENTRY * Pe,IN const UINT8 * Da,IN UINT8 * Mask)2307 Mvpp2PrsMacRangeEquals (
2308   IN MVPP2_PRS_ENTRY *Pe,
2309   IN const UINT8 *Da,
2310   IN UINT8 *Mask
2311   )
2312 {
2313   UINT8 TcamByte, TcamMask;
2314   INT32 Index;
2315 
2316   for (Index = 0; Index < MV_ETH_ALEN; Index++) {
2317     Mvpp2PrsTcamDataByteGet (Pe, Index, &TcamByte, &TcamMask);
2318     if (TcamMask != Mask[Index]) {
2319       return FALSE;
2320     }
2321 
2322     if ((TcamMask & TcamByte) != (Da[Index] & Mask[Index])) {
2323       return FALSE;
2324     }
2325   }
2326 
2327   return TRUE;
2328 }
2329 
2330 /* Find Tcam entry with matched pair <MAC DA, Port> */
2331 STATIC
2332 MVPP2_PRS_ENTRY *
Mvpp2PrsMacDaRangeFind(IN MVPP2_SHARED * Priv,IN INT32 Pmap,IN const UINT8 * Da,IN UINT8 * Mask,IN INT32 UdfType)2333 Mvpp2PrsMacDaRangeFind (
2334   IN MVPP2_SHARED *Priv,
2335   IN INT32 Pmap,
2336   IN const UINT8 *Da,
2337   IN UINT8 *Mask,
2338   IN INT32 UdfType
2339   )
2340 {
2341   MVPP2_PRS_ENTRY *Pe;
2342   INT32 Tid;
2343 
2344   Pe = Mvpp2Alloc (sizeof (*Pe));
2345   if (Pe == NULL) {
2346     return NULL;
2347   }
2348   Mvpp2PrsTcamLuSet (Pe, MVPP2_PRS_LU_MAC);
2349 
2350   /* Go through the all entires with MVPP2_PRS_LU_MAC */
2351   for (Tid = MVPP2_PE_FIRST_FREE_TID; Tid <= MVPP2_PE_LAST_FREE_TID; Tid++) {
2352     UINT32 EntryPmap;
2353 
2354     if (!Priv->PrsShadow[Tid].Valid ||
2355         (Priv->PrsShadow[Tid].Lu != MVPP2_PRS_LU_MAC) ||
2356         (Priv->PrsShadow[Tid].Udf != UdfType))
2357     {
2358       continue;
2359     }
2360 
2361     Pe->Index = Tid;
2362     Mvpp2PrsHwRead (Priv, Pe);
2363     EntryPmap = Mvpp2PrsTcamPortMapGet (Pe);
2364 
2365     if (Mvpp2PrsMacRangeEquals (Pe, Da, Mask) && EntryPmap == Pmap) {
2366       return Pe;
2367     }
2368   }
2369 
2370   Mvpp2Free (Pe);
2371 
2372   return NULL;
2373 }
2374 
2375 /* Update parser's mac Da entry */
2376 INT32
Mvpp2PrsMacDaAccept(IN MVPP2_SHARED * Priv,IN INT32 PortId,IN const UINT8 * Da,IN BOOLEAN Add)2377 Mvpp2PrsMacDaAccept (
2378   IN MVPP2_SHARED *Priv,
2379   IN INT32 PortId,
2380   IN const UINT8 *Da,
2381   IN BOOLEAN Add
2382   )
2383 {
2384   MVPP2_PRS_ENTRY *Pe;
2385   UINT32 Pmap, Len, Ri;
2386   UINT8 Mask[MV_ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2387   INT32 Tid;
2388 
2389   /* Scan TCAM and see if entry with this <MAC DA, PortId> already exist */
2390   Pe = Mvpp2PrsMacDaRangeFind (Priv, (1 << PortId), Da, Mask, MVPP2_PRS_UDF_MAC_DEF);
2391 
2392   /* No such entry */
2393   if (Pe == NULL) {
2394     if (!Add) {
2395       return 0;
2396     }
2397 
2398     /* Create new TCAM entry */
2399     /* Find first range mac entry*/
2400     for (Tid = MVPP2_PE_FIRST_FREE_TID; Tid <= MVPP2_PE_LAST_FREE_TID; Tid++) {
2401       if (Priv->PrsShadow[Tid].Valid &&
2402           (Priv->PrsShadow[Tid].Lu == MVPP2_PRS_LU_MAC) &&
2403           (Priv->PrsShadow[Tid].Udf == MVPP2_PRS_UDF_MAC_RANGE))
2404       {
2405         break;
2406       }
2407     }
2408 
2409 
2410     /* Go through the all entries from first to last */
2411     Tid = Mvpp2PrsTcamFirstFree (Priv, MVPP2_PE_FIRST_FREE_TID, Tid - 1);
2412     if (Tid < 0) {
2413       return Tid;
2414     }
2415 
2416     Pe = Mvpp2Alloc (sizeof (*Pe));
2417     if (Pe == NULL) {
2418       return -1;
2419     }
2420 
2421     Mvpp2PrsTcamLuSet (Pe, MVPP2_PRS_LU_MAC);
2422     Pe->Index = Tid;
2423 
2424     /* Mask all Ports */
2425     Mvpp2PrsTcamPortMapSet (Pe, 0);
2426   }
2427 
2428   /* Update PortId Mask */
2429   Mvpp2PrsTcamPortSet (Pe, PortId, Add);
2430 
2431   /* Invalidate the entry if no Ports are left enabled */
2432   Pmap = Mvpp2PrsTcamPortMapGet (Pe);
2433   if (Pmap == 0) {
2434     if (Add) {
2435       Mvpp2Free (Pe);
2436       return -1;
2437     }
2438 
2439     Mvpp2PrsHwInv (Priv, Pe->Index);
2440     Priv->PrsShadow[Pe->Index].Valid = FALSE;
2441 
2442     Mvpp2Free (Pe);
2443 
2444     return 0;
2445   }
2446 
2447   /* Continue - set next lookup */
2448   Mvpp2PrsSramNextLuSet (Pe, MVPP2_PRS_LU_DSA);
2449 
2450   /* Set match on DA */
2451   Len = MV_ETH_ALEN;
2452   while (Len--) {
2453     Mvpp2PrsTcamDataByteSet (Pe, Len, Da[Len], 0xff);
2454   }
2455 
2456   /* Set result info bits */
2457   if (Mvpp2IsBroadcastEtherAddr (Da)) {
2458     Ri = MVPP2_PRS_RI_L2_BCAST;
2459   } else if (Mvpp2IsMulticastEtherAddr (Da)) {
2460     Ri = MVPP2_PRS_RI_L2_MCAST;
2461   } else {
2462     Ri = MVPP2_PRS_RI_L2_UCAST | MVPP2_PRS_RI_MAC_ME_MASK;
2463   }
2464 
2465   Mvpp2PrsSramRiUpdate (Pe, Ri, MVPP2_PRS_RI_L2_CAST_MASK | MVPP2_PRS_RI_MAC_ME_MASK);
2466   Mvpp2PrsShadowRiSet (Priv, Pe->Index, Ri, MVPP2_PRS_RI_L2_CAST_MASK | MVPP2_PRS_RI_MAC_ME_MASK);
2467 
2468   /* Shift to ethertype */
2469   Mvpp2PrsSramShiftSet (Pe, 2 * MV_ETH_ALEN, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);
2470 
2471   /* Update shadow table and hw entry */
2472   Priv->PrsShadow[Pe->Index].Udf = MVPP2_PRS_UDF_MAC_DEF;
2473   Mvpp2PrsShadowSet (Priv, Pe->Index, MVPP2_PRS_LU_MAC);
2474   Mvpp2PrsHwWrite (Priv, Pe);
2475 
2476   Mvpp2Free (Pe);
2477 
2478   return 0;
2479 }
2480 
2481 /* Delete all Port's multicast simple (not range) entries */
2482 VOID
Mvpp2PrsMcastDelAll(IN MVPP2_SHARED * Priv,IN INT32 PortId)2483 Mvpp2PrsMcastDelAll (
2484   IN MVPP2_SHARED *Priv,
2485   IN INT32 PortId
2486   )
2487 {
2488   MVPP2_PRS_ENTRY Pe;
2489   INT32 Index, Tid;
2490 
2491   for (Tid = MVPP2_PE_FIRST_FREE_TID; Tid <= MVPP2_PE_LAST_FREE_TID; Tid++) {
2492     UINT8 Da[MV_ETH_ALEN], DaMask[MV_ETH_ALEN];
2493 
2494     if (!Priv->PrsShadow[Tid].Valid ||
2495         (Priv->PrsShadow[Tid].Lu != MVPP2_PRS_LU_MAC) ||
2496         (Priv->PrsShadow[Tid].Udf != MVPP2_PRS_UDF_MAC_DEF))
2497     {
2498       continue;
2499     }
2500 
2501     /* Only simple mac entries */
2502     Pe.Index = Tid;
2503     Mvpp2PrsHwRead (Priv, &Pe);
2504 
2505     /* Read mac Addr from entry */
2506     for (Index = 0; Index < MV_ETH_ALEN; Index++) {
2507       Mvpp2PrsTcamDataByteGet (&Pe, Index, &Da[Index], &DaMask[Index]);
2508     }
2509 
2510     if (Mvpp2IsMulticastEtherAddr (Da) && !Mvpp2IsBroadcastEtherAddr (Da)) {
2511       /* Delete this entry */
2512       Mvpp2PrsMacDaAccept (Priv, PortId, Da, FALSE);
2513     }
2514   }
2515 }
2516 
2517 INT32
Mvpp2PrsTagModeSet(IN MVPP2_SHARED * Priv,IN INT32 PortId,IN INT32 Type)2518 Mvpp2PrsTagModeSet (
2519   IN MVPP2_SHARED *Priv,
2520   IN INT32 PortId,
2521   IN INT32 Type
2522   )
2523 {
2524   switch (Type) {
2525   case MVPP2_TAG_TYPE_EDSA:
2526     /* Add PortId to EDSA entries */
2527     Mvpp2PrsDsaTagSet (Priv, PortId, TRUE, MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
2528     Mvpp2PrsDsaTagSet (Priv, PortId, TRUE, MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
2529     /* Remove PortId from DSA entries */
2530     Mvpp2PrsDsaTagSet (Priv, PortId, FALSE, MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
2531     Mvpp2PrsDsaTagSet (Priv, PortId, FALSE, MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);
2532     break;
2533   case MVPP2_TAG_TYPE_DSA:
2534     /* Add PortId to DSA entries */
2535     Mvpp2PrsDsaTagSet (Priv, PortId, TRUE, MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
2536     Mvpp2PrsDsaTagSet (Priv, PortId, TRUE, MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);
2537 
2538     /* Remove PortId from EDSA entries */
2539     Mvpp2PrsDsaTagSet (Priv, PortId, FALSE, MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
2540     Mvpp2PrsDsaTagSet (Priv, PortId, FALSE, MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
2541     break;
2542   case MVPP2_TAG_TYPE_MH:
2543   case MVPP2_TAG_TYPE_NONE:
2544     /* Remove PortId form EDSA and DSA entries */
2545     Mvpp2PrsDsaTagSet (Priv, PortId, FALSE, MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);
2546     Mvpp2PrsDsaTagSet (Priv, PortId, FALSE, MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);
2547     Mvpp2PrsDsaTagSet (Priv, PortId, FALSE, MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);
2548     Mvpp2PrsDsaTagSet (Priv, PortId, FALSE, MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);
2549     break;
2550   default:
2551     if ((Type < 0) || (Type > MVPP2_TAG_TYPE_EDSA)) {
2552       return MVPP2_EINVAL;
2553     }
2554   }
2555 
2556   return 0;
2557 }
2558 
2559 /* Set prs Flow for the Port */
2560 INT32
Mvpp2PrsDefFlow(IN PP2DXE_PORT * Port)2561 Mvpp2PrsDefFlow (
2562   IN PP2DXE_PORT *Port
2563   )
2564 {
2565   MVPP2_PRS_ENTRY *Pe;
2566   INT32 Tid;
2567 
2568   Pe = Mvpp2PrsFlowFind (Port->Priv, Port->Id);
2569 
2570   /* Such entry not exist */
2571   if (Pe == NULL) {
2572     /* Go through the all entires from last to first */
2573     Tid = Mvpp2PrsTcamFirstFree (Port->Priv, MVPP2_PE_LAST_FREE_TID, MVPP2_PE_FIRST_FREE_TID);
2574     if (Tid < 0) {
2575       return Tid;
2576     }
2577 
2578     Pe = Mvpp2Alloc (sizeof (*Pe));
2579     if (Pe == NULL) {
2580       return MVPP2_ENOMEM;
2581     }
2582 
2583     Mvpp2PrsTcamLuSet (Pe, MVPP2_PRS_LU_FLOWS);
2584     Pe->Index = Tid;
2585 
2586     /* Set Flow ID*/
2587     Mvpp2PrsSramAiUpdate (Pe, Port->Id, MVPP2_PRS_FLOW_ID_MASK);
2588     Mvpp2PrsSramBitsSet (Pe, MVPP2_PRS_SRAM_LU_DONE_BIT, 1);
2589 
2590     /* Update shadow table */
2591     Mvpp2PrsShadowSet (Port->Priv, Pe->Index, MVPP2_PRS_LU_FLOWS);
2592   }
2593 
2594   Mvpp2PrsTcamPortMapSet (Pe, (1 << Port->Id));
2595   Mvpp2PrsHwWrite (Port->Priv, Pe);
2596   Mvpp2Free (Pe);
2597 
2598   return 0;
2599 }
2600 
2601 /* Classifier configuration routines */
2602 
2603 /* Update classification Flow table RegValisters */
2604 STATIC
2605 VOID
Mvpp2ClsFlowWrite(IN MVPP2_SHARED * Priv,IN MVPP2_CLS_FLOW_ENTRY * Fe)2606 Mvpp2ClsFlowWrite (
2607   IN MVPP2_SHARED *Priv,
2608   IN MVPP2_CLS_FLOW_ENTRY *Fe
2609   )
2610 {
2611   Mvpp2Write (Priv, MVPP2_CLS_FLOW_INDEX_REG, Fe->Index);
2612   Mvpp2Write (Priv, MVPP2_CLS_FLOW_TBL0_REG, Fe->Data[0]);
2613   Mvpp2Write (Priv, MVPP2_CLS_FLOW_TBL1_REG, Fe->Data[1]);
2614   Mvpp2Write (Priv, MVPP2_CLS_FLOW_TBL2_REG, Fe->Data[2]);
2615 }
2616 
2617 /* Update classification lookup table RegValister */
2618 VOID
Mvpp2ClsLookupWrite(IN MVPP2_SHARED * Priv,IN OUT MVPP2_CLS_LOOKUP_ENTRY * Le)2619 Mvpp2ClsLookupWrite (
2620   IN MVPP2_SHARED *Priv,
2621   IN OUT MVPP2_CLS_LOOKUP_ENTRY *Le
2622   )
2623 {
2624   UINT32 Val;
2625 
2626   Val = (Le->Way << MVPP2_CLS_LKP_INDEX_WAY_OFFS) | Le->Lkpid;
2627   Mvpp2Write (Priv, MVPP2_CLS_LKP_INDEX_REG, Val);
2628   Mvpp2Write (Priv, MVPP2_CLS_LKP_TBL_REG, Le->Data);
2629 }
2630 
2631 /* Classifier default initialization */
2632 VOID
Mvpp2ClsInit(IN MVPP2_SHARED * Priv)2633 Mvpp2ClsInit (
2634   IN MVPP2_SHARED *Priv
2635   )
2636 {
2637   MVPP2_CLS_LOOKUP_ENTRY Le;
2638   MVPP2_CLS_FLOW_ENTRY Fe;
2639   INT32 Index;
2640 
2641   /* Enable classifier */
2642   Mvpp2Write (Priv, MVPP2_CLS_MODE_REG, MVPP2_CLS_MODE_ACTIVE_MASK);
2643 
2644   /* Clear classifier Flow table */
2645   Mvpp2Memset (&Fe.Data, 0, MVPP2_CLS_FLOWS_TBL_DATA_WORDS);
2646   for (Index = 0; Index < MVPP2_CLS_FLOWS_TBL_SIZE; Index++) {
2647     Fe.Index = Index;
2648     Mvpp2ClsFlowWrite (Priv, &Fe);
2649   }
2650 
2651   /* Clear classifier lookup table */
2652   Le.Data = 0;
2653   for (Index = 0; Index < MVPP2_CLS_LKP_TBL_SIZE; Index++) {
2654     Le.Lkpid = Index;
2655     Le.Way = 0;
2656     Mvpp2ClsLookupWrite (Priv, &Le);
2657 
2658     Le.Way = 1;
2659     Mvpp2ClsLookupWrite (Priv, &Le);
2660   }
2661 }
2662 
2663 VOID
Mvpp2ClsPortConfig(IN PP2DXE_PORT * Port)2664 Mvpp2ClsPortConfig (
2665   IN PP2DXE_PORT *Port
2666   )
2667 {
2668   MVPP2_CLS_LOOKUP_ENTRY Le;
2669   UINT32 Val;
2670 
2671   /* Set way for the Port */
2672   Val = Mvpp2Read (Port->Priv, MVPP2_CLS_PORT_WAY_REG);
2673   Val &= ~MVPP2_CLS_PORT_WAY_MASK (Port->Id);
2674   Mvpp2Write (Port->Priv, MVPP2_CLS_PORT_WAY_REG, Val);
2675 
2676   /*
2677    * Pick the entry to be accessed in lookup ID decoding table
2678    * according to the way and lkpid.
2679    */
2680   Le.Lkpid = Port->Id;
2681   Le.Way = 0;
2682   Le.Data = 0;
2683 
2684   /* Set initial CPU Queue for receiving packets */
2685   Le.Data &= ~MVPP2_CLS_LKP_TBL_RXQ_MASK;
2686   Le.Data |= Port->FirstRxq;
2687 
2688   /* Disable classification engines */
2689   Le.Data &= ~MVPP2_CLS_LKP_TBL_LOOKUP_EN_MASK;
2690 
2691   /* Update lookup ID table entry */
2692   Mvpp2ClsLookupWrite (Port->Priv, &Le);
2693 }
2694 
2695 /* Set CPU Queue number for oversize packets */
2696 VOID
Mvpp2ClsOversizeRxqSet(IN PP2DXE_PORT * Port)2697 Mvpp2ClsOversizeRxqSet (
2698   IN PP2DXE_PORT *Port
2699   )
2700 {
2701 
2702   Mvpp2Write (
2703           Port->Priv,
2704           MVPP2_CLS_OVERSIZE_RXQ_LOW_REG(Port->Id),
2705           Port->FirstRxq & MVPP2_CLS_OVERSIZE_RXQ_LOW_MASK
2706         );
2707 }
2708 
2709 /* BM helper routines */
2710 
2711 VOID
Mvpp2BmPoolHwCreate(IN MVPP2_SHARED * Priv,IN MVPP2_BMS_POOL * BmPool,IN INT32 Size)2712 Mvpp2BmPoolHwCreate (
2713   IN MVPP2_SHARED *Priv,
2714   IN MVPP2_BMS_POOL *BmPool,
2715   IN INT32 Size
2716   )
2717 {
2718   BmPool->Size = Size;
2719 
2720   Mvpp2Write (Priv, MVPP2_BM_POOL_BASE_REG(BmPool->Id), Lower32Bits (BmPool->PhysAddr));
2721   Mvpp2Write (Priv, MVPP22_BM_POOL_BASE_HIGH_REG, (Upper32Bits (BmPool->PhysAddr) & MVPP22_BM_POOL_BASE_HIGH_REG));
2722   Mvpp2Write (Priv, MVPP2_BM_POOL_SIZE_REG(BmPool->Id), BmPool->Size);
2723 }
2724 
2725 /* Set Pool buffer Size */
2726 VOID
Mvpp2BmPoolBufsizeSet(IN MVPP2_SHARED * Priv,IN MVPP2_BMS_POOL * BmPool,IN INT32 BufSize)2727 Mvpp2BmPoolBufsizeSet (
2728   IN MVPP2_SHARED *Priv,
2729   IN MVPP2_BMS_POOL *BmPool,
2730   IN INT32 BufSize
2731   )
2732 {
2733   UINT32 Val;
2734 
2735   BmPool->BufSize = BufSize;
2736 
2737   Val = MVPP2_ALIGN (BufSize, 1 << MVPP2_POOL_BUF_SIZE_OFFSET);
2738   Mvpp2Write (Priv, MVPP2_POOL_BUF_SIZE_REG(BmPool->Id), Val);
2739 }
2740 
2741 VOID
Mvpp2BmStop(IN MVPP2_SHARED * Priv,IN INT32 Pool)2742 Mvpp2BmStop (
2743   IN MVPP2_SHARED *Priv,
2744   IN INT32 Pool
2745   )
2746 {
2747   UINT32 Val, i;
2748 
2749   for (i = 0; i < MVPP2_BM_SIZE; i++) {
2750     Mvpp2Read (Priv, MVPP2_BM_PHY_ALLOC_REG(0));
2751   }
2752 
2753   Val = Mvpp2Read (Priv, MVPP2_BM_POOL_CTRL_REG(Pool));
2754   Val |= MVPP2_BM_STOP_MASK;
2755   Mvpp2Write (Priv, MVPP2_BM_POOL_CTRL_REG(Pool), Val);
2756 }
2757 
2758 VOID
Mvpp2BmIrqClear(IN MVPP2_SHARED * Priv,IN INT32 Pool)2759 Mvpp2BmIrqClear (
2760   IN MVPP2_SHARED *Priv,
2761   IN INT32 Pool
2762   )
2763 {
2764   /* Mask BM all interrupts */
2765   Mvpp2Write (Priv, MVPP2_BM_INTR_MASK_REG(Pool), 0);
2766 
2767   /* Clear BM cause RegValister */
2768   Mvpp2Write (Priv, MVPP2_BM_INTR_CAUSE_REG(Pool), 0);
2769 }
2770 
2771 /* Attach long Pool to Rxq */
2772 VOID
Mvpp2RxqLongPoolSet(IN PP2DXE_PORT * Port,IN INT32 Lrxq,IN INT32 LongPool)2773 Mvpp2RxqLongPoolSet (
2774   IN PP2DXE_PORT *Port,
2775   IN INT32 Lrxq,
2776   IN INT32 LongPool
2777   )
2778 {
2779   UINT32 Val;
2780   INT32 Prxq;
2781 
2782   /* Get Queue physical ID */
2783   Prxq = Port->Rxqs[Lrxq].Id;
2784 
2785   Val = Mvpp2Read (Port->Priv, MVPP2_RXQ_CONFIG_REG(Prxq));
2786   Val &= ~MVPP2_RXQ_POOL_LONG_MASK;
2787   Val |= ((LongPool << MVPP2_RXQ_POOL_LONG_OFFS) & MVPP2_RXQ_POOL_LONG_MASK);
2788 
2789   Mvpp2Write (Port->Priv, MVPP2_RXQ_CONFIG_REG(Prxq), Val);
2790 }
2791 
2792 /* Attach short Pool to Rxq */
2793 VOID
Mvpp2RxqShortPoolSet(IN PP2DXE_PORT * Port,IN INT32 Lrxq,IN INT32 ShortPool)2794 Mvpp2RxqShortPoolSet (
2795   IN PP2DXE_PORT *Port,
2796   IN INT32 Lrxq,
2797   IN INT32 ShortPool
2798   )
2799 {
2800   UINT32 Val;
2801   INT32 Prxq;
2802 
2803   /* Get Queue physical ID */
2804   Prxq = Port->Rxqs[Lrxq].Id;
2805 
2806   Val = Mvpp2Read (Port->Priv, MVPP2_RXQ_CONFIG_REG(Prxq));
2807   Val &= ~MVPP2_RXQ_POOL_SHORT_MASK;
2808   Val |= ((ShortPool << MVPP2_RXQ_POOL_SHORT_OFFS) & MVPP2_RXQ_POOL_SHORT_MASK);
2809 
2810   Mvpp2Write (Port->Priv, MVPP2_RXQ_CONFIG_REG(Prxq), Val);
2811 }
2812 
2813 /* Release multicast buffer */
2814 VOID
Mvpp2BmPoolMcPut(IN PP2DXE_PORT * Port,IN INT32 Pool,IN UINT32 BufPhysAddr,IN UINT32 BufVirtAddr,IN INT32 McId)2815 Mvpp2BmPoolMcPut (
2816   IN PP2DXE_PORT *Port,
2817   IN INT32 Pool,
2818   IN UINT32 BufPhysAddr,
2819   IN UINT32 BufVirtAddr,
2820   IN INT32 McId
2821   )
2822 {
2823   UINT32 Val = 0;
2824 
2825   Val |= (McId & MVPP2_BM_MC_ID_MASK);
2826   Mvpp2Write (Port->Priv, MVPP2_BM_MC_RLS_REG, Val);
2827 
2828   Mvpp2BmPoolPut (Port->Priv, Pool, BufPhysAddr | MVPP2_BM_PHY_RLS_MC_BUFF_MASK, BufVirtAddr);
2829 }
2830 
2831 /* Refill BM Pool */
2832 VOID
Mvpp2PoolRefill(IN PP2DXE_PORT * Port,IN UINT32 Bm,IN UINT32 PhysAddr,IN UINT32 cookie)2833 Mvpp2PoolRefill (
2834   IN PP2DXE_PORT *Port,
2835   IN UINT32 Bm,
2836   IN UINT32 PhysAddr,
2837   IN UINT32 cookie
2838   )
2839 {
2840   INT32 Pool = Mvpp2BmCookiePoolGet (Bm);
2841 
2842   Mvpp2BmPoolPut (Port->Priv, Pool, PhysAddr, cookie);
2843 }
2844 
2845 INTN
Mvpp2BmPoolCtrl(IN MVPP2_SHARED * Priv,IN INTN Pool,IN enum Mvpp2Command Cmd)2846 Mvpp2BmPoolCtrl (
2847   IN MVPP2_SHARED *Priv,
2848   IN INTN Pool,
2849   IN enum Mvpp2Command Cmd
2850   )
2851 {
2852   UINT32 RegVal = 0;
2853   RegVal = Mvpp2Read (Priv, MVPP2_BM_POOL_CTRL_REG(Pool));
2854 
2855   switch (Cmd) {
2856   case MVPP2_START:
2857     RegVal |= MVPP2_BM_START_MASK;
2858     break;
2859 
2860   case MVPP2_STOP:
2861     RegVal |= MVPP2_BM_STOP_MASK;
2862     break;
2863 
2864   default:
2865     return -1;
2866   }
2867   Mvpp2Write (Priv, MVPP2_BM_POOL_CTRL_REG(Pool), RegVal);
2868 
2869   return 0;
2870 }
2871 
2872 /* Mask the current CPU's Rx/Tx interrupts */
2873 VOID
Mvpp2InterruptsMask(IN VOID * arg)2874 Mvpp2InterruptsMask (
2875   IN VOID *arg
2876   )
2877 {
2878   PP2DXE_PORT *Port = arg;
2879 
2880   Mvpp2Write (Port->Priv, MVPP2_ISR_RX_TX_MASK_REG(Port->Id), 0);
2881 }
2882 
2883 /* Unmask the current CPU's Rx/Tx interrupts */
2884 VOID
Mvpp2InterruptsUnmask(IN VOID * arg)2885 Mvpp2InterruptsUnmask (
2886   IN VOID *arg
2887   )
2888 {
2889   PP2DXE_PORT *Port = arg;
2890 
2891   Mvpp2Write (
2892           Port->Priv,
2893           MVPP2_ISR_RX_TX_MASK_REG(Port->Id),
2894           (MVPP2_CAUSE_MISC_SUM_MASK | MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK)
2895         );
2896 }
2897 
2898 /* MAC configuration routines */
2899 
2900 STATIC
2901 VOID
Mvpp2PortMiiSet(IN PP2DXE_PORT * Port)2902 Mvpp2PortMiiSet (
2903   IN PP2DXE_PORT *Port
2904   )
2905 {
2906   UINT32 Val;
2907 
2908   Val = Mvpp2GmacRead (Port, MVPP2_GMAC_CTRL_2_REG);
2909 
2910   switch (Port->PhyInterface) {
2911   case MV_MODE_SGMII:
2912     Val |= MVPP2_GMAC_INBAND_AN_MASK;
2913     break;
2914   case MV_MODE_RGMII:
2915     Val |= MVPP2_GMAC_PORT_RGMII_MASK;
2916   default:
2917     Val &= ~MVPP2_GMAC_PCS_ENABLE_MASK;
2918   }
2919 
2920   Mvpp2GmacWrite (Port, MVPP2_GMAC_CTRL_2_REG, Val);
2921 }
2922 
2923 STATIC
Mvpp2PortFcAdvEnable(IN PP2DXE_PORT * Port)2924 VOID Mvpp2PortFcAdvEnable (
2925   IN PP2DXE_PORT *Port
2926   )
2927 {
2928   UINT32 Val;
2929 
2930   Val = Mvpp2GmacRead (Port, MVPP2_GMAC_AUTONEG_CONFIG);
2931   Val |= MVPP2_GMAC_FC_ADV_EN;
2932   Mvpp2GmacWrite (Port, MVPP2_GMAC_AUTONEG_CONFIG, Val);
2933 }
2934 
2935 VOID
Mvpp2PortEnable(IN PP2DXE_PORT * Port)2936 Mvpp2PortEnable (
2937   IN PP2DXE_PORT *Port
2938   )
2939 {
2940   UINT32 Val;
2941 
2942   Val = Mvpp2GmacRead (Port, MVPP2_GMAC_CTRL_0_REG);
2943   Val |= MVPP2_GMAC_PORT_EN_MASK;
2944   Val |= MVPP2_GMAC_MIB_CNTR_EN_MASK;
2945   Mvpp2GmacWrite (Port, MVPP2_GMAC_CTRL_0_REG, Val);
2946 }
2947 
2948 VOID
Mvpp2PortDisable(IN PP2DXE_PORT * Port)2949 Mvpp2PortDisable (
2950   IN PP2DXE_PORT *Port
2951   )
2952 {
2953   UINT32 Val;
2954 
2955   Val = Mvpp2GmacRead (Port, MVPP2_GMAC_CTRL_0_REG);
2956   Val &= ~(MVPP2_GMAC_PORT_EN_MASK);
2957   Mvpp2GmacWrite (Port, MVPP2_GMAC_CTRL_0_REG, Val);
2958 }
2959 
2960 /* Set IEEE 802.3x Flow Control Xon Packet Transmission Mode */
2961 STATIC
2962 VOID
Mvpp2PortPeriodicXonDisable(IN PP2DXE_PORT * Port)2963 Mvpp2PortPeriodicXonDisable (
2964   IN PP2DXE_PORT *Port
2965   )
2966 {
2967   UINT32 Val;
2968 
2969   Val = Mvpp2GmacRead (Port, MVPP2_GMAC_CTRL_1_REG) & ~MVPP2_GMAC_PERIODIC_XON_EN_MASK;
2970   Mvpp2GmacWrite (Port, MVPP2_GMAC_CTRL_1_REG, Val);
2971 }
2972 
2973 /* Configure loopback Port */
2974 STATIC
2975 VOID
Mvpp2PortReset(IN PP2DXE_PORT * Port)2976 Mvpp2PortReset (
2977   IN PP2DXE_PORT *Port
2978   )
2979 {
2980   UINT32 Val;
2981 
2982   Val = Mvpp2GmacRead (Port, MVPP2_GMAC_CTRL_2_REG) & ~MVPP2_GMAC_PORT_RESET_MASK;
2983   Mvpp2GmacWrite (Port, MVPP2_GMAC_CTRL_2_REG, Val);
2984 
2985   while (Mvpp2GmacRead (Port, MVPP2_GMAC_CTRL_2_REG) & MVPP2_GMAC_PORT_RESET_MASK) {
2986     continue;
2987   }
2988 }
2989 
2990 /* Set defaults to the MVPP2 Port */
2991 VOID
Mvpp2DefaultsSet(IN PP2DXE_PORT * Port)2992 Mvpp2DefaultsSet (
2993   IN PP2DXE_PORT *Port
2994   )
2995 {
2996   INT32 TxPortNum, Val, Queue, pTxq;
2997 
2998   /* Disable Legacy WRR, Disable EJP, Release from Reset */
2999   TxPortNum = Mvpp2EgressPort (Port);
3000   Mvpp2Write (Port->Priv, MVPP2_TXP_SCHED_PORT_INDEX_REG, TxPortNum);
3001   Mvpp2Write (Port->Priv, MVPP2_TXP_SCHED_CMD_1_REG, 0);
3002 
3003   /* Close bandwidth for all Queues */
3004   for (Queue = 0; Queue < MVPP2_MAX_TXQ; Queue++) {
3005     pTxq = Mvpp2TxqPhys (Port->Id, Queue);
3006     Mvpp2Write (Port->Priv, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(pTxq), 0);
3007   }
3008 
3009 
3010   /* Set refill period to 1 Usec, refill tokens and bucket Size to maximum */
3011   Mvpp2Write (Port->Priv, MVPP2_TXP_SCHED_PERIOD_REG, Port->Priv->Tclk / MVPP2_USEC_PER_SEC);
3012   Val = Mvpp2Read (Port->Priv, MVPP2_TXP_SCHED_REFILL_REG);
3013   Val &= ~MVPP2_TXP_REFILL_PERIOD_ALL_MASK;
3014   Val |= MVPP2_TXP_REFILL_PERIOD_MASK (1);
3015   Val |= MVPP2_TXP_REFILL_TOKENS_ALL_MASK;
3016   Mvpp2Write (Port->Priv, MVPP2_TXP_SCHED_REFILL_REG, Val);
3017   Val = MVPP2_TXP_TOKEN_SIZE_MAX;
3018   Mvpp2Write (Port->Priv, MVPP2_TXP_SCHED_TOKEN_SIZE_REG, Val);
3019 
3020   /* Set MaximumLowLatencyPacketSize value to 256 */
3021   Mvpp2Write (
3022           Port->Priv,
3023           MVPP2_RX_CTRL_REG(Port->Id),
3024           MVPP2_RX_USE_PSEUDO_FOR_CSUM_MASK | MVPP2_RX_LOW_LATENCY_PKT_SIZE (256)
3025         );
3026 
3027   /* Mask all interrupts to all present cpus */
3028   Mvpp2InterruptsDisable (Port, 0x1);
3029 }
3030 
3031 /* Enable/disable receiving packets */
3032 VOID
Mvpp2IngressEnable(IN PP2DXE_PORT * Port)3033 Mvpp2IngressEnable (
3034   IN PP2DXE_PORT *Port
3035   )
3036 {
3037   UINT32 Val;
3038   INT32 Lrxq, Queue;
3039 
3040   for (Lrxq = 0; Lrxq < RxqNumber; Lrxq++) {
3041     Queue = Port->Rxqs[Lrxq].Id;
3042     Val = Mvpp2Read (Port->Priv, MVPP2_RXQ_CONFIG_REG(Queue));
3043     Val &= ~MVPP2_RXQ_DISABLE_MASK;
3044     Mvpp2Write (Port->Priv, MVPP2_RXQ_CONFIG_REG(Queue), Val);
3045   }
3046 }
3047 
3048 VOID
Mvpp2IngressDisable(IN PP2DXE_PORT * Port)3049 Mvpp2IngressDisable (
3050   IN PP2DXE_PORT *Port
3051   )
3052 {
3053   UINT32 Val;
3054   INT32 Lrxq, Queue;
3055 
3056   for (Lrxq = 0; Lrxq < RxqNumber; Lrxq++) {
3057     Queue = Port->Rxqs[Lrxq].Id;
3058     Val = Mvpp2Read (Port->Priv, MVPP2_RXQ_CONFIG_REG(Queue));
3059     Val |= MVPP2_RXQ_DISABLE_MASK;
3060     Mvpp2Write (Port->Priv, MVPP2_RXQ_CONFIG_REG(Queue), Val);
3061   }
3062 }
3063 
3064 /* Enable transmit via physical egress Queue - HW starts take descriptors from DRAM */
3065 VOID
Mvpp2EgressEnable(IN PP2DXE_PORT * Port)3066 Mvpp2EgressEnable (
3067   IN PP2DXE_PORT *Port
3068   )
3069 {
3070   UINT32 qmap;
3071   INT32 Queue;
3072   INT32 TxPortNum = Mvpp2EgressPort (Port);
3073 
3074   /* Enable all initialized TXs. */
3075   qmap = 0;
3076   for (Queue = 0; Queue < TxqNumber; Queue++) {
3077     MVPP2_TX_QUEUE *Txq = &Port->Txqs[Queue];
3078 
3079     if (Txq->Descs != NULL) {
3080       qmap |= (1 << Queue);
3081     }
3082   }
3083 
3084   Mvpp2Write (Port->Priv, MVPP2_TXP_SCHED_PORT_INDEX_REG, TxPortNum);
3085   Mvpp2Write (Port->Priv, MVPP2_TXP_SCHED_Q_CMD_REG, qmap);
3086 }
3087 
3088 /* Disable transmit via physical egress Queue - HW doesn't take descriptors from DRAM */
3089 VOID
Mvpp2EgressDisable(IN PP2DXE_PORT * Port)3090 Mvpp2EgressDisable (
3091   IN PP2DXE_PORT *Port
3092   )
3093 {
3094   UINT32 RegData;
3095   INT32 Delay;
3096   INT32 TxPortNum = Mvpp2EgressPort (Port);
3097 
3098   /* Issue stop command for active channels only */
3099   Mvpp2Write (Port->Priv, MVPP2_TXP_SCHED_PORT_INDEX_REG, TxPortNum);
3100   RegData = (Mvpp2Read (Port->Priv, MVPP2_TXP_SCHED_Q_CMD_REG)) & MVPP2_TXP_SCHED_ENQ_MASK;
3101   if (RegData != 0) {
3102     Mvpp2Write (Port->Priv, MVPP2_TXP_SCHED_Q_CMD_REG, (RegData << MVPP2_TXP_SCHED_DISQ_OFFSET));
3103   }
3104 
3105   /* Wait for all Tx activity to terminate. */
3106   Delay = 0;
3107   do {
3108     if (Delay >= MVPP2_TX_DISABLE_TIMEOUT_MSEC) {
3109       Mvpp2Printf ("Tx stop timed out, status=0x%08x\n", RegData);
3110       break;
3111     }
3112     Mvpp2Mdelay (1);
3113     Delay++;
3114 
3115     /* Check Port TX Command RegValister that all Tx Queues are stopped */
3116     RegData = Mvpp2Read (Port->Priv, MVPP2_TXP_SCHED_Q_CMD_REG);
3117   } while (RegData & MVPP2_TXP_SCHED_ENQ_MASK);
3118 }
3119 
3120 /* Rx descriptors helper methods */
3121 
3122 /* Set rx Queue Offset */
3123 STATIC
3124 VOID
Mvpp2RxqOffsetSet(IN PP2DXE_PORT * Port,IN INT32 Prxq,IN INT32 Offset)3125 Mvpp2RxqOffsetSet (
3126   IN PP2DXE_PORT *Port,
3127   IN INT32 Prxq,
3128   IN INT32 Offset
3129   )
3130 {
3131   UINT32 Val;
3132 
3133   /* Convert Offset from bytes to units of 32 bytes */
3134   Offset = Offset >> 5;
3135 
3136   /* Clear previous value */
3137   Val = Mvpp2Read (Port->Priv, MVPP2_RXQ_CONFIG_REG(Prxq));
3138   Val &= ~MVPP2_RXQ_PACKET_OFFSET_MASK;
3139 
3140   /* Update packet Offset in received buffer */
3141   Val |= ((Offset << MVPP2_RXQ_PACKET_OFFSET_OFFS) & MVPP2_RXQ_PACKET_OFFSET_MASK);
3142   Mvpp2Write (Port->Priv, MVPP2_RXQ_CONFIG_REG(Prxq), Val);
3143 }
3144 
3145 /* Obtain BM cookie information from descriptor */
3146 UINT32
Mvpp2BmCookieBuild(IN MVPP2_RX_DESC * RxDesc,IN INT32 Cpu)3147 Mvpp2BmCookieBuild (
3148   IN MVPP2_RX_DESC *RxDesc,
3149   IN INT32 Cpu
3150   )
3151 {
3152   INT32 Pool;
3153   UINT32 ret;
3154 
3155   Pool = (RxDesc->status & MVPP2_RXD_BM_POOL_ID_MASK) >> MVPP2_RXD_BM_POOL_ID_OFFS;
3156 
3157   ret = ((Pool & 0xFF) << MVPP2_BM_COOKIE_POOL_OFFS) | ((Cpu & 0xFF) << MVPP2_BM_COOKIE_CPU_OFFS);
3158 
3159   return ret;
3160 }
3161 
3162 /* Tx descriptors helper methods */
3163 
3164 INT32
Mvpp2TxqDrainSet(IN PP2DXE_PORT * Port,IN INT32 Txq,IN BOOLEAN En)3165 Mvpp2TxqDrainSet (
3166   IN PP2DXE_PORT *Port,
3167   IN INT32 Txq,
3168   IN BOOLEAN En
3169   )
3170 {
3171   UINT32 RegVal;
3172   INT32 pTxq = Mvpp2TxqPhys (Port->Id, Txq);
3173 
3174   Mvpp2Write (Port->Priv, MVPP2_TXQ_NUM_REG, pTxq);
3175   RegVal = Mvpp2Read (Port->Priv, MVPP2_TXQ_PREF_BUF_REG);
3176 
3177   if (En) {
3178     RegVal |= MVPP2_TXQ_DRAIN_EN_MASK;
3179   } else {
3180     RegVal &= ~MVPP2_TXQ_DRAIN_EN_MASK;
3181   }
3182 
3183   Mvpp2Write (Port->Priv, MVPP2_TXQ_PREF_BUF_REG, RegVal);
3184 
3185   return 0;
3186 }
3187 
3188 /* Get number of Tx descriptors waiting to be transmitted by HW */
3189 INT32
Mvpp2TxqPendDescNumGet(IN PP2DXE_PORT * Port,IN MVPP2_TX_QUEUE * Txq)3190 Mvpp2TxqPendDescNumGet (
3191   IN PP2DXE_PORT *Port,
3192   IN MVPP2_TX_QUEUE *Txq
3193   )
3194 {
3195   UINT32 Val;
3196 
3197   Mvpp2Write (Port->Priv, MVPP2_TXQ_NUM_REG, Txq->Id);
3198   Val = Mvpp2Read (Port->Priv, MVPP2_TXQ_PENDING_REG);
3199 
3200   return Val & MVPP2_TXQ_PENDING_MASK;
3201 }
3202 
3203 /* Get number of occupied aggRegValated Tx descriptors */
3204 UINT32
Mvpp2AggrTxqPendDescNumGet(IN MVPP2_SHARED * Priv,IN INT32 Cpu)3205 Mvpp2AggrTxqPendDescNumGet (
3206   IN MVPP2_SHARED *Priv,
3207   IN INT32 Cpu
3208   )
3209 {
3210   UINT32 RegVal;
3211 
3212   RegVal = Mvpp2Read (Priv, MVPP2_AGGR_TXQ_STATUS_REG(Cpu));
3213 
3214   return RegVal & MVPP2_AGGR_TXQ_PENDING_MASK;
3215 }
3216 
3217 /* Get pointer to next Tx descriptor to be processed (send) by HW */
3218 MVPP2_TX_DESC *
Mvpp2TxqNextDescGet(MVPP2_TX_QUEUE * Txq)3219 Mvpp2TxqNextDescGet (
3220   MVPP2_TX_QUEUE *Txq
3221   )
3222 {
3223   INT32 TxDesc = Txq->NextDescToProc;
3224 
3225   Txq->NextDescToProc = MVPP2_QUEUE_NEXT_DESC (Txq, TxDesc);
3226 
3227   return Txq->Descs + TxDesc;
3228 }
3229 
3230 /* Update HW with number of aggRegValated Tx descriptors to be sent */
3231 VOID
Mvpp2AggrTxqPendDescAdd(IN PP2DXE_PORT * Port,IN INT32 Pending)3232 Mvpp2AggrTxqPendDescAdd (
3233   IN PP2DXE_PORT *Port,
3234   IN INT32 Pending
3235   )
3236 {
3237   /* AggRegValated access - relevant TXQ number is written in TX desc */
3238   Mvpp2Write (Port->Priv, MVPP2_AGGR_TXQ_UPDATE_REG, Pending);
3239 }
3240 
3241 /*
3242  * Check if there are enough free descriptors in aggRegValated Txq.
3243  * If not, update the number of occupied descriptors and repeat the check.
3244  */
3245 INT32
Mvpp2AggrDescNumCheck(IN MVPP2_SHARED * Priv,IN MVPP2_TX_QUEUE * AggrTxq,IN INT32 Num,IN INT32 Cpu)3246 Mvpp2AggrDescNumCheck (
3247   IN MVPP2_SHARED *Priv,
3248   IN MVPP2_TX_QUEUE *AggrTxq,
3249   IN INT32 Num,
3250   IN INT32 Cpu
3251   )
3252 {
3253   UINT32 Val;
3254 
3255   if ((AggrTxq->count + Num) > AggrTxq->Size) {
3256     /* Update number of occupied aggRegValated Tx descriptors */
3257     Val = Mvpp2Read (Priv, MVPP2_AGGR_TXQ_STATUS_REG(Cpu));
3258     AggrTxq->count = Val & MVPP2_AGGR_TXQ_PENDING_MASK;
3259   }
3260 
3261   if ((AggrTxq->count + Num) > AggrTxq->Size) {
3262     return MVPP2_ENOMEM;
3263   }
3264 
3265   return 0;
3266 }
3267 
3268 /* Reserved Tx descriptors allocation request */
3269 INT32
Mvpp2TxqAllocReservedDesc(IN MVPP2_SHARED * Priv,IN MVPP2_TX_QUEUE * Txq,IN INT32 Num)3270 Mvpp2TxqAllocReservedDesc (
3271   IN MVPP2_SHARED *Priv,
3272   IN MVPP2_TX_QUEUE *Txq,
3273   IN INT32 Num
3274   )
3275 {
3276   UINT32 Val;
3277 
3278   Val = (Txq->Id << MVPP2_TXQ_RSVD_REQ_Q_OFFSET) | Num;
3279   Mvpp2Write (Priv, MVPP2_TXQ_RSVD_REQ_REG, Val);
3280 
3281   Val = Mvpp2Read (Priv, MVPP2_TXQ_RSVD_RSLT_REG);
3282 
3283   return Val & MVPP2_TXQ_RSVD_RSLT_MASK;
3284 }
3285 
3286 /*
3287  * Release the last allocated Tx descriptor. Useful to handle DMA
3288  * mapping failures in the Tx path.
3289  */
3290 VOID
Mvpp2TxqDescPut(IN MVPP2_TX_QUEUE * Txq)3291 Mvpp2TxqDescPut (
3292   IN MVPP2_TX_QUEUE *Txq
3293   )
3294 {
3295   if (Txq->NextDescToProc == 0) {
3296     Txq->NextDescToProc = Txq->LastDesc - 1;
3297   } else {
3298     Txq->NextDescToProc--;
3299   }
3300 }
3301 
3302 /* Set Tx descriptors fields relevant for CSUM calculation */
3303 UINT32
Mvpp2TxqDescCsum(IN INT32 L3Offs,IN INT32 L3Proto,IN INT32 IpHdrLen,IN INT32 L4Proto)3304 Mvpp2TxqDescCsum (
3305   IN INT32 L3Offs,
3306   IN INT32 L3Proto,
3307   IN INT32 IpHdrLen,
3308   IN INT32 L4Proto
3309   )
3310 {
3311   UINT32 command;
3312 
3313   /*
3314    * Fields: L3_Offset, IP_hdrlen, L3_type, G_IPV4Chk,
3315    * G_L4_chk, L4_type required only for checksum calculation
3316    */
3317   command = (L3Offs << MVPP2_TXD_L3_OFF_SHIFT);
3318   command |= (IpHdrLen << MVPP2_TXD_IP_HLEN_SHIFT);
3319   command |= MVPP2_TXD_IP_CSUM_DISABLE;
3320 
3321   if (L3Proto == Mvpp2SwapBytes16 (MV_ETH_P_IP)) {
3322     command &= ~MVPP2_TXD_IP_CSUM_DISABLE;  /* enable IPv4 csum */
3323     command &= ~MVPP2_TXD_L3_IP6;           /* enable IPv4 */
3324   } else {
3325     command |= MVPP2_TXD_L3_IP6;            /* enable IPv6 */
3326   }
3327 
3328   if (L4Proto == MV_IPPR_TCP) {
3329     command &= ~MVPP2_TXD_L4_UDP;           /* enable TCP */
3330     command &= ~MVPP2_TXD_L4_CSUM_FRAG;     /* generate L4 csum */
3331   } else if (L4Proto == MV_IPPR_UDP) {
3332     command |= MVPP2_TXD_L4_UDP;            /* enable UDP */
3333     command &= ~MVPP2_TXD_L4_CSUM_FRAG;     /* generate L4 csum */
3334   } else {
3335     command |= MVPP2_TXD_L4_CSUM_NOT;
3336   }
3337 
3338   return command;
3339 }
3340 
3341 /* Clear counter of sent packets */
3342 VOID
Mvpp2TxqSentCounterClear(IN OUT VOID * arg)3343 Mvpp2TxqSentCounterClear (
3344   IN OUT VOID *arg
3345   )
3346 {
3347   PP2DXE_PORT *Port = arg;
3348   INT32 Queue;
3349 
3350   for (Queue = 0; Queue < TxqNumber; Queue++) {
3351     INT32 Id = Port->Txqs[Queue].Id;
3352 
3353     Mvpp2Read (Port->Priv, MVPP2_TXQ_SENT_REG(Id));
3354   }
3355 }
3356 
3357 /* Change maximum receive Size of the Port */
3358 VOID
Mvpp2GmacMaxRxSizeSet(IN PP2DXE_PORT * Port)3359 Mvpp2GmacMaxRxSizeSet (
3360   IN PP2DXE_PORT *Port
3361   )
3362 {
3363   UINT32 Val;
3364 
3365   Val = Mvpp2GmacRead (Port, MVPP2_GMAC_CTRL_0_REG);
3366   Val &= ~MVPP2_GMAC_MAX_RX_SIZE_MASK;
3367   Val |= (((Port->PktSize - MVPP2_MH_SIZE) / 2) << MVPP2_GMAC_MAX_RX_SIZE_OFFS);
3368   Mvpp2GmacWrite (Port, MVPP2_GMAC_CTRL_0_REG, Val);
3369 }
3370 
3371 /* Set max sizes for Tx Queues */
3372 VOID
Mvpp2TxpMaxTxSizeSet(IN PP2DXE_PORT * Port)3373 Mvpp2TxpMaxTxSizeSet (
3374   IN PP2DXE_PORT *Port
3375   )
3376 {
3377   UINT32  Val, Size, mtu;
3378   INT32 Txq, TxPortNum;
3379 
3380   mtu = Port->PktSize * 8;
3381   if (mtu > MVPP2_TXP_MTU_MAX) {
3382     mtu = MVPP2_TXP_MTU_MAX;
3383   }
3384 
3385   /* WA for wrong Token bucket update: Set MTU value = 3*real MTU value */
3386   mtu = 3 * mtu;
3387 
3388   /* Indirect access to RegValisters */
3389   TxPortNum = Mvpp2EgressPort (Port);
3390   Mvpp2Write (Port->Priv, MVPP2_TXP_SCHED_PORT_INDEX_REG, TxPortNum);
3391 
3392   /* Set MTU */
3393   Val = Mvpp2Read (Port->Priv, MVPP2_TXP_SCHED_MTU_REG);
3394   Val &= ~MVPP2_TXP_MTU_MAX;
3395   Val |= mtu;
3396   Mvpp2Write (Port->Priv, MVPP2_TXP_SCHED_MTU_REG, Val);
3397 
3398   /* TXP token Size and all TXQs token Size must be larger that MTU */
3399   Val = Mvpp2Read (Port->Priv, MVPP2_TXP_SCHED_TOKEN_SIZE_REG);
3400   Size = Val & MVPP2_TXP_TOKEN_SIZE_MAX;
3401   if (Size < mtu) {
3402     Size = mtu;
3403     Val &= ~MVPP2_TXP_TOKEN_SIZE_MAX;
3404     Val |= Size;
3405     Mvpp2Write (Port->Priv, MVPP2_TXP_SCHED_TOKEN_SIZE_REG, Val);
3406   }
3407 
3408   for (Txq = 0; Txq < TxqNumber; Txq++) {
3409     Val = Mvpp2Read (Port->Priv, MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(Txq));
3410     Size = Val & MVPP2_TXQ_TOKEN_SIZE_MAX;
3411 
3412     if (Size < mtu) {
3413       Size = mtu;
3414       Val &= ~MVPP2_TXQ_TOKEN_SIZE_MAX;
3415       Val |= Size;
3416       Mvpp2Write (Port->Priv, MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(Txq), Val);
3417     }
3418   }
3419 }
3420 
3421 /*
3422  * Set the number of packets that will be received before Rx interrupt
3423  * will be generated by HW.
3424  */
3425 VOID
Mvpp2RxPktsCoalSet(IN PP2DXE_PORT * Port,IN OUT MVPP2_RX_QUEUE * Rxq,IN UINT32 Pkts)3426 Mvpp2RxPktsCoalSet (
3427   IN PP2DXE_PORT *Port,
3428   IN OUT MVPP2_RX_QUEUE *Rxq,
3429   IN UINT32 Pkts
3430   )
3431 {
3432   UINT32 Val;
3433 
3434   Val = (Pkts & MVPP2_OCCUPIED_THRESH_MASK);
3435   Mvpp2Write (Port->Priv, MVPP2_RXQ_NUM_REG, Rxq->Id);
3436   Mvpp2Write (Port->Priv, MVPP2_RXQ_THRESH_REG, Val);
3437 
3438   Rxq->PktsCoal = Pkts;
3439 }
3440 
3441 /* Set the time Delay in Usec before Rx INT32errupt */
3442 VOID
Mvpp2RxTimeCoalSet(IN PP2DXE_PORT * Port,IN OUT MVPP2_RX_QUEUE * Rxq,IN UINT32 Usec)3443 Mvpp2RxTimeCoalSet (
3444   IN PP2DXE_PORT *Port,
3445   IN OUT MVPP2_RX_QUEUE *Rxq,
3446   IN UINT32 Usec
3447   )
3448 {
3449   UINT32 Val;
3450 
3451   Val = (Port->Priv->Tclk / MVPP2_USEC_PER_SEC) * Usec;
3452   Mvpp2Write (Port->Priv, MVPP2_ISR_RX_THRESHOLD_REG(Rxq->Id), Val);
3453 
3454   Rxq->TimeCoal = Usec;
3455 }
3456 
3457 /* Rx/Tx Queue initialization/cleanup methods */
3458 
3459 /* Configure RXQ's */
3460 VOID
Mvpp2RxqHwInit(IN PP2DXE_PORT * Port,IN OUT MVPP2_RX_QUEUE * Rxq)3461 Mvpp2RxqHwInit (
3462   IN PP2DXE_PORT *Port,
3463   IN OUT MVPP2_RX_QUEUE *Rxq
3464   )
3465 {
3466   Rxq->LastDesc = Rxq->Size - 1;
3467 
3468   /* Zero occupied and non-occupied counters - direct access */
3469   Mvpp2Write (Port->Priv, MVPP2_RXQ_STATUS_REG(Rxq->Id), 0);
3470 
3471   /* Set Rx descriptors Queue starting Address - indirect access */
3472   Mvpp2Write (Port->Priv, MVPP2_RXQ_NUM_REG, Rxq->Id);
3473   Mvpp2Write (Port->Priv, MVPP2_RXQ_DESC_ADDR_REG, Rxq->DescsPhys >> MVPP22_DESC_ADDR_SHIFT);
3474   Mvpp2Write (Port->Priv, MVPP2_RXQ_DESC_SIZE_REG, Rxq->Size);
3475   Mvpp2Write (Port->Priv, MVPP2_RXQ_INDEX_REG, 0);
3476 
3477   /* Set Offset */
3478   Mvpp2RxqOffsetSet (Port, Rxq->Id, MVPP2_RXQ_OFFSET);
3479 
3480   /* Set coalescing pkts and time */
3481   Mvpp2RxPktsCoalSet (Port, Rxq, MVPP2_RX_COAL_PKTS);
3482   Mvpp2RxTimeCoalSet (Port, Rxq, Rxq->TimeCoal);
3483 
3484   /* Add number of descriptors ready for receiving packets */
3485   Mvpp2RxqStatusUpdate (Port, Rxq->Id, 0, Rxq->Size);
3486 }
3487 
3488 /* Push packets received by the RXQ to BM Pool */
3489 VOID
Mvpp2RxqDropPkts(IN PP2DXE_PORT * Port,IN OUT MVPP2_RX_QUEUE * Rxq,IN INT32 Cpu)3490 Mvpp2RxqDropPkts (
3491   IN PP2DXE_PORT *Port,
3492   IN OUT MVPP2_RX_QUEUE *Rxq,
3493   IN INT32 Cpu
3494   )
3495 {
3496   INT32 RxReceived;
3497 
3498   RxReceived = Mvpp2RxqReceived (Port, Rxq->Id);
3499   if (!RxReceived) {
3500     return;
3501   }
3502 
3503   Mvpp2RxqStatusUpdate (Port, Rxq->Id, RxReceived, RxReceived);
3504 }
3505 
3506 VOID
Mvpp2RxqHwDeinit(IN PP2DXE_PORT * Port,IN OUT MVPP2_RX_QUEUE * Rxq)3507 Mvpp2RxqHwDeinit (
3508   IN PP2DXE_PORT *Port,
3509   IN OUT MVPP2_RX_QUEUE *Rxq
3510   )
3511 {
3512   Rxq->Descs = NULL;
3513   Rxq->LastDesc = 0;
3514   Rxq->NextDescToProc = 0;
3515   Rxq->DescsPhys = 0;
3516 
3517   /*
3518    * Clear Rx descriptors Queue starting Address and Size;
3519    * free descriptor number
3520    */
3521   Mvpp2Write (Port->Priv, MVPP2_RXQ_STATUS_REG(Rxq->Id), 0);
3522   Mvpp2Write (Port->Priv, MVPP2_RXQ_NUM_REG, Rxq->Id);
3523   Mvpp2Write (Port->Priv, MVPP2_RXQ_DESC_ADDR_REG, 0);
3524   Mvpp2Write (Port->Priv, MVPP2_RXQ_DESC_SIZE_REG, 0);
3525 }
3526 
3527 /* Configure TXQ's */
3528 VOID
Mvpp2TxqHwInit(IN PP2DXE_PORT * Port,IN OUT MVPP2_TX_QUEUE * Txq)3529 Mvpp2TxqHwInit (
3530   IN PP2DXE_PORT *Port,
3531   IN OUT MVPP2_TX_QUEUE *Txq
3532   )
3533 {
3534   INT32 Desc, DescPerTxq, TxPortNum;
3535   UINT32 Val;
3536 
3537   Txq->LastDesc = Txq->Size - 1;
3538 
3539   /* Set Tx descriptors Queue starting Address - indirect access */
3540   Mvpp2Write (Port->Priv, MVPP2_TXQ_NUM_REG, Txq->Id);
3541   Mvpp2Write (Port->Priv, MVPP2_TXQ_DESC_ADDR_REG, Txq->DescsPhys);
3542   Mvpp2Write (Port->Priv, MVPP2_TXQ_DESC_SIZE_REG, Txq->Size & MVPP2_TXQ_DESC_SIZE_MASK);
3543   Mvpp2Write (Port->Priv, MVPP2_TXQ_INDEX_REG, 0);
3544   Mvpp2Write (Port->Priv, MVPP2_TXQ_RSVD_CLR_REG, Txq->Id << MVPP2_TXQ_RSVD_CLR_OFFSET);
3545   Val = Mvpp2Read (Port->Priv, MVPP2_TXQ_PENDING_REG);
3546   Val &= ~MVPP2_TXQ_PENDING_MASK;
3547   Mvpp2Write (Port->Priv, MVPP2_TXQ_PENDING_REG, Val);
3548 
3549   /*
3550    * Calculate base Address in prefetch buffer. We reserve 16 descriptors
3551    * for each existing TXQ.
3552    * TCONTS for PON Port must be continuous from 0 to MVPP2_MAX_TCONT
3553    * GBE Ports assumed to be continious from 0 to MVPP2_MAX_PORTS
3554    */
3555   DescPerTxq = 16;
3556   Desc = (Port->Id * MVPP2_MAX_TXQ * DescPerTxq) + (Txq->LogId * DescPerTxq);
3557 
3558   Mvpp2Write (
3559           Port->Priv,
3560           MVPP2_TXQ_PREF_BUF_REG,
3561           MVPP2_PREF_BUF_PTR (Desc) | MVPP2_PREF_BUF_SIZE_16 | MVPP2_PREF_BUF_THRESH (DescPerTxq/2)
3562         );
3563 
3564   /* WRR / EJP configuration - indirect access */
3565   TxPortNum = Mvpp2EgressPort (Port);
3566   Mvpp2Write (Port->Priv, MVPP2_TXP_SCHED_PORT_INDEX_REG, TxPortNum);
3567 
3568   Val = Mvpp2Read (Port->Priv, MVPP2_TXQ_SCHED_REFILL_REG(Txq->LogId));
3569   Val &= ~MVPP2_TXQ_REFILL_PERIOD_ALL_MASK;
3570   Val |= MVPP2_TXQ_REFILL_PERIOD_MASK (1);
3571   Val |= MVPP2_TXQ_REFILL_TOKENS_ALL_MASK;
3572   Mvpp2Write (Port->Priv, MVPP2_TXQ_SCHED_REFILL_REG(Txq->LogId), Val);
3573 
3574   Val = MVPP2_TXQ_TOKEN_SIZE_MAX;
3575   Mvpp2Write (Port->Priv, MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(Txq->LogId), Val);
3576 }
3577 
3578 VOID
Mvpp2TxqHwDeinit(IN PP2DXE_PORT * Port,IN OUT MVPP2_TX_QUEUE * Txq)3579 Mvpp2TxqHwDeinit (
3580   IN PP2DXE_PORT *Port,
3581   IN OUT MVPP2_TX_QUEUE *Txq
3582   )
3583 {
3584   Txq->Descs = NULL;
3585   Txq->LastDesc = 0;
3586   Txq->NextDescToProc = 0;
3587   Txq->DescsPhys = 0;
3588 
3589   /* Set minimum bandwidth for disabled TXQs */
3590   Mvpp2Write (Port->Priv, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(Txq->Id), 0);
3591 
3592   /* Set Tx descriptors Queue starting Address and Size */
3593   Mvpp2Write (Port->Priv, MVPP2_TXQ_NUM_REG, Txq->Id);
3594   Mvpp2Write (Port->Priv, MVPP2_TXQ_DESC_ADDR_REG, 0);
3595   Mvpp2Write (Port->Priv, MVPP2_TXQ_DESC_SIZE_REG, 0);
3596 }
3597 
3598 /* Allocate and initialize descriptors for aggr TXQ */
3599 VOID
Mvpp2AggrTxqHwInit(IN OUT MVPP2_TX_QUEUE * AggrTxq,IN INT32 DescNum,IN INT32 Cpu,IN MVPP2_SHARED * Priv)3600 Mvpp2AggrTxqHwInit (
3601   IN OUT MVPP2_TX_QUEUE *AggrTxq,
3602   IN INT32 DescNum,
3603   IN INT32 Cpu,
3604   IN MVPP2_SHARED *Priv
3605   )
3606 {
3607   AggrTxq->LastDesc = AggrTxq->Size - 1;
3608 
3609   /* Aggr TXQ no Reset WA */
3610   AggrTxq->NextDescToProc = Mvpp2Read (Priv, MVPP2_AGGR_TXQ_INDEX_REG(Cpu));
3611 
3612   /* Set Tx descriptors Queue starting Address (indirect access) */
3613   Mvpp2Write (Priv, MVPP2_AGGR_TXQ_DESC_ADDR_REG(Cpu), AggrTxq->DescsPhys >> MVPP22_DESC_ADDR_SHIFT);
3614   Mvpp2Write (Priv, MVPP2_AGGR_TXQ_DESC_SIZE_REG(Cpu), DescNum & MVPP2_AGGR_TXQ_DESC_SIZE_MASK);
3615 }
3616 
3617 /* Enable gmac */
3618 VOID
Mvpp2PortPowerUp(IN PP2DXE_PORT * Port)3619 Mvpp2PortPowerUp (
3620   IN PP2DXE_PORT *Port
3621   )
3622 {
3623   Mvpp2PortMiiSet (Port);
3624   Mvpp2PortPeriodicXonDisable (Port);
3625   Mvpp2PortFcAdvEnable (Port);
3626   Mvpp2PortReset (Port);
3627 }
3628 
3629 /* Initialize Rx FIFO's */
3630 VOID
Mvpp2RxFifoInit(IN MVPP2_SHARED * Priv)3631 Mvpp2RxFifoInit (
3632   IN MVPP2_SHARED *Priv
3633   )
3634 {
3635   INT32 PortId;
3636 
3637   for (PortId = 0; PortId < MVPP2_MAX_PORTS; PortId++) {
3638     Mvpp2Write (Priv, MVPP2_RX_DATA_FIFO_SIZE_REG(PortId), MVPP2_RX_FIFO_PORT_DATA_SIZE);
3639     Mvpp2Write (Priv, MVPP2_RX_ATTR_FIFO_SIZE_REG(PortId), MVPP2_RX_FIFO_PORT_ATTR_SIZE);
3640   }
3641 
3642   Mvpp2Write (Priv, MVPP2_RX_MIN_PKT_SIZE_REG, MVPP2_RX_FIFO_PORT_MIN_PKT);
3643   Mvpp2Write (Priv, MVPP2_RX_FIFO_INIT_REG, 0x1);
3644 }
3645 
3646 VOID
MvGop110NetcActivePort(IN PP2DXE_PORT * Port,IN UINT32 PortId,IN UINT32 Val)3647 MvGop110NetcActivePort (
3648   IN PP2DXE_PORT *Port,
3649   IN UINT32 PortId,
3650   IN UINT32 Val
3651   )
3652 {
3653   UINT32 RegVal;
3654 
3655   RegVal = Mvpp2Rfu1Read (Port->Priv, MV_NETCOMP_PORTS_CONTROL_1);
3656   RegVal &= ~(NETC_PORTS_ACTIVE_MASK (PortId));
3657 
3658   Val <<= NETC_PORTS_ACTIVE_OFFSET (PortId);
3659   Val &= NETC_PORTS_ACTIVE_MASK (PortId);
3660 
3661   RegVal |= Val;
3662 
3663   Mvpp2Rfu1Write (Port->Priv, MV_NETCOMP_PORTS_CONTROL_1, RegVal);
3664 }
3665 
3666 STATIC
3667 VOID
MvGop110NetcXauiEnable(IN PP2DXE_PORT * Port,IN UINT32 PortId,IN UINT32 Val)3668 MvGop110NetcXauiEnable (
3669   IN PP2DXE_PORT *Port,
3670   IN UINT32 PortId,
3671   IN UINT32 Val
3672   )
3673 {
3674   UINT32 RegVal;
3675 
3676   RegVal = Mvpp2Rfu1Read (Port->Priv, SD1_CONTROL_1_REG);
3677   RegVal &= ~SD1_CONTROL_XAUI_EN_MASK;
3678 
3679   Val <<= SD1_CONTROL_XAUI_EN_OFFSET;
3680   Val &= SD1_CONTROL_XAUI_EN_MASK;
3681 
3682   RegVal |= Val;
3683 
3684   Mvpp2Rfu1Write (Port->Priv, SD1_CONTROL_1_REG, RegVal);
3685 }
3686 
3687 STATIC
3688 VOID
MvGop110NetcRxaui0Enable(IN PP2DXE_PORT * Port,IN UINT32 PortId,IN UINT32 Val)3689 MvGop110NetcRxaui0Enable (
3690   IN PP2DXE_PORT *Port,
3691   IN UINT32 PortId,
3692   IN UINT32 Val
3693   )
3694 {
3695   UINT32 RegVal;
3696 
3697   RegVal = Mvpp2Rfu1Read (Port->Priv, SD1_CONTROL_1_REG);
3698   RegVal &= ~SD1_CONTROL_RXAUI0_L23_EN_MASK;
3699 
3700   Val <<= SD1_CONTROL_RXAUI0_L23_EN_OFFSET;
3701   Val &= SD1_CONTROL_RXAUI0_L23_EN_MASK;
3702 
3703   RegVal |= Val;
3704 
3705   Mvpp2Rfu1Write (Port->Priv, SD1_CONTROL_1_REG, RegVal);
3706 }
3707 
3708 STATIC
3709 VOID
MvGop110NetcRxaui1Enable(IN PP2DXE_PORT * Port,IN UINT32 PortId,IN UINT32 Val)3710 MvGop110NetcRxaui1Enable (
3711   IN PP2DXE_PORT *Port,
3712   IN UINT32 PortId,
3713   IN UINT32 Val
3714   )
3715 {
3716   UINT32 RegVal;
3717 
3718   RegVal = Mvpp2Rfu1Read (Port->Priv, SD1_CONTROL_1_REG);
3719   RegVal &= ~SD1_CONTROL_RXAUI1_L45_EN_MASK;
3720 
3721   Val <<= SD1_CONTROL_RXAUI1_L45_EN_OFFSET;
3722   Val &= SD1_CONTROL_RXAUI1_L45_EN_MASK;
3723 
3724   RegVal |= Val;
3725 
3726   Mvpp2Rfu1Write (Port->Priv, SD1_CONTROL_1_REG, RegVal);
3727 }
3728 
3729 STATIC
3730 VOID
MvGop110NetcMiiMode(IN PP2DXE_PORT * Port,IN UINT32 PortId,IN UINT32 Val)3731 MvGop110NetcMiiMode (
3732   IN PP2DXE_PORT *Port,
3733   IN UINT32 PortId,
3734   IN UINT32 Val
3735   )
3736 {
3737   UINT32 RegVal;
3738 
3739   RegVal = Mvpp2Rfu1Read (Port->Priv, MV_NETCOMP_CONTROL_0);
3740   RegVal &= ~NETC_GBE_PORT1_MII_MODE_MASK;
3741 
3742   Val <<= NETC_GBE_PORT1_MII_MODE_OFFSET;
3743   Val &= NETC_GBE_PORT1_MII_MODE_MASK;
3744 
3745   RegVal |= Val;
3746 
3747   Mvpp2Rfu1Write (Port->Priv, MV_NETCOMP_CONTROL_0, RegVal);
3748 }
3749 
3750 STATIC
3751 VOID
MvGop110NetcGopReset(IN PP2DXE_PORT * Port,IN UINT32 Val)3752 MvGop110NetcGopReset (
3753   IN PP2DXE_PORT *Port,
3754   IN UINT32 Val
3755   )
3756 {
3757   UINT32 RegVal;
3758 
3759   RegVal = Mvpp2Rfu1Read (Port->Priv, MV_GOP_SOFT_RESET_1_REG);
3760   RegVal &= ~NETC_GOP_SOFT_RESET_MASK;
3761 
3762   Val <<= NETC_GOP_SOFT_RESET_OFFSET;
3763   Val &= NETC_GOP_SOFT_RESET_MASK;
3764 
3765   RegVal |= Val;
3766 
3767   Mvpp2Rfu1Write (Port->Priv, MV_GOP_SOFT_RESET_1_REG, RegVal);
3768 }
3769 
3770 STATIC
3771 VOID
MvGop110NetcGopClockLogicSet(IN PP2DXE_PORT * Port,IN UINT32 Val)3772 MvGop110NetcGopClockLogicSet (
3773   IN PP2DXE_PORT *Port,
3774   IN UINT32 Val
3775   )
3776 {
3777   UINT32 RegVal;
3778 
3779   RegVal = Mvpp2Rfu1Read (Port->Priv, MV_NETCOMP_PORTS_CONTROL_0);
3780   RegVal &= ~NETC_CLK_DIV_PHASE_MASK;
3781 
3782   Val <<= NETC_CLK_DIV_PHASE_OFFSET;
3783   Val &= NETC_CLK_DIV_PHASE_MASK;
3784 
3785   RegVal |= Val;
3786 
3787   Mvpp2Rfu1Write (Port->Priv, MV_NETCOMP_PORTS_CONTROL_0, RegVal);
3788 }
3789 
3790 STATIC
3791 VOID
MvGop110NetcPortRfReset(IN PP2DXE_PORT * Port,IN UINT32 PortId,IN UINT32 Val)3792 MvGop110NetcPortRfReset (
3793   IN PP2DXE_PORT *Port,
3794   IN UINT32 PortId,
3795   IN UINT32 Val
3796   )
3797 {
3798   UINT32 RegVal;
3799 
3800   RegVal = Mvpp2Rfu1Read (Port->Priv, MV_NETCOMP_PORTS_CONTROL_1);
3801   RegVal &= ~(NETC_PORT_GIG_RF_RESET_MASK (PortId));
3802 
3803   Val <<= NETC_PORT_GIG_RF_RESET_OFFSET (PortId);
3804   Val &= NETC_PORT_GIG_RF_RESET_MASK (PortId);
3805 
3806   RegVal |= Val;
3807 
3808   Mvpp2Rfu1Write (Port->Priv, MV_NETCOMP_PORTS_CONTROL_1, RegVal);
3809 }
3810 
3811 STATIC
3812 VOID
MvGop110NetcGbeSgmiiModeSelect(IN PP2DXE_PORT * Port,IN UINT32 PortId,IN UINT32 Val)3813 MvGop110NetcGbeSgmiiModeSelect (
3814   IN PP2DXE_PORT *Port,
3815   IN UINT32 PortId,
3816   IN UINT32 Val
3817   )
3818 {
3819   UINT32 RegVal, Mask, Offset;
3820 
3821   if (PortId == 2) {
3822     Mask = NETC_GBE_PORT0_SGMII_MODE_MASK;
3823     Offset = NETC_GBE_PORT0_SGMII_MODE_OFFSET;
3824   } else {
3825     Mask = NETC_GBE_PORT1_SGMII_MODE_MASK;
3826     Offset = NETC_GBE_PORT1_SGMII_MODE_OFFSET;
3827   }
3828   RegVal = Mvpp2Rfu1Read (Port->Priv, MV_NETCOMP_CONTROL_0);
3829   RegVal &= ~Mask;
3830 
3831   Val <<= Offset;
3832   Val &= Mask;
3833 
3834   RegVal |= Val;
3835 
3836   Mvpp2Rfu1Write (Port->Priv, MV_NETCOMP_CONTROL_0, RegVal);
3837 }
3838 
3839 STATIC
3840 VOID
MvGop110NetcBusWidthSelect(IN PP2DXE_PORT * Port,IN UINT32 Val)3841 MvGop110NetcBusWidthSelect (
3842   IN PP2DXE_PORT *Port,
3843   IN UINT32 Val
3844   )
3845 {
3846   UINT32 RegVal;
3847 
3848   RegVal = Mvpp2Rfu1Read (Port->Priv, MV_NETCOMP_PORTS_CONTROL_0);
3849   RegVal &= ~NETC_BUS_WIDTH_SELECT_MASK;
3850 
3851   Val <<= NETC_BUS_WIDTH_SELECT_OFFSET;
3852   Val &= NETC_BUS_WIDTH_SELECT_MASK;
3853 
3854   RegVal |= Val;
3855 
3856   Mvpp2Rfu1Write (Port->Priv, MV_NETCOMP_PORTS_CONTROL_0, RegVal);
3857 }
3858 
3859 STATIC
3860 VOID
MvGop110NetcSampleStagesTiming(IN PP2DXE_PORT * Port,IN UINT32 Val)3861 MvGop110NetcSampleStagesTiming (
3862   IN PP2DXE_PORT *Port,
3863   IN UINT32 Val
3864   )
3865 {
3866   UINT32 RegVal;
3867 
3868   RegVal = Mvpp2Rfu1Read (Port->Priv, MV_NETCOMP_PORTS_CONTROL_0);
3869   RegVal &= ~NETC_GIG_RX_DATA_SAMPLE_MASK;
3870 
3871   Val <<= NETC_GIG_RX_DATA_SAMPLE_OFFSET;
3872   Val &= NETC_GIG_RX_DATA_SAMPLE_MASK;
3873 
3874   RegVal |= Val;
3875 
3876   Mvpp2Rfu1Write (Port->Priv, MV_NETCOMP_PORTS_CONTROL_0, RegVal);
3877 }
3878 
3879 STATIC
3880 VOID
MvGop110NetcMacToXgmii(IN PP2DXE_PORT * Port,IN UINT32 PortId,IN enum MvNetcPhase Phase)3881 MvGop110NetcMacToXgmii (
3882   IN PP2DXE_PORT *Port,
3883   IN UINT32 PortId,
3884   IN enum MvNetcPhase Phase
3885   )
3886 {
3887   switch (Phase) {
3888   case MV_NETC_FIRST_PHASE:
3889 
3890     /* Set Bus Width to HB mode = 1 */
3891     MvGop110NetcBusWidthSelect (Port, 0x1);
3892 
3893     /* Select RGMII mode */
3894     MvGop110NetcGbeSgmiiModeSelect (Port, PortId, MV_NETC_GBE_XMII);
3895     break;
3896   case MV_NETC_SECOND_PHASE:
3897 
3898     /* De-assert the relevant PortId HB Reset */
3899     MvGop110NetcPortRfReset (Port, PortId, 0x1);
3900     break;
3901   }
3902 }
3903 
3904 STATIC
3905 VOID
MvGop110NetcMacToSgmii(IN PP2DXE_PORT * Port,IN UINT32 PortId,IN enum MvNetcPhase Phase)3906 MvGop110NetcMacToSgmii (
3907   IN PP2DXE_PORT *Port,
3908   IN UINT32 PortId,
3909   IN enum MvNetcPhase Phase
3910   )
3911 {
3912   switch (Phase) {
3913   case MV_NETC_FIRST_PHASE:
3914 
3915     /* Set Bus Width to HB mode = 1 */
3916     MvGop110NetcBusWidthSelect (Port, 1);
3917 
3918     /* Select SGMII mode */
3919     if (PortId >= 1) {
3920       MvGop110NetcGbeSgmiiModeSelect (Port, PortId, MV_NETC_GBE_SGMII);
3921     }
3922 
3923     /* Configure the sample stages */
3924     MvGop110NetcSampleStagesTiming (Port, 0);
3925     break;
3926   case MV_NETC_SECOND_PHASE:
3927 
3928     /* De-assert the relevant PortId HB Reset */
3929     MvGop110NetcPortRfReset (Port, PortId, 1);
3930     break;
3931   }
3932 }
3933 
3934 STATIC
3935 VOID
MvGop110NetcMacToRxaui(IN PP2DXE_PORT * Port,IN UINT32 PortId,IN enum MvNetcPhase Phase,IN enum MvNetcLanes Lanes)3936 MvGop110NetcMacToRxaui (
3937   IN PP2DXE_PORT *Port,
3938   IN UINT32 PortId,
3939   IN enum MvNetcPhase Phase,
3940   IN enum MvNetcLanes Lanes
3941   )
3942 {
3943   /* Currently only RXAUI0 supPorted */
3944   if (PortId != 0)
3945     return;
3946 
3947   switch (Phase) {
3948   case MV_NETC_FIRST_PHASE:
3949 
3950     /* RXAUI Serdes/s Clock alignment */
3951     if (Lanes == MV_NETC_LANE_23) {
3952       MvGop110NetcRxaui0Enable (Port, PortId, 1);
3953     } else {
3954       MvGop110NetcRxaui1Enable (Port, PortId, 1);
3955     }
3956     break;
3957   case MV_NETC_SECOND_PHASE:
3958 
3959     /* De-assert the relevant PortId HB Reset */
3960     MvGop110NetcPortRfReset (Port, PortId, 1);
3961     break;
3962   }
3963 }
3964 
3965 STATIC
3966 VOID
MvGop110NetcMacToXaui(IN PP2DXE_PORT * Port,IN UINT32 PortId,IN enum MvNetcPhase Phase)3967 MvGop110NetcMacToXaui (
3968   IN PP2DXE_PORT *Port,
3969   IN UINT32 PortId,
3970   IN enum MvNetcPhase Phase
3971   )
3972 {
3973   switch (Phase) {
3974   case MV_NETC_FIRST_PHASE:
3975 
3976     /* RXAUI Serdes/s Clock alignment */
3977     MvGop110NetcXauiEnable (Port, PortId, 1);
3978     break;
3979   case MV_NETC_SECOND_PHASE:
3980 
3981     /* De-assert the relevant PortId HB Reset */
3982     MvGop110NetcPortRfReset (Port, PortId, 1);
3983     break;
3984   }
3985 }
3986 
3987 INT32
MvGop110NetcInit(IN PP2DXE_PORT * Port,IN UINT32 NetCompConfig,IN enum MvNetcPhase Phase)3988 MvGop110NetcInit (
3989   IN PP2DXE_PORT *Port,
3990   IN UINT32 NetCompConfig,
3991   IN enum MvNetcPhase Phase
3992   )
3993 {
3994   UINT32 c = NetCompConfig;
3995 
3996   if (c & MV_NETC_GE_MAC0_RXAUI_L23) {
3997     MvGop110NetcMacToRxaui (Port, 0, Phase, MV_NETC_LANE_23);
3998   }
3999 
4000   if (c & MV_NETC_GE_MAC0_RXAUI_L45) {
4001     MvGop110NetcMacToRxaui (Port, 0, Phase, MV_NETC_LANE_45);
4002   }
4003 
4004   if (c & MV_NETC_GE_MAC0_XAUI) {
4005     MvGop110NetcMacToXaui (Port, 0, Phase);
4006   }
4007 
4008   if (c & MV_NETC_GE_MAC2_SGMII) {
4009     MvGop110NetcMacToSgmii (Port, 2, Phase);
4010   } else {
4011     MvGop110NetcMacToXgmii (Port, 2, Phase);
4012   }
4013 
4014   if (c & MV_NETC_GE_MAC3_SGMII) {
4015     MvGop110NetcMacToSgmii (Port, 3, Phase);
4016   } else {
4017     MvGop110NetcMacToXgmii (Port, 3, Phase);
4018     if (c & MV_NETC_GE_MAC3_RGMII) {
4019       MvGop110NetcMiiMode (Port, 3, MV_NETC_GBE_RGMII);
4020     } else {
4021       MvGop110NetcMiiMode (Port, 3, MV_NETC_GBE_MII);
4022     }
4023   }
4024 
4025   /* Activate gop Ports 0, 2, 3 */
4026   MvGop110NetcActivePort (Port, 0, 1);
4027   MvGop110NetcActivePort (Port, 2, 1);
4028   MvGop110NetcActivePort (Port, 3, 1);
4029 
4030   if (Phase == MV_NETC_SECOND_PHASE) {
4031 
4032     /* Enable the GOP internal clock logic */
4033     MvGop110NetcGopClockLogicSet (Port, 1);
4034 
4035     /* De-assert GOP unit Reset */
4036     MvGop110NetcGopReset (Port, 1);
4037   }
4038 
4039   return 0;
4040 }
4041 
4042 UINT32
MvpPp2xGop110NetcCfgCreate(IN PP2DXE_PORT * Port)4043 MvpPp2xGop110NetcCfgCreate (
4044   IN PP2DXE_PORT *Port
4045   )
4046 {
4047   UINT32 Val = 0;
4048 
4049     if (Port->GopIndex == 0) {
4050       if (Port->PhyInterface == MV_MODE_XAUI) {
4051         Val |= MV_NETC_GE_MAC0_XAUI;
4052       } else if (Port->PhyInterface == MV_MODE_RXAUI) {
4053         Val |= MV_NETC_GE_MAC0_RXAUI_L23;
4054       }
4055     }
4056 
4057     if (Port->GopIndex == 2) {
4058       if (Port->PhyInterface == MV_MODE_SGMII) {
4059         Val |= MV_NETC_GE_MAC2_SGMII;
4060       }
4061     }
4062 
4063     if (Port->GopIndex == 3) {
4064       if (Port->PhyInterface == MV_MODE_SGMII) {
4065         Val |= MV_NETC_GE_MAC3_SGMII;
4066       } else if (Port->PhyInterface == MV_MODE_RGMII) {
4067         Val |= MV_NETC_GE_MAC3_RGMII;
4068       }
4069     }
4070 
4071   return Val;
4072 }
4073 
4074 /*
4075  * Initialize physical Port. Configure the Port mode and
4076  * all its elements accordingly.
4077  */
4078 INT32
MvGop110PortInit(IN PP2DXE_PORT * Port)4079 MvGop110PortInit (
4080   IN PP2DXE_PORT *Port
4081   )
4082 {
4083 
4084   switch (Port->PhyInterface) {
4085   case MV_MODE_RGMII:
4086     MvGop110GmacReset (Port, RESET);
4087 
4088     /* Configure PCS */
4089     MvGop110GpcsModeCfg (Port, FALSE);
4090     MvGop110BypassClkCfg (Port, TRUE);
4091 
4092     /* Configure MAC */
4093     MvGop110GmacModeCfg (Port);
4094 
4095     /* PCS unreset */
4096     MvGop110GpcsReset (Port, UNRESET);
4097 
4098     /* MAC unreset */
4099     MvGop110GmacReset (Port, UNRESET);
4100   break;
4101   case MV_MODE_SGMII:
4102   case MV_MODE_QSGMII:
4103 
4104     /* Configure PCS */
4105     MvGop110GpcsModeCfg (Port, TRUE);
4106 
4107     /* Configure MAC */
4108     MvGop110GmacModeCfg (Port);
4109 
4110     /* Select proper MAC mode */
4111     MvGop110Xlg2GigMacCfg (Port);
4112 
4113     /* PCS unreset */
4114     MvGop110GpcsReset (Port, UNRESET);
4115 
4116     /* MAC unreset */
4117     MvGop110GmacReset (Port, UNRESET);
4118   break;
4119   default:
4120     return -1;
4121   }
4122 
4123   return 0;
4124 }
4125 
4126 /* Set the MAC to Reset or exit from Reset */
4127 INT32
MvGop110GmacReset(IN PP2DXE_PORT * Port,IN enum MvReset ResetCmd)4128 MvGop110GmacReset (
4129   IN PP2DXE_PORT *Port,
4130   IN enum MvReset ResetCmd
4131   )
4132 {
4133   UINT32 RegAddr;
4134   UINT32 Val;
4135 
4136   RegAddr = MVPP2_PORT_CTRL2_REG;
4137 
4138   Val = MvGop110GmacRead (Port, RegAddr);
4139 
4140   if (ResetCmd == RESET) {
4141     Val |= MVPP2_PORT_CTRL2_PORTMACRESET_MASK;
4142   } else {
4143     Val &= ~MVPP2_PORT_CTRL2_PORTMACRESET_MASK;
4144   }
4145 
4146   MvGop110GmacWrite (Port, RegAddr, Val);
4147 
4148   return 0;
4149 }
4150 
4151 /* Enable/Disable Port to work with Gig PCS */
4152 INT32
MvGop110GpcsModeCfg(IN PP2DXE_PORT * Port,BOOLEAN En)4153 MvGop110GpcsModeCfg (
4154   IN PP2DXE_PORT *Port,
4155   BOOLEAN En
4156   )
4157 {
4158   UINT32 Val;
4159 
4160   Val = MvGop110GmacRead (Port, MVPP2_PORT_CTRL2_REG);
4161 
4162   if (En) {
4163     Val |= MVPP2_PORT_CTRL2_PCS_EN_MASK;
4164   } else {
4165     Val &= ~MVPP2_PORT_CTRL2_PCS_EN_MASK;
4166   }
4167 
4168   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL2_REG, Val);
4169 
4170   return 0;
4171 }
4172 
4173 INT32
MvGop110BypassClkCfg(IN PP2DXE_PORT * Port,IN BOOLEAN En)4174 MvGop110BypassClkCfg (
4175   IN PP2DXE_PORT *Port,
4176   IN BOOLEAN En
4177   )
4178 {
4179   UINT32 Val;
4180 
4181   Val = MvGop110GmacRead (Port, MVPP2_PORT_CTRL2_REG);
4182 
4183   if (En) {
4184     Val |= MVPP2_PORT_CTRL2_CLK_125_BYPS_EN_MASK;
4185   } else {
4186     Val &= ~MVPP2_PORT_CTRL2_CLK_125_BYPS_EN_MASK;
4187   }
4188 
4189   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL2_REG, Val);
4190 
4191   return 0;
4192 }
4193 
4194 INT32
MvGop110GpcsReset(IN PP2DXE_PORT * Port,IN enum MvReset ResetCmd)4195 MvGop110GpcsReset (
4196   IN PP2DXE_PORT *Port,
4197   IN enum MvReset ResetCmd
4198   )
4199 {
4200   UINT32 RegData;
4201 
4202   RegData = MvGop110GmacRead (Port, MVPP2_PORT_CTRL2_REG);
4203 
4204   if (ResetCmd == RESET) {
4205     U32_SET_FIELD (
4206             RegData,
4207             MVPP2_PORT_CTRL2_SGMII_MODE_MASK,
4208             0
4209           );
4210 
4211   } else {
4212     U32_SET_FIELD (
4213             RegData,
4214             MVPP2_PORT_CTRL2_SGMII_MODE_MASK,
4215             1 << MVPP2_PORT_CTRL2_SGMII_MODE_OFFS
4216           );
4217 
4218   }
4219 
4220   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL2_REG, RegData);
4221 
4222   return 0;
4223 }
4224 
4225 VOID
MvGop110Xlg2GigMacCfg(IN PP2DXE_PORT * Port)4226 MvGop110Xlg2GigMacCfg (
4227   IN PP2DXE_PORT *Port
4228   )
4229 {
4230   UINT32 RegVal;
4231 
4232   /* Relevant only for MAC0 (XLG0 and GMAC0) */
4233   if (Port->GopIndex > 0) {
4234     return;
4235   }
4236 
4237   /* Configure 1Gig MAC mode */
4238   RegVal = Mvpp2XlgRead (Port, MV_XLG_PORT_MAC_CTRL3_REG);
4239   U32_SET_FIELD (
4240           RegVal,
4241           MV_XLG_MAC_CTRL3_MACMODESELECT_MASK,
4242           (0 << MV_XLG_MAC_CTRL3_MACMODESELECT_OFFS)
4243         );
4244 
4245   Mvpp2XlgWrite (Port, MV_XLG_PORT_MAC_CTRL3_REG, RegVal);
4246 }
4247 
4248 /* Set the internal mux's to the required MAC in the GOP */
4249 INT32
MvGop110GmacModeCfg(IN PP2DXE_PORT * Port)4250 MvGop110GmacModeCfg (
4251   IN PP2DXE_PORT *Port
4252   )
4253 {
4254   UINT32 RegAddr;
4255   UINT32 Val;
4256 
4257   /* Set TX FIFO thresholds */
4258   switch (Port->PhyInterface) {
4259   case MV_MODE_SGMII:
4260     if (Port->Speed == MV_PORT_SPEED_2500) {
4261       MvGop110GmacSgmii25Cfg (Port);
4262     } else {
4263       MvGop110GmacSgmiiCfg (Port);
4264     }
4265   break;
4266   case MV_MODE_RGMII:
4267     MvGop110GmacRgmiiCfg (Port);
4268   break;
4269   case MV_MODE_QSGMII:
4270     MvGop110GmacQsgmiiCfg (Port);
4271   break;
4272   default:
4273     return -1;
4274   }
4275 
4276   /* Jumbo frame supPort - 0x1400*2= 0x2800 bytes */
4277   Val = MvGop110GmacRead (Port, MVPP2_PORT_CTRL0_REG);
4278   U32_SET_FIELD (
4279           Val,
4280           MVPP2_PORT_CTRL0_FRAMESIZELIMIT_MASK,
4281           (0x1400 << MVPP2_PORT_CTRL0_FRAMESIZELIMIT_OFFS)
4282         );
4283 
4284   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL0_REG, Val);
4285 
4286   /* PeriodicXonEn disable */
4287   RegAddr = MVPP2_PORT_CTRL1_REG;
4288   Val = MvGop110GmacRead (Port, RegAddr);
4289   Val &= ~MVPP2_PORT_CTRL1_EN_PERIODIC_FC_XON_MASK;
4290   MvGop110GmacWrite (Port, RegAddr, Val);
4291 
4292   /* Mask all Ports interrupts */
4293   MvGop110GmacPortLinkEventMask (Port);
4294 
4295 #if MV_PP2x_INTERRUPT
4296   /* Unmask link change interrupt */
4297   Val = MvGop110GmacRead (Port, MVPP2_INTERRUPT_MASK_REG);
4298   Val |= MVPP2_INTERRUPT_CAUSE_LINK_CHANGE_MASK;
4299   Val |= 1; /* Unmask summary bit */
4300   MvGop110GmacWrite (Port, MVPP2_INTERRUPT_MASK_REG, Val);
4301 #endif
4302 
4303   return 0;
4304 }
4305 
4306 VOID
MvGop110GmacRgmiiCfg(IN PP2DXE_PORT * Port)4307 MvGop110GmacRgmiiCfg (
4308   IN PP2DXE_PORT *Port
4309   )
4310 {
4311   UINT32 Val, thresh, an;
4312 
4313   /* Configure minimal level of the Tx FIFO before the lower part starts to read a packet*/
4314   thresh = MV_RGMII_TX_FIFO_MIN_TH;
4315   Val = MvGop110GmacRead (Port, MVPP2_PORT_FIFO_CFG_1_REG);
4316   U32_SET_FIELD (
4317           Val,
4318           MVPP2_PORT_FIFO_CFG_1_TX_FIFO_MIN_TH_MASK,
4319           (thresh << MVPP2_PORT_FIFO_CFG_1_TX_FIFO_MIN_TH_OFFS)
4320         );
4321 
4322   MvGop110GmacWrite (Port, MVPP2_PORT_FIFO_CFG_1_REG, Val);
4323 
4324   /* Disable bypass of sync module */
4325   Val = MvGop110GmacRead (Port, MVPP2_PORT_CTRL4_REG);
4326   Val |= MVPP2_PORT_CTRL4_SYNC_BYPASS_MASK;
4327 
4328   /* Configure DP clock select according to mode */
4329   Val &= ~MVPP2_PORT_CTRL4_DP_CLK_SEL_MASK;
4330   Val |= MVPP2_PORT_CTRL4_QSGMII_BYPASS_ACTIVE_MASK;
4331   Val |= MVPP2_PORT_CTRL4_EXT_PIN_GMII_SEL_MASK;
4332   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL4_REG, Val);
4333 
4334   Val = MvGop110GmacRead (Port, MVPP2_PORT_CTRL2_REG);
4335   Val &= ~MVPP2_PORT_CTRL2_DIS_PADING_OFFS;
4336   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL2_REG, Val);
4337 
4338   /* Configure GIG MAC to SGMII mode */
4339   Val = MvGop110GmacRead (Port, MVPP2_PORT_CTRL0_REG);
4340   Val &= ~MVPP2_PORT_CTRL0_PORTTYPE_MASK;
4341   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL0_REG, Val);
4342 
4343   /* configure AN 0xb8e8 */
4344   an = MVPP2_PORT_AUTO_NEG_CFG_AN_BYPASS_EN_MASK |
4345        MVPP2_PORT_AUTO_NEG_CFG_EN_AN_SPEED_MASK |
4346        MVPP2_PORT_AUTO_NEG_CFG_EN_FC_AN_MASK |
4347        MVPP2_PORT_AUTO_NEG_CFG_EN_FDX_AN_MASK |
4348        MVPP2_PORT_AUTO_NEG_CFG_CHOOSE_SAMPLE_TX_CONFIG_MASK;
4349   MvGop110GmacWrite (Port, MVPP2_PORT_AUTO_NEG_CFG_REG, an);
4350 }
4351 
4352 VOID
MvGop110GmacSgmii25Cfg(IN PP2DXE_PORT * Port)4353 MvGop110GmacSgmii25Cfg (
4354   IN PP2DXE_PORT *Port
4355   )
4356 {
4357   UINT32 Val, thresh, an;
4358 
4359   /*
4360    * Configure minimal level of the Tx FIFO before
4361    * the lower part starts to read a packet.
4362    */
4363   thresh = MV_SGMII2_5_TX_FIFO_MIN_TH;
4364   Val = MvGop110GmacRead (Port, MVPP2_PORT_FIFO_CFG_1_REG);
4365   U32_SET_FIELD (
4366           Val,
4367           MVPP2_PORT_FIFO_CFG_1_TX_FIFO_MIN_TH_MASK,
4368           (thresh << MVPP2_PORT_FIFO_CFG_1_TX_FIFO_MIN_TH_OFFS)
4369         );
4370 
4371   MvGop110GmacWrite (Port, MVPP2_PORT_FIFO_CFG_1_REG, Val);
4372 
4373   /* Disable bypass of sync module */
4374   Val = MvGop110GmacRead (Port, MVPP2_PORT_CTRL4_REG);
4375   Val |= MVPP2_PORT_CTRL4_SYNC_BYPASS_MASK;
4376 
4377   /* Configure DP clock select according to mode */
4378   Val |= MVPP2_PORT_CTRL4_DP_CLK_SEL_MASK;
4379 
4380   /* Configure QSGMII bypass according to mode */
4381   Val |= MVPP2_PORT_CTRL4_QSGMII_BYPASS_ACTIVE_MASK;
4382   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL4_REG, Val);
4383 
4384   Val = MvGop110GmacRead (Port, MVPP2_PORT_CTRL2_REG);
4385   Val |= MVPP2_PORT_CTRL2_DIS_PADING_OFFS;
4386   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL2_REG, Val);
4387 
4388   /* Configure GIG MAC to 1000Base-X mode connected to a fiber transceiver */
4389   Val = MvGop110GmacRead (Port, MVPP2_PORT_CTRL0_REG);
4390   Val |= MVPP2_PORT_CTRL0_PORTTYPE_MASK;
4391   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL0_REG, Val);
4392 
4393   /* configure AN 0x9268 */
4394   an = MVPP2_PORT_AUTO_NEG_CFG_EN_PCS_AN_MASK |
4395        MVPP2_PORT_AUTO_NEG_CFG_AN_BYPASS_EN_MASK |
4396        MVPP2_PORT_AUTO_NEG_CFG_SET_MII_SPEED_MASK  |
4397        MVPP2_PORT_AUTO_NEG_CFG_SET_GMII_SPEED_MASK |
4398        MVPP2_PORT_AUTO_NEG_CFG_ADV_PAUSE_MASK |
4399        MVPP2_PORT_AUTO_NEG_CFG_SET_FULL_DX_MASK |
4400        MVPP2_PORT_AUTO_NEG_CFG_CHOOSE_SAMPLE_TX_CONFIG_MASK;
4401   MvGop110GmacWrite (Port, MVPP2_PORT_AUTO_NEG_CFG_REG, an);
4402 }
4403 
4404 VOID
MvGop110GmacSgmiiCfg(IN PP2DXE_PORT * Port)4405 MvGop110GmacSgmiiCfg (
4406   IN PP2DXE_PORT *Port
4407   )
4408 {
4409   UINT32 Val, thresh, an;
4410 
4411   /*
4412    * Configure minimal level of the Tx FIFO before
4413    * the lower part starts to read a packet.
4414    */
4415   thresh = MV_SGMII_TX_FIFO_MIN_TH;
4416   Val = MvGop110GmacRead (Port, MVPP2_PORT_FIFO_CFG_1_REG);
4417   U32_SET_FIELD (Val, MVPP2_PORT_FIFO_CFG_1_TX_FIFO_MIN_TH_MASK,
4418     (thresh << MVPP2_PORT_FIFO_CFG_1_TX_FIFO_MIN_TH_OFFS));
4419   MvGop110GmacWrite (Port, MVPP2_PORT_FIFO_CFG_1_REG, Val);
4420 
4421   /* Disable bypass of sync module */
4422   Val = MvGop110GmacRead (Port, MVPP2_PORT_CTRL4_REG);
4423   Val |= MVPP2_PORT_CTRL4_SYNC_BYPASS_MASK;
4424 
4425   /* Configure DP clock select according to mode */
4426   Val &= ~MVPP2_PORT_CTRL4_DP_CLK_SEL_MASK;
4427 
4428   /* Configure QSGMII bypass according to mode */
4429   Val |= MVPP2_PORT_CTRL4_QSGMII_BYPASS_ACTIVE_MASK;
4430   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL4_REG, Val);
4431 
4432   Val = MvGop110GmacRead (Port, MVPP2_PORT_CTRL2_REG);
4433   Val |= MVPP2_PORT_CTRL2_DIS_PADING_OFFS;
4434   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL2_REG, Val);
4435 
4436   /* Configure GIG MAC to SGMII mode */
4437   Val = MvGop110GmacRead (Port, MVPP2_PORT_CTRL0_REG);
4438   Val &= ~MVPP2_PORT_CTRL0_PORTTYPE_MASK;
4439   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL0_REG, Val);
4440 
4441   /* Configure AN */
4442   an = MVPP2_PORT_AUTO_NEG_CFG_EN_PCS_AN_MASK |
4443        MVPP2_PORT_AUTO_NEG_CFG_AN_BYPASS_EN_MASK |
4444        MVPP2_PORT_AUTO_NEG_CFG_EN_AN_SPEED_MASK |
4445        MVPP2_PORT_AUTO_NEG_CFG_EN_FC_AN_MASK |
4446        MVPP2_PORT_AUTO_NEG_CFG_EN_FDX_AN_MASK |
4447        MVPP2_PORT_AUTO_NEG_CFG_CHOOSE_SAMPLE_TX_CONFIG_MASK;
4448   MvGop110GmacWrite (Port, MVPP2_PORT_AUTO_NEG_CFG_REG, an);
4449 }
4450 
4451 VOID
MvGop110GmacQsgmiiCfg(IN PP2DXE_PORT * Port)4452 MvGop110GmacQsgmiiCfg (
4453   IN PP2DXE_PORT *Port
4454   )
4455 {
4456   UINT32 Val, thresh, an;
4457 
4458   /*
4459    * Configure minimal level of the Tx FIFO before
4460    * the lower part starts to read a packet.
4461    */
4462   thresh = MV_SGMII_TX_FIFO_MIN_TH;
4463   Val = MvGop110GmacRead (Port, MVPP2_PORT_FIFO_CFG_1_REG);
4464   U32_SET_FIELD (
4465           Val,
4466           MVPP2_PORT_FIFO_CFG_1_TX_FIFO_MIN_TH_MASK,
4467           (thresh << MVPP2_PORT_FIFO_CFG_1_TX_FIFO_MIN_TH_OFFS)
4468         );
4469 
4470   MvGop110GmacWrite (Port, MVPP2_PORT_FIFO_CFG_1_REG, Val);
4471 
4472   /* Disable bypass of sync module */
4473   Val = MvGop110GmacRead (Port, MVPP2_PORT_CTRL4_REG);
4474   Val |= MVPP2_PORT_CTRL4_SYNC_BYPASS_MASK;
4475 
4476   /* Configure DP clock select according to mode */
4477   Val &= ~MVPP2_PORT_CTRL4_DP_CLK_SEL_MASK;
4478   Val &= ~MVPP2_PORT_CTRL4_EXT_PIN_GMII_SEL_MASK;
4479 
4480   /* Configure QSGMII bypass according to mode */
4481   Val &= ~MVPP2_PORT_CTRL4_QSGMII_BYPASS_ACTIVE_MASK;
4482   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL4_REG, Val);
4483 
4484   Val = MvGop110GmacRead (Port, MVPP2_PORT_CTRL2_REG);
4485   Val &= ~MVPP2_PORT_CTRL2_DIS_PADING_OFFS;
4486   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL2_REG, Val);
4487 
4488   /* Configure GIG MAC to SGMII mode */
4489   Val = MvGop110GmacRead (Port, MVPP2_PORT_CTRL0_REG);
4490   Val &= ~MVPP2_PORT_CTRL0_PORTTYPE_MASK;
4491   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL0_REG, Val);
4492 
4493   /* Configure AN 0xB8EC */
4494   an = MVPP2_PORT_AUTO_NEG_CFG_EN_PCS_AN_MASK |
4495        MVPP2_PORT_AUTO_NEG_CFG_AN_BYPASS_EN_MASK |
4496        MVPP2_PORT_AUTO_NEG_CFG_EN_AN_SPEED_MASK |
4497        MVPP2_PORT_AUTO_NEG_CFG_EN_FC_AN_MASK |
4498        MVPP2_PORT_AUTO_NEG_CFG_EN_FDX_AN_MASK |
4499        MVPP2_PORT_AUTO_NEG_CFG_CHOOSE_SAMPLE_TX_CONFIG_MASK;
4500   MvGop110GmacWrite (Port, MVPP2_PORT_AUTO_NEG_CFG_REG, an);
4501 }
4502 
4503 INT32
Mvpp2SmiPhyAddrCfg(IN PP2DXE_PORT * Port,IN INT32 PortId,IN INT32 Addr)4504 Mvpp2SmiPhyAddrCfg (
4505   IN PP2DXE_PORT *Port,
4506   IN INT32 PortId,
4507   IN INT32 Addr
4508   )
4509 {
4510   Mvpp2SmiWrite (Port->Priv, MV_SMI_PHY_ADDRESS_REG(PortId), Addr);
4511 
4512   return 0;
4513 }
4514 
4515 BOOLEAN
MvGop110PortIsLinkUp(IN PP2DXE_PORT * Port)4516 MvGop110PortIsLinkUp (
4517   IN PP2DXE_PORT *Port
4518   )
4519 {
4520   switch (Port->PhyInterface) {
4521   case MV_MODE_RGMII:
4522   case MV_MODE_SGMII:
4523   case MV_MODE_QSGMII:
4524     return MvGop110GmacLinkStatusGet (Port);
4525   case MV_MODE_XAUI:
4526   case MV_MODE_RXAUI:
4527     return FALSE;
4528   default:
4529     return FALSE;
4530   }
4531 }
4532 
4533 /* Get MAC link status */
4534 BOOLEAN
MvGop110GmacLinkStatusGet(IN PP2DXE_PORT * Port)4535 MvGop110GmacLinkStatusGet (
4536   IN PP2DXE_PORT *Port
4537   )
4538 {
4539   UINT32 RegAddr;
4540   UINT32 Val;
4541 
4542   RegAddr = MVPP2_PORT_STATUS0_REG;
4543 
4544   Val = MvGop110GmacRead (Port, RegAddr);
4545 
4546   return (Val & 1) ? TRUE : FALSE;
4547 }
4548 
4549 VOID
MvGop110PortDisable(IN PP2DXE_PORT * Port)4550 MvGop110PortDisable (
4551   IN PP2DXE_PORT *Port
4552   )
4553 {
4554   switch (Port->PhyInterface) {
4555   case MV_MODE_RGMII:
4556   case MV_MODE_SGMII:
4557   case MV_MODE_QSGMII:
4558     MvGop110GmacPortDisable (Port);
4559     break;
4560   default:
4561     return;
4562   }
4563 }
4564 
4565 VOID
MvGop110PortEnable(IN PP2DXE_PORT * Port)4566 MvGop110PortEnable (
4567   IN PP2DXE_PORT *Port
4568   )
4569 {
4570   switch (Port->PhyInterface) {
4571   case MV_MODE_RGMII:
4572   case MV_MODE_SGMII:
4573   case MV_MODE_QSGMII:
4574     MvGop110GmacPortEnable (Port);
4575     break;
4576   default:
4577     return;
4578   }
4579 }
4580 
4581 /* Enable Port and MIB counters */
4582 VOID
MvGop110GmacPortEnable(IN PP2DXE_PORT * Port)4583 MvGop110GmacPortEnable (
4584   IN PP2DXE_PORT *Port
4585   )
4586 {
4587   UINT32 RegVal;
4588 
4589   RegVal = MvGop110GmacRead (Port, MVPP2_PORT_CTRL0_REG);
4590   RegVal |= MVPP2_PORT_CTRL0_PORTEN_MASK;
4591   RegVal |= MVPP2_PORT_CTRL0_COUNT_EN_MASK;
4592 
4593   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL0_REG, RegVal);
4594 }
4595 
4596 /* Disable Port */
4597 VOID
MvGop110GmacPortDisable(IN PP2DXE_PORT * Port)4598 MvGop110GmacPortDisable (
4599   IN PP2DXE_PORT *Port
4600   )
4601 {
4602   UINT32 RegVal;
4603 
4604   /* Mask all Ports interrupts */
4605   MvGop110GmacPortLinkEventMask (Port);
4606 
4607   RegVal = MvGop110GmacRead (Port, MVPP2_PORT_CTRL0_REG);
4608   RegVal &= ~MVPP2_PORT_CTRL0_PORTEN_MASK;
4609 
4610   MvGop110GmacWrite (Port, MVPP2_PORT_CTRL0_REG, RegVal);
4611 }
4612 
4613 VOID
MvGop110GmacPortLinkEventMask(IN PP2DXE_PORT * Port)4614 MvGop110GmacPortLinkEventMask (
4615   IN PP2DXE_PORT *Port
4616   )
4617 {
4618   UINT32 RegVal;
4619 
4620   RegVal = MvGop110GmacRead (Port, MV_GMAC_INTERRUPT_SUM_MASK_REG);
4621   RegVal &= ~MV_GMAC_INTERRUPT_SUM_CAUSE_LINK_CHANGE_MASK;
4622   MvGop110GmacWrite (Port, MV_GMAC_INTERRUPT_SUM_MASK_REG, RegVal);
4623 }
4624 
4625 INT32
MvGop110PortEventsMask(IN PP2DXE_PORT * Port)4626 MvGop110PortEventsMask (
4627   IN PP2DXE_PORT *Port
4628   )
4629 {
4630 
4631   switch (Port->PhyInterface) {
4632   case MV_MODE_RGMII:
4633   case MV_MODE_SGMII:
4634   case MV_MODE_QSGMII:
4635     MvGop110GmacPortLinkEventMask (Port);
4636     break;
4637   default:
4638     return -1;
4639   }
4640 
4641   return 0;
4642 }
4643 
4644 INT32
MvGop110FlCfg(IN PP2DXE_PORT * Port)4645 MvGop110FlCfg (
4646   IN PP2DXE_PORT *Port
4647   )
4648 {
4649   switch (Port->PhyInterface) {
4650   case MV_MODE_RGMII:
4651   case MV_MODE_SGMII:
4652   case MV_MODE_QSGMII:
4653     /* Disable AN */
4654     MvGop110SpeedDuplexSet (Port, Port->Speed, MV_PORT_DUPLEX_FULL);
4655     break;
4656   case MV_MODE_XAUI:
4657   case MV_MODE_RXAUI:
4658     return 0;
4659   default:
4660     return -1;
4661   }
4662 
4663   return 0;
4664 }
4665 
4666 /* Set Port Speed and Duplex */
4667 INT32
MvGop110SpeedDuplexSet(IN PP2DXE_PORT * Port,IN INT32 Speed,IN enum MvPortDuplex Duplex)4668 MvGop110SpeedDuplexSet (
4669   IN PP2DXE_PORT *Port,
4670   IN INT32 Speed,
4671   IN enum MvPortDuplex Duplex
4672   )
4673 {
4674   switch (Port->PhyInterface) {
4675   case MV_MODE_RGMII:
4676   case MV_MODE_SGMII:
4677   case MV_MODE_QSGMII:
4678     MvGop110GmacSpeedDuplexSet (Port, Speed, Duplex);
4679     break;
4680   case MV_MODE_XAUI:
4681   case MV_MODE_RXAUI:
4682     break;
4683   default:
4684     return -1;
4685   }
4686 
4687   return 0;
4688 }
4689 
4690 /*
4691  * Sets Port Speed to Auto Negotiation / 1000 / 100 / 10 Mbps.
4692  * Sets Port Duplex to Auto Negotiation / Full / Half Duplex.
4693  */
4694 INT32
MvGop110GmacSpeedDuplexSet(IN PP2DXE_PORT * Port,IN INT32 Speed,IN enum MvPortDuplex Duplex)4695 MvGop110GmacSpeedDuplexSet (
4696   IN PP2DXE_PORT *Port,
4697   IN INT32 Speed,
4698   IN enum MvPortDuplex Duplex
4699   )
4700 {
4701   UINT32 RegVal;
4702 
4703   RegVal = Mvpp2GmacRead (Port, MVPP2_PORT_AUTO_NEG_CFG_REG);
4704 
4705   switch (Speed) {
4706   case MV_PORT_SPEED_2500:
4707   case MV_PORT_SPEED_1000:
4708     RegVal &= ~MVPP2_PORT_AUTO_NEG_CFG_EN_AN_SPEED_MASK;
4709     RegVal |= MVPP2_PORT_AUTO_NEG_CFG_SET_GMII_SPEED_MASK;
4710     /* The 100/10 bit doesn't matter in this case */
4711     break;
4712   case MV_PORT_SPEED_100:
4713     RegVal &= ~MVPP2_PORT_AUTO_NEG_CFG_EN_AN_SPEED_MASK;
4714     RegVal &= ~MVPP2_PORT_AUTO_NEG_CFG_SET_GMII_SPEED_MASK;
4715     RegVal |= MVPP2_PORT_AUTO_NEG_CFG_SET_MII_SPEED_MASK;
4716     break;
4717   case MV_PORT_SPEED_10:
4718     RegVal &= ~MVPP2_PORT_AUTO_NEG_CFG_EN_AN_SPEED_MASK;
4719     RegVal &= ~MVPP2_PORT_AUTO_NEG_CFG_SET_GMII_SPEED_MASK;
4720     RegVal &= ~MVPP2_PORT_AUTO_NEG_CFG_SET_MII_SPEED_MASK;
4721     break;
4722   default:
4723     return MVPP2_EINVAL;
4724   }
4725 
4726   switch (Duplex) {
4727   case MV_PORT_DUPLEX_AN:
4728     RegVal  |= MVPP2_PORT_AUTO_NEG_CFG_EN_FDX_AN_MASK;
4729     /* The other bits don't matter in this case */
4730     break;
4731   case MV_PORT_DUPLEX_HALF:
4732     RegVal &= ~MVPP2_PORT_AUTO_NEG_CFG_EN_FDX_AN_MASK;
4733     RegVal &= ~MVPP2_PORT_AUTO_NEG_CFG_SET_FULL_DX_MASK;
4734     break;
4735   case MV_PORT_DUPLEX_FULL:
4736     RegVal &= ~MVPP2_PORT_AUTO_NEG_CFG_EN_FDX_AN_MASK;
4737     RegVal |= MVPP2_PORT_AUTO_NEG_CFG_SET_FULL_DX_MASK;
4738     break;
4739   default:
4740     return MVPP2_EINVAL;
4741   }
4742 
4743   Mvpp2GmacWrite (Port, MVPP2_PORT_AUTO_NEG_CFG_REG, RegVal);
4744 
4745   return 0;
4746 }
4747 
4748 VOID
Mvpp2AxiConfig(IN MVPP2_SHARED * Priv)4749 Mvpp2AxiConfig (
4750   IN MVPP2_SHARED *Priv
4751   )
4752 {
4753   /* Config AXI Read&Write Normal and Soop mode  */
4754   Mvpp2Write (Priv, MVPP22_AXI_BM_WR_ATTR_REG, MVPP22_AXI_ATTR_SNOOP_CNTRL_BIT);
4755   Mvpp2Write (Priv, MVPP22_AXI_BM_RD_ATTR_REG, MVPP22_AXI_ATTR_SNOOP_CNTRL_BIT);
4756   Mvpp2Write (Priv, MVPP22_AXI_AGGRQ_DESCR_RD_ATTR_REG, MVPP22_AXI_ATTR_SNOOP_CNTRL_BIT);
4757   Mvpp2Write (Priv, MVPP22_AXI_TXQ_DESCR_WR_ATTR_REG, MVPP22_AXI_ATTR_SNOOP_CNTRL_BIT);
4758   Mvpp2Write (Priv, MVPP22_AXI_TXQ_DESCR_RD_ATTR_REG, MVPP22_AXI_ATTR_SNOOP_CNTRL_BIT);
4759   Mvpp2Write (Priv, MVPP22_AXI_RXQ_DESCR_WR_ATTR_REG, MVPP22_AXI_ATTR_SNOOP_CNTRL_BIT);
4760   Mvpp2Write (Priv, MVPP22_AXI_RX_DATA_WR_ATTR_REG, MVPP22_AXI_ATTR_SNOOP_CNTRL_BIT);
4761   Mvpp2Write (Priv, MVPP22_AXI_TX_DATA_RD_ATTR_REG, MVPP22_AXI_ATTR_SNOOP_CNTRL_BIT);
4762 }
4763 
4764 /* Cleanup Tx Ports */
4765 VOID
Mvpp2TxpClean(IN PP2DXE_PORT * Port,IN INT32 Txp,IN MVPP2_TX_QUEUE * Txq)4766 Mvpp2TxpClean (
4767   IN PP2DXE_PORT *Port,
4768   IN INT32 Txp,
4769   IN MVPP2_TX_QUEUE *Txq
4770   )
4771 {
4772   INT32 Delay, Pending;
4773   UINT32 RegVal;
4774 
4775   Mvpp2Write (Port->Priv, MVPP2_TXQ_NUM_REG, Txq->Id);
4776   RegVal = Mvpp2Read (Port->Priv, MVPP2_TXQ_PREF_BUF_REG);
4777   RegVal |= MVPP2_TXQ_DRAIN_EN_MASK;
4778   Mvpp2Write (Port->Priv, MVPP2_TXQ_PREF_BUF_REG, RegVal);
4779 
4780   /*
4781    * The Queue has been stopped so wait for all packets
4782    * to be transmitted.
4783    */
4784   Delay = 0;
4785   do {
4786     if (Delay >= MVPP2_TX_PENDING_TIMEOUT_MSEC) {
4787       Mvpp2Printf ("Port %d: cleaning Queue %d timed out\n", Port->Id, Txq->LogId);
4788       break;
4789     }
4790     Mvpp2Mdelay (1);
4791     Delay++;
4792 
4793     Pending = Mvpp2TxqPendDescNumGet (Port, Txq);
4794   } while (Pending);
4795 
4796   RegVal &= ~MVPP2_TXQ_DRAIN_EN_MASK;
4797   Mvpp2Write (Port->Priv, MVPP2_TXQ_PREF_BUF_REG, RegVal);
4798 }
4799 
4800 /* Cleanup all Tx Queues */
4801 VOID
Mvpp2CleanupTxqs(IN PP2DXE_PORT * Port)4802 Mvpp2CleanupTxqs (
4803   IN PP2DXE_PORT *Port
4804   )
4805 {
4806   MVPP2_TX_QUEUE *Txq;
4807   INT32 Txp, Queue;
4808   UINT32 RegVal;
4809 
4810   RegVal = Mvpp2Read (Port->Priv, MVPP2_TX_PORT_FLUSH_REG);
4811 
4812   /* Reset Tx Ports and delete Tx Queues */
4813   for (Txp = 0; Txp < Port->TxpNum; Txp++) {
4814     RegVal |= MVPP2_TX_PORT_FLUSH_MASK (Port->Id);
4815     Mvpp2Write (Port->Priv, MVPP2_TX_PORT_FLUSH_REG, RegVal);
4816 
4817     for (Queue = 0; Queue < TxqNumber; Queue++) {
4818       Txq = &Port->Txqs[Txp * TxqNumber + Queue];
4819       Mvpp2TxpClean (Port, Txp, Txq);
4820       Mvpp2TxqHwDeinit (Port, Txq);
4821     }
4822 
4823     RegVal &= ~MVPP2_TX_PORT_FLUSH_MASK (Port->Id);
4824     Mvpp2Write (Port->Priv, MVPP2_TX_PORT_FLUSH_REG, RegVal);
4825   }
4826 }
4827 
4828 /* Cleanup all Rx Queues */
4829 VOID
Mvpp2CleanupRxqs(IN PP2DXE_PORT * Port)4830 Mvpp2CleanupRxqs (
4831   IN PP2DXE_PORT *Port
4832   )
4833 {
4834   INT32 Queue;
4835 
4836   for (Queue = 0; Queue < RxqNumber; Queue++) {
4837     Mvpp2RxqHwDeinit (Port, &Port->Rxqs[Queue]);
4838   }
4839 }
4840