iPXE
smsc95xx.c File Reference

SMSC LAN95xx USB Ethernet driver. More...

#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/ethernet.h>
#include <ipxe/usb.h>
#include <ipxe/usbnet.h>
#include <ipxe/profile.h>
#include <ipxe/base16.h>
#include <ipxe/smbios.h>
#include "smsc95xx.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static int smsc95xx_vm3_fetch_mac (struct smscusb_device *smscusb)
 Construct MAC address for Honeywell VM3.
static int smsc95xx_fetch_mac (struct smscusb_device *smscusb)
 Fetch MAC address.
static int smsc95xx_dump_statistics (struct smscusb_device *smscusb)
 Dump statistics (for debugging)
static int smsc95xx_reset (struct smscusb_device *smscusb)
 Reset device.
static void smsc95xx_in_complete (struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
 Complete bulk IN transfer.
static int smsc95xx_out_transmit (struct smscusb_device *smscusb, struct io_buffer *iobuf)
 Transmit packet.
static int smsc95xx_open (struct net_device *netdev)
 Open network device.
static void smsc95xx_close (struct net_device *netdev)
 Close network device.
static int smsc95xx_transmit (struct net_device *netdev, struct io_buffer *iobuf)
 Transmit packet.
static void smsc95xx_poll (struct net_device *netdev)
 Poll for completed and received packets.
static int smsc95xx_probe (struct usb_function *func, struct usb_configuration_descriptor *config)
 Probe device.
static void smsc95xx_remove (struct usb_function *func)
 Remove device.

Variables

static struct profiler smsc95xx_in_profiler __profiler
 Bulk IN completion profiler.
static struct usb_endpoint_driver_operations smsc95xx_in_operations
 Bulk IN endpoint operations.
static struct net_device_operations smsc95xx_operations
 SMSC95xx network device operations.
static struct usb_device_id smsc95xx_ids []
 SMSC95xx device IDs.
struct usb_driver smsc95xx_driver __usb_driver
 SMSC LAN95xx driver.

Detailed Description

SMSC LAN95xx USB Ethernet driver.

Definition in file smsc95xx.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ smsc95xx_vm3_fetch_mac()

int smsc95xx_vm3_fetch_mac ( struct smscusb_device * smscusb)
static

Construct MAC address for Honeywell VM3.

Parameters
smscusbSMSC USB device
Return values
rcReturn status code

Definition at line 66 of file smsc95xx.c.

66 {
67 struct net_device *netdev = smscusb->netdev;
68 const struct smbios_header *structure;
70 const char *manufacturer;
71 const char *product;
72 const char *mac;
73 int len;
74 int rc;
75
76 /* Find system information */
78 if ( ! structure ) {
79 DBGC ( smscusb, "SMSC95XX %p could not find system "
80 "information\n", smscusb );
81 return -ENOENT;
82 }
83 system = container_of ( structure, struct smbios_system_information,
84 header );
85
86 /* Fetch system manufacturer name */
87 manufacturer = smbios_string ( structure, system->manufacturer );
88 if ( ! manufacturer ) {
89 DBGC ( smscusb, "SMSC95XX %p could not read manufacturer "
90 "name\n", smscusb );
91 return -ENOENT;
92 }
93
94 /* Fetch system product name */
95 product = smbios_string ( structure, system->product );
96 if ( ! product ) {
97 DBGC ( smscusb, "SMSC95XX %p could not read product name\n",
98 smscusb );
99 return -ENOENT;
100 }
101
102 /* Ignore non-VM3 devices */
103 if ( ( strcmp ( manufacturer, "Honeywell" ) != 0 ) ||
104 ( strcmp ( product, "VM3" ) != 0 ) )
105 return -ENOTTY;
106
107 /* Find OEM strings */
108 structure = smbios_structure ( SMBIOS_TYPE_OEM_STRINGS, 0 );
109 if ( ! structure ) {
110 DBGC ( smscusb, "SMSC95XX %p could not find OEM strings\n",
111 smscusb );
112 return -ENOENT;
113 }
114
115 /* Fetch MAC address */
117 if ( ! mac ) {
118 DBGC ( smscusb, "SMSC95XX %p could not read OEM string\n",
119 smscusb );
120 return -ENOENT;
121 }
122
123 /* Decode MAC address */
124 len = base16_decode ( mac, netdev->hw_addr, ETH_ALEN );
125 if ( len < 0 ) {
126 rc = len;
127 DBGC ( smscusb, "SMSC95XX %p invalid MAC address \"%s\"\n",
128 smscusb, mac );
129 return rc;
130 }
131
132 DBGC ( smscusb, "SMSC95XX %p using VM3 MAC %s\n",
133 smscusb, eth_ntoa ( netdev->hw_addr ) );
134 return 0;
135}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
ring len
Length.
Definition dwmac.h:226
struct ena_llq_option header
Header locations.
Definition ena.h:5
uint8_t mac[ETH_ALEN]
MAC address.
Definition ena.h:13
uint8_t system[ETH_ALEN]
System identifier.
Definition eth_slow.h:13
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition ethernet.c:176
static struct net_device * netdev
Definition gdbudp.c:53
#define DBGC(...)
Definition compiler.h:505
#define ENOENT
No such file or directory.
Definition errno.h:515
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595
#define ETH_ALEN
Definition if_ether.h:9
uint8_t product
Product string.
Definition smbios.h:5
#define SMBIOS_TYPE_SYSTEM_INFORMATION
SMBIOS system information structure type.
Definition smbios.h:148
uint8_t manufacturer
Manufacturer string.
Definition smbios.h:3
#define SMBIOS_TYPE_OEM_STRINGS
SMBIOS OEM strings structure type.
Definition smbios.h:187
const char * smbios_string(const struct smbios_header *structure, unsigned int index)
Get indexed string within SMBIOS structure.
Definition smbios.c:252
const struct smbios_header * smbios_structure(unsigned int type, unsigned int instance)
Find specific structure type within SMBIOS.
Definition smbios.c:183
#define SMSC95XX_VM3_OEM_STRING_MAC
Honeywell VM3 MAC address OEM string index.
Definition smsc95xx.h:179
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
int strcmp(const char *first, const char *second)
Compare strings.
Definition string.c:174
A network device.
Definition netdevice.h:353
An SMBIOS structure header.
Definition smbios.h:120
SMBIOS system information structure.
Definition smbios.h:130
struct net_device * netdev
Network device.
Definition smscusb.h:151

References container_of, DBGC, ENOENT, ENOTTY, ETH_ALEN, eth_ntoa(), header, len, mac, manufacturer, netdev, smscusb_device::netdev, product, rc, smbios_string(), smbios_structure(), SMBIOS_TYPE_OEM_STRINGS, SMBIOS_TYPE_SYSTEM_INFORMATION, SMSC95XX_VM3_OEM_STRING_MAC, strcmp(), and system.

Referenced by smsc95xx_fetch_mac().

◆ smsc95xx_fetch_mac()

int smsc95xx_fetch_mac ( struct smscusb_device * smscusb)
static

Fetch MAC address.

Parameters
smscusbSMSC USB device
Return values
rcReturn status code

Definition at line 143 of file smsc95xx.c.

143 {
144 struct net_device *netdev = smscusb->netdev;
145 int rc;
146
147 /* Read MAC address from EEPROM, if present */
148 if ( ( rc = smscusb_eeprom_fetch_mac ( smscusb,
149 SMSC95XX_E2P_BASE ) ) == 0 )
150 return 0;
151
152 /* Read MAC address from device tree, if present */
153 if ( ( rc = smscusb_fdt_fetch_mac ( smscusb ) ) == 0 )
154 return 0;
155
156 /* Construct MAC address for Honeywell VM3, if applicable */
157 if ( ( rc = smsc95xx_vm3_fetch_mac ( smscusb ) ) == 0 )
158 return 0;
159
160 /* Otherwise, generate a random MAC address */
161 eth_random_addr ( netdev->hw_addr );
162 DBGC ( smscusb, "SMSC95XX %p using random MAC %s\n",
163 smscusb, eth_ntoa ( netdev->hw_addr ) );
164 return 0;
165}
void eth_random_addr(void *hw_addr)
Generate random Ethernet address.
Definition ethernet.c:160
static int smsc95xx_vm3_fetch_mac(struct smscusb_device *smscusb)
Construct MAC address for Honeywell VM3.
Definition smsc95xx.c:66
#define SMSC95XX_E2P_BASE
EEPROM register base.
Definition smsc95xx.h:42
int smscusb_eeprom_fetch_mac(struct smscusb_device *smscusb, unsigned int e2p_base)
Fetch MAC address from EEPROM.
Definition smscusb.c:216
int smscusb_fdt_fetch_mac(struct smscusb_device *smscusb)
Fetch MAC address from device tree.
Definition smscusb.c:457

References DBGC, eth_ntoa(), eth_random_addr(), netdev, smscusb_device::netdev, rc, SMSC95XX_E2P_BASE, smsc95xx_vm3_fetch_mac(), smscusb_eeprom_fetch_mac(), and smscusb_fdt_fetch_mac().

Referenced by smsc95xx_probe().

◆ smsc95xx_dump_statistics()

int smsc95xx_dump_statistics ( struct smscusb_device * smscusb)
static

Dump statistics (for debugging)

Parameters
smscusbSMSC USB device
Return values
rcReturn status code

Definition at line 180 of file smsc95xx.c.

180 {
183 int rc;
184
185 /* Do nothing unless debugging is enabled */
186 if ( ! DBG_LOG )
187 return 0;
188
189 /* Get RX statistics */
191 &rx, sizeof ( rx ) ) ) != 0 ) {
192 DBGC ( smscusb, "SMSC95XX %p could not get RX statistics: "
193 "%s\n", smscusb, strerror ( rc ) );
194 return rc;
195 }
196
197 /* Get TX statistics */
199 &tx, sizeof ( tx ) ) ) != 0 ) {
200 DBGC ( smscusb, "SMSC95XX %p could not get TX statistics: "
201 "%s\n", smscusb, strerror ( rc ) );
202 return rc;
203 }
204
205 /* Dump statistics */
206 DBGC ( smscusb, "SMSC95XX %p RX good %d bad %d crc %d und %d aln %d "
207 "ovr %d lat %d drp %d\n", smscusb, le32_to_cpu ( rx.good ),
208 le32_to_cpu ( rx.bad ), le32_to_cpu ( rx.crc ),
209 le32_to_cpu ( rx.undersize ), le32_to_cpu ( rx.alignment ),
210 le32_to_cpu ( rx.oversize ), le32_to_cpu ( rx.late ),
211 le32_to_cpu ( rx.dropped ) );
212 DBGC ( smscusb, "SMSC95XX %p TX good %d bad %d pau %d sgl %d mul %d "
213 "exc %d lat %d und %d def %d car %d\n", smscusb,
214 le32_to_cpu ( tx.good ), le32_to_cpu ( tx.bad ),
215 le32_to_cpu ( tx.pause ), le32_to_cpu ( tx.single ),
216 le32_to_cpu ( tx.multiple ), le32_to_cpu ( tx.excessive ),
217 le32_to_cpu ( tx.late ), le32_to_cpu ( tx.underrun ),
218 le32_to_cpu ( tx.deferred ), le32_to_cpu ( tx.carrier ) );
219
220 return 0;
221}
#define DBG_LOG
Definition compiler.h:317
#define le32_to_cpu(value)
Definition byteswap.h:114
#define SMSC95XX_RX_STATISTICS
Receive statistics.
Definition smsc95xx.h:134
#define SMSC95XX_TX_STATISTICS
Transmit statistics.
Definition smsc95xx.h:161
static int smscusb_get_statistics(struct smscusb_device *smscusb, unsigned int index, void *data, size_t len)
Get statistics.
Definition smscusb.h:223
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
Receive statistics.
Definition smsc95xx.h:114
Transmit statistics.
Definition smsc95xx.h:137
u8 tx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets to the AP.
Definition wpa.h:4
u8 rx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets from the AP.
Definition wpa.h:1

References DBG_LOG, DBGC, le32_to_cpu, rc, rx, SMSC95XX_RX_STATISTICS, SMSC95XX_TX_STATISTICS, smscusb_get_statistics(), strerror(), and tx.

Referenced by smsc95xx_close().

◆ smsc95xx_reset()

int smsc95xx_reset ( struct smscusb_device * smscusb)
static

Reset device.

Parameters
smscusbSMSC USB device
Return values
rcReturn status code

Definition at line 236 of file smsc95xx.c.

236 {
237 uint32_t hw_cfg;
238 uint32_t led_gpio_cfg;
239 int rc;
240
241 /* Reset device */
242 if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_HW_CFG,
243 SMSC95XX_HW_CFG_LRST ) ) != 0 )
244 return rc;
245
246 /* Wait for reset to complete */
248
249 /* Check that reset has completed */
250 if ( ( rc = smscusb_readl ( smscusb, SMSC95XX_HW_CFG, &hw_cfg ) ) != 0 )
251 return rc;
252 if ( hw_cfg & SMSC95XX_HW_CFG_LRST ) {
253 DBGC ( smscusb, "SMSC95XX %p failed to reset\n", smscusb );
254 return -ETIMEDOUT;
255 }
256
257 /* Configure LEDs */
261 if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_LED_GPIO_CFG,
262 led_gpio_cfg ) ) != 0 ) {
263 DBGC ( smscusb, "SMSC95XX %p could not configure LEDs: %s\n",
264 smscusb, strerror ( rc ) );
265 /* Ignore error and continue */
266 }
267
268 return 0;
269}
unsigned int uint32_t
Definition stdint.h:12
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
#define SMSC95XX_HW_CFG
Hardware configuration register.
Definition smsc95xx.h:25
#define SMSC95XX_HW_CFG_LRST
Soft lite reset.
Definition smsc95xx.h:27
#define SMSC95XX_RESET_DELAY_US
Reset delay (in microseconds)
Definition smsc95xx.h:164
#define SMSC95XX_LED_GPIO_CFG_GPCTL2_NSPD_LED
Link speed LED.
Definition smsc95xx.h:32
#define SMSC95XX_LED_GPIO_CFG
LED GPIO configuration register.
Definition smsc95xx.h:30
#define SMSC95XX_LED_GPIO_CFG_GPCTL0_NFDX_LED
Full-duplex LED.
Definition smsc95xx.h:38
#define SMSC95XX_LED_GPIO_CFG_GPCTL1_NLNKA_LED
Activity LED.
Definition smsc95xx.h:35
static int smscusb_readl(struct smscusb_device *smscusb, unsigned int address, uint32_t *value)
Read register.
Definition smscusb.h:201
static int smscusb_writel(struct smscusb_device *smscusb, unsigned int address, uint32_t value)
Write register.
Definition smscusb.h:180
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition timer.c:61

References DBGC, ETIMEDOUT, rc, SMSC95XX_HW_CFG, SMSC95XX_HW_CFG_LRST, SMSC95XX_LED_GPIO_CFG, SMSC95XX_LED_GPIO_CFG_GPCTL0_NFDX_LED, SMSC95XX_LED_GPIO_CFG_GPCTL1_NLNKA_LED, SMSC95XX_LED_GPIO_CFG_GPCTL2_NSPD_LED, SMSC95XX_RESET_DELAY_US, smscusb_readl(), smscusb_writel(), strerror(), and udelay().

Referenced by smsc95xx_close(), smsc95xx_open(), and smsc95xx_probe().

◆ smsc95xx_in_complete()

void smsc95xx_in_complete ( struct usb_endpoint * ep,
struct io_buffer * iobuf,
int rc )
static

Complete bulk IN transfer.

Parameters
epUSB endpoint
iobufI/O buffer
rcCompletion status code

Definition at line 285 of file smsc95xx.c.

286 {
287 struct smscusb_device *smscusb =
288 container_of ( ep, struct smscusb_device, usbnet.in );
289 struct net_device *netdev = smscusb->netdev;
291
292 /* Profile completions */
293 profile_start ( &smsc95xx_in_profiler );
294
295 /* Ignore packets cancelled when the endpoint closes */
296 if ( ! ep->open ) {
297 free_iob ( iobuf );
298 return;
299 }
300
301 /* Record USB errors against the network device */
302 if ( rc != 0 ) {
303 DBGC ( smscusb, "SMSC95XX %p bulk IN failed: %s\n",
304 smscusb, strerror ( rc ) );
305 goto err;
306 }
307
308 /* Sanity check */
309 if ( iob_len ( iobuf ) < ( sizeof ( *header ) + 4 /* CRC */ ) ) {
310 DBGC ( smscusb, "SMSC95XX %p underlength bulk IN\n",
311 smscusb );
312 DBGC_HDA ( smscusb, 0, iobuf->data, iob_len ( iobuf ) );
313 rc = -EINVAL;
314 goto err;
315 }
316
317 /* Strip header and CRC */
318 header = iobuf->data;
319 iob_pull ( iobuf, sizeof ( *header ) );
320 iob_unput ( iobuf, 4 /* CRC */ );
321
322 /* Check for errors */
323 if ( header->command & cpu_to_le32 ( SMSC95XX_RX_RUNT |
325 SMSC95XX_RX_CRC ) ) {
326 DBGC ( smscusb, "SMSC95XX %p receive error (%08x):\n",
327 smscusb, le32_to_cpu ( header->command ) );
328 DBGC_HDA ( smscusb, 0, iobuf->data, iob_len ( iobuf ) );
329 rc = -EIO;
330 goto err;
331 }
332
333 /* Hand off to network stack */
334 netdev_rx ( netdev, iob_disown ( iobuf ) );
335
336 profile_stop ( &smsc95xx_in_profiler );
337 return;
338
339 err:
340 /* Hand off to network stack */
341 netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
342}
#define DBGC_HDA(...)
Definition compiler.h:506
#define EINVAL
Invalid argument.
Definition errno.h:429
#define EIO
Input/output error.
Definition errno.h:434
#define cpu_to_le32(value)
Definition byteswap.h:108
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition profile.h:174
static void profile_start(struct profiler *profiler)
Start profiling.
Definition profile.h:161
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define iob_pull(iobuf, len)
Definition iobuf.h:107
#define iob_unput(iobuf, len)
Definition iobuf.h:140
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition netdevice.c:549
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition netdevice.c:587
#define SMSC95XX_RX_LATE
Late collision.
Definition smsc95xx.h:91
#define SMSC95XX_RX_CRC
CRC error.
Definition smsc95xx.h:94
#define SMSC95XX_RX_RUNT
Runt frame.
Definition smsc95xx.h:88
void * data
Start of data.
Definition iobuf.h:53
Receive packet header.
Definition smsc95xx.h:82
An SMSC USB device.
Definition smscusb.h:145
struct usbnet_device usbnet
USB network device.
Definition smscusb.h:153
int open
Endpoint is open.
Definition usb.h:419
struct usb_endpoint in
Bulk IN endpoint.
Definition usbnet.h:30

References container_of, cpu_to_le32, io_buffer::data, DBGC, DBGC_HDA, EINVAL, EIO, free_iob(), header, usbnet_device::in, iob_disown, iob_len(), iob_pull, iob_unput, le32_to_cpu, netdev, smscusb_device::netdev, netdev_rx(), netdev_rx_err(), usb_endpoint::open, profile_start(), profile_stop(), rc, SMSC95XX_RX_CRC, SMSC95XX_RX_LATE, SMSC95XX_RX_RUNT, strerror(), and smscusb_device::usbnet.

◆ smsc95xx_out_transmit()

int smsc95xx_out_transmit ( struct smscusb_device * smscusb,
struct io_buffer * iobuf )
static

Transmit packet.

Parameters
smscusbSMSC USB device
iobufI/O buffer
Return values
rcReturn status code

Definition at line 356 of file smsc95xx.c.

357 {
359 size_t len = iob_len ( iobuf );
360 int rc;
361
362 /* Profile transmissions */
363 profile_start ( &smsc95xx_out_profiler );
364
365 /* Prepend header */
366 if ( ( rc = iob_ensure_headroom ( iobuf, sizeof ( *header ) ) ) != 0 )
367 return rc;
368 header = iob_push ( iobuf, sizeof ( *header ) );
370 SMSC95XX_TX_LEN ( len ) );
371 header->len = cpu_to_le32 ( len );
372
373 /* Enqueue I/O buffer */
374 if ( ( rc = usb_stream ( &smscusb->usbnet.out, iobuf, 0 ) ) != 0 )
375 return rc;
376
377 profile_stop ( &smsc95xx_out_profiler );
378 return 0;
379}
int iob_ensure_headroom(struct io_buffer *iobuf, size_t len)
Ensure I/O buffer has sufficient headroom.
Definition iobuf.c:235
#define iob_push(iobuf, len)
Definition iobuf.h:89
#define SMSC95XX_TX_FIRST
First segment.
Definition smsc95xx.h:105
#define SMSC95XX_TX_LEN(len)
Buffer size.
Definition smsc95xx.h:111
#define SMSC95XX_TX_LAST
Last segment.
Definition smsc95xx.h:108
Transmit packet header.
Definition smsc95xx.h:97
struct usb_endpoint out
Bulk OUT endpoint.
Definition usbnet.h:32
int usb_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int terminate)
Enqueue USB stream transfer.
Definition usb.c:546

References cpu_to_le32, header, iob_ensure_headroom(), iob_len(), iob_push, len, usbnet_device::out, profile_start(), profile_stop(), rc, SMSC95XX_TX_FIRST, SMSC95XX_TX_LAST, SMSC95XX_TX_LEN, usb_stream(), and smscusb_device::usbnet.

Referenced by smsc95xx_transmit().

◆ smsc95xx_open()

int smsc95xx_open ( struct net_device * netdev)
static

Open network device.

Parameters
netdevNetwork device
Return values
rcReturn status code

Definition at line 394 of file smsc95xx.c.

394 {
395 struct smscusb_device *smscusb = netdev->priv;
396 int rc;
397
398 /* Clear stored interrupt status */
399 smscusb->int_sts = 0;
400
401 /* Configure bulk IN empty response */
402 if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_HW_CFG,
403 SMSC95XX_HW_CFG_BIR ) ) != 0 )
404 goto err_hw_cfg;
405
406 /* Open USB network device */
407 if ( ( rc = usbnet_open ( &smscusb->usbnet ) ) != 0 ) {
408 DBGC ( smscusb, "SMSC95XX %p could not open: %s\n",
409 smscusb, strerror ( rc ) );
410 goto err_open;
411 }
412
413 /* Configure interrupt endpoint */
414 if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_INT_EP_CTL,
416 SMSC95XX_INT_EP_CTL_PHY_EN ) ) ) != 0 )
417 goto err_int_ep_ctl;
418
419 /* Configure bulk IN delay */
420 if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_BULK_IN_DLY,
421 SMSC95XX_BULK_IN_DLY_SET ( 0 ) ) ) != 0 )
422 goto err_bulk_in_dly;
423
424 /* Configure MAC */
425 if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_MAC_CR,
432 SMSC95XX_MAC_CR_RXEN ) ) ) != 0 )
433 goto err_mac_cr;
434
435 /* Configure transmit datapath */
436 if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_TX_CFG,
437 SMSC95XX_TX_CFG_ON ) ) != 0 )
438 goto err_tx_cfg;
439
440 /* Set MAC address */
441 if ( ( rc = smscusb_set_address ( smscusb, SMSC95XX_ADDR_BASE ) ) != 0 )
442 goto err_set_address;
443
444 /* Enable PHY interrupts and update link status */
448 goto err_mii_open;
449
450 return 0;
451
452 err_mii_open:
453 err_set_address:
454 err_tx_cfg:
455 err_mac_cr:
456 err_bulk_in_dly:
457 err_int_ep_ctl:
458 usbnet_close ( &smscusb->usbnet );
459 err_open:
460 err_hw_cfg:
461 smsc95xx_reset ( smscusb );
462 return rc;
463}
static int smsc95xx_reset(struct smscusb_device *smscusb)
Reset device.
Definition smsc95xx.c:236
#define SMSC95XX_HW_CFG_BIR
Bulk IN use NAK.
Definition smsc95xx.h:26
#define SMSC95XX_MAC_CR_MCPAS
All multicast.
Definition smsc95xx.h:57
#define SMSC95XX_BULK_IN_DLY_SET(ticks)
Delay / 16.7ns.
Definition smsc95xx.h:51
#define SMSC95XX_MAC_CR_PASSBAD
Pass bad frames.
Definition smsc95xx.h:59
#define SMSC95XX_ADDR_BASE
MAC address register base.
Definition smsc95xx.h:64
#define SMSC95XX_TX_CFG
Transmit configuration register.
Definition smsc95xx.h:21
#define SMSC95XX_MAC_CR
MAC control register.
Definition smsc95xx.h:54
#define SMSC95XX_INT_EP_CTL_PHY_EN
PHY interrupt.
Definition smsc95xx.h:47
#define SMSC95XX_MAC_CR_RXEN
RX enabled.
Definition smsc95xx.h:61
#define SMSC95XX_INT_EP_CTL
Interrupt endpoint control register.
Definition smsc95xx.h:45
#define SMSC95XX_MAC_CR_FDPX
Full duplex.
Definition smsc95xx.h:56
#define SMSC95XX_MAC_CR_TXEN
TX enabled.
Definition smsc95xx.h:60
#define SMSC95XX_TX_CFG_ON
TX enable.
Definition smsc95xx.h:22
#define SMSC95XX_PHY_INTR_ANEG_DONE
PHY interrupt: auto-negotiation complete.
Definition smsc95xx.h:76
#define SMSC95XX_MAC_CR_PRMS
Promiscuous.
Definition smsc95xx.h:58
#define SMSC95XX_MII_PHY_INTR_MASK
PHY interrupt mask MII register.
Definition smsc95xx.h:73
#define SMSC95XX_BULK_IN_DLY
Bulk IN delay register.
Definition smsc95xx.h:50
#define SMSC95XX_MAC_CR_RXALL
Receive all.
Definition smsc95xx.h:55
#define SMSC95XX_PHY_INTR_LINK_DOWN
PHY interrupt: link down.
Definition smsc95xx.h:79
#define SMSC95XX_INT_EP_CTL_RXDF_EN
RX FIFO overflow.
Definition smsc95xx.h:46
int smscusb_set_address(struct smscusb_device *smscusb, unsigned int addr_base)
Set receive address.
Definition smscusb.c:687
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
uint32_t int_sts
Interrupt status.
Definition smscusb.h:163
int usbnet_open(struct usbnet_device *usbnet)
Open USB network device.
Definition usbnet.c:55
void usbnet_close(struct usbnet_device *usbnet)
Close USB network device.
Definition usbnet.c:128

References DBGC, smscusb_device::int_sts, netdev, rc, SMSC95XX_ADDR_BASE, SMSC95XX_BULK_IN_DLY, SMSC95XX_BULK_IN_DLY_SET, SMSC95XX_HW_CFG, SMSC95XX_HW_CFG_BIR, SMSC95XX_INT_EP_CTL, SMSC95XX_INT_EP_CTL_PHY_EN, SMSC95XX_INT_EP_CTL_RXDF_EN, SMSC95XX_MAC_CR, SMSC95XX_MAC_CR_FDPX, SMSC95XX_MAC_CR_MCPAS, SMSC95XX_MAC_CR_PASSBAD, SMSC95XX_MAC_CR_PRMS, SMSC95XX_MAC_CR_RXALL, SMSC95XX_MAC_CR_RXEN, SMSC95XX_MAC_CR_TXEN, SMSC95XX_MII_PHY_INTR_MASK, SMSC95XX_PHY_INTR_ANEG_DONE, SMSC95XX_PHY_INTR_LINK_DOWN, smsc95xx_reset(), SMSC95XX_TX_CFG, SMSC95XX_TX_CFG_ON, smscusb_mii_open(), smscusb_set_address(), smscusb_writel(), strerror(), smscusb_device::usbnet, usbnet_close(), and usbnet_open().

◆ smsc95xx_close()

void smsc95xx_close ( struct net_device * netdev)
static

Close network device.

Parameters
netdevNetwork device

Definition at line 470 of file smsc95xx.c.

470 {
471 struct smscusb_device *smscusb = netdev->priv;
472
473 /* Close USB network device */
474 usbnet_close ( &smscusb->usbnet );
475
476 /* Dump statistics (for debugging) */
477 smsc95xx_dump_statistics ( smscusb );
478
479 /* Reset device */
480 smsc95xx_reset ( smscusb );
481}
static int smsc95xx_dump_statistics(struct smscusb_device *smscusb)
Dump statistics (for debugging)
Definition smsc95xx.c:180

References netdev, smsc95xx_dump_statistics(), smsc95xx_reset(), smscusb_device::usbnet, and usbnet_close().

◆ smsc95xx_transmit()

int smsc95xx_transmit ( struct net_device * netdev,
struct io_buffer * iobuf )
static

Transmit packet.

Parameters
netdevNetwork device
iobufI/O buffer
Return values
rcReturn status code

Definition at line 490 of file smsc95xx.c.

491 {
492 struct smscusb_device *smscusb = netdev->priv;
493 int rc;
494
495 /* Transmit packet */
496 if ( ( rc = smsc95xx_out_transmit ( smscusb, iobuf ) ) != 0 )
497 return rc;
498
499 return 0;
500}
static int smsc95xx_out_transmit(struct smscusb_device *smscusb, struct io_buffer *iobuf)
Transmit packet.
Definition smsc95xx.c:356

References netdev, rc, and smsc95xx_out_transmit().

◆ smsc95xx_poll()

void smsc95xx_poll ( struct net_device * netdev)
static

Poll for completed and received packets.

Parameters
netdevNetwork device

Definition at line 507 of file smsc95xx.c.

507 {
508 struct smscusb_device *smscusb = netdev->priv;
510 int rc;
511
512 /* Poll USB bus */
513 usb_poll ( smscusb->bus );
514
515 /* Refill endpoints */
516 if ( ( rc = usbnet_refill ( &smscusb->usbnet ) ) != 0 )
518
519 /* Do nothing more unless there are interrupts to handle */
520 int_sts = smscusb->int_sts;
521 if ( ! int_sts )
522 return;
523
524 /* Check link status if applicable */
526 smscusb_mii_check_link ( smscusb );
528 }
529
530 /* Record RX FIFO overflow if applicable */
532 DBGC2 ( smscusb, "SMSC95XX %p RX FIFO overflowed\n",
533 smscusb );
536 }
537
538 /* Check for unexpected interrupts */
539 if ( int_sts ) {
540 DBGC ( smscusb, "SMSC95XX %p unexpected interrupt %#08x\n",
541 smscusb, int_sts );
543 }
544
545 /* Clear interrupts */
546 if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_INT_STS,
547 smscusb->int_sts ) ) != 0 )
549 smscusb->int_sts = 0;
550}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define DBGC2(...)
Definition compiler.h:522
#define ENOBUFS
No buffer space available.
Definition errno.h:499
static void usb_poll(struct usb_bus *bus)
Poll USB bus.
Definition usb.h:1072
#define SMSC95XX_INT_STS_RXDF_INT
RX FIFO overflow.
Definition smsc95xx.h:17
#define SMSC95XX_INT_STS_PHY_INT
PHY interrupt.
Definition smsc95xx.h:18
#define SMSC95XX_INT_STS
Interrupt status register.
Definition smsc95xx.h:16
int smscusb_mii_check_link(struct smscusb_device *smscusb)
Check link status.
Definition smscusb.c:614
struct usb_bus * bus
USB bus.
Definition smscusb.h:149
int usbnet_refill(struct usbnet_device *usbnet)
Refill USB network device bulk IN and interrupt endpoints.
Definition usbnet.c:152

References smscusb_device::bus, DBGC, DBGC2, ENOBUFS, ENOTTY, smscusb_device::int_sts, netdev, netdev_rx_err(), NULL, rc, SMSC95XX_INT_STS, SMSC95XX_INT_STS_PHY_INT, SMSC95XX_INT_STS_RXDF_INT, smscusb_mii_check_link(), smscusb_writel(), usb_poll(), smscusb_device::usbnet, and usbnet_refill().

◆ smsc95xx_probe()

int smsc95xx_probe ( struct usb_function * func,
struct usb_configuration_descriptor * config )
static

Probe device.

Parameters
funcUSB function
configConfiguration descriptor
Return values
rcReturn status code

Definition at line 574 of file smsc95xx.c.

575 {
576 struct net_device *netdev;
577 struct smscusb_device *smscusb;
578 int rc;
579
580 /* Allocate and initialise structure */
581 netdev = alloc_etherdev ( sizeof ( *smscusb ) );
582 if ( ! netdev ) {
583 rc = -ENOMEM;
584 goto err_alloc;
585 }
587 netdev->dev = &func->dev;
588 smscusb = netdev->priv;
589 memset ( smscusb, 0, sizeof ( *smscusb ) );
590 smscusb_init ( smscusb, netdev, func, &smsc95xx_in_operations );
593 usb_refill_init ( &smscusb->usbnet.in,
594 ( sizeof ( struct smsc95xx_tx_header ) -
595 sizeof ( struct smsc95xx_rx_header ) ),
597 DBGC ( smscusb, "SMSC95XX %p on %s\n", smscusb, func->name );
598
599 /* Describe USB network device */
600 if ( ( rc = usbnet_describe ( &smscusb->usbnet, config ) ) != 0 ) {
601 DBGC ( smscusb, "SMSC95XX %p could not describe: %s\n",
602 smscusb, strerror ( rc ) );
603 goto err_describe;
604 }
605
606 /* Reset device */
607 if ( ( rc = smsc95xx_reset ( smscusb ) ) != 0 )
608 goto err_reset;
609
610 /* Read MAC address */
611 if ( ( rc = smsc95xx_fetch_mac ( smscusb ) ) != 0 )
612 goto err_fetch_mac;
613
614 /* Register network device */
615 if ( ( rc = register_netdev ( netdev ) ) != 0 )
616 goto err_register;
617
619 return 0;
620
622 err_register:
623 err_fetch_mac:
624 err_reset:
625 err_describe:
627 netdev_put ( netdev );
628 err_alloc:
629 return rc;
630}
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:265
#define ENOMEM
Not enough space.
Definition errno.h:535
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 void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
Definition usb.h:707
void * memset(void *dest, int character, size_t len) __nonnull
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:942
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:519
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:532
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
static struct usb_endpoint_driver_operations smsc95xx_in_operations
Bulk IN endpoint operations.
Definition smsc95xx.c:345
static struct net_device_operations smsc95xx_operations
SMSC95xx network device operations.
Definition smsc95xx.c:553
static int smsc95xx_fetch_mac(struct smscusb_device *smscusb)
Fetch MAC address.
Definition smsc95xx.c:143
#define SMSC95XX_MII_BASE
MII register base.
Definition smsc95xx.h:67
#define SMSC95XX_MII_PHY_INTR_SOURCE
PHY interrupt source MII register.
Definition smsc95xx.h:70
#define SMSC95XX_IN_MAX_FILL
Bulk IN maximum fill level.
Definition smsc95xx.h:170
#define SMSC95XX_IN_MTU
Bulk IN buffer size.
Definition smsc95xx.h:173
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:278
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:257
struct device dev
Generic device.
Definition usb.h:682
const char * name
Name.
Definition usb.h:676
int usbnet_describe(struct usbnet_device *usbnet, struct usb_configuration_descriptor *config)
Describe USB network device interfaces.
Definition usbnet.c:278

References alloc_etherdev(), DBGC, usb_function::dev, ENOMEM, usbnet_device::in, memset(), usb_function::name, netdev, netdev_init(), netdev_nullify(), netdev_put(), rc, register_netdev(), smsc95xx_fetch_mac(), SMSC95XX_IN_MAX_FILL, SMSC95XX_IN_MTU, smsc95xx_in_operations, SMSC95XX_MII_BASE, SMSC95XX_MII_PHY_INTR_SOURCE, smsc95xx_operations, smsc95xx_reset(), smscusb_init(), smscusb_mii_init(), strerror(), unregister_netdev(), usb_func_set_drvdata(), usb_refill_init(), smscusb_device::usbnet, and usbnet_describe().

◆ smsc95xx_remove()

void smsc95xx_remove ( struct usb_function * func)
static

Remove device.

Parameters
funcUSB function

Definition at line 637 of file smsc95xx.c.

637 {
638 struct net_device *netdev = usb_func_get_drvdata ( func );
639
642 netdev_put ( netdev );
643}
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition usb.h:718

References netdev, netdev_nullify(), netdev_put(), unregister_netdev(), and usb_func_get_drvdata().

Variable Documentation

◆ __profiler

struct profiler smsc95xx_out_profiler __profiler
static
Initial value:
=
{ .name = "smsc95xx.in" }

Bulk IN completion profiler.

Bulk OUT profiler.

Definition at line 46 of file smsc95xx.c.

47 { .name = "smsc95xx.in" };

◆ smsc95xx_in_operations

struct usb_endpoint_driver_operations smsc95xx_in_operations
static
Initial value:
= {
.complete = smsc95xx_in_complete,
}
static void smsc95xx_in_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk IN transfer.
Definition smsc95xx.c:285

Bulk IN endpoint operations.

Definition at line 345 of file smsc95xx.c.

345 {
346 .complete = smsc95xx_in_complete,
347};

Referenced by smsc95xx_probe().

◆ smsc95xx_operations

struct net_device_operations smsc95xx_operations
static
Initial value:
= {
.open = smsc95xx_open,
.close = smsc95xx_close,
.transmit = smsc95xx_transmit,
.poll = smsc95xx_poll,
}
static int smsc95xx_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition smsc95xx.c:490
static void smsc95xx_poll(struct net_device *netdev)
Poll for completed and received packets.
Definition smsc95xx.c:507
static void smsc95xx_close(struct net_device *netdev)
Close network device.
Definition smsc95xx.c:470
static int smsc95xx_open(struct net_device *netdev)
Open network device.
Definition smsc95xx.c:394

SMSC95xx network device operations.

Definition at line 553 of file smsc95xx.c.

553 {
554 .open = smsc95xx_open,
555 .close = smsc95xx_close,
556 .transmit = smsc95xx_transmit,
557 .poll = smsc95xx_poll,
558};

Referenced by smsc95xx_probe().

◆ smsc95xx_ids

struct usb_device_id smsc95xx_ids[]
static
Initial value:
= {
USB_ROM ( 0x0424, 0x9500, "smsc9500", "SMSC LAN9500", 0 ),
USB_ROM ( 0x0424, 0x9505, "smsc9505", "SMSC LAN9505", 0 ),
USB_ROM ( 0x0424, 0x9e00, "smsc9500a", "SMSC LAN9500A", 0 ),
USB_ROM ( 0x0424, 0x9e01, "smsc9505a", "SMSC LAN9505A", 0 ),
USB_ROM ( 0x0424, 0xec00, "smsc9514", "SMSC LAN9512/9514", 0 ),
USB_ROM ( 0x0424, 0x9900, "smsc9500-s", "SMSC LAN9500-S", 0 ),
USB_ROM ( 0x0424, 0x9901, "smsc9505-s", "SMSC LAN9505-S", 0 ),
USB_ROM ( 0x0424, 0x9902, "smsc9500a-s", "SMSC LAN9500A-S", 0 ),
USB_ROM ( 0x0424, 0x9903, "smsc9505a-s", "SMSC LAN9505A-S", 0 ),
USB_ROM ( 0x0424, 0x9904, "smsc9514-s", "SMSC LAN9512/9514-S", 0 ),
USB_ROM ( 0x0424, 0x9905, "smsc9500a-h", "SMSC LAN9500A-H", 0 ),
USB_ROM ( 0x0424, 0x9906, "smsc9505a-h", "SMSC LAN9505A-H", 0 ),
USB_ROM ( 0x0424, 0x9907, "smsc9500-2", "SMSC LAN9500-2", 0 ),
USB_ROM ( 0x0424, 0x9908, "smsc9500a-2", "SMSC LAN9500A-2", 0 ),
USB_ROM ( 0x0424, 0x9909, "smsc9514-2", "SMSC LAN9512/9514-2", 0 ),
USB_ROM ( 0x0424, 0x9530, "smsc9530", "SMSC LAN9530", 0 ),
USB_ROM ( 0x0424, 0x9730, "smsc9730", "SMSC LAN9730", 0 ),
USB_ROM ( 0x0424, 0x9e08, "smsc89530", "SMSC LAN89530", 0 ),
}
#define USB_ROM(_vendor, _product, _name, _description, _data)
Definition usb.h:1381

SMSC95xx device IDs.

Definition at line 646 of file smsc95xx.c.

646 {
647 USB_ROM ( 0x0424, 0x9500, "smsc9500", "SMSC LAN9500", 0 ),
648 USB_ROM ( 0x0424, 0x9505, "smsc9505", "SMSC LAN9505", 0 ),
649 USB_ROM ( 0x0424, 0x9e00, "smsc9500a", "SMSC LAN9500A", 0 ),
650 USB_ROM ( 0x0424, 0x9e01, "smsc9505a", "SMSC LAN9505A", 0 ),
651 USB_ROM ( 0x0424, 0xec00, "smsc9514", "SMSC LAN9512/9514", 0 ),
652 USB_ROM ( 0x0424, 0x9900, "smsc9500-s", "SMSC LAN9500-S", 0 ),
653 USB_ROM ( 0x0424, 0x9901, "smsc9505-s", "SMSC LAN9505-S", 0 ),
654 USB_ROM ( 0x0424, 0x9902, "smsc9500a-s", "SMSC LAN9500A-S", 0 ),
655 USB_ROM ( 0x0424, 0x9903, "smsc9505a-s", "SMSC LAN9505A-S", 0 ),
656 USB_ROM ( 0x0424, 0x9904, "smsc9514-s", "SMSC LAN9512/9514-S", 0 ),
657 USB_ROM ( 0x0424, 0x9905, "smsc9500a-h", "SMSC LAN9500A-H", 0 ),
658 USB_ROM ( 0x0424, 0x9906, "smsc9505a-h", "SMSC LAN9505A-H", 0 ),
659 USB_ROM ( 0x0424, 0x9907, "smsc9500-2", "SMSC LAN9500-2", 0 ),
660 USB_ROM ( 0x0424, 0x9908, "smsc9500a-2", "SMSC LAN9500A-2", 0 ),
661 USB_ROM ( 0x0424, 0x9909, "smsc9514-2", "SMSC LAN9512/9514-2", 0 ),
662 USB_ROM ( 0x0424, 0x9530, "smsc9530", "SMSC LAN9530", 0 ),
663 USB_ROM ( 0x0424, 0x9730, "smsc9730", "SMSC LAN9730", 0 ),
664 USB_ROM ( 0x0424, 0x9e08, "smsc89530", "SMSC LAN89530", 0 ),
665};

◆ __usb_driver

struct usb_driver smsc95xx_driver __usb_driver
Initial value:
= {
.ids = smsc95xx_ids,
.id_count = ( sizeof ( smsc95xx_ids ) / sizeof ( smsc95xx_ids[0] ) ),
.class = USB_CLASS_ID ( 0xff, 0x00, 0xff ),
.score = USB_SCORE_NORMAL,
.probe = smsc95xx_probe,
.remove = smsc95xx_remove,
}
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition usb.h:1401
@ USB_SCORE_NORMAL
Normal driver.
Definition usb.h:1465
static void smsc95xx_remove(struct usb_function *func)
Remove device.
Definition smsc95xx.c:637
static int smsc95xx_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition smsc95xx.c:574
static struct usb_device_id smsc95xx_ids[]
SMSC95xx device IDs.
Definition smsc95xx.c:646

SMSC LAN95xx driver.

Definition at line 668 of file smsc95xx.c.

668 {
669 .ids = smsc95xx_ids,
670 .id_count = ( sizeof ( smsc95xx_ids ) / sizeof ( smsc95xx_ids[0] ) ),
671 .class = USB_CLASS_ID ( 0xff, 0x00, 0xff ),
672 .score = USB_SCORE_NORMAL,
673 .probe = smsc95xx_probe,
674 .remove = smsc95xx_remove,
675};