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