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