2
* Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
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.
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.
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
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.
24
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
30
#include <ipxe/netdevice.h>
31
#include <ipxe/ethernet.h>
32
#include <ipxe/if_ether.h>
33
#include <ipxe/profile.h>
39
* Asix 10/100/1000 USB Ethernet driver
41
* Large chunks of functionality are undocumented in the available
42
* datasheets. The gaps are deduced from combinations of the Linux
43
* driver, the FreeBSD driver, and experimentation with the hardware.
46
/** Interrupt completion profiler */
47
static struct profiler axge_intr_profiler __profiler =
48
{ .name = "axge.intr" };
50
/** Bulk IN completion profiler */
51
static struct profiler axge_in_profiler __profiler =
52
{ .name = "axge.in" };
54
/** Bulk OUT profiler */
55
static struct profiler axge_out_profiler __profiler =
56
{ .name = "axge.out" };
58
/** Default bulk IN configuration
60
* The Linux and FreeBSD drivers have set of magic constants which are
61
* chosen based on both the Ethernet and USB link speeds.
63
* Experimentation shows that setting the "timer" value to zero seems
64
* to prevent the device from ever coalescing multiple packets into a
65
* single bulk IN transfer. This allows us to get away with using a
66
* 2kB receive I/O buffer and a zerocopy receive path.
68
static struct axge_bulk_in_control axge_bicr = {
70
.timer = cpu_to_le16 ( 0 ),
75
/******************************************************************************
79
******************************************************************************
86
* @v offset Register offset
88
* @v len Length of data
89
* @ret rc Return status code
91
static inline int axge_read_register ( struct axge_device *axge,
92
unsigned int offset, void *data,
95
return usb_control ( axge->usb, AXGE_READ_MAC_REGISTER,
96
offset, len, data, len );
100
* Read one-byte register
102
* @v asix AXGE device
103
* @v offset Register offset
104
* @v value Value to fill in
105
* @ret rc Return status code
107
static inline int axge_read_byte ( struct axge_device *axge,
108
unsigned int offset, uint8_t *value ) {
110
return axge_read_register ( axge, offset, value, sizeof ( *value ) );
114
* Read two-byte register
116
* @v asix AXGE device
117
* @v offset Register offset
118
* @v value Value to fill in
119
* @ret rc Return status code
121
static inline int axge_read_word ( struct axge_device *axge,
122
unsigned int offset, uint16_t *value ) {
124
return axge_read_register ( axge, offset, value, sizeof ( *value ) );
128
* Read four-byte register
130
* @v asix AXGE device
131
* @v offset Register offset
132
* @v value Value to fill in
133
* @ret rc Return status code
135
static inline int axge_read_dword ( struct axge_device *axge,
136
unsigned int offset, uint32_t *value ) {
138
return axge_read_register ( axge, offset, value, sizeof ( *value ) );
144
* @v asix AXGE device
145
* @v offset Register offset
146
* @v data Data buffer
147
* @v len Length of data
148
* @ret rc Return status code
150
static inline int axge_write_register ( struct axge_device *axge,
151
unsigned int offset, void *data,
154
return usb_control ( axge->usb, AXGE_WRITE_MAC_REGISTER,
155
offset, len, data, len );
159
* Write one-byte register
161
* @v asix AXGE device
162
* @v offset Register offset
164
* @ret rc Return status code
166
static inline int axge_write_byte ( struct axge_device *axge,
167
unsigned int offset, uint8_t value ) {
169
return axge_write_register ( axge, offset, &value, sizeof ( value ));
173
* Write two-byte register
175
* @v asix AXGE device
176
* @v offset Register offset
178
* @ret rc Return status code
180
static inline int axge_write_word ( struct axge_device *axge,
181
unsigned int offset, uint16_t value ) {
183
return axge_write_register ( axge, offset, &value, sizeof ( value ));
187
* Write one-byte register
189
* @v asix AXGE device
190
* @v offset Register offset
192
* @ret rc Return status code
194
static inline int axge_write_dword ( struct axge_device *axge,
195
unsigned int offset, uint32_t value ) {
197
return axge_write_register ( axge, offset, &value, sizeof ( value ));
200
/******************************************************************************
204
******************************************************************************
210
* @v asix AXGE device
211
* @ret rc Return status code
213
static int axge_check_link ( struct axge_device *axge ) {
214
struct net_device *netdev = axge->netdev;
218
/* Read physical link status register */
219
if ( ( rc = axge_read_byte ( axge, AXGE_PLSR, &plsr ) ) != 0 ) {
220
DBGC ( axge, "AXGE %p could not read PLSR: %s\n",
221
axge, strerror ( rc ) );
225
/* Update link status */
226
if ( plsr & AXGE_PLSR_EPHY_ANY ) {
227
DBGC ( axge, "AXGE %p link up (PLSR %02x)\n", axge, plsr );
228
netdev_link_up ( netdev );
230
DBGC ( axge, "AXGE %p link down (PLSR %02x)\n", axge, plsr );
231
netdev_link_down ( netdev );
237
/******************************************************************************
239
* AXGE communications interface
241
******************************************************************************
245
* Complete interrupt transfer
248
* @v iobuf I/O buffer
249
* @v rc Completion status code
251
static void axge_intr_complete ( struct usb_endpoint *ep,
252
struct io_buffer *iobuf, int rc ) {
253
struct axge_device *axge = container_of ( ep, struct axge_device,
255
struct net_device *netdev = axge->netdev;
256
struct axge_interrupt *intr;
257
size_t len = iob_len ( iobuf );
258
unsigned int link_ok;
260
/* Profile completions */
261
profile_start ( &axge_intr_profiler );
263
/* Ignore packets cancelled when the endpoint closes */
267
/* Drop packets with errors */
269
DBGC ( axge, "AXGE %p interrupt failed: %s\n",
270
axge, strerror ( rc ) );
271
DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
275
/* Extract message header */
276
if ( len < sizeof ( *intr ) ) {
277
DBGC ( axge, "AXGE %p underlength interrupt:\n", axge );
278
DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
284
/* Check magic signature */
285
if ( intr->magic != cpu_to_le16 ( AXGE_INTR_MAGIC ) ) {
286
DBGC ( axge, "AXGE %p malformed interrupt:\n", axge );
287
DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
292
/* Extract link status */
293
link_ok = ( intr->link & cpu_to_le16 ( AXGE_INTR_LINK_PPLS ) );
294
if ( link_ok && ! netdev_link_ok ( netdev ) ) {
295
DBGC ( axge, "AXGE %p link up\n", axge );
296
netdev_link_up ( netdev );
297
} else if ( netdev_link_ok ( netdev ) && ! link_ok ) {
298
DBGC ( axge, "AXGE %p link down\n", axge );
299
netdev_link_down ( netdev );
302
/* Free I/O buffer */
304
profile_stop ( &axge_intr_profiler );
309
netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
315
/** Interrupt endpoint operations */
316
static struct usb_endpoint_driver_operations axge_intr_operations = {
317
.complete = axge_intr_complete,
320
/******************************************************************************
322
* AXGE data interface
324
******************************************************************************
328
* Complete bulk IN transfer
331
* @v iobuf I/O buffer
332
* @v rc Completion status code
334
static void axge_in_complete ( struct usb_endpoint *ep,
335
struct io_buffer *iobuf, int rc ) {
336
struct axge_device *axge = container_of ( ep, struct axge_device,
338
struct net_device *netdev = axge->netdev;
339
struct axge_rx_footer *ftr;
340
struct axge_rx_descriptor *desc;
341
struct io_buffer *pkt;
347
/* Profile receive completions */
348
profile_start ( &axge_in_profiler );
350
/* Ignore packets cancelled when the endpoint closes */
354
/* Record USB errors against the network device */
356
DBGC ( axge, "AXGE %p bulk IN failed: %s\n",
357
axge, strerror ( rc ) );
362
if ( iob_len ( iobuf ) < sizeof ( *ftr ) ) {
363
DBGC ( axge, "AXGE %p underlength bulk IN:\n", axge );
364
DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
369
/* Parse ftr, strip ftr and descriptors */
370
iob_unput ( iobuf, sizeof ( *ftr ) );
371
ftr = ( iobuf->data + iob_len ( iobuf ) );
372
count = le16_to_cpu ( ftr->count );
374
DBGC ( axge, "AXGE %p zero-packet bulk IN:\n", axge );
375
DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
378
offset = le16_to_cpu ( ftr->offset );
379
if ( ( iob_len ( iobuf ) < offset ) ||
380
( ( iob_len ( iobuf ) - offset ) < ( count * sizeof ( *desc ) ) )){
381
DBGC ( axge, "AXGE %p malformed bulk IN footer:\n", axge );
382
DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
386
desc = ( iobuf->data + offset );
387
iob_unput ( iobuf, ( iob_len ( iobuf ) - offset ) );
389
/* Process packets */
390
for ( ; count-- ; desc++ ) {
392
/* Parse descriptor */
393
len = ( le16_to_cpu ( desc->len_flags ) & AXGE_RX_LEN_MASK );
394
padded_len = ( ( len + AXGE_RX_LEN_PAD_ALIGN - 1 ) &
395
~( AXGE_RX_LEN_PAD_ALIGN - 1 ) );
396
if ( iob_len ( iobuf ) < padded_len ) {
397
DBGC ( axge, "AXGE %p malformed bulk IN descriptor:\n",
399
DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
404
/* Check for previous dropped packets */
405
if ( desc->len_flags & cpu_to_le16 ( AXGE_RX_CRC_ERROR ) )
406
netdev_rx_err ( netdev, NULL, -EIO );
407
if ( desc->len_flags & cpu_to_le16 ( AXGE_RX_DROP_ERROR ) )
408
netdev_rx_err ( netdev, NULL, -ENOBUFS );
410
/* Allocate new I/O buffer, if applicable */
413
/* More packets remain: allocate a new buffer */
414
pkt = alloc_iob ( AXGE_IN_RESERVE + len );
416
/* Record error and continue */
417
netdev_rx_err ( netdev, NULL, -ENOMEM );
418
iob_pull ( iobuf, padded_len );
421
iob_reserve ( pkt, AXGE_IN_RESERVE );
422
memcpy ( iob_put ( pkt, len ), iobuf->data, len );
423
iob_pull ( iobuf, padded_len );
427
/* This is the last (or only) packet: use this buffer */
428
iob_unput ( iobuf, ( padded_len - len ) );
429
pkt = iob_disown ( iobuf );
432
/* Hand off to network stack */
433
netdev_rx ( netdev, iob_disown ( pkt ) );
436
assert ( iobuf == NULL );
437
profile_stop ( &axge_in_profiler );
441
netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
446
/** Bulk IN endpoint operations */
447
static struct usb_endpoint_driver_operations axge_in_operations = {
448
.complete = axge_in_complete,
454
* @v asix AXGE device
455
* @v iobuf I/O buffer
456
* @ret rc Return status code
458
static int axge_out_transmit ( struct axge_device *axge,
459
struct io_buffer *iobuf ) {
460
struct axge_tx_header *hdr;
461
size_t len = iob_len ( iobuf );
464
/* Profile transmissions */
465
profile_start ( &axge_out_profiler );
468
if ( ( rc = iob_ensure_headroom ( iobuf, sizeof ( *hdr ) ) ) != 0 )
470
hdr = iob_push ( iobuf, sizeof ( *hdr ) );
471
hdr->len = cpu_to_le32 ( len );
474
/* Enqueue I/O buffer */
475
if ( ( rc = usb_stream ( &axge->usbnet.out, iobuf, 0 ) ) != 0 )
478
profile_stop ( &axge_out_profiler );
483
* Complete bulk OUT transfer
486
* @v iobuf I/O buffer
487
* @v rc Completion status code
489
static void axge_out_complete ( struct usb_endpoint *ep,
490
struct io_buffer *iobuf, int rc ) {
491
struct axge_device *axge = container_of ( ep, struct axge_device,
493
struct net_device *netdev = axge->netdev;
495
/* Report TX completion */
496
netdev_tx_complete_err ( netdev, iobuf, rc );
499
/** Bulk OUT endpoint operations */
500
static struct usb_endpoint_driver_operations axge_out_operations = {
501
.complete = axge_out_complete,
504
/******************************************************************************
506
* Network device interface
508
******************************************************************************
512
* Open network device
514
* @v netdev Network device
515
* @ret rc Return status code
517
static int axge_open ( struct net_device *netdev ) {
518
struct axge_device *axge = netdev->priv;
522
/* Open USB network device */
523
if ( ( rc = usbnet_open ( &axge->usbnet ) ) != 0 ) {
524
DBGC ( axge, "AXGE %p could not open: %s\n",
525
axge, strerror ( rc ) );
529
/* Set MAC address */
530
if ( ( rc = axge_write_register ( axge, AXGE_NIDR,
531
netdev->ll_addr, ETH_ALEN ) ) !=0){
532
DBGC ( axge, "AXGE %p could not set MAC address: %s\n",
533
axge, strerror ( rc ) );
537
/* Enable receiver */
538
rcr = cpu_to_le16 ( AXGE_RCR_PRO | AXGE_RCR_AMALL |
539
AXGE_RCR_AB | AXGE_RCR_SO );
540
if ( ( rc = axge_write_word ( axge, AXGE_RCR, rcr ) ) != 0 ) {
541
DBGC ( axge, "AXGE %p could not write RCR: %s\n",
542
axge, strerror ( rc ) );
546
/* Update link status */
547
axge_check_link ( axge );
551
axge_write_word ( axge, AXGE_RCR, 0 );
554
usbnet_close ( &axge->usbnet );
560
* Close network device
562
* @v netdev Network device
564
static void axge_close ( struct net_device *netdev ) {
565
struct axge_device *axge = netdev->priv;
567
/* Disable receiver */
568
axge_write_word ( axge, AXGE_RCR, 0 );
570
/* Close USB network device */
571
usbnet_close ( &axge->usbnet );
577
* @v netdev Network device
578
* @v iobuf I/O buffer
579
* @ret rc Return status code
581
static int axge_transmit ( struct net_device *netdev,
582
struct io_buffer *iobuf ) {
583
struct axge_device *axge = netdev->priv;
586
/* Transmit packet */
587
if ( ( rc = axge_out_transmit ( axge, iobuf ) ) != 0 )
594
* Poll for completed and received packets
596
* @v netdev Network device
598
static void axge_poll ( struct net_device *netdev ) {
599
struct axge_device *axge = netdev->priv;
603
usb_poll ( axge->bus );
605
/* Refill endpoints */
606
if ( ( rc = usbnet_refill ( &axge->usbnet ) ) != 0 )
607
netdev_rx_err ( netdev, NULL, rc );
610
/** AXGE network device operations */
611
static struct net_device_operations axge_operations = {
614
.transmit = axge_transmit,
618
/******************************************************************************
622
******************************************************************************
628
* @v func USB function
629
* @v config Configuration descriptor
630
* @ret rc Return status code
632
static int axge_probe ( struct usb_function *func,
633
struct usb_configuration_descriptor *config ) {
634
struct usb_device *usb = func->usb;
635
struct net_device *netdev;
636
struct axge_device *axge;
642
/* Allocate and initialise structure */
643
netdev = alloc_etherdev ( sizeof ( *axge ) );
648
netdev_init ( netdev, &axge_operations );
649
netdev->dev = &func->dev;
651
memset ( axge, 0, sizeof ( *axge ) );
653
axge->bus = usb->port->hub->bus;
654
axge->netdev = netdev;
655
usbnet_init ( &axge->usbnet, func, &axge_intr_operations,
656
&axge_in_operations, &axge_out_operations );
657
usb_refill_init ( &axge->usbnet.intr, 0, 0, AXGE_INTR_MAX_FILL );
658
usb_refill_init ( &axge->usbnet.in, AXGE_IN_RESERVE,
659
AXGE_IN_MTU, AXGE_IN_MAX_FILL );
660
DBGC ( axge, "AXGE %p on %s\n", axge, func->name );
662
/* Describe USB network device */
663
if ( ( rc = usbnet_describe ( &axge->usbnet, config ) ) != 0 ) {
664
DBGC ( axge, "AXGE %p could not describe: %s\n",
665
axge, strerror ( rc ) );
669
/* Fetch MAC address */
670
if ( ( rc = axge_read_register ( axge, AXGE_NIDR, netdev->hw_addr,
671
ETH_ALEN ) ) != 0 ) {
672
DBGC ( axge, "AXGE %p could not fetch MAC address: %s\n",
673
axge, strerror ( rc ) );
678
if ( ( rc = axge_write_word ( axge, AXGE_EPPRCR, 0 ) ) != 0 ) {
679
DBGC ( axge, "AXGE %p could not write EPPRCR: %s\n",
680
axge, strerror ( rc ) );
681
goto err_write_epprcr_off;
683
epprcr = cpu_to_le16 ( AXGE_EPPRCR_IPRL );
684
if ( ( rc = axge_write_word ( axge, AXGE_EPPRCR, epprcr ) ) != 0){
685
DBGC ( axge, "AXGE %p could not write EPPRCR: %s\n",
686
axge, strerror ( rc ) );
687
goto err_write_epprcr_on;
689
mdelay ( AXGE_EPPRCR_DELAY_MS );
692
csr = ( AXGE_CSR_BCS | AXGE_CSR_ACS );
693
if ( ( rc = axge_write_byte ( axge, AXGE_CSR, csr ) ) != 0){
694
DBGC ( axge, "AXGE %p could not write CSR: %s\n",
695
axge, strerror ( rc ) );
698
mdelay ( AXGE_CSR_DELAY_MS );
700
/* Configure bulk IN pipeline */
701
if ( ( rc = axge_write_register ( axge, AXGE_BICR, &axge_bicr,
702
sizeof ( axge_bicr ) ) ) != 0 ){
703
DBGC ( axge, "AXGE %p could not write BICR: %s\n",
704
axge, strerror ( rc ) );
708
/* Set medium status */
709
msr = cpu_to_le16 ( AXGE_MSR_GM | AXGE_MSR_FD | AXGE_MSR_RFC |
710
AXGE_MSR_TFC | AXGE_MSR_RE );
711
if ( ( rc = axge_write_word ( axge, AXGE_MSR, msr ) ) != 0 ) {
712
DBGC ( axge, "AXGE %p could not write MSR: %s\n",
713
axge, strerror ( rc ) );
717
/* Register network device */
718
if ( ( rc = register_netdev ( netdev ) ) != 0 )
721
/* Update link status */
722
axge_check_link ( axge );
724
usb_func_set_drvdata ( func, axge );
727
unregister_netdev ( netdev );
733
err_write_epprcr_off:
736
netdev_nullify ( netdev );
737
netdev_put ( netdev );
745
* @v func USB function
747
static void axge_remove ( struct usb_function *func ) {
748
struct axge_device *axge = usb_func_get_drvdata ( func );
749
struct net_device *netdev = axge->netdev;
751
unregister_netdev ( netdev );
752
netdev_nullify ( netdev );
753
netdev_put ( netdev );
756
/** AXGE device IDs */
757
static struct usb_device_id axge_ids[] = {
774
.name = "axge-sitecom",
779
.name = "axge-samsung",
784
.name = "onelinkdock",
791
struct usb_driver axge_driver __usb_driver = {
793
.id_count = ( sizeof ( axge_ids ) / sizeof ( axge_ids[0] ) ),
794
.class = USB_CLASS_ID ( USB_ANY_ID, USB_ANY_ID, USB_ANY_ID ),
795
.score = USB_SCORE_NORMAL,
797
.remove = axge_remove,