]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/npe/IxEthDBAPISupport.c
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
[karo-tx-uboot.git] / drivers / net / npe / IxEthDBAPISupport.c
1 /**
2  * @file IxEthDBAPISupport.c
3  *
4  * @brief Public API support functions
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  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
19  * 1. Redistributions of source code must retain the above copyright
20  *    notice, this list of conditions and the following disclaimer.
21  * 2. Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following disclaimer in the
23  *    documentation and/or other materials provided with the distribution.
24  * 3. Neither the name of the Intel Corporation nor the names of its contributors
25  *    may be used to endorse or promote products derived from this software
26  *    without specific prior written permission.
27  *
28  * @par
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
30  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39  * SUCH DAMAGE.
40  *
41  * @par
42  * -- End of Copyright Notice --
43  */
44
45 #include <IxEthDB.h>
46 #include <IxNpeMh.h>
47 #include <IxFeatureCtrl.h>
48
49 #include "IxEthDB_p.h"
50 #include "IxEthDBMessages_p.h"
51 #include "IxEthDB_p.h"
52 #include "IxEthDBLog_p.h"
53
54 #ifdef IX_UNIT_TEST
55
56 int dbAccessCounter = 0;
57 int overflowEvent   = 0;
58
59 #endif
60
61 /*
62  * External declaration
63  */
64 extern HashTable dbHashtable;
65
66 /*
67  * Internal declaration
68  */
69 IX_ETH_DB_PUBLIC
70 PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS];
71
72 IX_ETH_DB_PRIVATE
73 struct
74 {
75     BOOL saved;
76     IxEthDBPriorityTable priorityTable;
77     IxEthDBVlanSet vlanMembership;
78     IxEthDBVlanSet transmitTaggingInfo;
79     IxEthDBFrameFilter frameFilter;
80     IxEthDBTaggingAction taggingAction;
81     IxEthDBFirewallMode firewallMode;
82     BOOL stpBlocked;
83     BOOL srcAddressFilterEnabled;
84     UINT32 maxRxFrameSize;
85     UINT32 maxTxFrameSize;
86 } ixEthDBPortState[IX_ETH_DB_NUMBER_OF_PORTS];
87
88 #define IX_ETH_DB_DEFAULT_FRAME_SIZE (1518)
89
90 /**
91  * @brief initializes a port
92  *
93  * @param portID ID of the port to be initialized
94  *
95  * Note that redundant initializations are silently
96  * dealt with and do not constitute an error
97  *
98  * This function is fully documented in the main
99  * header file, IxEthDB.h
100  */
101 IX_ETH_DB_PUBLIC
102 void ixEthDBPortInit(IxEthDBPortId portID)
103 {
104     PortInfo *portInfo;
105
106     if (portID >= IX_ETH_DB_NUMBER_OF_PORTS)
107     {
108         return;
109     }
110
111     portInfo = &ixEthDBPortInfo[portID];
112
113     if (ixEthDBSingleEthNpeCheck(portID) != IX_ETH_DB_SUCCESS)
114     {
115         WARNING_LOG("EthDB: Unavailable Eth %d: Cannot initialize EthDB Port.\n", (UINT32) portID);
116
117         return;
118     }
119
120     if (portInfo->initialized)
121     {
122         /* redundant */
123         return;
124     }
125
126     /* initialize core fields */
127     portInfo->portID = portID;
128     SET_DEPENDENCY_MAP(portInfo->dependencyPortMap, portID);
129
130     /* default values */
131     portInfo->agingEnabled       = false;
132     portInfo->enabled            = false;
133     portInfo->macAddressUploaded = false;
134     portInfo->maxRxFrameSize     = IX_ETHDB_DEFAULT_FRAME_SIZE;
135     portInfo->maxTxFrameSize     = IX_ETHDB_DEFAULT_FRAME_SIZE;
136
137     /* default update control values */
138     portInfo->updateMethod.searchTree              = NULL;
139     portInfo->updateMethod.searchTreePendingWrite  = false;
140     portInfo->updateMethod.treeInitialized         = false;
141     portInfo->updateMethod.updateEnabled           = false;
142     portInfo->updateMethod.userControlled          = false;
143
144     /* default WiFi parameters */
145     memset(portInfo->bbsid, 0, sizeof (portInfo->bbsid));
146     portInfo->frameControlDurationID = 0;
147
148     /* Ethernet NPE-specific initializations */
149     if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
150     {
151         /* update handler */
152         portInfo->updateMethod.updateHandler = ixEthDBNPEUpdateHandler;
153     }
154
155     /* initialize state save */
156     ixEthDBPortState[portID].saved = false;
157
158     portInfo->initialized = true;
159 }
160
161 /**
162  * @brief enables a port
163  *
164  * @param portID ID of the port to enable
165  *
166  * This function is fully documented in the main
167  * header file, IxEthDB.h
168  *
169  * @return IX_ETH_DB_SUCCESS if enabling was
170  * accomplished, or a meaningful error message otherwise
171  */
172 IX_ETH_DB_PUBLIC
173 IxEthDBStatus ixEthDBPortEnable(IxEthDBPortId portID)
174 {
175     IxEthDBPortMap triggerPorts;
176     PortInfo *portInfo;
177
178     IX_ETH_DB_CHECK_PORT_EXISTS(portID);
179
180     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
181
182     portInfo = &ixEthDBPortInfo[portID];
183
184     if (portInfo->enabled)
185     {
186         /* redundant */
187         return IX_ETH_DB_SUCCESS;
188     }
189
190     SET_DEPENDENCY_MAP(triggerPorts, portID);
191
192     /* mark as enabled */
193     portInfo->enabled = true;
194
195     /* Operation stops here when Ethernet Learning is not enabled */
196     if(IX_FEATURE_CTRL_SWCONFIG_DISABLED ==
197        ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
198     {
199         return IX_ETH_DB_SUCCESS;
200     }
201
202     if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE && !portInfo->macAddressUploaded)
203     {
204         IX_ETH_DB_SUPPORT_TRACE("DB: (Support) MAC address not set on port %d, enable failed\n", portID);
205
206         /* must use UnicastAddressSet() before enabling an NPE port */
207         return IX_ETH_DB_MAC_UNINITIALIZED;
208     }
209
210     if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
211     {
212         IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Attempting to enable the NPE callback for port %d...\n", portID);
213
214         if (!portInfo->updateMethod.userControlled
215                 && ((portInfo->featureCapability & IX_ETH_DB_FILTERING) != 0))
216         {
217             portInfo->updateMethod.updateEnabled = true;
218         }
219
220         /* if this is first time initialization then we already have
221            write access to the tree and can AccessRelease directly */
222         if (!portInfo->updateMethod.treeInitialized)
223         {
224             IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Initializing tree for port %d\n", portID);
225
226             /* create an initial tree and release access into it */
227             ixEthDBUpdatePortLearningTrees(triggerPorts);
228
229             /* mark tree as being initialized */
230             portInfo->updateMethod.treeInitialized = true;
231         }
232     }
233
234     if (ixEthDBPortState[portID].saved)
235     {
236         /* previous configuration data stored, restore state */
237         if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
238         {
239             ixEthDBFirewallModeSet(portID, ixEthDBPortState[portID].firewallMode);
240             ixEthDBFirewallInvalidAddressFilterEnable(portID, ixEthDBPortState[portID].srcAddressFilterEnabled);
241         }
242
243 #if 0 /* test-only */
244         if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
245         {
246             ixEthDBAcceptableFrameTypeSet(portID, ixEthDBPortState[portID].frameFilter);
247             ixEthDBIngressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].taggingAction);
248
249             ixEthDBEgressVlanTaggingEnabledSet(portID, ixEthDBPortState[portID].transmitTaggingInfo);
250             ixEthDBPortVlanMembershipSet(portID, ixEthDBPortState[portID].vlanMembership);
251
252             ixEthDBPriorityMappingTableSet(portID, ixEthDBPortState[portID].priorityTable);
253         }
254 #endif
255
256         if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
257         {
258             ixEthDBSpanningTreeBlockingStateSet(portID, ixEthDBPortState[portID].stpBlocked);
259         }
260
261         ixEthDBFilteringPortMaximumRxFrameSizeSet(portID, ixEthDBPortState[portID].maxRxFrameSize);
262         ixEthDBFilteringPortMaximumTxFrameSizeSet(portID, ixEthDBPortState[portID].maxTxFrameSize);
263
264         /* discard previous save */
265         ixEthDBPortState[portID].saved = false;
266     }
267
268     IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Enabling succeeded for port %d\n", portID);
269
270     return IX_ETH_DB_SUCCESS;
271 }
272
273 /**
274  * @brief disables a port
275  *
276  * @param portID ID of the port to disable
277  *
278  * This function is fully documented in the
279  * main header file, IxEthDB.h
280  *
281  * @return IX_ETH_DB_SUCCESS if disabling was
282  * successful or an appropriate error message
283  * otherwise
284  */
285 IX_ETH_DB_PUBLIC
286 IxEthDBStatus ixEthDBPortDisable(IxEthDBPortId portID)
287 {
288     HashIterator iterator;
289     IxEthDBPortMap triggerPorts; /* ports who will have deleted records and therefore will need updating */
290     BOOL result;
291     PortInfo *portInfo;
292     IxEthDBFeature learningEnabled;
293 #if 0 /* test-only */
294     IxEthDBPriorityTable classZeroTable;
295 #endif
296
297     IX_ETH_DB_CHECK_PORT_EXISTS(portID);
298
299     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
300
301     portInfo = &ixEthDBPortInfo[portID];
302
303     if (!portInfo->enabled)
304     {
305         /* redundant */
306         return IX_ETH_DB_SUCCESS;
307     }
308
309     if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
310     {
311         /* save filtering state */
312         ixEthDBPortState[portID].firewallMode            = portInfo->firewallMode;
313         ixEthDBPortState[portID].frameFilter             = portInfo->frameFilter;
314         ixEthDBPortState[portID].taggingAction           = portInfo->taggingAction;
315         ixEthDBPortState[portID].stpBlocked              = portInfo->stpBlocked;
316         ixEthDBPortState[portID].srcAddressFilterEnabled = portInfo->srcAddressFilterEnabled;
317         ixEthDBPortState[portID].maxRxFrameSize          = portInfo->maxRxFrameSize;
318         ixEthDBPortState[portID].maxTxFrameSize          = portInfo->maxTxFrameSize;
319
320         memcpy(ixEthDBPortState[portID].vlanMembership, portInfo->vlanMembership, sizeof (IxEthDBVlanSet));
321         memcpy(ixEthDBPortState[portID].transmitTaggingInfo, portInfo->transmitTaggingInfo, sizeof (IxEthDBVlanSet));
322         memcpy(ixEthDBPortState[portID].priorityTable, portInfo->priorityTable, sizeof (IxEthDBPriorityTable));
323
324         ixEthDBPortState[portID].saved = true;
325
326         /* now turn off all EthDB filtering features on the port */
327
328 #if 0 /* test-only */
329         /* VLAN & QoS */
330         if ((portInfo->featureCapability & IX_ETH_DB_VLAN_QOS) != 0)
331         {
332             ixEthDBPortVlanMembershipRangeAdd((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID);
333             ixEthDBEgressVlanRangeTaggingEnabledSet((IxEthDBPortId) portID, 0, IX_ETH_DB_802_1Q_MAX_VLAN_ID, false);
334             ixEthDBAcceptableFrameTypeSet((IxEthDBPortId) portID, IX_ETH_DB_ACCEPT_ALL_FRAMES);
335             ixEthDBIngressVlanTaggingEnabledSet((IxEthDBPortId) portID, IX_ETH_DB_PASS_THROUGH);
336
337             memset(classZeroTable, 0, sizeof (classZeroTable));
338             ixEthDBPriorityMappingTableSet((IxEthDBPortId) portID, classZeroTable);
339         }
340 #endif
341
342         /* STP */
343         if ((portInfo->featureCapability & IX_ETH_DB_SPANNING_TREE_PROTOCOL) != 0)
344         {
345             ixEthDBSpanningTreeBlockingStateSet((IxEthDBPortId) portID, false);
346         }
347
348         /* Firewall */
349         if ((portInfo->featureCapability & IX_ETH_DB_FIREWALL) != 0)
350         {
351             ixEthDBFirewallModeSet((IxEthDBPortId) portID, IX_ETH_DB_FIREWALL_BLACK_LIST);
352             ixEthDBFirewallTableDownload((IxEthDBPortId) portID);
353             ixEthDBFirewallInvalidAddressFilterEnable((IxEthDBPortId) portID, false);
354         }
355
356         /* Frame size filter */
357         ixEthDBFilteringPortMaximumFrameSizeSet((IxEthDBPortId) portID, IX_ETH_DB_DEFAULT_FRAME_SIZE);
358
359         /* WiFi */
360         if ((portInfo->featureCapability & IX_ETH_DB_WIFI_HEADER_CONVERSION) != 0)
361         {
362             ixEthDBWiFiConversionTableDownload((IxEthDBPortId) portID);
363         }
364
365         /* save and disable the learning feature bit */
366         learningEnabled          = portInfo->featureStatus & IX_ETH_DB_LEARNING;
367         portInfo->featureStatus &= ~IX_ETH_DB_LEARNING;
368     }
369     else
370     {
371         /* save the learning feature bit */
372         learningEnabled          = portInfo->featureStatus & IX_ETH_DB_LEARNING;
373     }
374
375     SET_EMPTY_DEPENDENCY_MAP(triggerPorts);
376
377     ixEthDBUpdateLock();
378
379     /* wipe out current entries for this port */
380     BUSY_RETRY(ixEthDBInitHashIterator(&dbHashtable, &iterator));
381
382     while (IS_ITERATOR_VALID(&iterator))
383     {
384         MacDescriptor *descriptor =  (MacDescriptor *) iterator.node->data;
385
386         /* check if the port match. If so, remove the entry  */
387         if (descriptor->portID == portID
388                 && (descriptor->type == IX_ETH_DB_FILTERING_RECORD || descriptor->type == IX_ETH_DB_FILTERING_VLAN_RECORD)
389                 && !descriptor->recordData.filteringData.staticEntry)
390         {
391             /* delete entry */
392             BUSY_RETRY(ixEthDBRemoveEntryAtHashIterator(&dbHashtable, &iterator));
393
394             /* add port to the set of update trigger ports */
395             JOIN_PORT_TO_MAP(triggerPorts, portID);
396         }
397         else
398         {
399             /* move to the next record */
400             BUSY_RETRY(ixEthDBIncrementHashIterator(&dbHashtable, &iterator));
401         }
402     }
403
404     if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
405     {
406         if (portInfo->updateMethod.searchTree != NULL)
407         {
408             ixEthDBFreeMacTreeNode(portInfo->updateMethod.searchTree);
409             portInfo->updateMethod.searchTree = NULL;
410         }
411
412         ixEthDBNPEUpdateHandler(portID, IX_ETH_DB_FILTERING_RECORD);
413     }
414
415     /* mark as disabled */
416     portInfo->enabled = false;
417
418     /* disable updates unless the user has specifically altered the default behavior */
419     if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
420     {
421         if (!portInfo->updateMethod.userControlled)
422         {
423             portInfo->updateMethod.updateEnabled = false;
424         }
425
426         /* make sure we re-initialize the NPE learning tree when the port is re-enabled */
427         portInfo->updateMethod.treeInitialized = false;
428     }
429
430     ixEthDBUpdateUnlock();
431
432     /* restore learning feature bit */
433     portInfo->featureStatus |= learningEnabled;
434
435     /* if we've removed any records or lost any events make sure to force an update */
436     IS_EMPTY_DEPENDENCY_MAP(result, triggerPorts);
437
438     if (!result)
439     {
440         ixEthDBUpdatePortLearningTrees(triggerPorts);
441     }
442
443     return IX_ETH_DB_SUCCESS;
444 }
445
446 /**
447  * @brief sends the updated maximum Tx/Rx frame lengths to the NPE
448  *
449  * @param portID ID of the port to update
450  *
451  * @return IX_ETH_DB_SUCCESS if the update completed
452  * successfully or an appropriate error message otherwise
453  *
454  * @internal
455  */
456 IX_ETH_DB_PRIVATE
457 IxEthDBStatus ixEthDBPortFrameLengthsUpdate(IxEthDBPortId portID)
458 {
459     IxNpeMhMessage message;
460     PortInfo *portInfo = &ixEthDBPortInfo[portID];
461     IX_STATUS result;
462
463     FILL_SETMAXFRAMELENGTHS_MSG(message, portID, portInfo->maxRxFrameSize, portInfo->maxTxFrameSize);
464
465     IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
466
467     return result;
468 }
469
470 /**
471  * @brief sets the port maximum Rx frame size
472  *
473  * @param portID ID of the port to set the frame size on
474  * @param maximumRxFrameSize maximum Rx frame size
475  *
476  * This function updates the internal data structures and
477  * calls ixEthDBPortFrameLengthsUpdate() for NPE update.
478  *
479  * This function is fully documented in the main header
480  * file, IxEthDB.h.
481  *
482  * @return IX_ETH_DB_SUCCESS if the operation was
483  * successfull or an appropriate error message otherwise
484  */
485 IX_ETH_DB_PUBLIC
486 IxEthDBStatus ixEthDBFilteringPortMaximumRxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumRxFrameSize)
487 {
488     IX_ETH_DB_CHECK_PORT_EXISTS(portID);
489
490     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
491
492         if (!ixEthDBPortInfo[portID].initialized)
493         {
494                 return IX_ETH_DB_PORT_UNINITIALIZED;
495         }
496
497     if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
498     {
499         if ((maximumRxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
500             (maximumRxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
501         {
502             return IX_ETH_DB_INVALID_ARG;
503         }
504     }
505     else
506     {
507         return IX_ETH_DB_NO_PERMISSION;
508     }
509
510     /* update internal structure */
511     ixEthDBPortInfo[portID].maxRxFrameSize = maximumRxFrameSize;
512
513     /* update the maximum frame size in the NPE */
514     return ixEthDBPortFrameLengthsUpdate(portID);
515 }
516
517 /**
518  * @brief sets the port maximum Tx frame size
519  *
520  * @param portID ID of the port to set the frame size on
521  * @param maximumTxFrameSize maximum Tx frame size
522  *
523  * This function updates the internal data structures and
524  * calls ixEthDBPortFrameLengthsUpdate() for NPE update.
525  *
526  * This function is fully documented in the main header
527  * file, IxEthDB.h.
528  *
529  * @return IX_ETH_DB_SUCCESS if the operation was
530  * successfull or an appropriate error message otherwise
531  */
532 IX_ETH_DB_PUBLIC
533 IxEthDBStatus ixEthDBFilteringPortMaximumTxFrameSizeSet(IxEthDBPortId portID, UINT32 maximumTxFrameSize)
534 {
535     IX_ETH_DB_CHECK_PORT_EXISTS(portID);
536
537     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
538
539         if (!ixEthDBPortInfo[portID].initialized)
540         {
541                 return IX_ETH_DB_PORT_UNINITIALIZED;
542         }
543
544     if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
545     {
546         if ((maximumTxFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
547             (maximumTxFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
548         {
549             return IX_ETH_DB_INVALID_ARG;
550         }
551     }
552     else
553     {
554         return IX_ETH_DB_NO_PERMISSION;
555     }
556
557     /* update internal structure */
558     ixEthDBPortInfo[portID].maxTxFrameSize = maximumTxFrameSize;
559
560     /* update the maximum frame size in the NPE */
561     return ixEthDBPortFrameLengthsUpdate(portID);
562 }
563
564 /**
565  * @brief sets the port maximum Tx and Rx frame sizes
566  *
567  * @param portID ID of the port to set the frame size on
568  * @param maximumFrameSize maximum Tx and Rx frame sizes
569  *
570  * This function updates the internal data structures and
571  * calls ixEthDBPortFrameLengthsUpdate() for NPE update.
572  *
573  * Note that both the maximum Tx and Rx frame size are set
574  * to the same value. This function is kept for compatibility
575  * reasons.
576  *
577  * This function is fully documented in the main header
578  * file, IxEthDB.h.
579  *
580  * @return IX_ETH_DB_SUCCESS if the operation was
581  * successfull or an appropriate error message otherwise
582  */
583 IX_ETH_DB_PUBLIC
584 IxEthDBStatus ixEthDBFilteringPortMaximumFrameSizeSet(IxEthDBPortId portID, UINT32 maximumFrameSize)
585 {
586     IX_ETH_DB_CHECK_PORT_EXISTS(portID);
587
588     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
589
590     if (!ixEthDBPortInfo[portID].initialized)
591     {
592         return IX_ETH_DB_PORT_UNINITIALIZED;
593     }
594
595     if (ixEthDBPortDefinitions[portID].type == IX_ETH_NPE)
596     {
597         if ((maximumFrameSize < IX_ETHDB_MIN_NPE_FRAME_SIZE) ||
598             (maximumFrameSize > IX_ETHDB_MAX_NPE_FRAME_SIZE))
599         {
600             return IX_ETH_DB_INVALID_ARG;
601         }
602     }
603     else
604     {
605         return IX_ETH_DB_NO_PERMISSION;
606     }
607
608     /* update internal structure */
609     ixEthDBPortInfo[portID].maxRxFrameSize = maximumFrameSize;
610     ixEthDBPortInfo[portID].maxTxFrameSize = maximumFrameSize;
611
612     /* update the maximum frame size in the NPE */
613     return ixEthDBPortFrameLengthsUpdate(portID);
614 }
615
616 /**
617  * @brief sets the MAC address of an NPE port
618  *
619  * @param portID port ID to set the MAC address on
620  * @param macAddr pointer to the 6-byte MAC address
621  *
622  * This function is called by the EthAcc
623  * ixEthAccUnicastMacAddressSet() and should not be
624  * manually invoked unless required by special circumstances.
625  *
626  * @return IX_ETH_DB_SUCCESS if the operation succeeded
627  * or an appropriate error message otherwise
628  */
629 IX_ETH_DB_PUBLIC
630 IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
631 {
632     IxNpeMhMessage message;
633     IX_STATUS result;
634
635     /* use this macro instead CHECK_PORT
636        as the port doesn't need to be enabled */
637     IX_ETH_DB_CHECK_PORT_EXISTS(portID);
638
639     IX_ETH_DB_CHECK_REFERENCE(macAddr);
640
641     if (!ixEthDBPortInfo[portID].initialized)
642     {
643         return IX_ETH_DB_PORT_UNINITIALIZED;
644     }
645
646     /* Operation stops here when Ethernet Learning is not enabled */
647     if(IX_FEATURE_CTRL_SWCONFIG_DISABLED ==
648        ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
649     {
650         return IX_ETH_DB_SUCCESS;
651     }
652
653     IX_ETH_DB_CHECK_SINGLE_NPE(portID);
654
655     /* exit if the port is not an Ethernet NPE */
656     if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE)
657     {
658         return IX_ETH_DB_INVALID_PORT;
659     }
660
661     /* populate message */
662     FILL_SETPORTADDRESS_MSG(message, portID, macAddr->macAddress);
663
664     IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Sending SetPortAddress on port %d...\n", portID);
665
666     /* send a SetPortAddress message */
667     IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
668
669     if (result == IX_SUCCESS)
670     {
671         ixEthDBPortInfo[portID].macAddressUploaded = true;
672     }
673
674     return result;
675 }