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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  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. /** Maximum time to wait for MII (in milliseconds) */
  84. #define SMSCUSB_MII_MAX_WAIT_MS 100
  85. /** MAC address */
  86. union smscusb_mac {
  87. /** MAC receive address registers */
  88. struct {
  89. /** MAC receive address low register */
  90. uint32_t l;
  91. /** MAC receive address high register */
  92. uint32_t h;
  93. } __attribute__ (( packed )) addr;
  94. /** Raw MAC address */
  95. uint8_t raw[ETH_ALEN];
  96. };
  97. /** MAC receive address high register offset */
  98. #define SMSCUSB_RX_ADDRH 0x000
  99. /** MAC receive address low register offset */
  100. #define SMSCUSB_RX_ADDRL 0x004
  101. /** MAC address perfect filter N high register offset */
  102. #define SMSCUSB_ADDR_FILTH(n) ( 0x000 + ( 8 * (n) ) )
  103. #define SMSCUSB_ADDR_FILTH_VALID 0x80000000UL /**< Address valid */
  104. /** MAC address perfect filter N low register offset */
  105. #define SMSCUSB_ADDR_FILTL(n) ( 0x004 + ( 8 * (n) ) )
  106. /** Interrupt packet format */
  107. struct smscusb_interrupt {
  108. /** Current value of INT_STS register */
  109. uint32_t int_sts;
  110. } __attribute__ (( packed ));
  111. /** An SMSC USB device */
  112. struct smscusb_device {
  113. /** USB device */
  114. struct usb_device *usb;
  115. /** USB bus */
  116. struct usb_bus *bus;
  117. /** Network device */
  118. struct net_device *netdev;
  119. /** USB network device */
  120. struct usbnet_device usbnet;
  121. /** MII interface */
  122. struct mii_interface mdio;
  123. /** MII device */
  124. struct mii_device mii;
  125. /** MII register base */
  126. uint16_t mii_base;
  127. /** PHY interrupt source register */
  128. uint16_t phy_source;
  129. /** Interrupt status */
  130. uint32_t int_sts;
  131. };
  132. extern int smscusb_raw_writel ( struct smscusb_device *smscusb,
  133. unsigned int address, uint32_t value );
  134. extern int smscusb_raw_readl ( struct smscusb_device *smscusb,
  135. unsigned int address, uint32_t *value );
  136. /**
  137. * Write register
  138. *
  139. * @v smscusb SMSC USB device
  140. * @v address Register address
  141. * @v value Register value
  142. * @ret rc Return status code
  143. */
  144. static inline __attribute__ (( always_inline )) int
  145. smscusb_writel ( struct smscusb_device *smscusb, unsigned int address,
  146. uint32_t value ) {
  147. int rc;
  148. /* Write register */
  149. if ( ( rc = smscusb_raw_writel ( smscusb, address,
  150. cpu_to_le32 ( value ) ) ) != 0 )
  151. return rc;
  152. return 0;
  153. }
  154. /**
  155. * Read register
  156. *
  157. * @v smscusb SMSC USB device
  158. * @v address Register address
  159. * @ret value Register value
  160. * @ret rc Return status code
  161. */
  162. static inline __attribute__ (( always_inline )) int
  163. smscusb_readl ( struct smscusb_device *smscusb, unsigned int address,
  164. uint32_t *value ) {
  165. int rc;
  166. /* Read register */
  167. if ( ( rc = smscusb_raw_readl ( smscusb, address, value ) ) != 0 )
  168. return rc;
  169. le32_to_cpus ( value );
  170. return 0;
  171. }
  172. /**
  173. * Get statistics
  174. *
  175. * @v smscusb SMSC USB device
  176. * @v index Statistics set index
  177. * @v data Statistics data to fill in
  178. * @v len Length of statistics data
  179. * @ret rc Return status code
  180. */
  181. static inline __attribute__ (( always_inline )) int
  182. smscusb_get_statistics ( struct smscusb_device *smscusb, unsigned int index,
  183. void *data, size_t len ) {
  184. int rc;
  185. /* Read statistics */
  186. if ( ( rc = usb_control ( smscusb->usb, SMSCUSB_GET_STATISTICS, 0,
  187. index, data, len ) ) != 0 ) {
  188. DBGC ( smscusb, "SMSCUSB %p could not get statistics set %d: "
  189. "%s\n", smscusb, index, strerror ( rc ) );
  190. return rc;
  191. }
  192. return 0;
  193. }
  194. /** Interrupt maximum fill level
  195. *
  196. * This is a policy decision.
  197. */
  198. #define SMSCUSB_INTR_MAX_FILL 2
  199. extern struct usb_endpoint_driver_operations smscusb_intr_operations;
  200. extern struct usb_endpoint_driver_operations smscusb_out_operations;
  201. extern struct mii_operations smscusb_mii_operations;
  202. /**
  203. * Initialise SMSC USB device
  204. *
  205. * @v smscusb SMSC USB device
  206. * @v netdev Network device
  207. * @v func USB function
  208. * @v in Bulk IN endpoint operations
  209. */
  210. static inline __attribute__ (( always_inline )) void
  211. smscusb_init ( struct smscusb_device *smscusb, struct net_device *netdev,
  212. struct usb_function *func,
  213. struct usb_endpoint_driver_operations *in ) {
  214. struct usb_device *usb = func->usb;
  215. smscusb->usb = usb;
  216. smscusb->bus = usb->port->hub->bus;
  217. smscusb->netdev = netdev;
  218. usbnet_init ( &smscusb->usbnet, func, &smscusb_intr_operations, in,
  219. &smscusb_out_operations );
  220. usb_refill_init ( &smscusb->usbnet.intr, 0, 0, SMSCUSB_INTR_MAX_FILL );
  221. }
  222. /**
  223. * Initialise SMSC USB device MII interface
  224. *
  225. * @v smscusb SMSC USB device
  226. * @v mii_base MII register base
  227. * @v phy_source Interrupt source PHY register
  228. */
  229. static inline __attribute__ (( always_inline )) void
  230. smscusb_mii_init ( struct smscusb_device *smscusb, unsigned int mii_base,
  231. unsigned int phy_source ) {
  232. mdio_init ( &smscusb->mdio, &smscusb_mii_operations );
  233. mii_init ( &smscusb->mii, &smscusb->mdio, 0 );
  234. smscusb->mii_base = mii_base;
  235. smscusb->phy_source = phy_source;
  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_fdt_fetch_mac ( struct smscusb_device *smscusb );
  242. extern int smscusb_mii_check_link ( struct smscusb_device *smscusb );
  243. extern int smscusb_mii_open ( struct smscusb_device *smscusb,
  244. unsigned int phy_mask, unsigned int intrs );
  245. extern int smscusb_set_address ( struct smscusb_device *smscusb,
  246. unsigned int addr_base );
  247. extern int smscusb_set_filter ( struct smscusb_device *smscusb,
  248. unsigned int filt_base );
  249. #endif /* _SMSCUSB_H */