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