1 /******************************************************************************
2 * Copyright (c) 2011 Texas Instruments Incorporated - http://www.ti.com
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the
14 * distribution.
15 *
16 * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 *****************************************************************************/
34 #include <string.h>
35 #include "platform.h"
36 #include "types.h"
37 #include "post.h"
38 #include "net.h"
39 #include "cpmacdrv.h"
40 #include "target.h"
41 #include "qm_api.h"
42 #include "cpdma_api.h"
43 #include "pscapi.h"
45 /* CSL EMAC include */
46 #include <ti/csl/csl_cpsw.h>
47 #include <ti/csl/csl_cpsgmii.h>
48 #include <ti/csl/csl_cpsgmiiAux.h>
49 #include <ti/csl/cslr_cpsgmii.h>
50 #include <ti/csl/csl_mdio.h>
51 #include <ti/csl/csl_mdioAux.h>
53 /* BootCfg module include */
54 #include <ti/csl/csl_bootcfg.h>
55 #include <ti/csl/csl_bootcfgAux.h>
57 /* The version string */
58 #pragma DATA_SECTION(post_version, ".version")
59 #pragma DATA_ALIGN(post_version, 16)
60 char post_version[] = POST_VERSION;
62 /* OSAL functions for Platform Library */
63 uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment)
64 {
65 return malloc(num_bytes);
66 }
68 void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes)
69 {
70 /* Free up the memory */
71 if (dataPtr)
72 {
73 free(dataPtr);
74 }
75 }
77 /******************************************************************************
78 * Function: post_display_led_error
79 ******************************************************************************/
80 void
81 post_display_led_error
82 (
83 POST_TEST_ID test_id
84 )
85 {
86 uint8_t led_status[POST_MAX_NUM_LED];
87 uint32_t i;
89 memset(led_status, POST_LED_ON, POST_MAX_NUM_LED);
90 while (TRUE)
91 {
92 for (i = 0; i < POST_MAX_NUM_LED; i++)
93 {
94 if (post_led_status[test_id][i] == POST_LED_BLINK)
95 {
96 if (led_status[i] == POST_LED_ON)
97 {
98 led_status[i] = POST_LED_OFF;
99 }
100 else
101 {
102 led_status[i] = POST_LED_ON;
103 }
104 platform_led(i, (PLATFORM_LED_OP)led_status[i], PLATFORM_USER_LED_CLASS);
105 }
106 else
107 {
108 platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS);
109 }
110 }
111 platform_delay(POST_LED_BLINK_DELAY);
112 /* POST in the while(1) loop to display the LED error status */
113 }
114 }
116 /******************************************************************************
117 * Function: post_write_uart
118 ******************************************************************************/
119 Bool
120 post_write_uart
121 (
122 char* msg
123 )
124 {
125 uint32_t i;
126 uint32_t msg_len = strlen(msg);
128 /* Write the message to the UART */
129 for (i = 0; i < msg_len; i++)
130 {
131 if (platform_uart_write(msg[i]) != Platform_EOK)
132 {
133 return FALSE;
134 }
135 }
137 return TRUE;
138 }
140 /******************************************************************************
141 * Function: post_display_status
142 ******************************************************************************/
143 void
144 post_display_status
145 (
146 POST_TEST_ID test_id,
147 POST_TEST_RESULT test_result
148 )
149 {
150 uint32_t i;
151 char *msg;
152 char msg1[40] = "\r\n\r\nPOST ";
153 char msg2[] = " test passed!";
154 char msg3[] = " test failed!";
155 char msg4[] = " test started!";
157 msg = strcat(msg1, post_status[test_id]);
158 switch (test_id)
159 {
160 case POST_TEST_IN_PROGRESS:
161 case POST_TEST_COMPLETE:
162 /* Form the POST status message to write to the UART */
163 if (post_write_uart(msg) != TRUE)
164 {
165 post_display_led_error(POST_TEST_UART); /* Never return from this function */
166 }
168 for (i = 0; i < POST_MAX_NUM_LED; i++)
169 {
170 if (platform_led(i, (PLATFORM_LED_OP)post_led_status[test_id][i], PLATFORM_USER_LED_CLASS) != Platform_EOK)
171 {
172 post_write_uart("POST LED test failed \r\n");
173 }
174 }
175 break;
177 default:
178 /* Form the POST status message to write to the UART */
179 if (test_result == POST_TEST_RESULT_PASSED)
180 {
181 msg = strcat(msg, msg2);
182 if (post_write_uart(msg) != TRUE)
183 {
184 post_display_led_error(POST_TEST_UART); /* Never return from this function */
185 }
186 }
187 else if (test_result == POST_TEST_RESULT_FAILED)
188 {
189 msg = strcat(msg, msg3);
190 if (post_write_uart(msg) != TRUE)
191 {
192 post_display_led_error(POST_TEST_UART); /* Never return from this function */
193 }
194 post_display_led_error(test_id); /* Never return from this function */
195 }
196 else
197 {
198 msg = strcat(msg, msg4);
199 if (post_write_uart(msg) != TRUE)
200 {
201 post_display_led_error(POST_TEST_UART); /* Never return from this function */
202 }
203 }
204 break;
205 }
206 }
208 /******************************************************************************
209 * Function: post_test_external_memory
210 ******************************************************************************/
211 POST_TEST_RESULT
212 post_test_external_memory
213 (
214 void
215 )
216 {
217 POST_TEST_RESULT test_result = POST_TEST_RESULT_PASSED;
219 if(platform_external_memory_test(0, 0) != Platform_EOK)
220 {
221 test_result = POST_TEST_RESULT_FAILED;
222 }
224 return test_result;
225 }
227 /******************************************************************************
228 * Function: post_test_eeprom
229 ******************************************************************************/
230 POST_TEST_RESULT
231 post_test_eeprom
232 (
233 void
234 )
235 {
236 uint8_t test_buf[POST_EEPROM_TEST_READ_LENGTH];
237 POST_TEST_RESULT test_result = POST_TEST_RESULT_PASSED;
238 PLATFORM_DEVICE_info *p_device;
240 p_device = platform_device_open(POST_EEPROM_TEST_DEVICE_ID, 0);
241 if (p_device == NULL)
242 {
243 return POST_TEST_RESULT_FAILED;
244 }
246 if(platform_device_read(p_device->handle,
247 POST_EEPROM_TEST_READ_ADDRESS,
248 test_buf,
249 POST_EEPROM_TEST_READ_LENGTH) != Platform_EOK)
250 {
251 test_result = POST_TEST_RESULT_FAILED;
252 }
254 platform_device_close(p_device->handle);
255 return test_result;
256 }
258 /******************************************************************************
259 * Function: post_test_nand
260 ******************************************************************************/
261 POST_TEST_RESULT
262 post_test_nand
263 (
264 void
265 )
266 {
267 uint8_t test_buf[POST_NAND_TEST_READ_LENGTH];
268 POST_TEST_RESULT test_result = POST_TEST_RESULT_PASSED;
269 uint32_t addr;
270 PLATFORM_DEVICE_info *p_device;
272 p_device = platform_device_open(POST_NAND_TEST_DEVICE_ID, 0);
273 if (p_device == NULL)
274 {
275 return POST_TEST_RESULT_FAILED;
276 }
278 addr = (POST_NAND_TEST_READ_BLOCK_NUM * p_device->page_count + POST_NAND_TEST_READ_PAGE_NUM) * p_device->page_size;
279 if(platform_device_read(p_device->handle,
280 addr,
281 test_buf,
282 POST_NAND_TEST_READ_LENGTH) != Platform_EOK)
283 {
284 test_result = POST_TEST_RESULT_FAILED;
285 }
287 platform_device_close(p_device->handle);
288 return test_result;
289 }
291 /******************************************************************************
292 * Function: post_test_nor
293 ******************************************************************************/
294 POST_TEST_RESULT
295 post_test_nor
296 (
297 void
298 )
299 {
300 uint8_t test_buf[POST_NOR_TEST_READ_LENGTH];
301 POST_TEST_RESULT test_result = POST_TEST_RESULT_PASSED;
302 PLATFORM_DEVICE_info *p_device;
304 p_device = platform_device_open(POST_NOR_TEST_DEVICE_ID, 0);
305 if (p_device == NULL)
306 {
307 return POST_TEST_RESULT_FAILED;
308 }
310 if(platform_device_read(p_device->handle,
311 POST_NOR_TEST_READ_ADDR,
312 test_buf,
313 POST_NOR_TEST_READ_LENGTH) != Platform_EOK)
314 {
315 test_result = POST_TEST_RESULT_FAILED;
316 }
318 platform_device_close(p_device->handle);
319 return test_result;
320 }
322 /** Number of ports in the ethernet subsystem */
323 #define NUM_PORTS 3u
325 /** Number of MAC/GMII ports in the ethernet switch */
326 #define NUM_MAC_PORTS 2u
328 /* Define LoopBack modes */
329 #define CPSW_LOOPBACK_NONE 0
330 #define CPSW_LOOPBACK_INTERNAL 1
331 #define CPSW_LOOPBACK_EXTERNAL 2
333 #ifdef SIMULATOR_SUPPORT
334 int32_t cpswSimTest = 1;
335 int32_t cpswLpbkMode = CPSW_LOOPBACK_EXTERNAL;
336 #else
337 int32_t cpswSimTest = 0;
338 int32_t cpswLpbkMode = CPSW_LOOPBACK_INTERNAL;
339 #endif
340 int32_t cpswEvm6678 = 0;
342 /** ============================================================================
343 * @n@b Init_SGMII
344 *
345 * @b Description
346 * @n SGMII peripheral initialization code.
347 *
348 * @param[in]
349 * @n macPortNum MAC port number for which the SGMII port setup must
350 * be performed.
351 *
352 * @return
353 * @n None
354 * =============================================================================
355 */
356 int32_t Init_sgmii (uint32_t macPortNum)
357 {
358 CSL_SGMII_ADVABILITY sgmiiCfg;
359 CSL_SGMII_STATUS sgmiiStatus;
361 if ((macPortNum == 0) && (cpswEvm6678))
362 {
363 /* EVM6678 back end: MAC-to-MAC force link */
365 /* Reset the port before configuring it */
366 CSL_SGMII_doSoftReset (macPortNum);
367 while (CSL_SGMII_getSoftResetStatus (macPortNum) != 0);
369 /* Hold the port in soft reset and set up
370 * the SGMII control register:
371 * (1) Enable Master Mode (default)
372 */
373 CSL_SGMII_startRxTxSoftReset (macPortNum);
374 CSL_SGMII_enableMasterMode (macPortNum);
375 if (cpswLpbkMode != CPSW_LOOPBACK_NONE)
376 {
377 CSL_SGMII_enableLoopback (macPortNum);
378 }
380 /* Setup the Advertised Ability register for this port:
381 * (1) Enable Full duplex mode
382 * (2) Speed = 1000M
383 * (3) Force the Link
384 */
385 sgmiiCfg.bLinkUp = 1;
386 sgmiiCfg.linkSpeed = CSL_SGMII_1000_MBPS;
387 sgmiiCfg.duplexMode = CSL_SGMII_FULL_DUPLEX;
388 CSL_SGMII_setAdvAbility (macPortNum, &sgmiiCfg);
390 CSL_SGMII_endRxTxSoftReset (macPortNum);
392 /* Wait for SGMII Link */
393 do
394 {
395 CSL_SGMII_getStatus(macPortNum, &sgmiiStatus);
396 } while (sgmiiStatus.bIsLinkUp != 1);
397 }
398 else
399 {
400 /* Reset the port before configuring it */
401 CSL_SGMII_doSoftReset (macPortNum);
402 while (CSL_SGMII_getSoftResetStatus (macPortNum) != 0);
404 /* Hold the port in soft reset and set up
405 * the SGMII control register:
406 * (1) Enable Master Mode (default)
407 * (2) Enable Auto-negotiation
408 */
409 CSL_SGMII_startRxTxSoftReset (macPortNum);
410 if (cpswLpbkMode == CPSW_LOOPBACK_NONE)
411 {
412 CSL_SGMII_disableMasterMode (macPortNum);
413 }
414 else
415 {
416 CSL_SGMII_enableMasterMode (macPortNum);
418 if (cpswLpbkMode == CPSW_LOOPBACK_INTERNAL)
419 {
420 CSL_SGMII_enableLoopback (macPortNum);
421 }
422 }
424 /* Setup the Advertised Ability register for this port:
425 * (1) Enable Full duplex mode
426 * (2) Enable Auto Negotiation
427 */
428 sgmiiCfg.linkSpeed = CSL_SGMII_1000_MBPS;
429 sgmiiCfg.duplexMode = CSL_SGMII_FULL_DUPLEX;
430 CSL_SGMII_setAdvAbility (macPortNum, &sgmiiCfg);
432 CSL_SGMII_enableAutoNegotiation (macPortNum);
433 CSL_SGMII_endRxTxSoftReset (macPortNum);
435 /* Wait for SGMII Link */
436 if (!cpswSimTest && ((cpswLpbkMode == CPSW_LOOPBACK_EXTERNAL) || (cpswLpbkMode == CPSW_LOOPBACK_NONE)))
437 {
438 do
439 {
440 CSL_SGMII_getStatus(macPortNum, &sgmiiStatus);
441 } while (sgmiiStatus.bIsLinkUp != 1);
443 /* Wait for SGMII Autonegotiation to complete without error */
444 do
445 {
446 CSL_SGMII_getStatus(macPortNum, &sgmiiStatus);
447 if (sgmiiStatus.bIsAutoNegError != 0)
448 return -1;
449 } while (sgmiiStatus.bIsAutoNegComplete != 1);
450 }
451 }
453 /* All done with configuration. Return Now. */
454 return 0;
455 }
457 int Init_MAC (uint32_t macPortNum, uint8_t macAddress[6], uint32_t mtu)
458 {
459 /* Reset MAC Sliver 0 */
460 CSL_CPGMAC_SL_resetMac (macPortNum);
461 while (CSL_CPGMAC_SL_isMACResetDone (macPortNum) != TRUE);
463 /* Setup the MAC Control Register for this port:
464 * (1) Enable Full duplex
465 * (2) Enable GMII
466 * (3) Enable Gigabit
467 * (4) Enable External Configuration. This enables
468 * the "Full duplex" and "Gigabit" settings to be
469 * controlled externally from SGMII
470 * (5) Don't enable any control/error/short frames
471 */
472 CSL_CPGMAC_SL_enableFullDuplex (macPortNum);
473 CSL_CPGMAC_SL_enableGMII (macPortNum);
474 CSL_CPGMAC_SL_enableGigabit (macPortNum);
475 CSL_CPGMAC_SL_enableExtControl (macPortNum);
477 /* Configure the MAC address for this port */
478 CSL_CPSW_3GF_setPortMACAddress (macPortNum, macAddress);
480 /* Configure VLAN ID/CFI/Priority.
481 *
482 * For now, we are not using VLANs so just configure them
483 * to all zeros.
484 */
485 CSL_CPSW_3GF_setPortVlanReg (macPortNum, 0, 0, 0);
487 /* Configure the Receive Maximum length on this port,
488 * i.e., the maximum size the port can receive without
489 * any errors.
490 *
491 * Set the Rx Max length to the MTU configured for the
492 * interface.
493 */
494 CSL_CPGMAC_SL_setRxMaxLen (macPortNum, mtu);
496 /* Done setting up the MAC port */
497 return 0;
498 }
500 void Init_Switch (uint32_t mtu)
501 {
502 CSL_CPSW_3GF_PORTSTAT portStatCfg;
504 /* Enable the CPPI port, i.e., port 0 that does all
505 * the data streaming in/out of EMAC.
506 */
507 CSL_CPSW_3GF_enablePort0 ();
508 CSL_CPSW_3GF_disableVlanAware ();
509 CSL_CPSW_3GF_setPort0VlanReg (0, 0, 0);
510 CSL_CPSW_3GF_setPort0RxMaxLen (mtu);
512 /* Enable statistics on both the port groups:
513 *
514 * MAC Sliver ports - Port 1, Port 2
515 * CPPI Port - Port 0
516 */
517 portStatCfg.p0AStatEnable = 1;
518 portStatCfg.p0BStatEnable = 1;
519 portStatCfg.p1StatEnable = 1;
520 portStatCfg.p2StatEnable = 1;
521 CSL_CPSW_3GF_setPortStatsEnableReg (&portStatCfg);
523 /* Setup the Address Lookup Engine (ALE) Configuration:
524 * (1) Enable ALE.
525 * (2) Clear stale ALE entries.
526 * (3) Disable VLAN Aware lookups in ALE since
527 * we are not using VLANs by default.
528 * (4) No Flow control
529 * (5) Configure the Unknown VLAN processing
530 * properties for the switch, i.e., which
531 * ports to send the packets to.
532 */
533 CSL_CPSW_3GF_enableAle ();
534 CSL_CPSW_3GF_clearAleTable ();
536 CSL_CPSW_3GF_disableAleVlanAware ();
537 CSL_CPSW_3GF_disableAleTxRateLimit ();
538 CSL_CPSW_3GF_setAlePrescaleReg (125000000u/1000u);
539 CSL_CPSW_3GF_setAleUnkownVlanReg (7, 3, 3, 7);
541 if(cpswLpbkMode != CPSW_LOOPBACK_NONE)
542 CSL_CPSW_3GF_enableAleBypass();
544 /* Done with switch configuration */
545 return;
546 }
548 int Switch_update_addr (uint32_t portNum, uint8_t macAddress[6], Uint16 add)
549 {
550 uint32_t i;
551 CSL_CPSW_3GF_ALE_PORTCONTROL alePortControlCfg;
552 CSL_CPSW_3GF_ALE_UNICASTADDR_ENTRY ucastAddrCfg;
555 /* Configure the address in "Learning"/"Forward" state */
556 alePortControlCfg.portState = ALE_PORTSTATE_FORWARD;
557 alePortControlCfg.dropUntaggedEnable = 0;
558 alePortControlCfg.vidIngressCheckEnable = 0;
559 alePortControlCfg.noLearnModeEnable = (cpswLpbkMode != CPSW_LOOPBACK_NONE)?1:0;
560 alePortControlCfg.mcastLimit = 0;
561 alePortControlCfg.bcastLimit = 0;
563 CSL_CPSW_3GF_setAlePortControlReg (portNum, &alePortControlCfg);
565 if (cpswLpbkMode != CPSW_LOOPBACK_NONE)
566 {
567 /* Program the ALE with the MAC address.
568 *
569 * The ALE entries determine the switch port to which any
570 * matching received packet must be forwarded to.
571 */
572 /* Get the next free ALE entry to program */
573 for (i = 0; i < CSL_CPSW_3GF_NUMALE_ENTRIES; i++)
574 {
575 if (CSL_CPSW_3GF_getALEEntryType (i) == ALE_ENTRYTYPE_FREE)
576 {
577 /* Found a free entry */
578 break;
579 }
580 }
581 if (i == CSL_CPSW_3GF_NUMALE_ENTRIES)
582 {
583 /* No free ALE entry found. return error. */
584 return -1;
585 }
586 else
587 {
588 /* Found a free ALE entry to program our MAC address */
589 memcpy (ucastAddrCfg.macAddress, macAddress, 6); // Set the MAC address
590 ucastAddrCfg.ucastType = ALE_UCASTTYPE_UCAST_NOAGE; // Add a permanent unicast address entryALE_UCASTTYPE_UCAST_NOAGE.
591 ucastAddrCfg.secureEnable = FALSE;
592 ucastAddrCfg.blockEnable = FALSE;
593 ucastAddrCfg.portNumber = portNum; // Add the ALE entry for this port
595 /* Setup the ALE entry for this port's MAC address */
596 CSL_CPSW_3GF_setAleUnicastAddrEntry (i, &ucastAddrCfg);
597 }
598 }
600 /* Done with upading address */
601 return 0;
602 }
604 int32_t Init_SGMII_SERDES(void)
605 {
606 if (cpswSimTest)
607 {
609 /* Unlock the chip configuration registers to allow SGMII SERDES registers to
610 * be written */
611 CSL_BootCfgUnlockKicker();
613 CSL_BootCfgSetSGMIIConfigPLL (0x00000041);
614 CSL_BootCfgSetSGMIIRxConfig (0, 0x00700621);
615 CSL_BootCfgSetSGMIITxConfig (0, 0x000108A1);
616 CSL_BootCfgSetSGMIIRxConfig (1, 0x00700621);
617 CSL_BootCfgSetSGMIITxConfig (1, 0x000108A1);
619 /* Re-lock the chip configuration registers to prevent unintentional writes */
620 CSL_BootCfgLockKicker();
622 }
624 /* SGMII SERDES Configuration complete. Return. */
625 return 0;
626 }
628 int32_t Init_Cpsw (void)
629 {
630 uint32_t macPortNum, mtu = 1518;
631 uint8_t mac_address[6];
632 uint8_t sw_port0_mac_addr[6] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15};
634 /* Initialize the SERDES modules */
635 Init_SGMII_SERDES();
637 platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_address);
639 /* Initialize the SGMII/Sliver submodules for the
640 * two corresponding MAC ports.
641 */
642 for (macPortNum = 0; macPortNum < NUM_MAC_PORTS; macPortNum++)
643 {
644 if (Init_sgmii (macPortNum))
645 return -1;
646 mac_address[5] += macPortNum;
647 Init_MAC (macPortNum, mac_address, mtu);
648 mac_address[5] -= macPortNum;
649 }
651 /* Setup the Ethernet switch finally. */
652 Init_Switch (mtu);
654 Switch_update_addr(0, sw_port0_mac_addr, 0);
655 Switch_update_addr(1, mac_address, 0);
656 mac_address[5] += 1;
657 Switch_update_addr(2, mac_address, 0);
659 /* CPSW subsystem setup done. Return success */
660 return 0;
661 }
664 /******************************************************************************
665 * Function: post_test_emac_loopback
666 ******************************************************************************/
667 POST_TEST_RESULT
668 post_test_emac_loopback
669 (
670 void
671 )
672 {
673 uint8_t test_buf[POST_EMAC_TEST_PKT_LENGTH+14];
674 uint8_t sw_port0_mac_addr[6] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15};
675 uint8_t mac_address[6];
676 NET_DRV_DEVICE nDevice;
677 uint32_t modNum;
678 int32_t ret;
680 /* Note that if the sgmii power enable is requested the PA must be
681 * powered up first */
682 modNum = 8;
683 if (modNum == TARGET_PWR_ETH(x)) {
684 ret = (int32_t)pscEnableModule (TARGET_PWR_PA);
685 if (ret != 0)
686 return (POST_TEST_RESULT_FAILED);
687 }
689 ret = (int32_t)pscEnableModule(modNum);
690 if (ret != 0)
691 return (POST_TEST_RESULT_FAILED);
693 Init_Cpsw();
695 /* Queue manager configuration */
696 hwQmSetup ((qmConfig_t *)(targetGetQmConfig()));
697 targetInitQs ();
700 /* Cpdma configuration. */
701 hwCpdmaRxConfig ((cpdmaRxCfg_t *)targetGetCpdmaRxConfig());
702 hwCpdmaTxConfig ((cpdmaTxCfg_t *)targetGetCpdmaTxConfig());
705 /* Packet accelerator configuration. If PA is not present this statement is defined
706 * to void in target.h */
707 targetPaConfig(sw_port0_mac_addr);
709 /* Streaming switch configuration. If not present this statement is defined to void
710 * in target.h. If present this is usually defined to a series of register writes */
711 hwConfigStreamingSwitch();
713 /* Initialize the network device driver */
714 memset (&nDevice, 0, sizeof(nDevice));
716 /* Start the networking device */
717 if (cpmac_drv_start(&nDevice) < 0)
718 {
719 return POST_TEST_RESULT_FAILED;
720 }
722 /* Get the MAC address from efuse */
723 platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_address);
725 /* Set the dest MAC address to be broadcast, so that PA firmware will not filter out */
726 memset(test_buf, 0xff, 6);
727 memcpy(&test_buf[6], sw_port0_mac_addr, 6);
729 /* set the payload length to 256 bytes */
730 test_buf[12] = 0x01;
731 test_buf[13] = 0x00;
733 /* Send the Ethernet packet */
734 if (cpmac_drv_send (&nDevice, test_buf, POST_EMAC_TEST_PKT_LENGTH+14) < 0)
735 {
736 return POST_TEST_RESULT_FAILED;
737 }
739 platform_delay(100);
741 /* Receive the loopback packet */
742 if (ret = cpmac_drv_receive (&nDevice, test_buf) < 0)
743 {
744 return POST_TEST_RESULT_FAILED;
745 }
747 return POST_TEST_RESULT_PASSED;
748 }
750 void
751 post_hex_to_string
752 (
753 uint32_t hex,
754 uint32_t nibbles,
755 char *msg
756 )
757 {
758 int32_t i;
759 uint8_t nibble;
761 for (i = (nibbles-1); i >= 0; i--)
762 {
763 nibble = hex & 0xf;
764 if (nibble <= 0x9)
765 {
766 nibble += '0';
767 }
768 else
769 {
770 nibble += ('A' - 0xa);
771 }
773 msg[i] = nibble;
774 hex = hex >> 4;
775 }
776 msg[nibbles] = 0;
777 }
779 Bool
780 post_serial_num_isvalid
781 (
782 char c
783 )
784 {
785 if (
786 ((c >= '0') && (c <= '9')) ||
787 ((c >= 'a') && (c <= 'z')) ||
788 ((c >= 'A') && (c <= 'Z'))
789 )
790 {
791 return TRUE;
792 }
793 else
794 {
795 return FALSE;
796 }
797 }
799 /******************************************************************************
800 * Function: post_write_serial_no
801 ******************************************************************************/
802 void
803 post_write_serial_no
804 (
805 void
806 )
807 {
808 uint32_t i, j;
809 uint8_t msg[20], msg2[2];
810 PLATFORM_DEVICE_info *p_device;
812 /* Check if user key in the passcode "ti" to enter board serial number */
813 if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK)
814 {
815 return;
816 }
817 if (msg[0] != 't')
818 {
819 return;
820 }
822 if (platform_uart_read(msg, POST_UART_READ_TIMEOUT) != Platform_EOK)
823 {
824 return;
825 }
826 if (msg[0] != 'i')
827 {
828 return;
829 }
831 /* Passcode verified, prompt the user to enter serial number */
832 p_device = platform_device_open(PLATFORM_DEVID_EEPROM50, 0);
833 if (p_device == NULL)
834 {
835 return;
836 }
838 post_write_uart("\r\n\r\nPlease enter the 10 digit serial number for this board, and then press ENTER key:\r\n\r\n");
840 i = 0;
841 msg2[1] = 0;
842 while (TRUE)
843 {
844 if (platform_uart_read(&msg[i], POST_UART_READ_TIMEOUT) != Platform_EOK)
845 {
846 platform_device_close(p_device->handle);
847 post_write_uart("\r\n\r\nSerial number input time out!");
848 return;
849 }
851 if (msg[i] == '\r')
852 {
853 break;
854 }
855 if ((i < POST_MAX_SN_SIZE) && post_serial_num_isvalid(msg[i]))
856 {
857 msg2[0] = msg[i];
858 post_write_uart((char *)msg2);
859 i++;
860 }
861 }
863 if (i < POST_MAX_SN_SIZE)
864 {
865 for (j = i; j < POST_MAX_SN_SIZE; j++)
866 {
867 msg[j] = 0xff;
868 }
869 }
871 if(platform_device_write(p_device->handle, POST_SERIAL_NUM_ADDR, msg, 16) == Platform_EOK)
872 {
873 post_write_uart("\r\n\r\nSerial number programmed to EEPROM successfully! ");
874 }
875 else
876 {
877 post_write_uart("\r\n\r\nFailed to program the serial number to EEPROM!");
878 }
879 platform_device_close(p_device->handle);
881 }
883 /******************************************************************************
884 * Function: main function for POST
885 ******************************************************************************/
886 void
887 main
888 (
889 void
890 )
891 {
892 platform_init_flags init_flags;
893 platform_init_config init_config;
894 POST_TEST_ID test_id = POST_TEST_IN_PROGRESS;
895 POST_TEST_RESULT test_result;
896 uint32_t reset_type;
897 int32_t i;
898 char msg[9];
899 uint8_t mac_addr[6];
900 platform_info info;
901 uint32_t sa_enable;
903 /* Turn on all the platform initialize flags */
904 memset(&init_config, 0, sizeof(platform_init_config));
905 memset(&init_flags, 0x01, sizeof(platform_init_flags));
907 init_flags.phy = 0;
909 /* Initialize the platform */
910 if (platform_init(&init_flags, &init_config) != Platform_EOK)
911 {
912 switch (platform_errno)
913 {
914 case PLATFORM_ERRNO_PLL_SETUP:
915 test_id = POST_TEST_PLL_INIT;
916 break;
917 case PLATFORM_ERRNO_NAND:
918 test_id = POST_TEST_NAND_INIT;
919 break;
920 case PLATFORM_ERRNO_NOR:
921 test_id = POST_TEST_NOR_INIT;
922 break;
923 default:
924 test_id = POST_TEST_GENERAL;
925 break;
926 }
927 test_result = POST_TEST_RESULT_FAILED;
928 }
930 platform_uart_init();
931 platform_uart_set_baudrate(POST_UART_BAUDRATE);
932 if (test_id != POST_TEST_PLL_INIT)
933 {
934 if (post_write_uart("\r\n\r\n") != TRUE)
935 {
936 post_display_led_error(POST_TEST_UART); /* Never return from this function */
937 }
939 platform_get_info(&info);
941 /* Display the board name */
942 post_write_uart(info.board_name);
944 /* Display the POST version */
945 post_write_uart(POST_EVM_VERSION_MSG);
946 post_write_uart(post_version);
948 post_hex_to_string(info.board_rev, 4, msg);
949 post_write_uart("\r\n\r\nFPGA Version: ");
950 post_write_uart(msg);
952 if (info.serial_nbr[0] != 0)
953 {
954 post_write_uart("\r\n\r\nBoard Serial Number: ");
955 post_write_uart(info.serial_nbr);
956 }
958 /* Display the EFUSE MAC address */
959 platform_get_macaddr(PLATFORM_MAC_TYPE_EFUSE, mac_addr);
960 post_write_uart("\r\n\r\nEFUSE MAC ID is: ");
961 for (i = 0; i < 6; i++)
962 {
963 post_hex_to_string(info.emac.efuse_mac_address[i], 2, msg);
964 msg[2] = ' ';
965 msg[3] = 0;
966 post_write_uart(msg);
967 }
969 sa_enable = *(volatile uint32_t *)0x20c0004;
970 sa_enable &= 0x1;
972 if (sa_enable)
973 {
974 post_write_uart("\r\n\r\nSA is enabled on this board.");
975 }
976 else
977 {
978 post_write_uart("\r\n\r\nSA is disabled on this board.");
979 }
981 /* Read the PLL Reset Type Status register and display on UART */
982 reset_type = PLL_CTRL_REG_RSTYPE;
983 post_hex_to_string(reset_type, 8, msg);
984 post_write_uart("\r\n\r\nPLL Reset Type Status Register: 0x");
985 post_write_uart(msg);
986 }
988 /* Display test in progress UART/LED status or init error */
989 post_display_status(test_id, POST_TEST_RESULT_STARTED);
991 post_display_status(POST_TEST_EEPROM, POST_TEST_RESULT_STARTED);
992 test_result = post_test_eeprom();
993 post_display_status(POST_TEST_EEPROM, test_result);
995 post_display_status(POST_TEST_NOR, POST_TEST_RESULT_STARTED);
996 test_result = post_test_nor();
997 post_display_status(POST_TEST_NOR, test_result);
999 post_display_status(POST_TEST_NAND, POST_TEST_RESULT_STARTED);
1000 test_result = post_test_nand();
1001 post_display_status(POST_TEST_NAND, test_result);
1003 post_display_status(POST_TEST_EMAC_LOOPBACK, POST_TEST_RESULT_STARTED);
1004 test_result = post_test_emac_loopback();
1005 post_display_status(POST_TEST_EMAC_LOOPBACK, test_result);
1007 post_display_status(POST_TEST_DDR, POST_TEST_RESULT_STARTED);
1008 test_result = post_test_external_memory();
1009 post_display_status(POST_TEST_DDR, test_result);
1011 post_display_status(POST_TEST_COMPLETE, POST_TEST_RESULT_PASSED);
1013 post_write_serial_no();
1014 }