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.

smscusb.c 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. /*
  2. * Copyright (C) 2017 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 <errno.h>
  26. #include <unistd.h>
  27. #include <ipxe/usb.h>
  28. #include <ipxe/usbnet.h>
  29. #include <ipxe/ethernet.h>
  30. #include <ipxe/profile.h>
  31. #include "smscusb.h"
  32. /** @file
  33. *
  34. * SMSC USB Ethernet drivers
  35. *
  36. */
  37. /** Interrupt completion profiler */
  38. static struct profiler smscusb_intr_profiler __profiler =
  39. { .name = "smscusb.intr" };
  40. /******************************************************************************
  41. *
  42. * EEPROM access
  43. *
  44. ******************************************************************************
  45. */
  46. /**
  47. * Wait for EEPROM to become idle
  48. *
  49. * @v smscusb SMSC USB device
  50. * @v e2p_base E2P register base
  51. * @ret rc Return status code
  52. */
  53. static int smscusb_eeprom_wait ( struct smscusb_device *smscusb,
  54. unsigned int e2p_base ) {
  55. uint32_t e2p_cmd;
  56. unsigned int i;
  57. int rc;
  58. /* Wait for EPC_BSY to become clear */
  59. for ( i = 0 ; i < SMSCUSB_EEPROM_MAX_WAIT_MS ; i++ ) {
  60. /* Read E2P_CMD and check EPC_BSY */
  61. if ( ( rc = smscusb_readl ( smscusb,
  62. ( e2p_base + SMSCUSB_E2P_CMD ),
  63. &e2p_cmd ) ) != 0 )
  64. return rc;
  65. if ( ! ( e2p_cmd & SMSCUSB_E2P_CMD_EPC_BSY ) )
  66. return 0;
  67. /* Delay */
  68. mdelay ( 1 );
  69. }
  70. DBGC ( smscusb, "SMSCUSB %p timed out waiting for EEPROM\n",
  71. smscusb );
  72. return -ETIMEDOUT;
  73. }
  74. /**
  75. * Read byte from EEPROM
  76. *
  77. * @v smscusb SMSC USB device
  78. * @v e2p_base E2P register base
  79. * @v address EEPROM address
  80. * @ret byte Byte read, or negative error
  81. */
  82. static int smscusb_eeprom_read_byte ( struct smscusb_device *smscusb,
  83. unsigned int e2p_base,
  84. unsigned int address ) {
  85. uint32_t e2p_cmd;
  86. uint32_t e2p_data;
  87. int rc;
  88. /* Wait for EEPROM to become idle */
  89. if ( ( rc = smscusb_eeprom_wait ( smscusb, e2p_base ) ) != 0 )
  90. return rc;
  91. /* Initiate read command */
  92. e2p_cmd = ( SMSCUSB_E2P_CMD_EPC_BSY | SMSCUSB_E2P_CMD_EPC_CMD_READ |
  93. SMSCUSB_E2P_CMD_EPC_ADDR ( address ) );
  94. if ( ( rc = smscusb_writel ( smscusb, ( e2p_base + SMSCUSB_E2P_CMD ),
  95. e2p_cmd ) ) != 0 )
  96. return rc;
  97. /* Wait for command to complete */
  98. if ( ( rc = smscusb_eeprom_wait ( smscusb, e2p_base ) ) != 0 )
  99. return rc;
  100. /* Read EEPROM data */
  101. if ( ( rc = smscusb_readl ( smscusb, ( e2p_base + SMSCUSB_E2P_DATA ),
  102. &e2p_data ) ) != 0 )
  103. return rc;
  104. return SMSCUSB_E2P_DATA_GET ( e2p_data );
  105. }
  106. /**
  107. * Read data from EEPROM
  108. *
  109. * @v smscusb SMSC USB device
  110. * @v e2p_base E2P register base
  111. * @v address EEPROM address
  112. * @v data Data buffer
  113. * @v len Length of data
  114. * @ret rc Return status code
  115. */
  116. static int smscusb_eeprom_read ( struct smscusb_device *smscusb,
  117. unsigned int e2p_base, unsigned int address,
  118. void *data, size_t len ) {
  119. uint8_t *bytes;
  120. int byte;
  121. /* Read bytes */
  122. for ( bytes = data ; len-- ; address++, bytes++ ) {
  123. byte = smscusb_eeprom_read_byte ( smscusb, e2p_base, address );
  124. if ( byte < 0 )
  125. return byte;
  126. *bytes = byte;
  127. }
  128. return 0;
  129. }
  130. /**
  131. * Fetch MAC address from EEPROM
  132. *
  133. * @v smscusb SMSC USB device
  134. * @v e2p_base E2P register base
  135. * @ret rc Return status code
  136. */
  137. int smscusb_eeprom_fetch_mac ( struct smscusb_device *smscusb,
  138. unsigned int e2p_base ) {
  139. struct net_device *netdev = smscusb->netdev;
  140. int rc;
  141. /* Read MAC address from EEPROM */
  142. if ( ( rc = smscusb_eeprom_read ( smscusb, e2p_base, SMSCUSB_EEPROM_MAC,
  143. netdev->hw_addr, ETH_ALEN ) ) != 0 )
  144. return rc;
  145. /* Check that EEPROM is physically present */
  146. if ( ! is_valid_ether_addr ( netdev->hw_addr ) ) {
  147. DBGC ( smscusb, "SMSCUSB %p has no EEPROM MAC (%s)\n",
  148. smscusb, eth_ntoa ( netdev->hw_addr ) );
  149. return -ENODEV;
  150. }
  151. DBGC ( smscusb, "SMSCUSB %p using EEPROM MAC %s\n",
  152. smscusb, eth_ntoa ( netdev->hw_addr ) );
  153. return 0;
  154. }
  155. /******************************************************************************
  156. *
  157. * OTP access
  158. *
  159. ******************************************************************************
  160. */
  161. /**
  162. * Power up OTP
  163. *
  164. * @v smscusb SMSC USB device
  165. * @v otp_base OTP register base
  166. * @ret rc Return status code
  167. */
  168. static int smscusb_otp_power_up ( struct smscusb_device *smscusb,
  169. unsigned int otp_base ) {
  170. uint32_t otp_power;
  171. unsigned int i;
  172. int rc;
  173. /* Power up OTP */
  174. if ( ( rc = smscusb_writel ( smscusb, ( otp_base + SMSCUSB_OTP_POWER ),
  175. 0 ) ) != 0 )
  176. return rc;
  177. /* Wait for OTP_POWER_DOWN to become clear */
  178. for ( i = 0 ; i < SMSCUSB_OTP_MAX_WAIT_MS ; i++ ) {
  179. /* Read OTP_POWER and check OTP_POWER_DOWN */
  180. if ( ( rc = smscusb_readl ( smscusb,
  181. ( otp_base + SMSCUSB_OTP_POWER ),
  182. &otp_power ) ) != 0 )
  183. return rc;
  184. if ( ! ( otp_power & SMSCUSB_OTP_POWER_DOWN ) )
  185. return 0;
  186. /* Delay */
  187. mdelay ( 1 );
  188. }
  189. DBGC ( smscusb, "SMSCUSB %p timed out waiting for OTP power up\n",
  190. smscusb );
  191. return -ETIMEDOUT;
  192. }
  193. /**
  194. * Wait for OTP to become idle
  195. *
  196. * @v smscusb SMSC USB device
  197. * @v otp_base OTP register base
  198. * @ret rc Return status code
  199. */
  200. static int smscusb_otp_wait ( struct smscusb_device *smscusb,
  201. unsigned int otp_base ) {
  202. uint32_t otp_status;
  203. unsigned int i;
  204. int rc;
  205. /* Wait for OTP_STATUS_BUSY to become clear */
  206. for ( i = 0 ; i < SMSCUSB_OTP_MAX_WAIT_MS ; i++ ) {
  207. /* Read OTP_STATUS and check OTP_STATUS_BUSY */
  208. if ( ( rc = smscusb_readl ( smscusb,
  209. ( otp_base + SMSCUSB_OTP_STATUS ),
  210. &otp_status ) ) != 0 )
  211. return rc;
  212. if ( ! ( otp_status & SMSCUSB_OTP_STATUS_BUSY ) )
  213. return 0;
  214. /* Delay */
  215. mdelay ( 1 );
  216. }
  217. DBGC ( smscusb, "SMSCUSB %p timed out waiting for OTP\n",
  218. smscusb );
  219. return -ETIMEDOUT;
  220. }
  221. /**
  222. * Read byte from OTP
  223. *
  224. * @v smscusb SMSC USB device
  225. * @v otp_base OTP register base
  226. * @v address OTP address
  227. * @ret byte Byte read, or negative error
  228. */
  229. static int smscusb_otp_read_byte ( struct smscusb_device *smscusb,
  230. unsigned int otp_base,
  231. unsigned int address ) {
  232. uint8_t addrh = ( address >> 8 );
  233. uint8_t addrl = ( address >> 0 );
  234. uint32_t otp_data;
  235. int rc;
  236. /* Wait for OTP to become idle */
  237. if ( ( rc = smscusb_otp_wait ( smscusb, otp_base ) ) != 0 )
  238. return rc;
  239. /* Initiate read command */
  240. if ( ( rc = smscusb_writel ( smscusb, ( otp_base + SMSCUSB_OTP_ADDRH ),
  241. addrh ) ) != 0 )
  242. return rc;
  243. if ( ( rc = smscusb_writel ( smscusb, ( otp_base + SMSCUSB_OTP_ADDRL ),
  244. addrl ) ) != 0 )
  245. return rc;
  246. if ( ( rc = smscusb_writel ( smscusb, ( otp_base + SMSCUSB_OTP_CMD ),
  247. SMSCUSB_OTP_CMD_READ ) ) != 0 )
  248. return rc;
  249. if ( ( rc = smscusb_writel ( smscusb, ( otp_base + SMSCUSB_OTP_GO ),
  250. SMSCUSB_OTP_GO_GO ) ) != 0 )
  251. return rc;
  252. /* Wait for command to complete */
  253. if ( ( rc = smscusb_otp_wait ( smscusb, otp_base ) ) != 0 )
  254. return rc;
  255. /* Read OTP data */
  256. if ( ( rc = smscusb_readl ( smscusb, ( otp_base + SMSCUSB_OTP_DATA ),
  257. &otp_data ) ) != 0 )
  258. return rc;
  259. return SMSCUSB_OTP_DATA_GET ( otp_data );
  260. }
  261. /**
  262. * Read data from OTP
  263. *
  264. * @v smscusb SMSC USB device
  265. * @v otp_base OTP register base
  266. * @v address OTP address
  267. * @v data Data buffer
  268. * @v len Length of data
  269. * @ret rc Return status code
  270. */
  271. static int smscusb_otp_read ( struct smscusb_device *smscusb,
  272. unsigned int otp_base, unsigned int address,
  273. void *data, size_t len ) {
  274. uint8_t *bytes;
  275. int byte;
  276. int rc;
  277. /* Power up OTP */
  278. if ( ( rc = smscusb_otp_power_up ( smscusb, otp_base ) ) != 0 )
  279. return rc;
  280. /* Read bytes */
  281. for ( bytes = data ; len-- ; address++, bytes++ ) {
  282. byte = smscusb_otp_read_byte ( smscusb, otp_base, address );
  283. if ( byte < 0 )
  284. return byte;
  285. *bytes = byte;
  286. }
  287. return 0;
  288. }
  289. /**
  290. * Fetch MAC address from OTP
  291. *
  292. * @v smscusb SMSC USB device
  293. * @v otp_base OTP register base
  294. * @ret rc Return status code
  295. */
  296. int smscusb_otp_fetch_mac ( struct smscusb_device *smscusb,
  297. unsigned int otp_base ) {
  298. struct net_device *netdev = smscusb->netdev;
  299. uint8_t signature;
  300. unsigned int address;
  301. int rc;
  302. /* Read OTP signature byte */
  303. if ( ( rc = smscusb_otp_read ( smscusb, otp_base, 0, &signature,
  304. sizeof ( signature ) ) ) != 0 )
  305. return rc;
  306. /* Determine location of MAC address */
  307. switch ( signature ) {
  308. case SMSCUSB_OTP_1_SIG:
  309. address = SMSCUSB_OTP_1_MAC;
  310. break;
  311. case SMSCUSB_OTP_2_SIG:
  312. address = SMSCUSB_OTP_2_MAC;
  313. break;
  314. default:
  315. DBGC ( smscusb, "SMSCUSB %p unknown OTP signature %#02x\n",
  316. smscusb, signature );
  317. return -ENOTSUP;
  318. }
  319. /* Read MAC address from OTP */
  320. if ( ( rc = smscusb_otp_read ( smscusb, otp_base, address,
  321. netdev->hw_addr, ETH_ALEN ) ) != 0 )
  322. return rc;
  323. /* Check that OTP is valid */
  324. if ( ! is_valid_ether_addr ( netdev->hw_addr ) ) {
  325. DBGC ( smscusb, "SMSCUSB %p has no layout %#02x OTP MAC (%s)\n",
  326. smscusb, signature, eth_ntoa ( netdev->hw_addr ) );
  327. return -ENODEV;
  328. }
  329. DBGC ( smscusb, "SMSCUSB %p using layout %#02x OTP MAC %s\n",
  330. smscusb, signature, eth_ntoa ( netdev->hw_addr ) );
  331. return 0;
  332. }
  333. /******************************************************************************
  334. *
  335. * MII access
  336. *
  337. ******************************************************************************
  338. */
  339. /**
  340. * Wait for MII to become idle
  341. *
  342. * @v smscusb SMSC USB device
  343. * @ret rc Return status code
  344. */
  345. static int smscusb_mii_wait ( struct smscusb_device *smscusb ) {
  346. unsigned int base = smscusb->mii_base;
  347. uint32_t mii_access;
  348. unsigned int i;
  349. int rc;
  350. /* Wait for MIIBZY to become clear */
  351. for ( i = 0 ; i < SMSCUSB_MII_MAX_WAIT_MS ; i++ ) {
  352. /* Read MII_ACCESS and check MIIBZY */
  353. if ( ( rc = smscusb_readl ( smscusb,
  354. ( base + SMSCUSB_MII_ACCESS ),
  355. &mii_access ) ) != 0 )
  356. return rc;
  357. if ( ! ( mii_access & SMSCUSB_MII_ACCESS_MIIBZY ) )
  358. return 0;
  359. /* Delay */
  360. mdelay ( 1 );
  361. }
  362. DBGC ( smscusb, "SMSCUSB %p timed out waiting for MII\n",
  363. smscusb );
  364. return -ETIMEDOUT;
  365. }
  366. /**
  367. * Read from MII register
  368. *
  369. * @v mii MII interface
  370. * @v reg Register address
  371. * @ret value Data read, or negative error
  372. */
  373. static int smscusb_mii_read ( struct mii_interface *mii, unsigned int reg ) {
  374. struct smscusb_device *smscusb =
  375. container_of ( mii, struct smscusb_device, mii );
  376. unsigned int base = smscusb->mii_base;
  377. uint32_t mii_access;
  378. uint32_t mii_data;
  379. int rc;
  380. /* Wait for MII to become idle */
  381. if ( ( rc = smscusb_mii_wait ( smscusb ) ) != 0 )
  382. return rc;
  383. /* Initiate read command */
  384. mii_access = ( SMSCUSB_MII_ACCESS_PHY_ADDRESS |
  385. SMSCUSB_MII_ACCESS_MIIRINDA ( reg ) |
  386. SMSCUSB_MII_ACCESS_MIIBZY );
  387. if ( ( rc = smscusb_writel ( smscusb, ( base + SMSCUSB_MII_ACCESS ),
  388. mii_access ) ) != 0 )
  389. return rc;
  390. /* Wait for command to complete */
  391. if ( ( rc = smscusb_mii_wait ( smscusb ) ) != 0 )
  392. return rc;
  393. /* Read MII data */
  394. if ( ( rc = smscusb_readl ( smscusb, ( base + SMSCUSB_MII_DATA ),
  395. &mii_data ) ) != 0 )
  396. return rc;
  397. return SMSCUSB_MII_DATA_GET ( mii_data );
  398. }
  399. /**
  400. * Write to MII register
  401. *
  402. * @v mii MII interface
  403. * @v reg Register address
  404. * @v data Data to write
  405. * @ret rc Return status code
  406. */
  407. static int smscusb_mii_write ( struct mii_interface *mii, unsigned int reg,
  408. unsigned int data ) {
  409. struct smscusb_device *smscusb =
  410. container_of ( mii, struct smscusb_device, mii );
  411. unsigned int base = smscusb->mii_base;
  412. uint32_t mii_access;
  413. uint32_t mii_data;
  414. int rc;
  415. /* Wait for MII to become idle */
  416. if ( ( rc = smscusb_mii_wait ( smscusb ) ) != 0 )
  417. return rc;
  418. /* Write MII data */
  419. mii_data = SMSCUSB_MII_DATA_SET ( data );
  420. if ( ( rc = smscusb_writel ( smscusb, ( base + SMSCUSB_MII_DATA ),
  421. mii_data ) ) != 0 )
  422. return rc;
  423. /* Initiate write command */
  424. mii_access = ( SMSCUSB_MII_ACCESS_PHY_ADDRESS |
  425. SMSCUSB_MII_ACCESS_MIIRINDA ( reg ) |
  426. SMSCUSB_MII_ACCESS_MIIWNR |
  427. SMSCUSB_MII_ACCESS_MIIBZY );
  428. if ( ( rc = smscusb_writel ( smscusb, ( base + SMSCUSB_MII_ACCESS ),
  429. mii_access ) ) != 0 )
  430. return rc;
  431. /* Wait for command to complete */
  432. if ( ( rc = smscusb_mii_wait ( smscusb ) ) != 0 )
  433. return rc;
  434. return 0;
  435. }
  436. /** MII operations */
  437. struct mii_operations smscusb_mii_operations = {
  438. .read = smscusb_mii_read,
  439. .write = smscusb_mii_write,
  440. };
  441. /**
  442. * Check link status
  443. *
  444. * @v smscusb SMSC USB device
  445. * @ret rc Return status code
  446. */
  447. int smscusb_mii_check_link ( struct smscusb_device *smscusb ) {
  448. struct net_device *netdev = smscusb->netdev;
  449. int intr;
  450. int rc;
  451. /* Read PHY interrupt source */
  452. intr = mii_read ( &smscusb->mii, SMSCUSB_MII_PHY_INTR_SOURCE );
  453. if ( intr < 0 ) {
  454. rc = intr;
  455. DBGC ( smscusb, "SMSCUSB %p could not get PHY interrupt "
  456. "source: %s\n", smscusb, strerror ( rc ) );
  457. return rc;
  458. }
  459. /* Acknowledge PHY interrupt */
  460. if ( ( rc = mii_write ( &smscusb->mii, SMSCUSB_MII_PHY_INTR_SOURCE,
  461. intr ) ) != 0 ) {
  462. DBGC ( smscusb, "SMSCUSB %p could not acknowledge PHY "
  463. "interrupt: %s\n", smscusb, strerror ( rc ) );
  464. return rc;
  465. }
  466. /* Check link status */
  467. if ( ( rc = mii_check_link ( &smscusb->mii, netdev ) ) != 0 ) {
  468. DBGC ( smscusb, "SMSCUSB %p could not check link: %s\n",
  469. smscusb, strerror ( rc ) );
  470. return rc;
  471. }
  472. DBGC ( smscusb, "SMSCUSB %p link %s (intr %#04x)\n",
  473. smscusb, ( netdev_link_ok ( netdev ) ? "up" : "down" ), intr );
  474. return 0;
  475. }
  476. /**
  477. * Enable PHY interrupts and update link status
  478. *
  479. * @v smscusb SMSC USB device
  480. * @ret rc Return status code
  481. */
  482. int smscusb_mii_open ( struct smscusb_device *smscusb ) {
  483. int rc;
  484. /* Enable PHY interrupts */
  485. if ( ( rc = mii_write ( &smscusb->mii, SMSCUSB_MII_PHY_INTR_MASK,
  486. ( SMSCUSB_PHY_INTR_ANEG_DONE |
  487. SMSCUSB_PHY_INTR_LINK_DOWN ) ) ) != 0 ) {
  488. DBGC ( smscusb, "SMSCUSB %p could not set PHY interrupt "
  489. "mask: %s\n", smscusb, strerror ( rc ) );
  490. return rc;
  491. }
  492. /* Update link status */
  493. smscusb_mii_check_link ( smscusb );
  494. return 0;
  495. }
  496. /******************************************************************************
  497. *
  498. * Receive filtering
  499. *
  500. ******************************************************************************
  501. */
  502. /**
  503. * Set receive address
  504. *
  505. * @v smscusb SMSC USB device
  506. * @v addr_base Receive address register base
  507. * @ret rc Return status code
  508. */
  509. int smscusb_set_address ( struct smscusb_device *smscusb,
  510. unsigned int addr_base ) {
  511. struct net_device *netdev = smscusb->netdev;
  512. union smscusb_mac mac;
  513. int rc;
  514. /* Copy MAC address */
  515. memset ( &mac, 0, sizeof ( mac ) );
  516. memcpy ( mac.raw, netdev->ll_addr, ETH_ALEN );
  517. /* Write MAC address high register */
  518. if ( ( rc = smscusb_raw_writel ( smscusb,
  519. ( addr_base + SMSCUSB_RX_ADDRH ),
  520. mac.addr.h ) ) != 0 )
  521. return rc;
  522. /* Write MAC address low register */
  523. if ( ( rc = smscusb_raw_writel ( smscusb,
  524. ( addr_base + SMSCUSB_RX_ADDRL ),
  525. mac.addr.l ) ) != 0 )
  526. return rc;
  527. return 0;
  528. }
  529. /**
  530. * Set receive filter
  531. *
  532. * @v smscusb SMSC USB device
  533. * @v filt_base Receive filter register base
  534. * @ret rc Return status code
  535. */
  536. int smscusb_set_filter ( struct smscusb_device *smscusb,
  537. unsigned int filt_base ) {
  538. struct net_device *netdev = smscusb->netdev;
  539. union smscusb_mac mac;
  540. int rc;
  541. /* Copy MAC address */
  542. memset ( &mac, 0, sizeof ( mac ) );
  543. memcpy ( mac.raw, netdev->ll_addr, ETH_ALEN );
  544. mac.addr.h |= cpu_to_le32 ( SMSCUSB_ADDR_FILTH_VALID );
  545. /* Write MAC address perfect filter high register */
  546. if ( ( rc = smscusb_raw_writel ( smscusb,
  547. ( filt_base + SMSCUSB_ADDR_FILTH(0) ),
  548. mac.addr.h ) ) != 0 )
  549. return rc;
  550. /* Write MAC address perfect filter low register */
  551. if ( ( rc = smscusb_raw_writel ( smscusb,
  552. ( filt_base + SMSCUSB_ADDR_FILTL(0) ),
  553. mac.addr.l ) ) != 0 )
  554. return rc;
  555. return 0;
  556. }
  557. /******************************************************************************
  558. *
  559. * Endpoint operations
  560. *
  561. ******************************************************************************
  562. */
  563. /**
  564. * Complete interrupt transfer
  565. *
  566. * @v ep USB endpoint
  567. * @v iobuf I/O buffer
  568. * @v rc Completion status code
  569. */
  570. static void smscusb_intr_complete ( struct usb_endpoint *ep,
  571. struct io_buffer *iobuf, int rc ) {
  572. struct smscusb_device *smscusb =
  573. container_of ( ep, struct smscusb_device, usbnet.intr );
  574. struct net_device *netdev = smscusb->netdev;
  575. struct smscusb_interrupt *intr;
  576. /* Profile completions */
  577. profile_start ( &smscusb_intr_profiler );
  578. /* Ignore packets cancelled when the endpoint closes */
  579. if ( ! ep->open )
  580. goto done;
  581. /* Record USB errors against the network device */
  582. if ( rc != 0 ) {
  583. DBGC ( smscusb, "SMSCUSB %p interrupt failed: %s\n",
  584. smscusb, strerror ( rc ) );
  585. DBGC_HDA ( smscusb, 0, iobuf->data, iob_len ( iobuf ) );
  586. netdev_rx_err ( netdev, NULL, rc );
  587. goto done;
  588. }
  589. /* Extract interrupt data */
  590. if ( iob_len ( iobuf ) != sizeof ( *intr ) ) {
  591. DBGC ( smscusb, "SMSCUSB %p malformed interrupt\n",
  592. smscusb );
  593. DBGC_HDA ( smscusb, 0, iobuf->data, iob_len ( iobuf ) );
  594. netdev_rx_err ( netdev, NULL, rc );
  595. goto done;
  596. }
  597. intr = iobuf->data;
  598. /* Record interrupt status */
  599. smscusb->int_sts = le32_to_cpu ( intr->int_sts );
  600. profile_stop ( &smscusb_intr_profiler );
  601. done:
  602. /* Free I/O buffer */
  603. free_iob ( iobuf );
  604. }
  605. /** Interrupt endpoint operations */
  606. struct usb_endpoint_driver_operations smscusb_intr_operations = {
  607. .complete = smscusb_intr_complete,
  608. };
  609. /**
  610. * Complete bulk OUT transfer
  611. *
  612. * @v ep USB endpoint
  613. * @v iobuf I/O buffer
  614. * @v rc Completion status code
  615. */
  616. static void smscusb_out_complete ( struct usb_endpoint *ep,
  617. struct io_buffer *iobuf, int rc ) {
  618. struct smscusb_device *smscusb =
  619. container_of ( ep, struct smscusb_device, usbnet.out );
  620. struct net_device *netdev = smscusb->netdev;
  621. /* Report TX completion */
  622. netdev_tx_complete_err ( netdev, iobuf, rc );
  623. }
  624. /** Bulk OUT endpoint operations */
  625. struct usb_endpoint_driver_operations smscusb_out_operations = {
  626. .complete = smscusb_out_complete,
  627. };