2 * Copyright 2014 Broadcom Corporation.
4 * SPDX-License-Identifier: GPL-2.0+
18 #include "bcm-sf2-eth.h"
20 #if defined(CONFIG_BCM_SF2_ETH_GMAC)
21 #include "bcm-sf2-eth-gmac.h"
23 #error "bcm_sf2_eth: NEED to define a MAC!"
26 #define BCM_NET_MODULE_DESCRIPTION "Broadcom Starfighter2 Ethernet driver"
27 #define BCM_NET_MODULE_VERSION "0.1"
28 #define BCM_SF2_ETH_DEV_NAME "bcm_sf2"
30 static const char banner
[] =
31 BCM_NET_MODULE_DESCRIPTION
" " BCM_NET_MODULE_VERSION
"\n";
33 static int bcm_sf2_eth_init(struct eth_device
*dev
)
35 struct eth_info
*eth
= (struct eth_info
*)(dev
->priv
);
36 struct eth_dma
*dma
= &(eth
->dma
);
37 struct phy_device
*phydev
;
41 rc
= eth
->mac_init(dev
);
43 error("%s: Couldn't cofigure MAC!\n", __func__
);
48 dma
->disable_dma(dma
, MAC_DMA_RX
);
49 dma
->disable_dma(dma
, MAC_DMA_TX
);
52 debug("Connecting PHY 0...\n");
53 phydev
= phy_connect(miiphy_get_dev_by_name(dev
->name
),
54 0, dev
, eth
->phy_interface
);
56 eth
->port
[0] = phydev
;
59 debug("No PHY found for port 0\n");
62 for (i
= 0; i
< eth
->port_num
; i
++)
63 phy_config(eth
->port
[i
]);
69 * u-boot net functions
72 static int bcm_sf2_eth_send(struct eth_device
*dev
, void *packet
, int length
)
74 struct eth_dma
*dma
= &(((struct eth_info
*)(dev
->priv
))->dma
);
75 uint8_t *buf
= (uint8_t *)packet
;
79 debug("%s enter\n", __func__
);
81 /* load buf and start transmit */
82 rc
= dma
->tx_packet(dma
, buf
, length
);
84 debug("ERROR - Tx failed\n");
88 while (!(dma
->check_tx_done(dma
))) {
93 error("%s: Tx timeout: retried 20 times\n", __func__
);
99 debug("%s exit rc(0x%x)\n", __func__
, rc
);
103 static int bcm_sf2_eth_receive(struct eth_device
*dev
)
105 struct eth_dma
*dma
= &(((struct eth_info
*)(dev
->priv
))->dma
);
106 uint8_t *buf
= (uint8_t *)net_rx_packets
[0];
112 /* Poll Rx queue to get a packet */
113 rcvlen
= dma
->check_rx_done(dma
, buf
);
115 /* No packet received */
117 debug("\nNO More Rx\n");
119 } else if ((rcvlen
== 0) || (rcvlen
> RX_BUF_SIZE
)) {
120 error("%s: Wrong Ethernet packet size (%d B), skip!\n",
126 /* Forward received packet to uboot network handler */
127 net_process_received_packet(buf
, rcvlen
);
129 if (++i
>= PKTBUFSRX
)
131 buf
= net_rx_packets
[i
];
138 static int bcm_sf2_eth_write_hwaddr(struct eth_device
*dev
)
140 struct eth_info
*eth
= (struct eth_info
*)(dev
->priv
);
142 printf(" ETH MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
143 dev
->enetaddr
[0], dev
->enetaddr
[1], dev
->enetaddr
[2],
144 dev
->enetaddr
[3], dev
->enetaddr
[4], dev
->enetaddr
[5]);
146 return eth
->set_mac_addr(dev
->enetaddr
);
149 static int bcm_sf2_eth_open(struct eth_device
*dev
, bd_t
*bt
)
151 struct eth_info
*eth
= (struct eth_info
*)(dev
->priv
);
152 struct eth_dma
*dma
= &(eth
->dma
);
155 debug("Enabling BCM SF2 Ethernet.\n");
159 /* enable tx and rx DMA */
160 dma
->enable_dma(dma
, MAC_DMA_RX
);
161 dma
->enable_dma(dma
, MAC_DMA_TX
);
164 * Need to start PHY here because link speed can change
165 * before each ethernet operation
167 for (i
= 0; i
< eth
->port_num
; i
++) {
168 if (phy_startup(eth
->port
[i
])) {
169 error("%s: PHY %d startup failed!\n", __func__
, i
);
170 if (i
== CONFIG_BCM_SF2_ETH_DEFAULT_PORT
) {
171 error("%s: No default port %d!\n", __func__
, i
);
177 /* Set MAC speed using default port */
178 i
= CONFIG_BCM_SF2_ETH_DEFAULT_PORT
;
179 debug("PHY %d: speed:%d, duplex:%d, link:%d\n", i
,
180 eth
->port
[i
]->speed
, eth
->port
[i
]->duplex
, eth
->port
[i
]->link
);
181 eth
->set_mac_speed(eth
->port
[i
]->speed
, eth
->port
[i
]->duplex
);
183 debug("Enable Ethernet Done.\n");
188 static void bcm_sf2_eth_close(struct eth_device
*dev
)
190 struct eth_info
*eth
= (struct eth_info
*)(dev
->priv
);
191 struct eth_dma
*dma
= &(eth
->dma
);
194 dma
->disable_dma(dma
, MAC_DMA_RX
);
195 dma
->disable_dma(dma
, MAC_DMA_TX
);
200 int bcm_sf2_eth_register(bd_t
*bis
, u8 dev_num
)
202 struct eth_device
*dev
;
203 struct eth_info
*eth
;
206 dev
= (struct eth_device
*)malloc(sizeof(struct eth_device
));
208 error("%s: Not enough memory!\n", __func__
);
212 eth
= (struct eth_info
*)malloc(sizeof(struct eth_info
));
214 error("%s: Not enough memory!\n", __func__
);
220 memset(dev
, 0, sizeof(*dev
));
221 sprintf(dev
->name
, "%s_%s-%hu", BCM_SF2_ETH_DEV_NAME
,
222 BCM_SF2_ETH_MAC_NAME
, dev_num
);
224 dev
->priv
= (void *)eth
;
227 dev
->init
= bcm_sf2_eth_open
;
228 dev
->halt
= bcm_sf2_eth_close
;
229 dev
->send
= bcm_sf2_eth_send
;
230 dev
->recv
= bcm_sf2_eth_receive
;
231 dev
->write_hwaddr
= bcm_sf2_eth_write_hwaddr
;
233 #ifdef CONFIG_BCM_SF2_ETH_GMAC
237 error("%s: Adding GMAC failed!\n", __func__
);
241 #error "bcm_sf2_eth: NEED to register a MAC!"
246 #ifdef CONFIG_CMD_MII
247 miiphy_register(dev
->name
, eth
->miiphy_read
, eth
->miiphy_write
);
251 debug("Ethernet initialization ...");
253 rc
= bcm_sf2_eth_init(dev
);
255 error("%s: configuration failed!\n", __func__
);
259 printf("Basic ethernet functionality initialized\n");