diff options
author | Michael Brown <mcb30@ipxe.org> | 2014-12-11 17:13:38 +0000 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2014-12-18 14:46:38 +0000 |
commit | 1d2b7c91f780419c805062ccc474967d80dafe96 (patch) | |
tree | 622c179cb8bd25dec8b3fe8ce2f4678829beb815 /src/include/ipxe/rndis.h | |
parent | c86b22221dd2aa787e2eae49d9d46287b8cf381e (diff) | |
download | ipxe-1d2b7c91f780419c805062ccc474967d80dafe96.tar.gz |
[rndis] Add generic RNDIS device abstraction
RNDIS provides an abstraction of a network device on top of a generic
packet transmission mechanism.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include/ipxe/rndis.h')
-rw-r--r-- | src/include/ipxe/rndis.h | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/src/include/ipxe/rndis.h b/src/include/ipxe/rndis.h new file mode 100644 index 000000000..60ffd10f5 --- /dev/null +++ b/src/include/ipxe/rndis.h @@ -0,0 +1,348 @@ +#ifndef _IPXE_RNDIS_H +#define _IPXE_RNDIS_H + +/** @file + * + * Remote Network Driver Interface Specification + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> +#include <ipxe/netdevice.h> +#include <ipxe/iobuf.h> + +/** Maximum time to wait for a transaction to complete + * + * This is a policy decision. + */ +#define RNDIS_MAX_WAIT_MS 1000 + +/** RNDIS message header */ +struct rndis_header { + /** Message type */ + uint32_t type; + /** Message length */ + uint32_t len; +} __attribute__ (( packed )); + +/** RNDIS initialise message */ +#define RNDIS_INITIALIZE_MSG 0x00000002UL + +/** RNDIS initialise message */ +struct rndis_initialize_message { + /** Request ID */ + uint32_t id; + /** Major version */ + uint32_t major; + /** Minor version */ + uint32_t minor; + /** Maximum transfer size */ + uint32_t mtu; +} __attribute__ (( packed )); + +/** RNDIS initialise completion */ +#define RNDIS_INITIALISE_CMPLT 0x80000002UL + +/** RNDIS initialise completion */ +struct rndis_initialise_completion { + /** Request ID */ + uint32_t id; + /** Status */ + uint32_t status; + /** Major version */ + uint32_t major; + /** Minor version */ + uint32_t minor; + /** Device flags */ + uint32_t flags; + /** Medium */ + uint32_t medium; + /** Maximum packets per transfer */ + uint32_t max_pkts; + /** Maximum transfer size */ + uint32_t mtu; + /** Packet alignment factor */ + uint32_t align; + /** Reserved */ + uint32_t reserved; +} __attribute__ (( packed )); + +/** RNDIS halt message */ +#define RNIS_HALT_MSG 0x00000003UL + +/** RNDIS halt message */ +struct rndis_halt_message { + /** Request ID */ + uint32_t id; +} __attribute__ (( packed )); + +/** RNDIS query OID message */ +#define RNDIS_QUERY_MSG 0x00000004UL + +/** RNDIS set OID message */ +#define RNDIS_SET_MSG 0x00000005UL + +/** RNDIS query or set OID message */ +struct rndis_oid_message { + /** Request ID */ + uint32_t id; + /** Object ID */ + uint32_t oid; + /** Information buffer length */ + uint32_t len; + /** Information buffer offset */ + uint32_t offset; + /** Reserved */ + uint32_t reserved; +} __attribute__ (( packed )); + +/** RNDIS query OID completion */ +#define RNDIS_QUERY_CMPLT 0x80000004UL + +/** RNDIS query OID completion */ +struct rndis_query_completion { + /** Request ID */ + uint32_t id; + /** Status */ + uint32_t status; + /** Information buffer length */ + uint32_t len; + /** Information buffer offset */ + uint32_t offset; +} __attribute__ (( packed )); + +/** RNDIS set OID completion */ +#define RNDIS_SET_CMPLT 0x80000005UL + +/** RNDIS set OID completion */ +struct rndis_set_completion { + /** Request ID */ + uint32_t id; + /** Status */ + uint32_t status; +} __attribute__ (( packed )); + +/** RNDIS reset message */ +#define RNDIS_RESET_MSG 0x00000006UL + +/** RNDIS reset message */ +struct rndis_reset_message { + /** Reserved */ + uint32_t reserved; +} __attribute__ (( packed )); + +/** RNDIS reset completion */ +#define RNDIS_RESET_CMPLT 0x80000006UL + +/** RNDIS reset completion */ +struct rndis_reset_completion { + /** Status */ + uint32_t status; + /** Addressing reset */ + uint32_t addr; +} __attribute__ (( packed )); + +/** RNDIS indicate status message */ +#define RNDIS_INDICATE_STATUS_MSG 0x00000007UL + +/** RNDIS diagnostic information */ +struct rndis_diagnostic_info { + /** Status */ + uint32_t status; + /** Error offset */ + uint32_t offset; +} __attribute__ (( packed )); + +/** RNDIS indicate status message */ +struct rndis_indicate_status_message { + /** Status */ + uint32_t status; + /** Status buffer length */ + uint32_t len; + /** Status buffer offset */ + uint32_t offset; + /** Diagnostic information (optional) */ + struct rndis_diagnostic_info diag[0]; +} __attribute__ (( packed )); + +/** RNDIS status codes */ +enum rndis_status { + /** Device is connected to a network medium */ + RNDIS_STATUS_MEDIA_CONNECT = 0x4001000bUL, + /** Device is disconnected from the medium */ + RNDIS_STATUS_MEDIA_DISCONNECT = 0x4001000cUL, +}; + +/** RNDIS keepalive message */ +#define RNDIS_KEEPALIVE_MSG 0x00000008UL + +/** RNDIS keepalive message */ +struct rndis_keepalive_message { + /** Request ID */ + uint32_t id; +} __attribute__ (( packed )); + +/** RNDIS keepalive completion */ +#define RNDIS_KEEPALIVE_CMPLT 0x80000008UL + +/** RNDIS keepalive completion */ +struct rndis_keepalive_completion { + /** Request ID */ + uint32_t id; + /** Status */ + uint32_t status; +} __attribute__ (( packed )); + +/** RNDIS packet message */ +#define RNDIS_PACKET_MSG 0x00000001UL + +/** RNDIS packet field */ +struct rndis_packet_field { + /** Offset */ + uint32_t offset; + /** Length */ + uint32_t len; +} __attribute__ (( packed )); + +/** RNDIS packet message */ +struct rndis_packet_message { + /** Data */ + struct rndis_packet_field data; + /** Out-of-band data records */ + struct rndis_packet_field oob; + /** Number of out-of-band data records */ + uint32_t oob_count; + /** Per-packet information record */ + struct rndis_packet_field ppi; + /** Reserved */ + uint32_t reserved; +} __attribute__ (( packed )); + +/** RNDIS packet record */ +struct rndis_packet_record { + /** Length */ + uint32_t len; + /** Type */ + uint32_t type; + /** Offset */ + uint32_t offset; +} __attribute__ (( packed )); + +/** OID for packet filter */ +#define RNDIS_OID_GEN_CURRENT_PACKET_FILTER 0x0001010eUL + +/** Packet filter bits */ +enum rndis_packet_filter { + /** Unicast packets */ + RNDIS_FILTER_UNICAST = 0x00000001UL, + /** Multicast packets */ + RNDIS_FILTER_MULTICAST = 0x00000002UL, + /** All multicast packets */ + RNDIS_FILTER_ALL_MULTICAST = 0x00000004UL, + /** Broadcast packets */ + RNDIS_FILTER_BROADCAST = 0x00000008UL, + /** All packets */ + RNDIS_FILTER_PROMISCUOUS = 0x00000020UL +}; + +/** OID for media status */ +#define RNDIS_OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL + +/** OID for permanent MAC address */ +#define RNDIS_OID_802_3_PERMANENT_ADDRESS 0x01010101UL + +/** OID for current MAC address */ +#define RNDIS_OID_802_3_CURRENT_ADDRESS 0x01010102UL + +struct rndis_device; + +/** RNDIS device operations */ +struct rndis_operations { + /** + * Open RNDIS device + * + * @v rndis RNDIS device + * @ret rc Return status code + */ + int ( * open ) ( struct rndis_device *rndis ); + /** + * Close RNDIS device + * + * @v rndis RNDIS device + */ + void ( * close ) ( struct rndis_device *rndis ); + /** + * Transmit packet + * + * @v rndis RNDIS device + * @v iobuf I/O buffer + * @ret rc Return status code + * + * If this method returns success then the RNDIS device must + * eventually report completion via rndis_tx_complete(). + */ + int ( * transmit ) ( struct rndis_device *rndis, + struct io_buffer *iobuf ); + /** + * Poll for completed and received packets + * + * @v rndis RNDIS device + */ + void ( * poll ) ( struct rndis_device *rndis ); +}; + +/** An RNDIS device */ +struct rndis_device { + /** Network device */ + struct net_device *netdev; + /** Device name */ + const char *name; + /** RNDIS operations */ + struct rndis_operations *op; + /** Driver private data */ + void *priv; + + /** Request ID for current blocking request */ + unsigned int wait_id; + /** Return status code for current blocking request */ + int wait_rc; +}; + +/** + * Initialise an RNDIS device + * + * @v rndis RNDIS device + * @v op RNDIS device operations + */ +static inline void rndis_init ( struct rndis_device *rndis, + struct rndis_operations *op ) { + + rndis->op = op; +} + +extern void rndis_tx_complete_err ( struct rndis_device *rndis, + struct io_buffer *iobuf, int rc ); +extern int rndis_tx_defer ( struct rndis_device *rndis, + struct io_buffer *iobuf ); +extern void rndis_rx ( struct rndis_device *rndis, struct io_buffer *iobuf ); + +extern struct rndis_device * alloc_rndis ( size_t priv_len ); +extern int register_rndis ( struct rndis_device *rndis ); +extern void unregister_rndis ( struct rndis_device *rndis ); +extern void free_rndis ( struct rndis_device *rndis ); + +/** + * Complete message transmission + * + * @v rndis RNDIS device + * @v iobuf I/O buffer + */ +static inline void rndis_tx_complete ( struct rndis_device *rndis, + struct io_buffer *iobuf ) { + + rndis_tx_complete_err ( rndis, iobuf, 0 ); +} + +#endif /* _IPXE_RNDIS_H */ |