1 /* 2 * Copyright (c) 2024 Archermind Technology (Nanjing) Co. Ltd. 3 * 4 * HDF is dual licensed: you can use it either under the terms of 5 * the GPL, or the BSD license, at your option. 6 * See the LICENSE file in the root of this repository for complete details. 7 */ 8 9 #ifndef HDF_HOST_RNDIS_RAWAPI_H 10 #define HDF_HOST_RNDIS_RAWAPI_H 11 12 #include <linux/types.h> 13 #include <servmgr_hdi.h> 14 #include <hdf_remote_service.h> 15 #include <hdf_sbuf.h> 16 17 #include "data_fifo.h" 18 #include "hdf_device_desc.h" 19 #include "usb_raw_api.h" 20 #include "rndis_host.h" 21 22 /* MS-Windows uses this strange size, but RNDIS spec says 1024 minimum */ 23 #define CONTROL_BUFFER_SIZE 1025 24 25 /* RNDIS defines an (absurdly huge) 10 second control timeout, 26 * but ActiveSync seems to use a more usual 5 second timeout 27 * (which matches the USB 2.0 spec). 28 */ 29 #define RNDIS_CONTROL_TIMEOUT_MS (5 * 1000) 30 31 /* default filter used with RNDIS devices */ 32 #define RNDIS_DEFAULT_FILTER ( \ 33 RNDIS_PACKET_TYPE_DIRECTED | \ 34 RNDIS_PACKET_TYPE_BROADCAST | \ 35 RNDIS_PACKET_TYPE_ALL_MULTICAST | \ 36 RNDIS_PACKET_TYPE_PROMISCUOUS) 37 38 /* Flags to require specific physical medium type for generic_rndis_bind() */ 39 #define FLAG_RNDIS_PHYM_NOT_WIRELESS 0x0001 40 #define FLAG_RNDIS_PHYM_WIRELESS 0x0002 41 /* Flags for driver_info::data */ 42 #define RNDIS_DRIVER_DATA_POLL_STATUS 1 /* poll status before control */ 43 44 /* 45 * CONTROL uses CDC "encapsulated commands" with funky notifications. 46 * - control-out: SEND_ENCAPSULATED 47 * - interrupt-in: RESPONSE_AVAILABLE 48 * - control-in: GET_ENCAPSULATED 49 * 50 * We'll try to ignore the RESPONSE_AVAILABLE notifications. 51 * 52 * REVISIT some RNDIS implementations seem to have curious issues still 53 * to be resolved. 54 */ 55 struct RndisMsgHdr { 56 __le32 msgType; /* RNDIS_MSG_* */ 57 __le32 msgLen; 58 /* followed by data that varies between messages */ 59 __le32 requestId; 60 __le32 status; 61 /* ... and more */ 62 } __attribute__ ((packed)); 63 64 struct RndisDataHdr { 65 __le32 msgType; /* RNDIS_MSG_PACKET */ 66 __le32 msgLen; /* RndisDataHdr + dataLen + pad */ 67 __le32 dataOffset; /* 36 -- right after header */ 68 __le32 dataLen; /* ... real packet size */ 69 70 __le32 oobDataOffset; /* zero */ 71 __le32 oobDataLen; /* zero */ 72 __le32 numOob; /* zero */ 73 __le32 packetDataOffset; /* zero */ 74 75 __le32 packetDataLen; /* zero */ 76 __le32 vcHandle; /* zero */ 77 __le32 reserved; /* zero */ 78 } __attribute__ ((packed)); 79 80 struct RndisInit { /* OUT */ 81 /* header and: */ 82 __le32 msgType; /* RNDIS_MSG_INIT */ 83 __le32 msgLen; /* 24 */ 84 __le32 requestId; 85 __le32 majorVersion; /* of rndis (1.0) */ 86 __le32 minorVersion; 87 __le32 maxTransferSize; 88 } __attribute__ ((packed)); 89 90 struct RndisInitC { /* IN */ 91 /* header and: */ 92 __le32 msgType; /* RNDIS_MSG_INIT_C */ 93 __le32 msgLen; 94 __le32 requestId; 95 __le32 status; 96 __le32 majorVersion; /* of rndis (1.0) */ 97 __le32 minorVersion; 98 __le32 deviceFlags; 99 __le32 medium; /* zero == 802.3 */ 100 __le32 maxPacketsPerMessage; 101 __le32 maxTransferSize; 102 __le32 packetAlignment; /* max 7; (1<<n) bytes */ 103 __le32 afListOffset; /* zero */ 104 __le32 afListSize; /* zero */ 105 } __attribute__ ((packed)); 106 107 struct RndisHalt { /* OUT (no reply) */ 108 /* header and: */ 109 __le32 msgType; /* RNDIS_MSG_HALT */ 110 __le32 msgLen; 111 __le32 requestId; 112 } __attribute__ ((packed)); 113 114 struct RndisQuery { /* OUT */ 115 /* header and: */ 116 __le32 msgType; /* RNDIS_MSG_QUERY */ 117 __le32 msgLen; 118 __le32 requestId; 119 __le32 oid; 120 __le32 len; 121 __le32 offset; 122 __le32 handle; /* zero */ 123 } __attribute__ ((packed)); 124 125 struct RndisQueryParam { 126 void *buf; 127 uint32_t oid; 128 uint32_t in_len; 129 } __attribute__ ((packed)); 130 131 struct RndisQueryC { /* IN */ 132 /* header and: */ 133 __le32 msgType; /* RNDIS_MSG_QUERY_C */ 134 __le32 msgLen; 135 __le32 requestId; 136 __le32 status; 137 __le32 len; 138 __le32 offset; 139 } __attribute__ ((packed)); 140 141 struct RndisSet { /* OUT */ 142 /* header and: */ 143 __le32 msgType; /* RNDIS_MSG_SET */ 144 __le32 msgLen; 145 __le32 requestId; 146 __le32 oid; 147 __le32 len; 148 __le32 offset; 149 __le32 handle; /* zero */ 150 } __attribute__ ((packed)); 151 152 struct RndisSetC { /* IN */ 153 /* header and: */ 154 __le32 msgType; /* RNDIS_MSG_SET_C */ 155 __le32 msgLen; 156 __le32 requestId; 157 __le32 status; 158 } __attribute__ ((packed)); 159 160 struct RndisReset { /* IN */ 161 /* header and: */ 162 __le32 msgType; /* RNDIS_MSG_RESET */ 163 __le32 msgLen; 164 __le32 reserved; 165 } __attribute__ ((packed)); 166 167 struct RndisResetC { /* OUT */ 168 /* header and: */ 169 __le32 msgType; /* RNDIS_MSG_RESET_C */ 170 __le32 msgLen; 171 __le32 status; 172 __le32 addressingLost; 173 } __attribute__ ((packed)); 174 175 struct RndisIndicate { /* IN (unrequested) */ 176 /* header and: */ 177 __le32 msgType; /* RNDIS_MSG_INDICATE */ 178 __le32 msgLen; 179 __le32 status; 180 __le32 length; 181 __le32 offset; 182 __le32 diagStatus; 183 __le32 errorOffset; 184 __le32 message; 185 } __attribute__ ((packed)); 186 187 struct RndisKeepalive { /* OUT (optionally IN) */ 188 /* header and: */ 189 __le32 msgType; /* RNDIS_MSG_KEEPALIVE */ 190 __le32 msgLen; 191 __le32 requestId; 192 } __attribute__ ((packed)); 193 194 struct RndisKeepaliveC { /* IN (optionally OUT) */ 195 /* header and: */ 196 __le32 msgType; /* RNDIS_MSG_KEEPALIVE_C */ 197 __le32 msgLen; 198 __le32 requestId; 199 __le32 status; 200 } __attribute__ ((packed)); 201 202 #endif /* HDF_USB_SERIAL_RAWAPI_H */ 203