1 /*******************************************************************************
2 * Copyright 2020 Microchip Corporation.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * PolarFire SoC 10/100/1000 Mbps Ethernet MAC bare metal software driver implementation.
7 *
8 */
9 #include <stdint.h>
10 #include <stdbool.h>
11 #include <stddef.h>
12 #include <string.h>
13 #include "mpfs_hal/mss_hal.h"
14
15 #if defined(MSS_MAC_PHY_HW_RESET) || defined(MSS_MAC_PHY_HW_SRESET)
16 #include "drivers/mss_gpio/mss_gpio.h"
17 #endif
18
19 #include "drivers/mss_ethernet_mac/mss_ethernet_registers.h"
20 #include "drivers/mss_ethernet_mac/mss_ethernet_mac_regs.h"
21 #include "drivers/mss_ethernet_mac/mss_ethernet_mac_sw_cfg.h"
22
23 #if defined(USING_FREERTOS)
24 #include "FreeRTOS.h"
25 #endif
26
27 #include "drivers/mss_ethernet_mac/mss_ethernet_mac.h"
28 #include "drivers/mss_ethernet_mac/phy.h"
29 #include "hal/hal.h"
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 #if (defined(MSS_MAC_VSC8662_NWC_25) || defined(MSS_MAC_VSC8662_NWC_125))
36
37 extern PLL_TypeDef *MSS_SCB_MSS_PLL;
38 extern PLL_TypeDef *MSS_SCB_DDR_PLL;
39 extern PLL_TypeDef *MSS_SCB_SGMII_PLL;
40 extern IOSCB_CFM_MSS *MSS_SCB_CFM_MSS_MUX;
41 extern IOSCB_CFM_SGMII *MSS_SCB_CFM_SGMII_MUX;
42 extern IOSCB_IO_CALIB_STRUCT *IOSCB_IO_CALIB_SGMII;
43 extern IOSCB_IO_CALIB_STRUCT *IOSCB_IO_CALIB_DDR;
44
45 #endif
46
47 /**************************************************************************/
48 /* Preprocessor Macros */
49 /**************************************************************************/
50
51 #define NULL_POINTER (void *)0U
52
53 #if !defined(NDEBUG)
54 #define IS_STATE(x) ( ((x) == MSS_MAC_ENABLE) || ((x) == MSS_MAC_DISABLE) )
55
56 #endif /* NDEBUG */
57
58 #if defined(MSS_MAC_64_BIT_ADDRESS_MODE)
59 #define IS_WORD_ALIGNED(x) ((uint64_t)0U == ((uint64_t)(x) & (uint64_t)3U))
60 #else
61 #define IS_WORD_ALIGNED(x) ((uint32_t)0U == ((uint32_t)(x) & (uint32_t)3U))
62 #endif
63
64 #define BMSR_AUTO_NEGOTIATION_COMPLETE (0x0020U)
65
66 #define INVALID_INDEX (0xFFFFFFFFU)
67
68 #define PHY_ADDRESS_MIN (0U)
69 #define PHY_ADDRESS_MAX (31U)
70
71 /*
72 * Defines for determining DMA descriptor sizes
73 */
74 #if 0
75 #if !defined(MSS_MAC_TIME_STAMPED_MODE)
76 #define MSS_MAC_TIME_STAMPED_MODE 0 /* Default to non time stamped descriptors */
77 #endif
78 #endif
79
80 #if defined(TARGET_ALOE)
81 #define MSS_MAC0_BASE (0x10090000U);
82 #elif defined(TARGET_G5_SOC)
83 #define MSS_MAC0_BASE (0x20110000U)
84 #define MSS_EMAC0_BASE (0x20111000U)
85 #define MSS_MAC1_BASE (0x20112000U)
86 #define MSS_EMAC1_BASE (0x20113000U)
87
88 #define MSS_MAC0_BASE_HI (0x28110000U)
89 #define MSS_EMAC0_BASE_HI (0x28111000U)
90 #define MSS_MAC1_BASE_HI (0x28112000U)
91 #define MSS_EMAC1_BASE_HI (0x28113000U)
92
93 #define MSS_MAC_GEM0_ABP_BIT (0x00010000U)
94 #define MSS_MAC_GEM1_ABP_BIT (0x00020000U)
95 #else
96 #warning "No target platform defined for MSS Ethernet MAC"
97 #endif
98
99 /**************************************************************************/
100 /* Private variables */
101 /**************************************************************************/
102
103 #if defined(TARGET_ALOE)
104 static volatile uint32_t *GEMGXL_tx_clk_sel = (volatile uint32_t *)0x100A0000UL;
105 static volatile uint32_t *GEMGXL_speed_mode = (volatile uint32_t *)0x100A0020UL;
106 #endif
107
108 /**************************************************************************
109 * Global variables *
110 * *
111 * Note: there are two instances of the GMAC for G5 SOC and each has a *
112 * primary MAC and a secondary eMAC for time sensative traffic. The FU540 *
113 * device on the Aloe board has a single primary MAC. *
114 **************************************************************************/
115
116 #if defined(TARGET_G5_SOC)
117 mss_mac_instance_t g_mac0;
118 mss_mac_instance_t g_mac1;
119 mss_mac_instance_t g_emac0;
120 mss_mac_instance_t g_emac1;
121 #endif
122
123 #if defined(MSS_MAC_USE_DDR)
124 #if MSS_MAC_USE_DDR == MSS_MAC_MEM_DDR
125 uint8_t *g_mss_mac_ddr_ptr = (uint8_t *)0xC0000000LLU;
126 #elif MSS_MAC_USE_DDR == MSS_MAC_MEM_FIC0
127 uint8_t *g_mss_mac_ddr_ptr = (uint8_t *)0x60000000LLU;
128 #elif MSS_MAC_USE_DDR == MSS_MAC_MEM_FIC1
129 uint8_t *g_mss_mac_ddr_ptr = (uint8_t *)0xE0000000LLU;
130 #elif MSS_MAC_USE_DDR == MSS_MAC_MEM_CRYPTO
131 uint8_t *g_mss_mac_ddr_ptr = (uint8_t *)0x22002000LLU;
132 #else
133 #error "bad memory region defined"
134 #endif
135 #endif
136
137
138 #if defined(TARGET_ALOE)
139 mss_mac_instance_t g_mac0;
140 #endif
141
142
143 /**************************************************************************/
144 /* Private Functions */
145 /**************************************************************************/
146 static void mac_reset(void);
147 static void config_mac_hw(mss_mac_instance_t *this_mac, const mss_mac_cfg_t * cfg);
148 static void tx_desc_ring_init(mss_mac_instance_t *this_mac);
149 static void rx_desc_ring_init(mss_mac_instance_t *this_mac);
150 static void assign_station_addr(mss_mac_instance_t *this_mac, const uint8_t mac_addr[MSS_MAC_MAC_LEN]);
151 static void generic_mac_irq_handler(mss_mac_instance_t *this_mac, uint64_t queue_no);
152 static void rxpkt_handler(mss_mac_instance_t *this_mac, uint64_t queue_no);
153 static void txpkt_handler(mss_mac_instance_t *this_mac, uint64_t queue_no);
154 static void update_mac_cfg(const mss_mac_instance_t *this_mac);
155 static uint8_t probe_phy(const mss_mac_instance_t *this_mac);
156 static void instances_init(mss_mac_instance_t *this_mac, mss_mac_cfg_t *cfg);
157
158 static void msgmii_init(const mss_mac_instance_t *this_mac);
159
160 /* PMCS: Made non static for now for test program use... */
161 void msgmii_autonegotiate(const mss_mac_instance_t *this_mac);
162
163 /**************************************************************************/
164 /* Public Functions */
165 /**************************************************************************/
166 /******************************************************************************
167 * See mss_ethernet_mac.h for details of how to use this function.
168 */
169 void
MSS_MAC_init(mss_mac_instance_t * this_mac,mss_mac_cfg_t * cfg)170 MSS_MAC_init
171 (
172 mss_mac_instance_t *this_mac,
173 mss_mac_cfg_t *cfg
174 )
175 {
176 int32_t queue_no;
177 ASSERT(cfg != NULL_POINTER);
178 #if defined(TARGET_ALOE)
179 ASSERT(this_mac == &g_mac0);
180
181 instances_init(this_mac, cfg);
182
183 if((cfg != NULL_POINTER) && (this_mac == &g_mac0))
184 #endif
185 #if defined(TARGET_G5_SOC)
186 ASSERT((this_mac == &g_mac0) || (this_mac == &g_mac1) || (this_mac == &g_emac0) || (this_mac == &g_emac1));
187 instances_init(this_mac, cfg);
188
189 /*
190 * Always reset GEM if the pMAC is selected for init but not if eMAC
191 * The pMAC should always be initialised first followed by the eMAC so this
192 * is ok...
193 */
194 if(this_mac == &g_mac0)
195 {
196 SYSREG->SUBBLK_CLOCK_CR |= (uint32_t)2U;
197 /* Reset MAC */
198 SYSREG->SOFT_RESET_CR |= (uint32_t)2U;
199 {
200 volatile int64_t index;
201
202 index = 0;
203 while(1000 != index) /* Don't know if necessary, but delay a bit before de-asserting reset... */
204 {
205 index++;
206 }
207 }
208 /* Take MAC out of reset. */
209 SYSREG->SOFT_RESET_CR &= (uint32_t)~2U;
210 }
211
212 if(this_mac == &g_mac1)
213 {
214 SYSREG->SUBBLK_CLOCK_CR |= (uint32_t)4U;
215 /* Reset MAC */
216 SYSREG->SOFT_RESET_CR |= (uint32_t)4U;
217 {
218 volatile int64_t index;
219
220 index = 0;
221 while(1000 != index) /* Don't know if necessary, but delay a bit before de-asserting reset... */
222 {
223 index++;
224 }
225 }
226 /* Take MAC out of reset. */
227 SYSREG->SOFT_RESET_CR &= (uint32_t)~4U;
228 }
229
230 /*
231 * Disable all queues.
232 *
233 * In theory you only need to write 1UL to the queue pointers but in
234 * practice doing this results in spurious accesses to addresses in the
235 * lower 4K on the AXI bus when enabling a queue which can trigger hresp
236 * errors. To stop this we use real addresses with the lsb set instead.
237 */
238 if(0U == this_mac->is_emac)
239 {
240 *this_mac->queue[0].receive_q_ptr = (uint32_t)((uint64_t)this_mac->queue[0].rx_desc_tab) | 1U;
241 *this_mac->queue[1].receive_q_ptr = (uint32_t)((uint64_t)this_mac->queue[1].rx_desc_tab) | 1U;
242 *this_mac->queue[2].receive_q_ptr = (uint32_t)((uint64_t)this_mac->queue[2].rx_desc_tab) | 1U;
243 *this_mac->queue[3].receive_q_ptr = (uint32_t)((uint64_t)this_mac->queue[3].rx_desc_tab) | 1U;
244 *this_mac->queue[0].transmit_q_ptr = (uint32_t)((uint64_t)this_mac->queue[0].tx_desc_tab) | 1U;
245 *this_mac->queue[1].transmit_q_ptr = (uint32_t)((uint64_t)this_mac->queue[1].tx_desc_tab) | 1U;
246 *this_mac->queue[2].transmit_q_ptr = (uint32_t)((uint64_t)this_mac->queue[2].tx_desc_tab) | 1U;
247 *this_mac->queue[3].transmit_q_ptr = (uint32_t)((uint64_t)this_mac->queue[3].tx_desc_tab) | 1U;
248 }
249 else
250 {
251 *this_mac->queue[0].receive_q_ptr = (uint32_t)((uint64_t)this_mac->queue[0].rx_desc_tab) | 1U;
252 *this_mac->queue[0].transmit_q_ptr = (uint32_t)((uint64_t)this_mac->queue[0].tx_desc_tab) | 1U;
253 }
254
255 if(0U == this_mac->is_emac)
256 {
257 this_mac->mac_base->USER_IO = cfg->tsu_clock_select & 1U;
258 }
259
260 if((cfg != NULL_POINTER) && ((this_mac == &g_mac0) || (this_mac == &g_mac1) || (this_mac == &g_emac0) || (this_mac == &g_emac1)))
261 #endif /* defined(TARGET_G5_SOC) */
262 {
263 this_mac->phy_addr = cfg->phy_addr;
264 this_mac->pcs_phy_addr = cfg->pcs_phy_addr;
265 this_mac->interface_type = cfg->interface_type;
266 this_mac->jumbo_frame_enable = cfg->jumbo_frame_enable;
267 this_mac->phy_type = cfg->phy_type;
268 this_mac->phy_autonegotiate = cfg->phy_autonegotiate;
269 this_mac->phy_mac_autonegotiate = cfg->phy_mac_autonegotiate;
270 this_mac->phy_get_link_status = cfg->phy_get_link_status;
271 this_mac->phy_init = cfg->phy_init;
272 this_mac->phy_set_link_speed = cfg->phy_set_link_speed;
273 this_mac->append_CRC = cfg->append_CRC;
274 #if defined(MSS_MAC_PHY_HW_RESET) || defined(MSS_MAC_PHY_HW_SRESET)
275 this_mac->phy_soft_reset_gpio = cfg->phy_soft_reset_gpio;
276 this_mac->phy_soft_reset_pin = cfg->phy_soft_reset_pin;
277 this_mac->phy_hard_reset_gpio = cfg->phy_hard_reset_gpio;
278 this_mac->phy_hard_reset_pin = cfg->phy_hard_reset_pin;
279 #endif
280 this_mac->phy_controller = cfg->phy_controller;
281 this_mac->speed_mode = cfg->speed_mode;
282 this_mac->speed_duplex_select = cfg->speed_duplex_select;
283 #if MSS_MAC_USE_PHY_DP83867
284 this_mac->phy_extended_read = cfg->phy_extended_read;
285 this_mac->phy_extended_write = cfg->phy_extended_write;
286 #endif
287
288 #if defined(TARGET_G5_SOC)
289 if(0U != cfg->use_local_ints)
290 {
291 __disable_local_irq(this_mac->mac_q_int[0]);
292 if(0U == this_mac->is_emac)
293 {
294 __disable_local_irq(this_mac->mac_q_int[1]);
295 __disable_local_irq(this_mac->mac_q_int[2]);
296 __disable_local_irq(this_mac->mac_q_int[3]);
297 __disable_local_irq(this_mac->mmsl_int);
298 }
299 }
300 else
301 #endif
302 {
303 /*
304 * In the following if an interrupt is set to NoInterrupt_IRQn then
305 * the PLIC will ignore it as interrupt 0 is a dummy one.
306 */
307 PLIC_DisableIRQ(this_mac->mac_q_int[0]);
308 PLIC_SetPriority(this_mac->mac_q_int[0], cfg->queue0_int_priority);
309
310 #if defined(TARGET_G5_SOC)
311 PLIC_DisableIRQ(this_mac->mac_q_int[1]);
312 PLIC_SetPriority(this_mac->mac_q_int[1], cfg->queue1_int_priority);
313 PLIC_DisableIRQ(this_mac->mac_q_int[2]);
314 PLIC_SetPriority(this_mac->mac_q_int[2], cfg->queue2_int_priority);
315 PLIC_DisableIRQ(this_mac->mac_q_int[3]);
316 PLIC_SetPriority(this_mac->mac_q_int[3], cfg->queue3_int_priority);
317 PLIC_DisableIRQ(this_mac->mmsl_int);
318 PLIC_SetPriority(this_mac->mmsl_int, cfg->mmsl_int_priority);
319 #endif
320 }
321 mac_reset();
322
323 config_mac_hw(this_mac, cfg);
324
325 /* Assign MAC station address */
326 assign_station_addr(this_mac, cfg->mac_addr);
327
328 /* Intialize Tx & Rx descriptor rings */
329 tx_desc_ring_init(this_mac);
330 rx_desc_ring_init(this_mac);
331
332 this_mac->rx_discard = 0U; /* Ensure normal RX operation */
333
334 for(queue_no = 0; queue_no < MSS_MAC_QUEUE_COUNT; queue_no++)
335 {
336 /* Initialize Tx descriptors related variables. */
337 this_mac->queue[queue_no].nb_available_tx_desc = MSS_MAC_TX_RING_SIZE;
338
339 /* Initialize Rx descriptors related variables. */
340 this_mac->queue[queue_no].nb_available_rx_desc = MSS_MAC_RX_RING_SIZE;
341 this_mac->queue[queue_no].next_free_rx_desc_index = 0U;
342 this_mac->queue[queue_no].first_rx_desc_index = 0U;
343
344 /* initialize default interrupt handlers */
345 this_mac->queue[queue_no].pckt_tx_callback = (mss_mac_transmit_callback_t)NULL_POINTER;
346 this_mac->queue[queue_no].pckt_rx_callback = (mss_mac_receive_callback_t)NULL_POINTER;
347
348 /* Added these to MAC structure to make them MAC and queue specific... */
349
350 this_mac->queue[queue_no].ingress = 0U;
351 this_mac->queue[queue_no].egress = 0U;
352 this_mac->queue[queue_no].rx_overflow = 0U;
353 this_mac->queue[queue_no].hresp_error = 0U;
354 this_mac->queue[queue_no].rx_restart = 0U;
355 this_mac->queue[queue_no].tx_restart = 0U;
356 this_mac->queue[queue_no].tx_reenable = 0U;
357 }
358 #if 0
359 /* Initialize PHY interface */
360 if(MSS_MAC_AUTO_DETECT_PHY_ADDRESS == cfg->phy_addr)
361 {
362 cfg->phy_addr = probe_phy();
363 }
364 #endif
365 if(0U == this_mac->is_emac) /* Only do the PHY stuff for primary MAC */
366 {
367 if(TBI == this_mac->interface_type)
368 {
369 msgmii_init(this_mac);
370 }
371 #if defined(TARGET_ALOE)
372 this_mac->phy_addr = 0U;
373 #endif
374
375 this_mac->phy_init(this_mac, (uint8_t)this_mac->phy_addr);
376
377 #if (defined(MSS_MAC_VSC8662_NWC_25) || defined(MSS_MAC_VSC8662_NWC_125))
378 /* 0U => configure using scb, 1U => NVMAP reset */
379 pre_configure_sgmii_and_ddr_pll_via_scb(1U);
380 {
381 volatile uint32_t timer_out=0x00000FFFU;
382 while(((MSS_SCB_SGMII_PLL->PLL_CTRL & ((0x01U) << 25U))) == 0U)
383 {
384 #ifdef RENODE_DEBUG
385 break;
386 #endif
387 if (timer_out == 0U)
388 {
389 timer_out--;
390 }
391 }
392 }
393
394 #endif
395 this_mac->phy_set_link_speed(this_mac, this_mac->speed_duplex_select, this_mac->speed_mode);
396 this_mac->phy_autonegotiate(this_mac);
397
398 if(TBI == this_mac->interface_type)
399 {
400 msgmii_autonegotiate(this_mac);
401 }
402 }
403 update_mac_cfg(this_mac);
404
405 /*
406 * Enable TX Packet and TX Packet Bus Error interrupts.
407 * We don't enable the tx underrun interrupt as we only send on demand
408 * and don't need to explicitly note an underrun as that is the "normal"
409 * state for the interface to be in.
410 */
411 /*
412 * Enable RX Packet, RX Packet Overflow and RX Packet Bus Error
413 * interrupts.
414 */
415 if(0U != this_mac->is_emac)
416 {
417 this_mac->emac_base->INT_ENABLE = GEM_RECEIVE_OVERRUN_INT | GEM_TRANSMIT_COMPLETE |
418 GEM_RX_USED_BIT_READ | GEM_RECEIVE_COMPLETE | GEM_RESP_NOT_OK_INT;
419
420 this_mac->emac_base->NETWORK_CONTROL |= GEM_ENABLE_TRANSMIT;
421 this_mac->emac_base->NETWORK_CONTROL |= GEM_TRANSMIT_START;
422
423 }
424 else
425 {
426 for(queue_no = 0; queue_no < MSS_MAC_QUEUE_COUNT; queue_no++)
427 {
428 /* Enable pause related interrupts if pause control is selected */
429 if((MSS_MAC_ENABLE == cfg->rx_flow_ctrl) || (MSS_MAC_ENABLE == cfg->tx_flow_ctrl))
430 {
431 *this_mac->queue[queue_no].int_enable = GEM_RECEIVE_OVERRUN_INT | GEM_TRANSMIT_COMPLETE |
432 GEM_RX_USED_BIT_READ | GEM_RECEIVE_COMPLETE | GEM_RESP_NOT_OK_INT |
433 GEM_PAUSE_FRAME_TRANSMITTED | GEM_PAUSE_TIME_ELAPSED |
434 GEM_PAUSE_FRAME_WITH_NON_0_PAUSE_QUANTUM_RX | GEM_AMBA_ERROR;
435 }
436 else
437 {
438 *this_mac->queue[queue_no].int_enable = GEM_RECEIVE_OVERRUN_INT | GEM_TRANSMIT_COMPLETE |
439 GEM_RX_USED_BIT_READ | GEM_RECEIVE_COMPLETE | GEM_RESP_NOT_OK_INT;
440 }
441
442 #if 0 /* PMCS - set this to 1 if you want to check for un-handled interrupt conditions */
443 *this_mac->queue[queue_no].int_enable |= GEM_PAUSE_FRAME_TRANSMITTED | GEM_PAUSE_TIME_ELAPSED |
444 GEM_PAUSE_FRAME_WITH_NON_0_PAUSE_QUANTUM_RX | GEM_LINK_CHANGE |
445 GEM_TX_LOCKUP_DETECTED | GEM_RX_LOCKUP_DETECTED |
446 GEM_AMBA_ERROR | GEM_RETRY_LIMIT_EXCEEDED_OR_LATE_COLLISION |
447 GEM_TRANSMIT_UNDER_RUN;
448 #endif
449 }
450
451 this_mac->mac_base->NETWORK_CONTROL |= GEM_ENABLE_TRANSMIT;
452 this_mac->mac_base->NETWORK_CONTROL |= GEM_TRANSMIT_START;
453 }
454
455 /*
456 * At this stage, the MSS MAC interrupts are disabled and won't be enabled
457 * until at least one of the FIFOs is configured with a buffer(s) for
458 * data transfer.
459 */
460 }
461
462 this_mac->mac_available = MSS_MAC_AVAILABLE;
463 }
464
465
466 /******************************************************************************
467 * See mss_ethernet_mac.h for details of how to use this function.
468 */
469 void
MSS_MAC_update_hw_address(mss_mac_instance_t * this_mac,const mss_mac_cfg_t * cfg)470 MSS_MAC_update_hw_address
471 (
472 mss_mac_instance_t *this_mac,
473 const mss_mac_cfg_t * cfg
474 )
475 {
476 ASSERT(cfg != NULL_POINTER);
477
478 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
479 {
480 if(cfg != NULL_POINTER)
481 {
482 /* Assign MAC station address */
483 assign_station_addr(this_mac, cfg->mac_addr);
484 }
485 }
486 }
487
488
489 /******************************************************************************
490 *
491 */
update_mac_cfg(const mss_mac_instance_t * this_mac)492 static void update_mac_cfg(const mss_mac_instance_t *this_mac)
493 {
494 mss_mac_speed_t speed;
495 uint8_t fullduplex;
496 uint8_t link_up;
497 uint32_t temp_cr;
498
499 link_up = this_mac->phy_get_link_status(this_mac, &speed, &fullduplex);
500
501 if(link_up != MSS_MAC_LINK_DOWN)
502 {
503 if(0U != this_mac->is_emac)
504 {
505 temp_cr = this_mac->emac_base->NETWORK_CONFIG;
506 }
507 else
508 {
509 temp_cr = this_mac->mac_base->NETWORK_CONFIG;
510 }
511
512 temp_cr &= ~(GEM_GIGABIT_MODE_ENABLE | GEM_SPEED | GEM_FULL_DUPLEX);
513
514 if(MSS_MAC_1000MBPS == speed)
515 {
516 #if defined(TARGET_ALOE)
517 *GEMGXL_tx_clk_sel = (uint32_t)0U;
518 *GEMGXL_speed_mode = (uint32_t)2U;
519 #endif
520 temp_cr |= GEM_GIGABIT_MODE_ENABLE;
521 }
522 else
523 {
524 if(MSS_MAC_100MBPS == speed)
525 {
526 #if defined(TARGET_ALOE)
527 *GEMGXL_tx_clk_sel = (uint32_t)1U;
528 *GEMGXL_speed_mode = (uint32_t)1U;
529 #endif
530 temp_cr |= (uint32_t)GEM_SPEED;
531 }
532 #if defined(TARGET_ALOE)
533 else
534 {
535 *GEMGXL_tx_clk_sel = (uint32_t)1U;
536 *GEMGXL_speed_mode = (uint32_t)0U;
537 }
538 #endif
539 }
540 /* Configure duplex mode */
541 if(MSS_MAC_FULL_DUPLEX == fullduplex)
542 {
543 temp_cr |= GEM_FULL_DUPLEX;
544 }
545
546 if(0U != this_mac->is_emac)
547 {
548 this_mac->emac_base->NETWORK_CONFIG = temp_cr;
549 }
550 else
551 {
552 this_mac->mac_base->NETWORK_CONFIG = temp_cr;
553 }
554 }
555 }
556
557
558 /******************************************************************************
559 * See mss_ethernet_mac.h for details of how to use this function.
560 */
MSS_MAC_get_link_status(const mss_mac_instance_t * this_mac,mss_mac_speed_t * speed,uint8_t * fullduplex)561 uint8_t MSS_MAC_get_link_status
562 (
563 const mss_mac_instance_t *this_mac,
564 mss_mac_speed_t * speed,
565 uint8_t * fullduplex
566 )
567 {
568 /* Todo: These statics will only work for the single MAC Aloe case... */
569 static mss_mac_speed_t previous_speed = INVALID_SPEED;
570 static uint8_t previous_duplex = 0xAAU;
571 mss_mac_speed_t link_speed;
572 uint8_t link_fullduplex;
573 uint8_t link_up;
574
575 link_up = MSS_MAC_LINK_DOWN; /* Default condition in case we are not active yet */
576
577 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
578 {
579 link_up = this_mac->phy_get_link_status(this_mac, &link_speed, &link_fullduplex);
580
581 if(link_up != MSS_MAC_LINK_DOWN)
582 {
583 /*----------------------------------------------------------------------
584 * Update MAC configuration if link characteristics changed.
585 */
586 if((link_speed != previous_speed) || (link_fullduplex != previous_duplex))
587 {
588 uint32_t temp_cr;
589
590 if(0U != this_mac->is_emac)
591 {
592 temp_cr = this_mac->emac_base->NETWORK_CONFIG;
593 }
594 else
595 {
596 temp_cr = this_mac->mac_base->NETWORK_CONFIG;
597 }
598
599 temp_cr &= ~(GEM_GIGABIT_MODE_ENABLE | GEM_SPEED | GEM_FULL_DUPLEX);
600
601 if(MSS_MAC_1000MBPS == link_speed)
602 {
603 #if defined(TARGET_ALOE)
604 *GEMGXL_tx_clk_sel = (uint32_t)0U;
605 *GEMGXL_speed_mode = (uint32_t)2U;
606 #endif
607 temp_cr |= GEM_GIGABIT_MODE_ENABLE;
608 }
609 else
610 {
611 if(MSS_MAC_100MBPS == link_speed)
612 {
613 #if defined(TARGET_ALOE)
614 *GEMGXL_tx_clk_sel = (uint32_t)1U;
615 *GEMGXL_speed_mode = (uint32_t)1U;
616 #endif
617 temp_cr |= (uint32_t)GEM_SPEED;
618 }
619 #if defined(TARGET_ALOE)
620 else
621 {
622 *GEMGXL_tx_clk_sel = (uint32_t)1U;
623 *GEMGXL_speed_mode = (uint32_t)0U;
624 }
625 #endif
626 }
627 /* Configure duplex mode */
628 if(MSS_MAC_FULL_DUPLEX == link_fullduplex)
629 {
630 temp_cr |= GEM_FULL_DUPLEX;
631 }
632
633 if(0U != this_mac->is_emac)
634 {
635 this_mac->emac_base->NETWORK_CONFIG = temp_cr;
636 }
637 else
638 {
639 this_mac->mac_base->NETWORK_CONFIG = temp_cr;
640 }
641 }
642
643 previous_speed = link_speed;
644 previous_duplex = link_fullduplex;
645
646 /*----------------------------------------------------------------------
647 * Return current link speed and duplex mode.
648 */
649 if(speed != NULL_POINTER)
650 {
651 *speed = link_speed;
652 }
653
654 if(fullduplex != NULL_POINTER)
655 {
656 *fullduplex = link_fullduplex;
657 }
658 if(GMII_SGMII == this_mac->interface_type) /* Emulation platform with embedded SGMII link for PHY connection and GMII for MAC connection */
659 {
660 uint16_t phy_reg;
661 uint16_t sgmii_link_up;
662
663 /*
664 * Find out if link is up on SGMII link between GMII core and
665 * external PHY.
666 *
667 * The link status bit latches 0 state until read to record fact
668 * link has failed since last read so you need to read it twice to
669 * get the current status...
670 */
671 phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMSR);
672 phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMSR);
673 sgmii_link_up = phy_reg & BMSR_LSTATUS;
674
675 if(0U == sgmii_link_up)
676 {
677 /* Initiate auto-negotiation on the SGMII link. */
678 phy_reg = MSS_MAC_read_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR);
679 phy_reg |= BMCR_ANENABLE;
680 MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR, phy_reg);
681 phy_reg |= BMCR_ANRESTART;
682 MSS_MAC_write_phy_reg(this_mac, (uint8_t)this_mac->pcs_phy_addr, MII_BMCR, phy_reg);
683 }
684 }
685
686 #if 0 /* TBD old SF2 stuff keep here for now for guidance... */
687 #if ((MSS_MAC_PHY_INTERFACE == SGMII) || (MSS_MAC_PHY_INTERFACE == TBI))
688 #if (MSS_MAC_PHY_INTERFACE == TBI)
689 /*----------------------------------------------------------------------
690 * Make sure SGMII interface link is up. if interface is TBI
691 */
692 #define MDIO_PHY_ADDR SF2_MSGMII_PHY_ADDR
693 #endif /* #if (MSS_MAC_PHY_INTERFACE == TBI) */
694
695 #if (MSS_MAC_PHY_INTERFACE == SGMII)
696 /*----------------------------------------------------------------------
697 * Make sure SGMII/1000baseX interface link is up. if interface is
698 * SGMII/1000baseX
699 */
700 #define MDIO_PHY_ADDR MSS_MAC_INTERFACE_MDIO_ADDR
701 #endif /* #if ((MSS_MAC_PHY_INTERFACE == SGMII) || (MSS_MAC_PHY_INTERFACE == BASEX1000)) */
702
703 {
704 uint16_t phy_reg;
705 uint16_t sgmii_link_up;
706
707 /* Find out if link is up on SGMII link between MAC and external PHY. */
708 phy_reg = MSS_MAC_read_phy_reg(MDIO_PHY_ADDR, MII_BMSR);
709 sgmii_link_up = phy_reg & BMSR_LSTATUS;
710
711 if(0U == sgmii_link_up)
712 {
713 /* Initiate auto-negotiation on the SGMII link. */
714 phy_reg = MSS_MAC_read_phy_reg(MDIO_PHY_ADDR, MII_BMCR);
715 phy_reg |= BMCR_ANENABLE;
716 MSS_MAC_write_phy_reg(MDIO_PHY_ADDR, MII_BMCR, phy_reg);
717 phy_reg |= BMCR_ANRESTART;
718 MSS_MAC_write_phy_reg(MDIO_PHY_ADDR, MII_BMCR, phy_reg);
719 }
720 }
721 #endif
722 #endif
723 }
724 }
725
726 return link_up;
727 }
728
729
730 /******************************************************************************
731 * See mss_ethernet_mac.h for details of how to use this function.
732 */
733 void
MSS_MAC_cfg_struct_def_init(mss_mac_cfg_t * cfg)734 MSS_MAC_cfg_struct_def_init
735 (
736 mss_mac_cfg_t * cfg
737 )
738 {
739 ASSERT(NULL_POINTER != cfg);
740 if(NULL_POINTER != cfg)
741 {
742 (void)memset(cfg, 0, sizeof(mss_mac_cfg_t)); /* Start with clean slate */
743
744 cfg->speed_duplex_select = MSS_MAC_ANEG_ALL_SPEEDS;
745 cfg->speed_mode = MSS_MAC_SPEED_AN;
746 #if defined(TARGET_ALOE)
747 cfg->phy_addr = 0U;
748 #endif
749 #if defined(MSS_MAC_PHY_HW_RESET) || defined(MSS_MAC_PHY_HW_SRESET)
750 cfg->phy_addr = PHY_NULL_MDIO_ADDR;
751 cfg->phy_soft_reset_gpio = (GPIO_TypeDef *)0UL;
752 cfg->phy_soft_reset_pin = MSS_GPIO_0;
753 cfg->phy_hard_reset_gpio = (GPIO_TypeDef *)0UL;
754 cfg->phy_hard_reset_pin = MSS_GPIO_0;
755 #endif
756 cfg->phy_controller = (mss_mac_instance_t *)0UL;
757 cfg->tx_edc_enable = MSS_MAC_ERR_DET_CORR_DISABLE;
758 cfg->rx_edc_enable = MSS_MAC_ERR_DET_CORR_DISABLE;
759 cfg->jumbo_frame_enable = MSS_MAC_JUMBO_FRAME_DISABLE;
760 cfg->jumbo_frame_default = MSS_MAC_MAX_PACKET_SIZE;
761 cfg->length_field_check = MSS_MAC_LENGTH_FIELD_CHECK_ENABLE;
762 cfg->append_CRC = MSS_MAC_CRC_ENABLE;
763 cfg->loopback = MSS_MAC_LOOPBACK_DISABLE;
764 cfg->rx_flow_ctrl = MSS_MAC_RX_FLOW_CTRL_ENABLE;
765 cfg->tx_flow_ctrl = MSS_MAC_TX_FLOW_CTRL_ENABLE;
766 cfg->ipg_multiplier = MSS_MAC_IPG_DEFVAL;
767 cfg->ipg_divisor = MSS_MAC_IPG_DEFVAL;
768 cfg->phyclk = MSS_MAC_DEF_PHY_CLK;
769 cfg->mac_addr[0] = 0x00U;
770 cfg->mac_addr[1] = 0x00U;
771 cfg->mac_addr[2] = 0x00U;
772 cfg->mac_addr[3] = 0x00U;
773 cfg->mac_addr[4] = 0x00U;
774 cfg->mac_addr[5] = 0x00U;
775 cfg->queue_enable[0] = MSS_MAC_QUEUE_DISABLE;
776 cfg->queue_enable[1] = MSS_MAC_QUEUE_DISABLE;
777 cfg->queue_enable[2] = MSS_MAC_QUEUE_DISABLE;
778 cfg->queue_enable[3] = MSS_MAC_QUEUE_DISABLE;
779 cfg->phy_type = MSS_MAC_DEV_PHY_NULL;
780 cfg->interface_type = NULL_PHY;
781 cfg->phy_autonegotiate = MSS_MAC_NULL_phy_autonegotiate;
782 cfg->phy_mac_autonegotiate = MSS_MAC_NULL_phy_mac_autonegotiate;
783 cfg->phy_get_link_status = MSS_MAC_NULL_phy_get_link_status;
784 cfg->phy_init = MSS_MAC_NULL_phy_init;
785 cfg->phy_set_link_speed = MSS_MAC_NULL_phy_set_link_speed;
786 cfg->use_hi_address = MSS_MAC_DISABLE;
787 cfg->use_local_ints = MSS_MAC_DISABLE;
788 cfg->queue0_int_priority = 7U; /* Give them highest priority by default */
789 cfg->queue1_int_priority = 7U;
790 cfg->queue2_int_priority = 7U;
791 cfg->queue3_int_priority = 7U;
792 cfg->mmsl_int_priority = 7U;
793 /*
794 * PMCS: Note for the Emulation platform we need to select the non
795 * default TSU clock the moment or TX won't work
796 */
797 cfg->tsu_clock_select = 0U;
798 cfg->amba_burst_length = MSS_MAC_AMBA_BURST_16;
799
800 #if MSS_MAC_USE_PHY_DP83867
801 cfg->phy_extended_read = NULL_ti_read_extended_regs;
802 cfg->phy_extended_write = NULL_ti_write_extended_regs;
803 #endif
804 }
805 }
806
807
808 /******************************************************************************
809 *
810 */
811 static void
mac_reset(void)812 mac_reset
813 (
814 void
815 )
816 {
817 }
818
819 #if defined(TARGET_ALOE)
820
821 /******************************************************************************
822 * PLL and Reset registers after reset in "wait for debug mode"
823 * 0x10000000 : 0x10000000 <Hex Integer>
824 * Address 0 - 3 4 - 7 8 - B C - F
825 * 10000000 C0000000 030187C1 00000000 030187C1
826 * 10000010 00000000 00000000 00000000 030187C1
827 * 10000020 00000000 00000001 00000000 00000004
828 *
829 * PLL and Reset registers after Linux boot.
830 *
831 * 0x10000000 : 0x10000000 <Hex Integer>
832 * Address 0 - 3 4 - 7 8 - B C - F
833 * 10000000 C0000000 82110EC0 00000000 82110DC0
834 * 10000010 80000000 00000000 00000000 82128EC0
835 * 10000020 80000000 00000000 0000002F 00000004
836 *
837 */
838
839 /******************************************************************************
840 *
841 */
842 #define __I const volatile
843 #define __IO volatile
844 #define __O volatile
845
846 typedef struct
847 {
848 __IO uint32_t HFXOSCCFG; /* 0x0000 */
849 __IO uint32_t COREPLLCFG0; /* 0x0004 */
850 __IO uint32_t reserved0; /* 0x0008 */
851 __IO uint32_t DDRPLLCFG0; /* 0x000C */
852 __IO uint32_t DDRPLLCFG1; /* 0x0010 */
853 __IO uint32_t reserved1; /* 0x0014 */
854 __IO uint32_t reserved2; /* 0x0018 */
855 __IO uint32_t GEMGXLPLLCFG0; /* 0x001C */
856 __IO uint32_t GEMGXLPLLCFG1; /* 0x0020 */
857 __IO uint32_t CORECLKSEL; /* 0x0024 */
858 __IO uint32_t DEVICERESETREG; /* 0x0028 */
859 } AloePRCI_TypeDef;
860
861 AloePRCI_TypeDef *g_aloe_prci = (AloePRCI_TypeDef *)0x10000000UL;
862
863 typedef struct
864 {
865 __IO uint32_t PWMCFG; /* 0x0000 */
866 __IO uint32_t reserved0; /* 0x0004 */
867 __IO uint32_t PWMCOUNT; /* 0x0008 */
868 __IO uint32_t reserved1; /* 0x000C */
869 __IO uint32_t PWMS; /* 0x0010 */
870 __IO uint32_t reserved2; /* 0x0014 */
871 __IO uint32_t reserved3; /* 0x0018 */
872 __IO uint32_t reserved4; /* 0x001C */
873 __IO uint32_t PWMCMP0; /* 0x0020 */
874 __IO uint32_t PWMCMP1; /* 0x0024 */
875 __IO uint32_t PWMCMP2; /* 0x0028 */
876 __IO uint32_t PWMCMP3; /* 0x002C */
877 } AloePWM_TypeDef;
878
879 AloePWM_TypeDef *g_aloe_pwm0 = (AloePWM_TypeDef *)0x10020000UL;
880
881
882 static void config_mac_pll_and_reset(void);
config_mac_pll_and_reset(void)883 static void config_mac_pll_and_reset(void)
884 {
885 volatile int64_t ix;
886 volatile int64_t counter;
887 volatile int64_t loops = 0;
888
889 /*
890 * COREPLLCFG0 reset value = 0x030187C1
891 * divr = 1
892 * divf = 1F
893 * divq = 3
894 * range = 0
895 * bypass = 1
896 * fse = 1
897 * lock = 0
898 *
899 * Desired value = 82110EC0
900 * divr = 0
901 * divf = 1D
902 * divq = 2
903 * range = 4
904 * bypass = 0
905 * fse = 1
906 * lock = 1
907 */
908 #if 0 /* Test code for proving Core clock speed switching works */
909 g_aloe_pwm0->PWMCFG = 0x0000020EU;
910 g_aloe_pwm0->PWMCMP0 = 0x0000FFFFU;
911 g_aloe_pwm0->PWMCMP1 = 0x0000FFFFU;
912 g_aloe_pwm0->PWMCMP2 = 0x0000FFFFU;
913 g_aloe_pwm0->PWMCMP3 = 0x0000FFFFU;
914
915 while(loops < 16)
916 {
917 if(ix & 1)
918 {
919 g_aloe_pwm0->PWMCMP0 = 0x00000000U;
920 }
921 else
922 {
923 g_aloe_pwm0->PWMCMP0 = 0x0000FFFFU;
924 }
925
926 if(ix & 2)
927 {
928 g_aloe_pwm0->PWMCMP1 = 0x00000000U;
929 }
930 else
931 {
932 g_aloe_pwm0->PWMCMP1 = 0x0000FFFFU;
933 }
934
935 if(ix & 4)
936 {
937 g_aloe_pwm0->PWMCMP2 = 0x00000000U;
938 }
939 else
940 {
941 g_aloe_pwm0->PWMCMP2 = 0x0000FFFFU;
942 }
943
944 if(ix & 8)
945 {
946 g_aloe_pwm0->PWMCMP3 = 0x00000000U;
947 }
948 else
949 {
950 g_aloe_pwm0->PWMCMP3 = 0x0000FFFFU;
951 }
952
953 ix++;
954 for(counter = 0; counter != 100000; counter++)
955 ;
956
957 loops++;
958 }
959 #endif
960
961 g_aloe_prci->COREPLLCFG0 = 0x03110EC0U; /* Configure Core Clock PLL */
962 while(g_aloe_prci->COREPLLCFG0 & 0x80000000U) /* Wait for lock with PLL bypassed */
963 ix++;
964
965 g_aloe_prci->COREPLLCFG0 = 0x02110EC0U; /* Take PLL out of bypass */
966 g_aloe_prci->CORECLKSEL = 0x00000000U; /* Switch to PLL as clock source */
967
968 #if 0 /* Test code for proving Core clock speed switching works */
969 loops = 0;
970 while(loops < 20)
971 {
972 if(ix & 1)
973 {
974 g_aloe_pwm0->PWMCMP0 = 0x0000FFFFU;
975 }
976 else
977 {
978 g_aloe_pwm0->PWMCMP0 = 0x00000000U;
979 }
980
981 ix++;
982 for(counter = 0; counter != 3000000; counter++)
983 ;
984
985 loops++;
986 }
987 #endif
988 /*
989 * GEMGXLPLLCFG0 reset value = 0x030187C1
990 * divr = 1
991 * divf = 1F
992 * divq = 3
993 * range = 0
994 * bypass = 1
995 * fse = 1
996 * lock = 0
997 *
998 * Desired value = 82128EC0
999 * divr = 0
1000 * divf = 3B
1001 * divq = 5
1002 * range = 4
1003 * bypass = 0
1004 * fse = 1
1005 * lock = 1
1006 */
1007
1008 g_aloe_prci->GEMGXLPLLCFG0 = 0x03128EC0U; /* Configure GEM Clock PLL */
1009 while(g_aloe_prci->GEMGXLPLLCFG0 & 0x80000000U) /* Wait for lock with PLL bypassed */
1010 ix++;
1011
1012 g_aloe_prci->GEMGXLPLLCFG0 = 0x02128EC0U; /* Take PLL out of bypass */
1013 g_aloe_prci->GEMGXLPLLCFG1 = 0x80000000U; /* Switch to PLL as clock source */
1014
1015 g_aloe_prci->DEVICERESETREG |= 0x00000020U; /* Release MAC from reset */
1016
1017 }
1018 #endif
1019
1020
1021 /******************************************************************************
1022 *
1023 */
config_mac_hw(mss_mac_instance_t * this_mac,const mss_mac_cfg_t * cfg)1024 static void config_mac_hw(mss_mac_instance_t *this_mac, const mss_mac_cfg_t * cfg)
1025 {
1026 uint32_t temp_net_config = 0U;
1027 uint32_t temp_net_control = 0U;
1028 uint32_t temp_dma_config = 0U;
1029 uint32_t temp_length;
1030
1031 /* Check for validity of configuration parameters */
1032 ASSERT( IS_STATE(cfg->tx_edc_enable) );
1033 ASSERT( IS_STATE(cfg->rx_edc_enable) );
1034 ASSERT( IS_STATE(cfg->jumbo_frame_enable) );
1035 ASSERT( IS_STATE(cfg->length_field_check) );
1036 ASSERT( IS_STATE(cfg->append_CRC) );
1037 ASSERT( IS_STATE(cfg->loopback) );
1038 ASSERT( IS_STATE(cfg->rx_flow_ctrl) );
1039 ASSERT( IS_STATE(cfg->tx_flow_ctrl) );
1040
1041 #if defined(TARGET_ALOE)
1042 config_mac_pll_and_reset();
1043 #endif
1044 /*--------------------------------------------------------------------------
1045 * Configure MAC Network Control register
1046 */
1047 /* temp_net_control = GEM_MAN_PORT_EN | GEM_CLEAR_ALL_STATS_REGS | GEM_PFC_ENABLE; */
1048 temp_net_control = GEM_MAN_PORT_EN | GEM_CLEAR_ALL_STATS_REGS | GEM_PFC_ENABLE | GEM_ALT_SGMII_MODE;
1049 #if 0
1050 temp_net_control |= GEM_LOOPBACK_LOCAL; /* PMCS: Enable this to force local loop back */
1051 #endif
1052 if(MSS_MAC_ENABLE == cfg->loopback)
1053 {
1054 temp_net_control |= GEM_LOOPBACK_LOCAL;
1055 }
1056
1057 #if defined(MSS_MAC_TIME_STAMPED_MODE)
1058 temp_net_control |= GEM_PTP_UNICAST_ENA;
1059 #endif
1060
1061 /*
1062 * eMAC has to be configured as external TSU although it is actually using
1063 * the pMAC TSU. There is only really 1 TSU per GEM instance and all
1064 * adjustments etc should really be done via the pMAC.
1065 */
1066 if(0U != this_mac->is_emac)
1067 {
1068 temp_net_control |= GEM_EXT_TSU_PORT_ENABLE;
1069 }
1070 /*--------------------------------------------------------------------------
1071 * Configure MAC Network Config and Network Control registers
1072 */
1073
1074 #if defined(TARGET_G5_SOC)
1075 if(TBI == this_mac->interface_type)
1076 {
1077 temp_net_config = (((uint32_t)(1UL)) << GEM_DATA_BUS_WIDTH_SHIFT) | ((cfg->phyclk & GEM_MDC_CLOCK_DIVISOR_MASK) << GEM_MDC_CLOCK_DIVISOR_SHIFT) | GEM_PCS_SELECT | GEM_SGMII_MODE_ENABLE;
1078 }
1079 else
1080 {
1081 /* Actually for the G5 SoC Emulation Platform the interface is GMII... */
1082 temp_net_config = (((uint32_t)(1UL)) << GEM_DATA_BUS_WIDTH_SHIFT) | ((cfg->phyclk & GEM_MDC_CLOCK_DIVISOR_MASK) << GEM_MDC_CLOCK_DIVISOR_SHIFT);
1083 }
1084 #endif
1085 #if defined(TARGET_ALOE)
1086 /* No pause frames received in memory, divide PCLK by 224 for MDC */
1087 temp_net_config = (cfg->phyclk & GEM_MDC_CLOCK_DIVISOR_MASK) << GEM_MDC_CLOCK_DIVISOR_SHIFT;
1088 #endif
1089
1090 if((MSS_MAC_ENABLE == cfg->rx_flow_ctrl) || (MSS_MAC_ENABLE == cfg->tx_flow_ctrl))
1091 {
1092 temp_net_config |= GEM_FCS_REMOVE | GEM_DISABLE_COPY_OF_PAUSE_FRAMES | GEM_RECEIVE_1536_BYTE_FRAMES | GEM_PAUSE_ENABLE | GEM_FULL_DUPLEX | GEM_GIGABIT_MODE_ENABLE;
1093 }
1094 else
1095 {
1096 temp_net_config |= GEM_FCS_REMOVE | GEM_DISABLE_COPY_OF_PAUSE_FRAMES | GEM_RECEIVE_1536_BYTE_FRAMES | GEM_FULL_DUPLEX | GEM_GIGABIT_MODE_ENABLE;
1097 }
1098
1099 if(MSS_MAC_ENABLE == cfg->length_field_check)
1100 {
1101 temp_net_config |= GEM_LENGTH_FIELD_ERROR_FRAME_DISCARD;
1102 }
1103
1104 if(MSS_MAC_IPG_DEFVAL != cfg->ipg_multiplier) /* If we have a non zero value here then enable IPG stretching */
1105 {
1106 uint32_t stretch;
1107 temp_net_config |= GEM_IPG_STRETCH_ENABLE;
1108
1109 stretch = cfg->ipg_multiplier & GEM_IPG_STRETCH_MUL_MASK;
1110 stretch |= (cfg->ipg_divisor & GEM_IPG_STRETCH_DIV_MASK) << GEM_IPG_STRETCH_DIV_SHIFT;
1111
1112 if(0U != this_mac->is_emac)
1113 {
1114 this_mac->emac_base->STRETCH_RATIO = stretch;
1115 }
1116 else
1117 {
1118 this_mac->mac_base->STRETCH_RATIO = stretch;
1119 }
1120 }
1121
1122 if(0U != this_mac->is_emac)
1123 {
1124 this_mac->emac_base->NETWORK_CONTROL = temp_net_control;
1125 this_mac->emac_base->NETWORK_CONFIG = temp_net_config;
1126 this_mac->mac_base->NETWORK_CONFIG = temp_net_config;
1127 }
1128 else
1129 {
1130 this_mac->mac_base->NETWORK_CONTROL = temp_net_control;
1131 this_mac->mac_base->NETWORK_CONFIG = temp_net_config;
1132 #if defined(TARGET_G5_SOC)
1133 this_mac->emac_base->NETWORK_CONFIG = temp_net_config;
1134 #endif
1135 }
1136
1137 /*--------------------------------------------------------------------------
1138 * Reset PCS
1139 */
1140 if(0U == this_mac->is_emac)
1141 {
1142 this_mac->mac_base->PCS_CONTROL |= (uint32_t)0x8000UL;
1143 }
1144
1145 /*--------------------------------------------------------------------------
1146 * Configure MAC Network DMA Config register
1147 */
1148
1149 temp_dma_config = (MSS_MAC_RX_BUF_VALUE << GEM_RX_BUF_SIZE_SHIFT) |
1150 GEM_TX_PBUF_SIZE |
1151 (((uint32_t)(0x3UL)) << GEM_RX_PBUF_SIZE_SHIFT) |
1152 ((uint32_t)(cfg->amba_burst_length & MSS_MAC_AMBA_BURST_MASK));
1153
1154 #if defined(MSS_MAC_TIME_STAMPED_MODE)
1155 temp_dma_config |= GEM_TX_BD_EXTENDED_MODE_EN | GEM_RX_BD_EXTENDED_MODE_EN;
1156 #endif
1157
1158 #if defined(MSS_MAC_64_BIT_ADDRESS_MODE)
1159 temp_dma_config |= GEM_DMA_ADDR_BUS_WIDTH_1;
1160 #endif
1161
1162 if(0U != this_mac->is_emac)
1163 {
1164 this_mac->emac_base->DMA_CONFIG = temp_dma_config;
1165
1166 #if defined(MSS_MAC_TIME_STAMPED_MODE)
1167 /* Record TS for all packets by default */
1168 this_mac->emac_base->TX_BD_CONTROL = GEM_BD_TS_MODE;
1169 this_mac->emac_base->RX_BD_CONTROL = GEM_BD_TS_MODE;
1170 #endif
1171 }
1172 else
1173 {
1174 int32_t queue_index;
1175 this_mac->mac_base->DMA_CONFIG = temp_dma_config;
1176 #if defined(MSS_MAC_TIME_STAMPED_MODE)
1177 /* Record TS for all packets by default */
1178 this_mac->mac_base->TX_BD_CONTROL = GEM_BD_TS_MODE;
1179 this_mac->mac_base->RX_BD_CONTROL = GEM_BD_TS_MODE;
1180 #endif
1181 #if (MSS_MAC_QUEUE_COUNT > 1)
1182 for(queue_index = 1; queue_index < MSS_MAC_QUEUE_COUNT; queue_index++)
1183 {
1184 *(this_mac->queue[queue_index].dma_rxbuf_size) = ((uint32_t)MSS_MAC_RX_BUF_VALUE);
1185 }
1186 #endif
1187 }
1188
1189 /*
1190 * Disable the other queues as the GEM reset leaves them enabled with an
1191 * address pointer of 0 for some unfathomable reason... This screws things
1192 * up when we enable transmission or reception.
1193 *
1194 * Setting b0 of the queue pointer disables a queue.
1195 */
1196 #if (MSS_MAC_QUEUE_COUNT > 1)
1197 if(0U == this_mac->is_emac)
1198 { /* Added these to MAC structure to make them MAC specific... */
1199 this_mac->mac_base->TRANSMIT_Q1_PTR = ((uint32_t)(uint64_t)this_mac->queue[0].tx_desc_tab) | 1U; /* Use address of valid descriptor but set b0 to disable */
1200 this_mac->mac_base->TRANSMIT_Q2_PTR = ((uint32_t)(uint64_t)this_mac->queue[0].tx_desc_tab) | 1U;
1201 this_mac->mac_base->TRANSMIT_Q3_PTR = ((uint32_t)(uint64_t)this_mac->queue[0].tx_desc_tab) | 1U;
1202 this_mac->mac_base->RECEIVE_Q1_PTR = ((uint32_t)(uint64_t)this_mac->queue[0].rx_desc_tab) | 1U;
1203 this_mac->mac_base->RECEIVE_Q2_PTR = ((uint32_t)(uint64_t)this_mac->queue[0].rx_desc_tab) | 1U;
1204 this_mac->mac_base->RECEIVE_Q3_PTR = ((uint32_t)(uint64_t)this_mac->queue[0].rx_desc_tab) | 1U;
1205 }
1206 #endif
1207
1208 /* Set up maximum initial jumbo frame size - but bounds check first */
1209 if(cfg->jumbo_frame_default > MSS_MAC_JUMBO_MAX)
1210 {
1211 temp_length = MSS_MAC_JUMBO_MAX;
1212 }
1213 else
1214 {
1215 temp_length = cfg->jumbo_frame_default;
1216 }
1217
1218 if(0U != this_mac->is_emac)
1219 {
1220 this_mac->emac_base->JUMBO_MAX_LENGTH = temp_length;
1221 }
1222 else
1223 {
1224 this_mac->mac_base->JUMBO_MAX_LENGTH = temp_length;
1225 }
1226
1227 /*--------------------------------------------------------------------------
1228 * Disable all ints for now
1229 */
1230 if(0U != this_mac->is_emac)
1231 {
1232 this_mac->emac_base->INT_DISABLE = ((uint32_t)0xFFFFFFFFUL); /* Only one queue here... */
1233 }
1234 else
1235 {
1236 int32_t queue_no;
1237 for(queue_no = 0; queue_no < MSS_MAC_QUEUE_COUNT; queue_no++)
1238 {
1239 *(this_mac->queue[queue_no].int_disable) = ((uint32_t)0xFFFFFFFFUL);
1240 }
1241 }
1242
1243 }
1244
1245
1246 /******************************************************************************
1247 * See mss_ethernet_mac.h for details of how to use this function.
1248 */
1249 void
MSS_MAC_write_phy_reg(const mss_mac_instance_t * this_mac_in,uint8_t phyaddr,uint8_t regaddr,uint16_t regval)1250 MSS_MAC_write_phy_reg
1251 (
1252 const mss_mac_instance_t *this_mac_in,
1253 uint8_t phyaddr,
1254 uint8_t regaddr,
1255 uint16_t regval
1256 )
1257 {
1258 volatile uint32_t phy_op;
1259 psr_t lev;
1260 const mss_mac_instance_t *this_mac;
1261
1262 ASSERT(MSS_MAC_PHYADDR_MAXVAL >= phyaddr);
1263 ASSERT(MSS_MAC_PHYREGADDR_MAXVAL >= regaddr);
1264
1265 /* Check to see which MAC is actually in charge of PHY interface */
1266 if((struct mss_mac_instance *)0UL != this_mac_in->phy_controller)
1267 {
1268 this_mac = (const mss_mac_instance_t *)this_mac_in->phy_controller;
1269 }
1270 else
1271 {
1272 this_mac = this_mac_in;
1273 }
1274
1275 /*
1276 * Write PHY address in MII Mgmt address register.
1277 * Makes previous register address 0 & invalid.
1278 *
1279 * Don't check mac_available flag here as we may be called in the MAC init
1280 * phase before everything else is in place...
1281 */
1282 if((MSS_MAC_PHYADDR_MAXVAL >= phyaddr) &&
1283 (MSS_MAC_PHYREGADDR_MAXVAL >= regaddr))
1284 {
1285 phy_op = GEM_WRITE1 | (GEM_PHY_OP_CL22_WRITE << GEM_OPERATION_SHIFT) | (((uint32_t)(2UL)) << GEM_WRITE10_SHIFT) | (uint32_t)regval;
1286 phy_op |= ((uint32_t)phyaddr << GEM_PHY_ADDRESS_SHIFT) & GEM_PHY_ADDRESS;
1287 phy_op |= ((uint32_t)regaddr << GEM_REGISTER_ADDRESS_SHIFT) & GEM_REGISTER_ADDRESS;
1288
1289 lev = HAL_disable_interrupts();
1290 /*
1291 * Always use the pMAC for this as the eMAC MDIO interface is not
1292 * connected to the outside world...
1293 */
1294 /* Wait for MII Mgmt interface to complete previous operation. */
1295 do
1296 {
1297 volatile int32_t ix;
1298 ix++;
1299 } while(0U == (this_mac->mac_base->NETWORK_STATUS & GEM_MAN_DONE));
1300
1301 this_mac->mac_base->PHY_MANAGEMENT = phy_op;
1302 HAL_restore_interrupts(lev);
1303 }
1304 }
1305
1306
1307
1308
1309 /******************************************************************************
1310 * See mss_ethernet_mac.h for details of how to use this function.
1311 */
1312 uint16_t
MSS_MAC_read_phy_reg(const mss_mac_instance_t * this_mac_in,uint8_t phyaddr,uint8_t regaddr)1313 MSS_MAC_read_phy_reg
1314 (
1315 const mss_mac_instance_t *this_mac_in,
1316 uint8_t phyaddr,
1317 uint8_t regaddr
1318 )
1319 {
1320 volatile uint32_t phy_op;
1321 psr_t lev;
1322 const mss_mac_instance_t *this_mac;
1323
1324 ASSERT(MSS_MAC_PHYADDR_MAXVAL >= phyaddr);
1325 ASSERT(MSS_MAC_PHYREGADDR_MAXVAL >= regaddr);
1326
1327 /* Check to see which MAC is actually in charge of PHY interface */
1328 if((struct mss_mac_instance *)0UL != this_mac_in->phy_controller)
1329 {
1330 this_mac = (const mss_mac_instance_t *)this_mac_in->phy_controller;
1331 }
1332 else
1333 {
1334 this_mac = this_mac_in;
1335 }
1336
1337 /*
1338 * Write PHY address in MII Mgmt address register.
1339 * Makes previous register address 0 & invalid.
1340 *
1341 * Don't check mac_available flag here as we may be called in the MAC init
1342 * phase before everything else is in place...
1343 */
1344 if((MSS_MAC_PHYADDR_MAXVAL >= phyaddr) &&
1345 (MSS_MAC_PHYREGADDR_MAXVAL >= regaddr))
1346 {
1347 phy_op = GEM_WRITE1 | (GEM_PHY_OP_CL22_READ << GEM_OPERATION_SHIFT) | (((uint32_t)(2UL)) << GEM_WRITE10_SHIFT);
1348 phy_op |= ((uint32_t)phyaddr << GEM_PHY_ADDRESS_SHIFT) & GEM_PHY_ADDRESS;
1349 phy_op |= ((uint32_t)regaddr << GEM_REGISTER_ADDRESS_SHIFT) & GEM_REGISTER_ADDRESS;
1350
1351 /*
1352 * Always use the pMAC for this as the eMAC MDIO interface is not
1353 * connected to the outside world...
1354 */
1355 lev = HAL_disable_interrupts();
1356 /* Wait for MII Mgmt interface to complete previous operation. */
1357 do
1358 {
1359 volatile int32_t ix;
1360 ix++;
1361 } while(0U == (this_mac->mac_base->NETWORK_STATUS & GEM_MAN_DONE));
1362
1363 this_mac->mac_base->PHY_MANAGEMENT = phy_op;
1364
1365 do
1366 {
1367 volatile int32_t ix;
1368 ix++;
1369 } while(0U == (this_mac->mac_base->NETWORK_STATUS & GEM_MAN_DONE));
1370
1371 phy_op = this_mac->mac_base->PHY_MANAGEMENT;
1372 HAL_restore_interrupts(lev);
1373 }
1374 else
1375 {
1376 phy_op = 0U;
1377 }
1378
1379 return((uint16_t)phy_op);
1380 }
1381
1382
1383 /******************************************************************************
1384 * See mss_ethernet_mac.h for details of how to use this function.
1385 */
1386 void
MSS_MAC_phy_reset(const mss_mac_instance_t * this_mac,mss_mac_phy_reset_t reset_type,bool reset_state)1387 MSS_MAC_phy_reset
1388 (
1389 const mss_mac_instance_t *this_mac,
1390 mss_mac_phy_reset_t reset_type,
1391 bool reset_state
1392 )
1393 {
1394 #if defined(MSS_MAC_PHY_HW_RESET) || defined(MSS_MAC_PHY_HW_SRESET)
1395 /* Reset pointer to base MAC structure */
1396 if(&g_emac0 == this_mac)
1397 {
1398 this_mac = &g_mac0;
1399 }
1400
1401 if(&g_emac1 == this_mac)
1402 {
1403 this_mac = &g_mac1;
1404 }
1405
1406 if(MSS_MAC_SOFT_RESET == reset_type)
1407 {
1408 if((GPIO_TypeDef *)0UL != this_mac->phy_soft_reset_gpio)
1409 {
1410 MSS_GPIO_set_output(this_mac->phy_soft_reset_gpio, this_mac->phy_soft_reset_pin, reset_state);
1411 }
1412 }
1413 else
1414 {
1415 if((GPIO_TypeDef *)0UL != this_mac->phy_hard_reset_gpio)
1416 {
1417 MSS_GPIO_set_output(this_mac->phy_hard_reset_gpio, this_mac->phy_hard_reset_pin, reset_state);
1418 }
1419 }
1420 #else
1421 (void)this_mac;
1422 (void)reset_type;
1423 (void)reset_state;
1424 #endif
1425 }
1426
1427
1428 /******************************************************************************
1429 * See mss_ethernet_mac.h for details of how to use this function.
1430 */
1431
1432 /* Divide by 4 as offset is in bytes but pointer is 4 bytes */
1433 #define GEM_REG_OFFSET(x) (offsetof(MAC_TypeDef, x) / 4)
1434
1435 uint32_t
MSS_MAC_read_stat(const mss_mac_instance_t * this_mac,mss_mac_stat_t stat)1436 MSS_MAC_read_stat
1437 (
1438 const mss_mac_instance_t *this_mac,
1439 mss_mac_stat_t stat
1440 )
1441 {
1442 uint32_t stat_val = 0u;
1443
1444 static uint64_t const stat_regs_lut[] =
1445 {
1446 GEM_REG_OFFSET(OCTETS_TXED_BOTTOM),
1447 GEM_REG_OFFSET(OCTETS_TXED_TOP),
1448 GEM_REG_OFFSET(FRAMES_TXED_OK),
1449 GEM_REG_OFFSET(BROADCAST_TXED),
1450 GEM_REG_OFFSET(MULTICAST_TXED),
1451 GEM_REG_OFFSET(PAUSE_FRAMES_TXED),
1452 GEM_REG_OFFSET(FRAMES_TXED_64),
1453 GEM_REG_OFFSET(FRAMES_TXED_65),
1454 GEM_REG_OFFSET(FRAMES_TXED_128),
1455 GEM_REG_OFFSET(FRAMES_TXED_256),
1456 GEM_REG_OFFSET(FRAMES_TXED_512),
1457 GEM_REG_OFFSET(FRAMES_TXED_1024),
1458 GEM_REG_OFFSET(FRAMES_TXED_1519),
1459 GEM_REG_OFFSET(TX_UNDERRUNS),
1460 GEM_REG_OFFSET(SINGLE_COLLISIONS),
1461 GEM_REG_OFFSET(MULTIPLE_COLLISIONS),
1462 GEM_REG_OFFSET(EXCESSIVE_COLLISIONS),
1463 GEM_REG_OFFSET(LATE_COLLISIONS),
1464 GEM_REG_OFFSET(DEFERRED_FRAMES),
1465 GEM_REG_OFFSET(CRS_ERRORS),
1466 GEM_REG_OFFSET(OCTETS_RXED_BOTTOM),
1467 GEM_REG_OFFSET(OCTETS_RXED_TOP),
1468 GEM_REG_OFFSET(FRAMES_RXED_OK),
1469 GEM_REG_OFFSET(BROADCAST_RXED),
1470 GEM_REG_OFFSET(MULTICAST_RXED),
1471 GEM_REG_OFFSET(PAUSE_FRAMES_RXED),
1472 GEM_REG_OFFSET(FRAMES_RXED_64),
1473 GEM_REG_OFFSET(FRAMES_RXED_65),
1474 GEM_REG_OFFSET(FRAMES_RXED_128),
1475 GEM_REG_OFFSET(FRAMES_RXED_256),
1476 GEM_REG_OFFSET(FRAMES_RXED_512),
1477 GEM_REG_OFFSET(FRAMES_RXED_1024),
1478 GEM_REG_OFFSET(FRAMES_RXED_1519),
1479 GEM_REG_OFFSET(UNDERSIZE_FRAMES),
1480 GEM_REG_OFFSET(EXCESSIVE_RX_LENGTH),
1481 GEM_REG_OFFSET(RX_JABBERS),
1482 GEM_REG_OFFSET(FCS_ERRORS),
1483 GEM_REG_OFFSET(RX_LENGTH_ERRORS),
1484 GEM_REG_OFFSET(RX_SYMBOL_ERRORS),
1485 GEM_REG_OFFSET(ALIGNMENT_ERRORS),
1486 GEM_REG_OFFSET(RX_RESOURCE_ERRORS),
1487 GEM_REG_OFFSET(RX_OVERRUNS),
1488 GEM_REG_OFFSET(RX_IP_CK_ERRORS),
1489 GEM_REG_OFFSET(RX_TCP_CK_ERRORS),
1490 GEM_REG_OFFSET(RX_UDP_CK_ERRORS),
1491 GEM_REG_OFFSET(AUTO_FLUSHED_PKTS)
1492 };
1493
1494 ASSERT(MSS_MAC_LAST_STAT > stat);
1495
1496 if((MSS_MAC_LAST_STAT > stat) && (MSS_MAC_AVAILABLE == this_mac->mac_available))
1497 {
1498 if(0U != this_mac->is_emac)
1499 {
1500 stat_val = *(((uint32_t *)this_mac->emac_base) + stat_regs_lut[stat]);
1501 }
1502 else
1503 {
1504 stat_val = *(((uint32_t *)this_mac->mac_base) + stat_regs_lut[stat]);
1505 }
1506 }
1507
1508 return stat_val;
1509 }
1510
1511
1512 /*******************************************************************************
1513 See mss_ethernet_mac.h for details of how to use this function
1514 */
MSS_MAC_clear_statistics(const mss_mac_instance_t * this_mac)1515 void MSS_MAC_clear_statistics
1516 (
1517 const mss_mac_instance_t *this_mac
1518 )
1519 {
1520 if((0U != this_mac->is_emac) && (MSS_MAC_AVAILABLE == this_mac->mac_available))
1521 {
1522 this_mac->emac_base->NETWORK_CONTROL |= GEM_CLEAR_ALL_STATS_REGS;
1523 }
1524 else
1525 {
1526 this_mac->mac_base->NETWORK_CONTROL |= GEM_CLEAR_ALL_STATS_REGS;
1527 }
1528 }
1529
1530
1531 /******************************************************************************
1532 * See mss_ethernet_mac.h for details of how to use this function.
1533 */
1534 uint8_t
MSS_MAC_receive_pkt(mss_mac_instance_t * this_mac,uint32_t queue_no,uint8_t * rx_pkt_buffer,void * p_user_data,mss_mac_rx_int_ctrl_t enable)1535 MSS_MAC_receive_pkt
1536 (
1537 mss_mac_instance_t *this_mac,
1538 uint32_t queue_no,
1539 uint8_t * rx_pkt_buffer,
1540 void * p_user_data,
1541 mss_mac_rx_int_ctrl_t enable
1542 )
1543 {
1544 uint8_t status = MSS_MAC_FAILED;
1545 /* Make this function atomic w.r.to EMAC interrupt */
1546
1547 /* PLIC_DisableIRQ() et al should not be called from the associated interrupt... */
1548 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
1549 {
1550 if(0U == this_mac->queue[queue_no].in_isr)
1551 {
1552 if(0U != this_mac->use_local_ints)
1553 {
1554 __disable_local_irq(this_mac->mac_q_int[queue_no]);
1555 }
1556 else
1557 {
1558 PLIC_DisableIRQ(this_mac->mac_q_int[queue_no]); /* Single interrupt from GEM? */
1559 }
1560 }
1561
1562 ASSERT(NULL_POINTER != rx_pkt_buffer);
1563 ASSERT(IS_WORD_ALIGNED(rx_pkt_buffer));
1564
1565 if(this_mac->queue[queue_no].nb_available_rx_desc > 0U)
1566 {
1567 uint32_t next_rx_desc_index;
1568
1569 if(MSS_MAC_INT_DISABLE == enable)
1570 {
1571 /*
1572 * When setting up the chain of buffers, we don't want the DMA
1573 * engine active so shut down reception.
1574 */
1575 if(0U != this_mac->is_emac)
1576 {
1577 this_mac->emac_base->NETWORK_CONTROL &= ~GEM_ENABLE_RECEIVE;
1578 }
1579 else
1580 {
1581 this_mac->mac_base->NETWORK_CONTROL &= ~GEM_ENABLE_RECEIVE;
1582 }
1583 }
1584
1585 --this_mac->queue[queue_no].nb_available_rx_desc;
1586 next_rx_desc_index = this_mac->queue[queue_no].next_free_rx_desc_index;
1587
1588 if((MSS_MAC_RX_RING_SIZE - 1U) == next_rx_desc_index)
1589 {
1590 this_mac->queue[queue_no].rx_desc_tab[next_rx_desc_index].addr_low = (uint32_t)((uint64_t)rx_pkt_buffer | 2UL); /* Set wrap bit */
1591 }
1592 else
1593 {
1594 this_mac->queue[queue_no].rx_desc_tab[next_rx_desc_index].addr_low = (uint32_t)((uint64_t)rx_pkt_buffer);
1595 }
1596
1597 #if defined(MSS_MAC_64_BIT_ADDRESS_MODE)
1598 this_mac->queue[queue_no].rx_desc_tab[next_rx_desc_index].addr_high = (uint32_t)((uint64_t)rx_pkt_buffer >> 32);
1599 #endif
1600 this_mac->queue[queue_no].rx_caller_info[next_rx_desc_index] = p_user_data;
1601
1602 /*
1603 If the RX is found disabled, then it might be because this is the
1604 first time a packet is scheduled for reception or the RX ENABLE is
1605 made zero by RX overflow or RX bus error. In either case, this
1606 function tries to schedule the current packet for reception.
1607
1608 Don't bother if we are not enabling interrupt at the end of all this...
1609 */
1610 if(MSS_MAC_INT_ARM == enable)
1611 {
1612 /*
1613 * Starting receive operations off with a chain of buffers set up.
1614 */
1615
1616 if(0U != this_mac->is_emac)
1617 {
1618 this_mac->emac_base->NETWORK_CONTROL &= ~GEM_ENABLE_RECEIVE;
1619 this_mac->emac_base->RECEIVE_Q_PTR = (uint32_t)((uint64_t)this_mac->queue[queue_no].rx_desc_tab);
1620 #if defined(MSS_MAC_64_BIT_ADDRESS_MODE)
1621 this_mac->emac_base->UPPER_RX_Q_BASE_ADDR = (uint32_t)((uint64_t)this_mac->queue[queue_no].rx_desc_tab >> 32);
1622 #endif
1623 this_mac->emac_base->NETWORK_CONTROL |= GEM_ENABLE_RECEIVE;
1624 }
1625 else
1626 {
1627 this_mac->mac_base->NETWORK_CONTROL &= ~GEM_ENABLE_RECEIVE;
1628 *(this_mac->queue[queue_no].receive_q_ptr) = (uint32_t)((uint64_t)this_mac->queue[queue_no].rx_desc_tab);
1629 #if defined(MSS_MAC_64_BIT_ADDRESS_MODE)
1630 this_mac->mac_base->UPPER_RX_Q_BASE_ADDR = (uint32_t)((uint64_t)this_mac->queue[queue_no].rx_desc_tab >> 32);
1631 #endif
1632 this_mac->mac_base->NETWORK_CONTROL |= GEM_ENABLE_RECEIVE;
1633 }
1634 }
1635 else
1636 {
1637 if(MSS_MAC_INT_DISABLE != enable)
1638 {
1639 uint32_t temp_cr;
1640
1641 if(0U != this_mac->is_emac)
1642 {
1643 temp_cr = this_mac->emac_base->NETWORK_CONTROL;
1644 }
1645 else
1646 {
1647 temp_cr = this_mac->mac_base->NETWORK_CONTROL;
1648 }
1649 if(0U == (temp_cr & GEM_ENABLE_RECEIVE))
1650 {
1651 /* RX disabled so restart it... */
1652 if(0U != this_mac->is_emac)
1653 {
1654 this_mac->emac_base->NETWORK_CONTROL |= GEM_ENABLE_RECEIVE;
1655 }
1656 else
1657 {
1658 this_mac->mac_base->NETWORK_CONTROL |= GEM_ENABLE_RECEIVE;
1659 }
1660 }
1661 }
1662 }
1663
1664 /* Point the next_rx_desc to next free descriptor in the ring */
1665 /* Wrap around in case next descriptor is pointing to last in the ring */
1666 ++this_mac->queue[queue_no].next_free_rx_desc_index;
1667 this_mac->queue[queue_no].next_free_rx_desc_index %= MSS_MAC_RX_RING_SIZE;
1668
1669 }
1670
1671 /*
1672 * Only call Ethernet Interrupt Enable function if the user says so.
1673 * See note above for disable...
1674 */
1675 if((MSS_MAC_INT_ARM == enable) && (0U == this_mac->queue[queue_no].in_isr))
1676 {
1677 if(0U != this_mac->use_local_ints)
1678 {
1679 __enable_local_irq(this_mac->mac_q_int[queue_no]);
1680 }
1681 else
1682 {
1683 PLIC_EnableIRQ(this_mac->mac_q_int[queue_no]); /* Single interrupt from GEM? */
1684 }
1685 }
1686 }
1687
1688 return status;
1689 }
1690
1691 #if defined(MSS_MAC_UNH_TEST)
1692 /******************************************************************************
1693 * We take a lot of short cuts here as we "know" we are called from ISR and
1694 * are only supposed to be called for pMAC queue 0, we assume the packet buffer
1695 * for this descriptor has not changed, we ignore caller_info etc...
1696 */
1697 void
MSS_MAC_receive_pkt_isr(mss_mac_instance_t * this_mac)1698 MSS_MAC_receive_pkt_isr
1699 (
1700 mss_mac_instance_t *this_mac
1701 )
1702 {
1703 mss_mac_queue_t *p_queue = &this_mac->queue[0];
1704
1705 --p_queue->nb_available_rx_desc;
1706
1707 /* clear used bit and time stamp present bit */
1708 p_queue->rx_desc_tab[p_queue->next_free_rx_desc_index].addr_low &= 0xFFFFFFFA;
1709
1710 /* Point the next_rx_desc to next free descriptor in the ring */
1711 /* Wrap around in case next descriptor is pointing to last in the ring */
1712 ++p_queue->next_free_rx_desc_index;
1713 p_queue->next_free_rx_desc_index %= MSS_MAC_RX_RING_SIZE;
1714 }
1715 #endif
1716
1717 /*******************************************************************************
1718 * See mss_ethernet_mac.h for details of how to use this function.
1719 */
1720 int32_t
MSS_MAC_send_pkt(mss_mac_instance_t * this_mac,uint32_t queue_no,uint8_t const * tx_buffer,uint32_t length,void * p_user_data)1721 MSS_MAC_send_pkt
1722 (
1723 mss_mac_instance_t *this_mac,
1724 uint32_t queue_no,
1725 uint8_t const * tx_buffer,
1726 uint32_t length,
1727 void * p_user_data
1728 )
1729 {
1730 /*
1731 * Simplified transmit operation which depends on the following assumptions:
1732 *
1733 * 1. The TX DMA buffer size is big enough to contain a full packet.
1734 * 2. We will only transmit one packet at a time.
1735 * 3. We wait for any outstanding transmits on other queues to complete
1736 * because we need to ALWAYS write to the queue 0 pointer to trigger
1737 * internal restart of the DMA process.
1738 *
1739 * We do transmission by using two buffer descriptors. The first contains the
1740 * packet to transmit and the second is a dummy one with the USED bit set. This
1741 * halts transmission once the first packet is transmitted. We always reset the
1742 * TX DMA to point to the first packet when we send a packet so we don't have
1743 * to juggle buffer positions or worry about wrap.
1744 */
1745 uint32_t tx_length = length;
1746 int32_t status = MSS_MAC_ERR_NOT_DONE;
1747 /*
1748 * Hack for system testing. If b31 of the tx_length is 1 then we want to
1749 * send without a CRC appended. This is used for loopback testing where we
1750 * can get the GEM to receive packets with CRC appended and send them
1751 * straight back.
1752 */
1753 int32_t no_crc = 0;
1754 volatile int delay;
1755 volatile uint32_t *p_nw_control;
1756 volatile uint32_t *p_tx_status;
1757
1758 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
1759 {
1760 /* Is config option for disabling CRC set? */
1761 if(MSS_MAC_CRC_DISABLE == this_mac->append_CRC)
1762 {
1763 no_crc = 1;
1764 }
1765
1766 /* Or has the user requested just this packet? */
1767 if(0U != (tx_length & 0x80000000U))
1768 {
1769 no_crc = 1;
1770 }
1771
1772 tx_length &= 0x7FFFFFFFU; /* Make sure high bit is now clear */
1773
1774 /* Make this function atomic w.r.to EMAC interrupt */
1775 /* PLIC_DisableIRQ() et al should not be called from the associated interrupt... */
1776 if(0U == this_mac->queue[queue_no].in_isr)
1777 {
1778 if(0U != this_mac->use_local_ints)
1779 {
1780 __disable_local_irq(this_mac->mac_q_int[queue_no]);
1781 }
1782 else
1783 {
1784 PLIC_DisableIRQ(this_mac->mac_q_int[queue_no]); /* Single interrupt from GEM? */
1785 }
1786 }
1787
1788 ASSERT(NULL_POINTER != tx_buffer);
1789 ASSERT(0U != tx_length);
1790 ASSERT(IS_WORD_ALIGNED(tx_buffer));
1791
1792 /* We use these a lot and this cuts down on conditional code later on */
1793 if(0U != this_mac->is_emac)
1794 {
1795 p_nw_control = &this_mac->emac_base->NETWORK_CONTROL;
1796 p_tx_status = &this_mac->emac_base->TRANSMIT_STATUS;
1797 }
1798 else
1799 {
1800 p_nw_control = &this_mac->mac_base->NETWORK_CONTROL;
1801 p_tx_status = &this_mac->mac_base->TRANSMIT_STATUS;
1802 }
1803
1804 #if defined(MSS_MAC_SIMPLE_TX_QUEUE)
1805 if(this_mac->queue[queue_no].nb_available_tx_desc == (uint32_t)MSS_MAC_TX_RING_SIZE)
1806 {
1807 /* Queue is fully available for transmit so clear retry count */
1808 this_mac->queue[queue_no].tries = 0UL;
1809
1810 /* Make sure transmit is enabled */
1811 if(0 == (*p_nw_control & GEM_ENABLE_TRANSMIT))
1812 {
1813 *p_nw_control = *p_nw_control | GEM_ENABLE_TRANSMIT;
1814 }
1815 /*
1816 * Wait for pending transmits to complete as you cannot alter
1817 * tx queue pointers while transmit is active...
1818 */
1819 while(0 != (*p_tx_status & GEM_TRANSMIT_GO))
1820 {
1821 delay++; /* Empty loop will cause debug issues... */
1822 }
1823
1824 /* Make sure queue is currently disabled */
1825 *this_mac->queue[queue_no].transmit_q_ptr = (uint32_t)((uint64_t)this_mac->queue[queue_no].tx_desc_tab) | 1UL;
1826
1827 /* Set up tx descriptor for this packet */
1828 this_mac->queue[queue_no].nb_available_tx_desc--;
1829 this_mac->queue[queue_no].current_tx_desc = 0;
1830 this_mac->queue[queue_no].tx_desc_tab[0].addr_low = (uint32_t)((uint64_t)tx_buffer);
1831
1832 /* Mark as last buffer for frame */
1833 this_mac->queue[queue_no].tx_desc_tab[0].status = (tx_length & GEM_TX_DMA_BUFF_LEN) | GEM_TX_DMA_LAST;
1834 if(0 != no_crc)
1835 {
1836 this_mac->queue[queue_no].tx_desc_tab[0].status |= GEM_TX_DMA_NO_CRC;
1837 }
1838 #if 0
1839 this_mac->tx_desc_tab[0].status = (tx_length & GEM_TX_DMA_BUFF_LEN) | GEM_TX_DMA_LAST | GEM_TX_DMA_USED; /* PMCS deliberate error ! */
1840 #endif
1841 #if defined(MSS_MAC_64_BIT_ADDRESS_MODE)
1842 this_mac->queue[queue_no].tx_desc_tab[0].addr_high = (uint32_t)((uint64_t)tx_buffer >> 32);
1843 this_mac->queue[queue_no].tx_desc_tab[0].unused = 0U;
1844 #endif
1845
1846 this_mac->queue[queue_no].tx_desc_tab[1].status = GEM_TX_DMA_WRAP | GEM_TX_DMA_LAST | GEM_TX_DMA_USED ;
1847
1848 this_mac->queue[queue_no].tx_caller_info[0] = p_user_data;
1849
1850 *this_mac->queue[queue_no].transmit_q_ptr = (uint32_t)((uint64_t)&this_mac->queue[queue_no].tx_desc_tab[0]);
1851 /*
1852 * If not queue 0 then we need to write disabled value to queue 0 to
1853 * get the DMA engine reloaded...
1854 */
1855 if(0 != queue_no)
1856 {
1857 *this_mac->queue[0].transmit_q_ptr = (uint32_t)((uint64_t)this_mac->queue[0].tx_desc_tab) | 1U;
1858 }
1859
1860 /* When transmitting at 10M, this delay is needed, 625MHz cpu clock - YMMV */
1861 for(delay = 0; delay != 8; delay++)
1862 {
1863 }
1864
1865 *p_nw_control = *p_nw_control | GEM_TRANSMIT_START;
1866
1867 this_mac->queue[queue_no].egress += tx_length;
1868 status = MSS_MAC_ERR_OK;
1869 }
1870 else
1871 {
1872 /*
1873 * Queue not available so lets check some things...
1874 */
1875 if(0 == (*p_nw_control & GEM_ENABLE_TRANSMIT))
1876 {
1877 /*
1878 * TX is currently disabled so re-enable it and restart the last
1879 * operation on this queue to see if that gets us a completion.
1880 */
1881 this_mac->queue[queue_no].tx_reenable++;
1882 *p_nw_control = *p_nw_control | GEM_ENABLE_TRANSMIT;
1883 *this_mac->queue[queue_no].transmit_q_ptr = (uint32_t)((uint64_t)&this_mac->queue[queue_no].tx_desc_tab[0]);
1884 if(0 != queue_no)
1885 {
1886 *this_mac->queue[0].transmit_q_ptr = (uint32_t)((uint64_t)this_mac->queue[0].tx_desc_tab) | 1U;
1887 }
1888
1889 /* When transmitting at 10M, this delay is needed, 625MHz cpu clock - YMMV */
1890 for(delay = 0; delay != 8; delay++)
1891 {
1892 }
1893
1894 *p_nw_control = *p_nw_control | GEM_TRANSMIT_START;
1895 }
1896 else
1897 {
1898 /* Kick the tx start bit in case we are stalled... */
1899 this_mac->queue[queue_no].tx_restart++;
1900 *p_nw_control = *p_nw_control | GEM_TRANSMIT_START;
1901 }
1902
1903 /*
1904 * TX might have completed since we entered the function but if we
1905 * seem to be spinning on this and buffers haven't been returned to
1906 * the queue then just give up and reset queue.
1907 */
1908 if(this_mac->queue[queue_no].tx_desc_tab[0].status & GEM_TX_DMA_USED)
1909 {
1910 this_mac->queue[queue_no].tries++;
1911
1912 if(this_mac->queue[queue_no].tries > 3) /* Been here too often? */
1913 {
1914 /* Give up and reset FW queue count */
1915 this_mac->queue[queue_no].nb_available_tx_desc = (uint32_t)MSS_MAC_TX_RING_SIZE;
1916 status = MSS_MAC_ERR_TX_TIMEOUT;
1917 }
1918 }
1919
1920 if(this_mac->queue[queue_no].tx_desc_tab[0].status & (GEM_TX_DMA_RETRY_ERROR | GEM_TX_DMA_UNDERRUN | GEM_TX_DMA_BUS_ERROR | GEM_TX_DMA_LATE_COL_ERROR | GEM_TX_DMA_OFFLOAD_ERRORS))
1921 {
1922 /* Give up and reset FW queue count */
1923 this_mac->queue[queue_no].nb_available_tx_desc = (uint32_t)MSS_MAC_TX_RING_SIZE;
1924 status = MSS_MAC_ERR_TX_FAIL;
1925 }
1926 }
1927 #else
1928 /* TBD PMCS need to implement multi packet queuing... */
1929 #warning "Nothing implemented for multi packet tx yet"
1930 #endif
1931 /* Ethernet Interrupt Enable function. */
1932 /* PLIC_DisableIRQ() et al should not be called from the associated interrupt... */
1933 if(0U == this_mac->queue[queue_no].in_isr)
1934 {
1935 if(0U != this_mac->use_local_ints)
1936 {
1937 __enable_local_irq(this_mac->mac_q_int[queue_no]);
1938 }
1939 else
1940 {
1941 PLIC_EnableIRQ(this_mac->mac_q_int[queue_no]); /* Single interrupt from GEM? */
1942 }
1943 }
1944 }
1945 return status;
1946 }
1947
1948
1949 /*******************************************************************************
1950 * See mss_ethernet_mac.h for details of how to use this function.
1951 */
1952 int32_t
MSS_MAC_send_pkts(mss_mac_instance_t * this_mac,uint32_t queue_mask,mss_mac_tx_pkt_info_t * p_packets)1953 MSS_MAC_send_pkts
1954 (
1955 mss_mac_instance_t *this_mac,
1956 uint32_t queue_mask,
1957 mss_mac_tx_pkt_info_t *p_packets
1958 )
1959 {
1960 /*
1961 * Multi packet, multi queue transmit operation which depends on the
1962 * following assumptions:
1963 *
1964 * 1. queue_mask indicates the queues which may be involved so that we can
1965 * properly handle ISR vs normal calling.
1966 * Set the mask to 0x0000000F to indicate all queues if there is any
1967 * uncertainty.
1968 * Set the mask to 0xFFFFFFF0 to indicate we are being called from a GEM
1969 * ISR.
1970 * 2. We wait for any outstanding transmits on other queues to complete
1971 * because we need to ALWAYS write to the queue 0 pointer to trigger
1972 * internal restart of the DMA process.
1973 * 3. We accept at most MSS_MAC_TX_RING_SIZE-1 packets as the final packet
1974 * in the chain is a dummy one to get the TX DMA engine to stop. Any
1975 * packets beyond that are silently dropped.
1976 *
1977 * We do transmission by using multiple buffer descriptors. The initial
1978 * descriptors are for the packet(s) to transmit and the last is a dummy one
1979 * with the USED bit set. This halts transmission once the first packet is
1980 * transmitted. We always reset the TX DMA to point to the first packet when
1981 * we send packets so we don't have to juggle buffer positions or worry
1982 * about wrap.
1983 */
1984 uint32_t mask_bit;
1985 uint32_t counter;
1986 int32_t status = MSS_MAC_ERR_NOT_DONE;
1987 bool tx_done;
1988 uint32_t queues;
1989 mss_mac_tx_pkt_info_t *tx_rover;
1990 /*
1991 */
1992 int32_t no_crc = 0;
1993 volatile int delay;
1994 volatile uint32_t *p_nw_control;
1995 volatile uint32_t *p_tx_status;
1996
1997 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
1998 {
1999 /* We use these a lot and this cuts down on conditional code later on */
2000 if(0U != this_mac->is_emac)
2001 {
2002 p_nw_control = &this_mac->emac_base->NETWORK_CONTROL;
2003 p_tx_status = &this_mac->emac_base->TRANSMIT_STATUS;
2004 queues = 1;
2005 }
2006 else
2007 {
2008 p_nw_control = &this_mac->mac_base->NETWORK_CONTROL;
2009 p_tx_status = &this_mac->mac_base->TRANSMIT_STATUS;
2010 queues = 4;
2011 }
2012
2013 /* PLIC_DisableIRQ() et al should not be called from the associated interrupt... */
2014 if(0xFFFFFFF0U != queue_mask) /* Not called from ISR */
2015 {
2016 /*
2017 * Make this function atomic w.r.to EMAC interrupt for the queues we
2018 * are using and queue 0.
2019 */
2020 mask_bit = 1;
2021 queue_mask |= 1U; /* Force queue 0 interrupt disable */
2022 for(counter = 0; counter != 4; counter++)
2023 {
2024 if(0 != (mask_bit & queue_mask))
2025 {
2026 if(0U != this_mac->use_local_ints)
2027 {
2028 __disable_local_irq(this_mac->mac_q_int[counter]);
2029 }
2030 else
2031 {
2032 PLIC_DisableIRQ(this_mac->mac_q_int[counter]); /* Single interrupt from GEM? */
2033 }
2034 }
2035
2036 mask_bit <<= 1;
2037 }
2038 }
2039
2040 tx_done = true;
2041 for(counter = 0; counter != queues; counter++)
2042 {
2043 if(this_mac->queue[counter].nb_available_tx_desc != (uint32_t)MSS_MAC_TX_RING_SIZE)
2044 {
2045 tx_done = false; /* Not done if any queue still active */
2046 }
2047 }
2048
2049 if(tx_done)
2050 {
2051 /* Queues are fully available for transmit so clear retry counts */
2052 for(counter = 0; counter != queues; counter++)
2053 {
2054 /* Make sure queue is currently disabled */
2055 *this_mac->queue[counter].transmit_q_ptr = (uint32_t)((uint64_t)this_mac->queue[counter].tx_desc_tab) | 1UL;
2056 this_mac->queue[counter].tries = 0UL;
2057 }
2058
2059
2060 /* Make sure transmit is enabled */
2061 if(0 == (*p_nw_control & GEM_ENABLE_TRANSMIT))
2062 {
2063 *p_nw_control = *p_nw_control | GEM_ENABLE_TRANSMIT;
2064 }
2065 /*
2066 * Wait for pending transmits to complete as you cannot alter
2067 * tx queue pointers while transmit is active...
2068 */
2069 while(0 != (*p_tx_status & GEM_TRANSMIT_GO))
2070 {
2071 delay++; /* Empty loop will cause debug issues... */
2072 }
2073
2074 /* All is quiet now so let's construct the TX queue(s) */
2075
2076 tx_rover = p_packets;
2077 while(0 != tx_rover->length)
2078 {
2079 uint32_t tx_length;
2080 mss_mac_queue_t *p_queue;
2081
2082 tx_length = tx_rover->length;
2083
2084 /* Is config option for disabling CRC set? */
2085 if(MSS_MAC_CRC_DISABLE == this_mac->append_CRC)
2086 {
2087 no_crc = 1;
2088 }
2089
2090 /* Or has the user requested just this packet? */
2091 if(0U != (tx_length & 0x80000000U))
2092 {
2093 no_crc = 1;
2094 tx_length &= 0x7FFFFFFFU; /* Make sure high bit is now clear */
2095 }
2096
2097
2098 /*
2099 * We need to leave one spare at the end to halt the DMA when we
2100 * are done...
2101 */
2102 p_queue = &this_mac->queue[tx_rover->queue_no];
2103 if(p_queue->nb_available_tx_desc > 1)
2104 {
2105 uint32_t position;
2106 mss_mac_tx_desc_t *p_desc;
2107
2108
2109 /* Set up tx descriptor for this packet */
2110 position = MSS_MAC_TX_RING_SIZE - p_queue->nb_available_tx_desc;
2111 p_desc = &p_queue->tx_desc_tab[position];
2112
2113 p_queue->nb_available_tx_desc--;
2114 p_queue->current_tx_desc = 0;
2115 p_desc->addr_low = (uint32_t)((uint64_t)tx_rover->tx_buffer);
2116
2117 /* Mark as last buffer for frame */
2118 p_desc->status = (tx_length & GEM_TX_DMA_BUFF_LEN) | GEM_TX_DMA_LAST;
2119 if(0 != no_crc)
2120 {
2121 p_desc->status |= GEM_TX_DMA_NO_CRC;
2122 }
2123 #if defined(MSS_MAC_64_BIT_ADDRESS_MODE)
2124 p_desc->addr_high = (uint32_t)((uint64_t)tx_rover->tx_buffer >> 32);
2125 p_desc->unused = 0U;
2126 #endif
2127
2128 (p_desc + 1)->status |= GEM_TX_DMA_WRAP | GEM_TX_DMA_USED;
2129 p_queue->tx_caller_info[position] = tx_rover->p_user_data;
2130
2131 p_queue->egress += tx_length;
2132 }
2133
2134 tx_rover++;
2135 }
2136
2137 counter = queues;
2138 while(0 != counter)
2139 {
2140 counter--;
2141 if(this_mac->queue[counter].nb_available_tx_desc != (uint32_t)MSS_MAC_TX_RING_SIZE)
2142 {
2143 *this_mac->queue[counter].transmit_q_ptr = (uint32_t)((uint64_t)&this_mac->queue[counter].tx_desc_tab[0]);
2144 }
2145 }
2146
2147 /* If queue 0 not used we still need a dummy write... */
2148 if(this_mac->queue[0].nb_available_tx_desc == (uint32_t)MSS_MAC_TX_RING_SIZE)
2149 {
2150 *this_mac->queue[0].transmit_q_ptr = (uint32_t)((uint64_t)this_mac->queue[0].tx_desc_tab) | 1U;
2151 }
2152
2153 /* When transmitting at 10M, this delay is needed, 625MHz cpu clock - YMMV */
2154 for(delay = 0; delay != 8; delay++)
2155 {
2156 }
2157
2158 *p_nw_control = *p_nw_control | GEM_TRANSMIT_START;
2159
2160 status = MSS_MAC_ERR_OK;
2161 }
2162 else /* tx_done */
2163 {
2164 /*
2165 * Queues not available so lets check some things...
2166 */
2167 if(0 == (*p_nw_control & GEM_ENABLE_TRANSMIT))
2168 {
2169 /*
2170 * TX is currently disabled so re-enable it and restart the last
2171 * operation on the queues to see if that gets us a completion.
2172 */
2173 counter = queues;
2174 while(0 != counter)
2175 {
2176 counter--;
2177 if(this_mac->queue[counter].nb_available_tx_desc != (uint32_t)MSS_MAC_TX_RING_SIZE)
2178 {
2179 bool test_done = false;
2180 mss_mac_tx_desc_t *p_descriptor;
2181
2182 /* Scan descriptor lists to see where they are at */
2183 p_descriptor = &this_mac->queue[counter].tx_desc_tab[0];
2184 while(!test_done)
2185 {
2186 if((p_descriptor->status & GEM_TX_DMA_USED) && (p_descriptor->status & GEM_TX_DMA_WRAP))
2187 {
2188 /*
2189 * End of chain and no unsent packets...
2190 * Mark as all sent and disable queue.
2191 */
2192 *this_mac->queue[counter].transmit_q_ptr = (uint32_t)((uint64_t)this_mac->queue[counter].tx_desc_tab) | 1U;
2193 this_mac->queue[counter].nb_available_tx_desc = (uint32_t)MSS_MAC_TX_RING_SIZE;
2194 test_done = true;
2195 }
2196 else if(p_descriptor->status & GEM_TX_DMA_USED)
2197 {
2198 /* Used but not last so try next one */
2199 p_descriptor++;
2200 }
2201 else /* Not used - restart from here */
2202 {
2203 this_mac->queue[counter].tx_reenable++;
2204 *this_mac->queue[counter].transmit_q_ptr = (uint32_t)((uint64_t)p_descriptor);
2205 test_done = true;
2206 }
2207 }
2208 }
2209 }
2210
2211 *p_nw_control = *p_nw_control | GEM_ENABLE_TRANSMIT;
2212 /* When transmitting at 10M, this delay is needed, 625MHz cpu clock - YMMV */
2213 for(delay = 0; delay != 8; delay++)
2214 {
2215 }
2216
2217 *p_nw_control = *p_nw_control | GEM_TRANSMIT_START;
2218 }
2219 else
2220 {
2221 /* Kick the tx start bit in case we are stalled... */
2222 this_mac->queue[0].tx_restart++;
2223 *p_nw_control = *p_nw_control | GEM_TRANSMIT_START;
2224 }
2225
2226 /*
2227 * TX might have completed since we entered the function but if we
2228 * seem to be spinning on this and buffers haven't been returned to
2229 * the queue then just give up and reset queue.
2230 */
2231 for(counter = 0; counter != queues; counter++)
2232 {
2233 bool test_done = false;
2234 bool all_sent = false;
2235 mss_mac_tx_desc_t *p_descriptor;
2236
2237 /* Scan descriptor lists to see where they are at */
2238 p_descriptor = &this_mac->queue[counter].tx_desc_tab[0];
2239 while(!test_done)
2240 {
2241 if((p_descriptor->status & GEM_TX_DMA_USED) && (p_descriptor->status & GEM_TX_DMA_WRAP))
2242 {
2243 /*
2244 * End of chain and no unsent packets...
2245 * Mark as all sent and disable queue.
2246 */
2247 all_sent = true;
2248 test_done = true;
2249 }
2250 else if(p_descriptor->status & GEM_TX_DMA_USED)
2251 {
2252 /* Used but not last so try next one */
2253 p_descriptor++;
2254 }
2255 else /* Not used - not all sent yet */
2256 {
2257 test_done = true;
2258 }
2259 }
2260
2261 if(true == all_sent)
2262 {
2263 this_mac->queue[counter].tries++;
2264
2265 if(this_mac->queue[counter].tries > 3) /* Been here too often? */
2266 {
2267 /* Give up and reset FW queue count */
2268 this_mac->queue[counter].nb_available_tx_desc = (uint32_t)MSS_MAC_TX_RING_SIZE;
2269 status = MSS_MAC_ERR_TX_TIMEOUT;
2270 }
2271 }
2272 }
2273
2274 for(counter = 0; counter != queues; counter++) /* Scan for TX fails */
2275 {
2276 bool test_done = false;
2277 mss_mac_tx_desc_t *p_descriptor;
2278
2279 /* Scan descriptor lists to see where they are at */
2280 p_descriptor = &this_mac->queue[counter].tx_desc_tab[0];
2281 while(!test_done)
2282 {
2283 if(p_descriptor->status & (GEM_TX_DMA_RETRY_ERROR | GEM_TX_DMA_UNDERRUN | GEM_TX_DMA_BUS_ERROR | GEM_TX_DMA_LATE_COL_ERROR | GEM_TX_DMA_OFFLOAD_ERRORS))
2284 {
2285 /* Give up and reset FW queue count on first fail */
2286 this_mac->queue[counter].nb_available_tx_desc = (uint32_t)MSS_MAC_TX_RING_SIZE;
2287 status = MSS_MAC_ERR_TX_FAIL;
2288 test_done = true;
2289 }
2290
2291 if(p_descriptor->status & GEM_TX_DMA_WRAP)
2292 {
2293 /* End of chain so bail */
2294 test_done = true;
2295 }
2296
2297 p_descriptor++;
2298 }
2299 }
2300 }
2301
2302 /* Ethernet Interrupt Enable function. */
2303 /* PLIC_DisableIRQ() et al should not be called from the associated interrupt... */
2304 if(0xFFFFFFF0U != queue_mask) /* Not called from ISR */
2305 {
2306 mask_bit = 1;
2307 for(counter = 0; counter != 4; counter++)
2308 {
2309 if(0 != (mask_bit & queue_mask))
2310 {
2311 if(0U != this_mac->use_local_ints)
2312 {
2313 __enable_local_irq(this_mac->mac_q_int[counter]);
2314 }
2315 else
2316 {
2317 PLIC_EnableIRQ(this_mac->mac_q_int[counter]); /* Single interrupt from GEM? */
2318 }
2319 }
2320
2321 mask_bit <<= 1;
2322 }
2323 }
2324 }
2325 return status;
2326 }
2327
2328 #if defined(MSS_MAC_SPEED_TEST)
2329 /* Very stripped down queue 0 packet blaster - assumes full tx queue0 is being
2330 * used on pMAC and does little or no checking. Don't call from GEM interrupts!
2331 * Don't use with local interrupts or eMAC either...
2332 */
2333
copy8b(uint64_t * dest,uint64_t * source,uint32_t count)2334 void copy8b(uint64_t *dest, uint64_t *source, uint32_t count)
2335 {
2336 while(count--)
2337 *dest++ = *source++;
2338 }
2339
2340 int32_t
MSS_MAC_send_pkts_fast(mss_mac_instance_t * this_mac,mss_mac_tx_desc_t * descriptors,uint32_t tx_count)2341 MSS_MAC_send_pkts_fast
2342 (
2343 mss_mac_instance_t *this_mac,
2344 mss_mac_tx_desc_t *descriptors,
2345 uint32_t tx_count
2346 )
2347 {
2348 /*
2349 * Multi packet, multi queue transmit operation which depends on the
2350 * following assumptions:
2351 *
2352 * 1. queue_mask indicates the queues which may be involved so that we can
2353 * properly handle ISR vs normal calling.
2354 * Set the mask to 0x0000000F to indicate all queues if there is any
2355 * uncertainty.
2356 * Set the mask to 0xFFFFFFF0 to indicate we are being called from a GEM
2357 * ISR.
2358 * 2. We wait for any outstanding transmits on other queues to complete
2359 * because we need to ALWAYS write to the queue 0 pointer to trigger
2360 * internal restart of the DMA process.
2361 * 3. We accept at most MSS_MAC_TX_RING_SIZE-1 packets as the final packet
2362 * in the chain is a dummy one to get the TX DMA engine to stop. Any
2363 * packets beyond that are silently dropped.
2364 *
2365 * We do transmission by using multiple buffer descriptors. The initial
2366 * descriptors are for the packet(s) to transmit and the last is a dummy one
2367 * with the USED bit set. This halts transmission once the first packet is
2368 * transmitted. We always reset the TX DMA to point to the first packet when
2369 * we send packets so we don't have to juggle buffer positions or worry
2370 * about wrap.
2371 */
2372 volatile int delay;
2373 volatile uint32_t *p_nw_control;
2374 volatile uint32_t *p_tx_status;
2375
2376 p_nw_control = &this_mac->mac_base->NETWORK_CONTROL;
2377 p_tx_status = &this_mac->mac_base->TRANSMIT_STATUS;
2378
2379 /* Wait for queue to empty */
2380 while(this_mac->queue[0].nb_available_tx_desc != (uint32_t)MSS_MAC_TX_RING_SIZE)
2381 {
2382 /* Make sure transmit stays enabled */
2383 if(0 == (*p_nw_control & GEM_ENABLE_TRANSMIT))
2384 {
2385 *p_nw_control = *p_nw_control | GEM_ENABLE_TRANSMIT;
2386 }
2387 }
2388
2389 PLIC_DisableIRQ(this_mac->mac_q_int[0]); /* Single interrupt from GEM? */
2390
2391 /*
2392 * Wait for pending transmits to complete as you cannot alter
2393 * tx queue pointers while transmit is active...
2394 */
2395 while(0 != (*p_tx_status & GEM_TRANSMIT_GO))
2396 {
2397 delay++; /* Empty loop will cause debug issues... */
2398 }
2399
2400 *this_mac->queue[0].transmit_q_ptr = (uint32_t)((uint64_t)this_mac->queue[0].tx_desc_tab) | 1UL;
2401 this_mac->queue[0].tries = 0UL;
2402
2403 /* All is quiet now so let's construct the TX queue(s) */
2404
2405 copy8b((uint64_t *)this_mac->queue[0].tx_desc_tab, (uint64_t *)descriptors, sizeof(this_mac->queue[0].tx_desc_tab) / 8);
2406
2407 this_mac->queue[0].egress += tx_count;
2408
2409 this_mac->queue[0].nb_available_tx_desc = 1;
2410 this_mac->queue[0].current_tx_desc = 0;
2411 *this_mac->queue[0].transmit_q_ptr = (uint32_t)((uint64_t)&this_mac->queue[0].tx_desc_tab[0]);
2412 *p_nw_control = *p_nw_control | GEM_TRANSMIT_START;
2413
2414 PLIC_EnableIRQ(this_mac->mac_q_int[0]); /* Single interrupt from GEM? */
2415
2416 return(MSS_MAC_ERR_OK);
2417 }
2418
2419 #endif /* defined(MSS_MAC_SPEED_TEST) */
2420
2421 /******************************************************************************
2422 *
2423 */
2424 #if defined(USING_LWIP)
2425 extern BaseType_t g_mac_context_switch;
2426 #endif
2427
2428 #if defined(USING_FREERTOS)
2429 extern UBaseType_t uxCriticalNesting;
2430 #endif
2431 #if defined(TARGET_ALOE)
2432 uint8_t MAC0_plic_53_IRQHandler(void);
MAC0_plic_53_IRQHandler(void)2433 uint8_t MAC0_plic_53_IRQHandler(void)
2434 {
2435 #if defined(USING_FREERTOS)
2436 uxCriticalNesting++;
2437 generic_mac_irq_handler(&g_mac0, 0U);
2438 uxCriticalNesting--;
2439 #else
2440 generic_mac_irq_handler(&g_mac0, 0U);
2441 #endif
2442 return(EXT_IRQ_KEEP_ENABLED);
2443 }
2444 #else
2445
2446
2447 /******************************************************************************
2448 *
2449 */
mac0_int_plic_IRQHandler(void)2450 uint8_t mac0_int_plic_IRQHandler(void)
2451 {
2452 #if defined(USING_FREERTOS)
2453 uxCriticalNesting++;
2454 generic_mac_irq_handler(&g_mac0, 0U);
2455 uxCriticalNesting--;
2456 #else
2457 generic_mac_irq_handler(&g_mac0, 0U);
2458 #endif
2459
2460 return(EXT_IRQ_KEEP_ENABLED);
2461 }
2462
2463
2464 /******************************************************************************
2465 *
2466 */
mac0_queue1_plic_IRQHandler(void)2467 uint8_t mac0_queue1_plic_IRQHandler(void)
2468 {
2469 #if defined(USING_FREERTOS)
2470 uxCriticalNesting++;
2471 generic_mac_irq_handler(&g_mac0, 1U);
2472 uxCriticalNesting--;
2473 #else
2474 generic_mac_irq_handler(&g_mac0, 1U);
2475 #endif
2476 return(EXT_IRQ_KEEP_ENABLED);
2477 }
2478
2479
2480 /******************************************************************************
2481 *
2482 */
mac0_queue2_plic_IRQHandler(void)2483 uint8_t mac0_queue2_plic_IRQHandler(void)
2484 {
2485 #if defined(USING_FREERTOS)
2486 uxCriticalNesting++;
2487 generic_mac_irq_handler(&g_mac0, 2U);
2488 uxCriticalNesting--;
2489 #else
2490 generic_mac_irq_handler(&g_mac0, 2U);
2491 #endif
2492 return(EXT_IRQ_KEEP_ENABLED);
2493 }
2494
2495
2496 /******************************************************************************
2497 *
2498 */
mac0_queue3_plic_IRQHandler(void)2499 uint8_t mac0_queue3_plic_IRQHandler(void)
2500 {
2501 #if defined(USING_FREERTOS)
2502 uxCriticalNesting++;
2503 generic_mac_irq_handler(&g_mac0, 3U);
2504 uxCriticalNesting--;
2505 #else
2506 generic_mac_irq_handler(&g_mac0, 3U);
2507 #endif
2508 return(EXT_IRQ_KEEP_ENABLED);
2509 }
2510
2511
2512 /******************************************************************************
2513 *
2514 */
mac0_emac_plic_IRQHandler(void)2515 uint8_t mac0_emac_plic_IRQHandler(void)
2516 {
2517 #if defined(USING_FREERTOS)
2518 uxCriticalNesting++;
2519 generic_mac_irq_handler(&g_emac0, 0U);
2520 uxCriticalNesting--;
2521 #else
2522 generic_mac_irq_handler(&g_emac0, 0U);
2523 #endif
2524 return(EXT_IRQ_KEEP_ENABLED);
2525 }
2526
2527
2528 /******************************************************************************
2529 *
2530 */
mac0_mmsl_plic_IRQHandler(void)2531 uint8_t mac0_mmsl_plic_IRQHandler(void)
2532 {
2533 g_mac0.mac_base->MMSL_INT_DISABLE = 0x3F; /* Acknowledge ints */
2534 return(EXT_IRQ_KEEP_ENABLED);
2535 }
2536
2537
2538
2539 /******************************************************************************
2540 *
2541 */
mac1_int_plic_IRQHandler(void)2542 uint8_t mac1_int_plic_IRQHandler(void)
2543 {
2544 #if defined(USING_FREERTOS)
2545 uxCriticalNesting++;
2546 generic_mac_irq_handler(&g_mac1, 0U);
2547 uxCriticalNesting--;
2548 #else
2549 generic_mac_irq_handler(&g_mac1, 0U);
2550 #endif
2551 return(EXT_IRQ_KEEP_ENABLED);
2552 }
2553
2554
2555 /******************************************************************************
2556 *
2557 */
mac1_queue1_plic_IRQHandler(void)2558 uint8_t mac1_queue1_plic_IRQHandler(void)
2559 {
2560 #if defined(USING_FREERTOS)
2561 uxCriticalNesting++;
2562 generic_mac_irq_handler(&g_mac1, 1U);
2563 uxCriticalNesting--;
2564 #else
2565 generic_mac_irq_handler(&g_mac1, 1U);
2566 #endif
2567 return(EXT_IRQ_KEEP_ENABLED);
2568 }
2569
2570
2571 /******************************************************************************
2572 *
2573 */
mac1_queue2_plic_IRQHandler(void)2574 uint8_t mac1_queue2_plic_IRQHandler(void)
2575 {
2576 #if defined(USING_FREERTOS)
2577 uxCriticalNesting++;
2578 generic_mac_irq_handler(&g_mac1, 2U);
2579 uxCriticalNesting--;
2580 #else
2581 generic_mac_irq_handler(&g_mac1, 2U);
2582 #endif
2583 return(EXT_IRQ_KEEP_ENABLED);
2584 }
2585
2586
2587 /******************************************************************************
2588 *
2589 */
mac1_queue3_plic_IRQHandler(void)2590 uint8_t mac1_queue3_plic_IRQHandler(void)
2591 {
2592 #if defined(USING_FREERTOS)
2593 uxCriticalNesting++;
2594 generic_mac_irq_handler(&g_mac1, 3U);
2595 uxCriticalNesting--;
2596 #else
2597 generic_mac_irq_handler(&g_mac1, 3U);
2598 #endif
2599 return(EXT_IRQ_KEEP_ENABLED);
2600 }
2601
2602
2603 /******************************************************************************
2604 *
2605 */
mac1_emac_plic_IRQHandler(void)2606 uint8_t mac1_emac_plic_IRQHandler(void)
2607 {
2608 #if defined(USING_FREERTOS)
2609 uxCriticalNesting++;
2610 generic_mac_irq_handler(&g_emac1, 0U);
2611 uxCriticalNesting--;
2612 #else
2613 generic_mac_irq_handler(&g_emac1, 0U);
2614 #endif
2615 return(EXT_IRQ_KEEP_ENABLED);
2616 }
2617
2618
2619 /******************************************************************************
2620 *
2621 */
mac1_mmsl_plic_IRQHandler(void)2622 uint8_t mac1_mmsl_plic_IRQHandler(void)
2623 {
2624 g_mac1.mac_base->MMSL_INT_DISABLE = 0x3F; /* Acknowledge ints */
2625 return(EXT_IRQ_KEEP_ENABLED);
2626 }
2627
2628
2629 /******************************************************************************
2630 *
2631 */
2632 /* U54 1 */
mac_mmsl_u54_1_local_IRQHandler_3(void)2633 void mac_mmsl_u54_1_local_IRQHandler_3(void)
2634 {
2635 g_mac0.mac_base->MMSL_INT_DISABLE = 0x3F; /* Acknowledge ints */
2636 }
2637
2638
2639 /******************************************************************************
2640 *
2641 */
mac_emac_u54_1_local_IRQHandler_4(void)2642 void mac_emac_u54_1_local_IRQHandler_4(void)
2643 {
2644 #if defined(USING_FREERTOS)
2645 uxCriticalNesting++;
2646 generic_mac_irq_handler(&g_emac0, 0U);
2647 uxCriticalNesting--;
2648 #else
2649 generic_mac_irq_handler(&g_emac0, 0U);
2650 #endif
2651 #if defined(USING_LWIP)
2652 if(0 != g_mac_context_switch)
2653 {
2654 g_mac_context_switch = 0;
2655 vPortYieldISR();
2656 }
2657 #endif
2658 }
2659
2660
2661 /******************************************************************************
2662 *
2663 */
mac_queue3_u54_1_local_IRQHandler_5(void)2664 void mac_queue3_u54_1_local_IRQHandler_5(void)
2665 {
2666 #if defined(USING_FREERTOS)
2667 uxCriticalNesting++;
2668 generic_mac_irq_handler(&g_mac0, 3U);
2669 uxCriticalNesting--;
2670 #else
2671 generic_mac_irq_handler(&g_mac0, 3U);
2672 #endif
2673 #if defined(USING_LWIP)
2674 if(0 != g_mac_context_switch)
2675 {
2676 g_mac_context_switch = 0;
2677 vPortYieldISR();
2678 }
2679 #endif
2680 }
2681
2682
2683 /******************************************************************************
2684 *
2685 */
mac_queue2_u54_1_local_IRQHandler_6(void)2686 void mac_queue2_u54_1_local_IRQHandler_6(void)
2687 {
2688 #if defined(USING_FREERTOS)
2689 uxCriticalNesting++;
2690 generic_mac_irq_handler(&g_mac0, 2U);
2691 uxCriticalNesting--;
2692 #else
2693 generic_mac_irq_handler(&g_mac0, 2U);
2694 #endif
2695 #if defined(USING_LWIP)
2696 if(0 != g_mac_context_switch)
2697 {
2698 g_mac_context_switch = 0;
2699 vPortYieldISR();
2700 }
2701 #endif
2702 }
2703
2704
2705 /******************************************************************************
2706 *
2707 */
mac_queue1_u54_1_local_IRQHandler_7(void)2708 void mac_queue1_u54_1_local_IRQHandler_7(void)
2709 {
2710 #if defined(USING_FREERTOS)
2711 uxCriticalNesting++;
2712 generic_mac_irq_handler(&g_mac0, 1U);
2713 uxCriticalNesting--;
2714 #else
2715 generic_mac_irq_handler(&g_mac0, 1U);
2716 #endif
2717 #if defined(USING_LWIP)
2718 if(0 != g_mac_context_switch)
2719 {
2720 g_mac_context_switch = 0;
2721 vPortYieldISR();
2722 }
2723 #endif
2724 }
2725
2726
2727 /******************************************************************************
2728 *
2729 */
mac_int_u54_1_local_IRQHandler_8(void)2730 void mac_int_u54_1_local_IRQHandler_8(void)
2731 {
2732 #if defined(USING_FREERTOS)
2733 uxCriticalNesting++;
2734 generic_mac_irq_handler(&g_mac0, 0U);
2735 uxCriticalNesting--;
2736 #else
2737 generic_mac_irq_handler(&g_mac0, 0U);
2738 #endif
2739 #if defined(USING_LWIP)
2740 if(0 != g_mac_context_switch)
2741 {
2742 g_mac_context_switch = 0;
2743 vPortYieldISR();
2744 }
2745 #endif
2746 }
2747
2748
2749 /******************************************************************************
2750 *
2751 */
2752 /* U54 2 */
mac_mmsl_u54_2_local_IRQHandler_3(void)2753 void mac_mmsl_u54_2_local_IRQHandler_3(void)
2754 {
2755 g_mac0.mac_base->MMSL_INT_DISABLE = 0x3F; /* Acknowledge ints */
2756 }
2757
2758
2759 /******************************************************************************
2760 *
2761 */
mac_emac_u54_2_local_IRQHandler_4(void)2762 void mac_emac_u54_2_local_IRQHandler_4(void)
2763 {
2764 #if defined(USING_FREERTOS)
2765 uxCriticalNesting++;
2766 generic_mac_irq_handler(&g_emac0, 0U);
2767 uxCriticalNesting--;
2768 #else
2769 generic_mac_irq_handler(&g_emac0, 0U);
2770 #endif
2771 #if defined(USING_LWIP)
2772 if(0 != g_mac_context_switch)
2773 {
2774 g_mac_context_switch = 0;
2775 vPortYieldISR();
2776 }
2777 #endif
2778 }
2779
2780
2781 /******************************************************************************
2782 *
2783 */
mac_queue3_u54_2_local_IRQHandler_5(void)2784 void mac_queue3_u54_2_local_IRQHandler_5(void)
2785 {
2786 #if defined(USING_FREERTOS)
2787 uxCriticalNesting++;
2788 generic_mac_irq_handler(&g_mac0, 3U);
2789 uxCriticalNesting--;
2790 #else
2791 generic_mac_irq_handler(&g_mac0, 3U);
2792 #endif
2793 #if defined(USING_LWIP)
2794 if(0 != g_mac_context_switch)
2795 {
2796 g_mac_context_switch = 0;
2797 vPortYieldISR();
2798 }
2799 #endif
2800 }
2801
2802
2803 /******************************************************************************
2804 *
2805 */
mac_queue2_u54_2_local_IRQHandler_6(void)2806 void mac_queue2_u54_2_local_IRQHandler_6(void)
2807 {
2808 #if defined(USING_FREERTOS)
2809 uxCriticalNesting++;
2810 generic_mac_irq_handler(&g_mac0, 2U);
2811 uxCriticalNesting--;
2812 #else
2813 generic_mac_irq_handler(&g_mac0, 2U);
2814 #endif
2815 #if defined(USING_LWIP)
2816 if(0 != g_mac_context_switch)
2817 {
2818 g_mac_context_switch = 0;
2819 vPortYieldISR();
2820 }
2821 #endif
2822 }
2823
2824
2825 /******************************************************************************
2826 *
2827 */
mac_queue1_u54_2_local_IRQHandler_7(void)2828 void mac_queue1_u54_2_local_IRQHandler_7(void)
2829 {
2830 #if defined(USING_FREERTOS)
2831 uxCriticalNesting++;
2832 generic_mac_irq_handler(&g_mac0, 1U);
2833 uxCriticalNesting--;
2834 #else
2835 generic_mac_irq_handler(&g_mac0, 1U);
2836 #endif
2837 #if defined(USING_LWIP)
2838 if(0 != g_mac_context_switch)
2839 {
2840 g_mac_context_switch = 0;
2841 vPortYieldISR();
2842 }
2843 #endif
2844 }
2845
2846
2847 /******************************************************************************
2848 *
2849 */
mac_int_u54_2_local_IRQHandler_8(void)2850 void mac_int_u54_2_local_IRQHandler_8(void)
2851 {
2852 #if defined(USING_FREERTOS)
2853 uxCriticalNesting++;
2854 generic_mac_irq_handler(&g_mac0, 0U);
2855 uxCriticalNesting--;
2856 #else
2857 generic_mac_irq_handler(&g_mac0, 0U);
2858 #endif
2859 #if defined(USING_LWIP)
2860 if(0 != g_mac_context_switch)
2861 {
2862 g_mac_context_switch = 0;
2863 vPortYieldISR();
2864 }
2865 #endif
2866 }
2867
2868
2869 /******************************************************************************
2870 *
2871 */
2872 /* U54 3 */
mac_mmsl_u54_3_local_IRQHandler_3(void)2873 void mac_mmsl_u54_3_local_IRQHandler_3(void)
2874 {
2875 g_mac1.mac_base->MMSL_INT_DISABLE = 0x3F; /* Acknowledge ints */
2876 }
2877
2878
2879 /******************************************************************************
2880 *
2881 */
mac_emac_u54_3_local_IRQHandler_4(void)2882 void mac_emac_u54_3_local_IRQHandler_4(void)
2883 {
2884 #if defined(USING_FREERTOS)
2885 uxCriticalNesting++;
2886 generic_mac_irq_handler(&g_emac1, 0U);
2887 uxCriticalNesting--;
2888 #else
2889 generic_mac_irq_handler(&g_emac1, 0U);
2890 #endif
2891 #if defined(USING_LWIP)
2892 if(0 != g_mac_context_switch)
2893 {
2894 g_mac_context_switch = 0;
2895 vPortYieldISR();
2896 }
2897 #endif
2898 }
2899
2900
2901 /******************************************************************************
2902 *
2903 */
mac_queue3_u54_3_local_IRQHandler_5(void)2904 void mac_queue3_u54_3_local_IRQHandler_5(void)
2905 {
2906 #if defined(USING_FREERTOS)
2907 uxCriticalNesting++;
2908 generic_mac_irq_handler(&g_mac1, 3U);
2909 uxCriticalNesting--;
2910 #else
2911 generic_mac_irq_handler(&g_mac1, 3U);
2912 #endif
2913 #if defined(USING_LWIP)
2914 if(0 != g_mac_context_switch)
2915 {
2916 g_mac_context_switch = 0;
2917 vPortYieldISR();
2918 }
2919 #endif
2920 }
2921
2922
2923 /******************************************************************************
2924 *
2925 */
mac_queue2_u54_3_local_IRQHandler_6(void)2926 void mac_queue2_u54_3_local_IRQHandler_6(void)
2927 {
2928 #if defined(USING_FREERTOS)
2929 uxCriticalNesting++;
2930 generic_mac_irq_handler(&g_mac1, 2U);
2931 uxCriticalNesting--;
2932 #else
2933 generic_mac_irq_handler(&g_mac1, 2U);
2934 #endif
2935 #if defined(USING_LWIP)
2936 if(0 != g_mac_context_switch)
2937 {
2938 g_mac_context_switch = 0;
2939 vPortYieldISR();
2940 }
2941 #endif
2942 }
2943
2944
2945 /******************************************************************************
2946 *
2947 */
mac_queue1_u54_3_local_IRQHandler_7(void)2948 void mac_queue1_u54_3_local_IRQHandler_7(void)
2949 {
2950 #if defined(USING_FREERTOS)
2951 uxCriticalNesting++;
2952 generic_mac_irq_handler(&g_mac1, 1U);
2953 uxCriticalNesting--;
2954 #else
2955 generic_mac_irq_handler(&g_mac1, 1U);
2956 #endif
2957 #if defined(USING_LWIP)
2958 if(0 != g_mac_context_switch)
2959 {
2960 g_mac_context_switch = 0;
2961 vPortYieldISR();
2962 }
2963 #endif
2964 }
2965
2966
2967 /******************************************************************************
2968 *
2969 */
mac_int_u54_3_local_IRQHandler_8(void)2970 void mac_int_u54_3_local_IRQHandler_8(void)
2971 {
2972 #if defined(USING_FREERTOS)
2973 uxCriticalNesting++;
2974 generic_mac_irq_handler(&g_mac1, 0U);
2975 uxCriticalNesting--;
2976 #else
2977 generic_mac_irq_handler(&g_mac1, 0U);
2978 #endif
2979 #if defined(USING_LWIP)
2980 if(0 != g_mac_context_switch)
2981 {
2982 g_mac_context_switch = 0;
2983 vPortYieldISR();
2984 }
2985 #endif
2986 }
2987
2988
2989 /******************************************************************************
2990 *
2991 */
2992 /* U54 4 */
mac_mmsl_u54_4_local_IRQHandler_3(void)2993 void mac_mmsl_u54_4_local_IRQHandler_3(void)
2994 {
2995 g_mac1.mac_base->MMSL_INT_DISABLE = 0x3F; /* Acknowledge ints */
2996 }
2997
2998
2999 /******************************************************************************
3000 *
3001 */
mac_emac_u54_4_local_IRQHandler_4(void)3002 void mac_emac_u54_4_local_IRQHandler_4(void)
3003 {
3004 #if defined(USING_FREERTOS)
3005 uxCriticalNesting++;
3006 generic_mac_irq_handler(&g_emac1, 0U);
3007 uxCriticalNesting--;
3008 #else
3009 generic_mac_irq_handler(&g_emac1, 0U);
3010 #endif
3011 #if defined(USING_LWIP)
3012 if(0 != g_mac_context_switch)
3013 {
3014 g_mac_context_switch = 0;
3015 vPortYieldISR();
3016 }
3017 #endif
3018 }
3019
3020
3021 /******************************************************************************
3022 *
3023 */
mac_queue3_u54_4_local_IRQHandler_5(void)3024 void mac_queue3_u54_4_local_IRQHandler_5(void)
3025 {
3026 #if defined(USING_FREERTOS)
3027 uxCriticalNesting++;
3028 generic_mac_irq_handler(&g_mac1, 3U);
3029 uxCriticalNesting--;
3030 #else
3031 generic_mac_irq_handler(&g_mac1, 3U);
3032 #endif
3033 #if defined(USING_LWIP)
3034 if(0 != g_mac_context_switch)
3035 {
3036 g_mac_context_switch = 0;
3037 vPortYieldISR();
3038 }
3039 #endif
3040 }
3041
3042
3043 /******************************************************************************
3044 *
3045 */
mac_queue2_u54_4_local_IRQHandler_6(void)3046 void mac_queue2_u54_4_local_IRQHandler_6(void)
3047 {
3048 #if defined(USING_FREERTOS)
3049 uxCriticalNesting++;
3050 generic_mac_irq_handler(&g_mac1, 2U);
3051 uxCriticalNesting--;
3052 #else
3053 generic_mac_irq_handler(&g_mac1, 2U);
3054 #endif
3055 #if defined(USING_LWIP)
3056 if(0 != g_mac_context_switch)
3057 {
3058 g_mac_context_switch = 0;
3059 vPortYieldISR();
3060 }
3061 #endif
3062 }
3063
3064
3065 /******************************************************************************
3066 *
3067 */
mac_queue1_u54_4_local_IRQHandler_7(void)3068 void mac_queue1_u54_4_local_IRQHandler_7(void)
3069 {
3070 #if defined(USING_FREERTOS)
3071 uxCriticalNesting++;
3072 generic_mac_irq_handler(&g_mac1, 1U);
3073 uxCriticalNesting--;
3074 #else
3075 generic_mac_irq_handler(&g_mac1, 1U);
3076 #endif
3077 #if defined(USING_LWIP)
3078 if(0 != g_mac_context_switch)
3079 {
3080 g_mac_context_switch = 0;
3081 vPortYieldISR();
3082 }
3083 #endif
3084 }
3085
3086
3087 /******************************************************************************
3088 *
3089 */
mac_int_u54_4_local_IRQHandler_8(void)3090 void mac_int_u54_4_local_IRQHandler_8(void)
3091 {
3092 #if defined(USING_FREERTOS)
3093 uxCriticalNesting++;
3094 generic_mac_irq_handler(&g_mac1, 0U);
3095 uxCriticalNesting--;
3096 #else
3097 generic_mac_irq_handler(&g_mac1, 0U);
3098 #endif
3099 #if defined(USING_LWIP)
3100 if(0 != g_mac_context_switch)
3101 {
3102 g_mac_context_switch = 0;
3103 vPortYieldISR();
3104 }
3105 #endif
3106 }
3107
3108 #endif
3109
3110
3111 /* Define the following if your GEM is configured to clear on read for int flags
3112 * In this case you should not write to the int status reg ... */
3113 /* #define GEM_FLAGS_CLR_ON_RD */
3114
generic_mac_irq_handler(mss_mac_instance_t * this_mac,uint64_t queue_no)3115 static void generic_mac_irq_handler(mss_mac_instance_t *this_mac, uint64_t queue_no)
3116 {
3117 volatile uint32_t int_pending; /* We read and hold a working copy as many
3118 * of the bits can be clear on read if
3119 * the GEM is configured that way... */
3120 uint32_t volatile *rx_status; /* Address of receive status register */
3121 uint32_t volatile *tx_status; /* Address of transmit status register */
3122 uint32_t volatile *int_status; /* Address of interrupt status register */
3123 mss_mac_queue_t *p_queue;
3124
3125 p_queue = &this_mac->queue[queue_no];
3126
3127 p_queue->in_isr = 1U;
3128 int_status = p_queue->int_status;
3129 int_pending = *int_status;
3130
3131 if(0U != this_mac->is_emac)
3132 {
3133 rx_status = &this_mac->emac_base->RECEIVE_STATUS;
3134 tx_status = &this_mac->emac_base->TRANSMIT_STATUS;
3135 }
3136 else
3137 {
3138 rx_status = &this_mac->mac_base->RECEIVE_STATUS;
3139 tx_status = &this_mac->mac_base->TRANSMIT_STATUS;
3140 }
3141
3142 /*
3143 * Note, in the following code we generally clear any flags first and then
3144 * handle the condition as this allows any new events which occur in the
3145 * course of the ISR to be picked up later.
3146 */
3147
3148 /*
3149 * Packet received interrupt - first in line as most time critical. Followed
3150 * by transmit interrupt and then the less frequent ones.
3151 */
3152 if((int_pending & GEM_RECEIVE_COMPLETE) != 0U)
3153 {
3154 *rx_status = GEM_FRAME_RECEIVED;
3155 #if !defined(GEM_FLAGS_CLR_ON_RD)
3156 #if defined(TARGET_ALOE)
3157 *int_status = (uint32_t)3U; /* PMCS: Should be 2 but that does not work on Aloe... */
3158 #else
3159 *int_status = (uint32_t)2U;
3160 #endif
3161 rxpkt_handler(this_mac, queue_no);
3162 p_queue->overflow_counter = 0U; /* Reset counter as we have received something */
3163 #endif
3164 }
3165
3166 /* Transmit packet sent interrupt */
3167 if((int_pending & GEM_TRANSMIT_COMPLETE) != 0U)
3168 {
3169 if((*tx_status & GEM_STAT_TRANSMIT_COMPLETE) != 0U) /* If loopback test or other hasn't taken care of this... */
3170 {
3171 *tx_status = GEM_STAT_TRANSMIT_COMPLETE;
3172 *int_status = GEM_TRANSMIT_COMPLETE;
3173 #if !defined(GEM_FLAGS_CLR_ON_RD)
3174 #endif
3175 txpkt_handler(this_mac, queue_no);
3176 }
3177 }
3178
3179 /*
3180 * RX and TX are the majority cases so see if all done rather than testing
3181 * remaining one by one. Move on to one by one testing if not finished. Cuts
3182 * down on interrupt processing impact for 'normal' case...
3183 */
3184 if((int_pending & ~(GEM_RECEIVE_COMPLETE | GEM_TRANSMIT_COMPLETE)) != 0U)
3185 {
3186 if((int_pending & GEM_RECEIVE_OVERRUN_INT) != 0U)
3187 {
3188 *rx_status = GEM_RECEIVE_OVERRUN;
3189 #if !defined(GEM_FLAGS_CLR_ON_RD)
3190 *int_status = GEM_RECEIVE_OVERRUN_INT;
3191 #endif
3192 p_queue->overflow_counter++;
3193 p_queue->rx_overflow++;
3194 }
3195
3196 if((int_pending & GEM_RX_USED_BIT_READ) != 0U)
3197 {
3198 *rx_status = GEM_BUFFER_NOT_AVAILABLE;
3199 #if !defined(GEM_FLAGS_CLR_ON_RD)
3200 *int_status = GEM_RX_USED_BIT_READ;
3201 #endif
3202 rxpkt_handler(this_mac, queue_no);
3203 p_queue->rx_overflow++;
3204 p_queue->overflow_counter++;
3205 }
3206
3207 if((int_pending & GEM_RESP_NOT_OK_INT) != 0U) /* Hope this is transient and restart rx... */
3208 {
3209 *rx_status = GEM_RX_RESP_NOT_OK; /* One of them did it... */
3210 *tx_status = GEM_TX_RESP_NOT_OK;
3211 #if !defined(GEM_FLAGS_CLR_ON_RD)
3212 *int_status = GEM_RESP_NOT_OK_INT;
3213 #endif
3214 if(0U != this_mac->is_emac)
3215 {
3216 this_mac->emac_base->NETWORK_CONTROL |= GEM_ENABLE_RECEIVE;
3217 }
3218 else
3219 {
3220 this_mac->mac_base->NETWORK_CONTROL |= GEM_ENABLE_RECEIVE;
3221 }
3222
3223 p_queue->hresp_error++;
3224 }
3225
3226 /*
3227 * This may cause more problems than it cures so disabling for now until we
3228 * figure out a better strategy...
3229 */
3230 #if 0
3231 if(p_queue->overflow_counter > 4U) /* looks like we are stuck in a rut here... */
3232 {
3233 uint32_t descriptor;
3234 /* Restart receive operation from scratch */
3235 p_queue->overflow_counter = 0U;
3236 p_queue->rx_restart++;
3237
3238 if(0U != this_mac->is_emac)
3239 {
3240 this_mac->emac_base->NETWORK_CONTROL &= ~GEM_ENABLE_RECEIVE;
3241 }
3242 else
3243 {
3244 this_mac->mac_base->NETWORK_CONTROL &= ~GEM_ENABLE_RECEIVE;
3245 }
3246
3247 p_queue->nb_available_rx_desc = MSS_MAC_RX_RING_SIZE;
3248 p_queue->next_free_rx_desc_index = 0U;
3249 p_queue->first_rx_desc_index = 0U;
3250
3251 for(descriptor = 0U; descriptor < MSS_MAC_RX_RING_SIZE; descriptor++) /* Discard everything */
3252 {
3253 p_queue->rx_desc_tab[descriptor].addr_low &= ~GEM_RX_DMA_USED;
3254 }
3255
3256 if(0U != this_mac->is_emac)
3257 {
3258 this_mac->emac_base->RECEIVE_Q_PTR = (uint32_t)((uint64_t)p_queue->rx_desc_tab);
3259 #if defined(MSS_MAC_64_BIT_ADDRESS_MODE)
3260 this_mac->emac_base->UPPER_RX_Q_BASE_ADDR = (uint32_t)((uint64_t)p_queue->rx_desc_tab >> 32);
3261 #endif
3262 this_mac->emac_base->NETWORK_CONTROL |= GEM_ENABLE_RECEIVE;
3263 }
3264 else
3265 {
3266 this_mac->mac_base->RECEIVE_Q_PTR = (uint32_t)((uint64_t)p_queue->rx_desc_tab);
3267 #if defined(MSS_MAC_64_BIT_ADDRESS_MODE)
3268 this_mac->mac_base->UPPER_RX_Q_BASE_ADDR = (uint32_t)((uint64_t)p_queue->rx_desc_tab >> 32);
3269 #endif
3270 this_mac->mac_base->NETWORK_CONTROL |= GEM_ENABLE_RECEIVE;
3271 }
3272 }
3273 #endif
3274 if((int_pending & GEM_PAUSE_FRAME_TRANSMITTED) != 0U)
3275 {
3276 *int_status = GEM_PAUSE_FRAME_TRANSMITTED;
3277 this_mac->tx_pause++;
3278 }
3279 if((int_pending & GEM_PAUSE_TIME_ELAPSED) != 0U)
3280 {
3281 *int_status = GEM_PAUSE_TIME_ELAPSED;
3282 this_mac->pause_elapsed++;
3283 }
3284 if((int_pending & GEM_PAUSE_FRAME_WITH_NON_0_PAUSE_QUANTUM_RX) != 0U)
3285 {
3286 *int_status = GEM_PAUSE_FRAME_WITH_NON_0_PAUSE_QUANTUM_RX;
3287 this_mac->rx_pause++;
3288 }
3289
3290 /* Mask off checked ints and see if any left pending */
3291 int_pending &= ~(GEM_RECEIVE_OVERRUN_INT | GEM_RX_USED_BIT_READ | GEM_RECEIVE_COMPLETE |
3292 GEM_TRANSMIT_COMPLETE | GEM_RESP_NOT_OK_INT | GEM_PAUSE_FRAME_TRANSMITTED |
3293 GEM_PAUSE_TIME_ELAPSED | GEM_PAUSE_FRAME_WITH_NON_0_PAUSE_QUANTUM_RX);
3294 if(0U != int_pending)
3295 {
3296 if((int_pending & GEM_AMBA_ERROR) != 0U)
3297 {
3298 /* *int_status = (uint32_t)0x60U; */ /* Should be 0x40 but that doesn't clear it... */
3299 *int_status = (uint32_t)0x40U;
3300 *tx_status = GEM_STAT_AMBA_ERROR;
3301 *rx_status = GEM_AMBA_ERROR;
3302 p_queue->tx_amba_errors++;
3303 p_queue->nb_available_tx_desc = MSS_MAC_TX_RING_SIZE;
3304 }
3305 else
3306 {
3307 volatile int32_t index;
3308 ASSERT(0); /* Need to think about how to deal with this... */
3309 while(1)
3310 {
3311 index++;
3312 }
3313 }
3314 }
3315 }
3316 p_queue->in_isr = 0U;
3317 }
3318
3319
3320 /******************************************************************************
3321 * See mss_ethernet_mac.h for details of how to use this function.
3322 */
MSS_MAC_set_tx_callback(mss_mac_instance_t * this_mac,uint32_t queue_no,mss_mac_transmit_callback_t tx_complete_handler)3323 void MSS_MAC_set_tx_callback
3324 (
3325 mss_mac_instance_t *this_mac,
3326 uint32_t queue_no,
3327 mss_mac_transmit_callback_t tx_complete_handler
3328 )
3329 {
3330 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3331 {
3332 this_mac->queue[queue_no].pckt_tx_callback = tx_complete_handler;
3333 }
3334 }
3335
3336
3337 /******************************************************************************
3338 * See mss_ethernet_mac.h for details of how to use this function.
3339 */
MSS_MAC_set_rx_callback(mss_mac_instance_t * this_mac,uint32_t queue_no,mss_mac_receive_callback_t rx_callback)3340 void MSS_MAC_set_rx_callback
3341 (
3342 mss_mac_instance_t *this_mac,
3343 uint32_t queue_no,
3344 mss_mac_receive_callback_t rx_callback
3345 )
3346 {
3347 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3348 {
3349 this_mac->queue[queue_no].pckt_rx_callback = rx_callback;
3350 }
3351 }
3352
3353
3354 /******************************************************************************
3355 * See mss_ethernet_mac.h for details of how to use this function.
3356 */
MSS_MAC_change_speed(mss_mac_instance_t * this_mac,uint32_t speed_duplex_select,mss_mac_speed_mode_t speed_mode)3357 void MSS_MAC_change_speed
3358 (
3359 mss_mac_instance_t *this_mac, uint32_t speed_duplex_select, mss_mac_speed_mode_t speed_mode
3360 )
3361 {
3362 uint32_t temp_cr;
3363
3364 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3365 {
3366 /* Only change HW settings if there is a change in status */
3367 if((this_mac->speed_duplex_select |= speed_duplex_select) || (this_mac->speed_mode != speed_mode))
3368 {
3369 this_mac->speed_duplex_select = speed_duplex_select;
3370 this_mac->speed_mode = speed_mode;
3371
3372 /* Apply settings to the PHY */
3373 this_mac->phy_set_link_speed(this_mac, this_mac->speed_duplex_select, speed_mode);
3374 this_mac->phy_autonegotiate(this_mac); /* Do this in case it is needed */
3375 if(MSS_MAC_SPEED_AN == speed_mode) /* Apply results of AN to MAC */
3376 {
3377 update_mac_cfg(this_mac);
3378 }
3379 else
3380 {
3381 if(0U != this_mac->is_emac)
3382 {
3383 temp_cr = this_mac->emac_base->NETWORK_CONFIG;
3384 }
3385 else
3386 {
3387 temp_cr = this_mac->mac_base->NETWORK_CONFIG;
3388 }
3389
3390 temp_cr &= ~(GEM_GIGABIT_MODE_ENABLE | GEM_SPEED | GEM_FULL_DUPLEX);
3391
3392 if((MSS_MAC_1000_HDX == this_mac->speed_mode) || (MSS_MAC_1000_FDX == this_mac->speed_mode))
3393 {
3394 #if defined(TARGET_ALOE)
3395 *GEMGXL_tx_clk_sel = (uint32_t)0U;
3396 *GEMGXL_speed_mode = (uint32_t)2U;
3397 #endif
3398 temp_cr |= GEM_GIGABIT_MODE_ENABLE;
3399 }
3400 else
3401 {
3402 if((MSS_MAC_100_HDX == this_mac->speed_mode) || (MSS_MAC_100_FDX == this_mac->speed_mode))
3403 {
3404 #if defined(TARGET_ALOE)
3405 *GEMGXL_tx_clk_sel = (uint32_t)1U;
3406 *GEMGXL_speed_mode = (uint32_t)1U;
3407 #endif
3408 temp_cr |= (uint32_t)GEM_SPEED;
3409 }
3410 #if defined(TARGET_ALOE)
3411 else
3412 {
3413 *GEMGXL_tx_clk_sel = (uint32_t)1U;
3414 *GEMGXL_speed_mode = (uint32_t)0U;
3415 }
3416 #endif
3417 }
3418
3419 /* Configure duplex mode */
3420 if((MSS_MAC_10_FDX == this_mac->speed_mode) || (MSS_MAC_100_FDX == this_mac->speed_mode) || (MSS_MAC_1000_FDX == this_mac->speed_mode))
3421 {
3422 temp_cr |= GEM_FULL_DUPLEX;
3423 }
3424
3425 if(0U != this_mac->is_emac)
3426 {
3427 this_mac->emac_base->NETWORK_CONFIG = temp_cr;
3428 }
3429 else
3430 {
3431 this_mac->mac_base->NETWORK_CONFIG = temp_cr;
3432 }
3433 }
3434 }
3435 }
3436 }
3437
3438
3439 /******************************************************************************
3440 * See mss_ethernet_mac.h for details of how to use this function.
3441 */
3442
MSS_MAC_init_TSU(const mss_mac_instance_t * this_mac,const mss_mac_tsu_config_t * tsu_cfg)3443 void MSS_MAC_init_TSU(const mss_mac_instance_t *this_mac, const mss_mac_tsu_config_t *tsu_cfg)
3444 {
3445 uint32_t temp;
3446
3447 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3448 {
3449 temp = (tsu_cfg->sub_ns_inc & 0xFFU) << 24;
3450 temp |= (tsu_cfg->sub_ns_inc >> 8) & 0xFFFFU;
3451
3452 if(0U != this_mac->is_emac)
3453 {
3454 #if 0 /* Shouldn't really allow setting of tsu through eMAC as it is slaved to pMAC TSU */
3455 this_mac->emac_base->TSU_TIMER_INCR_SUB_NSEC = temp;
3456 this_mac->emac_base->TSU_TIMER_INCR = tsu_cfg->ns_inc;
3457
3458 /* PMCS: I'm not 100% sure about the sequencing here... */
3459
3460 this_mac->emac_base->TSU_TIMER_MSB_SEC = tsu_cfg->secs_msb;
3461 this_mac->emac_base->TSU_TIMER_SEC = tsu_cfg->secs_lsb;
3462 this_mac->emac_base->TSU_TIMER_NSEC = tsu_cfg->nanoseconds;
3463 #endif
3464 }
3465 else
3466 {
3467 this_mac->mac_base->TSU_TIMER_INCR_SUB_NSEC = temp;
3468 this_mac->mac_base->TSU_TIMER_INCR = tsu_cfg->ns_inc;
3469 this_mac->mac_base->TSU_TIMER_MSB_SEC = tsu_cfg->secs_msb;
3470 this_mac->mac_base->TSU_TIMER_SEC = tsu_cfg->secs_lsb;
3471 this_mac->mac_base->TSU_TIMER_NSEC = tsu_cfg->nanoseconds;
3472 }
3473 }
3474 }
3475
3476
3477 /******************************************************************************
3478 * See mss_ethernet_mac.h for details of how to use this function.
3479 */
3480
MSS_MAC_read_TSU(const mss_mac_instance_t * this_mac,mss_mac_tsu_time_t * tsu_time)3481 void MSS_MAC_read_TSU(const mss_mac_instance_t *this_mac, mss_mac_tsu_time_t *tsu_time)
3482 {
3483 int32_t got_time = 0;
3484
3485 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3486 {
3487 do
3488 {
3489 if(0U != this_mac->is_emac)
3490 {
3491 tsu_time->secs_lsb = this_mac->emac_base->TSU_TIMER_SEC;
3492 tsu_time->secs_msb = this_mac->emac_base->TSU_TIMER_MSB_SEC;
3493 tsu_time->nanoseconds = this_mac->emac_base->TSU_TIMER_NSEC;
3494
3495 /* Check for nanoseconds roll over and exit loop if none otherwise do again */
3496 if(tsu_time->secs_lsb == this_mac->emac_base->TSU_TIMER_SEC)
3497 {
3498 got_time = 1;
3499 }
3500 }
3501 else
3502 {
3503 tsu_time->secs_lsb = this_mac->mac_base->TSU_TIMER_SEC;
3504 tsu_time->secs_msb = this_mac->mac_base->TSU_TIMER_MSB_SEC;
3505 tsu_time->nanoseconds = this_mac->mac_base->TSU_TIMER_NSEC;
3506
3507 /* Check for nanoseconds roll over and exit loop if none otherwise do again */
3508 if(tsu_time->secs_lsb == this_mac->mac_base->TSU_TIMER_SEC)
3509 {
3510 got_time = 1;
3511 }
3512 }
3513 } while(0 == got_time);
3514 }
3515 }
3516
3517
3518 /******************************************************************************
3519 * See mss_ethernet_mac.h for details of how to use this function.
3520 */
3521
MSS_MAC_set_TSU_rx_mode(const mss_mac_instance_t * this_mac,mss_mac_tsu_mode_t tsu_mode)3522 void MSS_MAC_set_TSU_rx_mode(const mss_mac_instance_t *this_mac, mss_mac_tsu_mode_t tsu_mode)
3523 {
3524 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3525 {
3526 if(0U != this_mac->is_emac)
3527 {
3528 this_mac->emac_base->RX_BD_CONTROL = ((uint32_t)tsu_mode << GEM_BD_TS_MODE_SHIFT) & GEM_BD_TS_MODE;
3529 }
3530 else
3531 {
3532 this_mac->mac_base->RX_BD_CONTROL = ((uint32_t)tsu_mode << GEM_BD_TS_MODE_SHIFT) & GEM_BD_TS_MODE;
3533 }
3534 }
3535 }
3536
3537
3538 /******************************************************************************
3539 * See mss_ethernet_mac.h for details of how to use this function.
3540 */
3541
MSS_MAC_set_TSU_tx_mode(const mss_mac_instance_t * this_mac,mss_mac_tsu_mode_t tsu_mode)3542 void MSS_MAC_set_TSU_tx_mode(const mss_mac_instance_t *this_mac, mss_mac_tsu_mode_t tsu_mode)
3543 {
3544 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3545 {
3546 if(0U != this_mac->is_emac)
3547 {
3548 this_mac->emac_base->TX_BD_CONTROL = ((uint32_t)tsu_mode << GEM_BD_TS_MODE_SHIFT) & GEM_BD_TS_MODE;
3549 }
3550 else
3551 {
3552 this_mac->mac_base->TX_BD_CONTROL = ((uint32_t)tsu_mode << GEM_BD_TS_MODE_SHIFT) & GEM_BD_TS_MODE;
3553 }
3554 }
3555 }
3556
3557
3558 /******************************************************************************
3559 * See mss_ethernet_mac.h for details of how to use this function.
3560 */
3561
MSS_MAC_get_TSU_rx_mode(const mss_mac_instance_t * this_mac)3562 mss_mac_tsu_mode_t MSS_MAC_get_TSU_rx_mode(const mss_mac_instance_t *this_mac)
3563 {
3564 mss_mac_tsu_mode_t ret_val = MSS_MAC_TSU_MODE_DISABLED;
3565
3566 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3567 {
3568 if(0U != this_mac->is_emac)
3569 {
3570 ret_val = (mss_mac_tsu_mode_t)((this_mac->emac_base->RX_BD_CONTROL & GEM_BD_TS_MODE) >> GEM_BD_TS_MODE_SHIFT);
3571 }
3572 else
3573 {
3574 ret_val = (mss_mac_tsu_mode_t)((this_mac->mac_base->RX_BD_CONTROL & GEM_BD_TS_MODE) >> GEM_BD_TS_MODE_SHIFT);
3575 }
3576 }
3577
3578 return(ret_val);
3579 }
3580
3581
3582 /******************************************************************************
3583 * See mss_ethernet_mac.h for details of how to use this function.
3584 */
3585
MSS_MAC_get_TSU_tx_mode(const mss_mac_instance_t * this_mac)3586 mss_mac_tsu_mode_t MSS_MAC_get_TSU_tx_mode(const mss_mac_instance_t *this_mac)
3587 {
3588 mss_mac_tsu_mode_t ret_val= MSS_MAC_TSU_MODE_DISABLED;
3589
3590 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3591 {
3592 if(0U != this_mac->is_emac)
3593 {
3594 ret_val = (mss_mac_tsu_mode_t)((this_mac->emac_base->TX_BD_CONTROL & GEM_BD_TS_MODE) >> GEM_BD_TS_MODE_SHIFT);
3595 }
3596 else
3597 {
3598 ret_val = (mss_mac_tsu_mode_t)((this_mac->mac_base->TX_BD_CONTROL & GEM_BD_TS_MODE) >> GEM_BD_TS_MODE_SHIFT);
3599 }
3600 }
3601
3602 return(ret_val);
3603 }
3604
3605
3606 /******************************************************************************
3607 * See mss_ethernet_mac.h for details of how to use this function.
3608 */
3609
MSS_MAC_set_TSU_oss_mode(const mss_mac_instance_t * this_mac,mss_mac_oss_mode_t oss_mode)3610 void MSS_MAC_set_TSU_oss_mode(const mss_mac_instance_t *this_mac, mss_mac_oss_mode_t oss_mode)
3611 {
3612 volatile uint32_t temp_control;
3613
3614 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3615 {
3616 if(0U != this_mac->is_emac)
3617 {
3618 temp_control = this_mac->emac_base->NETWORK_CONTROL;
3619 }
3620 else
3621 {
3622 temp_control = this_mac->mac_base->NETWORK_CONTROL;
3623 }
3624
3625 /*
3626 * Note. The docs don't say these are mutually exclusive but I don't think
3627 * it makes sense to allow both modes at once...
3628 */
3629 if(MSS_MAC_OSS_MODE_DISABLED == oss_mode)
3630 {
3631 temp_control &= ~(GEM_OSS_CORRECTION_FIELD | GEM_ONE_STEP_SYNC_MODE);
3632 }
3633 else if(MSS_MAC_OSS_MODE_REPLACE == oss_mode)
3634 {
3635 temp_control &= ~GEM_OSS_CORRECTION_FIELD;
3636 temp_control |= GEM_ONE_STEP_SYNC_MODE;
3637 }
3638 else
3639 {
3640 if(MSS_MAC_OSS_MODE_ADJUST == oss_mode)
3641 {
3642 temp_control |= GEM_OSS_CORRECTION_FIELD;
3643 temp_control &= ~GEM_ONE_STEP_SYNC_MODE;
3644 }
3645 }
3646
3647 if(0U != this_mac->is_emac)
3648 {
3649 this_mac->emac_base->NETWORK_CONTROL = temp_control;
3650 }
3651 else
3652 {
3653 this_mac->mac_base->NETWORK_CONTROL = temp_control;
3654 }
3655 }
3656 }
3657
3658
3659 /******************************************************************************
3660 * See mss_ethernet_mac.h for details of how to use this function.
3661 */
3662
MSS_MAC_get_TSU_oss_mode(const mss_mac_instance_t * this_mac)3663 mss_mac_oss_mode_t MSS_MAC_get_TSU_oss_mode(const mss_mac_instance_t *this_mac)
3664 {
3665 mss_mac_oss_mode_t ret_val = MSS_MAC_OSS_MODE_DISABLED;
3666 volatile uint32_t temp_control;
3667
3668 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3669 {
3670 if(0U != this_mac->is_emac)
3671 {
3672 temp_control = this_mac->emac_base->NETWORK_CONTROL;
3673 }
3674 else
3675 {
3676 temp_control = this_mac->mac_base->NETWORK_CONTROL;
3677 }
3678
3679 /*
3680 * Note. The docs don't say these are mutually exclusive but I don't think
3681 * it makes sense to allow both modes at once so report this as invalid...
3682 */
3683 if((GEM_OSS_CORRECTION_FIELD | GEM_ONE_STEP_SYNC_MODE) == (temp_control & (GEM_OSS_CORRECTION_FIELD | GEM_ONE_STEP_SYNC_MODE)))
3684 {
3685 ret_val = MSS_MAC_OSS_MODE_INVALID;
3686 }
3687 else if(GEM_OSS_CORRECTION_FIELD == (temp_control & GEM_OSS_CORRECTION_FIELD))
3688 {
3689 ret_val = MSS_MAC_OSS_MODE_ADJUST;
3690 }
3691 else if(GEM_ONE_STEP_SYNC_MODE == (temp_control & GEM_ONE_STEP_SYNC_MODE))
3692 {
3693 ret_val = MSS_MAC_OSS_MODE_REPLACE;
3694 }
3695 else
3696 {
3697 ret_val = MSS_MAC_OSS_MODE_DISABLED;
3698 }
3699 }
3700
3701 return(ret_val);
3702 }
3703
3704
3705 /******************************************************************************
3706 * See mss_ethernet_mac.h for details of how to use this function.
3707 */
3708
MSS_MAC_set_TSU_unicast_addr(const mss_mac_instance_t * this_mac,mss_mac_tsu_addr_t select,uint32_t ip_address)3709 void MSS_MAC_set_TSU_unicast_addr(const mss_mac_instance_t *this_mac, mss_mac_tsu_addr_t select, uint32_t ip_address)
3710 {
3711 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3712 {
3713 if(0U != this_mac->is_emac)
3714 {
3715 if(MSS_MAC_TSU_UNICAST_RX == select)
3716 {
3717 this_mac->emac_base->RX_PTP_UNICAST = ip_address;
3718 }
3719 else
3720 {
3721 this_mac->emac_base->TX_PTP_UNICAST = ip_address;
3722 }
3723 }
3724 else
3725 {
3726 if(MSS_MAC_TSU_UNICAST_RX == select)
3727 {
3728 this_mac->mac_base->RX_PTP_UNICAST = ip_address;
3729 }
3730 else
3731 {
3732 this_mac->mac_base->TX_PTP_UNICAST = ip_address;
3733 }
3734 }
3735 }
3736 }
3737
3738
3739 /******************************************************************************
3740 * See mss_ethernet_mac.h for details of how to use this function.
3741 */
3742
MSS_MAC_get_TSU_unicast_addr(const mss_mac_instance_t * this_mac,mss_mac_tsu_addr_t select)3743 uint32_t MSS_MAC_get_TSU_unicast_addr(const mss_mac_instance_t *this_mac, mss_mac_tsu_addr_t select)
3744 {
3745 uint32_t ret_val = 0U;
3746
3747 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3748 {
3749 if(0U != this_mac->is_emac)
3750 {
3751 if(MSS_MAC_TSU_UNICAST_RX == select)
3752 {
3753 ret_val = this_mac->emac_base->RX_PTP_UNICAST;
3754 }
3755 else
3756 {
3757 ret_val = this_mac->emac_base->TX_PTP_UNICAST;
3758 }
3759 }
3760 else
3761 {
3762 if(MSS_MAC_TSU_UNICAST_RX == select)
3763 {
3764 ret_val = this_mac->mac_base->RX_PTP_UNICAST;
3765 }
3766 else
3767 {
3768 ret_val = this_mac->mac_base->TX_PTP_UNICAST;
3769 }
3770 }
3771 }
3772
3773 return(ret_val);
3774 }
3775
3776
3777 /******************************************************************************
3778 * See mss_ethernet_mac.h for details of how to use this function.
3779 */
3780
MSS_MAC_set_VLAN_only_mode(const mss_mac_instance_t * this_mac,bool enable)3781 void MSS_MAC_set_VLAN_only_mode(const mss_mac_instance_t *this_mac, bool enable)
3782 {
3783 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3784 {
3785 if(0U != this_mac->is_emac)
3786 {
3787 if(false == enable)
3788 {
3789 this_mac->emac_base->NETWORK_CONFIG &= ~GEM_DISCARD_NON_VLAN_FRAMES;
3790 }
3791 else
3792 {
3793 this_mac->emac_base->NETWORK_CONFIG |= GEM_DISCARD_NON_VLAN_FRAMES;
3794 }
3795 }
3796 else
3797 {
3798 if(false == enable)
3799 {
3800 this_mac->mac_base->NETWORK_CONFIG &= ~GEM_DISCARD_NON_VLAN_FRAMES;
3801 }
3802 else
3803 {
3804 this_mac->mac_base->NETWORK_CONFIG |= GEM_DISCARD_NON_VLAN_FRAMES;
3805 }
3806 }
3807 }
3808 }
3809
3810
3811 /******************************************************************************
3812 * See mss_ethernet_mac.h for details of how to use this function.
3813 */
3814
MSS_MAC_get_VLAN_only_mode(const mss_mac_instance_t * this_mac)3815 bool MSS_MAC_get_VLAN_only_mode(const mss_mac_instance_t *this_mac)
3816 {
3817 bool ret_val = false;
3818
3819 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3820 {
3821 if(0U != this_mac->is_emac)
3822 {
3823 ret_val = 0U != (this_mac->emac_base->NETWORK_CONFIG & GEM_DISCARD_NON_VLAN_FRAMES);
3824 }
3825 else
3826 {
3827 ret_val = 0U != (this_mac->mac_base->NETWORK_CONFIG & GEM_DISCARD_NON_VLAN_FRAMES);
3828 }
3829 }
3830
3831 return(ret_val);
3832 }
3833
3834
3835 /******************************************************************************
3836 * See mss_ethernet_mac.h for details of how to use this function.
3837 */
3838
MSS_MAC_set_stacked_VLAN(const mss_mac_instance_t * this_mac,uint16_t tag)3839 void MSS_MAC_set_stacked_VLAN(const mss_mac_instance_t *this_mac, uint16_t tag)
3840 {
3841 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3842 {
3843 if(0U != this_mac->is_emac)
3844 {
3845 if(GEM_VLAN_ETHERTYPE_MIN > tag)
3846 {
3847 this_mac->emac_base->STACKED_VLAN = 0U;
3848 }
3849 else
3850 {
3851 this_mac->emac_base->STACKED_VLAN = (uint32_t)tag | GEM_ENABLE_PROCESSING;
3852 }
3853 }
3854 else
3855 {
3856 if(GEM_VLAN_ETHERTYPE_MIN > tag)
3857 {
3858 this_mac->mac_base->STACKED_VLAN = 0U;
3859 }
3860 else
3861 {
3862 this_mac->mac_base->STACKED_VLAN = (uint32_t)tag | GEM_ENABLE_PROCESSING;
3863 }
3864 }
3865 }
3866 }
3867
3868
3869 /******************************************************************************
3870 * See mss_ethernet_mac.h for details of how to use this function.
3871 */
3872
MSS_MAC_get_stacked_VLAN(const mss_mac_instance_t * this_mac)3873 uint16_t MSS_MAC_get_stacked_VLAN(const mss_mac_instance_t *this_mac)
3874 {
3875 uint16_t ret_val = GEM_VLAN_NO_STACK; /* Return 0 if stacked VLANs not enabled */
3876
3877 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3878 {
3879 if(0U != this_mac->is_emac)
3880 {
3881 if(0U != (this_mac->emac_base->STACKED_VLAN & GEM_ENABLE_PROCESSING))
3882 {
3883 ret_val = (uint16_t)this_mac->emac_base->STACKED_VLAN;
3884 }
3885 }
3886 else
3887 {
3888 if(0U != (this_mac->mac_base->STACKED_VLAN & GEM_ENABLE_PROCESSING))
3889 {
3890 ret_val = (uint16_t)this_mac->mac_base->STACKED_VLAN;
3891 }
3892 }
3893 }
3894
3895 return(ret_val);
3896 }
3897
3898
3899 /******************************************************************************
3900 * See mss_ethernet_mac.h for details of how to use this function.
3901 */
3902
MSS_MAC_set_hash(const mss_mac_instance_t * this_mac,uint64_t hash_in)3903 void MSS_MAC_set_hash(const mss_mac_instance_t *this_mac, uint64_t hash_in)
3904 {
3905 uint64_t hash = hash_in; /* Avoids warning about modifying fn parameter passed by value */
3906
3907 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3908 {
3909 if(0U != this_mac->is_emac)
3910 {
3911 if(0ULL == hash) /* Short cut for disabling */
3912 {
3913 this_mac->emac_base->NETWORK_CONFIG &= ~(GEM_UNICAST_HASH_ENABLE | GEM_MULTICAST_HASH_ENABLE);
3914 }
3915
3916 this_mac->emac_base->HASH_BOTTOM = (uint32_t)hash;
3917 hash >>= 32;
3918 this_mac->emac_base->HASH_TOP = (uint32_t)hash;
3919 }
3920 else
3921 {
3922 if(0ULL == hash) /* Short cut for disabling */
3923 {
3924 this_mac->mac_base->NETWORK_CONFIG &= ~(GEM_UNICAST_HASH_ENABLE | GEM_MULTICAST_HASH_ENABLE);
3925 }
3926
3927 this_mac->mac_base->HASH_BOTTOM = (uint32_t)hash;
3928 hash >>= 32;
3929 this_mac->mac_base->HASH_TOP = (uint32_t)hash;
3930 }
3931 }
3932 }
3933
3934
3935 /******************************************************************************
3936 * See mss_ethernet_mac.h for details of how to use this function.
3937 */
3938
MSS_MAC_get_hash(const mss_mac_instance_t * this_mac)3939 uint64_t MSS_MAC_get_hash(const mss_mac_instance_t *this_mac)
3940 {
3941 uint64_t ret_val = 0U;
3942
3943 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3944 {
3945 if(0U != this_mac->is_emac)
3946 {
3947 ret_val = (uint64_t)this_mac->emac_base->HASH_TOP;
3948 ret_val <<= 32;
3949 ret_val |= (uint64_t)this_mac->emac_base->HASH_BOTTOM;
3950 }
3951 else
3952 {
3953 ret_val = (uint64_t)this_mac->mac_base->HASH_TOP;
3954 ret_val <<= 32;
3955 ret_val |= (uint64_t)this_mac->mac_base->HASH_BOTTOM;
3956 }
3957 }
3958
3959 return(ret_val);
3960 }
3961
3962
3963 /******************************************************************************
3964 * See mss_ethernet_mac.h for details of how to use this function.
3965 */
3966
MSS_MAC_set_hash_mode(const mss_mac_instance_t * this_mac,mss_mac_hash_mode_t mode)3967 void MSS_MAC_set_hash_mode(const mss_mac_instance_t *this_mac, mss_mac_hash_mode_t mode)
3968 {
3969 uint32_t temp;
3970
3971 /*
3972 * Enum values are matched to register bits but just to be safe we mask them
3973 * to ensure only the two hash control bits are modified...
3974 */
3975 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
3976 {
3977 if(0U != this_mac->is_emac)
3978 {
3979 temp = this_mac->emac_base->NETWORK_CONFIG & ~(GEM_UNICAST_HASH_ENABLE | GEM_MULTICAST_HASH_ENABLE);
3980 temp |= (uint32_t)mode & (GEM_UNICAST_HASH_ENABLE | GEM_MULTICAST_HASH_ENABLE);
3981 this_mac->emac_base->NETWORK_CONFIG = temp;
3982 }
3983 else
3984 {
3985 temp = this_mac->mac_base->NETWORK_CONFIG & ~(GEM_UNICAST_HASH_ENABLE | GEM_MULTICAST_HASH_ENABLE);
3986 temp |= (uint32_t)mode & (GEM_UNICAST_HASH_ENABLE | GEM_MULTICAST_HASH_ENABLE);
3987 this_mac->mac_base->NETWORK_CONFIG = temp;
3988 }
3989 }
3990 }
3991
3992
3993 /******************************************************************************
3994 * See mss_ethernet_mac.h for details of how to use this function.
3995 */
3996
MSS_MAC_get_hash_mode(const mss_mac_instance_t * this_mac)3997 mss_mac_hash_mode_t MSS_MAC_get_hash_mode(const mss_mac_instance_t *this_mac)
3998 {
3999 mss_mac_hash_mode_t ret_val = 0;
4000
4001 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4002 {
4003 if(0U != this_mac->is_emac)
4004 {
4005 ret_val = (mss_mac_hash_mode_t)(this_mac->emac_base->NETWORK_CONFIG & (GEM_UNICAST_HASH_ENABLE | GEM_MULTICAST_HASH_ENABLE));
4006 }
4007 else
4008 {
4009 ret_val = (mss_mac_hash_mode_t)(this_mac->mac_base->NETWORK_CONFIG & (GEM_UNICAST_HASH_ENABLE | GEM_MULTICAST_HASH_ENABLE));
4010 }
4011 }
4012
4013 return(ret_val);
4014 }
4015
4016
4017 /******************************************************************************
4018 * See mss_ethernet_mac.h for details of how to use this function.
4019 */
4020
MSS_MAC_set_type_filter(const mss_mac_instance_t * this_mac,uint32_t filter,uint16_t value)4021 void MSS_MAC_set_type_filter(const mss_mac_instance_t *this_mac, uint32_t filter, uint16_t value)
4022 {
4023 volatile uint32_t *p_reg;
4024
4025 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4026 {
4027 if(0U != this_mac->is_emac)
4028 {
4029 p_reg = &this_mac->emac_base->SPEC_TYPE1;
4030 }
4031 else
4032 {
4033 p_reg = &this_mac->mac_base->SPEC_TYPE1;
4034 }
4035 if((filter <= 4U) && (filter > 0U)) /* Filter is in range 1 to 4 to match register naming */
4036 {
4037 p_reg += filter - 1U;
4038 if(0U == value) /* Disable filter if match value is 0 as this should not be a valid type */
4039 {
4040 *p_reg = 0U;
4041 }
4042 else
4043 {
4044 *p_reg = (uint32_t)(0x80000000UL | (uint32_t)value);
4045 }
4046 }
4047 }
4048 }
4049
4050
4051 /******************************************************************************
4052 * See mss_ethernet_mac.h for details of how to use this function.
4053 */
4054
MSS_MAC_get_type_filter(const mss_mac_instance_t * this_mac,uint32_t filter)4055 uint16_t MSS_MAC_get_type_filter(const mss_mac_instance_t *this_mac, uint32_t filter)
4056 {
4057 volatile uint32_t *p_reg;
4058 uint16_t ret_val = 0U;
4059
4060 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4061 {
4062 if(0U != this_mac->is_emac)
4063 {
4064 p_reg = &this_mac->emac_base->SPEC_TYPE1;
4065 }
4066 else
4067 {
4068 p_reg = &this_mac->mac_base->SPEC_TYPE1;
4069 }
4070
4071 if((filter <= 4U) && (filter > 0U)) /* Filter is in range 1 to 4 to match register naming */
4072 {
4073 p_reg += filter - 1U;
4074 if(0U != (*p_reg & 0x80000000UL)) /* Not disabled filter... */
4075 {
4076 ret_val = (uint16_t)*p_reg;
4077 }
4078 }
4079 }
4080
4081 return(ret_val);
4082 }
4083
4084
4085 /******************************************************************************
4086 * See mss_ethernet_mac.h for details of how to use this function.
4087 */
4088
MSS_MAC_set_sa_filter(const mss_mac_instance_t * this_mac,uint32_t filter,uint16_t control,const uint8_t * mac_addr)4089 void MSS_MAC_set_sa_filter(const mss_mac_instance_t *this_mac, uint32_t filter, uint16_t control, const uint8_t *mac_addr)
4090 {
4091 volatile uint32_t *p_reg;
4092 uint32_t address32_l;
4093 uint32_t address32_h;
4094
4095 ASSERT(NULL_POINTER!= mac_addr);
4096
4097 if((MSS_MAC_AVAILABLE == this_mac->mac_available) && (NULL_POINTER != mac_addr))
4098 {
4099 if((filter >= 2U) && (filter <= 4U)) /* SA Filter 1 is for our address */
4100 {
4101 if(0U != this_mac->is_emac)
4102 {
4103 p_reg = &this_mac->emac_base->SPEC_ADD2_BOTTOM;
4104 }
4105 else
4106 {
4107 p_reg = &this_mac->mac_base->SPEC_ADD2_BOTTOM;
4108 }
4109
4110 p_reg = p_reg + ((filter - 2U) * 2U);
4111
4112 if(MSS_MAC_SA_FILTER_DISABLE == control)
4113 {
4114 /*
4115 * Clear filter and disable - must be done in this order...
4116 * Writing to [0] disables and [1] enables So this sequence
4117 * clears the registers and disables the filter as opposed to
4118 * setting a destination address filter for 00:00:00:00:00:00.
4119 */
4120 p_reg[1] = 0U;
4121 p_reg[0] = 0U;
4122 }
4123 else
4124 {
4125 /* Assemble correct register values */
4126 address32_l = ((uint32_t)mac_addr[3]) << 24;
4127 address32_l |= ((uint32_t)mac_addr[2]) << 16;
4128 address32_l |= ((uint32_t)mac_addr[1]) << 8;
4129 address32_l |= ((uint32_t)mac_addr[0]);
4130 address32_h = ((uint32_t)mac_addr[5]) << 8;
4131 address32_h |= ((uint32_t)mac_addr[4]);
4132
4133 address32_h |= (uint32_t)control << 16;
4134
4135 /* Update hardware registers - must be done in this order... */
4136 p_reg[0] = address32_l;
4137 p_reg[1] = address32_h;
4138 }
4139 }
4140 }
4141 }
4142
4143
4144 /******************************************************************************
4145 * See mss_ethernet_mac.h for details of how to use this function.
4146 */
4147
MSS_MAC_get_sa_filter(const mss_mac_instance_t * this_mac,uint32_t filter,uint8_t * mac_addr)4148 uint16_t MSS_MAC_get_sa_filter(const mss_mac_instance_t *this_mac, uint32_t filter, uint8_t *mac_addr)
4149 {
4150 volatile uint32_t *p_reg;
4151 uint32_t temp_reg;
4152 uint16_t ret_val = 0U;
4153
4154 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4155 {
4156 if(NULL_POINTER != mac_addr)
4157 {
4158 (void)memset(mac_addr, 0, 6); /* Consistent result if bad parameters passed... */
4159 }
4160
4161 if((filter >= 2U) && (filter <= 4U))
4162 {
4163 if(0U != this_mac->is_emac)
4164 {
4165 p_reg = &this_mac->emac_base->SPEC_ADD2_BOTTOM;
4166 }
4167 else
4168 {
4169 p_reg = &this_mac->mac_base->SPEC_ADD2_BOTTOM;
4170 }
4171
4172 p_reg = p_reg + ((filter - 2U) * 2U);
4173
4174 if(NULL_POINTER != mac_addr) /* Want MAC address and filter control info? */
4175 {
4176 temp_reg = p_reg[0];
4177 mac_addr[0] = (uint8_t)temp_reg & BITS_08;
4178 temp_reg >>= 8;
4179 mac_addr[1] = (uint8_t)temp_reg & BITS_08;
4180 temp_reg >>= 8;
4181 mac_addr[2] = (uint8_t)temp_reg & BITS_08;
4182 temp_reg >>= 8;
4183 mac_addr[3] = (uint8_t)temp_reg & BITS_08;
4184
4185 temp_reg = p_reg[1];
4186 mac_addr[4] = (uint8_t)temp_reg & BITS_08;
4187 temp_reg >>= 8;
4188 mac_addr[5] = (uint8_t)temp_reg & BITS_08;
4189 }
4190
4191 ret_val = (uint16_t)(p_reg[1] >> 16);
4192 }
4193 }
4194
4195 return(ret_val);
4196 }
4197
4198
4199 /******************************************************************************
4200 * See mss_ethernet_mac.h for details of how to use this function.
4201 */
4202
MSS_MAC_set_type_1_filter(const mss_mac_instance_t * this_mac,uint32_t filter_no,const mss_mac_type_1_filter_t * filter)4203 void MSS_MAC_set_type_1_filter(const mss_mac_instance_t *this_mac, uint32_t filter_no, const mss_mac_type_1_filter_t *filter)
4204 {
4205 if((MSS_MAC_AVAILABLE == this_mac->mac_available) && (filter_no < MSS_MAC_TYPE_1_SCREENERS))
4206 {
4207 volatile uint32_t *p_reg;
4208 uint32_t temp_reg;
4209
4210 if(0U != this_mac->is_emac)
4211 {
4212 p_reg = &this_mac->emac_base->SCREENING_TYPE_1_REGISTER_0;
4213 }
4214 else
4215 {
4216 p_reg = &this_mac->mac_base->SCREENING_TYPE_1_REGISTER_0;
4217 }
4218
4219 temp_reg = (uint32_t)filter->queue_no & GEM_QUEUE_NUMBER;
4220 temp_reg |= ((uint32_t)filter->dstc << GEM_DSTC_MATCH_SHIFT) & GEM_DSTC_MATCH;
4221 temp_reg |= ((uint32_t)filter->udp_port << GEM_UDP_PORT_MATCH_SHIFT) & GEM_UDP_PORT_MATCH;
4222 if(0U != filter->drop_on_match)
4223 {
4224 temp_reg |= GEM_DROP_ON_MATCH;
4225 }
4226
4227 if(0U != filter->dstc_enable)
4228 {
4229 temp_reg |= GEM_DSTC_ENABLE;
4230 }
4231
4232 if(0U != filter->udp_port_enable)
4233 {
4234 temp_reg |= GEM_UDP_PORT_MATCH_ENABLE;
4235 }
4236
4237 p_reg[filter_no] = temp_reg;
4238 }
4239 }
4240
4241
4242 /******************************************************************************
4243 * See mss_ethernet_mac.h for details of how to use this function.
4244 */
4245
MSS_MAC_get_type_1_filter(const mss_mac_instance_t * this_mac,uint32_t filter_no,mss_mac_type_1_filter_t * filter)4246 void MSS_MAC_get_type_1_filter(const mss_mac_instance_t *this_mac, uint32_t filter_no, mss_mac_type_1_filter_t *filter)
4247 {
4248
4249 if((MSS_MAC_AVAILABLE == this_mac->mac_available) && (filter_no < MSS_MAC_TYPE_1_SCREENERS))
4250 {
4251 volatile uint32_t *p_reg;
4252 uint32_t temp_reg;
4253
4254 (void)memset(filter, 0, sizeof(mss_mac_type_1_filter_t)); /* Blank canvass to start */
4255
4256 if(0U != this_mac->is_emac)
4257 {
4258 p_reg = &this_mac->emac_base->SCREENING_TYPE_1_REGISTER_0;
4259 }
4260 else
4261 {
4262 p_reg = &this_mac->mac_base->SCREENING_TYPE_1_REGISTER_0;
4263 }
4264
4265 temp_reg = p_reg[filter_no];
4266
4267 filter->queue_no = (uint8_t)(temp_reg & GEM_QUEUE_NUMBER);
4268 temp_reg >>= 4;
4269
4270 filter->dstc = (uint8_t)(temp_reg & GEM_DSTC_MATCH);
4271 temp_reg >>= GEM_DSTC_MATCH_SHIFT;
4272
4273 filter->udp_port = (uint16_t)(temp_reg & GEM_UDP_PORT_MATCH);
4274 temp_reg >>= GEM_UDP_PORT_MATCH_SHIFT;
4275
4276 filter->dstc_enable = (uint8_t)(temp_reg & 1U);
4277 temp_reg >>= 1;
4278
4279 filter->udp_port_enable = (uint8_t)(temp_reg & 1U);
4280 temp_reg >>= 1;
4281
4282 filter->drop_on_match = (uint8_t)(temp_reg & 1U);
4283 }
4284 }
4285
4286
4287 /******************************************************************************
4288 * See mss_ethernet_mac.h for details of how to use this function.
4289 */
4290
MSS_MAC_set_type_2_ethertype(const mss_mac_instance_t * this_mac,uint32_t ethertype_no,uint16_t ethertype)4291 void MSS_MAC_set_type_2_ethertype(const mss_mac_instance_t *this_mac, uint32_t ethertype_no, uint16_t ethertype)
4292 {
4293 volatile uint32_t *p_reg;
4294
4295 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4296 {
4297 if(0U == this_mac->is_emac) /* Ethertype filter not supported on eMAC */
4298 {
4299 p_reg = &this_mac->mac_base->SCREENING_TYPE_2_ETHERTYPE_REG_0;
4300 if(ethertype_no < MSS_MAC_TYPE_2_ETHERTYPES)
4301 {
4302 p_reg[ethertype_no] = (uint32_t)ethertype;
4303 }
4304 }
4305 }
4306 }
4307
4308
4309 /******************************************************************************
4310 * See mss_ethernet_mac.h for details of how to use this function.
4311 */
4312
MSS_MAC_get_type_2_ethertype(const mss_mac_instance_t * this_mac,uint32_t ethertype_no)4313 uint16_t MSS_MAC_get_type_2_ethertype(const mss_mac_instance_t *this_mac, uint32_t ethertype_no)
4314 {
4315 volatile uint32_t *p_reg;
4316 uint16_t temp_reg = 0U;
4317
4318 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4319 {
4320 if(0U == this_mac->is_emac) /* Ethertype filter not supported on eMAC */
4321 {
4322 p_reg = &this_mac->mac_base->SCREENING_TYPE_2_ETHERTYPE_REG_0;
4323 if(ethertype_no < MSS_MAC_TYPE_2_ETHERTYPES)
4324 {
4325 temp_reg = (uint16_t)p_reg[ethertype_no];
4326 }
4327 }
4328 }
4329
4330 return(temp_reg);
4331 }
4332
4333
4334 /******************************************************************************
4335 * See mss_ethernet_mac.h for details of how to use this function.
4336 */
4337
MSS_MAC_set_type_2_compare(const mss_mac_instance_t * this_mac,uint32_t comparer_no_in,const mss_mac_type_2_compare_t * comparer)4338 void MSS_MAC_set_type_2_compare(const mss_mac_instance_t *this_mac, uint32_t comparer_no_in, const mss_mac_type_2_compare_t *comparer)
4339 {
4340 volatile uint32_t *p_reg;
4341 uint32_t limit;
4342 uint32_t temp_reg;
4343 uint32_t comparer_no = comparer_no_in;
4344
4345 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4346 {
4347 if(0U != this_mac->is_emac) /* eMAC limits are different to pMAC ones */
4348 {
4349 p_reg = &this_mac->emac_base->TYPE2_COMPARE_0_WORD_0;
4350 limit = MSS_MAC_EMAC_TYPE_2_COMPARERS;
4351 }
4352 else
4353 {
4354 p_reg = &this_mac->mac_base->TYPE2_COMPARE_0_WORD_0;
4355 limit = MSS_MAC_TYPE_2_COMPARERS;
4356 }
4357
4358 if(comparer_no < limit)
4359 {
4360 comparer_no *= 2U; /* Working with consecutive pairs of registers for this one */
4361 if(0U != comparer->disable_mask)
4362 {
4363 p_reg[comparer_no] = comparer->data; /* Mask disabled so just 4 byte compare value */
4364 temp_reg = GEM_DISABLE_MASK; /* and no mask */
4365 }
4366 else
4367 {
4368 temp_reg = comparer->data << 16; /* 16 bit compare value and 16 bit mask */
4369 temp_reg |= (uint32_t)comparer->mask;
4370 p_reg[comparer_no] = temp_reg;
4371 temp_reg = 0U;
4372 }
4373
4374 if(0U != comparer->compare_vlan_c_id)
4375 {
4376 temp_reg |= GEM_COMPARE_VLAN_ID;
4377 }
4378 else if(0U != comparer->compare_vlan_s_id)
4379 {
4380 temp_reg |= GEM_COMPARE_VLAN_ID | GEM_COMPARE_S_TAG;
4381 }
4382 else
4383 {
4384 temp_reg |= (uint32_t)comparer->offset_value & BITS_07;
4385 temp_reg |= ((uint32_t)comparer->compare_offset & BITS_02) << GEM_COMPARE_OFFSET_SHIFT;
4386 }
4387
4388 p_reg[comparer_no + 1] = temp_reg; /* Set second word of comparer */
4389 }
4390 }
4391 }
4392
4393
4394 /******************************************************************************
4395 * See mss_ethernet_mac.h for details of how to use this function.
4396 */
4397
MSS_MAC_get_type_2_compare(const mss_mac_instance_t * this_mac,uint32_t comparer_no_in,mss_mac_type_2_compare_t * comparer)4398 void MSS_MAC_get_type_2_compare(const mss_mac_instance_t *this_mac, uint32_t comparer_no_in, mss_mac_type_2_compare_t *comparer)
4399 {
4400 volatile uint32_t *p_reg;
4401 uint32_t limit;
4402 uint32_t comparer_no = comparer_no_in;
4403
4404 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4405 {
4406 if(0U != this_mac->is_emac) /* eMAC limits are different to pMAC ones */
4407 {
4408 p_reg = &this_mac->emac_base->TYPE2_COMPARE_0_WORD_0;
4409 limit = MSS_MAC_EMAC_TYPE_2_COMPARERS;
4410 }
4411 else
4412 {
4413 p_reg = &this_mac->mac_base->TYPE2_COMPARE_0_WORD_0;
4414 limit = MSS_MAC_TYPE_2_COMPARERS;
4415 }
4416
4417 (void)memset(comparer, 0, sizeof(mss_mac_type_2_compare_t));
4418 if(comparer_no < limit)
4419 {
4420 comparer_no *= 2U; /* Working with consecutive pairs of registers for this one */
4421 if(0U != (p_reg[comparer_no + 1] & GEM_DISABLE_MASK))
4422 {
4423 comparer->data = p_reg[comparer_no]; /* Mask disabled so just 4 byte compare value */
4424 comparer->disable_mask = 1; /* and no mask */
4425 }
4426 else
4427 {
4428 comparer->data = p_reg[comparer_no] >> 16; /* 16 bit compare value and 16 bit mask */
4429 comparer->mask = (uint16_t)p_reg[comparer_no];
4430 }
4431
4432 if(0U != (p_reg[comparer_no + 1U] & GEM_COMPARE_VLAN_ID))
4433 {
4434 if(0U != (p_reg[comparer_no + 1U] & GEM_COMPARE_S_TAG))
4435 {
4436 comparer->compare_vlan_s_id = 1U;
4437 }
4438 else
4439 {
4440 comparer->compare_vlan_c_id = 1U;
4441 }
4442 }
4443 else
4444 {
4445 comparer->compare_offset = (uint8_t)((p_reg[comparer_no + 1U] >> GEM_COMPARE_OFFSET_SHIFT) & BITS_02);
4446 }
4447
4448 comparer->offset_value = (uint8_t)(p_reg[comparer_no + 1U] & GEM_OFFSET_VALUE);
4449 }
4450 }
4451 }
4452
4453
4454 /******************************************************************************
4455 * See mss_ethernet_mac.h for details of how to use this function.
4456 */
4457
MSS_MAC_set_type_2_filter(const mss_mac_instance_t * this_mac,uint32_t filter_no,const mss_mac_type_2_filter_t * filter)4458 void MSS_MAC_set_type_2_filter(const mss_mac_instance_t *this_mac, uint32_t filter_no, const mss_mac_type_2_filter_t *filter)
4459 {
4460 volatile uint32_t *p_reg;
4461 uint32_t limit;
4462 uint32_t temp_reg = 0U;
4463
4464 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4465 {
4466 if(0U != this_mac->is_emac) /* eMAC limits are different to pMAC ones */
4467 {
4468 p_reg = &this_mac->emac_base->SCREENING_TYPE_2_REGISTER_0;
4469 limit = MSS_MAC_EMAC_TYPE_2_SCREENERS;
4470 }
4471 else
4472 {
4473 p_reg = &this_mac->mac_base->SCREENING_TYPE_2_REGISTER_0;
4474 limit = MSS_MAC_TYPE_2_SCREENERS;
4475 }
4476
4477 if(filter_no < limit) /* Lets go build a filter... */
4478 {
4479 if(0u != (filter->drop_on_match))
4480 {
4481 temp_reg = GEM_T2_DROP_ON_MATCH;
4482 }
4483 else
4484 {
4485 temp_reg = 0U;
4486 }
4487
4488 if(0U != (filter->compare_a_enable))
4489 {
4490 temp_reg |= GEM_COMPARE_A_ENABLE;
4491 temp_reg |= ((uint32_t)filter->compare_a_index & BITS_05) << GEM_COMPARE_A_SHIFT;
4492 }
4493
4494 if(0U != (filter->compare_b_enable))
4495 {
4496 temp_reg |= GEM_COMPARE_B_ENABLE;
4497 temp_reg |= ((uint32_t)filter->compare_b_index & BITS_05) << GEM_COMPARE_B_SHIFT;
4498 }
4499
4500 if(0U != (filter->compare_c_enable))
4501 {
4502 temp_reg |= GEM_COMPARE_C_ENABLE;
4503 temp_reg |= ((uint32_t)filter->compare_c_index & BITS_05) << GEM_COMPARE_C_SHIFT;
4504 }
4505
4506 if(0U != (filter->ethertype_enable))
4507 {
4508 temp_reg |= GEM_ETHERTYPE_ENABLE;
4509 temp_reg |= ((uint32_t)filter->ethertype_index & BITS_03) << GEM_ETHERTYPE_REG_INDEX_SHIFT;
4510 }
4511
4512 if(0U != (filter->vlan_priority_enable))
4513 {
4514 temp_reg |= GEM_VLAN_ENABLE;
4515 temp_reg |= ((uint32_t)filter->vlan_priority & BITS_03) << GEM_VLAN_PRIORITY_SHIFT;
4516 }
4517
4518 temp_reg |= (uint32_t)filter->queue_no & GEM_QUEUE_NUMBER;
4519
4520 p_reg[filter_no] = temp_reg; /* Set filter up at last */
4521 }
4522 }
4523 }
4524
4525
4526 /******************************************************************************
4527 * See mss_ethernet_mac.h for details of how to use this function.
4528 */
4529
MSS_MAC_get_type_2_filter(const mss_mac_instance_t * this_mac,uint32_t filter_no,mss_mac_type_2_filter_t * filter)4530 void MSS_MAC_get_type_2_filter(const mss_mac_instance_t *this_mac, uint32_t filter_no, mss_mac_type_2_filter_t *filter)
4531 {
4532 volatile uint32_t *p_reg;
4533 uint32_t limit;
4534
4535 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4536 {
4537 (void)memset(filter, 0, sizeof(mss_mac_type_2_filter_t));
4538 if(0U != this_mac->is_emac) /* eMAC limits are different to pMAC ones */
4539 {
4540 p_reg = &this_mac->emac_base->SCREENING_TYPE_2_REGISTER_0;
4541 limit = MSS_MAC_EMAC_TYPE_2_SCREENERS;
4542 }
4543 else
4544 {
4545 p_reg = &this_mac->mac_base->SCREENING_TYPE_2_REGISTER_0;
4546 limit = MSS_MAC_TYPE_2_SCREENERS;
4547 }
4548
4549 if(filter_no < limit) /* Lets go fetch a filter... */
4550 {
4551 if(0U != (p_reg[filter_no] & GEM_T2_DROP_ON_MATCH))
4552 {
4553 filter->drop_on_match = 1;
4554 }
4555
4556 if(0U != (p_reg[filter_no] & GEM_COMPARE_A_ENABLE))
4557 {
4558 filter->compare_a_enable = 1;
4559 }
4560
4561 if(0U != (p_reg[filter_no] & GEM_COMPARE_B_ENABLE))
4562 {
4563 filter->compare_b_enable = 1;
4564 }
4565
4566 if(0U != (p_reg[filter_no] & GEM_COMPARE_C_ENABLE))
4567 {
4568 filter->compare_c_enable = 1;
4569 }
4570
4571 if(0U != (p_reg[filter_no] & GEM_ETHERTYPE_ENABLE))
4572 {
4573 filter->ethertype_enable = 1;
4574 }
4575
4576 if(0U != (p_reg[filter_no] & GEM_VLAN_ENABLE))
4577 {
4578 filter->vlan_priority_enable = 1;
4579 }
4580
4581 filter->compare_a_index = (uint8_t)((p_reg[filter_no] & GEM_COMPARE_A) >> GEM_COMPARE_A_SHIFT);
4582 filter->compare_b_index = (uint8_t)((p_reg[filter_no] & GEM_COMPARE_B) >> GEM_COMPARE_B_SHIFT);
4583 filter->compare_c_index = (uint8_t)((p_reg[filter_no] & GEM_COMPARE_C) >> GEM_COMPARE_C_SHIFT);
4584 filter->ethertype_index = (uint8_t)((p_reg[filter_no] & GEM_ETHERTYPE_REG_INDEX) >> GEM_ETHERTYPE_REG_INDEX_SHIFT);
4585 filter->vlan_priority = (uint8_t)((p_reg[filter_no] & GEM_VLAN_PRIORITY) >> GEM_VLAN_PRIORITY_SHIFT);
4586 filter->queue_no = (uint8_t)(p_reg[filter_no] & GEM_QUEUE_NUMBER);
4587 }
4588 }
4589 }
4590
4591
4592 /******************************************************************************
4593 * See mss_ethernet_mac.h for details of how to use this function.
4594 */
4595
MSS_MAC_set_mmsl_mode(const mss_mac_instance_t * this_mac,const mss_mac_mmsl_config_t * mmsl_cfg)4596 void MSS_MAC_set_mmsl_mode(const mss_mac_instance_t *this_mac, const mss_mac_mmsl_config_t *mmsl_cfg)
4597 {
4598 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4599 {
4600 if(0U != mmsl_cfg->preemption) /* Preemption is enabled so deal with it */
4601 {
4602 /*
4603 * Need to shut preemption down in case it is already enabled
4604 * otherwise the new settings may not be recognised properly.
4605 */
4606 this_mac->mac_base->MMSL_CONTROL = 0U;
4607
4608 if(0U != mmsl_cfg->verify_disable)
4609 {
4610 this_mac->mac_base->MMSL_CONTROL |= ((uint32_t)(mmsl_cfg->frag_size)) | GEM_VERIFY_DISABLE;
4611 this_mac->mac_base->MMSL_CONTROL |= GEM_PRE_ENABLE;
4612 }
4613 else
4614 {
4615 this_mac->mac_base->MMSL_CONTROL |= (uint32_t)(mmsl_cfg->frag_size);
4616 this_mac->mac_base->MMSL_CONTROL |= GEM_PRE_ENABLE;
4617 }
4618 }
4619 else /* Preemption is not enabled so see which MAC we want to use */
4620 {
4621 if(0U != mmsl_cfg->use_pmac)
4622 {
4623 this_mac->mac_base->MMSL_CONTROL = GEM_ROUTE_RX_TO_PMAC;
4624 }
4625 else
4626 {
4627 this_mac->mac_base->MMSL_CONTROL = 0U;
4628 }
4629 }
4630 }
4631 }
4632
4633
4634 /******************************************************************************
4635 * See mss_ethernet_mac.h for details of how to use this function.
4636 */
4637
MSS_MAC_get_mmsl_mode(const mss_mac_instance_t * this_mac,mss_mac_mmsl_config_t * mmsl_cfg)4638 void MSS_MAC_get_mmsl_mode(const mss_mac_instance_t *this_mac, mss_mac_mmsl_config_t *mmsl_cfg)
4639 {
4640 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4641 {
4642 (void)memset(mmsl_cfg, 0, sizeof(mss_mac_mmsl_config_t));
4643 if(0U != (this_mac->mac_base->MMSL_CONTROL & GEM_ROUTE_RX_TO_PMAC))
4644 {
4645 mmsl_cfg->use_pmac = 1U;
4646 }
4647
4648 if(0U != (this_mac->mac_base->MMSL_CONTROL & GEM_PRE_ENABLE))
4649 {
4650 mmsl_cfg->preemption = 1U;
4651 }
4652
4653 if(0U != (this_mac->mac_base->MMSL_CONTROL & GEM_VERIFY_DISABLE))
4654 {
4655 mmsl_cfg->verify_disable = 1U;
4656 }
4657
4658 mmsl_cfg->frag_size = (mss_mac_frag_size_t)(this_mac->mac_base->MMSL_CONTROL & BITS_02);
4659 }
4660 }
4661
4662
4663 /******************************************************************************
4664 * See mss_ethernet_mac.h for details of how to use this function.
4665 */
4666
MSS_MAC_start_preemption_verify(const mss_mac_instance_t * this_mac)4667 void MSS_MAC_start_preemption_verify(const mss_mac_instance_t *this_mac)
4668 {
4669 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4670 {
4671 if(0U != (this_mac->mac_base->MMSL_CONTROL & GEM_PRE_ENABLE)) /* Preemption is enabled */
4672 {
4673 this_mac->mac_base->MMSL_CONTROL |= GEM_RESTART_VER;
4674 }
4675 }
4676 }
4677
4678
4679 /******************************************************************************
4680 * See mss_ethernet_mac.h for details of how to use this function.
4681 */
4682
MSS_MAC_get_mmsl_status(const mss_mac_instance_t * this_mac)4683 uint32_t MSS_MAC_get_mmsl_status(const mss_mac_instance_t *this_mac)
4684 {
4685 uint32_t ret_val = 0U;
4686
4687 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4688 {
4689 ret_val = this_mac->mac_base->MMSL_STATUS; /* Just return raw value, user can decode using defined bits */
4690 }
4691
4692 return(ret_val);
4693 }
4694
4695
4696 /******************************************************************************
4697 * See mss_ethernet_mac.h for details of how to use this function.
4698 */
4699
MSS_MAC_get_mmsl_stats(const mss_mac_instance_t * this_mac,mss_mac_mmsl_stats_t * stats)4700 void MSS_MAC_get_mmsl_stats(const mss_mac_instance_t *this_mac, mss_mac_mmsl_stats_t *stats)
4701 {
4702 /*
4703 * We return these differently to the general statistics as they are pMAC
4704 * specific and don't have a corresponding eMAC equivalent.
4705 */
4706 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4707 {
4708 (void)memset(stats, 0, sizeof(mss_mac_mmsl_stats_t));
4709 stats->smd_err_count = (this_mac->mac_base->MMSL_ERR_STATS & GEM_SMD_ERR_COUNT) >> GEM_SMD_ERR_COUNT_SHIFT;
4710 stats->ass_err_count = this_mac->mac_base->MMSL_ERR_STATS & GEM_ASS_ERR_COUNT;
4711 stats->ass_ok_count = this_mac->mac_base->MMSL_ASS_OK_COUNT;
4712 stats->frag_count_rx = this_mac->mac_base->MMSL_FRAG_COUNT_RX;
4713 stats->frag_count_tx = this_mac->mac_base->MMSL_FRAG_COUNT_TX;
4714 }
4715 }
4716
4717
4718 /******************************************************************************
4719 * See mss_ethernet_mac.h for details of how to use this function.
4720 */
4721
MSS_MAC_set_tx_cutthru(const mss_mac_instance_t * this_mac,uint32_t level)4722 void MSS_MAC_set_tx_cutthru(const mss_mac_instance_t *this_mac, uint32_t level)
4723 {
4724 volatile uint32_t *p_reg;
4725 uint32_t mask;
4726
4727 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4728 {
4729 p_reg = (0U != this_mac->is_emac) ? &this_mac->emac_base->PBUF_TXCUTTHRU : &this_mac->mac_base->PBUF_TXCUTTHRU;
4730 mask = (0U != this_mac->is_emac) ? GEM_DMA_EMAC_CUTTHRU_THRESHOLD : GEM_DMA_TX_CUTTHRU_THRESHOLD;
4731
4732 if(0U == level) /* Disabling cutthru? */
4733 {
4734 *p_reg = 0U;
4735 }
4736 else
4737 {
4738 *p_reg = GEM_DMA_CUTTHRU | (level & mask);
4739 }
4740 }
4741 }
4742
4743
4744 /******************************************************************************
4745 * See mss_ethernet_mac.h for details of how to use this function.
4746 */
4747
MSS_MAC_set_rx_cutthru(const mss_mac_instance_t * this_mac,uint32_t level)4748 void MSS_MAC_set_rx_cutthru(const mss_mac_instance_t *this_mac, uint32_t level)
4749 {
4750 volatile uint32_t *p_reg;
4751 uint32_t mask;
4752
4753 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4754 {
4755 p_reg = (0U != this_mac->is_emac) ? &this_mac->emac_base->PBUF_RXCUTTHRU : &this_mac->mac_base->PBUF_RXCUTTHRU;
4756 mask = (0U != this_mac->is_emac) ? GEM_DMA_EMAC_CUTTHRU_THRESHOLD : GEM_DMA_RX_CUTTHRU_THRESHOLD;
4757
4758 if(0U == level) /* Disabling cutthru? */
4759 {
4760 *p_reg = 0U;
4761 }
4762 else
4763 {
4764 *p_reg = GEM_DMA_CUTTHRU | (level & mask);
4765 }
4766 }
4767 }
4768
4769
4770 /******************************************************************************
4771 * See mss_ethernet_mac.h for details of how to use this function.
4772 */
4773
MSS_MAC_get_tx_cutthru(const mss_mac_instance_t * this_mac)4774 uint32_t MSS_MAC_get_tx_cutthru(const mss_mac_instance_t *this_mac)
4775 {
4776 uint32_t temp_reg = 0U;
4777 volatile uint32_t *p_reg;
4778 uint32_t mask;
4779
4780 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4781 {
4782 p_reg = (0U != this_mac->is_emac) ? &this_mac->emac_base->PBUF_TXCUTTHRU : &this_mac->mac_base->PBUF_TXCUTTHRU;
4783 mask = (0U != this_mac->is_emac) ? GEM_DMA_EMAC_CUTTHRU_THRESHOLD : GEM_DMA_TX_CUTTHRU_THRESHOLD;
4784
4785 temp_reg = *p_reg;
4786 if(0U == (temp_reg & GEM_DMA_CUTTHRU))
4787 {
4788 temp_reg = 0U;
4789 }
4790 else
4791 {
4792 temp_reg &= mask;
4793 }
4794 }
4795
4796 return(temp_reg);
4797 }
4798
4799
4800 /******************************************************************************
4801 * See mss_ethernet_mac.h for details of how to use this function.
4802 */
4803
MSS_MAC_get_rx_cutthru(const mss_mac_instance_t * this_mac)4804 uint32_t MSS_MAC_get_rx_cutthru(const mss_mac_instance_t *this_mac)
4805 {
4806 uint32_t temp_reg = 0U;
4807 volatile uint32_t *p_reg;
4808 uint32_t mask;
4809
4810 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4811 {
4812 p_reg = (0U != this_mac->is_emac) ? &this_mac->emac_base->PBUF_RXCUTTHRU : &this_mac->mac_base->PBUF_RXCUTTHRU;
4813 mask = (0U != this_mac->is_emac) ? GEM_DMA_EMAC_CUTTHRU_THRESHOLD : GEM_DMA_RX_CUTTHRU_THRESHOLD;
4814
4815 temp_reg = *p_reg;
4816 if(0U == (temp_reg & GEM_DMA_CUTTHRU))
4817 {
4818 temp_reg = 0U;
4819 }
4820 else
4821 {
4822 temp_reg &= mask;
4823 }
4824 }
4825
4826 return(temp_reg);
4827 }
4828
4829
4830 /******************************************************************************
4831 * See mss_ethernet_mac.h for details of how to use this function.
4832 */
4833
MSS_MAC_tx_enable(const mss_mac_instance_t * this_mac)4834 void MSS_MAC_tx_enable(const mss_mac_instance_t *this_mac)
4835 {
4836 /* Don't do this if already done in case it has side effects... */
4837 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4838 {
4839 if(0U != this_mac->is_emac)
4840 {
4841 if(0U == (this_mac->emac_base->NETWORK_CONTROL & GEM_ENABLE_TRANSMIT))
4842 {
4843 this_mac->emac_base->NETWORK_CONTROL |= GEM_ENABLE_TRANSMIT;
4844 }
4845 }
4846 else
4847 {
4848 if(0U == (this_mac->mac_base->NETWORK_CONTROL & GEM_ENABLE_TRANSMIT))
4849 {
4850 this_mac->mac_base->NETWORK_CONTROL |= GEM_ENABLE_TRANSMIT;
4851 }
4852 }
4853 }
4854 }
4855
4856
4857 /******************************************************************************
4858 * See mss_ethernet_mac.h for details of how to use this function.
4859 */
4860
MSS_MAC_set_jumbo_frames_mode(const mss_mac_instance_t * this_mac,bool state)4861 void MSS_MAC_set_jumbo_frames_mode(const mss_mac_instance_t *this_mac, bool state)
4862 {
4863 volatile uint32_t *p_reg = &this_mac->mac_base->NETWORK_CONFIG;
4864
4865 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4866 {
4867 if(0U != this_mac->is_emac)
4868 {
4869 p_reg = &this_mac->emac_base->NETWORK_CONFIG;
4870 }
4871
4872 if(0U != this_mac->jumbo_frame_enable) /* Only look at this if the feature is enabled in config */
4873 {
4874 if(state)
4875 {
4876 *p_reg |= GEM_JUMBO_FRAMES;
4877 }
4878 else
4879 {
4880 *p_reg &= ~GEM_JUMBO_FRAMES;
4881 }
4882 }
4883 else /* Ensure it is disabled if not allowed... */
4884 {
4885 *p_reg &= ~GEM_JUMBO_FRAMES;
4886 }
4887 }
4888 }
4889
4890
4891 /******************************************************************************
4892 * See mss_ethernet_mac.h for details of how to use this function.
4893 */
4894
MSS_MAC_get_jumbo_frames_mode(const mss_mac_instance_t * this_mac)4895 bool MSS_MAC_get_jumbo_frames_mode(const mss_mac_instance_t *this_mac)
4896 {
4897 bool ret_val = false;
4898 volatile uint32_t *p_reg = &this_mac->mac_base->NETWORK_CONFIG;
4899
4900 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4901 {
4902 if(0U != this_mac->is_emac)
4903 {
4904 p_reg = &this_mac->emac_base->NETWORK_CONFIG;
4905 }
4906
4907 ret_val = ((*p_reg & GEM_JUMBO_FRAMES) != 0U);
4908 }
4909
4910 return(ret_val);
4911 }
4912
4913
4914 /******************************************************************************
4915 * See mss_ethernet_mac.h for details of how to use this function.
4916 */
4917
MSS_MAC_set_jumbo_frame_length(const mss_mac_instance_t * this_mac,uint32_t length_in)4918 void MSS_MAC_set_jumbo_frame_length(const mss_mac_instance_t *this_mac, uint32_t length_in)
4919 {
4920 volatile uint32_t *p_reg = &this_mac->mac_base->JUMBO_MAX_LENGTH;
4921 uint32_t length = length_in; /* Avoids warning about modifying parameter passed by value */
4922
4923 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4924 {
4925 if(0U != this_mac->is_emac)
4926 {
4927 p_reg = &this_mac->emac_base->JUMBO_MAX_LENGTH;
4928 }
4929
4930 /* Set up maximum jumbo frame size - but bounds check first */
4931 if(length > MSS_MAC_JUMBO_MAX)
4932 {
4933 length = MSS_MAC_JUMBO_MAX;
4934 }
4935
4936 if(0U != this_mac->jumbo_frame_enable) /* Only look at this if the feature is enabled in config */
4937 {
4938 *p_reg = length;
4939 }
4940 else /* Ensure it is set to reset value if not allowed... */
4941 {
4942 *p_reg = MSS_MAC_JUMBO_MAX;
4943 }
4944 }
4945 }
4946
4947
4948 /******************************************************************************
4949 * See mss_ethernet_mac.h for details of how to use this function.
4950 */
4951
MSS_MAC_get_jumbo_frame_length(const mss_mac_instance_t * this_mac)4952 uint32_t MSS_MAC_get_jumbo_frame_length(const mss_mac_instance_t *this_mac)
4953 {
4954 uint32_t ret_val = 0;
4955 volatile uint32_t *p_reg = &this_mac->mac_base->JUMBO_MAX_LENGTH;
4956
4957 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4958 {
4959 if(0U != this_mac->is_emac)
4960 {
4961 p_reg = &this_mac->emac_base->JUMBO_MAX_LENGTH;
4962 }
4963
4964 ret_val = *p_reg;
4965 }
4966
4967 return(ret_val);
4968 }
4969
4970
4971 /******************************************************************************
4972 * See mss_ethernet_mac.h for details of how to use this function.
4973 */
4974
MSS_MAC_set_pause_frame_copy_to_mem(const mss_mac_instance_t * this_mac,bool state)4975 void MSS_MAC_set_pause_frame_copy_to_mem(const mss_mac_instance_t *this_mac, bool state)
4976 {
4977 volatile uint32_t *p_reg = &this_mac->mac_base->NETWORK_CONFIG;
4978
4979 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
4980 {
4981 if(0U != this_mac->is_emac)
4982 {
4983 p_reg = &this_mac->emac_base->NETWORK_CONFIG;
4984 }
4985 /*
4986 * Logic is inverted as enabling copy to memory means disabling
4987 * GEM_DISABLE_COPY_OF_PAUSE_FRAMES
4988 */
4989 if(state)
4990 {
4991 *p_reg &= ~GEM_DISABLE_COPY_OF_PAUSE_FRAMES;
4992 }
4993 else
4994 {
4995 *p_reg |= GEM_DISABLE_COPY_OF_PAUSE_FRAMES;
4996 }
4997 }
4998 }
4999
5000
5001 /******************************************************************************
5002 * See mss_ethernet_mac.h for details of how to use this function.
5003 */
5004
MSS_MAC_get_pause_frame_copy_to_mem(const mss_mac_instance_t * this_mac)5005 bool MSS_MAC_get_pause_frame_copy_to_mem(const mss_mac_instance_t *this_mac)
5006 {
5007 bool ret_val = false;
5008 volatile uint32_t *p_reg = &this_mac->mac_base->NETWORK_CONFIG;
5009
5010 if(MSS_MAC_AVAILABLE == this_mac->mac_available)
5011 {
5012 if(0U != this_mac->is_emac)
5013 {
5014 p_reg = &this_mac->emac_base->NETWORK_CONFIG;
5015 }
5016
5017 /*
5018 * Logic is inverted as enabling copy to memory means disabling
5019 * GEM_DISABLE_COPY_OF_PAUSE_FRAMES
5020 */
5021 ret_val = 0U == (*p_reg & GEM_DISABLE_COPY_OF_PAUSE_FRAMES);
5022 }
5023
5024 return(ret_val);
5025 }
5026
5027
5028 /**************************************************************************/
5029 /* Private Function definitions */
5030 /**************************************************************************/
5031
5032 /******************************************************************************
5033 * This is default "Receive packet interrupt handler. This function finds the
5034 * descriptor that received the packet and caused the interrupt.
5035 * This informs the received packet size to the application and
5036 * relinquishes the packet buffer from the associated DMA descriptor.
5037 */
5038 static void
rxpkt_handler(mss_mac_instance_t * this_mac,uint64_t queue_no)5039 rxpkt_handler
5040 (
5041 mss_mac_instance_t *this_mac, uint64_t queue_no
5042 )
5043 {
5044 mss_mac_queue_t *this_queue = &this_mac->queue[queue_no];
5045 mss_mac_rx_desc_t * cdesc = &this_queue->rx_desc_tab[this_queue->first_rx_desc_index];
5046 uint64_t burst = MSS_MAC_RX_RING_SIZE;
5047
5048 if(0U != (cdesc->addr_low & GEM_RX_DMA_USED)) /* Check in case we already got it... */
5049 {
5050 /* Execution comes here because at-least one packet is received. */
5051 do
5052 {
5053 uint8_t * p_rx_packet;
5054 uint32_t pckt_length;
5055 #if defined(MSS_MAC_64_BIT_ADDRESS_MODE)
5056 uint64_t addr_temp;
5057 #else
5058 uint32_t addr_temp;
5059 #endif
5060
5061 ++this_queue->nb_available_rx_desc;
5062 #if defined(MSS_MAC_64_BIT_ADDRESS_MODE)
5063 addr_temp = (uint64_t)(cdesc->addr_low & ~(GEM_RX_DMA_WRAP | GEM_RX_DMA_USED | GEM_RX_DMA_TS_PRESENT));
5064 addr_temp |= (uint64_t)cdesc->addr_high << 32;
5065 #else
5066 addr_temp = (cdesc->addr_low & ~(GEM_RX_DMA_WRAP | GEM_RX_DMA_USED | GEM_RX_DMA_TS_PRESENT));
5067 #endif
5068 p_rx_packet = (uint8_t *)addr_temp;
5069 /*
5070 * Pass received packet up to application layer - if enabled...
5071 *
5072 * Note if rx_packet comes back as 0 we can't recover and will leave a
5073 * used packet stuck in the queue...
5074 */
5075 #if !defined(MSS_MAC_UNH_TEST)
5076 if((NULL_POINTER != this_queue->pckt_rx_callback) && (NULL_POINTER != p_rx_packet) && (0U == this_mac->rx_discard))
5077 #endif
5078 {
5079 pckt_length = cdesc->status & (GEM_RX_DMA_BUFF_LEN | GEM_RX_DMA_JUMBO_BIT_13);
5080 this_queue->ingress += pckt_length;
5081
5082 this_queue->pckt_rx_callback(this_mac, queue_no, p_rx_packet, pckt_length, cdesc, this_queue->rx_caller_info[this_queue->first_rx_desc_index]);
5083 }
5084
5085 #if !defined(MSS_MAC_UNH_TEST)
5086 if((NULL_POINTER != p_rx_packet) && (0U != this_mac->rx_discard))
5087 {
5088 /*
5089 * Need to return receive packet buffer to the queue as rx handler
5090 * hasn't been called to do it for us...
5091 */
5092 (void)MSS_MAC_receive_pkt(this_mac, queue_no, p_rx_packet, this_queue->rx_caller_info[this_queue->first_rx_desc_index], MSS_MAC_INT_ENABLE);
5093 }
5094 #endif
5095
5096 /* Point the curr_rx_desc to next descriptor in the ring */
5097 /* Wrap around in case next descriptor is pointing to last in the ring */
5098 ++this_queue->first_rx_desc_index;
5099 this_queue->first_rx_desc_index %= MSS_MAC_RX_RING_SIZE;
5100
5101 cdesc = &this_queue->rx_desc_tab[this_queue->first_rx_desc_index];
5102 burst--;
5103 } while(0 != (cdesc->addr_low & GEM_RX_DMA_USED) && (0 != burst)); /* loop while there are packets available */
5104 }
5105
5106 if(0U == (this_mac->mac_base->NETWORK_CONTROL & GEM_ENABLE_RECEIVE))
5107 {
5108 this_mac->mac_base->NETWORK_CONTROL |= GEM_ENABLE_RECEIVE;
5109 }
5110 }
5111
5112
5113 /******************************************************************************
5114 * This is default "Transmit packet interrupt handler. This function finds the
5115 * descriptor that transmitted the packet and caused the interrupt.
5116 * This relinquishes the packet buffer from the associated DMA descriptor.
5117 */
5118
5119 static void
txpkt_handler(mss_mac_instance_t * this_mac,uint64_t queue_no)5120 txpkt_handler
5121 (
5122 mss_mac_instance_t *this_mac, uint64_t queue_no
5123 )
5124 {
5125 #if defined(MSS_MAC_SIMPLE_TX_QUEUE)
5126 mss_mac_queue_t *this_queue = &this_mac->queue[queue_no];
5127 mss_mac_tx_desc_t *p_current_desc;
5128 uint32_t finished;
5129
5130 /*
5131 * Simple multi packet TX queue where only the one packet buffer is used
5132 * per frame but we do have 1 extra descriptor to stop DMA engine running
5133 * over itself...
5134 */
5135
5136 p_current_desc = &this_queue->tx_desc_tab[this_queue->current_tx_desc];
5137 finished = 0;
5138 while(!finished)
5139 {
5140 if(this_queue->nb_available_tx_desc == MSS_MAC_TX_RING_SIZE)
5141 {
5142 *this_queue->transmit_q_ptr = (uint32_t)((uint64_t)this_queue->tx_desc_tab) | 1UL; /* Disable the TX queue */
5143 finished = 1;
5144 }
5145 else
5146 {
5147 if(p_current_desc->status & GEM_TX_DMA_USED)
5148 {
5149 if(NULL_POINTER != this_queue->pckt_tx_callback)
5150 {
5151 this_queue->pckt_tx_callback(this_mac, queue_no, p_current_desc, this_queue->tx_caller_info[this_queue->current_tx_desc]);
5152 }
5153 this_queue->nb_available_tx_desc++;
5154 p_current_desc++;
5155 this_queue->current_tx_desc++;
5156 }
5157 else
5158 {
5159 finished = 1;
5160 }
5161 }
5162 }
5163 #else
5164 #error "Multi packet TX not implemented!"
5165 #endif
5166 }
5167
5168
5169 /******************************************************************************
5170 *
5171 */
tx_desc_ring_init(mss_mac_instance_t * this_mac)5172 static void tx_desc_ring_init(mss_mac_instance_t *this_mac)
5173 {
5174 int32_t inc;
5175 int32_t queue_no;
5176
5177 for(queue_no = 0; queue_no < MSS_MAC_QUEUE_COUNT; queue_no++)
5178 {
5179 #if defined(MSS_MAC_USE_DDR)
5180 this_mac->queue[queue_no].tx_desc_tab = g_mss_mac_ddr_ptr;
5181 g_mss_mac_ddr_ptr += MSS_MAC_TX_RING_SIZE * sizeof(mss_mac_tx_desc_t);
5182 #endif
5183 for(inc = 0; inc < MSS_MAC_TX_RING_SIZE; ++inc)
5184 {
5185 this_mac->queue[queue_no].tx_desc_tab[inc].addr_low = 0U;
5186 #if defined(MSS_MAC_64_BIT_ADDRESS_MODE)
5187 this_mac->queue[queue_no].tx_desc_tab[inc].addr_high = 0U;
5188 #endif
5189 this_mac->queue[queue_no].tx_desc_tab[inc].status = GEM_TX_DMA_USED;
5190 }
5191
5192 inc--; /* Step back to last buffer descriptor and mark as end of list */
5193 this_mac->queue[queue_no].tx_desc_tab[inc].status |= GEM_TX_DMA_WRAP;
5194 }
5195 }
5196
5197
5198 /******************************************************************************
5199 *
5200 */
rx_desc_ring_init(mss_mac_instance_t * this_mac)5201 static void rx_desc_ring_init(mss_mac_instance_t *this_mac)
5202 {
5203 uint32_t inc;
5204 int32_t queue_no;
5205
5206 for(queue_no = 0; queue_no < MSS_MAC_QUEUE_COUNT; queue_no++)
5207 {
5208 #if defined(MSS_MAC_USE_DDR)
5209 this_mac->queue[queue_no].rx_desc_tab = g_mss_mac_ddr_ptr;
5210 g_mss_mac_ddr_ptr += MSS_MAC_RX_RING_SIZE * sizeof(mss_mac_rx_desc_t);
5211 #endif
5212
5213 for(inc = 0U; inc < MSS_MAC_RX_RING_SIZE; ++inc)
5214 {
5215 this_mac->queue[queue_no].rx_desc_tab[inc].addr_low = 0U; /* Mark buffers as used for now in case DMA gets enabled before we attach a buffer */
5216 #if defined(MSS_MAC_64_BIT_ADDRESS_MODE)
5217 this_mac->queue[queue_no].rx_desc_tab[inc].addr_high = 0U;
5218 #endif
5219 this_mac->queue[queue_no].rx_desc_tab[inc].status = 0U;
5220 }
5221
5222 inc--; /* Step back to last buffer descriptor and mark as end of list */
5223 this_mac->queue[queue_no].rx_desc_tab[inc].addr_low |= GEM_RX_DMA_WRAP;
5224 }
5225 }
5226
5227
5228 /******************************************************************************
5229 *
5230 */
assign_station_addr(mss_mac_instance_t * this_mac,const uint8_t mac_addr[MSS_MAC_MAC_LEN])5231 static void assign_station_addr
5232 (
5233 mss_mac_instance_t *this_mac,
5234 const uint8_t mac_addr[MSS_MAC_MAC_LEN]
5235 )
5236 {
5237 uint32_t address32_l;
5238 uint32_t address32_h;
5239
5240 ASSERT(NULL_POINTER != mac_addr);
5241
5242 if((NULL_POINTER != mac_addr) && (NULL_POINTER != this_mac))
5243 {
5244 /* Update current instance data */
5245 (void)memcpy(this_mac->mac_addr, mac_addr, MSS_MAC_MAC_LEN);
5246
5247 /* Assemble correct register values */
5248 address32_l = ((uint32_t)mac_addr[3]) << 24;
5249 address32_l |= ((uint32_t)mac_addr[2]) << 16;
5250 address32_l |= ((uint32_t)mac_addr[1]) << 8;
5251 address32_l |= ((uint32_t)mac_addr[0]);
5252 address32_h = ((uint32_t)mac_addr[5]) << 8;
5253 address32_h |= ((uint32_t)mac_addr[4]);
5254
5255 /* Update hardware registers */
5256 if(0U != this_mac->is_emac)
5257 {
5258 this_mac->emac_base->SPEC_ADD1_BOTTOM = address32_l;
5259 this_mac->emac_base->SPEC_ADD1_TOP = address32_h;
5260 /*
5261 * If being done from init for first time we also make sure the
5262 * specific address filters are disabled...
5263 */
5264 if(this_mac->mac_available != MSS_MAC_AVAILABLE)
5265 {
5266 this_mac->emac_base->SPEC_ADD2_TOP = 0U;
5267 this_mac->emac_base->SPEC_ADD2_BOTTOM = 0U;
5268 this_mac->emac_base->SPEC_ADD3_TOP = 0U;
5269 this_mac->emac_base->SPEC_ADD3_BOTTOM = 0U;
5270 this_mac->emac_base->SPEC_ADD4_TOP = 0U;
5271 this_mac->emac_base->SPEC_ADD4_BOTTOM = 0U;
5272 }
5273 }
5274 else
5275 {
5276 this_mac->mac_base->SPEC_ADD1_BOTTOM = address32_l;
5277 this_mac->mac_base->SPEC_ADD1_TOP = address32_h;
5278 /*
5279 * If being done from init for first time we also make sure the
5280 * specific address filters are disabled...
5281 */
5282 if(this_mac->mac_available != MSS_MAC_AVAILABLE)
5283 {
5284 this_mac->mac_base->SPEC_ADD2_TOP = 0U;
5285 this_mac->mac_base->SPEC_ADD2_BOTTOM = 0U;
5286 this_mac->mac_base->SPEC_ADD3_TOP = 0U;
5287 this_mac->mac_base->SPEC_ADD3_BOTTOM = 0U;
5288 this_mac->mac_base->SPEC_ADD4_TOP = 0U;
5289 this_mac->mac_base->SPEC_ADD4_BOTTOM = 0U;
5290 }
5291 }
5292 }
5293 }
5294
5295
5296 /*******************************************************************************
5297 * Auto-detect the PHY's address by attempting to read the PHY identification
5298 * register containing the PHY manufacturer's identifier.
5299 * Attempting to read a PHY register using an incorrect PHY address will result
5300 * in a value with all bits set to one on the MDIO bus. Reading any other value
5301 * means that a PHY responded to the read request, therefore we have found the
5302 * PHY's address.
5303 * This function returns the detected PHY's address or 32 (PHY_ADDRESS_MAX + 1)
5304 * if no PHY is responding.
5305 */
probe_phy(const mss_mac_instance_t * this_mac)5306 static uint8_t probe_phy(const mss_mac_instance_t *this_mac)
5307 {
5308 uint8_t phy_address = PHY_ADDRESS_MIN;
5309 const uint16_t ALL_BITS_HIGH = 0xFFFFU;
5310 const uint8_t PHYREG_PHYID1R = 0x02U; /* PHY Identifier 1 register address. */
5311 uint32_t found;
5312
5313 do
5314 {
5315 uint16_t reg;
5316
5317 reg = MSS_MAC_read_phy_reg(this_mac, phy_address, PHYREG_PHYID1R);
5318 if (reg != ALL_BITS_HIGH)
5319 {
5320 found = 1U;
5321 }
5322 else
5323 {
5324 found = 0U;
5325 ++phy_address;
5326 }
5327 }
5328 while ((phy_address <= PHY_ADDRESS_MAX) && (0U == found));
5329
5330 return phy_address;
5331 }
5332
5333
5334 /*******************************************************************************
5335 * MSS MAC TBI interface
5336 */
msgmii_init(const mss_mac_instance_t * this_mac)5337 static void msgmii_init(const mss_mac_instance_t *this_mac)
5338 {
5339 if(GMII_SGMII == this_mac->interface_type)
5340 {
5341 if(0U == this_mac->is_emac)
5342 {
5343 this_mac->mac_base->PCS_CONTROL = 0x9000UL; /* Reset and enable autonegotiation */
5344 }
5345 }
5346
5347 if(TBI == this_mac->interface_type)
5348 {
5349 if(0U == this_mac->is_emac)
5350 {
5351 this_mac->mac_base->PCS_CONTROL = 0x9000UL; /* Reset and enable autonegotiation */
5352 }
5353 }
5354 }
5355
5356
5357 /*******************************************************************************
5358 *
5359 */
msgmii_autonegotiate(const mss_mac_instance_t * this_mac)5360 void msgmii_autonegotiate(const mss_mac_instance_t *this_mac)
5361 {
5362 uint16_t phy_reg;
5363 uint16_t autoneg_complete;
5364 uint8_t link_fullduplex;
5365 mss_mac_speed_t link_speed;
5366 uint8_t copper_link_up;
5367
5368 volatile uint32_t sgmii_aneg_timeout = 100000U;
5369
5370 copper_link_up = this_mac->phy_get_link_status(this_mac, &link_speed, &link_fullduplex);
5371
5372 if(MSS_MAC_LINK_UP == copper_link_up)
5373 {
5374 /* Initiate auto-negotiation on the TBI SGMII link. */
5375 if(TBI == this_mac->interface_type)
5376 {
5377 phy_reg = (uint16_t)this_mac->mac_base->PCS_CONTROL;
5378 phy_reg |= 0x1000U;
5379 this_mac->mac_base->PCS_CONTROL = phy_reg;
5380 phy_reg |= 0x0200U;
5381 this_mac->mac_base->PCS_CONTROL = phy_reg;
5382
5383 /* Wait for SGMII auto-negotiation to complete. */
5384 do
5385 {
5386 phy_reg = (uint16_t)this_mac->mac_base->PCS_STATUS;
5387 autoneg_complete = phy_reg & BMSR_AUTO_NEGOTIATION_COMPLETE;
5388 --sgmii_aneg_timeout;
5389 } while(((0U == autoneg_complete) && (sgmii_aneg_timeout != 0U)) || (0xFFFFU == phy_reg));
5390 }
5391 }
5392 }
5393
5394
5395 #if 0
5396 /*******************************************************************************
5397 * SGMII or 1000BaseX interface with CoreSGMII
5398 */
5399 #if (MSS_MAC_PHY_INTERFACE == SGMII)
5400
5401 #define CORE_SGMII_PHY_ADDR MSS_MAC_INTERFACE_MDIO_ADDR
5402 /*******************************************************************************
5403 *
5404 */
5405 static void coresgmii_init(void)
5406 {
5407 uint16_t phy_reg;
5408
5409 /* Reset C-SGMII. */
5410 MSS_MAC_write_phy_reg(CORE_SGMII_PHY_ADDR, 0x00U, 0x9000U);
5411 /* Register 0x04 of C-SGMII must be always be set to 0x0001. */
5412 MSS_MAC_write_phy_reg(CORE_SGMII_PHY_ADDR, 0x04U, 0x0001U);
5413
5414 /* Enable auto-negotiation inside CoreSGMII block. */
5415 phy_reg = MSS_MAC_read_phy_reg(CORE_SGMII_PHY_ADDR, 0x00U);
5416 phy_reg |= 0x1000U;
5417 MSS_MAC_write_phy_reg(CORE_SGMII_PHY_ADDR, 0x00U, phy_reg);
5418 }
5419
5420
5421 /*******************************************************************************
5422 *
5423 */
5424 static void coresgmii_autonegotiate(void)
5425 {
5426 uint16_t phy_reg;
5427 uint16_t autoneg_complete;
5428 volatile uint32_t sgmii_aneg_timeout = 1000000U;
5429
5430 uint8_t link_fullduplex;
5431 mss_mac_speed_t link_speed;
5432 uint8_t copper_link_up;
5433
5434 copper_link_up = MSS_MAC_phy_get_link_status(&link_speed, &link_fullduplex);
5435
5436 if(MSS_MAC_LINK_UP == copper_link_up)
5437 {
5438 SYSREG->MAC_CR = (SYSREG->MAC_CR & ~MAC_CONFIG_SPEED_MASK) | link_speed;
5439
5440 /* Configure duplex mode */
5441 if(MSS_MAC_HALF_DUPLEX == link_fullduplex)
5442 {
5443 /* half duplex */
5444 MAC->CFG2 &= ~CFG2_FDX_MASK;
5445 }
5446 else
5447 {
5448 /* full duplex */
5449 MAC->CFG2 |= CFG2_FDX_MASK;
5450 }
5451 /* Initiate auto-negotiation on the SGMII link. */
5452 phy_reg = MSS_MAC_read_phy_reg(CORE_SGMII_PHY_ADDR, 0x00U);
5453 phy_reg |= 0x1000U;
5454 MSS_MAC_write_phy_reg(CORE_SGMII_PHY_ADDR, 0x00U, phy_reg);
5455 phy_reg |= 0x0200U;
5456 MSS_MAC_write_phy_reg(CORE_SGMII_PHY_ADDR, 0x00U, phy_reg);
5457
5458 /* Wait for SGMII auto-negotiation to complete. */
5459 do {
5460 phy_reg = MSS_MAC_read_phy_reg(CORE_SGMII_PHY_ADDR, MII_BMSR);
5461 autoneg_complete = phy_reg & BMSR_AUTO_NEGOTIATION_COMPLETE;
5462 --sgmii_aneg_timeout;
5463 } while(((0U == autoneg_complete) && (sgmii_aneg_timeout != 0U)) || (0xFFFFU == phy_reg));
5464 }
5465 }
5466
5467
5468 /*******************************************************************************
5469 * Generate clock 2.5/25/125MHz for 10/100/1000Mbps using Clock Condition Circuit(CCC)
5470 */
5471 static void coresgmii_set_link_speed(uint32_t speed)
5472 {
5473 uint16_t phy_reg;
5474
5475 phy_reg = MSS_MAC_read_phy_reg(CORE_SGMII_PHY_ADDR, 0x11U);
5476 phy_reg |= (speed << 2);
5477 MSS_MAC_write_phy_reg(CORE_SGMII_PHY_ADDR, 0x11U, phy_reg);
5478 }
5479
5480 #endif /* #if (MSS_MAC_PHY_INTERFACE == SGMII) */
5481 #endif
5482
5483
5484 /*******************************************************************************
5485 * Setup hardware addresses etc for instance structure(s).
5486 */
instances_init(mss_mac_instance_t * this_mac,mss_mac_cfg_t * cfg)5487 static void instances_init(mss_mac_instance_t *this_mac, mss_mac_cfg_t *cfg)
5488 {
5489 #if defined(TARGET_ALOE)
5490 /* These are unused for Aloe as there is only one pMAC and no alternate
5491 * address support required
5492 */
5493 (void)this_mac;
5494 (void)cfg;
5495
5496 (void)memset(&g_mac0, 0, sizeof(g_mac0));
5497
5498 g_mac0.use_hi_address = cfg->use_hi_address; /* Not really needed but to be consistent... */
5499
5500 g_mac0.is_emac = 0U;
5501 g_mac0.mac_base = (MAC_TypeDef *)MSS_MAC0_BASE;
5502 g_mac0.emac_base = (eMAC_TypeDef *)MSS_MAC0_BASE;
5503 g_mac0.mac_q_int[0] = ethernet_PLIC_53;
5504 g_mac0.queue[0].int_status = &g_mac0.mac_base->INT_STATUS;
5505 g_mac0.queue[0].int_mask = &g_mac0.mac_base->INT_MASK;
5506 g_mac0.queue[0].int_enable = &g_mac0.mac_base->INT_ENABLE;
5507 g_mac0.queue[0].int_disable = &g_mac0.mac_base->INT_DISABLE;
5508 g_mac0.queue[0].receive_q_ptr = &g_mac0.mac_base->RECEIVE_Q_PTR;
5509 g_mac0.queue[0].transmit_q_ptr = &g_mac0.mac_base->TRANSMIT_Q_PTR;
5510 g_mac0.queue[0].dma_rxbuf_size = &g_mac0.mac_base->DMA_RXBUF_SIZE_Q1; /* Not really true as this is done differently for queue 0 */
5511 #endif
5512 #if defined(TARGET_G5_SOC)
5513 (void)memset(this_mac, 0, sizeof(mss_mac_instance_t)); /* Start with blank canvas */
5514
5515 this_mac->use_hi_address = cfg->use_hi_address; /* Need to remember this for sanity checking */
5516 this_mac->use_local_ints = cfg->use_local_ints; /* Need to remember this for interrupt management */
5517
5518 if(&g_mac0 == this_mac)
5519 {
5520 if(MSS_MAC_DISABLE == cfg->use_hi_address)
5521 {
5522 this_mac->mac_base = (MAC_TypeDef *)MSS_MAC0_BASE;
5523 this_mac->emac_base = (eMAC_TypeDef *)MSS_EMAC0_BASE;
5524
5525 SYSREG->APBBUS_CR &= ~MSS_MAC_GEM0_ABP_BIT;
5526 }
5527 else
5528 {
5529 this_mac->mac_base = (MAC_TypeDef *)MSS_MAC0_BASE_HI;
5530 this_mac->emac_base = (eMAC_TypeDef *)MSS_EMAC0_BASE_HI;
5531
5532 SYSREG->APBBUS_CR |= MSS_MAC_GEM0_ABP_BIT;
5533 }
5534
5535 if(0U != this_mac->use_local_ints)
5536 {
5537 PLIC_DisableIRQ(MAC0_INT_PLIC);
5538 PLIC_DisableIRQ(MAC0_QUEUE1_PLIC);
5539 PLIC_DisableIRQ(MAC0_QUEUE2_PLIC);
5540 PLIC_DisableIRQ(MAC0_QUEUE3_PLIC);
5541 PLIC_DisableIRQ(MAC0_MMSL_PLIC);
5542
5543 this_mac->mac_q_int[0] = MAC0_INT_U54_INT;
5544 this_mac->mac_q_int[1] = MAC0_QUEUE1_U54_INT;
5545 this_mac->mac_q_int[2] = MAC0_QUEUE2_U54_INT;
5546 this_mac->mac_q_int[3] = MAC0_QUEUE3_U54_INT;
5547 this_mac->mmsl_int = MAC0_MMSL_U54_INT;
5548 }
5549 else
5550 {
5551 __disable_local_irq(MAC0_INT_U54_INT);
5552 __disable_local_irq(MAC0_QUEUE1_U54_INT);
5553 __disable_local_irq(MAC0_QUEUE2_U54_INT);
5554 __disable_local_irq(MAC0_QUEUE3_U54_INT);
5555 __disable_local_irq(MAC0_MMSL_U54_INT);
5556
5557 this_mac->mac_q_int[0] = MAC0_INT_PLIC;
5558 this_mac->mac_q_int[1] = MAC0_QUEUE1_PLIC;
5559 this_mac->mac_q_int[2] = MAC0_QUEUE2_PLIC;
5560 this_mac->mac_q_int[3] = MAC0_QUEUE3_PLIC;
5561 this_mac->mmsl_int = MAC0_MMSL_PLIC;
5562 }
5563 }
5564 else if(&g_mac1 == this_mac)
5565 {
5566 if(MSS_MAC_DISABLE == cfg->use_hi_address)
5567 {
5568 this_mac->mac_base = (MAC_TypeDef *)MSS_MAC1_BASE;
5569 this_mac->emac_base = (eMAC_TypeDef *)MSS_EMAC1_BASE;
5570
5571 SYSREG->APBBUS_CR &= ~MSS_MAC_GEM1_ABP_BIT;
5572 }
5573 else
5574 {
5575 this_mac->mac_base = (MAC_TypeDef *)MSS_MAC1_BASE_HI;
5576 this_mac->emac_base = (eMAC_TypeDef *)MSS_EMAC1_BASE_HI;
5577
5578 SYSREG->APBBUS_CR |= MSS_MAC_GEM1_ABP_BIT;
5579 }
5580
5581 if(0U != this_mac->use_local_ints)
5582 {
5583 PLIC_DisableIRQ(MAC1_INT_PLIC);
5584 PLIC_DisableIRQ(MAC1_QUEUE1_PLIC);
5585 PLIC_DisableIRQ(MAC1_QUEUE2_PLIC);
5586 PLIC_DisableIRQ(MAC1_QUEUE3_PLIC);
5587 PLIC_DisableIRQ(MAC1_MMSL_PLIC);
5588
5589 this_mac->mac_q_int[0] = MAC1_INT_U54_INT;
5590 this_mac->mac_q_int[1] = MAC1_QUEUE1_U54_INT;
5591 this_mac->mac_q_int[2] = MAC1_QUEUE2_U54_INT;
5592 this_mac->mac_q_int[3] = MAC1_QUEUE3_U54_INT;
5593 this_mac->mmsl_int = MAC1_MMSL_U54_INT;
5594 }
5595 else
5596 {
5597 __disable_local_irq(MAC1_INT_U54_INT);
5598 __disable_local_irq(MAC1_QUEUE1_U54_INT);
5599 __disable_local_irq(MAC1_QUEUE2_U54_INT);
5600 __disable_local_irq(MAC1_QUEUE3_U54_INT);
5601 __disable_local_irq(MAC1_MMSL_U54_INT);
5602
5603 this_mac->mac_q_int[0] = MAC1_INT_PLIC;
5604 this_mac->mac_q_int[1] = MAC1_QUEUE1_PLIC;
5605 this_mac->mac_q_int[2] = MAC1_QUEUE2_PLIC;
5606 this_mac->mac_q_int[3] = MAC1_QUEUE3_PLIC;
5607 this_mac->mmsl_int = MAC1_MMSL_PLIC;
5608 }
5609 }
5610 else if(&g_emac0 == this_mac)
5611 {
5612 this_mac->is_emac = 1;
5613 if(NULL_POINTER != g_mac0.mac_base) /* If pMAC already configured must use same */
5614 {
5615 cfg->use_hi_address = g_mac0.use_hi_address;
5616 }
5617
5618 if(MSS_MAC_DISABLE == cfg->use_hi_address)
5619 {
5620 this_mac->mac_base = (MAC_TypeDef *)MSS_MAC0_BASE;
5621 this_mac->emac_base = (eMAC_TypeDef *)MSS_EMAC0_BASE;
5622
5623 SYSREG->APBBUS_CR &= ~MSS_MAC_GEM0_ABP_BIT;
5624 }
5625 else
5626 {
5627 this_mac->mac_base = (MAC_TypeDef *)MSS_MAC0_BASE_HI;
5628 this_mac->emac_base = (eMAC_TypeDef *)MSS_EMAC0_BASE_HI;
5629 }
5630
5631 if(0U != this_mac->use_local_ints)
5632 {
5633 PLIC_DisableIRQ(MAC0_EMAC_PLIC);
5634
5635 this_mac->mac_q_int[0] = MAC0_EMAC_U54_INT;
5636 this_mac->mac_q_int[1] = LOCAL_INT_UNUSED;
5637 this_mac->mac_q_int[2] = LOCAL_INT_UNUSED;
5638 this_mac->mac_q_int[3] = LOCAL_INT_UNUSED;
5639 this_mac->mmsl_int = LOCAL_INT_UNUSED;
5640 }
5641 else
5642 {
5643 __disable_local_irq(MAC0_EMAC_U54_INT);
5644
5645 this_mac->mac_q_int[0] = MAC0_EMAC_PLIC;
5646 this_mac->mac_q_int[1] = INVALID_IRQn;
5647 this_mac->mac_q_int[2] = INVALID_IRQn;
5648 this_mac->mac_q_int[3] = INVALID_IRQn;
5649 this_mac->mmsl_int = INVALID_IRQn;
5650 }
5651 }
5652 else
5653 {
5654 if(&g_emac1 == this_mac)
5655 {
5656 this_mac->is_emac = 1U;
5657 if(MSS_MAC_DISABLE == cfg->use_hi_address)
5658 {
5659 this_mac->mac_base = (MAC_TypeDef *)MSS_MAC1_BASE;
5660 this_mac->emac_base = (eMAC_TypeDef *)MSS_EMAC1_BASE;
5661
5662 SYSREG->APBBUS_CR &= ~MSS_MAC_GEM1_ABP_BIT;
5663 }
5664 else
5665 {
5666 this_mac->mac_base = (MAC_TypeDef *)MSS_MAC1_BASE_HI;
5667 this_mac->emac_base = (eMAC_TypeDef *)MSS_EMAC1_BASE_HI;
5668
5669 SYSREG->APBBUS_CR |= MSS_MAC_GEM1_ABP_BIT;
5670 }
5671
5672 if(0U != this_mac->use_local_ints)
5673 {
5674 PLIC_DisableIRQ(MAC1_EMAC_PLIC);
5675
5676 this_mac->mac_q_int[0] = MAC1_EMAC_U54_INT;
5677 this_mac->mac_q_int[1] = LOCAL_INT_UNUSED;
5678 this_mac->mac_q_int[2] = LOCAL_INT_UNUSED;
5679 this_mac->mac_q_int[3] = LOCAL_INT_UNUSED;
5680 this_mac->mmsl_int = LOCAL_INT_UNUSED;
5681 }
5682 else
5683 {
5684 __disable_local_irq(MAC1_EMAC_U54_INT);
5685
5686 this_mac->mac_q_int[0] = MAC1_EMAC_PLIC;
5687 this_mac->mac_q_int[1] = INVALID_IRQn;
5688 this_mac->mac_q_int[2] = INVALID_IRQn;
5689 this_mac->mac_q_int[3] = INVALID_IRQn;
5690 this_mac->mmsl_int = INVALID_IRQn;
5691 }
5692 }
5693 }
5694
5695 if(0U == this_mac->is_emac)
5696 {
5697 this_mac->queue[0].int_status = &this_mac->mac_base->INT_STATUS;
5698 this_mac->queue[1].int_status = &this_mac->mac_base->INT_Q1_STATUS;
5699 this_mac->queue[2].int_status = &this_mac->mac_base->INT_Q2_STATUS;
5700 this_mac->queue[3].int_status = &this_mac->mac_base->INT_Q3_STATUS;
5701
5702 this_mac->queue[0].int_mask = &this_mac->mac_base->INT_MASK;
5703 this_mac->queue[1].int_mask = &this_mac->mac_base->INT_Q1_MASK;
5704 this_mac->queue[2].int_mask = &this_mac->mac_base->INT_Q2_MASK;
5705 this_mac->queue[3].int_mask = &this_mac->mac_base->INT_Q3_MASK;
5706
5707 this_mac->queue[0].int_enable = &this_mac->mac_base->INT_ENABLE;
5708 this_mac->queue[1].int_enable = &this_mac->mac_base->INT_Q1_ENABLE;
5709 this_mac->queue[2].int_enable = &this_mac->mac_base->INT_Q2_ENABLE;
5710 this_mac->queue[3].int_enable = &this_mac->mac_base->INT_Q3_ENABLE;
5711
5712 this_mac->queue[0].int_disable = &this_mac->mac_base->INT_DISABLE;
5713 this_mac->queue[1].int_disable = &this_mac->mac_base->INT_Q1_DISABLE;
5714 this_mac->queue[2].int_disable = &this_mac->mac_base->INT_Q2_DISABLE;
5715 this_mac->queue[3].int_disable = &this_mac->mac_base->INT_Q3_DISABLE;
5716
5717 this_mac->queue[0].receive_q_ptr = &this_mac->mac_base->RECEIVE_Q_PTR;
5718 this_mac->queue[1].receive_q_ptr = &this_mac->mac_base->RECEIVE_Q1_PTR;
5719 this_mac->queue[2].receive_q_ptr = &this_mac->mac_base->RECEIVE_Q2_PTR;
5720 this_mac->queue[3].receive_q_ptr = &this_mac->mac_base->RECEIVE_Q3_PTR;
5721
5722 this_mac->queue[0].transmit_q_ptr = &this_mac->mac_base->TRANSMIT_Q_PTR;
5723 this_mac->queue[1].transmit_q_ptr = &this_mac->mac_base->TRANSMIT_Q1_PTR;
5724 this_mac->queue[2].transmit_q_ptr = &this_mac->mac_base->TRANSMIT_Q2_PTR;
5725 this_mac->queue[3].transmit_q_ptr = &this_mac->mac_base->TRANSMIT_Q3_PTR;
5726
5727 this_mac->queue[0].dma_rxbuf_size = &this_mac->mac_base->DMA_RXBUF_SIZE_Q1; /* Not really true as this is done differently for queue 0 */
5728 this_mac->queue[1].dma_rxbuf_size = &this_mac->mac_base->DMA_RXBUF_SIZE_Q1;
5729 this_mac->queue[2].dma_rxbuf_size = &this_mac->mac_base->DMA_RXBUF_SIZE_Q2;
5730 this_mac->queue[3].dma_rxbuf_size = &this_mac->mac_base->DMA_RXBUF_SIZE_Q3;
5731 }
5732 else
5733 {
5734 this_mac->queue[0].int_status = &this_mac->emac_base->INT_STATUS;
5735 this_mac->queue[1].int_status = &this_mac->emac_base->INT_STATUS; /* Not Really correct but don't want 0 here... */
5736 this_mac->queue[2].int_status = &this_mac->emac_base->INT_STATUS;
5737 this_mac->queue[3].int_status = &this_mac->emac_base->INT_STATUS;
5738
5739 this_mac->queue[0].int_mask = &this_mac->emac_base->INT_MASK;
5740 this_mac->queue[1].int_mask = &this_mac->emac_base->INT_MASK;
5741 this_mac->queue[2].int_mask = &this_mac->emac_base->INT_MASK;
5742 this_mac->queue[3].int_mask = &this_mac->emac_base->INT_MASK;
5743
5744 this_mac->queue[0].int_enable = &this_mac->emac_base->INT_ENABLE;
5745 this_mac->queue[1].int_enable = &this_mac->emac_base->INT_ENABLE;
5746 this_mac->queue[2].int_enable = &this_mac->emac_base->INT_ENABLE;
5747 this_mac->queue[3].int_enable = &this_mac->emac_base->INT_ENABLE;
5748
5749 this_mac->queue[0].int_disable = &this_mac->emac_base->INT_DISABLE;
5750 this_mac->queue[1].int_disable = &this_mac->emac_base->INT_DISABLE;
5751 this_mac->queue[2].int_disable = &this_mac->emac_base->INT_DISABLE;
5752 this_mac->queue[3].int_disable = &this_mac->emac_base->INT_DISABLE;
5753
5754 this_mac->queue[0].receive_q_ptr = &this_mac->emac_base->RECEIVE_Q_PTR;
5755 this_mac->queue[1].receive_q_ptr = &this_mac->emac_base->RECEIVE_Q_PTR;
5756 this_mac->queue[2].receive_q_ptr = &this_mac->emac_base->RECEIVE_Q_PTR;
5757 this_mac->queue[3].receive_q_ptr = &this_mac->emac_base->RECEIVE_Q_PTR;
5758
5759 this_mac->queue[0].transmit_q_ptr = &this_mac->emac_base->TRANSMIT_Q_PTR;
5760 this_mac->queue[1].transmit_q_ptr = &this_mac->emac_base->TRANSMIT_Q_PTR;
5761 this_mac->queue[2].transmit_q_ptr = &this_mac->emac_base->TRANSMIT_Q_PTR;
5762 this_mac->queue[3].transmit_q_ptr = &this_mac->emac_base->TRANSMIT_Q_PTR;
5763
5764 this_mac->queue[0].dma_rxbuf_size = &this_mac->mac_base->DMA_RXBUF_SIZE_Q1; /* Not really true as this is done differently for queue 0 */
5765 this_mac->queue[1].dma_rxbuf_size = &this_mac->mac_base->DMA_RXBUF_SIZE_Q1; /* Not Really correct but don't want 0 here... */
5766 this_mac->queue[2].dma_rxbuf_size = &this_mac->mac_base->DMA_RXBUF_SIZE_Q2;
5767 this_mac->queue[3].dma_rxbuf_size = &this_mac->mac_base->DMA_RXBUF_SIZE_Q3;
5768 }
5769 #endif /* defined(TARGET_G5_SOC) */
5770 }
5771
5772 #ifdef __cplusplus
5773 }
5774 #endif
5775
5776 /******************************** END OF FILE ******************************/
5777