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.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  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. /** OTP power register offset */
  43. #define SMSCUSB_OTP_POWER 0x000
  44. #define SMSCUSB_OTP_POWER_DOWN 0x00000001UL /**< OTP power down */
  45. /** OTP address high byte register offset */
  46. #define SMSCUSB_OTP_ADDRH 0x004
  47. /** OTP address low byte register offset */
  48. #define SMSCUSB_OTP_ADDRL 0x008
  49. /** OTP data register offset */
  50. #define SMSCUSB_OTP_DATA 0x018
  51. #define SMSCUSB_OTP_DATA_GET(otp_data) \
  52. ( ( (otp_data) >> 0 ) & 0xff ) /**< OTP data */
  53. /** OTP command selection register offset */
  54. #define SMSCUSB_OTP_CMD 0x020
  55. #define SMSCUSB_OTP_CMD_READ 0x00000001UL /**< Read command */
  56. /** OTP command initiation register offset */
  57. #define SMSCUSB_OTP_GO 0x028
  58. #define SMSCUSB_OTP_GO_GO 0x00000001UL /**< Initiate command */
  59. /** OTP status register offset */
  60. #define SMSCUSB_OTP_STATUS 0x030
  61. #define SMSCUSB_OTP_STATUS_BUSY 0x00000001UL /**< OTP busy */
  62. /** Maximum time to wait for OTP (in milliseconds) */
  63. #define SMSCUSB_OTP_MAX_WAIT_MS 100
  64. /** OTP layout 1 signature */
  65. #define SMSCUSB_OTP_1_SIG 0xf3
  66. /** OTP layout 1 MAC address offset */
  67. #define SMSCUSB_OTP_1_MAC 0x001
  68. /** OTP layout 2 signature */
  69. #define SMSCUSB_OTP_2_SIG 0xf7
  70. /** OTP layout 2 MAC address offset */
  71. #define SMSCUSB_OTP_2_MAC 0x101
  72. /** MII access register offset */
  73. #define SMSCUSB_MII_ACCESS 0x000
  74. #define SMSCUSB_MII_ACCESS_PHY_ADDRESS 0x00000800UL /**< PHY address */
  75. #define SMSCUSB_MII_ACCESS_MIIRINDA(addr) ( (addr) << 6 ) /**< MII register */
  76. #define SMSCUSB_MII_ACCESS_MIIWNR 0x00000002UL /**< MII write */
  77. #define SMSCUSB_MII_ACCESS_MIIBZY 0x00000001UL /**< MII busy */
  78. /** MII data register offset */
  79. #define SMSCUSB_MII_DATA 0x004
  80. #define SMSCUSB_MII_DATA_SET(data) ( (data) << 0 ) /**< Set data */
  81. #define SMSCUSB_MII_DATA_GET(mii_data) \
  82. ( ( (mii_data) >> 0 ) & 0xffff ) /**< Get data */
  83. /** PHY interrupt source MII register */
  84. #define SMSCUSB_MII_PHY_INTR_SOURCE 29
  85. /** PHY interrupt mask MII register */
  86. #define SMSCUSB_MII_PHY_INTR_MASK 30
  87. /** PHY interrupt: auto-negotiation complete */
  88. #define SMSCUSB_PHY_INTR_ANEG_DONE 0x0040
  89. /** PHY interrupt: link down */
  90. #define SMSCUSB_PHY_INTR_LINK_DOWN 0x0010
  91. /** Maximum time to wait for MII (in milliseconds) */
  92. #define SMSCUSB_MII_MAX_WAIT_MS 100
  93. /** MAC address */
  94. union smscusb_mac {
  95. /** MAC receive address registers */
  96. struct {
  97. /** MAC receive address low register */
  98. uint32_t l;
  99. /** MAC receive address high register */
  100. uint32_t h;
  101. } __attribute__ (( packed )) addr;
  102. /** Raw MAC address */
  103. uint8_t raw[ETH_ALEN];
  104. };
  105. /** MAC receive address high register offset */
  106. #define SMSCUSB_RX_ADDRH 0x000
  107. /** MAC receive address low register offset */
  108. #define SMSCUSB_RX_ADDRL 0x004
  109. /** MAC address perfect filter N high register offset */
  110. #define SMSCUSB_ADDR_FILTH(n) ( 0x000 + ( 8 * (n) ) )
  111. #define SMSCUSB_ADDR_FILTH_VALID 0x80000000UL /**< Address valid */
  112. /** MAC address perfect filter N low register offset */
  113. #define SMSCUSB_ADDR_FILTL(n) ( 0x004 + ( 8 * (n) ) )
  114. /** Interrupt packet format */
  115. struct smscusb_interrupt {
  116. /** Current value of INT_STS register */
  117. uint32_t int_sts;
  118. } __attribute__ (( packed ));
  119. /** An SMSC USB device */
  120. struct smscusb_device {
  121. /** USB device */
  122. struct usb_device *usb;
  123. /** USB bus */
  124. struct usb_bus *bus;
  125. /** Network device */
  126. struct net_device *netdev;
  127. /** USB network device */
  128. struct usbnet_device usbnet;
  129. /** MII interface */
  130. struct mii_interface mii;
  131. /** MII register base */
  132. uint16_t mii_base;
  133. /** Interrupt status */
  134. uint32_t int_sts;
  135. };
  136. extern int smscusb_raw_writel ( struct smscusb_device *smscusb,
  137. unsigned int address, uint32_t value );
  138. extern int smscusb_raw_readl ( struct smscusb_device *smscusb,
  139. unsigned int address, uint32_t *value );
  140. /**
  141. * Write register
  142. *
  143. * @v smscusb SMSC USB device
  144. * @v address Register address
  145. * @v value Register value
  146. * @ret rc Return status code
  147. */
  148. static inline __attribute__ (( always_inline )) int
  149. smscusb_writel ( struct smscusb_device *smscusb, unsigned int address,
  150. uint32_t value ) {
  151. int rc;
  152. /* Write register */
  153. if ( ( rc = smscusb_raw_writel ( smscusb, address,
  154. cpu_to_le32 ( value ) ) ) != 0 )
  155. return rc;
  156. return 0;
  157. }
  158. /**
  159. * Read register
  160. *
  161. * @v smscusb SMSC USB device
  162. * @v address Register address
  163. * @ret value Register value
  164. * @ret rc Return status code
  165. */
  166. static inline __attribute__ (( always_inline )) int
  167. smscusb_readl ( struct smscusb_device *smscusb, unsigned int address,
  168. uint32_t *value ) {
  169. int rc;
  170. /* Read register */
  171. if ( ( rc = smscusb_raw_readl ( smscusb, address, value ) ) != 0 )
  172. return rc;
  173. le32_to_cpus ( value );
  174. return 0;
  175. }
  176. /**
  177. * Get statistics
  178. *
  179. * @v smscusb SMSC USB device
  180. * @v index Statistics set index
  181. * @v data Statistics data to fill in
  182. * @v len Length of statistics data
  183. * @ret rc Return status code
  184. */
  185. static inline __attribute__ (( always_inline )) int
  186. smscusb_get_statistics ( struct smscusb_device *smscusb, unsigned int index,
  187. void *data, size_t len ) {
  188. int rc;
  189. /* Read statistics */
  190. if ( ( rc = usb_control ( smscusb->usb, SMSCUSB_GET_STATISTICS, 0,
  191. index, data, len ) ) != 0 ) {
  192. DBGC ( smscusb, "SMSCUSB %p could not get statistics set %d: "
  193. "%s\n", smscusb, index, strerror ( rc ) );
  194. return rc;
  195. }
  196. return 0;
  197. }
  198. /** Interrupt maximum fill level
  199. *
  200. * This is a policy decision.
  201. */
  202. #define SMSCUSB_INTR_MAX_FILL 2
  203. extern struct usb_endpoint_driver_operations smscusb_intr_operations;
  204. extern struct usb_endpoint_driver_operations smscusb_out_operations;
  205. extern struct mii_operations smscusb_mii_operations;
  206. /**
  207. * Initialise SMSC USB device
  208. *
  209. * @v smscusb SMSC USB device
  210. * @v netdev Network device
  211. * @v func USB function
  212. * @v in Bulk IN endpoint operations
  213. */
  214. static inline __attribute__ (( always_inline )) void
  215. smscusb_init ( struct smscusb_device *smscusb, struct net_device *netdev,
  216. struct usb_function *func,
  217. struct usb_endpoint_driver_operations *in ) {
  218. struct usb_device *usb = func->usb;
  219. smscusb->usb = usb;
  220. smscusb->bus = usb->port->hub->bus;
  221. smscusb->netdev = netdev;
  222. usbnet_init ( &smscusb->usbnet, func, &smscusb_intr_operations, in,
  223. &smscusb_out_operations );
  224. usb_refill_init ( &smscusb->usbnet.intr, 0, 0, SMSCUSB_INTR_MAX_FILL );
  225. }
  226. /**
  227. * Initialise SMSC USB device MII interface
  228. *
  229. * @v smscusb SMSC USB device
  230. * @v mii_base MII register base
  231. */
  232. static inline __attribute__ (( always_inline )) void
  233. smscusb_mii_init ( struct smscusb_device *smscusb, unsigned int mii_base ) {
  234. mii_init ( &smscusb->mii, &smscusb_mii_operations );
  235. smscusb->mii_base = mii_base;
  236. }
  237. extern int smscusb_eeprom_fetch_mac ( struct smscusb_device *smscusb,
  238. unsigned int e2p_base );
  239. extern int smscusb_otp_fetch_mac ( struct smscusb_device *smscusb,
  240. unsigned int otp_base );
  241. extern int smscusb_mii_check_link ( struct smscusb_device *smscusb );
  242. extern int smscusb_mii_open ( struct smscusb_device *smscusb );
  243. extern int smscusb_set_address ( struct smscusb_device *smscusb,
  244. unsigned int addr_base );
  245. extern int smscusb_set_filter ( struct smscusb_device *smscusb,
  246. unsigned int filt_base );
  247. #endif /* _SMSCUSB_H */