You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

axge.c 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  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. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  24. #include <stdint.h>
  25. #include <string.h>
  26. #include <unistd.h>
  27. #include <errno.h>
  28. #include <ipxe/netdevice.h>
  29. #include <ipxe/ethernet.h>
  30. #include <ipxe/if_ether.h>
  31. #include <ipxe/profile.h>
  32. #include <ipxe/usb.h>
  33. #include "axge.h"
  34. /** @file
  35. *
  36. * Asix 10/100/1000 USB Ethernet driver
  37. *
  38. * Large chunks of functionality are undocumented in the available
  39. * datasheets. The gaps are deduced from combinations of the Linux
  40. * driver, the FreeBSD driver, and experimentation with the hardware.
  41. */
  42. /** Interrupt completion profiler */
  43. static struct profiler axge_intr_profiler __profiler =
  44. { .name = "axge.intr" };
  45. /** Bulk IN completion profiler */
  46. static struct profiler axge_in_profiler __profiler =
  47. { .name = "axge.in" };
  48. /** Bulk OUT profiler */
  49. static struct profiler axge_out_profiler __profiler =
  50. { .name = "axge.out" };
  51. /** Default bulk IN configuration
  52. *
  53. * The Linux and FreeBSD drivers have set of magic constants which are
  54. * chosen based on both the Ethernet and USB link speeds.
  55. *
  56. * Experimentation shows that setting the "timer" value to zero seems
  57. * to prevent the device from ever coalescing multiple packets into a
  58. * single bulk IN transfer. This allows us to get away with using a
  59. * 2kB receive I/O buffer and a zerocopy receive path.
  60. */
  61. static struct axge_bulk_in_control axge_bicr = {
  62. .ctrl = 7,
  63. .timer = cpu_to_le16 ( 0 ),
  64. .size = 0,
  65. .ifg = 0,
  66. };
  67. /******************************************************************************
  68. *
  69. * Register access
  70. *
  71. ******************************************************************************
  72. */
  73. /**
  74. * Read register
  75. *
  76. * @v asix AXGE device
  77. * @v offset Register offset
  78. * @v data Data buffer
  79. * @v len Length of data
  80. * @ret rc Return status code
  81. */
  82. static inline int axge_read_register ( struct axge_device *axge,
  83. unsigned int offset, void *data,
  84. size_t len ) {
  85. return usb_control ( axge->usb, AXGE_READ_MAC_REGISTER,
  86. offset, len, data, len );
  87. }
  88. /**
  89. * Read one-byte register
  90. *
  91. * @v asix AXGE device
  92. * @v offset Register offset
  93. * @v value Value to fill in
  94. * @ret rc Return status code
  95. */
  96. static inline int axge_read_byte ( struct axge_device *axge,
  97. unsigned int offset, uint8_t *value ) {
  98. return axge_read_register ( axge, offset, value, sizeof ( *value ) );
  99. }
  100. /**
  101. * Read two-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_word ( struct axge_device *axge,
  109. unsigned int offset, uint16_t *value ) {
  110. return axge_read_register ( axge, offset, value, sizeof ( *value ) );
  111. }
  112. /**
  113. * Read four-byte register
  114. *
  115. * @v asix AXGE device
  116. * @v offset Register offset
  117. * @v value Value to fill in
  118. * @ret rc Return status code
  119. */
  120. static inline int axge_read_dword ( struct axge_device *axge,
  121. unsigned int offset, uint32_t *value ) {
  122. return axge_read_register ( axge, offset, value, sizeof ( *value ) );
  123. }
  124. /**
  125. * Write register
  126. *
  127. * @v asix AXGE device
  128. * @v offset Register offset
  129. * @v data Data buffer
  130. * @v len Length of data
  131. * @ret rc Return status code
  132. */
  133. static inline int axge_write_register ( struct axge_device *axge,
  134. unsigned int offset, void *data,
  135. size_t len ) {
  136. return usb_control ( axge->usb, AXGE_WRITE_MAC_REGISTER,
  137. offset, len, data, len );
  138. }
  139. /**
  140. * Write one-byte register
  141. *
  142. * @v asix AXGE device
  143. * @v offset Register offset
  144. * @v value Value
  145. * @ret rc Return status code
  146. */
  147. static inline int axge_write_byte ( struct axge_device *axge,
  148. unsigned int offset, uint8_t value ) {
  149. return axge_write_register ( axge, offset, &value, sizeof ( value ));
  150. }
  151. /**
  152. * Write two-byte register
  153. *
  154. * @v asix AXGE device
  155. * @v offset Register offset
  156. * @v value Value
  157. * @ret rc Return status code
  158. */
  159. static inline int axge_write_word ( struct axge_device *axge,
  160. unsigned int offset, uint16_t value ) {
  161. return axge_write_register ( axge, offset, &value, sizeof ( value ));
  162. }
  163. /**
  164. * Write one-byte register
  165. *
  166. * @v asix AXGE device
  167. * @v offset Register offset
  168. * @v value Value
  169. * @ret rc Return status code
  170. */
  171. static inline int axge_write_dword ( struct axge_device *axge,
  172. unsigned int offset, uint32_t value ) {
  173. return axge_write_register ( axge, offset, &value, sizeof ( value ));
  174. }
  175. /******************************************************************************
  176. *
  177. * Link status
  178. *
  179. ******************************************************************************
  180. */
  181. /**
  182. * Get link status
  183. *
  184. * @v asix AXGE device
  185. * @ret rc Return status code
  186. */
  187. static int axge_check_link ( struct axge_device *axge ) {
  188. struct net_device *netdev = axge->netdev;
  189. uint8_t plsr;
  190. int rc;
  191. /* Read physical link status register */
  192. if ( ( rc = axge_read_byte ( axge, AXGE_PLSR, &plsr ) ) != 0 ) {
  193. DBGC ( axge, "AXGE %p could not read PLSR: %s\n",
  194. axge, strerror ( rc ) );
  195. return rc;
  196. }
  197. /* Update link status */
  198. if ( plsr & AXGE_PLSR_EPHY_ANY ) {
  199. DBGC ( axge, "AXGE %p link up (PLSR %02x)\n", axge, plsr );
  200. netdev_link_up ( netdev );
  201. } else {
  202. DBGC ( axge, "AXGE %p link down (PLSR %02x)\n", axge, plsr );
  203. netdev_link_down ( netdev );
  204. }
  205. return 0;
  206. }
  207. /******************************************************************************
  208. *
  209. * AXGE communications interface
  210. *
  211. ******************************************************************************
  212. */
  213. /**
  214. * Complete interrupt transfer
  215. *
  216. * @v ep USB endpoint
  217. * @v iobuf I/O buffer
  218. * @v rc Completion status code
  219. */
  220. static void axge_intr_complete ( struct usb_endpoint *ep,
  221. struct io_buffer *iobuf, int rc ) {
  222. struct axge_device *axge = container_of ( ep, struct axge_device,
  223. usbnet.intr );
  224. struct net_device *netdev = axge->netdev;
  225. struct axge_interrupt *intr;
  226. size_t len = iob_len ( iobuf );
  227. unsigned int link_ok;
  228. /* Profile completions */
  229. profile_start ( &axge_intr_profiler );
  230. /* Ignore packets cancelled when the endpoint closes */
  231. if ( ! ep->open )
  232. goto ignore;
  233. /* Drop packets with errors */
  234. if ( rc != 0 ) {
  235. DBGC ( axge, "AXGE %p interrupt failed: %s\n",
  236. axge, strerror ( rc ) );
  237. DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
  238. goto error;
  239. }
  240. /* Extract message header */
  241. if ( len < sizeof ( *intr ) ) {
  242. DBGC ( axge, "AXGE %p underlength interrupt:\n", axge );
  243. DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
  244. rc = -EINVAL;
  245. goto error;
  246. }
  247. intr = iobuf->data;
  248. /* Check magic signature */
  249. if ( intr->magic != cpu_to_le16 ( AXGE_INTR_MAGIC ) ) {
  250. DBGC ( axge, "AXGE %p malformed interrupt:\n", axge );
  251. DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
  252. rc = -EINVAL;
  253. goto error;
  254. }
  255. /* Extract link status */
  256. link_ok = ( intr->link & cpu_to_le16 ( AXGE_INTR_LINK_PPLS ) );
  257. if ( link_ok && ! netdev_link_ok ( netdev ) ) {
  258. DBGC ( axge, "AXGE %p link up\n", axge );
  259. netdev_link_up ( netdev );
  260. } else if ( netdev_link_ok ( netdev ) && ! link_ok ) {
  261. DBGC ( axge, "AXGE %p link down\n", axge );
  262. netdev_link_down ( netdev );
  263. }
  264. /* Free I/O buffer */
  265. free_iob ( iobuf );
  266. profile_stop ( &axge_intr_profiler );
  267. return;
  268. error:
  269. netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
  270. ignore:
  271. free_iob ( iobuf );
  272. return;
  273. }
  274. /** Interrupt endpoint operations */
  275. static struct usb_endpoint_driver_operations axge_intr_operations = {
  276. .complete = axge_intr_complete,
  277. };
  278. /******************************************************************************
  279. *
  280. * AXGE data interface
  281. *
  282. ******************************************************************************
  283. */
  284. /**
  285. * Complete bulk IN transfer
  286. *
  287. * @v ep USB endpoint
  288. * @v iobuf I/O buffer
  289. * @v rc Completion status code
  290. */
  291. static void axge_in_complete ( struct usb_endpoint *ep,
  292. struct io_buffer *iobuf, int rc ) {
  293. struct axge_device *axge = container_of ( ep, struct axge_device,
  294. usbnet.in );
  295. struct net_device *netdev = axge->netdev;
  296. struct axge_rx_footer *ftr;
  297. struct axge_rx_descriptor *desc;
  298. struct io_buffer *pkt;
  299. unsigned int count;
  300. unsigned int offset;
  301. size_t len;
  302. size_t padded_len;
  303. /* Profile receive completions */
  304. profile_start ( &axge_in_profiler );
  305. /* Ignore packets cancelled when the endpoint closes */
  306. if ( ! ep->open )
  307. goto ignore;
  308. /* Record USB errors against the network device */
  309. if ( rc != 0 ) {
  310. DBGC ( axge, "AXGE %p bulk IN failed: %s\n",
  311. axge, strerror ( rc ) );
  312. goto error;
  313. }
  314. /* Sanity check */
  315. if ( iob_len ( iobuf ) < sizeof ( *ftr ) ) {
  316. DBGC ( axge, "AXGE %p underlength bulk IN:\n", axge );
  317. DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
  318. rc = -EINVAL;
  319. goto error;
  320. }
  321. /* Parse ftr, strip ftr and descriptors */
  322. iob_unput ( iobuf, sizeof ( *ftr ) );
  323. ftr = ( iobuf->data + iob_len ( iobuf ) );
  324. count = le16_to_cpu ( ftr->count );
  325. if ( count == 0 ) {
  326. DBGC ( axge, "AXGE %p zero-packet bulk IN:\n", axge );
  327. DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
  328. goto ignore;
  329. }
  330. offset = le16_to_cpu ( ftr->offset );
  331. if ( ( iob_len ( iobuf ) < offset ) ||
  332. ( ( iob_len ( iobuf ) - offset ) < ( count * sizeof ( *desc ) ) )){
  333. DBGC ( axge, "AXGE %p malformed bulk IN footer:\n", axge );
  334. DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
  335. rc = -EINVAL;
  336. goto error;
  337. }
  338. desc = ( iobuf->data + offset );
  339. iob_unput ( iobuf, ( iob_len ( iobuf ) - offset ) );
  340. /* Process packets */
  341. for ( ; count-- ; desc++ ) {
  342. /* Parse descriptor */
  343. len = ( le16_to_cpu ( desc->len_flags ) & AXGE_RX_LEN_MASK );
  344. padded_len = ( ( len + AXGE_RX_LEN_PAD_ALIGN - 1 ) &
  345. ~( AXGE_RX_LEN_PAD_ALIGN - 1 ) );
  346. if ( iob_len ( iobuf ) < padded_len ) {
  347. DBGC ( axge, "AXGE %p malformed bulk IN descriptor:\n",
  348. axge );
  349. DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
  350. rc = -EINVAL;
  351. goto error;
  352. }
  353. /* Check for previous dropped packets */
  354. if ( desc->len_flags & cpu_to_le16 ( AXGE_RX_CRC_ERROR ) )
  355. netdev_rx_err ( netdev, NULL, -EIO );
  356. if ( desc->len_flags & cpu_to_le16 ( AXGE_RX_DROP_ERROR ) )
  357. netdev_rx_err ( netdev, NULL, -ENOBUFS );
  358. /* Allocate new I/O buffer, if applicable */
  359. if ( count ) {
  360. /* More packets remain: allocate a new buffer */
  361. pkt = alloc_iob ( AXGE_IN_RESERVE + len );
  362. if ( ! pkt ) {
  363. /* Record error and continue */
  364. netdev_rx_err ( netdev, NULL, -ENOMEM );
  365. iob_pull ( iobuf, padded_len );
  366. continue;
  367. }
  368. iob_reserve ( pkt, AXGE_IN_RESERVE );
  369. memcpy ( iob_put ( pkt, len ), iobuf->data, len );
  370. iob_pull ( iobuf, padded_len );
  371. } else {
  372. /* This is the last (or only) packet: use this buffer */
  373. iob_unput ( iobuf, ( padded_len - len ) );
  374. pkt = iob_disown ( iobuf );
  375. }
  376. /* Hand off to network stack */
  377. netdev_rx ( netdev, iob_disown ( pkt ) );
  378. }
  379. assert ( iobuf == NULL );
  380. profile_stop ( &axge_in_profiler );
  381. return;
  382. error:
  383. netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
  384. ignore:
  385. free_iob ( iobuf );
  386. }
  387. /** Bulk IN endpoint operations */
  388. static struct usb_endpoint_driver_operations axge_in_operations = {
  389. .complete = axge_in_complete,
  390. };
  391. /**
  392. * Transmit packet
  393. *
  394. * @v asix AXGE device
  395. * @v iobuf I/O buffer
  396. * @ret rc Return status code
  397. */
  398. static int axge_out_transmit ( struct axge_device *axge,
  399. struct io_buffer *iobuf ) {
  400. struct axge_tx_header *hdr;
  401. size_t len = iob_len ( iobuf );
  402. int rc;
  403. /* Profile transmissions */
  404. profile_start ( &axge_out_profiler );
  405. /* Prepend header */
  406. if ( ( rc = iob_ensure_headroom ( iobuf, sizeof ( *hdr ) ) ) != 0 )
  407. return rc;
  408. hdr = iob_push ( iobuf, sizeof ( *hdr ) );
  409. hdr->len = cpu_to_le32 ( len );
  410. hdr->wtf = 0;
  411. /* Enqueue I/O buffer */
  412. if ( ( rc = usb_stream ( &axge->usbnet.out, iobuf, 0 ) ) != 0 )
  413. return rc;
  414. profile_stop ( &axge_out_profiler );
  415. return 0;
  416. }
  417. /**
  418. * Complete bulk OUT transfer
  419. *
  420. * @v ep USB endpoint
  421. * @v iobuf I/O buffer
  422. * @v rc Completion status code
  423. */
  424. static void axge_out_complete ( struct usb_endpoint *ep,
  425. struct io_buffer *iobuf, int rc ) {
  426. struct axge_device *axge = container_of ( ep, struct axge_device,
  427. usbnet.out );
  428. struct net_device *netdev = axge->netdev;
  429. /* Report TX completion */
  430. netdev_tx_complete_err ( netdev, iobuf, rc );
  431. }
  432. /** Bulk OUT endpoint operations */
  433. static struct usb_endpoint_driver_operations axge_out_operations = {
  434. .complete = axge_out_complete,
  435. };
  436. /******************************************************************************
  437. *
  438. * Network device interface
  439. *
  440. ******************************************************************************
  441. */
  442. /**
  443. * Open network device
  444. *
  445. * @v netdev Network device
  446. * @ret rc Return status code
  447. */
  448. static int axge_open ( struct net_device *netdev ) {
  449. struct axge_device *axge = netdev->priv;
  450. uint16_t rcr;
  451. int rc;
  452. /* Open USB network device */
  453. if ( ( rc = usbnet_open ( &axge->usbnet ) ) != 0 ) {
  454. DBGC ( axge, "AXGE %p could not open: %s\n",
  455. axge, strerror ( rc ) );
  456. goto err_open;
  457. }
  458. /* Set MAC address */
  459. if ( ( rc = axge_write_register ( axge, AXGE_NIDR,
  460. netdev->ll_addr, ETH_ALEN ) ) !=0){
  461. DBGC ( axge, "AXGE %p could not set MAC address: %s\n",
  462. axge, strerror ( rc ) );
  463. goto err_write_mac;
  464. }
  465. /* Enable receiver */
  466. rcr = cpu_to_le16 ( AXGE_RCR_PRO | AXGE_RCR_AMALL |
  467. AXGE_RCR_AB | AXGE_RCR_SO );
  468. if ( ( rc = axge_write_word ( axge, AXGE_RCR, rcr ) ) != 0 ) {
  469. DBGC ( axge, "AXGE %p could not write RCR: %s\n",
  470. axge, strerror ( rc ) );
  471. goto err_write_rcr;
  472. }
  473. /* Update link status */
  474. axge_check_link ( axge );
  475. return 0;
  476. axge_write_word ( axge, AXGE_RCR, 0 );
  477. err_write_rcr:
  478. err_write_mac:
  479. usbnet_close ( &axge->usbnet );
  480. err_open:
  481. return rc;
  482. }
  483. /**
  484. * Close network device
  485. *
  486. * @v netdev Network device
  487. */
  488. static void axge_close ( struct net_device *netdev ) {
  489. struct axge_device *axge = netdev->priv;
  490. /* Disable receiver */
  491. axge_write_word ( axge, AXGE_RCR, 0 );
  492. /* Close USB network device */
  493. usbnet_close ( &axge->usbnet );
  494. }
  495. /**
  496. * Transmit packet
  497. *
  498. * @v netdev Network device
  499. * @v iobuf I/O buffer
  500. * @ret rc Return status code
  501. */
  502. static int axge_transmit ( struct net_device *netdev,
  503. struct io_buffer *iobuf ) {
  504. struct axge_device *axge = netdev->priv;
  505. int rc;
  506. /* Transmit packet */
  507. if ( ( rc = axge_out_transmit ( axge, iobuf ) ) != 0 )
  508. return rc;
  509. return 0;
  510. }
  511. /**
  512. * Poll for completed and received packets
  513. *
  514. * @v netdev Network device
  515. */
  516. static void axge_poll ( struct net_device *netdev ) {
  517. struct axge_device *axge = netdev->priv;
  518. int rc;
  519. /* Poll USB bus */
  520. usb_poll ( axge->bus );
  521. /* Refill endpoints */
  522. if ( ( rc = usbnet_refill ( &axge->usbnet ) ) != 0 )
  523. netdev_rx_err ( netdev, NULL, rc );
  524. }
  525. /** AXGE network device operations */
  526. static struct net_device_operations axge_operations = {
  527. .open = axge_open,
  528. .close = axge_close,
  529. .transmit = axge_transmit,
  530. .poll = axge_poll,
  531. };
  532. /******************************************************************************
  533. *
  534. * USB interface
  535. *
  536. ******************************************************************************
  537. */
  538. /**
  539. * Probe device
  540. *
  541. * @v func USB function
  542. * @v config Configuration descriptor
  543. * @ret rc Return status code
  544. */
  545. static int axge_probe ( struct usb_function *func,
  546. struct usb_configuration_descriptor *config ) {
  547. struct usb_device *usb = func->usb;
  548. struct net_device *netdev;
  549. struct axge_device *axge;
  550. uint16_t epprcr;
  551. uint16_t msr;
  552. uint8_t csr;
  553. int rc;
  554. /* Allocate and initialise structure */
  555. netdev = alloc_etherdev ( sizeof ( *axge ) );
  556. if ( ! netdev ) {
  557. rc = -ENOMEM;
  558. goto err_alloc;
  559. }
  560. netdev_init ( netdev, &axge_operations );
  561. netdev->dev = &func->dev;
  562. axge = netdev->priv;
  563. memset ( axge, 0, sizeof ( *axge ) );
  564. axge->usb = usb;
  565. axge->bus = usb->port->hub->bus;
  566. axge->netdev = netdev;
  567. usbnet_init ( &axge->usbnet, func, &axge_intr_operations,
  568. &axge_in_operations, &axge_out_operations );
  569. usb_refill_init ( &axge->usbnet.intr, 0, 0, AXGE_INTR_MAX_FILL );
  570. usb_refill_init ( &axge->usbnet.in, AXGE_IN_RESERVE,
  571. AXGE_IN_MTU, AXGE_IN_MAX_FILL );
  572. DBGC ( axge, "AXGE %p on %s\n", axge, func->name );
  573. /* Describe USB network device */
  574. if ( ( rc = usbnet_describe ( &axge->usbnet, config ) ) != 0 ) {
  575. DBGC ( axge, "AXGE %p could not describe: %s\n",
  576. axge, strerror ( rc ) );
  577. goto err_describe;
  578. }
  579. /* Fetch MAC address */
  580. if ( ( rc = axge_read_register ( axge, AXGE_NIDR, netdev->hw_addr,
  581. ETH_ALEN ) ) != 0 ) {
  582. DBGC ( axge, "AXGE %p could not fetch MAC address: %s\n",
  583. axge, strerror ( rc ) );
  584. goto err_read_mac;
  585. }
  586. /* Power up PHY */
  587. if ( ( rc = axge_write_word ( axge, AXGE_EPPRCR, 0 ) ) != 0 ) {
  588. DBGC ( axge, "AXGE %p could not write EPPRCR: %s\n",
  589. axge, strerror ( rc ) );
  590. goto err_write_epprcr_off;
  591. }
  592. epprcr = cpu_to_le16 ( AXGE_EPPRCR_IPRL );
  593. if ( ( rc = axge_write_word ( axge, AXGE_EPPRCR, epprcr ) ) != 0){
  594. DBGC ( axge, "AXGE %p could not write EPPRCR: %s\n",
  595. axge, strerror ( rc ) );
  596. goto err_write_epprcr_on;
  597. }
  598. mdelay ( AXGE_EPPRCR_DELAY_MS );
  599. /* Select clocks */
  600. csr = ( AXGE_CSR_BCS | AXGE_CSR_ACS );
  601. if ( ( rc = axge_write_byte ( axge, AXGE_CSR, csr ) ) != 0){
  602. DBGC ( axge, "AXGE %p could not write CSR: %s\n",
  603. axge, strerror ( rc ) );
  604. goto err_write_csr;
  605. }
  606. mdelay ( AXGE_CSR_DELAY_MS );
  607. /* Configure bulk IN pipeline */
  608. if ( ( rc = axge_write_register ( axge, AXGE_BICR, &axge_bicr,
  609. sizeof ( axge_bicr ) ) ) != 0 ){
  610. DBGC ( axge, "AXGE %p could not write BICR: %s\n",
  611. axge, strerror ( rc ) );
  612. goto err_write_bicr;
  613. }
  614. /* Set medium status */
  615. msr = cpu_to_le16 ( AXGE_MSR_GM | AXGE_MSR_FD | AXGE_MSR_RFC |
  616. AXGE_MSR_TFC | AXGE_MSR_RE );
  617. if ( ( rc = axge_write_word ( axge, AXGE_MSR, msr ) ) != 0 ) {
  618. DBGC ( axge, "AXGE %p could not write MSR: %s\n",
  619. axge, strerror ( rc ) );
  620. goto err_write_msr;
  621. }
  622. /* Register network device */
  623. if ( ( rc = register_netdev ( netdev ) ) != 0 )
  624. goto err_register;
  625. /* Update link status */
  626. axge_check_link ( axge );
  627. usb_func_set_drvdata ( func, axge );
  628. return 0;
  629. unregister_netdev ( netdev );
  630. err_register:
  631. err_write_msr:
  632. err_write_bicr:
  633. err_write_csr:
  634. err_write_epprcr_on:
  635. err_write_epprcr_off:
  636. err_read_mac:
  637. err_describe:
  638. netdev_nullify ( netdev );
  639. netdev_put ( netdev );
  640. err_alloc:
  641. return rc;
  642. }
  643. /**
  644. * Remove device
  645. *
  646. * @v func USB function
  647. */
  648. static void axge_remove ( struct usb_function *func ) {
  649. struct axge_device *axge = usb_func_get_drvdata ( func );
  650. struct net_device *netdev = axge->netdev;
  651. unregister_netdev ( netdev );
  652. netdev_nullify ( netdev );
  653. netdev_put ( netdev );
  654. }
  655. /** AXGE device IDs */
  656. static struct usb_device_id axge_ids[] = {
  657. {
  658. .name = "ax88179",
  659. .vendor = 0x0b95,
  660. .product = 0x1790,
  661. },
  662. {
  663. .name = "ax88178a",
  664. .vendor = 0x0b95,
  665. .product = 0x178a,
  666. },
  667. {
  668. .name = "dub1312",
  669. .vendor = 0x2001,
  670. .product = 0x4a00,
  671. },
  672. {
  673. .name = "axge-sitecom",
  674. .vendor = 0x0df6,
  675. .product = 0x0072,
  676. },
  677. {
  678. .name = "axge-samsung",
  679. .vendor = 0x04e8,
  680. .product = 0xa100,
  681. },
  682. {
  683. .name = "onelinkdock",
  684. .vendor = 0x17ef,
  685. .product = 0x304b,
  686. },
  687. };
  688. /** AXGE driver */
  689. struct usb_driver axge_driver __usb_driver = {
  690. .ids = axge_ids,
  691. .id_count = ( sizeof ( axge_ids ) / sizeof ( axge_ids[0] ) ),
  692. .class = USB_CLASS_ID ( USB_ANY_ID, USB_ANY_ID, USB_ANY_ID ),
  693. .score = USB_SCORE_NORMAL,
  694. .probe = axge_probe,
  695. .remove = axge_remove,
  696. };