change console=tty0 to enable linux framebuffer console
[jz_uboot.git] / cpu / ixp / npe / IxEthAccMac.c
blobd57e71678efe6e4e8b39c930063bf65ab3bf15fd
1 /**
2 * @file IxEthAccMac.c
4 * @author Intel Corporation
5 * @date
7 * @brief MAC control functions
9 * Design Notes:
11 * @par
12 * IXP400 SW Release version 2.0
14 * -- Copyright Notice --
16 * @par
17 * Copyright 2001-2005, Intel Corporation.
18 * All rights reserved.
20 * @par
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
23 * are met:
24 * 1. Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * 2. Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 * 3. Neither the name of the Intel Corporation nor the names of its contributors
30 * may be used to endorse or promote products derived from this software
31 * without specific prior written permission.
33 * @par
34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
35 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
46 * @par
47 * -- End of Copyright Notice --
50 #include "IxOsal.h"
51 #include "IxNpeMh.h"
52 #ifdef CONFIG_IXP425_COMPONENT_ETHDB
53 #include "IxEthDB.h"
54 #endif
55 #include "IxEthDBPortDefs.h"
56 #include "IxEthNpe.h"
57 #include "IxEthAcc.h"
58 #include "IxEthAccDataPlane_p.h"
59 #include "IxEthAcc_p.h"
60 #include "IxEthAccMac_p.h"
62 /* Maximum number of retries during ixEthAccPortDisable, which
63 * is approximately 10 seconds
65 #define IX_ETH_ACC_MAX_RETRY 500
67 /* Maximum number of retries during ixEthAccPortDisable when expecting
68 * timeout
70 #define IX_ETH_ACC_MAX_RETRY_TIMEOUT 5
72 #define IX_ETH_ACC_VALIDATE_PORT_ID(portId) \
73 do \
74 { \
75 if(!IX_ETH_ACC_IS_PORT_VALID(portId)) \
76 { \
77 return IX_ETH_ACC_INVALID_PORT; \
78 } \
79 } while(0)
81 PUBLIC IxEthAccMacState ixEthAccMacState[IX_ETH_ACC_NUMBER_OF_PORTS];
83 PRIVATE UINT32 ixEthAccMacBase[IX_ETH_ACC_NUMBER_OF_PORTS];
85 /*Forward function declarations*/
86 PRIVATE void
87 ixEthAccPortDisableRx (IxEthAccPortId portId,
88 IX_OSAL_MBUF * mBufPtr,
89 BOOL useMultiBufferCallback);
91 PRIVATE void
92 ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId,
93 IX_OSAL_MBUF * mBufPtr,
94 BOOL useMultiBufferCallback);
96 PRIVATE void
97 ixEthAccPortDisableTxDone (UINT32 cbTag,
98 IX_OSAL_MBUF *mbuf);
100 PRIVATE void
101 ixEthAccPortDisableTxDoneAndSubmit (UINT32 cbTag,
102 IX_OSAL_MBUF *mbuf);
104 PRIVATE void
105 ixEthAccPortDisableRxCallback (UINT32 cbTag,
106 IX_OSAL_MBUF * mBufPtr,
107 UINT32 learnedPortId);
109 PRIVATE void
110 ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag,
111 IX_OSAL_MBUF **mBufPtr);
113 PRIVATE IxEthAccStatus
114 ixEthAccPortDisableTryTransmit(UINT32 portId);
116 PRIVATE IxEthAccStatus
117 ixEthAccPortDisableTryReplenish(UINT32 portId);
119 PRIVATE IxEthAccStatus
120 ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId,
121 IxEthAccMacAddr *macAddr);
123 PRIVATE IxEthAccStatus
124 ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId,
125 IxEthAccMacAddr *macAddr);
127 PRIVATE void
128 ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId,
129 IxNpeMhMessage msg);
131 PRIVATE void
132 ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId,
133 IxNpeMhMessage msg);
135 PRIVATE void
136 ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId,
137 IxNpeMhMessage msg);
139 PRIVATE void
140 ixEthAccMulticastAddressSet(IxEthAccPortId portId);
142 PRIVATE BOOL
143 ixEthAccMacEqual(IxEthAccMacAddr *macAddr1,
144 IxEthAccMacAddr *macAddr2);
146 PRIVATE void
147 ixEthAccMacPrint(IxEthAccMacAddr *m);
149 PRIVATE void
150 ixEthAccMacStateUpdate(IxEthAccPortId portId);
152 IxEthAccStatus
153 ixEthAccMacMemInit(void)
155 ixEthAccMacBase[IX_ETH_PORT_1] =
156 (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_0_BASE,
157 IX_OSAL_IXP400_ETHA_MAP_SIZE);
158 ixEthAccMacBase[IX_ETH_PORT_2] =
159 (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_1_BASE,
160 IX_OSAL_IXP400_ETHB_MAP_SIZE);
161 #ifdef __ixp46X
162 ixEthAccMacBase[IX_ETH_PORT_3] =
163 (UINT32) IX_OSAL_MEM_MAP(IX_ETH_ACC_MAC_2_BASE,
164 IX_OSAL_IXP400_ETH_NPEA_MAP_SIZE);
165 if (ixEthAccMacBase[IX_ETH_PORT_3] == 0)
167 ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
168 IX_OSAL_LOG_DEV_STDOUT,
169 "EthAcc: Could not map MAC I/O memory\n",
170 0, 0, 0, 0, 0 ,0);
172 return IX_ETH_ACC_FAIL;
174 #endif
176 if (ixEthAccMacBase[IX_ETH_PORT_1] == 0
177 || ixEthAccMacBase[IX_ETH_PORT_2] == 0)
179 ixOsalLog(IX_OSAL_LOG_LVL_FATAL,
180 IX_OSAL_LOG_DEV_STDOUT,
181 "EthAcc: Could not map MAC I/O memory\n",
182 0, 0, 0, 0, 0 ,0);
184 return IX_ETH_ACC_FAIL;
187 return IX_ETH_ACC_SUCCESS;
190 void
191 ixEthAccMacUnload(void)
193 IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_1]);
194 IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_2]);
195 #ifdef __ixp46X
196 IX_OSAL_MEM_UNMAP(ixEthAccMacBase[IX_ETH_PORT_3]);
197 ixEthAccMacBase[IX_ETH_PORT_3] = 0;
198 #endif
199 ixEthAccMacBase[IX_ETH_PORT_2] = 0;
200 ixEthAccMacBase[IX_ETH_PORT_1] = 0;
203 IxEthAccStatus
204 ixEthAccPortEnablePriv(IxEthAccPortId portId)
206 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
208 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
210 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0);
211 return IX_ETH_ACC_SUCCESS ;
214 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
216 printf("EthAcc: (Mac) cannot enable port %d, port not initialized\n", portId);
217 return (IX_ETH_ACC_PORT_UNINITIALIZED);
220 if (ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn == NULL)
222 /* TxDone callback not registered */
223 printf("EthAcc: (Mac) cannot enable port %d, TxDone callback not registered\n", portId);
224 return (IX_ETH_ACC_PORT_UNINITIALIZED);
227 if ((ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn == NULL)
228 && (ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn == NULL))
230 /* Receive callback not registered */
231 printf("EthAcc: (Mac) cannot enable port %d, Rx callback not registered\n", portId);
232 return (IX_ETH_ACC_PORT_UNINITIALIZED);
235 if(!ixEthAccMacState[portId].initDone)
237 printf("EthAcc: (Mac) cannot enable port %d, MAC address not set\n", portId);
238 return (IX_ETH_ACC_MAC_UNINITIALIZED);
241 /* if the state is being set to what it is already at, do nothing*/
242 if (ixEthAccMacState[portId].enabled)
244 return IX_ETH_ACC_SUCCESS;
247 #ifdef CONFIG_IXP425_COMPONENT_ETHDB
248 /* enable ethernet database for this port */
249 if (ixEthDBPortEnable(portId) != IX_ETH_DB_SUCCESS)
251 printf("EthAcc: (Mac) cannot enable port %d, EthDB failure\n", portId);
252 return IX_ETH_ACC_FAIL;
254 #endif
256 /* set the MAC core registers */
257 REG_WRITE(ixEthAccMacBase[portId],
258 IX_ETH_ACC_MAC_TX_CNTRL2,
259 IX_ETH_ACC_TX_CNTRL2_RETRIES_MASK);
261 REG_WRITE(ixEthAccMacBase[portId],
262 IX_ETH_ACC_MAC_RANDOM_SEED,
263 IX_ETH_ACC_RANDOM_SEED_DEFAULT);
265 REG_WRITE(ixEthAccMacBase[portId],
266 IX_ETH_ACC_MAC_THRESH_P_EMPTY,
267 IX_ETH_ACC_MAC_THRESH_P_EMPTY_DEFAULT);
269 REG_WRITE(ixEthAccMacBase[portId],
270 IX_ETH_ACC_MAC_THRESH_P_FULL,
271 IX_ETH_ACC_MAC_THRESH_P_FULL_DEFAULT);
273 REG_WRITE(ixEthAccMacBase[portId],
274 IX_ETH_ACC_MAC_TX_DEFER,
275 IX_ETH_ACC_MAC_TX_DEFER_DEFAULT);
277 REG_WRITE(ixEthAccMacBase[portId],
278 IX_ETH_ACC_MAC_TX_TWO_DEFER_1,
279 IX_ETH_ACC_MAC_TX_TWO_DEFER_1_DEFAULT);
281 REG_WRITE(ixEthAccMacBase[portId],
282 IX_ETH_ACC_MAC_TX_TWO_DEFER_2,
283 IX_ETH_ACC_MAC_TX_TWO_DEFER_2_DEFAULT);
285 REG_WRITE(ixEthAccMacBase[portId],
286 IX_ETH_ACC_MAC_SLOT_TIME,
287 IX_ETH_ACC_MAC_SLOT_TIME_DEFAULT);
289 REG_WRITE(ixEthAccMacBase[portId],
290 IX_ETH_ACC_MAC_INT_CLK_THRESH,
291 IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
293 REG_WRITE(ixEthAccMacBase[portId],
294 IX_ETH_ACC_MAC_BUF_SIZE_TX,
295 IX_ETH_ACC_MAC_BUF_SIZE_TX_DEFAULT);
297 REG_WRITE(ixEthAccMacBase[portId],
298 IX_ETH_ACC_MAC_TX_CNTRL1,
299 IX_ETH_ACC_TX_CNTRL1_DEFAULT);
301 REG_WRITE(ixEthAccMacBase[portId],
302 IX_ETH_ACC_MAC_RX_CNTRL1,
303 IX_ETH_ACC_RX_CNTRL1_DEFAULT);
305 /* set the global state */
306 ixEthAccMacState[portId].portDisableState = ACTIVE;
307 ixEthAccMacState[portId].enabled = TRUE;
309 /* rewrite the setup (including mac filtering) depending
310 * on current options
312 ixEthAccMacStateUpdate(portId);
314 return IX_ETH_ACC_SUCCESS;
318 * PortDisable local variables. They contain the intermediate steps
319 * while the port is being disabled and the buffers being drained out
320 * of the NPE.
322 typedef void (*IxEthAccPortDisableRx)(IxEthAccPortId portId,
323 IX_OSAL_MBUF * mBufPtr,
324 BOOL useMultiBufferCallback);
325 static IxEthAccPortRxCallback
326 ixEthAccPortDisableFn[IX_ETH_ACC_NUMBER_OF_PORTS];
327 static IxEthAccPortMultiBufferRxCallback
328 ixEthAccPortDisableMultiBufferFn[IX_ETH_ACC_NUMBER_OF_PORTS];
329 static IxEthAccPortDisableRx
330 ixEthAccPortDisableRxTable[IX_ETH_ACC_NUMBER_OF_PORTS];
331 static UINT32
332 ixEthAccPortDisableCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];
333 static UINT32
334 ixEthAccPortDisableMultiBufferCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];
336 static IxEthAccPortTxDoneCallback
337 ixEthAccPortDisableTxDoneFn[IX_ETH_ACC_NUMBER_OF_PORTS];
338 static UINT32
339 ixEthAccPortDisableTxDoneCbTag[IX_ETH_ACC_NUMBER_OF_PORTS];
341 static UINT32
342 ixEthAccPortDisableUserBufferCount[IX_ETH_ACC_NUMBER_OF_PORTS];
345 * PortDisable private callbacks functions. They handle the user
346 * traffic, and the special buffers (one for tx, one for rx) used
347 * in portDisable.
349 PRIVATE void
350 ixEthAccPortDisableTxDone(UINT32 cbTag,
351 IX_OSAL_MBUF *mbuf)
353 IxEthAccPortId portId = (IxEthAccPortId)cbTag;
354 volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState;
356 /* check for the special mbuf used in portDisable */
357 if (mbuf == ixEthAccMacState[portId].portDisableTxMbufPtr)
359 *txState = TRANSMIT_DONE;
361 else
363 /* increment the count of user traffic during portDisable */
364 ixEthAccPortDisableUserBufferCount[portId]++;
366 /* call client TxDone function */
367 ixEthAccPortDisableTxDoneFn[portId](ixEthAccPortDisableTxDoneCbTag[portId], mbuf);
371 PRIVATE IxEthAccStatus
372 ixEthAccPortDisableTryTransmit(UINT32 portId)
374 int key;
375 IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
376 volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState;
377 /* transmit the special buffer again if it is transmitted
378 * and update the txState
379 * This section is protected because the portDisable context
380 * run an identical code, so the system keeps transmitting at the
381 * maximum rate.
383 key = ixOsalIrqLock();
384 if (*txState == TRANSMIT_DONE)
386 IX_OSAL_MBUF *mbufTxPtr = ixEthAccMacState[portId].portDisableTxMbufPtr;
387 *txState = TRANSMIT;
388 status = ixEthAccPortTxFrameSubmit(portId,
389 mbufTxPtr,
390 IX_ETH_ACC_TX_DEFAULT_PRIORITY);
392 ixOsalIrqUnlock(key);
394 return status;
397 PRIVATE void
398 ixEthAccPortDisableTxDoneAndSubmit(UINT32 cbTag,
399 IX_OSAL_MBUF *mbuf)
401 IxEthAccPortId portId = (IxEthAccPortId)cbTag;
403 /* call the callback which forwards the traffic to the client */
404 ixEthAccPortDisableTxDone(cbTag, mbuf);
406 /* try to transmit the buffer used in portDisable
407 * if seen in TxDone
409 ixEthAccPortDisableTryTransmit(portId);
412 PRIVATE void
413 ixEthAccPortDisableRx (IxEthAccPortId portId,
414 IX_OSAL_MBUF * mBufPtr,
415 BOOL useMultiBufferCallback)
417 volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState;
418 IX_OSAL_MBUF *mNextPtr;
420 while (mBufPtr)
422 mNextPtr = IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr);
423 IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(mBufPtr) = NULL;
425 /* check for the special mbuf used in portDisable */
426 if (mBufPtr == ixEthAccMacState[portId].portDisableRxMbufPtr)
428 *rxState = RECEIVE;
430 else
432 /* increment the count of user traffic during portDisable */
433 ixEthAccPortDisableUserBufferCount[portId]++;
435 /* reset the received payload length during portDisable */
436 IX_OSAL_MBUF_MLEN(mBufPtr) = 0;
437 IX_OSAL_MBUF_PKT_LEN(mBufPtr) = 0;
439 if (useMultiBufferCallback)
441 /* call the user callback with one unchained
442 * buffer, without payload. A small array is built
443 * to be used as a parameter (the user callback expects
444 * to receive an array ended by a NULL pointer.
446 IX_OSAL_MBUF *mBufPtrArray[2];
448 mBufPtrArray[0] = mBufPtr;
449 mBufPtrArray[1] = NULL;
450 ixEthAccPortDisableMultiBufferFn[portId](
451 ixEthAccPortDisableMultiBufferCbTag[portId],
452 mBufPtrArray);
454 else
456 /* call the user callback with a unchained
457 * buffer, without payload and the destination port is
458 * unknown.
460 ixEthAccPortDisableFn[portId](
461 ixEthAccPortDisableCbTag[portId],
462 mBufPtr,
463 IX_ETH_DB_UNKNOWN_PORT /* port not found */);
467 mBufPtr = mNextPtr;
471 PRIVATE IxEthAccStatus
472 ixEthAccPortDisableTryReplenish(UINT32 portId)
474 int key;
475 IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
476 volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState;
477 /* replenish with the special buffer again if it is received
478 * and update the rxState
479 * This section is protected because the portDisable context
480 * run an identical code, so the system keeps replenishing at the
481 * maximum rate.
483 key = ixOsalIrqLock();
484 if (*rxState == RECEIVE)
486 IX_OSAL_MBUF *mbufRxPtr = ixEthAccMacState[portId].portDisableRxMbufPtr;
487 *rxState = REPLENISH;
488 IX_OSAL_MBUF_MLEN(mbufRxPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE;
489 status = ixEthAccPortRxFreeReplenish(portId, mbufRxPtr);
491 ixOsalIrqUnlock(key);
493 return status;
496 PRIVATE void
497 ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId,
498 IX_OSAL_MBUF * mBufPtr,
499 BOOL useMultiBufferCallback)
501 /* call the callback which forwards the traffic to the client */
502 ixEthAccPortDisableRx(portId, mBufPtr, useMultiBufferCallback);
504 /* try to replenish with the buffer used in portDisable
505 * if seen in Rx
507 ixEthAccPortDisableTryReplenish(portId);
510 PRIVATE void
511 ixEthAccPortDisableRxCallback (UINT32 cbTag,
512 IX_OSAL_MBUF * mBufPtr,
513 UINT32 learnedPortId)
515 IxEthAccPortId portId = (IxEthAccPortId)cbTag;
517 /* call the portDisable receive callback */
518 (ixEthAccPortDisableRxTable[portId])(portId, mBufPtr, FALSE);
521 PRIVATE void
522 ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag,
523 IX_OSAL_MBUF **mBufPtr)
525 IxEthAccPortId portId = (IxEthAccPortId)cbTag;
527 while (*mBufPtr)
529 /* call the portDisable receive callback with one buffer at a time */
530 (ixEthAccPortDisableRxTable[portId])(portId, *mBufPtr++, TRUE);
534 IxEthAccStatus
535 ixEthAccPortDisablePriv(IxEthAccPortId portId)
537 IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
538 int key;
539 int retry, retryTimeout;
540 volatile IxEthAccPortDisableState *state = &ixEthAccMacState[portId].portDisableState;
541 volatile IxEthAccPortDisableState *rxState = &ixEthAccMacState[portId].rxState;
542 volatile IxEthAccPortDisableState *txState = &ixEthAccMacState[portId].txState;
544 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
546 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
548 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable port.\n",(INT32)portId,0,0,0,0,0);
549 return IX_ETH_ACC_SUCCESS ;
552 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
554 return (IX_ETH_ACC_PORT_UNINITIALIZED);
557 /* if the state is being set to what it is already at, do nothing */
558 if (!ixEthAccMacState[portId].enabled)
560 return IX_ETH_ACC_SUCCESS;
563 *state = DISABLED;
565 /* disable MAC receive first */
566 ixEthAccPortRxDisablePriv(portId);
568 #ifdef CONFIG_IXP425_COMPONENT_ETHDB
569 /* disable ethernet database for this port - It is done now to avoid
570 * issuing ELT maintenance after requesting 'port disable' in an NPE
572 if (ixEthDBPortDisable(portId) != IX_ETH_DB_SUCCESS)
574 status = IX_ETH_ACC_FAIL;
575 IX_ETH_ACC_FATAL_LOG("ixEthAccPortDisable: failed to disable EthDB for this port\n", 0, 0, 0, 0, 0, 0);
577 #endif
579 /* enter the critical section */
580 key = ixOsalIrqLock();
582 /* swap the Rx and TxDone callbacks */
583 ixEthAccPortDisableFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn;
584 ixEthAccPortDisableMultiBufferFn[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn;
585 ixEthAccPortDisableCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag;
586 ixEthAccPortDisableMultiBufferCbTag[portId] = ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag;
587 ixEthAccPortDisableTxDoneFn[portId] = ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn;
588 ixEthAccPortDisableTxDoneCbTag[portId] = ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag;
589 ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRx;
591 /* register temporary callbacks */
592 ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = ixEthAccPortDisableRxCallback;
593 ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = portId;
595 ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferRxCallback;
596 ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = portId;
598 ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = ixEthAccPortDisableTxDone;
599 ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = portId;
601 /* initialise the Rx state and Tx states */
602 *txState = TRANSMIT_DONE;
603 *rxState = RECEIVE;
605 /* exit the critical section */
606 ixOsalIrqUnlock(key);
608 /* enable a NPE loopback */
609 if (ixEthAccNpeLoopbackEnablePriv(portId) != IX_ETH_ACC_SUCCESS)
611 status = IX_ETH_ACC_FAIL;
614 if (status == IX_ETH_ACC_SUCCESS)
616 retry = 0;
618 /* Step 1 : Drain Tx traffic and TxDone queues :
620 * Transmit and replenish at least once with the
621 * special buffers until both of them are seen
622 * in the callback hook
624 * (the receive callback keeps replenishing, so once we see
625 * the special Tx buffer, we can be sure that Tx drain is complete)
627 ixEthAccPortDisableRxTable[portId]
628 = ixEthAccPortDisableRxAndReplenish;
629 ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn
630 = ixEthAccPortDisableTxDone;
634 /* keep replenishing */
635 status = ixEthAccPortDisableTryReplenish(portId);
636 if (status == IX_ETH_ACC_SUCCESS)
638 /* keep transmitting */
639 status = ixEthAccPortDisableTryTransmit(portId);
641 if (status == IX_ETH_ACC_SUCCESS)
643 /* wait for some traffic being processed */
644 ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
647 while ((status == IX_ETH_ACC_SUCCESS)
648 && (retry++ < IX_ETH_ACC_MAX_RETRY)
649 && (*txState == TRANSMIT));
651 /* Step 2 : Drain Rx traffic, RxFree and Rx queues :
653 * Transmit and replenish at least once with the
654 * special buffers until both of them are seen
655 * in the callback hook
656 * (the transmit callback keeps transmitting, and when we see
657 * the special Rx buffer, we can be sure that rxFree drain
658 * is complete)
660 * The nested loop helps to retry if the user was keeping
661 * replenishing or transmitting during portDisable.
663 * The 2 nested loops ensure more retries if user traffic is
664 * seen during portDisable : the user should not replenish
665 * or transmit while portDisable is running. However, because of
666 * the queueing possibilities in ethAcc dataplane, it is possible
667 * that a lot of traffic is left in the queues (e.g. when
668 * transmitting over a low speed link) and therefore, more
669 * retries are allowed to help flushing the buffers out.
671 ixEthAccPortDisableRxTable[portId]
672 = ixEthAccPortDisableRx;
673 ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn
674 = ixEthAccPortDisableTxDoneAndSubmit;
680 ixEthAccPortDisableUserBufferCount[portId] = 0;
682 /* keep replenishing */
683 status = ixEthAccPortDisableTryReplenish(portId);
684 if (status == IX_ETH_ACC_SUCCESS)
686 /* keep transmitting */
687 status = ixEthAccPortDisableTryTransmit(portId);
689 if (status == IX_ETH_ACC_SUCCESS)
691 /* wait for some traffic being processed */
692 ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
695 while ((status == IX_ETH_ACC_SUCCESS)
696 && (retry++ < IX_ETH_ACC_MAX_RETRY)
697 && ((ixEthAccPortDisableUserBufferCount[portId] != 0)
698 || (*rxState == REPLENISH)));
700 /* After the first iteration, change the receive callbacks,
701 * to process only 1 buffer at a time
703 ixEthAccPortDisableRxTable[portId]
704 = ixEthAccPortDisableRx;
705 ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn
706 = ixEthAccPortDisableTxDone;
708 /* repeat the whole process while user traffic is seen in TxDone
710 * The conditions to stop the loop are
711 * - Xscale has both Rx and Tx special buffers
712 * (txState = transmit, rxState = receive)
713 * - any error in txSubmit or rxReplenish
714 * - no user traffic seen
715 * - an excessive amount of retries
718 while ((status == IX_ETH_ACC_SUCCESS)
719 && (retry < IX_ETH_ACC_MAX_RETRY)
720 && (*txState == TRANSMIT));
722 /* check the loop exit conditions. The NPE should not hold
723 * the special buffers.
725 if ((*rxState == REPLENISH) || (*txState == TRANSMIT))
727 status = IX_ETH_ACC_FAIL;
730 if (status == IX_ETH_ACC_SUCCESS)
732 /* Step 3 : Replenish without transmitting until a timeout
733 * occurs, in order to drain the internal NPE fifos
735 * we can expect a few frames srill held
736 * in the NPE.
738 * The 2 nested loops take care about the NPE dropping traffic
739 * (including loopback traffic) when the Rx queue is full.
741 * The timeout value is very conservative
742 * since the loopback used keeps replenishhing.
747 ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRxAndReplenish;
748 ixEthAccPortDisableUserBufferCount[portId] = 0;
749 retryTimeout = 0;
752 /* keep replenishing */
753 status = ixEthAccPortDisableTryReplenish(portId);
754 if (status == IX_ETH_ACC_SUCCESS)
756 /* wait for some traffic being processed */
757 ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
760 while ((status == IX_ETH_ACC_SUCCESS)
761 && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT));
763 /* Step 4 : Transmit once. Stop replenish
765 * After the Rx timeout, we are sure that the NPE does not
766 * hold any frame in its internal NPE fifos.
768 * At this point, the NPE still holds the last rxFree buffer.
769 * By transmitting a single frame, this should unblock the
770 * last rxFree buffer. This code just transmit once and
771 * wait for both frames seen in TxDone and in rxFree.
774 ixEthAccPortDisableRxTable[portId] = ixEthAccPortDisableRx;
775 status = ixEthAccPortDisableTryTransmit(portId);
777 /* the NPE should immediatelyt release
778 * the last Rx buffer and the last transmitted buffer
779 * unless the last Tx frame was dropped (rx queue full)
781 if (status == IX_ETH_ACC_SUCCESS)
783 retryTimeout = 0;
786 ixOsalSleep(IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS);
788 while ((*rxState == REPLENISH)
789 && (retryTimeout++ < IX_ETH_ACC_MAX_RETRY_TIMEOUT));
792 /* the NPE may have dropped the traffic because of Rx
793 * queue being full. This code ensures that the last
794 * Tx and Rx frames are both received.
797 while ((status == IX_ETH_ACC_SUCCESS)
798 && (retry++ < IX_ETH_ACC_MAX_RETRY)
799 && ((*txState == TRANSMIT)
800 || (*rxState == REPLENISH)
801 || (ixEthAccPortDisableUserBufferCount[portId] != 0)));
803 /* Step 5 : check the final states : the NPE has
804 * no buffer left, nor in Tx , nor in Rx directions.
806 if ((*rxState == REPLENISH) || (*txState == TRANSMIT))
808 status = IX_ETH_ACC_FAIL;
812 /* now all the buffers are drained, disable NPE loopback
813 * This is done regardless of the logic to drain the queues and
814 * the internal buffers held by the NPE.
816 if (ixEthAccNpeLoopbackDisablePriv(portId) != IX_ETH_ACC_SUCCESS)
818 status = IX_ETH_ACC_FAIL;
822 /* disable MAC Tx and Rx services */
823 ixEthAccMacState[portId].enabled = FALSE;
824 ixEthAccMacStateUpdate(portId);
826 /* restore the Rx and TxDone callbacks (within a critical section) */
827 key = ixOsalIrqLock();
829 ixEthAccPortData[portId].ixEthAccRxData.rxCallbackFn = ixEthAccPortDisableFn[portId];
830 ixEthAccPortData[portId].ixEthAccRxData.rxCallbackTag = ixEthAccPortDisableCbTag[portId];
831 ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackFn = ixEthAccPortDisableMultiBufferFn[portId];
832 ixEthAccPortData[portId].ixEthAccRxData.rxMultiBufferCallbackTag = ixEthAccPortDisableMultiBufferCbTag[portId];
833 ixEthAccPortData[portId].ixEthAccTxData.txBufferDoneCallbackFn = ixEthAccPortDisableTxDoneFn[portId];
834 ixEthAccPortData[portId].ixEthAccTxData.txCallbackTag = ixEthAccPortDisableTxDoneCbTag[portId];
836 ixOsalIrqUnlock(key);
838 /* the MAC core rx/tx disable may left the MAC hardware in an
839 * unpredictable state. A hw reset is executed before resetting
840 * all the MAC parameters to a known value.
842 REG_WRITE(ixEthAccMacBase[portId],
843 IX_ETH_ACC_MAC_CORE_CNTRL,
844 IX_ETH_ACC_CORE_RESET);
846 ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY);
848 /* rewrite all parameters to their current value */
849 ixEthAccMacStateUpdate(portId);
851 REG_WRITE(ixEthAccMacBase[portId],
852 IX_ETH_ACC_MAC_INT_CLK_THRESH,
853 IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
855 REG_WRITE(ixEthAccMacBase[portId],
856 IX_ETH_ACC_MAC_CORE_CNTRL,
857 IX_ETH_ACC_CORE_MDC_EN);
859 return status;
862 IxEthAccStatus
863 ixEthAccPortEnabledQueryPriv(IxEthAccPortId portId, BOOL *enabled)
865 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
867 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
869 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable port.\n",(INT32)portId,0,0,0,0,0);
871 /* Since Eth NPE is not available, port must be disabled */
872 *enabled = FALSE ;
873 return IX_ETH_ACC_SUCCESS ;
876 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
878 /* Since Eth NPE is not available, port must be disabled */
879 *enabled = FALSE ;
880 return (IX_ETH_ACC_PORT_UNINITIALIZED);
883 *enabled = ixEthAccMacState[portId].enabled;
885 return IX_ETH_ACC_SUCCESS;
888 IxEthAccStatus
889 ixEthAccPortMacResetPriv(IxEthAccPortId portId)
891 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
893 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
895 IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot reset Ethernet coprocessor.\n",(INT32)portId,0,0,0,0,0);
896 return IX_ETH_ACC_SUCCESS ;
899 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
901 return (IX_ETH_ACC_PORT_UNINITIALIZED);
904 REG_WRITE(ixEthAccMacBase[portId],
905 IX_ETH_ACC_MAC_CORE_CNTRL,
906 IX_ETH_ACC_CORE_RESET);
908 ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY);
910 /* rewrite all parameters to their current value */
911 ixEthAccMacStateUpdate(portId);
913 REG_WRITE(ixEthAccMacBase[portId],
914 IX_ETH_ACC_MAC_INT_CLK_THRESH,
915 IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
917 REG_WRITE(ixEthAccMacBase[portId],
918 IX_ETH_ACC_MAC_CORE_CNTRL,
919 IX_ETH_ACC_CORE_MDC_EN);
921 return IX_ETH_ACC_SUCCESS;
924 IxEthAccStatus
925 ixEthAccPortLoopbackEnable(IxEthAccPortId portId)
927 UINT32 regval;
929 /* Turn off promiscuous mode */
930 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
932 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
934 IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable loopback.\n",(INT32)portId,0,0,0,0,0);
935 return IX_ETH_ACC_SUCCESS ;
938 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
940 return (IX_ETH_ACC_PORT_UNINITIALIZED);
943 /* read register */
944 REG_READ(ixEthAccMacBase[portId],
945 IX_ETH_ACC_MAC_RX_CNTRL1,
946 regval);
948 /* update register */
949 REG_WRITE(ixEthAccMacBase[portId],
950 IX_ETH_ACC_MAC_RX_CNTRL1,
951 regval | IX_ETH_ACC_RX_CNTRL1_LOOP_EN);
953 return IX_ETH_ACC_SUCCESS;
956 PRIVATE void
957 ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId,
958 IxNpeMhMessage msg)
960 IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
962 #ifndef NDEBUG
963 /* Prudent to at least check the port is within range */
964 if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
966 IX_ETH_ACC_FATAL_LOG("IXETHACC:ixEthAccPortDisableMessageCallback: Illegal port: %u\n",
967 (UINT32) portId, 0, 0, 0, 0, 0);
969 return;
971 #endif
973 /* unlock message reception mutex */
974 ixOsalMutexUnlock(&ixEthAccMacState[portId].npeLoopbackMessageLock);
977 IxEthAccStatus
978 ixEthAccNpeLoopbackEnablePriv(IxEthAccPortId portId)
980 IX_STATUS npeMhStatus;
981 IxNpeMhMessage message;
982 IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
984 /* Turn off promiscuous mode */
985 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
987 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
989 IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0);
990 return IX_ETH_ACC_SUCCESS ;
993 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
995 return (IX_ETH_ACC_PORT_UNINITIALIZED);
998 /* enable NPE loopback (lsb of the message contains the value 1) */
999 message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL)
1000 | 0x01;
1001 message.data[1] = 0;
1003 npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
1004 message,
1005 IX_ETHNPE_SETLOOPBACK_MODE_ACK,
1006 ixEthAccNpeLoopbackMessageCallback,
1007 IX_NPEMH_SEND_RETRIES_DEFAULT);
1009 if (npeMhStatus != IX_SUCCESS)
1011 status = IX_ETH_ACC_FAIL;
1013 else
1015 /* wait for NPE loopbackEnable response */
1016 if (ixOsalMutexLock(&ixEthAccMacState[portId]. npeLoopbackMessageLock,
1017 IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS)
1018 != IX_SUCCESS)
1020 status = IX_ETH_ACC_FAIL;
1024 return status;
1027 IxEthAccStatus
1028 ixEthAccPortTxEnablePriv(IxEthAccPortId portId)
1030 UINT32 regval;
1032 /* Turn off promiscuous mode */
1033 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1035 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1037 IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable TX.\n",(INT32)portId,0,0,0,0,0);
1038 return IX_ETH_ACC_SUCCESS ;
1041 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1043 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1046 /* read register */
1047 REG_READ(ixEthAccMacBase[portId],
1048 IX_ETH_ACC_MAC_TX_CNTRL1,
1049 regval);
1051 /* update register */
1052 REG_WRITE(ixEthAccMacBase[portId],
1053 IX_ETH_ACC_MAC_TX_CNTRL1,
1054 regval | IX_ETH_ACC_TX_CNTRL1_TX_EN);
1056 return IX_ETH_ACC_SUCCESS;
1059 IxEthAccStatus
1060 ixEthAccPortRxEnablePriv(IxEthAccPortId portId)
1062 UINT32 regval;
1064 /* Turn off promiscuous mode */
1065 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1067 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1069 IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable RX.\n",(INT32)portId,0,0,0,0,0);
1070 return IX_ETH_ACC_SUCCESS ;
1073 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1075 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1078 /* read register */
1079 REG_READ(ixEthAccMacBase[portId],
1080 IX_ETH_ACC_MAC_RX_CNTRL1,
1081 regval);
1083 /* update register */
1084 REG_WRITE(ixEthAccMacBase[portId],
1085 IX_ETH_ACC_MAC_RX_CNTRL1,
1086 regval | IX_ETH_ACC_RX_CNTRL1_RX_EN);
1088 return IX_ETH_ACC_SUCCESS;
1091 IxEthAccStatus
1092 ixEthAccPortLoopbackDisable(IxEthAccPortId portId)
1094 UINT32 regval;
1096 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1098 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1100 IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable loopback.\n",(INT32)portId,0,0,0,0,0);
1101 return IX_ETH_ACC_SUCCESS ;
1104 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1106 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1109 /*disable MAC loopabck */
1110 REG_READ(ixEthAccMacBase[portId],
1111 IX_ETH_ACC_MAC_RX_CNTRL1,
1112 regval);
1114 REG_WRITE(ixEthAccMacBase[portId],
1115 IX_ETH_ACC_MAC_RX_CNTRL1,
1116 (regval & ~IX_ETH_ACC_RX_CNTRL1_LOOP_EN));
1118 return IX_ETH_ACC_SUCCESS;
1121 IxEthAccStatus
1122 ixEthAccNpeLoopbackDisablePriv(IxEthAccPortId portId)
1124 IX_STATUS npeMhStatus;
1125 IxNpeMhMessage message;
1126 IxEthAccStatus status = IX_ETH_ACC_SUCCESS;
1128 /* Turn off promiscuous mode */
1129 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1131 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1133 IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot enable NPE loopback.\n",(INT32)portId,0,0,0,0,0);
1134 return IX_ETH_ACC_SUCCESS ;
1137 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1139 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1142 /* disable NPE loopback (lsb of the message contains the value 0) */
1143 message.data[0] = (IX_ETHNPE_SETLOOPBACK_MODE << IX_ETH_ACC_MAC_MSGID_SHL);
1144 message.data[1] = 0;
1146 npeMhStatus = ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
1147 message,
1148 IX_ETHNPE_SETLOOPBACK_MODE_ACK,
1149 ixEthAccNpeLoopbackMessageCallback,
1150 IX_NPEMH_SEND_RETRIES_DEFAULT);
1152 if (npeMhStatus != IX_SUCCESS)
1154 status = IX_ETH_ACC_FAIL;
1156 else
1158 /* wait for NPE loopbackEnable response */
1159 if (ixOsalMutexLock(&ixEthAccMacState[portId].npeLoopbackMessageLock,
1160 IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS)
1161 != IX_SUCCESS)
1163 status = IX_ETH_ACC_FAIL;
1167 return status;
1170 IxEthAccStatus
1171 ixEthAccPortTxDisablePriv(IxEthAccPortId portId)
1173 UINT32 regval;
1175 /* Turn off promiscuous mode */
1176 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1178 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1180 IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable TX.\n", (INT32)portId,0,0,0,0,0);
1181 return IX_ETH_ACC_SUCCESS ;
1184 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1186 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1189 /* read register */
1190 REG_READ(ixEthAccMacBase[portId],
1191 IX_ETH_ACC_MAC_TX_CNTRL1,
1192 regval);
1194 /* update register */
1195 REG_WRITE(ixEthAccMacBase[portId],
1196 IX_ETH_ACC_MAC_TX_CNTRL1,
1197 (regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN));
1199 return IX_ETH_ACC_SUCCESS;
1202 IxEthAccStatus
1203 ixEthAccPortRxDisablePriv(IxEthAccPortId portId)
1205 UINT32 regval;
1207 /* Turn off promiscuous mode */
1208 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1210 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1212 IX_ETH_ACC_WARNING_LOG("EthAcc: Eth %d: Cannot disable RX.\n", (INT32)portId,0,0,0,0,0);
1213 return IX_ETH_ACC_SUCCESS ;
1216 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1218 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1221 /* read register */
1222 REG_READ(ixEthAccMacBase[portId],
1223 IX_ETH_ACC_MAC_RX_CNTRL1,
1224 regval);
1226 /* update register */
1227 REG_WRITE(ixEthAccMacBase[portId],
1228 IX_ETH_ACC_MAC_RX_CNTRL1,
1229 (regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN));
1231 return IX_ETH_ACC_SUCCESS;
1234 IxEthAccStatus
1235 ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId)
1237 UINT32 regval;
1239 /* Turn off promiscuous mode */
1240 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1242 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1244 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear promiscuous mode.\n",(INT32)portId,0,0,0,0,0);
1245 return IX_ETH_ACC_SUCCESS ;
1248 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1250 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1253 /*set bit 5 of Rx control 1 - enable address filtering*/
1254 REG_READ(ixEthAccMacBase[portId],
1255 IX_ETH_ACC_MAC_RX_CNTRL1,
1256 regval);
1258 REG_WRITE(ixEthAccMacBase[portId],
1259 IX_ETH_ACC_MAC_RX_CNTRL1,
1260 regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN);
1262 ixEthAccMacState[portId].promiscuous = FALSE;
1264 ixEthAccMulticastAddressSet(portId);
1266 return IX_ETH_ACC_SUCCESS;
1269 IxEthAccStatus
1270 ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId)
1272 UINT32 regval;
1274 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1276 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1278 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set promiscuous mode.\n",(INT32)portId,0,0,0,0,0);
1279 return IX_ETH_ACC_SUCCESS ;
1282 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1284 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1288 * Set bit 5 of Rx control 1 - We enable address filtering even in
1289 * promiscuous mode because we want the MAC to set the appropriate
1290 * bits in m_flags which doesn't happen if we turn off filtering.
1292 REG_READ(ixEthAccMacBase[portId],
1293 IX_ETH_ACC_MAC_RX_CNTRL1,
1294 regval);
1296 REG_WRITE(ixEthAccMacBase[portId],
1297 IX_ETH_ACC_MAC_RX_CNTRL1,
1298 regval | IX_ETH_ACC_RX_CNTRL1_ADDR_FLTR_EN);
1300 ixEthAccMacState[portId].promiscuous = TRUE;
1302 ixEthAccMulticastAddressSet(portId);
1304 return IX_ETH_ACC_SUCCESS;
1307 IxEthAccStatus
1308 ixEthAccPortUnicastMacAddressSetPriv (IxEthAccPortId portId,
1309 IxEthAccMacAddr *macAddr)
1311 UINT32 i;
1313 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1315 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1317 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0);
1318 return IX_ETH_ACC_SUCCESS ;
1321 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1323 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1327 if (macAddr == NULL)
1329 return IX_ETH_ACC_FAIL;
1332 if ( macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT )
1334 /* This is a multicast/broadcast address cant set it ! */
1335 return IX_ETH_ACC_FAIL;
1338 if ( macAddr->macAddress[0] == 0 &&
1339 macAddr->macAddress[1] == 0 &&
1340 macAddr->macAddress[2] == 0 &&
1341 macAddr->macAddress[3] == 0 &&
1342 macAddr->macAddress[4] == 0 &&
1343 macAddr->macAddress[5] == 0 )
1345 /* This is an invalid mac address cant set it ! */
1346 return IX_ETH_ACC_FAIL;
1349 #ifdef CONFIG_IXP425_COMPONENT_ETHDB
1350 /* update the MAC address in the ethernet database */
1351 if (ixEthDBPortAddressSet(portId, (IxEthDBMacAddr *) macAddr) != IX_ETH_DB_SUCCESS)
1353 return IX_ETH_ACC_FAIL;
1355 #endif
1357 /*Set the Unicast MAC to the specified value*/
1358 for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
1360 REG_WRITE(ixEthAccMacBase[portId],
1361 IX_ETH_ACC_MAC_UNI_ADDR_1 + i*sizeof(UINT32),
1362 macAddr->macAddress[i]);
1364 ixEthAccMacState[portId].initDone = TRUE;
1366 return IX_ETH_ACC_SUCCESS;
1369 IxEthAccStatus
1370 ixEthAccPortUnicastMacAddressGetPriv (IxEthAccPortId portId,
1371 IxEthAccMacAddr *macAddr)
1373 /*Return the current value of the Unicast MAC from h/w
1374 for the specified port*/
1375 UINT32 i;
1377 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1379 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1381 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get Unicast Mac Address.\n",(INT32)portId,0,0,0,0,0);
1382 /* Since Eth Npe is unavailable, return invalid MAC Address = 00:00:00:00:00:00 */
1383 for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
1385 macAddr->macAddress[i] = 0;
1387 return IX_ETH_ACC_SUCCESS ;
1390 if(!ixEthAccMacState[portId].initDone)
1392 return (IX_ETH_ACC_MAC_UNINITIALIZED);
1395 if (macAddr == NULL)
1397 return IX_ETH_ACC_FAIL;
1401 for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
1403 REG_READ(ixEthAccMacBase[portId],
1404 IX_ETH_ACC_MAC_UNI_ADDR_1 + i*sizeof(UINT32),
1405 macAddr->macAddress[i]);
1407 return IX_ETH_ACC_SUCCESS;
1410 PRIVATE IxEthAccStatus
1411 ixEthAccPortMulticastMacAddressGet (IxEthAccPortId portId,
1412 IxEthAccMacAddr *macAddr)
1414 /*Return the current value of the Multicast MAC from h/w
1415 for the specified port*/
1416 UINT32 i;
1418 for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
1421 REG_READ(ixEthAccMacBase[portId],
1422 IX_ETH_ACC_MAC_ADDR_1 + i*sizeof(UINT32),
1423 macAddr->macAddress[i]);
1426 return IX_ETH_ACC_SUCCESS;
1429 PRIVATE IxEthAccStatus
1430 ixEthAccPortMulticastMacFilterGet (IxEthAccPortId portId,
1431 IxEthAccMacAddr *macAddr)
1433 /*Return the current value of the Multicast MAC from h/w
1434 for the specified port*/
1435 UINT32 i;
1437 for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
1440 REG_READ(ixEthAccMacBase[portId],
1441 IX_ETH_ACC_MAC_ADDR_MASK_1 + i*sizeof(UINT32),
1442 macAddr->macAddress[i]);
1444 return IX_ETH_ACC_SUCCESS;
1447 IxEthAccStatus
1448 ixEthAccPortMulticastAddressJoinPriv (IxEthAccPortId portId,
1449 IxEthAccMacAddr *macAddr)
1451 UINT32 i;
1452 IxEthAccMacAddr broadcastAddr = {{0xff,0xff,0xff,0xff,0xff,0xff}};
1454 /*Check that the port parameter is valid*/
1455 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1457 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1459 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join Multicast Mac Address.\n",(INT32)portId,0,0,0,0,0);
1460 return IX_ETH_ACC_SUCCESS ;
1463 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1465 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1468 /*Check that the mac address is valid*/
1469 if(macAddr == NULL)
1471 return IX_ETH_ACC_FAIL;
1474 /* Check that this is a multicast address */
1475 if (!(macAddr->macAddress[0] & IX_ETH_ACC_ETH_MAC_BCAST_MCAST_BIT))
1477 return IX_ETH_ACC_FAIL;
1480 /* We don't add the Broadcast address */
1481 if(ixEthAccMacEqual(&broadcastAddr, macAddr))
1483 return IX_ETH_ACC_FAIL;
1486 for (i = 0;
1487 i<ixEthAccMacState[portId].mcastAddrIndex;
1488 i++)
1490 /*Check if the current entry already match an existing matches*/
1491 if(ixEthAccMacEqual(&ixEthAccMacState[portId].mcastAddrsTable[i], macAddr))
1493 /* Address found in the list and already configured,
1494 * return a success status
1496 return IX_ETH_ACC_SUCCESS;
1500 /* check for availability at the end of the current table */
1501 if(ixEthAccMacState[portId].mcastAddrIndex >= IX_ETH_ACC_MAX_MULTICAST_ADDRESSES)
1503 return IX_ETH_ACC_FAIL;
1506 /*First add the address to the multicast table for the
1507 specified port*/
1508 i=ixEthAccMacState[portId].mcastAddrIndex;
1510 memcpy(&ixEthAccMacState[portId].mcastAddrsTable[i],
1511 &macAddr->macAddress,
1512 IX_IEEE803_MAC_ADDRESS_SIZE);
1514 /*Increment the index into the table, this must be done here
1515 as MulticastAddressSet below needs to know about the latest
1516 entry.
1518 ixEthAccMacState[portId].mcastAddrIndex++;
1520 /*Then calculate the new value to be written to the address and
1521 address mask registers*/
1522 ixEthAccMulticastAddressSet(portId);
1524 return IX_ETH_ACC_SUCCESS;
1528 IxEthAccStatus
1529 ixEthAccPortMulticastAddressJoinAllPriv (IxEthAccPortId portId)
1531 IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}};
1533 /*Check that the port parameter is valid*/
1534 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1536 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1538 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot join all Multicast Address.\n",(INT32)portId,0,0,0,0,0);
1539 return IX_ETH_ACC_SUCCESS ;
1542 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1544 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1547 /* remove all entries from the database and
1548 * insert a multicast entry
1550 memcpy(&ixEthAccMacState[portId].mcastAddrsTable[0],
1551 &mcastMacAddr.macAddress,
1552 IX_IEEE803_MAC_ADDRESS_SIZE);
1554 ixEthAccMacState[portId].mcastAddrIndex = 1;
1555 ixEthAccMacState[portId].joinAll = TRUE;
1557 ixEthAccMulticastAddressSet(portId);
1559 return IX_ETH_ACC_SUCCESS;
1562 IxEthAccStatus
1563 ixEthAccPortMulticastAddressLeavePriv (IxEthAccPortId portId,
1564 IxEthAccMacAddr *macAddr)
1566 UINT32 i;
1567 IxEthAccMacAddr mcastMacAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}};
1569 /*Check that the port parameter is valid*/
1570 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1572 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1574 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot leave Multicast Address.\n",(INT32)portId,0,0,0,0,0);
1575 return IX_ETH_ACC_SUCCESS ;
1578 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1580 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1583 /*Check that the mac address is valid*/
1584 if(macAddr == NULL)
1586 return IX_ETH_ACC_FAIL;
1588 /* Remove this mac address from the mask for the specified port
1589 * we copy down all entries above the blanked entry, and
1590 * decrement the index
1592 i=0;
1594 while(i<ixEthAccMacState[portId].mcastAddrIndex)
1596 /*Check if the current entry matches*/
1597 if(ixEthAccMacEqual(&ixEthAccMacState[portId].mcastAddrsTable[i],
1598 macAddr))
1600 if(ixEthAccMacEqual(macAddr, &mcastMacAddr))
1602 ixEthAccMacState[portId].joinAll = FALSE;
1604 /*Decrement the index into the multicast address table
1605 for the current port*/
1606 ixEthAccMacState[portId].mcastAddrIndex--;
1608 /*Copy down all entries above the current entry*/
1609 while(i<ixEthAccMacState[portId].mcastAddrIndex)
1611 memcpy(&ixEthAccMacState[portId].mcastAddrsTable[i],
1612 &ixEthAccMacState[portId].mcastAddrsTable[i+1],
1613 IX_IEEE803_MAC_ADDRESS_SIZE);
1614 i++;
1616 /*recalculate the mask and write it to the MAC*/
1617 ixEthAccMulticastAddressSet(portId);
1619 return IX_ETH_ACC_SUCCESS;
1621 /* search the next entry */
1622 i++;
1624 /* no matching entry found */
1625 return IX_ETH_ACC_NO_SUCH_ADDR;
1628 IxEthAccStatus
1629 ixEthAccPortMulticastAddressLeaveAllPriv (IxEthAccPortId portId)
1631 /*Check that the port parameter is valid*/
1632 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1634 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1636 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot leave all Multicast Address.\n",(INT32)portId,0,0,0,0,0);
1637 return IX_ETH_ACC_SUCCESS ;
1640 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1642 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1645 ixEthAccMacState[portId].mcastAddrIndex = 0;
1646 ixEthAccMacState[portId].joinAll = FALSE;
1648 ixEthAccMulticastAddressSet(portId);
1650 return IX_ETH_ACC_SUCCESS;
1654 IxEthAccStatus
1655 ixEthAccPortUnicastAddressShowPriv (IxEthAccPortId portId)
1657 IxEthAccMacAddr macAddr;
1659 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1661 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1663 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot show Unicast Address.\n",(INT32)portId,0,0,0,0,0);
1664 return IX_ETH_ACC_SUCCESS ;
1667 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1669 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1672 /*Get the MAC (UINICAST) address from hardware*/
1673 if(ixEthAccPortUnicastMacAddressGetPriv(portId, &macAddr) != IX_ETH_ACC_SUCCESS)
1675 IX_ETH_ACC_WARNING_LOG("EthAcc: MAC address uninitialised port %u\n",
1676 (INT32)portId,0,0,0,0,0);
1677 return IX_ETH_ACC_MAC_UNINITIALIZED;
1680 /*print it out*/
1681 ixEthAccMacPrint(&macAddr);
1682 printf("\n");
1683 return IX_ETH_ACC_SUCCESS;
1688 void
1689 ixEthAccPortMulticastAddressShowPriv(IxEthAccPortId portId)
1691 IxEthAccMacAddr macAddr;
1692 UINT32 i;
1694 if(!IX_ETH_ACC_IS_PORT_VALID(portId))
1696 return;
1699 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1701 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot show Multicast Address.\n",(INT32)portId,0,0,0,0,0);
1702 return ;
1705 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1707 return;
1710 printf("Multicast MAC: ");
1711 /*Get the MAC (MULTICAST) address from hardware*/
1712 ixEthAccPortMulticastMacAddressGet(portId, &macAddr);
1713 /*print it out*/
1714 ixEthAccMacPrint(&macAddr);
1715 /*Get the MAC (MULTICAST) filter from hardware*/
1716 ixEthAccPortMulticastMacFilterGet(portId, &macAddr);
1717 /*print it out*/
1718 printf(" ( ");
1719 ixEthAccMacPrint(&macAddr);
1720 printf(" )\n");
1721 printf("Constituent Addresses:\n");
1722 for(i=0;i<ixEthAccMacState[portId].mcastAddrIndex;i++)
1724 ixEthAccMacPrint(&ixEthAccMacState[portId].mcastAddrsTable[i]);
1725 printf("\n");
1727 return;
1730 /*Set the duplex mode*/
1731 IxEthAccStatus
1732 ixEthAccPortDuplexModeSetPriv (IxEthAccPortId portId,
1733 IxEthAccDuplexMode mode)
1735 UINT32 txregval;
1736 UINT32 rxregval;
1738 /*This is bit 1 of the transmit control reg, set to 1 for half
1739 duplex, 0 for full duplex*/
1740 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1742 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1744 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot set Duplex Mode.\n",(INT32)portId,0,0,0,0,0);
1745 return IX_ETH_ACC_SUCCESS ;
1748 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1750 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1753 REG_READ(ixEthAccMacBase[portId],
1754 IX_ETH_ACC_MAC_TX_CNTRL1,
1755 txregval);
1757 REG_READ(ixEthAccMacBase[portId],
1758 IX_ETH_ACC_MAC_RX_CNTRL1,
1759 rxregval);
1761 if (mode == IX_ETH_ACC_FULL_DUPLEX)
1763 /*Clear half duplex bit in TX*/
1764 REG_WRITE(ixEthAccMacBase[portId],
1765 IX_ETH_ACC_MAC_TX_CNTRL1,
1766 txregval & ~IX_ETH_ACC_TX_CNTRL1_DUPLEX);
1768 /*We must set the pause enable in the receive logic when in
1769 full duplex mode*/
1770 REG_WRITE(ixEthAccMacBase[portId],
1771 IX_ETH_ACC_MAC_RX_CNTRL1,
1772 rxregval | IX_ETH_ACC_RX_CNTRL1_PAUSE_EN);
1773 ixEthAccMacState[portId].fullDuplex = TRUE;
1776 else if (mode == IX_ETH_ACC_HALF_DUPLEX)
1778 /*Set half duplex bit in TX*/
1779 REG_WRITE(ixEthAccMacBase[portId],
1780 IX_ETH_ACC_MAC_TX_CNTRL1,
1781 txregval | IX_ETH_ACC_TX_CNTRL1_DUPLEX);
1783 /*We must clear pause enable in the receive logic when in
1784 half duplex mode*/
1785 REG_WRITE(ixEthAccMacBase[portId],
1786 IX_ETH_ACC_MAC_RX_CNTRL1,
1787 rxregval & ~IX_ETH_ACC_RX_CNTRL1_PAUSE_EN);
1789 ixEthAccMacState[portId].fullDuplex = FALSE;
1791 else
1793 return IX_ETH_ACC_FAIL;
1797 return IX_ETH_ACC_SUCCESS;
1803 IxEthAccStatus
1804 ixEthAccPortDuplexModeGetPriv (IxEthAccPortId portId,
1805 IxEthAccDuplexMode *mode)
1807 /*Return the duplex mode for the specified port*/
1808 UINT32 regval;
1810 /*This is bit 1 of the transmit control reg, set to 1 for half
1811 duplex, 0 for full duplex*/
1812 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1814 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1816 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get Duplex Mode.\n",(INT32)portId,0,0,0,0,0);
1817 /* return hald duplex */
1818 *mode = IX_ETH_ACC_HALF_DUPLEX ;
1819 return IX_ETH_ACC_SUCCESS ;
1822 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1824 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1827 if (mode == NULL)
1829 return (IX_ETH_ACC_FAIL);
1832 REG_READ(ixEthAccMacBase[portId],
1833 IX_ETH_ACC_MAC_TX_CNTRL1,
1834 regval);
1836 if( regval & IX_ETH_ACC_TX_CNTRL1_DUPLEX)
1838 *mode = IX_ETH_ACC_HALF_DUPLEX;
1840 else
1842 *mode = IX_ETH_ACC_FULL_DUPLEX;
1845 return IX_ETH_ACC_SUCCESS;
1850 IxEthAccStatus
1851 ixEthAccPortTxFrameAppendPaddingEnablePriv (IxEthAccPortId portId)
1853 UINT32 regval;
1854 /*Enable FCS computation by the MAC and appending to the
1855 frame*/
1857 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1859 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1861 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable Tx Frame Append Padding.\n",(INT32)portId,0,0,0,0,0);
1862 return IX_ETH_ACC_SUCCESS ;
1865 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1867 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1870 REG_READ(ixEthAccMacBase[portId],
1871 IX_ETH_ACC_MAC_TX_CNTRL1,
1872 regval);
1874 REG_WRITE(ixEthAccMacBase[portId],
1875 IX_ETH_ACC_MAC_TX_CNTRL1,
1876 regval |
1877 IX_ETH_ACC_TX_CNTRL1_PAD_EN);
1879 ixEthAccMacState[portId].txPADAppend = TRUE;
1880 return IX_ETH_ACC_SUCCESS;
1883 IxEthAccStatus
1884 ixEthAccPortTxFrameAppendPaddingDisablePriv (IxEthAccPortId portId)
1886 UINT32 regval;
1888 /*disable FCS computation and appending*/
1889 /*Set bit 4 of Tx control register one to zero*/
1890 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1892 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1894 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disble Tx Frame Append Padding.\n",(INT32)portId,0,0,0,0,0);
1895 return IX_ETH_ACC_SUCCESS ;
1898 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1900 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1903 REG_READ(ixEthAccMacBase[portId],
1904 IX_ETH_ACC_MAC_TX_CNTRL1,
1905 regval);
1907 REG_WRITE(ixEthAccMacBase[portId],
1908 IX_ETH_ACC_MAC_TX_CNTRL1,
1909 regval & ~IX_ETH_ACC_TX_CNTRL1_PAD_EN);
1911 ixEthAccMacState[portId].txPADAppend = FALSE;
1912 return IX_ETH_ACC_SUCCESS;
1915 IxEthAccStatus
1916 ixEthAccPortTxFrameAppendFCSEnablePriv (IxEthAccPortId portId)
1918 UINT32 regval;
1920 /*Enable FCS computation by the MAC and appending to the
1921 frame*/
1923 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1925 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1927 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable Tx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
1928 return IX_ETH_ACC_SUCCESS ;
1931 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1933 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1936 REG_READ(ixEthAccMacBase[portId],
1937 IX_ETH_ACC_MAC_TX_CNTRL1,
1938 regval);
1940 REG_WRITE(ixEthAccMacBase[portId],
1941 IX_ETH_ACC_MAC_TX_CNTRL1,
1942 regval | IX_ETH_ACC_TX_CNTRL1_FCS_EN);
1944 ixEthAccMacState[portId].txFCSAppend = TRUE;
1945 return IX_ETH_ACC_SUCCESS;
1948 IxEthAccStatus
1949 ixEthAccPortTxFrameAppendFCSDisablePriv (IxEthAccPortId portId)
1951 UINT32 regval;
1953 /*disable FCS computation and appending*/
1954 /*Set bit 4 of Tx control register one to zero*/
1955 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1957 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1959 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable Tx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
1960 return IX_ETH_ACC_SUCCESS ;
1963 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1965 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1968 REG_READ(ixEthAccMacBase[portId],
1969 IX_ETH_ACC_MAC_TX_CNTRL1,
1970 regval);
1972 REG_WRITE(ixEthAccMacBase[portId],
1973 IX_ETH_ACC_MAC_TX_CNTRL1,
1974 regval & ~IX_ETH_ACC_TX_CNTRL1_FCS_EN);
1976 ixEthAccMacState[portId].txFCSAppend = FALSE;
1977 return IX_ETH_ACC_SUCCESS;
1980 IxEthAccStatus
1981 ixEthAccPortRxFrameAppendFCSEnablePriv (IxEthAccPortId portId)
1983 /*Set bit 2 of Rx control 1*/
1984 UINT32 regval;
1986 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
1988 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
1990 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot enable Rx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
1991 return IX_ETH_ACC_SUCCESS ;
1994 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
1996 return (IX_ETH_ACC_PORT_UNINITIALIZED);
1999 REG_READ(ixEthAccMacBase[portId],
2000 IX_ETH_ACC_MAC_RX_CNTRL1,
2001 regval);
2003 REG_WRITE(ixEthAccMacBase[portId],
2004 IX_ETH_ACC_MAC_RX_CNTRL1,
2005 regval | IX_ETH_ACC_RX_CNTRL1_CRC_EN);
2007 ixEthAccMacState[portId].rxFCSAppend = TRUE;
2008 return IX_ETH_ACC_SUCCESS;
2011 IxEthAccStatus
2012 ixEthAccPortRxFrameAppendFCSDisablePriv (IxEthAccPortId portId)
2014 UINT32 regval;
2016 /*Clear bit 2 of Rx control 1*/
2017 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
2019 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
2021 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot disable Rx Frame Append FCS.\n",(INT32)portId,0,0,0,0,0);
2022 return IX_ETH_ACC_SUCCESS ;
2025 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
2027 return (IX_ETH_ACC_PORT_UNINITIALIZED);
2030 REG_READ(ixEthAccMacBase[portId],
2031 IX_ETH_ACC_MAC_RX_CNTRL1,
2032 regval);
2034 REG_WRITE(ixEthAccMacBase[portId],
2035 IX_ETH_ACC_MAC_RX_CNTRL1,
2036 regval & ~IX_ETH_ACC_RX_CNTRL1_CRC_EN);
2038 ixEthAccMacState[portId].rxFCSAppend = FALSE;
2039 return IX_ETH_ACC_SUCCESS;
2044 PRIVATE void
2045 ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId,
2046 IxNpeMhMessage msg)
2048 IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
2050 #ifndef NDEBUG
2051 /* Prudent to at least check the port is within range */
2052 if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
2054 IX_ETH_ACC_FATAL_LOG(
2055 "IXETHACC:ixEthAccMacNpeStatsMessageCallback: Illegal port: %u\n",
2056 (UINT32)portId, 0, 0, 0, 0, 0);
2057 return;
2059 #endif
2061 /*Unblock Stats Get call*/
2062 ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsLock);
2066 PRIVATE void
2067 ixEthAccMibIIStatsEndianConvert (IxEthEthObjStats *retStats)
2069 /* endianness conversion */
2071 /* Rx stats */
2072 retStats->dot3StatsAlignmentErrors =
2073 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsAlignmentErrors);
2074 retStats->dot3StatsFCSErrors =
2075 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsFCSErrors);
2076 retStats->dot3StatsInternalMacReceiveErrors =
2077 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacReceiveErrors);
2078 retStats->RxOverrunDiscards =
2079 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxOverrunDiscards);
2080 retStats->RxLearnedEntryDiscards =
2081 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLearnedEntryDiscards);
2082 retStats->RxLargeFramesDiscards =
2083 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxLargeFramesDiscards);
2084 retStats->RxSTPBlockedDiscards =
2085 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxSTPBlockedDiscards);
2086 retStats->RxVLANTypeFilterDiscards =
2087 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANTypeFilterDiscards);
2088 retStats->RxVLANIdFilterDiscards =
2089 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxVLANIdFilterDiscards);
2090 retStats->RxInvalidSourceDiscards =
2091 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxInvalidSourceDiscards);
2092 retStats->RxBlackListDiscards =
2093 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxBlackListDiscards);
2094 retStats->RxWhiteListDiscards =
2095 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxWhiteListDiscards);
2096 retStats->RxUnderflowEntryDiscards =
2097 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->RxUnderflowEntryDiscards);
2099 /* Tx stats */
2100 retStats->dot3StatsSingleCollisionFrames =
2101 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsSingleCollisionFrames);
2102 retStats->dot3StatsMultipleCollisionFrames =
2103 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsMultipleCollisionFrames);
2104 retStats->dot3StatsDeferredTransmissions =
2105 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsDeferredTransmissions);
2106 retStats->dot3StatsLateCollisions =
2107 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsLateCollisions);
2108 retStats->dot3StatsExcessiveCollsions =
2109 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsExcessiveCollsions);
2110 retStats->dot3StatsInternalMacTransmitErrors =
2111 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsInternalMacTransmitErrors);
2112 retStats->dot3StatsCarrierSenseErrors =
2113 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->dot3StatsCarrierSenseErrors);
2114 retStats->TxLargeFrameDiscards =
2115 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxLargeFrameDiscards);
2116 retStats->TxVLANIdFilterDiscards =
2117 IX_OSAL_SWAP_BE_SHARED_LONG(retStats->TxVLANIdFilterDiscards);
2120 IxEthAccStatus
2121 ixEthAccMibIIStatsGet (IxEthAccPortId portId,
2122 IxEthEthObjStats *retStats )
2124 IxNpeMhMessage message;
2126 if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
2128 printf("EthAcc: ixEthAccMibIIStatsGet (Mac) EthAcc service is not initialized\n");
2129 return (IX_ETH_ACC_FAIL);
2132 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
2134 if (retStats == NULL)
2136 printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NULL argument\n");
2137 return (IX_ETH_ACC_FAIL);
2140 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
2142 printf("EthAcc: ixEthAccMibIIStatsGet (Mac) NPE for port %d is not available\n", portId);
2144 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get MIB II Stats.\n",(INT32)portId,0,0,0,0,0);
2146 /* Return all zero stats */
2147 IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats));
2149 return IX_ETH_ACC_SUCCESS ;
2152 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
2154 printf("EthAcc: ixEthAccMibIIStatsGet (Mac) port %d is not initialized\n", portId);
2155 return (IX_ETH_ACC_PORT_UNINITIALIZED);
2158 IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats));
2160 message.data[0] = IX_ETHNPE_GETSTATS << IX_ETH_ACC_MAC_MSGID_SHL;
2161 message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats);
2163 /* Permit only one task to request MIB statistics Get operation
2164 at a time */
2165 ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetAccessLock, IX_OSAL_WAIT_FOREVER);
2167 if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
2168 message,
2169 IX_ETHNPE_GETSTATS,
2170 ixEthAccMacNpeStatsMessageCallback,
2171 IX_NPEMH_SEND_RETRIES_DEFAULT)
2172 != IX_SUCCESS)
2174 ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock);
2176 printf("EthAcc: (Mac) StatsGet failed to send NPE message\n");
2178 return IX_ETH_ACC_FAIL;
2181 /* Wait for callback invocation indicating response to
2182 this request - we need this mutex in order to ensure
2183 that the return from this function is synchronous */
2184 ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS);
2186 /* Permit other tasks to perform MIB statistics Get operation */
2187 ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetAccessLock);
2189 ixEthAccMibIIStatsEndianConvert (retStats);
2191 return IX_ETH_ACC_SUCCESS;
2195 PRIVATE void
2196 ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId,
2197 IxNpeMhMessage msg)
2199 IxEthAccPortId portId = IX_ETH_ACC_NPE_TO_PORT_ID(npeId);
2201 #ifndef NDEBUG
2202 /* Prudent to at least check the port is within range */
2203 if (portId >= IX_ETH_ACC_NUMBER_OF_PORTS)
2205 IX_ETH_ACC_FATAL_LOG(
2206 "IXETHACC:ixEthAccMacNpeStatsResetMessageCallback: Illegal port: %u\n",
2207 (UINT32)portId, 0, 0, 0, 0, 0);
2208 return;
2210 #endif
2212 /*Unblock Stats Get & reset call*/
2213 ixOsalMutexUnlock(&ixEthAccMacState[portId].ackMIBStatsResetLock);
2219 IxEthAccStatus
2220 ixEthAccMibIIStatsGetClear (IxEthAccPortId portId,
2221 IxEthEthObjStats *retStats)
2223 IxNpeMhMessage message;
2225 if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
2227 printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) EthAcc service is not initialized\n");
2228 return (IX_ETH_ACC_FAIL);
2231 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
2233 if (retStats == NULL)
2235 printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NULL argument\n");
2236 return (IX_ETH_ACC_FAIL);
2239 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
2241 printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) NPE for port %d is not available\n", portId);
2243 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot get and clear MIB II Stats.\n", (INT32)portId, 0, 0, 0, 0, 0);
2245 /* Return all zero stats */
2246 IX_ETH_ACC_MEMSET(retStats, 0, sizeof(IxEthEthObjStats));
2248 return IX_ETH_ACC_SUCCESS ;
2251 if (!IX_ETH_IS_PORT_INITIALIZED(portId))
2253 printf("EthAcc: ixEthAccMibIIStatsGetClear (Mac) port %d is not initialized\n", portId);
2254 return (IX_ETH_ACC_PORT_UNINITIALIZED);
2257 IX_OSAL_CACHE_INVALIDATE(retStats, sizeof(IxEthEthObjStats));
2259 message.data[0] = IX_ETHNPE_RESETSTATS << IX_ETH_ACC_MAC_MSGID_SHL;
2260 message.data[1] = (UINT32) IX_OSAL_MMU_VIRT_TO_PHYS(retStats);
2262 /* Permit only one task to request MIB statistics Get-Reset operation at a time */
2263 ixOsalMutexLock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock, IX_OSAL_WAIT_FOREVER);
2265 if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId),
2266 message,
2267 IX_ETHNPE_RESETSTATS,
2268 ixEthAccMacNpeStatsResetMessageCallback,
2269 IX_NPEMH_SEND_RETRIES_DEFAULT)
2270 != IX_SUCCESS)
2272 ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock);
2274 printf("EthAcc: (Mac) ixEthAccMibIIStatsGetClear failed to send NPE message\n");
2276 return IX_ETH_ACC_FAIL;
2279 /* Wait for callback invocation indicating response to this request */
2280 ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_ETH_ACC_MIB_STATS_DELAY_MSECS);
2282 /* permit other tasks to get and reset MIB stats*/
2283 ixOsalMutexUnlock(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock);
2285 ixEthAccMibIIStatsEndianConvert(retStats);
2287 return IX_ETH_ACC_SUCCESS;
2290 IxEthAccStatus
2291 ixEthAccMibIIStatsClear (IxEthAccPortId portId)
2293 static IxEthEthObjStats retStats;
2294 IxEthAccStatus status;
2296 if (!IX_ETH_ACC_IS_SERVICE_INITIALIZED())
2298 return (IX_ETH_ACC_FAIL);
2301 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
2303 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
2305 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot clear MIB II Stats.\n",(INT32)portId,0,0,0,0,0);
2306 return IX_ETH_ACC_SUCCESS ;
2309 /* there is no reset operation without a corresponding Get */
2310 status = ixEthAccMibIIStatsGetClear(portId, &retStats);
2312 return status;
2315 /* Initialize the ethernet MAC settings */
2316 IxEthAccStatus
2317 ixEthAccMacInit(IxEthAccPortId portId)
2319 IX_OSAL_MBUF_POOL* portDisablePool;
2320 UINT8 *data;
2322 IX_ETH_ACC_VALIDATE_PORT_ID(portId);
2324 if (IX_ETH_ACC_SUCCESS != ixEthAccSingleEthNpeCheck(portId))
2326 IX_ETH_ACC_WARNING_LOG("EthAcc: Unavailable Eth %d: Cannot initialize Mac.\n",(INT32)portId,0,0,0,0,0);
2327 return IX_ETH_ACC_SUCCESS ;
2330 if(ixEthAccMacState[portId].macInitialised == FALSE)
2332 ixEthAccMacState[portId].fullDuplex = TRUE;
2333 ixEthAccMacState[portId].rxFCSAppend = TRUE;
2334 ixEthAccMacState[portId].txFCSAppend = TRUE;
2335 ixEthAccMacState[portId].txPADAppend = TRUE;
2336 ixEthAccMacState[portId].enabled = FALSE;
2337 ixEthAccMacState[portId].promiscuous = TRUE;
2338 ixEthAccMacState[portId].joinAll = FALSE;
2339 ixEthAccMacState[portId].initDone = FALSE;
2340 ixEthAccMacState[portId].macInitialised = TRUE;
2342 /* initialize MIB stats mutexes */
2343 ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsLock);
2344 ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsLock, IX_OSAL_WAIT_FOREVER);
2346 ixOsalMutexInit(&ixEthAccMacState[portId].ackMIBStatsResetLock);
2347 ixOsalMutexLock(&ixEthAccMacState[portId].ackMIBStatsResetLock, IX_OSAL_WAIT_FOREVER);
2349 ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetAccessLock);
2351 ixOsalMutexInit(&ixEthAccMacState[portId].MIBStatsGetResetAccessLock);
2353 ixOsalMutexInit(&ixEthAccMacState[portId].npeLoopbackMessageLock);
2355 ixEthAccMacState[portId].portDisableRxMbufPtr = NULL;
2356 ixEthAccMacState[portId].portDisableTxMbufPtr = NULL;
2358 portDisablePool = IX_OSAL_MBUF_POOL_INIT(2,
2359 IX_ETHACC_RX_MBUF_MIN_SIZE,
2360 "portDisable Pool");
2362 IX_OSAL_ENSURE(portDisablePool != NULL, "Failed to initialize PortDisable pool");
2364 ixEthAccMacState[portId].portDisableRxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool);
2365 ixEthAccMacState[portId].portDisableTxMbufPtr = IX_OSAL_MBUF_POOL_GET(portDisablePool);
2367 IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableRxMbufPtr != NULL,
2368 "Pool allocation failed");
2369 IX_OSAL_ENSURE(ixEthAccMacState[portId].portDisableTxMbufPtr != NULL,
2370 "Pool allocation failed");
2371 /* fill the payload of the Rx mbuf used in portDisable */
2372 IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableRxMbufPtr) = IX_ETHACC_RX_MBUF_MIN_SIZE;
2374 memset(IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableRxMbufPtr),
2375 0xAA,
2376 IX_ETHACC_RX_MBUF_MIN_SIZE);
2378 /* fill the payload of the Tx mbuf used in portDisable (64 bytes) */
2379 IX_OSAL_MBUF_MLEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64;
2380 IX_OSAL_MBUF_PKT_LEN(ixEthAccMacState[portId].portDisableTxMbufPtr) = 64;
2382 data = (UINT8 *) IX_OSAL_MBUF_MDATA(ixEthAccMacState[portId].portDisableTxMbufPtr);
2383 memset(data, 0xBB, 64);
2384 data[0] = 0x00; /* unicast destination MAC address */
2385 data[6] = 0x00; /* unicast source MAC address */
2386 data[12] = 0x08; /* typelength : IP frame */
2387 data[13] = 0x00; /* typelength : IP frame */
2389 IX_OSAL_CACHE_FLUSH(data, 64);
2392 IX_OSAL_ASSERT (ixEthAccMacBase[portId] != 0);
2394 REG_WRITE(ixEthAccMacBase[portId],
2395 IX_ETH_ACC_MAC_CORE_CNTRL,
2396 IX_ETH_ACC_CORE_RESET);
2398 ixOsalSleep(IX_ETH_ACC_MAC_RESET_DELAY);
2400 REG_WRITE(ixEthAccMacBase[portId],
2401 IX_ETH_ACC_MAC_CORE_CNTRL,
2402 IX_ETH_ACC_CORE_MDC_EN);
2404 REG_WRITE(ixEthAccMacBase[portId],
2405 IX_ETH_ACC_MAC_INT_CLK_THRESH,
2406 IX_ETH_ACC_MAC_INT_CLK_THRESH_DEFAULT);
2408 ixEthAccMacStateUpdate(portId);
2410 return IX_ETH_ACC_SUCCESS;
2413 /* PRIVATE Functions*/
2415 PRIVATE void
2416 ixEthAccMacStateUpdate(IxEthAccPortId portId)
2418 UINT32 regval;
2420 if ( ixEthAccMacState[portId].enabled == FALSE )
2422 /* Just disable both the transmitter and reciver in the MAC. */
2423 REG_READ(ixEthAccMacBase[portId],
2424 IX_ETH_ACC_MAC_RX_CNTRL1,
2425 regval);
2426 REG_WRITE(ixEthAccMacBase[portId],
2427 IX_ETH_ACC_MAC_RX_CNTRL1,
2428 regval & ~IX_ETH_ACC_RX_CNTRL1_RX_EN);
2430 REG_READ(ixEthAccMacBase[portId],
2431 IX_ETH_ACC_MAC_TX_CNTRL1,
2432 regval);
2433 REG_WRITE(ixEthAccMacBase[portId],
2434 IX_ETH_ACC_MAC_TX_CNTRL1,
2435 regval & ~IX_ETH_ACC_TX_CNTRL1_TX_EN);
2438 if(ixEthAccMacState[portId].fullDuplex)
2440 ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_FULL_DUPLEX);
2442 else
2444 ixEthAccPortDuplexModeSetPriv (portId, IX_ETH_ACC_HALF_DUPLEX);
2447 if(ixEthAccMacState[portId].rxFCSAppend)
2449 ixEthAccPortRxFrameAppendFCSEnablePriv (portId);
2451 else
2453 ixEthAccPortRxFrameAppendFCSDisablePriv (portId);
2456 if(ixEthAccMacState[portId].txFCSAppend)
2458 ixEthAccPortTxFrameAppendFCSEnablePriv (portId);
2460 else
2462 ixEthAccPortTxFrameAppendFCSDisablePriv (portId);
2465 if(ixEthAccMacState[portId].txPADAppend)
2467 ixEthAccPortTxFrameAppendPaddingEnablePriv (portId);
2469 else
2471 ixEthAccPortTxFrameAppendPaddingDisablePriv (portId);
2474 if(ixEthAccMacState[portId].promiscuous)
2476 ixEthAccPortPromiscuousModeSetPriv(portId);
2478 else
2480 ixEthAccPortPromiscuousModeClearPriv(portId);
2483 if ( ixEthAccMacState[portId].enabled == TRUE )
2485 /* Enable both the transmitter and reciver in the MAC. */
2486 REG_READ(ixEthAccMacBase[portId],
2487 IX_ETH_ACC_MAC_RX_CNTRL1,
2488 regval);
2489 REG_WRITE(ixEthAccMacBase[portId],
2490 IX_ETH_ACC_MAC_RX_CNTRL1,
2491 regval | IX_ETH_ACC_RX_CNTRL1_RX_EN);
2493 REG_READ(ixEthAccMacBase[portId],
2494 IX_ETH_ACC_MAC_TX_CNTRL1,
2495 regval);
2496 REG_WRITE(ixEthAccMacBase[portId],
2497 IX_ETH_ACC_MAC_TX_CNTRL1,
2498 regval | IX_ETH_ACC_TX_CNTRL1_TX_EN);
2503 PRIVATE BOOL
2504 ixEthAccMacEqual(IxEthAccMacAddr *macAddr1,
2505 IxEthAccMacAddr *macAddr2)
2507 UINT32 i;
2508 for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE; i++)
2510 if(macAddr1->macAddress[i] != macAddr2->macAddress[i])
2512 return FALSE;
2515 return TRUE;
2518 PRIVATE void
2519 ixEthAccMacPrint(IxEthAccMacAddr *m)
2521 printf("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
2522 m->macAddress[0], m->macAddress[1],
2523 m->macAddress[2], m->macAddress[3],
2524 m->macAddress[4], m->macAddress[5]);
2527 /* Set the multicast address and address mask registers
2529 * A bit in the address mask register must be set if
2530 * all multicast addresses always have that bit set, or if
2531 * all multicast addresses always have that bit cleared.
2533 * A bit in the address register must be set if all multicast
2534 * addresses have that bit set, otherwise, it should be cleared
2537 PRIVATE void
2538 ixEthAccMulticastAddressSet(IxEthAccPortId portId)
2540 UINT32 i;
2541 UINT32 j;
2542 IxEthAccMacAddr addressMask;
2543 IxEthAccMacAddr address;
2544 IxEthAccMacAddr alwaysClearBits;
2545 IxEthAccMacAddr alwaysSetBits;
2547 /* calculate alwaysClearBits and alwaysSetBits:
2548 * alwaysClearBits is calculated by ORing all
2549 * multicast addresses, those bits that are always
2550 * clear are clear in the result
2552 * alwaysSetBits is calculated by ANDing all
2553 * multicast addresses, those bits that are always set
2554 * are set in the result
2557 if (ixEthAccMacState[portId].promiscuous == TRUE)
2559 /* Promiscuous Mode is set, and filtering
2560 * allow all packets, and enable the mcast and
2561 * bcast detection.
2563 memset(&addressMask.macAddress,
2565 IX_IEEE803_MAC_ADDRESS_SIZE);
2566 memset(&address.macAddress,
2568 IX_IEEE803_MAC_ADDRESS_SIZE);
2570 else
2572 if(ixEthAccMacState[portId].joinAll == TRUE)
2574 /* Join all is set. The mask and address are
2575 * the multicast settings.
2577 IxEthAccMacAddr macAddr = {{0x1,0x0,0x0,0x0,0x0,0x0}};
2579 memcpy(addressMask.macAddress,
2580 macAddr.macAddress,
2581 IX_IEEE803_MAC_ADDRESS_SIZE);
2582 memcpy(address.macAddress,
2583 macAddr.macAddress,
2584 IX_IEEE803_MAC_ADDRESS_SIZE);
2586 else if(ixEthAccMacState[portId].mcastAddrIndex == 0)
2588 /* No entry in the filtering database,
2589 * Promiscuous Mode is cleared, Broadcast filtering
2590 * is configured.
2592 memset(addressMask.macAddress,
2593 IX_ETH_ACC_MAC_ALL_BITS_SET,
2594 IX_IEEE803_MAC_ADDRESS_SIZE);
2595 memset(address.macAddress,
2596 IX_ETH_ACC_MAC_ALL_BITS_SET,
2597 IX_IEEE803_MAC_ADDRESS_SIZE);
2599 else
2601 /* build a mask and an address which mix all entreis
2602 * from the list of multicast addresses
2604 memset(alwaysClearBits.macAddress,
2606 IX_IEEE803_MAC_ADDRESS_SIZE);
2607 memset(alwaysSetBits.macAddress,
2608 IX_ETH_ACC_MAC_ALL_BITS_SET,
2609 IX_IEEE803_MAC_ADDRESS_SIZE);
2611 for(i=0;i<ixEthAccMacState[portId].mcastAddrIndex;i++)
2613 for(j=0;j<IX_IEEE803_MAC_ADDRESS_SIZE;j++)
2615 alwaysClearBits.macAddress[j] |=
2616 ixEthAccMacState[portId].mcastAddrsTable[i].macAddress[j];
2617 alwaysSetBits.macAddress[j] &=
2618 ixEthAccMacState[portId].mcastAddrsTable[i].macAddress[j];
2622 for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
2624 addressMask.macAddress[i] = alwaysSetBits.macAddress[i]
2625 | ~alwaysClearBits.macAddress[i];
2626 address.macAddress[i] = alwaysSetBits.macAddress[i];
2631 /*write the new addr filtering to h/w*/
2632 for(i=0;i<IX_IEEE803_MAC_ADDRESS_SIZE;i++)
2634 REG_WRITE(ixEthAccMacBase[portId],
2635 IX_ETH_ACC_MAC_ADDR_MASK_1+i*sizeof(UINT32),
2636 addressMask.macAddress[i]);
2637 REG_WRITE(ixEthAccMacBase[portId],
2638 IX_ETH_ACC_MAC_ADDR_1+i*sizeof(UINT32),
2639 address.macAddress[i]);