xref: /openbmc/u-boot/drivers/usb/eth/lan7x.c (revision a3b36c84)
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 <malloc.h>
9 #include <miiphy.h>
10 #include <memalign.h>
11 #include <usb.h>
12 #include <linux/ethtool.h>
13 #include <linux/mii.h>
14 #include "usb_ether.h"
15 #include "lan7x.h"
16 
17 /*
18  * Lan7x infrastructure commands
19  */
20 int lan7x_write_reg(struct usb_device *udev, u32 index, u32 data)
21 {
22 	int len;
23 	ALLOC_CACHE_ALIGN_BUFFER(u32, tmpbuf, 1);
24 
25 	cpu_to_le32s(&data);
26 	tmpbuf[0] = data;
27 
28 	len = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
29 			      USB_VENDOR_REQUEST_WRITE_REGISTER,
30 			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
31 			      0, index, tmpbuf, sizeof(data),
32 			      USB_CTRL_SET_TIMEOUT_MS);
33 	if (len != sizeof(data)) {
34 		debug("%s failed: index=%d, data=%d, len=%d",
35 		      __func__, index, data, len);
36 		return -EIO;
37 	}
38 	return 0;
39 }
40 
41 int lan7x_read_reg(struct usb_device *udev, u32 index, u32 *data)
42 {
43 	int len;
44 	ALLOC_CACHE_ALIGN_BUFFER(u32, tmpbuf, 1);
45 
46 	len = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
47 			      USB_VENDOR_REQUEST_READ_REGISTER,
48 			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
49 			      0, index, tmpbuf, sizeof(*data),
50 			      USB_CTRL_GET_TIMEOUT_MS);
51 	*data = tmpbuf[0];
52 	if (len != sizeof(*data)) {
53 		debug("%s failed: index=%d, len=%d", __func__, index, len);
54 		return -EIO;
55 	}
56 
57 	le32_to_cpus(data);
58 	return 0;
59 }
60 
61 static int lan7x_phy_wait_not_busy(struct usb_device *udev)
62 {
63 	return lan7x_wait_for_bit(udev, __func__,
64 				  MII_ACC, MII_ACC_MII_BUSY,
65 				  false, 100, 0);
66 }
67 
68 int lan7x_mdio_read(struct usb_device *udev, int phy_id, int idx)
69 {
70 	u32 val, addr;
71 
72 	/* confirm MII not busy */
73 	if (lan7x_phy_wait_not_busy(udev)) {
74 		debug("MII is busy in %s\n", __func__);
75 		return -ETIMEDOUT;
76 	}
77 
78 	/* set the address, index & direction (read from PHY) */
79 	addr = (phy_id << 11) | (idx << 6) |
80 		MII_ACC_MII_READ | MII_ACC_MII_BUSY;
81 	lan7x_write_reg(udev, MII_ACC, addr);
82 
83 	if (lan7x_phy_wait_not_busy(udev)) {
84 		debug("Timed out reading MII reg %02X\n", idx);
85 		return -ETIMEDOUT;
86 	}
87 
88 	lan7x_read_reg(udev, MII_DATA, &val);
89 
90 	return val & 0xFFFF;
91 }
92 
93 void lan7x_mdio_write(struct usb_device *udev, int phy_id, int idx, int regval)
94 {
95 	u32 addr;
96 
97 	/* confirm MII not busy */
98 	if (lan7x_phy_wait_not_busy(udev)) {
99 		debug("MII is busy in %s\n", __func__);
100 		return;
101 	}
102 
103 	lan7x_write_reg(udev, MII_DATA, regval);
104 
105 	/* set the address, index & direction (write to PHY) */
106 	addr = (phy_id << 11) | (idx << 6) |
107 		MII_ACC_MII_WRITE | MII_ACC_MII_BUSY;
108 	lan7x_write_reg(udev, MII_ACC, addr);
109 
110 	if (lan7x_phy_wait_not_busy(udev))
111 		debug("Timed out writing MII reg %02X\n", idx);
112 }
113 
114 /*
115  * Lan7x phylib wrappers
116  */
117 static int lan7x_phylib_mdio_read(struct mii_dev *bus,
118 				  int addr, int devad, int reg)
119 {
120 	struct usb_device *udev = dev_get_parent_priv(bus->priv);
121 
122 	return lan7x_mdio_read(udev, addr, reg);
123 }
124 
125 static int lan7x_phylib_mdio_write(struct mii_dev *bus,
126 				   int addr, int devad, int reg, u16 val)
127 {
128 	struct usb_device *udev = dev_get_parent_priv(bus->priv);
129 
130 	lan7x_mdio_write(udev, addr, reg, (int)val);
131 
132 	return 0;
133 }
134 
135 /*
136  * Lan7x eeprom functions
137  */
138 static int lan7x_eeprom_confirm_not_busy(struct usb_device *udev)
139 {
140 	return lan7x_wait_for_bit(udev, __func__,
141 				  E2P_CMD, E2P_CMD_EPC_BUSY,
142 				  false, 100, 0);
143 }
144 
145 static int lan7x_wait_eeprom(struct usb_device *udev)
146 {
147 	return lan7x_wait_for_bit(udev, __func__,
148 				  E2P_CMD,
149 				  (E2P_CMD_EPC_BUSY | E2P_CMD_EPC_TIMEOUT),
150 				  false, 100, 0);
151 }
152 
153 static int lan7x_read_eeprom(struct usb_device *udev,
154 			     u32 offset, u32 length, u8 *data)
155 {
156 	u32 val;
157 	int i, ret;
158 
159 	ret = lan7x_eeprom_confirm_not_busy(udev);
160 	if (ret)
161 		return ret;
162 
163 	for (i = 0; i < length; i++) {
164 		val = E2P_CMD_EPC_BUSY | E2P_CMD_EPC_CMD_READ |
165 			(offset & E2P_CMD_EPC_ADDR_MASK);
166 		lan7x_write_reg(udev, E2P_CMD, val);
167 
168 		ret = lan7x_wait_eeprom(udev);
169 		if (ret)
170 			return ret;
171 
172 		lan7x_read_reg(udev, E2P_DATA, &val);
173 		data[i] = val & 0xFF;
174 		offset++;
175 	}
176 	return ret;
177 }
178 
179 /*
180  * Lan7x phylib functions
181  */
182 int lan7x_phylib_register(struct udevice *udev)
183 {
184 	struct usb_device *usbdev = dev_get_parent_priv(udev);
185 	struct lan7x_private *priv = dev_get_priv(udev);
186 	int ret;
187 
188 	priv->mdiobus = mdio_alloc();
189 	if (!priv->mdiobus) {
190 		printf("mdio_alloc failed\n");
191 		return -ENOMEM;
192 	}
193 	priv->mdiobus->read = lan7x_phylib_mdio_read;
194 	priv->mdiobus->write = lan7x_phylib_mdio_write;
195 	sprintf(priv->mdiobus->name,
196 		"lan7x_mdiobus-d%hu-p%hu", usbdev->devnum, usbdev->portnr);
197 	priv->mdiobus->priv = (void *)udev;
198 
199 	ret = mdio_register(priv->mdiobus);
200 	if (ret) {
201 		printf("mdio_register failed\n");
202 		free(priv->mdiobus);
203 		return -ENOMEM;
204 	}
205 
206 	return 0;
207 }
208 
209 int lan7x_eth_phylib_connect(struct udevice *udev, struct ueth_data *dev)
210 {
211 	struct lan7x_private *priv = dev_get_priv(udev);
212 
213 	priv->phydev = phy_connect(priv->mdiobus, dev->phy_id,
214 			     udev, PHY_INTERFACE_MODE_MII);
215 
216 	if (!priv->phydev) {
217 		printf("phy_connect failed\n");
218 		return -ENODEV;
219 	}
220 	return 0;
221 }
222 
223 int lan7x_eth_phylib_config_start(struct udevice *udev)
224 {
225 	struct lan7x_private *priv = dev_get_priv(udev);
226 	int ret;
227 
228 	/* configure supported modes */
229 	priv->phydev->supported = PHY_BASIC_FEATURES |
230 				  SUPPORTED_1000baseT_Full |
231 				  SUPPORTED_Pause |
232 				  SUPPORTED_Asym_Pause;
233 
234 	priv->phydev->advertising = ADVERTISED_10baseT_Half |
235 				    ADVERTISED_10baseT_Full |
236 				    ADVERTISED_100baseT_Half |
237 				    ADVERTISED_100baseT_Full |
238 				    ADVERTISED_1000baseT_Full |
239 				    ADVERTISED_Pause |
240 				    ADVERTISED_Asym_Pause |
241 				    ADVERTISED_Autoneg;
242 
243 	priv->phydev->autoneg = AUTONEG_ENABLE;
244 
245 	ret = genphy_config_aneg(priv->phydev);
246 	if (ret) {
247 		printf("genphy_config_aneg failed\n");
248 		return ret;
249 	}
250 	ret = phy_startup(priv->phydev);
251 	if (ret) {
252 		printf("phy_startup failed\n");
253 		return ret;
254 	}
255 
256 	debug("** %s() speed %i duplex %i adv %X supp %X\n", __func__,
257 	      priv->phydev->speed, priv->phydev->duplex,
258 	      priv->phydev->advertising, priv->phydev->supported);
259 
260 	return 0;
261 }
262 
263 int lan7x_update_flowcontrol(struct usb_device *udev,
264 			     struct ueth_data *dev,
265 			     uint32_t *flow, uint32_t *fct_flow)
266 {
267 	uint32_t lcladv, rmtadv;
268 	u8 cap = 0;
269 	struct lan7x_private *priv = dev_get_priv(udev->dev);
270 
271 	debug("** %s()\n", __func__);
272 	debug("** %s() priv->phydev->speed %i duplex %i\n", __func__,
273 	      priv->phydev->speed, priv->phydev->duplex);
274 
275 	if (priv->phydev->duplex == DUPLEX_FULL) {
276 		lcladv = lan7x_mdio_read(udev, dev->phy_id, MII_ADVERTISE);
277 		rmtadv = lan7x_mdio_read(udev, dev->phy_id, MII_LPA);
278 		cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv);
279 
280 		debug("TX Flow ");
281 		if (cap & FLOW_CTRL_TX) {
282 			*flow = (FLOW_CR_TX_FCEN | 0xFFFF);
283 			/* set fct_flow thresholds to 20% and 80% */
284 			*fct_flow = ((MAX_RX_FIFO_SIZE * 2) / (10 * 512))
285 					& 0x7FUL;
286 			*fct_flow <<= 8UL;
287 			*fct_flow |= ((MAX_RX_FIFO_SIZE * 8) / (10 * 512))
288 					& 0x7FUL;
289 			debug("EN ");
290 		} else {
291 			debug("DIS ");
292 		}
293 		debug("RX Flow ");
294 		if (cap & FLOW_CTRL_RX) {
295 			*flow |= FLOW_CR_RX_FCEN;
296 			debug("EN");
297 		} else {
298 			debug("DIS");
299 		}
300 	}
301 	debug("\n");
302 	return 0;
303 }
304 
305 int lan7x_read_eeprom_mac(unsigned char *enetaddr, struct usb_device *udev)
306 {
307 	int ret;
308 
309 	memset(enetaddr, 0, 6);
310 
311 	ret = lan7x_read_eeprom(udev, 0, 1, enetaddr);
312 
313 	if ((ret == 0) && (enetaddr[0] == EEPROM_INDICATOR)) {
314 		ret = lan7x_read_eeprom(udev,
315 					EEPROM_MAC_OFFSET, ETH_ALEN,
316 					enetaddr);
317 		if ((ret == 0) && is_valid_ethaddr(enetaddr)) {
318 			/* eeprom values are valid so use them */
319 			debug("MAC address read from EEPROM %pM\n",
320 			      enetaddr);
321 			return 0;
322 		}
323 	}
324 	debug("MAC address read from EEPROM invalid %pM\n", enetaddr);
325 
326 	memset(enetaddr, 0, 6);
327 	return -EINVAL;
328 }
329 
330 int lan7x_pmt_phy_reset(struct usb_device *udev,
331 			struct ueth_data *dev)
332 {
333 	int ret;
334 	u32 data;
335 
336 	ret = lan7x_read_reg(udev, PMT_CTL, &data);
337 	if (ret)
338 		return ret;
339 	ret = lan7x_write_reg(udev, PMT_CTL, data | PMT_CTL_PHY_RST);
340 	if (ret)
341 		return ret;
342 
343 	/* for LAN7x, we need to check PMT_CTL_READY asserted */
344 	ret = lan7x_wait_for_bit(udev, "PMT_CTL_PHY_RST",
345 				 PMT_CTL, PMT_CTL_PHY_RST,
346 				 false, 1000, 0); /* could take over 125mS */
347 	if (ret)
348 		return ret;
349 
350 	return lan7x_wait_for_bit(udev, "PMT_CTL_READY",
351 				 PMT_CTL, PMT_CTL_READY,
352 				 true, 1000, 0);
353 }
354 
355 int lan7x_basic_reset(struct usb_device *udev,
356 		      struct ueth_data *dev)
357 {
358 	int ret;
359 
360 	dev->phy_id = LAN7X_INTERNAL_PHY_ID; /* fixed phy id */
361 
362 	ret = lan7x_write_reg(udev, HW_CFG, HW_CFG_LRST);
363 	if (ret)
364 		return ret;
365 
366 	ret = lan7x_wait_for_bit(udev, "HW_CFG_LRST",
367 				 HW_CFG, HW_CFG_LRST,
368 				 false, 1000, 0);
369 	if (ret)
370 		return ret;
371 
372 	debug("USB devnum %d portnr %d\n", udev->devnum, udev->portnr);
373 
374 	return lan7x_pmt_phy_reset(udev, dev);
375 }
376 
377 void lan7x_eth_stop(struct udevice *dev)
378 {
379 	debug("** %s()\n", __func__);
380 }
381 
382 int lan7x_eth_send(struct udevice *dev, void *packet, int length)
383 {
384 	struct lan7x_private *priv = dev_get_priv(dev);
385 	struct ueth_data *ueth = &priv->ueth;
386 	int err;
387 	int actual_len;
388 	u32 tx_cmd_a;
389 	u32 tx_cmd_b;
390 	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, msg,
391 				 PKTSIZE + sizeof(tx_cmd_a) + sizeof(tx_cmd_b));
392 
393 	debug("** %s(), len %d, buf %#x\n", __func__, length,
394 	      (unsigned int)(ulong) msg);
395 	if (length > PKTSIZE)
396 		return -ENOSPC;
397 
398 	/* LAN7x disable all TX offload features for u-boot */
399 	tx_cmd_a = (u32) (length & TX_CMD_A_LEN_MASK) | TX_CMD_A_FCS;
400 	tx_cmd_b = 0;
401 	cpu_to_le32s(&tx_cmd_a);
402 	cpu_to_le32s(&tx_cmd_b);
403 
404 	/* prepend cmd_a and cmd_b */
405 	memcpy(msg, &tx_cmd_a, sizeof(tx_cmd_a));
406 	memcpy(msg + sizeof(tx_cmd_a), &tx_cmd_b, sizeof(tx_cmd_b));
407 	memcpy(msg + sizeof(tx_cmd_a) + sizeof(tx_cmd_b), (void *)packet,
408 	       length);
409 	err = usb_bulk_msg(ueth->pusb_dev,
410 			   usb_sndbulkpipe(ueth->pusb_dev, ueth->ep_out),
411 			   (void *)msg,
412 			   length + sizeof(tx_cmd_a) +
413 			   sizeof(tx_cmd_b),
414 			   &actual_len, USB_BULK_SEND_TIMEOUT_MS);
415 	debug("Tx: len = %u, actual = %u, err = %d\n",
416 	      (unsigned int)(length + sizeof(tx_cmd_a) + sizeof(tx_cmd_b)),
417 	      (unsigned int)actual_len, err);
418 
419 	return err;
420 }
421 
422 int lan7x_eth_recv(struct udevice *dev, int flags, uchar **packetp)
423 {
424 	struct lan7x_private *priv = dev_get_priv(dev);
425 	struct ueth_data *ueth = &priv->ueth;
426 	uint8_t *ptr;
427 	int ret, len;
428 	u32 packet_len = 0;
429 	u32 rx_cmd_a = 0;
430 
431 	len = usb_ether_get_rx_bytes(ueth, &ptr);
432 	debug("%s: first try, len=%d\n", __func__, len);
433 	if (!len) {
434 		if (!(flags & ETH_RECV_CHECK_DEVICE))
435 			return -EAGAIN;
436 		ret = usb_ether_receive(ueth, RX_URB_SIZE);
437 		if (ret == -EAGAIN)
438 			return ret;
439 
440 		len = usb_ether_get_rx_bytes(ueth, &ptr);
441 		debug("%s: second try, len=%d\n", __func__, len);
442 	}
443 
444 	/*
445 	 * 1st 4 bytes contain the length of the actual data plus error info.
446 	 * Extract data length.
447 	 */
448 	if (len < sizeof(packet_len)) {
449 		debug("Rx: incomplete packet length\n");
450 		goto err;
451 	}
452 	memcpy(&rx_cmd_a, ptr, sizeof(rx_cmd_a));
453 	le32_to_cpus(&rx_cmd_a);
454 	if (rx_cmd_a & RX_CMD_A_RXE) {
455 		debug("Rx: Error header=%#x", rx_cmd_a);
456 		goto err;
457 	}
458 	packet_len = (u16) (rx_cmd_a & RX_CMD_A_LEN_MASK);
459 
460 	if (packet_len > len - sizeof(packet_len)) {
461 		debug("Rx: too large packet: %d\n", packet_len);
462 		goto err;
463 	}
464 
465 	/*
466 	 * For LAN7x, the length in command A does not
467 	 * include command A, B, and C length.
468 	 * So use it as is.
469 	 */
470 
471 	*packetp = ptr + 10;
472 	return packet_len;
473 
474 err:
475 	usb_ether_advance_rxbuf(ueth, -1);
476 	return -EINVAL;
477 }
478 
479 int lan7x_free_pkt(struct udevice *dev, uchar *packet, int packet_len)
480 {
481 	struct lan7x_private *priv = dev_get_priv(dev);
482 
483 	packet_len = ALIGN(packet_len, 4);
484 	usb_ether_advance_rxbuf(&priv->ueth, sizeof(u32) + packet_len);
485 
486 	return 0;
487 }
488 
489 int lan7x_eth_remove(struct udevice *dev)
490 {
491 	struct lan7x_private *priv = dev_get_priv(dev);
492 
493 	debug("** %s()\n", __func__);
494 	free(priv->phydev);
495 	mdio_unregister(priv->mdiobus);
496 	mdio_free(priv->mdiobus);
497 
498 	return 0;
499 }
500