add initial support for the crisarchitecture used on foxboards to openwrt
[openwrt/staging/dedeckeh.git] / target / linux / etrax-2.6 / image / e100boot / src / cbl / src / net_init.c
1 #define net_init init_interface
2 #define handle_network_read handle_read
3 #define send_network_ack send_ack
4 #define send_network_string send_string
5 #define send_network_hex send_hex
6
7 #include "sv_addr_ag.h"
8 #include "e100boot.h"
9
10 static void start_network_trans(void);
11
12 void
13 net_init(void)
14 {
15 *R_NETWORK_GA_1 = *R_NETWORK_GA_0 = 0;
16
17 SET_ETHER_ADDR(0x01,0x40,0x8c,0x00,0x01,0x00,
18 0x01,0x40,0x8c,0x00,0x01,0x00);
19
20 *R_NETWORK_REC_CONFIG =
21 IO_STATE (R_NETWORK_REC_CONFIG, duplex, half) |
22 IO_STATE (R_NETWORK_REC_CONFIG, bad_crc, discard) |
23 IO_STATE (R_NETWORK_REC_CONFIG, oversize, discard) |
24 IO_STATE (R_NETWORK_REC_CONFIG, undersize, discard) |
25 IO_STATE (R_NETWORK_REC_CONFIG, all_roots, discard) |
26 IO_STATE (R_NETWORK_REC_CONFIG, broadcast, discard) |
27 IO_STATE (R_NETWORK_REC_CONFIG, individual, discard) |
28 IO_STATE (R_NETWORK_REC_CONFIG, ma1, disable) |
29 IO_STATE (R_NETWORK_REC_CONFIG, ma0, enable);
30
31 *R_NETWORK_MGM_CTRL =
32 IO_FIELD(R_NETWORK_MGM_CTRL, txd_pins, 0) |
33 IO_FIELD(R_NETWORK_MGM_CTRL, txer_pin, 0) |
34 IO_FIELD(R_NETWORK_MGM_CTRL, mdck, 0) |
35 IO_STATE(R_NETWORK_MGM_CTRL, mdoe, disable) |
36 IO_FIELD(R_NETWORK_MGM_CTRL, mdio, 0);
37
38 *R_NETWORK_TR_CTRL =
39 (IO_STATE (R_NETWORK_TR_CTRL, clr_error, clr) |
40 IO_STATE (R_NETWORK_TR_CTRL, delay, none) |
41 IO_STATE (R_NETWORK_TR_CTRL, cancel, dont) |
42 IO_STATE (R_NETWORK_TR_CTRL, cd, enable) |
43 IO_STATE (R_NETWORK_TR_CTRL, pad, enable) |
44 IO_STATE (R_NETWORK_TR_CTRL, crc, enable) |
45 IO_STATE (R_NETWORK_TR_CTRL, retry, enable));
46
47 *R_NETWORK_GEN_CONFIG =
48 IO_STATE (R_NETWORK_GEN_CONFIG, loopback, off) |
49 IO_STATE (R_NETWORK_GEN_CONFIG, frame, ether) |
50 IO_STATE (R_NETWORK_GEN_CONFIG, vg, off) |
51 IO_STATE (R_NETWORK_GEN_CONFIG, phy, mii_clk) |
52 IO_STATE (R_NETWORK_GEN_CONFIG, enable, on);
53
54 *R_DMA_CH0_CMD = IO_STATE(R_DMA_CH0_CMD, cmd, reset);
55 *R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, reset);
56
57 rx_descr.sw_len = NETWORK_HEADER_LENGTH;
58 rx_descr.ctrl = TX_CTRL;
59 rx_descr.next = (udword)&rx_descr2;
60 rx_descr.buf = (udword)&rx_header;
61
62 rx_descr2.sw_len = 1500;
63 rx_descr2.ctrl = TX_CTRL_EOP;
64 rx_descr2.buf = target_address;
65
66 /* Endian dependent, but saves a few bytes... */
67 *(udword*)&tx_header.src[0] = htonl(0x02408c00);
68 *(uword*)&tx_header.src[4] = htons(0x0100);
69 tx_header.length = htons(64);
70 tx_header.snap1 = htonl(0xaaaa0300);
71 tx_header.snap2 = htonl(0x408c8856);
72 tx_header.tag = htonl(0xfffffffe);
73 tx_header.seq = 0;
74 tx_header.type = 0;
75
76 tx_descr.sw_len = NETWORK_HEADER_LENGTH;
77 tx_descr.ctrl = TX_CTRL_EOP;
78 tx_descr.buf = (udword)&tx_header;
79
80 set_dest = FALSE;
81 seq = 0;
82
83 *R_DMA_CH1_FIRST = (udword)&rx_descr;
84 *R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, start);
85 }
86
87 int
88 handle_network_read(void)
89 {
90 if (!(rx_descr2.status & d_eop)) {
91 return FALSE;
92 }
93
94 /* Even if wasn't to us, we must do this... */
95 rx_descr2.status = 0;
96 *R_DMA_CH1_FIRST = (udword)&rx_descr;
97
98 /* Was it to me? */
99 if (ntohl(rx_header.seq) == (seq+1)) {
100 interface = NETWORK;
101 last_timeout = *R_TIMER_DATA >> IO_BITNR(R_TIMER_DATA, timer0);
102 nbr_read += rx_descr2.hw_len - CRC_LEN;
103 rx_descr2.buf += rx_descr2.hw_len - CRC_LEN;
104 rx_descr2.sw_len = bytes_to_read - nbr_read - CRC_LEN < 1500 ?
105 bytes_to_read - nbr_read + CRC_LEN: 1500; /* FIX!!!!! */
106 rx_descr2.sw_len = rx_descr2.sw_len + NETWORK_HEADER_LENGTH < 64
107 ? 64 - NETWORK_HEADER_LENGTH : rx_descr2.sw_len; /* Less than minimum eth packet? */
108
109 seq++;
110 send_network_ack();
111 }
112
113 return TRUE;
114 }
115
116 void
117 send_network_ack(void)
118 {
119 /* send_serial_string(">send_network_ack.\r\n"); */
120
121 if (!set_dest) { /* Copy destination address from first received packet */
122 set_dest = TRUE;
123 /* If we have done a bootrom network boot, source address is in a different
124 place... */
125 if (((*R_BUS_STATUS & IO_MASK(R_BUS_STATUS, boot))
126 >> IO_BITNR(R_BUS_STATUS, boot)) - 1 == NETWORK) {
127 *(udword*)&tx_header.dest[0] = *(udword*)0x380000dc;
128 *(uword*)&tx_header.dest[4] = *(uword*)0x380000e0;
129 }
130 else {
131 *(udword*)&tx_header.dest[0] = *(udword*)&rx_header.src[0];
132 *(uword*)&tx_header.dest[4] = *(uword*)&rx_header.src[4];
133 }
134 }
135
136 #if 1
137 tx_header.seq = htonl(seq);
138 tx_header.type = htonl(ACK);
139 #else
140 tx_header.seq = htonl(seq);
141 tx_header.type = htonl(bytes_to_read);
142 tx_header.id = htonl(target_address);
143 /* tx_header.id already set in start(). */
144 #endif
145
146 tx_descr.ctrl = TX_CTRL_EOP;
147 tx_descr.sw_len = NETWORK_HEADER_LENGTH;
148
149 start_network_trans();
150 }
151
152 void
153 start_network_trans(void)
154 {
155 /* send_serial_string(">start_network_trans\r\n"); */
156
157 /* Clear possible underrun or excessive retry errors */
158 /* *R_NETWORK_TR_CTRL = */
159 /* (IO_STATE (R_NETWORK_TR_CTRL, clr_error, clr) | */
160 /* IO_STATE (R_NETWORK_TR_CTRL, delay, none) | */
161 /* IO_STATE (R_NETWORK_TR_CTRL, cancel, dont) | */
162 /* IO_STATE (R_NETWORK_TR_CTRL, cd, enable) | */
163 /* IO_STATE (R_NETWORK_TR_CTRL, pad, enable) | */
164 /* IO_STATE (R_NETWORK_TR_CTRL, crc, enable) | */
165 /* IO_STATE (R_NETWORK_TR_CTRL, retry, enable)); */
166
167 *R_DMA_CH0_FIRST = (udword)&tx_descr;
168 *R_DMA_CH0_CMD = IO_STATE(R_DMA_CH0_CMD, cmd, start);
169 while(*R_DMA_CH0_FIRST)
170 ;
171 }
172
173 void
174 send_network_string(char *str)
175 {
176 int i;
177
178 tx_descr.next = (udword)&tx_descr2;
179 tx_descr.ctrl = TX_CTRL;
180 for (i = 0; str[i]; i++) /* strlen */
181 ;
182
183 tx_header.type = STRING;
184
185 tx_descr2.ctrl = TX_CTRL_EOP;
186 tx_descr2.buf = (udword)str;
187 tx_descr2.sw_len = i+1;
188
189 start_network_trans();
190 }
191
192 void
193 send_network_hex(udword v, byte nl)
194 {
195 tx_descr.next = (udword)&tx_descr2;
196 tx_descr.ctrl = TX_CTRL;
197
198 tx_header.type = nl ? htonl(NET_INT_NL) : htonl(NET_INT);
199
200 /* Pause so we don't saturate network. */
201 /* Hehe, the asm will fool gcc to not remove the loop even though it
202 probably should. If we volatile i the code will be a few bytes
203 longer than this version. Well I really did it like this just
204 because it is possible... */
205 {
206 udword i;
207
208 for(i = 0; i != 16384; i++)
209 __asm__ ("");
210 }
211
212 v = htonl(v);
213 tx_descr2.ctrl = TX_CTRL_EOP;
214 tx_descr2.buf = (udword)&v;
215 tx_descr2.sw_len = (uword)sizeof(udword);
216
217 start_network_trans();
218 }