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");
157 /* Set MAC address from env */
158 if (bcm_sf2_eth_write_hwaddr(dev) != 0) {
159 error("%s: MAC set error when opening !\n", __func__);
165 /* enable tx and rx DMA */
166 dma->enable_dma(dma, MAC_DMA_RX);
167 dma->enable_dma(dma, MAC_DMA_TX);
170 * Need to start PHY here because link speed can change
171 * before each ethernet operation
173 for (i = 0; i < eth->port_num; i++) {
174 if (phy_startup(eth->port[i])) {
175 error("%s: PHY %d startup failed!\n", __func__, i);
176 if (i == CONFIG_BCM_SF2_ETH_DEFAULT_PORT) {
177 error("%s: No default port %d!\n", __func__, i);
183 /* Set MAC speed using default port */
184 i = CONFIG_BCM_SF2_ETH_DEFAULT_PORT;
185 debug("PHY %d: speed:%d, duplex:%d, link:%d\n", i,
186 eth->port[i]->speed, eth->port[i]->duplex, eth->port[i]->link);
187 eth->set_mac_speed(eth->port[i]->speed, eth->port[i]->duplex);
189 debug("Enable Ethernet Done.\n");
194 static void bcm_sf2_eth_close(struct eth_device *dev)
196 struct eth_info *eth = (struct eth_info *)(dev->priv);
197 struct eth_dma *dma = &(eth->dma);
200 dma->disable_dma(dma, MAC_DMA_RX);
201 dma->disable_dma(dma, MAC_DMA_TX);
206 int bcm_sf2_eth_register(bd_t *bis, u8 dev_num)
208 struct eth_device *dev;
209 struct eth_info *eth;
212 dev = (struct eth_device *)malloc(sizeof(struct eth_device));
214 error("%s: Not enough memory!\n", __func__);
218 eth = (struct eth_info *)malloc(sizeof(struct eth_info));
220 error("%s: Not enough memory!\n", __func__);
226 memset(dev, 0, sizeof(*dev));
227 sprintf(dev->name, "%s_%s-%hu", BCM_SF2_ETH_DEV_NAME,
228 BCM_SF2_ETH_MAC_NAME, dev_num);
230 dev->priv = (void *)eth;
233 dev->init = bcm_sf2_eth_open;
234 dev->halt = bcm_sf2_eth_close;
235 dev->send = bcm_sf2_eth_send;
236 dev->recv = bcm_sf2_eth_receive;
237 dev->write_hwaddr = bcm_sf2_eth_write_hwaddr;
239 #ifdef CONFIG_BCM_SF2_ETH_GMAC
243 error("%s: Adding GMAC failed!\n", __func__);
247 #error "bcm_sf2_eth: NEED to register a MAC!"
252 #ifdef CONFIG_CMD_MII
253 miiphy_register(dev->name, eth->miiphy_read, eth->miiphy_write);
257 debug("Ethernet initialization ...");
259 rc = bcm_sf2_eth_init(dev);
261 error("%s: configuration failed!\n", __func__);
265 printf("Basic ethernet functionality initialized\n");