iPXE
smscusb.h
Go to the documentation of this file.
1 #ifndef _SMSCUSB_H
2 #define _SMSCUSB_H
3 
4 /** @file
5  *
6  * SMSC USB Ethernet drivers
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 FILE_SECBOOT ( PERMITTED );
12 
13 #include <stdint.h>
14 #include <string.h>
15 #include <byteswap.h>
16 #include <ipxe/usb.h>
17 #include <ipxe/usbnet.h>
18 #include <ipxe/netdevice.h>
19 #include <ipxe/mii.h>
20 #include <ipxe/if_ether.h>
21 
22 /** Register write command */
23 #define SMSCUSB_REGISTER_WRITE \
24  ( USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE | \
25  USB_REQUEST_TYPE ( 0xa0 ) )
26 
27 /** Register read command */
28 #define SMSCUSB_REGISTER_READ \
29  ( USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE | \
30  USB_REQUEST_TYPE ( 0xa1 ) )
31 
32 /** Get statistics command */
33 #define SMSCUSB_GET_STATISTICS \
34  ( USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE | \
35  USB_REQUEST_TYPE ( 0xa2 ) )
36 
37 /** EEPROM command register offset */
38 #define SMSCUSB_E2P_CMD 0x000
39 #define SMSCUSB_E2P_CMD_EPC_BSY 0x80000000UL /**< EPC busy */
40 #define SMSCUSB_E2P_CMD_EPC_CMD_READ 0x00000000UL /**< READ command */
41 #define SMSCUSB_E2P_CMD_EPC_ADDR(addr) ( (addr) << 0 ) /**< EPC address */
42 
43 /** EEPROM data register offset */
44 #define SMSCUSB_E2P_DATA 0x004
45 #define SMSCUSB_E2P_DATA_GET(e2p_data) \
46  ( ( (e2p_data) >> 0 ) & 0xff ) /**< EEPROM data */
47 
48 /** MAC address EEPROM address */
49 #define SMSCUSB_EEPROM_MAC 0x01
50 
51 /** Maximum time to wait for EEPROM (in milliseconds) */
52 #define SMSCUSB_EEPROM_MAX_WAIT_MS 100
53 
54 /** OTP power register offset */
55 #define SMSCUSB_OTP_POWER 0x000
56 #define SMSCUSB_OTP_POWER_DOWN 0x00000001UL /**< OTP power down */
57 
58 /** OTP address high byte register offset */
59 #define SMSCUSB_OTP_ADDRH 0x004
60 
61 /** OTP address low byte register offset */
62 #define SMSCUSB_OTP_ADDRL 0x008
63 
64 /** OTP data register offset */
65 #define SMSCUSB_OTP_DATA 0x018
66 #define SMSCUSB_OTP_DATA_GET(otp_data) \
67  ( ( (otp_data) >> 0 ) & 0xff ) /**< OTP data */
68 
69 /** OTP command selection register offset */
70 #define SMSCUSB_OTP_CMD 0x020
71 #define SMSCUSB_OTP_CMD_READ 0x00000001UL /**< Read command */
72 
73 /** OTP command initiation register offset */
74 #define SMSCUSB_OTP_GO 0x028
75 #define SMSCUSB_OTP_GO_GO 0x00000001UL /**< Initiate command */
76 
77 /** OTP status register offset */
78 #define SMSCUSB_OTP_STATUS 0x030
79 #define SMSCUSB_OTP_STATUS_BUSY 0x00000001UL /**< OTP busy */
80 
81 /** Maximum time to wait for OTP (in milliseconds) */
82 #define SMSCUSB_OTP_MAX_WAIT_MS 100
83 
84 /** OTP layout 1 signature */
85 #define SMSCUSB_OTP_1_SIG 0xf3
86 
87 /** OTP layout 1 MAC address offset */
88 #define SMSCUSB_OTP_1_MAC 0x001
89 
90 /** OTP layout 2 signature */
91 #define SMSCUSB_OTP_2_SIG 0xf7
92 
93 /** OTP layout 2 MAC address offset */
94 #define SMSCUSB_OTP_2_MAC 0x101
95 
96 /** MII access register offset */
97 #define SMSCUSB_MII_ACCESS 0x000
98 #define SMSCUSB_MII_ACCESS_PHY_ADDRESS 0x00000800UL /**< PHY address */
99 #define SMSCUSB_MII_ACCESS_MIIRINDA(addr) ( (addr) << 6 ) /**< MII register */
100 #define SMSCUSB_MII_ACCESS_MIIWNR 0x00000002UL /**< MII write */
101 #define SMSCUSB_MII_ACCESS_MIIBZY 0x00000001UL /**< MII busy */
103 /** MII data register offset */
104 #define SMSCUSB_MII_DATA 0x004
105 #define SMSCUSB_MII_DATA_SET(data) ( (data) << 0 ) /**< Set data */
106 #define SMSCUSB_MII_DATA_GET(mii_data) \
107  ( ( (mii_data) >> 0 ) & 0xffff ) /**< Get data */
109 /** Maximum time to wait for MII (in milliseconds) */
110 #define SMSCUSB_MII_MAX_WAIT_MS 100
111 
112 /** MAC address */
113 union smscusb_mac {
114  /** MAC receive address registers */
115  struct {
116  /** MAC receive address low register */
117  uint32_t l;
118  /** MAC receive address high register */
119  uint32_t h;
120  } __attribute__ (( packed )) addr;
121  /** Raw MAC address */
123 };
124 
125 /** MAC receive address high register offset */
126 #define SMSCUSB_RX_ADDRH 0x000
127 
128 /** MAC receive address low register offset */
129 #define SMSCUSB_RX_ADDRL 0x004
130 
131 /** MAC address perfect filter N high register offset */
132 #define SMSCUSB_ADDR_FILTH(n) ( 0x000 + ( 8 * (n) ) )
133 #define SMSCUSB_ADDR_FILTH_VALID 0x80000000UL /**< Address valid */
134 
135 /** MAC address perfect filter N low register offset */
136 #define SMSCUSB_ADDR_FILTL(n) ( 0x004 + ( 8 * (n) ) )
137 
138 /** Interrupt packet format */
140  /** Current value of INT_STS register */
142 } __attribute__ (( packed ));
143 
144 /** An SMSC USB device */
145 struct smscusb_device {
146  /** USB device */
147  struct usb_device *usb;
148  /** USB bus */
149  struct usb_bus *bus;
150  /** Network device */
151  struct net_device *netdev;
152  /** USB network device */
153  struct usbnet_device usbnet;
154  /** MII interface */
155  struct mii_interface mdio;
156  /** MII device */
157  struct mii_device mii;
158  /** MII register base */
160  /** PHY interrupt source register */
162  /** Interrupt status */
164 };
165 
166 extern int smscusb_raw_writel ( struct smscusb_device *smscusb,
167  unsigned int address, uint32_t value );
168 extern int smscusb_raw_readl ( struct smscusb_device *smscusb,
169  unsigned int address, uint32_t *value );
170 
171 /**
172  * Write register
173  *
174  * @v smscusb SMSC USB device
175  * @v address Register address
176  * @v value Register value
177  * @ret rc Return status code
178  */
179 static inline __attribute__ (( always_inline )) int
180 smscusb_writel ( struct smscusb_device *smscusb, unsigned int address,
181  uint32_t value ) {
182  int rc;
184  /* Write register */
185  if ( ( rc = smscusb_raw_writel ( smscusb, address,
186  cpu_to_le32 ( value ) ) ) != 0 )
187  return rc;
188 
189  return 0;
190 }
191 
192 /**
193  * Read register
194  *
195  * @v smscusb SMSC USB device
196  * @v address Register address
197  * @ret value Register value
198  * @ret rc Return status code
199  */
200 static inline __attribute__ (( always_inline )) int
201 smscusb_readl ( struct smscusb_device *smscusb, unsigned int address,
202  uint32_t *value ) {
203  int rc;
205  /* Read register */
206  if ( ( rc = smscusb_raw_readl ( smscusb, address, value ) ) != 0 )
207  return rc;
208  le32_to_cpus ( value );
209 
210  return 0;
211 }
212 
213 /**
214  * Get statistics
215  *
216  * @v smscusb SMSC USB device
217  * @v index Statistics set index
218  * @v data Statistics data to fill in
219  * @v len Length of statistics data
220  * @ret rc Return status code
221  */
222 static inline __attribute__ (( always_inline )) int
223 smscusb_get_statistics ( struct smscusb_device *smscusb, unsigned int index,
224  void *data, size_t len ) {
225  int rc;
227  /* Read statistics */
228  if ( ( rc = usb_control ( smscusb->usb, SMSCUSB_GET_STATISTICS, 0,
229  index, data, len ) ) != 0 ) {
230  DBGC ( smscusb, "SMSCUSB %p could not get statistics set %d: "
231  "%s\n", smscusb, index, strerror ( rc ) );
232  return rc;
233  }
234 
235  return 0;
236 }
237 
238 /** Interrupt maximum fill level
239  *
240  * This is a policy decision.
241  */
242 #define SMSCUSB_INTR_MAX_FILL 2
243 
247 
248 /**
249  * Initialise SMSC USB device
250  *
251  * @v smscusb SMSC USB device
252  * @v netdev Network device
253  * @v func USB function
254  * @v in Bulk IN endpoint operations
255  */
256 static inline __attribute__ (( always_inline )) void
257 smscusb_init ( struct smscusb_device *smscusb, struct net_device *netdev,
258  struct usb_function *func,
260  struct usb_device *usb = func->usb;
261 
262  smscusb->usb = usb;
263  smscusb->bus = usb->port->hub->bus;
264  smscusb->netdev = netdev;
265  usbnet_init ( &smscusb->usbnet, func, &smscusb_intr_operations, in,
267  usb_refill_init ( &smscusb->usbnet.intr, 0, 0, SMSCUSB_INTR_MAX_FILL );
268 }
269 
270 /**
271  * Initialise SMSC USB device MII interface
272  *
273  * @v smscusb SMSC USB device
274  * @v mii_base MII register base
275  * @v phy_source Interrupt source PHY register
276  */
277 static inline __attribute__ (( always_inline )) void
278 smscusb_mii_init ( struct smscusb_device *smscusb, unsigned int mii_base,
279  unsigned int phy_source ) {
280 
282  mii_init ( &smscusb->mii, &smscusb->mdio, 0 );
283  smscusb->mii_base = mii_base;
284  smscusb->phy_source = phy_source;
285 }
286 
287 extern int smscusb_eeprom_fetch_mac ( struct smscusb_device *smscusb,
288  unsigned int e2p_base );
289 extern int smscusb_otp_fetch_mac ( struct smscusb_device *smscusb,
290  unsigned int otp_base );
291 extern int smscusb_fdt_fetch_mac ( struct smscusb_device *smscusb );
292 extern int smscusb_mii_check_link ( struct smscusb_device *smscusb );
293 extern int smscusb_mii_open ( struct smscusb_device *smscusb,
294  unsigned int phy_mask, unsigned int intrs );
295 extern int smscusb_set_address ( struct smscusb_device *smscusb,
296  unsigned int addr_base );
297 extern int smscusb_set_filter ( struct smscusb_device *smscusb,
298  unsigned int filt_base );
299 
300 #endif /* _SMSCUSB_H */
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
__be32 in[4]
Definition: CIB_PRM.h:35
Interrupt packet format.
Definition: smscusb.h:142
An SMSC USB device.
Definition: smscusb.h:148
uint64_t address
Base address.
Definition: ena.h:24
int smscusb_mii_open(struct smscusb_device *smscusb, unsigned int phy_mask, unsigned int intrs)
Enable PHY interrupts and update link status.
Definition: smscusb.c:656
static void smscusb_init(struct smscusb_device *smscusb, struct net_device *netdev, struct usb_function *func, struct usb_endpoint_driver_operations *in)
Initialise SMSC USB device.
Definition: smscusb.h:260
#define DBGC(...)
Definition: compiler.h:505
long index
Definition: bigint.h:65
struct usb_device * usb
USB device.
Definition: smscusb.h:150
static int smscusb_writel(struct smscusb_device *smscusb, unsigned int address, uint32_t value)
Write register.
Definition: smscusb.h:183
struct usb_endpoint_driver_operations smscusb_out_operations
Bulk OUT endpoint operations.
Definition: smscusb.c:824
struct usb_endpoint intr
Interrupt endpoint.
Definition: usbnet.h:28
static void smscusb_mii_init(struct smscusb_device *smscusb, unsigned int mii_base, unsigned int phy_source)
Initialise SMSC USB device MII interface.
Definition: smscusb.h:281
int usb_control(struct usb_device *usb, unsigned int request, unsigned int value, unsigned int index, void *data, size_t len)
Issue USB control transaction.
Definition: usb.c:784
static void mdio_init(struct mii_interface *mdio, struct mii_operations *op)
Initialise MII interface.
Definition: mii.h:64
#define SMSCUSB_INTR_MAX_FILL
Interrupt maximum fill level.
Definition: smscusb.h:245
uint32_t int_sts
Interrupt status.
Definition: smscusb.h:166
uint16_t phy_source
PHY interrupt source register.
Definition: smscusb.h:164
An MII device.
Definition: mii.h:50
struct usbnet_device usbnet
USB network device.
Definition: smscusb.h:156
struct usb_port * port
USB port.
Definition: usb.h:727
uint8_t raw[ETH_ALEN]
Raw MAC address.
Definition: smscusb.h:125
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
ring len
Length.
Definition: dwmac.h:231
struct smscusb_mac::@354 addr
MAC receive address registers.
static void usb_refill_init(struct usb_endpoint *ep, size_t reserve, size_t len, unsigned int max)
Initialise USB endpoint refill.
Definition: usb.h:617
static struct net_device * netdev
Definition: gdbudp.c:52
struct mii_operations smscusb_mii_operations
MII operations.
Definition: smscusb.c:603
static int smscusb_readl(struct smscusb_device *smscusb, unsigned int address, uint32_t *value)
Read register.
Definition: smscusb.h:204
#define SMSCUSB_GET_STATISTICS
Get statistics command.
Definition: smscusb.h:33
MAC address.
Definition: smscusb.h:116
int smscusb_set_address(struct smscusb_device *smscusb, unsigned int addr_base)
Set receive address.
Definition: smscusb.c:687
#define cpu_to_le32(value)
Definition: byteswap.h:108
A USB device.
Definition: usb.h:723
struct mii_interface mdio
MII interface.
Definition: smscusb.h:158
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
A USB network device.
Definition: usbnet.h:16
uint32_t l
MAC receive address low register.
Definition: smscusb.h:120
A network device.
Definition: netdevice.h:353
Media Independent Interface.
uint32_t int_sts
Current value of INT_STS register.
Definition: smscusb.h:144
unsigned char uint8_t
Definition: stdint.h:10
int smscusb_fdt_fetch_mac(struct smscusb_device *smscusb)
Fetch MAC address from device tree.
Definition: smscusb.c:457
#define ETH_ALEN
Definition: if_ether.h:9
FILE_SECBOOT(PERMITTED)
struct usb_device * usb
USB device.
Definition: usb.h:678
struct mii_device mii
MII device.
Definition: smscusb.h:160
unsigned int uint32_t
Definition: stdint.h:12
int smscusb_set_filter(struct smscusb_device *smscusb, unsigned int filt_base)
Set receive filter.
Definition: smscusb.c:719
int smscusb_otp_fetch_mac(struct smscusb_device *smscusb, unsigned int otp_base)
Fetch MAC address from OTP.
Definition: smscusb.c:401
static void mii_init(struct mii_device *mii, struct mii_interface *mdio, unsigned int address)
Initialise MII device.
Definition: mii.h:76
int smscusb_raw_readl(struct smscusb_device *smscusb, unsigned int address, uint32_t *value)
Read register (without byte-swapping)
Definition: smscusb.c:87
struct usb_endpoint_driver_operations smscusb_intr_operations
Interrupt endpoint operations.
Definition: smscusb.c:802
Network device management.
MII interface operations.
Definition: mii.h:19
USB network devices.
Universal Serial Bus (USB)
static void usbnet_init(struct usbnet_device *usbnet, struct usb_function *func, struct usb_endpoint_driver_operations *intr, struct usb_endpoint_driver_operations *in, struct usb_endpoint_driver_operations *out)
Initialise USB network device.
Definition: usbnet.h:45
struct usb_hub * hub
USB hub.
Definition: usb.h:815
uint16_t mii_base
MII register base.
Definition: smscusb.h:162
An MII interface.
Definition: mii.h:44
uint8_t data[48]
Additional event data.
Definition: ena.h:22
int smscusb_mii_check_link(struct smscusb_device *smscusb)
Check link status.
Definition: smscusb.c:614
int smscusb_eeprom_fetch_mac(struct smscusb_device *smscusb, unsigned int e2p_base)
Fetch MAC address from EEPROM.
Definition: smscusb.c:216
struct usb_bus * bus
USB bus.
Definition: smscusb.h:152
struct net_device * netdev
Network device.
Definition: smscusb.h:154
static int smscusb_get_statistics(struct smscusb_device *smscusb, unsigned int index, void *data, size_t len)
Get statistics.
Definition: smscusb.h:226
USB endpoint driver operations.
Definition: usb.h:489
A USB function.
Definition: usb.h:674
struct usb_bus * bus
USB bus.
Definition: usb.h:845
uint32_t h
MAC receive address high register.
Definition: smscusb.h:122
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
String functions.
A USB bus.
Definition: usb.h:966
int smscusb_raw_writel(struct smscusb_device *smscusb, unsigned int address, uint32_t value)
Write register (without byte-swapping)
Definition: smscusb.c:62
#define le32_to_cpus(ptr)
Definition: byteswap.h:126