]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/npe/IxEthDBVlan.c
doc: SPI: Add qspi test details on AM43xx
[karo-tx-uboot.git] / drivers / net / npe / IxEthDBVlan.c
1 /**
2  * @file IxEthDBVlan.c
3  *
4  * @brief Implementation of the VLAN API
5  * 
6  * @par
7  * IXP400 SW Release version 2.0
8  * 
9  * -- Copyright Notice --
10  * 
11  * @par
12  * Copyright 2001-2005, Intel Corporation.
13  * All rights reserved.
14  * 
15  * @par
16  * SPDX-License-Identifier:     BSD-3-Clause
17  * @par
18  * -- End of Copyright Notice --
19  */
20
21 #include "IxEthDB.h"
22 #include "IxEthDB_p.h"
23
24 /* forward prototypes */
25 IX_ETH_DB_PUBLIC
26 IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex);
27 IX_ETH_DB_PUBLIC
28 IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet);
29
30 /* contants used by various functions as "action" parameter */
31 #define ADD_VLAN    (0x1)
32 #define REMOVE_VLAN (0x2)
33
34 /**
35  * @brief adds or removes a VLAN from a VLAN set
36  *
37  * @param vlanID VLAN ID to add or remove
38  * @param table VLAN set to add into or remove from
39  * @param action ADD_VLAN or REMOVE_VLAN
40  * 
41  * @internal
42  */
43 IX_ETH_DB_PRIVATE
44 void ixEthDBLocalVlanMembershipChange(UINT32 vlanID, IxEthDBVlanSet table, UINT32 action)
45 {
46     UINT32 setOffset;
47     
48     /* add/remove VID to membership table */
49     setOffset = VLAN_SET_OFFSET(vlanID); /* we need 9 bits to index the 512 byte membership array */
50
51     if (action == ADD_VLAN)
52     {
53         table[setOffset] |= 1 << VLAN_SET_MASK(vlanID);
54     }
55     else if (action == REMOVE_VLAN)
56     {
57         table[setOffset] &= ~(1 << VLAN_SET_MASK(vlanID));
58     }
59 }
60
61 /**
62  * @brief updates a set of 8 VLANs in an NPE
63  *
64  * @param portID ID of the port
65  * @param setOffset offset of the 8 VLANs
66  *
67  * This function updates the VLAN membership table
68  * and Transmit Tagging Info table for 8 consecutive
69  * VLAN IDs indexed by setOffset.
70  *
71  * For example, a setOffset of 0 indexes VLAN IDs 0
72  * through 7, 1 indexes VLAN IDs 8 through 9 etc.
73  *
74  * @return IX_ETH_DB_SUCCESS if the operation completed
75  * successfully or an appropriate error message otherwise
76  *
77  * @internal
78  */
79 IX_ETH_DB_PRIVATE
80 IxEthDBStatus ixEthDBVlanTableEntryUpdate(IxEthDBPortId portID, UINT32 setOffset)
81 {
82     PortInfo *portInfo = &ixEthDBPortInfo[portID];
83     IxNpeMhMessage message;
84     IX_STATUS result;
85         
86     FILL_SETPORTVLANTABLEENTRY_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 
87         2 * setOffset, 
88         portInfo->vlanMembership[setOffset], 
89         portInfo->transmitTaggingInfo[setOffset]);
90     
91     IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
92     
93     return result;
94 }
95
96 /**
97  * @brief updates a VLAN range in an NPE
98  *
99  * @param portID ID of the port
100  *
101  * This function is similar to @ref ixEthDBVlanTableEntryUpdate
102  * except that it can update more than one VLAN set (up to
103  * the entire VLAN membership and TTI tables if the offset is 0
104  * and length is sizeof (IxEthDBVlanSet) (512 bytes).
105  *
106  * Updating the NPE via this method is slower as it requires
107  * a memory copy from SDRAM, hence it is recommended that the
108  * ixEthDBVlanTableEntryUpdate function is used where possible.
109  *
110  * @return IX_ETH_DB_SUCCESS if the operation completed
111  * successfully or an appropriate error message otherwise
112  *
113  * @internal
114  */
115 IX_ETH_DB_PRIVATE
116 IxEthDBStatus ixEthDBVlanTableRangeUpdate(IxEthDBPortId portID)
117 {
118     PortInfo *portInfo    = &ixEthDBPortInfo[portID];
119     UINT8 *vlanUpdateZone = (UINT8 *) portInfo->updateMethod.vlanUpdateZone;
120     IxNpeMhMessage message;
121     UINT32 setIndex;
122     IX_STATUS result;
123
124     /* copy membership info and transmit tagging into into exchange area */
125     for (setIndex = 0 ; setIndex < sizeof (portInfo->vlanMembership) ; setIndex++)
126     {
127         /* membership and TTI data are interleaved */
128         vlanUpdateZone[setIndex * 2]     = portInfo->vlanMembership[setIndex];
129         vlanUpdateZone[setIndex * 2 + 1] = portInfo->transmitTaggingInfo[setIndex];
130     }
131
132     IX_OSAL_CACHE_FLUSH(vlanUpdateZone, FULL_VLAN_BYTE_SIZE);
133     
134     /* build NPE message */
135     FILL_SETPORTVLANTABLERANGE_MSG(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 0, 0, 
136         IX_OSAL_MMU_VIRT_TO_PHYS(vlanUpdateZone));
137
138     /* send message */    
139     IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
140
141     return result;
142 }
143
144 /**
145  * @brief adds or removes a VLAN from a port's VLAN membership table
146  * or Transmit Tagging Information table
147  *
148  * @param portID ID of the port
149  * @param vlanID VLAN ID to add or remove
150  * @param table to add or remove from
151  * @param action ADD_VLAN or REMOVE_VLAN
152  *
153  * @return IX_ETH_DB_SUCCESS if the operation completed
154  * successfully or an appropriate error message otherwise
155  *
156  * @internal
157  */
158 IX_ETH_DB_PRIVATE
159 IxEthDBStatus ixEthDBPortVlanMembershipChange(IxEthDBPortId portID, IxEthDBVlanId vlanID, IxEthDBVlanSet table, UINT32 action)
160 {
161     /* change VLAN in local membership table */
162     ixEthDBLocalVlanMembershipChange(vlanID, table, action);
163     
164     /* send updated entry to NPE */
165     return ixEthDBVlanTableEntryUpdate(portID, VLAN_SET_OFFSET(vlanID));
166 }
167
168 /**
169  * @brief sets the default port VLAN tag (the lower 3 bytes are the PVID)
170  *
171  * @param portID ID of the port
172  * @param vlanTag port VLAN tag (802.1Q tag)
173  * 
174  * Note that this function is documented in the main component
175  * header file, IxEthDB.h.
176  *
177  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
178  * or an appropriate error message otherwise
179  */
180 IX_ETH_DB_PUBLIC 
181 IxEthDBStatus ixEthDBPortVlanTagSet(IxEthDBPortId portID, IxEthDBVlanTag vlanTag)
182 {
183     IxNpeMhMessage message;
184     IX_STATUS result;
185     
186     IX_ETH_DB_CHECK_PORT(portID);
187     
188     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
189  
190     IX_ETH_DB_CHECK_VLAN_TAG(vlanTag);
191     
192     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
193         
194     /* add VLAN ID to local membership table */
195     ixEthDBPortVlanMembershipChange(portID, 
196         vlanTag & IX_ETH_DB_802_1Q_VLAN_MASK, 
197         ixEthDBPortInfo[portID].vlanMembership, 
198         ADD_VLAN);
199         
200     /* set tag in portInfo */
201     ixEthDBPortInfo[portID].vlanTag = vlanTag;
202     
203     /* build VLAN_SetDefaultRxVID message */
204     FILL_SETDEFAULTRXVID_MSG(message, 
205         IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), 
206         IX_IEEE802_1Q_VLAN_TPID, 
207         vlanTag);
208     
209     IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
210     
211     return result;
212 }
213
214 /**
215  * @brief retrieves the default port VLAN tag (the lower 3 bytes are the PVID)
216  *
217  * @param portID ID of the port
218  * @param vlanTag address to write the port VLAN tag (802.1Q tag) into
219  * 
220  * Note that this function is documented in the main component
221  * header file, IxEthDB.h.
222  *
223  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
224  * or an appropriate error message otherwise
225  */
226 IX_ETH_DB_PUBLIC 
227 IxEthDBStatus ixEthDBPortVlanTagGet(IxEthDBPortId portID, IxEthDBVlanTag *vlanTag)
228 {
229     IX_ETH_DB_CHECK_PORT(portID);
230     
231     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
232     
233     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
234     
235     IX_ETH_DB_CHECK_REFERENCE(vlanTag);
236     
237     *vlanTag = ixEthDBPortInfo[portID].vlanTag;
238     
239     return IX_ETH_DB_SUCCESS;
240 }
241
242 /**
243  * @brief sets the VLAN tag (the lower 3 bytes are the PVID) of a 
244  * database filtering record
245  *
246  * @param portID ID of the port
247  * @param vlanTag VLAN tag (802.1Q tag)
248  * 
249  * Important: filtering records are automatically converted to 
250  * IX_ETH_DB_FILTERING_VLAN record when added a VLAN tag.
251  *
252  * Note that this function is documented in the main component
253  * header file, IxEthDB.h.
254  *
255  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
256  * or an appropriate error message otherwise
257  */
258 IX_ETH_DB_PUBLIC 
259 IxEthDBStatus ixEthDBVlanTagSet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag vlanTag)
260 {
261     HashNode *searchResult;
262     MacDescriptor *descriptor;
263     
264     IX_ETH_DB_CHECK_REFERENCE(macAddr);
265     
266     IX_ETH_DB_CHECK_VLAN_TAG(vlanTag);
267     
268     searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_ALL_FILTERING_RECORDS);
269     
270     if (searchResult == NULL)
271     {
272         return IX_ETH_DB_NO_SUCH_ADDR;
273     }
274     
275     descriptor = (MacDescriptor *) searchResult->data;
276     
277     /* set record type to VLAN if not already set */
278     descriptor->type = IX_ETH_DB_FILTERING_VLAN_RECORD;
279     
280     /* add vlan tag */
281     descriptor->recordData.filteringVlanData.ieee802_1qTag = vlanTag;
282     
283     /* transaction completed */
284     ixEthDBReleaseHashNode(searchResult);
285     
286     return IX_ETH_DB_SUCCESS;
287 }
288
289 /**
290  * @brief retrieves the VLAN tag (the lower 3 bytes are the PVID) from a 
291  * database VLAN filtering record
292  *
293  * @param portID ID of the port
294  * @param vlanTag address to write the VLAN tag (802.1Q tag) into
295  * 
296  * Note that this function is documented in the main component
297  * header file, IxEthDB.h.
298  *
299  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
300  * or an appropriate error message otherwise
301  */
302 IX_ETH_DB_PUBLIC 
303 IxEthDBStatus ixEthDBVlanTagGet(IxEthDBMacAddr *macAddr, IxEthDBVlanTag *vlanTag)
304 {
305     HashNode *searchResult;
306     MacDescriptor *descriptor;
307     
308     IX_ETH_DB_CHECK_REFERENCE(macAddr);
309     
310     IX_ETH_DB_CHECK_REFERENCE(vlanTag);
311     
312     searchResult = ixEthDBSearch(macAddr, IX_ETH_DB_FILTERING_VLAN_RECORD);
313     
314     if (searchResult == NULL)
315     {
316         return IX_ETH_DB_NO_SUCH_ADDR;
317     }
318     
319     descriptor = (MacDescriptor *) searchResult->data;
320         
321     /* get vlan tag */
322     *vlanTag = descriptor->recordData.filteringVlanData.ieee802_1qTag;
323     
324     /* transaction completed */
325     ixEthDBReleaseHashNode(searchResult);
326     
327     return IX_ETH_DB_SUCCESS;
328 }
329
330 /**
331  * @brief adds a VLAN to a port's VLAN membership table
332  *
333  * @param portID ID of the port
334  * @param vlanID VLAN ID to add
335  * 
336  * Note that this function is documented in the main component
337  * header file, IxEthDB.h.
338  *
339  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
340  * or an appropriate error message otherwise
341  */
342 IX_ETH_DB_PUBLIC 
343 IxEthDBStatus ixEthDBPortVlanMembershipAdd(IxEthDBPortId portID, IxEthDBVlanId vlanID)
344 {
345     IX_ETH_DB_CHECK_PORT(portID);
346
347     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
348
349     IX_ETH_DB_CHECK_VLAN_ID(vlanID);
350
351     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
352
353     return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN);
354 }
355
356 /**
357  * @brief removes a VLAN from a port's VLAN membership table
358  *
359  * @param portID ID of the port
360  * @param vlanID VLAN ID to remove
361  *
362  * Note that this function is documented in the main component
363  * header file, IxEthDB.h.
364  *
365  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
366  * or an appropriate error message otherwise
367  */
368 IX_ETH_DB_PUBLIC 
369 IxEthDBStatus ixEthDBPortVlanMembershipRemove(IxEthDBPortId portID, IxEthDBVlanId vlanID)
370 {
371     IX_ETH_DB_CHECK_PORT(portID);
372
373     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
374
375     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
376
377     IX_ETH_DB_CHECK_VLAN_ID(vlanID);
378
379     /* for safety isolate only the VLAN ID in the tag (the lower 12 bits) */
380     vlanID = vlanID & IX_ETH_DB_802_1Q_VLAN_MASK;
381     
382     /* check we're not asked to remove the default port VID */
383     if (vlanID == IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag))
384     {
385         return IX_ETH_DB_NO_PERMISSION;
386     }
387     
388     return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN);
389 }
390
391 /**
392  * @brief adds or removes a VLAN range from a port's 
393  * VLAN membership table or TTI table
394  *
395  * @param portID ID of the port
396  * @param vlanIDMin start of the VLAN range
397  * @param vlanIDMax end of the VLAN range
398  * @param table VLAN set to add or remove from
399  * @param action ADD_VLAN or REMOVE_VLAN
400  *
401  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
402  * or an appropriate error message otherwise
403  *
404  * @internal
405  */
406 IX_ETH_DB_PRIVATE
407 IxEthDBStatus ixEthDBPortVlanMembershipRangeChange(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, IxEthDBVlanSet table, UINT32 action)
408 {
409     UINT32 setOffsetMin, setOffsetMax;
410     
411     IX_ETH_DB_CHECK_PORT(portID);
412     
413     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
414     
415     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
416     
417     IX_ETH_DB_CHECK_VLAN_ID(vlanIDMin);
418     
419     IX_ETH_DB_CHECK_VLAN_ID(vlanIDMax);
420     
421     /* for safety isolate only the VLAN ID in the tags (the lower 12 bits) */
422     vlanIDMin = vlanIDMin & IX_ETH_DB_802_1Q_VLAN_MASK;
423     vlanIDMax = vlanIDMax & IX_ETH_DB_802_1Q_VLAN_MASK;
424     
425     /* is this a range? */
426     if (vlanIDMax < vlanIDMin)
427     {
428         return IX_ETH_DB_INVALID_VLAN;
429     }
430     
431     /* check that we're not specifically asked to remove the default port VID */
432     if (action == REMOVE_VLAN && vlanIDMax == vlanIDMin && IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag) == vlanIDMin)
433     {
434         return IX_ETH_DB_NO_PERMISSION;
435     }
436     
437     /* compute set offsets */
438     setOffsetMin = VLAN_SET_OFFSET(vlanIDMin);
439     setOffsetMax = VLAN_SET_OFFSET(vlanIDMax);
440
441     /* change VLAN range */
442     for (; vlanIDMin <= vlanIDMax ; vlanIDMin++)
443     {
444         /* change vlan in local membership table */
445         ixEthDBLocalVlanMembershipChange(vlanIDMin, table, action);
446     }
447
448     /* if the range is within one set (max 8 VLANs in one table byte) we can just update that entry in the NPE */
449     if (setOffsetMin == setOffsetMax)
450     {
451         /* send updated entry to NPE */
452         return ixEthDBVlanTableEntryUpdate(portID, setOffsetMin);
453     }
454     else
455     {
456         /* update a zone of the membership/transmit tag info table */
457         return ixEthDBVlanTableRangeUpdate(portID);
458     }
459 }
460
461 /**
462  * @brief adds a VLAN range to a port's VLAN membership table
463  *
464  * @param portID ID of the port
465  * @param vlanIDMin start of the VLAN range
466  * @param vlanIDMax end of the VLAN range
467  * 
468  * Note that this function is documented in the main component
469  * header file, IxEthDB.h.
470  *
471  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
472  * or an appropriate error message otherwise
473  */
474 IX_ETH_DB_PUBLIC 
475 IxEthDBStatus ixEthDBPortVlanMembershipRangeAdd(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax)
476 {
477     IX_ETH_DB_CHECK_PORT(portID);
478
479     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
480
481     return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, ADD_VLAN);
482 }
483
484 /**
485  * @brief removes a VLAN range from a port's VLAN membership table
486  *
487  * @param portID ID of the port
488  * @param vlanIDMin start of the VLAN range
489  * @param vlanIDMax end of the VLAN range
490  *
491  * Note that this function is documented in the main component
492  * header file, IxEthDB.h.
493  *
494  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
495  * or an appropriate error message otherwise
496  */
497 IX_ETH_DB_PUBLIC 
498 IxEthDBStatus ixEthDBPortVlanMembershipRangeRemove(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax)
499 {
500     IX_ETH_DB_CHECK_PORT(portID);
501
502     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
503
504     return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].vlanMembership, REMOVE_VLAN);
505 }
506
507 /**
508  * @brief sets a port's VLAN membership table or TTI table and
509  * updates the NPE VLAN configuration
510  *
511  * @param portID ID of the port
512  * @param portVlanTable port VLAN table to set
513  * @param vlanSet new set contents
514  *
515  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
516  * or an appropriate error message otherwise
517  *
518  * @internal
519  */
520 IX_ETH_DB_PUBLIC
521 IxEthDBStatus ixEthDBPortVlanTableSet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet)
522 {
523     IX_ETH_DB_CHECK_PORT(portID);
524     
525     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
526     
527     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
528     
529     IX_ETH_DB_CHECK_REFERENCE(vlanSet);
530
531     memcpy(portVlanTable, vlanSet, sizeof (IxEthDBVlanSet));
532     
533     return ixEthDBVlanTableRangeUpdate(portID);
534 }
535
536 /**
537  * @brief retireves a port's VLAN membership table or TTI table
538  *
539  * @param portID ID of the port
540  * @param portVlanTable port VLAN table to retrieve
541  * @param vlanSet address to 
542  *
543  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
544  * or an appropriate error message otherwise
545  *
546  * @internal
547  */
548 IX_ETH_DB_PUBLIC
549 IxEthDBStatus ixEthDBVlanTableGet(IxEthDBPortId portID, IxEthDBVlanSet portVlanTable, IxEthDBVlanSet vlanSet)
550 {
551     IX_ETH_DB_CHECK_PORT(portID);
552     
553     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
554     
555     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
556     
557     IX_ETH_DB_CHECK_REFERENCE(vlanSet);
558     
559     memcpy(vlanSet, portVlanTable, sizeof (IxEthDBVlanSet));
560     
561     return IX_ETH_DB_SUCCESS;
562 }
563
564 /**
565  * @brief sets a port's VLAN membership table
566  *
567  * @param portID ID of the port
568  * @param vlanSet new VLAN membership table
569  *
570  * Note that this function is documented in the main component
571  * header file, IxEthDB.h.
572  *
573  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
574  * or an appropriate error message otherwise
575  */
576 IX_ETH_DB_PUBLIC 
577 IxEthDBStatus ixEthDBPortVlanMembershipSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
578 {
579     IxEthDBVlanId vlanID;
580
581     IX_ETH_DB_CHECK_PORT(portID);
582     
583     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
584
585     IX_ETH_DB_CHECK_REFERENCE(vlanSet);
586
587     /* set the bit corresponding to the PVID just in case */
588     vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag);
589     vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID);
590     
591     return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet);
592 }
593
594 /**
595  * @brief retrieves a port's VLAN membership table
596  *
597  * @param portID ID of the port
598  * @param vlanSet location to store the port's VLAN membership table
599  *
600  * Note that this function is documented in the main component
601  * header file, IxEthDB.h.
602  *
603  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
604  * or an appropriate error message otherwise
605  */
606 IX_ETH_DB_PUBLIC 
607 IxEthDBStatus ixEthDBPortVlanMembershipGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
608 {
609     IX_ETH_DB_CHECK_PORT(portID);
610     
611     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
612     
613     return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].vlanMembership, vlanSet);
614 }
615
616 /**
617  * @brief enables or disables Egress tagging for one VLAN ID
618  *
619  * @param portID ID of the port
620  * @param vlanID VLAN ID to enable or disable Egress tagging on
621  * @param enabled true to enable and false to disable tagging
622  *
623  * Note that this function is documented in the main component
624  * header file, IxEthDB.h.
625  *
626  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
627  * or an appropriate error message otherwise
628  */
629 IX_ETH_DB_PUBLIC 
630 IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL enabled)
631 {
632     IX_ETH_DB_CHECK_PORT(portID);
633     
634     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
635
636     IX_ETH_DB_CHECK_VLAN_ID(vlanID);
637
638     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
639
640     return ixEthDBPortVlanMembershipChange(portID, vlanID, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN);
641 }
642
643 /**
644  * @brief retrieves the Egress tagging status for one VLAN ID
645  *
646  * @param portID ID of the port
647  * @param vlanID VLAN ID to retrieve the tagging status for
648  * @param enabled location to store the tagging status
649  * (true - tagging enabled, false - tagging disabled)
650  *
651  * Note that this function is documented in the main component
652  * header file, IxEthDB.h.
653  *
654  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
655  * or an appropriate error message otherwise
656  */
657 IX_ETH_DB_PUBLIC 
658 IxEthDBStatus ixEthDBEgressVlanEntryTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanId vlanID, BOOL *enabled)
659 {
660     IX_ETH_DB_CHECK_PORT(portID);
661     
662     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
663     
664     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
665     
666     IX_ETH_DB_CHECK_REFERENCE(enabled);
667
668     IX_ETH_DB_CHECK_VLAN_ID(vlanID);
669     
670     *enabled = ((ixEthDBPortInfo[portID].transmitTaggingInfo[VLAN_SET_OFFSET(vlanID)] & (1 << VLAN_SET_MASK(vlanID))) != 0);
671     
672     return IX_ETH_DB_SUCCESS;
673 }
674
675 /**
676  * @brief enables or disables Egress VLAN tagging for a VLAN range
677  *
678  * @param portID ID of the port
679  * @param vlanIDMin start of VLAN range
680  * @param vlanIDMax end of VLAN range
681  * @param enabled true to enable or false to disable VLAN tagging
682  *
683  * Note that this function is documented in the main component
684  * header file, IxEthDB.h.
685  *
686  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
687  * or an appropriate error message otherwise
688  */
689 IX_ETH_DB_PUBLIC 
690 IxEthDBStatus ixEthDBEgressVlanRangeTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanId vlanIDMin, IxEthDBVlanId vlanIDMax, BOOL enabled)
691 {
692     IX_ETH_DB_CHECK_PORT(portID);
693     
694     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
695     
696     return ixEthDBPortVlanMembershipRangeChange(portID, vlanIDMin, vlanIDMax, ixEthDBPortInfo[portID].transmitTaggingInfo, enabled? ADD_VLAN : REMOVE_VLAN);
697 }
698
699 /**
700  * @brief sets the Egress VLAN tagging table (the Transmit Tagging
701  * Information table)
702  *
703  * @param portID ID of the port
704  * @param vlanSet new TTI table
705  *
706  * Note that this function is documented in the main component
707  * header file, IxEthDB.h.
708  *
709  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
710  * or an appropriate error message otherwise
711  */
712 IX_ETH_DB_PUBLIC 
713 IxEthDBStatus ixEthDBEgressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
714 {
715     IxEthDBVlanId vlanID;
716
717     IX_ETH_DB_CHECK_PORT(portID);
718     
719     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
720
721     IX_ETH_DB_CHECK_REFERENCE(vlanSet);
722
723     /* set the PVID bit just in case */
724     vlanID = IX_ETH_DB_GET_VLAN_ID(ixEthDBPortInfo[portID].vlanTag);
725     vlanSet[VLAN_SET_OFFSET(vlanID)] |= 1 << VLAN_SET_MASK(vlanID);
726     
727     return ixEthDBPortVlanTableSet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet);
728 }
729
730 /**
731  * @brief retrieves the Egress VLAN tagging table (the Transmit 
732  * Tagging Information table)
733  *
734  * @param portID ID of the port
735  * @param vlanSet location to store the port's TTI table
736  *
737  * Note that this function is documented in the main component
738  * header file, IxEthDB.h.
739  *
740  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
741  * or an appropriate error message otherwise
742  */
743 IX_ETH_DB_PUBLIC 
744 IxEthDBStatus ixEthDBEgressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBVlanSet vlanSet)
745 {
746     IX_ETH_DB_CHECK_PORT(portID);
747     
748     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
749     
750     return ixEthDBVlanTableGet(portID, ixEthDBPortInfo[portID].transmitTaggingInfo, vlanSet);
751 }
752
753 /**
754  * @brief sends the NPE the updated frame filter and default
755  * Ingress tagging
756  *
757  * @param portID ID of the port
758  * 
759  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
760  * or an appropriate error message otherwise
761  *
762  * @internal
763  */
764 IX_ETH_DB_PRIVATE
765 IxEthDBStatus ixEthDBIngressVlanModeUpdate(IxEthDBPortId portID)
766 {
767     PortInfo *portInfo = &ixEthDBPortInfo[portID];
768     IxNpeMhMessage message;
769     IX_STATUS result;
770
771     FILL_SETRXTAGMODE_MSG(message, portID, portInfo->npeFrameFilter, portInfo->npeTaggingAction);
772     IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
773
774     return result;
775 }
776
777 /**
778  * @brief sets the default Ingress tagging behavior
779  *
780  * @param portID ID of the port
781  * @param taggingAction default tagging behavior
782  *
783  * Note that this function is documented in the main component
784  * header file, IxEthDB.h.
785  *
786  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
787  * or an appropriate error message otherwise
788  */
789 IX_ETH_DB_PUBLIC 
790 IxEthDBStatus ixEthDBIngressVlanTaggingEnabledSet(IxEthDBPortId portID, IxEthDBTaggingAction taggingAction)
791 {
792     PortInfo *portInfo;
793     
794     IX_ETH_DB_CHECK_PORT(portID);
795     
796     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
797     
798     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
799     
800     portInfo = &ixEthDBPortInfo[portID];
801     
802     if (taggingAction == IX_ETH_DB_PASS_THROUGH)
803     {
804         portInfo->npeTaggingAction = 0x00;
805     }
806     else if (taggingAction == IX_ETH_DB_ADD_TAG)
807     {
808         portInfo->npeTaggingAction = 0x02;
809     }
810     else if (taggingAction == IX_ETH_DB_REMOVE_TAG)
811     {
812         portInfo->npeTaggingAction = 0x01;
813     }
814     else
815     {
816         return IX_ETH_DB_INVALID_ARG;
817     }
818     
819     portInfo->taggingAction = taggingAction;
820     
821     return ixEthDBIngressVlanModeUpdate(portID);
822 }
823
824 /**
825  * @brief retrieves the default Ingress tagging behavior of a port
826  *
827  * @param portID ID of the port
828  * @param taggingAction location to save the default tagging behavior
829  * 
830  * Note that this function is documented in the main component
831  * header file, IxEthDB.h.
832  *
833  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
834  * or an appropriate error message otherwise
835  */
836 IX_ETH_DB_PUBLIC 
837 IxEthDBStatus ixEthDBIngressVlanTaggingEnabledGet(IxEthDBPortId portID, IxEthDBTaggingAction *taggingAction)
838 {
839     IX_ETH_DB_CHECK_PORT(portID);
840     
841     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
842     
843     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
844
845     IX_ETH_DB_CHECK_REFERENCE(taggingAction);
846     
847     *taggingAction = ixEthDBPortInfo[portID].taggingAction;
848     
849     return IX_ETH_DB_SUCCESS;
850 }
851
852 /**
853  * @brief sets the Ingress acceptable frame type filter
854  *
855  * @param portID ID of the port
856  * @param frameFilter acceptable frame type filter
857  * 
858  * Note that this function is documented in the main component
859  * header file, IxEthDB.h.
860  *
861  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
862  * or an appropriate error message otherwise
863  */
864 IX_ETH_DB_PUBLIC 
865 IxEthDBStatus ixEthDBAcceptableFrameTypeSet(IxEthDBPortId portID, IxEthDBFrameFilter frameFilter)
866 {
867     PortInfo *portInfo;
868     IxEthDBStatus result = IX_ETH_DB_SUCCESS;
869         
870     IX_ETH_DB_CHECK_PORT(portID);
871     
872     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
873     
874     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
875     
876     /* check parameter range 
877        the ORed value of the valid values is 0x7
878        a value having extra bits is invalid */
879     if ((frameFilter | 0x7) != 0x7 || frameFilter == 0)
880     {
881         return IX_ETH_DB_INVALID_ARG;
882     }
883     
884     portInfo = &ixEthDBPortInfo[portID];
885     
886     portInfo->frameFilter    = frameFilter;
887     portInfo->npeFrameFilter = 0; /* allow all by default */
888     
889     /* if accepting priority tagged but not all VLAN tagged
890        set the membership table to contain only VLAN ID 0 
891        hence remove vlans 1-4094 and add VLAN ID 0 */
892     if (((frameFilter & IX_ETH_DB_PRIORITY_TAGGED_FRAMES) != 0)
893         && ((frameFilter & IX_ETH_DB_VLAN_TAGGED_FRAMES) == 0))
894     {
895         result = ixEthDBPortVlanMembershipRangeChange(portID, 
896             1, IX_ETH_DB_802_1Q_MAX_VLAN_ID, portInfo->vlanMembership, REMOVE_VLAN);
897
898         if (result == IX_ETH_DB_SUCCESS)
899         {
900             ixEthDBLocalVlanMembershipChange(0, portInfo->vlanMembership, ADD_VLAN);
901             result = ixEthDBVlanTableRangeUpdate(portID);
902         }
903     }
904     
905     /* untagged only? */
906     if (frameFilter == IX_ETH_DB_UNTAGGED_FRAMES)
907     {
908         portInfo->npeFrameFilter = 0x01;
909     }
910     
911     /* tagged only? */
912     if ((frameFilter & IX_ETH_DB_UNTAGGED_FRAMES) == 0)
913     {
914         portInfo->npeFrameFilter = 0x02;
915     }
916
917     if (result == IX_ETH_DB_SUCCESS)
918     {
919         result = ixEthDBIngressVlanModeUpdate(portID);
920     }
921
922     return result;
923 }
924
925 /**
926  * @brief retrieves the acceptable frame type filter for a port
927  *
928  * @param portID ID of the port
929  * @param frameFilter location to store the frame filter
930  *
931  * Note that this function is documented in the main component
932  * header file, IxEthDB.h.
933  *
934  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
935  * or an appropriate error message otherwise
936  */
937 IX_ETH_DB_PUBLIC 
938 IxEthDBStatus ixEthDBAcceptableFrameTypeGet(IxEthDBPortId portID, IxEthDBFrameFilter *frameFilter)
939 {
940     IX_ETH_DB_CHECK_PORT(portID);
941     
942     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
943     
944     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
945     
946     IX_ETH_DB_CHECK_REFERENCE(frameFilter);
947     
948     *frameFilter = ixEthDBPortInfo[portID].frameFilter;
949     
950     return IX_ETH_DB_SUCCESS;
951 }
952
953 /**
954  * @brief sends an NPE the updated configuration related
955  * to one QoS priority (associated traffic class and AQM mapping)
956  *
957  * @param portID ID of the port
958  * @param classIndex QoS priority (traffic class index)
959  *
960  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
961  * or an appropriate error message otherwise
962  *
963  * @internal
964  */
965 IX_ETH_DB_PUBLIC
966 IxEthDBStatus ixEthDBUpdateTrafficClass(IxEthDBPortId portID, UINT32 classIndex)
967 {
968     IxNpeMhMessage message;
969     IX_STATUS result;
970
971     UINT32 trafficClass = ixEthDBPortInfo[portID].priorityTable[classIndex];
972     UINT32 aqmQueue     = ixEthDBPortInfo[portID].ixEthDBTrafficClassAQMAssignments[trafficClass];
973     
974     FILL_SETRXQOSENTRY(message, IX_ETH_DB_PORT_ID_TO_NPE_LOGICAL_ID(portID), classIndex, trafficClass, aqmQueue);
975     
976     IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
977     
978     return result;
979 }
980
981 /**
982  * @brief sets the priority mapping table
983  *
984  * @param portID ID of the port
985  * @param priorityTable new priority mapping table
986  *
987  * Note that this function is documented in the main component
988  * header file, IxEthDB.h.
989  *
990  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
991  * or an appropriate error message otherwise
992  */
993 IX_ETH_DB_PUBLIC 
994 IxEthDBStatus ixEthDBPriorityMappingTableSet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable)
995 {
996     UINT32 classIndex;
997     
998     IX_ETH_DB_CHECK_PORT(portID);
999     
1000     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
1001     
1002     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
1003     
1004     IX_ETH_DB_CHECK_REFERENCE(priorityTable);
1005            
1006     for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++)
1007     {
1008         /* check range */
1009         if (priorityTable[classIndex] >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount)
1010         {
1011             return IX_ETH_DB_INVALID_PRIORITY;
1012         }
1013     }
1014     
1015     /* set new traffic classes */
1016     for (classIndex = 0 ; classIndex < IX_IEEE802_1Q_QOS_PRIORITY_COUNT ; classIndex++)
1017     {
1018         ixEthDBPortInfo[portID].priorityTable[classIndex] = priorityTable[classIndex];
1019         
1020         if (ixEthDBUpdateTrafficClass(portID, classIndex) != IX_ETH_DB_SUCCESS)
1021         {
1022             return IX_ETH_DB_FAIL;
1023         }
1024     }
1025     
1026     return IX_ETH_DB_SUCCESS;
1027  }
1028
1029 /**
1030  * @brief retrieves a port's priority mapping table
1031  *
1032  * @param portID ID of the port
1033  * @param priorityTable location to store the priority table
1034  *
1035  * Note that this function is documented in the main component
1036  * header file, IxEthDB.h.
1037  *
1038  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
1039  * or an appropriate error message otherwise
1040  */
1041 IX_ETH_DB_PUBLIC 
1042 IxEthDBStatus ixEthDBPriorityMappingTableGet(IxEthDBPortId portID, IxEthDBPriorityTable priorityTable)
1043 {
1044     IX_ETH_DB_CHECK_PORT(portID);
1045     
1046     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
1047     
1048     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
1049     
1050     IX_ETH_DB_CHECK_REFERENCE(priorityTable);
1051     
1052     memcpy(priorityTable, ixEthDBPortInfo[portID].priorityTable, sizeof (IxEthDBPriorityTable));
1053     
1054     return IX_ETH_DB_SUCCESS;
1055 }
1056
1057 /**
1058  * @brief sets one QoS priority => traffic class mapping
1059  *
1060  * @param portID ID of the port
1061  * @param userPriority QoS (user) priority
1062  * @param trafficClass associated traffic class
1063  *
1064  * Note that this function is documented in the main component
1065  * header file, IxEthDB.h.
1066  *
1067  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
1068  * or an appropriate error message otherwise
1069  */
1070 IX_ETH_DB_PUBLIC 
1071 IxEthDBStatus ixEthDBPriorityMappingClassSet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority trafficClass)
1072 {
1073     IX_ETH_DB_CHECK_PORT(portID);
1074     
1075     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
1076     
1077     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
1078
1079     /* check ranges for userPriority and trafficClass */
1080     if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT || trafficClass >= ixEthDBPortInfo[portID].ixEthDBTrafficClassCount)
1081     {
1082         return IX_ETH_DB_INVALID_PRIORITY;
1083     }
1084     
1085     ixEthDBPortInfo[portID].priorityTable[userPriority] = trafficClass;
1086     
1087     return ixEthDBUpdateTrafficClass(portID, userPriority);
1088 }
1089
1090 /**
1091  * @brief retrieves one QoS priority => traffic class mapping
1092  *
1093  * @param portID ID of the port
1094  * @param userPriority QoS (user) priority
1095  * @param trafficClass location to store the associated traffic class
1096  * 
1097  * Note that this function is documented in the main component
1098  * header file, IxEthDB.h.
1099  *
1100  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
1101  * or an appropriate error message otherwise
1102  */
1103 IX_ETH_DB_PUBLIC 
1104 IxEthDBStatus ixEthDBPriorityMappingClassGet(IxEthDBPortId portID, IxEthDBPriority userPriority, IxEthDBPriority *trafficClass)
1105 {
1106     IX_ETH_DB_CHECK_PORT(portID);
1107     
1108     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
1109     
1110     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
1111     
1112     IX_ETH_DB_CHECK_REFERENCE(trafficClass);
1113     
1114     /* check userPriority range */
1115     if (userPriority >= IX_IEEE802_1Q_QOS_PRIORITY_COUNT)
1116     {
1117         return IX_ETH_DB_INVALID_PRIORITY;
1118     }
1119     
1120     *trafficClass = ixEthDBPortInfo[portID].priorityTable[userPriority];
1121     
1122     return IX_ETH_DB_SUCCESS;
1123 }
1124
1125 /**
1126  * @brief enables or disables the source port extraction
1127  * from the VLAN TPID field
1128  *
1129  * @param portID ID of the port
1130  * @param enable true to enable or false to disable
1131  *
1132  * Note that this function is documented in the main component
1133  * header file, IxEthDB.h.
1134  *
1135  * @return IX_ETH_DB_SUCCESS if the operation completed successfully
1136  * or an appropriate error message otherwise
1137  */
1138 IX_ETH_DB_PUBLIC 
1139 IxEthDBStatus ixEthDBVlanPortExtractionEnable(IxEthDBPortId portID, BOOL enable)
1140 {
1141     IxNpeMhMessage message;
1142     IX_STATUS result;
1143
1144     IX_ETH_DB_CHECK_PORT(portID);
1145     
1146     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
1147     
1148     IX_ETH_DB_CHECK_FEATURE(portID, IX_ETH_DB_VLAN_QOS);
1149
1150     FILL_SETPORTIDEXTRACTIONMODE(message, portID, enable);
1151
1152     IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
1153     
1154     return result;
1155 }