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");