iPXE
axge.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 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 <stdint.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <errno.h>
30 #include <ipxe/netdevice.h>
31 #include <ipxe/ethernet.h>
32 #include <ipxe/if_ether.h>
33 #include <ipxe/profile.h>
34 #include <ipxe/usb.h>
35 #include "axge.h"
36 
37 /** @file
38  *
39  * Asix 10/100/1000 USB Ethernet driver
40  *
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.
44  */
45 
46 /** Interrupt completion profiler */
47 static struct profiler axge_intr_profiler __profiler =
48  { .name = "axge.intr" };
49 
50 /** Bulk IN completion profiler */
51 static struct profiler axge_in_profiler __profiler =
52  { .name = "axge.in" };
53 
54 /** Bulk OUT profiler */
55 static struct profiler axge_out_profiler __profiler =
56  { .name = "axge.out" };
57 
58 /** Default bulk IN configuration
59  *
60  * The Linux and FreeBSD drivers have set of magic constants which are
61  * chosen based on both the Ethernet and USB link speeds.
62  *
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.
67  */
69  .ctrl = 7,
70  .timer = cpu_to_le16 ( 0 ),
71  .size = 0,
72  .ifg = 0,
73 };
74 
75 /******************************************************************************
76  *
77  * Register access
78  *
79  ******************************************************************************
80  */
81 
82 /**
83  * Read register
84  *
85  * @v asix AXGE device
86  * @v offset Register offset
87  * @v data Data buffer
88  * @v len Length of data
89  * @ret rc Return status code
90  */
91 static inline int axge_read_register ( struct axge_device *axge,
92  unsigned int offset, void *data,
93  size_t len ) {
94 
95  return usb_control ( axge->usb, AXGE_READ_MAC_REGISTER,
96  offset, len, data, len );
97 }
98 
99 /**
100  * Read one-byte register
101  *
102  * @v asix AXGE device
103  * @v offset Register offset
104  * @v value Value to fill in
105  * @ret rc Return status code
106  */
107 static inline int axge_read_byte ( struct axge_device *axge,
108  unsigned int offset, uint8_t *value ) {
109 
110  return axge_read_register ( axge, offset, value, sizeof ( *value ) );
111 }
112 
113 /**
114  * Read two-byte register
115  *
116  * @v asix AXGE device
117  * @v offset Register offset
118  * @v value Value to fill in
119  * @ret rc Return status code
120  */
121 static inline int axge_read_word ( struct axge_device *axge,
122  unsigned int offset, uint16_t *value ) {
123 
124  return axge_read_register ( axge, offset, value, sizeof ( *value ) );
125 }
126 
127 /**
128  * Read four-byte register
129  *
130  * @v asix AXGE device
131  * @v offset Register offset
132  * @v value Value to fill in
133  * @ret rc Return status code
134  */
135 static inline int axge_read_dword ( struct axge_device *axge,
136  unsigned int offset, uint32_t *value ) {
137 
138  return axge_read_register ( axge, offset, value, sizeof ( *value ) );
139 }
140 
141 /**
142  * Write register
143  *
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
149  */
150 static inline int axge_write_register ( struct axge_device *axge,
151  unsigned int offset, void *data,
152  size_t len ) {
153 
154  return usb_control ( axge->usb, AXGE_WRITE_MAC_REGISTER,
155  offset, len, data, len );
156 }
157 
158 /**
159  * Write one-byte register
160  *
161  * @v asix AXGE device
162  * @v offset Register offset
163  * @v value Value
164  * @ret rc Return status code
165  */
166 static inline int axge_write_byte ( struct axge_device *axge,
167  unsigned int offset, uint8_t value ) {
168 
169  return axge_write_register ( axge, offset, &value, sizeof ( value ));
170 }
171 
172 /**
173  * Write two-byte register
174  *
175  * @v asix AXGE device
176  * @v offset Register offset
177  * @v value Value
178  * @ret rc Return status code
179  */
180 static inline int axge_write_word ( struct axge_device *axge,
181  unsigned int offset, uint16_t value ) {
182 
183  return axge_write_register ( axge, offset, &value, sizeof ( value ));
184 }
185 
186 /**
187  * Write one-byte register
188  *
189  * @v asix AXGE device
190  * @v offset Register offset
191  * @v value Value
192  * @ret rc Return status code
193  */
194 static inline int axge_write_dword ( struct axge_device *axge,
195  unsigned int offset, uint32_t value ) {
196 
197  return axge_write_register ( axge, offset, &value, sizeof ( value ));
198 }
199 
200 /******************************************************************************
201  *
202  * Link status
203  *
204  ******************************************************************************
205  */
206 
207 /**
208  * Get link status
209  *
210  * @v asix AXGE device
211  * @ret rc Return status code
212  */
213 static int axge_check_link ( struct axge_device *axge ) {
214  struct net_device *netdev = axge->netdev;
215  uint8_t plsr;
216  uint16_t msr;
217  int rc;
218 
219  /* Read physical link status register */
220  if ( ( rc = axge_read_byte ( axge, AXGE_PLSR, &plsr ) ) != 0 ) {
221  DBGC ( axge, "AXGE %p could not read PLSR: %s\n",
222  axge, strerror ( rc ) );
223  return rc;
224  }
225 
226  /* Write medium status register */
228  AXGE_MSR_RE );
229  if ( plsr & AXGE_PLSR_EPHY_1000 ) {
230  msr |= cpu_to_le16 ( AXGE_MSR_GM );
231  } else if ( plsr & AXGE_PLSR_EPHY_100 ) {
232  msr |= cpu_to_le16 ( AXGE_MSR_PS );
233  }
234  if ( ( rc = axge_write_word ( axge, AXGE_MSR, msr ) ) != 0 ) {
235  DBGC ( axge, "AXGE %p could not write MSR: %s\n",
236  axge, strerror ( rc ) );
237  return rc;
238  }
239 
240  /* Update link status */
241  if ( plsr & AXGE_PLSR_EPHY_ANY ) {
242  DBGC ( axge, "AXGE %p link up (PLSR %02x MSR %04x)\n",
243  axge, plsr, msr );
245  } else {
246  DBGC ( axge, "AXGE %p link down (PLSR %02x MSR %04x)\n",
247  axge, plsr, msr );
249  }
250 
251  return 0;
252 }
253 
254 /******************************************************************************
255  *
256  * AXGE communications interface
257  *
258  ******************************************************************************
259  */
260 
261 /**
262  * Complete interrupt transfer
263  *
264  * @v ep USB endpoint
265  * @v iobuf I/O buffer
266  * @v rc Completion status code
267  */
268 static void axge_intr_complete ( struct usb_endpoint *ep,
269  struct io_buffer *iobuf, int rc ) {
270  struct axge_device *axge = container_of ( ep, struct axge_device,
271  usbnet.intr );
272  struct net_device *netdev = axge->netdev;
273  struct axge_interrupt *intr;
274  size_t len = iob_len ( iobuf );
275  unsigned int link_ok;
276 
277  /* Profile completions */
278  profile_start ( &axge_intr_profiler );
279 
280  /* Ignore packets cancelled when the endpoint closes */
281  if ( ! ep->open )
282  goto ignore;
283 
284  /* Drop packets with errors */
285  if ( rc != 0 ) {
286  DBGC ( axge, "AXGE %p interrupt failed: %s\n",
287  axge, strerror ( rc ) );
288  DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
289  goto error;
290  }
291 
292  /* Extract message header */
293  if ( len < sizeof ( *intr ) ) {
294  DBGC ( axge, "AXGE %p underlength interrupt:\n", axge );
295  DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
296  rc = -EINVAL;
297  goto error;
298  }
299  intr = iobuf->data;
300 
301  /* Check magic signature */
302  if ( intr->magic != cpu_to_le16 ( AXGE_INTR_MAGIC ) ) {
303  DBGC ( axge, "AXGE %p malformed interrupt:\n", axge );
304  DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
305  rc = -EINVAL;
306  goto error;
307  }
308 
309  /* Extract link status */
310  link_ok = ( intr->link & cpu_to_le16 ( AXGE_INTR_LINK_PPLS ) );
311  if ( ( !! link_ok ) ^ ( !! netdev_link_ok ( netdev ) ) )
312  axge->check_link = 1;
313 
314  /* Free I/O buffer */
315  free_iob ( iobuf );
316  profile_stop ( &axge_intr_profiler );
317 
318  return;
319 
320  error:
321  netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
322  ignore:
323  free_iob ( iobuf );
324  return;
325 }
326 
327 /** Interrupt endpoint operations */
330 };
331 
332 /******************************************************************************
333  *
334  * AXGE data interface
335  *
336  ******************************************************************************
337  */
338 
339 /**
340  * Complete bulk IN transfer
341  *
342  * @v ep USB endpoint
343  * @v iobuf I/O buffer
344  * @v rc Completion status code
345  */
346 static void axge_in_complete ( struct usb_endpoint *ep,
347  struct io_buffer *iobuf, int rc ) {
348  struct axge_device *axge = container_of ( ep, struct axge_device,
349  usbnet.in );
350  struct net_device *netdev = axge->netdev;
351  struct axge_rx_footer *ftr;
352  struct axge_rx_descriptor *desc;
353  struct io_buffer *pkt;
354  unsigned int count;
355  unsigned int offset;
356  size_t len;
357  size_t padded_len;
358 
359  /* Profile receive completions */
360  profile_start ( &axge_in_profiler );
361 
362  /* Ignore packets cancelled when the endpoint closes */
363  if ( ! ep->open )
364  goto ignore;
365 
366  /* Record USB errors against the network device */
367  if ( rc != 0 ) {
368  DBGC ( axge, "AXGE %p bulk IN failed: %s\n",
369  axge, strerror ( rc ) );
370  goto error;
371  }
372 
373  /* Sanity check */
374  if ( iob_len ( iobuf ) < sizeof ( *ftr ) ) {
375  DBGC ( axge, "AXGE %p underlength bulk IN:\n", axge );
376  DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
377  rc = -EINVAL;
378  goto error;
379  }
380 
381  /* Parse ftr, strip ftr and descriptors */
382  iob_unput ( iobuf, sizeof ( *ftr ) );
383  ftr = ( iobuf->data + iob_len ( iobuf ) );
384  count = le16_to_cpu ( ftr->count );
385  if ( count == 0 ) {
386  DBGC ( axge, "AXGE %p zero-packet bulk IN:\n", axge );
387  DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
388  goto ignore;
389  }
390  offset = le16_to_cpu ( ftr->offset );
391  if ( ( iob_len ( iobuf ) < offset ) ||
392  ( ( iob_len ( iobuf ) - offset ) < ( count * sizeof ( *desc ) ) )){
393  DBGC ( axge, "AXGE %p malformed bulk IN footer:\n", axge );
394  DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
395  rc = -EINVAL;
396  goto error;
397  }
398  desc = ( iobuf->data + offset );
399  iob_unput ( iobuf, ( iob_len ( iobuf ) - offset ) );
400 
401  /* Process packets */
402  for ( ; count-- ; desc++ ) {
403 
404  /* Parse descriptor */
405  len = ( le16_to_cpu ( desc->len_flags ) & AXGE_RX_LEN_MASK );
406  padded_len = ( ( len + AXGE_RX_LEN_PAD_ALIGN - 1 ) &
407  ~( AXGE_RX_LEN_PAD_ALIGN - 1 ) );
408  if ( iob_len ( iobuf ) < padded_len ) {
409  DBGC ( axge, "AXGE %p malformed bulk IN descriptor:\n",
410  axge );
411  DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
412  rc = -EINVAL;
413  goto error;
414  }
415 
416  /* Check for previous dropped packets */
417  if ( desc->len_flags & cpu_to_le16 ( AXGE_RX_CRC_ERROR ) )
418  netdev_rx_err ( netdev, NULL, -EIO );
419  if ( desc->len_flags & cpu_to_le16 ( AXGE_RX_DROP_ERROR ) )
421 
422  /* Allocate new I/O buffer, if applicable */
423  if ( count ) {
424 
425  /* More packets remain: allocate a new buffer */
426  pkt = alloc_iob ( AXGE_IN_RESERVE + len );
427  if ( ! pkt ) {
428  /* Record error and continue */
430  iob_pull ( iobuf, padded_len );
431  continue;
432  }
433  iob_reserve ( pkt, AXGE_IN_RESERVE );
434  memcpy ( iob_put ( pkt, len ), iobuf->data, len );
435  iob_pull ( iobuf, padded_len );
436 
437  } else {
438 
439  /* This is the last (or only) packet: use this buffer */
440  iob_unput ( iobuf, ( padded_len - len ) );
441  pkt = iob_disown ( iobuf );
442  }
443 
444  /* Hand off to network stack */
445  netdev_rx ( netdev, iob_disown ( pkt ) );
446  }
447 
448  assert ( iobuf == NULL );
449  profile_stop ( &axge_in_profiler );
450  return;
451 
452  error:
453  netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
454  ignore:
455  free_iob ( iobuf );
456 }
457 
458 /** Bulk IN endpoint operations */
461 };
462 
463 /**
464  * Transmit packet
465  *
466  * @v asix AXGE device
467  * @v iobuf I/O buffer
468  * @ret rc Return status code
469  */
470 static int axge_out_transmit ( struct axge_device *axge,
471  struct io_buffer *iobuf ) {
472  struct axge_tx_header *hdr;
473  size_t len = iob_len ( iobuf );
474  int rc;
475 
476  /* Profile transmissions */
477  profile_start ( &axge_out_profiler );
478 
479  /* Prepend header */
480  if ( ( rc = iob_ensure_headroom ( iobuf, sizeof ( *hdr ) ) ) != 0 )
481  return rc;
482  hdr = iob_push ( iobuf, sizeof ( *hdr ) );
483  hdr->len = cpu_to_le32 ( len );
484  hdr->wtf = 0;
485 
486  /* Enqueue I/O buffer */
487  if ( ( rc = usb_stream ( &axge->usbnet.out, iobuf, 0 ) ) != 0 )
488  return rc;
489 
490  profile_stop ( &axge_out_profiler );
491  return 0;
492 }
493 
494 /**
495  * Complete bulk OUT transfer
496  *
497  * @v ep USB endpoint
498  * @v iobuf I/O buffer
499  * @v rc Completion status code
500  */
501 static void axge_out_complete ( struct usb_endpoint *ep,
502  struct io_buffer *iobuf, int rc ) {
503  struct axge_device *axge = container_of ( ep, struct axge_device,
504  usbnet.out );
505  struct net_device *netdev = axge->netdev;
506 
507  /* Report TX completion */
508  netdev_tx_complete_err ( netdev, iobuf, rc );
509 }
510 
511 /** Bulk OUT endpoint operations */
514 };
515 
516 /******************************************************************************
517  *
518  * Network device interface
519  *
520  ******************************************************************************
521  */
522 
523 /**
524  * Open network device
525  *
526  * @v netdev Network device
527  * @ret rc Return status code
528  */
529 static int axge_open ( struct net_device *netdev ) {
530  struct axge_device *axge = netdev->priv;
531  uint16_t rcr;
532  int rc;
533 
534  /* Reapply device configuration to avoid transaction errors */
535  if ( ( rc = usb_set_configuration ( axge->usb, axge->config ) ) != 0 ) {
536  DBGC ( axge, "AXGE %p could not set configuration: %s\n",
537  axge, strerror ( rc ) );
538  goto err_set_configuration;
539  }
540 
541  /* Open USB network device */
542  if ( ( rc = usbnet_open ( &axge->usbnet ) ) != 0 ) {
543  DBGC ( axge, "AXGE %p could not open: %s\n",
544  axge, strerror ( rc ) );
545  goto err_open;
546  }
547 
548  /* Set MAC address */
549  if ( ( rc = axge_write_register ( axge, AXGE_NIDR,
550  netdev->ll_addr, ETH_ALEN ) ) !=0){
551  DBGC ( axge, "AXGE %p could not set MAC address: %s\n",
552  axge, strerror ( rc ) );
553  goto err_write_mac;
554  }
555 
556  /* Enable receiver */
559  if ( ( rc = axge_write_word ( axge, AXGE_RCR, rcr ) ) != 0 ) {
560  DBGC ( axge, "AXGE %p could not write RCR: %s\n",
561  axge, strerror ( rc ) );
562  goto err_write_rcr;
563  }
564 
565  /* Update link status */
566  if ( ( rc = axge_check_link ( axge ) ) != 0 )
567  goto err_check_link;
568 
569  return 0;
570 
571  err_check_link:
572  axge_write_word ( axge, AXGE_RCR, 0 );
573  err_write_rcr:
574  err_write_mac:
575  usbnet_close ( &axge->usbnet );
576  err_open:
577  err_set_configuration:
578  return rc;
579 }
580 
581 /**
582  * Close network device
583  *
584  * @v netdev Network device
585  */
586 static void axge_close ( struct net_device *netdev ) {
587  struct axge_device *axge = netdev->priv;
588 
589  /* Disable receiver */
590  axge_write_word ( axge, AXGE_RCR, 0 );
591 
592  /* Close USB network device */
593  usbnet_close ( &axge->usbnet );
594 }
595 
596 /**
597  * Transmit packet
598  *
599  * @v netdev Network device
600  * @v iobuf I/O buffer
601  * @ret rc Return status code
602  */
603 static int axge_transmit ( struct net_device *netdev,
604  struct io_buffer *iobuf ) {
605  struct axge_device *axge = netdev->priv;
606  int rc;
607 
608  /* Transmit packet */
609  if ( ( rc = axge_out_transmit ( axge, iobuf ) ) != 0 )
610  return rc;
611 
612  return 0;
613 }
614 
615 /**
616  * Poll for completed and received packets
617  *
618  * @v netdev Network device
619  */
620 static void axge_poll ( struct net_device *netdev ) {
621  struct axge_device *axge = netdev->priv;
622  int rc;
623 
624  /* Poll USB bus */
625  usb_poll ( axge->bus );
626 
627  /* Refill endpoints */
628  if ( ( rc = usbnet_refill ( &axge->usbnet ) ) != 0 )
629  netdev_rx_err ( netdev, NULL, rc );
630 
631  /* Update link state, if applicable */
632  if ( axge->check_link ) {
633  if ( ( rc = axge_check_link ( axge ) ) == 0 ) {
634  axge->check_link = 0;
635  } else {
636  netdev_rx_err ( netdev, NULL, rc );
637  }
638  }
639 }
640 
641 /** AXGE network device operations */
643  .open = axge_open,
644  .close = axge_close,
645  .transmit = axge_transmit,
646  .poll = axge_poll,
647 };
648 
649 /******************************************************************************
650  *
651  * USB interface
652  *
653  ******************************************************************************
654  */
655 
656 /**
657  * Probe device
658  *
659  * @v func USB function
660  * @v config Configuration descriptor
661  * @ret rc Return status code
662  */
663 static int axge_probe ( struct usb_function *func,
664  struct usb_configuration_descriptor *config ) {
665  struct usb_device *usb = func->usb;
666  struct net_device *netdev;
667  struct axge_device *axge;
668  uint16_t epprcr;
669  uint8_t csr;
670  int rc;
671 
672  /* Allocate and initialise structure */
673  netdev = alloc_etherdev ( sizeof ( *axge ) );
674  if ( ! netdev ) {
675  rc = -ENOMEM;
676  goto err_alloc;
677  }
679  netdev->dev = &func->dev;
680  axge = netdev->priv;
681  memset ( axge, 0, sizeof ( *axge ) );
682  axge->usb = usb;
683  axge->bus = usb->port->hub->bus;
684  axge->netdev = netdev;
685  axge->config = config->config;
686  usbnet_init ( &axge->usbnet, func, &axge_intr_operations,
688  usb_refill_init ( &axge->usbnet.intr, 0, 0, AXGE_INTR_MAX_FILL );
691  DBGC ( axge, "AXGE %p on %s\n", axge, func->name );
692 
693  /* Describe USB network device */
694  if ( ( rc = usbnet_describe ( &axge->usbnet, config ) ) != 0 ) {
695  DBGC ( axge, "AXGE %p could not describe: %s\n",
696  axge, strerror ( rc ) );
697  goto err_describe;
698  }
699 
700  /* Fetch MAC address */
701  if ( ( rc = axge_read_register ( axge, AXGE_NIDR, netdev->hw_addr,
702  ETH_ALEN ) ) != 0 ) {
703  DBGC ( axge, "AXGE %p could not fetch MAC address: %s\n",
704  axge, strerror ( rc ) );
705  goto err_read_mac;
706  }
707 
708  /* Power up PHY */
709  if ( ( rc = axge_write_word ( axge, AXGE_EPPRCR, 0 ) ) != 0 ) {
710  DBGC ( axge, "AXGE %p could not write EPPRCR: %s\n",
711  axge, strerror ( rc ) );
712  goto err_write_epprcr_off;
713  }
714  epprcr = cpu_to_le16 ( AXGE_EPPRCR_IPRL );
715  if ( ( rc = axge_write_word ( axge, AXGE_EPPRCR, epprcr ) ) != 0){
716  DBGC ( axge, "AXGE %p could not write EPPRCR: %s\n",
717  axge, strerror ( rc ) );
718  goto err_write_epprcr_on;
719  }
721 
722  /* Select clocks */
723  csr = ( AXGE_CSR_BCS | AXGE_CSR_ACS );
724  if ( ( rc = axge_write_byte ( axge, AXGE_CSR, csr ) ) != 0){
725  DBGC ( axge, "AXGE %p could not write CSR: %s\n",
726  axge, strerror ( rc ) );
727  goto err_write_csr;
728  }
730 
731  /* Configure bulk IN pipeline */
732  if ( ( rc = axge_write_register ( axge, AXGE_BICR, &axge_bicr,
733  sizeof ( axge_bicr ) ) ) != 0 ){
734  DBGC ( axge, "AXGE %p could not write BICR: %s\n",
735  axge, strerror ( rc ) );
736  goto err_write_bicr;
737  }
738 
739  /* Register network device */
740  if ( ( rc = register_netdev ( netdev ) ) != 0 )
741  goto err_register;
742 
743  /* Update link status */
744  if ( ( rc = axge_check_link ( axge ) ) != 0 )
745  goto err_check_link;
746 
747  usb_func_set_drvdata ( func, axge );
748  return 0;
749 
750  err_check_link:
752  err_register:
753  err_write_bicr:
754  err_write_csr:
755  err_write_epprcr_on:
756  err_write_epprcr_off:
757  err_read_mac:
758  err_describe:
760  netdev_put ( netdev );
761  err_alloc:
762  return rc;
763 }
764 
765 /**
766  * Remove device
767  *
768  * @v func USB function
769  */
770 static void axge_remove ( struct usb_function *func ) {
771  struct axge_device *axge = usb_func_get_drvdata ( func );
772  struct net_device *netdev = axge->netdev;
773 
776  netdev_put ( netdev );
777 }
778 
779 /** AXGE device IDs */
780 static struct usb_device_id axge_ids[] = {
781  {
782  .name = "ax88179",
783  .vendor = 0x0b95,
784  .product = 0x1790,
785  },
786  {
787  .name = "ax88178a",
788  .vendor = 0x0b95,
789  .product = 0x178a,
790  },
791  {
792  .name = "dub1312",
793  .vendor = 0x2001,
794  .product = 0x4a00,
795  },
796  {
797  .name = "axge-sitecom",
798  .vendor = 0x0df6,
799  .product = 0x0072,
800  },
801  {
802  .name = "axge-samsung",
803  .vendor = 0x04e8,
804  .product = 0xa100,
805  },
806  {
807  .name = "onelinkdock",
808  .vendor = 0x17ef,
809  .product = 0x304b,
810  },
811 };
812 
813 /** AXGE driver */
814 struct usb_driver axge_driver __usb_driver = {
815  .ids = axge_ids,
816  .id_count = ( sizeof ( axge_ids ) / sizeof ( axge_ids[0] ) ),
818  .score = USB_SCORE_NORMAL,
819  .probe = axge_probe,
820  .remove = axge_remove,
821 };
Asix 10/100/1000 USB Ethernet driver.
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
A USB driver.
Definition: usb.h:1381
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define AXGE_INTR_MAGIC
Interrupt magic signature.
Definition: axge.h:133
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
A USB device ID.
Definition: usb.h:1335
#define AXGE_EPPRCR_IPRL
Undocumented.
Definition: axge.h:56
#define iob_put(iobuf, len)
Definition: iobuf.h:120
void(* complete)(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete transfer.
Definition: usb.h:481
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition: netdevice.c:586
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition: usb.h:703
static int axge_read_byte(struct axge_device *axge, unsigned int offset, uint8_t *value)
Read one-byte register.
Definition: axge.c:107
static int usb_set_configuration(struct usb_device *usb, unsigned int index)
Set USB configuration.
Definition: usb.h:1221
#define AXGE_RX_DROP_ERROR
Receive packet dropped error.
Definition: axge.h:118
const char * name
Name.
Definition: usb.h:661
struct usb_device * usb
USB device.
Definition: axge.h:141
#define AXGE_PLSR_EPHY_100
Ethernet at 100Mbps.
Definition: axge.h:28
int(* open)(struct net_device *netdev)
Open network device.
Definition: netdevice.h:222
const char * name
Name.
Definition: usb.h:1337
static void axge_close(struct net_device *netdev)
Close network device.
Definition: axge.c:586
static void axge_poll(struct net_device *netdev)
Poll for completed and received packets.
Definition: axge.c:620
Error codes.
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
#define iob_push(iobuf, len)
Definition: iobuf.h:84
#define AXGE_EPPRCR_DELAY_MS
Delay after initialising EPPRCR.
Definition: axge.h:59
struct usb_bus * bus
USB bus.
Definition: axge.h:143
Interrupt data.
Definition: axge.h:121
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
#define AXGE_RCR
RX Control Register.
Definition: axge.h:36
struct arbelprm_completion_with_error error
Definition: arbel.h:12
static int axge_open(struct net_device *netdev)
Open network device.
Definition: axge.c:529
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
#define DBGC(...)
Definition: compiler.h:505
#define AXGE_IN_RESERVE
Amount of space to reserve at start of bulk IN buffers.
Definition: axge.h:177
#define AXGE_INTR_MAX_FILL
Interrupt maximum fill level.
Definition: axge.h:158
int usb_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int terminate)
Enqueue USB stream transfer.
Definition: usb.c:545
void netdev_link_down(struct net_device *netdev)
Mark network device as having link down.
Definition: netdevice.c:230
#define AXGE_RX_CRC_ERROR
Receive packet CRC error.
Definition: axge.h:115
static void axge_remove(struct usb_function *func)
Remove device.
Definition: axge.c:770
#define AXGE_MSR_RFC
RX flow control enable.
Definition: axge.h:49
#define AXGE_RX_LEN_PAD_ALIGN
Receive packet length alignment.
Definition: axge.h:112
static struct profiler axge_intr_profiler __profiler
Interrupt completion profiler.
Definition: axge.c:47
A data structure for storing profiling information.
Definition: profile.h:26
#define AXGE_RCR_SO
Start operation.
Definition: axge.h:40
#define AXGE_MSR
Medium Status Register.
Definition: axge.h:46
int open
Endpoint is open.
Definition: usb.h:404
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition: profile.h:171
struct usb_endpoint intr
Interrupt endpoint.
Definition: usbnet.h:27
static void axge_intr_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete interrupt transfer.
Definition: axge.c:268
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:129
int usb_control(struct usb_device *usb, unsigned int request, unsigned int value, unsigned int index, void *data, size_t len)
Issue USB control transaction.
Definition: usb.c:783
static struct axge_bulk_in_control axge_bicr
Default bulk IN configuration.
Definition: axge.c:68
#define AXGE_RCR_PRO
Promiscuous mode.
Definition: axge.h:37
static struct net_device_operations axge_operations
AXGE network device operations.
Definition: axge.c:642
An AXGE network device.
Definition: axge.h:139
static int axge_out_transmit(struct axge_device *axge, struct io_buffer *iobuf)
Transmit packet.
Definition: axge.c:470
struct usb_endpoint out
Bulk OUT endpoint.
Definition: usbnet.h:31
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:515
#define AXGE_PLSR
Physical Link Status Register.
Definition: axge.h:26
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:212
A USB endpoint.
Definition: usb.h:389
static int axge_check_link(struct axge_device *axge)
Get link status.
Definition: axge.c:213
void * memcpy(void *dest, const void *src, size_t len) __nonnull
Transmit packet header.
Definition: axge.h:85
const char * name
Name.
Definition: profile.h:28
struct usb_port * port
USB port.
Definition: usb.h:712
#define AXGE_CSR_DELAY_MS
Delay after initialising CSR.
Definition: axge.h:82
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:572
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
Ethernet protocol.
uint8_t intr
Interrupts enabled.
Definition: ena.h:14
void * priv
Driver private data.
Definition: netdevice.h:431
static void axge_in_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk IN transfer.
Definition: axge.c:346
struct net_device * netdev
Network device.
Definition: axge.h:145
#define DBGC_HDA(...)
Definition: compiler.h:506
#define AXGE_READ_MAC_REGISTER
Read MAC register.
Definition: axge.h:16
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition: netdevice.h:774
#define AXGE_CSR
Clock Select Register (undocumented)
Definition: axge.h:77
static void usb_refill_init(struct usb_endpoint *ep, size_t reserve, size_t len, unsigned int max)
Initialise USB endpoint refill.
Definition: usb.h:602
static int axge_read_dword(struct axge_device *axge, unsigned int offset, uint32_t *value)
Read four-byte register.
Definition: axge.c:135
static int netdev_link_ok(struct net_device *netdev)
Check link state of network device.
Definition: netdevice.h:636
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static struct net_device * netdev
Definition: gdbudp.c:52
#define AXGE_MSR_PS
100Mbps port speed
Definition: axge.h:52
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
Definition: usb.h:692
static void profile_start(struct profiler *profiler)
Start profiling.
Definition: profile.h:158
Profiling.
static int axge_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition: axge.c:603
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:941
static int axge_write_dword(struct axge_device *axge, unsigned int offset, uint32_t value)
Write one-byte register.
Definition: axge.c:194
int usbnet_refill(struct usbnet_device *usbnet)
Refill USB network device bulk IN and interrupt endpoints.
Definition: usbnet.c:151
#define cpu_to_le32(value)
Definition: byteswap.h:107
A USB device.
Definition: usb.h:708
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
int check_link
Link state has changed.
Definition: axge.h:151
#define AXGE_IN_MAX_FILL
Bulk IN maximum fill level.
Definition: axge.h:164
static void usb_poll(struct usb_bus *bus)
Poll USB bus.
Definition: usb.h:1051
#define iob_unput(iobuf, len)
Definition: iobuf.h:135
#define AXGE_INTR_LINK_PPLS
Link is up.
Definition: axge.h:136
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
Bulk IN Control (undocumented)
Definition: axge.h:65
int register_netdev(struct net_device *netdev)
Register network device.
Definition: netdevice.c:759
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition: usb.h:1363
A network device.
Definition: netdevice.h:352
#define AXGE_CSR_BCS
Undocumented.
Definition: axge.h:78
#define AXGE_BICR
Bulk IN Control Register (undocumented)
Definition: axge.h:62
struct usb_endpoint in
Bulk IN endpoint.
Definition: usbnet.h:29
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:528
static int axge_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition: axge.c:663
Normal driver.
Definition: usb.h:1427
unsigned char uint8_t
Definition: stdint.h:10
#define AXGE_PLSR_EPHY_ANY
Definition: axge.h:30
#define ETH_ALEN
Definition: if_ether.h:8
struct usb_device * usb
USB device.
Definition: usb.h:663
struct usb_driver axge_driver __usb_driver
AXGE driver.
Definition: axge.c:814
#define le16_to_cpu(value)
Definition: byteswap.h:112
unsigned int uint32_t
Definition: stdint.h:12
static struct usb_endpoint_driver_operations axge_intr_operations
Interrupt endpoint operations.
Definition: axge.c:328
Network device operations.
Definition: netdevice.h:213
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition: netdevice.c:548
struct device * dev
Underlying hardware device.
Definition: netdevice.h:364
#define AXGE_WRITE_MAC_REGISTER
Write MAC register.
Definition: axge.h:21
#define AXGE_MSR_GM
Gigabit mode.
Definition: axge.h:47
Network device management.
static int axge_write_word(struct axge_device *axge, unsigned int offset, uint16_t value)
Write two-byte register.
Definition: axge.c:180
#define AXGE_NIDR
Node ID Register.
Definition: axge.h:43
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
#define iob_reserve(iobuf, len)
Definition: iobuf.h:67
#define AXGE_RX_LEN_MASK
Receive packet length mask.
Definition: axge.h:109
A USB configuration descriptor.
Definition: usb.h:195
void netdev_tx_complete_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Complete network transmission.
Definition: netdevice.c:470
#define AXGE_CSR_ACS
Undocumented.
Definition: axge.h:79
uint32_t len
Length.
Definition: ena.h:14
static int axge_read_register(struct axge_device *axge, unsigned int offset, void *data, size_t len)
Read register.
Definition: axge.c:91
#define ENOBUFS
No buffer space available.
Definition: errno.h:498
#define USB_ANY_ID
Match-anything ID.
Definition: usb.h:1347
Universal Serial Bus (USB)
static void usbnet_init(struct usbnet_device *usbnet, struct usb_function *func, struct usb_endpoint_driver_operations *intr, struct usb_endpoint_driver_operations *in, struct usb_endpoint_driver_operations *out)
Initialise USB network device.
Definition: usbnet.h:44
#define AXGE_RCR_AMALL
Accept all multicasts.
Definition: axge.h:38
void * data
Start of data.
Definition: iobuf.h:48
struct usb_hub * hub
USB hub.
Definition: usb.h:800
#define EIO
Input/output error.
Definition: errno.h:433
uint16_t count
Number of entries.
Definition: ena.h:22
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition: ethernet.c:264
static struct usb_endpoint_driver_operations axge_out_operations
Bulk OUT endpoint operations.
Definition: axge.c:512
#define cpu_to_le16(value)
Definition: byteswap.h:106
unsigned int config
Device configuration.
Definition: axge.h:149
static void axge_out_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk OUT transfer.
Definition: axge.c:501
uint8_t data[48]
Additional event data.
Definition: ena.h:22
static struct usb_endpoint_driver_operations axge_in_operations
Bulk IN endpoint operations.
Definition: axge.c:459
static struct usb_device_id axge_ids[]
AXGE device IDs.
Definition: axge.c:780
#define AXGE_PLSR_EPHY_1000
Ethernet at 1000Mbps.
Definition: axge.h:29
#define AXGE_EPPRCR
Ethernet PHY Power and Reset Control Register.
Definition: axge.h:55
int usbnet_describe(struct usbnet_device *usbnet, struct usb_configuration_descriptor *config)
Describe USB network device interfaces.
Definition: usbnet.c:277
#define AXGE_MSR_TFC
TX flow control enable.
Definition: axge.h:50
uint8_t ctrl
Control.
Definition: axge.h:67
Receive packet descriptor.
Definition: axge.h:101
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
void usbnet_close(struct usbnet_device *usbnet)
Close USB network device.
Definition: usbnet.c:127
USB endpoint driver operations.
Definition: usb.h:474
struct device dev
Generic device.
Definition: usb.h:667
A USB function.
Definition: usb.h:659
static int axge_write_register(struct axge_device *axge, unsigned int offset, void *data, size_t len)
Write register.
Definition: axge.c:150
struct usb_bus * bus
USB bus.
Definition: usb.h:830
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
int iob_ensure_headroom(struct io_buffer *iobuf, size_t len)
Ensure I/O buffer has sufficient headroom.
Definition: iobuf.c:228
static int axge_write_byte(struct axge_device *axge, unsigned int offset, uint8_t value)
Write one-byte register.
Definition: axge.c:166
struct usbnet_device usbnet
USB network device.
Definition: axge.h:147
#define AXGE_IN_MTU
Bulk IN buffer size.
Definition: axge.h:170
#define AXGE_RCR_AB
Accept broadcasts.
Definition: axge.h:39
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:381
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
#define AXGE_MSR_FD
Full duplex.
Definition: axge.h:48
static int axge_read_word(struct axge_device *axge, unsigned int offset, uint16_t *value)
Read two-byte register.
Definition: axge.c:121
#define AXGE_MSR_RE
Receive enable.
Definition: axge.h:51
struct usb_device_id * ids
USB ID table.
Definition: usb.h:1383
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:33
int usbnet_open(struct usbnet_device *usbnet)
Open USB network device.
Definition: usbnet.c:54