|
|
1.1 root 1: /*
2: * QEMU USB Net devices
3: *
4: * Copyright (c) 2006 Thomas Sailer
5: * Copyright (c) 2008 Andrzej Zaborowski
6: *
7: * Permission is hereby granted, free of charge, to any person obtaining a copy
8: * of this software and associated documentation files (the "Software"), to deal
9: * in the Software without restriction, including without limitation the rights
10: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11: * copies of the Software, and to permit persons to whom the Software is
12: * furnished to do so, subject to the following conditions:
13: *
14: * The above copyright notice and this permission notice shall be included in
15: * all copies or substantial portions of the Software.
16: *
17: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23: * THE SOFTWARE.
24: */
25:
26: #include "qemu-common.h"
27: #include "usb.h"
1.1.1.8 root 28: #include "usb-desc.h"
1.1 root 29: #include "net.h"
1.1.1.4 root 30: #include "qemu-queue.h"
1.1.1.8 root 31: #include "sysemu.h"
1.1 root 32:
33: /*#define TRAFFIC_DEBUG*/
34: /* Thanks to NetChip Technologies for donating this product ID.
35: * It's for devices with only CDC Ethernet configurations.
36: */
37: #define CDC_VENDOR_NUM 0x0525 /* NetChip */
38: #define CDC_PRODUCT_NUM 0xa4a1 /* Linux-USB Ethernet Gadget */
39: /* For hardware that can talk RNDIS and either of the above protocols,
40: * use this ID ... the windows INF files will know it.
41: */
42: #define RNDIS_VENDOR_NUM 0x0525 /* NetChip */
43: #define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */
44:
45: enum usbstring_idx {
46: STRING_MANUFACTURER = 1,
47: STRING_PRODUCT,
48: STRING_ETHADDR,
49: STRING_DATA,
50: STRING_CONTROL,
51: STRING_RNDIS_CONTROL,
52: STRING_CDC,
53: STRING_SUBSET,
54: STRING_RNDIS,
55: STRING_SERIALNUMBER,
56: };
57:
58: #define DEV_CONFIG_VALUE 1 /* CDC or a subset */
59: #define DEV_RNDIS_CONFIG_VALUE 2 /* RNDIS; optional */
60:
61: #define USB_CDC_SUBCLASS_ACM 0x02
62: #define USB_CDC_SUBCLASS_ETHERNET 0x06
63:
64: #define USB_CDC_PROTO_NONE 0
65: #define USB_CDC_ACM_PROTO_VENDOR 0xff
66:
67: #define USB_CDC_HEADER_TYPE 0x00 /* header_desc */
68: #define USB_CDC_CALL_MANAGEMENT_TYPE 0x01 /* call_mgmt_descriptor */
69: #define USB_CDC_ACM_TYPE 0x02 /* acm_descriptor */
70: #define USB_CDC_UNION_TYPE 0x06 /* union_desc */
71: #define USB_CDC_ETHERNET_TYPE 0x0f /* ether_desc */
72:
73: #define USB_DT_CS_INTERFACE 0x24
74: #define USB_DT_CS_ENDPOINT 0x25
75:
76: #define USB_CDC_SEND_ENCAPSULATED_COMMAND 0x00
77: #define USB_CDC_GET_ENCAPSULATED_RESPONSE 0x01
78: #define USB_CDC_REQ_SET_LINE_CODING 0x20
79: #define USB_CDC_REQ_GET_LINE_CODING 0x21
80: #define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22
81: #define USB_CDC_REQ_SEND_BREAK 0x23
82: #define USB_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40
83: #define USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER 0x41
84: #define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER 0x42
85: #define USB_CDC_SET_ETHERNET_PACKET_FILTER 0x43
86: #define USB_CDC_GET_ETHERNET_STATISTIC 0x44
87:
88: #define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
89: #define STATUS_BYTECOUNT 16 /* 8 byte header + data */
90:
91: #define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
92:
1.1.1.8 root 93: static const USBDescStrings usb_net_stringtable = {
94: [STRING_MANUFACTURER] = "QEMU",
95: [STRING_PRODUCT] = "RNDIS/QEMU USB Network Device",
96: [STRING_ETHADDR] = "400102030405",
97: [STRING_DATA] = "QEMU USB Net Data Interface",
98: [STRING_CONTROL] = "QEMU USB Net Control Interface",
99: [STRING_RNDIS_CONTROL] = "QEMU USB Net RNDIS Control Interface",
100: [STRING_CDC] = "QEMU USB Net CDC",
101: [STRING_SUBSET] = "QEMU USB Net Subset",
102: [STRING_RNDIS] = "QEMU USB Net RNDIS",
103: [STRING_SERIALNUMBER] = "1",
104: };
105:
106: static const USBDescIface desc_iface_rndis[] = {
107: {
108: /* RNDIS Control Interface */
109: .bInterfaceNumber = 0,
110: .bNumEndpoints = 1,
111: .bInterfaceClass = USB_CLASS_COMM,
112: .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
113: .bInterfaceProtocol = USB_CDC_ACM_PROTO_VENDOR,
114: .iInterface = STRING_RNDIS_CONTROL,
115: .ndesc = 4,
116: .descs = (USBDescOther[]) {
117: {
118: /* Header Descriptor */
119: .data = (uint8_t[]) {
120: 0x05, /* u8 bLength */
121: USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
122: USB_CDC_HEADER_TYPE, /* u8 bDescriptorSubType */
123: 0x10, 0x01, /* le16 bcdCDC */
124: },
125: },{
126: /* Call Management Descriptor */
127: .data = (uint8_t[]) {
128: 0x05, /* u8 bLength */
129: USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
130: USB_CDC_CALL_MANAGEMENT_TYPE, /* u8 bDescriptorSubType */
131: 0x00, /* u8 bmCapabilities */
132: 0x01, /* u8 bDataInterface */
133: },
134: },{
135: /* ACM Descriptor */
136: .data = (uint8_t[]) {
137: 0x04, /* u8 bLength */
138: USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
139: USB_CDC_ACM_TYPE, /* u8 bDescriptorSubType */
140: 0x00, /* u8 bmCapabilities */
141: },
142: },{
143: /* Union Descriptor */
144: .data = (uint8_t[]) {
145: 0x05, /* u8 bLength */
146: USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
147: USB_CDC_UNION_TYPE, /* u8 bDescriptorSubType */
148: 0x00, /* u8 bMasterInterface0 */
149: 0x01, /* u8 bSlaveInterface0 */
150: },
151: },
152: },
153: .eps = (USBDescEndpoint[]) {
154: {
155: .bEndpointAddress = USB_DIR_IN | 0x01,
156: .bmAttributes = USB_ENDPOINT_XFER_INT,
157: .wMaxPacketSize = STATUS_BYTECOUNT,
158: .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
159: },
160: }
161: },{
162: /* RNDIS Data Interface */
163: .bInterfaceNumber = 1,
164: .bNumEndpoints = 2,
165: .bInterfaceClass = USB_CLASS_CDC_DATA,
166: .iInterface = STRING_DATA,
167: .eps = (USBDescEndpoint[]) {
168: {
169: .bEndpointAddress = USB_DIR_IN | 0x02,
170: .bmAttributes = USB_ENDPOINT_XFER_BULK,
171: .wMaxPacketSize = 0x40,
172: },{
173: .bEndpointAddress = USB_DIR_OUT | 0x02,
174: .bmAttributes = USB_ENDPOINT_XFER_BULK,
175: .wMaxPacketSize = 0x40,
176: }
177: }
178: }
179: };
180:
181: static const USBDescIface desc_iface_cdc[] = {
182: {
183: /* CDC Control Interface */
184: .bInterfaceNumber = 0,
185: .bNumEndpoints = 1,
186: .bInterfaceClass = USB_CLASS_COMM,
187: .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
188: .bInterfaceProtocol = USB_CDC_PROTO_NONE,
189: .iInterface = STRING_CONTROL,
190: .ndesc = 3,
191: .descs = (USBDescOther[]) {
192: {
193: /* Header Descriptor */
194: .data = (uint8_t[]) {
195: 0x05, /* u8 bLength */
196: USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
197: USB_CDC_HEADER_TYPE, /* u8 bDescriptorSubType */
198: 0x10, 0x01, /* le16 bcdCDC */
199: },
200: },{
201: /* Union Descriptor */
202: .data = (uint8_t[]) {
203: 0x05, /* u8 bLength */
204: USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
205: USB_CDC_UNION_TYPE, /* u8 bDescriptorSubType */
206: 0x00, /* u8 bMasterInterface0 */
207: 0x01, /* u8 bSlaveInterface0 */
208: },
209: },{
210: /* Ethernet Descriptor */
211: .data = (uint8_t[]) {
212: 0x0d, /* u8 bLength */
213: USB_DT_CS_INTERFACE, /* u8 bDescriptorType */
214: USB_CDC_ETHERNET_TYPE, /* u8 bDescriptorSubType */
215: STRING_ETHADDR, /* u8 iMACAddress */
216: 0x00, 0x00, 0x00, 0x00, /* le32 bmEthernetStatistics */
217: ETH_FRAME_LEN & 0xff,
218: ETH_FRAME_LEN >> 8, /* le16 wMaxSegmentSize */
219: 0x00, 0x00, /* le16 wNumberMCFilters */
220: 0x00, /* u8 bNumberPowerFilters */
221: },
222: },
223: },
224: .eps = (USBDescEndpoint[]) {
225: {
226: .bEndpointAddress = USB_DIR_IN | 0x01,
227: .bmAttributes = USB_ENDPOINT_XFER_INT,
228: .wMaxPacketSize = STATUS_BYTECOUNT,
229: .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
230: },
231: }
232: },{
233: /* CDC Data Interface (off) */
234: .bInterfaceNumber = 1,
235: .bAlternateSetting = 0,
236: .bNumEndpoints = 0,
237: .bInterfaceClass = USB_CLASS_CDC_DATA,
238: },{
239: /* CDC Data Interface */
240: .bInterfaceNumber = 1,
241: .bAlternateSetting = 1,
242: .bNumEndpoints = 2,
243: .bInterfaceClass = USB_CLASS_CDC_DATA,
244: .iInterface = STRING_DATA,
245: .eps = (USBDescEndpoint[]) {
246: {
247: .bEndpointAddress = USB_DIR_IN | 0x02,
248: .bmAttributes = USB_ENDPOINT_XFER_BULK,
249: .wMaxPacketSize = 0x40,
250: },{
251: .bEndpointAddress = USB_DIR_OUT | 0x02,
252: .bmAttributes = USB_ENDPOINT_XFER_BULK,
253: .wMaxPacketSize = 0x40,
254: }
255: }
256: }
1.1 root 257: };
258:
1.1.1.8 root 259: static const USBDescDevice desc_device_net = {
260: .bcdUSB = 0x0200,
261: .bDeviceClass = USB_CLASS_COMM,
262: .bMaxPacketSize0 = 0x40,
263: .bNumConfigurations = 2,
264: .confs = (USBDescConfig[]) {
265: {
266: .bNumInterfaces = 2,
267: .bConfigurationValue = DEV_RNDIS_CONFIG_VALUE,
268: .iConfiguration = STRING_RNDIS,
269: .bmAttributes = 0xc0,
270: .bMaxPower = 0x32,
271: .nif = ARRAY_SIZE(desc_iface_rndis),
272: .ifs = desc_iface_rndis,
273: },{
274: .bNumInterfaces = 2,
275: .bConfigurationValue = DEV_CONFIG_VALUE,
276: .iConfiguration = STRING_CDC,
277: .bmAttributes = 0xc0,
278: .bMaxPower = 0x32,
279: .nif = ARRAY_SIZE(desc_iface_cdc),
280: .ifs = desc_iface_cdc,
281: }
282: },
1.1 root 283: };
284:
1.1.1.8 root 285: static const USBDesc desc_net = {
286: .id = {
287: .idVendor = RNDIS_VENDOR_NUM,
288: .idProduct = RNDIS_PRODUCT_NUM,
289: .bcdDevice = 0,
290: .iManufacturer = STRING_MANUFACTURER,
291: .iProduct = STRING_PRODUCT,
292: .iSerialNumber = STRING_SERIALNUMBER,
293: },
294: .full = &desc_device_net,
295: .str = usb_net_stringtable,
1.1 root 296: };
297:
298: /*
299: * RNDIS Definitions - in theory not specific to USB.
300: */
301: #define RNDIS_MAXIMUM_FRAME_SIZE 1518
302: #define RNDIS_MAX_TOTAL_SIZE 1558
303:
304: /* Remote NDIS Versions */
305: #define RNDIS_MAJOR_VERSION 1
306: #define RNDIS_MINOR_VERSION 0
307:
308: /* Status Values */
309: #define RNDIS_STATUS_SUCCESS 0x00000000U /* Success */
310: #define RNDIS_STATUS_FAILURE 0xc0000001U /* Unspecified error */
311: #define RNDIS_STATUS_INVALID_DATA 0xc0010015U /* Invalid data */
312: #define RNDIS_STATUS_NOT_SUPPORTED 0xc00000bbU /* Unsupported request */
313: #define RNDIS_STATUS_MEDIA_CONNECT 0x4001000bU /* Device connected */
314: #define RNDIS_STATUS_MEDIA_DISCONNECT 0x4001000cU /* Device disconnected */
315:
316: /* Message Set for Connectionless (802.3) Devices */
317: enum {
318: RNDIS_PACKET_MSG = 1,
319: RNDIS_INITIALIZE_MSG = 2, /* Initialize device */
320: RNDIS_HALT_MSG = 3,
321: RNDIS_QUERY_MSG = 4,
322: RNDIS_SET_MSG = 5,
323: RNDIS_RESET_MSG = 6,
324: RNDIS_INDICATE_STATUS_MSG = 7,
325: RNDIS_KEEPALIVE_MSG = 8,
326: };
327:
328: /* Message completion */
329: enum {
330: RNDIS_INITIALIZE_CMPLT = 0x80000002U,
331: RNDIS_QUERY_CMPLT = 0x80000004U,
332: RNDIS_SET_CMPLT = 0x80000005U,
333: RNDIS_RESET_CMPLT = 0x80000006U,
334: RNDIS_KEEPALIVE_CMPLT = 0x80000008U,
335: };
336:
337: /* Device Flags */
338: enum {
339: RNDIS_DF_CONNECTIONLESS = 1,
340: RNDIS_DF_CONNECTIONORIENTED = 2,
341: };
342:
343: #define RNDIS_MEDIUM_802_3 0x00000000U
344:
345: /* from drivers/net/sk98lin/h/skgepnmi.h */
346: #define OID_PNP_CAPABILITIES 0xfd010100
347: #define OID_PNP_SET_POWER 0xfd010101
348: #define OID_PNP_QUERY_POWER 0xfd010102
349: #define OID_PNP_ADD_WAKE_UP_PATTERN 0xfd010103
350: #define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xfd010104
351: #define OID_PNP_ENABLE_WAKE_UP 0xfd010106
352:
353: typedef uint32_t le32;
354:
355: typedef struct rndis_init_msg_type {
356: le32 MessageType;
357: le32 MessageLength;
358: le32 RequestID;
359: le32 MajorVersion;
360: le32 MinorVersion;
361: le32 MaxTransferSize;
362: } rndis_init_msg_type;
363:
364: typedef struct rndis_init_cmplt_type {
365: le32 MessageType;
366: le32 MessageLength;
367: le32 RequestID;
368: le32 Status;
369: le32 MajorVersion;
370: le32 MinorVersion;
371: le32 DeviceFlags;
372: le32 Medium;
373: le32 MaxPacketsPerTransfer;
374: le32 MaxTransferSize;
375: le32 PacketAlignmentFactor;
376: le32 AFListOffset;
377: le32 AFListSize;
378: } rndis_init_cmplt_type;
379:
380: typedef struct rndis_halt_msg_type {
381: le32 MessageType;
382: le32 MessageLength;
383: le32 RequestID;
384: } rndis_halt_msg_type;
385:
386: typedef struct rndis_query_msg_type {
387: le32 MessageType;
388: le32 MessageLength;
389: le32 RequestID;
390: le32 OID;
391: le32 InformationBufferLength;
392: le32 InformationBufferOffset;
393: le32 DeviceVcHandle;
394: } rndis_query_msg_type;
395:
396: typedef struct rndis_query_cmplt_type {
397: le32 MessageType;
398: le32 MessageLength;
399: le32 RequestID;
400: le32 Status;
401: le32 InformationBufferLength;
402: le32 InformationBufferOffset;
403: } rndis_query_cmplt_type;
404:
405: typedef struct rndis_set_msg_type {
406: le32 MessageType;
407: le32 MessageLength;
408: le32 RequestID;
409: le32 OID;
410: le32 InformationBufferLength;
411: le32 InformationBufferOffset;
412: le32 DeviceVcHandle;
413: } rndis_set_msg_type;
414:
415: typedef struct rndis_set_cmplt_type {
416: le32 MessageType;
417: le32 MessageLength;
418: le32 RequestID;
419: le32 Status;
420: } rndis_set_cmplt_type;
421:
422: typedef struct rndis_reset_msg_type {
423: le32 MessageType;
424: le32 MessageLength;
425: le32 Reserved;
426: } rndis_reset_msg_type;
427:
428: typedef struct rndis_reset_cmplt_type {
429: le32 MessageType;
430: le32 MessageLength;
431: le32 Status;
432: le32 AddressingReset;
433: } rndis_reset_cmplt_type;
434:
435: typedef struct rndis_indicate_status_msg_type {
436: le32 MessageType;
437: le32 MessageLength;
438: le32 Status;
439: le32 StatusBufferLength;
440: le32 StatusBufferOffset;
441: } rndis_indicate_status_msg_type;
442:
443: typedef struct rndis_keepalive_msg_type {
444: le32 MessageType;
445: le32 MessageLength;
446: le32 RequestID;
447: } rndis_keepalive_msg_type;
448:
449: typedef struct rndis_keepalive_cmplt_type {
450: le32 MessageType;
451: le32 MessageLength;
452: le32 RequestID;
453: le32 Status;
454: } rndis_keepalive_cmplt_type;
455:
456: struct rndis_packet_msg_type {
457: le32 MessageType;
458: le32 MessageLength;
459: le32 DataOffset;
460: le32 DataLength;
461: le32 OOBDataOffset;
462: le32 OOBDataLength;
463: le32 NumOOBDataElements;
464: le32 PerPacketInfoOffset;
465: le32 PerPacketInfoLength;
466: le32 VcHandle;
467: le32 Reserved;
468: };
469:
470: struct rndis_config_parameter {
471: le32 ParameterNameOffset;
472: le32 ParameterNameLength;
473: le32 ParameterType;
474: le32 ParameterValueOffset;
475: le32 ParameterValueLength;
476: };
477:
478: /* implementation specific */
479: enum rndis_state
480: {
481: RNDIS_UNINITIALIZED,
482: RNDIS_INITIALIZED,
483: RNDIS_DATA_INITIALIZED,
484: };
485:
486: /* from ndis.h */
487: enum ndis_oid {
488: /* Required Object IDs (OIDs) */
489: OID_GEN_SUPPORTED_LIST = 0x00010101,
490: OID_GEN_HARDWARE_STATUS = 0x00010102,
491: OID_GEN_MEDIA_SUPPORTED = 0x00010103,
492: OID_GEN_MEDIA_IN_USE = 0x00010104,
493: OID_GEN_MAXIMUM_LOOKAHEAD = 0x00010105,
494: OID_GEN_MAXIMUM_FRAME_SIZE = 0x00010106,
495: OID_GEN_LINK_SPEED = 0x00010107,
496: OID_GEN_TRANSMIT_BUFFER_SPACE = 0x00010108,
497: OID_GEN_RECEIVE_BUFFER_SPACE = 0x00010109,
498: OID_GEN_TRANSMIT_BLOCK_SIZE = 0x0001010a,
499: OID_GEN_RECEIVE_BLOCK_SIZE = 0x0001010b,
500: OID_GEN_VENDOR_ID = 0x0001010c,
501: OID_GEN_VENDOR_DESCRIPTION = 0x0001010d,
502: OID_GEN_CURRENT_PACKET_FILTER = 0x0001010e,
503: OID_GEN_CURRENT_LOOKAHEAD = 0x0001010f,
504: OID_GEN_DRIVER_VERSION = 0x00010110,
505: OID_GEN_MAXIMUM_TOTAL_SIZE = 0x00010111,
506: OID_GEN_PROTOCOL_OPTIONS = 0x00010112,
507: OID_GEN_MAC_OPTIONS = 0x00010113,
508: OID_GEN_MEDIA_CONNECT_STATUS = 0x00010114,
509: OID_GEN_MAXIMUM_SEND_PACKETS = 0x00010115,
510: OID_GEN_VENDOR_DRIVER_VERSION = 0x00010116,
511: OID_GEN_SUPPORTED_GUIDS = 0x00010117,
512: OID_GEN_NETWORK_LAYER_ADDRESSES = 0x00010118,
513: OID_GEN_TRANSPORT_HEADER_OFFSET = 0x00010119,
514: OID_GEN_MACHINE_NAME = 0x0001021a,
515: OID_GEN_RNDIS_CONFIG_PARAMETER = 0x0001021b,
516: OID_GEN_VLAN_ID = 0x0001021c,
517:
518: /* Optional OIDs */
519: OID_GEN_MEDIA_CAPABILITIES = 0x00010201,
520: OID_GEN_PHYSICAL_MEDIUM = 0x00010202,
521:
522: /* Required statistics OIDs */
523: OID_GEN_XMIT_OK = 0x00020101,
524: OID_GEN_RCV_OK = 0x00020102,
525: OID_GEN_XMIT_ERROR = 0x00020103,
526: OID_GEN_RCV_ERROR = 0x00020104,
527: OID_GEN_RCV_NO_BUFFER = 0x00020105,
528:
529: /* Optional statistics OIDs */
530: OID_GEN_DIRECTED_BYTES_XMIT = 0x00020201,
531: OID_GEN_DIRECTED_FRAMES_XMIT = 0x00020202,
532: OID_GEN_MULTICAST_BYTES_XMIT = 0x00020203,
533: OID_GEN_MULTICAST_FRAMES_XMIT = 0x00020204,
534: OID_GEN_BROADCAST_BYTES_XMIT = 0x00020205,
535: OID_GEN_BROADCAST_FRAMES_XMIT = 0x00020206,
536: OID_GEN_DIRECTED_BYTES_RCV = 0x00020207,
537: OID_GEN_DIRECTED_FRAMES_RCV = 0x00020208,
538: OID_GEN_MULTICAST_BYTES_RCV = 0x00020209,
539: OID_GEN_MULTICAST_FRAMES_RCV = 0x0002020a,
540: OID_GEN_BROADCAST_BYTES_RCV = 0x0002020b,
541: OID_GEN_BROADCAST_FRAMES_RCV = 0x0002020c,
542: OID_GEN_RCV_CRC_ERROR = 0x0002020d,
543: OID_GEN_TRANSMIT_QUEUE_LENGTH = 0x0002020e,
544: OID_GEN_GET_TIME_CAPS = 0x0002020f,
545: OID_GEN_GET_NETCARD_TIME = 0x00020210,
546: OID_GEN_NETCARD_LOAD = 0x00020211,
547: OID_GEN_DEVICE_PROFILE = 0x00020212,
548: OID_GEN_INIT_TIME_MS = 0x00020213,
549: OID_GEN_RESET_COUNTS = 0x00020214,
550: OID_GEN_MEDIA_SENSE_COUNTS = 0x00020215,
551: OID_GEN_FRIENDLY_NAME = 0x00020216,
552: OID_GEN_MINIPORT_INFO = 0x00020217,
553: OID_GEN_RESET_VERIFY_PARAMETERS = 0x00020218,
554:
555: /* IEEE 802.3 (Ethernet) OIDs */
556: OID_802_3_PERMANENT_ADDRESS = 0x01010101,
557: OID_802_3_CURRENT_ADDRESS = 0x01010102,
558: OID_802_3_MULTICAST_LIST = 0x01010103,
559: OID_802_3_MAXIMUM_LIST_SIZE = 0x01010104,
560: OID_802_3_MAC_OPTIONS = 0x01010105,
561: OID_802_3_RCV_ERROR_ALIGNMENT = 0x01020101,
562: OID_802_3_XMIT_ONE_COLLISION = 0x01020102,
563: OID_802_3_XMIT_MORE_COLLISIONS = 0x01020103,
564: OID_802_3_XMIT_DEFERRED = 0x01020201,
565: OID_802_3_XMIT_MAX_COLLISIONS = 0x01020202,
566: OID_802_3_RCV_OVERRUN = 0x01020203,
567: OID_802_3_XMIT_UNDERRUN = 0x01020204,
568: OID_802_3_XMIT_HEARTBEAT_FAILURE = 0x01020205,
569: OID_802_3_XMIT_TIMES_CRS_LOST = 0x01020206,
570: OID_802_3_XMIT_LATE_COLLISIONS = 0x01020207,
571: };
572:
573: static const uint32_t oid_supported_list[] =
574: {
575: /* the general stuff */
576: OID_GEN_SUPPORTED_LIST,
577: OID_GEN_HARDWARE_STATUS,
578: OID_GEN_MEDIA_SUPPORTED,
579: OID_GEN_MEDIA_IN_USE,
580: OID_GEN_MAXIMUM_FRAME_SIZE,
581: OID_GEN_LINK_SPEED,
582: OID_GEN_TRANSMIT_BLOCK_SIZE,
583: OID_GEN_RECEIVE_BLOCK_SIZE,
584: OID_GEN_VENDOR_ID,
585: OID_GEN_VENDOR_DESCRIPTION,
586: OID_GEN_VENDOR_DRIVER_VERSION,
587: OID_GEN_CURRENT_PACKET_FILTER,
588: OID_GEN_MAXIMUM_TOTAL_SIZE,
589: OID_GEN_MEDIA_CONNECT_STATUS,
590: OID_GEN_PHYSICAL_MEDIUM,
591:
592: /* the statistical stuff */
593: OID_GEN_XMIT_OK,
594: OID_GEN_RCV_OK,
595: OID_GEN_XMIT_ERROR,
596: OID_GEN_RCV_ERROR,
597: OID_GEN_RCV_NO_BUFFER,
598:
599: /* IEEE 802.3 */
600: /* the general stuff */
601: OID_802_3_PERMANENT_ADDRESS,
602: OID_802_3_CURRENT_ADDRESS,
603: OID_802_3_MULTICAST_LIST,
604: OID_802_3_MAC_OPTIONS,
605: OID_802_3_MAXIMUM_LIST_SIZE,
606:
607: /* the statistical stuff */
608: OID_802_3_RCV_ERROR_ALIGNMENT,
609: OID_802_3_XMIT_ONE_COLLISION,
610: OID_802_3_XMIT_MORE_COLLISIONS,
611: };
612:
613: #define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA (1 << 0)
614: #define NDIS_MAC_OPTION_RECEIVE_SERIALIZED (1 << 1)
615: #define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND (1 << 2)
616: #define NDIS_MAC_OPTION_NO_LOOPBACK (1 << 3)
617: #define NDIS_MAC_OPTION_FULL_DUPLEX (1 << 4)
618: #define NDIS_MAC_OPTION_EOTX_INDICATION (1 << 5)
619: #define NDIS_MAC_OPTION_8021P_PRIORITY (1 << 6)
620:
621: struct rndis_response {
1.1.1.4 root 622: QTAILQ_ENTRY(rndis_response) entries;
1.1 root 623: uint32_t length;
624: uint8_t buf[0];
625: };
626:
627: typedef struct USBNetState {
628: USBDevice dev;
629:
630: enum rndis_state rndis_state;
631: uint32_t medium;
632: uint32_t speed;
633: uint32_t media_state;
634: uint16_t filter;
635: uint32_t vendorid;
636:
637: unsigned int out_ptr;
638: uint8_t out_buf[2048];
639:
640: USBPacket *inpkt;
641: unsigned int in_ptr, in_len;
642: uint8_t in_buf[2048];
643:
644: char usbstring_mac[13];
1.1.1.4 root 645: NICState *nic;
646: NICConf conf;
647: QTAILQ_HEAD(rndis_resp_head, rndis_response) rndis_resp;
1.1 root 648: } USBNetState;
649:
1.1.1.8 root 650: static int is_rndis(USBNetState *s)
651: {
652: return s->dev.config->bConfigurationValue == DEV_RNDIS_CONFIG_VALUE;
653: }
654:
1.1 root 655: static int ndis_query(USBNetState *s, uint32_t oid,
656: uint8_t *inbuf, unsigned int inlen, uint8_t *outbuf,
657: size_t outlen)
658: {
659: unsigned int i;
660:
661: switch (oid) {
662: /* general oids (table 4-1) */
663: /* mandatory */
664: case OID_GEN_SUPPORTED_LIST:
665: for (i = 0; i < ARRAY_SIZE(oid_supported_list); i++)
666: ((le32 *) outbuf)[i] = cpu_to_le32(oid_supported_list[i]);
667: return sizeof(oid_supported_list);
668:
669: /* mandatory */
670: case OID_GEN_HARDWARE_STATUS:
671: *((le32 *) outbuf) = cpu_to_le32(0);
672: return sizeof(le32);
673:
674: /* mandatory */
675: case OID_GEN_MEDIA_SUPPORTED:
676: *((le32 *) outbuf) = cpu_to_le32(s->medium);
677: return sizeof(le32);
678:
679: /* mandatory */
680: case OID_GEN_MEDIA_IN_USE:
681: *((le32 *) outbuf) = cpu_to_le32(s->medium);
682: return sizeof(le32);
683:
684: /* mandatory */
685: case OID_GEN_MAXIMUM_FRAME_SIZE:
686: *((le32 *) outbuf) = cpu_to_le32(ETH_FRAME_LEN);
687: return sizeof(le32);
688:
689: /* mandatory */
690: case OID_GEN_LINK_SPEED:
691: *((le32 *) outbuf) = cpu_to_le32(s->speed);
692: return sizeof(le32);
693:
694: /* mandatory */
695: case OID_GEN_TRANSMIT_BLOCK_SIZE:
696: *((le32 *) outbuf) = cpu_to_le32(ETH_FRAME_LEN);
697: return sizeof(le32);
698:
699: /* mandatory */
700: case OID_GEN_RECEIVE_BLOCK_SIZE:
701: *((le32 *) outbuf) = cpu_to_le32(ETH_FRAME_LEN);
702: return sizeof(le32);
703:
704: /* mandatory */
705: case OID_GEN_VENDOR_ID:
706: *((le32 *) outbuf) = cpu_to_le32(s->vendorid);
707: return sizeof(le32);
708:
709: /* mandatory */
710: case OID_GEN_VENDOR_DESCRIPTION:
711: pstrcpy((char *)outbuf, outlen, "QEMU USB RNDIS Net");
712: return strlen((char *)outbuf) + 1;
713:
714: case OID_GEN_VENDOR_DRIVER_VERSION:
715: *((le32 *) outbuf) = cpu_to_le32(1);
716: return sizeof(le32);
717:
718: /* mandatory */
719: case OID_GEN_CURRENT_PACKET_FILTER:
720: *((le32 *) outbuf) = cpu_to_le32(s->filter);
721: return sizeof(le32);
722:
723: /* mandatory */
724: case OID_GEN_MAXIMUM_TOTAL_SIZE:
725: *((le32 *) outbuf) = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
726: return sizeof(le32);
727:
728: /* mandatory */
729: case OID_GEN_MEDIA_CONNECT_STATUS:
730: *((le32 *) outbuf) = cpu_to_le32(s->media_state);
731: return sizeof(le32);
732:
733: case OID_GEN_PHYSICAL_MEDIUM:
734: *((le32 *) outbuf) = cpu_to_le32(0);
735: return sizeof(le32);
736:
737: case OID_GEN_MAC_OPTIONS:
738: *((le32 *) outbuf) = cpu_to_le32(
739: NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
740: NDIS_MAC_OPTION_FULL_DUPLEX);
741: return sizeof(le32);
742:
743: /* statistics OIDs (table 4-2) */
744: /* mandatory */
745: case OID_GEN_XMIT_OK:
746: *((le32 *) outbuf) = cpu_to_le32(0);
747: return sizeof(le32);
748:
749: /* mandatory */
750: case OID_GEN_RCV_OK:
751: *((le32 *) outbuf) = cpu_to_le32(0);
752: return sizeof(le32);
753:
754: /* mandatory */
755: case OID_GEN_XMIT_ERROR:
756: *((le32 *) outbuf) = cpu_to_le32(0);
757: return sizeof(le32);
758:
759: /* mandatory */
760: case OID_GEN_RCV_ERROR:
761: *((le32 *) outbuf) = cpu_to_le32(0);
762: return sizeof(le32);
763:
764: /* mandatory */
765: case OID_GEN_RCV_NO_BUFFER:
766: *((le32 *) outbuf) = cpu_to_le32(0);
767: return sizeof(le32);
768:
769: /* ieee802.3 OIDs (table 4-3) */
770: /* mandatory */
771: case OID_802_3_PERMANENT_ADDRESS:
1.1.1.4 root 772: memcpy(outbuf, s->conf.macaddr.a, 6);
1.1 root 773: return 6;
774:
775: /* mandatory */
776: case OID_802_3_CURRENT_ADDRESS:
1.1.1.4 root 777: memcpy(outbuf, s->conf.macaddr.a, 6);
1.1 root 778: return 6;
779:
780: /* mandatory */
781: case OID_802_3_MULTICAST_LIST:
782: *((le32 *) outbuf) = cpu_to_le32(0xe0000000);
783: return sizeof(le32);
784:
785: /* mandatory */
786: case OID_802_3_MAXIMUM_LIST_SIZE:
787: *((le32 *) outbuf) = cpu_to_le32(1);
788: return sizeof(le32);
789:
790: case OID_802_3_MAC_OPTIONS:
791: return 0;
792:
793: /* ieee802.3 statistics OIDs (table 4-4) */
794: /* mandatory */
795: case OID_802_3_RCV_ERROR_ALIGNMENT:
796: *((le32 *) outbuf) = cpu_to_le32(0);
797: return sizeof(le32);
798:
799: /* mandatory */
800: case OID_802_3_XMIT_ONE_COLLISION:
801: *((le32 *) outbuf) = cpu_to_le32(0);
802: return sizeof(le32);
803:
804: /* mandatory */
805: case OID_802_3_XMIT_MORE_COLLISIONS:
806: *((le32 *) outbuf) = cpu_to_le32(0);
807: return sizeof(le32);
808:
809: default:
810: fprintf(stderr, "usbnet: unknown OID 0x%08x\n", oid);
811: return 0;
812: }
813: return -1;
814: }
815:
816: static int ndis_set(USBNetState *s, uint32_t oid,
817: uint8_t *inbuf, unsigned int inlen)
818: {
819: switch (oid) {
820: case OID_GEN_CURRENT_PACKET_FILTER:
821: s->filter = le32_to_cpup((le32 *) inbuf);
822: if (s->filter) {
823: s->rndis_state = RNDIS_DATA_INITIALIZED;
824: } else {
825: s->rndis_state = RNDIS_INITIALIZED;
826: }
827: return 0;
828:
829: case OID_802_3_MULTICAST_LIST:
830: return 0;
831: }
832: return -1;
833: }
834:
835: static int rndis_get_response(USBNetState *s, uint8_t *buf)
836: {
837: int ret = 0;
838: struct rndis_response *r = s->rndis_resp.tqh_first;
839:
840: if (!r)
841: return ret;
842:
1.1.1.4 root 843: QTAILQ_REMOVE(&s->rndis_resp, r, entries);
1.1 root 844: ret = r->length;
845: memcpy(buf, r->buf, r->length);
846: qemu_free(r);
847:
848: return ret;
849: }
850:
851: static void *rndis_queue_response(USBNetState *s, unsigned int length)
852: {
853: struct rndis_response *r =
854: qemu_mallocz(sizeof(struct rndis_response) + length);
855:
1.1.1.4 root 856: QTAILQ_INSERT_TAIL(&s->rndis_resp, r, entries);
1.1 root 857: r->length = length;
858:
859: return &r->buf[0];
860: }
861:
862: static void rndis_clear_responsequeue(USBNetState *s)
863: {
864: struct rndis_response *r;
865:
866: while ((r = s->rndis_resp.tqh_first)) {
1.1.1.4 root 867: QTAILQ_REMOVE(&s->rndis_resp, r, entries);
1.1 root 868: qemu_free(r);
869: }
870: }
871:
872: static int rndis_init_response(USBNetState *s, rndis_init_msg_type *buf)
873: {
874: rndis_init_cmplt_type *resp =
875: rndis_queue_response(s, sizeof(rndis_init_cmplt_type));
876:
877: if (!resp)
878: return USB_RET_STALL;
879:
880: resp->MessageType = cpu_to_le32(RNDIS_INITIALIZE_CMPLT);
881: resp->MessageLength = cpu_to_le32(sizeof(rndis_init_cmplt_type));
882: resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
883: resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
884: resp->MajorVersion = cpu_to_le32(RNDIS_MAJOR_VERSION);
885: resp->MinorVersion = cpu_to_le32(RNDIS_MINOR_VERSION);
886: resp->DeviceFlags = cpu_to_le32(RNDIS_DF_CONNECTIONLESS);
887: resp->Medium = cpu_to_le32(RNDIS_MEDIUM_802_3);
888: resp->MaxPacketsPerTransfer = cpu_to_le32(1);
889: resp->MaxTransferSize = cpu_to_le32(ETH_FRAME_LEN +
890: sizeof(struct rndis_packet_msg_type) + 22);
891: resp->PacketAlignmentFactor = cpu_to_le32(0);
892: resp->AFListOffset = cpu_to_le32(0);
893: resp->AFListSize = cpu_to_le32(0);
894: return 0;
895: }
896:
897: static int rndis_query_response(USBNetState *s,
898: rndis_query_msg_type *buf, unsigned int length)
899: {
900: rndis_query_cmplt_type *resp;
901: /* oid_supported_list is the largest data reply */
902: uint8_t infobuf[sizeof(oid_supported_list)];
903: uint32_t bufoffs, buflen;
904: int infobuflen;
905: unsigned int resplen;
906:
907: bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
908: buflen = le32_to_cpu(buf->InformationBufferLength);
909: if (bufoffs + buflen > length)
910: return USB_RET_STALL;
911:
912: infobuflen = ndis_query(s, le32_to_cpu(buf->OID),
913: bufoffs + (uint8_t *) buf, buflen, infobuf,
914: sizeof(infobuf));
915: resplen = sizeof(rndis_query_cmplt_type) +
916: ((infobuflen < 0) ? 0 : infobuflen);
917: resp = rndis_queue_response(s, resplen);
918: if (!resp)
919: return USB_RET_STALL;
920:
921: resp->MessageType = cpu_to_le32(RNDIS_QUERY_CMPLT);
922: resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
923: resp->MessageLength = cpu_to_le32(resplen);
924:
925: if (infobuflen < 0) {
926: /* OID not supported */
927: resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED);
928: resp->InformationBufferLength = cpu_to_le32(0);
929: resp->InformationBufferOffset = cpu_to_le32(0);
930: return 0;
931: }
932:
933: resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
934: resp->InformationBufferOffset =
935: cpu_to_le32(infobuflen ? sizeof(rndis_query_cmplt_type) - 8 : 0);
936: resp->InformationBufferLength = cpu_to_le32(infobuflen);
937: memcpy(resp + 1, infobuf, infobuflen);
938:
939: return 0;
940: }
941:
942: static int rndis_set_response(USBNetState *s,
943: rndis_set_msg_type *buf, unsigned int length)
944: {
945: rndis_set_cmplt_type *resp =
946: rndis_queue_response(s, sizeof(rndis_set_cmplt_type));
947: uint32_t bufoffs, buflen;
948: int ret;
949:
950: if (!resp)
951: return USB_RET_STALL;
952:
953: bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8;
954: buflen = le32_to_cpu(buf->InformationBufferLength);
955: if (bufoffs + buflen > length)
956: return USB_RET_STALL;
957:
958: ret = ndis_set(s, le32_to_cpu(buf->OID),
959: bufoffs + (uint8_t *) buf, buflen);
960: resp->MessageType = cpu_to_le32(RNDIS_SET_CMPLT);
961: resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
962: resp->MessageLength = cpu_to_le32(sizeof(rndis_set_cmplt_type));
963: if (ret < 0) {
964: /* OID not supported */
965: resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED);
966: return 0;
967: }
968: resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
969:
970: return 0;
971: }
972:
973: static int rndis_reset_response(USBNetState *s, rndis_reset_msg_type *buf)
974: {
975: rndis_reset_cmplt_type *resp =
976: rndis_queue_response(s, sizeof(rndis_reset_cmplt_type));
977:
978: if (!resp)
979: return USB_RET_STALL;
980:
981: resp->MessageType = cpu_to_le32(RNDIS_RESET_CMPLT);
982: resp->MessageLength = cpu_to_le32(sizeof(rndis_reset_cmplt_type));
983: resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
984: resp->AddressingReset = cpu_to_le32(1); /* reset information */
985:
986: return 0;
987: }
988:
989: static int rndis_keepalive_response(USBNetState *s,
990: rndis_keepalive_msg_type *buf)
991: {
992: rndis_keepalive_cmplt_type *resp =
993: rndis_queue_response(s, sizeof(rndis_keepalive_cmplt_type));
994:
995: if (!resp)
996: return USB_RET_STALL;
997:
998: resp->MessageType = cpu_to_le32(RNDIS_KEEPALIVE_CMPLT);
999: resp->MessageLength = cpu_to_le32(sizeof(rndis_keepalive_cmplt_type));
1000: resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
1001: resp->Status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
1002:
1003: return 0;
1004: }
1005:
1006: static int rndis_parse(USBNetState *s, uint8_t *data, int length)
1007: {
1.1.1.7 root 1008: uint32_t msg_type;
1.1 root 1009: le32 *tmp = (le32 *) data;
1010:
1.1.1.7 root 1011: msg_type = le32_to_cpup(tmp);
1.1 root 1012:
1013: switch (msg_type) {
1014: case RNDIS_INITIALIZE_MSG:
1015: s->rndis_state = RNDIS_INITIALIZED;
1016: return rndis_init_response(s, (rndis_init_msg_type *) data);
1017:
1018: case RNDIS_HALT_MSG:
1019: s->rndis_state = RNDIS_UNINITIALIZED;
1020: return 0;
1021:
1022: case RNDIS_QUERY_MSG:
1023: return rndis_query_response(s, (rndis_query_msg_type *) data, length);
1024:
1025: case RNDIS_SET_MSG:
1026: return rndis_set_response(s, (rndis_set_msg_type *) data, length);
1027:
1028: case RNDIS_RESET_MSG:
1029: rndis_clear_responsequeue(s);
1030: s->out_ptr = s->in_ptr = s->in_len = 0;
1031: return rndis_reset_response(s, (rndis_reset_msg_type *) data);
1032:
1033: case RNDIS_KEEPALIVE_MSG:
1034: /* For USB: host does this every 5 seconds */
1035: return rndis_keepalive_response(s, (rndis_keepalive_msg_type *) data);
1036: }
1037:
1038: return USB_RET_STALL;
1039: }
1040:
1041: static void usb_net_handle_reset(USBDevice *dev)
1042: {
1043: }
1044:
1.1.1.9 ! root 1045: static int usb_net_handle_control(USBDevice *dev, USBPacket *p,
! 1046: int request, int value, int index, int length, uint8_t *data)
1.1 root 1047: {
1048: USBNetState *s = (USBNetState *) dev;
1.1.1.8 root 1049: int ret;
1.1 root 1050:
1.1.1.9 ! root 1051: ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
1.1.1.8 root 1052: if (ret >= 0) {
1053: return ret;
1054: }
1.1 root 1055:
1.1.1.8 root 1056: ret = 0;
1057: switch(request) {
1.1 root 1058: case ClassInterfaceOutRequest | USB_CDC_SEND_ENCAPSULATED_COMMAND:
1.1.1.8 root 1059: if (!is_rndis(s) || value || index != 0) {
1.1 root 1060: goto fail;
1.1.1.8 root 1061: }
1.1 root 1062: #ifdef TRAFFIC_DEBUG
1063: {
1064: unsigned int i;
1065: fprintf(stderr, "SEND_ENCAPSULATED_COMMAND:");
1066: for (i = 0; i < length; i++) {
1067: if (!(i & 15))
1068: fprintf(stderr, "\n%04x:", i);
1069: fprintf(stderr, " %02x", data[i]);
1070: }
1071: fprintf(stderr, "\n\n");
1072: }
1073: #endif
1074: ret = rndis_parse(s, data, length);
1075: break;
1076:
1077: case ClassInterfaceRequest | USB_CDC_GET_ENCAPSULATED_RESPONSE:
1.1.1.8 root 1078: if (!is_rndis(s) || value || index != 0) {
1.1 root 1079: goto fail;
1.1.1.8 root 1080: }
1.1 root 1081: ret = rndis_get_response(s, data);
1082: if (!ret) {
1083: data[0] = 0;
1084: ret = 1;
1085: }
1086: #ifdef TRAFFIC_DEBUG
1087: {
1088: unsigned int i;
1089: fprintf(stderr, "GET_ENCAPSULATED_RESPONSE:");
1090: for (i = 0; i < ret; i++) {
1091: if (!(i & 15))
1092: fprintf(stderr, "\n%04x:", i);
1093: fprintf(stderr, " %02x", data[i]);
1094: }
1095: fprintf(stderr, "\n\n");
1096: }
1097: #endif
1098: break;
1099:
1100: case DeviceRequest | USB_REQ_GET_INTERFACE:
1101: case InterfaceRequest | USB_REQ_GET_INTERFACE:
1102: data[0] = 0;
1103: ret = 1;
1104: break;
1105:
1106: case DeviceOutRequest | USB_REQ_SET_INTERFACE:
1107: case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
1108: ret = 0;
1109: break;
1110:
1111: default:
1112: fail:
1113: fprintf(stderr, "usbnet: failed control transaction: "
1114: "request 0x%x value 0x%x index 0x%x length 0x%x\n",
1115: request, value, index, length);
1116: ret = USB_RET_STALL;
1117: break;
1118: }
1119: return ret;
1120: }
1121:
1122: static int usb_net_handle_statusin(USBNetState *s, USBPacket *p)
1123: {
1124: int ret = 8;
1125:
1126: if (p->len < 8)
1127: return USB_RET_STALL;
1128:
1129: ((le32 *) p->data)[0] = cpu_to_le32(1);
1130: ((le32 *) p->data)[1] = cpu_to_le32(0);
1131: if (!s->rndis_resp.tqh_first)
1132: ret = USB_RET_NAK;
1133:
1134: #ifdef TRAFFIC_DEBUG
1135: fprintf(stderr, "usbnet: interrupt poll len %u return %d", p->len, ret);
1136: {
1137: int i;
1138: fprintf(stderr, ":");
1139: for (i = 0; i < ret; i++) {
1140: if (!(i & 15))
1141: fprintf(stderr, "\n%04x:", i);
1142: fprintf(stderr, " %02x", p->data[i]);
1143: }
1144: fprintf(stderr, "\n\n");
1145: }
1146: #endif
1147:
1148: return ret;
1149: }
1150:
1151: static int usb_net_handle_datain(USBNetState *s, USBPacket *p)
1152: {
1153: int ret = USB_RET_NAK;
1154:
1155: if (s->in_ptr > s->in_len) {
1156: s->in_ptr = s->in_len = 0;
1157: ret = USB_RET_NAK;
1158: return ret;
1159: }
1160: if (!s->in_len) {
1161: ret = USB_RET_NAK;
1162: return ret;
1163: }
1164: ret = s->in_len - s->in_ptr;
1165: if (ret > p->len)
1166: ret = p->len;
1167: memcpy(p->data, &s->in_buf[s->in_ptr], ret);
1168: s->in_ptr += ret;
1169: if (s->in_ptr >= s->in_len &&
1.1.1.8 root 1170: (is_rndis(s) || (s->in_len & (64 - 1)) || !ret)) {
1.1 root 1171: /* no short packet necessary */
1172: s->in_ptr = s->in_len = 0;
1173: }
1174:
1175: #ifdef TRAFFIC_DEBUG
1176: fprintf(stderr, "usbnet: data in len %u return %d", p->len, ret);
1177: {
1178: int i;
1179: fprintf(stderr, ":");
1180: for (i = 0; i < ret; i++) {
1181: if (!(i & 15))
1182: fprintf(stderr, "\n%04x:", i);
1183: fprintf(stderr, " %02x", p->data[i]);
1184: }
1185: fprintf(stderr, "\n\n");
1186: }
1187: #endif
1188:
1189: return ret;
1190: }
1191:
1192: static int usb_net_handle_dataout(USBNetState *s, USBPacket *p)
1193: {
1194: int ret = p->len;
1195: int sz = sizeof(s->out_buf) - s->out_ptr;
1196: struct rndis_packet_msg_type *msg =
1197: (struct rndis_packet_msg_type *) s->out_buf;
1198: uint32_t len;
1199:
1200: #ifdef TRAFFIC_DEBUG
1201: fprintf(stderr, "usbnet: data out len %u\n", p->len);
1202: {
1203: int i;
1204: fprintf(stderr, ":");
1205: for (i = 0; i < p->len; i++) {
1206: if (!(i & 15))
1207: fprintf(stderr, "\n%04x:", i);
1208: fprintf(stderr, " %02x", p->data[i]);
1209: }
1210: fprintf(stderr, "\n\n");
1211: }
1212: #endif
1213:
1214: if (sz > ret)
1215: sz = ret;
1216: memcpy(&s->out_buf[s->out_ptr], p->data, sz);
1217: s->out_ptr += sz;
1218:
1.1.1.8 root 1219: if (!is_rndis(s)) {
1.1 root 1220: if (ret < 64) {
1.1.1.4 root 1221: qemu_send_packet(&s->nic->nc, s->out_buf, s->out_ptr);
1.1 root 1222: s->out_ptr = 0;
1223: }
1224: return ret;
1225: }
1226: len = le32_to_cpu(msg->MessageLength);
1227: if (s->out_ptr < 8 || s->out_ptr < len)
1228: return ret;
1229: if (le32_to_cpu(msg->MessageType) == RNDIS_PACKET_MSG) {
1230: uint32_t offs = 8 + le32_to_cpu(msg->DataOffset);
1231: uint32_t size = le32_to_cpu(msg->DataLength);
1232: if (offs + size <= len)
1.1.1.4 root 1233: qemu_send_packet(&s->nic->nc, s->out_buf + offs, size);
1.1 root 1234: }
1235: s->out_ptr -= len;
1236: memmove(s->out_buf, &s->out_buf[len], s->out_ptr);
1237:
1238: return ret;
1239: }
1240:
1241: static int usb_net_handle_data(USBDevice *dev, USBPacket *p)
1242: {
1243: USBNetState *s = (USBNetState *) dev;
1244: int ret = 0;
1245:
1246: switch(p->pid) {
1247: case USB_TOKEN_IN:
1248: switch (p->devep) {
1249: case 1:
1250: ret = usb_net_handle_statusin(s, p);
1251: break;
1252:
1253: case 2:
1254: ret = usb_net_handle_datain(s, p);
1255: break;
1256:
1257: default:
1258: goto fail;
1259: }
1260: break;
1261:
1262: case USB_TOKEN_OUT:
1263: switch (p->devep) {
1264: case 2:
1265: ret = usb_net_handle_dataout(s, p);
1266: break;
1267:
1268: default:
1269: goto fail;
1270: }
1271: break;
1272:
1273: default:
1274: fail:
1275: ret = USB_RET_STALL;
1276: break;
1277: }
1278: if (ret == USB_RET_STALL)
1279: fprintf(stderr, "usbnet: failed data transaction: "
1280: "pid 0x%x ep 0x%x len 0x%x\n",
1281: p->pid, p->devep, p->len);
1282: return ret;
1283: }
1284:
1.1.1.4 root 1285: static ssize_t usbnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
1.1 root 1286: {
1.1.1.4 root 1287: USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
1.1 root 1288: struct rndis_packet_msg_type *msg;
1289:
1.1.1.8 root 1290: if (is_rndis(s)) {
1.1 root 1291: msg = (struct rndis_packet_msg_type *) s->in_buf;
1292: if (!s->rndis_state == RNDIS_DATA_INITIALIZED)
1.1.1.3 root 1293: return -1;
1.1 root 1294: if (size + sizeof(struct rndis_packet_msg_type) > sizeof(s->in_buf))
1.1.1.3 root 1295: return -1;
1.1 root 1296:
1297: memset(msg, 0, sizeof(struct rndis_packet_msg_type));
1298: msg->MessageType = cpu_to_le32(RNDIS_PACKET_MSG);
1299: msg->MessageLength = cpu_to_le32(size + sizeof(struct rndis_packet_msg_type));
1300: msg->DataOffset = cpu_to_le32(sizeof(struct rndis_packet_msg_type) - 8);
1301: msg->DataLength = cpu_to_le32(size);
1302: /* msg->OOBDataOffset;
1303: * msg->OOBDataLength;
1304: * msg->NumOOBDataElements;
1305: * msg->PerPacketInfoOffset;
1306: * msg->PerPacketInfoLength;
1307: * msg->VcHandle;
1308: * msg->Reserved;
1309: */
1310: memcpy(msg + 1, buf, size);
1311: s->in_len = size + sizeof(struct rndis_packet_msg_type);
1312: } else {
1313: if (size > sizeof(s->in_buf))
1.1.1.3 root 1314: return -1;
1.1 root 1315: memcpy(s->in_buf, buf, size);
1316: s->in_len = size;
1317: }
1318: s->in_ptr = 0;
1.1.1.3 root 1319: return size;
1.1 root 1320: }
1321:
1.1.1.4 root 1322: static int usbnet_can_receive(VLANClientState *nc)
1.1 root 1323: {
1.1.1.4 root 1324: USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
1.1 root 1325:
1.1.1.8 root 1326: if (is_rndis(s) && !s->rndis_state == RNDIS_DATA_INITIALIZED) {
1.1 root 1327: return 1;
1.1.1.8 root 1328: }
1.1 root 1329:
1330: return !s->in_len;
1331: }
1332:
1.1.1.4 root 1333: static void usbnet_cleanup(VLANClientState *nc)
1.1.1.2 root 1334: {
1.1.1.4 root 1335: USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
1.1.1.2 root 1336:
1.1.1.4 root 1337: s->nic = NULL;
1.1.1.2 root 1338: }
1339:
1.1 root 1340: static void usb_net_handle_destroy(USBDevice *dev)
1341: {
1342: USBNetState *s = (USBNetState *) dev;
1343:
1344: /* TODO: remove the nd_table[] entry */
1.1.1.4 root 1345: rndis_clear_responsequeue(s);
1346: qemu_del_vlan_client(&s->nic->nc);
1.1 root 1347: }
1348:
1.1.1.4 root 1349: static NetClientInfo net_usbnet_info = {
1350: .type = NET_CLIENT_TYPE_NIC,
1351: .size = sizeof(NICState),
1352: .can_receive = usbnet_can_receive,
1353: .receive = usbnet_receive,
1354: .cleanup = usbnet_cleanup,
1355: };
1.1 root 1356:
1.1.1.4 root 1357: static int usb_net_initfn(USBDevice *dev)
1358: {
1359: USBNetState *s = DO_UPCAST(USBNetState, dev, dev);
1.1 root 1360:
1.1.1.8 root 1361: usb_desc_init(dev);
1.1 root 1362:
1363: s->rndis_state = RNDIS_UNINITIALIZED;
1.1.1.4 root 1364: QTAILQ_INIT(&s->rndis_resp);
1365:
1.1 root 1366: s->medium = 0; /* NDIS_MEDIUM_802_3 */
1367: s->speed = 1000000; /* 100MBps, in 100Bps units */
1368: s->media_state = 0; /* NDIS_MEDIA_STATE_CONNECTED */;
1369: s->filter = 0;
1370: s->vendorid = 0x1234;
1371:
1.1.1.4 root 1372: qemu_macaddr_default_if_unset(&s->conf.macaddr);
1373: s->nic = qemu_new_nic(&net_usbnet_info, &s->conf,
1374: s->dev.qdev.info->name, s->dev.qdev.id, s);
1375: qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
1376: snprintf(s->usbstring_mac, sizeof(s->usbstring_mac),
1377: "%02x%02x%02x%02x%02x%02x",
1378: 0x40,
1379: s->conf.macaddr.a[1],
1380: s->conf.macaddr.a[2],
1381: s->conf.macaddr.a[3],
1382: s->conf.macaddr.a[4],
1383: s->conf.macaddr.a[5]);
1.1.1.8 root 1384: usb_desc_set_string(dev, STRING_ETHADDR, s->usbstring_mac);
1.1 root 1385:
1.1.1.8 root 1386: add_boot_device_path(s->conf.bootindex, &dev->qdev, "/ethernet@0");
1.1.1.4 root 1387: return 0;
1388: }
1.1 root 1389:
1.1.1.4 root 1390: static USBDevice *usb_net_init(const char *cmdline)
1391: {
1392: USBDevice *dev;
1393: QemuOpts *opts;
1394: int idx;
1395:
1.1.1.8 root 1396: opts = qemu_opts_parse(qemu_find_opts("net"), cmdline, 0);
1.1.1.4 root 1397: if (!opts) {
1398: return NULL;
1399: }
1400: qemu_opt_set(opts, "type", "nic");
1401: qemu_opt_set(opts, "model", "usb");
1.1 root 1402:
1.1.1.4 root 1403: idx = net_client_init(NULL, opts, 0);
1404: if (idx == -1) {
1405: return NULL;
1406: }
1.1 root 1407:
1.1.1.4 root 1408: dev = usb_create(NULL /* FIXME */, "usb-net");
1.1.1.6 root 1409: if (!dev) {
1410: return NULL;
1411: }
1.1.1.4 root 1412: qdev_set_nic_properties(&dev->qdev, &nd_table[idx]);
1.1.1.5 root 1413: qdev_init_nofail(&dev->qdev);
1.1.1.4 root 1414: return dev;
1415: }
1416:
1417: static struct USBDeviceInfo net_info = {
1418: .product_desc = "QEMU USB Network Interface",
1419: .qdev.name = "usb-net",
1.1.1.8 root 1420: .qdev.fw_name = "network",
1.1.1.4 root 1421: .qdev.size = sizeof(USBNetState),
1.1.1.8 root 1422: .usb_desc = &desc_net,
1.1.1.4 root 1423: .init = usb_net_initfn,
1424: .handle_packet = usb_generic_handle_packet,
1425: .handle_reset = usb_net_handle_reset,
1426: .handle_control = usb_net_handle_control,
1427: .handle_data = usb_net_handle_data,
1428: .handle_destroy = usb_net_handle_destroy,
1429: .usbdevice_name = "net",
1430: .usbdevice_init = usb_net_init,
1431: .qdev.props = (Property[]) {
1432: DEFINE_NIC_PROPERTIES(USBNetState, conf),
1433: DEFINE_PROP_END_OF_LIST(),
1434: }
1435: };
1436:
1437: static void usb_net_register_devices(void)
1438: {
1439: usb_qdev_register(&net_info);
1.1 root 1440: }
1.1.1.4 root 1441: device_init(usb_net_register_devices)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.