1 /******************************************************************************
2 * Copyright (c) 2011-2012 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 /******************************************************************************
35 *
36 * File Name: evm665x_emac.c
37 *
38 * Description: This file contains the EMAC initialization API
39 *
40 ******************************************************************************/
42 /************************
43 * Include Files
44 ************************/
45 #ifdef _EVMC6657L_
46 #include <stdio.h>
47 #include <stdint.h>
48 #include <evmc665x_emac.h>
49 #include <cslr_psc.h>
50 #include <csl_bootcfgAux.h>
51 #include <csl_pscAux.h>
52 #include <string.h>
55 EMAC_MCB emac_mcb;
56 volatile Uint8 rxbuff[RX_BUFF_SIZE];
59 Uint32 EMAC_init()
60 {
61 volatile Uint32* pRegAddr;
62 uint32_t i = 0;
63 uint32_t mac_addr2, mac_addr1;
64 #if 0
65 uint32_t power_domain_num = 0;
66 uint32_t mdctl_emac_module_num = 3;
67 uint32_t mdstat_emac_module_num = 3;
68 CSL_PSC_MODSTATE mdstat;
70 /* EMAC clock domain enable */
71 CSL_PSC_enablePowerDomain(power_domain_num);
72 CSL_PSC_setModuleNextState (mdctl_emac_module_num, PSC_MODSTATE_ENABLE);
74 /* start the process and wait. but timeout in 1000 loops. */
75 CSL_PSC_startStateTransition(power_domain_num);
76 while(((CSL_PSC_isStateTransitionDone (power_domain_num)) != 0) && (i < 1000)) {
77 i++;
78 }
80 mdstat = CSL_PSC_getModuleState(mdstat_emac_module_num);
81 /* report result. */
82 if (mdstat != PSC_MODSTATE_ENABLE) {
83 return 1; /* Could not enable the PSC Module */
84 }
85 #endif
86 CSL_BootCfgGetMacIdentifier(&mac_addr1, &mac_addr2);
88 /* Reset MAC */
89 EMAC_REGS->SOFTRESET = 0x01;
90 while(EMAC_REGS->SOFTRESET != 0);
92 /* Reset MAC Control */
93 EMAC_REGS->MACCONTROL = 0x0;
95 /* Init HDPs to NULL */
96 pRegAddr = &EMAC_REGS->TX0HDP;
97 for(i = 0; i < 8; i++)
98 *pRegAddr++ = 0;
100 pRegAddr = &EMAC_REGS->RX0HDP;
101 for(i = 0; i < 8; i++)
102 *pRegAddr++ = 0;
104 /* Init CPs to NULL */
105 pRegAddr = &EMAC_REGS->TX0CP;
106 for(i = 0; i < 8; i++)
107 *pRegAddr++ = 0;
109 pRegAddr = &EMAC_REGS->RX0CP;
110 for(i = 0; i < 8; i++)
111 *pRegAddr++ = 0;
113 /* Init MAC Addresses */
114 for(i = 0; i < 32; i++)
115 {
116 EMAC_REGS->MACINDEX = i;
117 EMAC_REGS->MACADDRHI = 0;
118 EMAC_REGS->MACADDRLO = 0;
119 }
121 /* Setup MAC Address for Channel 0 */
122 EMAC_REGS->MACINDEX = 0;
123 EMAC_REGS->MACADDRHI = ((mac_addr1 & 0x00ff0000) << 8)
124 | ((mac_addr1 & 0xff000000) >> 8)
125 | ((mac_addr2 & 0x000000ff) << 8)
126 | ((mac_addr2 & 0x0000ff00) >> 8);
128 EMAC_REGS->MACADDRLO = CSL_FMK(EMAC_MACADDRLO_VALID, 1)
129 | CSL_FMK(EMAC_MACADDRLO_MATCHFILT, 1)
130 | ((mac_addr1 & 0x000000ff) << 8)
131 | ((mac_addr1 & 0x0000ff00) >> 8);
133 /* Setup MAC Address for Channel 0 */
134 EMAC_REGS->MACINDEX = 0;
135 EMAC_REGS->MACADDRHI = ((mac_addr1 & 0x00ff0000) << 8)
136 | ((mac_addr1 & 0xff000000) >> 8)
137 | ((mac_addr2 & 0x000000ff) << 8)
138 | ((mac_addr2 & 0x0000ff00) >> 8);
140 EMAC_REGS->MACADDRLO = CSL_FMK(EMAC_MACADDRLO_VALID, 1)
141 | CSL_FMK(EMAC_MACADDRLO_MATCHFILT, 1)
142 | ((mac_addr1 & 0x000000ff) << 8)
143 | ((mac_addr1 & 0x0000ff00) >> 8);
145 printf("macaddress: %02X:%02X:%02X:%02X:%02X:%02X\n",
146 ((mac_addr2 & 0x0000ff00) >> 8),
147 (mac_addr2 & 0x000000ff),
148 ((mac_addr1 & 0xff000000) >> 24),
149 ((mac_addr1 & 0x00ff0000) >> 16),
150 ((mac_addr1 & 0x0000ff00) >> 8),
151 (mac_addr1 & 0x000000ff));
153 EMAC_REGS->RXBUFFEROFFSET = 0;
155 EMAC_REGS->RXMBPENABLE = 0;
156 EMAC_REGS->MACHASH1 = 0;
157 EMAC_REGS->MACHASH2 = 0;
159 /* Clear Unicast RX on channel 0-7 */
160 EMAC_REGS->RXUNICASTCLEAR = 0xff;
162 /* Disable all interrupts */
163 EMAC_REGS->RXINTMASKCLEAR = 0xFF;
164 EMAC_REGS->TXINTMASKCLEAR = 0xFF;
165 EMAC_REGS->MACINTMASKCLEAR = 0x0;
167 /* Set TX descriptor address */
168 /* Use CPPI Ram for buffer descriptor and buffer */
169 emac_mcb.tx_desc = (EMAC_Desc *)TX_DESC_ADD(0);
170 /* setup TX descriptor */
171 emac_mcb.tx_desc->pNext = 0;
172 emac_mcb.tx_desc->pBuffer = 0;
173 emac_mcb.tx_desc->BufOffLen = 0;
174 emac_mcb.tx_desc->PktFlgLen = 0;
176 /* Set RX descriptor address */
177 /* Use CPPI Ram for buffer descriptor and buffer */
178 emac_mcb.rx_desc = (EMAC_Desc *)RX_DESC_ADD(0);
179 /* setup RX descriptor */
180 emac_mcb.rx_desc->pNext = 0;
181 emac_mcb.rx_desc->pBuffer = (Uint8 *)RX_BUFF_ADD(0);
182 emac_mcb.rx_desc->BufOffLen = RX_BUFF_SIZE;
183 emac_mcb.rx_desc->PktFlgLen = EMAC_DSC_FLAG_OWNER;
185 /* Enable RX and TX for channel 0 */
186 EMAC_REGS->TXCONTROL = 0x01;
187 EMAC_REGS->RXCONTROL = 0x01;
189 EMAC_REGS->MACCONTROL = ( 1 << 18) /* EXT_EN */
190 | ( 0 << 9 ) /* Round robin */
191 | ( 1 << 7 ) /* GIG */
192 | ( 0 << 6 ) /* TX pacing disabled */
193 | ( 1 << 5 ) /* GMII RX & TX */
194 | ( 0 << 4 ) /* TX flow disabled */
195 | ( 0 << 3 ) /* RX flow disabled */
196 | ( 0 << 1 ) /* Loopback enabled */
197 | ( 1 << 0 ); /* full duplex */
199 /* Start RX for channel 0 */
200 EMAC_REGS->RX0HDP = (Uint32) emac_mcb.rx_desc;
201 emac_mcb.lastrxhdp = (Uint32) emac_mcb.rx_desc;
203 /* Enable RX Filter for Channel 0 */
204 EMAC_REGS->RXUNICASTSET = 0x01;
206 /* Enable receive for all broadcast packet */
207 EMAC_REGS->RXMBPENABLE = CSL_FMK(EMAC_RXMBPENABLE_RXBROADEN, 1);
209 return 0;
210 }
212 Int32 EMAC_Send(Uint8 *buff, int len)
213 {
214 volatile EMAC_Desc *pDesc;
216 /* minimum 64 bytes required */
217 if (len < 64)
218 len = 64;
220 /* setup descriptor for transmission */
221 emac_mcb.tx_desc->pNext = 0;
222 emac_mcb.tx_desc->BufOffLen = len;
223 emac_mcb.tx_desc->pBuffer = (Uint8 *)TX_BUFF_ADD;
224 memcpy(emac_mcb.tx_desc->pBuffer, buff, len);
225 emac_mcb.tx_desc->PktFlgLen = EMAC_DSC_FLAG_SOP | EMAC_DSC_FLAG_EOP | EMAC_DSC_FLAG_OWNER | len;
227 /* send packet */
228 EMAC_REGS->TX0HDP = (Uint32)emac_mcb.tx_desc;
230 /* wait for TX complete */
231 do {
232 pDesc = (EMAC_Desc *)EMAC_REGS->TX0CP;
233 } while(pDesc->PktFlgLen & EMAC_DSC_FLAG_OWNER);
235 /* return no. of bytes transmitted */
236 return len;
237 }
239 Int32 EMAC_Recv(Uint8 *buff)
240 {
241 EMAC_Desc *pDesc;
242 int recv_bytes = 0;
244 /* check for new packet */
245 if(emac_mcb.lastrxhdp == (Uint32)EMAC_REGS->RX0HDP)
246 return 0;
248 pDesc = (EMAC_Desc *)EMAC_REGS->RX0CP;
249 if (pDesc->PktFlgLen & EMAC_DSC_FLAG_SOP) {
250 /* Acknowledge recevied packet */
251 EMAC_REGS->RX0CP = (Uint32)pDesc;
253 /* store bytes recevied */
254 recv_bytes = pDesc->PktFlgLen & 0xFFFF;
256 /* copy data to output buffer */
257 memcpy(buff, pDesc->pBuffer, recv_bytes);
259 /* re-initalize descriptor to recevie more data */
260 pDesc->BufOffLen = RX_BUFF_SIZE;
261 pDesc->PktFlgLen = EMAC_DSC_FLAG_OWNER;
263 /* assign descriptor to HDP */
264 EMAC_REGS->RX0HDP = (Uint32)pDesc;
265 }
267 /* return number of bytes received */
268 return recv_bytes;
269 }
270 #endif