1 #include "commands/cmd_emac.h"
5 unsigned int emacCtrlBase = EMAC_CTRL_BASE;
6 unsigned int emacBase = EMAC_BASE;
7 unsigned int emacCtrlRamBase = EMAC_CTRL_RAM_BASE;
8 unsigned int mdioBase = MDIO_BASE;
10 int rx_irq_cnt; /* Interrupt counters */
13 unsigned int phyalive;
17 unsigned int intvectraw;
19 uint8_t emacAddress[6] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab};
20 uint32_t emacPhyAddress = 0x1; /* Address of PHY on "MDIO bus"
21 (depends on PHY configuration) */
22 int channel = 0; /* Emac has 8 RX and TX channels; we use only one */
24 EMAC_Desc fr1 __attribute__((aligned(4))); /* Frame descriptor of Ethernet frame to be sent */
26 /* Frame descriptor used for receiving frames --
27 it might be placed in normal RAM or in CPPI ram of EMAC */
28 //EMAC_Desc rx_desc __attribute__((aligned(4)));
29 volatile EMAC_Desc *rx_desc = ((EMAC_Desc*) EMAC_CTRL_RAM_BASE);
32 #define BUFF_SIZE 2048
33 uint8_t rx_buff[BUFF_SIZE]; /* Buffer for data reception */
35 eth_frame_t efr1; /* Buffer for TX -- Before sending some data we have to
36 prepare it in "Ethernet frame" format */
43 for (i = 0; i < 65555; i ++)
47 #pragma INTERRUPT(EMACCore0RxIsr, FIQ)
48 void EMACCore0RxIsr(void)
52 /* We know we have only one RX Packet Buffer descriptor --
53 so we write it in CP to disable interrupt */
54 EMACRxCPWrite(emacBase, channel, (unsigned int)rx_desc);
55 EMACCoreIntAck(emacBase, EMAC_INT_CORE0_RX);
58 #pragma INTERRUPT(EMACCore0TxIsr, FIQ)
59 void EMACCore0TxIsr(void)
62 /* If is not being processed by the EMAC anymore */
63 if (!(fr1.PktFlgLen & EMAC_DSC_FLAG_OWNER)) {
64 EMACTxCPWrite(emacBase, channel, (unsigned int)&fr1);
65 EMACCoreIntAck(emacBase, EMAC_INT_CORE0_TX);
69 int emac_test(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
72 volatile unsigned int delay = 0xfff;
76 /* Deactivate reset pin of PHY */
77 dmmREG->PC4 = (1 << DMM_CLK); /* Set to H */
79 dmmREG->PC5 = (1 << DMM_CLK); /* Set to L */
81 dmmREG->PC4 = (1 << DMM_CLK); /* Set to H */
84 /* Prepare RX Packet buffer descriptor */
85 rx_desc->pBuffer = rx_buff;
86 rx_desc->PktFlgLen = EMAC_DSC_FLAG_OWNER;
87 rx_desc->pNext = NULL;
88 rx_desc->BufOffLen = BUFF_SIZE;
91 /* Fill some testing Ethernet frame with relevant data */
92 efr1.destination[0] = 0x00;
93 efr1.destination[1] = 0x21;
94 efr1.destination[2] = 0x70;
95 efr1.destination[3] = 0xb5;
96 efr1.destination[4] = 0x4b;
97 efr1.destination[5] = 0xea;
98 efr1.source[0] = 0xff;
99 efr1.source[1] = 0xff;
100 efr1.source[2] = 0xff;
101 efr1.source[3] = 0xff;
102 efr1.source[4] = 0xff;
103 efr1.source[5] = 0xff;
112 EMACInit(emacCtrlBase, emacBase);
113 MDIOInit(mdioBase, 0x0, 0x0);
114 dummy_wait(); // FIXME
116 EMACMACSrcAddrSet(emacBase, emacAddress);
117 /* Be sure to program all eight MAC address registers -
118 * whether the receive channel is to be enabled or not.
120 for (chan = 0; chan < 8; chan++)
121 EMACMACAddrSet(emacBase, chan, emacAddress, EMAC_MACADDR_NO_MATCH_NO_FILTER);
123 phyalive = MDIOPhyAliveStatusGet(mdioBase);
125 rpp_sci_printf("PHY not alive\r\n");
129 phylink = MDIOPhyLinkStatusGet(mdioBase);
131 rpp_sci_printf("PHY link down\r\n");
133 rpp_sci_printf("PHY link up\r\n");
135 rpp_sci_printf("Configuring PHY and EMAC...\r\n");
136 PHY_configure(mdioBase, emacPhyAddress);
138 /* Set the EMAC with the negotiation results if it is successful */
139 PHY_partner_ability_get(mdioBase, emacPhyAddress, &data);
140 if (data & PHY_100BASETXDUPL_m) {
141 EMACDuplexSet(emacBase, EMAC_DUPLEX_FULL);
143 } else if (data & PHY_100BASETX_m) {
144 EMACDuplexSet(emacBase, EMAC_DUPLEX_HALF);
151 for (chan = 0; chan < 8; chan++) {
152 EMACTxHdrDescPtrWrite(emacBase, 0, chan);
153 EMACRxHdrDescPtrWrite(emacBase, 0, chan);
156 //EMACCoreIntAck(emacBase, EMAC_INT_CORE0_RX);
157 //EMACCoreIntAck(emacBase, EMAC_INT_CORE0_TX);
159 EMACRxBroadCastEnable(emacBase, channel);
160 EMACRxPromiscEnable(emacBase, channel);
162 EMACTxIntPulseEnable(emacBase, emacCtrlBase, 0, channel);
163 EMACRxIntPulseEnable(emacBase, emacCtrlBase, 0, channel);
165 EMACRxHdrDescPtrWrite(emacBase, (unsigned int)rx_desc, channel);
167 //EMACRxUnicastSet(emacBase, 0);
168 EMACTxEnable(emacBase);
169 EMACRxEnable(emacBase);
171 EMACMIIEnable(emacBase);
173 phylink = MDIOPhyLinkStatusGet(mdioBase);
175 rpp_sci_printf("PHY link down\r\n");
177 rpp_sci_printf("PHY link up\r\n");
181 for (j = 0; j < 8; j++) {
183 fr1.pBuffer = (uint8_t*)&efr1;
185 fr1.PktFlgLen = (EMAC_DSC_FLAG_SOP | EMAC_DSC_FLAG_EOP | EMAC_DSC_FLAG_OWNER | 65);
187 EMACTxHdrDescPtrWrite(emacBase, (unsigned int)&fr1, channel);
188 rpp_sci_printf("Packet sent\r\n");
190 intvect = EMACIntVectorGet(emacBase);
191 intvectraw = EMACIntVectorRawGet(emacBase);
199 rpp_sci_printf("Trying to receive some data\r\n");
200 EMACRxIntPulseEnable(emacBase, emacCtrlBase, 0, channel);
202 for (j = 0; j < 8; j++) {
203 while (!(rx_desc->PktFlgLen & EMAC_DSC_FLAG_SOP))
206 rpp_sci_printf("Received packet:\r\n");
207 rpp_sci_printf("Length: %d\r\n", rx_desc->PktFlgLen & 0xffff);
209 for (i = 0; i < (rx_desc->PktFlgLen & 0xffff); i++) {
210 i2str(rx_fr, rx_desc->pBuffer[i], 0, 16);
211 rpp_sci_printf("%h ", rx_desc->pBuffer[i]);
212 if (((i+1) % 8) == 0)
213 rpp_sci_printf("\r\n");
216 /* Reinitialize RX buffer */
217 rx_desc->pBuffer = rx_buff;
218 rx_desc->PktFlgLen = EMAC_DSC_FLAG_OWNER;
219 rx_desc->pNext = NULL;
220 rx_desc->BufOffLen = BUFF_SIZE;
221 EMACRxHdrDescPtrWrite(emacBase, (unsigned int)rx_desc, channel);
222 rpp_sci_printf("\r\n-------------------------------------------\r\n");
225 EMACRxIntPulseDisable(emacBase, emacCtrlBase, 0, channel);
233 cmd_des_t const cmd_des_test_ethernet={
235 "ethernet", "Try to send few ethernet frames",
236 emac_test, (void *)&cmd_list_emac
239 cmd_des_t const *cmd_list_emac[]={
240 &cmd_des_test_ethernet,