]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/mcsdk-tools.git/blob - post/src/evmc665x_emac.c
96ec9ec573b552b92982082432601271846796fc
[keystone-rtos/mcsdk-tools.git] / post / src / evmc665x_emac.c
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;
212 Int32 EMAC_Send(Uint8 *buff, int len)
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;
239 Int32 EMAC_Recv(Uint8 *buff)
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;
270 #endif