]>
git.ipfire.org Git - people/ms/u-boot.git/blob - board/keymile/mgcoge/mgcoge_hdlc_enet.c
3 * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de.
5 * Based in part on arch/powerpc/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 */