3
* Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de.
5
* Based in part on cpu/mpc8260/ether_scc.c.
7
* See file CREDITS for list of people who contributed to this
10
* This program is free software; you can redistribute it and/or
11
* modify it under the terms of the GNU General Public License as
12
* published by the Free Software Foundation; either version 2 of
13
* the License, or (at your option) any later version.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
30
#ifdef CONFIG_KEYMILE_HDLC_ENET
32
#include "../common/keymile_hdlc_enet.h"
34
char keymile_slot; /* our slot number in the backplane */
37
* Since, except during initialization, ethact is always HDLC ETHERNET
38
* while we're in the driver, just use serial_printf() everywhere for
39
* output. This avoids possible conflicts when netconsole is being
42
#define dprintf(fmt, args...) serial_printf(fmt, ##args)
44
static int already_inited;
47
* SCC Ethernet Tx and Rx buffer descriptors allocated at the
48
* immr->udata_bd address on Dual-Port RAM
49
* Provide for Double Buffering
51
typedef volatile struct CommonBufferDescriptor {
52
cbd_t txbd; /* Tx BD */
53
cbd_t rxbd[HDLC_PKTBUFSRX]; /* Rx BD */
58
int keymile_hdlc_enet_init(struct eth_device *, bd_t *);
59
void keymile_hdlc_enet_halt(struct eth_device *);
60
extern void keymile_hdlc_enet_init_bds(RTXBD *);
61
extern void initCachedNumbers(int);
64
#define CPM_CR_SCC_PAGE CPM_CR_SCC1_PAGE
65
#define CPM_CR_SCC_SBLOCK CPM_CR_SCC1_SBLOCK
66
#define CMXSCR_MASK (CMXSCR_GR1|CMXSCR_SC1|\
67
CMXSCR_RS1CS_MSK|CMXSCR_TS1CS_MSK)
68
#define CMXSCR_VALUE (CMXSCR_RS1CS_CLK11|CMXSCR_TS1CS_CLK11)
69
#define MGC_PROFF_HDLC PROFF_SCC1
70
#define MGC_SCC_HDLC 0 /* Index, not number! */
72
int keymile_hdlc_enet_init(struct eth_device *dev, bd_t *bis)
76
/* volatile cbd_t *bdp; */
77
volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
78
volatile cpm8260_t *cp = &(im->im_cpm);
80
volatile scc_hdlc_t *hpr;
81
volatile iop8260_t *iop;
86
hpr = (scc_hdlc_t *)(&im->im_dprambase[MGC_PROFF_HDLC]);
87
sccp = (scc_t *)(&im->im_scc[MGC_SCC_HDLC]);
91
* Disable receive and transmit just in case.
93
sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
96
* Avoid exhausting DPRAM, which would cause a panic.
99
/* dpr is an offset into dpram */
100
dpr = m8260_cpm_dpalloc(sizeof(RTXBD), 8);
101
rtx = (RTXBD *)&im->im_dprambase[dpr];
104
/* We need the slot number for addressing. */
105
keymile_slot = *(char *)(CONFIG_SYS_SLOT_ID_BASE +
106
CONFIG_SYS_SLOT_ID_OFF) & CONFIG_SYS_SLOT_ID_MASK;
108
* Be consistent with the Linux driver and set
111
* Always add 1 to the slot number so that
112
* there are no problems with an ethaddr which
113
* is all 0s. This should be acceptable because
114
* a board should never have a slot number of 255,
115
* which is the broadcast address. The HDLC addressing
116
* uses only the slot number.
118
dev->enetaddr[0] = keymile_slot + 1;
120
dprintf("slot %d\n", keymile_slot);
123
/* use pd30, pd31 pins for TXD1, RXD1 respectively */
124
iop->iop_ppard |= (0x80000000 >> 30) | (0x80000000 >> 31);
125
iop->iop_pdird |= (0x80000000 >> 30);
126
iop->iop_psord |= (0x80000000 >> 30);
128
/* use pc21 as CLK11 */
129
iop->iop_pparc |= (0x80000000 >> 21);
130
iop->iop_pdirc &= ~(0x80000000 >> 21);
131
iop->iop_psorc &= ~(0x80000000 >> 21);
133
/* use pc15 as CTS1 */
134
iop->iop_pparc |= (0x80000000 >> 15);
135
iop->iop_pdirc &= ~(0x80000000 >> 15);
136
iop->iop_psorc &= ~(0x80000000 >> 15);
141
* this also connects SCC1 to NMSI
143
im->im_cpmux.cmx_scr = (im->im_cpmux.cmx_scr & ~CMXSCR_MASK) |
146
/* keymile_rxIdx = 0; */
149
* Initialize function code registers for big-endian.
151
hpr->sh_genscc.scc_rfcr = CPMFCR_EB;
152
hpr->sh_genscc.scc_tfcr = CPMFCR_EB;
155
* Set maximum bytes per receive buffer.
157
hpr->sh_genscc.scc_mrblr = MAX_FRAME_LENGTH;
159
/* Setup CRC generator values for HDLC */
160
hpr->sh_cmask = 0x0000F0B8;
161
hpr->sh_cpres = 0x0000FFFF;
163
/* Initialize all error counters to 0 */
170
/* Set maximum frame length size */
171
hpr->sh_mflr = MAX_FRAME_LENGTH;
173
/* set to 1 for per frame processing change later if needed */
176
hpr->sh_hmask = 0xff;
178
hpr->sh_haddr2 = SET_HDLC_UUA(keymile_slot);
179
hpr->sh_haddr3 = hpr->sh_haddr2;
180
hpr->sh_haddr4 = hpr->sh_haddr2;
182
hpr->sh_haddr1 = HDLC_BCAST;
184
hpr->sh_genscc.scc_rbase = (unsigned int) &rtx->rxbd[0];
185
hpr->sh_genscc.scc_tbase = (unsigned int) &rtx->txbd;
189
* Initialize the buffer descriptors.
193
bdp->cbd_bufaddr = 0;
194
bdp->cbd_sc = BD_SC_WRAP;
197
* Setup RX packet buffers, aligned correctly.
198
* Borrowed from net/net.c.
200
MyRxPackets[0] = &MyPktBuf[0] + (PKTALIGN - 1);
201
MyRxPackets[0] -= (ulong)MyRxPackets[0] % PKTALIGN;
202
for (i = 1; i < HDLC_PKTBUFSRX; i++)
203
MyRxPackets[i] = MyRxPackets[0] + i * PKT_MAXBLR_SIZE;
206
for (i = 0; i < HDLC_PKTBUFSRX; i++) {
207
bdp->cbd_sc = BD_SC_EMPTY;
208
/* Leave space at the start for INET header. */
209
bdp->cbd_bufaddr = (unsigned int)(MyRxPackets[i] +
214
bdp->cbd_sc |= BD_SC_WRAP;
216
keymile_hdlc_enet_init_bds(rtx);
219
/* Let's re-initialize the channel now. We have to do it later
220
* than the manual describes because we have just now finished
221
* the BD initialization.
223
cp->cp_cpcr = mk_cr_cmd(CPM_CR_SCC_PAGE, CPM_CR_SCC_SBLOCK,
224
0, CPM_CR_INIT_TRX) | CPM_CR_FLG;
225
while (cp->cp_cpcr & CPM_CR_FLG);
227
sccp->scc_gsmrl = SCC_GSMRL_MODE_HDLC;
229
sccp->scc_gsmrh = SCC_GSMRH_CTSS;
230
/* NOF=0, RTE=1, DRT=0, BUS=1 */
231
sccp->scc_psmr = ((0x8000 >> 6) | (0x8000 >> 10));
233
/* loopback for local testing */
235
dprintf("LOOPBACK!\n");
236
sccp->scc_gsmrl |= SCC_GSMRL_DIAG_LOOP;
240
* Disable all interrupts and clear all pending
244
sccp->scc_scce = 0xffff;
247
* And last, enable the transmit and receive processing.
249
sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
251
dprintf("%s: HDLC ENET Version 0.3 on SCC%d\n", dev->name,
255
* We may not get an ARP packet because ARP was already done on
256
* a different interface, so initialize the cached values now.
258
initCachedNumbers(1);
265
void keymile_hdlc_enet_halt(struct eth_device *dev)
267
#if 0 /* just return, but keep this for reference */
268
volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
270
/* maybe should do a graceful stop here? */
271
immr->im_scc[MGC_SCC_HDLC].scc_gsmrl &=
272
~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
276
#endif /* CONFIG_MGCOGE_HDLC_ENET */