[rndis] Add rndis_rx_err()
[ipxe.git] / src / include / ipxe / rndis.h
1 #ifndef _IPXE_RNDIS_H
2 #define _IPXE_RNDIS_H
3
4 /** @file
5 *
6 * Remote Network Driver Interface Specification
7 *
8 */
9
10 FILE_LICENCE ( GPL2_OR_LATER );
11
12 #include <stdint.h>
13 #include <ipxe/netdevice.h>
14 #include <ipxe/iobuf.h>
15
16 /** Maximum time to wait for a transaction to complete
17 *
18 * This is a policy decision.
19 */
20 #define RNDIS_MAX_WAIT_MS 1000
21
22 /** RNDIS message header */
23 struct rndis_header {
24 /** Message type */
25 uint32_t type;
26 /** Message length */
27 uint32_t len;
28 } __attribute__ (( packed ));
29
30 /** RNDIS initialise message */
31 #define RNDIS_INITIALISE_MSG 0x00000002UL
32
33 /** RNDIS initialise message */
34 struct rndis_initialise_message {
35 /** Request ID */
36 uint32_t id;
37 /** Major version */
38 uint32_t major;
39 /** Minor version */
40 uint32_t minor;
41 /** Maximum transfer size */
42 uint32_t mtu;
43 } __attribute__ (( packed ));
44
45 /** Request ID used for initialisation
46 *
47 * This is a policy decision.
48 */
49 #define RNDIS_INIT_ID 0xe110e110UL
50
51 /** RNDIS major version */
52 #define RNDIS_VERSION_MAJOR 1
53
54 /** RNDIS minor version */
55 #define RNDIS_VERSION_MINOR 0
56
57 /** RNDIS maximum transfer size
58 *
59 * This is a policy decision.
60 */
61 #define RNDIS_MTU 2048
62
63 /** RNDIS initialise completion */
64 #define RNDIS_INITIALISE_CMPLT 0x80000002UL
65
66 /** RNDIS initialise completion */
67 struct rndis_initialise_completion {
68 /** Request ID */
69 uint32_t id;
70 /** Status */
71 uint32_t status;
72 /** Major version */
73 uint32_t major;
74 /** Minor version */
75 uint32_t minor;
76 /** Device flags */
77 uint32_t flags;
78 /** Medium */
79 uint32_t medium;
80 /** Maximum packets per transfer */
81 uint32_t max_pkts;
82 /** Maximum transfer size */
83 uint32_t mtu;
84 /** Packet alignment factor */
85 uint32_t align;
86 /** Reserved */
87 uint32_t reserved;
88 } __attribute__ (( packed ));
89
90 /** RNDIS halt message */
91 #define RNDIS_HALT_MSG 0x00000003UL
92
93 /** RNDIS halt message */
94 struct rndis_halt_message {
95 /** Request ID */
96 uint32_t id;
97 } __attribute__ (( packed ));
98
99 /** RNDIS query OID message */
100 #define RNDIS_QUERY_MSG 0x00000004UL
101
102 /** RNDIS set OID message */
103 #define RNDIS_SET_MSG 0x00000005UL
104
105 /** RNDIS query or set OID message */
106 struct rndis_oid_message {
107 /** Request ID */
108 uint32_t id;
109 /** Object ID */
110 uint32_t oid;
111 /** Information buffer length */
112 uint32_t len;
113 /** Information buffer offset */
114 uint32_t offset;
115 /** Reserved */
116 uint32_t reserved;
117 } __attribute__ (( packed ));
118
119 /** RNDIS query OID completion */
120 #define RNDIS_QUERY_CMPLT 0x80000004UL
121
122 /** RNDIS query OID completion */
123 struct rndis_query_completion {
124 /** Request ID */
125 uint32_t id;
126 /** Status */
127 uint32_t status;
128 /** Information buffer length */
129 uint32_t len;
130 /** Information buffer offset */
131 uint32_t offset;
132 } __attribute__ (( packed ));
133
134 /** RNDIS set OID completion */
135 #define RNDIS_SET_CMPLT 0x80000005UL
136
137 /** RNDIS set OID completion */
138 struct rndis_set_completion {
139 /** Request ID */
140 uint32_t id;
141 /** Status */
142 uint32_t status;
143 } __attribute__ (( packed ));
144
145 /** RNDIS reset message */
146 #define RNDIS_RESET_MSG 0x00000006UL
147
148 /** RNDIS reset message */
149 struct rndis_reset_message {
150 /** Reserved */
151 uint32_t reserved;
152 } __attribute__ (( packed ));
153
154 /** RNDIS reset completion */
155 #define RNDIS_RESET_CMPLT 0x80000006UL
156
157 /** RNDIS reset completion */
158 struct rndis_reset_completion {
159 /** Status */
160 uint32_t status;
161 /** Addressing reset */
162 uint32_t addr;
163 } __attribute__ (( packed ));
164
165 /** RNDIS indicate status message */
166 #define RNDIS_INDICATE_STATUS_MSG 0x00000007UL
167
168 /** RNDIS diagnostic information */
169 struct rndis_diagnostic_info {
170 /** Status */
171 uint32_t status;
172 /** Error offset */
173 uint32_t offset;
174 } __attribute__ (( packed ));
175
176 /** RNDIS indicate status message */
177 struct rndis_indicate_status_message {
178 /** Status */
179 uint32_t status;
180 /** Status buffer length */
181 uint32_t len;
182 /** Status buffer offset */
183 uint32_t offset;
184 /** Diagnostic information (optional) */
185 struct rndis_diagnostic_info diag[0];
186 } __attribute__ (( packed ));
187
188 /** RNDIS status codes */
189 enum rndis_status {
190 /** Device is connected to a network medium */
191 RNDIS_STATUS_MEDIA_CONNECT = 0x4001000bUL,
192 /** Device is disconnected from the medium */
193 RNDIS_STATUS_MEDIA_DISCONNECT = 0x4001000cUL,
194 /** Unknown start-of-day status code */
195 RNDIS_STATUS_WTF_WORLD = 0x40020006UL,
196 };
197
198 /** RNDIS keepalive message */
199 #define RNDIS_KEEPALIVE_MSG 0x00000008UL
200
201 /** RNDIS keepalive message */
202 struct rndis_keepalive_message {
203 /** Request ID */
204 uint32_t id;
205 } __attribute__ (( packed ));
206
207 /** RNDIS keepalive completion */
208 #define RNDIS_KEEPALIVE_CMPLT 0x80000008UL
209
210 /** RNDIS keepalive completion */
211 struct rndis_keepalive_completion {
212 /** Request ID */
213 uint32_t id;
214 /** Status */
215 uint32_t status;
216 } __attribute__ (( packed ));
217
218 /** RNDIS packet message */
219 #define RNDIS_PACKET_MSG 0x00000001UL
220
221 /** RNDIS packet field */
222 struct rndis_packet_field {
223 /** Offset */
224 uint32_t offset;
225 /** Length */
226 uint32_t len;
227 } __attribute__ (( packed ));
228
229 /** RNDIS packet message */
230 struct rndis_packet_message {
231 /** Data */
232 struct rndis_packet_field data;
233 /** Out-of-band data records */
234 struct rndis_packet_field oob;
235 /** Number of out-of-band data records */
236 uint32_t oob_count;
237 /** Per-packet information record */
238 struct rndis_packet_field ppi;
239 /** Reserved */
240 uint32_t reserved;
241 } __attribute__ (( packed ));
242
243 /** RNDIS packet record */
244 struct rndis_packet_record {
245 /** Length */
246 uint32_t len;
247 /** Type */
248 uint32_t type;
249 /** Offset */
250 uint32_t offset;
251 } __attribute__ (( packed ));
252
253 /** OID for packet filter */
254 #define RNDIS_OID_GEN_CURRENT_PACKET_FILTER 0x0001010eUL
255
256 /** Packet filter bits */
257 enum rndis_packet_filter {
258 /** Unicast packets */
259 RNDIS_FILTER_UNICAST = 0x00000001UL,
260 /** Multicast packets */
261 RNDIS_FILTER_MULTICAST = 0x00000002UL,
262 /** All multicast packets */
263 RNDIS_FILTER_ALL_MULTICAST = 0x00000004UL,
264 /** Broadcast packets */
265 RNDIS_FILTER_BROADCAST = 0x00000008UL,
266 /** All packets */
267 RNDIS_FILTER_PROMISCUOUS = 0x00000020UL
268 };
269
270 /** OID for media status */
271 #define RNDIS_OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL
272
273 /** OID for permanent MAC address */
274 #define RNDIS_OID_802_3_PERMANENT_ADDRESS 0x01010101UL
275
276 /** OID for current MAC address */
277 #define RNDIS_OID_802_3_CURRENT_ADDRESS 0x01010102UL
278
279 struct rndis_device;
280
281 /** RNDIS device operations */
282 struct rndis_operations {
283 /**
284 * Open RNDIS device
285 *
286 * @v rndis RNDIS device
287 * @ret rc Return status code
288 */
289 int ( * open ) ( struct rndis_device *rndis );
290 /**
291 * Close RNDIS device
292 *
293 * @v rndis RNDIS device
294 */
295 void ( * close ) ( struct rndis_device *rndis );
296 /**
297 * Transmit packet
298 *
299 * @v rndis RNDIS device
300 * @v iobuf I/O buffer
301 * @ret rc Return status code
302 *
303 * If this method returns success then the RNDIS device must
304 * eventually report completion via rndis_tx_complete().
305 */
306 int ( * transmit ) ( struct rndis_device *rndis,
307 struct io_buffer *iobuf );
308 /**
309 * Poll for completed and received packets
310 *
311 * @v rndis RNDIS device
312 */
313 void ( * poll ) ( struct rndis_device *rndis );
314 };
315
316 /** An RNDIS device */
317 struct rndis_device {
318 /** Network device */
319 struct net_device *netdev;
320 /** Device name */
321 const char *name;
322 /** RNDIS operations */
323 struct rndis_operations *op;
324 /** Driver private data */
325 void *priv;
326
327 /** Request ID for current blocking request */
328 unsigned int wait_id;
329 /** Return status code for current blocking request */
330 int wait_rc;
331 };
332
333 /**
334 * Initialise an RNDIS device
335 *
336 * @v rndis RNDIS device
337 * @v op RNDIS device operations
338 */
339 static inline void rndis_init ( struct rndis_device *rndis,
340 struct rndis_operations *op ) {
341
342 rndis->op = op;
343 }
344
345 extern void rndis_tx_complete_err ( struct rndis_device *rndis,
346 struct io_buffer *iobuf, int rc );
347 extern int rndis_tx_defer ( struct rndis_device *rndis,
348 struct io_buffer *iobuf );
349 extern void rndis_rx ( struct rndis_device *rndis, struct io_buffer *iobuf );
350 extern void rndis_rx_err ( struct rndis_device *rndis, struct io_buffer *iobuf,
351 int rc );
352
353 extern struct rndis_device * alloc_rndis ( size_t priv_len );
354 extern int register_rndis ( struct rndis_device *rndis );
355 extern void unregister_rndis ( struct rndis_device *rndis );
356 extern void free_rndis ( struct rndis_device *rndis );
357
358 /**
359 * Complete message transmission
360 *
361 * @v rndis RNDIS device
362 * @v iobuf I/O buffer
363 */
364 static inline void rndis_tx_complete ( struct rndis_device *rndis,
365 struct io_buffer *iobuf ) {
366
367 rndis_tx_complete_err ( rndis, iobuf, 0 );
368 }
369
370 #endif /* _IPXE_RNDIS_H */