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.h 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. #ifndef _SMSCUSB_H
  2. #define _SMSCUSB_H
  3. /** @file
  4. *
  5. * SMSC USB Ethernet drivers
  6. *
  7. */
  8. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  9. #include <stdint.h>
  10. #include <string.h>
  11. #include <byteswap.h>
  12. #include <ipxe/usb.h>
  13. #include <ipxe/usbnet.h>
  14. #include <ipxe/netdevice.h>
  15. #include <ipxe/mii.h>
  16. #include <ipxe/if_ether.h>
  17. /** Register write command */
  18. #define SMSCUSB_REGISTER_WRITE \
  19. ( USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE | \
  20. USB_REQUEST_TYPE ( 0xa0 ) )
  21. /** Register read command */
  22. #define SMSCUSB_REGISTER_READ \
  23. ( USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE | \
  24. USB_REQUEST_TYPE ( 0xa1 ) )
  25. /** Get statistics command */
  26. #define SMSCUSB_GET_STATISTICS \
  27. ( USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE | \
  28. USB_REQUEST_TYPE ( 0xa2 ) )
  29. /** EEPROM command register offset */
  30. #define SMSCUSB_E2P_CMD 0x000
  31. #define SMSCUSB_E2P_CMD_EPC_BSY 0x80000000UL /**< EPC busy */
  32. #define SMSCUSB_E2P_CMD_EPC_CMD_READ 0x00000000UL /**< READ command */
  33. #define SMSCUSB_E2P_CMD_EPC_ADDR(addr) ( (addr) << 0 ) /**< EPC address */
  34. /** EEPROM data register offset */
  35. #define SMSCUSB_E2P_DATA 0x004
  36. #define SMSCUSB_E2P_DATA_GET(e2p_data) \
  37. ( ( (e2p_data) >> 0 ) & 0xff ) /**< EEPROM data */
  38. /** MAC address EEPROM address */
  39. #define SMSCUSB_EEPROM_MAC 0x01
  40. /** Maximum time to wait for EEPROM (in milliseconds) */
  41. #define SMSCUSB_EEPROM_MAX_WAIT_MS 100
  42. /** MII access register offset */
  43. #define SMSCUSB_MII_ACCESS 0x000
  44. #define SMSCUSB_MII_ACCESS_PHY_ADDRESS 0x00000800UL /**< PHY address */
  45. #define SMSCUSB_MII_ACCESS_MIIRINDA(addr) ( (addr) << 6 ) /**< MII register */
  46. #define SMSCUSB_MII_ACCESS_MIIWNR 0x00000002UL /**< MII write */
  47. #define SMSCUSB_MII_ACCESS_MIIBZY 0x00000001UL /**< MII busy */
  48. /** MII data register offset */
  49. #define SMSCUSB_MII_DATA 0x004
  50. #define SMSCUSB_MII_DATA_SET(data) ( (data) << 0 ) /**< Set data */
  51. #define SMSCUSB_MII_DATA_GET(mii_data) \
  52. ( ( (mii_data) >> 0 ) & 0xffff ) /**< Get data */
  53. /** PHY interrupt source MII register */
  54. #define SMSCUSB_MII_PHY_INTR_SOURCE 29
  55. /** PHY interrupt mask MII register */
  56. #define SMSCUSB_MII_PHY_INTR_MASK 30
  57. /** PHY interrupt: auto-negotiation complete */
  58. #define SMSCUSB_PHY_INTR_ANEG_DONE 0x0040
  59. /** PHY interrupt: link down */
  60. #define SMSCUSB_PHY_INTR_LINK_DOWN 0x0010
  61. /** Maximum time to wait for MII (in milliseconds) */
  62. #define SMSCUSB_MII_MAX_WAIT_MS 100
  63. /** MAC address */
  64. union smscusb_mac {
  65. /** MAC receive address registers */
  66. struct {
  67. /** MAC receive address low register */
  68. uint32_t l;
  69. /** MAC receive address high register */
  70. uint32_t h;
  71. } __attribute__ (( packed )) addr;
  72. /** Raw MAC address */
  73. uint8_t raw[ETH_ALEN];
  74. };
  75. /** MAC receive address high register offset */
  76. #define SMSCUSB_RX_ADDRH 0x000
  77. /** MAC receive address low register offset */
  78. #define SMSCUSB_RX_ADDRL 0x004
  79. /** MAC address perfect filter N high register offset */
  80. #define SMSCUSB_ADDR_FILTH(n) ( 0x000 + ( 8 * (n) ) )
  81. #define SMSCUSB_ADDR_FILTH_VALID 0x80000000UL /**< Address valid */
  82. /** MAC address perfect filter N low register offset */
  83. #define SMSCUSB_ADDR_FILTL(n) ( 0x004 + ( 8 * (n) ) )
  84. /** Interrupt packet format */
  85. struct smscusb_interrupt {
  86. /** Current value of INT_STS register */
  87. uint32_t int_sts;
  88. } __attribute__ (( packed ));
  89. /** An SMSC USB device */
  90. struct smscusb_device {
  91. /** USB device */
  92. struct usb_device *usb;
  93. /** USB bus */
  94. struct usb_bus *bus;
  95. /** Network device */
  96. struct net_device *netdev;
  97. /** USB network device */
  98. struct usbnet_device usbnet;
  99. /** MII interface */
  100. struct mii_interface mii;
  101. /** MII register base */
  102. uint16_t mii_base;
  103. /** Interrupt status */
  104. uint32_t int_sts;
  105. };
  106. /**
  107. * Write register (without byte-swapping)
  108. *
  109. * @v smscusb Smscusb device
  110. * @v address Register address
  111. * @v value Register value
  112. * @ret rc Return status code
  113. */
  114. static int smscusb_raw_writel ( struct smscusb_device *smscusb,
  115. unsigned int address, uint32_t value ) {
  116. int rc;
  117. /* Write register */
  118. DBGCIO ( smscusb, "SMSCUSB %p [%03x] <= %08x\n",
  119. smscusb, address, le32_to_cpu ( value ) );
  120. if ( ( rc = usb_control ( smscusb->usb, SMSCUSB_REGISTER_WRITE, 0,
  121. address, &value, sizeof ( value ) ) ) != 0 ) {
  122. DBGC ( smscusb, "SMSCUSB %p could not write %03x: %s\n",
  123. smscusb, address, strerror ( rc ) );
  124. return rc;
  125. }
  126. return 0;
  127. }
  128. /**
  129. * Write register
  130. *
  131. * @v smscusb SMSC USB device
  132. * @v address Register address
  133. * @v value Register value
  134. * @ret rc Return status code
  135. */
  136. static inline __attribute__ (( always_inline )) int
  137. smscusb_writel ( struct smscusb_device *smscusb, unsigned int address,
  138. uint32_t value ) {
  139. int rc;
  140. /* Write register */
  141. if ( ( rc = smscusb_raw_writel ( smscusb, address,
  142. cpu_to_le32 ( value ) ) ) != 0 )
  143. return rc;
  144. return 0;
  145. }
  146. /**
  147. * Read register (without byte-swapping)
  148. *
  149. * @v smscusb SMSC USB device
  150. * @v address Register address
  151. * @ret value Register value
  152. * @ret rc Return status code
  153. */
  154. static int smscusb_raw_readl ( struct smscusb_device *smscusb,
  155. unsigned int address, uint32_t *value ) {
  156. int rc;
  157. /* Read register */
  158. if ( ( rc = usb_control ( smscusb->usb, SMSCUSB_REGISTER_READ, 0,
  159. address, value, sizeof ( *value ) ) ) != 0 ) {
  160. DBGC ( smscusb, "SMSCUSB %p could not read %03x: %s\n",
  161. smscusb, address, strerror ( rc ) );
  162. return rc;
  163. }
  164. DBGCIO ( smscusb, "SMSCUSB %p [%03x] => %08x\n",
  165. smscusb, address, le32_to_cpu ( *value ) );
  166. return 0;
  167. }
  168. /**
  169. * Read register
  170. *
  171. * @v smscusb SMSC USB device
  172. * @v address Register address
  173. * @ret value Register value
  174. * @ret rc Return status code
  175. */
  176. static inline __attribute__ (( always_inline )) int
  177. smscusb_readl ( struct smscusb_device *smscusb, unsigned int address,
  178. uint32_t *value ) {
  179. int rc;
  180. /* Read register */
  181. if ( ( rc = smscusb_raw_readl ( smscusb, address, value ) ) != 0 )
  182. return rc;
  183. le32_to_cpus ( value );
  184. return 0;
  185. }
  186. /**
  187. * Get statistics
  188. *
  189. * @v smscusb SMSC USB device
  190. * @v index Statistics set index
  191. * @v data Statistics data to fill in
  192. * @v len Length of statistics data
  193. * @ret rc Return status code
  194. */
  195. static inline __attribute__ (( always_inline )) int
  196. smscusb_get_statistics ( struct smscusb_device *smscusb, unsigned int index,
  197. void *data, size_t len ) {
  198. int rc;
  199. /* Read statistics */
  200. if ( ( rc = usb_control ( smscusb->usb, SMSCUSB_GET_STATISTICS, 0,
  201. index, data, len ) ) != 0 ) {
  202. DBGC ( smscusb, "SMSCUSB %p could not get statistics set %d: "
  203. "%s\n", smscusb, index, strerror ( rc ) );
  204. return rc;
  205. }
  206. return 0;
  207. }
  208. /** Interrupt maximum fill level
  209. *
  210. * This is a policy decision.
  211. */
  212. #define SMSCUSB_INTR_MAX_FILL 2
  213. extern struct usb_endpoint_driver_operations smscusb_intr_operations;
  214. extern struct usb_endpoint_driver_operations smscusb_out_operations;
  215. extern struct mii_operations smscusb_mii_operations;
  216. /**
  217. * Initialise SMSC USB device
  218. *
  219. * @v smscusb SMSC USB device
  220. * @v netdev Network device
  221. * @v func USB function
  222. * @v in Bulk IN endpoint operations
  223. */
  224. static inline __attribute__ (( always_inline )) void
  225. smscusb_init ( struct smscusb_device *smscusb, struct net_device *netdev,
  226. struct usb_function *func,
  227. struct usb_endpoint_driver_operations *in ) {
  228. struct usb_device *usb = func->usb;
  229. smscusb->usb = usb;
  230. smscusb->bus = usb->port->hub->bus;
  231. smscusb->netdev = netdev;
  232. usbnet_init ( &smscusb->usbnet, func, &smscusb_intr_operations, in,
  233. &smscusb_out_operations );
  234. usb_refill_init ( &smscusb->usbnet.intr, 0, 0, SMSCUSB_INTR_MAX_FILL );
  235. }
  236. /**
  237. * Initialise SMSC USB device MII interface
  238. *
  239. * @v smscusb SMSC USB device
  240. * @v mii_base MII register base
  241. */
  242. static inline __attribute__ (( always_inline )) void
  243. smscusb_mii_init ( struct smscusb_device *smscusb, unsigned int mii_base ) {
  244. mii_init ( &smscusb->mii, &smscusb_mii_operations );
  245. smscusb->mii_base = mii_base;
  246. }
  247. extern int smscusb_eeprom_fetch_mac ( struct smscusb_device *smscusb,
  248. unsigned int e2p_base );
  249. extern int smscusb_mii_check_link ( struct smscusb_device *smscusb );
  250. extern int smscusb_mii_open ( struct smscusb_device *smscusb );
  251. extern int smscusb_set_address ( struct smscusb_device *smscusb,
  252. unsigned int addr_base );
  253. extern int smscusb_set_filter ( struct smscusb_device *smscusb,
  254. unsigned int filt_base );
  255. #endif /* _SMSCUSB_H */