1 /* 2 * Copyright (c) 2011 The Chromium OS Authors. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <errno.h> 10 #include <malloc.h> 11 #include <usb.h> 12 #include <dm/device-internal.h> 13 14 #include "usb_ether.h" 15 16 #ifdef CONFIG_DM_ETH 17 18 #define USB_BULK_RECV_TIMEOUT 500 19 20 int usb_ether_register(struct udevice *dev, struct ueth_data *ueth, int rxsize) 21 { 22 struct usb_device *udev = dev_get_parent_priv(dev); 23 struct usb_interface_descriptor *iface_desc; 24 bool ep_in_found = false, ep_out_found = false; 25 struct usb_interface *iface; 26 const int ifnum = 0; /* Always use interface 0 */ 27 int ret, i; 28 29 iface = &udev->config.if_desc[ifnum]; 30 iface_desc = &udev->config.if_desc[ifnum].desc; 31 32 /* Initialize the ueth_data structure with some useful info */ 33 ueth->ifnum = ifnum; 34 ueth->subclass = iface_desc->bInterfaceSubClass; 35 ueth->protocol = iface_desc->bInterfaceProtocol; 36 37 /* 38 * We are expecting a minimum of 3 endpoints - in, out (bulk), and int. 39 * We will ignore any others. 40 */ 41 for (i = 0; i < iface_desc->bNumEndpoints; i++) { 42 int ep_addr = iface->ep_desc[i].bEndpointAddress; 43 44 /* is it an BULK endpoint? */ 45 if ((iface->ep_desc[i].bmAttributes & 46 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) { 47 if (ep_addr & USB_DIR_IN && !ep_in_found) { 48 ueth->ep_in = ep_addr & 49 USB_ENDPOINT_NUMBER_MASK; 50 ep_in_found = true; 51 } else if (!(ep_addr & USB_DIR_IN) && !ep_out_found) { 52 ueth->ep_out = ep_addr & 53 USB_ENDPOINT_NUMBER_MASK; 54 ep_out_found = true; 55 } 56 } 57 58 /* is it an interrupt endpoint? */ 59 if ((iface->ep_desc[i].bmAttributes & 60 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) { 61 ueth->ep_int = iface->ep_desc[i].bEndpointAddress & 62 USB_ENDPOINT_NUMBER_MASK; 63 ueth->irqinterval = iface->ep_desc[i].bInterval; 64 } 65 } 66 debug("Endpoints In %d Out %d Int %d\n", ueth->ep_in, ueth->ep_out, 67 ueth->ep_int); 68 69 /* Do some basic sanity checks, and bail if we find a problem */ 70 if (!ueth->ep_in || !ueth->ep_out || !ueth->ep_int) { 71 debug("%s: %s: Cannot find endpoints\n", __func__, dev->name); 72 return -ENXIO; 73 } 74 75 ueth->rxsize = rxsize; 76 ueth->rxbuf = memalign(ARCH_DMA_MINALIGN, rxsize); 77 if (!ueth->rxbuf) 78 return -ENOMEM; 79 80 ret = usb_set_interface(udev, iface_desc->bInterfaceNumber, ifnum); 81 if (ret) { 82 debug("%s: %s: Cannot set interface: %d\n", __func__, dev->name, 83 ret); 84 return ret; 85 } 86 ueth->pusb_dev = udev; 87 88 return 0; 89 } 90 91 int usb_ether_deregister(struct ueth_data *ueth) 92 { 93 return 0; 94 } 95 96 int usb_ether_receive(struct ueth_data *ueth, int rxsize) 97 { 98 int actual_len; 99 int ret; 100 101 if (rxsize > ueth->rxsize) 102 return -EINVAL; 103 ret = usb_bulk_msg(ueth->pusb_dev, 104 usb_rcvbulkpipe(ueth->pusb_dev, ueth->ep_in), 105 ueth->rxbuf, rxsize, &actual_len, 106 USB_BULK_RECV_TIMEOUT); 107 debug("Rx: len = %u, actual = %u, err = %d\n", rxsize, actual_len, ret); 108 if (ret) { 109 printf("Rx: failed to receive: %d\n", ret); 110 return ret; 111 } 112 if (actual_len > rxsize) { 113 debug("Rx: received too many bytes %d\n", actual_len); 114 return -ENOSPC; 115 } 116 ueth->rxlen = actual_len; 117 ueth->rxptr = 0; 118 119 return actual_len ? 0 : -EAGAIN; 120 } 121 122 void usb_ether_advance_rxbuf(struct ueth_data *ueth, int num_bytes) 123 { 124 ueth->rxptr += num_bytes; 125 if (num_bytes < 0 || ueth->rxptr >= ueth->rxlen) 126 ueth->rxlen = 0; 127 } 128 129 int usb_ether_get_rx_bytes(struct ueth_data *ueth, uint8_t **ptrp) 130 { 131 if (!ueth->rxlen) 132 return 0; 133 134 *ptrp = &ueth->rxbuf[ueth->rxptr]; 135 136 return ueth->rxlen - ueth->rxptr; 137 } 138 139 #else 140 141 typedef void (*usb_eth_before_probe)(void); 142 typedef int (*usb_eth_probe)(struct usb_device *dev, unsigned int ifnum, 143 struct ueth_data *ss); 144 typedef int (*usb_eth_get_info)(struct usb_device *dev, struct ueth_data *ss, 145 struct eth_device *dev_desc); 146 147 struct usb_eth_prob_dev { 148 usb_eth_before_probe before_probe; /* optional */ 149 usb_eth_probe probe; 150 usb_eth_get_info get_info; 151 }; 152 153 /* driver functions go here, each bracketed by #ifdef CONFIG_USB_ETHER_xxx */ 154 static const struct usb_eth_prob_dev prob_dev[] = { 155 #ifdef CONFIG_USB_ETHER_ASIX 156 { 157 .before_probe = asix_eth_before_probe, 158 .probe = asix_eth_probe, 159 .get_info = asix_eth_get_info, 160 }, 161 #endif 162 #ifdef CONFIG_USB_ETHER_ASIX88179 163 { 164 .before_probe = ax88179_eth_before_probe, 165 .probe = ax88179_eth_probe, 166 .get_info = ax88179_eth_get_info, 167 }, 168 #endif 169 #ifdef CONFIG_USB_ETHER_MCS7830 170 { 171 .before_probe = mcs7830_eth_before_probe, 172 .probe = mcs7830_eth_probe, 173 .get_info = mcs7830_eth_get_info, 174 }, 175 #endif 176 #ifdef CONFIG_USB_ETHER_SMSC95XX 177 { 178 .before_probe = smsc95xx_eth_before_probe, 179 .probe = smsc95xx_eth_probe, 180 .get_info = smsc95xx_eth_get_info, 181 }, 182 #endif 183 #ifdef CONFIG_USB_ETHER_RTL8152 184 { 185 .before_probe = r8152_eth_before_probe, 186 .probe = r8152_eth_probe, 187 .get_info = r8152_eth_get_info, 188 }, 189 #endif 190 { }, /* END */ 191 }; 192 193 static int usb_max_eth_dev; /* number of highest available usb eth device */ 194 static struct ueth_data usb_eth[USB_MAX_ETH_DEV]; 195 196 /******************************************************************************* 197 * tell if current ethernet device is a usb dongle 198 */ 199 int is_eth_dev_on_usb_host(void) 200 { 201 int i; 202 struct eth_device *dev = eth_get_dev(); 203 204 if (dev) { 205 for (i = 0; i < usb_max_eth_dev; i++) 206 if (&usb_eth[i].eth_dev == dev) 207 return 1; 208 } 209 return 0; 210 } 211 212 /* 213 * Given a USB device, ask each driver if it can support it, and attach it 214 * to the first driver that says 'yes' 215 */ 216 static void probe_valid_drivers(struct usb_device *dev) 217 { 218 struct eth_device *eth; 219 int j; 220 221 for (j = 0; prob_dev[j].probe && prob_dev[j].get_info; j++) { 222 if (!prob_dev[j].probe(dev, 0, &usb_eth[usb_max_eth_dev])) 223 continue; 224 /* 225 * ok, it is a supported eth device. Get info and fill it in 226 */ 227 eth = &usb_eth[usb_max_eth_dev].eth_dev; 228 if (prob_dev[j].get_info(dev, 229 &usb_eth[usb_max_eth_dev], 230 eth)) { 231 /* found proper driver */ 232 /* register with networking stack */ 233 usb_max_eth_dev++; 234 235 /* 236 * usb_max_eth_dev must be incremented prior to this 237 * call since eth_current_changed (internally called) 238 * relies on it 239 */ 240 eth_register(eth); 241 if (eth_write_hwaddr(eth, "usbeth", 242 usb_max_eth_dev - 1)) 243 puts("Warning: failed to set MAC address\n"); 244 break; 245 } 246 } 247 } 248 249 /******************************************************************************* 250 * scan the usb and reports device info 251 * to the user if mode = 1 252 * returns current device or -1 if no 253 */ 254 int usb_host_eth_scan(int mode) 255 { 256 int i, old_async; 257 258 if (mode == 1) 259 printf(" scanning usb for ethernet devices... "); 260 261 old_async = usb_disable_asynch(1); /* asynch transfer not allowed */ 262 263 /* unregister a previously detected device */ 264 for (i = 0; i < usb_max_eth_dev; i++) 265 eth_unregister(&usb_eth[i].eth_dev); 266 267 memset(usb_eth, 0, sizeof(usb_eth)); 268 269 for (i = 0; prob_dev[i].probe; i++) { 270 if (prob_dev[i].before_probe) 271 prob_dev[i].before_probe(); 272 } 273 274 usb_max_eth_dev = 0; 275 #ifdef CONFIG_DM_USB 276 /* 277 * TODO: We should add U_BOOT_USB_DEVICE() declarations to each USB 278 * Ethernet driver and then most of this file can be removed. 279 */ 280 struct udevice *bus; 281 struct uclass *uc; 282 int ret; 283 284 ret = uclass_get(UCLASS_USB, &uc); 285 if (ret) 286 return ret; 287 uclass_foreach_dev(bus, uc) { 288 for (i = 0; i < USB_MAX_DEVICE; i++) { 289 struct usb_device *dev; 290 291 dev = usb_get_dev_index(bus, i); /* get device */ 292 debug("i=%d, %s\n", i, dev ? dev->dev->name : "(done)"); 293 if (!dev) 294 break; /* no more devices available */ 295 296 /* 297 * find valid usb_ether driver for this device, 298 * if any 299 */ 300 probe_valid_drivers(dev); 301 302 /* check limit */ 303 if (usb_max_eth_dev == USB_MAX_ETH_DEV) 304 break; 305 } /* for */ 306 } 307 #else 308 for (i = 0; i < USB_MAX_DEVICE; i++) { 309 struct usb_device *dev; 310 311 dev = usb_get_dev_index(i); /* get device */ 312 debug("i=%d\n", i); 313 if (!dev) 314 break; /* no more devices available */ 315 316 /* find valid usb_ether driver for this device, if any */ 317 probe_valid_drivers(dev); 318 319 /* check limit */ 320 if (usb_max_eth_dev == USB_MAX_ETH_DEV) 321 break; 322 } /* for */ 323 #endif 324 if (usb_max_eth_dev == USB_MAX_ETH_DEV) { 325 printf("max USB Ethernet Device reached: %d stopping\n", 326 usb_max_eth_dev); 327 } 328 usb_disable_asynch(old_async); /* restore asynch value */ 329 printf("%d Ethernet Device(s) found\n", usb_max_eth_dev); 330 if (usb_max_eth_dev > 0) 331 return 0; 332 return -1; 333 } 334 #endif 335