These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / drivers / net / dm96xx.c
1 /*
2  * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 #include <string.h>
27 #include <unistd.h>
28 #include <errno.h>
29 #include <ipxe/ethernet.h>
30 #include <ipxe/usb.h>
31 #include <ipxe/usbnet.h>
32 #include "dm96xx.h"
33
34 /** @file
35  *
36  * Davicom DM96xx USB Ethernet driver
37  *
38  */
39
40 /******************************************************************************
41  *
42  * Register operations
43  *
44  ******************************************************************************
45  */
46
47 /**
48  * Reset device
49  *
50  * @v dm96xx            DM96xx device
51  * @ret rc              Return status code
52  */
53 static int dm96xx_reset ( struct dm96xx_device *dm96xx ) {
54         int ncr;
55         int rc;
56
57         /* Reset device */
58         if ( ( rc = dm96xx_write_register ( dm96xx, DM96XX_NCR,
59                                             DM96XX_NCR_RST ) ) != 0 ) {
60                 DBGC ( dm96xx, "DM96XX %p could not reset: %s\n",
61                        dm96xx, strerror ( rc ) );
62                 return rc;
63         }
64
65         /* Wait for reset to complete */
66         udelay ( DM96XX_RESET_DELAY_US );
67
68         /* Check that reset has completed */
69         ncr = dm96xx_read_register ( dm96xx, DM96XX_NCR );
70         if ( ncr < 0 ) {
71                 rc = ncr;
72                 DBGC ( dm96xx, "DM96XX %p failed to reset: %s\n",
73                        dm96xx, strerror ( rc ) );
74                 return rc;
75         }
76         if ( ncr & DM96XX_NCR_RST ) {
77                 DBGC ( dm96xx, "DM96XX %p failed to reset (NCR=%#02x)\n",
78                        dm96xx, ncr );
79                 return -EIO;
80         }
81
82         return 0;
83 }
84
85 /**
86  * Read MAC address
87  *
88  * @v dm96xx            DM96xx device
89  * @v mac               MAC address to fill in
90  * @ret rc              Return status code
91  */
92 static int dm96xx_read_mac ( struct dm96xx_device *dm96xx, uint8_t *mac ) {
93         int rc;
94
95         /* Read MAC address */
96         if ( ( rc = dm96xx_read_registers ( dm96xx, DM96XX_PAR, mac,
97                                             ETH_ALEN ) ) != 0 ) {
98                 DBGC ( dm96xx, "DM96XX %p could not read MAC address: %s\n",
99                        dm96xx, strerror ( rc ) );
100                 return rc;
101         }
102
103         return 0;
104 }
105
106 /**
107  * Write MAC address
108  *
109  * @v dm96xx            DM96xx device
110  * @v mac               MAC address
111  * @ret rc              Return status code
112  */
113 static int dm96xx_write_mac ( struct dm96xx_device *dm96xx, uint8_t *mac ) {
114         int rc;
115
116         /* Write MAC address */
117         if ( ( rc = dm96xx_write_registers ( dm96xx, DM96XX_PAR, mac,
118                                              ETH_ALEN ) ) != 0 ) {
119                 DBGC ( dm96xx, "DM96XX %p could not write MAC address: %s\n",
120                        dm96xx, strerror ( rc ) );
121                 return rc;
122         }
123
124         return 0;
125 }
126
127 /**
128  * Update link status based on network status register
129  *
130  * @v dm96xx            DM96xx device
131  * @v nsr               Network status register
132  */
133 static void dm96xx_link_nsr ( struct dm96xx_device *dm96xx, unsigned int nsr ) {
134         struct net_device *netdev = dm96xx->netdev;
135
136         if ( nsr & DM96XX_NSR_LINKST ) {
137                 if ( ! netdev_link_ok ( netdev ) )
138                         netdev_link_up ( netdev );
139         } else {
140                 if ( netdev_link_ok ( netdev ) )
141                         netdev_link_down ( netdev );
142         }
143 }
144
145 /**
146  * Get link status
147  *
148  * @v dm96xx            DM96xx device
149  * @ret rc              Return status code
150  */
151 static int dm96xx_check_link ( struct dm96xx_device *dm96xx ) {
152         int nsr;
153         int rc;
154
155         /* Read network status register */
156         nsr = dm96xx_read_register ( dm96xx, DM96XX_NSR );
157         if ( nsr < 0 ) {
158                 rc = nsr;
159                 DBGC ( dm96xx, "DM96XX %p could not read network status: %s\n",
160                        dm96xx, strerror ( rc ) );
161                 return rc;
162         }
163
164         /* Update link status */
165         dm96xx_link_nsr ( dm96xx, nsr );
166
167         return 0;
168 }
169
170 /**
171  * Set DM9601-compatible RX header mode
172  *
173  * @v dm96xx            DM96xx device
174  * @ret rc              Return status code
175  */
176 static int dm96xx_rx_mode ( struct dm96xx_device *dm96xx ) {
177         int chipr;
178         int mode_ctl;
179         int rc;
180
181         /* Get chip revision */
182         chipr = dm96xx_read_register ( dm96xx, DM96XX_CHIPR );
183         if ( chipr < 0 ) {
184                 rc = chipr;
185                 DBGC ( dm96xx, "DM96XX %p could not read chip revision: %s\n",
186                        dm96xx, strerror ( rc ) );
187                 return rc;
188         }
189
190         /* Do nothing if device is a DM9601 anyway */
191         if ( chipr == DM96XX_CHIPR_9601 )
192                 return 0;
193
194         /* Read current mode control */
195         mode_ctl = dm96xx_read_register ( dm96xx, DM96XX_MODE_CTL );
196         if ( mode_ctl < 0 ) {
197                 rc = mode_ctl;
198                 DBGC ( dm96xx, "DM96XX %p could not read mode control: %s\n",
199                        dm96xx, strerror ( rc ) );
200                 return rc;
201         }
202
203         /* Write mode control */
204         mode_ctl &= ~DM96XX_MODE_CTL_MODE;
205         if ( ( rc = dm96xx_write_register ( dm96xx, DM96XX_MODE_CTL,
206                                             mode_ctl ) ) != 0 ) {
207                 DBGC ( dm96xx, "DM96XX %p could not write mode control: %s\n",
208                        dm96xx, strerror ( rc ) );
209                 return rc;
210         }
211
212         return 0;
213 }
214
215 /******************************************************************************
216  *
217  * Endpoint operations
218  *
219  ******************************************************************************
220  */
221
222 /**
223  * Complete interrupt transfer
224  *
225  * @v ep                USB endpoint
226  * @v iobuf             I/O buffer
227  * @v rc                Completion status code
228  */
229 static void dm96xx_intr_complete ( struct usb_endpoint *ep,
230                                    struct io_buffer *iobuf, int rc ) {
231         struct dm96xx_device *dm96xx = container_of ( ep, struct dm96xx_device,
232                                                       usbnet.intr );
233         struct net_device *netdev = dm96xx->netdev;
234         struct dm96xx_interrupt *intr;
235         size_t len = iob_len ( iobuf );
236
237         /* Ignore packets cancelled when the endpoint closes */
238         if ( ! ep->open )
239                 goto done;
240
241         /* Record USB errors against the network device */
242         if ( rc != 0 ) {
243                 DBGC ( dm96xx, "DM96XX %p interrupt failed: %s\n",
244                        dm96xx, strerror ( rc ) );
245                 DBGC_HDA ( dm96xx, 0, iobuf->data, iob_len ( iobuf ) );
246                 netdev_rx_err ( netdev, NULL, rc );
247                 goto done;
248         }
249
250         /* Extract message header */
251         if ( len < sizeof ( *intr ) ) {
252                 DBGC ( dm96xx, "DM96XX %p underlength interrupt:\n", dm96xx );
253                 DBGC_HDA ( dm96xx, 0, iobuf->data, iob_len ( iobuf ) );
254                 netdev_rx_err ( netdev, NULL, -EINVAL );
255                 goto done;
256         }
257         intr = iobuf->data;
258
259         /* Update link status */
260         dm96xx_link_nsr ( dm96xx, intr->nsr );
261
262  done:
263         /* Free I/O buffer */
264         free_iob ( iobuf );
265 }
266
267 /** Interrupt endpoint operations */
268 static struct usb_endpoint_driver_operations dm96xx_intr_operations = {
269         .complete = dm96xx_intr_complete,
270 };
271
272 /**
273  * Complete bulk IN transfer
274  *
275  * @v ep                USB endpoint
276  * @v iobuf             I/O buffer
277  * @v rc                Completion status code
278  */
279 static void dm96xx_in_complete ( struct usb_endpoint *ep,
280                                  struct io_buffer *iobuf, int rc ) {
281         struct dm96xx_device *dm96xx = container_of ( ep, struct dm96xx_device,
282                                                       usbnet.in );
283         struct net_device *netdev = dm96xx->netdev;
284         struct dm96xx_rx_header *header;
285
286         /* Ignore packets cancelled when the endpoint closes */
287         if ( ! ep->open ) {
288                 free_iob ( iobuf );
289                 return;
290         }
291
292         /* Record USB errors against the network device */
293         if ( rc != 0 ) {
294                 DBGC ( dm96xx, "DM96XX %p bulk IN failed: %s\n",
295                        dm96xx, strerror ( rc ) );
296                 goto err;
297         }
298
299         /* Sanity check */
300         if ( iob_len ( iobuf ) < ( sizeof ( *header ) + 4 /* CRC */ ) ) {
301                 DBGC ( dm96xx, "DM96XX %p underlength bulk IN\n", dm96xx );
302                 DBGC_HDA ( dm96xx, 0, iobuf->data, iob_len ( iobuf ) );
303                 rc = -EINVAL;
304                 goto err;
305         }
306
307         /* Strip header and CRC */
308         header = iobuf->data;
309         iob_pull ( iobuf, sizeof ( *header ) );
310         iob_unput ( iobuf, 4 /* CRC */ );
311
312         /* Check status */
313         if ( header->rsr & ~DM96XX_RSR_MF ) {
314                 DBGC ( dm96xx, "DM96XX %p receive error %02x:\n",
315                        dm96xx, header->rsr );
316                 DBGC_HDA ( dm96xx, 0, iobuf->data, iob_len ( iobuf ) );
317                 rc = -EIO;
318                 goto err;
319         }
320
321         /* Hand off to network stack */
322         netdev_rx ( netdev, iob_disown ( iobuf ) );
323         return;
324
325  err:
326         /* Hand off to network stack */
327         netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
328 }
329
330 /** Bulk IN endpoint operations */
331 static struct usb_endpoint_driver_operations dm96xx_in_operations = {
332         .complete = dm96xx_in_complete,
333 };
334
335 /**
336  * Transmit packet
337  *
338  * @v dm96xx            DM96xx device
339  * @v iobuf             I/O buffer
340  * @ret rc              Return status code
341  */
342 static int dm96xx_out_transmit ( struct dm96xx_device *dm96xx,
343                                  struct io_buffer *iobuf ) {
344         struct dm96xx_tx_header *header;
345         size_t len = iob_len ( iobuf );
346         int rc;
347
348         /* Prepend header */
349         if ( ( rc = iob_ensure_headroom ( iobuf, sizeof ( *header ) ) ) != 0 )
350                 return rc;
351         header = iob_push ( iobuf, sizeof ( *header ) );
352         header->len = cpu_to_le16 ( len );
353
354         /* Enqueue I/O buffer */
355         if ( ( rc = usb_stream ( &dm96xx->usbnet.out, iobuf, 0 ) ) != 0 )
356                 return rc;
357
358         return 0;
359 }
360
361 /**
362  * Complete bulk OUT transfer
363  *
364  * @v ep                USB endpoint
365  * @v iobuf             I/O buffer
366  * @v rc                Completion status code
367  */
368 static void dm96xx_out_complete ( struct usb_endpoint *ep,
369                                   struct io_buffer *iobuf, int rc ) {
370         struct dm96xx_device *dm96xx = container_of ( ep, struct dm96xx_device,
371                                                       usbnet.out );
372         struct net_device *netdev = dm96xx->netdev;
373
374         /* Report TX completion */
375         netdev_tx_complete_err ( netdev, iobuf, rc );
376 }
377
378 /** Bulk OUT endpoint operations */
379 static struct usb_endpoint_driver_operations dm96xx_out_operations = {
380         .complete = dm96xx_out_complete,
381 };
382
383 /******************************************************************************
384  *
385  * Network device interface
386  *
387  ******************************************************************************
388  */
389
390 /**
391  * Open network device
392  *
393  * @v netdev            Network device
394  * @ret rc              Return status code
395  */
396 static int dm96xx_open ( struct net_device *netdev ) {
397         struct dm96xx_device *dm96xx = netdev->priv;
398         unsigned int rcr;
399         int rc;
400
401         /* Set DM9601-compatible RX header mode */
402         if ( ( rc = dm96xx_rx_mode ( dm96xx ) ) != 0 )
403                 goto err_rx_mode;
404
405         /* Write MAC address */
406         if ( ( rc = dm96xx_write_mac ( dm96xx, netdev->ll_addr ) ) != 0 )
407                 goto err_write_mac;
408
409         /* Open USB network device */
410         if ( ( rc = usbnet_open ( &dm96xx->usbnet ) ) != 0 ) {
411                 DBGC ( dm96xx, "DM96XX %p could not open: %s\n",
412                        dm96xx, strerror ( rc ) );
413                 goto err_open;
414         }
415
416         /* Set receive filters */
417         rcr = ( DM96XX_RCR_ALL | DM96XX_RCR_RUNT | DM96XX_RCR_PRMSC |
418                 DM96XX_RCR_RXEN );
419         if ( ( rc = dm96xx_write_register ( dm96xx, DM96XX_RCR, rcr ) ) != 0 ) {
420                 DBGC ( dm96xx, "DM96XX %p could not write receive filters: "
421                        "%s\n", dm96xx, strerror ( rc ) );
422                 goto err_write_rcr;
423         }
424
425         /* Update link status */
426         if ( ( rc = dm96xx_check_link ( dm96xx ) ) != 0 )
427                 goto err_check_link;
428
429         return 0;
430
431  err_check_link:
432  err_write_rcr:
433         usbnet_close ( &dm96xx->usbnet );
434  err_open:
435  err_write_mac:
436  err_rx_mode:
437         return rc;
438 }
439
440 /**
441  * Close network device
442  *
443  * @v netdev            Network device
444  */
445 static void dm96xx_close ( struct net_device *netdev ) {
446         struct dm96xx_device *dm96xx = netdev->priv;
447
448         /* Close USB network device */
449         usbnet_close ( &dm96xx->usbnet );
450
451         /* Reset device */
452         dm96xx_reset ( dm96xx );
453 }
454
455 /**
456  * Transmit packet
457  *
458  * @v netdev            Network device
459  * @v iobuf             I/O buffer
460  * @ret rc              Return status code
461  */
462 static int dm96xx_transmit ( struct net_device *netdev,
463                              struct io_buffer *iobuf ) {
464         struct dm96xx_device *dm96xx = netdev->priv;
465         int rc;
466
467         /* Transmit packet */
468         if ( ( rc = dm96xx_out_transmit ( dm96xx, iobuf ) ) != 0 )
469                 return rc;
470
471         return 0;
472 }
473
474 /**
475  * Poll for completed and received packets
476  *
477  * @v netdev            Network device
478  */
479 static void dm96xx_poll ( struct net_device *netdev ) {
480         struct dm96xx_device *dm96xx = netdev->priv;
481         int rc;
482
483         /* Poll USB bus */
484         usb_poll ( dm96xx->bus );
485
486         /* Refill endpoints */
487         if ( ( rc = usbnet_refill ( &dm96xx->usbnet ) ) != 0 )
488                 netdev_rx_err ( netdev, NULL, rc );
489 }
490
491 /** DM96xx network device operations */
492 static struct net_device_operations dm96xx_operations = {
493         .open           = dm96xx_open,
494         .close          = dm96xx_close,
495         .transmit       = dm96xx_transmit,
496         .poll           = dm96xx_poll,
497 };
498
499 /******************************************************************************
500  *
501  * USB interface
502  *
503  ******************************************************************************
504  */
505
506 /**
507  * Probe device
508  *
509  * @v func              USB function
510  * @v config            Configuration descriptor
511  * @ret rc              Return status code
512  */
513 static int dm96xx_probe ( struct usb_function *func,
514                        struct usb_configuration_descriptor *config ) {
515         struct usb_device *usb = func->usb;
516         struct net_device *netdev;
517         struct dm96xx_device *dm96xx;
518         int rc;
519
520         /* Allocate and initialise structure */
521         netdev = alloc_etherdev ( sizeof ( *dm96xx ) );
522         if ( ! netdev ) {
523                 rc = -ENOMEM;
524                 goto err_alloc;
525         }
526         netdev_init ( netdev, &dm96xx_operations );
527         netdev->dev = &func->dev;
528         dm96xx = netdev->priv;
529         memset ( dm96xx, 0, sizeof ( *dm96xx ) );
530         dm96xx->usb = usb;
531         dm96xx->bus = usb->port->hub->bus;
532         dm96xx->netdev = netdev;
533         usbnet_init ( &dm96xx->usbnet, func, &dm96xx_intr_operations,
534                       &dm96xx_in_operations, &dm96xx_out_operations );
535         usb_refill_init ( &dm96xx->usbnet.intr, 0, DM96XX_INTR_MAX_FILL );
536         usb_refill_init ( &dm96xx->usbnet.in, DM96XX_IN_MTU,
537                           DM96XX_IN_MAX_FILL );
538         DBGC ( dm96xx, "DM96XX %p on %s\n", dm96xx, func->name );
539
540         /* Describe USB network device */
541         if ( ( rc = usbnet_describe ( &dm96xx->usbnet, config ) ) != 0 ) {
542                 DBGC ( dm96xx, "DM96XX %p could not describe: %s\n",
543                        dm96xx, strerror ( rc ) );
544                 goto err_describe;
545         }
546
547         /* Reset device */
548         if ( ( rc = dm96xx_reset ( dm96xx ) ) != 0 )
549                 goto err_reset;
550
551         /* Read MAC address */
552         if ( ( rc = dm96xx_read_mac ( dm96xx, netdev->hw_addr ) ) != 0 )
553                 goto err_read_mac;
554
555         /* Get initial link status */
556         if ( ( rc = dm96xx_check_link ( dm96xx ) ) != 0 )
557                 goto err_check_link;
558
559         /* Register network device */
560         if ( ( rc = register_netdev ( netdev ) ) != 0 )
561                 goto err_register;
562
563         usb_func_set_drvdata ( func, netdev );
564         return 0;
565
566         unregister_netdev ( netdev );
567  err_register:
568  err_check_link:
569  err_read_mac:
570  err_reset:
571  err_describe:
572         netdev_nullify ( netdev );
573         netdev_put ( netdev );
574  err_alloc:
575         return rc;
576 }
577
578 /**
579  * Remove device
580  *
581  * @v func              USB function
582  */
583 static void dm96xx_remove ( struct usb_function *func ) {
584         struct net_device *netdev = usb_func_get_drvdata ( func );
585
586         unregister_netdev ( netdev );
587         netdev_nullify ( netdev );
588         netdev_put ( netdev );
589 }
590
591 /** DM96xx device IDs */
592 static struct usb_device_id dm96xx_ids[] = {
593         {
594                 .name = "dm9601-corega",
595                 .vendor = 0x07aa,
596                 .product = 0x9601,
597         },
598         {
599                 .name = "dm9601",
600                 .vendor = 0x0a46,
601                 .product = 0x9601,
602         },
603         {
604                 .name = "zt6688",
605                 .vendor = 0x0a46,
606                 .product = 0x6688,
607         },
608         {
609                 .name = "st268",
610                 .vendor = 0x0a46,
611                 .product = 0x0268,
612         },
613         {
614                 .name = "adm8515",
615                 .vendor = 0x0a46,
616                 .product = 0x8515,
617         },
618         {
619                 .name = "dm9601-hirose",
620                 .vendor = 0x0a47,
621                 .product = 0x9601,
622         },
623         {
624                 .name = "dm9601-8101",
625                 .vendor = 0x0fe6,
626                 .product = 0x8101,
627         },
628         {
629                 .name = "dm9601-9700",
630                 .vendor = 0x0fe6,
631                 .product = 0x9700,
632         },
633         {
634                 .name = "dm9000e",
635                 .vendor = 0x0a46,
636                 .product = 0x9000,
637         },
638         {
639                 .name = "dm9620",
640                 .vendor = 0x0a46,
641                 .product = 0x9620,
642         },
643         {
644                 .name = "dm9621A",
645                 .vendor = 0x0a46,
646                 .product = 0x9621,
647         },
648         {
649                 .name = "dm9622",
650                 .vendor = 0x0a46,
651                 .product = 0x9622,
652         },
653         {
654                 .name = "dm962Oa",
655                 .vendor = 0x0a46,
656                 .product = 0x0269,
657         },
658         {
659                 .name = "dm9621a",
660                 .vendor = 0x0a46,
661                 .product = 0x1269,
662         },
663 };
664
665 /** Davicom DM96xx driver */
666 struct usb_driver dm96xx_driver __usb_driver = {
667         .ids = dm96xx_ids,
668         .id_count = ( sizeof ( dm96xx_ids ) / sizeof ( dm96xx_ids[0] ) ),
669         .probe = dm96xx_probe,
670         .remove = dm96xx_remove,
671 };