iPXE
rndis.h
Go to the documentation of this file.
00001 #ifndef _IPXE_RNDIS_H
00002 #define _IPXE_RNDIS_H
00003 
00004 /** @file
00005  *
00006  * Remote Network Driver Interface Specification
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 #include <stdint.h>
00013 #include <ipxe/netdevice.h>
00014 #include <ipxe/iobuf.h>
00015 
00016 /** Maximum time to wait for a transaction to complete
00017  *
00018  * This is a policy decision.
00019  */
00020 #define RNDIS_MAX_WAIT_MS 1000
00021 
00022 /** RNDIS message header */
00023 struct rndis_header {
00024         /** Message type */
00025         uint32_t type;
00026         /** Message length */
00027         uint32_t len;
00028 } __attribute__ (( packed ));
00029 
00030 /** RNDIS initialise message */
00031 #define RNDIS_INITIALISE_MSG 0x00000002UL
00032 
00033 /** RNDIS initialise message */
00034 struct rndis_initialise_message {
00035         /** Request ID */
00036         uint32_t id;
00037         /** Major version */
00038         uint32_t major;
00039         /** Minor version */
00040         uint32_t minor;
00041         /** Maximum transfer size */
00042         uint32_t mtu;
00043 } __attribute__ (( packed ));
00044 
00045 /** Request ID used for initialisation
00046  *
00047  * This is a policy decision.
00048  */
00049 #define RNDIS_INIT_ID 0xe110e110UL
00050 
00051 /** RNDIS major version */
00052 #define RNDIS_VERSION_MAJOR 1
00053 
00054 /** RNDIS minor version */
00055 #define RNDIS_VERSION_MINOR 0
00056 
00057 /** RNDIS maximum transfer size
00058  *
00059  * This is a policy decision.
00060  */
00061 #define RNDIS_MTU 2048
00062 
00063 /** RNDIS initialise completion */
00064 #define RNDIS_INITIALISE_CMPLT 0x80000002UL
00065 
00066 /** RNDIS initialise completion */
00067 struct rndis_initialise_completion {
00068         /** Request ID */
00069         uint32_t id;
00070         /** Status */
00071         uint32_t status;
00072         /** Major version */
00073         uint32_t major;
00074         /** Minor version */
00075         uint32_t minor;
00076         /** Device flags */
00077         uint32_t flags;
00078         /** Medium */
00079         uint32_t medium;
00080         /** Maximum packets per transfer */
00081         uint32_t max_pkts;
00082         /** Maximum transfer size */
00083         uint32_t mtu;
00084         /** Packet alignment factor */
00085         uint32_t align;
00086         /** Reserved */
00087         uint32_t reserved;
00088 } __attribute__ (( packed ));
00089 
00090 /** RNDIS halt message */
00091 #define RNDIS_HALT_MSG 0x00000003UL
00092 
00093 /** RNDIS halt message */
00094 struct rndis_halt_message {
00095         /** Request ID */
00096         uint32_t id;
00097 } __attribute__ (( packed ));
00098 
00099 /** RNDIS query OID message */
00100 #define RNDIS_QUERY_MSG 0x00000004UL
00101 
00102 /** RNDIS set OID message */
00103 #define RNDIS_SET_MSG 0x00000005UL
00104 
00105 /** RNDIS query or set OID message */
00106 struct rndis_oid_message {
00107         /** Request ID */
00108         uint32_t id;
00109         /** Object ID */
00110         uint32_t oid;
00111         /** Information buffer length */
00112         uint32_t len;
00113         /** Information buffer offset */
00114         uint32_t offset;
00115         /** Reserved */
00116         uint32_t reserved;
00117 } __attribute__ (( packed ));
00118 
00119 /** RNDIS query OID completion */
00120 #define RNDIS_QUERY_CMPLT 0x80000004UL
00121 
00122 /** RNDIS query OID completion */
00123 struct rndis_query_completion {
00124         /** Request ID */
00125         uint32_t id;
00126         /** Status */
00127         uint32_t status;
00128         /** Information buffer length */
00129         uint32_t len;
00130         /** Information buffer offset */
00131         uint32_t offset;
00132 } __attribute__ (( packed ));
00133 
00134 /** RNDIS set OID completion */
00135 #define RNDIS_SET_CMPLT 0x80000005UL
00136 
00137 /** RNDIS set OID completion */
00138 struct rndis_set_completion {
00139         /** Request ID */
00140         uint32_t id;
00141         /** Status */
00142         uint32_t status;
00143 } __attribute__ (( packed ));
00144 
00145 /** RNDIS reset message */
00146 #define RNDIS_RESET_MSG 0x00000006UL
00147 
00148 /** RNDIS reset message */
00149 struct rndis_reset_message {
00150         /** Reserved */
00151         uint32_t reserved;
00152 } __attribute__ (( packed ));
00153 
00154 /** RNDIS reset completion */
00155 #define RNDIS_RESET_CMPLT 0x80000006UL
00156 
00157 /** RNDIS reset completion */
00158 struct rndis_reset_completion {
00159         /** Status */
00160         uint32_t status;
00161         /** Addressing reset */
00162         uint32_t addr;
00163 } __attribute__ (( packed ));
00164 
00165 /** RNDIS indicate status message */
00166 #define RNDIS_INDICATE_STATUS_MSG 0x00000007UL
00167 
00168 /** RNDIS diagnostic information */
00169 struct rndis_diagnostic_info {
00170         /** Status */
00171         uint32_t status;
00172         /** Error offset */
00173         uint32_t offset;
00174 } __attribute__ (( packed ));
00175 
00176 /** RNDIS indicate status message */
00177 struct rndis_indicate_status_message {
00178         /** Status */
00179         uint32_t status;
00180         /** Status buffer length */
00181         uint32_t len;
00182         /** Status buffer offset */
00183         uint32_t offset;
00184         /** Diagnostic information (optional) */
00185         struct rndis_diagnostic_info diag[0];
00186 } __attribute__ (( packed ));
00187 
00188 /** RNDIS status codes */
00189 enum rndis_status {
00190         /** Device is connected to a network medium */
00191         RNDIS_STATUS_MEDIA_CONNECT = 0x4001000bUL,
00192         /** Device is disconnected from the medium */
00193         RNDIS_STATUS_MEDIA_DISCONNECT = 0x4001000cUL,
00194         /** Unknown start-of-day status code */
00195         RNDIS_STATUS_WTF_WORLD = 0x40020006UL,
00196 };
00197 
00198 /** RNDIS keepalive message */
00199 #define RNDIS_KEEPALIVE_MSG 0x00000008UL
00200 
00201 /** RNDIS keepalive message */
00202 struct rndis_keepalive_message {
00203         /** Request ID */
00204         uint32_t id;
00205 } __attribute__ (( packed ));
00206 
00207 /** RNDIS keepalive completion */
00208 #define RNDIS_KEEPALIVE_CMPLT 0x80000008UL
00209 
00210 /** RNDIS keepalive completion */
00211 struct rndis_keepalive_completion {
00212         /** Request ID */
00213         uint32_t id;
00214         /** Status */
00215         uint32_t status;
00216 } __attribute__ (( packed ));
00217 
00218 /** RNDIS packet message */
00219 #define RNDIS_PACKET_MSG 0x00000001UL
00220 
00221 /** RNDIS packet field */
00222 struct rndis_packet_field {
00223         /** Offset */
00224         uint32_t offset;
00225         /** Length */
00226         uint32_t len;
00227 } __attribute__ (( packed ));
00228 
00229 /** RNDIS packet message */
00230 struct rndis_packet_message {
00231         /** Data */
00232         struct rndis_packet_field data;
00233         /** Out-of-band data records */
00234         struct rndis_packet_field oob;
00235         /** Number of out-of-band data records */
00236         uint32_t oob_count;
00237         /** Per-packet information record */
00238         struct rndis_packet_field ppi;
00239         /** Reserved */
00240         uint32_t reserved;
00241 } __attribute__ (( packed ));
00242 
00243 /** RNDIS packet record */
00244 struct rndis_packet_record {
00245         /** Length */
00246         uint32_t len;
00247         /** Type */
00248         uint32_t type;
00249         /** Offset */
00250         uint32_t offset;
00251 } __attribute__ (( packed ));
00252 
00253 /** OID for packet filter */
00254 #define RNDIS_OID_GEN_CURRENT_PACKET_FILTER 0x0001010eUL
00255 
00256 /** Packet filter bits */
00257 enum rndis_packet_filter {
00258         /** Unicast packets */
00259         RNDIS_FILTER_UNICAST = 0x00000001UL,
00260         /** Multicast packets */
00261         RNDIS_FILTER_MULTICAST = 0x00000002UL,
00262         /** All multicast packets */
00263         RNDIS_FILTER_ALL_MULTICAST = 0x00000004UL,
00264         /** Broadcast packets */
00265         RNDIS_FILTER_BROADCAST = 0x00000008UL,
00266         /** All packets */
00267         RNDIS_FILTER_PROMISCUOUS = 0x00000020UL
00268 };
00269 
00270 /** OID for media status */
00271 #define RNDIS_OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL
00272 
00273 /** OID for permanent MAC address */
00274 #define RNDIS_OID_802_3_PERMANENT_ADDRESS 0x01010101UL
00275 
00276 /** OID for current MAC address */
00277 #define RNDIS_OID_802_3_CURRENT_ADDRESS 0x01010102UL
00278 
00279 struct rndis_device;
00280 
00281 /** RNDIS device operations */
00282 struct rndis_operations {
00283         /**
00284          * Open RNDIS device
00285          *
00286          * @v rndis             RNDIS device
00287          * @ret rc              Return status code
00288          */
00289         int ( * open ) ( struct rndis_device *rndis );
00290         /**
00291          * Close RNDIS device
00292          *
00293          * @v rndis             RNDIS device
00294          */
00295         void ( * close ) ( struct rndis_device *rndis );
00296         /**
00297          * Transmit packet
00298          *
00299          * @v rndis             RNDIS device
00300          * @v iobuf             I/O buffer
00301          * @ret rc              Return status code
00302          *
00303          * If this method returns success then the RNDIS device must
00304          * eventually report completion via rndis_tx_complete().
00305          */
00306         int ( * transmit ) ( struct rndis_device *rndis,
00307                              struct io_buffer *iobuf );
00308         /**
00309          * Poll for completed and received packets
00310          *
00311          * @v rndis             RNDIS device
00312          */
00313         void ( * poll ) ( struct rndis_device *rndis );
00314 };
00315 
00316 /** An RNDIS device */
00317 struct rndis_device {
00318         /** Network device */
00319         struct net_device *netdev;
00320         /** Device name */
00321         const char *name;
00322         /** RNDIS operations */
00323         struct rndis_operations *op;
00324         /** Driver private data */
00325         void *priv;
00326 
00327         /** Request ID for current blocking request */
00328         unsigned int wait_id;
00329         /** Return status code for current blocking request */
00330         int wait_rc;
00331 };
00332 
00333 /**
00334  * Initialise an RNDIS device
00335  *
00336  * @v rndis             RNDIS device
00337  * @v op                RNDIS device operations
00338  */
00339 static inline void rndis_init ( struct rndis_device *rndis,
00340                                 struct rndis_operations *op ) {
00341 
00342         rndis->op = op;
00343 }
00344 
00345 extern void rndis_tx_complete_err ( struct rndis_device *rndis,
00346                                     struct io_buffer *iobuf, int rc );
00347 extern int rndis_tx_defer ( struct rndis_device *rndis,
00348                             struct io_buffer *iobuf );
00349 extern void rndis_rx ( struct rndis_device *rndis, struct io_buffer *iobuf );
00350 extern void rndis_rx_err ( struct rndis_device *rndis, struct io_buffer *iobuf,
00351                            int rc );
00352 
00353 extern struct rndis_device * alloc_rndis ( size_t priv_len );
00354 extern int register_rndis ( struct rndis_device *rndis );
00355 extern void unregister_rndis ( struct rndis_device *rndis );
00356 extern void free_rndis ( struct rndis_device *rndis );
00357 
00358 /**
00359  * Complete message transmission
00360  *
00361  * @v rndis             RNDIS device
00362  * @v iobuf             I/O buffer
00363  */
00364 static inline void rndis_tx_complete ( struct rndis_device *rndis,
00365                                        struct io_buffer *iobuf ) {
00366 
00367         rndis_tx_complete_err ( rndis, iobuf, 0 );
00368 }
00369 
00370 #endif /* _IPXE_RNDIS_H */