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