Annotation of qemu/hw/usb-net.c, revision 1.1.1.9

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)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.