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.

dm96xx.c 15KB

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