1  /**********************************************************************
2  * Copyright (C) 2014-2015 Cadence Design Systems, Inc.- http://www.cadence.com
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  ******************************************************************************
17  * edd.c
18  * Ethernet DMA MAC Driver,
19  * for GEM GXL core part no. IP7014, from rev 1p05 up
20  * for GEM XL  core part no. IP7012, from rev 1p01 up
21  * and XGM GXL core part no. IP716,  from rev 1p01 up
22  *
23  * Main source file
24  *****************************************************************************/
25 
26 /****************************************************************************
27 * Modification by Infineon: To make this file compile with ModusToolbox
28 * toolchain
29 *****************************************************************************/
30 
31 #include "cy_device.h"
32 #include "cy_syslib.h"
33 
34 #if defined(CY_IP_MXETH)
35 
36 #include "cdn_stdint.h"
37 #include "cdn_errno.h"
38 #include "log.h"
39 #include "cps_v2.h"
40 #include "emac_regs.h"
41 #include "cedi.h"
42 #include "edd_int.h"
43 
44 #ifdef __cplusplus
45     extern "C" {
46 #endif
47 
48 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
49 __STATIC_FORCEINLINE void SCB_InvalidateDCache_by_Addr (volatile void *addr, int32_t dsize);
50 __STATIC_FORCEINLINE void SCB_CleanDCache_by_Addr (volatile void *addr, int32_t dsize);
51 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
52 /******************************************************************************
53  * Private Driver functions
54  *****************************************************************************/
55 
CPS_UncachedRead32(volatile uint32_t * address)56 uint32_t CPS_UncachedRead32(volatile uint32_t* address) {
57     /** Invalidate cache **/
58 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
59     SCB_InvalidateDCache_by_Addr(address, (int32_t)4);
60 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
61     return (*((volatile uint32_t *)(address)));
62 }
63 
CPS_UncachedWrite32(volatile uint32_t * address,uint32_t value)64 void CPS_UncachedWrite32(volatile uint32_t* address, uint32_t value) {
65     (*((volatile uint32_t *)(address)) = (value));
66     /** Clean cache **/
67 #if (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE)
68     SCB_CleanDCache_by_Addr(address, (int32_t)4);
69 #endif /* (CY_CPU_CORTEX_M7) && defined (ENABLE_CM7_DATA_CACHE) */
70     return;
71 }
72 
CPS_WritePhysAddress32(volatile uint32_t * address,uint32_t value)73 void CPS_WritePhysAddress32(volatile uint32_t* address, uint32_t value) {
74     (*((volatile uint32_t *)(address)) = (value));
75     return;
76 }
77 /* Calculate the descriptor sizes (in bytes) for a given DMA config */
calcDescriptorSizes(const CEDI_Config * config,uint16_t * txDescSize,uint16_t * rxDescSize)78 static void calcDescriptorSizes(const CEDI_Config *config,
79                                 uint16_t *txDescSize,
80                                 uint16_t *rxDescSize) {
81 
82     /* use 1 contiguous block for Tx descriptor lists
83      * and another contiguous block for Rx descriptor lists */
84     *txDescSize = CEDI_TWO_BD_WORD_SIZE;
85     *rxDescSize = CEDI_TWO_BD_WORD_SIZE;
86 
87     if (config->dmaAddrBusWidth)  // DMA address bus width. 0 =32b , 1=64b
88     {
89          *txDescSize += CEDI_TWO_BD_WORD_SIZE;
90          *rxDescSize += CEDI_TWO_BD_WORD_SIZE;
91     }
92 
93     if (config->enTxExtBD){
94         *txDescSize += CEDI_TWO_BD_WORD_SIZE;
95     }
96 
97     if (config->enRxExtBD){
98         *rxDescSize += CEDI_TWO_BD_WORD_SIZE;
99     }
100 }
101 
numTxDescriptors(CEDI_Config * config)102 static uint32_t numTxDescriptors(CEDI_Config *config)
103 {
104     uint16_t i;
105     uint16_t sumTxDesc = 0;
106 
107     for (i=0; i<config->txQs; i++)
108         /* allow 1 extra for "endstop" descriptor */
109         sumTxDesc += ((uint32_t)((config->txQLen)[i]+CEDI_MIN_TXBD));
110     return sumTxDesc;
111 }
112 
numRxDescriptors(CEDI_Config * config)113 static uint32_t numRxDescriptors(CEDI_Config *config)
114 {
115     uint16_t i;
116     uint16_t sumRxDesc = 0;
117 
118     for (i=0; i<config->rxQs; i++)
119         /* allow 1 extra for "endstop" descriptor */
120         sumRxDesc += ((uint32_t)((config->rxQLen)[i]+CEDI_MIN_RXBD));
121     return sumRxDesc;
122 }
123 
initTxDescLists(void * pD)124 static uint32_t initTxDescLists(void *pD)
125 {
126     uint8_t q;
127 
128     /* set start of Tx vAddr lists - place in pD block after
129      * privateData struct */
130     CEDI_PdVar(txQueue[0]).vAddrList =
131                             (uintptr_t *)((uint8_t *)pD + sizeof(CEDI_PrivateData));
132     for (q=0; q<CEDI_PdVar(cfg).txQs; q++)
133         if (0!=emacResetTxQ(pD, q))
134             return EINVAL;
135 
136     return 0;
137 }
138 
139 /* Initialise Rx descriptor lists - also in pD block, after the Tx ones */
initRxDescLists(void * pD)140 uint32_t initRxDescLists(void *pD)
141 {
142     uint8_t q;
143     uint32_t pAddr, i;
144     uintptr_t vAddr;
145     rxQueue_t *rxQ;
146     rxDesc* descPtr;
147 
148     /* set start of Rx vAddr lists after Tx lists */
149     CEDI_PdVar(rxQueue[0]).rxBufVAddr =
150                 (uintptr_t *)((uint8_t *)pD + sizeof(CEDI_PrivateData) +
151                   sizeof(uintptr_t)*(numTxDescriptors(&CEDI_PdVar(cfg))));
152 
153     for (q=0; q<CEDI_PdVar(cfg).rxQs; q++) {
154 
155         rxQ = &(CEDI_PdVar(rxQueue[q]));
156         rxQ->numRxDesc = CEDI_PdVar(cfg).rxQLen[q] + CEDI_MIN_RXBD;
157 
158         emacFindQBaseAddr(pD, q, rxQ, &pAddr, &vAddr);
159         rxQ->rxDescStart = (rxDesc *)vAddr;
160 
161         /* initialise the descriptors */
162         descPtr = rxQ->rxDescStart;
163         for (i = 0; i<rxQ->numRxDesc; i++) {
164             CPS_UncachedWrite32((uint32_t *)
165                     &(descPtr->word[0]), i?0:CEDI_RXD_WRAP|CEDI_RXD_USED);
166             CPS_UncachedWrite32((uint32_t *)
167                     &(descPtr->word[1]), CEDI_RXD_EMPTY);
168             descPtr = (rxDesc*) (((uintptr_t)(descPtr)) +
169                     (CEDI_PdVar(rxDescriptorSize)));
170         }
171 
172         if (0!=emacResetRxQ(pD, q, 0))
173           return EINVAL;
174     }
175 
176     return 0;
177 }
178 
179 
180 /* return the number of priority queues available in the h/w config */
maxHwQs(uintptr_t regBase)181 static uint8_t maxHwQs(uintptr_t regBase) {
182     uint8_t qCount = 1;
183     uint32_t reg = CPS_UncachedRead32(
184             (&(((struct emac_regs *)(regBase))->designcfg_debug6)));
185     if (EMAC_REGS__DESIGNCFG_DEBUG6__DMA_PRIORITY_QUEUE1__READ(reg)) qCount++;
186     if (EMAC_REGS__DESIGNCFG_DEBUG6__DMA_PRIORITY_QUEUE2__READ(reg)) qCount++;
187     if (EMAC_REGS__DESIGNCFG_DEBUG6__DMA_PRIORITY_QUEUE3__READ(reg)) qCount++;
188     if (EMAC_REGS__DESIGNCFG_DEBUG6__DMA_PRIORITY_QUEUE4__READ(reg)) qCount++;
189     if (EMAC_REGS__DESIGNCFG_DEBUG6__DMA_PRIORITY_QUEUE5__READ(reg)) qCount++;
190     if (EMAC_REGS__DESIGNCFG_DEBUG6__DMA_PRIORITY_QUEUE6__READ(reg)) qCount++;
191     if (EMAC_REGS__DESIGNCFG_DEBUG6__DMA_PRIORITY_QUEUE7__READ(reg)) qCount++;
192     if (EMAC_REGS__DESIGNCFG_DEBUG6__DMA_PRIORITY_QUEUE8__READ(reg)) qCount++;
193     if (EMAC_REGS__DESIGNCFG_DEBUG6__DMA_PRIORITY_QUEUE9__READ(reg)) qCount++;
194     if (EMAC_REGS__DESIGNCFG_DEBUG6__DMA_PRIORITY_QUEUE10__READ(reg)) qCount++;
195     if (EMAC_REGS__DESIGNCFG_DEBUG6__DMA_PRIORITY_QUEUE11__READ(reg)) qCount++;
196     if (EMAC_REGS__DESIGNCFG_DEBUG6__DMA_PRIORITY_QUEUE12__READ(reg)) qCount++;
197     if (EMAC_REGS__DESIGNCFG_DEBUG6__DMA_PRIORITY_QUEUE13__READ(reg)) qCount++;
198     if (EMAC_REGS__DESIGNCFG_DEBUG6__DMA_PRIORITY_QUEUE14__READ(reg)) qCount++;
199     if (EMAC_REGS__DESIGNCFG_DEBUG6__DMA_PRIORITY_QUEUE15__READ(reg)) qCount++;
200     return qCount;
201 }
202 
disableAllInterrupts(void * pD)203 static void disableAllInterrupts(void *pD)
204 {
205 #define CEDI_DISABLE_ALL_INT(Q)  if (CEDI_PdVar(numQs)>Q) \
206         CPS_UncachedWrite32(CEDI_RegAddr(int_q##Q##_disable), 0xFFFFFFFF);
207 
208     CPS_UncachedWrite32(CEDI_RegAddr(int_disable), 0xFFFFFFFF);
209 
210     CEDI_DISABLE_ALL_INT(1);
211     CEDI_DISABLE_ALL_INT(2);
212 /*  // Only Three Queues are supported
213     CEDI_DISABLE_ALL_INT(3);
214     CEDI_DISABLE_ALL_INT(4);
215     CEDI_DISABLE_ALL_INT(5);
216     CEDI_DISABLE_ALL_INT(6);
217     CEDI_DISABLE_ALL_INT(7);
218     CEDI_DISABLE_ALL_INT(8);
219     CEDI_DISABLE_ALL_INT(9);
220     CEDI_DISABLE_ALL_INT(10);
221     CEDI_DISABLE_ALL_INT(11);
222     CEDI_DISABLE_ALL_INT(12);
223     CEDI_DISABLE_ALL_INT(13);
224     CEDI_DISABLE_ALL_INT(14);
225     CEDI_DISABLE_ALL_INT(15);
226 */
227 }
228 
clearAllInterrupts(void * pD)229 static void clearAllInterrupts(void *pD)
230 {
231 
232 #define CEDI_CLEAR_ALL_WRCLR_INT(Q)  if (CEDI_PdVar(numQs)>Q) \
233         CPS_UncachedWrite32(CEDI_RegAddr(int_q##Q##_status), 0xFFFFFFFF);
234 
235 #define CEDI_CLEAR_ALL_RDCLR_INT(Q)  if (CEDI_PdVar(numQs)>Q) \
236         CPS_UncachedRead32(CEDI_RegAddr(int_q##Q##_status));
237 
238     if (0==CEDI_PdVar(hwCfg).irq_read_clear) {
239         CPS_UncachedWrite32(CEDI_RegAddr(int_status), 0xFFFFFFFF);
240         CEDI_CLEAR_ALL_RDCLR_INT(1);
241         CEDI_CLEAR_ALL_RDCLR_INT(2);
242 /*      // Only Three Queues are supported
243         CEDI_CLEAR_ALL_RDCLR_INT(3);
244         CEDI_CLEAR_ALL_RDCLR_INT(4);
245         CEDI_CLEAR_ALL_RDCLR_INT(5);
246         CEDI_CLEAR_ALL_RDCLR_INT(6);
247         CEDI_CLEAR_ALL_RDCLR_INT(7);
248         CEDI_CLEAR_ALL_RDCLR_INT(8);
249         CEDI_CLEAR_ALL_RDCLR_INT(9);
250         CEDI_CLEAR_ALL_RDCLR_INT(10);
251         CEDI_CLEAR_ALL_RDCLR_INT(11);
252         CEDI_CLEAR_ALL_RDCLR_INT(12);
253         CEDI_CLEAR_ALL_RDCLR_INT(13);
254         CEDI_CLEAR_ALL_RDCLR_INT(14);
255         CEDI_CLEAR_ALL_RDCLR_INT(15);
256 */
257     }
258     else {
259         CPS_UncachedRead32(CEDI_RegAddr(int_status));
260         CEDI_CLEAR_ALL_WRCLR_INT(1);
261         CEDI_CLEAR_ALL_WRCLR_INT(2);
262 /*      // Only Three Queues are supported
263         CEDI_CLEAR_ALL_WRCLR_INT(3);
264         CEDI_CLEAR_ALL_WRCLR_INT(4);
265         CEDI_CLEAR_ALL_WRCLR_INT(5);
266         CEDI_CLEAR_ALL_WRCLR_INT(6);
267         CEDI_CLEAR_ALL_WRCLR_INT(7);
268         CEDI_CLEAR_ALL_WRCLR_INT(8);
269         CEDI_CLEAR_ALL_WRCLR_INT(9);
270         CEDI_CLEAR_ALL_WRCLR_INT(10);
271         CEDI_CLEAR_ALL_WRCLR_INT(11);
272         CEDI_CLEAR_ALL_WRCLR_INT(12);
273         CEDI_CLEAR_ALL_WRCLR_INT(13);
274         CEDI_CLEAR_ALL_WRCLR_INT(14);
275         CEDI_CLEAR_ALL_WRCLR_INT(15);
276 */
277     }
278 }
279 
280 /* Return all registers to reset values */
initAllRegs(void * pD)281 static void initAllRegs(void *pD)
282 {
283     CPS_UncachedWrite32(CEDI_RegAddr(network_control), 0);
284     CPS_UncachedWrite32(CEDI_RegAddr(network_config), 0);
285 //    CPS_UncachedWrite32(CEDI_RegAddr(user_io_register), 0);
286     CPS_UncachedWrite32(CEDI_RegAddr(transmit_status), 0);
287     CPS_UncachedWrite32(CEDI_RegAddr(receive_q_ptr), 0);
288     CPS_UncachedWrite32(CEDI_RegAddr(transmit_q_ptr), 0);
289     CPS_UncachedWrite32(CEDI_RegAddr(receive_status), 0);
290     CPS_UncachedWrite32(CEDI_RegAddr(int_disable), 0xFFFFFFFF);
291     CPS_UncachedWrite32(CEDI_RegAddr(phy_management), 0);
292     CPS_UncachedWrite32(CEDI_RegAddr(tx_pause_quantum), 0xFFFFFFFF);
293     CPS_UncachedWrite32(CEDI_RegAddr(pbuf_txcutthru), 0x00003FFF);
294     CPS_UncachedWrite32(CEDI_RegAddr(pbuf_rxcutthru), 0x000007FF);
295     CPS_UncachedWrite32(CEDI_RegAddr(jumbo_max_length), 0x00002800);
296 //    CPS_UncachedWrite32(CEDI_RegAddr(external_fifo_interface), 0);
297 //    CPS_UncachedWrite32(CEDI_RegAddr(axi_max_pipeline), 0x00000101);
298 //    CPS_UncachedWrite32(CEDI_RegAddr(rsc_control), 0);
299     CPS_UncachedWrite32(CEDI_RegAddr(int_moderation), 0);
300     CPS_UncachedWrite32(CEDI_RegAddr(sys_wake_time), 0);
301     CPS_UncachedWrite32(CEDI_RegAddr(hash_bottom), 0);
302     CPS_UncachedWrite32(CEDI_RegAddr(hash_top), 0);
303     CPS_UncachedWrite32(CEDI_RegAddr(wol_register), 0);
304     CPS_UncachedWrite32(CEDI_RegAddr(stretch_ratio), 0);
305     CPS_UncachedWrite32(CEDI_RegAddr(stacked_vlan), 0);
306     CPS_UncachedWrite32(CEDI_RegAddr(tx_pfc_pause), 0);
307     CPS_UncachedWrite32(CEDI_RegAddr(mask_add1_bottom), 0);
308     CPS_UncachedWrite32(CEDI_RegAddr(mask_add1_top), 0);
309     CPS_UncachedWrite32(CEDI_RegAddr(dma_addr_or_mask), 0);
310     CPS_UncachedWrite32(CEDI_RegAddr(rx_ptp_unicast), 0);
311     CPS_UncachedWrite32(CEDI_RegAddr(tx_ptp_unicast), 0);
312     CPS_UncachedWrite32(CEDI_RegAddr(tsu_nsec_cmp), 0);
313     CPS_UncachedWrite32(CEDI_RegAddr(tsu_sec_cmp), 0);
314     CPS_UncachedWrite32(CEDI_RegAddr(tsu_msb_sec_cmp), 0);
315     CPS_UncachedWrite32(CEDI_RegAddr(dpram_fill_dbg), 0);
316 //    CPS_UncachedWrite32(CEDI_RegAddr(pcs_control), 0);
317 //    CPS_UncachedWrite32(CEDI_RegAddr(pcs_an_adv), 0);
318 //    CPS_UncachedWrite32(CEDI_RegAddr(pcs_an_np_tx), 0);
319     CPS_UncachedWrite32(CEDI_RegAddr(tx_pause_quantum1), 0xFFFFFFFF);
320     CPS_UncachedWrite32(CEDI_RegAddr(tx_pause_quantum2), 0xFFFFFFFF);
321     CPS_UncachedWrite32(CEDI_RegAddr(tx_pause_quantum3), 0xFFFFFFFF);
322     CPS_UncachedWrite32(CEDI_RegAddr(rx_lpi), 0);
323     CPS_UncachedWrite32(CEDI_RegAddr(rx_lpi_time), 0);
324     CPS_UncachedWrite32(CEDI_RegAddr(tx_lpi), 0);
325     CPS_UncachedWrite32(CEDI_RegAddr(tx_lpi_time), 0);
326     CPS_UncachedWrite32(CEDI_RegAddr(dpram_fill_dbg), 0);
327     CPS_UncachedWrite32(CEDI_RegAddr(cbs_control), 0);
328     CPS_UncachedWrite32(CEDI_RegAddr(cbs_idleslope_q_a), 0);
329     CPS_UncachedWrite32(CEDI_RegAddr(cbs_idleslope_q_b), 0);
330     CPS_UncachedWrite32(CEDI_RegAddr(upper_tx_q_base_addr), 0);
331     CPS_UncachedWrite32(CEDI_RegAddr(upper_rx_q_base_addr), 0);
332     CPS_UncachedWrite32(CEDI_RegAddr(tx_bd_control), 0);
333     CPS_UncachedWrite32(CEDI_RegAddr(rx_bd_control), 0);
334 }
335 
336 /* Check the selected callback(s) have non-NULL call addresses.
337  * Test all events selected, returning any with NULL callbacks.
338  * @param selection - bit-flags defining callback selection
339  * @return 0 if all OK (not NULL)
340  * @return OR'd combination of events whose cb function pointers are NULL
341  */
callbacksNullCheck(void * pD,uint32_t selection)342 static uint32_t callbacksNullCheck(void *pD, uint32_t selection)
343 {
344     uint32_t nullCbEvents = 0;
345 
346     if (!selection)
347         return 0;
348 
349     if ((selection & (CEDI_EV_TX_COMPLETE | CEDI_EV_TX_USED_READ))
350             && ((CEDI_PdVar(cb).txEvent)==NULL))
351     {
352         nullCbEvents |=
353                 (selection & (CEDI_EV_TX_COMPLETE | CEDI_EV_TX_USED_READ));
354         selection &= ~(CEDI_EV_TX_COMPLETE | CEDI_EV_TX_USED_READ);
355         if (!selection)
356             return nullCbEvents;
357     }
358 
359     if ((selection & CEDI_EV_RX_COMPLETE) &&
360                 ((CEDI_PdVar(cb).rxFrame)==NULL))
361     {
362         nullCbEvents |= (selection & CEDI_EV_RX_COMPLETE);
363         selection ^= ~selection & CEDI_EV_RX_COMPLETE;
364         if (!selection)
365             return nullCbEvents;
366     }
367     if ((selection & (CEDI_EV_TX_UNDERRUN | CEDI_EV_TX_RETRY_EX_LATE_COLL
368                         | CEDI_EV_TX_FR_CORRUPT )) &&
369                 ((CEDI_PdVar(cb).txError)==NULL))
370     {
371         nullCbEvents |= (selection & (CEDI_EV_TX_UNDERRUN |
372                         CEDI_EV_TX_RETRY_EX_LATE_COLL | CEDI_EV_TX_FR_CORRUPT));
373         selection &= ~(CEDI_EV_TX_UNDERRUN |
374                         CEDI_EV_TX_RETRY_EX_LATE_COLL | CEDI_EV_TX_FR_CORRUPT);
375         if (!selection)
376             return nullCbEvents;
377     }
378 
379     if ((selection & (CEDI_EV_RX_USED_READ | CEDI_EV_RX_OVERRUN)) &&
380                 ((((CEDI_PrivateData *)pD)->cb.rxError)==NULL))
381     {
382         nullCbEvents |= (selection & (CEDI_EV_RX_USED_READ | CEDI_EV_RX_OVERRUN));
383         selection &= ~(CEDI_EV_RX_USED_READ | CEDI_EV_RX_OVERRUN);
384         if (!selection)
385             return nullCbEvents;
386     }
387 
388     if ((selection & CEDI_EV_MAN_FRAME) &&
389             ((CEDI_PdVar(cb).phyManComplete)==NULL))
390     {
391         nullCbEvents |= CEDI_EV_MAN_FRAME;
392         selection &= ~CEDI_EV_MAN_FRAME;
393         if (!selection)
394             return nullCbEvents;
395     }
396 
397     if ((selection & CEDI_EV_HRESP_NOT_OK) &&
398                 ((CEDI_PdVar(cb).hrespError)==NULL))
399     {
400         nullCbEvents |= CEDI_EV_HRESP_NOT_OK;
401         selection &= ~CEDI_EV_HRESP_NOT_OK;
402         if (!selection)
403             return nullCbEvents;
404     }
405 
406     if ((selection & CEDI_EV_PCS_LP_PAGE_RX) &&
407                 ((CEDI_PdVar(cb).lpPageRx)==NULL))
408     {
409         nullCbEvents |= CEDI_EV_PCS_LP_PAGE_RX;
410         selection &= ~CEDI_EV_PCS_LP_PAGE_RX;
411         if (!selection)
412             return nullCbEvents;
413     }
414 
415     if ((selection & CEDI_EV_PCS_AN_COMPLETE) &&
416                 ((CEDI_PdVar(cb).anComplete)==NULL))
417     {
418         nullCbEvents |= CEDI_EV_PCS_AN_COMPLETE;
419         selection &= ~CEDI_EV_PCS_AN_COMPLETE;
420         if (!selection)
421             return nullCbEvents;
422     }
423 
424     if ((selection & CEDI_EV_PCS_LINK_CHANGE_DET) &&
425                 ((CEDI_PdVar(cb).linkChange)==NULL))
426     {
427         nullCbEvents |= CEDI_EV_PCS_LINK_CHANGE_DET;
428         selection &= ~CEDI_EV_PCS_LINK_CHANGE_DET;
429         if (!selection)
430             return nullCbEvents;
431     }
432 
433     if ((selection & (CEDI_EV_TSU_SEC_INC | CEDI_EV_TSU_TIME_MATCH)) &&
434                 ((CEDI_PdVar(cb).tsuEvent)==NULL))
435     {
436         nullCbEvents |= (selection &
437                         (CEDI_EV_TSU_SEC_INC | CEDI_EV_TSU_TIME_MATCH));
438         selection &= ~(CEDI_EV_TSU_SEC_INC | CEDI_EV_TSU_TIME_MATCH);
439         if (!selection)
440             return nullCbEvents;
441     }
442 
443     if ((selection & (CEDI_EV_PAUSE_FRAME_TX | CEDI_EV_PAUSE_TIME_ZERO |
444             CEDI_EV_PAUSE_NZ_QU_RX)) &&
445                 ((CEDI_PdVar(cb).pauseEvent)==NULL))
446     {
447         nullCbEvents |= (selection & (CEDI_EV_PAUSE_FRAME_TX |
448                 CEDI_EV_PAUSE_TIME_ZERO | CEDI_EV_PAUSE_NZ_QU_RX));
449         selection &= ~(CEDI_EV_PAUSE_FRAME_TX | CEDI_EV_PAUSE_TIME_ZERO |
450                             CEDI_EV_PAUSE_NZ_QU_RX);
451         if (!selection)
452             return nullCbEvents;
453     }
454 
455     if ((selection & (CEDI_EV_PTP_TX_DLY_REQ | CEDI_EV_PTP_TX_SYNC)) &&
456                 ((CEDI_PdVar(cb).ptpPriFrameTx)==NULL))
457     {
458         nullCbEvents |= (selection &
459                         (CEDI_EV_PTP_TX_DLY_REQ | CEDI_EV_PTP_TX_SYNC));
460         selection &= ~(CEDI_EV_PTP_TX_DLY_REQ | CEDI_EV_PTP_TX_SYNC);
461         if (!selection)
462             return nullCbEvents;
463     }
464 
465 
466     if ((selection & (CEDI_EV_PTP_TX_PDLY_REQ | CEDI_EV_PTP_TX_PDLY_RSP)) &&
467                 ((CEDI_PdVar(cb).ptpPeerFrameTx)==NULL))
468     {
469         nullCbEvents |= (selection &
470                         (CEDI_EV_PTP_TX_PDLY_REQ | CEDI_EV_PTP_TX_PDLY_RSP ));
471         selection &= ~(CEDI_EV_PTP_TX_PDLY_REQ | CEDI_EV_PTP_TX_PDLY_RSP );
472         if (!selection)
473             return nullCbEvents;
474     }
475 
476     if ((selection & (CEDI_EV_PTP_RX_DLY_REQ | CEDI_EV_PTP_RX_SYNC)) &&
477                 ((CEDI_PdVar(cb).ptpPriFrameRx)==NULL))
478     {
479         nullCbEvents |= (selection &
480                         (CEDI_EV_PTP_RX_DLY_REQ | CEDI_EV_PTP_RX_SYNC));
481         selection &= ~(CEDI_EV_PTP_RX_DLY_REQ | CEDI_EV_PTP_RX_SYNC);
482         if (!selection)
483             return nullCbEvents;
484     }
485 
486     if ((selection & (CEDI_EV_PTP_RX_PDLY_REQ | CEDI_EV_PTP_RX_PDLY_RSP)) &&
487                 ((CEDI_PdVar(cb).ptpPeerFrameRx)==NULL))
488     {
489         nullCbEvents |= (selection &
490                         (CEDI_EV_PTP_RX_PDLY_REQ | CEDI_EV_PTP_RX_PDLY_RSP));
491         selection &= ~(CEDI_EV_PTP_RX_PDLY_REQ | CEDI_EV_PTP_RX_PDLY_RSP);
492         if (!selection)
493             return nullCbEvents;
494     }
495 
496     if ((selection & CEDI_EV_LPI_CH_RX) && ((CEDI_PdVar(cb).lpiStatus)==NULL))
497     {
498         nullCbEvents |= CEDI_EV_LPI_CH_RX;
499         selection &= ~CEDI_EV_LPI_CH_RX;
500         if (!selection)
501             return nullCbEvents;
502     }
503 
504     if ((selection & CEDI_EV_WOL_RX) && ((CEDI_PdVar(cb).wolEvent)==NULL))
505     {
506         nullCbEvents |= CEDI_EV_WOL_RX;
507         selection &= ~CEDI_EV_WOL_RX;
508         if (!selection)
509             return nullCbEvents;
510     }
511 
512     if ((selection & CEDI_EV_EXT_INTR) && ((CEDI_PdVar(cb).extInpIntr)==NULL))
513     {
514         nullCbEvents |= CEDI_EV_EXT_INTR;
515         selection &= ~CEDI_EV_EXT_INTR;
516     }
517 
518 
519     return nullCbEvents;
520 }
521 
522 /* initializing the upper 32 bit buffer queue base addresses from config */
initUpper32BuffQAddr(void * pD)523 static void  initUpper32BuffQAddr(void *pD)
524 {
525     uint32_t regData;
526 
527     regData = 0;
528 
529 #ifdef EMAC_REGS__UPPER_RX_Q_BASE_ADDR__UPPER_RX_Q_BASE_ADDR__MODIFY
530     EMAC_REGS__UPPER_TX_Q_BASE_ADDR__UPPER_TX_Q_BASE_ADDR__MODIFY(
531             regData, CEDI_PdVar(cfg).upper32BuffTxQAddr);
532 
533     CPS_UncachedWrite32(CEDI_RegAddr(upper_tx_q_base_addr), regData);
534 
535     regData = 0;
536     EMAC_REGS__UPPER_RX_Q_BASE_ADDR__UPPER_RX_Q_BASE_ADDR__MODIFY(
537             regData, CEDI_PdVar(cfg).upper32BuffRxQAddr);
538 
539     CPS_UncachedWrite32(CEDI_RegAddr(upper_rx_q_base_addr), regData);
540 #else
541     EMAC_REGS__MSB_BUFF_Q_BASE_ADDR_REG__MSB_BUFF_Q_BASE_ADDR__MODIFY(
542             regData, CEDI_PdVar(cfg).upper32BuffTxQAddr);
543 
544     CPS_UncachedWrite32(CEDI_RegAddr(msb_buff_q_base_addr_reg), regData);
545 #endif
546 }
547 
548 /* Initialise axi_max_pipeline register from config struct */
initAxiMaxPipelineReg(void * pD)549 static void initAxiMaxPipelineReg(void *pD)
550 {
551     CEDI_Config *config = &CEDI_PdVar(cfg);
552     uint32_t regData, axiPipelineFifoDepth;
553 
554     regData = CPS_UncachedRead32(CEDI_RegAddr(axi_max_pipeline));
555     axiPipelineFifoDepth = 1<<(CEDI_PdVar(hwCfg).axi_access_pipeline_bits);
556 
557     /* value of max pipeline must be >0 and not greater than fifo depth
558      * (2^axi_access_pipeline) */
559     if ((CEDI_PdVar(hwCfg).axi) && (config->aw2wMaxPipeline==0)) {
560         vDbgMsg(DBG_GEN_MSG, 5, "%s\n",
561             "*** Warning: aw2wMaxPipeline requested value = 0, increasing to 1");
562         config->aw2wMaxPipeline = 1;
563     } else if ((config->aw2wMaxPipeline) > axiPipelineFifoDepth) {
564         vDbgMsg(DBG_GEN_MSG, 5, "*** Warning: aw2wMaxPipeline requested"\
565             "value (%u) greater than fifo depth (%u), reducing to %u\n",
566             config->aw2wMaxPipeline, axiPipelineFifoDepth, axiPipelineFifoDepth);
567         config->aw2wMaxPipeline = axiPipelineFifoDepth;
568     }
569     EMAC_REGS__AXI_MAX_PIPELINE__AW2W_MAX_PIPELINE__MODIFY(
570                                     regData, config->aw2wMaxPipeline);
571 
572     if ((CEDI_PdVar(hwCfg).axi) && (config->ar2rMaxPipeline==0)) {
573         vDbgMsg(DBG_GEN_MSG, 5, "%s\n",
574             "*** Warning: ar2rMaxPipeline requested value = 0, increasing to 1");
575         config->ar2rMaxPipeline = 1;
576     }
577     else if ((config->ar2rMaxPipeline) > axiPipelineFifoDepth) {
578         vDbgMsg(DBG_GEN_MSG, 5, "*** Warning: ar2rMaxPipeline requested"\
579             "value (%u) greater than fifo depth (%u), reducing to %u\n",
580             config->ar2rMaxPipeline, axiPipelineFifoDepth, axiPipelineFifoDepth);
581         config->ar2rMaxPipeline = axiPipelineFifoDepth;
582     }
583     EMAC_REGS__AXI_MAX_PIPELINE__AR2R_MAX_PIPELINE__MODIFY(
584                                     regData, config->ar2rMaxPipeline);
585 
586     CPS_UncachedWrite32(CEDI_RegAddr(axi_max_pipeline), regData);
587 }
588 
589 /* Initialise Network Control register from config struct */
initNetControlReg(void * pD)590 static void initNetControlReg(void *pD)
591 {
592     CEDI_Config *config = &CEDI_PdVar(cfg);
593     uint32_t regTmp;
594 
595     /* Disable everything first to be safe */
596     regTmp = 0;
597     CPS_UncachedWrite32(CEDI_RegAddr(network_control), regTmp);
598 
599     if (config->enableMdio)
600         EMAC_REGS__NETWORK_CONTROL__MAN_PORT_EN__SET(regTmp);
601 
602     if (config->altSgmiiEn)
603         EMAC_REGS__NETWORK_CONTROL__ALT_SGMII_MODE__SET(regTmp);
604 
605     if (config->storeUdpTcpOffset)
606         EMAC_REGS__NETWORK_CONTROL__STORE_UDP_OFFSET__SET(regTmp);
607 
608     /* for ext. TSU require tsu configured */
609     if ((config->enExtTsuPort) && CEDI_PdVar(hwCfg).tsu)
610         EMAC_REGS__NETWORK_CONTROL__EXT_TSU_PORT_ENABLE__SET(regTmp);
611     /* pfc multi quantum functionality */
612     if(config->pfcMultiQuantum)
613         EMAC_REGS__NETWORK_CONTROL__PFC_CTRL__SET(regTmp);
614     /* clear stats */
615     EMAC_REGS__NETWORK_CONTROL__CLEAR_ALL_STATS_REGS__SET(regTmp);
616 
617     CPS_UncachedWrite32(CEDI_RegAddr(network_control), regTmp);
618 }
619 
620 /* Initialise DMA Config register from config struct */
initDmaConfigReg(void * pD)621 static void initDmaConfigReg(void *pD)
622 {
623   CEDI_Config *config = &CEDI_PdVar(cfg);
624   uint32_t regTmp = 0, tmp1;
625 
626   switch(config->dmaDataBurstLen) {
627   case CEDI_DMA_DBUR_LEN_1:
628       tmp1 = CEDI_AMBD_BURST_LEN_1;
629       break;
630   case CEDI_DMA_DBUR_LEN_4:
631       tmp1 = CEDI_AMBD_BURST_LEN_4;
632       break;
633   case CEDI_DMA_DBUR_LEN_8:
634       tmp1 = CEDI_AMBD_BURST_LEN_8;
635       break;
636   case CEDI_DMA_DBUR_LEN_16:
637       tmp1 = CEDI_AMBD_BURST_LEN_16;
638       break;
639   default:
640       tmp1 = CEDI_AMBD_BURST_LEN_4;
641       break;
642   }
643   EMAC_REGS__DMA_CONFIG__AMBA_BURST_LENGTH__MODIFY(regTmp, tmp1);
644 
645   if (config->dmaEndianism & CEDI_END_SWAP_DESC)
646       EMAC_REGS__DMA_CONFIG__ENDIAN_SWAP_MANAGEMENT__SET(regTmp);
647   if (config->dmaEndianism & CEDI_END_SWAP_DATA)
648       EMAC_REGS__DMA_CONFIG__ENDIAN_SWAP_PACKET__SET(regTmp);
649 
650   EMAC_REGS__DMA_CONFIG__RX_PBUF_SIZE__MODIFY(regTmp, config->rxPktBufSize);
651   EMAC_REGS__DMA_CONFIG__TX_PBUF_SIZE__MODIFY(regTmp, config->txPktBufSize);
652 
653   if (config->chkSumOffEn & CEDI_CFG_CHK_OFF_TX)
654       EMAC_REGS__DMA_CONFIG__TX_PBUF_TCP_EN__SET(regTmp);
655 
656   EMAC_REGS__DMA_CONFIG__RX_BUF_SIZE__MODIFY(regTmp, config->rxBufLength[0]);
657 
658   if (config->dmaCfgFlags & CEDI_CFG_DMA_DISC_RXP)
659       EMAC_REGS__DMA_CONFIG__FORCE_DISCARD_ON_ERR__SET(regTmp);
660 
661   if (config->dmaCfgFlags & CEDI_CFG_DMA_FRCE_RX_BRST)
662       EMAC_REGS__DMA_CONFIG__FORCE_MAX_AMBA_BURST_RX__SET(regTmp);
663 
664   if (config->dmaCfgFlags & CEDI_CFG_DMA_FRCE_TX_BRST)
665       EMAC_REGS__DMA_CONFIG__FORCE_MAX_AMBA_BURST_TX__SET(regTmp);
666 
667   if (config->dmaAddrBusWidth)
668       EMAC_REGS__DMA_CONFIG__DMA_ADDR_BUS_WIDTH_1__SET(regTmp);
669 
670   if (config->enTxExtBD)
671       EMAC_REGS__DMA_CONFIG__TX_BD_EXTENDED_MODE_EN__SET(regTmp);
672 
673   if (config->enRxExtBD)
674       EMAC_REGS__DMA_CONFIG__RX_BD_EXTENDED_MODE_EN__SET(regTmp);
675 
676   CPS_UncachedWrite32(CEDI_RegAddr(dma_config), regTmp);
677 }
678 
679 /* Initialise Network Config register from config struct */
initNetConfigReg(void * pD)680 static void initNetConfigReg(void *pD)
681 {
682     CEDI_Config *config = &CEDI_PdVar(cfg);
683     uint32_t regTmp = 0;
684 
685     if ((config->ifTypeSel==CEDI_IFSP_1000M_GMII) ||
686             (config->ifTypeSel==CEDI_IFSP_1000M_SGMII) ||
687             (config->ifTypeSel==CEDI_IFSP_1000BASE_X))
688         EMAC_REGS__NETWORK_CONFIG__GIGABIT_MODE_ENABLE__SET(regTmp);
689 
690     if ((config->ifTypeSel==CEDI_IFSP_10M_SGMII) ||
691             (config->ifTypeSel==CEDI_IFSP_100M_SGMII) ||
692             (config->ifTypeSel==CEDI_IFSP_1000M_SGMII) ||
693             (config->ifTypeSel==CEDI_IFSP_1000BASE_X))
694         EMAC_REGS__NETWORK_CONFIG__PCS_SELECT__SET(regTmp);
695 
696     if ((config->ifTypeSel==CEDI_IFSP_10M_SGMII) ||
697             (config->ifTypeSel==CEDI_IFSP_100M_SGMII) ||
698             (config->ifTypeSel==CEDI_IFSP_1000M_SGMII))
699         EMAC_REGS__NETWORK_CONFIG__SGMII_MODE_ENABLE__SET(regTmp);
700 
701     if (config->uniDirEnable)
702         EMAC_REGS__NETWORK_CONFIG__UNI_DIRECTION_ENABLE__SET(regTmp);
703 
704     if ((config->ifTypeSel != CEDI_IFSP_10M_MII) &&
705             (config->ifTypeSel != CEDI_IFSP_10M_SGMII))
706         EMAC_REGS__NETWORK_CONFIG__SPEED__SET(regTmp);
707 
708     if (config->fullDuplex)
709         EMAC_REGS__NETWORK_CONFIG__FULL_DUPLEX__SET(regTmp);
710 
711     if (config->enRxHalfDupTx)
712         EMAC_REGS__NETWORK_CONFIG__EN_HALF_DUPLEX_RX__SET(regTmp);
713 
714     if (config->ignoreIpgRxEr)
715         EMAC_REGS__NETWORK_CONFIG__IGNORE_IPG_RX_ER__SET(regTmp);
716 
717     if (config->enRxBadPreamble)
718         EMAC_REGS__NETWORK_CONFIG__NSP_CHANGE__SET(regTmp);
719 
720     if (config->rxJumboFrEn)
721         EMAC_REGS__NETWORK_CONFIG__JUMBO_FRAMES__SET(regTmp);
722 
723     if (config->rx1536ByteEn)
724         EMAC_REGS__NETWORK_CONFIG__RECEIVE_1536_BYTE_FRAMES__SET(regTmp);
725 
726     if (config->extAddrMatch)
727         EMAC_REGS__NETWORK_CONFIG__EXTERNAL_ADDRESS_MATCH_ENABLE__SET(regTmp);
728 
729     EMAC_REGS__NETWORK_CONFIG__RECEIVE_BUFFER_OFFSET__MODIFY(regTmp,
730             config->rxBufOffset);
731 
732     if (config->rxLenErrDisc)
733         EMAC_REGS__NETWORK_CONFIG__LENGTH_FIELD_ERROR_FRAME_DISCARD__SET(
734                 regTmp);
735 
736     EMAC_REGS__NETWORK_CONFIG__MDC_CLOCK_DIVISION__MODIFY(regTmp,
737             config->mdcPclkDiv);
738 
739     EMAC_REGS__NETWORK_CONFIG__DATA_BUS_WIDTH__MODIFY(regTmp,
740             config->dmaBusWidth);
741 
742     if (config->disCopyPause)
743         EMAC_REGS__NETWORK_CONFIG__DISABLE_COPY_OF_PAUSE_FRAMES__SET(regTmp);
744 
745     if (config->chkSumOffEn & CEDI_CFG_CHK_OFF_RX)
746         EMAC_REGS__NETWORK_CONFIG__RECEIVE_CHECKSUM_OFFLOAD_ENABLE__SET(regTmp);
747 
748     CPS_UncachedWrite32(CEDI_RegAddr(network_config), regTmp);
749 }
750 
751 
752 /* set Rx buffer sizes for Q>0 */
setRxQBufferSizes(void * pD,const CEDI_Config * config)753 static void setRxQBufferSizes(void *pD, const CEDI_Config *config)
754 {
755 #define CEDI_WR_RXQB_SIZE_N_CASE(Q) \
756      case Q: CPS_UncachedWrite32(CEDI_RegAddr(dma_rxbuf_size_q##Q), reg);\
757                     break;
758 
759     uint32_t reg, q;
760     if (CEDI_PdVar(cfg).rxQs>1)
761         for (q=1; q<=CEDI_PdVar(cfg).rxQs; q++) {
762             reg = 0;
763             EMAC_REGS__DMA_RXBUF_SIZE_Q__DMA_RX_Q_BUF_SIZE__MODIFY(
764                                     reg, config->rxBufLength[q]);
765             switch(q) {
766             CEDI_WR_RXQB_SIZE_N_CASE(1);
767             CEDI_WR_RXQB_SIZE_N_CASE(2);
768 /*          // Three queues are supported
769             CEDI_WR_RXQB_SIZE_N_CASE(3);
770             CEDI_WR_RXQB_SIZE_N_CASE(4);
771             CEDI_WR_RXQB_SIZE_N_CASE(5);
772             CEDI_WR_RXQB_SIZE_N_CASE(6);
773             CEDI_WR_RXQB_SIZE_N_CASE(7);
774             CEDI_WR_RXQB_SIZE_N_CASE(8);
775             CEDI_WR_RXQB_SIZE_N_CASE(9);
776             CEDI_WR_RXQB_SIZE_N_CASE(10);
777             CEDI_WR_RXQB_SIZE_N_CASE(11);
778             CEDI_WR_RXQB_SIZE_N_CASE(12);
779             CEDI_WR_RXQB_SIZE_N_CASE(13);
780             CEDI_WR_RXQB_SIZE_N_CASE(14);
781             CEDI_WR_RXQB_SIZE_N_CASE(15);
782 */
783             }
784         }
785 }
786 
787 /*****************  Hardware Revision Compatibility Tests  *******************/
788 
789 /* Return non-zero if h/w includes stateless offloads */
offloadsSupport(void * pD)790 uint32_t offloadsSupport(void *pD)
791 {
792     if (pD==NULL)
793         return 0;
794     else
795         return (((CEDI_PdVar(hwCfg).moduleId==GEM_GXL_MODULE_ID_V0)
796         || (CEDI_PdVar(hwCfg).moduleId==GEM_GXL_MODULE_ID_V1))
797                 && (CEDI_PdVar(hwCfg).moduleRev>=OFFLOADS_GEM_GXL_REV));
798 }
799 
800 /* Return non-zero if h/w includes 24bit sub-ns timer increment resolution */
subNsTsuInc24bSupport(void * pD)801 uint32_t subNsTsuInc24bSupport(void *pD)
802 {
803     if (pD==NULL)
804         return 0;
805     else
806     /* resolution increase came in at r1p06f2 */
807         return (((CEDI_PdVar(hwCfg).moduleId==GEM_GXL_MODULE_ID_V0)
808                  && (CEDI_PdVar(hwCfg).moduleRev==0x0106)
809                  && (CEDI_PdVar(hwCfg).fixNumber>=2))
810                 || ((CEDI_PdVar(hwCfg).moduleId==GEM_GXL_MODULE_ID_V0)
811                  && (CEDI_PdVar(hwCfg).moduleRev>0x0106))
812         || (CEDI_PdVar(hwCfg).moduleId>=GEM_GXL_MODULE_ID_V1));
813 }
814 
815 /* Read DesignConfig Debug registers into privateData for faster access.
816  * pD must point to a privateData struct with cfg.regBase set */
readDesignConfig(void * pD)817 uint32_t readDesignConfig(void *pD)
818 {
819     uint32_t reg;
820 
821     if (pD==NULL)
822         return EINVAL;
823 
824     /* read in revision & number of queues, which are also set by defs file */
825     CEDI_PdVar(hwCfg).numQueues = maxHwQs(CEDI_PdVar(cfg).regBase);
826 
827     reg = CPS_UncachedRead32(CEDI_RegAddr(revision_reg));
828 
829     CEDI_PdVar(hwCfg).moduleId =
830             EMAC_REGS__REVISION_REG__MODULE_IDENTIFICATION_NUMBER__READ(reg);
831     CEDI_PdVar(hwCfg).moduleRev =
832             EMAC_REGS__REVISION_REG__MODULE_REVISION__READ(reg);
833     CEDI_PdVar(hwCfg).fixNumber =
834 #ifdef EMAC_REGS__REVISION_REG__FIX_NUMBER__READ
835             EMAC_REGS__REVISION_REG__FIX_NUMBER__READ(reg);
836 #else
837             0;
838 #endif
839 
840     reg = CPS_UncachedRead32(CEDI_RegAddr(designcfg_debug1));
841     CEDI_PdVar(hwCfg).no_pcs =
842             EMAC_REGS__DESIGNCFG_DEBUG1__NO_PCS__READ(reg);
843 #ifdef EMAC_REGS__DESIGNCFG_DEBUG1__SERDES__READ
844     CEDI_PdVar(hwCfg).serdes =
845             EMAC_REGS__DESIGNCFG_DEBUG1__SERDES__READ(reg);
846 #endif
847 #ifdef EMAC_REGS__DESIGNCFG_DEBUG1__RDC_50__READ
848     CEDI_PdVar(hwCfg).RDC_50 =
849             EMAC_REGS__DESIGNCFG_DEBUG1__RDC_50__READ(reg);
850 #endif
851 #ifdef EMAC_REGS__DESIGNCFG_DEBUG1__TDC_50__READ
852     CEDI_PdVar(hwCfg).TDC_50 =
853             EMAC_REGS__DESIGNCFG_DEBUG1__TDC_50__READ(reg);
854 #endif
855     CEDI_PdVar(hwCfg).int_loopback =
856             EMAC_REGS__DESIGNCFG_DEBUG1__INT_LOOPBACK__READ(reg);
857 #ifdef EMAC_REGS__DESIGNCFG_DEBUG1__NO_INT_LOOPBACK__READ
858     CEDI_PdVar(hwCfg).no_int_loopback =
859             EMAC_REGS__DESIGNCFG_DEBUG1__NO_INT_LOOPBACK__READ(reg);
860 #else
861     CEDI_PdVar(hwCfg).no_int_loopback = !CEDI_PdVar(hwCfg).int_loopback;
862 #endif
863     CEDI_PdVar(hwCfg).ext_fifo_interface =
864             EMAC_REGS__DESIGNCFG_DEBUG1__EXT_FIFO_INTERFACE__READ(reg);
865 
866 #ifdef EMAC_REGS__DESIGNCFG_DEBUG1__APB_REV1__READ
867     CEDI_PdVar(hwCfg).apb_rev1 =
868             EMAC_REGS__DESIGNCFG_DEBUG1__APB_REV1__READ(reg);
869 #endif
870 #ifdef EMAC_REGS__DESIGNCFG_DEBUG1__APB_REV2__READ
871     CEDI_PdVar(hwCfg).apb_rev2 =
872             EMAC_REGS__DESIGNCFG_DEBUG1__APB_REV2__READ(reg);
873 #endif
874     CEDI_PdVar(hwCfg).user_io =
875             EMAC_REGS__DESIGNCFG_DEBUG1__USER_IO__READ(reg);
876     CEDI_PdVar(hwCfg).user_out_width =
877             EMAC_REGS__DESIGNCFG_DEBUG1__USER_OUT_WIDTH__READ(reg);
878     CEDI_PdVar(hwCfg).user_in_width =
879             EMAC_REGS__DESIGNCFG_DEBUG1__USER_IN_WIDTH__READ(reg);
880 #ifdef EMAC_REGS__DESIGNCFG_DEBUG1__NO_SCAN_PINS__READ
881     CEDI_PdVar(hwCfg).no_scan_pins =
882             EMAC_REGS__DESIGNCFG_DEBUG1__NO_SCAN_PINS__READ(reg);
883 #endif
884     CEDI_PdVar(hwCfg).no_stats =
885             EMAC_REGS__DESIGNCFG_DEBUG1__NO_STATS__READ(reg);
886     CEDI_PdVar(hwCfg).no_snapshot =
887             EMAC_REGS__DESIGNCFG_DEBUG1__NO_SNAPSHOT__READ(reg);
888     CEDI_PdVar(hwCfg).irq_read_clear =
889             EMAC_REGS__DESIGNCFG_DEBUG1__IRQ_READ_CLEAR__READ(reg);
890 #ifdef EMAC_REGS__DESIGNCFG_DEBUG1__EXCLUDE_CBS__READ
891     /* need both compile-time test for macro and runtime test for feature
892        support, to allow regression against older h/w */
893     if (offloadsSupport(pD))
894         CEDI_PdVar(hwCfg).exclude_cbs =
895             EMAC_REGS__DESIGNCFG_DEBUG1__EXCLUDE_CBS__READ(reg);
896 #else
897     CEDI_PdVar(hwCfg).exclude_cbs = 0;
898 #endif
899     CEDI_PdVar(hwCfg).dma_bus_width =
900             EMAC_REGS__DESIGNCFG_DEBUG1__DMA_BUS_WIDTH__READ(reg);
901     CEDI_PdVar(hwCfg).axi_cache_value =
902             EMAC_REGS__DESIGNCFG_DEBUG1__AXI_CACHE_VALUE__READ(reg);
903 
904     reg = CPS_UncachedRead32(CEDI_RegAddr(designcfg_debug2));
905     CEDI_PdVar(hwCfg).jumbo_max_length =
906             EMAC_REGS__DESIGNCFG_DEBUG2__JUMBO_MAX_LENGTH__READ(reg);
907     CEDI_PdVar(hwCfg).hprot_value =
908             EMAC_REGS__DESIGNCFG_DEBUG2__HPROT_VALUE__READ(reg);
909     CEDI_PdVar(hwCfg).rx_pkt_buffer =
910             EMAC_REGS__DESIGNCFG_DEBUG2__RX_PKT_BUFFER__READ(reg);
911     CEDI_PdVar(hwCfg).tx_pkt_buffer =
912             EMAC_REGS__DESIGNCFG_DEBUG2__TX_PKT_BUFFER__READ(reg);
913     CEDI_PdVar(hwCfg).rx_pbuf_addr =
914             EMAC_REGS__DESIGNCFG_DEBUG2__RX_PBUF_ADDR__READ(reg);
915     CEDI_PdVar(hwCfg).tx_pbuf_addr =
916             EMAC_REGS__DESIGNCFG_DEBUG2__TX_PBUF_ADDR__READ(reg);
917     CEDI_PdVar(hwCfg).axi =
918             EMAC_REGS__DESIGNCFG_DEBUG2__AXI__READ(reg);
919 
920     reg = CPS_UncachedRead32(CEDI_RegAddr(designcfg_debug3));
921     CEDI_PdVar(hwCfg).num_spec_add_filters =
922             EMAC_REGS__DESIGNCFG_DEBUG3__NUM_SPEC_ADD_FILTERS__READ(reg);
923 
924     reg = CPS_UncachedRead32(CEDI_RegAddr(designcfg_debug5));
925     CEDI_PdVar(hwCfg).rx_fifo_cnt_width =
926             EMAC_REGS__DESIGNCFG_DEBUG5__RX_FIFO_CNT_WIDTH__READ(reg);
927     CEDI_PdVar(hwCfg).tx_fifo_cnt_width =
928             EMAC_REGS__DESIGNCFG_DEBUG5__TX_FIFO_CNT_WIDTH__READ(reg);
929     CEDI_PdVar(hwCfg).tsu =
930             EMAC_REGS__DESIGNCFG_DEBUG5__TSU__READ(reg);
931     CEDI_PdVar(hwCfg).phy_ident =
932             EMAC_REGS__DESIGNCFG_DEBUG5__PHY_IDENT__READ(reg);
933     CEDI_PdVar(hwCfg).dma_bus_width_def =
934             EMAC_REGS__DESIGNCFG_DEBUG5__DMA_BUS_WIDTH_DEF__READ(reg);
935     CEDI_PdVar(hwCfg).mdc_clock_div =
936             EMAC_REGS__DESIGNCFG_DEBUG5__MDC_CLOCK_DIV__READ(reg);
937     CEDI_PdVar(hwCfg).endian_swap_def =
938             EMAC_REGS__DESIGNCFG_DEBUG5__ENDIAN_SWAP_DEF__READ(reg);
939     CEDI_PdVar(hwCfg).rx_pbuf_size_def =
940             EMAC_REGS__DESIGNCFG_DEBUG5__RX_PBUF_SIZE_DEF__READ(reg);
941     CEDI_PdVar(hwCfg).tx_pbuf_size_def =
942             EMAC_REGS__DESIGNCFG_DEBUG5__TX_PBUF_SIZE_DEF__READ(reg);
943     CEDI_PdVar(hwCfg).rx_buffer_length_def =
944             EMAC_REGS__DESIGNCFG_DEBUG5__RX_BUFFER_LENGTH_DEF__READ(reg);
945     CEDI_PdVar(hwCfg).tsu_clk =
946             EMAC_REGS__DESIGNCFG_DEBUG5__TSU_CLK__READ(reg);
947     CEDI_PdVar(hwCfg).axi_prot_value =
948             EMAC_REGS__DESIGNCFG_DEBUG5__AXI_PROT_VALUE__READ(reg);
949 
950     reg = CPS_UncachedRead32(CEDI_RegAddr(designcfg_debug6));
951     CEDI_PdVar(hwCfg).tx_pbuf_queue_segment_size =
952             EMAC_REGS__DESIGNCFG_DEBUG6__TX_PBUF_QUEUE_SEGMENT_SIZE__READ(reg);
953     CEDI_PdVar(hwCfg).ext_tsu_timer =
954             EMAC_REGS__DESIGNCFG_DEBUG6__EXT_TSU_TIMER__READ(reg);
955     CEDI_PdVar(hwCfg).tx_add_fifo_if =
956             EMAC_REGS__DESIGNCFG_DEBUG6__TX_ADD_FIFO_IF__READ(reg);
957     CEDI_PdVar(hwCfg).host_if_soft_select =
958             EMAC_REGS__DESIGNCFG_DEBUG6__HOST_IF_SOFT_SELECT__READ(reg);
959     CEDI_PdVar(hwCfg).dma_addr_width =
960             EMAC_REGS__DESIGNCFG_DEBUG6__DMA_ADDR_WIDTH_IS_64B__READ(reg);
961     CEDI_PdVar(hwCfg).pfc_multi_quantum =
962             EMAC_REGS__DESIGNCFG_DEBUG6__PFC_MULTI_QUANTUM__READ(reg);
963     /* Offloads features: first available in GEM_GXL rev 1p07- */
964     if (offloadsSupport(pD)) {
965 #ifdef EMAC_REGS__DESIGNCFG_DEBUG6__PBUF_LSO__READ
966         CEDI_PdVar(hwCfg).pbuf_lso =
967                 EMAC_REGS__DESIGNCFG_DEBUG6__PBUF_LSO__READ(reg);
968 #else
969         CEDI_PdVar(hwCfg).pbuf_lso = 0;
970 #endif
971 #ifdef EMAC_REGS__DESIGNCFG_DEBUG6__PBUF_RSC__READ
972         CEDI_PdVar(hwCfg).pbuf_rsc =
973                 EMAC_REGS__DESIGNCFG_DEBUG6__PBUF_RSC__READ(reg);
974 #else
975         CEDI_PdVar(hwCfg).pbuf_rsc = 0;
976 #endif
977         CEDI_PdVar(hwCfg).intrpt_mod = 1;
978         CEDI_PdVar(hwCfg).hdr_split = 1;
979     } else {
980         CEDI_PdVar(hwCfg).pbuf_lso = 0;
981         CEDI_PdVar(hwCfg).pbuf_rsc = 0;
982         CEDI_PdVar(hwCfg).intrpt_mod = 0;
983         CEDI_PdVar(hwCfg).hdr_split = 0;
984     }
985     reg = CPS_UncachedRead32(CEDI_RegAddr(designcfg_debug7));
986     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q0 =
987             EMAC_REGS__DESIGNCFG_DEBUG7__TX_PBUF_NUM_SEGMENTS_Q0__READ(reg);
988     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q1 =
989             EMAC_REGS__DESIGNCFG_DEBUG7__TX_PBUF_NUM_SEGMENTS_Q1__READ(reg);
990     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q2 =
991             EMAC_REGS__DESIGNCFG_DEBUG7__TX_PBUF_NUM_SEGMENTS_Q2__READ(reg);
992     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q3 =
993             EMAC_REGS__DESIGNCFG_DEBUG7__TX_PBUF_NUM_SEGMENTS_Q3__READ(reg);
994     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q4 =
995             EMAC_REGS__DESIGNCFG_DEBUG7__TX_PBUF_NUM_SEGMENTS_Q4__READ(reg);
996     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q5 =
997             EMAC_REGS__DESIGNCFG_DEBUG7__TX_PBUF_NUM_SEGMENTS_Q5__READ(reg);
998     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q6 =
999             EMAC_REGS__DESIGNCFG_DEBUG7__TX_PBUF_NUM_SEGMENTS_Q6__READ(reg);
1000     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q7 =
1001             EMAC_REGS__DESIGNCFG_DEBUG7__TX_PBUF_NUM_SEGMENTS_Q7__READ(reg);
1002 
1003     reg = CPS_UncachedRead32(CEDI_RegAddr(designcfg_debug8));
1004     CEDI_PdVar(hwCfg).num_type1_screeners =
1005             EMAC_REGS__DESIGNCFG_DEBUG8__NUM_TYPE1_SCREENERS__READ(reg);
1006     CEDI_PdVar(hwCfg).num_type2_screeners =
1007             EMAC_REGS__DESIGNCFG_DEBUG8__NUM_TYPE2_SCREENERS__READ(reg);
1008     CEDI_PdVar(hwCfg).num_scr2_ethtype_regs =
1009             EMAC_REGS__DESIGNCFG_DEBUG8__NUM_SCR2_ETHTYPE_REGS__READ(reg);
1010     CEDI_PdVar(hwCfg).num_scr2_compare_regs =
1011             EMAC_REGS__DESIGNCFG_DEBUG8__NUM_SCR2_COMPARE_REGS__READ(reg);
1012 
1013     reg = CPS_UncachedRead32(CEDI_RegAddr(designcfg_debug9));
1014     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q8 =
1015             EMAC_REGS__DESIGNCFG_DEBUG9__TX_PBUF_NUM_SEGMENTS_Q8__READ(reg);
1016     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q9 =
1017             EMAC_REGS__DESIGNCFG_DEBUG9__TX_PBUF_NUM_SEGMENTS_Q9__READ(reg);
1018     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q10 =
1019             EMAC_REGS__DESIGNCFG_DEBUG9__TX_PBUF_NUM_SEGMENTS_Q10__READ(reg);
1020     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q11 =
1021             EMAC_REGS__DESIGNCFG_DEBUG9__TX_PBUF_NUM_SEGMENTS_Q11__READ(reg);
1022     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q12 =
1023             EMAC_REGS__DESIGNCFG_DEBUG9__TX_PBUF_NUM_SEGMENTS_Q12__READ(reg);
1024     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q13 =
1025             EMAC_REGS__DESIGNCFG_DEBUG9__TX_PBUF_NUM_SEGMENTS_Q13__READ(reg);
1026     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q14 =
1027             EMAC_REGS__DESIGNCFG_DEBUG9__TX_PBUF_NUM_SEGMENTS_Q14__READ(reg);
1028     CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q15 =
1029             EMAC_REGS__DESIGNCFG_DEBUG9__TX_PBUF_NUM_SEGMENTS_Q15__READ(reg);
1030 
1031     reg = CPS_UncachedRead32(CEDI_RegAddr(designcfg_debug10));
1032     CEDI_PdVar(hwCfg).axi_access_pipeline_bits =
1033           EMAC_REGS__DESIGNCFG_DEBUG10__AXI_ACCESS_PIPELINE_BITS__READ(reg);
1034     CEDI_PdVar(hwCfg).rx_pbuf_data =
1035             EMAC_REGS__DESIGNCFG_DEBUG10__RX_PBUF_DATA__READ(reg);
1036     CEDI_PdVar(hwCfg).tx_pbuf_data =
1037             EMAC_REGS__DESIGNCFG_DEBUG10__TX_PBUF_DATA__READ(reg);
1038 
1039     return 0;
1040 }
1041 
1042 /******************************************************************************
1043  * Public Driver functions
1044  * ***************************************************************************/
1045 
emacProbe(CEDI_Config * config,CEDI_SysReq * sysReq)1046 uint32_t emacProbe(CEDI_Config *config, CEDI_SysReq *sysReq)
1047 {
1048     uint32_t regTmp, regVal;
1049     uint16_t txDescSize, rxDescSize, sumTxDesc, sumRxDesc;
1050     struct emac_regs *regAddr;
1051     uint8_t paramErr = 0, numQs;
1052     uint16_t i;
1053 
1054     if ((config==NULL) || (sysReq==NULL)) {
1055         vDbgMsg(DBG_GEN_MSG, 5, "%s\n", "Error: NULL parameter supplied");
1056         return EINVAL;
1057     }
1058 
1059     vDbgMsg(DBG_GEN_MSG, 10, "%s entered (regBase %p)\n", __func__,
1060                     (void *)config->regBase);
1061 
1062     if (config->regBase % sizeof(uint32_t)) {
1063         vDbgMsg(DBG_GEN_MSG, 5,
1064                 "%s\n", "Error: regBase address not 32-bit aligned");
1065         return EINVAL;
1066     }
1067 
1068     /* Module ID check */
1069     regAddr = ((struct emac_regs *)(config->regBase));
1070     regVal = CPS_UncachedRead32(&(regAddr->revision_reg));
1071     regTmp = EMAC_REGS__REVISION_REG__MODULE_IDENTIFICATION_NUMBER__READ(
1072                     regVal);
1073     if ((regTmp!=GEM_GXL_MODULE_ID_V0) &&
1074     (regTmp!=GEM_GXL_MODULE_ID_V1) &&
1075           (regTmp!=GEM_XL_MODULE_ID)) {
1076         vDbgMsg(DBG_GEN_MSG, 5,
1077           "Error: Module ID check failed - 0x%04X read, IP type not supported\n",
1078           regTmp);
1079 #ifndef SANITY_CHECK_TESTS
1080         return EINVAL;
1081 #endif //SANITY_CHECK_TESTS
1082     }
1083     else
1084     {
1085         /**/
1086 #ifdef EMAC_REGS__REVISION_REG__FIX_NUMBER__READ
1087         vDbgMsg(DBG_GEN_MSG, 10,
1088                 "Module ID = 0x%03X, design rev = 0x%04X, fix no. = %u\n",
1089                 regTmp,
1090                 EMAC_REGS__REVISION_REG__MODULE_REVISION__READ(regVal),
1091                 EMAC_REGS__REVISION_REG__FIX_NUMBER__READ(regVal)
1092                 );
1093 #else
1094         vDbgMsg(DBG_GEN_MSG, 10, "Module ID = 0x%04X, design rev = 0x%04X\n", regTmp,
1095                 EMAC_REGS__REVISION_REG__MODULE_REVISION__READ(regVal));
1096 #endif
1097     }
1098 
1099     /* required config parameters range checking */
1100     paramErr = ((config->rxQs==0) || (config->txQs==0));
1101 
1102     /* limit numbers of queues to what is available */
1103     numQs = maxHwQs(config->regBase);
1104     if (config->rxQs>numQs) {
1105         vDbgMsg(DBG_GEN_MSG, 10,
1106             "Warning: Too many Rx queues requested (%u), only %u in h/w config\n",
1107             config->rxQs, numQs);
1108         config->rxQs = numQs;
1109     }
1110     if (config->txQs>numQs) {
1111         vDbgMsg(DBG_GEN_MSG, 10,
1112             "Warning: Too many Tx queues requested (%u), only %u in h/w config\n",
1113                 config->txQs, numQs);
1114         config->txQs = numQs;
1115     }
1116 
1117     regTmp = EMAC_REGS__DESIGNCFG_DEBUG6__DMA_ADDR_WIDTH_IS_64B__READ(
1118                 CPS_UncachedRead32(&(regAddr->designcfg_debug6)));
1119 
1120     // DMA address bus width. 0 =32b , 1=64b
1121     if ((config->dmaAddrBusWidth) && (!regTmp))
1122     {
1123         vDbgMsg(DBG_GEN_MSG, 10, "%s\n",
1124                   "Warning: 64-bit DMA addressing not supported in h/w config");
1125         config->dmaAddrBusWidth = 0;
1126     }
1127 
1128     for (i=0; i<config->rxQs; i++)
1129     {
1130         if (config->rxQLen[i]>CEDI_MAX_RBQ_LENGTH)
1131         {
1132             vDbgMsg(DBG_GEN_MSG, 10,
1133                 "config->rxQLen(%u) (=%u) greater than maximum limit (%u)\n",
1134                 i, config->rxQLen[i], CEDI_MAX_RBQ_LENGTH);
1135             paramErr = 1;
1136             break;
1137         }
1138     }
1139     if (!paramErr)
1140         for (i=0; i<config->txQs; i++)
1141         {
1142             if (config->txQLen[i]>CEDI_MAX_TBQ_LENGTH)
1143             {
1144                 vDbgMsg(DBG_GEN_MSG, 10,
1145                     "config->txQLen(%u) (=%u) greater than maximum limit (%u)\n",
1146                     i, config->txQLen[i], CEDI_MAX_TBQ_LENGTH);
1147                 paramErr = 1;
1148                 break;
1149             }
1150         }
1151 
1152     if (paramErr)
1153     {
1154         vDbgMsg(DBG_GEN_MSG, 5, "%s\n", "Error: parameter out of range");
1155         return EINVAL;
1156     }
1157 
1158     /* required memory allocations */
1159 
1160     /* descriptor list sizes */
1161     calcDescriptorSizes(config, &txDescSize, &rxDescSize);
1162 
1163     sumTxDesc = numTxDescriptors(config);
1164     sysReq->txDescListSize = sumTxDesc * txDescSize;
1165     vDbgMsg(DBG_GEN_MSG, 10, "txQSize = %u\n", sysReq->txDescListSize);
1166     vDbgMsg(DBG_GEN_MSG, 10, "txDescSize = %u bytes\n", txDescSize);
1167 
1168     sumRxDesc = numRxDescriptors(config);
1169     sysReq->rxDescListSize = sumRxDesc * rxDescSize;
1170     vDbgMsg(DBG_GEN_MSG, 10, "rxQSize = %u\n", sysReq->rxDescListSize);
1171     vDbgMsg(DBG_GEN_MSG, 10, "rxDescSize = %u bytes\n", rxDescSize);
1172 
1173     /* privateData including vAddr lists */
1174     sysReq->privDataSize = sizeof(CEDI_PrivateData)
1175                                   + sizeof(uintptr_t)*(sumTxDesc+sumRxDesc);
1176     vDbgMsg(DBG_GEN_MSG, 10, "privDataSize = %u bytes\n",
1177             sysReq->privDataSize);
1178     sysReq->statsSize = sizeof(CEDI_Statistics);
1179     vDbgMsg(DBG_GEN_MSG, 10, "statsSize = %u bytes\n",
1180             sysReq->statsSize);
1181 
1182     return 0;
1183 }
1184 
emacInit(void * pD,const CEDI_Config * config,CEDI_Callbacks * callbacks)1185 uint32_t emacInit(void *pD, const CEDI_Config *config,
1186     CEDI_Callbacks *callbacks)
1187 {
1188 #define CEDI_ADD_TX_PBUF_SEGS(Q)  if (CEDI_PdVar(numQs)>Q)\
1189           numQSegs += 1<<CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q##Q;
1190 
1191     uint8_t hwConfigErr = 0;
1192     uint32_t  paramErr = 0;
1193     int i;
1194     uint32_t numTxSegs, numQSegs;
1195     CEDI_T1Screen clrT1Scrn = {0, 0, 0, 0, 0};
1196     CEDI_T2Screen clrT2Scrn = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1197     vDbgMsg(DBG_GEN_MSG, 10, "%s entered (regBase %08X)\n", __func__,
1198             (uint32_t)config->regBase);
1199 
1200     /* parameter validation */
1201     if ((pD==NULL) || (config==NULL) || (callbacks==NULL))
1202     {
1203         vDbgMsg(DBG_GEN_MSG, 5, "%s\n",
1204                 "Error: NULL main parameter");
1205         return EINVAL;
1206     }
1207 
1208     if (!paramErr)
1209     {
1210         /* Copy config & callbacks into private data */
1211         ((CEDI_PrivateData *)pD)->cfg = *config;
1212         ((CEDI_PrivateData *)pD)->cb = *callbacks;
1213 
1214         paramErr = callbacksNullCheck(pD, config->intrEnable);
1215 
1216         if (paramErr)
1217         {
1218             /**/
1219             vDbgMsg(DBG_GEN_MSG, 5,
1220                     "Error: Callback =NULL for event(s) 0x%08X\n", paramErr);
1221         }
1222 
1223         readDesignConfig(pD);
1224 
1225         initAllRegs(pD);
1226     }
1227 
1228     if (!paramErr) {
1229         CEDI_PdVar(numQs) = CEDI_PdVar(hwCfg).numQueues;
1230         if ((config->rxQs==0) || (config->rxQs>CEDI_PdVar(numQs)) ||
1231                 (config->txQs==0) || (config->txQs>CEDI_PdVar(numQs)))
1232         {
1233             vDbgMsg(DBG_GEN_MSG, 5, "%s\n",
1234                     "Error: out-of-range numQs parameter");
1235             paramErr = 1;
1236         }
1237     }
1238 
1239     if (!paramErr)
1240         for (i=0; i<config->rxQs; i++)
1241         {
1242             if (config->rxQLen[i]>CEDI_MAX_RBQ_LENGTH)
1243             {
1244                 paramErr = 1;
1245                 vDbgMsg(DBG_GEN_MSG, 5,
1246                         "Error: out-of-range rxQLen(%u) parameter\n", i);
1247                 break;
1248             }
1249         }
1250 
1251     if (!paramErr) {
1252         if ((config->txQAddr==(uintptr_t)NULL) ||
1253                 (config->txQPhyAddr==0) ||
1254                 (config->rxQAddr==(uintptr_t)NULL) ||
1255                 (config->rxQPhyAddr==0))
1256         {
1257             vDbgMsg(DBG_GEN_MSG, 5, "%s\n",
1258                     "Error: NULL Tx or Rx descriptor address parameter");
1259             paramErr = 1;
1260         }
1261     }
1262 
1263     if (!paramErr)
1264         for (i=0; i<config->txQs; i++)
1265         {
1266             if (config->txQLen[i]>CEDI_MAX_TBQ_LENGTH)
1267             {
1268                 paramErr = 1;
1269                 vDbgMsg(DBG_GEN_MSG, 5,
1270                         "Error: out-of-range txQLen(%u) parameter\n", i);
1271                 break;
1272             }
1273         }
1274 
1275     if (!paramErr)  {
1276         if ((config->dmaAddrBusWidth) &&
1277                 (!((CEDI_PrivateData *)pD)->hwCfg.dma_addr_width))
1278         {
1279             vDbgMsg(DBG_GEN_MSG, 5, "%s\n",
1280                     "Error: 64-bit DMA addressing not supported in h/w config");
1281             paramErr = 1;
1282         }
1283     }
1284 
1285     if (!paramErr)  {
1286         paramErr = ((config->txPktBufSize>1) || (config->rxPktBufSize>3));
1287         if (!paramErr)
1288             for (i=0; i<config->rxQs; i++) {
1289                 paramErr = paramErr || (config->rxBufLength[i]==0);
1290             }
1291         if (paramErr)
1292         {
1293             /**/
1294             vDbgMsg(DBG_GEN_MSG, 5, "%s\n",
1295                     "Error: Invalid Packet buffer size or Rx buffer length");
1296         }
1297     }
1298 
1299     if (!paramErr)  {
1300         if (config->dmaDataBurstLen>CEDI_DMA_DBUR_LEN_16) {
1301             vDbgMsg(DBG_GEN_MSG, 5, "%s\n",
1302                     "Error: Requested DMA burst length value out of range");
1303             paramErr = 1;
1304         }
1305     }
1306 
1307     if (!paramErr)  {
1308         vDbgMsg(DBG_GEN_MSG, 10, "1 << config->dmaBusWidth = %u, "\
1309                 "CEDI_PdVar(hwCfg).dma_bus_width = %u\n",
1310                 1 << config->dmaBusWidth, CEDI_PdVar(hwCfg).dma_bus_width);
1311         if ((1 << config->dmaBusWidth)>CEDI_PdVar(hwCfg).dma_bus_width) {
1312             vDbgMsg(DBG_GEN_MSG, 5, "%s\n",
1313                     "Error: Requested DMA bus width greater than h/w allows");
1314             paramErr = 1;
1315         }
1316     }
1317 
1318     if (!paramErr)  {
1319         // enforce 32- or 64-bit alignment for RX buffers only
1320         if (config->dmaBusWidth==CEDI_DMA_BUS_WIDTH_32)
1321             paramErr = ((config->rxQPhyAddr) % 4);
1322         else   /* expect 64-bit word alignment for 64/128-bit bus */
1323             paramErr = ((config->rxQPhyAddr) % 8);
1324 
1325         if (paramErr)
1326         {
1327             /**/
1328             vDbgMsg(DBG_GEN_MSG, 5, "%s\n",
1329                     "Error: bad alignment of descriptor list memory");
1330         }
1331     }
1332 
1333     if (!paramErr) {
1334         if (0!=(paramErr = config->ifTypeSel>CEDI_IFSP_1000BASE_X))
1335         {
1336             vDbgMsg(DBG_GEN_MSG, 5,
1337                     "Error: ifTypeSel out of range 0-CEDI_IFSP_1000BASE_X (%u)\n",
1338                     CEDI_PdVar(cfg).ifTypeSel);
1339         }
1340     }
1341 
1342     if (!paramErr) {
1343         if (0!=(paramErr = CEDI_PdVar(cfg).rxBufOffset>3))
1344         {
1345             vDbgMsg(DBG_GEN_MSG, 5,
1346                     "Error: rxBufOffset out of range 0-3 bytes (%u)\n",
1347                     CEDI_PdVar(cfg).rxBufOffset);
1348         }
1349     }
1350 
1351     if (!paramErr) {
1352         if (0!=(paramErr = config->mdcPclkDiv>CEDI_MDC_DIV_BY_224))
1353         {
1354             vDbgMsg(DBG_GEN_MSG, 5,
1355                     "Error: mdcPclkDiv out of range (%u)\n",
1356                     config->mdcPclkDiv);
1357         }
1358     }
1359 
1360     if (!paramErr && (0==CEDI_PdVar(hwCfg).no_stats)) {
1361         paramErr = (config->statsRegs==(uintptr_t)NULL);
1362         if (paramErr)
1363         {
1364             /**/
1365             vDbgMsg(DBG_GEN_MSG, 5, "%s",
1366                     "Error: NULL statistics struct address\n");
1367         }
1368     }
1369 
1370     if (!paramErr && (0==CEDI_PdVar(hwCfg).pfc_multi_quantum)) {
1371         paramErr = (config->pfcMultiQuantum == 1);
1372         if (paramErr)
1373         {
1374             /**/
1375             vDbgMsg(DBG_GEN_MSG, 5, "%s",
1376                     "Error: pfc Multiple quantum not supported by h/w\n");
1377         }
1378     }
1379 
1380     /* sanity-check multi-queue packet buffer segments and distribution */
1381     if ((CEDI_PdVar(numQs)>1) && (CEDI_PdVar(hwCfg).tx_pkt_buffer))
1382     {
1383         if (CEDI_PdVar(hwCfg).tx_pbuf_queue_segment_size>=
1384                 CEDI_PdVar(hwCfg).tx_pbuf_addr) {
1385             vDbgMsg(DBG_GEN_MSG, 5,
1386                     "Error: H/w configuration specifies Tx segment size %u, "\
1387                     "must be less than Tx pbuf addr (%u)\n",
1388                     CEDI_PdVar(hwCfg).tx_pbuf_queue_segment_size,
1389                     CEDI_PdVar(hwCfg).tx_pbuf_addr);
1390             hwConfigErr = 1;
1391         }
1392 
1393         numTxSegs = 1<<CEDI_PdVar(hwCfg).tx_pbuf_queue_segment_size;
1394         if (numTxSegs<CEDI_PdVar(numQs)) {
1395             vDbgMsg(DBG_GEN_MSG, 5, "Error: H/w configuration specifies %u"\
1396                     " queues but only %u packet buffer segments\n",
1397                     CEDI_PdVar(numQs), numTxSegs);
1398             hwConfigErr = 1;
1399         }
1400 
1401         numQSegs = 1<<CEDI_PdVar(hwCfg).tx_pbuf_num_segments_q0;
1402         CEDI_ADD_TX_PBUF_SEGS(1);
1403         CEDI_ADD_TX_PBUF_SEGS(2);
1404 /*      // Three Queues are supported
1405         CEDI_ADD_TX_PBUF_SEGS(3);
1406         CEDI_ADD_TX_PBUF_SEGS(4);
1407         CEDI_ADD_TX_PBUF_SEGS(5);
1408         CEDI_ADD_TX_PBUF_SEGS(6);
1409         CEDI_ADD_TX_PBUF_SEGS(7);
1410         CEDI_ADD_TX_PBUF_SEGS(8);
1411         CEDI_ADD_TX_PBUF_SEGS(9);
1412         CEDI_ADD_TX_PBUF_SEGS(10);
1413         CEDI_ADD_TX_PBUF_SEGS(11);
1414         CEDI_ADD_TX_PBUF_SEGS(12);
1415         CEDI_ADD_TX_PBUF_SEGS(13);
1416         CEDI_ADD_TX_PBUF_SEGS(14);
1417         CEDI_ADD_TX_PBUF_SEGS(15);
1418 */
1419 
1420         if (numQSegs>numTxSegs) {
1421             vDbgMsg(DBG_GEN_MSG, 5,
1422                     "Error: H/w configuration allocates %u Tx packet buffer"\
1423                     " segments to queues out of %u total\n", numQSegs, numTxSegs);
1424             hwConfigErr = 1;
1425         }
1426     }
1427 
1428 
1429     /* Need PCS present for these interface types */
1430     if (((config->ifTypeSel==CEDI_IFSP_10M_SGMII) ||
1431             (config->ifTypeSel==CEDI_IFSP_100M_SGMII) ||
1432             (config->ifTypeSel==CEDI_IFSP_1000M_SGMII) ||
1433             (config->ifTypeSel==CEDI_IFSP_1000BASE_X))
1434         && (EMAC_REGS__DESIGNCFG_DEBUG1__NO_PCS__READ(
1435                 CPS_UncachedRead32(CEDI_RegAddr(designcfg_debug1))))) {
1436 
1437         vDbgMsg(DBG_GEN_MSG, 5,
1438             "Error: config struct specifies interface type (%u) which requires"\
1439             " PCS but this is not present in EMAC h/w\n", config->ifTypeSel);
1440         hwConfigErr = 1;
1441     }
1442 
1443     if (hwConfigErr)
1444         return ENOTSUP;
1445     else if (paramErr)
1446       return EINVAL;
1447 
1448    /****************** Initialise driver internal data ************************/
1449 
1450     ((CEDI_PrivateData *)pD)->anLinkStat = 0;
1451     ((CEDI_PrivateData *)pD)->anRemFault = 0;
1452     ((CEDI_PrivateData *)pD)->autoNegActive = 0;
1453     ((CEDI_PrivateData *)pD)->basePageExp = 1;
1454 
1455     /* ensure all interrupt sources disabled */
1456     disableAllInterrupts(pD);
1457     /* ensure ISRs are cleared */
1458     clearAllInterrupts(pD);
1459 
1460     /****************** Initialise Tx & Rx descriptor lists ********************/
1461 
1462     calcDescriptorSizes(config, &CEDI_PdVar(txDescriptorSize),
1463                                  &CEDI_PdVar(rxDescriptorSize));
1464 
1465     /* DMA config register */
1466     initDmaConfigReg(pD);
1467 
1468     /* writing the upper 32 bit buffer queue base address from config */
1469     initUpper32BuffQAddr(pD);
1470 
1471     if (0!=initTxDescLists(pD))
1472         return EINVAL;
1473     if (0!=initRxDescLists(pD))
1474         return EINVAL;
1475 
1476     /****************************** Initialise hardware ************************/
1477 
1478     /* Network control register */
1479     initNetControlReg(pD);
1480 
1481     /* Network config register */
1482     initNetConfigReg(pD);
1483 
1484     /* AXI Max pipeline register */
1485     if(ETH_AXI_MASTER_PRESENT == 1)
1486     {
1487         initAxiMaxPipelineReg(pD);
1488     }
1489 
1490     setRxQBufferSizes(pD, config);
1491 
1492     /* Ensure specific address registers disabled */
1493     for (i=1; i<=CEDI_PdVar(hwCfg).num_spec_add_filters; i++)
1494         emacDisableSpecAddr(pD, i);
1495 
1496     /* and screener registers */
1497     for (i=0; i<CEDI_PdVar(hwCfg).num_type1_screeners-1; i++)
1498         emacSetType1ScreenReg(pD, i, &clrT1Scrn);
1499     for (i=0; i<CEDI_PdVar(hwCfg).num_type2_screeners-1; i++)
1500         emacSetType2ScreenReg(pD, i, &clrT2Scrn);
1501 
1502     /* and hash match register cleared */
1503     emacSetHashAddr(pD, 0, 0);
1504 
1505     /* clear statistics */
1506     emacClearStats(pD);
1507 
1508     /* User outputs */
1509     emacWriteUserOutputs(pD, 0);
1510 
1511 
1512     /* PCS - PCS Select is set by initNetConfigReg */
1513     if (EMAC_REGS__NETWORK_CONFIG__PCS_SELECT__READ(
1514             CPS_UncachedRead32(CEDI_RegAddr(network_config)))) {
1515         emacSetAutoNegEnable(pD, 0);
1516         CEDI_PdVar(anLinkStat) = 1;
1517         CEDI_PdVar(anRemFault) = 0;
1518     }
1519 
1520     /* Transmit Status */
1521     emacClearTxStatus(pD, CEDI_TXS_USED_READ | CEDI_TXS_COLLISION |
1522             CEDI_TXS_RETRY_EXC | CEDI_TXS_FRAME_ERR | CEDI_TXS_TX_COMPLETE |
1523             CEDI_TXS_UNDERRUN | CEDI_TXS_LATE_COLL | CEDI_TXS_HRESP_ERR);
1524 
1525     /* Receive Status */
1526     emacClearRxStatus(pD, CEDI_RXS_NO_BUFF | CEDI_RXS_FRAME_RX |
1527                             CEDI_RXS_OVERRUN | CEDI_RXS_HRESP_ERR);
1528 
1529     return 0;
1530 }
1531 
emacDestroy(void * pD)1532 void emacDestroy(void *pD)
1533 {
1534     if (pD==NULL) return;
1535     vDbgMsg(DBG_GEN_MSG, 10, "%s entered (regBase %08X)\n", __func__,
1536             (uint32_t)CEDI_PdVar(cfg).regBase);
1537 
1538     emacAbortTx(pD);
1539     emacDisableRx(pD);
1540 
1541   /* disable interrupts & ... */
1542     disableAllInterrupts(pD);
1543 }
1544 
emacStart(void * pD)1545 void emacStart(void *pD)
1546 {
1547     if (pD==NULL) return;
1548     vDbgMsg(DBG_GEN_MSG, 10, "%s entered (regBase %08X)\n", __func__,
1549             (uint32_t)CEDI_PdVar(cfg).regBase);
1550 
1551     /* enable events for all queues */
1552     emacSetEventEnable(pD, CEDI_PdVar(cfg).intrEnable, 1, CEDI_ALL_QUEUES);
1553 
1554     emacEnableRx(pD);
1555     emacEnableTx(pD);
1556 }
1557 
emacStop(void * pD)1558 void emacStop(void *pD)
1559 {
1560     uint32_t t;
1561     // uint8_t q;
1562     if (pD==NULL) return;
1563 
1564     vDbgMsg(DBG_GEN_MSG, 10, "%s entered (regBase %08X)\n", __func__,
1565             (uint32_t)CEDI_PdVar(cfg).regBase);
1566 
1567     /* Halt any Tx after present frame has finished */
1568     emacStopTx(pD);
1569     for (t=10000; (t && emacTransmitting(pD)); t--) ;
1570     if (emacTransmitting(pD))
1571         emacAbortTx(pD);
1572 
1573     emacDisableRx(pD);
1574 //    emacResetPcs(pD);
1575 
1576     /* disable all interrupt sources */
1577     disableAllInterrupts(pD);
1578 
1579 }
1580 
emacIsr(void * pD)1581 uint32_t emacIsr(void *pD)
1582 {
1583 #define CEDI_INT_STATUS_WR_CASE(Q) case Q: \
1584         CPS_UncachedWrite32(CEDI_RegAddr(int_q##Q##_status), isrReg); break;
1585 
1586     uint32_t isrReg, regVal;
1587     uint32_t events;
1588     uint16_t dat16;
1589     uint8_t  qNum, cond1, cond2, cond3, handled = 0;
1590     CEDI_AnNextPage nullNp;
1591     uint8_t linkState;
1592     if (pD==NULL) return EINVAL;
1593 
1594 //  vDbgMsg(DBG_GEN_MSG, 10, "%s entered (regBase %08X), int_mask = 0x%08X\n",
1595 //          __func__, CEDI_PdVar(cfg).regBase,
1596 //          CPS_UncachedRead32(CEDI_RegAddr(int_mask)));
1597 
1598     /* test for any ISR bits set */
1599 
1600     for (qNum=CEDI_PdVar(numQs)-1; qNum<CEDI_MAX_TX_QUEUES; qNum--) {
1601 
1602         /* read Interrupt Status Register */
1603         switch(qNum) {
1604         default: /* default */
1605         case 0: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_status)); break;
1606         case 1: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_q1_status)); break;
1607         case 2: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_q2_status)); break;
1608         case 3: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_q3_status)); break;
1609         case 4: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_q4_status)); break;
1610         case 5: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_q5_status)); break;
1611         case 6: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_q6_status)); break;
1612         case 7: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_q7_status)); break;
1613         case 8: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_q8_status)); break;
1614         case 9: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_q9_status)); break;
1615         case 10: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_q10_status)); break;
1616         case 11: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_q11_status)); break;
1617         case 12: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_q12_status)); break;
1618         case 13: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_q13_status)); break;
1619         case 14: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_q14_status)); break;
1620         case 15: isrReg = CPS_UncachedRead32(CEDI_RegAddr(int_q15_status)); break;
1621         }
1622 
1623         if (isrReg) {
1624 
1625             handled = 1;
1626 
1627             /* do clear-write if required */
1628             if (0==CEDI_PdVar(hwCfg).irq_read_clear) {
1629                 switch(qNum) {
1630                 default: /* default */
1631                 case 0: CPS_UncachedWrite32(CEDI_RegAddr(int_status), isrReg);
1632                 break;
1633                 CEDI_INT_STATUS_WR_CASE(1);
1634                 CEDI_INT_STATUS_WR_CASE(2);
1635 /*              // Three queues are supported
1636                 CEDI_INT_STATUS_WR_CASE(3);
1637                 CEDI_INT_STATUS_WR_CASE(4);
1638                 CEDI_INT_STATUS_WR_CASE(5);
1639                 CEDI_INT_STATUS_WR_CASE(6);
1640                 CEDI_INT_STATUS_WR_CASE(7);
1641                 CEDI_INT_STATUS_WR_CASE(8);
1642                 CEDI_INT_STATUS_WR_CASE(9);
1643                 CEDI_INT_STATUS_WR_CASE(10);
1644                 CEDI_INT_STATUS_WR_CASE(11);
1645                 CEDI_INT_STATUS_WR_CASE(12);
1646                 CEDI_INT_STATUS_WR_CASE(13);
1647                 CEDI_INT_STATUS_WR_CASE(14);
1648                 CEDI_INT_STATUS_WR_CASE(15);
1649 */
1650                 }
1651             }
1652 
1653             /*vDbgMsg(DBG_GEN_MSG, 10, "EMAC (0x%08X) ISR Q%u = 0x%08X\n",
1654                             (uint32_t)CEDI_PdVar(cfg).regBase, qNum, isrReg);*/
1655 
1656             /*** test all intr status bits & do associated callbacks ***/
1657 
1658             /************************ PHY MDIO Frame Tx'd **********************/
1659             if ((qNum==0) &&
1660                     (EMAC_REGS__INT_STATUS__MANAGEMENT_FRAME_SENT__READ(isrReg)))
1661             {
1662                 regVal = CPS_UncachedRead32(CEDI_RegAddr(phy_management));
1663                 cond1 = (EMAC_REGS__PHY_MANAGEMENT__OPERATION__READ(regVal)==2)?1:0;
1664                 dat16 = EMAC_REGS__PHY_MANAGEMENT__PHY_WRITE_READ_DATA__READ(regVal);
1665                 vDbgMsg(DBG_GEN_MSG, 10,
1666                         "EMAC (0x%08X) PHY Management Frame sent to PHY(0x%02X) "\
1667                         "reg=0x%02X - %s operation, data=0x%04X\n",
1668                         (uint32_t)(((CEDI_PrivateData *)pD)->cfg).regBase,
1669                         EMAC_REGS__PHY_MANAGEMENT__PHY_ADDRESS__READ(regVal),
1670                         EMAC_REGS__PHY_MANAGEMENT__REGISTER_ADDRESS__READ(regVal),
1671                         cond1?"read":"write",
1672                                 dat16);
1673 
1674                 (*(CEDI_PdVar(cb).phyManComplete))(pD, cond1, dat16);
1675             }
1676 
1677             /****************************** TxEvent ****************************/
1678             cond1 = 0;
1679             cond2 = 0;
1680 
1681             if (qNum==0) {
1682                 cond1 = EMAC_REGS__INT_STATUS__TX_USED_BIT_READ__READ(isrReg);
1683                 cond2 = EMAC_REGS__INT_STATUS__TRANSMIT_COMPLETE__READ(isrReg);
1684             }
1685             else {
1686                 cond1 = 0;
1687                 cond2 = EMAC_REGS__INT_Q_STATUS__TRANSMIT_COMPLETE__READ(isrReg);
1688             }
1689             if (cond1 || cond2)
1690             {
1691                 events = cond1?CEDI_EV_TX_USED_READ:0;
1692                 events |= cond2?CEDI_EV_TX_COMPLETE:0;
1693 
1694                 /* report both events in one callback call */
1695                 /*vDbgMsg(DBG_GEN_MSG, 10,
1696                         "EMAC (0x%08X) Tx Event:0x%08X queue:%u\n",
1697                         (uint32_t)CEDI_PdVar(cfg).regBase, events, qNum);*/
1698 
1699                 (*(CEDI_PdVar(cb).txEvent))(pD, events, qNum);
1700             }
1701 
1702             /****************************** TxError ****************************/
1703             cond1 = 0;
1704             cond2 = 0;
1705             cond3 = 0;
1706 
1707             if (qNum==0) {
1708                 cond1 = EMAC_REGS__INT_STATUS__TRANSMIT_UNDER_RUN__READ(isrReg);
1709                 cond2 =
1710                          EMAC_REGS__INT_STATUS__RETRY_LIMIT_EXCEEDED_OR_LATE_COLLISION__READ(
1711                                  isrReg);
1712                 cond3 = EMAC_REGS__INT_STATUS__AMBA_ERROR__READ(isrReg);
1713             }
1714             else {
1715                 cond2 =
1716                          EMAC_REGS__INT_Q_STATUS__RETRY_LIMIT_EXCEEDED_OR_LATE_COLLISION__READ(
1717                                  isrReg);
1718                 cond3 = EMAC_REGS__INT_Q_STATUS__AMBA_ERROR__READ(isrReg);
1719             }
1720             if (cond1 || cond2 || cond3)
1721             {
1722                 events = cond1?CEDI_EV_TX_UNDERRUN:0;
1723                 events |= cond2?CEDI_EV_TX_RETRY_EX_LATE_COLL:0;
1724                 events |= cond3?CEDI_EV_TX_FR_CORRUPT:0;
1725 
1726 #ifdef DEBUG
1727                 /* read Q ptr for debug */
1728                 switch(qNum) {
1729                 default: /* default */
1730                 case 0: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q_ptr)); break;
1731                 case 1: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q1_ptr)); break;
1732                 case 2: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q2_ptr)); break;
1733                 case 3: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q3_ptr)); break;
1734                 case 4: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q4_ptr)); break;
1735                 case 5: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q5_ptr)); break;
1736                 case 6: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q6_ptr)); break;
1737                 case 7: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q7_ptr)); break;
1738                 case 8: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q8_ptr)); break;
1739                 case 9: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q9_ptr)); break;
1740                 case 10: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q10_ptr)); break;
1741                 case 11: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q11_ptr)); break;
1742                 case 12: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q12_ptr)); break;
1743                 case 13: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q13_ptr)); break;
1744                 case 14: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q14_ptr)); break;
1745                 case 15: regVal = CPS_UncachedRead32(CEDI_RegAddr(transmit_q15_ptr)); break;
1746                 }
1747 
1748                 vDbgMsg(DBG_GEN_MSG, 10,
1749                         "EMAC (0x%08X) Tx Error:0x%08X queue:%u tx_q_ptr:"\
1750                         "0x%08X  isr0=%08X\n", (uint32_t)CEDI_PdVar(cfg).regBase,
1751                         events, qNum, regVal, isrReg);
1752 #endif
1753 
1754                 (*(CEDI_PdVar(cb).txError))(pD, events, qNum);
1755             }
1756 
1757             /*************************** RxFrame *******************************/
1758             if (((qNum==0) &&
1759                     (EMAC_REGS__INT_STATUS__RECEIVE_COMPLETE__READ(isrReg)))
1760                     ||
1761                     ((qNum>0) &&
1762                             (EMAC_REGS__INT_Q_STATUS__RECEIVE_COMPLETE__READ(isrReg))))
1763             {
1764                 /*vDbgMsg(DBG_GEN_MSG, 10,
1765                         "EMAC (0x%08X) Rx Frame Complete, queue:%u\n",
1766                         (uint32_t)CEDI_PdVar(cfg).regBase, qNum);*/
1767                 (*(CEDI_PdVar(cb).rxFrame))(pD, qNum);
1768             }
1769 
1770             /*************************** RxError *******************************/
1771             cond1 = 0;
1772             cond2 = 0;
1773 
1774             if (qNum==0) {
1775                 cond1 = EMAC_REGS__INT_STATUS__RX_USED_BIT_READ__READ(isrReg);
1776                 cond2 = EMAC_REGS__INT_STATUS__RECEIVE_OVERRUN__READ(isrReg);
1777             }
1778             else {
1779                 cond1 = EMAC_REGS__INT_Q_STATUS__RX_USED_BIT_READ__READ(isrReg);
1780                 cond2 = EMAC_REGS__INT_Q_STATUS__RECEIVE_OVERRUN__READ(isrReg);
1781             }
1782             if (cond1 || cond2)
1783             {
1784                 events = cond1?CEDI_EV_RX_USED_READ:0;
1785                 events |= cond2?CEDI_EV_RX_OVERRUN:0;
1786 
1787                 vDbgMsg(DBG_GEN_MSG, 10,
1788                         "EMAC (0x%08X) Rx Error:0x%08X queue:%u\n",
1789                         (uint32_t)CEDI_PdVar(cfg).regBase, events, qNum);
1790                 (*(CEDI_PdVar(cb).rxError))(pD, events, qNum);
1791             }
1792 
1793             /************************ HResp not OK Event ***********************/
1794             if (((qNum==0) &&
1795                     (EMAC_REGS__INT_STATUS__RESP_NOT_OK__READ(isrReg)))
1796                     ||
1797                     ((qNum>0) &&
1798                             (EMAC_REGS__INT_Q_STATUS__RESP_NOT_OK__READ(isrReg))))
1799             {
1800                 vDbgMsg(DBG_GEN_MSG, 10,
1801                         "EMAC (0x%08X) HResp not OK, queue:%u\n",
1802                         (uint32_t)CEDI_PdVar(cfg).regBase, qNum);
1803 
1804                 (*(CEDI_PdVar(cb).hrespError))(pD, qNum);
1805             }
1806 
1807              /************************* AN LP Page Rx ***************************/
1808              if ((qNum==0) &&
1809                      EMAC_REGS__INT_STATUS__PCS_LINK_PARTNER_PAGE_RECEIVED__READ(isrReg))
1810              {
1811                  if (CEDI_PdVar(basePageExp)) {
1812                      CEDI_PdVar(lpPageRx).nextPage = 0;
1813                      /* Read base page data */
1814                      emacGetLpAbilityPage(pD, &CEDI_PdVar(lpPageRx).lpPageDat.lpBasePage);
1815                  }
1816                  else {
1817                      CEDI_PdVar(lpPageRx).nextPage = 1;
1818                      /* Read next page data */
1819                      emacGetLpNextPage(pD, &CEDI_PdVar(lpPageRx).lpPageDat.lpNextPage);
1820                  }
1821 
1822                  vDbgMsg(DBG_GEN_MSG, 10, "EMAC (0x%08X) AN Link Partner %s Page Rx\n",
1823                          (uint32_t)CEDI_PdVar(cfg).regBase,
1824                          CEDI_PdVar(basePageExp)?"Base":"Next");
1825                  if (CEDI_PdVar(basePageExp))
1826                  {
1827                      /**/
1828                      vDbgMsg(DBG_GEN_MSG, 10, "LpNextPage: %u  LpAck: %u  FullDuplex: %u  HalfDuplex: %u  Pause Capability: %u RemoteFault: %u\n",
1829                              CEDI_PdVar(lpPageRx).lpPageDat.lpBasePage.ablInfo.defLpAbl.lpNextPage,
1830                              CEDI_PdVar(lpPageRx).lpPageDat.lpBasePage.ablInfo.defLpAbl.lpAck,
1831                              CEDI_PdVar(lpPageRx).lpPageDat.lpBasePage.ablInfo.defLpAbl.fullDuplex,
1832                              CEDI_PdVar(lpPageRx).lpPageDat.lpBasePage.ablInfo.defLpAbl.halfDuplex,
1833                              CEDI_PdVar(lpPageRx).lpPageDat.lpBasePage.ablInfo.defLpAbl.pauseCap,
1834                              CEDI_PdVar(lpPageRx).lpPageDat.lpBasePage.ablInfo.defLpAbl.remFlt);
1835                  }
1836 
1837                  /* write Null message next page as default, can be overridden in callback or later */
1838                  nullNp.ack2 = 0;
1839                  nullNp.message = 0x001;
1840                  nullNp.msgPage = 1;
1841                  nullNp.np = 0;
1842                  emacSetNextPageTx(pD, &nullNp);
1843 
1844                  (*(CEDI_PdVar(cb).lpPageRx))(pD, &CEDI_PdVar(lpPageRx));
1845 
1846                  CEDI_PdVar(basePageExp) = 0;
1847              }
1848 
1849             /************************* AN Complete *****************************/
1850             if ((qNum==0) &&
1851                     EMAC_REGS__INT_STATUS__PCS_AUTO_NEGOTIATION_COMPLETE__READ(isrReg))
1852             {
1853                 CEDI_PdVar(basePageExp) = 1;
1854                 CEDI_PdVar(autoNegActive) = 0;
1855 
1856                 regVal = CPS_UncachedRead32(CEDI_RegAddr(network_status));
1857                 CEDI_PdVar(anStatus).duplexRes =
1858                         EMAC_REGS__NETWORK_STATUS__MAC_FULL_DUPLEX__READ(regVal);
1859                 CEDI_PdVar(anStatus).linkState =
1860                         EMAC_REGS__NETWORK_STATUS__PCS_LINK_STATE__READ(regVal);
1861                 CEDI_PdVar(anStatus).pauseRxRes =
1862                         EMAC_REGS__NETWORK_STATUS__MAC_PAUSE_RX_EN__READ(regVal);
1863                 CEDI_PdVar(anStatus).pauseTxRes =
1864                         EMAC_REGS__NETWORK_STATUS__MAC_PAUSE_TX_EN__READ(regVal);
1865 
1866                 vDbgMsg(DBG_GEN_MSG, 10, "EMAC (0x%08X) Auto-negotiation Complete\n",
1867                         (uint32_t)CEDI_PdVar(cfg).regBase);
1868 
1869                 (*(CEDI_PdVar(cb).anComplete))(pD, &CEDI_PdVar(anStatus));
1870             }
1871 
1872             /*********************** Link State Change *************************/
1873             if ((qNum==0) && EMAC_REGS__INT_STATUS__LINK_CHANGE__READ(isrReg))
1874             {
1875                 if (CEDI_PdVar(autoNegActive)) {
1876                     emacGetLinkStatus(pD, &linkState);
1877                 }
1878                 else {
1879                     linkState = EMAC_REGS__NETWORK_STATUS__PCS_LINK_STATE__READ(
1880                             CPS_UncachedRead32(CEDI_RegAddr(network_status)));
1881                 }
1882 
1883                 vDbgMsg(DBG_GEN_MSG, 10, "EMAC (0x%08X) Link State changed - state = %u\n",
1884                         (uint32_t)CEDI_PdVar(cfg).regBase, linkState);
1885 
1886                 (*(CEDI_PdVar(cb).linkChange))(pD, linkState);
1887             }
1888 
1889              /************************ Pause Event ******************************/
1890              if (qNum==0) {
1891                  cond1 =
1892                          EMAC_REGS__INT_STATUS__PAUSE_FRAME_TRANSMITTED__READ(isrReg);
1893                  cond2 = EMAC_REGS__INT_STATUS__PAUSE_TIME_ELAPSED__READ(isrReg);
1894                  cond3 =
1895                          EMAC_REGS__INT_STATUS__PAUSE_FRAME_WITH_NON_ZERO_PAUSE_QUANTUM_RECEIVED__READ(isrReg);
1896 
1897                  if (cond1 || cond2 || cond3)
1898                  {
1899                      events = cond1?CEDI_EV_PAUSE_FRAME_TX:0;
1900                      events |= cond2?CEDI_EV_PAUSE_TIME_ZERO:0;
1901                      events |= cond3?CEDI_EV_PAUSE_NZ_QU_RX:0;
1902 
1903                      vDbgMsg(DBG_GEN_MSG, 10, "EMAC (0x%08X) Pause Event, type:0x%08X\n",
1904                              (uint32_t)CEDI_PdVar(cfg).regBase, events);
1905 
1906                      (*(CEDI_PdVar(cb).pauseEvent))(pD, events);
1907                  }
1908              }
1909 
1910             /***************** PTP Primary Frame Tx Event **********************/
1911             if (qNum==0) {
1912                 cond1 =
1913                         EMAC_REGS__INT_STATUS__PTP_DELAY_REQ_FRAME_TRANSMITTED__READ(
1914                                 isrReg);
1915                 cond2 = EMAC_REGS__INT_STATUS__PTP_SYNC_FRAME_TRANSMITTED__READ(
1916                         isrReg);
1917 
1918                 if (cond1 || cond2)
1919                 {
1920                     events = cond1?CEDI_EV_PTP_TX_DLY_REQ:0;
1921                     events |= cond2?CEDI_EV_PTP_TX_SYNC:0;
1922 
1923                     vDbgMsg(DBG_GEN_MSG, 10,
1924                             "EMAC (0x%08X) PTP Primary Frame Tx, type:0x%08X\n",
1925                             (uint32_t)CEDI_PdVar(cfg).regBase, events);
1926 
1927                     if (0!=emacGetPtpFrameTxTime(pD, &CEDI_PdVar(ptpTime))) {
1928                         CEDI_PdVar(ptpTime).secsUpper = 0;
1929                         CEDI_PdVar(ptpTime).secsLower = 0;
1930                         CEDI_PdVar(ptpTime).nanosecs = 0;
1931                     }
1932                     (*(CEDI_PdVar(cb).ptpPriFrameTx))(pD, events, &CEDI_PdVar(ptpTime));
1933                 }
1934             }
1935 
1936             /******************* PTP Peer Frame Tx Event ***********************/
1937             if (qNum==0) {
1938                 cond1 =
1939                         EMAC_REGS__INT_STATUS__PTP_PDELAY_REQ_FRAME_TRANSMITTED__READ(
1940                                 isrReg);
1941                 cond2 =
1942                         EMAC_REGS__INT_STATUS__PTP_PDELAY_RESP_FRAME_TRANSMITTED__READ(
1943                                 isrReg);
1944 
1945                 if (cond1 || cond2)
1946                 {
1947                     events = cond1?CEDI_EV_PTP_TX_PDLY_REQ:0;
1948                     events |= cond2?CEDI_EV_PTP_TX_PDLY_RSP:0;
1949 
1950                     vDbgMsg(DBG_GEN_MSG, 10,
1951                             "EMAC (0x%08X) PTP Peer Frame Tx, type:0x%08X\n",
1952                             (uint32_t)CEDI_PdVar(cfg).regBase, events);
1953 
1954                     if (0!=emacGetPtpPeerFrameTxTime(pD, &CEDI_PdVar(ptpTime))) {
1955                         CEDI_PdVar(ptpTime).secsUpper = 0;
1956                         CEDI_PdVar(ptpTime).secsLower = 0;
1957                         CEDI_PdVar(ptpTime).nanosecs = 0;
1958                     }
1959                     (*(CEDI_PdVar(cb).ptpPeerFrameTx))(pD, events, &CEDI_PdVar(ptpTime));
1960                 }
1961             }
1962 
1963             /***************** PTP Primary Frame Rx Event **********************/
1964             if (qNum==0) {
1965                 cond1 =
1966                         EMAC_REGS__INT_STATUS__PTP_DELAY_REQ_FRAME_RECEIVED__READ(
1967                                 isrReg);
1968                 cond2 = EMAC_REGS__INT_STATUS__PTP_SYNC_FRAME_RECEIVED__READ(
1969                         isrReg);
1970 
1971                 if (cond1 || cond2)
1972                 {
1973                     events = cond1?CEDI_EV_PTP_RX_DLY_REQ:0;
1974                     events |= cond2?CEDI_EV_PTP_RX_SYNC:0;
1975 
1976                     vDbgMsg(DBG_GEN_MSG, 10,
1977                             "EMAC (0x%08X) PTP Primary Frame Rx, type:0x%08X\n",
1978                             (uint32_t)CEDI_PdVar(cfg).regBase, events);
1979 
1980                     if (0!=emacGetPtpFrameRxTime(pD, &CEDI_PdVar(ptpTime))) {
1981                         CEDI_PdVar(ptpTime).secsUpper = 0;
1982                         CEDI_PdVar(ptpTime).secsLower = 0;
1983                         CEDI_PdVar(ptpTime).nanosecs = 0;
1984                     }
1985                     (*(CEDI_PdVar(cb).ptpPriFrameRx))(pD, events, &CEDI_PdVar(ptpTime));
1986                 }
1987             }
1988 
1989             /******************* PTP Peer Frame Rx Event ***********************/
1990             if (qNum==0) {
1991                 cond1 =
1992                         EMAC_REGS__INT_STATUS__PTP_PDELAY_REQ_FRAME_RECEIVED__READ(
1993                                 isrReg);
1994                 cond2 =
1995                         EMAC_REGS__INT_STATUS__PTP_PDELAY_RESP_FRAME_RECEIVED__READ(
1996                                 isrReg);
1997 
1998                 if (cond1 || cond2)
1999                 {
2000                     events = cond1?CEDI_EV_PTP_RX_PDLY_REQ:0;
2001                     events |= cond2?CEDI_EV_PTP_RX_PDLY_RSP:0;
2002 
2003                     vDbgMsg(DBG_GEN_MSG, 10,
2004                             "EMAC (0x%08X) PTP Peer Frame Rx, type:0x%08X\n",
2005                             (uint32_t)CEDI_PdVar(cfg).regBase, events);
2006 
2007                     if (0!=emacGetPtpPeerFrameRxTime(pD, &CEDI_PdVar(ptpTime))) {
2008                         CEDI_PdVar(ptpTime).secsUpper = 0;
2009                         CEDI_PdVar(ptpTime).secsLower = 0;
2010                         CEDI_PdVar(ptpTime).nanosecs = 0;
2011                     }
2012                     (*(CEDI_PdVar(cb).ptpPeerFrameRx))(pD, events, &CEDI_PdVar(ptpTime));
2013                 }
2014             }
2015 
2016             /************************* TSU Event *******************************/
2017             if (qNum==0) {
2018                 cond1 =
2019                         EMAC_REGS__INT_STATUS__TSU_SECONDS_REGISTER_INCREMENT__READ(
2020                                 isrReg);
2021                 cond2 =
2022                         EMAC_REGS__INT_STATUS__TSU_TIMER_COMPARISON_INTERRUPT__READ(
2023                                 isrReg);
2024 
2025                 if (cond1 || cond2)
2026                 {
2027                     events = cond1?CEDI_EV_TSU_SEC_INC:0;
2028                     events |= cond2?CEDI_EV_TSU_TIME_MATCH:0;
2029 
2030                     vDbgMsg(DBG_GEN_MSG, 10, "EMAC (0x%08X) TSU Event, type:0x%08X\n",
2031                             (uint32_t)CEDI_PdVar(cfg).regBase, events);
2032 
2033                     (*(CEDI_PdVar(cb).tsuEvent))(pD, events);
2034                 }
2035             }
2036 
2037             /************************* LPI Status Change ***********************/
2038             if ((qNum==0) &&
2039                     EMAC_REGS__INT_STATUS__RECEIVE_LPI_INDICATION_STATUS_BIT_CHANGE__READ(isrReg))
2040             {
2041                 vDbgMsg(DBG_GEN_MSG, 10, "EMAC (0x%08X) LPI Status change Event\n",
2042 
2043                         (uint32_t)CEDI_PdVar(cfg).regBase);
2044 
2045                 (*(CEDI_PdVar(cb).lpiStatus))(pD);
2046             }
2047 
2048             /************************* Wake On LAN Event ***********************/
2049             if ((qNum==0) && EMAC_REGS__INT_STATUS__WOL_INTERRUPT__READ(isrReg))
2050             {
2051                 vDbgMsg(DBG_GEN_MSG, 10, "EMAC (0x%08X) Wake on LAN Event\n",
2052                         (uint32_t)CEDI_PdVar(cfg).regBase);
2053 
2054                 (*(CEDI_PdVar(cb).wolEvent))(pD);
2055             }
2056 
2057             /****************** External Input Interrupt Event *****************/
2058             if ((qNum==0) && EMAC_REGS__INT_STATUS__EXTERNAL_INTERRUPT__READ(isrReg))
2059             {
2060                 vDbgMsg(DBG_GEN_MSG, 10, "EMAC (0x%08X) External Input Interrupt\n",
2061                         (uint32_t)CEDI_PdVar(cfg).regBase);
2062 
2063                 (*(CEDI_PdVar(cb).extInpIntr))(pD);
2064             }
2065 
2066         }  /* for qNum */
2067     }
2068 
2069     if (handled)
2070         return 0;
2071     else
2072         return ECANCELED;
2073 }
2074 
2075 /**
2076  * Enable or disable the specified interrupts.
2077  * @param[in] pD driver private state info specific to this instance
2078  * @param[in] events
2079  *    OR'd combination of bit-flags selecting the events to
2080  *    be enabled or disabled
2081  * @param[in] enable if equal 1 enable the events, if 0 then disable
2082  * @param[in] queueNum between 0 and config->rxQs-1, or =CEDI_ALL_QUEUES -
2083  *    number of Tx or Rx priority queue, relevant to some of
2084  *    Tx and Rx events:
2085  *    CEDI_EV_TX_COMPLETE, CEDI_EV_TX_FR_CORRUPT,
2086  *    CEDI_EV_RX_COMPLETE, CEDI_EV_RX_USED_READ, CEDI_EV_RX_OVERRUN,
2087  *    CEDI_EV_HRESP_NOT_OK
2088  *    Must be =0 or CEDI_ALL_QUEUES for other events.
2089  *    To dis/enable on all available Qs, set queueNum to CEDI_ALL_QUEUES and
2090  *    set events to CEDI_EVSET_ALL_Q0_EVENTS.
2091  * @return EINVAL for invalid pD pointer or enable
2092  * @return EINVAL for invalid queueNum
2093  * @return EINVAL for invalid event,
2094  *    e.g. CEDI_EV_PAUSE_FRAME_TX when queueNum = 2
2095  * @return EINVAL for NULL callback for event to be enabled
2096  * @return 0 for success
2097  */
2098 
emacSetEventEnable(void * pD,uint32_t events,uint8_t enable,uint8_t queueNum)2099 uint32_t emacSetEventEnable(void *pD, uint32_t events, uint8_t enable,
2100         uint8_t queueNum)
2101 {
2102 #define CEDI_ENABLE_INT(Q) if ((queueNum==Q) || (queueNum==CEDI_ALL_QUEUES)) \
2103                     CPS_UncachedWrite32(CEDI_RegAddr(int_q##Q##_enable), regVal);
2104 
2105 #define CEDI_DISABLE_INT(Q) if ((queueNum==Q) || (queueNum==CEDI_ALL_QUEUES))\
2106                     CPS_UncachedWrite32(CEDI_RegAddr(int_q##Q##_disable), regVal);
2107 
2108     uint32_t regVal, paramErr;
2109 
2110     if (pD==NULL) {
2111         vDbgMsg(DBG_GEN_MSG, 5, "%s", "*** Error: NULL pD parameter\n");
2112         return EINVAL;
2113     }
2114     if ((queueNum>=CEDI_PdVar(numQs)) && (queueNum!=CEDI_ALL_QUEUES)) {
2115         vDbgMsg(DBG_GEN_MSG, 5,
2116                 "*** Error: Invalid parameter, queueNum: %u\n", queueNum);
2117         return EINVAL;
2118     }
2119     if (enable>1) {
2120         vDbgMsg(DBG_GEN_MSG, 5,
2121                 "*** Error: Invalid parameter, enable: %u\n", enable);
2122         return EINVAL;
2123     }
2124     /* test for invalid events */
2125     if ((events &(~(((queueNum==0)||(queueNum==CEDI_ALL_QUEUES))
2126                     ?CEDI_EVSET_ALL_Q0_EVENTS:CEDI_EVSET_ALL_QN_EVENTS)))!=0) {
2127         vDbgMsg(DBG_GEN_MSG, 5,
2128                 "*** Error: Invalid parameter, events: 0x%08X (queueNum=%u)\n",
2129                 events, queueNum);
2130         return EINVAL;
2131     }
2132 
2133     regVal = 0;
2134 
2135     if (events)
2136     {
2137         if (enable) {
2138             paramErr=callbacksNullCheck(pD, events);
2139             if (0 != paramErr) {
2140                 vDbgMsg(DBG_GEN_MSG, 5,
2141                     "*** Error: Callback =NULL for event(s) 0x%08X\n", paramErr);
2142                 return EINVAL;
2143             }
2144 
2145             if ((queueNum==0) || (queueNum==CEDI_ALL_QUEUES)) {
2146                 regVal = 0;
2147                 if (events & CEDI_EV_MAN_FRAME)
2148                     EMAC_REGS__INT_ENABLE__ENABLE_MANAGEMENT_DONE_INTERRUPT__SET(regVal);
2149 
2150                 if (events & CEDI_EV_RX_COMPLETE)
2151                     EMAC_REGS__INT_ENABLE__ENABLE_RECEIVE_COMPLETE_INTERRUPT__SET(regVal);
2152 
2153                 if (events & CEDI_EV_RX_USED_READ)
2154                     EMAC_REGS__INT_ENABLE__ENABLE_RECEIVE_USED_BIT_READ_INTERRUPT__SET(regVal);
2155 
2156                 if (events & CEDI_EV_TX_USED_READ)
2157                     EMAC_REGS__INT_ENABLE__ENABLE_TRANSMIT_USED_BIT_READ_INTERRUPT__SET(regVal);
2158 
2159                 if (events & CEDI_EV_TX_UNDERRUN)
2160                     EMAC_REGS__INT_ENABLE__ENABLE_TRANSMIT_BUFFER_UNDER_RUN_INTERRUPT__SET
2161                     (regVal);
2162 
2163                 if (events & CEDI_EV_TX_RETRY_EX_LATE_COLL)
2164                     EMAC_REGS__INT_ENABLE__ENABLE_RETRY_LIMIT_EXCEEDED_OR_LATE_COLLISION_INTERRUPT__SET
2165                     (regVal);
2166 
2167                 if (events & CEDI_EV_PCS_LINK_CHANGE_DET)
2168                     EMAC_REGS__INT_ENABLE__ENABLE_LINK_CHANGE_INTERRUPT__SET(regVal);
2169 
2170                 if (events & CEDI_EV_PCS_AN_COMPLETE)
2171                     EMAC_REGS__INT_ENABLE__ENABLE_PCS_AUTO_NEGOTIATION_COMPLETE_INTERRUPT__SET
2172                     (regVal);
2173 
2174                 if (events & CEDI_EV_PCS_LP_PAGE_RX)
2175                     EMAC_REGS__INT_ENABLE__ENABLE_PCS_LINK_PARTNER_PAGE_RECEIVED__SET(regVal);
2176 
2177                 if (events & CEDI_EV_TSU_SEC_INC)
2178                     EMAC_REGS__INT_ENABLE__ENABLE_TSU_SECONDS_REGISTER_INCREMENT__SET(regVal);
2179 
2180                 if (events & CEDI_EV_TSU_TIME_MATCH)
2181                     EMAC_REGS__INT_ENABLE__ENABLE_TSU_TIMER_COMPARISON_INTERRUPT__SET(regVal);
2182 
2183                 if (events & CEDI_EV_TX_FR_CORRUPT)
2184                     EMAC_REGS__INT_ENABLE__ENABLE_TRANSMIT_FRAME_CORRUPTION_DUE_TO_AMBA_ERROR_INTERRUPT__SET
2185                     (regVal);
2186 
2187                 if (events & CEDI_EV_TX_COMPLETE)
2188                     EMAC_REGS__INT_ENABLE__ENABLE_TRANSMIT_COMPLETE_INTERRUPT__SET(regVal);
2189 
2190                 if (events & CEDI_EV_RX_OVERRUN)
2191                     EMAC_REGS__INT_ENABLE__ENABLE_RECEIVE_OVERRUN_INTERRUPT__SET(regVal);
2192 
2193                 if (events & CEDI_EV_HRESP_NOT_OK)
2194                     EMAC_REGS__INT_ENABLE__ENABLE_RESP_NOT_OK_INTERRUPT__SET(regVal);
2195 
2196                 if (events & CEDI_EV_PAUSE_NZ_QU_RX)
2197                     EMAC_REGS__INT_ENABLE__ENABLE_PAUSE_FRAME_WITH_NON_ZERO_PAUSE_QUANTUM_INTERRUPT__SET
2198                     (regVal);
2199 
2200                 if (events & CEDI_EV_PAUSE_TIME_ZERO)
2201                     EMAC_REGS__INT_ENABLE__ENABLE_PAUSE_TIME_ZERO_INTERRUPT__SET(regVal);
2202 
2203                 if (events & CEDI_EV_PAUSE_FRAME_TX)
2204                     EMAC_REGS__INT_ENABLE__ENABLE_PAUSE_FRAME_TRANSMITTED_INTERRUPT__SET(regVal);
2205 
2206                 if (events & CEDI_EV_EXT_INTR)
2207                     EMAC_REGS__INT_ENABLE__ENABLE_EXTERNAL_INTERRUPT__SET(regVal);
2208 
2209                 if (events & CEDI_EV_PTP_RX_DLY_REQ)
2210                     EMAC_REGS__INT_ENABLE__ENABLE_PTP_DELAY_REQ_FRAME_RECEIVED__SET(regVal);
2211 
2212                 if (events & CEDI_EV_PTP_RX_SYNC)
2213                     EMAC_REGS__INT_ENABLE__ENABLE_PTP_SYNC_FRAME_RECEIVED__SET(regVal);
2214 
2215                 if (events & CEDI_EV_PTP_TX_DLY_REQ)
2216                     EMAC_REGS__INT_ENABLE__ENABLE_PTP_DELAY_REQ_FRAME_TRANSMITTED__SET(regVal);
2217 
2218                 if (events & CEDI_EV_PTP_TX_SYNC)
2219                     EMAC_REGS__INT_ENABLE__ENABLE_PTP_SYNC_FRAME_TRANSMITTED__SET(regVal);
2220 
2221                 if (events & CEDI_EV_PTP_RX_PDLY_REQ)
2222                     EMAC_REGS__INT_ENABLE__ENABLE_PTP_PDELAY_REQ_FRAME_RECEIVED__SET(regVal);
2223 
2224                 if (events & CEDI_EV_PTP_RX_PDLY_RSP)
2225                     EMAC_REGS__INT_ENABLE__ENABLE_PTP_PDELAY_RESP_FRAME_RECEIVED__SET(regVal);
2226 
2227                 if (events & CEDI_EV_PTP_TX_PDLY_REQ)
2228                     EMAC_REGS__INT_ENABLE__ENABLE_PTP_PDELAY_REQ_FRAME_TRANSMITTED__SET(regVal);
2229 
2230                 if (events & CEDI_EV_PTP_TX_PDLY_RSP)
2231                     EMAC_REGS__INT_ENABLE__ENABLE_PTP_PDELAY_RESP_FRAME_TRANSMITTED__SET(regVal);
2232 
2233                 if (events & CEDI_EV_LPI_CH_RX)
2234                     EMAC_REGS__INT_ENABLE__ENABLE_RX_LPI_INDICATION_INTERRUPT__SET(regVal);
2235 
2236                 if (events & CEDI_EV_WOL_RX)
2237                     EMAC_REGS__INT_ENABLE__ENABLE_WOL_EVENT_RECEIVED_INTERRUPT__SET(regVal);
2238 
2239                 CPS_UncachedWrite32(CEDI_RegAddr(int_enable), regVal);
2240             }
2241             if (queueNum>0) {
2242                 regVal = 0;
2243                 if (events & CEDI_EV_RX_COMPLETE)
2244                     EMAC_REGS__INT_Q_ENABLE__ENABLE_RECEIVE_COMPLETE_INTERRUPT__SET(regVal);
2245 
2246                 if (events & CEDI_EV_RX_USED_READ)
2247                     EMAC_REGS__INT_Q_ENABLE__ENABLE_RX_USED_BIT_READ_INTERRUPT__SET(regVal);
2248 
2249                 if (events & CEDI_EV_TX_RETRY_EX_LATE_COLL)
2250                     EMAC_REGS__INT_Q_ENABLE__ENABLE_RETRY_LIMIT_EXCEEDED_OR_LATE_COLLISION_INTERRUPT__SET
2251                     (regVal);
2252 
2253                 if (events & CEDI_EV_TX_FR_CORRUPT)
2254                     EMAC_REGS__INT_Q_ENABLE__ENABLE_TRANSMIT_FRAME_CORRUPTION_DUE_TO_AMBA_ERROR_INTERRUPT__SET
2255                     (regVal);
2256 
2257                 if (events & CEDI_EV_TX_COMPLETE)
2258                     EMAC_REGS__INT_Q_ENABLE__ENABLE_TRANSMIT_COMPLETE_INTERRUPT__SET(regVal);
2259 
2260                 if (events & CEDI_EV_HRESP_NOT_OK)
2261                     EMAC_REGS__INT_Q_ENABLE__ENABLE_RESP_NOT_OK_INTERRUPT__SET(regVal);
2262 
2263 
2264                 /* write to interrupt enable register */
2265                 CEDI_ENABLE_INT(1);
2266                 CEDI_ENABLE_INT(2);
2267 /*              // Three queues are supported
2268                 CEDI_ENABLE_INT(3);
2269                 CEDI_ENABLE_INT(4);
2270                 CEDI_ENABLE_INT(5);
2271                 CEDI_ENABLE_INT(6);
2272                 CEDI_ENABLE_INT(7);
2273                 CEDI_ENABLE_INT(8);
2274                 CEDI_ENABLE_INT(9);
2275                 CEDI_ENABLE_INT(10);
2276                 CEDI_ENABLE_INT(11);
2277                 CEDI_ENABLE_INT(12);
2278                 CEDI_ENABLE_INT(13);
2279                 CEDI_ENABLE_INT(14);
2280                 CEDI_ENABLE_INT(15);
2281 */
2282             }
2283         }
2284         else  /* enable==0, i.e. disabling specified events */
2285         {
2286             if ((queueNum==0) || (queueNum==CEDI_ALL_QUEUES)) {
2287                 regVal = 0;
2288                 if (events & CEDI_EV_MAN_FRAME)
2289                     EMAC_REGS__INT_DISABLE__DISABLE_MANAGEMENT_DONE_INTERRUPT__SET(regVal);
2290 
2291                 if (events & CEDI_EV_RX_COMPLETE)
2292                     EMAC_REGS__INT_DISABLE__DISABLE_RECEIVE_COMPLETE_INTERRUPT__SET(regVal);
2293 
2294                 if (events & CEDI_EV_RX_USED_READ)
2295                     EMAC_REGS__INT_DISABLE__DISABLE_RECEIVE_USED_BIT_READ_INTERRUPT__SET(regVal);
2296 
2297                 if (events & CEDI_EV_TX_USED_READ)
2298                     EMAC_REGS__INT_DISABLE__DISABLE_TRANSMIT_USED_BIT_READ_INTERRUPT__SET(regVal);
2299 
2300                 if (events & CEDI_EV_TX_UNDERRUN)
2301                     EMAC_REGS__INT_DISABLE__DISABLE_TRANSMIT_BUFFER_UNDER_RUN_INTERRUPT__SET
2302                     (regVal);
2303 
2304                 if (events & CEDI_EV_TX_RETRY_EX_LATE_COLL)
2305                     EMAC_REGS__INT_DISABLE__DISABLE_RETRY_LIMIT_EXCEEDED_OR_LATE_COLLISION_INTERRUPT__SET
2306                     (regVal);
2307 
2308                 if (events & CEDI_EV_PCS_LINK_CHANGE_DET)
2309                     EMAC_REGS__INT_DISABLE__DISABLE_LINK_CHANGE_INTERRUPT__SET(regVal);
2310 
2311                 if (events & CEDI_EV_PCS_AN_COMPLETE)
2312                     EMAC_REGS__INT_DISABLE__DISABLE_PCS_AUTO_NEGOTIATION_COMPLETE_INTERRUPT__SET
2313                     (regVal);
2314 
2315                 if (events & CEDI_EV_PCS_LP_PAGE_RX)
2316                     EMAC_REGS__INT_DISABLE__DISABLE_PCS_LINK_PARTNER_PAGE_RECEIVED__SET(regVal);
2317 
2318                 if (events & CEDI_EV_TSU_SEC_INC)
2319                     EMAC_REGS__INT_DISABLE__DISABLE_TSU_SECONDS_REGISTER_INCREMENT__SET(regVal);
2320 
2321                 if (events & CEDI_EV_TSU_TIME_MATCH)
2322                     EMAC_REGS__INT_DISABLE__DISABLE_TSU_TIMER_COMPARISON_INTERRUPT__SET(regVal);
2323 
2324                 if (events & CEDI_EV_TX_FR_CORRUPT)
2325                     EMAC_REGS__INT_DISABLE__DISABLE_TRANSMIT_FRAME_CORRUPTION_DUE_TO_AMBA_ERROR_INTERRUPT__SET
2326                     (regVal);
2327 
2328                 if (events & CEDI_EV_TX_COMPLETE)
2329                     EMAC_REGS__INT_DISABLE__DISABLE_TRANSMIT_COMPLETE_INTERRUPT__SET(regVal);
2330 
2331                 if (events & CEDI_EV_RX_OVERRUN)
2332                     EMAC_REGS__INT_DISABLE__DISABLE_RECEIVE_OVERRUN_INTERRUPT__SET(regVal);
2333 
2334                 if (events & CEDI_EV_HRESP_NOT_OK)
2335                     EMAC_REGS__INT_DISABLE__DISABLE_RESP_NOT_OK_INTERRUPT__SET(regVal);
2336 
2337                 if (events & CEDI_EV_PAUSE_NZ_QU_RX)
2338                     EMAC_REGS__INT_DISABLE__DISABLE_PAUSE_FRAME_WITH_NON_ZERO_PAUSE_QUANTUM_INTERRUPT__SET
2339                     (regVal);
2340 
2341                 if (events & CEDI_EV_PAUSE_TIME_ZERO)
2342                     EMAC_REGS__INT_DISABLE__DISABLE_PAUSE_TIME_ZERO_INTERRUPT__SET(regVal);
2343 
2344                 if (events & CEDI_EV_PAUSE_FRAME_TX)
2345                     EMAC_REGS__INT_DISABLE__DISABLE_PAUSE_FRAME_TRANSMITTED_INTERRUPT__SET(regVal);
2346 
2347                 if (events & CEDI_EV_EXT_INTR)
2348                     EMAC_REGS__INT_DISABLE__DISABLE_EXTERNAL_INTERRUPT__SET(regVal);
2349 
2350                 if (events & CEDI_EV_PTP_RX_DLY_REQ)
2351                     EMAC_REGS__INT_DISABLE__DISABLE_PTP_DELAY_REQ_FRAME_RECEIVED__SET(regVal);
2352 
2353                 if (events & CEDI_EV_PTP_RX_SYNC)
2354                     EMAC_REGS__INT_DISABLE__DISABLE_PTP_SYNC_FRAME_RECEIVED__SET(regVal);
2355 
2356                 if (events & CEDI_EV_PTP_TX_DLY_REQ)
2357                     EMAC_REGS__INT_DISABLE__DISABLE_PTP_DELAY_REQ_FRAME_TRANSMITTED__SET(regVal);
2358 
2359                 if (events & CEDI_EV_PTP_TX_SYNC)
2360                     EMAC_REGS__INT_DISABLE__DISABLE_PTP_SYNC_FRAME_TRANSMITTED__SET(regVal);
2361 
2362                 if (events & CEDI_EV_PTP_RX_PDLY_REQ)
2363                     EMAC_REGS__INT_DISABLE__DISABLE_PTP_PDELAY_REQ_FRAME_RECEIVED__SET(regVal);
2364 
2365                 if (events & CEDI_EV_PTP_RX_PDLY_RSP)
2366                     EMAC_REGS__INT_DISABLE__DISABLE_PTP_PDELAY_RESP_FRAME_RECEIVED__SET(regVal);
2367 
2368                 if (events & CEDI_EV_PTP_TX_PDLY_REQ)
2369                     EMAC_REGS__INT_DISABLE__DISABLE_PTP_PDELAY_REQ_FRAME_TRANSMITTED__SET(regVal);
2370 
2371                 if (events & CEDI_EV_PTP_TX_PDLY_RSP)
2372                     EMAC_REGS__INT_DISABLE__DISABLE_PTP_PDELAY_RESP_FRAME_TRANSMITTED__SET(regVal);
2373 
2374                 if (events & CEDI_EV_LPI_CH_RX)
2375                     EMAC_REGS__INT_DISABLE__DISABLE_RX_LPI_INDICATION_INTERRUPT__SET(regVal);
2376 
2377                 if (events & CEDI_EV_WOL_RX)
2378                     EMAC_REGS__INT_DISABLE__DISABLE_WOL_EVENT_RECEIVED_INTERRUPT__SET(regVal);
2379 
2380                 CPS_UncachedWrite32(CEDI_RegAddr(int_disable), regVal);
2381             }
2382             if (queueNum>0) {
2383                 regVal = 0;
2384                 if (events & CEDI_EV_RX_COMPLETE)
2385                     EMAC_REGS__INT_Q_DISABLE__DISABLE_RECEIVE_COMPLETE_INTERRUPT__SET(regVal);
2386 
2387                 if (events & CEDI_EV_RX_USED_READ)
2388                     EMAC_REGS__INT_Q_DISABLE__DISABLE_RX_USED_BIT_READ_INTERRUPT__SET(regVal);
2389 
2390                 if (events & CEDI_EV_TX_RETRY_EX_LATE_COLL)
2391                     EMAC_REGS__INT_Q_DISABLE__DISABLE_RETRY_LIMIT_EXCEEDED_OR_LATE_COLLISION_INTERRUPT__SET
2392                     (regVal);
2393 
2394                 if (events & CEDI_EV_TX_FR_CORRUPT)
2395                     EMAC_REGS__INT_Q_DISABLE__DISABLE_TRANSMIT_FRAME_CORRUPTION_DUE_TO_AMBA_ERROR_INTERRUPT__SET
2396                     (regVal);
2397 
2398                 if (events & CEDI_EV_TX_COMPLETE)
2399                     EMAC_REGS__INT_Q_DISABLE__DISABLE_TRANSMIT_COMPLETE_INTERRUPT__SET(regVal);
2400 
2401                 if (events & CEDI_EV_HRESP_NOT_OK)
2402                     EMAC_REGS__INT_Q_DISABLE__DISABLE_RESP_NOT_OK_INTERRUPT__SET(regVal);
2403 
2404 
2405                 /* write to interrupt disable register */
2406                 CEDI_DISABLE_INT(1);
2407                 CEDI_DISABLE_INT(2);
2408 /*              // Three queues are supported
2409                 CEDI_DISABLE_INT(3);
2410                 CEDI_DISABLE_INT(4);
2411                 CEDI_DISABLE_INT(5);
2412                 CEDI_DISABLE_INT(6);
2413                 CEDI_DISABLE_INT(7);
2414                 CEDI_DISABLE_INT(8);
2415                 CEDI_DISABLE_INT(9);
2416                 CEDI_DISABLE_INT(10);
2417                 CEDI_DISABLE_INT(11);
2418                 CEDI_DISABLE_INT(12);
2419                 CEDI_DISABLE_INT(13);
2420                 CEDI_DISABLE_INT(14);
2421                 CEDI_DISABLE_INT(15);
2422 */
2423             }
2424         }
2425     }
2426     return 0;
2427 }
2428 
emacGetEventEnable(void * pD,uint8_t queueNum,uint32_t * event)2429 uint32_t emacGetEventEnable(void *pD, uint8_t queueNum, uint32_t *event)
2430 {
2431 #define CEDI_READ_INT_MASK_CASE(Q) case Q:\
2432      regVal = ~CPS_UncachedRead32(CEDI_RegAddr(int_q##Q##_mask)); break;
2433 
2434     uint32_t ret = 0;
2435     uint32_t regVal = 0;
2436 
2437     if ((pD==NULL)||(event==NULL))
2438       return EINVAL;
2439 
2440     if (queueNum>=CEDI_PdVar(numQs))
2441         return EINVAL;
2442 
2443     if (queueNum==0) {
2444         regVal = ~CPS_UncachedRead32(CEDI_RegAddr(int_mask));
2445         if (regVal) {
2446             if (EMAC_REGS__INT_MASK__MANAGEMENT_DONE_INTERRUPT_MASK__READ(regVal))
2447                 ret |= CEDI_EV_MAN_FRAME;
2448 
2449             if (EMAC_REGS__INT_MASK__RECEIVE_COMPLETE_INTERRUPT_MASK__READ(regVal))
2450                 ret |= CEDI_EV_RX_COMPLETE;
2451 
2452             if (EMAC_REGS__INT_MASK__RECEIVE_USED_BIT_READ_INTERRUPT_MASK__READ(
2453                     regVal))
2454                 ret |= CEDI_EV_RX_USED_READ;
2455 
2456             if (EMAC_REGS__INT_MASK__TRANSMIT_USED_BIT_READ_INTERRUPT_MASK__READ(
2457                     regVal))
2458                 ret |= CEDI_EV_TX_USED_READ;
2459 
2460             if (EMAC_REGS__INT_MASK__TRANSMIT_BUFFER_UNDER_RUN_INTERRUPT_MASK__READ(
2461                     regVal))
2462                 ret |= CEDI_EV_TX_UNDERRUN;
2463 
2464             if (EMAC_REGS__INT_MASK__RETRY_LIMIT_EXCEEDED_OR_LATE_COLLISION_MASK__READ(
2465                     regVal))
2466                 ret |= CEDI_EV_TX_RETRY_EX_LATE_COLL;
2467 
2468             if (EMAC_REGS__INT_MASK__LINK_CHANGE_INTERRUPT_MASK__READ(regVal))
2469                 ret |= CEDI_EV_PCS_LINK_CHANGE_DET;
2470 
2471             if (EMAC_REGS__INT_MASK__PCS_AUTO_NEGOTIATION_COMPLETE_INTERRUPT_MASK__READ(
2472                     regVal))
2473                 ret |= CEDI_EV_PCS_AN_COMPLETE;
2474 
2475             if (EMAC_REGS__INT_MASK__PCS_LINK_PARTNER_PAGE_MASK__READ(regVal))
2476                 ret |= CEDI_EV_PCS_LP_PAGE_RX;
2477 
2478             if (EMAC_REGS__INT_MASK__TSU_SECONDS_REGISTER_INCREMENT_MASK__READ(
2479                     regVal))
2480                 ret |= CEDI_EV_TSU_SEC_INC;
2481 
2482             if (EMAC_REGS__INT_MASK__TSU_TIMER_COMPARISON_MASK__READ(regVal))
2483                 ret |= CEDI_EV_TSU_TIME_MATCH;
2484 
2485             if (EMAC_REGS__INT_MASK__AMBA_ERROR_INTERRUPT_MASK__READ(regVal))
2486                 ret |= CEDI_EV_TX_FR_CORRUPT;
2487 
2488             if (EMAC_REGS__INT_MASK__TRANSMIT_COMPLETE_INTERRUPT_MASK__READ(regVal))
2489                 ret |= CEDI_EV_TX_COMPLETE;
2490 
2491             if (EMAC_REGS__INT_MASK__RECEIVE_OVERRUN_INTERRUPT_MASK__READ(regVal))
2492                 ret |= CEDI_EV_RX_OVERRUN;
2493 
2494             if (EMAC_REGS__INT_MASK__RESP_NOT_OK_INTERRUPT_MASK__READ(regVal))
2495                 ret |= CEDI_EV_HRESP_NOT_OK;
2496 
2497             if (EMAC_REGS__INT_MASK__PAUSE_FRAME_WITH_NON_ZERO_PAUSE_QUANTUM_INTERRUPT_MASK__READ(
2498                     regVal))
2499                 ret |= CEDI_EV_PAUSE_NZ_QU_RX;
2500 
2501             if (EMAC_REGS__INT_MASK__PAUSE_TIME_ZERO_INTERRUPT_MASK__READ(regVal))
2502                 ret |= CEDI_EV_PAUSE_TIME_ZERO;
2503 
2504             if (EMAC_REGS__INT_MASK__PAUSE_FRAME_TRANSMITTED_INTERRUPT_MASK__READ(
2505                     regVal))
2506                 ret |= CEDI_EV_PAUSE_FRAME_TX;
2507 
2508             if (EMAC_REGS__INT_MASK__EXTERNAL_INTERRUPT_MASK__READ(regVal))
2509                 ret |= CEDI_EV_EXT_INTR;
2510 
2511             if (EMAC_REGS__INT_MASK__PTP_DELAY_REQ_FRAME_RECEIVED_MASK__READ(regVal))
2512                 ret |= CEDI_EV_PTP_RX_DLY_REQ;
2513 
2514             if (EMAC_REGS__INT_MASK__PTP_SYNC_FRAME_RECEIVED_MASK__READ(regVal))
2515                 ret |= CEDI_EV_PTP_RX_SYNC;
2516 
2517             if (EMAC_REGS__INT_MASK__PTP_DELAY_REQ_FRAME_TRANSMITTED_MASK__READ(
2518                     regVal))
2519                 ret |= CEDI_EV_PTP_TX_DLY_REQ;
2520 
2521             if (EMAC_REGS__INT_MASK__PTP_SYNC_FRAME_TRANSMITTED_MASK__READ(regVal))
2522                 ret |= CEDI_EV_PTP_TX_SYNC;
2523 
2524             if (EMAC_REGS__INT_MASK__PTP_PDELAY_REQ_FRAME_RECEIVED_MASK__READ(
2525                     regVal))
2526                 ret |= CEDI_EV_PTP_RX_PDLY_REQ;
2527 
2528             if (EMAC_REGS__INT_MASK__PTP_PDELAY_RESP_FRAME_RECEIVED_MASK__READ(
2529                     regVal))
2530                 ret |= CEDI_EV_PTP_RX_PDLY_RSP;
2531 
2532             if (EMAC_REGS__INT_MASK__PTP_PDELAY_REQ_FRAME_TRANSMITTED_MASK__READ(
2533                     regVal))
2534                 ret |= CEDI_EV_PTP_TX_PDLY_REQ;
2535 
2536             if (EMAC_REGS__INT_MASK__PTP_PDELAY_RESP_FRAME_TRANSMITTED_MASK__READ(
2537                     regVal))
2538                 ret |= CEDI_EV_PTP_TX_PDLY_RSP;
2539 
2540             if (EMAC_REGS__INT_MASK__RX_LPI_INDICATION_MASK__READ(regVal))
2541                 ret |= CEDI_EV_LPI_CH_RX;
2542 
2543             if (EMAC_REGS__INT_MASK__WOL_EVENT_RECEIVED_MASK__READ(regVal))
2544                 ret |= CEDI_EV_WOL_RX;
2545         }
2546     }
2547     else
2548     {
2549         switch(queueNum) {
2550             CEDI_READ_INT_MASK_CASE(1);
2551             CEDI_READ_INT_MASK_CASE(2);
2552 /*          // Three queues are supported
2553             CEDI_READ_INT_MASK_CASE(3);
2554             CEDI_READ_INT_MASK_CASE(4);
2555             CEDI_READ_INT_MASK_CASE(5);
2556             CEDI_READ_INT_MASK_CASE(6);
2557             CEDI_READ_INT_MASK_CASE(7);
2558             CEDI_READ_INT_MASK_CASE(8);
2559             CEDI_READ_INT_MASK_CASE(9);
2560             CEDI_READ_INT_MASK_CASE(10);
2561             CEDI_READ_INT_MASK_CASE(11);
2562             CEDI_READ_INT_MASK_CASE(12);
2563             CEDI_READ_INT_MASK_CASE(13);
2564             CEDI_READ_INT_MASK_CASE(14);
2565             CEDI_READ_INT_MASK_CASE(15);
2566 */
2567         }
2568 
2569         if (regVal) {
2570             if (EMAC_REGS__INT_Q_MASK__RECEIVE_COMPLETE_INTERRUPT_MASK__READ(
2571                     regVal))
2572                 ret |= CEDI_EV_RX_COMPLETE;
2573 
2574             if (EMAC_REGS__INT_Q_MASK__RX_USED_INTERRUPT_MASK__READ(
2575                     regVal))
2576                 ret |= CEDI_EV_RX_USED_READ;
2577 
2578             if (EMAC_REGS__INT_Q_MASK__RETRY_LIMIT_EXCEEDED_OR_LATE_COLLISION_INTERRUPT_MASK__READ(
2579                     regVal))
2580                 ret |= CEDI_EV_TX_RETRY_EX_LATE_COLL;
2581 
2582             if (EMAC_REGS__INT_Q_MASK__AMBA_ERROR_INTERRUPT_MASK__READ(regVal))
2583                 ret |= CEDI_EV_TX_FR_CORRUPT;
2584 
2585             if (EMAC_REGS__INT_Q_MASK__TRANSMIT_COMPLETE_INTERRUPT_MASK__READ(
2586                     regVal))
2587                 ret |= CEDI_EV_TX_COMPLETE;
2588 
2589             if (EMAC_REGS__INT_Q_MASK__RESP_NOT_OK_INTERRUPT_MASK__READ(regVal))
2590                 ret |= CEDI_EV_HRESP_NOT_OK;
2591         }
2592     }
2593 
2594     (*event) = ret;
2595     return 0;
2596 }
2597 
emacSetIntrptModerate(void * pD,uint8_t txIntDelay,uint8_t rxIntDelay)2598 uint32_t emacSetIntrptModerate(void *pD, uint8_t txIntDelay,
2599                                         uint8_t rxIntDelay)
2600 {
2601     uint32_t reg;
2602     if (pD==NULL) return EINVAL;
2603     if ((CEDI_PdVar(hwCfg).intrpt_mod==0) && (txIntDelay || rxIntDelay))
2604         return ENOTSUP;
2605 
2606     reg = CPS_UncachedRead32(CEDI_RegAddr(int_moderation));
2607     EMAC_REGS__INT_MODERATION__TX_INT_MODERATION__MODIFY(reg, txIntDelay);
2608     EMAC_REGS__INT_MODERATION__RX_INT_MODERATION__MODIFY(reg, rxIntDelay);
2609     CPS_UncachedWrite32(CEDI_RegAddr(int_moderation), reg);
2610     return 0;
2611 }
2612 
emacGetIntrptModerate(void * pD,uint8_t * txIntDelay,uint8_t * rxIntDelay)2613 uint32_t emacGetIntrptModerate(void *pD, uint8_t *txIntDelay,
2614                                         uint8_t *rxIntDelay)
2615 {
2616     uint32_t reg;
2617     if ((pD==NULL) || (txIntDelay==NULL) || (rxIntDelay==NULL))
2618         return EINVAL;
2619 
2620     if (CEDI_PdVar(hwCfg).intrpt_mod==0) {
2621         *txIntDelay = 0;
2622         *rxIntDelay = 0;
2623     } else {
2624         reg = CPS_UncachedRead32(CEDI_RegAddr(int_moderation));
2625         *txIntDelay=EMAC_REGS__INT_MODERATION__TX_INT_MODERATION__READ(reg);
2626         *rxIntDelay=EMAC_REGS__INT_MODERATION__RX_INT_MODERATION__READ(reg);
2627     }
2628     return 0;
2629 }
2630 
emacSetIfSpeed(void * pD,CEDI_IfSpeed speedSel)2631 uint32_t emacSetIfSpeed(void *pD, CEDI_IfSpeed speedSel)
2632 {
2633     uint32_t reg;
2634 
2635 //    vDbgMsg(DBG_GEN_MSG, 10, "%s entered:  speedSel = %u\n",
2636 //            __func__, speedSel);
2637 
2638     if (pD==NULL) return EINVAL;
2639 //yots    if ((speedSel<CEDI_SPEED_10M) || (speedSel>CEDI_SPEED_1000M))
2640 //yots        return EINVAL;
2641 
2642     reg = CPS_UncachedRead32(CEDI_RegAddr(network_config));
2643     switch (speedSel) {
2644     case CEDI_SPEED_10M:
2645         EMAC_REGS__NETWORK_CONFIG__SPEED__CLR(reg);
2646         EMAC_REGS__NETWORK_CONFIG__GIGABIT_MODE_ENABLE__CLR(reg);
2647         break;
2648     case CEDI_SPEED_100M:
2649         EMAC_REGS__NETWORK_CONFIG__SPEED__SET(reg);
2650         EMAC_REGS__NETWORK_CONFIG__GIGABIT_MODE_ENABLE__CLR(reg);
2651         break;
2652     case CEDI_SPEED_1000M:
2653         EMAC_REGS__NETWORK_CONFIG__SPEED__CLR(reg);
2654         EMAC_REGS__NETWORK_CONFIG__GIGABIT_MODE_ENABLE__SET(reg);
2655         break;
2656     }
2657     CPS_UncachedWrite32(CEDI_RegAddr(network_config), reg);
2658     return 0;
2659 }
2660 
emacGetIfSpeed(void * pD,CEDI_IfSpeed * speedSel)2661 uint32_t emacGetIfSpeed(void *pD, CEDI_IfSpeed *speedSel)
2662 {
2663     uint32_t reg;
2664 
2665     if ((pD==NULL)||(speedSel==NULL))
2666       return EINVAL;
2667 
2668     reg = CPS_UncachedRead32(CEDI_RegAddr(network_config));
2669     if (EMAC_REGS__NETWORK_CONFIG__GIGABIT_MODE_ENABLE__READ(reg))
2670         *speedSel = CEDI_SPEED_1000M;
2671     else if (EMAC_REGS__NETWORK_CONFIG__SPEED__READ(reg))
2672         *speedSel = CEDI_SPEED_100M;
2673     else
2674         *speedSel = CEDI_SPEED_10M;
2675 
2676     return 0;
2677 }
2678 
emacSetJumboFramesRx(void * pD,uint8_t enable)2679 void emacSetJumboFramesRx(void *pD, uint8_t enable)
2680 {
2681     uint32_t reg;
2682     if (pD==NULL) return;
2683     if (enable>1) return;
2684     reg = CPS_UncachedRead32(CEDI_RegAddr(network_config));
2685     if (enable)
2686         EMAC_REGS__NETWORK_CONFIG__JUMBO_FRAMES__SET(reg);
2687     else
2688         EMAC_REGS__NETWORK_CONFIG__JUMBO_FRAMES__CLR(reg);
2689     CPS_UncachedWrite32(CEDI_RegAddr(network_config), reg);
2690 }
2691 
emacGetJumboFramesRx(void * pD,uint8_t * enable)2692 uint32_t emacGetJumboFramesRx(void *pD, uint8_t *enable)
2693 {
2694     if ((pD==NULL)||(enable==NULL))
2695       return EINVAL;
2696 
2697     *enable=EMAC_REGS__NETWORK_CONFIG__JUMBO_FRAMES__READ(
2698             CPS_UncachedRead32(CEDI_RegAddr(network_config)));
2699 
2700     return 0;
2701 }
2702 
emacSetJumboFrameRxMaxLen(void * pD,uint16_t length)2703 uint32_t emacSetJumboFrameRxMaxLen(void *pD, uint16_t length)
2704 {
2705     uint32_t reg;
2706     uint8_t enabled;
2707     if (pD==NULL) return EINVAL;
2708     if (length>MAX_JUMBO_FRAME_LENGTH)
2709         return EINVAL;
2710 
2711     emacGetJumboFramesRx(pD, &enabled);
2712     reg = CPS_UncachedRead32(CEDI_RegAddr(jumbo_max_length));
2713     if (enabled)
2714         emacSetJumboFramesRx(pD, 0);
2715     EMAC_REGS__JUMBO_MAX_LENGTH__JUMBO_MAX_LENGTH__MODIFY(reg, length);
2716     CPS_UncachedWrite32(CEDI_RegAddr(jumbo_max_length), reg);
2717     if (enabled)
2718         emacSetJumboFramesRx(pD, 1);
2719     return 0;
2720 }
2721 
emacGetJumboFrameRxMaxLen(void * pD,uint16_t * length)2722 uint32_t emacGetJumboFrameRxMaxLen(void *pD, uint16_t *length)
2723 {
2724     if ((pD==NULL)||(length==NULL))
2725       return EINVAL;
2726 
2727     *length=EMAC_REGS__JUMBO_MAX_LENGTH__JUMBO_MAX_LENGTH__READ(
2728             CPS_UncachedRead32(CEDI_RegAddr(jumbo_max_length)));
2729 
2730     return 0;
2731 }
2732 
emacSetUniDirEnable(void * pD,uint8_t enable)2733 void emacSetUniDirEnable(void *pD, uint8_t enable)
2734 {
2735     uint32_t reg;
2736     if (pD==NULL) return;
2737     if (enable>1) return;
2738     reg = CPS_UncachedRead32(CEDI_RegAddr(network_config));
2739     if (enable)
2740         EMAC_REGS__NETWORK_CONFIG__UNI_DIRECTION_ENABLE__SET(reg);
2741     else
2742         EMAC_REGS__NETWORK_CONFIG__UNI_DIRECTION_ENABLE__CLR(reg);
2743     CPS_UncachedWrite32(CEDI_RegAddr(network_config), reg);
2744 }
2745 
emacGetUniDirEnable(void * pD,uint8_t * enable)2746 uint32_t emacGetUniDirEnable(void *pD, uint8_t *enable)
2747 {
2748     if ((pD==NULL)||(enable==NULL))
2749       return EINVAL;
2750     *enable= EMAC_REGS__NETWORK_CONFIG__UNI_DIRECTION_ENABLE__READ(
2751             CPS_UncachedRead32(CEDI_RegAddr(network_config)));
2752 
2753     return 0;
2754 }
2755 
emacSetTxChecksumOffload(void * pD,uint8_t enable)2756 uint32_t emacSetTxChecksumOffload(void *pD, uint8_t enable)
2757 {
2758     uint32_t reg;
2759     if (pD==NULL) return EINVAL;
2760     if (enable>1) return EINVAL;
2761     if (!CEDI_PdVar(hwCfg).tx_pkt_buffer)
2762         return EINVAL;
2763     vDbgMsg(DBG_GEN_MSG, 10, "%s entered: enable = %u\n",
2764                                 __func__, enable);
2765 
2766     reg = CPS_UncachedRead32(CEDI_RegAddr(dma_config));
2767     if (enable)
2768         EMAC_REGS__DMA_CONFIG__TX_PBUF_TCP_EN__SET(reg);
2769     else
2770         EMAC_REGS__DMA_CONFIG__TX_PBUF_TCP_EN__CLR(reg);
2771     CPS_UncachedWrite32(CEDI_RegAddr(dma_config), reg);
2772     return 0;
2773 }
2774 
emacGetTxChecksumOffload(void * pD,uint8_t * enable)2775 uint32_t emacGetTxChecksumOffload(void *pD, uint8_t *enable)
2776 {
2777     if ((pD==NULL)||(enable==NULL))
2778       return EINVAL;
2779     *enable= EMAC_REGS__DMA_CONFIG__TX_PBUF_TCP_EN__READ(
2780             CPS_UncachedRead32(CEDI_RegAddr(dma_config)));
2781 
2782     return 0;
2783 }
2784 
emacSetRxBufOffset(void * pD,uint8_t offset)2785 uint32_t emacSetRxBufOffset(void *pD, uint8_t offset)
2786 {
2787     uint32_t reg;
2788     if (pD==NULL) return EINVAL;
2789     reg = CPS_UncachedRead32(CEDI_RegAddr(network_config));
2790     if (offset>3) return EINVAL;
2791     EMAC_REGS__NETWORK_CONFIG__RECEIVE_BUFFER_OFFSET__MODIFY(reg, offset);
2792     CPS_UncachedWrite32(CEDI_RegAddr(network_config), reg);
2793     return 0;
2794 }
2795 
emacGetRxBufOffset(void * pD,uint8_t * offset)2796 uint32_t emacGetRxBufOffset(void *pD, uint8_t *offset)
2797 {
2798     if ((pD==NULL)||(offset==NULL))
2799       return EINVAL;
2800     *offset= EMAC_REGS__NETWORK_CONFIG__RECEIVE_BUFFER_OFFSET__READ(
2801             CPS_UncachedRead32(CEDI_RegAddr(network_config)));
2802 
2803     return 0;
2804 }
2805 
emacSet1536ByteFramesRx(void * pD,uint8_t enable)2806 void emacSet1536ByteFramesRx(void *pD, uint8_t enable)
2807 {
2808     uint32_t reg;
2809     if (pD==NULL) return;
2810     if (enable>1) return;
2811     reg = CPS_UncachedRead32(CEDI_RegAddr(network_config));
2812     if (enable)
2813         EMAC_REGS__NETWORK_CONFIG__RECEIVE_1536_BYTE_FRAMES__SET(reg);
2814     else
2815         EMAC_REGS__NETWORK_CONFIG__RECEIVE_1536_BYTE_FRAMES__CLR(reg);
2816     CPS_UncachedWrite32(CEDI_RegAddr(network_config), reg);
2817 }
2818 
emacGet1536ByteFramesRx(void * pD,uint8_t * enable)2819 uint32_t emacGet1536ByteFramesRx(void *pD, uint8_t *enable)
2820 {
2821     if ((pD==NULL)||(enable==NULL))
2822       return EINVAL;
2823     *enable= EMAC_REGS__NETWORK_CONFIG__RECEIVE_1536_BYTE_FRAMES__READ(
2824             CPS_UncachedRead32(CEDI_RegAddr(network_config)));
2825 
2826     return 0;
2827 }
2828 
emacSetRxChecksumOffload(void * pD,uint8_t enable)2829 void emacSetRxChecksumOffload(void *pD, uint8_t enable)
2830 {
2831     uint32_t reg;
2832     if (pD==NULL) return;
2833     if (enable>1) return;
2834     vDbgMsg(DBG_GEN_MSG, 10, "%s entered: enable = %u\n",
2835                                 __func__, enable);
2836 
2837     reg = CPS_UncachedRead32(CEDI_RegAddr(network_config));
2838     if (enable)
2839         EMAC_REGS__NETWORK_CONFIG__RECEIVE_CHECKSUM_OFFLOAD_ENABLE__SET(reg);
2840     else
2841         EMAC_REGS__NETWORK_CONFIG__RECEIVE_CHECKSUM_OFFLOAD_ENABLE__CLR(reg);
2842     CPS_UncachedWrite32(CEDI_RegAddr(network_config), reg);
2843 }
2844 
emacGetRxChecksumOffload(void * pD,uint8_t * enable)2845 uint32_t emacGetRxChecksumOffload(void *pD, uint8_t *enable)
2846 {
2847     if ((pD==NULL)||(enable==NULL))
2848       return EINVAL;
2849     *enable= EMAC_REGS__NETWORK_CONFIG__RECEIVE_CHECKSUM_OFFLOAD_ENABLE__READ(
2850             CPS_UncachedRead32(CEDI_RegAddr(network_config)));
2851 
2852     return 0;
2853 }
2854 
emacSetFcsRemove(void * pD,uint8_t enable)2855 void emacSetFcsRemove(void *pD, uint8_t enable)
2856 {
2857     uint32_t reg;
2858     if (pD==NULL) return;
2859     if (enable>1) return;
2860     reg = CPS_UncachedRead32(CEDI_RegAddr(network_config));
2861     if (enable)
2862         EMAC_REGS__NETWORK_CONFIG__FCS_REMOVE__SET(reg);
2863     else
2864         EMAC_REGS__NETWORK_CONFIG__FCS_REMOVE__CLR(reg);
2865     CPS_UncachedWrite32(CEDI_RegAddr(network_config), reg);
2866 }
2867 
emacGetFcsRemove(void * pD,uint8_t * enable)2868 uint32_t emacGetFcsRemove(void *pD, uint8_t *enable)
2869 {
2870     if ((pD==NULL)||(enable==NULL))
2871       return EINVAL;
2872     *enable= EMAC_REGS__NETWORK_CONFIG__FCS_REMOVE__READ(
2873             CPS_UncachedRead32(CEDI_RegAddr(network_config)));
2874 
2875     return 0;
2876 }
2877 
emacSetRxDmaDataAddrMask(void * pD,uint8_t enableBit,uint8_t bitValues)2878 uint32_t emacSetRxDmaDataAddrMask(void *pD, uint8_t enableBit,
2879         uint8_t bitValues)
2880 {
2881     uint32_t reg = 0;
2882     if (pD==NULL) return EINVAL;
2883     if ((enableBit>0xf) || (bitValues>0xf)) return EINVAL;
2884 
2885     EMAC_REGS__DMA_ADDR_OR_MASK__MASK_ENABLE__MODIFY(reg, enableBit);
2886     EMAC_REGS__DMA_ADDR_OR_MASK__MASK_VALUE__MODIFY(reg, bitValues);
2887     CPS_UncachedWrite32(CEDI_RegAddr(dma_addr_or_mask), reg);
2888     return 0;
2889 }
2890 
emacGetRxDmaDataAddrMask(void * pD,uint8_t * enableBit,uint8_t * bitValues)2891 uint32_t emacGetRxDmaDataAddrMask(void *pD, uint8_t *enableBit,
2892         uint8_t *bitValues)
2893 {
2894     uint32_t reg;
2895     if (pD==NULL || !enableBit || !bitValues) return EINVAL;
2896 
2897     reg = CPS_UncachedRead32(CEDI_RegAddr(dma_addr_or_mask));
2898     *enableBit = EMAC_REGS__DMA_ADDR_OR_MASK__MASK_ENABLE__READ(reg);
2899     *bitValues = EMAC_REGS__DMA_ADDR_OR_MASK__MASK_VALUE__READ(reg);
2900     return 0;
2901 }
2902 
emacSetRxBadPreamble(void * pD,uint8_t enable)2903 void emacSetRxBadPreamble(void *pD, uint8_t enable)
2904 {
2905     uint32_t reg;
2906     if (pD==NULL) return;
2907     if (enable>1) return;
2908     reg = CPS_UncachedRead32(CEDI_RegAddr(network_config));
2909     if (enable)
2910         EMAC_REGS__NETWORK_CONFIG__NSP_CHANGE__SET(reg);
2911     else
2912         EMAC_REGS__NETWORK_CONFIG__NSP_CHANGE__CLR(reg);
2913     CPS_UncachedWrite32(CEDI_RegAddr(network_config), reg);
2914 }
2915 
emacGetRxBadPreamble(void * pD,uint8_t * enable)2916 uint32_t emacGetRxBadPreamble(void *pD, uint8_t *enable)
2917 {
2918     if ((pD==NULL)||(enable==NULL))
2919       return EINVAL;
2920     *enable= EMAC_REGS__NETWORK_CONFIG__NSP_CHANGE__READ(
2921             CPS_UncachedRead32(CEDI_RegAddr(network_config)));
2922 
2923     return 0;
2924 }
2925 
emacSetFullDuplex(void * pD,uint8_t enable)2926 void emacSetFullDuplex(void *pD, uint8_t enable)
2927 {
2928     uint32_t reg;
2929     if (pD==NULL) return;
2930     if (enable>1) return;
2931     vDbgMsg(DBG_GEN_MSG, 10, "%s entered: set to %s duplex\n",
2932             __func__, enable?"full":"half");
2933 
2934     reg = CPS_UncachedRead32(CEDI_RegAddr(network_config));
2935     if (enable)
2936         EMAC_REGS__NETWORK_CONFIG__FULL_DUPLEX__SET(reg);
2937     else
2938         EMAC_REGS__NETWORK_CONFIG__FULL_DUPLEX__CLR(reg);
2939     CPS_UncachedWrite32(CEDI_RegAddr(network_config), reg);
2940 }
2941 
emacGetFullDuplex(void * pD,uint8_t * enable)2942 uint32_t emacGetFullDuplex(void *pD, uint8_t *enable)
2943 {
2944     if ((pD==NULL)||(enable==NULL))
2945       return EINVAL;
2946 
2947     *enable=EMAC_REGS__NETWORK_CONFIG__FULL_DUPLEX__READ(
2948             CPS_UncachedRead32(CEDI_RegAddr(network_config)));
2949 
2950     return 0;
2951 }
2952 
emacSetIgnoreFcsRx(void * pD,uint8_t enable)2953 void emacSetIgnoreFcsRx(void *pD, uint8_t enable)
2954 {
2955     uint32_t reg;
2956     if (pD==NULL) return;
2957     if (enable>1) return;
2958     reg = CPS_UncachedRead32(CEDI_RegAddr(network_config));
2959     if (enable)
2960         EMAC_REGS__NETWORK_CONFIG__IGNORE_RX_FCS__SET(reg);
2961     else
2962         EMAC_REGS__NETWORK_CONFIG__IGNORE_RX_FCS__CLR(reg);
2963     CPS_UncachedWrite32(CEDI_RegAddr(network_config), reg);
2964 }
2965 
emacGetIgnoreFcsRx(void * pD,uint8_t * enable)2966 uint32_t emacGetIgnoreFcsRx(void *pD, uint8_t *enable)
2967 {
2968     if ((pD==NULL)||(enable==NULL))
2969       return EINVAL;
2970     *enable= EMAC_REGS__NETWORK_CONFIG__IGNORE_RX_FCS__READ(
2971             CPS_UncachedRead32(CEDI_RegAddr(network_config)));
2972 
2973     return 0;
2974 }
2975 
emacSetRxHalfDuplexInTx(void * pD,uint8_t enable)2976 void emacSetRxHalfDuplexInTx(void *pD, uint8_t enable)
2977 {
2978     uint32_t reg;
2979     if (pD==NULL) return;
2980     if (enable>1) return;
2981 
2982     reg = CPS_UncachedRead32(CEDI_RegAddr(network_config));
2983     if (enable)
2984         EMAC_REGS__NETWORK_CONFIG__EN_HALF_DUPLEX_RX__SET(reg);
2985     else
2986         EMAC_REGS__NETWORK_CONFIG__EN_HALF_DUPLEX_RX__CLR(reg);
2987     CPS_UncachedWrite32(CEDI_RegAddr(network_config), reg);
2988 }
2989 
emacGetRxHalfDuplexInTx(void * pD,uint8_t * enable)2990 uint32_t emacGetRxHalfDuplexInTx(void *pD, uint8_t *enable)
2991 {
2992     if ((pD==NULL)||(enable==NULL))
2993       return EINVAL;
2994 
2995     *enable= EMAC_REGS__NETWORK_CONFIG__EN_HALF_DUPLEX_RX__READ(
2996             CPS_UncachedRead32(CEDI_RegAddr(network_config)));
2997 
2998     return 0;
2999 }
3000 
3001 
emacGetIfCapabilities(void * pD,uint32_t * cap)3002 uint32_t emacGetIfCapabilities(void *pD, uint32_t *cap)
3003 {
3004     if ((pD==NULL)||(cap==NULL))
3005         return EINVAL;
3006 
3007     *cap = 0;
3008 
3009 // TODO: temporary detection based on header-data splitting until get LSO-related define
3010 #ifdef EMAC_REGS__DMA_CONFIG__HDR_DATA_SPLITTING_EN__READ
3011     *cap |= CEDI_CAP_LSO;
3012 #endif
3013 // TODO: RSC, RSS,...
3014 
3015     return EOK;
3016 }
3017 
3018 /******************************** Pause Control ******************************/
3019 
emacSetPauseEnable(void * pD,uint8_t enable)3020 void emacSetPauseEnable(void *pD, uint8_t enable)
3021 {
3022     uint32_t reg;
3023     if (pD==NULL) return;
3024     if (enable>1) return;
3025     reg = CPS_UncachedRead32(CEDI_RegAddr(network_config));
3026     if (enable)
3027         EMAC_REGS__NETWORK_CONFIG__PAUSE_ENABLE__SET(reg);
3028     else
3029         EMAC_REGS__NETWORK_CONFIG__PAUSE_ENABLE__CLR(reg);
3030     CPS_UncachedWrite32(CEDI_RegAddr(network_config), reg);
3031 }
3032 
emacGetPauseEnable(void * pD,uint8_t * enable)3033 uint32_t emacGetPauseEnable(void *pD, uint8_t *enable)
3034 {
3035     if ((pD==NULL)||(enable==NULL))
3036       return EINVAL;
3037     *enable= EMAC_REGS__NETWORK_CONFIG__PAUSE_ENABLE__READ(
3038             CPS_UncachedRead32(CEDI_RegAddr(network_config)));
3039 
3040     return 0;
3041 }
3042 
emacTxPauseFrame(void * pD)3043 void emacTxPauseFrame(void *pD)
3044 {
3045     uint32_t reg;
3046     if (pD==NULL) return;
3047 
3048     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
3049     EMAC_REGS__NETWORK_CONTROL__TX_PAUSE_FRAME_REQ__SET(reg);
3050     CPS_UncachedWrite32(CEDI_RegAddr(network_control), reg);
3051     return;
3052 }
3053 
emacTxZeroQPause(void * pD)3054 void emacTxZeroQPause(void *pD)
3055 {
3056     uint32_t reg;
3057     if (pD==NULL) return;
3058 
3059     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
3060     EMAC_REGS__NETWORK_CONTROL__TX_PAUSE_FRAME_ZERO__SET(reg);
3061     CPS_UncachedWrite32(CEDI_RegAddr(network_control), reg);
3062     return;
3063 }
3064 
emacGetRxPauseQuantum(void * pD,uint16_t * value)3065 uint32_t emacGetRxPauseQuantum(void *pD, uint16_t *value)
3066 {
3067     if ((pD==NULL)||(value==NULL))
3068       return EINVAL;
3069 
3070     *value = EMAC_REGS__PAUSE_TIME__QUANTUM__READ(
3071             CPS_UncachedRead32(CEDI_RegAddr(pause_time)));
3072     return 0;
3073 }
3074 
emacSetTxPauseQuantum(void * pD,uint16_t value,uint8_t qpriority)3075 uint32_t emacSetTxPauseQuantum(void *pD, uint16_t value, uint8_t qpriority)
3076 {
3077     uint32_t reg;
3078     if (pD==NULL) return EINVAL;
3079     if (qpriority >= CEDI_QUANTA_PRIORITY_MAX) return EINVAL;
3080     if ((CEDI_PdVar(hwCfg).pfc_multi_quantum==0)
3081                            && (qpriority>0)) {
3082         return ENOTSUP;
3083     }
3084 
3085     switch (qpriority) {
3086     default: /* default */
3087     case 0:
3088         reg = CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum));
3089         EMAC_REGS__TX_PAUSE_QUANTUM__QUANTUM__MODIFY(reg, value);
3090         CPS_UncachedWrite32(CEDI_RegAddr(tx_pause_quantum), reg);
3091         break;
3092     case 1:
3093         reg = CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum));
3094         EMAC_REGS__TX_PAUSE_QUANTUM__QUANTUM_P1__MODIFY(reg, value);
3095         CPS_UncachedWrite32(CEDI_RegAddr(tx_pause_quantum), reg);
3096         break;
3097     case 2:
3098         reg = CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum1));
3099         EMAC_REGS__TX_PAUSE_QUANTUM1__QUANTUM_P2__MODIFY(reg, value);
3100         CPS_UncachedWrite32(CEDI_RegAddr(tx_pause_quantum1), reg);
3101         break;
3102     case 3:
3103         reg = CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum1));
3104         EMAC_REGS__TX_PAUSE_QUANTUM1__QUANTUM_P3__MODIFY(reg, value);
3105         CPS_UncachedWrite32(CEDI_RegAddr(tx_pause_quantum1), reg);
3106         break;
3107     case 4:
3108         reg = CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum2));
3109         EMAC_REGS__TX_PAUSE_QUANTUM2__QUANTUM_P4__MODIFY(reg, value);
3110         CPS_UncachedWrite32(CEDI_RegAddr(tx_pause_quantum2), reg);
3111         break;
3112     case 5:
3113         reg = CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum2));
3114         EMAC_REGS__TX_PAUSE_QUANTUM2__QUANTUM_P5__MODIFY(reg, value);
3115         CPS_UncachedWrite32(CEDI_RegAddr(tx_pause_quantum2), reg);
3116         break;
3117     case 6:
3118         reg = CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum3));
3119         EMAC_REGS__TX_PAUSE_QUANTUM3__QUANTUM_P6__MODIFY(reg, value);
3120         CPS_UncachedWrite32(CEDI_RegAddr(tx_pause_quantum3), reg);
3121         break;
3122     case 7:
3123         reg = CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum3));
3124         EMAC_REGS__TX_PAUSE_QUANTUM3__QUANTUM_P7__MODIFY(reg, value);
3125         CPS_UncachedWrite32(CEDI_RegAddr(tx_pause_quantum3), reg);
3126         break;
3127     }
3128     return EOK;
3129 }
3130 
emacGetTxPauseQuantum(void * pD,uint16_t * value,uint8_t qpriority)3131 uint32_t emacGetTxPauseQuantum(void *pD, uint16_t *value, uint8_t qpriority)
3132 {
3133     if ((pD==NULL)||(value==NULL))
3134       return EINVAL;
3135     if ((CEDI_PdVar(hwCfg).pfc_multi_quantum==0)
3136                         && (qpriority>0)) {
3137         return ENOTSUP;
3138     }
3139     if (qpriority >= CEDI_QUANTA_PRIORITY_MAX)
3140       return EINVAL;
3141 
3142     switch(qpriority){
3143     default: /* default */
3144     case 0:
3145         *value= EMAC_REGS__TX_PAUSE_QUANTUM__QUANTUM__READ(
3146                     CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum)));
3147         break;
3148     case 1:
3149         *value= EMAC_REGS__TX_PAUSE_QUANTUM__QUANTUM_P1__READ(
3150                     CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum)));
3151         break;
3152     case 2:
3153         *value= EMAC_REGS__TX_PAUSE_QUANTUM1__QUANTUM_P2__READ(
3154                     CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum1)));
3155         break;
3156     case 3:
3157         *value= EMAC_REGS__TX_PAUSE_QUANTUM1__QUANTUM_P3__READ(
3158                     CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum1)));
3159         break;
3160     case 4:
3161         *value= EMAC_REGS__TX_PAUSE_QUANTUM2__QUANTUM_P4__READ(
3162                     CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum2)));
3163         break;
3164     case 5:
3165         *value= EMAC_REGS__TX_PAUSE_QUANTUM2__QUANTUM_P5__READ(
3166                     CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum2)));
3167         break;
3168     case 6:
3169         *value= EMAC_REGS__TX_PAUSE_QUANTUM3__QUANTUM_P6__READ(
3170                     CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum3)));
3171         break;
3172     case 7:
3173         *value= EMAC_REGS__TX_PAUSE_QUANTUM3__QUANTUM_P7__READ(
3174                     CPS_UncachedRead32(CEDI_RegAddr(tx_pause_quantum3)));
3175         break;
3176     }
3177 
3178     return EOK;
3179 }
3180 
emacSetCopyPauseDisable(void * pD,uint8_t disable)3181 void emacSetCopyPauseDisable(void *pD, uint8_t disable)
3182 {
3183     uint32_t reg;
3184     if (pD==NULL) return;
3185     reg = CPS_UncachedRead32(CEDI_RegAddr(network_config));
3186     if (disable)
3187         EMAC_REGS__NETWORK_CONFIG__DISABLE_COPY_OF_PAUSE_FRAMES__SET(reg);
3188     else
3189         EMAC_REGS__NETWORK_CONFIG__DISABLE_COPY_OF_PAUSE_FRAMES__CLR(reg);
3190     CPS_UncachedWrite32(CEDI_RegAddr(network_config), reg);
3191 }
3192 
emacGetCopyPauseDisable(void * pD,uint8_t * disable)3193 uint32_t emacGetCopyPauseDisable(void *pD, uint8_t *disable)
3194 {
3195     if ((pD==NULL)||(disable==NULL))
3196       return EINVAL;
3197     *disable= EMAC_REGS__NETWORK_CONFIG__DISABLE_COPY_OF_PAUSE_FRAMES__READ(
3198             CPS_UncachedRead32(CEDI_RegAddr(network_config)));
3199 
3200     return 0;
3201 }
3202 
emacSetPfcPriorityBasedPauseRx(void * pD,uint8_t enable)3203 void emacSetPfcPriorityBasedPauseRx(void *pD, uint8_t enable)
3204 {
3205     uint32_t reg;
3206     if (pD==NULL) return;
3207     if (enable>1) return;
3208     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
3209     if (enable)
3210         EMAC_REGS__NETWORK_CONTROL__PFC_ENABLE__SET(reg);
3211     else
3212         EMAC_REGS__NETWORK_CONTROL__PFC_ENABLE__CLR(reg);
3213     CPS_UncachedWrite32(CEDI_RegAddr(network_control), reg);
3214 }
3215 
emacGetPfcPriorityBasedPauseRx(void * pD,uint8_t * enable)3216 uint32_t emacGetPfcPriorityBasedPauseRx(void *pD, uint8_t *enable)
3217 {
3218     if ((pD==NULL)||(enable==NULL))
3219       return EINVAL;
3220     *enable = EMAC_REGS__NETWORK_CONTROL__PFC_ENABLE__READ(
3221             CPS_UncachedRead32(CEDI_RegAddr(network_control)));
3222 
3223     return 0;
3224 }
3225 
emacTxPfcPriorityBasedPause(void * pD)3226 uint32_t emacTxPfcPriorityBasedPause(void *pD)
3227 {
3228     uint8_t fullDup = 1;
3229     uint32_t reg;
3230 
3231     if (pD==NULL)
3232         return EINVAL;
3233     emacGetFullDuplex(pD, &fullDup);
3234     if ((!fullDup) || !emacGetTxEnabled(pD))
3235         return EINVAL;
3236 
3237     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
3238     EMAC_REGS__NETWORK_CONTROL__TRANSMIT_PFC_PRIORITY_BASED_PAUSE_FRAME__SET(reg);
3239     CPS_UncachedWrite32(CEDI_RegAddr(network_control), reg);
3240     return 0;
3241 }
3242 
emacSetTxPfcPauseFrameFields(void * pD,uint8_t priEnVector,uint8_t zeroQSelVector)3243 uint32_t emacSetTxPfcPauseFrameFields(void *pD, uint8_t priEnVector,
3244             uint8_t zeroQSelVector)
3245 {
3246     uint32_t reg = 0;
3247     if (pD==NULL) return EINVAL;
3248 
3249     EMAC_REGS__TX_PFC_PAUSE__VECTOR_ENABLE__MODIFY(reg, priEnVector);
3250     EMAC_REGS__TX_PFC_PAUSE__VECTOR__MODIFY(reg, zeroQSelVector);
3251     CPS_UncachedWrite32(CEDI_RegAddr(tx_pfc_pause), reg);
3252     return 0;
3253 }
3254 
emacGetTxPfcPauseFrameFields(void * pD,uint8_t * priEnVector,uint8_t * zeroQSelVector)3255 uint32_t emacGetTxPfcPauseFrameFields(void *pD, uint8_t *priEnVector,
3256             uint8_t *zeroQSelVector)
3257 {
3258     uint32_t reg = 0;
3259     if ((pD==NULL) || (priEnVector==NULL) || (zeroQSelVector==NULL))
3260       return EINVAL;
3261 
3262     reg = CPS_UncachedRead32(CEDI_RegAddr(tx_pfc_pause));
3263     *priEnVector = EMAC_REGS__TX_PFC_PAUSE__VECTOR_ENABLE__READ(reg);
3264     *zeroQSelVector = EMAC_REGS__TX_PFC_PAUSE__VECTOR__READ(reg);
3265     return 0;
3266 }
3267 
emacSetEnableMultiPfcPauseQuantum(void * pD,uint8_t enMultiPfcPause)3268 uint32_t emacSetEnableMultiPfcPauseQuantum(void *pD, uint8_t enMultiPfcPause)
3269 {
3270     uint32_t regVal = 0;
3271     if (pD==NULL) return EINVAL;
3272     if (enMultiPfcPause>1) return EINVAL;
3273 
3274     if ((CEDI_PdVar(hwCfg).pfc_multi_quantum==0) && (enMultiPfcPause==1))
3275         return ENOTSUP;
3276 
3277     regVal = CPS_UncachedRead32(CEDI_RegAddr(network_control));
3278     EMAC_REGS__NETWORK_CONTROL__PFC_CTRL__MODIFY(regVal,enMultiPfcPause);
3279 
3280     CPS_UncachedWrite32(CEDI_RegAddr(network_control), regVal);
3281     return 0;
3282 }
3283 
emacGetEnableMultiPfcPauseQuantum(void * pD,uint8_t * enMultiPfcPause)3284 uint32_t emacGetEnableMultiPfcPauseQuantum(void *pD, uint8_t *enMultiPfcPause)
3285 {
3286     uint32_t regVal = 0;
3287     if ((pD==NULL) || (enMultiPfcPause==NULL))
3288       return EINVAL;
3289 
3290     regVal = CPS_UncachedRead32(CEDI_RegAddr(network_control));
3291     *enMultiPfcPause = EMAC_REGS__NETWORK_CONTROL__PFC_CTRL__READ(regVal);
3292     return 0;
3293 }
3294 
3295 
3296 /****************************** Loopback Control *****************************/
3297 
3298 /**
3299  * Enable or disable loop back mode in the EMAC.
3300  * @param pD - driver private state info specific to this instance
3301  * @param mode - enum selecting mode enable/disable:
3302  *    CEDI_SERDES_LOOPBACK :select loopback mode in PHY transceiver, if
3303  *        available
3304  *    CEDI_LOCAL_LOOPBACK  :select internal loopback mode. Tx and Rx should be
3305  *                        :disabled when enabling or disabling this mode.
3306  *                        :Only available if int_loopback defined.
3307  *    CEDI_NO_LOOPBACK     :disable loopback mode
3308  * @return ENOTSUP if CEDI_SERDES_LOOPBACK selected and no_pcs defined, or
3309  *    if CEDI_LOCAL_LOOPBACK selected and either
3310  *        (no_int_loopback defined or PCS mode is selected)
3311  * @return ENOTSUP if CEDI_LOCAL_LOOPBACK selected and no_int_loopback defined
3312  * @return 0 otherwise.
3313  */
emacSetLoopback(void * pD,uint8_t mode)3314 uint32_t emacSetLoopback(void *pD, uint8_t mode)
3315 {
3316     uint32_t reg;
3317     uint32_t reg2;
3318     if (pD==NULL) return EINVAL;
3319     if (mode>CEDI_SERDES_LOOPBACK) return EINVAL;
3320 
3321     if ((CEDI_PdVar(hwCfg).no_pcs && (mode==CEDI_SERDES_LOOPBACK)) ||
3322         (CEDI_PdVar(hwCfg).no_int_loopback &&
3323             (mode==CEDI_LOCAL_LOOPBACK)))
3324         return ENOTSUP;
3325     if ((EMAC_REGS__NETWORK_CONFIG__PCS_SELECT__READ(
3326             CPS_UncachedRead32(CEDI_RegAddr(network_config)))) &&
3327             (mode==CEDI_LOCAL_LOOPBACK))
3328         return ENOTSUP;
3329 
3330     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
3331     reg2 = CPS_UncachedRead32(CEDI_RegAddr(pcs_control));
3332     EMAC_REGS__NETWORK_CONTROL__LOOPBACK__CLR(reg);
3333     if (mode==CEDI_LOCAL_LOOPBACK) {
3334         EMAC_REGS__NETWORK_CONTROL__LOOPBACK_LOCAL__SET(reg);
3335         EMAC_REGS__PCS_CONTROL__LOOPBACK_MODE__CLR(reg2);
3336     }
3337     else if (mode==CEDI_SERDES_LOOPBACK) {
3338         EMAC_REGS__NETWORK_CONTROL__LOOPBACK_LOCAL__CLR(reg);
3339         EMAC_REGS__PCS_CONTROL__LOOPBACK_MODE__SET(reg2);
3340     }
3341     else {  /* CEDI_NO_LOOPBACK */
3342         EMAC_REGS__NETWORK_CONTROL__LOOPBACK_LOCAL__CLR(reg);
3343         EMAC_REGS__PCS_CONTROL__LOOPBACK_MODE__CLR(reg2);
3344     }
3345     CPS_UncachedWrite32(CEDI_RegAddr(network_control), reg);
3346     CPS_UncachedWrite32(CEDI_RegAddr(pcs_control), reg2);
3347 
3348     return 0;
3349 }
3350 
emacGetLoopback(void * pD,uint8_t * mode)3351 uint32_t emacGetLoopback(void *pD, uint8_t *mode)
3352 {
3353     uint32_t reg;
3354     uint32_t reg2;
3355     if ((pD==NULL)||(mode==NULL))
3356       return EINVAL;
3357 
3358     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
3359     reg2 = CPS_UncachedRead32(CEDI_RegAddr(pcs_control));
3360     if (EMAC_REGS__PCS_CONTROL__LOOPBACK_MODE__READ(reg2))
3361         *mode= CEDI_SERDES_LOOPBACK;
3362     else
3363     if (EMAC_REGS__NETWORK_CONTROL__LOOPBACK_LOCAL__READ(reg))
3364         *mode= CEDI_LOCAL_LOOPBACK;
3365     else
3366         *mode= CEDI_NO_LOOPBACK;
3367 
3368     return 0;
3369 }
3370 
3371 /**************************** PTP/1588 Support *******************************/
3372 
emacSetUnicastPtpDetect(void * pD,uint8_t enable)3373 void emacSetUnicastPtpDetect(void *pD, uint8_t enable)
3374 {
3375     uint32_t reg;
3376     if (pD==NULL) return;
3377     if (enable>1) return;
3378     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
3379     if (enable)
3380         EMAC_REGS__NETWORK_CONTROL__PTP_UNICAST_ENA__SET(reg);
3381     else
3382         EMAC_REGS__NETWORK_CONTROL__PTP_UNICAST_ENA__CLR(reg);
3383     CPS_UncachedWrite32(CEDI_RegAddr(network_control), reg);
3384 }
3385 
emacGetUnicastPtpDetect(void * pD,uint8_t * enable)3386 uint32_t emacGetUnicastPtpDetect(void *pD, uint8_t *enable)
3387 {
3388     if ((pD==NULL)||(enable==NULL))
3389       return EINVAL;
3390     *enable= EMAC_REGS__NETWORK_CONTROL__PTP_UNICAST_ENA__READ(
3391             CPS_UncachedRead32(CEDI_RegAddr(network_control)));
3392 
3393     return 0;
3394 }
3395 
emacSetPtpRxUnicastIpAddr(void * pD,uint32_t rxAddr)3396 uint32_t emacSetPtpRxUnicastIpAddr(void *pD, uint32_t rxAddr)
3397 {
3398     uint32_t reg = 0;
3399     uint32_t ret = 0;
3400     uint8_t enabled = 0;
3401     ret = emacGetUnicastPtpDetect(pD, &enabled);
3402     if (ret!=0)
3403       return ret;
3404     if (enabled)
3405       return ENOTSUP;
3406     EMAC_REGS__RX_PTP_UNICAST__ADDRESS__MODIFY(reg, rxAddr);
3407     CPS_UncachedWrite32(CEDI_RegAddr(rx_ptp_unicast), reg);
3408     return 0;
3409 }
3410 
emacGetPtpRxUnicastIpAddr(void * pD,uint32_t * rxAddr)3411 uint32_t emacGetPtpRxUnicastIpAddr(void *pD, uint32_t *rxAddr)
3412 {
3413     if ((pD==NULL)||(rxAddr==NULL))
3414       return EINVAL;
3415     *rxAddr= EMAC_REGS__RX_PTP_UNICAST__ADDRESS__READ(
3416             CPS_UncachedRead32(CEDI_RegAddr(rx_ptp_unicast)));
3417 
3418     return 0;
3419 }
3420 
emacSetPtpTxUnicastIpAddr(void * pD,uint32_t txAddr)3421 uint32_t emacSetPtpTxUnicastIpAddr(void *pD, uint32_t txAddr)
3422 {
3423     uint32_t reg = 0;
3424     uint32_t ret = 0;
3425     uint8_t enabled = 0;
3426     ret = emacGetUnicastPtpDetect(pD,&enabled);
3427     if (ret!=0)
3428       return ret;
3429     if (enabled)
3430       return ENOTSUP;
3431     EMAC_REGS__TX_PTP_UNICAST__ADDRESS__MODIFY(reg, txAddr);
3432     CPS_UncachedWrite32(CEDI_RegAddr(tx_ptp_unicast), reg);
3433     return 0;
3434 }
3435 
emacGetPtpTxUnicastIpAddr(void * pD,uint32_t * txAddr)3436 uint32_t emacGetPtpTxUnicastIpAddr(void *pD, uint32_t *txAddr)
3437 {
3438     if ((pD==NULL)||(txAddr==NULL))
3439       return EINVAL;
3440     *txAddr= EMAC_REGS__TX_PTP_UNICAST__ADDRESS__READ(
3441             CPS_UncachedRead32(CEDI_RegAddr(tx_ptp_unicast)));
3442 
3443     return 0;
3444 }
3445 
emacSet1588Timer(void * pD,CEDI_1588TimerVal * time)3446 uint32_t emacSet1588Timer(void *pD, CEDI_1588TimerVal *time)
3447 {
3448     uint32_t reg;
3449     if ((pD==NULL) || (time==NULL))
3450         return EINVAL;
3451     if (0==CEDI_PdVar(hwCfg).tsu)
3452         return ENOTSUP;
3453     if (time->nanosecs>0x3FFFFFFF)
3454         return EINVAL;
3455 
3456     reg = CPS_UncachedRead32(CEDI_RegAddr(tsu_timer_msb_sec));
3457     EMAC_REGS__TSU_TIMER_MSB_SEC__TIMER__MODIFY(reg, time->secsUpper);
3458     CPS_UncachedWrite32(CEDI_RegAddr(tsu_timer_msb_sec), reg);
3459     /* write lower bits 2nd, for synchronised secs update */
3460     reg = 0;
3461     EMAC_REGS__TSU_TIMER_SEC__TIMER__MODIFY(reg, time->secsLower);
3462     CPS_UncachedWrite32(CEDI_RegAddr(tsu_timer_sec), reg);
3463     reg = 0;
3464     EMAC_REGS__TSU_TIMER_NSEC__TIMER__MODIFY(reg, time->nanosecs);
3465     CPS_UncachedWrite32(CEDI_RegAddr(tsu_timer_nsec), reg);
3466     return 0;
3467 }
3468 
emacGet1588Timer(void * pD,CEDI_1588TimerVal * time)3469 uint32_t emacGet1588Timer(void *pD, CEDI_1588TimerVal *time)
3470 {
3471     uint32_t reg, first;
3472     if ((pD==NULL) || (time==NULL)) return EINVAL;
3473     if (0==CEDI_PdVar(hwCfg).tsu)
3474         return ENOTSUP;
3475 
3476     first = EMAC_REGS__TSU_TIMER_NSEC__TIMER__READ(
3477             CPS_UncachedRead32(CEDI_RegAddr(tsu_timer_nsec)));
3478     time->secsLower = EMAC_REGS__TSU_TIMER_SEC__TIMER__READ(
3479             CPS_UncachedRead32(CEDI_RegAddr(tsu_timer_sec)));
3480     time->secsUpper = EMAC_REGS__TSU_TIMER_MSB_SEC__TIMER__READ(
3481             CPS_UncachedRead32(CEDI_RegAddr(tsu_timer_msb_sec)));
3482     /* test for nsec rollover */
3483     reg = CPS_UncachedRead32(CEDI_RegAddr(tsu_timer_nsec));
3484     if (first>(EMAC_REGS__TSU_TIMER_NSEC__TIMER__READ(reg))) {
3485         /* if so, use later read & re-read seconds
3486          * (assume all done within 1s) */
3487         time->nanosecs = EMAC_REGS__TSU_TIMER_NSEC__TIMER__READ(reg);
3488         time->secsLower = EMAC_REGS__TSU_TIMER_SEC__TIMER__READ(
3489                 CPS_UncachedRead32(CEDI_RegAddr(tsu_timer_sec)));
3490         time->secsUpper = EMAC_REGS__TSU_TIMER_MSB_SEC__TIMER__READ(
3491                 CPS_UncachedRead32(CEDI_RegAddr(tsu_timer_msb_sec)));
3492     }
3493     else
3494         time->nanosecs = first;
3495 
3496     return 0;
3497 }
3498 
emacAdjust1588Timer(void * pD,int32_t nSecAdjust)3499 uint32_t emacAdjust1588Timer(void *pD, int32_t nSecAdjust)
3500 {
3501     uint32_t reg;
3502     if (pD==NULL) return EINVAL;
3503     if (0==CEDI_PdVar(hwCfg).tsu)
3504         return ENOTSUP;
3505     if ((nSecAdjust<(-0x3FFFFFFF)) || (nSecAdjust>0x3FFFFFFF))
3506         return EINVAL;
3507 
3508     reg = 0;
3509     if (nSecAdjust<0) {
3510         EMAC_REGS__TSU_TIMER_ADJUST__ADD_SUBTRACT__SET(reg);
3511         nSecAdjust = -nSecAdjust;
3512     }
3513 
3514     EMAC_REGS__TSU_TIMER_ADJUST__INCREMENT_VALUE__MODIFY(reg, nSecAdjust);
3515     CPS_UncachedWrite32(CEDI_RegAddr(tsu_timer_adjust), reg);
3516     return 0;
3517 }
3518 
emacSet1588TimerInc(void * pD,CEDI_TimerIncrement * incSettings)3519 uint32_t emacSet1588TimerInc(void *pD, CEDI_TimerIncrement *incSettings)
3520 {
3521     uint32_t reg;
3522     if ((pD==NULL) || (incSettings==NULL))
3523         return EINVAL;
3524     if (0==CEDI_PdVar(hwCfg).tsu)
3525         return ENOTSUP;
3526 
3527 #ifdef  EMAC_REGS__TSU_TIMER_INCR_SUB_NSEC__SUB_NS_INCR_LSB__MODIFY
3528     reg = 0;
3529     EMAC_REGS__TSU_TIMER_INCR_SUB_NSEC__SUB_NS_INCR__MODIFY(reg,
3530                        incSettings->subNsInc);
3531     if (subNsTsuInc24bSupport(pD))
3532         EMAC_REGS__TSU_TIMER_INCR_SUB_NSEC__SUB_NS_INCR_LSB__MODIFY(reg,
3533                           incSettings->lsbSubNsInc);
3534     CPS_UncachedWrite32(CEDI_RegAddr(tsu_timer_incr_sub_nsec), reg);
3535 
3536     reg = 0;
3537     EMAC_REGS__TSU_TIMER_INCR__NS_INCREMENT__MODIFY(reg,
3538                         incSettings->nanoSecsInc);
3539     EMAC_REGS__TSU_TIMER_INCR__ALT_NS_INCR__MODIFY(reg,
3540                         incSettings->altNanoSInc);
3541     EMAC_REGS__TSU_TIMER_INCR__NUM_INCS__MODIFY(reg,
3542                         incSettings->altIncCount);
3543     CPS_UncachedWrite32(CEDI_RegAddr(tsu_timer_incr), reg);
3544 
3545 #else
3546     reg = 0;
3547     EMAC_REGS__TSU_TIMER_INCR_SUB_NSEC__TIMER__MODIFY(reg,
3548                                                     incSettings->subNsInc);
3549     CPS_UncachedWrite32(CEDI_RegAddr(tsu_timer_incr_sub_nsec), reg);
3550 
3551     reg = 0;
3552     EMAC_REGS__TSU_TIMER_INCR__COUNT__MODIFY(reg, incSettings->nanoSecsInc);
3553     EMAC_REGS__TSU_TIMER_INCR__ALT_COUNT__MODIFY(reg,
3554                         incSettings->altNanoSInc);
3555     EMAC_REGS__TSU_TIMER_INCR__NUM_INCS__MODIFY(reg, incSettings->altIncCount);
3556     CPS_UncachedWrite32(CEDI_RegAddr(tsu_timer_incr), reg);
3557 #endif
3558 
3559     return 0;
3560 }
3561 
emacGet1588TimerInc(void * pD,CEDI_TimerIncrement * incSettings)3562 uint32_t emacGet1588TimerInc(void *pD, CEDI_TimerIncrement *incSettings)
3563 {
3564     uint32_t reg;
3565     if ((pD==NULL) || (incSettings==NULL))
3566         return EINVAL;
3567     if (0==CEDI_PdVar(hwCfg).tsu)
3568         return ENOTSUP;
3569 
3570 #ifdef  EMAC_REGS__TSU_TIMER_INCR_SUB_NSEC__SUB_NS_INCR_LSB__READ
3571     reg = CPS_UncachedRead32(CEDI_RegAddr(tsu_timer_incr_sub_nsec));
3572     incSettings->subNsInc =
3573                 EMAC_REGS__TSU_TIMER_INCR_SUB_NSEC__SUB_NS_INCR__READ(reg);
3574     if (subNsTsuInc24bSupport(pD))
3575         incSettings->lsbSubNsInc =
3576                 EMAC_REGS__TSU_TIMER_INCR_SUB_NSEC__SUB_NS_INCR_LSB__READ(reg);
3577     else
3578         incSettings->lsbSubNsInc = 0;
3579     reg = CPS_UncachedRead32(CEDI_RegAddr(tsu_timer_incr));
3580     incSettings->nanoSecsInc =
3581                 EMAC_REGS__TSU_TIMER_INCR__NS_INCREMENT__READ(reg);
3582     incSettings->altNanoSInc =
3583                 EMAC_REGS__TSU_TIMER_INCR__ALT_NS_INCR__READ(reg);
3584     incSettings->altIncCount = EMAC_REGS__TSU_TIMER_INCR__NUM_INCS__READ(reg);
3585 #else
3586     incSettings->subNsInc = EMAC_REGS__TSU_TIMER_INCR_SUB_NSEC__TIMER__READ(
3587             CPS_UncachedRead32(CEDI_RegAddr(tsu_timer_incr_sub_nsec)));
3588     incSettings->lsbSubNsInc = 0;
3589     reg = CPS_UncachedRead32(CEDI_RegAddr(tsu_timer_incr));
3590     incSettings->nanoSecsInc = EMAC_REGS__TSU_TIMER_INCR__COUNT__READ(reg);
3591     incSettings->altNanoSInc = EMAC_REGS__TSU_TIMER_INCR__ALT_COUNT__READ(reg);
3592     incSettings->altIncCount = EMAC_REGS__TSU_TIMER_INCR__NUM_INCS__READ(reg);
3593 #endif
3594 
3595     return 0;
3596 }
3597 
emacSetTsuTimerCompVal(void * pD,CEDI_TsuTimerVal * time)3598 uint32_t emacSetTsuTimerCompVal(void *pD, CEDI_TsuTimerVal *time)
3599 {
3600     uint32_t reg;
3601     if ((pD==NULL) || (time==NULL))
3602         return EINVAL;
3603     if (0==CEDI_PdVar(hwCfg).tsu)
3604         return ENOTSUP;
3605     if (time->nanosecs>0x003FFFFF)
3606         return EINVAL;
3607 
3608     reg = 0;
3609     EMAC_REGS__TSU_NSEC_CMP__COMPARISON_VALUE__MODIFY(reg, time->nanosecs);
3610     CPS_UncachedWrite32(CEDI_RegAddr(tsu_nsec_cmp), reg);
3611     reg = 0;
3612     EMAC_REGS__TSU_SEC_CMP__COMPARISON_VALUE__MODIFY(reg, time->secsLower);
3613     CPS_UncachedWrite32(CEDI_RegAddr(tsu_sec_cmp), reg);
3614     reg = 0;
3615     EMAC_REGS__TSU_MSB_SEC_CMP__COMPARISON_VALUE__MODIFY(reg, time->secsUpper);
3616     CPS_UncachedWrite32(CEDI_RegAddr(tsu_msb_sec_cmp), reg);
3617     return 0;
3618 }
3619 
emacGetTsuTimerCompVal(void * pD,CEDI_TsuTimerVal * time)3620 uint32_t emacGetTsuTimerCompVal(void *pD, CEDI_TsuTimerVal *time)
3621 {
3622     if ((pD==NULL) || (time==NULL))
3623         return EINVAL;
3624     if (0==CEDI_PdVar(hwCfg).tsu)
3625         return ENOTSUP;
3626 
3627     time->nanosecs = EMAC_REGS__TSU_NSEC_CMP__COMPARISON_VALUE__READ(
3628             CPS_UncachedRead32(CEDI_RegAddr(tsu_nsec_cmp)));
3629     time->secsLower = EMAC_REGS__TSU_SEC_CMP__COMPARISON_VALUE__READ(
3630             CPS_UncachedRead32(CEDI_RegAddr(tsu_sec_cmp)));
3631     time->secsUpper = EMAC_REGS__TSU_MSB_SEC_CMP__COMPARISON_VALUE__READ(
3632             CPS_UncachedRead32(CEDI_RegAddr(tsu_msb_sec_cmp)));
3633     return 0;
3634 }
3635 
emacGetPtpFrameTxTime(void * pD,CEDI_1588TimerVal * time)3636 uint32_t emacGetPtpFrameTxTime(void *pD, CEDI_1588TimerVal *time)
3637 {
3638     if ((pD==NULL) || (time==NULL))
3639         return EINVAL;
3640     if (0==CEDI_PdVar(hwCfg).tsu)
3641         return ENOTSUP;
3642 
3643     time->nanosecs = EMAC_REGS__TSU_PTP_TX_NSEC__TIMER__READ(
3644             CPS_UncachedRead32(CEDI_RegAddr(tsu_ptp_tx_nsec)));
3645     time->secsLower = EMAC_REGS__TSU_PTP_TX_SEC__TIMER__READ(
3646             CPS_UncachedRead32(CEDI_RegAddr(tsu_ptp_tx_sec)));
3647     time->secsUpper = EMAC_REGS__TSU_PTP_TX_MSB_SEC__TIMER_SECONDS__READ(
3648             CPS_UncachedRead32(CEDI_RegAddr(tsu_ptp_tx_msb_sec)));
3649     return 0;
3650 }
3651 
emacGetPtpFrameRxTime(void * pD,CEDI_1588TimerVal * time)3652 uint32_t emacGetPtpFrameRxTime(void *pD, CEDI_1588TimerVal *time)
3653 {
3654     if ((pD==NULL) || (time==NULL))
3655         return EINVAL;
3656     if (0==CEDI_PdVar(hwCfg).tsu)
3657         return ENOTSUP;
3658 
3659     time->nanosecs = EMAC_REGS__TSU_PTP_RX_NSEC__TIMER__READ(
3660             CPS_UncachedRead32(CEDI_RegAddr(tsu_ptp_rx_nsec)));
3661     time->secsLower = EMAC_REGS__TSU_PTP_RX_SEC__TIMER__READ(
3662             CPS_UncachedRead32(CEDI_RegAddr(tsu_ptp_rx_sec)));
3663     time->secsUpper = EMAC_REGS__TSU_PTP_RX_MSB_SEC__TIMER_SECONDS__READ(
3664             CPS_UncachedRead32(CEDI_RegAddr(tsu_ptp_rx_msb_sec)));
3665     return 0;
3666 }
3667 
emacGetPtpPeerFrameTxTime(void * pD,CEDI_1588TimerVal * time)3668 uint32_t emacGetPtpPeerFrameTxTime(void *pD, CEDI_1588TimerVal *time)
3669 {
3670     if ((pD==NULL) || (time==NULL))
3671         return EINVAL;
3672     if (0==CEDI_PdVar(hwCfg).tsu)
3673         return ENOTSUP;
3674 
3675     time->nanosecs = EMAC_REGS__TSU_PEER_TX_NSEC__TIMER__READ(
3676             CPS_UncachedRead32(CEDI_RegAddr(tsu_peer_tx_nsec)));
3677     time->secsLower = EMAC_REGS__TSU_PEER_TX_SEC__TIMER__READ(
3678             CPS_UncachedRead32(CEDI_RegAddr(tsu_peer_tx_sec)));
3679     time->secsUpper = EMAC_REGS__TSU_PEER_TX_MSB_SEC__TIMER_SECONDS__READ(
3680             CPS_UncachedRead32(CEDI_RegAddr(tsu_peer_tx_msb_sec)));
3681     return 0;
3682 }
3683 
emacGetPtpPeerFrameRxTime(void * pD,CEDI_1588TimerVal * time)3684 uint32_t emacGetPtpPeerFrameRxTime(void *pD, CEDI_1588TimerVal *time)
3685 {
3686     if ((pD==NULL) || (time==NULL))
3687         return EINVAL;
3688     if (0==CEDI_PdVar(hwCfg).tsu)
3689         return ENOTSUP;
3690 
3691     time->nanosecs = EMAC_REGS__TSU_PEER_RX_NSEC__TIMER__READ(
3692             CPS_UncachedRead32(CEDI_RegAddr(tsu_peer_rx_nsec)));
3693     time->secsLower = EMAC_REGS__TSU_PEER_RX_SEC__TIMER__READ(
3694             CPS_UncachedRead32(CEDI_RegAddr(tsu_peer_rx_sec)));
3695     time->secsUpper = EMAC_REGS__TSU_PEER_RX_MSB_SEC__TIMER_SECONDS__READ(
3696             CPS_UncachedRead32(CEDI_RegAddr(tsu_peer_rx_msb_sec)));
3697     return 0;
3698 }
3699 
emacGet1588SyncStrobeTime(void * pD,CEDI_1588TimerVal * time)3700 uint32_t emacGet1588SyncStrobeTime(void *pD, CEDI_1588TimerVal *time)
3701 {
3702     if ((pD==NULL) || (time==NULL))
3703         return EINVAL;
3704     if (0==CEDI_PdVar(hwCfg).tsu)
3705         return ENOTSUP;
3706 
3707     time->nanosecs = EMAC_REGS__TSU_STROBE_NSEC__STROBE__READ(
3708             CPS_UncachedRead32(CEDI_RegAddr(tsu_strobe_nsec)));
3709     time->secsLower = EMAC_REGS__TSU_STROBE_SEC__STROBE__READ(
3710             CPS_UncachedRead32(CEDI_RegAddr(tsu_strobe_sec)));
3711     time->secsUpper =
3712             EMAC_REGS__TSU_STROBE_MSB_SEC__STROBE__READ(
3713             CPS_UncachedRead32(CEDI_RegAddr(tsu_strobe_msb_sec)));
3714     return 0;
3715 }
3716 
emacSetExtTsuPortEnable(void * pD,uint8_t enable)3717 uint32_t emacSetExtTsuPortEnable(void *pD, uint8_t enable)
3718 {
3719     uint32_t reg;
3720 
3721     if (pD==NULL) return EINVAL;
3722     if (enable>1) return EINVAL;
3723     if (0==CEDI_PdVar(hwCfg).ext_tsu_timer)
3724         return ENOTSUP;
3725 
3726     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
3727     if (enable)
3728         EMAC_REGS__NETWORK_CONTROL__EXT_TSU_PORT_ENABLE__SET(reg);
3729     else
3730         EMAC_REGS__NETWORK_CONTROL__EXT_TSU_PORT_ENABLE__CLR(reg);
3731     CPS_UncachedWrite32(CEDI_RegAddr(network_control), reg);
3732 
3733     return 0;
3734 }
3735 
emacGetExtTsuPortEnable(void * pD,uint8_t * enable)3736 uint32_t emacGetExtTsuPortEnable(void *pD, uint8_t *enable)
3737 {
3738     if ((pD==NULL)||(enable==NULL))
3739       return EINVAL;
3740     *enable= 0;
3741 
3742     if (0==CEDI_PdVar(hwCfg).tsu)
3743         return ENOTSUP;
3744 
3745     *enable = EMAC_REGS__NETWORK_CONTROL__EXT_TSU_PORT_ENABLE__READ(
3746             CPS_UncachedRead32(CEDI_RegAddr(network_control)));
3747     return 0;
3748 }
3749 
emacSet1588OneStepTxSyncEnable(void * pD,uint8_t enable)3750 uint32_t emacSet1588OneStepTxSyncEnable(void *pD, uint8_t enable)
3751 {
3752     uint32_t reg;
3753 
3754     if (pD==NULL) return EINVAL;
3755     if (enable>1) return EINVAL;
3756     if (0==CEDI_PdVar(hwCfg).tsu)
3757         return ENOTSUP;
3758 
3759     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
3760     if (enable)
3761         EMAC_REGS__NETWORK_CONTROL__ONE_STEP_SYNC_MODE__SET(reg);
3762     else
3763         EMAC_REGS__NETWORK_CONTROL__ONE_STEP_SYNC_MODE__CLR(reg);
3764     CPS_UncachedWrite32(CEDI_RegAddr(network_control), reg);
3765 
3766     return 0;
3767 }
3768 
emacGet1588OneStepTxSyncEnable(void * pD,uint8_t * enable)3769 uint32_t emacGet1588OneStepTxSyncEnable(void *pD, uint8_t *enable)
3770 {
3771     if ((pD==NULL)||(enable==NULL))
3772         return EINVAL;
3773     *enable = 0;
3774 
3775     if (CEDI_PdVar(hwCfg).tsu)
3776     {
3777         *enable = EMAC_REGS__NETWORK_CONTROL__ONE_STEP_SYNC_MODE__READ(
3778             CPS_UncachedRead32(CEDI_RegAddr(network_control)));
3779     }
3780     return 0;
3781 }
3782 
3783 /****************************** Time Stamping *********************************/
3784 
emacSetDescTimeStampMode(void * pD,CEDI_TxTsMode txMode,CEDI_RxTsMode rxMode)3785 uint32_t emacSetDescTimeStampMode(void *pD, CEDI_TxTsMode txMode,
3786                                     CEDI_RxTsMode rxMode)
3787 {
3788     uint32_t regData;
3789     CEDI_Config *config = &CEDI_PdVar(cfg);
3790 
3791     if (pD==NULL)
3792         return EINVAL;
3793     if ((txMode>CEDI_TX_TS_ALL) || (rxMode>CEDI_RX_TS_ALL))
3794         return EINVAL;
3795 
3796     if (((config->enTxExtBD==0) && (txMode!=0))||
3797             ((config->enRxExtBD==0) && (rxMode!=0)))
3798     {
3799         vDbgMsg(DBG_GEN_MSG, 5, "%s","ERROR: Time stamping not enabled in DMA config ");
3800         return EINVAL;
3801     }
3802 
3803     regData = CPS_UncachedRead32(CEDI_RegAddr(tx_bd_control));
3804     EMAC_REGS__TX_BD_CONTROL__TX_BD_TS_MODE__MODIFY(regData,txMode);
3805     CPS_UncachedWrite32(CEDI_RegAddr(tx_bd_control),regData);
3806 
3807     regData = CPS_UncachedRead32(CEDI_RegAddr(rx_bd_control));
3808     EMAC_REGS__RX_BD_CONTROL__RX_BD_TS_MODE__MODIFY(regData,rxMode);
3809     CPS_UncachedWrite32(CEDI_RegAddr(rx_bd_control),regData);
3810 
3811     return 0;
3812 }
3813 
emacGetDescTimeStampMode(void * pD,CEDI_TxTsMode * txMode,CEDI_RxTsMode * rxMode)3814 uint32_t emacGetDescTimeStampMode(void *pD, CEDI_TxTsMode* txMode,
3815                                     CEDI_RxTsMode* rxMode)
3816 {
3817     uint32_t regData;
3818     CEDI_Config *config = &CEDI_PdVar(cfg);
3819 
3820     if ((pD==NULL) || (txMode==NULL) || (rxMode==NULL))
3821         return EINVAL;
3822     if ((config->enTxExtBD==0)||(config->enRxExtBD==0))
3823         return ENOTSUP;
3824 
3825     regData = CPS_UncachedRead32(CEDI_RegAddr(tx_bd_control));
3826     *txMode = (CEDI_TxTsMode)EMAC_REGS__TX_BD_CONTROL__TX_BD_TS_MODE__READ(regData);
3827 
3828     regData = CPS_UncachedRead32(CEDI_RegAddr(rx_bd_control));
3829     *rxMode = (CEDI_RxTsMode)EMAC_REGS__RX_BD_CONTROL__RX_BD_TS_MODE__READ(regData);
3830 
3831     return 0;
3832 }
3833 
emacSetStoreRxTimeStamp(void * pD,uint8_t enable)3834 uint32_t emacSetStoreRxTimeStamp(void *pD, uint8_t enable)
3835 {
3836     uint32_t reg;
3837 
3838     if (pD==NULL) return EINVAL;
3839     if (enable>1) return EINVAL;
3840     if (0==CEDI_PdVar(hwCfg).tsu)
3841         return ENOTSUP;
3842 
3843     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
3844     if (enable)
3845         EMAC_REGS__NETWORK_CONTROL__STORE_RX_TS__SET(reg);
3846     else
3847         EMAC_REGS__NETWORK_CONTROL__STORE_RX_TS__CLR(reg);
3848     CPS_UncachedWrite32(CEDI_RegAddr(network_control), reg);
3849     return 0;
3850 }
3851 
emacGetStoreRxTimeStamp(void * pD,uint8_t * enable)3852 uint32_t emacGetStoreRxTimeStamp(void *pD, uint8_t *enable)
3853 {
3854     if ((pD==NULL)||(enable==NULL))
3855       return EINVAL;
3856     *enable = 0;
3857 
3858     if (0==CEDI_PdVar(hwCfg).tsu)
3859         return ENOTSUP;
3860 
3861     *enable = EMAC_REGS__NETWORK_CONTROL__STORE_RX_TS__READ(
3862             CPS_UncachedRead32(CEDI_RegAddr(network_control)));
3863     return 0;
3864 }
3865 
3866 /********************** PCS Control/Auto-negotiation *************************/
3867 
emacResetPcs(void * pD)3868 uint32_t emacResetPcs(void *pD)
3869 {
3870     uint32_t reg;
3871     if (pD==NULL) return EINVAL;
3872     vDbgMsg(DBG_GEN_MSG, 10, "%s entered (regBase %08X)\n", __func__,
3873             (uint32_t)CEDI_PdVar(cfg).regBase);
3874     if (CEDI_PdVar(hwCfg).no_pcs)
3875         return ENOTSUP;
3876 
3877     reg = CPS_UncachedRead32(CEDI_RegAddr(pcs_control));
3878     EMAC_REGS__PCS_CONTROL__PCS_SOFTWARE_RESET__SET(reg);
3879     CPS_UncachedWrite32(CEDI_RegAddr(pcs_control), reg);
3880 
3881     CEDI_PdVar(basePageExp) = 1;
3882     CEDI_PdVar(autoNegActive) = 0;
3883 
3884     return 0;
3885 }
3886 
emacGetPcsReady(void * pD,uint8_t * ready)3887 uint32_t emacGetPcsReady(void *pD, uint8_t *ready)
3888 {
3889     if ((pD==NULL)||(ready==NULL))
3890       return EINVAL;
3891     if (CEDI_PdVar(hwCfg).no_pcs)
3892         return ENOTSUP;
3893 
3894     *ready = (0==EMAC_REGS__PCS_CONTROL__PCS_SOFTWARE_RESET__READ(
3895             CPS_UncachedRead32(CEDI_RegAddr(pcs_control))));
3896     return 0;
3897 }
3898 
emacStartAutoNegotiation(void * pD,CEDI_AnAdvPage * advDat)3899 uint32_t emacStartAutoNegotiation(void *pD, CEDI_AnAdvPage *advDat)
3900 {
3901     uint32_t reg;
3902     uint32_t event;
3903     uint32_t ret;
3904 
3905     if ((pD==NULL)||(advDat==NULL))
3906         return EINVAL;
3907 
3908     if ((CEDI_PdVar(hwCfg).no_pcs) ||
3909        (EMAC_REGS__NETWORK_CONFIG__SGMII_MODE_ENABLE__READ(
3910             CPS_UncachedRead32(CEDI_RegAddr(network_config)))))
3911         return ENOTSUP;
3912     if (CEDI_PdVar(autoNegActive))
3913         return EBUSY;
3914 
3915     //check if we have an event for auto negotiation complete:
3916     ret=emacGetEventEnable(pD,0,&event);
3917     if (ret!=0)
3918         return ret;
3919     if ((event & CEDI_EV_PCS_AN_COMPLETE) == 0)
3920         return EINVAL;
3921 
3922     if ((advDat->fullDuplex>1) || (advDat->halfDuplex>1) || (advDat->nextPage>1)
3923             || (advDat->pauseCap>CEDI_AN_PAUSE_CAP_BOTH)
3924             || (advDat->remFlt>CEDI_AN_REM_FLT_AN_ERR))
3925         return EINVAL;
3926 
3927     reg = CPS_UncachedRead32(CEDI_RegAddr(pcs_control));
3928     EMAC_REGS__PCS_CONTROL__ENABLE_AUTO_NEG__SET(reg);
3929     CPS_UncachedWrite32(CEDI_RegAddr(pcs_control), reg);
3930 
3931     emacSetAnAdvPage(pD, advDat);
3932 
3933     CEDI_PdVar(autoNegActive) = 1;
3934     CEDI_PdVar(basePageExp) = 1;
3935 
3936     reg = CPS_UncachedRead32(CEDI_RegAddr(pcs_control));
3937     EMAC_REGS__PCS_CONTROL__RESTART_AUTO_NEG__SET(reg);
3938     CPS_UncachedWrite32(CEDI_RegAddr(pcs_control), reg);
3939     return 0;
3940 }
3941 
emacSetAutoNegEnable(void * pD,uint8_t enable)3942 uint32_t emacSetAutoNegEnable(void *pD, uint8_t enable)
3943 {
3944     uint32_t reg;
3945 
3946     if (pD==NULL)
3947         return EINVAL;
3948     if (enable>1) return EINVAL;
3949     if (CEDI_PdVar(hwCfg).no_pcs ||
3950        (EMAC_REGS__NETWORK_CONFIG__SGMII_MODE_ENABLE__READ(
3951             CPS_UncachedRead32(CEDI_RegAddr(network_config)))))
3952         return ENOTSUP;
3953     if ((enable) && CEDI_PdVar(autoNegActive))
3954         return EBUSY;
3955 
3956     reg = CPS_UncachedRead32(CEDI_RegAddr(pcs_control));
3957     if (enable) {
3958         EMAC_REGS__PCS_CONTROL__ENABLE_AUTO_NEG__SET(reg);
3959     }
3960     else
3961     {
3962         EMAC_REGS__PCS_CONTROL__ENABLE_AUTO_NEG__CLR(reg);
3963         CEDI_PdVar(autoNegActive) = 0;
3964     }
3965     CPS_UncachedWrite32(CEDI_RegAddr(pcs_control), reg);
3966 
3967     return 0;
3968 }
3969 
emacGetAutoNegEnable(void * pD,uint8_t * enable)3970 uint32_t emacGetAutoNegEnable(void *pD, uint8_t *enable)
3971 {
3972     if ((pD==NULL)||(enable==NULL))
3973         return EINVAL;
3974     if (CEDI_PdVar(hwCfg).no_pcs)
3975         return ENOTSUP;
3976 
3977     *enable = EMAC_REGS__PCS_CONTROL__ENABLE_AUTO_NEG__READ(
3978         CPS_UncachedRead32(CEDI_RegAddr(pcs_control)));
3979     return 0;
3980 }
3981 
3982 /* internal utility for reading PCS status & maintaining
3983  * "read-once" functionality of link status & remote fault
3984  */
readPcsStatus(void * pD)3985 uint32_t readPcsStatus(void *pD) {
3986     uint32_t reg = CPS_UncachedRead32(CEDI_RegAddr(pcs_status));
3987     if (0==EMAC_REGS__PCS_STATUS__LINK_STATUS__READ(reg))
3988         CEDI_PdVar(anLinkStat) = 0;
3989     if (1==EMAC_REGS__PCS_STATUS__REMOTE_FAULT__READ(reg))
3990         CEDI_PdVar(anRemFault) = 1;
3991     return reg;
3992 }
3993 
emacGetLinkStatus(void * pD,uint8_t * status)3994 uint32_t emacGetLinkStatus(void *pD, uint8_t *status)
3995 {
3996     uint32_t reg;
3997 
3998     if ((pD==NULL)||(status==NULL))
3999       return EINVAL;
4000 
4001     reg = readPcsStatus(pD);
4002     /* return low if this has not been done yet */
4003     *status = CEDI_PdVar(anLinkStat);
4004 
4005     CEDI_PdVar(anLinkStat) =
4006             EMAC_REGS__PCS_STATUS__LINK_STATUS__READ(reg);
4007 
4008     return 0;
4009 }
4010 
emacGetAnRemoteFault(void * pD,uint8_t * status)4011 uint32_t emacGetAnRemoteFault(void *pD, uint8_t *status)
4012 {
4013     uint32_t reg;
4014 
4015     if ((pD==NULL)||(status==NULL))
4016       return EINVAL;
4017 
4018     reg = readPcsStatus(pD);
4019     /* return high if this has not been done yet */
4020     *status = CEDI_PdVar(anRemFault);
4021 
4022     CEDI_PdVar(anRemFault) =
4023             EMAC_REGS__PCS_STATUS__REMOTE_FAULT__READ(reg);
4024 
4025     return 0;
4026 }
4027 
emacGetAnComplete(void * pD,uint8_t * status)4028 uint32_t emacGetAnComplete(void *pD, uint8_t *status)
4029 {
4030     if ((pD==NULL)||(status==NULL))
4031       return EINVAL;
4032     if (CEDI_PdVar(hwCfg).no_pcs)
4033         return ENOTSUP;
4034 
4035     *status = EMAC_REGS__PCS_STATUS__AUTO_NEG_COMPLETE__READ(readPcsStatus(pD));
4036 
4037     return 0;
4038 }
4039 
emacSetAnAdvPage(void * pD,CEDI_AnAdvPage * advDat)4040 uint32_t emacSetAnAdvPage(void *pD, CEDI_AnAdvPage *advDat)
4041 {
4042     uint32_t reg;
4043 
4044     if ((pD==NULL)||(advDat==NULL))
4045         return EINVAL;
4046     if (CEDI_PdVar(hwCfg).no_pcs)
4047         return ENOTSUP;
4048     if ((advDat->fullDuplex>1) || (advDat->halfDuplex>1) || (advDat->nextPage>1)
4049             || (advDat->pauseCap>CEDI_AN_PAUSE_CAP_BOTH)
4050             || (advDat->remFlt>CEDI_AN_REM_FLT_AN_ERR))
4051         return EINVAL;
4052 
4053     reg = 0;
4054     if (advDat->fullDuplex)
4055         EMAC_REGS__PCS_AN_ADV__FULL_DUPLEX__SET(reg);
4056     if (advDat->halfDuplex)
4057         EMAC_REGS__PCS_AN_ADV__HALF_DUPLEX__SET(reg);
4058     EMAC_REGS__PCS_AN_ADV__PAUSE__MODIFY(reg, advDat->pauseCap);
4059     EMAC_REGS__PCS_AN_ADV__REMOTE_FAULT__MODIFY(reg, advDat->remFlt);
4060     if (advDat->nextPage)
4061         EMAC_REGS__PCS_AN_ADV__NEXT_PAGE__SET(reg);
4062     CPS_UncachedWrite32(CEDI_RegAddr(pcs_an_adv), reg);
4063 
4064     return 0;
4065 }
4066 
emacGetAnAdvPage(void * pD,CEDI_AnAdvPage * advDat)4067 uint32_t emacGetAnAdvPage(void *pD, CEDI_AnAdvPage *advDat)
4068 {
4069     uint32_t reg;
4070 
4071     if ((pD==NULL)||(advDat==NULL))
4072         return EINVAL;
4073     if (CEDI_PdVar(hwCfg).no_pcs)
4074         return ENOTSUP;
4075 
4076     reg = CPS_UncachedRead32(CEDI_RegAddr(pcs_an_adv));
4077     advDat->fullDuplex = EMAC_REGS__PCS_AN_ADV__FULL_DUPLEX__READ(reg);
4078     advDat->halfDuplex = EMAC_REGS__PCS_AN_ADV__HALF_DUPLEX__READ(reg);
4079     advDat->pauseCap = (CEDI_PauseCap)EMAC_REGS__PCS_AN_ADV__PAUSE__READ(reg);
4080     advDat->remFlt = (CEDI_RemoteFault)EMAC_REGS__PCS_AN_ADV__REMOTE_FAULT__READ(reg);
4081     advDat->nextPage = EMAC_REGS__PCS_AN_ADV__NEXT_PAGE__READ(reg);
4082 
4083     return 0;
4084 }
4085 
emacGetLpAbilityPage(void * pD,CEDI_LpAbilityPage * lpAbl)4086 uint32_t emacGetLpAbilityPage(void *pD, CEDI_LpAbilityPage *lpAbl)
4087 {
4088     uint32_t reg;
4089 
4090     if ((pD==NULL) || (lpAbl==NULL))
4091          return EINVAL;
4092     if (CEDI_PdVar(hwCfg).no_pcs)
4093          return ENOTSUP;
4094 
4095     reg = CPS_UncachedRead32(CEDI_RegAddr(pcs_an_lp_base));
4096 
4097     if (EMAC_REGS__NETWORK_CONFIG__SGMII_MODE_ENABLE__READ(
4098             CPS_UncachedRead32(CEDI_RegAddr(network_config))))
4099     {
4100         /* SGMII mode format */
4101         lpAbl->sgmii = 1;
4102         lpAbl->ablInfo.sgmLpAbl.speed =
4103                 (CEDI_IfSpeed)(EMAC_REGS__PCS_AN_LP_BASE__SPEED_RESERVED__READ(reg)>>1);
4104         lpAbl->ablInfo.sgmLpAbl.lpAck =
4105                 EMAC_REGS__PCS_AN_LP_BASE__LINK_PARTNER_ACKNOWLEDGE__READ(reg);
4106         lpAbl->ablInfo.sgmLpAbl.linkStatus =
4107                 EMAC_REGS__PCS_AN_LP_BASE__LINK_PARTNER_NEXT_PAGE_STATUS__READ(reg);
4108         lpAbl->ablInfo.sgmLpAbl.duplex =
4109                 EMAC_REGS__PCS_AN_LP_BASE__LINK_PARTNER_REMOTE_FAULT_DUPLEX_MODE__READ(reg);
4110     }
4111     else
4112     {
4113         /* Default format */
4114         lpAbl->sgmii = 0;
4115         lpAbl->ablInfo.defLpAbl.fullDuplex =
4116                 EMAC_REGS__PCS_AN_LP_BASE__LINK_PARTNER_FULL_DUPLEX__READ(reg);
4117         lpAbl->ablInfo.defLpAbl.halfDuplex =
4118                 EMAC_REGS__PCS_AN_LP_BASE__LINK_PARTNER_HALF_DUPLEX__READ(reg);
4119         lpAbl->ablInfo.defLpAbl.pauseCap =
4120                 (CEDI_PauseCap)EMAC_REGS__PCS_AN_LP_BASE__PAUSE__READ(reg);
4121         lpAbl->ablInfo.defLpAbl.lpAck =
4122                 EMAC_REGS__PCS_AN_LP_BASE__LINK_PARTNER_ACKNOWLEDGE__READ(reg);
4123         lpAbl->ablInfo.defLpAbl.remFlt =
4124                 (CEDI_RemoteFault)EMAC_REGS__PCS_AN_LP_BASE__LINK_PARTNER_REMOTE_FAULT_DUPLEX_MODE__READ(reg);
4125         lpAbl->ablInfo.defLpAbl.lpNextPage =
4126                 EMAC_REGS__PCS_AN_LP_BASE__LINK_PARTNER_NEXT_PAGE_STATUS__READ(reg);
4127     }
4128 
4129     return 0;
4130 }
4131 
emacGetPageRx(void * pD)4132 uint32_t emacGetPageRx(void *pD)
4133 {
4134     if (pD==NULL) return 0;
4135     if (CEDI_PdVar(hwCfg).no_pcs)
4136         return 0;
4137 
4138     return EMAC_REGS__PCS_AN_EXP__PAGE_RECEIVED__READ(
4139             CPS_UncachedRead32(CEDI_RegAddr(pcs_an_exp)));
4140 }
4141 
emacSetNextPageTx(void * pD,CEDI_AnNextPage * npDat)4142 uint32_t emacSetNextPageTx(void *pD, CEDI_AnNextPage *npDat)
4143 {
4144     uint32_t reg;
4145 
4146     if ((pD==NULL)||(npDat==NULL))
4147       return EINVAL;
4148     if (CEDI_PdVar(hwCfg).no_pcs)
4149         return ENOTSUP;
4150     if ((npDat->message>0x7FF) || (npDat->ack2>1) || (npDat->msgPage>1)
4151             || (npDat->np>1))
4152         return EINVAL;
4153 
4154     reg = 0;
4155     EMAC_REGS__PCS_AN_NP_TX__MESSAGE__MODIFY(reg, npDat->message);
4156     if (npDat->ack2)
4157         EMAC_REGS__PCS_AN_NP_TX__ACKNOWLEDGE_2__SET(reg);
4158     if (npDat->msgPage)
4159         EMAC_REGS__PCS_AN_NP_TX__MESSAGE_PAGE_INDICATOR__SET(reg);
4160     if (npDat->np)
4161         EMAC_REGS__PCS_AN_NP_TX__NEXT_PAGE_TO_TRANSMIT__SET(reg);
4162     CPS_UncachedWrite32(CEDI_RegAddr(pcs_an_np_tx), reg);
4163 
4164     return 0;
4165 }
4166 
emacGetNextPageTx(void * pD,CEDI_AnNextPage * npDat)4167 uint32_t emacGetNextPageTx(void *pD, CEDI_AnNextPage *npDat)
4168 {
4169     uint32_t reg;
4170 
4171     if ((pD==NULL)||(npDat==NULL))
4172       return EINVAL;
4173 
4174     reg = CPS_UncachedRead32(CEDI_RegAddr(pcs_an_np_tx));
4175     npDat->message = EMAC_REGS__PCS_AN_NP_TX__MESSAGE__READ(reg);
4176     npDat->ack2 = EMAC_REGS__PCS_AN_NP_TX__ACKNOWLEDGE_2__READ(reg);
4177     npDat->msgPage = EMAC_REGS__PCS_AN_NP_TX__MESSAGE_PAGE_INDICATOR__READ(reg);
4178     npDat->np = EMAC_REGS__PCS_AN_NP_TX__NEXT_PAGE_TO_TRANSMIT__READ(reg);
4179 
4180     return 0;
4181 }
4182 
emacGetLpNextPage(void * pD,CEDI_LpNextPage * npDat)4183 uint32_t emacGetLpNextPage(void *pD, CEDI_LpNextPage *npDat)
4184 {
4185     uint32_t reg;
4186 
4187     if ((pD==NULL)||(npDat==NULL))
4188       return EINVAL;
4189 
4190     reg = CPS_UncachedRead32(CEDI_RegAddr(pcs_an_lp_np));
4191     npDat->message = EMAC_REGS__PCS_AN_LP_NP__MESSAGE__READ(reg);
4192     npDat->toggle = EMAC_REGS__PCS_AN_LP_NP__TOGGLE__READ(reg);
4193     npDat->ack2 = EMAC_REGS__PCS_AN_LP_NP__ACKNOWLEDGE_2__READ(reg);
4194     npDat->msgPage = EMAC_REGS__PCS_AN_LP_NP__MESSAGE_PAGE_INDICATOR__READ(reg);
4195     npDat->ack = EMAC_REGS__PCS_AN_LP_NP__ACKNOWLEDGE__READ(reg);
4196     npDat->np = EMAC_REGS__PCS_AN_LP_NP__NEXT_PAGE_TO_RECEIVE__READ(reg);
4197 
4198     return 0;
4199 }
4200 
4201 /**************************** PHY Management *********************************/
4202 
emacGetPhyId(void * pD,uint32_t * phyId)4203 uint32_t emacGetPhyId(void *pD, uint32_t *phyId)
4204 {
4205     if ((pD==NULL)||(phyId==NULL))
4206       return EINVAL;
4207 
4208 #ifdef EMAC_REGS__PCS_PHY_TOP_ID__ID_CODE__READ
4209     volatile uint32_t reg, retVal;
4210     reg = CPS_UncachedRead32(CEDI_RegAddr(pcs_phy_top_id));
4211     retVal = EMAC_REGS__PCS_PHY_TOP_ID__ID_CODE__READ(reg)<<16;
4212     reg = CPS_UncachedRead32(CEDI_RegAddr(pcs_phy_bot_id));
4213     retVal |= EMAC_REGS__PCS_PHY_BOT_ID__ID_CODE__READ(reg);
4214     *phyId= retVal;
4215     return 0;
4216 #endif
4217     return ENOTSUP;
4218 }
4219 
emacSetMdioEnable(void * pD,uint8_t enable)4220 void emacSetMdioEnable(void *pD, uint8_t enable)
4221 {
4222     uint32_t ncr;
4223     if (pD==NULL) return;
4224     if (enable>1) return;
4225     ncr = CPS_UncachedRead32(CEDI_RegAddr(network_control));
4226     if (enable)
4227         EMAC_REGS__NETWORK_CONTROL__MAN_PORT_EN__SET(ncr);
4228     else
4229         EMAC_REGS__NETWORK_CONTROL__MAN_PORT_EN__CLR(ncr);
4230     CPS_UncachedWrite32(CEDI_RegAddr(network_control), ncr);
4231 }
4232 
emacGetMdioEnable(void * pD)4233 uint32_t emacGetMdioEnable(void *pD)
4234 {
4235     if (pD==NULL) return 0;
4236     return EMAC_REGS__NETWORK_CONTROL__MAN_PORT_EN__READ(
4237           CPS_UncachedRead32(CEDI_RegAddr(network_control)));
4238 }
4239 
4240 /* Initiate a write or set address operation on the MDIO interface.
4241  * Clause 45 devices require a call to set the register address (if
4242  * this is changing since last access), and then a write or read
4243  * operation.
4244  * The command writes to the shift register, which starts output on
4245  * the MDIO interface. Write completion is signalled by the
4246  * phyManComplete callback, or by polling getMdioIdle.
4247  * @param pD - driver private state info specific to this instance
4248  * @param flags - combination of 2 bit-flags:
4249  *        if CEDI_MDIO_FLG_CLAUSE_45 present, specifies clause 45 PHY
4250  *        (else clause 22).
4251  *        if CEDI_MDIO_FLG_SET_ADDR present, specifies a set address operation
4252  *        (else do a write operation)  Ignored if not clause 45.
4253  * @param phyAddr - PHY address
4254  * @param devReg - device type (clause 45) or register address (clause 22)
4255  *           - enum CEDI_MdioDevType is available to specify the device type
4256  * @param addrData - register address (if CEDI_MDIO_FLG_SET_ADDR) or data to write
4257  */
emacPhyStartMdioWrite(void * pD,uint8_t flags,uint8_t phyAddr,uint8_t devReg,uint16_t addrData)4258 void emacPhyStartMdioWrite(void *pD, uint8_t flags, uint8_t phyAddr,
4259         uint8_t devReg, uint16_t addrData)
4260 {
4261     uint32_t reg;
4262     if (pD==NULL) return;
4263     reg = 0;
4264     EMAC_REGS__PHY_MANAGEMENT__PHY_WRITE_READ_DATA__MODIFY(reg, addrData);
4265     EMAC_REGS__PHY_MANAGEMENT__WRITE10__MODIFY(reg, 2);
4266     EMAC_REGS__PHY_MANAGEMENT__REGISTER_ADDRESS__MODIFY(reg, devReg);
4267     EMAC_REGS__PHY_MANAGEMENT__PHY_ADDRESS__MODIFY(reg, phyAddr);
4268     if ((flags & CEDI_MDIO_FLG_CLAUSE_45) && (flags & CEDI_MDIO_FLG_SET_ADDR)) {
4269         EMAC_REGS__PHY_MANAGEMENT__OPERATION__MODIFY(reg, CEDI_PHY_ADDR_OP);
4270     }
4271     else
4272         EMAC_REGS__PHY_MANAGEMENT__OPERATION__MODIFY(reg, CEDI_PHY_WRITE_OP);
4273     if ((flags & CEDI_MDIO_FLG_CLAUSE_45)==0)
4274         EMAC_REGS__PHY_MANAGEMENT__WRITE1__SET(reg);
4275     CPS_UncachedWrite32(CEDI_RegAddr(phy_management), reg);
4276 }
4277 
4278 /* Initiate a read operation on the MDIO interface.  If clause 45, the
4279  * register address will need to be set by a preceding phyStartMdioWrite
4280  * call, unless same as for last operation. Completion is signalled by the
4281  * phyManComplete callback, which will return the read data by a pointer
4282  * parameter. Alternatively polling getMdioIdle will indicate when
4283  * the operation completes, then getMdioReadDat will return the data.
4284  * @param pD - driver private state info specific to this instance
4285  * @param flags - combination of 2 bit-flags:
4286  *        if CEDI_MDIO_FLG_CLAUSE_45 present, specifies clause 45 PHY
4287  *        (else clause 22).
4288  *        if CEDI_MDIO_FLG_INC_ADDR present, and clause 45, then address will
4289  *        be incremented after the read operation.
4290  * @param phyAddr - PHY address
4291  * @param devReg - device type (clause 45) or register address (clause 22)
4292  *           - enum CEDI_MdioDevType is available to specify the device type
4293  */
emacPhyStartMdioRead(void * pD,uint8_t flags,uint8_t phyAddr,uint8_t devReg)4294 void emacPhyStartMdioRead(void *pD, uint8_t flags, uint8_t phyAddr,
4295         uint8_t devReg)
4296 {
4297     uint32_t reg;
4298     if (pD==NULL) return;
4299     reg = 0;
4300     EMAC_REGS__PHY_MANAGEMENT__WRITE10__MODIFY(reg, 2);
4301     EMAC_REGS__PHY_MANAGEMENT__REGISTER_ADDRESS__MODIFY(reg, devReg);
4302     EMAC_REGS__PHY_MANAGEMENT__PHY_ADDRESS__MODIFY(reg, phyAddr);
4303     if (flags & CEDI_MDIO_FLG_CLAUSE_45) {
4304         if (flags & CEDI_MDIO_FLG_INC_ADDR) {
4305             EMAC_REGS__PHY_MANAGEMENT__OPERATION__MODIFY(reg,
4306                     CEDI_PHY_CL45_READ_INC_OP);
4307         }
4308         else {
4309             EMAC_REGS__PHY_MANAGEMENT__OPERATION__MODIFY(reg,
4310                     CEDI_PHY_CL45_READ_OP);
4311         }
4312     }
4313     else
4314         EMAC_REGS__PHY_MANAGEMENT__OPERATION__MODIFY(reg, CEDI_PHY_CL22_READ_OP);
4315     if ((flags & CEDI_MDIO_FLG_CLAUSE_45)==0)
4316         EMAC_REGS__PHY_MANAGEMENT__WRITE1__SET(reg);
4317     CPS_UncachedWrite32(CEDI_RegAddr(phy_management), reg);
4318 }
4319 
emacGetMdioReadData(void * pD,uint16_t * readData)4320 uint32_t emacGetMdioReadData(void *pD, uint16_t *readData)
4321 {
4322     if ((pD==NULL)||(readData==NULL))
4323       return EINVAL;
4324     *readData= EMAC_REGS__PHY_MANAGEMENT__PHY_WRITE_READ_DATA__READ(
4325            CPS_UncachedRead32(CEDI_RegAddr(phy_management)));
4326 
4327     return 0;
4328 }
4329 
emacGetMdioIdle(void * pD)4330 uint32_t emacGetMdioIdle(void *pD)
4331 {
4332     if (pD==NULL) return 0;
4333     return EMAC_REGS__NETWORK_STATUS__MAN_DONE__READ(
4334            CPS_UncachedRead32(CEDI_RegAddr(network_status)));
4335 }
4336 
4337 /************************* Statistics Registers ******************************/
4338 
emacReadStats(void * pD)4339 uint32_t emacReadStats(void *pD)
4340 {
4341     CEDI_Statistics *stats;
4342 
4343     if (pD==NULL)
4344       return EINVAL;
4345 
4346     stats = ((CEDI_Statistics *)(CEDI_PdVar(cfg).statsRegs));
4347 
4348     if (CEDI_PdVar(hwCfg).no_stats)
4349         return ENOTSUP;
4350 
4351     stats->octetsTxLo = CPS_UncachedRead32(CEDI_RegAddr(octets_txed_bottom));
4352     stats->octetsTxHi = EMAC_REGS__OCTETS_TXED_TOP__COUNT__READ(
4353                          CPS_UncachedRead32(CEDI_RegAddr(octets_txed_top)));
4354     stats->framesTx = CPS_UncachedRead32(CEDI_RegAddr(frames_txed_ok));
4355     stats->broadcastTx = CPS_UncachedRead32(CEDI_RegAddr(broadcast_txed));
4356     stats->multicastTx = CPS_UncachedRead32(CEDI_RegAddr(multicast_txed));
4357     stats->pauseFrTx = EMAC_REGS__PAUSE_FRAMES_TXED__COUNT__READ(
4358                         CPS_UncachedRead32(CEDI_RegAddr(pause_frames_txed)));
4359     stats->fr64byteTx = CPS_UncachedRead32(CEDI_RegAddr(frames_txed_64));
4360     stats->fr65_127byteTx = CPS_UncachedRead32(CEDI_RegAddr(frames_txed_65));
4361     stats->fr128_255byteTx = CPS_UncachedRead32(CEDI_RegAddr(frames_txed_128));
4362     stats->fr256_511byteTx = CPS_UncachedRead32(CEDI_RegAddr(frames_txed_256));
4363     stats->fr512_1023byteTx = CPS_UncachedRead32(CEDI_RegAddr(frames_txed_512));
4364     stats->fr1024_1518byteTx =
4365                             CPS_UncachedRead32(CEDI_RegAddr(frames_txed_1024));
4366     stats->fr1519_byteTx = CPS_UncachedRead32(CEDI_RegAddr(frames_txed_1519));
4367     stats->underrunFrTx = EMAC_REGS__TX_UNDERRUNS__COUNT__READ(
4368                             CPS_UncachedRead32(CEDI_RegAddr(tx_underruns)));
4369     stats->singleCollFrTx =
4370                         CPS_UncachedRead32(CEDI_RegAddr(single_collisions));
4371     stats->multiCollFrTx =
4372                         CPS_UncachedRead32(CEDI_RegAddr(multiple_collisions));
4373     stats->excessCollFrTx = EMAC_REGS__EXCESSIVE_COLLISIONS__COUNT__READ(
4374                        CPS_UncachedRead32(CEDI_RegAddr(excessive_collisions)));
4375     stats->lateCollFrTx = EMAC_REGS__LATE_COLLISIONS__COUNT__READ(
4376                             CPS_UncachedRead32(CEDI_RegAddr(late_collisions)));
4377     stats->carrSensErrsTx = EMAC_REGS__CRS_ERRORS__COUNT__READ(
4378                               CPS_UncachedRead32(CEDI_RegAddr(crs_errors)));
4379     stats->deferredFrTx = CPS_UncachedRead32(CEDI_RegAddr(deferred_frames));
4380     stats->alignErrsRx = EMAC_REGS__ALIGNMENT_ERRORS__COUNT__READ(
4381                         CPS_UncachedRead32(CEDI_RegAddr(alignment_errors)));
4382     stats->octetsRxLo = CPS_UncachedRead32(CEDI_RegAddr(octets_rxed_bottom));
4383     stats->octetsRxHi = EMAC_REGS__OCTETS_RXED_TOP__COUNT__READ(
4384                           CPS_UncachedRead32(CEDI_RegAddr(octets_rxed_top)));
4385     stats->framesRx = CPS_UncachedRead32(CEDI_RegAddr(frames_rxed_ok));
4386     stats->broadcastRx = CPS_UncachedRead32(CEDI_RegAddr(broadcast_rxed));
4387     stats->multicastRx = CPS_UncachedRead32(CEDI_RegAddr(multicast_rxed));
4388     stats->pauseFrRx = EMAC_REGS__PAUSE_FRAMES_RXED__COUNT__READ(
4389                         CPS_UncachedRead32(CEDI_RegAddr(pause_frames_rxed)));
4390     stats->fr64byteRx = CPS_UncachedRead32(CEDI_RegAddr(frames_rxed_64));
4391     stats->fr65_127byteRx = CPS_UncachedRead32(CEDI_RegAddr(frames_rxed_65));
4392     stats->fr128_255byteRx = CPS_UncachedRead32(CEDI_RegAddr(frames_rxed_128));
4393     stats->fr256_511byteRx = CPS_UncachedRead32(CEDI_RegAddr(frames_rxed_256));
4394     stats->fr512_1023byteRx =
4395                             CPS_UncachedRead32(CEDI_RegAddr(frames_rxed_512));
4396     stats->fr1024_1518byteRx =
4397                             CPS_UncachedRead32(CEDI_RegAddr(frames_rxed_1024));
4398     stats->fr1519_byteRx =
4399                             CPS_UncachedRead32(CEDI_RegAddr(frames_rxed_1519));
4400     stats->undersizeFrRx = EMAC_REGS__UNDERSIZE_FRAMES__COUNT__READ(
4401                           CPS_UncachedRead32(CEDI_RegAddr(undersize_frames)));
4402     stats->oversizeFrRx = EMAC_REGS__EXCESSIVE_RX_LENGTH__COUNT__READ(
4403                     CPS_UncachedRead32(CEDI_RegAddr(excessive_rx_length)));
4404     stats->jabbersRx = EMAC_REGS__RX_JABBERS__COUNT__READ(
4405                             CPS_UncachedRead32(CEDI_RegAddr(rx_jabbers)));
4406     stats->fcsErrorsRx = EMAC_REGS__FCS_ERRORS__COUNT__READ(
4407                             CPS_UncachedRead32(CEDI_RegAddr(fcs_errors)));
4408     stats->lenChkErrRx = EMAC_REGS__RX_LENGTH_ERRORS__COUNT__READ(
4409                           CPS_UncachedRead32(CEDI_RegAddr(rx_length_errors)));
4410     stats->rxSymbolErrs = EMAC_REGS__RX_SYMBOL_ERRORS__COUNT__READ(
4411                         CPS_UncachedRead32(CEDI_RegAddr(rx_symbol_errors)));
4412     stats->rxResourcErrs =
4413                         CPS_UncachedRead32(CEDI_RegAddr(rx_resource_errors));
4414     stats->overrunFrRx = EMAC_REGS__RX_OVERRUNS__COUNT__READ(
4415                             CPS_UncachedRead32(CEDI_RegAddr(rx_overruns)));
4416     stats->ipChksumErrs = EMAC_REGS__RX_IP_CK_ERRORS__COUNT__READ(
4417                         CPS_UncachedRead32(CEDI_RegAddr(rx_ip_ck_errors)));
4418     stats->tcpChksumErrs = EMAC_REGS__RX_TCP_CK_ERRORS__COUNT__READ(
4419                         CPS_UncachedRead32(CEDI_RegAddr(rx_tcp_ck_errors)));
4420     stats->udpChksumErrs = EMAC_REGS__RX_UDP_CK_ERRORS__COUNT__READ(
4421                         CPS_UncachedRead32(CEDI_RegAddr(rx_udp_ck_errors)));
4422     stats->dmaRxPBufFlush = EMAC_REGS__AUTO_FLUSHED_PKTS__COUNT__READ(
4423                         CPS_UncachedRead32(CEDI_RegAddr(auto_flushed_pkts)));
4424 
4425 /*
4426     vDbgMsg(DBG_GEN_MSG, 10, "Non-zero Error Stats: %s%u %s%u %s%u %s%u %s%u %s%u %s%u %s%u %s%u %s%u %s%u %s%u %s%u %s%u %s%u %s%u %s%u %s%u %s%u %s%u\n",
4427         stats->underrunFrTx?"Tx underruns=":"", stats->underrunFrTx,
4428         stats->singleCollFrTx?"Single coll=":"", stats->singleCollFrTx,
4429         stats->multiCollFrTx?"Multiple coll=":"", stats->multiCollFrTx,
4430         stats->excessCollFrTx?"Excessive coll=":"", stats->excessCollFrTx,
4431         stats->lateCollFrTx?"Late coll=":"", stats->lateCollFrTx,
4432         stats->deferredFrTx?"Deferred fr=":"", stats->deferredFrTx,
4433         stats->carrSensErrsTx?"CarrSense errs=":"", stats->carrSensErrsTx,
4434         stats->undersizeFrRx?"Undersize fr":"", stats->undersizeFrRx,
4435         stats->oversizeFrRx?"Excess rx len=":"", stats->oversizeFrRx,
4436         stats->jabbersRx?"Rx jabbers=":"", stats->jabbersRx,
4437         stats->fcsErrorsRx?"FCS errs=":"", stats->fcsErrorsRx,
4438         stats->lenChkErrRx?"Rx len errs=":"", stats->lenChkErrRx,
4439         stats->rxSymbolErrs?"Rx sym errs=":"", stats->rxSymbolErrs,
4440         stats->alignErrsRx?"Align errs=":"", stats->alignErrsRx,
4441         stats->rxResourcErrs?"Rx res. errs=":"", stats->rxResourcErrs,
4442         stats->overrunFrRx?"Rx overruns=":"", stats->overrunFrRx,
4443         stats->ipChksumErrs?"Rx IP chk errs=":"", stats->ipChksumErrs,
4444         stats->tcpChksumErrs?"Rx TCP chk errs=":"", stats->tcpChksumErrs,
4445         stats->udpChksumErrs?"Rx UDP chk errs=":"", stats->udpChksumErrs,
4446         stats->dmaRxPBufFlush?"Auto flushed pkts=":"", stats->dmaRxPBufFlush );
4447 */
4448 
4449     return 0;
4450 }
4451 
emacClearStats(void * pD)4452 uint32_t emacClearStats(void *pD)
4453 {
4454     uint32_t reg;
4455     if (pD==NULL) return EINVAL;
4456 
4457     if (CEDI_PdVar(hwCfg).no_stats)
4458         return ENOTSUP;
4459 
4460     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
4461     EMAC_REGS__NETWORK_CONTROL__CLEAR_ALL_STATS_REGS__SET(reg);
4462     CPS_UncachedWrite32(CEDI_RegAddr(network_control), reg);
4463     return 0;
4464 }
4465 
emacTakeSnapshot(void * pD)4466 uint32_t emacTakeSnapshot(void *pD)
4467 {
4468     uint32_t reg;
4469 
4470     if (pD==NULL) return EINVAL;
4471     if (CEDI_PdVar(hwCfg).no_snapshot || CEDI_PdVar(hwCfg).no_stats)
4472         return ENOTSUP;
4473 
4474     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
4475     EMAC_REGS__NETWORK_CONTROL__STATS_TAKE_SNAP__SET(reg);
4476     CPS_UncachedWrite32(CEDI_RegAddr(network_control), reg);
4477     return 0;
4478 }
4479 
emacSetReadSnapshot(void * pD,uint8_t enable)4480 uint32_t emacSetReadSnapshot(void *pD, uint8_t enable)
4481 {
4482     uint32_t reg;
4483 
4484     if (pD==NULL) return EINVAL;
4485     if (enable>1) return EINVAL;
4486     if (CEDI_PdVar(hwCfg).no_snapshot || CEDI_PdVar(hwCfg).no_stats)
4487         return ENOTSUP;
4488 
4489     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
4490     if (enable)
4491         EMAC_REGS__NETWORK_CONTROL__STATS_READ_SNAP__SET(reg);
4492     else
4493         EMAC_REGS__NETWORK_CONTROL__STATS_READ_SNAP__CLR(reg);
4494     CPS_UncachedWrite32(CEDI_RegAddr(network_control), reg);
4495     return 0;
4496 }
4497 
emacGetReadSnapshot(void * pD,uint8_t * enable)4498 uint32_t emacGetReadSnapshot(void *pD, uint8_t *enable)
4499 {
4500     if ((pD==NULL)||(enable==NULL))
4501         return EINVAL;
4502 
4503     if (CEDI_PdVar(hwCfg).no_snapshot || CEDI_PdVar(hwCfg).no_stats)
4504         return ENOTSUP;
4505 
4506     *enable = EMAC_REGS__NETWORK_CONTROL__STATS_READ_SNAP__READ(
4507             CPS_UncachedRead32(CEDI_RegAddr(network_control)));
4508     return 0;
4509 }
4510 
4511 /************************ WakeOnLAN/EEE Support ******************************/
4512 
emacSetWakeOnLanReg(void * pD,CEDI_WakeOnLanReg * regVals)4513 uint32_t emacSetWakeOnLanReg(void *pD, CEDI_WakeOnLanReg *regVals)
4514 {
4515     uint32_t reg = 0;
4516 
4517     if ((pD==NULL) || (regVals==NULL) || (regVals->magPktEn>1) ||
4518       (regVals->arpEn>1) || (regVals->specAd1En>1) || (regVals->multiHashEn>1))
4519         return EINVAL;
4520 
4521     EMAC_REGS__WOL_REGISTER__ADDR__MODIFY(reg, regVals->wolReqAddr);
4522     if (regVals->magPktEn)
4523         EMAC_REGS__WOL_REGISTER__WOL_MASK_0__SET(reg);
4524     if (regVals->arpEn)
4525         EMAC_REGS__WOL_REGISTER__WOL_MASK_1__SET(reg);
4526     if (regVals->specAd1En)
4527         EMAC_REGS__WOL_REGISTER__WOL_MASK_2__SET(reg);
4528     if (regVals->multiHashEn)
4529         EMAC_REGS__WOL_REGISTER__WOL_MASK_3__SET(reg);
4530     CPS_UncachedWrite32(CEDI_RegAddr(wol_register), reg);
4531 
4532     return 0;
4533 }
4534 
emacGetWakeOnLanReg(void * pD,CEDI_WakeOnLanReg * regVals)4535 uint32_t emacGetWakeOnLanReg(void *pD, CEDI_WakeOnLanReg *regVals)
4536 {
4537     uint32_t reg = 0;
4538 
4539     if ((pD==NULL) || (regVals==NULL))
4540         return EINVAL;
4541 
4542     reg = CPS_UncachedRead32(CEDI_RegAddr(wol_register));
4543     regVals->wolReqAddr = EMAC_REGS__WOL_REGISTER__ADDR__READ(reg);
4544     regVals->magPktEn = EMAC_REGS__WOL_REGISTER__WOL_MASK_0__READ(reg);
4545     regVals->arpEn = EMAC_REGS__WOL_REGISTER__WOL_MASK_1__READ(reg);
4546     regVals->specAd1En = EMAC_REGS__WOL_REGISTER__WOL_MASK_2__READ(reg);
4547     regVals->multiHashEn = EMAC_REGS__WOL_REGISTER__WOL_MASK_3__READ(reg);
4548 
4549     return 0;
4550 }
4551 
emacSetLpiTxEnable(void * pD,uint8_t enable)4552 uint32_t emacSetLpiTxEnable(void *pD, uint8_t enable)
4553 {
4554     uint32_t reg;
4555     if (pD==NULL) return EINVAL;
4556     if (enable>1) return EINVAL;
4557     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
4558     if (enable)
4559         EMAC_REGS__NETWORK_CONTROL__TX_LPI_EN__SET(reg);
4560     else
4561         EMAC_REGS__NETWORK_CONTROL__TX_LPI_EN__CLR(reg);
4562     CPS_UncachedWrite32(CEDI_RegAddr(network_control), reg);
4563     return 0;
4564 }
4565 
emacGetLpiTxEnable(void * pD,uint8_t * enable)4566 uint32_t emacGetLpiTxEnable(void *pD, uint8_t *enable)
4567 {
4568     if ((pD==NULL)||(enable==NULL))
4569       return EINVAL;
4570 
4571     *enable = EMAC_REGS__NETWORK_CONTROL__TX_LPI_EN__READ(
4572             CPS_UncachedRead32(CEDI_RegAddr(network_control)));
4573     return 0;
4574 }
4575 
emacGetLpiStats(void * pD,CEDI_LpiStats * lpiStats)4576 uint32_t emacGetLpiStats(void *pD, CEDI_LpiStats *lpiStats)
4577 {
4578     if ((pD==NULL) || (lpiStats==NULL))
4579       return EINVAL;
4580 
4581     lpiStats->rxLpiTrans = EMAC_REGS__RX_LPI__COUNT__READ(
4582             CPS_UncachedRead32(CEDI_RegAddr(rx_lpi)));
4583     lpiStats->rxLpiTime = EMAC_REGS__RX_LPI_TIME__LPI_TIME__READ(
4584             CPS_UncachedRead32(CEDI_RegAddr(rx_lpi_time)));
4585     lpiStats->txLpiTrans = EMAC_REGS__TX_LPI__COUNT__READ(
4586             CPS_UncachedRead32(CEDI_RegAddr(tx_lpi)));
4587     lpiStats->txLpiTime = EMAC_REGS__TX_LPI_TIME__LPI_TIME__READ(
4588             CPS_UncachedRead32(CEDI_RegAddr(tx_lpi_time)));
4589     return 0;
4590 }
4591 
4592 /**************************** Design Config **********************************/
4593 
emacGetDesignConfig(void * pD,CEDI_DesignCfg * hwCfg)4594 uint32_t emacGetDesignConfig(void *pD, CEDI_DesignCfg *hwCfg)
4595 {
4596     if ((pD==NULL) || (hwCfg==NULL))
4597         return EINVAL;
4598 
4599     /* Copy h/w config into user-supplied struct */
4600     *hwCfg = CEDI_PdVar(hwCfg);
4601     return 0;
4602 }
4603 
4604 /**************************** Debug Functionality ****************************/
4605 
emacSetWriteStatsEnable(void * pD,uint8_t enable)4606 uint32_t emacSetWriteStatsEnable(void *pD, uint8_t enable)
4607 {
4608     uint32_t reg;
4609     if (pD==NULL) return EINVAL;
4610     if (enable>1) return EINVAL;
4611     if (CEDI_PdVar(hwCfg).no_stats)
4612         return EINVAL;
4613 
4614     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
4615     if (enable)
4616         EMAC_REGS__NETWORK_CONTROL__STATS_WRITE_EN__SET(reg);
4617     else
4618         EMAC_REGS__NETWORK_CONTROL__STATS_WRITE_EN__CLR(reg);
4619     CPS_UncachedWrite32(CEDI_RegAddr(network_control), reg);
4620     return 0;
4621 }
4622 
emacGetWriteStatsEnable(void * pD,uint8_t * enable)4623 uint32_t emacGetWriteStatsEnable(void *pD, uint8_t *enable)
4624 {
4625     uint32_t reg;
4626     if ((pD==NULL)||(enable==NULL))
4627       return EINVAL;
4628 
4629     if (CEDI_PdVar(hwCfg).no_stats)
4630         return EINVAL;
4631     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
4632     *enable = EMAC_REGS__NETWORK_CONTROL__STATS_WRITE_EN__READ(reg);
4633     return 0;
4634 }
4635 
emacIncStatsRegs(void * pD)4636 uint32_t emacIncStatsRegs(void *pD)
4637 {
4638     uint32_t reg;
4639 
4640     if (pD==NULL) return EINVAL;
4641     if (CEDI_PdVar(hwCfg).no_stats)
4642         return EINVAL;
4643     reg = CPS_UncachedRead32(CEDI_RegAddr(network_control));
4644     EMAC_REGS__NETWORK_CONTROL__INC_ALL_STATS_REGS__SET(reg);
4645     CPS_UncachedWrite32(CEDI_RegAddr(network_control), reg);
4646     return 0;
4647 }
4648 
emacSetRxBackPressure(void * pD,uint8_t enable)4649 void emacSetRxBackPressure(void *pD, uint8_t enable)
4650 {
4651     uint32_t ncr;
4652     if (pD==NULL) return;
4653     if (enable>1) return;
4654     ncr = CPS_UncachedRead32(CEDI_RegAddr(network_control));
4655     if (enable)
4656         EMAC_REGS__NETWORK_CONTROL__BACK_PRESSURE__SET(ncr);
4657     else
4658         EMAC_REGS__NETWORK_CONTROL__BACK_PRESSURE__CLR(ncr);
4659     CPS_UncachedWrite32(CEDI_RegAddr(network_control), ncr);
4660 }
4661 
emacGetRxBackPressure(void * pD,uint8_t * enable)4662 uint32_t emacGetRxBackPressure(void *pD, uint8_t *enable)
4663 {
4664     if ((pD==NULL)||(enable==NULL))
4665       return EINVAL;
4666     *enable= EMAC_REGS__NETWORK_CONTROL__BACK_PRESSURE__READ(
4667             CPS_UncachedRead32(CEDI_RegAddr(network_control)));
4668 
4669     return 0;
4670 }
4671 
emacSetCollisionTest(void * pD,uint8_t enable)4672 uint32_t emacSetCollisionTest(void *pD, uint8_t enable)
4673 {
4674     uint32_t reg;
4675     if (pD==NULL) return EINVAL;
4676     if (enable>1) return EINVAL;
4677     if (CEDI_PdVar(hwCfg).no_pcs)
4678         return ENOTSUP;
4679     reg = CPS_UncachedRead32(CEDI_RegAddr(pcs_control));
4680     if (enable)
4681         EMAC_REGS__PCS_CONTROL__COLLISION_TEST__SET(reg);
4682     else
4683         EMAC_REGS__PCS_CONTROL__COLLISION_TEST__CLR(reg);
4684     CPS_UncachedWrite32(CEDI_RegAddr(pcs_control), reg);
4685     return 0;
4686 }
4687 
emacGetCollisionTest(void * pD,uint8_t * enable)4688 uint32_t emacGetCollisionTest(void *pD, uint8_t *enable)
4689 {
4690     uint32_t reg;
4691     if ((pD==NULL)||(enable==NULL))
4692         return EINVAL;
4693 
4694     if (CEDI_PdVar(hwCfg).no_pcs || (enable==NULL))
4695         return ENOTSUP;
4696     reg = CPS_UncachedRead32(CEDI_RegAddr(pcs_control));
4697     *enable = EMAC_REGS__PCS_CONTROL__COLLISION_TEST__READ(reg);
4698     return 0;
4699 }
4700 
emacSetRetryTest(void * pD,uint8_t enable)4701 void emacSetRetryTest(void *pD, uint8_t enable)
4702 {
4703     uint32_t reg;
4704     if (pD==NULL) return;
4705     if (enable>1) return;
4706     reg = CPS_UncachedRead32(CEDI_RegAddr(network_config));
4707     if (enable)
4708         EMAC_REGS__NETWORK_CONFIG__RETRY_TEST__SET(reg);
4709     else
4710         EMAC_REGS__NETWORK_CONFIG__RETRY_TEST__CLR(reg);
4711     CPS_UncachedWrite32(CEDI_RegAddr(network_config), reg);
4712 }
4713 
emacGetRetryTest(void * pD,uint8_t * enable)4714 uint32_t emacGetRetryTest(void *pD, uint8_t *enable)
4715 {
4716     if ((pD==NULL)||(enable==NULL))
4717       return EINVAL;
4718     *enable= EMAC_REGS__NETWORK_CONFIG__RETRY_TEST__READ(
4719             CPS_UncachedRead32(CEDI_RegAddr(network_config)));
4720 
4721     return 0;
4722 }
4723 
emacWriteUserOutputs(void * pD,uint16_t outVal)4724 uint32_t emacWriteUserOutputs(void *pD, uint16_t outVal)
4725 {
4726     uint32_t tmp;
4727     if (pD==NULL) return EINVAL;
4728     if (0==CEDI_PdVar(hwCfg).user_io)
4729         return ENOTSUP;
4730 
4731     tmp = 0;
4732     EMAC_REGS__USER_IO_REGISTER__USER_PROGRAMMABLE_OUTPUTS__MODIFY(
4733             tmp, outVal);
4734     CPS_UncachedWrite32(CEDI_RegAddr(user_io_register), tmp);
4735     return 0;
4736 }
4737 
emacReadUserOutputs(void * pD,uint16_t * outVal)4738 uint32_t emacReadUserOutputs(void *pD, uint16_t *outVal)
4739 {
4740     uint32_t reg;
4741     if ((pD==NULL) || (outVal==NULL))
4742         return EINVAL;
4743     if (0==CEDI_PdVar(hwCfg).user_io)
4744         return ENOTSUP;
4745 
4746     reg = CPS_UncachedRead32(CEDI_RegAddr(user_io_register));
4747     *outVal = EMAC_REGS__USER_IO_REGISTER__USER_PROGRAMMABLE_OUTPUTS__READ(reg);
4748     return 0;
4749 }
4750 
emacSetUserOutPin(void * pD,uint8_t pin,uint8_t state)4751 uint32_t emacSetUserOutPin(void *pD, uint8_t pin, uint8_t state)
4752 {
4753     uint32_t reg, val;
4754     if (pD==NULL) return EINVAL;
4755     if (0==CEDI_PdVar(hwCfg).user_io)
4756         return ENOTSUP;
4757     if (pin>=CEDI_PdVar(hwCfg).user_out_width)
4758         return EINVAL;
4759 
4760     reg = CPS_UncachedRead32(CEDI_RegAddr(user_io_register));
4761     val = EMAC_REGS__USER_IO_REGISTER__USER_PROGRAMMABLE_OUTPUTS__READ(reg);
4762     if (state) {
4763         val |= (1<<pin);
4764     }
4765     else {
4766         val &= ~(1<<pin);
4767     }
4768     EMAC_REGS__USER_IO_REGISTER__USER_PROGRAMMABLE_OUTPUTS__MODIFY(
4769             reg, val);
4770     CPS_UncachedWrite32(CEDI_RegAddr(user_io_register), reg);
4771     return 0;
4772 }
4773 
emacReadUserInputs(void * pD,uint16_t * inVal)4774 uint32_t emacReadUserInputs(void *pD, uint16_t *inVal)
4775 {
4776     uint32_t reg;
4777     if ((pD==NULL) || (inVal==NULL))
4778         return EINVAL;
4779     if (0==CEDI_PdVar(hwCfg).user_io)
4780         return ENOTSUP;
4781 
4782     reg = CPS_UncachedRead32(CEDI_RegAddr(user_io_register));
4783     *inVal = EMAC_REGS__USER_IO_REGISTER__USER_PROGRAMMABLE_INPUTS__READ(reg);
4784     return 0;
4785 }
4786 
emacGetUserInPin(void * pD,uint8_t pin,uint8_t * state)4787 uint32_t emacGetUserInPin(void *pD, uint8_t pin, uint8_t *state)
4788 {
4789     uint32_t reg, val;
4790     if ((pD==NULL) || (state==NULL))
4791         return EINVAL;
4792     if (0==CEDI_PdVar(hwCfg).user_io)
4793         return ENOTSUP;
4794     if (pin>=CEDI_PdVar(hwCfg).user_in_width)
4795         return EINVAL;
4796 
4797     reg = CPS_UncachedRead32(CEDI_RegAddr(user_io_register));
4798     val = EMAC_REGS__USER_IO_REGISTER__USER_PROGRAMMABLE_INPUTS__READ(reg);
4799     *state = (val & (1<<pin))?1:0;
4800     return 0;
4801 }
4802 
emacGetMdioInState(void * pD,uint8_t * state)4803 uint32_t emacGetMdioInState(void *pD, uint8_t *state)
4804 {
4805     if ((pD==NULL)||(state==NULL))
4806       return EINVAL;
4807     *state= EMAC_REGS__NETWORK_STATUS__MDIO_IN__READ(
4808             CPS_UncachedRead32(CEDI_RegAddr(network_status)));
4809 
4810     return 0;
4811 }
4812 
emacReadReg(void * pD,uint32_t offs,uint32_t * data)4813 uint32_t emacReadReg(void *pD, uint32_t offs, uint32_t *data)
4814 {
4815     if ((pD==NULL) || (data==NULL) || (offs>=sizeof(struct emac_regs)))
4816         return EINVAL;
4817 
4818     *data = CPS_UncachedRead32((uint32_t *)(CEDI_PdVar(cfg).regBase + offs));
4819     return 0;
4820 }
4821 
emacWriteReg(void * pD,uint32_t offs,uint32_t data)4822 uint32_t emacWriteReg(void *pD, uint32_t offs, uint32_t data)
4823 {
4824     if ((pD==NULL) || (offs>=sizeof(struct emac_regs)))
4825         return EINVAL;
4826 
4827     CPS_UncachedWrite32((uint32_t *)(CEDI_PdVar(cfg).regBase + offs), data);
4828     return 0;
4829 }
4830 
4831 
4832 CEDI_OBJ EmacDrv = {
4833     emacProbe,               // probe
4834     emacInit,                 // init
4835     emacDestroy,             // destroy
4836     emacStart,               // start
4837     emacStop,                // stop
4838     emacIsr,                 // isr
4839     emacSetEventEnable,
4840     emacGetEventEnable,
4841     emacSetIntrptModerate,
4842     emacGetIntrptModerate,
4843     emacSetIfSpeed,
4844     emacGetIfSpeed,
4845     emacSetJumboFramesRx,
4846     emacGetJumboFramesRx,
4847     emacSetJumboFrameRxMaxLen,
4848     emacGetJumboFrameRxMaxLen,
4849     emacSetUniDirEnable,
4850     emacGetUniDirEnable,
4851     emacSetTxChecksumOffload,
4852     emacGetTxChecksumOffload,
4853     emacSetRxBufOffset,
4854     emacGetRxBufOffset,
4855     emacSet1536ByteFramesRx,
4856     emacGet1536ByteFramesRx,
4857     emacSetRxChecksumOffload,
4858     emacGetRxChecksumOffload,
4859     emacSetFcsRemove,
4860     emacGetFcsRemove,
4861     emacSetTxPartialStFwd,
4862     emacGetTxPartialStFwd,
4863     emacSetRxPartialStFwd,
4864     emacGetRxPartialStFwd,
4865     emacSetRxDmaDataAddrMask,
4866     emacGetRxDmaDataAddrMask,
4867     emacSetRxBadPreamble,
4868     emacGetRxBadPreamble,
4869     emacSetFullDuplex,
4870     emacGetFullDuplex,
4871     emacSetIgnoreFcsRx,
4872     emacGetIgnoreFcsRx,
4873     emacSetRxHalfDuplexInTx,
4874     emacGetRxHalfDuplexInTx,
4875     emacGetIfCapabilities,
4876     emacSetLoopback,
4877     emacGetLoopback,
4878 
4879     emacCalcMaxTxFrameSize,
4880     emacQueueTxBuf,
4881     emacQTxBuf,
4882     emacDeQTxBuf,
4883     emacTxDescFree,
4884     emacFreeTxDesc,
4885     emacGetTxDescStat,
4886     emacGetTxDescSize,
4887     emacResetTxQ,
4888     emacStartTx,
4889     emacStopTx,
4890     emacAbortTx,
4891     emacTransmitting,
4892     emacEnableTx,
4893     emacGetTxEnabled,
4894     emacGetTxStatus,
4895     emacClearTxStatus,
4896     emacEnableCbs,
4897     emacDisableCbs,
4898     emacGetCbsQSetting,
4899     emacSetIpgStretch,
4900     emacGetIpgStretch,
4901 
4902     emacCalcMaxRxFrameSize,
4903     emacAddRxBuf,
4904     emacNumRxBufs,
4905     emacNumRxUsed,
4906     emacReadRxBuf,
4907     emacGetRxDescStat,
4908     emacGetRxDescSize,
4909     emacRxEnabled,
4910     emacEnableRx,
4911     emacDisableRx,
4912     emacRemoveRxBuf,
4913     emacResetRxQ,
4914     emacGetRxStatus,
4915     emacClearRxStatus,
4916     emacSetHdrDataSplit,
4917     emacGetHdrDataSplit,
4918     emacSetRscEnable,
4919     emacGetRscEnable,
4920     emacSetRscClearMask,
4921     emacSetSpecificAddr,
4922     emacGetSpecificAddr,
4923     emacSetSpecificAddr1Mask,
4924     emacGetSpecificAddr1Mask,
4925     emacDisableSpecAddr,
4926     emacSetTypeIdMatch,
4927     emacGetTypeIdMatch,
4928     emacSetUnicastEnable,
4929     emacGetUnicastEnable,
4930     emacSetMulticastEnable,
4931     emacGetMulticastEnable,
4932     emacSetNoBroadcast,
4933     emacGetNoBroadcast,
4934     emacSetVlanOnly,
4935     emacGetVlanOnly,
4936     emacSetStackedVlanReg,
4937     emacGetStackedVlanReg,
4938     emacSetCopyAllFrames,
4939     emacGetCopyAllFrames,
4940     emacSetHashAddr,
4941     emacGetHashAddr,
4942     emacSetLenErrDiscard,
4943     emacGetLenErrDiscard,
4944     emacGetNumScreenRegs,
4945     emacSetType1ScreenReg,
4946     emacGetType1ScreenReg,
4947     emacSetType2ScreenReg,
4948     emacGetType2ScreenReg,
4949     emacSetType2EthertypeReg,
4950     emacGetType2EthertypeReg,
4951     emacSetType2CompareReg,
4952     emacGetType2CompareReg,
4953 
4954     emacSetPauseEnable,
4955     emacGetPauseEnable,
4956     emacTxPauseFrame,
4957     emacTxZeroQPause,
4958     emacGetRxPauseQuantum,
4959     emacSetTxPauseQuantum,
4960     emacGetTxPauseQuantum,
4961     emacSetCopyPauseDisable,
4962     emacGetCopyPauseDisable,
4963     emacSetPfcPriorityBasedPauseRx,
4964     emacGetPfcPriorityBasedPauseRx,
4965     emacTxPfcPriorityBasedPause,
4966     emacSetTxPfcPauseFrameFields,
4967     emacGetTxPfcPauseFrameFields,
4968     emacSetEnableMultiPfcPauseQuantum,
4969     emacGetEnableMultiPfcPauseQuantum,
4970 
4971     emacSetUnicastPtpDetect,
4972     emacGetUnicastPtpDetect,
4973     emacSetPtpRxUnicastIpAddr,
4974     emacGetPtpRxUnicastIpAddr,
4975     emacSetPtpTxUnicastIpAddr,
4976     emacGetPtpTxUnicastIpAddr,
4977     emacSet1588Timer,
4978     emacGet1588Timer,
4979     emacAdjust1588Timer,
4980     emacSet1588TimerInc,
4981     emacGet1588TimerInc,
4982     emacSetTsuTimerCompVal,
4983     emacGetTsuTimerCompVal,
4984     emacGetPtpFrameTxTime,
4985     emacGetPtpFrameRxTime,
4986     emacGetPtpPeerFrameTxTime,
4987     emacGetPtpPeerFrameRxTime,
4988     emacGet1588SyncStrobeTime,
4989     emacSetExtTsuPortEnable,
4990     emacGetExtTsuPortEnable,
4991     emacSet1588OneStepTxSyncEnable,
4992     emacGet1588OneStepTxSyncEnable,
4993     emacSetDescTimeStampMode,
4994     emacGetDescTimeStampMode,
4995     emacSetStoreRxTimeStamp,
4996     emacGetStoreRxTimeStamp,
4997 
4998     emacResetPcs,
4999     emacGetPcsReady,
5000     emacStartAutoNegotiation,
5001     emacSetAutoNegEnable,
5002     emacGetAutoNegEnable,
5003     emacGetLinkStatus,
5004     emacGetAnRemoteFault,
5005     emacGetAnComplete,
5006     emacSetAnAdvPage,
5007     emacGetAnAdvPage,
5008     emacGetLpAbilityPage,
5009     emacGetPageRx,
5010     emacSetNextPageTx,
5011     emacGetNextPageTx,
5012     emacGetLpNextPage,
5013 
5014     emacGetPhyId,
5015     emacSetMdioEnable,
5016     emacGetMdioEnable,
5017     emacPhyStartMdioWrite,
5018     emacPhyStartMdioRead,
5019     emacGetMdioReadData,
5020     emacGetMdioIdle,
5021 
5022     emacReadStats,
5023     emacClearStats,
5024     emacTakeSnapshot,
5025     emacSetReadSnapshot,
5026     emacGetReadSnapshot,
5027     emacSetWakeOnLanReg,
5028     emacGetWakeOnLanReg,
5029     emacSetLpiTxEnable,
5030     emacGetLpiTxEnable,
5031     emacGetLpiStats,
5032     emacGetDesignConfig,
5033 
5034     emacSetWriteStatsEnable,
5035     emacGetWriteStatsEnable,
5036     emacIncStatsRegs,
5037     emacSetRxBackPressure,
5038     emacGetRxBackPressure,
5039     emacSetCollisionTest,
5040     emacGetCollisionTest,
5041     emacSetRetryTest,
5042     emacGetRetryTest,
5043     emacWriteUserOutputs,
5044     emacReadUserOutputs,
5045     emacSetUserOutPin,
5046     emacReadUserInputs,
5047     emacGetUserInPin,
5048     emacGetMdioInState,
5049     emacReadReg,
5050     emacWriteReg,
5051 };
5052 
CEDI_GetInstance(void)5053 CEDI_OBJ *CEDI_GetInstance(void) {
5054     return &EmacDrv;
5055 }
5056 
5057 #ifdef __cplusplus
5058 }
5059 #endif
5060 
5061 #endif /* CY_IP_MXETH */
5062 
5063 
5064