4 * @author Intel Corporation
7 * @brief MAC control functions
12 * IXP400 SW Release version 2.0
14 * -- Copyright Notice --
17 * Copyright 2001-2005, Intel Corporation.
18 * All rights reserved.
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions
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.
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
47 * -- End of Copyright Notice --
52 #ifdef CONFIG_IXP425_COMPONENT_ETHDB
55 #include "IxEthDBPortDefs.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
70 #define IX_ETH_ACC_MAX_RETRY_TIMEOUT 5
72 #define IX_ETH_ACC_VALIDATE_PORT_ID(portId) \
75 if(!IX_ETH_ACC_IS_PORT_VALID(portId)) \
77 return IX_ETH_ACC_INVALID_PORT; \
81 PUBLIC IxEthAccMacState ixEthAccMacState
[IX_ETH_ACC_NUMBER_OF_PORTS
];
83 PRIVATE UINT32 ixEthAccMacBase
[IX_ETH_ACC_NUMBER_OF_PORTS
];
85 /*Forward function declarations*/
87 ixEthAccPortDisableRx (IxEthAccPortId portId
,
88 IX_OSAL_MBUF
* mBufPtr
,
89 BOOL useMultiBufferCallback
);
92 ixEthAccPortDisableRxAndReplenish (IxEthAccPortId portId
,
93 IX_OSAL_MBUF
* mBufPtr
,
94 BOOL useMultiBufferCallback
);
97 ixEthAccPortDisableTxDone (UINT32 cbTag
,
101 ixEthAccPortDisableTxDoneAndSubmit (UINT32 cbTag
,
105 ixEthAccPortDisableRxCallback (UINT32 cbTag
,
106 IX_OSAL_MBUF
* mBufPtr
,
107 UINT32 learnedPortId
);
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
);
128 ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId
,
132 ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId
,
136 ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId
,
140 ixEthAccMulticastAddressSet(IxEthAccPortId portId
);
143 ixEthAccMacEqual(IxEthAccMacAddr
*macAddr1
,
144 IxEthAccMacAddr
*macAddr2
);
147 ixEthAccMacPrint(IxEthAccMacAddr
*m
);
150 ixEthAccMacStateUpdate(IxEthAccPortId portId
);
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
);
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",
172 return IX_ETH_ACC_FAIL
;
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",
184 return IX_ETH_ACC_FAIL
;
187 return IX_ETH_ACC_SUCCESS
;
191 ixEthAccMacUnload(void)
193 IX_OSAL_MEM_UNMAP(ixEthAccMacBase
[IX_ETH_PORT_1
]);
194 IX_OSAL_MEM_UNMAP(ixEthAccMacBase
[IX_ETH_PORT_2
]);
196 IX_OSAL_MEM_UNMAP(ixEthAccMacBase
[IX_ETH_PORT_3
]);
197 ixEthAccMacBase
[IX_ETH_PORT_3
] = 0;
199 ixEthAccMacBase
[IX_ETH_PORT_2
] = 0;
200 ixEthAccMacBase
[IX_ETH_PORT_1
] = 0;
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
;
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
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
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
];
332 ixEthAccPortDisableCbTag
[IX_ETH_ACC_NUMBER_OF_PORTS
];
334 ixEthAccPortDisableMultiBufferCbTag
[IX_ETH_ACC_NUMBER_OF_PORTS
];
336 static IxEthAccPortTxDoneCallback
337 ixEthAccPortDisableTxDoneFn
[IX_ETH_ACC_NUMBER_OF_PORTS
];
339 ixEthAccPortDisableTxDoneCbTag
[IX_ETH_ACC_NUMBER_OF_PORTS
];
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
350 ixEthAccPortDisableTxDone(UINT32 cbTag
,
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
;
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
)
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
383 key
= ixOsalIrqLock();
384 if (*txState
== TRANSMIT_DONE
)
386 IX_OSAL_MBUF
*mbufTxPtr
= ixEthAccMacState
[portId
].portDisableTxMbufPtr
;
388 status
= ixEthAccPortTxFrameSubmit(portId
,
390 IX_ETH_ACC_TX_DEFAULT_PRIORITY
);
392 ixOsalIrqUnlock(key
);
398 ixEthAccPortDisableTxDoneAndSubmit(UINT32 cbTag
,
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
409 ixEthAccPortDisableTryTransmit(portId
);
413 ixEthAccPortDisableRx (IxEthAccPortId portId
,
414 IX_OSAL_MBUF
* mBufPtr
,
415 BOOL useMultiBufferCallback
)
417 volatile IxEthAccPortDisableState
*rxState
= &ixEthAccMacState
[portId
].rxState
;
418 IX_OSAL_MBUF
*mNextPtr
;
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
)
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
],
456 /* call the user callback with a unchained
457 * buffer, without payload and the destination port is
460 ixEthAccPortDisableFn
[portId
](
461 ixEthAccPortDisableCbTag
[portId
],
463 IX_ETH_DB_UNKNOWN_PORT
/* port not found */);
471 PRIVATE IxEthAccStatus
472 ixEthAccPortDisableTryReplenish(UINT32 portId
)
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
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
);
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
507 ixEthAccPortDisableTryReplenish(portId
);
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
);
522 ixEthAccPortDisableMultiBufferRxCallback (UINT32 cbTag
,
523 IX_OSAL_MBUF
**mBufPtr
)
525 IxEthAccPortId portId
= (IxEthAccPortId
)cbTag
;
529 /* call the portDisable receive callback with one buffer at a time */
530 (ixEthAccPortDisableRxTable
[portId
])(portId
, *mBufPtr
++, TRUE
);
535 ixEthAccPortDisablePriv(IxEthAccPortId portId
)
537 IxEthAccStatus status
= IX_ETH_ACC_SUCCESS
;
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
;
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);
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
;
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
)
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
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
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;
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
)
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
);
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 */
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 */
880 return (IX_ETH_ACC_PORT_UNINITIALIZED
);
883 *enabled
= ixEthAccMacState
[portId
].enabled
;
885 return IX_ETH_ACC_SUCCESS
;
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
;
925 ixEthAccPortLoopbackEnable(IxEthAccPortId portId
)
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
);
944 REG_READ(ixEthAccMacBase
[portId
],
945 IX_ETH_ACC_MAC_RX_CNTRL1
,
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
;
957 ixEthAccNpeLoopbackMessageCallback (IxNpeMhNpeId npeId
,
960 IxEthAccPortId portId
= IX_ETH_ACC_NPE_TO_PORT_ID(npeId
);
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);
973 /* unlock message reception mutex */
974 ixOsalMutexUnlock(&ixEthAccMacState
[portId
].npeLoopbackMessageLock
);
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
)
1001 message
.data
[1] = 0;
1003 npeMhStatus
= ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId
),
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
;
1015 /* wait for NPE loopbackEnable response */
1016 if (ixOsalMutexLock(&ixEthAccMacState
[portId
]. npeLoopbackMessageLock
,
1017 IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS
)
1020 status
= IX_ETH_ACC_FAIL
;
1028 ixEthAccPortTxEnablePriv(IxEthAccPortId portId
)
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
);
1047 REG_READ(ixEthAccMacBase
[portId
],
1048 IX_ETH_ACC_MAC_TX_CNTRL1
,
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
;
1060 ixEthAccPortRxEnablePriv(IxEthAccPortId portId
)
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
);
1079 REG_READ(ixEthAccMacBase
[portId
],
1080 IX_ETH_ACC_MAC_RX_CNTRL1
,
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
;
1092 ixEthAccPortLoopbackDisable(IxEthAccPortId portId
)
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
,
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
;
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
),
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
;
1158 /* wait for NPE loopbackEnable response */
1159 if (ixOsalMutexLock(&ixEthAccMacState
[portId
].npeLoopbackMessageLock
,
1160 IX_ETH_ACC_PORT_DISABLE_DELAY_MSECS
)
1163 status
= IX_ETH_ACC_FAIL
;
1171 ixEthAccPortTxDisablePriv(IxEthAccPortId portId
)
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
);
1190 REG_READ(ixEthAccMacBase
[portId
],
1191 IX_ETH_ACC_MAC_TX_CNTRL1
,
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
;
1203 ixEthAccPortRxDisablePriv(IxEthAccPortId portId
)
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
);
1222 REG_READ(ixEthAccMacBase
[portId
],
1223 IX_ETH_ACC_MAC_RX_CNTRL1
,
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
;
1235 ixEthAccPortPromiscuousModeClearPriv(IxEthAccPortId portId
)
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
,
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
;
1270 ixEthAccPortPromiscuousModeSetPriv(IxEthAccPortId portId
)
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
,
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
;
1308 ixEthAccPortUnicastMacAddressSetPriv (IxEthAccPortId portId
,
1309 IxEthAccMacAddr
*macAddr
)
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
;
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
;
1370 ixEthAccPortUnicastMacAddressGetPriv (IxEthAccPortId portId
,
1371 IxEthAccMacAddr
*macAddr
)
1373 /*Return the current value of the Unicast MAC from h/w
1374 for the specified port*/
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*/
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*/
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
;
1448 ixEthAccPortMulticastAddressJoinPriv (IxEthAccPortId portId
,
1449 IxEthAccMacAddr
*macAddr
)
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*/
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
;
1487 i
<ixEthAccMacState
[portId
].mcastAddrIndex
;
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
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
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
;
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
;
1563 ixEthAccPortMulticastAddressLeavePriv (IxEthAccPortId portId
,
1564 IxEthAccMacAddr
*macAddr
)
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*/
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
1594 while(i
<ixEthAccMacState
[portId
].mcastAddrIndex
)
1596 /*Check if the current entry matches*/
1597 if(ixEthAccMacEqual(&ixEthAccMacState
[portId
].mcastAddrsTable
[i
],
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
);
1616 /*recalculate the mask and write it to the MAC*/
1617 ixEthAccMulticastAddressSet(portId
);
1619 return IX_ETH_ACC_SUCCESS
;
1621 /* search the next entry */
1624 /* no matching entry found */
1625 return IX_ETH_ACC_NO_SUCH_ADDR
;
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
;
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
;
1681 ixEthAccMacPrint(&macAddr
);
1683 return IX_ETH_ACC_SUCCESS
;
1689 ixEthAccPortMulticastAddressShowPriv(IxEthAccPortId portId
)
1691 IxEthAccMacAddr macAddr
;
1694 if(!IX_ETH_ACC_IS_PORT_VALID(portId
))
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);
1705 if (!IX_ETH_IS_PORT_INITIALIZED(portId
))
1710 printf("Multicast MAC: ");
1711 /*Get the MAC (MULTICAST) address from hardware*/
1712 ixEthAccPortMulticastMacAddressGet(portId
, &macAddr
);
1714 ixEthAccMacPrint(&macAddr
);
1715 /*Get the MAC (MULTICAST) filter from hardware*/
1716 ixEthAccPortMulticastMacFilterGet(portId
, &macAddr
);
1719 ixEthAccMacPrint(&macAddr
);
1721 printf("Constituent Addresses:\n");
1722 for(i
=0;i
<ixEthAccMacState
[portId
].mcastAddrIndex
;i
++)
1724 ixEthAccMacPrint(&ixEthAccMacState
[portId
].mcastAddrsTable
[i
]);
1730 /*Set the duplex mode*/
1732 ixEthAccPortDuplexModeSetPriv (IxEthAccPortId portId
,
1733 IxEthAccDuplexMode mode
)
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
,
1757 REG_READ(ixEthAccMacBase
[portId
],
1758 IX_ETH_ACC_MAC_RX_CNTRL1
,
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
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
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
;
1793 return IX_ETH_ACC_FAIL
;
1797 return IX_ETH_ACC_SUCCESS
;
1804 ixEthAccPortDuplexModeGetPriv (IxEthAccPortId portId
,
1805 IxEthAccDuplexMode
*mode
)
1807 /*Return the duplex mode for the specified port*/
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
);
1829 return (IX_ETH_ACC_FAIL
);
1832 REG_READ(ixEthAccMacBase
[portId
],
1833 IX_ETH_ACC_MAC_TX_CNTRL1
,
1836 if( regval
& IX_ETH_ACC_TX_CNTRL1_DUPLEX
)
1838 *mode
= IX_ETH_ACC_HALF_DUPLEX
;
1842 *mode
= IX_ETH_ACC_FULL_DUPLEX
;
1845 return IX_ETH_ACC_SUCCESS
;
1851 ixEthAccPortTxFrameAppendPaddingEnablePriv (IxEthAccPortId portId
)
1854 /*Enable FCS computation by the MAC and appending to the
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
,
1874 REG_WRITE(ixEthAccMacBase
[portId
],
1875 IX_ETH_ACC_MAC_TX_CNTRL1
,
1877 IX_ETH_ACC_TX_CNTRL1_PAD_EN
);
1879 ixEthAccMacState
[portId
].txPADAppend
= TRUE
;
1880 return IX_ETH_ACC_SUCCESS
;
1884 ixEthAccPortTxFrameAppendPaddingDisablePriv (IxEthAccPortId portId
)
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
,
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
;
1916 ixEthAccPortTxFrameAppendFCSEnablePriv (IxEthAccPortId portId
)
1920 /*Enable FCS computation by the MAC and appending to the
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
,
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
;
1949 ixEthAccPortTxFrameAppendFCSDisablePriv (IxEthAccPortId portId
)
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
,
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
;
1981 ixEthAccPortRxFrameAppendFCSEnablePriv (IxEthAccPortId portId
)
1983 /*Set bit 2 of Rx control 1*/
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
,
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
;
2012 ixEthAccPortRxFrameAppendFCSDisablePriv (IxEthAccPortId portId
)
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
,
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
;
2045 ixEthAccMacNpeStatsMessageCallback (IxNpeMhNpeId npeId
,
2048 IxEthAccPortId portId
= IX_ETH_ACC_NPE_TO_PORT_ID(npeId
);
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);
2061 /*Unblock Stats Get call*/
2062 ixOsalMutexUnlock(&ixEthAccMacState
[portId
].ackMIBStatsLock
);
2067 ixEthAccMibIIStatsEndianConvert (IxEthEthObjStats
*retStats
)
2069 /* endianness conversion */
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
);
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
);
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
2165 ixOsalMutexLock(&ixEthAccMacState
[portId
].MIBStatsGetAccessLock
, IX_OSAL_WAIT_FOREVER
);
2167 if(ixNpeMhMessageWithResponseSend(IX_ETH_ACC_PORT_TO_NPE_ID(portId
),
2170 ixEthAccMacNpeStatsMessageCallback
,
2171 IX_NPEMH_SEND_RETRIES_DEFAULT
)
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
;
2196 ixEthAccMacNpeStatsResetMessageCallback (IxNpeMhNpeId npeId
,
2199 IxEthAccPortId portId
= IX_ETH_ACC_NPE_TO_PORT_ID(npeId
);
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);
2212 /*Unblock Stats Get & reset call*/
2213 ixOsalMutexUnlock(&ixEthAccMacState
[portId
].ackMIBStatsResetLock
);
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
),
2267 IX_ETHNPE_RESETSTATS
,
2268 ixEthAccMacNpeStatsResetMessageCallback
,
2269 IX_NPEMH_SEND_RETRIES_DEFAULT
)
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
;
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
);
2315 /* Initialize the ethernet MAC settings */
2317 ixEthAccMacInit(IxEthAccPortId portId
)
2319 IX_OSAL_MBUF_POOL
* portDisablePool
;
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
),
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*/
2416 ixEthAccMacStateUpdate(IxEthAccPortId portId
)
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
,
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
,
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
);
2444 ixEthAccPortDuplexModeSetPriv (portId
, IX_ETH_ACC_HALF_DUPLEX
);
2447 if(ixEthAccMacState
[portId
].rxFCSAppend
)
2449 ixEthAccPortRxFrameAppendFCSEnablePriv (portId
);
2453 ixEthAccPortRxFrameAppendFCSDisablePriv (portId
);
2456 if(ixEthAccMacState
[portId
].txFCSAppend
)
2458 ixEthAccPortTxFrameAppendFCSEnablePriv (portId
);
2462 ixEthAccPortTxFrameAppendFCSDisablePriv (portId
);
2465 if(ixEthAccMacState
[portId
].txPADAppend
)
2467 ixEthAccPortTxFrameAppendPaddingEnablePriv (portId
);
2471 ixEthAccPortTxFrameAppendPaddingDisablePriv (portId
);
2474 if(ixEthAccMacState
[portId
].promiscuous
)
2476 ixEthAccPortPromiscuousModeSetPriv(portId
);
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
,
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
,
2496 REG_WRITE(ixEthAccMacBase
[portId
],
2497 IX_ETH_ACC_MAC_TX_CNTRL1
,
2498 regval
| IX_ETH_ACC_TX_CNTRL1_TX_EN
);
2504 ixEthAccMacEqual(IxEthAccMacAddr
*macAddr1
,
2505 IxEthAccMacAddr
*macAddr2
)
2508 for(i
=0;i
<IX_IEEE803_MAC_ADDRESS_SIZE
; i
++)
2510 if(macAddr1
->macAddress
[i
] != macAddr2
->macAddress
[i
])
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
2538 ixEthAccMulticastAddressSet(IxEthAccPortId portId
)
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
2563 memset(&addressMask
.macAddress
,
2565 IX_IEEE803_MAC_ADDRESS_SIZE
);
2566 memset(&address
.macAddress
,
2568 IX_IEEE803_MAC_ADDRESS_SIZE
);
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
,
2581 IX_IEEE803_MAC_ADDRESS_SIZE
);
2582 memcpy(address
.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
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
);
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
]);