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 */
101 
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 */
107 
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 */
121 	uint8_t raw[ETH_ALEN];
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 */
138 struct smscusb_interrupt {
139 	/** Current value of INT_STS register */
140 	uint32_t int_sts;
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 */
158 	uint16_t mii_base;
159 	/** PHY interrupt source register */
160 	uint16_t phy_source;
161 	/** Interrupt status */
162 	uint32_t int_sts;
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
smscusb_writel(struct smscusb_device * smscusb,unsigned int address,uint32_t value)179 smscusb_writel ( struct smscusb_device *smscusb, unsigned int address,
180 		 uint32_t value ) {
181 	int rc;
182 
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
smscusb_readl(struct smscusb_device * smscusb,unsigned int address,uint32_t * value)200 smscusb_readl ( struct smscusb_device *smscusb, unsigned int address,
201 		uint32_t *value ) {
202 	int rc;
203 
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
smscusb_get_statistics(struct smscusb_device * smscusb,unsigned int index,void * data,size_t len)222 smscusb_get_statistics ( struct smscusb_device *smscusb, unsigned int index,
223 			 void *data, size_t len ) {
224 	int rc;
225 
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 
243 extern struct usb_endpoint_driver_operations smscusb_intr_operations;
244 extern struct usb_endpoint_driver_operations smscusb_out_operations;
245 extern struct mii_operations smscusb_mii_operations;
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
smscusb_init(struct smscusb_device * smscusb,struct net_device * netdev,struct usb_function * func,struct usb_endpoint_driver_operations * in)256 smscusb_init ( struct smscusb_device *smscusb, struct net_device *netdev,
257 	       struct usb_function *func,
258 	       struct usb_endpoint_driver_operations *in ) {
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,
265 		      &smscusb_out_operations );
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
smscusb_mii_init(struct smscusb_device * smscusb,unsigned int mii_base,unsigned int phy_source)277 smscusb_mii_init ( struct smscusb_device *smscusb, unsigned int mii_base,
278 		   unsigned int phy_source ) {
279 
280 	mdio_init ( &smscusb->mdio, &smscusb_mii_operations );
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 */
300