1 /* SPDX-License-Identifier: GPL-2.0+
3 * * Copyright 2019 Broadcom Ltd.
12 #include <asm/system.h>
13 #include <linux/errno.h>
15 #include <linux/ioport.h>
18 #include "asm/arch/gmac.h"
19 #include "bcm_ethsw.h"
21 /*---------------------------------------------------------------------*/
22 /* specify number of BDs and buffers to use */
23 /*---------------------------------------------------------------------*/
27 #define ENET_MAX_MTU_SIZE 1522 /* Body(1500) + EH_SIZE(14) + FCS(4) + VLAN(4) */
28 #define DMA_MAX_BURST_LENGTH 8 /* in 64 bit words */
29 #define ENET_BUF_SIZE ((ENET_MAX_MTU_SIZE + 63) & ~63)
30 #define DMA_FC_THRESH_LO 5
31 #define DMA_FC_THRESH_HI 10
32 #define EMAC_TX_WATERMARK 32
34 // for now physical address = virtual
37 typedef struct sf2gmac_priv
{
39 volatile GmacIntf
*gmac_intf
;
40 volatile GmacMac
*gmac_mac
;
41 volatile DmaRegs
*dmaCtrl
;
43 struct udevice
*sf2_devp
;
44 bcm_ethsw_ops_t
*sf2_ops
;
45 unsigned char *rcv_buffer
;
48 /* transmit variables */
49 volatile DmaChannelCfg
*txDma
; /* location of transmit DMA register set */
50 volatile DmaDesc
*txBds
; /* Memory location of tx Dma BD ring */
51 volatile DmaDesc
*txFirstBdPtr
; /* ptr to first allocated Tx BD */
52 volatile DmaDesc
*txNextBdPtr
; /* ptr to next Tx BD to transmit with */
53 volatile DmaDesc
*txLastBdPtr
; /* ptr to last allocated Tx BD */
55 /* receive variables */
56 volatile DmaChannelCfg
*rxDma
; /* location of receive DMA register set */
57 volatile DmaDesc
*rxBds
; /* Memory location of rx bd ring */
58 volatile DmaDesc
*rxFirstBdPtr
; /* ptr to first allocated rx bd */
59 volatile DmaDesc
*rxBdReadPtr
; /* ptr to next rx bd to be processed */
60 volatile DmaDesc
*rxLastBdPtr
; /* ptr to last allocated rx bd */
67 #define IncRxBdPtr(x, s) if (x == ((sf2gmac_priv *)s)->rxLastBdPtr) \
68 x = ((sf2gmac_priv *)s)->rxBds; \
70 #define InctxBdPtr(x, s) if (x == ((sf2gmac_priv *)s)->txLastBdPtr) \
71 x = ((sf2gmac_priv *)s)->txBds; \
78 #define CACHE_ALIGN 64
82 * init_dma: Initialize DMA control register
85 #define NUM_PORTS 1 // only 1 port supported
86 static void init_dma(struct sf2gmac_priv
*softc
)
94 StateRam
= (uint32_t *)&softc
->dmaCtrl
->stram
.s
[0];
95 for (i
= 0; i
< sizeof(DmaStateRam
) / sizeof(uint32_t) * NUM_PORTS
* 2; i
++)
99 * initialize IUDMA controller register
101 softc
->dmaCtrl
->controller_cfg
= DMA_FLOWC_CH1_EN
;
102 softc
->dmaCtrl
->flowctl_ch1_thresh_lo
= DMA_FC_THRESH_LO
;
103 softc
->dmaCtrl
->flowctl_ch1_thresh_hi
= DMA_FC_THRESH_HI
;
104 softc
->dmaCtrl
->flowctl_ch1_alloc
= 0;
107 softc
->txDma
->cfg
= 0; /* initialize first (will enable later) */
108 softc
->txDma
->maxBurst
= DMA_MAX_BURST_LENGTH
;
109 softc
->txDma
->intMask
= 0; /* mask all ints */
110 /* clr any pending interrupts on channel */
111 softc
->txDma
->intStat
= DMA_DONE
|DMA_NO_DESC
|DMA_BUFF_DONE
;
112 softc
->txDma
->intMask
= DMA_DONE
;
113 softc
->dmaCtrl
->stram
.s
[DMA_TX_CHAN
].baseDescPtr
= (uint32_t)softc
->txFirstBdPtr
;
116 softc
->rxDma
->cfg
= 0; // initialize first (will enable later)
117 softc
->rxDma
->maxBurst
= DMA_MAX_BURST_LENGTH
;
118 softc
->rxDma
->intMask
= 0; /* mask all ints */
119 /* clr any pending interrupts on channel */
120 softc
->rxDma
->intStat
= DMA_DONE
|DMA_NO_DESC
|DMA_BUFF_DONE
;
121 softc
->rxDma
->intMask
= DMA_DONE
;
122 softc
->dmaCtrl
->stram
.s
[DMA_RX_CHAN
].baseDescPtr
= (uint32_t)softc
->rxFirstBdPtr
;
126 static void gmac_init(sf2gmac_priv
*priv
)
128 volatile GmacIntf
*GMAC_INTF
= priv
->gmac_intf
;
129 volatile GmacMac
*GMAC_MAC
= priv
->gmac_mac
;
132 GMAC_MAC
->Cmd
.sw_reset
= 1;
134 GMAC_MAC
->Cmd
.sw_reset
= 0;
136 GMAC_INTF
->Flush
.txfifo_flush
= 1;
137 GMAC_INTF
->Flush
.rxfifo_flush
= 1;
139 GMAC_INTF
->Flush
.txfifo_flush
= 0;
140 GMAC_INTF
->Flush
.rxfifo_flush
= 0;
142 GMAC_INTF
->MibCtrl
.clrMib
= 1;
143 GMAC_INTF
->MibCtrl
.clrMib
= 0;
145 /* default CMD configuration */
146 GMAC_MAC
->Cmd
.eth_speed
= CMD_ETH_SPEED_1000
;
148 /* Disable Tx and Rx */
149 GMAC_MAC
->Cmd
.tx_ena
= 0;
150 GMAC_MAC
->Cmd
.rx_ena
= 0;
155 static void gmac_enable_port(sf2gmac_priv
*priv
, int enable
)
157 volatile GmacMac
*GMAC_MAC
= priv
->gmac_mac
;
160 GMAC_MAC
->Cmd
.tx_ena
= 1;
161 GMAC_MAC
->Cmd
.rx_ena
= 1;
164 GMAC_MAC
->Cmd
.tx_ena
= 0;
165 GMAC_MAC
->Cmd
.rx_ena
= 0;
171 static int internal_open (struct sf2gmac_priv
*softc
)
176 softc
->rxDma
= &softc
->dmaCtrl
->chcfg
[DMA_RX_CHAN
];
177 softc
->txDma
= &softc
->dmaCtrl
->chcfg
[DMA_TX_CHAN
];
179 // If doing SW reboot in EPI the controller can still be active
180 softc
->rxDma
->cfg
= 0;
181 softc
->txDma
->cfg
= 0;
182 softc
->dmaCtrl
->controller_cfg
&= ~DMA_MASTER_EN
;
184 // noncached memory can only be allocated once
185 if (softc
->txBds
== NULL
)
187 // allocate a chunk of non cached memory for packet descriptors
188 p
= noncached_alloc((NR_TX_BDS
+ NR_RX_BDS
) * sizeof(DmaDesc
), CACHE_ALIGN
);
190 printf( "BCM63xx : Fail alloctxBds mem\n" );
194 softc
->txBds
= (DmaDesc
*)p
;
195 p
+= (NR_TX_BDS
* sizeof(DmaDesc
));
196 softc
->rxBds
= (DmaDesc
*)p
;
199 // allocate memory for RX and TX data (cached memory)
200 softc
->rxBuffers
= (uint8_t*)memalign( CACHE_ALIGN
, NR_RX_BDS
* ENET_BUF_SIZE
);
201 if( softc
->rxBuffers
== NULL
) {
202 printf( "BCM63xx : Failed allocRxBuffer mem\n" );
205 invalidate_dcache_range((unsigned long)softc
->rxBuffers
, (unsigned long)softc
->rxBuffers
+ NR_RX_BDS
* ENET_BUF_SIZE
);
207 softc
->txBuffers
= (uint8_t*)memalign( CACHE_ALIGN
, NR_TX_BDS
* ENET_BUF_SIZE
);
208 if( softc
->txBuffers
== NULL
) {
209 printf( "BCM63xx : Failed alloc txBuffer mem\n" );
210 free( (void *)(softc
->rxBuffers
) );
211 softc
->rxBuffers
= NULL
;
214 invalidate_dcache_range((unsigned long)softc
->txBuffers
, (unsigned long)softc
->txBuffers
+ NR_TX_BDS
* ENET_BUF_SIZE
);
216 /* Init the Receive Buffer Descriptor Ring. */
217 softc
->rxFirstBdPtr
= softc
->rxBdReadPtr
= softc
->rxBds
;
218 softc
->rxLastBdPtr
= softc
->rxBds
+ NR_RX_BDS
- 1;
220 for(i
= 0; i
< NR_RX_BDS
; i
++) {
221 (softc
->rxBds
+ i
)->status
= DMA_OWN
;
222 (softc
->rxBds
+ i
)->length
= ENET_BUF_SIZE
;
223 (softc
->rxBds
+ i
)->address
= K0_TO_PHYS( (uintptr_t)softc
->rxBuffers
+ i
* ENET_BUF_SIZE
);
224 softc
->dmaCtrl
->flowctl_ch1_alloc
= 1;
226 softc
->rxLastBdPtr
->status
|= DMA_WRAP
;
228 /* Init Transmit Buffer Descriptor Ring. */
229 softc
->txFirstBdPtr
= softc
->txNextBdPtr
= softc
->txBds
;
230 softc
->txLastBdPtr
= softc
->txBds
+ NR_TX_BDS
- 1;
232 for(i
= 0; i
< NR_TX_BDS
; i
++) {
233 (softc
->txBds
+ i
)->status
= 0;
234 (softc
->txBds
+ i
)->length
= 0;
235 (softc
->txBds
+ i
)->address
= K0_TO_PHYS( (uintptr_t)softc
->txBuffers
+ i
* ENET_BUF_SIZE
);
237 softc
->txLastBdPtr
->status
= DMA_WRAP
;
239 /* init dma registers */
241 softc
->dmaCtrl
->controller_cfg
|= DMA_MASTER_EN
;
242 softc
->rxDma
->cfg
|= DMA_ENABLE
;
244 softc
->rcv_buffer
= (unsigned char *)memalign(sizeof(int), ENET_BUF_SIZE
);
245 if (softc
->rcv_buffer
== NULL
) {
246 printf("failed to allocate receive buffer\n");
253 static int bcmbca_sf2gmac_eth_start (struct udevice
*dev
)
256 struct sf2gmac_priv
*priv
= dev_get_priv(dev
);
258 debug("bcmbca_sf2gmac_eth_start called %s\n", dev
->name
);
262 rc
= internal_open(priv
);
264 printf("internal open failed rx %d\n", rc
);
269 priv
->sf2_ops
->open (priv
->sf2_devp
);
272 gmac_enable_port(priv
, 1);
278 static void bcmbca_sf2gmac_eth_stop(struct udevice
*dev
)
280 struct sf2gmac_priv
*priv
= dev_get_priv(dev
);
282 debug("bcmbca_sf2gmac_eth_stop called %s\n", dev
->name
);
287 static int bcmbca_sf2gmac_eth_read_mac(struct udevice
*dev
)
292 static int bcmbca_sf2gmac_eth_send(struct udevice
*dev
, void *buffer
, int length
)
294 volatile DmaDesc
* CurrentBdPtr
;
295 unsigned char * dstptr
;
296 struct sf2gmac_priv
*softc
= dev_get_priv(dev
);
297 uint32_t status
, offset
;
300 if (length
> ENET_MAX_MTU_SIZE
)
305 CurrentBdPtr
= softc
->txNextBdPtr
;
307 /* Find out if the next BD is available. */
308 if( CurrentBdPtr
->status
& DMA_OWN
) {
309 printf( "No tx BD available ?!\n" );
313 dstptr
= (unsigned char *)( CurrentBdPtr
->address
);
314 memcpy( dstptr
, buffer
, length
);
315 flush_cache((unsigned long)dstptr
, length
);
317 /* Set status of DMA BD to be transmitted. */
318 status
= DMA_SOP
| DMA_EOP
| DMA_APPEND_CRC
| DMA_OWN
;
319 if( CurrentBdPtr
== softc
->txLastBdPtr
) {
323 CurrentBdPtr
->length
= length
;
324 CurrentBdPtr
->status
= status
;
327 softc
->txDma
->cfg
|= DMA_ENABLE
;
329 // poll dma status until done
332 invalidate_dcache_range((unsigned long)dstptr
, (unsigned long)dstptr
+ CACHE_ALIGN
);
333 } while((CurrentBdPtr
->status
& DMA_OWN
) && timeout
--);
336 //Advance BD pointer to next in the chain.
337 InctxBdPtr( CurrentBdPtr
, softc
);
338 softc
->txNextBdPtr
= CurrentBdPtr
;
342 printf("timeout sending packet of size %d\n", length
);
343 // clear the buffer pointer and force the PD pointer
344 softc
->txDma
->intStat
= DMA_DONE
|DMA_NO_DESC
|DMA_BUFF_DONE
;
345 offset
= softc
->dmaCtrl
->stram
.s
[DMA_TX_CHAN
].state_data
& RING_OFFSET_MASK
;
346 softc
->txNextBdPtr
= (volatile DmaDesc
*)((unsigned char *)softc
->txFirstBdPtr
+ (offset
* sizeof(DmaDesc
)));
351 static int bcmbca_sf2gmac_eth_recv(struct udevice
*dev
, int flags
, uchar
** packetp
)
356 volatile DmaDesc
* CurrentBdPtr
;
357 struct sf2gmac_priv
*softc
= dev_get_priv(dev
);
359 dmaFlag
= (uint16_t) softc
->rxBdReadPtr
->status
;
361 if (!(dmaFlag
& DMA_EOP
)) {
365 CurrentBdPtr
= softc
->rxBdReadPtr
;
366 srcptr
= CurrentBdPtr
->address
;
368 length
= CurrentBdPtr
->length
;
370 if (length
== ENET_BUF_SIZE
|| length
< ENET_ZLEN
|| length
> ENET_MAX_MTU_SIZE
)
372 printf("received data length is incorrect %d\n", length
);
376 invalidate_dcache_range((unsigned long)srcptr
, (unsigned long)srcptr
+ ENET_BUF_SIZE
);
379 *packetp
= softc
->rcv_buffer
;
381 memcpy (*packetp
, srcptr
, length
);
385 CurrentBdPtr
->length
= ENET_BUF_SIZE
;
386 CurrentBdPtr
->status
&= DMA_WRAP
;
387 CurrentBdPtr
->status
|= DMA_OWN
;
389 IncRxBdPtr( CurrentBdPtr
, softc
);
390 softc
->rxBdReadPtr
= CurrentBdPtr
;
391 softc
->dmaCtrl
->flowctl_ch1_alloc
= 1;
394 softc
->rxDma
->cfg
= DMA_ENABLE
;
398 static int sf2gmac_free_pkt (struct udevice
*dev
, uchar
*packet
, int length
)
400 struct sf2gmac_priv
*priv
= dev_get_priv(dev
);
401 if (packet
!= priv
->rcv_buffer
)
402 printf("why free this? %p\n", packet
);
407 static const struct eth_ops sf2gmac_eth_ops
= {
408 .start
= bcmbca_sf2gmac_eth_start
,
409 .send
= bcmbca_sf2gmac_eth_send
,
410 .recv
= bcmbca_sf2gmac_eth_recv
,
411 .stop
= bcmbca_sf2gmac_eth_stop
,
412 .free_pkt
= sf2gmac_free_pkt
,
413 .read_rom_hwaddr
= bcmbca_sf2gmac_eth_read_mac
,
416 static int sf2gmac_probe (struct udevice
*dev
)
420 struct udevice
*sf2_devp
;
421 struct sf2gmac_priv
*priv
= dev_get_priv(dev
);
425 ret
= dev_read_resource_byname(dev
, "gmac-intf-base", &res
);
427 dev_err(dev
, "can't get regs gmac-intf-base address(ret = %d)!\n", ret
);
430 priv
->gmac_intf
= devm_ioremap(dev
, res
.start
, resource_size(&res
));
432 ret
= dev_read_resource_byname(dev
, "gmac-mac-base", &res
);
434 dev_err(dev
, "can't get regs gmac-mac-base address(ret = %d)!\n", ret
);
437 priv
->gmac_mac
= devm_ioremap(dev
, res
.start
, resource_size(&res
));
439 ret
= dev_read_resource_byname(dev
, "gmac-dma-base", &res
);
441 dev_err(dev
, "can't get regs gmac-dma-base address(ret = %d)!\n", ret
);
444 priv
->dmaCtrl
= devm_ioremap(dev
, res
.start
, resource_size(&res
));
446 priv
->sf2_devp
= NULL
;
447 list
= dev_read_prop (dev
, "ethsw", &size
);
449 phandle_id
= fdt32_to_cpu(*list
);
450 if (!uclass_get_device_by_phandle_id(UCLASS_NOP
, phandle_id
, &sf2_devp
))
452 printf("sf2 found, should have been probed name %s driver name %s\n",
453 sf2_devp
->name
, sf2_devp
->driver
->name
);
454 priv
->sf2_devp
= sf2_devp
;
455 priv
->sf2_ops
= dev_get_priv(sf2_devp
);
456 priv
->sf2_ops
->init (priv
->sf2_devp
);
457 PowerOnDevice(PMB_ADDR_GMAC
);
460 // in case sf2 is not initialized, the sf2 gmac network interface will not work
461 if (priv
->sf2_devp
== NULL
) {
462 printf("cannot find the pairing SF2 driver\n");
473 static int sf2gmac_remove(struct udevice
*dev
)
475 struct sf2gmac_priv
*priv
= dev_get_priv(dev
);
481 priv
->sf2_ops
->close (priv
->sf2_devp
);
483 gmac_enable_port(priv
, 0);
485 free( (void *)(priv
->rcv_buffer
) );
486 free( (void *)(priv
->rxBuffers
) );
487 free( (void *)(priv
->txBuffers
) );
488 priv
->rxBuffers
= NULL
;
489 priv
->txBuffers
= NULL
;
491 PowerOffDevice(PMB_ADDR_GMAC
, 0);
496 static const struct udevice_id bcmbca_sf2gmac_match_ids
[] = {
497 { .compatible
= "brcm,bcmbca-sf2gmac"},
502 U_BOOT_DRIVER(sf2gmac
) = {
505 .of_match
= bcmbca_sf2gmac_match_ids
,
506 .flags
= DM_REMOVE_ACTIVE_ALL
,
507 .probe
= sf2gmac_probe
,
508 .remove
= sf2gmac_remove
,
509 .ops
= &sf2gmac_eth_ops
,
510 .priv_auto_alloc_size
= sizeof(struct sf2gmac_priv
),
511 .platdata_auto_alloc_size
= sizeof(struct eth_pdata
),