2 * Faraday FTMAC100 Ethernet
4 * (C) Copyright 2009 Faraday Technology
5 * Po-Yu Chuang <ratbert@faraday-tech.com>
7 * SPDX-License-Identifier: GPL-2.0+
19 DECLARE_GLOBAL_DATA_PTR
;
23 struct ftmac100_data
{
24 struct ftmac100_txdes txdes
[1];
25 struct ftmac100_rxdes rxdes
[PKTBUFSRX
];
34 static void ftmac100_reset(struct ftmac100_data
*priv
)
36 struct ftmac100
*ftmac100
= (struct ftmac100
*)priv
->iobase
;
38 debug ("%s()\n", __func__
);
40 writel (FTMAC100_MACCR_SW_RST
, &ftmac100
->maccr
);
42 while (readl (&ftmac100
->maccr
) & FTMAC100_MACCR_SW_RST
)
45 * When soft reset complete, write mac address immediately maybe fail somehow
46 * Wait for a while can avoid this problem
54 static void ftmac100_set_mac(struct ftmac100_data
*priv
,
55 const unsigned char *mac
)
57 struct ftmac100
*ftmac100
= (struct ftmac100
*)priv
->iobase
;
58 unsigned int maddr
= mac
[0] << 8 | mac
[1];
59 unsigned int laddr
= mac
[2] << 24 | mac
[3] << 16 | mac
[4] << 8 | mac
[5];
61 debug ("%s(%x %x)\n", __func__
, maddr
, laddr
);
63 writel (maddr
, &ftmac100
->mac_madr
);
64 writel (laddr
, &ftmac100
->mac_ladr
);
70 static void _ftmac100_halt(struct ftmac100_data
*priv
)
72 struct ftmac100
*ftmac100
= (struct ftmac100
*)priv
->iobase
;
73 debug ("%s()\n", __func__
);
74 writel (0, &ftmac100
->maccr
);
80 static int _ftmac100_init(struct ftmac100_data
*priv
, unsigned char enetaddr
[6])
82 struct ftmac100
*ftmac100
= (struct ftmac100
*)priv
->iobase
;
83 struct ftmac100_txdes
*txdes
= priv
->txdes
;
84 struct ftmac100_rxdes
*rxdes
= priv
->rxdes
;
87 debug ("%s()\n", __func__
);
91 /* set the ethernet address */
92 ftmac100_set_mac(priv
, enetaddr
);
95 /* disable all interrupts */
97 writel (0, &ftmac100
->imr
);
99 /* initialize descriptors */
103 txdes
[0].txdes1
= FTMAC100_TXDES1_EDOTR
;
104 rxdes
[PKTBUFSRX
- 1].rxdes1
= FTMAC100_RXDES1_EDORR
;
106 for (i
= 0; i
< PKTBUFSRX
; i
++) {
108 rxdes
[i
].rxdes2
= (unsigned int)net_rx_packets
[i
];
109 rxdes
[i
].rxdes1
|= FTMAC100_RXDES1_RXBUF_SIZE (PKTSIZE_ALIGN
);
110 rxdes
[i
].rxdes0
= FTMAC100_RXDES0_RXDMA_OWN
;
115 writel ((unsigned int)txdes
, &ftmac100
->txr_badr
);
119 writel ((unsigned int)rxdes
, &ftmac100
->rxr_badr
);
121 /* poll receive descriptor automatically */
123 writel (FTMAC100_APTC_RXPOLL_CNT (1), &ftmac100
->aptc
);
125 /* enable transmitter, receiver */
127 maccr
= FTMAC100_MACCR_XMT_EN
|
128 FTMAC100_MACCR_RCV_EN
|
129 FTMAC100_MACCR_XDMA_EN
|
130 FTMAC100_MACCR_RDMA_EN
|
131 FTMAC100_MACCR_CRC_APD
|
132 FTMAC100_MACCR_ENRX_IN_HALFTX
|
133 FTMAC100_MACCR_RX_RUNT
|
134 FTMAC100_MACCR_RX_BROADPKT
;
136 writel (maccr
, &ftmac100
->maccr
);
142 * Free receiving buffer
144 static int _ftmac100_free_pkt(struct ftmac100_data
*priv
)
146 struct ftmac100_rxdes
*curr_des
;
147 curr_des
= &priv
->rxdes
[priv
->rx_index
];
148 /* release buffer to DMA */
149 curr_des
->rxdes0
|= FTMAC100_RXDES0_RXDMA_OWN
;
150 priv
->rx_index
= (priv
->rx_index
+ 1) % PKTBUFSRX
;
155 * Receive a data block via Ethernet
157 static int __ftmac100_recv(struct ftmac100_data
*priv
)
159 struct ftmac100_rxdes
*curr_des
;
160 unsigned short rxlen
;
162 curr_des
= &priv
->rxdes
[priv
->rx_index
];
163 if (curr_des
->rxdes0
& FTMAC100_RXDES0_RXDMA_OWN
)
166 if (curr_des
->rxdes0
& (FTMAC100_RXDES0_RX_ERR
|
167 FTMAC100_RXDES0_CRC_ERR
|
168 FTMAC100_RXDES0_FTL
|
169 FTMAC100_RXDES0_RUNT
|
170 FTMAC100_RXDES0_RX_ODD_NB
)) {
174 rxlen
= FTMAC100_RXDES0_RFL (curr_des
->rxdes0
);
175 invalidate_dcache_range(curr_des
->rxdes2
,curr_des
->rxdes2
+rxlen
);
176 debug ("%s(): RX buffer %d, %x received\n",
177 __func__
, priv
->rx_index
, rxlen
);
183 * Send a data block via Ethernet
185 static int _ftmac100_send(struct ftmac100_data
*priv
, void *packet
, int length
)
187 struct ftmac100
*ftmac100
= (struct ftmac100
*)priv
->iobase
;
188 struct ftmac100_txdes
*curr_des
= priv
->txdes
;
191 if (curr_des
->txdes0
& FTMAC100_TXDES0_TXDMA_OWN
) {
192 debug ("%s(): no TX descriptor available\n", __func__
);
196 debug ("%s(%x, %x)\n", __func__
, (int)packet
, length
);
198 length
= (length
< ETH_ZLEN
) ? ETH_ZLEN
: length
;
200 /* initiate a transmit sequence */
202 flush_dcache_range((u32
)packet
,(u32
)packet
+length
);
203 curr_des
->txdes2
= (unsigned int)packet
; /* TXBUF_BADR */
205 curr_des
->txdes1
&= FTMAC100_TXDES1_EDOTR
;
206 curr_des
->txdes1
|= FTMAC100_TXDES1_FTS
|
207 FTMAC100_TXDES1_LTS
|
208 FTMAC100_TXDES1_TXBUF_SIZE (length
);
210 curr_des
->txdes0
= FTMAC100_TXDES0_TXDMA_OWN
;
214 writel (1, &ftmac100
->txpd
);
216 /* wait for transfer to succeed */
218 start
= get_timer(0);
219 while (curr_des
->txdes0
& FTMAC100_TXDES0_TXDMA_OWN
) {
220 if (get_timer(start
) >= 5) {
221 debug ("%s(): timed out\n", __func__
);
226 debug ("%s(): packet sent\n", __func__
);
231 #ifndef CONFIG_DM_ETH
233 * disable transmitter, receiver
235 static void ftmac100_halt(struct eth_device
*dev
)
237 struct ftmac100_data
*priv
= dev
->priv
;
238 return _ftmac100_halt(priv
);
241 static int ftmac100_init(struct eth_device
*dev
, bd_t
*bd
)
243 struct ftmac100_data
*priv
= dev
->priv
;
244 return _ftmac100_init(priv
, dev
->enetaddr
);
247 static int _ftmac100_recv(struct ftmac100_data
*priv
)
249 struct ftmac100_rxdes
*curr_des
;
251 curr_des
= &priv
->rxdes
[priv
->rx_index
];
252 len
= __ftmac100_recv(priv
);
254 /* pass the packet up to the protocol layers. */
255 net_process_received_packet((void *)curr_des
->rxdes2
, len
);
256 _ftmac100_free_pkt(priv
);
262 * Get a data block via Ethernet
264 static int ftmac100_recv(struct eth_device
*dev
)
266 struct ftmac100_data
*priv
= dev
->priv
;
267 return _ftmac100_recv(priv
);
271 * Send a data block via Ethernet
273 static int ftmac100_send(struct eth_device
*dev
, void *packet
, int length
)
275 struct ftmac100_data
*priv
= dev
->priv
;
276 return _ftmac100_send(priv
, packet
, length
);
279 int ftmac100_initialize (bd_t
*bd
)
281 struct eth_device
*dev
;
282 struct ftmac100_data
*priv
;
283 dev
= malloc (sizeof *dev
);
285 printf ("%s(): failed to allocate dev\n", __func__
);
288 /* Transmit and receive descriptors should align to 16 bytes */
289 priv
= memalign (16, sizeof (struct ftmac100_data
));
291 printf ("%s(): failed to allocate priv\n", __func__
);
294 memset (dev
, 0, sizeof (*dev
));
295 memset (priv
, 0, sizeof (*priv
));
297 strcpy(dev
->name
, "FTMAC100");
298 dev
->iobase
= CONFIG_FTMAC100_BASE
;
299 dev
->init
= ftmac100_init
;
300 dev
->halt
= ftmac100_halt
;
301 dev
->send
= ftmac100_send
;
302 dev
->recv
= ftmac100_recv
;
304 priv
->iobase
= dev
->iobase
;
317 static int ftmac100_start(struct udevice
*dev
)
319 struct eth_pdata
*plat
= dev_get_platdata(dev
);
320 struct ftmac100_data
*priv
= dev_get_priv(dev
);
322 return _ftmac100_init(priv
, plat
->enetaddr
);
325 static void ftmac100_stop(struct udevice
*dev
)
327 struct ftmac100_data
*priv
= dev_get_priv(dev
);
328 _ftmac100_halt(priv
);
331 static int ftmac100_send(struct udevice
*dev
, void *packet
, int length
)
333 struct ftmac100_data
*priv
= dev_get_priv(dev
);
335 ret
= _ftmac100_send(priv
, packet
, length
);
336 return ret
? 0 : -ETIMEDOUT
;
339 static int ftmac100_recv(struct udevice
*dev
, int flags
, uchar
**packetp
)
341 struct ftmac100_data
*priv
= dev_get_priv(dev
);
342 struct ftmac100_rxdes
*curr_des
;
343 curr_des
= &priv
->rxdes
[priv
->rx_index
];
345 len
= __ftmac100_recv(priv
);
347 *packetp
= (void *)curr_des
->rxdes2
;
349 return len
? len
: -EAGAIN
;
352 static int ftmac100_free_pkt(struct udevice
*dev
, uchar
*packet
, int length
)
354 struct ftmac100_data
*priv
= dev_get_priv(dev
);
355 _ftmac100_free_pkt(priv
);
359 int ftmac100_read_rom_hwaddr(struct udevice
*dev
)
361 struct eth_pdata
*pdata
= dev_get_platdata(dev
);
362 eth_env_get_enetaddr("ethaddr", pdata
->enetaddr
);
366 static const char *dtbmacaddr(u32 ifno
)
372 if (gd
->fdt_blob
== NULL
) {
373 printf("%s: don't have a valid gd->fdt_blob!\n", __func__
);
376 node
= fdt_path_offset(gd
->fdt_blob
, "/aliases");
380 sprintf(enet
, "ethernet%d", ifno
);
381 path
= fdt_getprop(gd
->fdt_blob
, node
, enet
, NULL
);
383 printf("no alias for %s\n", enet
);
386 node
= fdt_path_offset(gd
->fdt_blob
, path
);
387 mac
= fdt_getprop(gd
->fdt_blob
, node
, "mac-address", &len
);
388 if (mac
&& is_valid_ethaddr((u8
*)mac
))
394 static int ftmac100_ofdata_to_platdata(struct udevice
*dev
)
396 struct ftmac100_data
*priv
= dev_get_priv(dev
);
397 struct eth_pdata
*pdata
= dev_get_platdata(dev
);
399 pdata
->iobase
= devfdt_get_addr(dev
);
400 priv
->iobase
= pdata
->iobase
;
403 memcpy(pdata
->enetaddr
, mac
, 6);
408 static int ftmac100_probe(struct udevice
*dev
)
410 struct ftmac100_data
*priv
= dev_get_priv(dev
);
411 priv
->name
= dev
->name
;
415 static int ftmac100_bind(struct udevice
*dev
)
417 return device_set_name(dev
, dev
->name
);
420 static const struct eth_ops ftmac100_ops
= {
421 .start
= ftmac100_start
,
422 .send
= ftmac100_send
,
423 .recv
= ftmac100_recv
,
424 .stop
= ftmac100_stop
,
425 .free_pkt
= ftmac100_free_pkt
,
428 static const struct udevice_id ftmac100_ids
[] = {
429 { .compatible
= "andestech,atmac100" },
433 U_BOOT_DRIVER(ftmac100
) = {
436 .of_match
= ftmac100_ids
,
437 .bind
= ftmac100_bind
,
438 .ofdata_to_platdata
= ftmac100_ofdata_to_platdata
,
439 .probe
= ftmac100_probe
,
440 .ops
= &ftmac100_ops
,
441 .priv_auto_alloc_size
= sizeof(struct ftmac100_data
),
442 .platdata_auto_alloc_size
= sizeof(struct eth_pdata
),
443 .flags
= DM_FLAG_ALLOC_PRIV_DMA
,