1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <common.h>
27#include <malloc.h>
28#include <net.h>
29
30#ifdef CONFIG_KEYMILE_HDLC_ENET
31
32#include "../common/keymile_hdlc_enet.h"
33
34char keymile_slot;
35
36
37
38
39
40
41
42#define dprintf(fmt, args...) serial_printf(fmt, ##args)
43
44static int already_inited;
45
46
47
48
49
50
51typedef volatile struct CommonBufferDescriptor {
52 cbd_t txbd;
53 cbd_t rxbd[HDLC_PKTBUFSRX];
54} RTXBD;
55
56static RTXBD *rtx;
57
58int keymile_hdlc_enet_init(struct eth_device *, bd_t *);
59void keymile_hdlc_enet_halt(struct eth_device *);
60extern void keymile_hdlc_enet_init_bds(RTXBD *);
61extern void initCachedNumbers(int);
62
63
64#define MGS_CPM_CR_HDLC CPM_CR_CH_SCC4
65#define MGS_PROFF_HDLC PROFF_SCC4
66#define MGS_SCC_HDLC 3
67
68int keymile_hdlc_enet_init(struct eth_device *dev, bd_t *bis)
69{
70
71
72 volatile cpm8xx_t *cp;
73 volatile scc_t *sccp;
74 volatile hdlc_pram_t *hpr;
75 volatile iop8xx_t *iop;
76
77 if (already_inited)
78 return 0;
79
80 cp = (cpm8xx_t *)&(((volatile immap_t *)CONFIG_SYS_IMMR)->im_cpm);
81 hpr = (hdlc_pram_t *)(&cp->cp_dparam[MGS_PROFF_HDLC]);
82 sccp = (volatile scc_t *)(&cp->cp_scc[MGS_SCC_HDLC]);
83 iop = (iop8xx_t *)&(((volatile immap_t *)CONFIG_SYS_IMMR)->im_ioport);
84
85
86
87
88 sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
89
90#ifndef CONFIG_SYS_ALLOC_DPRAM
91#error "CONFIG_SYS_ALLOC_DPRAM must be defined"
92#else
93
94
95
96
97
98 if (rtx == NULL) {
99 rtx = (RTXBD *) (cp->cp_dpmem +
100 dpram_alloc_align(sizeof(RTXBD), 8));
101 if (rtx == (RTXBD *)CPM_DP_NOSPACE)
102 return -1;
103 memset((void *)rtx, 0, sizeof(RTXBD));
104 }
105#endif
106
107
108 keymile_slot = *(char *)(CONFIG_SYS_SLOT_ID_BASE +
109 CONFIG_SYS_SLOT_ID_OFF) & CONFIG_SYS_SLOT_ID_MASK;
110
111
112
113
114
115
116
117
118
119
120
121 dev->enetaddr[0] = keymile_slot + 1;
122
123#ifdef TEST_IT
124 dprintf("slot %d\n", keymile_slot);
125#endif
126
127
128 iop->iop_papar |= ((0x8000 >> 8) | (0x8000 >> 9));
129 iop->iop_padir &= ~((0x8000 >> 8) | (0x8000 >> 9));
130 iop->iop_paodr &= ~((0x8000 >> 8) | (0x8000 >> 9));
131
132
133 iop->iop_papar |= 0x8000;
134 iop->iop_padir &= ~0x8000;
135 iop->iop_paodr &= ~0x8000;
136
137
138 iop->iop_pcpar &= ~(0x8000 >> 5);
139 iop->iop_pcdir &= ~(0x8000 >> 5);
140 iop->iop_pcso |= (0x8000 >> 5);
141
142
143
144
145
146
147 cp->cp_sicr = (cp->cp_sicr & ~0xff000000) | 0x3f000000;
148
149
150
151
152
153
154 hpr->rfcr = SCC_EB;
155 hpr->tfcr = SCC_EB;
156
157
158
159
160 hpr->mrblr = MAX_FRAME_LENGTH;
161
162
163 hpr->c_mask = 0x0000F0B8;
164 hpr->c_pres = 0x0000FFFF;
165
166
167 hpr->disfc = 0;
168 hpr->crcec = 0;
169 hpr->abtsc = 0;
170 hpr->nmarc = 0;
171 hpr->retrc = 0;
172
173
174 hpr->mflr = MAX_FRAME_LENGTH;
175
176
177 hpr->rfthr = 1;
178
179 hpr->hmask = 0xff;
180
181 hpr->haddr2 = SET_HDLC_UUA(keymile_slot);
182 hpr->haddr3 = hpr->haddr2;
183 hpr->haddr4 = hpr->haddr2;
184
185 hpr->haddr1 = HDLC_BCAST;
186
187 hpr->rbase = (unsigned int) &rtx->rxbd[0];
188 hpr->tbase = (unsigned int) &rtx->txbd;
189
190#if 0
191
192
193
194 bdp = &rtx->txbd;
195 bdp->cbd_sc = 0;
196 bdp->cbd_bufaddr = 0;
197 bdp->cbd_sc = BD_SC_WRAP;
198
199
200
201
202
203 MyRxPackets[0] = &MyPktBuf[0] + (PKTALIGN - 1);
204 MyRxPackets[0] -= (ulong)MyRxPackets[0] % PKTALIGN;
205 for (i = 1; i < HDLC_PKTBUFSRX; i++)
206 MyRxPackets[i] = MyRxPackets[0] + i * PKT_MAXBLR_SIZE;
207
208 bdp = &rtx->rxbd[0];
209 for (i = 0; i < HDLC_PKTBUFSRX; i++) {
210 bdp->cbd_sc = BD_SC_EMPTY;
211
212 bdp->cbd_bufaddr = (unsigned int)(MyRxPackets[i] +
213 INET_HDR_ALIGN);
214 bdp++;
215 }
216 bdp--;
217 bdp->cbd_sc |= BD_SC_WRAP;
218#else
219 keymile_hdlc_enet_init_bds(rtx);
220#endif
221
222
223
224
225
226 cp->cp_cpcr = mk_cr_cmd(MGS_CPM_CR_HDLC, CPM_CR_INIT_TRX) | CPM_CR_FLG;
227 while (cp->cp_cpcr & CPM_CR_FLG);
228
229 sccp->scc_gsmrl = SCC_GSMRL_MODE_HDLC;
230
231 sccp->scc_gsmrh = SCC_GSMRH_CTSS;
232
233 sccp->scc_psmr = ((0x8000 >> 6) | (0x8000 >> 10));
234
235
236#ifdef GJTEST
237 dprintf("LOOPBACK!\n");
238 sccp->scc_gsmrl |= SCC_GSMRL_DIAG_LOOP;
239#endif
240
241
242
243
244
245 sccp->scc_sccm = 0;
246 sccp->scc_scce = 0xffff;
247
248
249
250
251 sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
252
253 dprintf("%s: HDLC ENET Version 0.3 on SCC%d\n", dev->name,
254 MGS_SCC_HDLC + 1);
255
256
257
258
259
260 initCachedNumbers(1);
261
262 already_inited = 1;
263
264 return 0;
265}
266
267void keymile_hdlc_enet_halt(struct eth_device *dev)
268{
269#if 0
270 volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
271
272
273 immr->im_cpm.cp_scc[MGS_SCC_HDLC].scc_gsmrl &=
274 ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
275#endif
276}
277
278#endif
279