Skip to content

Commit cc5a27f

Browse files
committed
[ncm] Add support for CDC-NCM USB Ethernet devices
Signed-off-by: Michael Brown <mcb30@ipxe.org>
1 parent fd53ada commit cc5a27f

File tree

6 files changed

+1198
-0
lines changed

6 files changed

+1198
-0
lines changed

src/drivers/net/ecm.c

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3+
*
4+
* This program is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU General Public License as
6+
* published by the Free Software Foundation; either version 2 of the
7+
* License, or (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful, but
10+
* WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17+
* 02110-1301, USA.
18+
*/
19+
20+
FILE_LICENCE ( GPL2_OR_LATER );
21+
22+
#include <stdint.h>
23+
#include <errno.h>
24+
#include <ipxe/if_ether.h>
25+
#include <ipxe/base16.h>
26+
#include <ipxe/usb.h>
27+
#include "ecm.h"
28+
29+
/** @file
30+
*
31+
* CDC-ECM USB Ethernet driver
32+
*
33+
*/
34+
35+
/**
36+
* Locate Ethernet functional descriptor
37+
*
38+
* @v config Configuration descriptor
39+
* @v interface Interface descriptor
40+
* @ret desc Descriptor, or NULL if not found
41+
*/
42+
struct ecm_ethernet_descriptor *
43+
ecm_ethernet_descriptor ( struct usb_configuration_descriptor *config,
44+
struct usb_interface_descriptor *interface ) {
45+
struct ecm_ethernet_descriptor *desc;
46+
47+
for_each_interface_descriptor ( desc, config, interface ) {
48+
if ( ( desc->header.type == USB_CS_INTERFACE_DESCRIPTOR ) &&
49+
( desc->subtype == CDC_SUBTYPE_ETHERNET ) )
50+
return desc;
51+
}
52+
return NULL;
53+
}
54+
55+
/**
56+
* Get hardware MAC address
57+
*
58+
* @v usb USB device
59+
* @v desc Ethernet functional descriptor
60+
* @v hw_addr Hardware address to fill in
61+
* @ret rc Return status code
62+
*/
63+
int ecm_fetch_mac ( struct usb_device *usb,
64+
struct ecm_ethernet_descriptor *desc, uint8_t *hw_addr ) {
65+
char buf[ base16_encoded_len ( ETH_ALEN ) + 1 /* NUL */ ];
66+
int len;
67+
int rc;
68+
69+
/* Fetch MAC address string */
70+
len = usb_get_string_descriptor ( usb, desc->mac, 0, buf,
71+
sizeof ( buf ) );
72+
if ( len < 0 ) {
73+
rc = len;
74+
return rc;
75+
}
76+
77+
/* Sanity check */
78+
if ( len != ( ( int ) ( sizeof ( buf ) - 1 /* NUL */ ) ) )
79+
return -EINVAL;
80+
81+
/* Decode MAC address */
82+
len = base16_decode ( buf, hw_addr );
83+
if ( len < 0 ) {
84+
rc = len;
85+
return rc;
86+
}
87+
88+
return 0;
89+
}

src/drivers/net/ecm.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#ifndef _ECM_H
2+
#define _ECM_H
3+
4+
/** @file
5+
*
6+
* CDC-ECM USB Ethernet driver
7+
*
8+
*/
9+
10+
FILE_LICENCE ( GPL2_OR_LATER );
11+
12+
#include <ipxe/usb.h>
13+
#include <ipxe/cdc.h>
14+
15+
/** An Ethernet Functional Descriptor */
16+
struct ecm_ethernet_descriptor {
17+
/** Descriptor header */
18+
struct usb_descriptor_header header;
19+
/** Descriptor subtype */
20+
uint8_t subtype;
21+
/** MAC addres string */
22+
uint8_t mac;
23+
/** Ethernet statistics bitmap */
24+
uint32_t statistics;
25+
/** Maximum segment size */
26+
uint16_t mtu;
27+
/** Multicast filter configuration */
28+
uint16_t mcast;
29+
/** Number of wake-on-LAN filters */
30+
uint8_t wol;
31+
} __attribute__ (( packed ));
32+
33+
extern struct ecm_ethernet_descriptor *
34+
ecm_ethernet_descriptor ( struct usb_configuration_descriptor *config,
35+
struct usb_interface_descriptor *interface );
36+
extern int ecm_fetch_mac ( struct usb_device *usb,
37+
struct ecm_ethernet_descriptor *desc,
38+
uint8_t *hw_addr );
39+
40+
#endif /* _ECM_H */

0 commit comments

Comments
 (0)