blob: 25633a3d56e6d1bb0b880b82edb6605b9d266590 [file] [log] [blame]
Wolfgang Denk4646d2a2006-05-30 15:56:48 +02001/**
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
56int dbAccessCounter = 0;
57int overflowEvent = 0;
58
59#endif
60
61/*
62 * External declaration
63 */
64extern HashTable dbHashtable;
65
66/*
67 * Internal declaration
68 */
69IX_ETH_DB_PUBLIC
70PortInfo ixEthDBPortInfo[IX_ETH_DB_NUMBER_OF_PORTS];
71
72IX_ETH_DB_PRIVATE
73struct
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 */
101IX_ETH_DB_PUBLIC
102void 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 */
172IX_ETH_DB_PUBLIC
173IxEthDBStatus 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 */
285IX_ETH_DB_PUBLIC
286IxEthDBStatus 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 */
456IX_ETH_DB_PRIVATE
457IxEthDBStatus 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 */
485IX_ETH_DB_PUBLIC
486IxEthDBStatus 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 */
532IX_ETH_DB_PUBLIC
533IxEthDBStatus 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 */
583IX_ETH_DB_PUBLIC
584IxEthDBStatus 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 */
629IX_ETH_DB_PUBLIC
630IxEthDBStatus ixEthDBPortAddressSet(IxEthDBPortId portID, IxEthDBMacAddr *macAddr)
631{
632 IxNpeMhMessage message;
633 IxOsalMutex *ackPortAddressLock;
634 IX_STATUS result;
635
636 /* use this macro instead CHECK_PORT
637 as the port doesn't need to be enabled */
638 IX_ETH_DB_CHECK_PORT_EXISTS(portID);
639
640 IX_ETH_DB_CHECK_REFERENCE(macAddr);
641
642 if (!ixEthDBPortInfo[portID].initialized)
643 {
644 return IX_ETH_DB_PORT_UNINITIALIZED;
645 }
646
647 ackPortAddressLock = &ixEthDBPortInfo[portID].npeAckLock;
648
649 /* Operation stops here when Ethernet Learning is not enabled */
650 if(IX_FEATURE_CTRL_SWCONFIG_DISABLED ==
651 ixFeatureCtrlSwConfigurationCheck(IX_FEATURECTRL_ETH_LEARNING))
652 {
653 return IX_ETH_DB_SUCCESS;
654 }
655
656 IX_ETH_DB_CHECK_SINGLE_NPE(portID);
657
658 /* exit if the port is not an Ethernet NPE */
659 if (ixEthDBPortDefinitions[portID].type != IX_ETH_NPE)
660 {
661 return IX_ETH_DB_INVALID_PORT;
662 }
663
664 /* populate message */
665 FILL_SETPORTADDRESS_MSG(message, portID, macAddr->macAddress);
666
667 IX_ETH_DB_SUPPORT_TRACE("DB: (Support) Sending SetPortAddress on port %d...\n", portID);
668
669 /* send a SetPortAddress message */
670 IX_ETHDB_SEND_NPE_MSG(IX_ETH_DB_PORT_ID_TO_NPE(portID), message, result);
671
672 if (result == IX_SUCCESS)
673 {
674 ixEthDBPortInfo[portID].macAddressUploaded = TRUE;
675 }
676
677 return result;
678}