1 /* 2 * Copyright (c) 2017 Microchip Technology Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <dm.h> 8 #include <usb.h> 9 #include <linux/mii.h> 10 #include "usb_ether.h" 11 #include "lan7x.h" 12 13 /* LAN75xx specific register/bit defines */ 14 #define LAN75XX_HW_CFG_BIR BIT(7) 15 16 #define LAN75XX_BURST_CAP 0x034 17 18 #define LAN75XX_BULK_IN_DLY 0x03C 19 20 #define LAN75XX_RFE_CTL 0x060 21 22 #define LAN75XX_FCT_RX_CTL 0x090 23 24 #define LAN75XX_FCT_TX_CTL 0x094 25 26 #define LAN75XX_FCT_RX_FIFO_END 0x098 27 28 #define LAN75XX_FCT_TX_FIFO_END 0x09C 29 30 #define LAN75XX_FCT_FLOW 0x0A0 31 32 /* MAC ADDRESS PERFECT FILTER For LAN75xx */ 33 #define LAN75XX_ADDR_FILTX 0x300 34 #define LAN75XX_ADDR_FILTX_FB_VALID BIT(31) 35 36 /* 37 * Lan75xx infrastructure commands 38 */ 39 static int lan75xx_phy_gig_workaround(struct usb_device *udev, 40 struct ueth_data *dev) 41 { 42 int ret = 0; 43 44 /* Only internal phy */ 45 /* Set the phy in Gig loopback */ 46 lan7x_mdio_write(udev, dev->phy_id, MII_BMCR, 47 (BMCR_LOOPBACK | BMCR_SPEED1000)); 48 49 /* Wait for the link up */ 50 ret = lan7x_mdio_wait_for_bit(udev, "BMSR_LSTATUS", 51 dev->phy_id, MII_BMSR, BMSR_LSTATUS, 52 true, PHY_CONNECT_TIMEOUT_MS, 1); 53 if (ret) 54 return ret; 55 56 /* phy reset */ 57 return lan7x_pmt_phy_reset(udev, dev); 58 } 59 60 static int lan75xx_update_flowcontrol(struct usb_device *udev, 61 struct ueth_data *dev) 62 { 63 uint32_t flow = 0, fct_flow = 0; 64 int ret; 65 66 ret = lan7x_update_flowcontrol(udev, dev, &flow, &fct_flow); 67 if (ret) 68 return ret; 69 70 ret = lan7x_write_reg(udev, LAN75XX_FCT_FLOW, fct_flow); 71 if (ret) 72 return ret; 73 return lan7x_write_reg(udev, FLOW, flow); 74 } 75 76 static int lan75xx_set_receive_filter(struct usb_device *udev) 77 { 78 /* No multicast in u-boot */ 79 return lan7x_write_reg(udev, LAN75XX_RFE_CTL, 80 RFE_CTL_BCAST_EN | RFE_CTL_DA_PERFECT); 81 } 82 83 /* starts the TX path */ 84 static void lan75xx_start_tx_path(struct usb_device *udev) 85 { 86 /* Enable Tx at MAC */ 87 lan7x_write_reg(udev, MAC_TX, MAC_TX_TXEN); 88 89 /* Enable Tx at SCSRs */ 90 lan7x_write_reg(udev, LAN75XX_FCT_TX_CTL, FCT_TX_CTL_EN); 91 } 92 93 /* Starts the Receive path */ 94 static void lan75xx_start_rx_path(struct usb_device *udev) 95 { 96 /* Enable Rx at MAC */ 97 lan7x_write_reg(udev, MAC_RX, 98 LAN7X_MAC_RX_MAX_SIZE_DEFAULT | 99 MAC_RX_FCS_STRIP | MAC_RX_RXEN); 100 101 /* Enable Rx at SCSRs */ 102 lan7x_write_reg(udev, LAN75XX_FCT_RX_CTL, FCT_RX_CTL_EN); 103 } 104 105 static int lan75xx_basic_reset(struct usb_device *udev, 106 struct ueth_data *dev, 107 struct lan7x_private *priv) 108 { 109 int ret; 110 u32 val; 111 112 ret = lan7x_basic_reset(udev, dev); 113 if (ret) 114 return ret; 115 116 /* Keep the chip ID */ 117 ret = lan7x_read_reg(udev, ID_REV, &val); 118 if (ret) 119 return ret; 120 debug("LAN75xx ID_REV = 0x%08x\n", val); 121 122 priv->chipid = (val & ID_REV_CHIP_ID_MASK) >> 16; 123 124 /* Respond to the IN token with a NAK */ 125 ret = lan7x_read_reg(udev, HW_CFG, &val); 126 if (ret) 127 return ret; 128 val |= LAN75XX_HW_CFG_BIR; 129 return lan7x_write_reg(udev, HW_CFG, val); 130 } 131 132 int lan75xx_write_hwaddr(struct udevice *dev) 133 { 134 struct usb_device *udev = dev_get_parent_priv(dev); 135 struct eth_pdata *pdata = dev_get_platdata(dev); 136 unsigned char *enetaddr = pdata->enetaddr; 137 u32 addr_lo = get_unaligned_le32(&enetaddr[0]); 138 u32 addr_hi = (u32)get_unaligned_le16(&enetaddr[4]); 139 int ret; 140 141 /* set hardware address */ 142 ret = lan7x_write_reg(udev, RX_ADDRL, addr_lo); 143 if (ret) 144 return ret; 145 146 ret = lan7x_write_reg(udev, RX_ADDRH, addr_hi); 147 if (ret) 148 return ret; 149 150 ret = lan7x_write_reg(udev, LAN75XX_ADDR_FILTX + 4, addr_lo); 151 if (ret) 152 return ret; 153 154 addr_hi |= LAN75XX_ADDR_FILTX_FB_VALID; 155 ret = lan7x_write_reg(udev, LAN75XX_ADDR_FILTX, addr_hi); 156 if (ret) 157 return ret; 158 159 debug("MAC addr %pM written\n", enetaddr); 160 161 return 0; 162 } 163 164 static int lan75xx_eth_start(struct udevice *dev) 165 { 166 struct usb_device *udev = dev_get_parent_priv(dev); 167 struct lan7x_private *priv = dev_get_priv(dev); 168 struct ueth_data *ueth = &priv->ueth; 169 int ret; 170 u32 write_buf; 171 172 /* Reset and read Mac addr were done in probe() */ 173 ret = lan75xx_write_hwaddr(dev); 174 if (ret) 175 return ret; 176 177 ret = lan7x_write_reg(udev, INT_STS, 0xFFFFFFFF); 178 if (ret) 179 return ret; 180 181 ret = lan7x_write_reg(udev, LAN75XX_BURST_CAP, 0); 182 if (ret) 183 return ret; 184 185 ret = lan7x_write_reg(udev, LAN75XX_BULK_IN_DLY, DEFAULT_BULK_IN_DELAY); 186 if (ret) 187 return ret; 188 189 /* set FIFO sizes */ 190 write_buf = (MAX_RX_FIFO_SIZE - 512) / 512; 191 ret = lan7x_write_reg(udev, LAN75XX_FCT_RX_FIFO_END, write_buf); 192 if (ret) 193 return ret; 194 195 write_buf = (MAX_TX_FIFO_SIZE - 512) / 512; 196 ret = lan7x_write_reg(udev, LAN75XX_FCT_TX_FIFO_END, write_buf); 197 if (ret) 198 return ret; 199 200 /* Init Tx */ 201 ret = lan7x_write_reg(udev, FLOW, 0); 202 if (ret) 203 return ret; 204 205 /* Init Rx. Set Vlan, keep default for VLAN on 75xx */ 206 ret = lan75xx_set_receive_filter(udev); 207 if (ret) 208 return ret; 209 210 /* phy workaround for gig link */ 211 ret = lan75xx_phy_gig_workaround(udev, ueth); 212 if (ret) 213 return ret; 214 215 /* Init PHY, autonego, and link */ 216 ret = lan7x_eth_phylib_connect(dev, &priv->ueth); 217 if (ret) 218 return ret; 219 ret = lan7x_eth_phylib_config_start(dev); 220 if (ret) 221 return ret; 222 223 /* 224 * MAC_CR has to be set after PHY init. 225 * MAC will auto detect the PHY speed. 226 */ 227 ret = lan7x_read_reg(udev, MAC_CR, &write_buf); 228 if (ret) 229 return ret; 230 write_buf |= MAC_CR_AUTO_DUPLEX | MAC_CR_AUTO_SPEED | MAC_CR_ADP; 231 ret = lan7x_write_reg(udev, MAC_CR, write_buf); 232 if (ret) 233 return ret; 234 235 lan75xx_start_tx_path(udev); 236 lan75xx_start_rx_path(udev); 237 238 return lan75xx_update_flowcontrol(udev, ueth); 239 } 240 241 int lan75xx_read_rom_hwaddr(struct udevice *dev) 242 { 243 struct usb_device *udev = dev_get_parent_priv(dev); 244 struct eth_pdata *pdata = dev_get_platdata(dev); 245 int ret; 246 247 /* 248 * Refer to the doc/README.enetaddr and doc/README.usb for 249 * the U-Boot MAC address policy 250 */ 251 ret = lan7x_read_eeprom_mac(pdata->enetaddr, udev); 252 if (ret) 253 memset(pdata->enetaddr, 0, 6); 254 255 return 0; 256 } 257 258 static int lan75xx_eth_probe(struct udevice *dev) 259 { 260 struct usb_device *udev = dev_get_parent_priv(dev); 261 struct lan7x_private *priv = dev_get_priv(dev); 262 struct ueth_data *ueth = &priv->ueth; 263 struct eth_pdata *pdata = dev_get_platdata(dev); 264 int ret; 265 266 /* Do a reset in order to get the MAC address from HW */ 267 if (lan75xx_basic_reset(udev, ueth, priv)) 268 return 0; 269 270 /* Get the MAC address */ 271 /* 272 * We must set the eth->enetaddr from HW because the upper layer 273 * will force to use the environmental var (usbethaddr) or random if 274 * there is no valid MAC address in eth->enetaddr. 275 * 276 * Refer to the doc/README.enetaddr and doc/README.usb for 277 * the U-Boot MAC address policy 278 */ 279 lan7x_read_eeprom_mac(pdata->enetaddr, udev); 280 /* Do not return 0 for not finding MAC addr in HW */ 281 282 ret = usb_ether_register(dev, ueth, RX_URB_SIZE); 283 if (ret) 284 return ret; 285 286 /* Register phylib */ 287 return lan7x_phylib_register(dev); 288 } 289 290 static const struct eth_ops lan75xx_eth_ops = { 291 .start = lan75xx_eth_start, 292 .send = lan7x_eth_send, 293 .recv = lan7x_eth_recv, 294 .free_pkt = lan7x_free_pkt, 295 .stop = lan7x_eth_stop, 296 .write_hwaddr = lan75xx_write_hwaddr, 297 .read_rom_hwaddr = lan75xx_read_rom_hwaddr, 298 }; 299 300 U_BOOT_DRIVER(lan75xx_eth) = { 301 .name = "lan75xx_eth", 302 .id = UCLASS_ETH, 303 .probe = lan75xx_eth_probe, 304 .remove = lan7x_eth_remove, 305 .ops = &lan75xx_eth_ops, 306 .priv_auto_alloc_size = sizeof(struct lan7x_private), 307 .platdata_auto_alloc_size = sizeof(struct eth_pdata), 308 }; 309 310 static const struct usb_device_id lan75xx_eth_id_table[] = { 311 { USB_DEVICE(0x0424, 0x7500) }, /* LAN7500 USB Ethernet */ 312 { } /* Terminating entry */ 313 }; 314 315 U_BOOT_USB_DEVICE(lan75xx_eth, lan75xx_eth_id_table); 316