iPXE
axge.c File Reference

Asix 10/100/1000 USB Ethernet driver. More...

#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <ipxe/netdevice.h>
#include <ipxe/ethernet.h>
#include <ipxe/if_ether.h>
#include <ipxe/profile.h>
#include <ipxe/usb.h>
#include "axge.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static int axge_read_register (struct axge_device *axge, unsigned int offset, void *data, size_t len)
 Read register.
static int axge_read_byte (struct axge_device *axge, unsigned int offset, uint8_t *value)
 Read one-byte register.
static int axge_read_word (struct axge_device *axge, unsigned int offset, uint16_t *value)
 Read two-byte register.
static int axge_read_dword (struct axge_device *axge, unsigned int offset, uint32_t *value)
 Read four-byte register.
static int axge_write_register (struct axge_device *axge, unsigned int offset, void *data, size_t len)
 Write register.
static int axge_write_byte (struct axge_device *axge, unsigned int offset, uint8_t value)
 Write one-byte register.
static int axge_write_word (struct axge_device *axge, unsigned int offset, uint16_t value)
 Write two-byte register.
static int axge_write_dword (struct axge_device *axge, unsigned int offset, uint32_t value)
 Write one-byte register.
static int axge_check_link (struct axge_device *axge)
 Get link status.
static void axge_intr_complete (struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
 Complete interrupt transfer.
static void axge_in_complete (struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
 Complete bulk IN transfer.
static int axge_out_transmit (struct axge_device *axge, struct io_buffer *iobuf)
 Transmit packet.
static void axge_out_complete (struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
 Complete bulk OUT transfer.
static int axge_open (struct net_device *netdev)
 Open network device.
static void axge_close (struct net_device *netdev)
 Close network device.
static int axge_transmit (struct net_device *netdev, struct io_buffer *iobuf)
 Transmit packet.
static void axge_poll (struct net_device *netdev)
 Poll for completed and received packets.
static int axge_probe (struct usb_function *func, struct usb_configuration_descriptor *config)
 Probe device.
static void axge_remove (struct usb_function *func)
 Remove device.

Variables

static struct profiler axge_intr_profiler __profiler
 Interrupt completion profiler.
static struct axge_bulk_in_control axge_bicr
 Default bulk IN configuration.
static struct usb_endpoint_driver_operations axge_intr_operations
 Interrupt endpoint operations.
static struct usb_endpoint_driver_operations axge_in_operations
 Bulk IN endpoint operations.
static struct usb_endpoint_driver_operations axge_out_operations
 Bulk OUT endpoint operations.
static struct net_device_operations axge_operations
 AXGE network device operations.
static struct usb_device_id axge_ids []
 AXGE device IDs.
struct usb_driver axge_driver __usb_driver
 AXGE driver.

Detailed Description

Asix 10/100/1000 USB Ethernet driver.

Large chunks of functionality are undocumented in the available datasheets. The gaps are deduced from combinations of the Linux driver, the FreeBSD driver, and experimentation with the hardware.

Definition in file axge.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ axge_read_register()

int axge_read_register ( struct axge_device * axge,
unsigned int offset,
void * data,
size_t len )
inlinestatic

Read register.

Parameters
asixAXGE device
offsetRegister offset
dataData buffer
lenLength of data
Return values
rcReturn status code

Definition at line 92 of file axge.c.

94 {
95
97 offset, len, data, len );
98}
#define AXGE_READ_MAC_REGISTER
Read MAC register.
Definition axge.h:17
uint16_t offset
Offset to command line.
Definition bzimage.h:3
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
struct usb_device * usb
USB device.
Definition axge.h:142
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

References AXGE_READ_MAC_REGISTER, data, len, offset, axge_device::usb, and usb_control().

Referenced by axge_probe(), axge_read_byte(), axge_read_dword(), and axge_read_word().

◆ axge_read_byte()

int axge_read_byte ( struct axge_device * axge,
unsigned int offset,
uint8_t * value )
inlinestatic

Read one-byte register.

Parameters
asixAXGE device
offsetRegister offset
valueValue to fill in
Return values
rcReturn status code

Definition at line 108 of file axge.c.

109 {
110
111 return axge_read_register ( axge, offset, value, sizeof ( *value ) );
112}
pseudo_bit_t value[0x00020]
Definition arbel.h:2
static int axge_read_register(struct axge_device *axge, unsigned int offset, void *data, size_t len)
Read register.
Definition axge.c:92

References axge_read_register(), offset, and value.

Referenced by axge_check_link().

◆ axge_read_word()

int axge_read_word ( struct axge_device * axge,
unsigned int offset,
uint16_t * value )
inlinestatic

Read two-byte register.

Parameters
asixAXGE device
offsetRegister offset
valueValue to fill in
Return values
rcReturn status code

Definition at line 122 of file axge.c.

123 {
124
125 return axge_read_register ( axge, offset, value, sizeof ( *value ) );
126}

References axge_read_register(), offset, and value.

◆ axge_read_dword()

int axge_read_dword ( struct axge_device * axge,
unsigned int offset,
uint32_t * value )
inlinestatic

Read four-byte register.

Parameters
asixAXGE device
offsetRegister offset
valueValue to fill in
Return values
rcReturn status code

Definition at line 136 of file axge.c.

137 {
138
139 return axge_read_register ( axge, offset, value, sizeof ( *value ) );
140}

References axge_read_register(), offset, and value.

◆ axge_write_register()

int axge_write_register ( struct axge_device * axge,
unsigned int offset,
void * data,
size_t len )
inlinestatic

Write register.

Parameters
asixAXGE device
offsetRegister offset
dataData buffer
lenLength of data
Return values
rcReturn status code

Definition at line 151 of file axge.c.

153 {
154
156 offset, len, data, len );
157}
#define AXGE_WRITE_MAC_REGISTER
Write MAC register.
Definition axge.h:22

References AXGE_WRITE_MAC_REGISTER, data, len, offset, axge_device::usb, and usb_control().

Referenced by axge_open(), axge_probe(), axge_write_byte(), axge_write_dword(), and axge_write_word().

◆ axge_write_byte()

int axge_write_byte ( struct axge_device * axge,
unsigned int offset,
uint8_t value )
inlinestatic

Write one-byte register.

Parameters
asixAXGE device
offsetRegister offset
valueValue
Return values
rcReturn status code

Definition at line 167 of file axge.c.

168 {
169
170 return axge_write_register ( axge, offset, &value, sizeof ( value ));
171}
static int axge_write_register(struct axge_device *axge, unsigned int offset, void *data, size_t len)
Write register.
Definition axge.c:151

References axge_write_register(), offset, and value.

Referenced by axge_probe().

◆ axge_write_word()

int axge_write_word ( struct axge_device * axge,
unsigned int offset,
uint16_t value )
inlinestatic

Write two-byte register.

Parameters
asixAXGE device
offsetRegister offset
valueValue
Return values
rcReturn status code

Definition at line 181 of file axge.c.

182 {
183
184 return axge_write_register ( axge, offset, &value, sizeof ( value ));
185}

References axge_write_register(), offset, and value.

Referenced by axge_check_link(), axge_close(), axge_open(), and axge_probe().

◆ axge_write_dword()

int axge_write_dword ( struct axge_device * axge,
unsigned int offset,
uint32_t value )
inlinestatic

Write one-byte register.

Parameters
asixAXGE device
offsetRegister offset
valueValue
Return values
rcReturn status code

Definition at line 195 of file axge.c.

196 {
197
198 return axge_write_register ( axge, offset, &value, sizeof ( value ));
199}

References axge_write_register(), offset, and value.

◆ axge_check_link()

int axge_check_link ( struct axge_device * axge)
static

Get link status.

Parameters
asixAXGE device
Return values
rcReturn status code

Definition at line 214 of file axge.c.

214 {
215 struct net_device *netdev = axge->netdev;
216 uint8_t plsr;
217 uint16_t msr;
218 int rc;
219
220 /* Read physical link status register */
221 if ( ( rc = axge_read_byte ( axge, AXGE_PLSR, &plsr ) ) != 0 ) {
222 DBGC ( axge, "AXGE %p could not read PLSR: %s\n",
223 axge, strerror ( rc ) );
224 return rc;
225 }
226
227 /* Write medium status register */
229 AXGE_MSR_RE );
230 if ( plsr & AXGE_PLSR_EPHY_1000 ) {
231 msr |= cpu_to_le16 ( AXGE_MSR_GM );
232 } else if ( plsr & AXGE_PLSR_EPHY_100 ) {
233 msr |= cpu_to_le16 ( AXGE_MSR_PS );
234 }
235 if ( ( rc = axge_write_word ( axge, AXGE_MSR, msr ) ) != 0 ) {
236 DBGC ( axge, "AXGE %p could not write MSR: %s\n",
237 axge, strerror ( rc ) );
238 return rc;
239 }
240
241 /* Update link status */
242 if ( plsr & AXGE_PLSR_EPHY_ANY ) {
243 DBGC ( axge, "AXGE %p link up (PLSR %02x MSR %04x)\n",
244 axge, plsr, msr );
246 } else {
247 DBGC ( axge, "AXGE %p link down (PLSR %02x MSR %04x)\n",
248 axge, plsr, msr );
250 }
251
252 return 0;
253}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned short uint16_t
Definition stdint.h:11
unsigned char uint8_t
Definition stdint.h:10
static int axge_write_word(struct axge_device *axge, unsigned int offset, uint16_t value)
Write two-byte register.
Definition axge.c:181
static int axge_read_byte(struct axge_device *axge, unsigned int offset, uint8_t *value)
Read one-byte register.
Definition axge.c:108
#define AXGE_PLSR_EPHY_ANY
Definition axge.h:31
#define AXGE_MSR_GM
Gigabit mode.
Definition axge.h:48
#define AXGE_PLSR_EPHY_1000
Ethernet at 1000Mbps.
Definition axge.h:30
#define AXGE_PLSR_EPHY_100
Ethernet at 100Mbps.
Definition axge.h:29
#define AXGE_MSR_FD
Full duplex.
Definition axge.h:49
#define AXGE_MSR
Medium Status Register.
Definition axge.h:47
#define AXGE_MSR_RFC
RX flow control enable.
Definition axge.h:50
#define AXGE_MSR_TFC
TX flow control enable.
Definition axge.h:51
#define AXGE_PLSR
Physical Link Status Register.
Definition axge.h:27
#define AXGE_MSR_PS
100Mbps port speed
Definition axge.h:53
#define AXGE_MSR_RE
Receive enable.
Definition axge.h:52
static struct net_device * netdev
Definition gdbudp.c:53
#define DBGC(...)
Definition compiler.h:505
#define cpu_to_le16(value)
Definition byteswap.h:107
void netdev_link_down(struct net_device *netdev)
Mark network device as having link down.
Definition netdevice.c:231
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition netdevice.h:789
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
struct net_device * netdev
Network device.
Definition axge.h:146
A network device.
Definition netdevice.h:353

References AXGE_MSR, AXGE_MSR_FD, AXGE_MSR_GM, AXGE_MSR_PS, AXGE_MSR_RE, AXGE_MSR_RFC, AXGE_MSR_TFC, AXGE_PLSR, AXGE_PLSR_EPHY_100, AXGE_PLSR_EPHY_1000, AXGE_PLSR_EPHY_ANY, axge_read_byte(), axge_write_word(), cpu_to_le16, DBGC, axge_device::netdev, netdev, netdev_link_down(), netdev_link_up(), rc, and strerror().

Referenced by axge_open(), axge_poll(), and axge_probe().

◆ axge_intr_complete()

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

Complete interrupt transfer.

Parameters
epUSB endpoint
iobufI/O buffer
rcCompletion status code

Definition at line 269 of file axge.c.

270 {
271 struct axge_device *axge = container_of ( ep, struct axge_device,
272 usbnet.intr );
273 struct net_device *netdev = axge->netdev;
274 struct axge_interrupt *intr;
275 size_t len = iob_len ( iobuf );
276 unsigned int link_ok;
277
278 /* Profile completions */
279 profile_start ( &axge_intr_profiler );
280
281 /* Ignore packets cancelled when the endpoint closes */
282 if ( ! ep->open )
283 goto ignore;
284
285 /* Drop packets with errors */
286 if ( rc != 0 ) {
287 DBGC ( axge, "AXGE %p interrupt failed: %s\n",
288 axge, strerror ( rc ) );
289 DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
290 goto error;
291 }
292
293 /* Extract message header */
294 if ( len < sizeof ( *intr ) ) {
295 DBGC ( axge, "AXGE %p underlength interrupt:\n", axge );
296 DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
297 rc = -EINVAL;
298 goto error;
299 }
300 intr = iobuf->data;
301
302 /* Check magic signature */
303 if ( intr->magic != cpu_to_le16 ( AXGE_INTR_MAGIC ) ) {
304 DBGC ( axge, "AXGE %p malformed interrupt:\n", axge );
305 DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
306 rc = -EINVAL;
307 goto error;
308 }
309
310 /* Extract link status */
311 link_ok = ( intr->link & cpu_to_le16 ( AXGE_INTR_LINK_PPLS ) );
312 if ( ( !! link_ok ) ^ ( !! netdev_link_ok ( netdev ) ) )
313 axge->check_link = 1;
314
315 /* Free I/O buffer */
316 free_iob ( iobuf );
317 profile_stop ( &axge_intr_profiler );
318
319 return;
320
321 error:
322 netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
323 ignore:
324 free_iob ( iobuf );
325 return;
326}
struct arbelprm_completion_with_error error
Definition arbel.h:1
#define AXGE_INTR_LINK_PPLS
Link is up.
Definition axge.h:137
#define AXGE_INTR_MAGIC
Interrupt magic signature.
Definition axge.h:134
uint8_t intr
Interrupts enabled.
Definition ena.h:3
#define DBGC_HDA(...)
Definition compiler.h:506
#define EINVAL
Invalid argument.
Definition errno.h:429
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
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition netdevice.c:587
static int netdev_link_ok(struct net_device *netdev)
Check link state of network device.
Definition netdevice.h:640
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
An AXGE network device.
Definition axge.h:140
struct usbnet_device usbnet
USB network device.
Definition axge.h:148
int check_link
Link state has changed.
Definition axge.h:152
Interrupt data.
Definition axge.h:122
void * data
Start of data.
Definition iobuf.h:53
int open
Endpoint is open.
Definition usb.h:419
struct usb_endpoint intr
Interrupt endpoint.
Definition usbnet.h:28

References AXGE_INTR_LINK_PPLS, AXGE_INTR_MAGIC, axge_device::check_link, container_of, cpu_to_le16, io_buffer::data, DBGC, DBGC_HDA, EINVAL, error, free_iob(), intr, usbnet_device::intr, iob_disown, iob_len(), len, axge_device::netdev, netdev, netdev_link_ok(), netdev_rx_err(), usb_endpoint::open, profile_start(), profile_stop(), rc, strerror(), and axge_device::usbnet.

◆ axge_in_complete()

void axge_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 347 of file axge.c.

348 {
349 struct axge_device *axge = container_of ( ep, struct axge_device,
350 usbnet.in );
351 struct net_device *netdev = axge->netdev;
352 struct axge_rx_footer *ftr;
353 struct axge_rx_descriptor *desc;
354 struct io_buffer *pkt;
355 unsigned int count;
356 unsigned int offset;
357 size_t len;
358 size_t padded_len;
359
360 /* Profile receive completions */
361 profile_start ( &axge_in_profiler );
362
363 /* Ignore packets cancelled when the endpoint closes */
364 if ( ! ep->open )
365 goto ignore;
366
367 /* Record USB errors against the network device */
368 if ( rc != 0 ) {
369 DBGC ( axge, "AXGE %p bulk IN failed: %s\n",
370 axge, strerror ( rc ) );
371 goto error;
372 }
373
374 /* Sanity check */
375 if ( iob_len ( iobuf ) < sizeof ( *ftr ) ) {
376 DBGC ( axge, "AXGE %p underlength bulk IN:\n", axge );
377 DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
378 rc = -EINVAL;
379 goto error;
380 }
381
382 /* Parse ftr, strip ftr and descriptors */
383 iob_unput ( iobuf, sizeof ( *ftr ) );
384 ftr = ( iobuf->data + iob_len ( iobuf ) );
385 count = le16_to_cpu ( ftr->count );
386 if ( count == 0 ) {
387 DBGC ( axge, "AXGE %p zero-packet bulk IN:\n", axge );
388 DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
389 goto ignore;
390 }
391 offset = le16_to_cpu ( ftr->offset );
392 if ( ( iob_len ( iobuf ) < offset ) ||
393 ( ( iob_len ( iobuf ) - offset ) < ( count * sizeof ( *desc ) ) )){
394 DBGC ( axge, "AXGE %p malformed bulk IN footer:\n", axge );
395 DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
396 rc = -EINVAL;
397 goto error;
398 }
399 desc = ( iobuf->data + offset );
400 iob_unput ( iobuf, ( iob_len ( iobuf ) - offset ) );
401
402 /* Process packets */
403 for ( ; count-- ; desc++ ) {
404
405 /* Parse descriptor */
406 len = ( le16_to_cpu ( desc->len_flags ) & AXGE_RX_LEN_MASK );
407 padded_len = ( ( len + AXGE_RX_LEN_PAD_ALIGN - 1 ) &
408 ~( AXGE_RX_LEN_PAD_ALIGN - 1 ) );
409 if ( iob_len ( iobuf ) < padded_len ) {
410 DBGC ( axge, "AXGE %p malformed bulk IN descriptor:\n",
411 axge );
412 DBGC_HDA ( axge, 0, iobuf->data, iob_len ( iobuf ) );
413 rc = -EINVAL;
414 goto error;
415 }
416
417 /* Check for previous dropped packets */
418 if ( desc->len_flags & cpu_to_le16 ( AXGE_RX_CRC_ERROR ) )
420 if ( desc->len_flags & cpu_to_le16 ( AXGE_RX_DROP_ERROR ) )
422
423 /* Allocate new I/O buffer, if applicable */
424 if ( count ) {
425
426 /* More packets remain: allocate a new buffer */
427 pkt = alloc_iob ( AXGE_IN_RESERVE + len );
428 if ( ! pkt ) {
429 /* Record error and continue */
431 iob_pull ( iobuf, padded_len );
432 continue;
433 }
435 memcpy ( iob_put ( pkt, len ), iobuf->data, len );
436 iob_pull ( iobuf, padded_len );
437
438 } else {
439
440 /* This is the last (or only) packet: use this buffer */
441 iob_unput ( iobuf, ( padded_len - len ) );
442 pkt = iob_disown ( iobuf );
443 }
444
445 /* Hand off to network stack */
446 netdev_rx ( netdev, iob_disown ( pkt ) );
447 }
448
449 assert ( iobuf == NULL );
450 profile_stop ( &axge_in_profiler );
451 return;
452
453 error:
454 netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
455 ignore:
456 free_iob ( iobuf );
457}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define AXGE_RX_LEN_MASK
Receive packet length mask.
Definition axge.h:110
#define AXGE_RX_LEN_PAD_ALIGN
Receive packet length alignment.
Definition axge.h:113
#define AXGE_IN_RESERVE
Amount of space to reserve at start of bulk IN buffers.
Definition axge.h:178
#define AXGE_RX_DROP_ERROR
Receive packet dropped error.
Definition axge.h:119
#define AXGE_RX_CRC_ERROR
Receive packet CRC error.
Definition axge.h:116
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define ENOMEM
Not enough space.
Definition errno.h:535
#define EIO
Input/output error.
Definition errno.h:434
#define ENOBUFS
No buffer space available.
Definition errno.h:499
#define le16_to_cpu(value)
Definition byteswap.h:113
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define iob_put(iobuf, len)
Definition iobuf.h:125
#define iob_reserve(iobuf, len)
Definition iobuf.h:72
#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
Receive packet descriptor.
Definition axge.h:102
A persistent I/O buffer.
Definition iobuf.h:38
struct usb_endpoint in
Bulk IN endpoint.
Definition usbnet.h:30

References alloc_iob(), assert, AXGE_IN_RESERVE, AXGE_RX_CRC_ERROR, AXGE_RX_DROP_ERROR, AXGE_RX_LEN_MASK, AXGE_RX_LEN_PAD_ALIGN, container_of, axge_rx_footer::count, count, cpu_to_le16, io_buffer::data, DBGC, DBGC_HDA, desc, EINVAL, EIO, ENOBUFS, ENOMEM, error, free_iob(), usbnet_device::in, iob_disown, iob_len(), iob_pull, iob_put, iob_reserve, iob_unput, le16_to_cpu, len, memcpy(), axge_device::netdev, netdev, netdev_rx(), netdev_rx_err(), NULL, axge_rx_footer::offset, offset, usb_endpoint::open, profile_start(), profile_stop(), rc, strerror(), and axge_device::usbnet.

◆ axge_out_transmit()

int axge_out_transmit ( struct axge_device * axge,
struct io_buffer * iobuf )
static

Transmit packet.

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

Definition at line 471 of file axge.c.

472 {
473 struct axge_tx_header *hdr;
474 size_t len = iob_len ( iobuf );
475 int rc;
476
477 /* Profile transmissions */
478 profile_start ( &axge_out_profiler );
479
480 /* Prepend header */
481 if ( ( rc = iob_ensure_headroom ( iobuf, sizeof ( *hdr ) ) ) != 0 )
482 return rc;
483 hdr = iob_push ( iobuf, sizeof ( *hdr ) );
484 hdr->len = cpu_to_le32 ( len );
485 hdr->wtf = 0;
486
487 /* Enqueue I/O buffer */
488 if ( ( rc = usb_stream ( &axge->usbnet.out, iobuf, 0 ) ) != 0 )
489 return rc;
490
491 profile_stop ( &axge_out_profiler );
492 return 0;
493}
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
#define cpu_to_le32(value)
Definition byteswap.h:108
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
Transmit packet header.
Definition axge.h:86
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, hdr, iob_ensure_headroom(), iob_len(), iob_push, len, usbnet_device::out, profile_start(), profile_stop(), rc, usb_stream(), and axge_device::usbnet.

Referenced by axge_transmit().

◆ axge_out_complete()

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

Complete bulk OUT transfer.

Parameters
epUSB endpoint
iobufI/O buffer
rcCompletion status code

Definition at line 502 of file axge.c.

503 {
504 struct axge_device *axge = container_of ( ep, struct axge_device,
505 usbnet.out );
506 struct net_device *netdev = axge->netdev;
507
508 /* Report TX completion */
509 netdev_tx_complete_err ( netdev, iobuf, rc );
510}
void netdev_tx_complete_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Complete network transmission.
Definition netdevice.c:471

References container_of, axge_device::netdev, netdev, netdev_tx_complete_err(), usbnet_device::out, rc, and axge_device::usbnet.

◆ axge_open()

int axge_open ( struct net_device * netdev)
static

Open network device.

Parameters
netdevNetwork device
Return values
rcReturn status code

Definition at line 530 of file axge.c.

530 {
531 struct axge_device *axge = netdev->priv;
532 uint16_t rcr;
533 int rc;
534
535 /* Reapply device configuration to avoid transaction errors */
536 if ( ( rc = usb_set_configuration ( axge->usb, axge->config ) ) != 0 ) {
537 DBGC ( axge, "AXGE %p could not set configuration: %s\n",
538 axge, strerror ( rc ) );
539 goto err_set_configuration;
540 }
541
542 /* Open USB network device */
543 if ( ( rc = usbnet_open ( &axge->usbnet ) ) != 0 ) {
544 DBGC ( axge, "AXGE %p could not open: %s\n",
545 axge, strerror ( rc ) );
546 goto err_open;
547 }
548
549 /* Set MAC address */
550 if ( ( rc = axge_write_register ( axge, AXGE_NIDR,
551 netdev->ll_addr, ETH_ALEN ) ) !=0){
552 DBGC ( axge, "AXGE %p could not set MAC address: %s\n",
553 axge, strerror ( rc ) );
554 goto err_write_mac;
555 }
556
557 /* Enable receiver */
560 if ( ( rc = axge_write_word ( axge, AXGE_RCR, rcr ) ) != 0 ) {
561 DBGC ( axge, "AXGE %p could not write RCR: %s\n",
562 axge, strerror ( rc ) );
563 goto err_write_rcr;
564 }
565
566 /* Update link status */
567 if ( ( rc = axge_check_link ( axge ) ) != 0 )
568 goto err_check_link;
569
570 return 0;
571
572 err_check_link:
573 axge_write_word ( axge, AXGE_RCR, 0 );
574 err_write_rcr:
575 err_write_mac:
576 usbnet_close ( &axge->usbnet );
577 err_open:
578 err_set_configuration:
579 return rc;
580}
static int axge_check_link(struct axge_device *axge)
Get link status.
Definition axge.c:214
#define AXGE_RCR_SO
Start operation.
Definition axge.h:41
#define AXGE_RCR
RX Control Register.
Definition axge.h:37
#define AXGE_RCR_PRO
Promiscuous mode.
Definition axge.h:38
#define AXGE_RCR_AMALL
Accept all multicasts.
Definition axge.h:39
#define AXGE_NIDR
Node ID Register.
Definition axge.h:44
#define AXGE_RCR_AB
Accept broadcasts.
Definition axge.h:40
#define ETH_ALEN
Definition if_ether.h:9
static int usb_set_configuration(struct usb_device *usb, unsigned int index)
Set USB configuration.
Definition usb.h:1242
unsigned int config
Device configuration.
Definition axge.h:150
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 axge_check_link(), AXGE_NIDR, AXGE_RCR, AXGE_RCR_AB, AXGE_RCR_AMALL, AXGE_RCR_PRO, AXGE_RCR_SO, axge_write_register(), axge_write_word(), axge_device::config, cpu_to_le16, DBGC, ETH_ALEN, netdev, rc, strerror(), axge_device::usb, usb_set_configuration(), axge_device::usbnet, usbnet_close(), and usbnet_open().

◆ axge_close()

void axge_close ( struct net_device * netdev)
static

Close network device.

Parameters
netdevNetwork device

Definition at line 587 of file axge.c.

587 {
588 struct axge_device *axge = netdev->priv;
589
590 /* Disable receiver */
591 axge_write_word ( axge, AXGE_RCR, 0 );
592
593 /* Close USB network device */
594 usbnet_close ( &axge->usbnet );
595}

References AXGE_RCR, axge_write_word(), netdev, axge_device::usbnet, and usbnet_close().

◆ axge_transmit()

int axge_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 604 of file axge.c.

605 {
606 struct axge_device *axge = netdev->priv;
607 int rc;
608
609 /* Transmit packet */
610 if ( ( rc = axge_out_transmit ( axge, iobuf ) ) != 0 )
611 return rc;
612
613 return 0;
614}
static int axge_out_transmit(struct axge_device *axge, struct io_buffer *iobuf)
Transmit packet.
Definition axge.c:471

References axge_out_transmit(), netdev, and rc.

◆ axge_poll()

void axge_poll ( struct net_device * netdev)
static

Poll for completed and received packets.

Parameters
netdevNetwork device

Definition at line 621 of file axge.c.

621 {
622 struct axge_device *axge = netdev->priv;
623 int rc;
624
625 /* Poll USB bus */
626 usb_poll ( axge->bus );
627
628 /* Refill endpoints */
629 if ( ( rc = usbnet_refill ( &axge->usbnet ) ) != 0 )
631
632 /* Update link state, if applicable */
633 if ( axge->check_link ) {
634 if ( ( rc = axge_check_link ( axge ) ) == 0 ) {
635 axge->check_link = 0;
636 } else {
638 }
639 }
640}
static void usb_poll(struct usb_bus *bus)
Poll USB bus.
Definition usb.h:1072
struct usb_bus * bus
USB bus.
Definition axge.h:144
int usbnet_refill(struct usbnet_device *usbnet)
Refill USB network device bulk IN and interrupt endpoints.
Definition usbnet.c:152

References axge_check_link(), axge_device::bus, axge_device::check_link, netdev, netdev_rx_err(), NULL, rc, usb_poll(), axge_device::usbnet, and usbnet_refill().

◆ axge_probe()

int axge_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 664 of file axge.c.

665 {
666 struct usb_device *usb = func->usb;
667 struct net_device *netdev;
668 struct axge_device *axge;
669 uint16_t epprcr;
670 uint8_t csr;
671 int rc;
672
673 /* Allocate and initialise structure */
674 netdev = alloc_etherdev ( sizeof ( *axge ) );
675 if ( ! netdev ) {
676 rc = -ENOMEM;
677 goto err_alloc;
678 }
680 netdev->dev = &func->dev;
681 axge = netdev->priv;
682 memset ( axge, 0, sizeof ( *axge ) );
683 axge->usb = usb;
684 axge->bus = usb->port->hub->bus;
685 axge->netdev = netdev;
686 axge->config = config->config;
687 usbnet_init ( &axge->usbnet, func, &axge_intr_operations,
692 DBGC ( axge, "AXGE %p on %s\n", axge, func->name );
693
694 /* Describe USB network device */
695 if ( ( rc = usbnet_describe ( &axge->usbnet, config ) ) != 0 ) {
696 DBGC ( axge, "AXGE %p could not describe: %s\n",
697 axge, strerror ( rc ) );
698 goto err_describe;
699 }
700
701 /* Fetch MAC address */
702 if ( ( rc = axge_read_register ( axge, AXGE_NIDR, netdev->hw_addr,
703 ETH_ALEN ) ) != 0 ) {
704 DBGC ( axge, "AXGE %p could not fetch MAC address: %s\n",
705 axge, strerror ( rc ) );
706 goto err_read_mac;
707 }
708
709 /* Power up PHY */
710 if ( ( rc = axge_write_word ( axge, AXGE_EPPRCR, 0 ) ) != 0 ) {
711 DBGC ( axge, "AXGE %p could not write EPPRCR: %s\n",
712 axge, strerror ( rc ) );
713 goto err_write_epprcr_off;
714 }
715 epprcr = cpu_to_le16 ( AXGE_EPPRCR_IPRL );
716 if ( ( rc = axge_write_word ( axge, AXGE_EPPRCR, epprcr ) ) != 0){
717 DBGC ( axge, "AXGE %p could not write EPPRCR: %s\n",
718 axge, strerror ( rc ) );
719 goto err_write_epprcr_on;
720 }
722
723 /* Select clocks */
724 csr = ( AXGE_CSR_BCS | AXGE_CSR_ACS );
725 if ( ( rc = axge_write_byte ( axge, AXGE_CSR, csr ) ) != 0){
726 DBGC ( axge, "AXGE %p could not write CSR: %s\n",
727 axge, strerror ( rc ) );
728 goto err_write_csr;
729 }
731
732 /* Configure bulk IN pipeline */
733 if ( ( rc = axge_write_register ( axge, AXGE_BICR, &axge_bicr,
734 sizeof ( axge_bicr ) ) ) != 0 ){
735 DBGC ( axge, "AXGE %p could not write BICR: %s\n",
736 axge, strerror ( rc ) );
737 goto err_write_bicr;
738 }
739
740 /* Register network device */
741 if ( ( rc = register_netdev ( netdev ) ) != 0 )
742 goto err_register;
743
744 /* Update link status */
745 if ( ( rc = axge_check_link ( axge ) ) != 0 )
746 goto err_check_link;
747
748 usb_func_set_drvdata ( func, axge );
749 return 0;
750
751 err_check_link:
753 err_register:
754 err_write_bicr:
755 err_write_csr:
756 err_write_epprcr_on:
757 err_write_epprcr_off:
758 err_read_mac:
759 err_describe:
761 netdev_put ( netdev );
762 err_alloc:
763 return rc;
764}
static int axge_write_byte(struct axge_device *axge, unsigned int offset, uint8_t value)
Write one-byte register.
Definition axge.c:167
static struct usb_endpoint_driver_operations axge_intr_operations
Interrupt endpoint operations.
Definition axge.c:329
static struct axge_bulk_in_control axge_bicr
Default bulk IN configuration.
Definition axge.c:69
static struct usb_endpoint_driver_operations axge_out_operations
Bulk OUT endpoint operations.
Definition axge.c:513
static struct net_device_operations axge_operations
AXGE network device operations.
Definition axge.c:643
static struct usb_endpoint_driver_operations axge_in_operations
Bulk IN endpoint operations.
Definition axge.c:460
#define AXGE_BICR
Bulk IN Control Register (undocumented)
Definition axge.h:63
#define AXGE_IN_MAX_FILL
Bulk IN maximum fill level.
Definition axge.h:165
#define AXGE_CSR_DELAY_MS
Delay after initialising CSR.
Definition axge.h:83
#define AXGE_INTR_MAX_FILL
Interrupt maximum fill level.
Definition axge.h:159
#define AXGE_CSR_BCS
Undocumented.
Definition axge.h:79
#define AXGE_EPPRCR_DELAY_MS
Delay after initialising EPPRCR.
Definition axge.h:60
#define AXGE_IN_MTU
Bulk IN buffer size.
Definition axge.h:171
#define AXGE_EPPRCR_IPRL
Undocumented.
Definition axge.h:57
#define AXGE_CSR_ACS
Undocumented.
Definition axge.h:80
#define AXGE_CSR
Clock Select Register (undocumented)
Definition axge.h:78
#define AXGE_EPPRCR
Ethernet PHY Power and Reset Control Register.
Definition axge.h:56
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:265
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
A USB device.
Definition usb.h:723
struct usb_port * port
USB port.
Definition usb.h:727
struct usb_device * usb
USB device.
Definition usb.h:678
struct device dev
Generic device.
Definition usb.h:682
const char * name
Name.
Definition usb.h:676
struct usb_bus * bus
USB bus.
Definition usb.h:845
struct usb_hub * hub
USB hub.
Definition usb.h:815
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition timer.c:79
int usbnet_describe(struct usbnet_device *usbnet, struct usb_configuration_descriptor *config)
Describe USB network device interfaces.
Definition usbnet.c:278
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

References alloc_etherdev(), AXGE_BICR, axge_bicr, axge_check_link(), AXGE_CSR, AXGE_CSR_ACS, AXGE_CSR_BCS, AXGE_CSR_DELAY_MS, AXGE_EPPRCR, AXGE_EPPRCR_DELAY_MS, AXGE_EPPRCR_IPRL, AXGE_IN_MAX_FILL, AXGE_IN_MTU, axge_in_operations, AXGE_IN_RESERVE, AXGE_INTR_MAX_FILL, axge_intr_operations, AXGE_NIDR, axge_operations, axge_out_operations, axge_read_register(), axge_write_byte(), axge_write_register(), axge_write_word(), axge_device::bus, usb_hub::bus, axge_device::config, cpu_to_le16, DBGC, usb_function::dev, ENOMEM, ETH_ALEN, usb_port::hub, usbnet_device::in, usbnet_device::intr, mdelay(), memset(), usb_function::name, axge_device::netdev, netdev, netdev_init(), netdev_nullify(), netdev_put(), usb_device::port, rc, register_netdev(), strerror(), unregister_netdev(), axge_device::usb, usb_function::usb, usb_func_set_drvdata(), usb_refill_init(), axge_device::usbnet, usbnet_describe(), and usbnet_init().

◆ axge_remove()

void axge_remove ( struct usb_function * func)
static

Remove device.

Parameters
funcUSB function

Definition at line 771 of file axge.c.

771 {
772 struct axge_device *axge = usb_func_get_drvdata ( func );
773 struct net_device *netdev = axge->netdev;
774
777 netdev_put ( netdev );
778}
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition usb.h:718

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

Variable Documentation

◆ __profiler

struct profiler axge_out_profiler __profiler
static
Initial value:
=
{ .name = "axge.intr" }

Interrupt completion profiler.

Bulk OUT profiler.

Bulk IN completion profiler.

Definition at line 48 of file axge.c.

49 { .name = "axge.intr" };

◆ axge_bicr

struct axge_bulk_in_control axge_bicr
static
Initial value:
= {
.ctrl = 7,
.timer = cpu_to_le16 ( 0 ),
.size = 0,
.ifg = 0,
}

Default bulk IN configuration.

The Linux and FreeBSD drivers have set of magic constants which are chosen based on both the Ethernet and USB link speeds.

Experimentation shows that setting the "timer" value to zero seems to prevent the device from ever coalescing multiple packets into a single bulk IN transfer. This allows us to get away with using a 2kB receive I/O buffer and a zerocopy receive path.

Definition at line 69 of file axge.c.

69 {
70 .ctrl = 7,
71 .timer = cpu_to_le16 ( 0 ),
72 .size = 0,
73 .ifg = 0,
74};

Referenced by axge_probe().

◆ axge_intr_operations

struct usb_endpoint_driver_operations axge_intr_operations
static
Initial value:
= {
.complete = axge_intr_complete,
}
static void axge_intr_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete interrupt transfer.
Definition axge.c:269

Interrupt endpoint operations.

Definition at line 329 of file axge.c.

329 {
330 .complete = axge_intr_complete,
331};

Referenced by axge_probe().

◆ axge_in_operations

struct usb_endpoint_driver_operations axge_in_operations
static
Initial value:
= {
.complete = axge_in_complete,
}
static void axge_in_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk IN transfer.
Definition axge.c:347

Bulk IN endpoint operations.

Definition at line 460 of file axge.c.

460 {
461 .complete = axge_in_complete,
462};

Referenced by axge_probe().

◆ axge_out_operations

struct usb_endpoint_driver_operations axge_out_operations
static
Initial value:
= {
.complete = axge_out_complete,
}
static void axge_out_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk OUT transfer.
Definition axge.c:502

Bulk OUT endpoint operations.

Definition at line 513 of file axge.c.

513 {
514 .complete = axge_out_complete,
515};

Referenced by axge_probe().

◆ axge_operations

struct net_device_operations axge_operations
static
Initial value:
= {
.open = axge_open,
.close = axge_close,
.transmit = axge_transmit,
.poll = axge_poll,
}
static void axge_close(struct net_device *netdev)
Close network device.
Definition axge.c:587
static int axge_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition axge.c:604
static void axge_poll(struct net_device *netdev)
Poll for completed and received packets.
Definition axge.c:621
static int axge_open(struct net_device *netdev)
Open network device.
Definition axge.c:530

AXGE network device operations.

Definition at line 643 of file axge.c.

643 {
644 .open = axge_open,
645 .close = axge_close,
646 .transmit = axge_transmit,
647 .poll = axge_poll,
648};

Referenced by axge_probe().

◆ axge_ids

struct usb_device_id axge_ids[]
static
Initial value:
= {
USB_ROM ( 0x0b95, 0x1790, "ax88179", "AX88179", 0 ),
USB_ROM ( 0x0b95, 0x178a, "ax88178a", "AX88178A", 0 ),
USB_ROM ( 0x2001, 0x4a00, "dub1312", "DUB-1312", 0 ),
USB_ROM ( 0x0df6, 0x0072, "axge-sitecom", "AX88179 (Sitecom)", 0 ),
USB_ROM ( 0x04e8, 0xa100, "axge-samsung", "AX88179 (Samsung)", 0 ),
USB_ROM ( 0x17ef, 0x304b, "onelinkdock", "ThinkPad OneLink dock", 0 ),
}
#define USB_ROM(_vendor, _product, _name, _description, _data)
Definition usb.h:1381

AXGE device IDs.

Definition at line 781 of file axge.c.

781 {
782 USB_ROM ( 0x0b95, 0x1790, "ax88179", "AX88179", 0 ),
783 USB_ROM ( 0x0b95, 0x178a, "ax88178a", "AX88178A", 0 ),
784 USB_ROM ( 0x2001, 0x4a00, "dub1312", "DUB-1312", 0 ),
785 USB_ROM ( 0x0df6, 0x0072, "axge-sitecom", "AX88179 (Sitecom)", 0 ),
786 USB_ROM ( 0x04e8, 0xa100, "axge-samsung", "AX88179 (Samsung)", 0 ),
787 USB_ROM ( 0x17ef, 0x304b, "onelinkdock", "ThinkPad OneLink dock", 0 ),
788};

◆ __usb_driver

struct usb_driver axge_driver __usb_driver
Initial value:
= {
.ids = axge_ids,
.id_count = ( sizeof ( axge_ids ) / sizeof ( axge_ids[0] ) ),
.score = USB_SCORE_NORMAL,
.probe = axge_probe,
.remove = axge_remove,
}
static struct usb_device_id axge_ids[]
AXGE device IDs.
Definition axge.c:781
static int axge_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition axge.c:664
static void axge_remove(struct usb_function *func)
Remove device.
Definition axge.c:771
#define USB_ANY_ID
Match-anything ID.
Definition usb.h:1385
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition usb.h:1401
@ USB_SCORE_NORMAL
Normal driver.
Definition usb.h:1465

AXGE driver.

Definition at line 791 of file axge.c.

791 {
792 .ids = axge_ids,
793 .id_count = ( sizeof ( axge_ids ) / sizeof ( axge_ids[0] ) ),
795 .score = USB_SCORE_NORMAL,
796 .probe = axge_probe,
797 .remove = axge_remove,
798};