xref: /plan9/sys/src/cmd/usb/ether/cdc.c (revision 906943f9f6b8411972abb5e3a03ed19f74be7ccc)
1*906943f9SDavid du Colombier /*
2*906943f9SDavid du Colombier  * Standard usb ethernet communications device.
3*906943f9SDavid du Colombier  */
4*906943f9SDavid du Colombier #include <u.h>
5*906943f9SDavid du Colombier #include <libc.h>
6*906943f9SDavid du Colombier #include <fcall.h>
7*906943f9SDavid du Colombier #include <thread.h>
8*906943f9SDavid du Colombier #include "usb.h"
9*906943f9SDavid du Colombier #include "usbfs.h"
10*906943f9SDavid du Colombier #include "ether.h"
11*906943f9SDavid du Colombier 
12*906943f9SDavid du Colombier static int
okclass(Iface * iface)13*906943f9SDavid du Colombier okclass(Iface *iface)
14*906943f9SDavid du Colombier {
15*906943f9SDavid du Colombier 	return Class(iface->csp) == Clcomms && Subclass(iface->csp) == Scether;
16*906943f9SDavid du Colombier }
17*906943f9SDavid du Colombier 
18*906943f9SDavid du Colombier static int
getmac(Ether * ether)19*906943f9SDavid du Colombier getmac(Ether *ether)
20*906943f9SDavid du Colombier {
21*906943f9SDavid du Colombier 	int i;
22*906943f9SDavid du Colombier 	Usbdev *ud;
23*906943f9SDavid du Colombier 	uchar *b;
24*906943f9SDavid du Colombier 	Desc *dd;
25*906943f9SDavid du Colombier 	char *mac;
26*906943f9SDavid du Colombier 
27*906943f9SDavid du Colombier 	ud = ether->dev->usb;
28*906943f9SDavid du Colombier 
29*906943f9SDavid du Colombier 	for(i = 0; i < nelem(ud->ddesc); i++)
30*906943f9SDavid du Colombier 		if((dd = ud->ddesc[i]) != nil && okclass(dd->iface)){
31*906943f9SDavid du Colombier 			b = (uchar*)&dd->data;
32*906943f9SDavid du Colombier 			if(b[1] == Dfunction && b[2] == Fnether){
33*906943f9SDavid du Colombier 				mac = loaddevstr(ether->dev, b[3]);
34*906943f9SDavid du Colombier 				if(mac != nil && strlen(mac) != 12){
35*906943f9SDavid du Colombier 					free(mac);
36*906943f9SDavid du Colombier 					mac = nil;
37*906943f9SDavid du Colombier 				}
38*906943f9SDavid du Colombier 				if(mac != nil){
39*906943f9SDavid du Colombier 					parseaddr(ether->addr, mac);
40*906943f9SDavid du Colombier 					free(mac);
41*906943f9SDavid du Colombier 					return 0;
42*906943f9SDavid du Colombier 				}
43*906943f9SDavid du Colombier 			}
44*906943f9SDavid du Colombier 		}
45*906943f9SDavid du Colombier 	return -1;
46*906943f9SDavid du Colombier }
47*906943f9SDavid du Colombier 
48*906943f9SDavid du Colombier int
cdcreset(Ether * ether)49*906943f9SDavid du Colombier cdcreset(Ether *ether)
50*906943f9SDavid du Colombier {
51*906943f9SDavid du Colombier 	/*
52*906943f9SDavid du Colombier 	 * Assume that all communication devices are going to
53*906943f9SDavid du Colombier 	 * be std. ethernet communication devices. Specific controllers
54*906943f9SDavid du Colombier 	 * must have been probed first.
55*906943f9SDavid du Colombier 	 * NB: This ignores unions.
56*906943f9SDavid du Colombier 	 */
57*906943f9SDavid du Colombier 	if(ether->dev->usb->class == Clcomms)
58*906943f9SDavid du Colombier 		return getmac(ether);
59*906943f9SDavid du Colombier 	return -1;
60*906943f9SDavid du Colombier }
61