aboutsummaryrefslogtreecommitdiffstats
path: root/gpxe/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'gpxe/src/include')
-rw-r--r--gpxe/src/include/assert.h2
-rw-r--r--gpxe/src/include/byteswap.h2
-rw-r--r--gpxe/src/include/compiler.h345
-rw-r--r--gpxe/src/include/console.h7
-rw-r--r--gpxe/src/include/ctype.h4
-rw-r--r--gpxe/src/include/curses.h2
-rw-r--r--gpxe/src/include/debug.h28
-rw-r--r--gpxe/src/include/dhcp.h12
-rw-r--r--gpxe/src/include/elf.h2
-rw-r--r--gpxe/src/include/endian.h2
-rw-r--r--gpxe/src/include/errno.h2
-rw-r--r--gpxe/src/include/etherboot.h2
-rw-r--r--gpxe/src/include/getopt.h2
-rw-r--r--gpxe/src/include/gpxe/acpi.h2
-rw-r--r--gpxe/src/include/gpxe/aes.h22
-rw-r--r--gpxe/src/include/gpxe/ansiesc.h2
-rw-r--r--gpxe/src/include/gpxe/aoe.h2
-rw-r--r--gpxe/src/include/gpxe/api.h2
-rw-r--r--gpxe/src/include/gpxe/arc4.h22
-rw-r--r--gpxe/src/include/gpxe/arp.h9
-rw-r--r--gpxe/src/include/gpxe/asn1.h2
-rw-r--r--gpxe/src/include/gpxe/ata.h4
-rw-r--r--gpxe/src/include/gpxe/base64.h2
-rw-r--r--gpxe/src/include/gpxe/bitbash.h2
-rw-r--r--gpxe/src/include/gpxe/bitmap.h2
-rw-r--r--gpxe/src/include/gpxe/bitops.h2
-rw-r--r--gpxe/src/include/gpxe/blockdev.h2
-rw-r--r--gpxe/src/include/gpxe/cbc.h2
-rw-r--r--gpxe/src/include/gpxe/chap.h2
-rw-r--r--gpxe/src/include/gpxe/command.h6
-rw-r--r--gpxe/src/include/gpxe/cpio.h2
-rw-r--r--gpxe/src/include/gpxe/crc32.h10
-rw-r--r--gpxe/src/include/gpxe/crypto.h8
-rw-r--r--gpxe/src/include/gpxe/device.h7
-rw-r--r--gpxe/src/include/gpxe/dhcp.h23
-rw-r--r--gpxe/src/include/gpxe/dhcpopts.h2
-rw-r--r--gpxe/src/include/gpxe/dhcppkt.h2
-rw-r--r--gpxe/src/include/gpxe/dns.h2
-rw-r--r--gpxe/src/include/gpxe/downloader.h2
-rw-r--r--gpxe/src/include/gpxe/eapol.h112
-rw-r--r--gpxe/src/include/gpxe/editbox.h2
-rw-r--r--gpxe/src/include/gpxe/editstring.h2
-rw-r--r--gpxe/src/include/gpxe/efi/efi.h21
-rw-r--r--gpxe/src/include/gpxe/efi/efi_io.h2
-rw-r--r--gpxe/src/include/gpxe/efi/efi_pci.h2
-rw-r--r--gpxe/src/include/gpxe/efi/efi_smbios.h2
-rw-r--r--gpxe/src/include/gpxe/efi/efi_timer.h2
-rw-r--r--gpxe/src/include/gpxe/efi/efi_uaccess.h2
-rw-r--r--gpxe/src/include/gpxe/efi/efi_umalloc.h2
-rw-r--r--gpxe/src/include/gpxe/eisa.h7
-rw-r--r--gpxe/src/include/gpxe/elf.h2
-rw-r--r--gpxe/src/include/gpxe/errfile.h29
-rw-r--r--gpxe/src/include/gpxe/errortab.h6
-rw-r--r--gpxe/src/include/gpxe/ethernet.h28
-rw-r--r--gpxe/src/include/gpxe/fakedhcp.h2
-rw-r--r--gpxe/src/include/gpxe/features.h14
-rw-r--r--gpxe/src/include/gpxe/filter.h2
-rw-r--r--gpxe/src/include/gpxe/ftp.h2
-rw-r--r--gpxe/src/include/gpxe/gdbserial.h2
-rw-r--r--gpxe/src/include/gpxe/gdbstub.h6
-rw-r--r--gpxe/src/include/gpxe/gdbudp.h2
-rw-r--r--gpxe/src/include/gpxe/hidemem.h2
-rw-r--r--gpxe/src/include/gpxe/hmac.h2
-rw-r--r--gpxe/src/include/gpxe/http.h2
-rw-r--r--gpxe/src/include/gpxe/i2c.h2
-rw-r--r--gpxe/src/include/gpxe/ib_cm.h72
-rw-r--r--gpxe/src/include/gpxe/ib_cmrc.h20
-rw-r--r--gpxe/src/include/gpxe/ib_mad.h205
-rw-r--r--gpxe/src/include/gpxe/ib_mcast.h48
-rw-r--r--gpxe/src/include/gpxe/ib_mi.h135
-rw-r--r--gpxe/src/include/gpxe/ib_packet.h14
-rw-r--r--gpxe/src/include/gpxe/ib_pathrec.h76
-rw-r--r--gpxe/src/include/gpxe/ib_sma.h59
-rw-r--r--gpxe/src/include/gpxe/ib_smc.h2
-rw-r--r--gpxe/src/include/gpxe/ib_srp.h79
-rw-r--r--gpxe/src/include/gpxe/icmp.h2
-rw-r--r--gpxe/src/include/gpxe/icmp6.h2
-rw-r--r--gpxe/src/include/gpxe/ieee80211.h1160
-rw-r--r--gpxe/src/include/gpxe/if_arp.h2
-rw-r--r--gpxe/src/include/gpxe/if_ether.h3
-rw-r--r--gpxe/src/include/gpxe/image.h8
-rw-r--r--gpxe/src/include/gpxe/in.h3
-rw-r--r--gpxe/src/include/gpxe/infiniband.h218
-rw-r--r--gpxe/src/include/gpxe/init.h13
-rw-r--r--gpxe/src/include/gpxe/interface.h2
-rw-r--r--gpxe/src/include/gpxe/io.h2
-rw-r--r--gpxe/src/include/gpxe/iobuf.h2
-rw-r--r--gpxe/src/include/gpxe/ip.h2
-rw-r--r--gpxe/src/include/gpxe/ip6.h2
-rw-r--r--gpxe/src/include/gpxe/ipoib.h31
-rw-r--r--gpxe/src/include/gpxe/isa.h7
-rw-r--r--gpxe/src/include/gpxe/isa_ids.h2
-rw-r--r--gpxe/src/include/gpxe/isapnp.h7
-rw-r--r--gpxe/src/include/gpxe/iscsi.h17
-rw-r--r--gpxe/src/include/gpxe/job.h4
-rw-r--r--gpxe/src/include/gpxe/keys.h2
-rw-r--r--gpxe/src/include/gpxe/linebuf.h2
-rw-r--r--gpxe/src/include/gpxe/linux_compat.h2
-rw-r--r--gpxe/src/include/gpxe/list.h2
-rw-r--r--gpxe/src/include/gpxe/login_ui.h2
-rw-r--r--gpxe/src/include/gpxe/malloc.h2
-rw-r--r--gpxe/src/include/gpxe/mca.h7
-rw-r--r--gpxe/src/include/gpxe/md5.h2
-rw-r--r--gpxe/src/include/gpxe/memmap.h2
-rw-r--r--gpxe/src/include/gpxe/monojob.h2
-rw-r--r--gpxe/src/include/gpxe/nap.h2
-rw-r--r--gpxe/src/include/gpxe/net80211.h1186
-rw-r--r--gpxe/src/include/gpxe/netdevice.h135
-rw-r--r--gpxe/src/include/gpxe/null_nap.h2
-rw-r--r--gpxe/src/include/gpxe/nvo.h2
-rw-r--r--gpxe/src/include/gpxe/nvs.h2
-rw-r--r--gpxe/src/include/gpxe/open.h14
-rw-r--r--gpxe/src/include/gpxe/pci.h52
-rw-r--r--gpxe/src/include/gpxe/pci_ids.h3
-rw-r--r--gpxe/src/include/gpxe/pci_io.h2
-rw-r--r--gpxe/src/include/gpxe/pcibackup.h33
-rw-r--r--gpxe/src/include/gpxe/posix_io.h2
-rw-r--r--gpxe/src/include/gpxe/process.h9
-rw-r--r--gpxe/src/include/gpxe/profile.h2
-rw-r--r--gpxe/src/include/gpxe/ramdisk.h2
-rw-r--r--gpxe/src/include/gpxe/rarp.h2
-rw-r--r--gpxe/src/include/gpxe/rc80211.h19
-rw-r--r--gpxe/src/include/gpxe/refcnt.h2
-rw-r--r--gpxe/src/include/gpxe/resolv.h8
-rw-r--r--gpxe/src/include/gpxe/retry.h2
-rw-r--r--gpxe/src/include/gpxe/rotate.h2
-rw-r--r--gpxe/src/include/gpxe/rsa.h2
-rw-r--r--gpxe/src/include/gpxe/sanboot.h10
-rw-r--r--gpxe/src/include/gpxe/scsi.h31
-rw-r--r--gpxe/src/include/gpxe/sec80211.h83
-rw-r--r--gpxe/src/include/gpxe/segment.h2
-rw-r--r--gpxe/src/include/gpxe/serial.h2
-rw-r--r--gpxe/src/include/gpxe/settings.h64
-rw-r--r--gpxe/src/include/gpxe/settings_ui.h2
-rw-r--r--gpxe/src/include/gpxe/sha1.h11
-rw-r--r--gpxe/src/include/gpxe/shell.h2
-rw-r--r--gpxe/src/include/gpxe/shell_banner.h2
-rw-r--r--gpxe/src/include/gpxe/smbios.h21
-rw-r--r--gpxe/src/include/gpxe/socket.h2
-rw-r--r--gpxe/src/include/gpxe/spi.h10
-rw-r--r--gpxe/src/include/gpxe/spi_bit.h2
-rw-r--r--gpxe/src/include/gpxe/srp.h868
-rw-r--r--gpxe/src/include/gpxe/tables.h263
-rw-r--r--gpxe/src/include/gpxe/tcp.h12
-rw-r--r--gpxe/src/include/gpxe/tcpip.h15
-rw-r--r--gpxe/src/include/gpxe/tftp.h2
-rw-r--r--gpxe/src/include/gpxe/threewire.h16
-rw-r--r--gpxe/src/include/gpxe/timer.h2
-rw-r--r--gpxe/src/include/gpxe/tls.h2
-rw-r--r--gpxe/src/include/gpxe/uaccess.h2
-rw-r--r--gpxe/src/include/gpxe/udp.h2
-rw-r--r--gpxe/src/include/gpxe/umalloc.h2
-rw-r--r--gpxe/src/include/gpxe/uri.h46
-rw-r--r--gpxe/src/include/gpxe/uuid.h2
-rw-r--r--gpxe/src/include/gpxe/vsprintf.h2
-rw-r--r--gpxe/src/include/gpxe/wpa.h503
-rw-r--r--gpxe/src/include/gpxe/x509.h2
-rw-r--r--gpxe/src/include/gpxe/xfer.h2
-rw-r--r--gpxe/src/include/hci/ifmgmt_cmd.h30
-rw-r--r--gpxe/src/include/igmp.h42
-rw-r--r--gpxe/src/include/lib.h42
-rw-r--r--gpxe/src/include/libgen.h2
-rw-r--r--gpxe/src/include/little_bswap.h2
-rw-r--r--gpxe/src/include/mii.h122
-rw-r--r--gpxe/src/include/nfs.h63
-rw-r--r--gpxe/src/include/nic.h4
-rw-r--r--gpxe/src/include/nmb.h22
-rw-r--r--gpxe/src/include/readline/readline.h2
-rw-r--r--gpxe/src/include/stdarg.h2
-rw-r--r--gpxe/src/include/stddef.h2
-rw-r--r--gpxe/src/include/stdint.h12
-rw-r--r--gpxe/src/include/stdio.h2
-rw-r--r--gpxe/src/include/stdlib.h2
-rw-r--r--gpxe/src/include/string.h2
-rw-r--r--gpxe/src/include/strings.h2
-rw-r--r--gpxe/src/include/unistd.h2
-rw-r--r--gpxe/src/include/usr/autoboot.h6
-rw-r--r--gpxe/src/include/usr/dhcpmgmt.h2
-rw-r--r--gpxe/src/include/usr/ifmgmt.h2
-rw-r--r--gpxe/src/include/usr/imgmgmt.h2
-rw-r--r--gpxe/src/include/usr/iwmgmt.h17
-rw-r--r--gpxe/src/include/usr/route.h2
182 files changed, 6324 insertions, 576 deletions
diff --git a/gpxe/src/include/assert.h b/gpxe/src/include/assert.h
index 93750a1e..cc784bc1 100644
--- a/gpxe/src/include/assert.h
+++ b/gpxe/src/include/assert.h
@@ -10,6 +10,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifdef NDEBUG
#define ASSERTING 0
#else
diff --git a/gpxe/src/include/byteswap.h b/gpxe/src/include/byteswap.h
index 6c3ced25..466759cf 100644
--- a/gpxe/src/include/byteswap.h
+++ b/gpxe/src/include/byteswap.h
@@ -1,6 +1,8 @@
#ifndef ETHERBOOT_BYTESWAP_H
#define ETHERBOOT_BYTESWAP_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include "endian.h"
#include "bits/byteswap.h"
diff --git a/gpxe/src/include/compiler.h b/gpxe/src/include/compiler.h
index 889c2404..ea81fc89 100644
--- a/gpxe/src/include/compiler.h
+++ b/gpxe/src/include/compiler.h
@@ -24,51 +24,201 @@
*
*/
-/* Not quite sure why cpp requires two levels of macro call in order
- * to actually expand OBJECT...
- */
-#undef _H1
-#define _H1( x, y ) x ## y
-#undef _H2
-#define _H2( x, y ) _H1 ( x, y )
-#define PREFIX_OBJECT(prefix) _H2 ( prefix, OBJECT )
-#define OBJECT_SYMBOL PREFIX_OBJECT(obj_)
-#undef _STR
-#define _STR(s) #s
-#undef _XSTR
-#define _XSTR(s) _STR(s)
-#define OBJECT_SYMBOL_STR _XSTR ( OBJECT_SYMBOL )
+/* Force visibility of all symbols to "hidden", i.e. inform gcc that
+ * all symbol references resolve strictly within our final binary.
+ * This avoids unnecessary PLT/GOT entries on x86_64.
+ *
+ * This is a stronger claim than specifying "-fvisibility=hidden",
+ * since it also affects symbols marked with "extern".
+ */
+#ifndef ASSEMBLY
+#if __GNUC__ >= 4
+#pragma GCC visibility push(hidden)
+#endif
+#endif /* ASSEMBLY */
+
+#undef _S1
+#undef _S2
+#undef _C1
+#undef _C2
+
+/** Concatenate non-expanded arguments */
+#define _C1( x, y ) x ## y
+/** Concatenate expanded arguments */
+#define _C2( x, y ) _C1 ( x, y )
+
+/** Stringify non-expanded argument */
+#define _S1( x ) #x
+/** Stringify expanded argument */
+#define _S2( x ) _S1 ( x )
+
+/**
+ * @defgroup symmacros Macros to provide or require explicit symbols
+ * @{
+ */
+/** Provide a symbol within this object file */
#ifdef ASSEMBLY
+#define PROVIDE_SYMBOL( _sym ) \
+ .globl _sym ; \
+ .comm _sym, 0
+#else /* ASSEMBLY */
+#define PROVIDE_SYMBOL( _sym ) \
+ char _sym[0]
+#endif /* ASSEMBLY */
- .globl OBJECT_SYMBOL
- .equ OBJECT_SYMBOL, 0
+/** Require a symbol within this object file
+ *
+ * The symbol is referenced by a relocation in a discarded section, so
+ * if it is not available at link time the link will fail.
+ */
+#ifdef ASSEMBLY
+#define REQUIRE_SYMBOL( _sym ) \
+ .section ".discard", "a", @progbits ; \
+ .extern _sym ; \
+ .long _sym ; \
+ .previous
+#else /* ASSEMBLY */
+#define REQUIRE_SYMBOL( _sym ) \
+ extern char _sym; \
+ static char * _C2 ( _C2 ( __require_, _sym ), _C2 ( _, __LINE__ ) ) \
+ __attribute__ (( section ( ".discard" ), used )) \
+ = &_sym
+#endif
+/** Request that a symbol be available at runtime
+ *
+ * The requested symbol is entered as undefined into the symbol table
+ * for this object, so the linker will pull in other object files as
+ * necessary to satisfy the reference. However, the undefined symbol
+ * is not referenced in any relocations, so the link can still succeed
+ * if no file contains it.
+ *
+ * A symbol passed to this macro may not be referenced anywhere
+ * else in the file. If you want to do that, see IMPORT_SYMBOL().
+ */
+#ifdef ASSEMBLY
+#define REQUEST_SYMBOL( _sym ) \
+ .equ __need_ ## _sym, _sym
#else /* ASSEMBLY */
+#define REQUEST_SYMBOL( _sym ) \
+ __asm__ ( ".equ\t__need_" #_sym ", " #_sym )
+#endif /* ASSEMBLY */
-__asm__ ( ".globl\t" OBJECT_SYMBOL_STR );
-__asm__ ( ".equ\t" OBJECT_SYMBOL_STR ", 0" );
+/** Set up a symbol to be usable in another file by IMPORT_SYMBOL()
+ *
+ * The symbol must already be marked as global.
+ */
+#define EXPORT_SYMBOL( _sym ) PROVIDE_SYMBOL ( __export_ ## _sym )
+
+/** Make a symbol usable to this file if available at link time
+ *
+ * If no file passed to the linker contains the symbol, it will have
+ * @c NULL value to future uses. Keep in mind that the symbol value is
+ * really the @e address of a variable or function; see the code
+ * snippet below.
+ *
+ * In C using IMPORT_SYMBOL, you must specify the declaration as the
+ * second argument, for instance
+ *
+ * @code
+ * IMPORT_SYMBOL ( my_func, int my_func ( int arg ) );
+ * IMPORT_SYMBOL ( my_var, int my_var );
+ *
+ * void use_imports ( void ) {
+ * if ( my_func && &my_var )
+ * my_var = my_func ( my_var );
+ * }
+ * @endcode
+ *
+ * GCC considers a weak declaration to override a strong one no matter
+ * which comes first, so it is safe to include a header file declaring
+ * the imported symbol normally, but providing the declaration to
+ * IMPORT_SYMBOL is still required.
+ *
+ * If no EXPORT_SYMBOL declaration exists for the imported symbol in
+ * another file, the behavior will be most likely be identical to that
+ * for an unavailable symbol.
+ */
+#ifdef ASSEMBLY
+#define IMPORT_SYMBOL( _sym ) \
+ REQUEST_SYMBOL ( __export_ ## _sym ) ; \
+ .weak _sym
+#else /* ASSEMBLY */
+#define IMPORT_SYMBOL( _sym, _decl ) \
+ REQUEST_SYMBOL ( __export_ ## _sym ) ; \
+ extern _decl __attribute__ (( weak ))
+#endif
+
+/** @} */
/**
- * Drag in an object by object name.
+ * @defgroup objmacros Macros to provide or require explicit objects
+ * @{
+ */
+
+#define PREFIX_OBJECT( _prefix ) _C2 ( _prefix, OBJECT )
+#define OBJECT_SYMBOL PREFIX_OBJECT ( obj_ )
+#define REQUEST_EXPANDED( _sym ) REQUEST_SYMBOL ( _sym )
+#define CONFIG_SYMBOL PREFIX_OBJECT ( obj_config_ )
+
+/** Always provide the symbol for the current object (defined by -DOBJECT) */
+PROVIDE_SYMBOL ( OBJECT_SYMBOL );
+
+/** Pull in an object-specific configuration file if available */
+REQUEST_EXPANDED ( CONFIG_SYMBOL );
+
+/** Explicitly require another object */
+#define REQUIRE_OBJECT( _obj ) REQUIRE_SYMBOL ( obj_ ## _obj )
+
+/** Pull in another object if it exists */
+#define REQUEST_OBJECT( _obj ) REQUEST_SYMBOL ( obj_ ## _obj )
+
+/** @} */
+
+/** Select file identifier for errno.h (if used) */
+#define ERRFILE PREFIX_OBJECT ( ERRFILE_ )
+
+/**
+ * @defgroup weakmacros Macros to manage weak symbol definitions
*
- * Macro to allow objects to explicitly drag in other objects by
- * object name. Used by config.c.
+ * Weak symbols allow one to reference a function in another file
+ * without necessarily requiring that file to be linked in. In their
+ * native form, the function will be @c NULL if its file is not linked
+ * in; these macros provide an inline wrapper that returns an
+ * appropriate error indication or default value.
*
+ * @{
*/
-#define REQUIRE_OBJECT(object) \
- __asm__ ( ".equ\tneed_" #object ", obj_" #object );
+#ifndef ASSEMBLY
-/* Force visibility of all symbols to "hidden", i.e. inform gcc that
- * all symbol references resolve strictly within our final binary.
- * This avoids unnecessary PLT/GOT entries on x86_64.
+/** Mangle @a name into its weakly-referenced implementation */
+#define __weak_impl( name ) _w_ ## name
+
+/**
+ * Declare a weak function with inline safety wrapper
*
- * This is a stronger claim than specifying "-fvisibility=hidden",
- * since it also affects symbols marked with "extern".
+ * @v ret Return type of weak function
+ * @v name Name of function to expose
+ * @v proto Parenthesized list of arguments with types
+ * @v args Parenthesized list of argument names
+ * @v dfl Value to return if weak function is not available
*/
-#if __GNUC__ >= 4
-#pragma GCC visibility push(hidden)
+#define __weak_decl( ret, name, proto, args, dfl ) \
+ ret __weak_impl( name ) proto __attribute__ (( weak )); \
+ static inline ret name proto { \
+ if ( __weak_impl( name ) ) \
+ return __weak_impl( name ) args; \
+ return dfl; \
+ }
+
#endif
+/** @} */
+
+/** @defgroup dbg Debugging infrastructure
+ * @{
+ */
+#ifndef ASSEMBLY
/** @def DBG
*
@@ -117,12 +267,7 @@ __asm__ ( ".equ\t" OBJECT_SYMBOL_STR ", 0" );
* DEBUG_LEVEL will be inserted into the object file.
*
*/
-#define DEBUG_SYMBOL PREFIX_OBJECT(debug_)
-
-#if DEBUG_SYMBOL
-#define DEBUG_SYMBOL_STR _XSTR ( DEBUG_SYMBOL )
-__asm__ ( ".equ\tDBGLVL, " DEBUG_SYMBOL_STR );
-#endif
+#define DEBUG_SYMBOL PREFIX_OBJECT ( debug_ )
/** printf() for debugging
*
@@ -212,7 +357,8 @@ int __debug_disable;
* @v len Length of data
*/
#define DBG_HD_IF( level, data, len ) do { \
- DBG_HDA_IF ( level, data, data, len ); \
+ const void *_data = data; \
+ DBG_HDA_IF ( level, _data, _data, len ); \
} while ( 0 )
/**
@@ -304,8 +450,13 @@ int __debug_disable;
#define NDEBUG
#endif
-/** Select file identifier for errno.h (if used) */
-#define ERRFILE PREFIX_OBJECT ( ERRFILE_ )
+#endif /* ASSEMBLY */
+/** @} */
+
+/** @defgroup attrs Miscellaneous attributes
+ * @{
+ */
+#ifndef ASSEMBLY
/** Declare a data structure as packed. */
#define PACKED __attribute__ (( packed ))
@@ -373,13 +524,127 @@ int __debug_disable;
*/
#define __shared __asm__ ( "_shared_bss" ) __aligned
+#endif /* ASSEMBLY */
+/** @} */
+
/**
* Optimisation barrier
*/
+#ifndef ASSEMBLY
#define barrier() __asm__ __volatile__ ( "" : : : "memory" )
-
#endif /* ASSEMBLY */
+/**
+ * @defgroup licences Licence declarations
+ *
+ * For reasons that are partly historical, various different files
+ * within the gPXE codebase have differing licences.
+ *
+ * @{
+ */
+
+/** Declare a file as being in the public domain
+ *
+ * This licence declaration is applicable when a file states itself to
+ * be in the public domain.
+ */
+#define FILE_LICENCE_PUBLIC_DOMAIN \
+ PROVIDE_SYMBOL ( __licence_public_domain )
+
+/** Declare a file as being under version 2 (or later) of the GNU GPL
+ *
+ * This licence declaration is applicable when a file states itself to
+ * be licensed under the GNU GPL; "either version 2 of the License, or
+ * (at your option) any later version".
+ */
+#define FILE_LICENCE_GPL2_OR_LATER \
+ PROVIDE_SYMBOL ( __licence_gpl2_or_later )
+
+/** Declare a file as being under version 2 of the GNU GPL
+ *
+ * This licence declaration is applicable when a file states itself to
+ * be licensed under version 2 of the GPL, and does not include the
+ * "or, at your option, any later version" clause.
+ */
+#define FILE_LICENCE_GPL2_ONLY \
+ PROVIDE_SYMBOL ( __licence_gpl2_only )
+
+/** Declare a file as being under any version of the GNU GPL
+ *
+ * This licence declaration is applicable when a file states itself to
+ * be licensed under the GPL, but does not specify a version.
+ *
+ * According to section 9 of the GPLv2, "If the Program does not
+ * specify a version number of this License, you may choose any
+ * version ever published by the Free Software Foundation".
+ */
+#define FILE_LICENCE_GPL_ANY \
+ PROVIDE_SYMBOL ( __licence_gpl_any )
+
+/** Declare a file as being under the three-clause BSD licence
+ *
+ * This licence declaration is applicable when a file states itself to
+ * be licensed under terms allowing redistribution in source and
+ * binary forms (with or without modification) provided that:
+ *
+ * redistributions of source code retain the copyright notice,
+ * list of conditions and any attached disclaimers
+ *
+ * redistributions in binary form reproduce the copyright notice,
+ * list of conditions and any attached disclaimers in the
+ * documentation and/or other materials provided with the
+ * distribution
+ *
+ * the name of the author is not used to endorse or promote
+ * products derived from the software without specific prior
+ * written permission
+ *
+ * It is not necessary for the file to explicitly state that it is
+ * under a "BSD" licence; only that the licensing terms be
+ * functionally equivalent to the standard three-clause BSD licence.
+ */
+#define FILE_LICENCE_BSD3 \
+ PROVIDE_SYMBOL ( __licence_bsd3 )
+
+/** Declare a file as being under the two-clause BSD licence
+ *
+ * This licence declaration is applicable when a file states itself to
+ * be licensed under terms allowing redistribution in source and
+ * binary forms (with or without modification) provided that:
+ *
+ * redistributions of source code retain the copyright notice,
+ * list of conditions and any attached disclaimers
+ *
+ * redistributions in binary form reproduce the copyright notice,
+ * list of conditions and any attached disclaimers in the
+ * documentation and/or other materials provided with the
+ * distribution
+ *
+ * It is not necessary for the file to explicitly state that it is
+ * under a "BSD" licence; only that the licensing terms be
+ * functionally equivalent to the standard two-clause BSD licence.
+ */
+#define FILE_LICENCE_BSD2 \
+ PROVIDE_SYMBOL ( __licence_bsd2 )
+
+/** Declare a file as being under the one-clause MIT-style licence
+ *
+ * This licence declaration is applicable when a file states itself to
+ * be licensed under terms allowing redistribution for any purpose
+ * with or without fee, provided that the copyright notice and
+ * permission notice appear in all copies.
+ */
+#define FILE_LICENCE_MIT \
+ PROVIDE_SYMBOL ( __licence_mit )
+
+/** Declare a particular licence as applying to a file */
+#define FILE_LICENCE( _licence ) FILE_LICENCE_ ## _licence
+
+/** @} */
+
+/* This file itself is under GPLv2-or-later */
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <bits/compiler.h>
#endif /* COMPILER_H */
diff --git a/gpxe/src/include/console.h b/gpxe/src/include/console.h
index 9addd526..62fedf5b 100644
--- a/gpxe/src/include/console.h
+++ b/gpxe/src/include/console.h
@@ -14,6 +14,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/**
* A console driver
*
@@ -85,6 +87,9 @@ struct console_driver {
int ( *iskey ) ( void );
};
+/** Console driver table */
+#define CONSOLES __table ( struct console_driver, "consoles" )
+
/**
* Mark a <tt> struct console_driver </tt> as being part of the
* console drivers table.
@@ -102,7 +107,7 @@ struct console_driver {
* @endcode
*
*/
-#define __console_driver __table ( struct console_driver, console, 01 )
+#define __console_driver __table_entry ( CONSOLES, 01 )
/* Function prototypes */
diff --git a/gpxe/src/include/ctype.h b/gpxe/src/include/ctype.h
index 7740443d..ed4d8846 100644
--- a/gpxe/src/include/ctype.h
+++ b/gpxe/src/include/ctype.h
@@ -6,6 +6,8 @@
* Character types
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#define isdigit(c) ((c) >= '0' && (c) <= '9')
#define islower(c) ((c) >= 'a' && (c) <= 'z')
#define isupper(c) ((c) >= 'A' && (c) <= 'Z')
@@ -24,4 +26,6 @@ static inline unsigned char toupper(unsigned char c)
return c;
}
+extern int isspace ( int c );
+
#endif /* _CTYPE_H */
diff --git a/gpxe/src/include/curses.h b/gpxe/src/include/curses.h
index 6b1c42d8..e2c5af23 100644
--- a/gpxe/src/include/curses.h
+++ b/gpxe/src/include/curses.h
@@ -10,6 +10,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#undef ERR
#define ERR (-1)
diff --git a/gpxe/src/include/debug.h b/gpxe/src/include/debug.h
deleted file mode 100644
index bb5d33f3..00000000
--- a/gpxe/src/include/debug.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef DEBUG_H
-#define DEBUG_H
-
-//#include <lib.h>
-extern int last_putchar;
-
-/* Defining DEBUG_THIS before including this file enables debug() macro
- * for the file. DEBUG_ALL is for global control. */
-
-#if DEBUG_THIS || DEBUG_ALL
-#define DEBUG 1
-#else
-#undef DEBUG
-#endif
-
-#if DEBUG
-# define debug(...) \
- ((last_putchar=='\n' ? printf("%s: ", __FUNCTION__) : 0), \
- printf(__VA_ARGS__))
-# define debug_hexdump hexdump
-#else
-# define debug(...) /* nothing */
-# define debug_hexdump(...) /* nothing */
-#endif
-
-#define debugx debug
-
-#endif /* DEBUG_H */
diff --git a/gpxe/src/include/dhcp.h b/gpxe/src/include/dhcp.h
deleted file mode 100644
index deba219b..00000000
--- a/gpxe/src/include/dhcp.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef DHCP_H
-#define DHCP_H
-
-#include "stdint.h"
-
-struct dhcp_dev_id {
- uint8_t bus_type;
- uint16_t vendor_id;
- uint16_t device_id;
-} __attribute__ (( packed ));
-
-#endif /* DHCP_H */
diff --git a/gpxe/src/include/elf.h b/gpxe/src/include/elf.h
index fadc0bdb..04022b68 100644
--- a/gpxe/src/include/elf.h
+++ b/gpxe/src/include/elf.h
@@ -1,6 +1,8 @@
#ifndef ELF_H
#define ELF_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#define EI_NIDENT 16 /* Size of e_ident array. */
/* Values for e_type. */
diff --git a/gpxe/src/include/endian.h b/gpxe/src/include/endian.h
index 32006224..9682cf9b 100644
--- a/gpxe/src/include/endian.h
+++ b/gpxe/src/include/endian.h
@@ -1,6 +1,8 @@
#ifndef ETHERBOOT_ENDIAN_H
#define ETHERBOOT_ENDIAN_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
/* Definitions for byte order, according to significance of bytes,
from low addresses to high addresses. The value is what you get by
putting '4' in the most significant byte, '3' in the second most
diff --git a/gpxe/src/include/errno.h b/gpxe/src/include/errno.h
index 58dff1fd..56095ecb 100644
--- a/gpxe/src/include/errno.h
+++ b/gpxe/src/include/errno.h
@@ -1,6 +1,8 @@
#ifndef ERRNO_H
#define ERRNO_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
/** @file
*
* Error codes
diff --git a/gpxe/src/include/etherboot.h b/gpxe/src/include/etherboot.h
index 2a465954..ad44e8a9 100644
--- a/gpxe/src/include/etherboot.h
+++ b/gpxe/src/include/etherboot.h
@@ -6,6 +6,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
diff --git a/gpxe/src/include/getopt.h b/gpxe/src/include/getopt.h
index 2505223e..0fe43567 100644
--- a/gpxe/src/include/getopt.h
+++ b/gpxe/src/include/getopt.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stddef.h>
enum getopt_argument_requirement {
diff --git a/gpxe/src/include/gpxe/acpi.h b/gpxe/src/include/gpxe/acpi.h
index 33b1b2b7..12edda90 100644
--- a/gpxe/src/include/gpxe/acpi.h
+++ b/gpxe/src/include/gpxe/acpi.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
/**
diff --git a/gpxe/src/include/gpxe/aes.h b/gpxe/src/include/gpxe/aes.h
index bdb4b351..fc1694b3 100644
--- a/gpxe/src/include/gpxe/aes.h
+++ b/gpxe/src/include/gpxe/aes.h
@@ -1,8 +1,30 @@
#ifndef _GPXE_AES_H
#define _GPXE_AES_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
struct cipher_algorithm;
+/** Basic AES blocksize */
+#define AES_BLOCKSIZE 16
+
+#include "crypto/axtls/crypto.h"
+
+/** AES context */
+struct aes_context {
+ /** AES context for AXTLS */
+ AES_CTX axtls_ctx;
+ /** Cipher is being used for decrypting */
+ int decrypting;
+};
+
+/** AES context size */
+#define AES_CTX_SIZE sizeof ( struct aes_context )
+
+extern struct cipher_algorithm aes_algorithm;
extern struct cipher_algorithm aes_cbc_algorithm;
+int aes_wrap ( const void *kek, const void *src, void *dest, int nblk );
+int aes_unwrap ( const void *kek, const void *src, void *dest, int nblk );
+
#endif /* _GPXE_AES_H */
diff --git a/gpxe/src/include/gpxe/ansiesc.h b/gpxe/src/include/gpxe/ansiesc.h
index ccc4ca65..85f7a9f3 100644
--- a/gpxe/src/include/gpxe/ansiesc.h
+++ b/gpxe/src/include/gpxe/ansiesc.h
@@ -26,6 +26,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/** A handler for an escape sequence */
struct ansiesc_handler {
/** The control function identifier
diff --git a/gpxe/src/include/gpxe/aoe.h b/gpxe/src/include/gpxe/aoe.h
index 6de6b965..6b42fd5b 100644
--- a/gpxe/src/include/gpxe/aoe.h
+++ b/gpxe/src/include/gpxe/aoe.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/list.h>
#include <gpxe/if_ether.h>
diff --git a/gpxe/src/include/gpxe/api.h b/gpxe/src/include/gpxe/api.h
index df5d1ae3..ff2ba595 100644
--- a/gpxe/src/include/gpxe/api.h
+++ b/gpxe/src/include/gpxe/api.h
@@ -11,6 +11,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/** @defgroup Single-implementation APIs
*
* These are APIs for which only a single implementation may be
diff --git a/gpxe/src/include/gpxe/arc4.h b/gpxe/src/include/gpxe/arc4.h
new file mode 100644
index 00000000..9917628a
--- /dev/null
+++ b/gpxe/src/include/gpxe/arc4.h
@@ -0,0 +1,22 @@
+#ifndef _GPXE_ARC4_H
+#define _GPXE_ARC4_H
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+struct cipher_algorithm;
+
+#include <stdint.h>
+
+struct arc4_ctx {
+ int i, j;
+ u8 state[256];
+};
+
+#define ARC4_CTX_SIZE sizeof ( struct arc4_ctx )
+
+extern struct cipher_algorithm arc4_algorithm;
+
+void arc4_skip ( const void *key, size_t keylen, size_t skip,
+ const void *src, void *dst, size_t msglen );
+
+#endif /* _GPXE_ARC4_H */
diff --git a/gpxe/src/include/gpxe/arp.h b/gpxe/src/include/gpxe/arp.h
index 6464ce0c..0623d35c 100644
--- a/gpxe/src/include/gpxe/arp.h
+++ b/gpxe/src/include/gpxe/arp.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/tables.h>
struct net_device;
@@ -26,9 +28,12 @@ struct arp_net_protocol {
const void *net_addr );
};
+/** ARP protocol table */
+#define ARP_NET_PROTOCOLS \
+ __table ( struct arp_net_protocol, "arp_net_protocols" )
+
/** Declare an ARP protocol */
-#define __arp_net_protocol \
- __table ( struct arp_net_protocol, arp_net_protocols, 01 )
+#define __arp_net_protocol __table_entry ( ARP_NET_PROTOCOLS, 01 )
extern struct net_protocol arp_protocol;
diff --git a/gpxe/src/include/gpxe/asn1.h b/gpxe/src/include/gpxe/asn1.h
index 5440c48c..477c209d 100644
--- a/gpxe/src/include/gpxe/asn1.h
+++ b/gpxe/src/include/gpxe/asn1.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#define ASN1_INTEGER 0x02
#define ASN1_BIT_STRING 0x03
#define ASN1_OCTET_STRING 0x04
diff --git a/gpxe/src/include/gpxe/ata.h b/gpxe/src/include/gpxe/ata.h
index b6da3930..3c565844 100644
--- a/gpxe/src/include/gpxe/ata.h
+++ b/gpxe/src/include/gpxe/ata.h
@@ -12,6 +12,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/**
* An ATA Logical Block Address
*
@@ -152,6 +154,8 @@ struct ata_command {
* sectors in size.
*/
userptr_t data_in;
+ /** Command status code */
+ int rc;
};
/**
diff --git a/gpxe/src/include/gpxe/base64.h b/gpxe/src/include/gpxe/base64.h
index 3321971a..e38bef01 100644
--- a/gpxe/src/include/gpxe/base64.h
+++ b/gpxe/src/include/gpxe/base64.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
/**
diff --git a/gpxe/src/include/gpxe/bitbash.h b/gpxe/src/include/gpxe/bitbash.h
index 62bdce00..f2ba9f7a 100644
--- a/gpxe/src/include/gpxe/bitbash.h
+++ b/gpxe/src/include/gpxe/bitbash.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
struct bit_basher;
/** Bit-bashing operations */
diff --git a/gpxe/src/include/gpxe/bitmap.h b/gpxe/src/include/gpxe/bitmap.h
index 0c2f53c8..d6911a51 100644
--- a/gpxe/src/include/gpxe/bitmap.h
+++ b/gpxe/src/include/gpxe/bitmap.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
diff --git a/gpxe/src/include/gpxe/bitops.h b/gpxe/src/include/gpxe/bitops.h
index 5405c854..8db34312 100644
--- a/gpxe/src/include/gpxe/bitops.h
+++ b/gpxe/src/include/gpxe/bitops.h
@@ -19,6 +19,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/**
* @file
*
diff --git a/gpxe/src/include/gpxe/blockdev.h b/gpxe/src/include/gpxe/blockdev.h
index 8222984a..cf28524d 100644
--- a/gpxe/src/include/gpxe/blockdev.h
+++ b/gpxe/src/include/gpxe/blockdev.h
@@ -8,6 +8,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/uaccess.h>
struct block_device;
diff --git a/gpxe/src/include/gpxe/cbc.h b/gpxe/src/include/gpxe/cbc.h
index fcc115eb..1262f1db 100644
--- a/gpxe/src/include/gpxe/cbc.h
+++ b/gpxe/src/include/gpxe/cbc.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/crypto.h>
/**
diff --git a/gpxe/src/include/gpxe/chap.h b/gpxe/src/include/gpxe/chap.h
index 87e5484f..e86ede35 100644
--- a/gpxe/src/include/gpxe/chap.h
+++ b/gpxe/src/include/gpxe/chap.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/md5.h>
diff --git a/gpxe/src/include/gpxe/command.h b/gpxe/src/include/gpxe/command.h
index 5d8057ab..51ca6d6d 100644
--- a/gpxe/src/include/gpxe/command.h
+++ b/gpxe/src/include/gpxe/command.h
@@ -1,6 +1,8 @@
#ifndef _GPXE_COMMAND_H
#define _GPXE_COMMAND_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/tables.h>
/** A command-line command */
@@ -17,6 +19,8 @@ struct command {
int ( * exec ) ( int argc, char **argv );
};
-#define __command __table ( struct command, commands, 01 )
+#define COMMANDS __table ( struct command, "commands" )
+
+#define __command __table_entry ( COMMANDS, 01 )
#endif /* _GPXE_COMMAND_H */
diff --git a/gpxe/src/include/gpxe/cpio.h b/gpxe/src/include/gpxe/cpio.h
index ba6f844a..f462cec1 100644
--- a/gpxe/src/include/gpxe/cpio.h
+++ b/gpxe/src/include/gpxe/cpio.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/** A CPIO archive header
*
* All field are hexadecimal ASCII numbers padded with '0' on the
diff --git a/gpxe/src/include/gpxe/crc32.h b/gpxe/src/include/gpxe/crc32.h
new file mode 100644
index 00000000..d1c7437d
--- /dev/null
+++ b/gpxe/src/include/gpxe/crc32.h
@@ -0,0 +1,10 @@
+#ifndef _GPXE_CRC32_H
+#define _GPXE_CRC32_H
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdint.h>
+
+u32 crc32_le ( u32 seed, const void *data, size_t len );
+
+#endif
diff --git a/gpxe/src/include/gpxe/crypto.h b/gpxe/src/include/gpxe/crypto.h
index 10882d37..ecda5f6d 100644
--- a/gpxe/src/include/gpxe/crypto.h
+++ b/gpxe/src/include/gpxe/crypto.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <stddef.h>
@@ -127,7 +129,7 @@ static inline void cipher_encrypt ( struct cipher_algorithm *cipher,
cipher->encrypt ( ctx, src, dst, len );
}
#define cipher_encrypt( cipher, ctx, src, dst, len ) do { \
- assert ( ( len & ( (cipher)->blocksize - 1 ) ) == 0 ); \
+ assert ( ( (len) & ( (cipher)->blocksize - 1 ) ) == 0 ); \
cipher_encrypt ( (cipher), (ctx), (src), (dst), (len) ); \
} while ( 0 )
@@ -137,7 +139,7 @@ static inline void cipher_decrypt ( struct cipher_algorithm *cipher,
cipher->decrypt ( ctx, src, dst, len );
}
#define cipher_decrypt( cipher, ctx, src, dst, len ) do { \
- assert ( ( len & ( (cipher)->blocksize - 1 ) ) == 0 ); \
+ assert ( ( (len) & ( (cipher)->blocksize - 1 ) ) == 0 ); \
cipher_decrypt ( (cipher), (ctx), (src), (dst), (len) ); \
} while ( 0 )
@@ -149,4 +151,6 @@ extern struct digest_algorithm digest_null;
extern struct cipher_algorithm cipher_null;
extern struct pubkey_algorithm pubkey_null;
+void get_random_bytes ( void *buf, size_t len );
+
#endif /* _GPXE_CRYPTO_H */
diff --git a/gpxe/src/include/gpxe/device.h b/gpxe/src/include/gpxe/device.h
index f40cc95a..1db3ff90 100644
--- a/gpxe/src/include/gpxe/device.h
+++ b/gpxe/src/include/gpxe/device.h
@@ -8,6 +8,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/list.h>
#include <gpxe/tables.h>
@@ -102,7 +104,10 @@ struct root_driver {
void ( * remove ) ( struct root_device *rootdev );
};
+/** Root device table */
+#define ROOT_DEVICES __table ( struct root_device, "root_devices" )
+
/** Declare a root device */
-#define __root_device __table ( struct root_device, root_devices, 01 )
+#define __root_device __table_entry ( ROOT_DEVICES, 01 )
#endif /* _GPXE_DEVICE_H */
diff --git a/gpxe/src/include/gpxe/dhcp.h b/gpxe/src/include/gpxe/dhcp.h
index 33e0c5d4..ebfe8ede 100644
--- a/gpxe/src/include/gpxe/dhcp.h
+++ b/gpxe/src/include/gpxe/dhcp.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/in.h>
#include <gpxe/list.h>
@@ -14,6 +16,7 @@
#include <gpxe/tables.h>
#include <gpxe/uuid.h>
#include <gpxe/netdevice.h>
+#include <gpxe/uaccess.h>
struct job_interface;
struct dhcp_options;
@@ -330,6 +333,16 @@ struct dhcp_netdev_desc {
uint16_t device;
} __attribute__ (( packed ));
+/** Use cached network settings
+ *
+ * Cached network settings may be available from a prior DHCP request
+ * (if running as a PXE NBP), non-volatile storage on the NIC, or
+ * settings set via the command line or an embedded image. If this
+ * flag is not set, it will be assumed that those sources are
+ * insufficient and that DHCP should still be run when autobooting.
+ */
+#define DHCP_EB_USE_CACHED DHCP_ENCAP_OPT ( DHCP_EB_ENCAP, 0xb2 )
+
/** BIOS drive number
*
* This is the drive number for a drive emulated via INT 13. 0x80 is
@@ -599,6 +612,8 @@ struct dhcphdr {
/** Setting block name used for BootServerDHCP responses */
#define PXEBS_SETTINGS_NAME "pxebs"
+extern void * dhcp_chaddr ( struct net_device *netdev, uint8_t *hlen,
+ uint16_t *flags );
extern int dhcp_create_packet ( struct dhcp_packet *dhcppkt,
struct net_device *netdev, uint8_t msgtype,
const void *options, size_t options_len,
@@ -611,4 +626,12 @@ extern int start_dhcp ( struct job_interface *job, struct net_device *netdev );
extern int start_pxebs ( struct job_interface *job, struct net_device *netdev,
unsigned int pxe_type );
+/* In environments that can provide cached DHCP packets, this function
+ * should look for such a packet and call store_cached_dhcpack() with
+ * it if it exists.
+ */
+__weak_decl ( void, get_cached_dhcpack, ( void ), (), );
+
+extern void store_cached_dhcpack ( userptr_t data, size_t len );
+
#endif /* _GPXE_DHCP_H */
diff --git a/gpxe/src/include/gpxe/dhcpopts.h b/gpxe/src/include/gpxe/dhcpopts.h
index 8391a9d4..3d90f411 100644
--- a/gpxe/src/include/gpxe/dhcpopts.h
+++ b/gpxe/src/include/gpxe/dhcpopts.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
/** A DHCP options block */
diff --git a/gpxe/src/include/gpxe/dhcppkt.h b/gpxe/src/include/gpxe/dhcppkt.h
index e8f8fafd..6007ccab 100644
--- a/gpxe/src/include/gpxe/dhcppkt.h
+++ b/gpxe/src/include/gpxe/dhcppkt.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/dhcp.h>
#include <gpxe/dhcpopts.h>
#include <gpxe/refcnt.h>
diff --git a/gpxe/src/include/gpxe/dns.h b/gpxe/src/include/gpxe/dns.h
index 3e3cff1b..9e5e874f 100644
--- a/gpxe/src/include/gpxe/dns.h
+++ b/gpxe/src/include/gpxe/dns.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/in.h>
diff --git a/gpxe/src/include/gpxe/downloader.h b/gpxe/src/include/gpxe/downloader.h
index 33aa7692..7f21e07b 100644
--- a/gpxe/src/include/gpxe/downloader.h
+++ b/gpxe/src/include/gpxe/downloader.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
struct job_interface;
struct image;
diff --git a/gpxe/src/include/gpxe/eapol.h b/gpxe/src/include/gpxe/eapol.h
new file mode 100644
index 00000000..c9855d09
--- /dev/null
+++ b/gpxe/src/include/gpxe/eapol.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _GPXE_EAPOL_H
+#define _GPXE_EAPOL_H
+
+/** @file
+ *
+ * Definitions for EAPOL (Extensible Authentication Protocol over
+ * LANs) frames. Definitions for the packets usually encapsulated in
+ * them are elsewhere.
+ */
+
+#include <gpxe/tables.h>
+#include <stdint.h>
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+
+/**
+ * @defgroup eapol_type EAPOL archetype identifiers
+ * @{
+ */
+#define EAPOL_TYPE_EAP 0 /**< EAP authentication handshake packet */
+#define EAPOL_TYPE_START 1 /**< Request by Peer to begin (no data) */
+#define EAPOL_TYPE_LOGOFF 2 /**< Request by Peer to terminate (no data) */
+#define EAPOL_TYPE_KEY 3 /**< EAPOL-Key packet */
+/** @} */
+
+/** Expected EAPOL version field value
+ *
+ * Version 2 is often seen and has no format differences from version 1;
+ * however, many older APs will completely drop version-2 packets, so
+ * we advertise ourselves as version 1.
+ */
+#define EAPOL_THIS_VERSION 1
+
+/** Length of an EAPOL frame header */
+#define EAPOL_HDR_LEN 4
+
+/** An EAPOL frame
+ *
+ * This may encapsulate an eap_pkt, an eapol_key_pkt, or a Start or
+ * Logoff request with no data attached. It is transmitted directly in
+ * an Ethernet frame, with no IP packet header.
+ */
+struct eapol_frame
+{
+ /** EAPOL version identifier, always 1 */
+ u8 version;
+
+ /** EAPOL archetype identifier indicating format of payload */
+ u8 type;
+
+ /** Length of payload, in network byte order */
+ u16 length;
+
+ /** Payload, if @a type is EAP or EAPOL-Key */
+ u8 data[0];
+} __attribute__ (( packed ));
+
+
+/** An EAPOL frame type handler
+ *
+ * Normally there will be at most two of these, one for EAP and one
+ * for EAPOL-Key frames. The EAPOL interface code handles Start and
+ * Logoff directly.
+ */
+struct eapol_handler
+{
+ /** EAPOL archetype identifier for payload this handler will handle */
+ u8 type;
+
+ /** Receive EAPOL-encapsulated packet of specified type
+ *
+ * @v iob I/O buffer containing packet payload
+ * @v netdev Network device from which packet was received
+ * @v ll_source Source link-layer address from which packet was received
+ * @ret rc Return status code
+ *
+ * The I/O buffer will have the EAPOL header pulled off it, so
+ * @c iob->data points to the first byte of the payload.
+ *
+ * This function takes ownership of the I/O buffer passed to it.
+ */
+ int ( * rx ) ( struct io_buffer *iob, struct net_device *netdev,
+ const void *ll_source );
+};
+
+#define EAPOL_HANDLERS __table ( struct eapol_handler, "eapol_handlers" )
+#define __eapol_handler __table_entry ( EAPOL_HANDLERS, 01 )
+
+
+extern struct net_protocol eapol_protocol __net_protocol;
+
+
+#endif /* _GPXE_EAPOL_H */
diff --git a/gpxe/src/include/gpxe/editbox.h b/gpxe/src/include/gpxe/editbox.h
index 007b042f..b7cc411b 100644
--- a/gpxe/src/include/gpxe/editbox.h
+++ b/gpxe/src/include/gpxe/editbox.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <curses.h>
#include <gpxe/editstring.h>
diff --git a/gpxe/src/include/gpxe/editstring.h b/gpxe/src/include/gpxe/editstring.h
index fad8bd5a..48c1baa0 100644
--- a/gpxe/src/include/gpxe/editstring.h
+++ b/gpxe/src/include/gpxe/editstring.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/** An editable string */
struct edit_string {
/** Buffer for string */
diff --git a/gpxe/src/include/gpxe/efi/efi.h b/gpxe/src/include/gpxe/efi/efi.h
index c7f63b6c..f4459b74 100644
--- a/gpxe/src/include/gpxe/efi/efi.h
+++ b/gpxe/src/include/gpxe/efi/efi.h
@@ -31,11 +31,17 @@
/* EFI headers rudely redefine NULL */
#undef NULL
+/* EFI headers expect ICC to define __GNUC__ */
+#if defined ( __ICC ) && ! defined ( __GNUC__ )
+#define __GNUC__ 1
+#endif
+
/* Include the top-level EFI header files */
#include <gpxe/efi/Uefi.h>
#include <gpxe/efi/PiDxe.h>
/* Reset any trailing #pragma pack directives */
+#pragma pack(1)
#pragma pack()
#include <gpxe/tables.h>
@@ -54,9 +60,11 @@ struct efi_protocol {
void **protocol;
};
+/** EFI protocol table */
+#define EFI_PROTOCOLS __table ( struct efi_protocol, "efi_protocols" )
+
/** Declare an EFI protocol used by gPXE */
-#define __efi_protocol \
- __table ( struct efi_protocol, efi_protocols, 01 )
+#define __efi_protocol __table_entry ( EFI_PROTOCOLS, 01 )
/** Declare an EFI protocol to be required by gPXE
*
@@ -67,7 +75,7 @@ struct efi_protocol {
struct efi_protocol __ ## _protocol __efi_protocol = { \
.u.guid = _protocol ## _GUID, \
.protocol = ( ( void ** ) ( void * ) \
- ( ( (_ptr) == ( ( _protocol ** ) NULL ) ) ? \
+ ( ( (_ptr) == ( ( _protocol ** ) (_ptr) ) ) ? \
(_ptr) : (_ptr) ) ), \
}
@@ -86,9 +94,12 @@ struct efi_config_table {
int required;
};
+/** EFI configuration table table */
+#define EFI_CONFIG_TABLES \
+ __table ( struct efi_config_table, "efi_config_tables" )
+
/** Declare an EFI configuration table used by gPXE */
-#define __efi_config_table \
- __table ( struct efi_config_table, efi_config_tables, 01 )
+#define __efi_config_table __table_entry ( EFI_CONFIG_TABLES, 01 )
/** Declare an EFI configuration table to be used by gPXE
*
diff --git a/gpxe/src/include/gpxe/efi/efi_io.h b/gpxe/src/include/gpxe/efi/efi_io.h
index 93f559db..7ad5ffe7 100644
--- a/gpxe/src/include/gpxe/efi/efi_io.h
+++ b/gpxe/src/include/gpxe/efi/efi_io.h
@@ -10,6 +10,8 @@
* no-ops. I/O is handled using the EFI_CPU_IO_PROTOCOL.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifdef IOAPI_EFI
#define IOAPI_PREFIX_efi
#else
diff --git a/gpxe/src/include/gpxe/efi/efi_pci.h b/gpxe/src/include/gpxe/efi/efi_pci.h
index 8be331ab..59c0eb1d 100644
--- a/gpxe/src/include/gpxe/efi/efi_pci.h
+++ b/gpxe/src/include/gpxe/efi/efi_pci.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifdef PCIAPI_EFI
#define PCIAPI_PREFIX_efi
#else
diff --git a/gpxe/src/include/gpxe/efi/efi_smbios.h b/gpxe/src/include/gpxe/efi/efi_smbios.h
index df947de5..01631e52 100644
--- a/gpxe/src/include/gpxe/efi/efi_smbios.h
+++ b/gpxe/src/include/gpxe/efi/efi_smbios.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifdef SMBIOS_EFI
#define SMBIOS_PREFIX_efi
#else
diff --git a/gpxe/src/include/gpxe/efi/efi_timer.h b/gpxe/src/include/gpxe/efi/efi_timer.h
index c332c9d6..e0531d5a 100644
--- a/gpxe/src/include/gpxe/efi/efi_timer.h
+++ b/gpxe/src/include/gpxe/efi/efi_timer.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifdef TIMER_EFI
#define TIMER_PREFIX_efi
#else
diff --git a/gpxe/src/include/gpxe/efi/efi_uaccess.h b/gpxe/src/include/gpxe/efi/efi_uaccess.h
index bae5fb41..a6b61c58 100644
--- a/gpxe/src/include/gpxe/efi/efi_uaccess.h
+++ b/gpxe/src/include/gpxe/efi/efi_uaccess.h
@@ -10,6 +10,8 @@
* no-ops.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifdef UACCESS_EFI
#define UACCESS_PREFIX_efi
#else
diff --git a/gpxe/src/include/gpxe/efi/efi_umalloc.h b/gpxe/src/include/gpxe/efi/efi_umalloc.h
index def17b2d..0388dd10 100644
--- a/gpxe/src/include/gpxe/efi/efi_umalloc.h
+++ b/gpxe/src/include/gpxe/efi/efi_umalloc.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifdef UMALLOC_EFI
#define UMALLOC_PREFIX_efi
#else
diff --git a/gpxe/src/include/gpxe/eisa.h b/gpxe/src/include/gpxe/eisa.h
index e9d890e1..f76e4b9d 100644
--- a/gpxe/src/include/gpxe/eisa.h
+++ b/gpxe/src/include/gpxe/eisa.h
@@ -1,6 +1,8 @@
#ifndef EISA_H
#define EISA_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/isa_ids.h>
#include <gpxe/device.h>
@@ -79,8 +81,11 @@ struct eisa_driver {
void ( * remove ) ( struct eisa_device *eisa );
};
+/** EISA driver table */
+#define EISA_DRIVERS __table ( struct eisa_driver, "eisa_drivers" )
+
/** Declare an EISA driver */
-#define __eisa_driver __table ( struct eisa_driver, eisa_drivers, 01 )
+#define __eisa_driver __table_entry ( EISA_DRIVERS, 01 )
extern void eisa_device_enabled ( struct eisa_device *eisa, int enabled );
diff --git a/gpxe/src/include/gpxe/elf.h b/gpxe/src/include/gpxe/elf.h
index db28a60a..da9d2fc0 100644
--- a/gpxe/src/include/gpxe/elf.h
+++ b/gpxe/src/include/gpxe/elf.h
@@ -8,6 +8,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <elf.h>
extern int elf_load ( struct image *image );
diff --git a/gpxe/src/include/gpxe/errfile.h b/gpxe/src/include/gpxe/errfile.h
index dcfd4e4a..def8f357 100644
--- a/gpxe/src/include/gpxe/errfile.h
+++ b/gpxe/src/include/gpxe/errfile.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <bits/errfile.h>
/**
@@ -108,11 +110,20 @@
#define ERRFILE_phantom ( ERRFILE_DRIVER | 0x004b0000 )
#define ERRFILE_ne2k_isa ( ERRFILE_DRIVER | 0x004c0000 )
#define ERRFILE_b44 ( ERRFILE_DRIVER | 0x004d0000 )
+#define ERRFILE_rtl818x ( ERRFILE_DRIVER | 0x004e0000 )
+#define ERRFILE_sky2 ( ERRFILE_DRIVER | 0x004f0000 )
+#define ERRFILE_ath5k ( ERRFILE_DRIVER | 0x00500000 )
+#define ERRFILE_atl1e ( ERRFILE_DRIVER | 0x00510000 )
+#define ERRFILE_sis190 ( ERRFILE_DRIVER | 0x00520000 )
+#define ERRFILE_myri10ge ( ERRFILE_DRIVER | 0x00530000 )
+#define ERRFILE_skge ( ERRFILE_DRIVER | 0x00540000 )
#define ERRFILE_scsi ( ERRFILE_DRIVER | 0x00700000 )
#define ERRFILE_arbel ( ERRFILE_DRIVER | 0x00710000 )
#define ERRFILE_hermon ( ERRFILE_DRIVER | 0x00720000 )
#define ERRFILE_linda ( ERRFILE_DRIVER | 0x00730000 )
+#define ERRFILE_ata ( ERRFILE_DRIVER | 0x00740000 )
+#define ERRFILE_srp ( ERRFILE_DRIVER | 0x00750000 )
#define ERRFILE_aoe ( ERRFILE_NET | 0x00000000 )
#define ERRFILE_arp ( ERRFILE_NET | 0x00010000 )
@@ -140,6 +151,22 @@
#define ERRFILE_ib_sma ( ERRFILE_NET | 0x00170000 )
#define ERRFILE_ib_packet ( ERRFILE_NET | 0x00180000 )
#define ERRFILE_icmp ( ERRFILE_NET | 0x00190000 )
+#define ERRFILE_ib_qset ( ERRFILE_NET | 0x001a0000 )
+#define ERRFILE_ib_gma ( ERRFILE_NET | 0x001b0000 )
+#define ERRFILE_ib_pathrec ( ERRFILE_NET | 0x001c0000 )
+#define ERRFILE_ib_mcast ( ERRFILE_NET | 0x001d0000 )
+#define ERRFILE_ib_cm ( ERRFILE_NET | 0x001e0000 )
+#define ERRFILE_net80211 ( ERRFILE_NET | 0x001f0000 )
+#define ERRFILE_ib_mi ( ERRFILE_NET | 0x00200000 )
+#define ERRFILE_ib_cmrc ( ERRFILE_NET | 0x00210000 )
+#define ERRFILE_ib_srp ( ERRFILE_NET | 0x00220000 )
+#define ERRFILE_sec80211 ( ERRFILE_NET | 0x00230000 )
+#define ERRFILE_wep ( ERRFILE_NET | 0x00240000 )
+#define ERRFILE_eapol ( ERRFILE_NET | 0x00250000 )
+#define ERRFILE_wpa ( ERRFILE_NET | 0x00260000 )
+#define ERRFILE_wpa_psk ( ERRFILE_NET | 0x00270000 )
+#define ERRFILE_wpa_tkip ( ERRFILE_NET | 0x00280000 )
+#define ERRFILE_wpa_ccmp ( ERRFILE_NET | 0x00290000 )
#define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 )
#define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 )
@@ -172,6 +199,8 @@
#define ERRFILE_pxemenu ( ERRFILE_OTHER | 0x00150000 )
#define ERRFILE_x509 ( ERRFILE_OTHER | 0x00160000 )
#define ERRFILE_login_ui ( ERRFILE_OTHER | 0x00170000 )
+#define ERRFILE_ib_srpboot ( ERRFILE_OTHER | 0x00180000 )
+#define ERRFILE_iwmgmt ( ERRFILE_OTHER | 0x00190000 )
/** @} */
diff --git a/gpxe/src/include/gpxe/errortab.h b/gpxe/src/include/gpxe/errortab.h
index e9a56768..35765d48 100644
--- a/gpxe/src/include/gpxe/errortab.h
+++ b/gpxe/src/include/gpxe/errortab.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/tables.h>
struct errortab {
@@ -14,6 +16,8 @@ struct errortab {
const char *text;
};
-#define __errortab __table ( struct errortab, errortab, 01 )
+#define ERRORTAB __table ( struct errortab, "errortab" )
+
+#define __errortab __table_entry ( ERRORTAB, 01 )
#endif /* _GPXE_ERRORTAB_H */
diff --git a/gpxe/src/include/gpxe/ethernet.h b/gpxe/src/include/gpxe/ethernet.h
index ff0fd6c1..4dfc24d3 100644
--- a/gpxe/src/include/gpxe/ethernet.h
+++ b/gpxe/src/include/gpxe/ethernet.h
@@ -7,29 +7,15 @@
*
*/
-#include <stdint.h>
-#include <gpxe/netdevice.h>
-#include <gpxe/if_ether.h>
+FILE_LICENCE ( GPL2_OR_LATER );
-extern struct ll_protocol ethernet_protocol;
+#include <stdint.h>
+extern void eth_init_addr ( const void *hw_addr, void *ll_addr );
extern const char * eth_ntoa ( const void *ll_addr );
-
-/**
- * Allocate Ethernet device
- *
- * @v priv_size Size of driver private data
- * @ret netdev Network device, or NULL
- */
-static inline struct net_device * alloc_etherdev ( size_t priv_size ) {
- struct net_device *netdev;
-
- netdev = alloc_netdev ( priv_size );
- if ( netdev ) {
- netdev->ll_protocol = &ethernet_protocol;
- netdev->max_pkt_len = ETH_FRAME_LEN;
- }
- return netdev;
-}
+extern int eth_mc_hash ( unsigned int af, const void *net_addr,
+ void *ll_addr );
+extern int eth_eth_addr ( const void *ll_addr, void *eth_addr );
+extern struct net_device * alloc_etherdev ( size_t priv_size );
#endif /* _GPXE_ETHERNET_H */
diff --git a/gpxe/src/include/gpxe/fakedhcp.h b/gpxe/src/include/gpxe/fakedhcp.h
index 550b74f7..c603bdc4 100644
--- a/gpxe/src/include/gpxe/fakedhcp.h
+++ b/gpxe/src/include/gpxe/fakedhcp.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
struct net_device;
diff --git a/gpxe/src/include/gpxe/features.h b/gpxe/src/include/gpxe/features.h
index 32c31694..34431867 100644
--- a/gpxe/src/include/gpxe/features.h
+++ b/gpxe/src/include/gpxe/features.h
@@ -11,6 +11,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/**
* @defgroup featurecat Feature categories
* @{
@@ -42,6 +44,7 @@
#define DHCP_EB_FEATURE_BZIMAGE 0x18 /**< bzImage format */
#define DHCP_EB_FEATURE_MULTIBOOT 0x19 /**< Multiboot format */
#define DHCP_EB_FEATURE_SLAM 0x1a /**< SLAM protocol */
+#define DHCP_EB_FEATURE_SRP 0x1b /**< SRP protocol */
#define DHCP_EB_FEATURE_NBI 0x20 /**< NBI format */
#define DHCP_EB_FEATURE_PXE 0x21 /**< PXE format */
#define DHCP_EB_FEATURE_ELF 0x22 /**< ELF format */
@@ -50,8 +53,11 @@
/** @} */
+/** DHCP feature table */
+#define DHCP_FEATURES __table ( uint8_t, "dhcp_features" )
+
/** Declare a feature code for DHCP */
-#define __dhcp_feature __table ( uint8_t, dhcp_features, 01 )
+#define __dhcp_feature __table_entry ( DHCP_FEATURES, 01 )
/** Construct a DHCP feature table entry */
#define DHCP_FEATURE( feature_opt, ... ) \
@@ -69,9 +75,11 @@ struct feature {
char *name;
};
+/** Named feature table */
+#define FEATURES __table ( struct feature, "features" )
+
/** Declare a named feature */
-#define __feature_name( category ) \
- __table ( struct feature, features, category )
+#define __feature_name( category ) __table_entry ( FEATURES, category )
/** Construct a named feature */
#define FEATURE_NAME( category, text ) \
diff --git a/gpxe/src/include/gpxe/filter.h b/gpxe/src/include/gpxe/filter.h
index 126f6347..1f59fccc 100644
--- a/gpxe/src/include/gpxe/filter.h
+++ b/gpxe/src/include/gpxe/filter.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stddef.h>
#include <gpxe/xfer.h>
diff --git a/gpxe/src/include/gpxe/ftp.h b/gpxe/src/include/gpxe/ftp.h
index 370285c6..93194f65 100644
--- a/gpxe/src/include/gpxe/ftp.h
+++ b/gpxe/src/include/gpxe/ftp.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/** FTP default port */
#define FTP_PORT 21
diff --git a/gpxe/src/include/gpxe/gdbserial.h b/gpxe/src/include/gpxe/gdbserial.h
index 1863e907..2613ab47 100644
--- a/gpxe/src/include/gpxe/gdbserial.h
+++ b/gpxe/src/include/gpxe/gdbserial.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
struct gdb_transport;
/**
diff --git a/gpxe/src/include/gpxe/gdbstub.h b/gpxe/src/include/gpxe/gdbstub.h
index bf5d24d2..8f9b7c1d 100644
--- a/gpxe/src/include/gpxe/gdbstub.h
+++ b/gpxe/src/include/gpxe/gdbstub.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/tables.h>
#include <gdbmach.h>
@@ -45,7 +47,9 @@ struct gdb_transport {
void ( * send ) ( const char *buf, size_t len );
};
-#define __gdb_transport __table ( struct gdb_transport, gdb_transports, 01 )
+#define GDB_TRANSPORTS __table ( struct gdb_transport, "gdb_transports" )
+
+#define __gdb_transport __table_entry ( GDB_TRANSPORTS, 01 )
/**
* Look up GDB transport by name
diff --git a/gpxe/src/include/gpxe/gdbudp.h b/gpxe/src/include/gpxe/gdbudp.h
index 1a990933..5f02faaa 100644
--- a/gpxe/src/include/gpxe/gdbudp.h
+++ b/gpxe/src/include/gpxe/gdbudp.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
struct sockaddr_in;
struct gdb_transport;
diff --git a/gpxe/src/include/gpxe/hidemem.h b/gpxe/src/include/gpxe/hidemem.h
index 010fdb58..01b3fc24 100644
--- a/gpxe/src/include/gpxe/hidemem.h
+++ b/gpxe/src/include/gpxe/hidemem.h
@@ -8,6 +8,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
extern void hide_umalloc ( physaddr_t start, physaddr_t end );
diff --git a/gpxe/src/include/gpxe/hmac.h b/gpxe/src/include/gpxe/hmac.h
index 67aefdce..cb001b9d 100644
--- a/gpxe/src/include/gpxe/hmac.h
+++ b/gpxe/src/include/gpxe/hmac.h
@@ -6,6 +6,8 @@
* Keyed-Hashing for Message Authentication
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/crypto.h>
/**
diff --git a/gpxe/src/include/gpxe/http.h b/gpxe/src/include/gpxe/http.h
index fa92a950..baa6d83e 100644
--- a/gpxe/src/include/gpxe/http.h
+++ b/gpxe/src/include/gpxe/http.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/** HTTP default port */
#define HTTP_PORT 80
diff --git a/gpxe/src/include/gpxe/i2c.h b/gpxe/src/include/gpxe/i2c.h
index 9d229546..87b89d46 100644
--- a/gpxe/src/include/gpxe/i2c.h
+++ b/gpxe/src/include/gpxe/i2c.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/bitbash.h>
diff --git a/gpxe/src/include/gpxe/ib_cm.h b/gpxe/src/include/gpxe/ib_cm.h
new file mode 100644
index 00000000..670fffda
--- /dev/null
+++ b/gpxe/src/include/gpxe/ib_cm.h
@@ -0,0 +1,72 @@
+#ifndef _GPXE_IB_CM_H
+#define _GPXE_IB_CM_H
+
+/** @file
+ *
+ * Infiniband communication management
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <gpxe/infiniband.h>
+#include <gpxe/retry.h>
+
+struct ib_mad_transaction;
+struct ib_connection;
+
+/** Infiniband connection operations */
+struct ib_connection_operations {
+ /** Handle change of connection status
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ * @v conn Connection
+ * @v rc Connection status code
+ * @v private_data Private data, if available
+ * @v private_data_len Length of private data
+ */
+ void ( * changed ) ( struct ib_device *ibdev, struct ib_queue_pair *qp,
+ struct ib_connection *conn, int rc,
+ void *private_data, size_t private_data_len );
+};
+
+/** An Infiniband connection */
+struct ib_connection {
+ /** Infiniband device */
+ struct ib_device *ibdev;
+ /** Queue pair */
+ struct ib_queue_pair *qp;
+ /** Local communication ID */
+ uint32_t local_id;
+ /** Remote communication ID */
+ uint32_t remote_id;
+ /** Target service ID */
+ struct ib_gid_half service_id;
+ /** Connection operations */
+ struct ib_connection_operations *op;
+
+ /** List of connections */
+ struct list_head list;
+
+ /** Path to target */
+ struct ib_path *path;
+ /** Connection request management transaction */
+ struct ib_mad_transaction *madx;
+
+ /** Length of connection request private data */
+ size_t private_data_len;
+ /** Connection request private data */
+ uint8_t private_data[0];
+};
+
+extern struct ib_connection *
+ib_create_conn ( struct ib_device *ibdev, struct ib_queue_pair *qp,
+ struct ib_gid *dgid, struct ib_gid_half *service_id,
+ void *req_private_data, size_t req_private_data_len,
+ struct ib_connection_operations *op );
+extern void ib_destroy_conn ( struct ib_device *ibdev,
+ struct ib_queue_pair *qp,
+ struct ib_connection *conn );
+
+#endif /* _GPXE_IB_CM_H */
diff --git a/gpxe/src/include/gpxe/ib_cmrc.h b/gpxe/src/include/gpxe/ib_cmrc.h
new file mode 100644
index 00000000..efa741ac
--- /dev/null
+++ b/gpxe/src/include/gpxe/ib_cmrc.h
@@ -0,0 +1,20 @@
+#ifndef _GPXE_IB_CMRC_H
+#define _GPXE_IB_CMRC_H
+
+/** @file
+ *
+ * Infiniband Communication-managed Reliable Connections
+ *
+ */
+
+FILE_LICENCE ( BSD2 );
+
+#include <gpxe/infiniband.h>
+#include <gpxe/xfer.h>
+
+extern int ib_cmrc_open ( struct xfer_interface *xfer,
+ struct ib_device *ibdev,
+ struct ib_gid *dgid,
+ struct ib_gid_half *service_id );
+
+#endif /* _GPXE_IB_CMRC_H */
diff --git a/gpxe/src/include/gpxe/ib_mad.h b/gpxe/src/include/gpxe/ib_mad.h
index 6c4e95b7..8b497183 100644
--- a/gpxe/src/include/gpxe/ib_mad.h
+++ b/gpxe/src/include/gpxe/ib_mad.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/ib_packet.h>
@@ -73,9 +75,9 @@ struct ib_node_info {
uint8_t class_version;
uint8_t node_type;
uint8_t num_ports;
- uint8_t sys_guid[8];
- uint8_t node_guid[8];
- uint8_t port_guid[8];
+ struct ib_gid_half sys_guid;
+ struct ib_gid_half node_guid;
+ struct ib_gid_half port_guid;
uint16_t partition_cap;
uint16_t device_id;
uint32_t revision;
@@ -199,6 +201,10 @@ struct ib_smp_class_specific {
*****************************************************************************
*/
+#define IB_SA_CLASS_VERSION 2
+
+#define IB_SA_METHOD_DELETE_RESP 0x95
+
struct ib_rmpp_hdr {
uint32_t raw[3];
} __attribute__ (( packed ));
@@ -275,6 +281,188 @@ union ib_sa_data {
/*****************************************************************************
*
+ * Communication management MADs
+ *
+ *****************************************************************************
+ */
+
+/** Communication management class version */
+#define IB_CM_CLASS_VERSION 2
+
+/* Communication management attributes */
+#define IB_CM_ATTR_CLASS_PORT_INFO 0x0001
+#define IB_CM_ATTR_CONNECT_REQUEST 0x0010
+#define IB_CM_ATTR_MSG_RCPT_ACK 0x0011
+#define IB_CM_ATTR_CONNECT_REJECT 0x0012
+#define IB_CM_ATTR_CONNECT_REPLY 0x0013
+#define IB_CM_ATTR_READY_TO_USE 0x0014
+#define IB_CM_ATTR_DISCONNECT_REQUEST 0x0015
+#define IB_CM_ATTR_DISCONNECT_REPLY 0x0016
+#define IB_CM_ATTR_SERVICE_ID_RES_REQ 0x0016
+#define IB_CM_ATTR_SERVICE_ID_RES_REQ_RESP 0x0018
+#define IB_CM_ATTR_LOAD_ALTERNATE_PATH 0x0019
+#define IB_CM_ATTR_ALTERNATE_PATH_RESPONSE 0x001a
+
+/** Communication management common fields */
+struct ib_cm_common {
+ /** Local communication ID */
+ uint32_t local_id;
+ /** Remote communication ID */
+ uint32_t remote_id;
+ /** Reserved */
+ uint8_t reserved[224];
+} __attribute__ (( packed ));
+
+/** A communication management path */
+struct ib_cm_path {
+ /** Local port LID */
+ uint16_t local_lid;
+ /** Remote port LID */
+ uint16_t remote_lid;
+ /** Local port GID */
+ struct ib_gid local_gid;
+ /** Remote port GID */
+ struct ib_gid remote_gid;
+ /** Flow label and rate */
+ uint32_t flow_label__rate;
+ /** Traffic class */
+ uint8_t tc;
+ /** Hop limit */
+ uint8_t hop_limit;
+ /** SL and subnet local*/
+ uint8_t sl__subnet_local;
+ /** Local ACK timeout */
+ uint8_t local_ack_timeout;
+} __attribute__ (( packed ));
+
+/** A communication management connection request
+ *
+ * Defined in section 12.6.5 of the IBA.
+ */
+struct ib_cm_connect_request {
+ /** Local communication ID */
+ uint32_t local_id;
+ /** Reserved */
+ uint32_t reserved0[1];
+ /** Service ID */
+ struct ib_gid_half service_id;
+ /** Local CA GUID */
+ struct ib_gid_half local_ca;
+ /** Reserved */
+ uint32_t reserved1[1];
+ /** Local queue key */
+ uint32_t local_qkey;
+ /** Local QPN and responder resources*/
+ uint32_t local_qpn__responder_resources;
+ /** Local EECN and initiator depth */
+ uint32_t local_eecn__initiator_depth;
+ /** Remote EECN, remote CM response timeout, transport service
+ * type, EE flow control
+ */
+ uint32_t remote_eecn__remote_timeout__service_type__ee_flow_ctrl;
+ /** Starting PSN, local CM response timeout and retry count */
+ uint32_t starting_psn__local_timeout__retry_count;
+ /** Partition key */
+ uint16_t pkey;
+ /** Path packet payload MTU, RDC exists, RNR retry count */
+ uint8_t payload_mtu__rdc_exists__rnr_retry;
+ /** Max CM retries and SRQ */
+ uint8_t max_cm_retries__srq;
+ /** Primary path */
+ struct ib_cm_path primary;
+ /** Alternate path */
+ struct ib_cm_path alternate;
+ /** Private data */
+ uint8_t private_data[92];
+} __attribute__ (( packed ));
+
+/** CM transport types */
+#define IB_CM_TRANSPORT_RC 0
+#define IB_CM_TRANSPORT_UC 1
+#define IB_CM_TRANSPORT_RD 2
+
+/** A communication management connection rejection
+ *
+ * Defined in section 12.6.7 of the IBA.
+ */
+struct ib_cm_connect_reject {
+ /** Local communication ID */
+ uint32_t local_id;
+ /** Remote communication ID */
+ uint32_t remote_id;
+ /** Message rejected */
+ uint8_t message;
+ /** Reject information length */
+ uint8_t info_len;
+ /** Rejection reason */
+ uint16_t reason;
+ /** Additional rejection information */
+ uint8_t info[72];
+ /** Private data */
+ uint8_t private_data[148];
+} __attribute__ (( packed ));
+
+/** CM rejection reasons */
+#define IB_CM_REJECT_BAD_SERVICE_ID 8
+#define IB_CM_REJECT_STALE_CONN 10
+#define IB_CM_REJECT_CONSUMER 28
+
+/** A communication management connection reply
+ *
+ * Defined in section 12.6.8 of the IBA.
+ */
+struct ib_cm_connect_reply {
+ /** Local communication ID */
+ uint32_t local_id;
+ /** Remote communication ID */
+ uint32_t remote_id;
+ /** Local queue key */
+ uint32_t local_qkey;
+ /** Local QPN */
+ uint32_t local_qpn;
+ /** Local EECN */
+ uint32_t local_eecn;
+ /** Starting PSN */
+ uint32_t starting_psn;
+ /** Responder resources */
+ uint8_t responder_resources;
+ /** Initiator depth */
+ uint8_t initiator_depth;
+ /** Target ACK delay, failover accepted, and end-to-end flow control */
+ uint8_t target_ack_delay__failover_accepted__ee_flow_ctrl;
+ /** RNR retry count, SRQ */
+ uint8_t rnr_retry__srq;
+ /** Local CA GUID */
+ struct ib_gid_half local_ca;
+ /** Private data */
+ uint8_t private_data[196];
+} __attribute__ (( packed ));
+
+/** A communication management ready to use reply
+ *
+ * Defined in section 12.6.9 of the IBA.
+ */
+struct ib_cm_ready_to_use {
+ /** Local communication ID */
+ uint32_t local_id;
+ /** Remote communication ID */
+ uint32_t remote_id;
+ /** Private data */
+ uint8_t private_data[224];
+} __attribute__ (( packed ));
+
+/** A communication management attribute */
+union ib_cm_data {
+ struct ib_cm_common common;
+ struct ib_cm_connect_request connect_request;
+ struct ib_cm_connect_reject connect_reject;
+ struct ib_cm_connect_reply connect_reply;
+ struct ib_cm_ready_to_use ready_to_use;
+ uint8_t bytes[232];
+} __attribute__ (( packed ));
+
+/*****************************************************************************
+ *
* MADs
*
*****************************************************************************
@@ -316,7 +504,9 @@ struct ib_mad_hdr {
#define IB_MGMT_CLASS_CM 0x07
#define IB_MGMT_CLASS_SNMP 0x08
#define IB_MGMT_CLASS_VENDOR_RANGE2_START 0x30
-#define IB_MGMT_CLASS_VENDOR_RANGE2_END 0x4F
+#define IB_MGMT_CLASS_VENDOR_RANGE2_END 0x4f
+
+#define IB_MGMT_CLASS_MASK 0x7f
/* Management methods */
#define IB_MGMT_METHOD_GET 0x01
@@ -353,11 +543,18 @@ struct ib_mad_sa {
union ib_sa_data sa_data;
} __attribute__ (( packed ));
+/** A communication management MAD */
+struct ib_mad_cm {
+ struct ib_mad_hdr mad_hdr;
+ union ib_cm_data cm_data;
+} __attribute__ (( packed ));
+
/** A management datagram */
union ib_mad {
struct ib_mad_hdr hdr;
struct ib_mad_smp smp;
struct ib_mad_sa sa;
+ struct ib_mad_cm cm;
uint8_t bytes[256];
} __attribute__ (( packed ));
diff --git a/gpxe/src/include/gpxe/ib_mcast.h b/gpxe/src/include/gpxe/ib_mcast.h
new file mode 100644
index 00000000..74eccd0b
--- /dev/null
+++ b/gpxe/src/include/gpxe/ib_mcast.h
@@ -0,0 +1,48 @@
+#ifndef _GPXE_IB_MCAST_H
+#define _GPXE_IB_MCAST_H
+
+/** @file
+ *
+ * Infiniband multicast groups
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <gpxe/infiniband.h>
+
+struct ib_mad_transaction;
+
+/** An Infiniband multicast group membership */
+struct ib_mc_membership {
+ /** Queue pair */
+ struct ib_queue_pair *qp;
+ /** Multicast GID */
+ struct ib_gid gid;
+ /** Multicast group join transaction */
+ struct ib_mad_transaction *madx;
+ /** Handle join success/failure
+ *
+ * @v ibdev Infiniband device
+ * @v qp Queue pair
+ * @v membership Multicast group membership
+ * @v rc Status code
+ * @v mad Response MAD (or NULL on error)
+ */
+ void ( * complete ) ( struct ib_device *ibdev, struct ib_queue_pair *qp,
+ struct ib_mc_membership *membership, int rc,
+ union ib_mad *mad );
+};
+
+extern int ib_mcast_join ( struct ib_device *ibdev, struct ib_queue_pair *qp,
+ struct ib_mc_membership *membership,
+ struct ib_gid *gid,
+ void ( * joined ) ( struct ib_device *ibdev,
+ struct ib_queue_pair *qp,
+ struct ib_mc_membership *memb,
+ int rc, union ib_mad *mad ) );
+
+extern void ib_mcast_leave ( struct ib_device *ibdev, struct ib_queue_pair *qp,
+ struct ib_mc_membership *membership );
+
+#endif /* _GPXE_IB_MCAST_H */
diff --git a/gpxe/src/include/gpxe/ib_mi.h b/gpxe/src/include/gpxe/ib_mi.h
new file mode 100644
index 00000000..b1cf686d
--- /dev/null
+++ b/gpxe/src/include/gpxe/ib_mi.h
@@ -0,0 +1,135 @@
+#ifndef _GPXE_IB_MI_H
+#define _GPXE_IB_MI_H
+
+/** @file
+ *
+ * Infiniband management interfaces
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <gpxe/list.h>
+#include <gpxe/retry.h>
+#include <gpxe/tables.h>
+#include <gpxe/infiniband.h>
+
+struct ib_mad_interface;
+struct ib_mad_transaction;
+
+/** An Infiniband management agent */
+struct ib_mad_agent {
+ /** Management class */
+ uint8_t mgmt_class;
+ /** Class version */
+ uint8_t class_version;
+ /** Attribute (in network byte order) */
+ uint16_t attr_id;
+ /** Handle MAD
+ *
+ * @v ibdev Infiniband device
+ * @v mi Management interface
+ * @v mad Received MAD
+ * @v av Source address vector
+ * @ret rc Return status code
+ */
+ void ( * handle ) ( struct ib_device *ibdev,
+ struct ib_mad_interface *mi,
+ union ib_mad *mad,
+ struct ib_address_vector *av );
+};
+
+/** Infiniband management agents */
+#define IB_MAD_AGENTS __table ( struct ib_mad_agent, "ib_mad_agents" )
+
+/** Declare an Infiniband management agent */
+#define __ib_mad_agent __table_entry ( IB_MAD_AGENTS, 01 )
+
+/** Infiniband management transaction operations */
+struct ib_mad_transaction_operations {
+ /** Handle transaction completion
+ *
+ * @v ibdev Infiniband device
+ * @v mi Management interface
+ * @v madx Management transaction
+ * @v rc Status code
+ * @v mad Received MAD (or NULL on error)
+ * @v av Source address vector (or NULL on error)
+ *
+ * The completion handler should in most cases call
+ * ib_destroy_madx() to free up the completed transaction.
+ */
+ void ( * complete ) ( struct ib_device *ibdev,
+ struct ib_mad_interface *mi,
+ struct ib_mad_transaction *madx,
+ int rc, union ib_mad *mad,
+ struct ib_address_vector *av );
+};
+
+/** An Infiniband management transaction */
+struct ib_mad_transaction {
+ /** Associated management interface */
+ struct ib_mad_interface *mi;
+ /** List of transactions */
+ struct list_head list;
+ /** Retry timer */
+ struct retry_timer timer;
+ /** Destination address vector */
+ struct ib_address_vector av;
+ /** MAD being sent */
+ union ib_mad mad;
+ /** Transaction operations */
+ struct ib_mad_transaction_operations *op;
+ /** Owner private data */
+ void *owner_priv;
+};
+
+/** An Infiniband management interface */
+struct ib_mad_interface {
+ /** Infiniband device */
+ struct ib_device *ibdev;
+ /** Completion queue */
+ struct ib_completion_queue *cq;
+ /** Queue pair */
+ struct ib_queue_pair *qp;
+ /** List of management transactions */
+ struct list_head madx;
+};
+
+/**
+ * Set Infiniband management transaction owner-private data
+ *
+ * @v madx Management transaction
+ * @v priv Private data
+ */
+static inline __always_inline void
+ib_madx_set_ownerdata ( struct ib_mad_transaction *madx, void *priv ) {
+ madx->owner_priv = priv;
+}
+
+/**
+ * Get Infiniband management transaction owner-private data
+ *
+ * @v madx Management transaction
+ * @ret priv Private data
+ */
+static inline __always_inline void *
+ib_madx_get_ownerdata ( struct ib_mad_transaction *madx ) {
+ return madx->owner_priv;
+}
+
+extern int ib_mi_send ( struct ib_device *ibdev, struct ib_mad_interface *mi,
+ union ib_mad *mad, struct ib_address_vector *av );
+extern struct ib_mad_transaction *
+ib_create_madx ( struct ib_device *ibdev, struct ib_mad_interface *mi,
+ union ib_mad *mad, struct ib_address_vector *av,
+ struct ib_mad_transaction_operations *op );
+extern void ib_destroy_madx ( struct ib_device *ibdev,
+ struct ib_mad_interface *mi,
+ struct ib_mad_transaction *madx );
+extern struct ib_mad_interface * ib_create_mi ( struct ib_device *ibdev,
+ enum ib_queue_pair_type type );
+extern void ib_destroy_mi ( struct ib_device *ibdev,
+ struct ib_mad_interface *mi );
+
+#endif /* _GPXE_IB_MI_H */
diff --git a/gpxe/src/include/gpxe/ib_packet.h b/gpxe/src/include/gpxe/ib_packet.h
index 5374802c..d4688596 100644
--- a/gpxe/src/include/gpxe/ib_packet.h
+++ b/gpxe/src/include/gpxe/ib_packet.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
struct ib_device;
struct ib_queue_pair;
struct ib_address_vector;
@@ -14,7 +16,11 @@ struct io_buffer;
/** Half of an Infiniband Global Identifier */
struct ib_gid_half {
- uint8_t bytes[8];
+ union {
+ uint8_t bytes[8];
+ uint16_t words[4];
+ uint32_t dwords[2];
+ } u;
};
/** An Infiniband Global Identifier */
@@ -104,12 +110,6 @@ enum ib_bth_opcode {
BTH_OPCODE_UD_SEND = 0x64,
};
-/** Default Infiniband partition key */
-#define IB_PKEY_NONE 0xffff
-
-/** Subnet management queue pair number */
-#define IB_QPN_SMP 0
-
/** An Infiniband Datagram Extended Transport Header */
struct ib_datagram_extended_transport_header {
/** Queue key */
diff --git a/gpxe/src/include/gpxe/ib_pathrec.h b/gpxe/src/include/gpxe/ib_pathrec.h
new file mode 100644
index 00000000..5884d536
--- /dev/null
+++ b/gpxe/src/include/gpxe/ib_pathrec.h
@@ -0,0 +1,76 @@
+#ifndef _GPXE_IB_PATHREC_H
+#define _GPXE_IB_PATHREC_H
+
+/** @file
+ *
+ * Infiniband path records
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <gpxe/infiniband.h>
+
+struct ib_mad_transaction;
+struct ib_path;
+
+/** Infiniband path operations */
+struct ib_path_operations {
+ /** Handle path transaction completion
+ *
+ * @v ibdev Infiniband device
+ * @v path Path
+ * @v rc Status code
+ * @v av Address vector, or NULL on error
+ */
+ void ( * complete ) ( struct ib_device *ibdev,
+ struct ib_path *path, int rc,
+ struct ib_address_vector *av );
+};
+
+/** An Infiniband path */
+struct ib_path {
+ /** Infiniband device */
+ struct ib_device *ibdev;
+ /** Address vector */
+ struct ib_address_vector av;
+ /** Management transaction */
+ struct ib_mad_transaction *madx;
+ /** Path operations */
+ struct ib_path_operations *op;
+ /** Owner private data */
+ void *owner_priv;
+};
+
+/**
+ * Set Infiniband path owner-private data
+ *
+ * @v path Path
+ * @v priv Private data
+ */
+static inline __always_inline void
+ib_path_set_ownerdata ( struct ib_path *path, void *priv ) {
+ path->owner_priv = priv;
+}
+
+/**
+ * Get Infiniband path owner-private data
+ *
+ * @v path Path
+ * @ret priv Private data
+ */
+static inline __always_inline void *
+ib_path_get_ownerdata ( struct ib_path *path ) {
+ return path->owner_priv;
+}
+
+extern struct ib_path *
+ib_create_path ( struct ib_device *ibdev, struct ib_address_vector *av,
+ struct ib_path_operations *op );
+extern void ib_destroy_path ( struct ib_device *ibdev,
+ struct ib_path *path );
+
+extern int ib_resolve_path ( struct ib_device *ibdev,
+ struct ib_address_vector *av );
+
+#endif /* _GPXE_IB_PATHREC_H */
diff --git a/gpxe/src/include/gpxe/ib_sma.h b/gpxe/src/include/gpxe/ib_sma.h
index 835ed4ea..78fc6729 100644
--- a/gpxe/src/include/gpxe/ib_sma.h
+++ b/gpxe/src/include/gpxe/ib_sma.h
@@ -3,61 +3,18 @@
/** @file
*
- * Infiniband Subnet Management Agent
+ * Infiniband subnet management agent
*
*/
-#include <gpxe/infiniband.h>
-#include <gpxe/process.h>
+FILE_LICENCE ( GPL2_OR_LATER );
-/** Infiniband Subnet Management Agent operations */
-struct ib_sma_operations {
- /** Set port information
- *
- * @v ibdev Infiniband device
- * @v port_info New port information
- */
- int ( * set_port_info ) ( struct ib_device *ibdev,
- const struct ib_port_info *port_info );
-};
+struct ib_device;
+struct ib_mad_interface;
-/** An Infiniband Subnet Management Agent */
-struct ib_sma {
- /** Infiniband device */
- struct ib_device *ibdev;
- /** SMA operations */
- struct ib_sma_operations *op;
- /** SMA completion queue */
- struct ib_completion_queue *cq;
- /** SMA queue pair */
- struct ib_queue_pair *qp;
- /** Poll process */
- struct process poll;
-};
-
-/** SMA payload size allocated for received packets */
-#define IB_SMA_PAYLOAD_LEN 2048
-
-/** SMA number of send WQEs
- *
- * This is a policy decision.
- */
-#define IB_SMA_NUM_SEND_WQES 4
-
-/** SMA number of receive WQEs
- *
- * This is a policy decision.
- */
-#define IB_SMA_NUM_RECV_WQES 2
-
-/** SMA number of completion queue entries
- *
- * This is a policy decision
- */
-#define IB_SMA_NUM_CQES 8
-
-extern int ib_create_sma ( struct ib_sma *sma, struct ib_device *ibdev,
- struct ib_sma_operations *op );
-extern void ib_destroy_sma ( struct ib_sma *sma );
+extern int ib_create_sma ( struct ib_device *ibdev,
+ struct ib_mad_interface *mi );
+extern void ib_destroy_sma ( struct ib_device *ibdev,
+ struct ib_mad_interface *mi );
#endif /* _GPXE_IB_SMA_H */
diff --git a/gpxe/src/include/gpxe/ib_smc.h b/gpxe/src/include/gpxe/ib_smc.h
index bb9020bf..fdd1c9cc 100644
--- a/gpxe/src/include/gpxe/ib_smc.h
+++ b/gpxe/src/include/gpxe/ib_smc.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/infiniband.h>
typedef int ( * ib_local_mad_t ) ( struct ib_device *ibdev,
diff --git a/gpxe/src/include/gpxe/ib_srp.h b/gpxe/src/include/gpxe/ib_srp.h
new file mode 100644
index 00000000..cf705b30
--- /dev/null
+++ b/gpxe/src/include/gpxe/ib_srp.h
@@ -0,0 +1,79 @@
+#ifndef _GPXE_IB_SRP_H
+#define _GPXE_IB_SRP_H
+
+/** @file
+ *
+ * SCSI RDMA Protocol over Infiniband
+ *
+ */
+
+FILE_LICENCE ( BSD2 );
+
+#include <stdint.h>
+#include <gpxe/infiniband.h>
+#include <gpxe/srp.h>
+
+/** SRP initiator port identifier for Infiniband */
+struct ib_srp_initiator_port_id {
+ /** Identifier extension */
+ struct ib_gid_half id_ext;
+ /** IB channel adapter GUID */
+ struct ib_gid_half hca_guid;
+} __attribute__ (( packed ));
+
+/** SRP target port identifier for Infiniband */
+struct ib_srp_target_port_id {
+ /** Identifier extension */
+ struct ib_gid_half id_ext;
+ /** I/O controller GUID */
+ struct ib_gid_half ioc_guid;
+} __attribute__ (( packed ));
+
+/**
+ * Get Infiniband-specific initiator port ID
+ *
+ * @v port_ids SRP port IDs
+ * @ret initiator_port_id Infiniband-specific initiator port ID
+ */
+static inline __always_inline struct ib_srp_initiator_port_id *
+ib_srp_initiator_port_id ( struct srp_port_ids *port_ids ) {
+ return ( ( struct ib_srp_initiator_port_id * ) &port_ids->initiator );
+}
+
+/**
+ * Get Infiniband-specific target port ID
+ *
+ * @v port_ids SRP port IDs
+ * @ret target_port_id Infiniband-specific target port ID
+ */
+static inline __always_inline struct ib_srp_target_port_id *
+ib_srp_target_port_id ( struct srp_port_ids *port_ids ) {
+ return ( ( struct ib_srp_target_port_id * ) &port_ids->target );
+}
+
+/** Infiniband-specific SRP parameters */
+struct ib_srp_parameters {
+ /** Source GID */
+ struct ib_gid sgid;
+ /** Destination GID */
+ struct ib_gid dgid;
+ /** Service ID */
+ struct ib_gid_half service_id;
+ /** Partition key */
+ uint16_t pkey;
+};
+
+/**
+ * Get Infiniband-specific transport parameters
+ *
+ * @v srp SRP device
+ * @ret ib_params Infiniband-specific transport parameters
+ */
+static inline __always_inline struct ib_srp_parameters *
+ib_srp_params ( struct srp_device *srp ) {
+ return srp_transport_priv ( srp );
+}
+
+extern struct srp_transport_type ib_srp_transport;
+
+#endif /* _GPXE_IB_SRP_H */
diff --git a/gpxe/src/include/gpxe/icmp.h b/gpxe/src/include/gpxe/icmp.h
index 49ade2f2..bb8fce8b 100644
--- a/gpxe/src/include/gpxe/icmp.h
+++ b/gpxe/src/include/gpxe/icmp.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/** An ICMP header */
struct icmp_header {
/** Type */
diff --git a/gpxe/src/include/gpxe/icmp6.h b/gpxe/src/include/gpxe/icmp6.h
index 34093616..e8fd1eb3 100644
--- a/gpxe/src/include/gpxe/icmp6.h
+++ b/gpxe/src/include/gpxe/icmp6.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/ip6.h>
#include <gpxe/ndp.h>
diff --git a/gpxe/src/include/gpxe/ieee80211.h b/gpxe/src/include/gpxe/ieee80211.h
new file mode 100644
index 00000000..e5b10c30
--- /dev/null
+++ b/gpxe/src/include/gpxe/ieee80211.h
@@ -0,0 +1,1160 @@
+#ifndef _GPXE_IEEE80211_H
+#define _GPXE_IEEE80211_H
+
+#include <gpxe/if_ether.h> /* for ETH_ALEN */
+#include <endian.h>
+
+/** @file
+ * Constants and data structures defined in IEEE 802.11, subsetted
+ * according to what gPXE knows how to use.
+ */
+
+FILE_LICENCE(GPL2_OR_LATER);
+
+/* ---------- Maximum lengths of things ---------- */
+
+/**
+ * @defgroup ieee80211_maxlen Maximum lengths in the 802.11 protocol
+ * @{
+ */
+
+/** Maximum length of frame payload
+ *
+ * This does not include cryptographic overhead, which can be up to 20
+ * bytes, but it DOES include the 802.2 LLC/SNAP headers that are used
+ * on data frames (but not management frames).
+ */
+#define IEEE80211_MAX_DATA_LEN 2304
+
+/** Length of LLC/SNAP headers on data frames */
+#define IEEE80211_LLC_HEADER_LEN 8
+
+/** Maximum cryptographic overhead before encrypted data */
+#define IEEE80211_MAX_CRYPTO_HEADER 8
+
+/** Maximum cryptographic overhead after encrypted data
+ *
+ * This does not count the MIC in TKIP frames, since that is
+ * considered to be part of the MSDU and thus contributes to the size
+ * of the data field.
+ *
+ * It @e does count the MIC in CCMP frames, which is considered part
+ * of the MPDU (outside the data field).
+ */
+#define IEEE80211_MAX_CRYPTO_TRAILER 8
+
+/** Total maximum cryptographic overhead */
+#define IEEE80211_MAX_CRYPTO_OVERHEAD 16
+
+/** Bytes of network-layer data that can go into a regular data frame */
+#define IEEE80211_MAX_FRAME_DATA 2296
+
+/** Frame header length for frames we might work with
+ *
+ * QoS adds a two-byte field on top of this, and APs communicating
+ * with each other in Wireless Distribution System (WDS) mode add an
+ * extra 6-byte MAC address field, but we do not work with such
+ * frames.
+ */
+#define IEEE80211_TYP_FRAME_HEADER_LEN 24
+
+/** Theoretical maximum frame header length
+ *
+ * This includes the QoS and WDS Addr4 fields that we should never
+ * see.
+ */
+#define IEEE80211_MAX_FRAME_HEADER_LEN 32
+
+/** Maximum combined frame length
+ *
+ * The biggest frame will include 32 frame header bytes, 16 bytes of
+ * crypto overhead, and 2304 data bytes.
+ */
+#define IEEE80211_MAX_FRAME_LEN 2352
+
+/** Maximum length of an ESSID */
+#define IEEE80211_MAX_SSID_LEN 32
+
+/** @} */
+
+
+/* ---------- Frame Control defines ---------- */
+
+/**
+ * @defgroup ieee80211_fc 802.11 Frame Control field bits
+ * @{
+ */
+
+/** 802.11 Frame Control field, Version bitmask */
+#define IEEE80211_FC_VERSION 0x0003
+
+/** Expected value of Version bits in Frame Control */
+#define IEEE80211_THIS_VERSION 0x0000
+
+
+/** 802.11 Frame Control field, Frame Type bitmask */
+#define IEEE80211_FC_TYPE 0x000C
+
+/** Type value for management (layer-2) frames */
+#define IEEE80211_TYPE_MGMT 0x0000
+
+/** Type value for control (layer-1, hardware-managed) frames */
+#define IEEE80211_TYPE_CTRL 0x0004
+
+/** Type value for data frames */
+#define IEEE80211_TYPE_DATA 0x0008
+
+
+/** 802.11 Frame Control field, Frame Subtype bitmask */
+#define IEEE80211_FC_SUBTYPE 0x00F0
+
+/** Subtype value for association-request management frames
+ *
+ * Association request frames are sent after authentication from the
+ * client to the Access Point to establish the client as part of the
+ * Access Point's network.
+ */
+#define IEEE80211_STYPE_ASSOC_REQ 0x0000
+
+/** Subtype value for association-response management frames
+ *
+ * Association response frames are sent by the Access Point to confirm
+ * or deny the association requested in an association request frame.
+ */
+#define IEEE80211_STYPE_ASSOC_RESP 0x0010
+
+/** Subtype value for reassociation-request management frames
+ *
+ * Reassociation request frames are sent by clients wishing to change
+ * from one Access Point to another while roaming within the same
+ * extended network (same ESSID).
+ */
+#define IEEE80211_STYPE_REASSOC_REQ 0x0020
+
+/** Subtype value for reassociation-response management frames
+ *
+ * Reassociation response frames are sent by the Access Point to
+ * confirm or deny the swap requested in a reassociation request
+ * frame.
+ */
+#define IEEE80211_STYPE_REASSOC_RESP 0x0030
+
+/** Subtype value for probe-request management frames
+ *
+ * Probe request frames are sent by clients to request that all Access
+ * Points on the sending channel, or all belonging to a particular
+ * ESSID, identify themselves by BSSID, supported transfer rates, RF
+ * configuration, and other capabilities.
+ */
+#define IEEE80211_STYPE_PROBE_REQ 0x0040
+
+/** Subtype value for probe-response management frames
+ *
+ * Probe response frames are sent by Access Points in response to
+ * probe request frames, providing the requested information.
+ */
+#define IEEE80211_STYPE_PROBE_RESP 0x0050
+
+/** Subtype value for beacon management frames
+ *
+ * Beacon frames are sent by Access Points at regular intervals,
+ * usually ten per second, on the channel on which they communicate.
+ * They can be used to probe passively for access points on a channel
+ * where local regulatory restrictions prohibit active scanning, or
+ * due to their regularity as a mechanism to determine the fraction of
+ * packets that are being dropped.
+ */
+#define IEEE80211_STYPE_BEACON 0x0080
+
+/** Subtype value for disassociation management frames
+ *
+ * Disassociation frames are sent by either a client or an Access
+ * Point to unequivocally terminate the association between the two.
+ * They may be sent by clients upon leaving the network, or by an
+ * Access Point upon reconfiguration, among other reasons; they are
+ * usually more "polite" than deauthentication frames.
+ */
+#define IEEE80211_STYPE_DISASSOC 0x00A0
+
+/** Subtype value for authentication management frames
+ *
+ * Authentication frames are exchanged between a client and an Access
+ * Point before association may be performed. Confusingly, in the most
+ * common authentication method (Open System) no security tokens are
+ * exchanged at all. Modern 802.11 security handshaking takes place
+ * after association.
+ */
+#define IEEE80211_STYPE_AUTH 0x00B0
+
+/** Subtype value for deauthentication management frames
+ *
+ * Deauthentication frames are sent by either a client or an Access
+ * Point to terminate the authentication (and therefore also the
+ * association) between the two. They are generally more forceful than
+ * disassociation frames, sent for such reasons as a failure to
+ * set up security properly after associating.
+ */
+#define IEEE80211_STYPE_DEAUTH 0x00C0
+
+/** Subtype value for action management frames
+ *
+ * Action frames are used to implement spectrum management and QoS
+ * features that gPXE currently does not support.
+ */
+#define IEEE80211_STYPE_ACTION 0x00D0
+
+
+/** Subtype value for RTS (request to send) control frames */
+#define IEEE80211_STYPE_RTS 0x00B0
+
+/** Subtype value for CTS (clear to send) control frames */
+#define IEEE80211_STYPE_CTS 0x00C0
+
+/** Subtype value for ACK (acknowledgement) control frames */
+#define IEEE80211_STYPE_ACK 0x00D0
+
+
+/** Subtype value for ordinary data frames, with no QoS or CF add-ons */
+#define IEEE80211_STYPE_DATA 0x0000
+
+/** Subtype value for data frames containing no data */
+#define IEEE80211_STYPE_NODATA 0x0040
+
+
+/** 802.11 Frame Control field: To Data System flag
+ *
+ * This is set on data frames sent to an Access Point.
+ */
+#define IEEE80211_FC_TODS 0x0100
+
+/** 802.11 Frame Control field: From Data System flag
+ *
+ * This is set on data frames sent from an Access Point. If both TODS
+ * and FROMDS are set, the frame header is a 4-address format used for
+ * inter-Access Point communication.
+ */
+#define IEEE80211_FC_FROMDS 0x0200
+
+/** 802.11 Frame Control field: More Fragments flag */
+#define IEEE80211_FC_MORE_FRAG 0x0400
+
+/** 802.11 Frame Control field: Retransmission flag */
+#define IEEE80211_FC_RETRY 0x0800
+
+/** 802.11 Frame Control field: Power Managed flag
+ *
+ * This is set on any frame sent by a low-power station that will go
+ * into a power-saving mode immediately after this frame. Access
+ * Points are not allowed to act as low-power stations.
+ */
+#define IEEE80211_FC_PWR_MGMT 0x1000
+
+/** 802.11 Frame Control field: More Data flag
+ *
+ * This is set on any frame sent by a station that has more data
+ * queued to be sent than is in the frame.
+ */
+#define IEEE80211_FC_MORE_DATA 0x2000
+
+/** 802.11 Frame Control field: Protected flag
+ *
+ * This is set on frames in which data is encrypted (by any method).
+ */
+#define IEEE80211_FC_PROTECTED 0x4000
+
+/** 802.11 Frame Control field: Ordered flag [?] */
+#define IEEE80211_FC_ORDER 0x8000
+
+/** @} */
+
+
+/* ---------- Sequence Control defines ---------- */
+
+/**
+ * @defgroup ieee80211_seq 802.11 Sequence Control field handling
+ * @{
+ */
+
+/** Extract sequence number from 802.11 Sequence Control field */
+#define IEEE80211_SEQNR( seq ) ( ( seq ) >> 4 )
+
+/** Extract fragment number from 802.11 Sequence Control field */
+#define IEEE80211_FRAG( seq ) ( ( seq ) & 0x000F )
+
+/** Make 802.11 Sequence Control field from sequence and fragment numbers */
+#define IEEE80211_MAKESEQ( seqnr, frag ) \
+ ( ( ( ( seqnr ) & 0xFFF ) << 4 ) | ( ( frag ) & 0xF ) )
+
+/** @} */
+
+
+/* ---------- Frame header formats ---------- */
+
+/**
+ * @defgroup ieee80211_hdr 802.11 frame header formats
+ * @{
+ */
+
+/** An 802.11 data or management frame without QoS or WDS header fields */
+struct ieee80211_frame
+{
+ u16 fc; /**< 802.11 Frame Control field */
+ u16 duration; /**< Microseconds to reserve link */
+ u8 addr1[ETH_ALEN]; /**< Address 1 (immediate receiver) */
+ u8 addr2[ETH_ALEN]; /**< Address 2 (immediate sender) */
+ u8 addr3[ETH_ALEN]; /**< Address 3 (often "forward to") */
+ u16 seq; /**< 802.11 Sequence Control field */
+ u8 data[0]; /**< Beginning of frame data */
+} __attribute__((packed));
+
+/** The 802.2 LLC/SNAP header sent before actual data in a data frame
+ *
+ * This header is not acknowledged in the 802.11 standard at all; it
+ * is treated just like data for MAC-layer purposes, including
+ * fragmentation and encryption. It is actually two headers
+ * concatenated: a three-byte 802.2 LLC header indicating Subnetwork
+ * Accesss Protocol (SNAP) in both source and destination Service
+ * Access Point (SAP) fields, and a five-byte SNAP header indicating a
+ * zero OUI and two-byte Ethernet protocol type field.
+ *
+ * Thus, an eight-byte header in which six of the bytes are redundant.
+ * Lovely, isn't it?
+ */
+struct ieee80211_llc_snap_header
+{
+ /* LLC part: */
+ u8 dsap; /**< Destination SAP ID */
+ u8 ssap; /**< Source SAP ID */
+ u8 ctrl; /**< Control information */
+
+ /* SNAP part: */
+ u8 oui[3]; /**< Organization code, usually 0 */
+ u16 ethertype; /**< Ethernet Type field */
+} __attribute__((packed));
+
+/** Value for DSAP field in 802.2 LLC header for 802.11 frames: SNAP */
+#define IEEE80211_LLC_DSAP 0xAA
+
+/** Value for SSAP field in 802.2 LLC header for 802.11 frames: SNAP */
+#define IEEE80211_LLC_SSAP 0xAA
+
+/** Value for control field in 802.2 LLC header for 802.11 frames
+ *
+ * "Unnumbered Information".
+ */
+#define IEEE80211_LLC_CTRL 0x03
+
+
+/** 16-byte RTS frame format, with abbreviated header */
+struct ieee80211_rts
+{
+ u16 fc; /**< 802.11 Frame Control field */
+ u16 duration; /**< Microseconds to reserve link */
+ u8 addr1[ETH_ALEN]; /**< Address 1 (immediate receiver) */
+ u8 addr2[ETH_ALEN]; /**< Address 2 (immediate sender) */
+} __attribute__((packed));
+
+/** Length of 802.11 RTS control frame */
+#define IEEE80211_RTS_LEN 16
+
+/** 10-byte CTS or ACK frame format, with abbreviated header */
+struct ieee80211_cts_or_ack
+{
+ u16 fc; /**< 802.11 Frame Control field */
+ u16 duration; /**< Microseconds to reserve link */
+ u8 addr1[ETH_ALEN]; /**< Address 1 (immediate receiver) */
+} __attribute__((packed));
+
+#define ieee80211_cts ieee80211_cts_or_ack
+#define ieee80211_ack ieee80211_cts_or_ack
+
+/** Length of 802.11 CTS control frame */
+#define IEEE80211_CTS_LEN 10
+
+/** Length of 802.11 ACK control frame */
+#define IEEE80211_ACK_LEN 10
+
+/** @} */
+
+
+/* ---------- Capability bits, status and reason codes ---------- */
+
+/**
+ * @defgroup ieee80211_capab 802.11 management frame capability field bits
+ * @{
+ */
+
+/** Set if using an Access Point (managed mode) */
+#define IEEE80211_CAPAB_MANAGED 0x0001
+
+/** Set if operating in IBSS (no-AP, "Ad-Hoc") mode */
+#define IEEE80211_CAPAB_ADHOC 0x0002
+
+/** Set if we support Contention-Free Period operation */
+#define IEEE80211_CAPAB_CFPOLL 0x0004
+
+/** Set if we wish to be polled for Contention-Free operation */
+#define IEEE80211_CAPAB_CFPR 0x0008
+
+/** Set if the network is encrypted (by any method) */
+#define IEEE80211_CAPAB_PRIVACY 0x0010
+
+/** Set if PHY supports short preambles on 802.11b */
+#define IEEE80211_CAPAB_SHORT_PMBL 0x0020
+
+/** Set if PHY supports PBCC modulation */
+#define IEEE80211_CAPAB_PBCC 0x0040
+
+/** Set if we support Channel Agility */
+#define IEEE80211_CAPAB_CHAN_AGILITY 0x0080
+
+/** Set if we support spectrum management (DFS and TPC) on the 5GHz band */
+#define IEEE80211_CAPAB_SPECTRUM_MGMT 0x0100
+
+/** Set if we support Quality of Service enhancements */
+#define IEEE80211_CAPAB_QOS 0x0200
+
+/** Set if PHY supports short slot time on 802.11g */
+#define IEEE80211_CAPAB_SHORT_SLOT 0x0400
+
+/** Set if PHY supports APSD option */
+#define IEEE80211_CAPAB_APSD 0x0800
+
+/** Set if PHY supports DSSS/OFDM modulation (one way of 802.11 b/g mixing) */
+#define IEEE80211_CAPAB_DSSS_OFDM 0x2000
+
+/** Set if we support delayed block ACK */
+#define IEEE80211_CAPAB_DELAYED_BACK 0x4000
+
+/** Set if we support immediate block ACK */
+#define IEEE80211_CAPAB_IMMED_BACK 0x8000
+
+/** @} */
+
+
+/**
+ * @defgroup ieee80211_status 802.11 status codes
+ *
+ * These are returned to indicate an immediate denial of
+ * authentication or association. In gPXE, the lower 5 bits of the
+ * status code are encoded into the file-unique portion of an error
+ * code, the ERRFILE portion is always @c ERRFILE_net80211, and the
+ * POSIX error code is @c ECONNREFUSED for status 0-31 or @c
+ * EHOSTUNREACH for status 32-63.
+ *
+ * For a complete table with non-abbreviated error messages, see IEEE
+ * Std 802.11-2007, Table 7-23, p.94.
+ *
+ * @{
+ */
+
+#define IEEE80211_STATUS_SUCCESS 0
+#define IEEE80211_STATUS_FAILURE 1
+#define IEEE80211_STATUS_CAPAB_UNSUPP 10
+#define IEEE80211_STATUS_REASSOC_INVALID 11
+#define IEEE80211_STATUS_ASSOC_DENIED 12
+#define IEEE80211_STATUS_AUTH_ALGO_UNSUPP 13
+#define IEEE80211_STATUS_AUTH_SEQ_INVALID 14
+#define IEEE80211_STATUS_AUTH_CHALL_INVALID 15
+#define IEEE80211_STATUS_AUTH_TIMEOUT 16
+#define IEEE80211_STATUS_ASSOC_NO_ROOM 17
+#define IEEE80211_STATUS_ASSOC_NEED_RATE 18
+#define IEEE80211_STATUS_ASSOC_NEED_SHORT_PMBL 19
+#define IEEE80211_STATUS_ASSOC_NEED_PBCC 20
+#define IEEE80211_STATUS_ASSOC_NEED_CHAN_AGILITY 21
+#define IEEE80211_STATUS_ASSOC_NEED_SPECTRUM_MGMT 22
+#define IEEE80211_STATUS_ASSOC_BAD_POWER 23
+#define IEEE80211_STATUS_ASSOC_BAD_CHANNELS 24
+#define IEEE80211_STATUS_ASSOC_NEED_SHORT_SLOT 25
+#define IEEE80211_STATUS_ASSOC_NEED_DSSS_OFDM 26
+#define IEEE80211_STATUS_QOS_FAILURE 32
+#define IEEE80211_STATUS_QOS_NO_ROOM 33
+#define IEEE80211_STATUS_LINK_IS_HORRIBLE 34
+#define IEEE80211_STATUS_ASSOC_NEED_QOS 35
+#define IEEE80211_STATUS_REQUEST_DECLINED 37
+#define IEEE80211_STATUS_REQUEST_INVALID 38
+#define IEEE80211_STATUS_TS_NOT_CREATED_AGAIN 39
+#define IEEE80211_STATUS_INVALID_IE 40
+#define IEEE80211_STATUS_GROUP_CIPHER_INVALID 41
+#define IEEE80211_STATUS_PAIR_CIPHER_INVALID 42
+#define IEEE80211_STATUS_AKMP_INVALID 43
+#define IEEE80211_STATUS_RSN_VERSION_UNSUPP 44
+#define IEEE80211_STATUS_RSN_CAPAB_INVALID 45
+#define IEEE80211_STATUS_CIPHER_REJECTED 46
+#define IEEE80211_STATUS_TS_NOT_CREATED_WAIT 47
+#define IEEE80211_STATUS_DIRECT_LINK_FORBIDDEN 48
+#define IEEE80211_STATUS_DEST_NOT_PRESENT 49
+#define IEEE80211_STATUS_DEST_NOT_QOS 50
+#define IEEE80211_STATUS_ASSOC_LISTEN_TOO_HIGH 51
+
+/** @} */
+
+
+
+/**
+ * @defgroup ieee80211_reason 802.11 reason codes
+ *
+ * These are returned to indicate the reason for a deauthentication or
+ * disassociation sent (usually) after authentication or association
+ * had succeeded. In gPXE, the lower 5 bits of the reason code are
+ * encoded into the file-unique portion of an error code, the ERRFILE
+ * portion is always @c ERRFILE_net80211, and the POSIX error code is
+ * @c ECONNRESET for reason 0-31 or @c ENETRESET for reason 32-63.
+ *
+ * For a complete table with non-abbreviated error messages, see IEEE
+ * Std 802.11-2007, Table 7-22, p.92.
+ *
+ * @{
+ */
+
+#define IEEE80211_REASON_NONE 0
+#define IEEE80211_REASON_UNSPECIFIED 1
+#define IEEE80211_REASON_AUTH_NO_LONGER_VALID 2
+#define IEEE80211_REASON_LEAVING 3
+#define IEEE80211_REASON_INACTIVITY 4
+#define IEEE80211_REASON_OUT_OF_RESOURCES 5
+#define IEEE80211_REASON_NEED_AUTH 6
+#define IEEE80211_REASON_NEED_ASSOC 7
+#define IEEE80211_REASON_LEAVING_TO_ROAM 8
+#define IEEE80211_REASON_REASSOC_INVALID 9
+#define IEEE80211_REASON_BAD_POWER 10
+#define IEEE80211_REASON_BAD_CHANNELS 11
+#define IEEE80211_REASON_INVALID_IE 13
+#define IEEE80211_REASON_MIC_FAILURE 14
+#define IEEE80211_REASON_4WAY_TIMEOUT 15
+#define IEEE80211_REASON_GROUPKEY_TIMEOUT 16
+#define IEEE80211_REASON_4WAY_INVALID 17
+#define IEEE80211_REASON_GROUP_CIPHER_INVALID 18
+#define IEEE80211_REASON_PAIR_CIPHER_INVALID 19
+#define IEEE80211_REASON_AKMP_INVALID 20
+#define IEEE80211_REASON_RSN_VERSION_INVALID 21
+#define IEEE80211_REASON_RSN_CAPAB_INVALID 22
+#define IEEE80211_REASON_8021X_FAILURE 23
+#define IEEE80211_REASON_CIPHER_REJECTED 24
+#define IEEE80211_REASON_QOS_UNSPECIFIED 32
+#define IEEE80211_REASON_QOS_OUT_OF_RESOURCES 33
+#define IEEE80211_REASON_LINK_IS_HORRIBLE 34
+#define IEEE80211_REASON_INVALID_TXOP 35
+#define IEEE80211_REASON_REQUESTED_LEAVING 36
+#define IEEE80211_REASON_REQUESTED_NO_USE 37
+#define IEEE80211_REASON_REQUESTED_NEED_SETUP 38
+#define IEEE80211_REASON_REQUESTED_TIMEOUT 39
+#define IEEE80211_REASON_CIPHER_UNSUPPORTED 45
+
+/** @} */
+
+/* ---------- Information element declarations ---------- */
+
+/**
+ * @defgroup ieee80211_ie 802.11 information elements
+ *
+ * Many management frames include a section that amounts to a
+ * concatenation of these information elements, so that the sender can
+ * choose which information to send and the receiver can ignore the
+ * parts it doesn't understand. Each IE contains a two-byte header,
+ * one byte ID and one byte length, followed by IE-specific data. The
+ * length does not include the two-byte header. Information elements
+ * are required to be sorted by ID, but gPXE does not require that in
+ * those it receives.
+ *
+ * This group also includes a few inline functions to simplify common
+ * tasks in IE processing.
+ *
+ * @{
+ */
+
+/** Generic 802.11 information element header */
+struct ieee80211_ie_header {
+ u8 id; /**< Information element ID */
+ u8 len; /**< Information element length */
+} __attribute__ ((packed));
+
+
+/** 802.11 SSID information element */
+struct ieee80211_ie_ssid {
+ u8 id; /**< SSID ID: 0 */
+ u8 len; /**< SSID length */
+ char ssid[0]; /**< SSID data, not NUL-terminated */
+} __attribute__ ((packed));
+
+/** Information element ID for SSID information element */
+#define IEEE80211_IE_SSID 0
+
+
+/** 802.11 rates information element
+ *
+ * The first 8 rates go in an IE of type RATES (1), and any more rates
+ * go in one of type EXT_RATES (50). Each rate is a byte with the low
+ * 7 bits equal to the rate in units of 500 kbps, and the high bit set
+ * if and only if the rate is "basic" (must be supported by all
+ * connected stations).
+ */
+struct ieee80211_ie_rates {
+ u8 id; /**< Rates ID: 1 or 50 */
+ u8 len; /**< Number of rates */
+ u8 rates[0]; /**< Rates data, one rate per byte */
+} __attribute__ ((packed));
+
+/** Information element ID for rates information element */
+#define IEEE80211_IE_RATES 1
+
+/** Information element ID for extended rates information element */
+#define IEEE80211_IE_EXT_RATES 50
+
+
+/** 802.11 Direct Spectrum parameter information element
+ *
+ * This just contains the channel number. It has the fancy name
+ * because IEEE 802.11 also defines a frequency-hopping PHY that
+ * changes channels at regular intervals following a predetermined
+ * pattern; in practice nobody uses the FH PHY.
+ */
+struct ieee80211_ie_ds_param {
+ u8 id; /**< DS parameter ID: 3 */
+ u8 len; /**< DS parameter length: 1 */
+ u8 current_channel; /**< Current channel number, 1-14 */
+} __attribute__ ((packed));
+
+/** Information element ID for Direct Spectrum parameter information element */
+#define IEEE80211_IE_DS_PARAM 3
+
+
+/** 802.11 Country information element regulatory extension triplet */
+struct ieee80211_ie_country_ext_triplet {
+ u8 reg_ext_id; /**< Regulatory extension ID */
+ u8 reg_class_id; /**< Regulatory class ID */
+ u8 coverage_class; /**< Coverage class */
+} __attribute__ ((packed));
+
+/** 802.11 Country information element regulatory band triplet */
+struct ieee80211_ie_country_band_triplet {
+ u8 first_channel; /**< Channel number for first channel in band */
+ u8 nr_channels; /**< Number of contiguous channels in band */
+ u8 max_txpower; /**< Maximum TX power in dBm */
+} __attribute__ ((packed));
+
+/** 802.11 Country information element regulatory triplet
+ *
+ * It is a band triplet if the first byte is 200 or less, and a
+ * regulatory extension triplet otherwise.
+ */
+union ieee80211_ie_country_triplet {
+ /** Differentiator between band and ext triplets */
+ u8 first;
+
+ /** Information about a band of channels */
+ struct ieee80211_ie_country_band_triplet band;
+
+ /** Regulatory extension information */
+ struct ieee80211_ie_country_ext_triplet ext;
+};
+
+/** 802.11 Country information element
+ *
+ * This contains some data about RF regulations.
+ */
+struct ieee80211_ie_country {
+ u8 id; /**< Country information ID: 7 */
+ u8 len; /**< Country information length: varies */
+ char name[2]; /**< ISO Alpha2 country code */
+ char in_out; /**< 'I' for indoor, 'O' for outdoor */
+
+ /** List of regulatory triplets */
+ union ieee80211_ie_country_triplet triplet[0];
+} __attribute__ ((packed));
+
+/** Information element ID for Country information element */
+#define IEEE80211_IE_COUNTRY 7
+
+
+/** 802.11 Request information element
+ *
+ * This contains a list of information element types we would like to
+ * be included in probe response frames.
+ */
+struct ieee80211_ie_request {
+ u8 id; /**< Request ID: 10 */
+ u8 len; /**< Number of IEs requested */
+ u8 request[0]; /**< List of IEs requested */
+} __attribute__ ((packed));
+
+/** Information element ID for Request information element */
+#define IEEE80211_IE_REQUEST 10
+
+
+/** 802.11 Challenge Text information element
+ *
+ * This is used in authentication frames under Shared Key
+ * authentication.
+ */
+struct ieee80211_ie_challenge_text {
+ u8 id; /**< Challenge Text ID: 16 */
+ u8 len; /**< Challenge Text length: usually 128 */
+ u8 challenge_text[0]; /**< Challenge Text data */
+} __attribute__ ((packed));
+
+/** Information element ID for Challenge Text information element */
+#define IEEE80211_IE_CHALLENGE_TEXT 16
+
+
+/** 802.11 Power Constraint information element
+ *
+ * This is used to specify an additional power limitation on top of
+ * the Country requirements.
+ */
+struct ieee80211_ie_power_constraint {
+ u8 id; /**< Power Constraint ID: 52 */
+ u8 len; /**< Power Constraint length: 1 */
+ u8 power_constraint; /**< Decrease in allowed TX power, dBm */
+} __attribute__ ((packed));
+
+/** Information element ID for Power Constraint information element */
+#define IEEE80211_IE_POWER_CONSTRAINT 52
+
+
+/** 802.11 Power Capability information element
+ *
+ * This is used in association request frames to indicate the extremes
+ * of our TX power abilities. It is required only if we indicate
+ * support for spectrum management.
+ */
+struct ieee80211_ie_power_capab {
+ u8 id; /**< Power Capability ID: 33 */
+ u8 len; /**< Power Capability length: 2 */
+ u8 min_txpower; /**< Minimum possible TX power, dBm */
+ u8 max_txpower; /**< Maximum possible TX power, dBm */
+} __attribute__ ((packed));
+
+/** Information element ID for Power Capability information element */
+#define IEEE80211_IE_POWER_CAPAB 33
+
+
+/** 802.11 Channels information element channel band tuple */
+struct ieee80211_ie_channels_channel_band {
+ u8 first_channel; /**< Channel number of first channel in band */
+ u8 nr_channels; /**< Number of channels in band */
+} __attribute__ ((packed));
+
+/** 802.11 Channels information element
+ *
+ * This is used in association frames to indicate the channels we can
+ * use. It is required only if we indicate support for spectrum
+ * management.
+ */
+struct ieee80211_ie_channels {
+ u8 id; /**< Channels ID: 36 */
+ u8 len; /**< Channels length: 2 */
+
+ /** List of (start, length) channel bands we can use */
+ struct ieee80211_ie_channels_channel_band channels[0];
+} __attribute__ ((packed));
+
+/** Information element ID for Channels information element */
+#define IEEE80211_IE_CHANNELS 36
+
+
+/** 802.11 ERP Information information element
+ *
+ * This is used to communicate some PHY-level flags.
+ */
+struct ieee80211_ie_erp_info {
+ u8 id; /**< ERP Information ID: 42 */
+ u8 len; /**< ERP Information length: 1 */
+ u8 erp_info; /**< ERP flags */
+} __attribute__ ((packed));
+
+/** Information element ID for ERP Information information element */
+#define IEEE80211_IE_ERP_INFO 42
+
+/** ERP information element: Flag set if 802.11b stations are present */
+#define IEEE80211_ERP_NONERP_PRESENT 0x01
+
+/** ERP information element: Flag set if CTS protection must be used */
+#define IEEE80211_ERP_USE_PROTECTION 0x02
+
+/** ERP information element: Flag set if long preambles must be used */
+#define IEEE80211_ERP_BARKER_LONG 0x04
+
+
+/** 802.11 Robust Security Network ("WPA") information element
+ *
+ * Showing once again a striking clarity of design, the IEEE folks put
+ * dynamically-sized data in the middle of this structure. As such,
+ * the below structure definition only works for IEs we create
+ * ourselves, which always have one pairwise cipher and one AKM;
+ * received IEs should be parsed piecemeal.
+ *
+ * Also inspired was IEEE's choice of 16-bit fields to count the
+ * number of 4-byte elements in a structure with a maximum length of
+ * 255 bytes.
+ *
+ * Many fields reference a cipher or authentication-type ID; this is a
+ * three-byte OUI followed by one byte identifying the cipher with
+ * respect to that OUI. For all standard ciphers the OUI is 00:0F:AC,
+ * except in old-style WPA IEs encapsulated in vendor-specific IEs,
+ * where it's 00:50:F2.
+ */
+struct ieee80211_ie_rsn {
+ /** Information element ID */
+ u8 id;
+
+ /** Information element length */
+ u8 len;
+
+ /** RSN information element version */
+ u16 version;
+
+ /** Cipher ID for the cipher used in multicast/broadcast frames */
+ u32 group_cipher;
+
+ /** Number of unicast ciphers supported */
+ u16 pairwise_count;
+
+ /** List of cipher IDs for supported unicast frame ciphers */
+ u32 pairwise_cipher[1];
+
+ /** Number of authentication types supported */
+ u16 akm_count;
+
+ /** List of authentication type IDs for supported types */
+ u32 akm_list[1];
+
+ /** Security capabilities field (RSN only) */
+ u16 rsn_capab;
+
+ /** Number of PMKIDs included (present only in association frames) */
+ u16 pmkid_count;
+
+ /** List of PMKIDs included, each a 16-byte SHA1 hash */
+ u8 pmkid_list[0];
+} __attribute__((packed));
+
+/** Information element ID for Robust Security Network information element */
+#define IEEE80211_IE_RSN 48
+
+/** Calculate necessary size of RSN information element
+ *
+ * @v npair Number of pairwise ciphers supported
+ * @v nauth Number of authentication types supported
+ * @v npmkid Number of PMKIDs to include
+ * @v is_rsn If TRUE, calculate RSN IE size; if FALSE, calculate WPA IE size
+ * @ret size Necessary size of IE, including header bytes
+ */
+static inline size_t ieee80211_rsn_size ( int npair, int nauth, int npmkid,
+ int rsn_ie ) {
+ return 16 + 4 * ( npair + nauth ) + 16 * npmkid - 4 * ! rsn_ie;
+}
+
+/** Make OUI plus type byte into 32-bit integer for easy comparison */
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define _MKOUI( a, b, c, t ) \
+ ( ( ( a ) << 24 ) | ( ( b ) << 16 ) | ( ( c ) << 8 ) | ( d ) )
+#define OUI_ORG_MASK 0xFFFFFF00
+#define OUI_TYPE_MASK 0x000000FF
+#else
+#define _MKOUI( a, b, c, t ) \
+ ( ( ( t ) << 24 ) | ( ( c ) << 16 ) | ( ( b ) << 8 ) | ( a ) )
+#define OUI_ORG_MASK 0x00FFFFFF
+#define OUI_TYPE_MASK 0xFF000000
+#endif
+
+/** Organization part for OUIs in standard RSN IE */
+#define IEEE80211_RSN_OUI _MKOUI ( 0x00, 0x0F, 0xAC, 0 )
+
+/** Organization part for OUIs in old WPA IE */
+#define IEEE80211_WPA_OUI _MKOUI ( 0x00, 0x50, 0xF2, 0 )
+
+/** Old vendor-type WPA IE OUI type + subtype */
+#define IEEE80211_WPA_OUI_VEN _MKOUI ( 0x00, 0x50, 0xF2, 0x01 )
+
+
+/** 802.11 RSN IE: expected version number */
+#define IEEE80211_RSN_VERSION 1
+
+/** 802.11 RSN IE: cipher type for 40-bit WEP */
+#define IEEE80211_RSN_CTYPE_WEP40 _MKOUI ( 0, 0, 0, 0x01 )
+
+/** 802.11 RSN IE: cipher type for 104-bit WEP */
+#define IEEE80211_RSN_CTYPE_WEP104 _MKOUI ( 0, 0, 0, 0x05 )
+
+/** 802.11 RSN IE: cipher type for TKIP ("WPA") */
+#define IEEE80211_RSN_CTYPE_TKIP _MKOUI ( 0, 0, 0, 0x02 )
+
+/** 802.11 RSN IE: cipher type for CCMP ("WPA2") */
+#define IEEE80211_RSN_CTYPE_CCMP _MKOUI ( 0, 0, 0, 0x04 )
+
+/** 802.11 RSN IE: cipher type for "use group"
+ *
+ * This can only appear as a pairwise cipher, and means unicast frames
+ * should be encrypted in the same way as broadcast/multicast frames.
+ */
+#define IEEE80211_RSN_CTYPE_USEGROUP _MKOUI ( 0, 0, 0, 0x00 )
+
+/** 802.11 RSN IE: auth method type for using an 802.1X server */
+#define IEEE80211_RSN_ATYPE_8021X _MKOUI ( 0, 0, 0, 0x01 )
+
+/** 802.11 RSN IE: auth method type for using a pre-shared key */
+#define IEEE80211_RSN_ATYPE_PSK _MKOUI ( 0, 0, 0, 0x02 )
+
+/** 802.11 RSN IE capabilities: AP supports pre-authentication */
+#define IEEE80211_RSN_CAPAB_PREAUTH 0x001
+
+/** 802.11 RSN IE capabilities: Node has conflict between TKIP and WEP
+ *
+ * This is a legacy issue; APs always set it to 0, and gPXE sets it to
+ * 0.
+ */
+#define IEEE80211_RSN_CAPAB_NO_PAIRWISE 0x002
+
+/** 802.11 RSN IE capabilities: Number of PTKSA replay counters
+ *
+ * A value of 0 means one replay counter, 1 means two, 2 means four,
+ * and 3 means sixteen.
+ */
+#define IEEE80211_RSN_CAPAB_PTKSA_REPLAY 0x00C
+
+/** 802.11 RSN IE capabilities: Number of GTKSA replay counters
+ *
+ * A value of 0 means one replay counter, 1 means two, 2 means four,
+ * and 3 means sixteen.
+ */
+#define IEEE80211_RSN_CAPAB_GTKSA_REPLAY 0x030
+
+/** 802.11 RSN IE capabilities: PeerKey Handshaking is suported */
+#define IEEE80211_RSN_CAPAB_PEERKEY 0x200
+
+
+/** 802.11 RSN IE capabilities: One replay counter
+ *
+ * This should be AND'ed with @c IEEE80211_RSN_CAPAB_PTKSA_REPLAY or
+ * @c IEEE80211_RSN_CAPAB_GTKSA_REPLAY (or both) to produce a value
+ * which can be OR'ed into the capabilities field.
+ */
+#define IEEE80211_RSN_1_CTR 0x000
+
+/** 802.11 RSN IE capabilities: Two replay counters */
+#define IEEE80211_RSN_2_CTR 0x014
+
+/** 802.11 RSN IE capabilities: Four replay counters */
+#define IEEE80211_RSN_4_CTR 0x028
+
+/** 802.11 RSN IE capabilities: 16 replay counters */
+#define IEEE80211_RSN_16_CTR 0x03C
+
+
+/** 802.11 Vendor Specific information element
+ *
+ * One often sees the RSN IE masquerading as vendor-specific on
+ * devices that were produced prior to 802.11i (the WPA amendment)
+ * being finalized.
+ */
+struct ieee80211_ie_vendor {
+ u8 id; /**< Vendor-specific ID: 221 */
+ u8 len; /**< Vendor-specific length: variable */
+ u32 oui; /**< OUI and vendor-specific type byte */
+ u8 data[0]; /**< Vendor-specific data */
+} __attribute__ ((packed));
+
+/** Information element ID for Vendor Specific information element */
+#define IEEE80211_IE_VENDOR 221
+
+
+
+
+/** Any 802.11 information element
+ *
+ * This is formatted for ease of use, so IEs with complex structures
+ * get referenced in full, while those with only one byte of data or a
+ * simple array are pulled in to avoid a layer of indirection like
+ * ie->channels.channels[0].
+ */
+union ieee80211_ie
+{
+ /** Generic and simple information element info */
+ struct {
+ u8 id; /**< Information element ID */
+ u8 len; /**< Information element data length */
+ union {
+ char ssid[0]; /**< SSID text */
+ u8 rates[0]; /**< Rates data */
+ u8 request[0]; /**< Request list */
+ u8 challenge_text[0]; /**< Challenge text data */
+ u8 power_constraint; /**< Power constraint, dBm */
+ u8 erp_info; /**< ERP information flags */
+ /** List of channels */
+ struct ieee80211_ie_channels_channel_band channels[0];
+ };
+ };
+
+ /** DS parameter set */
+ struct ieee80211_ie_ds_param ds_param;
+
+ /** Country information */
+ struct ieee80211_ie_country country;
+
+ /** Power capability */
+ struct ieee80211_ie_power_capab power_capab;
+
+ /** Security information */
+ struct ieee80211_ie_rsn rsn;
+
+ /** Vendor-specific */
+ struct ieee80211_ie_vendor vendor;
+};
+
+/** Check that 802.11 information element is bounded by buffer
+ *
+ * @v ie Information element
+ * @v end End of buffer in which information element is stored
+ * @ret ok TRUE if the IE is completely contained within the buffer
+ */
+static inline int ieee80211_ie_bound ( union ieee80211_ie *ie, void *end )
+{
+ void *iep = ie;
+ return ( iep + 2 <= end && iep + 2 + ie->len <= end );
+}
+
+/** Advance to next 802.11 information element
+ *
+ * @v ie Current information element pointer
+ * @v end Pointer to first byte not in information element space
+ * @ret next Pointer to next information element, or NULL if no more
+ *
+ * When processing received IEs, @a end should be set to the I/O
+ * buffer tail pointer; when marshalling IEs for sending, @a end
+ * should be NULL.
+ */
+static inline union ieee80211_ie * ieee80211_next_ie ( union ieee80211_ie *ie,
+ void *end )
+{
+ void *next_ie_byte = ( void * ) ie + ie->len + 2;
+ union ieee80211_ie *next_ie = next_ie_byte;
+
+ if ( ! end )
+ return next_ie;
+
+ if ( ieee80211_ie_bound ( next_ie, end ) )
+ return next_ie;
+
+ return NULL;
+}
+
+/** @} */
+
+
+/* ---------- Management frame data formats ---------- */
+
+/**
+ * @defgroup ieee80211_mgmt_data Management frame data payloads
+ * @{
+ */
+
+/** Beacon or probe response frame data */
+struct ieee80211_beacon_or_probe_resp
+{
+ /** 802.11 TSFT value at frame send */
+ u64 timestamp;
+
+ /** Interval at which beacons are sent, in units of 1024 us */
+ u16 beacon_interval;
+
+ /** Capability flags */
+ u16 capability;
+
+ /** List of information elements */
+ union ieee80211_ie info_element[0];
+} __attribute__((packed));
+
+#define ieee80211_beacon ieee80211_beacon_or_probe_resp
+#define ieee80211_probe_resp ieee80211_beacon_or_probe_resp
+
+/** Disassociation or deauthentication frame data */
+struct ieee80211_disassoc_or_deauth
+{
+ /** Reason code */
+ u16 reason;
+} __attribute__((packed));
+
+#define ieee80211_disassoc ieee80211_disassoc_or_deauth
+#define ieee80211_deauth ieee80211_disassoc_or_deauth
+
+/** Association request frame data */
+struct ieee80211_assoc_req
+{
+ /** Capability flags */
+ u16 capability;
+
+ /** Interval at which we wake up, in units of the beacon interval */
+ u16 listen_interval;
+
+ /** List of information elements */
+ union ieee80211_ie info_element[0];
+} __attribute__((packed));
+
+/** Association or reassociation response frame data */
+struct ieee80211_assoc_or_reassoc_resp
+{
+ /** Capability flags */
+ u16 capability;
+
+ /** Status code */
+ u16 status;
+
+ /** Association ID */
+ u16 aid;
+
+ /** List of information elements */
+ union ieee80211_ie info_element[0];
+} __attribute__((packed));
+
+#define ieee80211_assoc_resp ieee80211_assoc_or_reassoc_resp
+#define ieee80211_reassoc_resp ieee80211_assoc_or_reassoc_resp
+
+/** Reassociation request frame data */
+struct ieee80211_reassoc_req
+{
+ /** Capability flags */
+ u16 capability;
+
+ /** Interval at which we wake up, in units of the beacon interval */
+ u16 listen_interval;
+
+ /** MAC address of current Access Point */
+ u8 current_addr[ETH_ALEN];
+
+ /** List of information elements */
+ union ieee80211_ie info_element[0];
+} __attribute__((packed));
+
+/** Probe request frame data */
+struct ieee80211_probe_req
+{
+ /** List of information elements */
+ union ieee80211_ie info_element[0];
+} __attribute__((packed));
+
+/** Authentication frame data */
+struct ieee80211_auth
+{
+ /** Authentication algorithm (Open System or Shared Key) */
+ u16 algorithm;
+
+ /** Sequence number of this frame; first from client to AP is 1 */
+ u16 tx_seq;
+
+ /** Status code */
+ u16 status;
+
+ /** List of information elements */
+ union ieee80211_ie info_element[0];
+} __attribute__((packed));
+
+/** Open System authentication algorithm */
+#define IEEE80211_AUTH_OPEN_SYSTEM 0
+
+/** Shared Key authentication algorithm */
+#define IEEE80211_AUTH_SHARED_KEY 1
+
+/** @} */
+
+#endif
diff --git a/gpxe/src/include/gpxe/if_arp.h b/gpxe/src/include/gpxe/if_arp.h
index 5b250337..932bb3b2 100644
--- a/gpxe/src/include/gpxe/if_arp.h
+++ b/gpxe/src/include/gpxe/if_arp.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
/* ARP protocol HARDWARE identifiers. */
diff --git a/gpxe/src/include/gpxe/if_ether.h b/gpxe/src/include/gpxe/if_ether.h
index 2f3f33d4..b96bee08 100644
--- a/gpxe/src/include/gpxe/if_ether.h
+++ b/gpxe/src/include/gpxe/if_ether.h
@@ -1,6 +1,8 @@
#ifndef _GPXE_IF_ETHER_H
#define _GPXE_IF_ETHER_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#define ETH_ALEN 6 /* Size of Ethernet address */
@@ -18,6 +20,7 @@
#define ETH_P_RARP 0x8035 /* Reverse Address resolution Protocol */
#define ETH_P_IPV6 0x86DD /* IPv6 over blueblook */
#define ETH_P_SLOW 0x8809 /* Ethernet slow protocols */
+#define ETH_P_EAPOL 0x888E /* 802.1X EAP over LANs */
#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
/** An Ethernet link-layer header */
diff --git a/gpxe/src/include/gpxe/image.h b/gpxe/src/include/gpxe/image.h
index b953e150..10db8af2 100644
--- a/gpxe/src/include/gpxe/image.h
+++ b/gpxe/src/include/gpxe/image.h
@@ -8,6 +8,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/tables.h>
#include <gpxe/list.h>
#include <gpxe/uaccess.h>
@@ -123,9 +125,11 @@ struct image_type {
*/
#define PROBE_PXE 03
+/** Executable or loadable image type table */
+#define IMAGE_TYPES __table ( struct image_type, "image_types" )
+
/** An executable or loadable image type */
-#define __image_type( probe_order ) \
- __table ( struct image_type, image_types, probe_order )
+#define __image_type( probe_order ) __table_entry ( IMAGE_TYPES, probe_order )
extern struct list_head images;
diff --git a/gpxe/src/include/gpxe/in.h b/gpxe/src/include/gpxe/in.h
index 831a6110..c313717c 100644
--- a/gpxe/src/include/gpxe/in.h
+++ b/gpxe/src/include/gpxe/in.h
@@ -1,13 +1,14 @@
#ifndef _GPXE_IN_H
#define _GPXE_IN_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/socket.h>
/* Protocol numbers */
#define IP_ICMP 1
-#define IP_IGMP 2
#define IP_TCP 6
#define IP_UDP 17
#define IP_ICMP6 58
diff --git a/gpxe/src/include/gpxe/infiniband.h b/gpxe/src/include/gpxe/infiniband.h
index 196b5950..d90b1c10 100644
--- a/gpxe/src/include/gpxe/infiniband.h
+++ b/gpxe/src/include/gpxe/infiniband.h
@@ -7,25 +7,88 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/refcnt.h>
#include <gpxe/device.h>
#include <gpxe/ib_packet.h>
#include <gpxe/ib_mad.h>
-/** Subnet administrator QPN */
-#define IB_SA_QPN 1
+/** Subnet management interface QPN */
+#define IB_QPN_SMI 0
+
+/** Subnet management interface queue key */
+#define IB_QKEY_SMI 0
+
+/** General service interface QPN */
+#define IB_QPN_GSI 1
+
+/** General service interface queue key */
+#define IB_QKEY_GSI 0x80010000UL
/** Broadcast QPN */
-#define IB_BROADCAST_QPN 0xffffffUL
+#define IB_QPN_BROADCAST 0xffffffUL
+
+/** QPN mask */
+#define IB_QPN_MASK 0xffffffUL
+
+/** Default Infiniband partition key */
+#define IB_PKEY_DEFAULT 0xffff
-/** Subnet administrator queue key */
-#define IB_GLOBAL_QKEY 0x80010000UL
+/** Infiniband partition key full membership flag */
+#define IB_PKEY_FULL 0x8000
+
+/**
+ * Maximum payload size
+ *
+ * This is currently hard-coded in various places (drivers, subnet
+ * management agent, etc.) to 2048.
+ */
+#define IB_MAX_PAYLOAD_SIZE 2048
struct ib_device;
struct ib_queue_pair;
struct ib_address_vector;
struct ib_completion_queue;
+struct ib_mad_interface;
+
+/** Infiniband transmission rates */
+enum ib_rate {
+ IB_RATE_2_5 = 2,
+ IB_RATE_10 = 3,
+ IB_RATE_30 = 4,
+ IB_RATE_5 = 5,
+ IB_RATE_20 = 6,
+ IB_RATE_40 = 7,
+ IB_RATE_60 = 8,
+ IB_RATE_80 = 9,
+ IB_RATE_120 = 10,
+};
+
+/** An Infiniband Address Vector */
+struct ib_address_vector {
+ /** Queue Pair Number */
+ unsigned long qpn;
+ /** Queue key
+ *
+ * Not specified for received packets.
+ */
+ unsigned long qkey;
+ /** Local ID */
+ unsigned int lid;
+ /** Rate
+ *
+ * Not specified for received packets.
+ */
+ enum ib_rate rate;
+ /** Service level */
+ unsigned int sl;
+ /** GID is present */
+ unsigned int gid_present;
+ /** GID, if present */
+ struct ib_gid gid;
+};
/** An Infiniband Work Queue */
struct ib_work_queue {
@@ -37,6 +100,8 @@ struct ib_work_queue {
struct ib_completion_queue *cq;
/** List of work queues on this completion queue */
struct list_head list;
+ /** Packet sequence number */
+ uint32_t psn;
/** Number of work queue entries */
unsigned int num_wqes;
/** Number of occupied work queue entries */
@@ -63,14 +128,31 @@ struct ib_multicast_gid {
struct ib_gid gid;
};
+/** An Infiniband queue pair type */
+enum ib_queue_pair_type {
+ IB_QPT_SMI,
+ IB_QPT_GSI,
+ IB_QPT_UD,
+ IB_QPT_RC,
+};
+
/** An Infiniband Queue Pair */
struct ib_queue_pair {
/** Containing Infiniband device */
struct ib_device *ibdev;
/** List of queue pairs on this Infiniband device */
struct list_head list;
- /** Queue Pair Number */
+ /** Queue pair number */
unsigned long qpn;
+ /** Externally-visible queue pair number
+ *
+ * This may differ from the real queue pair number (e.g. when
+ * the HCA cannot use the management QPNs 0 and 1 as hardware
+ * QPNs and needs to remap them).
+ */
+ unsigned long ext_qpn;
+ /** Queue pair type */
+ enum ib_queue_pair_type type;
/** Queue key */
unsigned long qkey;
/** Send queue */
@@ -79,41 +161,14 @@ struct ib_queue_pair {
struct ib_work_queue recv;
/** List of multicast GIDs */
struct list_head mgids;
+ /** Address vector */
+ struct ib_address_vector av;
/** Driver private data */
void *drv_priv;
/** Queue owner private data */
void *owner_priv;
};
-/** Infiniband queue pair modification flags */
-enum ib_queue_pair_mods {
- IB_MODIFY_QKEY = 0x0001,
-};
-
-/** An Infiniband Address Vector */
-struct ib_address_vector {
- /** Queue Pair Number */
- unsigned long qpn;
- /** Queue key
- *
- * Not specified for received packets.
- */
- unsigned long qkey;
- /** Local ID */
- unsigned int lid;
- /** Rate
- *
- * Not specified for received packets.
- */
- unsigned int rate;
- /** Service level */
- unsigned int sl;
- /** GID is present */
- unsigned int gid_present;
- /** GID, if present */
- struct ib_gid gid;
-};
-
/** Infiniband completion queue operations */
struct ib_completion_queue_operations {
/**
@@ -144,6 +199,10 @@ struct ib_completion_queue_operations {
/** An Infiniband Completion Queue */
struct ib_completion_queue {
+ /** Containing Infiniband device */
+ struct ib_device *ibdev;
+ /** List of completion queues on this Infiniband device */
+ struct list_head list;
/** Completion queue number */
unsigned long cqn;
/** Number of completion queue entries */
@@ -197,12 +256,10 @@ struct ib_device_operations {
*
* @v ibdev Infiniband device
* @v qp Queue pair
- * @v mod_list Modification list
* @ret rc Return status code
*/
int ( * modify_qp ) ( struct ib_device *ibdev,
- struct ib_queue_pair *qp,
- unsigned long mod_list );
+ struct ib_queue_pair *qp );
/** Destroy queue pair
*
* @v ibdev Infiniband device
@@ -290,6 +347,25 @@ struct ib_device_operations {
void ( * mcast_detach ) ( struct ib_device *ibdev,
struct ib_queue_pair *qp,
struct ib_gid *gid );
+ /** Set port information
+ *
+ * @v ibdev Infiniband device
+ * @v mad Set port information MAD
+ *
+ * This method is required only by adapters that do not have
+ * an embedded SMA.
+ */
+ int ( * set_port_info ) ( struct ib_device *ibdev, union ib_mad *mad );
+ /** Set partition key table
+ *
+ * @v ibdev Infiniband device
+ * @v mad Set partition key table MAD
+ *
+ * This method is required only by adapters that do not have
+ * an embedded SMA.
+ */
+ int ( * set_pkey_table ) ( struct ib_device *ibdev,
+ union ib_mad *mad );
};
/** An Infiniband device */
@@ -298,8 +374,12 @@ struct ib_device {
struct refcnt refcnt;
/** List of Infiniband devices */
struct list_head list;
+ /** List of open Infiniband devices */
+ struct list_head open_list;
/** Underlying device */
struct device *dev;
+ /** List of completion queues */
+ struct list_head cqs;
/** List of queue pairs */
struct list_head qps;
/** Infiniband operations */
@@ -311,10 +391,18 @@ struct ib_device {
/** Port state */
uint8_t port_state;
- /** Link width */
- uint8_t link_width;
- /** Link speed */
- uint8_t link_speed;
+ /** Link width supported */
+ uint8_t link_width_supported;
+ /** Link width enabled */
+ uint8_t link_width_enabled;
+ /** Link width active */
+ uint8_t link_width_active;
+ /** Link speed supported */
+ uint8_t link_speed_supported;
+ /** Link speed enabled */
+ uint8_t link_speed_enabled;
+ /** Link speed active */
+ uint8_t link_speed_active;
/** Port GID */
struct ib_gid gid;
/** Port LID */
@@ -326,8 +414,17 @@ struct ib_device {
/** Partition key */
uint16_t pkey;
- /** Outbound packet sequence number */
- uint32_t psn;
+ /** RDMA key
+ *
+ * This is a single key allowing unrestricted access to
+ * memory.
+ */
+ uint32_t rdma_key;
+
+ /** Subnet management interface */
+ struct ib_mad_interface *smi;
+ /** General services interface */
+ struct ib_mad_interface *gsi;
/** Driver private data */
void *drv_priv;
@@ -340,12 +437,14 @@ ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
struct ib_completion_queue_operations *op );
extern void ib_destroy_cq ( struct ib_device *ibdev,
struct ib_completion_queue *cq );
+extern void ib_poll_cq ( struct ib_device *ibdev,
+ struct ib_completion_queue *cq );
extern struct ib_queue_pair *
-ib_create_qp ( struct ib_device *ibdev, unsigned int num_send_wqes,
- struct ib_completion_queue *send_cq, unsigned int num_recv_wqes,
- struct ib_completion_queue *recv_cq, unsigned long qkey );
-extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp,
- unsigned long mod_list, unsigned long qkey );
+ib_create_qp ( struct ib_device *ibdev, enum ib_queue_pair_type type,
+ unsigned int num_send_wqes, struct ib_completion_queue *send_cq,
+ unsigned int num_recv_wqes,
+ struct ib_completion_queue *recv_cq );
+extern int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp );
extern void ib_destroy_qp ( struct ib_device *ibdev,
struct ib_queue_pair *qp );
extern struct ib_queue_pair * ib_find_qp_qpn ( struct ib_device *ibdev,
@@ -366,16 +465,26 @@ extern void ib_complete_recv ( struct ib_device *ibdev,
struct ib_queue_pair *qp,
struct ib_address_vector *av,
struct io_buffer *iobuf, int rc );
+extern void ib_refill_recv ( struct ib_device *ibdev,
+ struct ib_queue_pair *qp );
extern int ib_open ( struct ib_device *ibdev );
extern void ib_close ( struct ib_device *ibdev );
+extern int ib_link_rc ( struct ib_device *ibdev );
extern int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
struct ib_gid *gid );
extern void ib_mcast_detach ( struct ib_device *ibdev,
struct ib_queue_pair *qp, struct ib_gid *gid );
+extern int ib_get_hca_info ( struct ib_device *ibdev,
+ struct ib_gid_half *hca_guid );
+extern int ib_set_port_info ( struct ib_device *ibdev, union ib_mad *mad );
+extern int ib_set_pkey_table ( struct ib_device *ibdev, union ib_mad *mad );
extern struct ib_device * alloc_ibdev ( size_t priv_size );
extern int register_ibdev ( struct ib_device *ibdev );
extern void unregister_ibdev ( struct ib_device *ibdev );
+extern struct ib_device * find_ibdev ( struct ib_gid *gid );
+extern struct ib_device * last_opened_ibdev ( void );
extern void ib_link_state_changed ( struct ib_device *ibdev );
+extern void ib_poll_eq ( struct ib_device *ibdev );
extern struct list_head ib_devices;
/** Iterate over all network devices */
@@ -383,17 +492,6 @@ extern struct list_head ib_devices;
list_for_each_entry ( (ibdev), &ib_devices, list )
/**
- * Poll completion queue
- *
- * @v ibdev Infiniband device
- * @v cq Completion queue
- */
-static inline __always_inline void
-ib_poll_cq ( struct ib_device *ibdev, struct ib_completion_queue *cq ) {
- ibdev->op->poll_cq ( ibdev, cq );
-}
-
-/**
* Check link state
*
* @v ibdev Infiniband device
diff --git a/gpxe/src/include/gpxe/init.h b/gpxe/src/include/gpxe/init.h
index e0e9f9c8..a72cba7a 100644
--- a/gpxe/src/include/gpxe/init.h
+++ b/gpxe/src/include/gpxe/init.h
@@ -1,6 +1,8 @@
#ifndef _GPXE_INIT_H
#define _GPXE_INIT_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/tables.h>
/**
@@ -13,9 +15,11 @@ struct init_fn {
void ( * initialise ) ( void );
};
+/** Initialisation function table */
+#define INIT_FNS __table ( struct init_fn, "init_fns" )
+
/** Declare an initialisation functon */
-#define __init_fn( init_order ) \
- __table ( struct init_fn, init_fns, init_order )
+#define __init_fn( init_order ) __table_entry ( INIT_FNS, init_order )
/** @defgroup initfn_order Initialisation function ordering
* @{
@@ -49,9 +53,12 @@ struct startup_fn {
void ( * shutdown ) ( int flags );
};
+/** Startup/shutdown function table */
+#define STARTUP_FNS __table ( struct startup_fn, "startup_fns" )
+
/** Declare a startup/shutdown function */
#define __startup_fn( startup_order ) \
- __table ( struct startup_fn, startup_fns, startup_order )
+ __table_entry ( STARTUP_FNS, startup_order )
/** @defgroup startfn_order Startup/shutdown function ordering
*
diff --git a/gpxe/src/include/gpxe/interface.h b/gpxe/src/include/gpxe/interface.h
index 94c711a9..114ebf32 100644
--- a/gpxe/src/include/gpxe/interface.h
+++ b/gpxe/src/include/gpxe/interface.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/refcnt.h>
/** An object communication interface */
diff --git a/gpxe/src/include/gpxe/io.h b/gpxe/src/include/gpxe/io.h
index ebb8ba30..919823d9 100644
--- a/gpxe/src/include/gpxe/io.h
+++ b/gpxe/src/include/gpxe/io.h
@@ -16,6 +16,8 @@
* the address parameter.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/api.h>
#include <config/ioapi.h>
diff --git a/gpxe/src/include/gpxe/iobuf.h b/gpxe/src/include/gpxe/iobuf.h
index 6d1a58a4..8f05f9ea 100644
--- a/gpxe/src/include/gpxe/iobuf.h
+++ b/gpxe/src/include/gpxe/iobuf.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <assert.h>
#include <gpxe/list.h>
diff --git a/gpxe/src/include/gpxe/ip.h b/gpxe/src/include/gpxe/ip.h
index b1b0c48c..4342a0c7 100644
--- a/gpxe/src/include/gpxe/ip.h
+++ b/gpxe/src/include/gpxe/ip.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/in.h>
#include <gpxe/list.h>
diff --git a/gpxe/src/include/gpxe/ip6.h b/gpxe/src/include/gpxe/ip6.h
index dc0ae31f..edb2863c 100644
--- a/gpxe/src/include/gpxe/ip6.h
+++ b/gpxe/src/include/gpxe/ip6.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/in.h>
diff --git a/gpxe/src/include/gpxe/ipoib.h b/gpxe/src/include/gpxe/ipoib.h
index 80adee5b..1d02f792 100644
--- a/gpxe/src/include/gpxe/ipoib.h
+++ b/gpxe/src/include/gpxe/ipoib.h
@@ -6,10 +6,9 @@
* IP over Infiniband
*/
-#include <gpxe/infiniband.h>
+FILE_LICENCE ( GPL2_OR_LATER );
-/** IPoIB packet length */
-#define IPOIB_PKT_LEN 2048
+#include <gpxe/infiniband.h>
/** IPoIB MAC address length */
#define IPOIB_ALEN 20
@@ -18,9 +17,10 @@
struct ipoib_mac {
/** Queue pair number
*
- * MSB must be zero; QPNs are only 24-bit.
+ * MSB indicates support for IPoIB "connected mode". Lower 24
+ * bits are the QPN.
*/
- uint32_t qpn;
+ uint32_t flags__qpn;
/** Port GID */
struct ib_gid gid;
} __attribute__ (( packed ));
@@ -52,29 +52,10 @@ struct ipoib_hdr {
} __attribute__ (( packed )) u;
} __attribute__ (( packed ));
-extern struct ll_protocol ipoib_protocol;
-
extern const char * ipoib_ntoa ( const void *ll_addr );
-
-/**
- * Allocate IPoIB device
- *
- * @v priv_size Size of driver private data
- * @ret netdev Network device, or NULL
- */
-static inline struct net_device * alloc_ipoibdev ( size_t priv_size ) {
- struct net_device *netdev;
-
- netdev = alloc_netdev ( priv_size );
- if ( netdev ) {
- netdev->ll_protocol = &ipoib_protocol;
- netdev->max_pkt_len = IPOIB_PKT_LEN;
- }
- return netdev;
-}
-
extern void ipoib_link_state_changed ( struct ib_device *ibdev );
extern int ipoib_probe ( struct ib_device *ibdev );
extern void ipoib_remove ( struct ib_device *ibdev );
+extern struct net_device * alloc_ipoibdev ( size_t priv_size );
#endif /* _GPXE_IPOIB_H */
diff --git a/gpxe/src/include/gpxe/isa.h b/gpxe/src/include/gpxe/isa.h
index bb25dbce..63027a5a 100644
--- a/gpxe/src/include/gpxe/isa.h
+++ b/gpxe/src/include/gpxe/isa.h
@@ -1,6 +1,8 @@
#ifndef ISA_H
#define ISA_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/isa_ids.h>
#include <gpxe/device.h>
@@ -58,8 +60,11 @@ struct isa_driver {
void ( * remove ) ( struct isa_device *isa );
};
+/** ISA driver table */
+#define ISA_DRIVERS __table ( struct isa_driver, "isa_drivers" )
+
/** Declare an ISA driver */
-#define __isa_driver __table ( struct isa_driver, isa_drivers, 01 )
+#define __isa_driver __table_entry ( ISA_DRIVERS, 01 )
/**
* Set ISA driver-private data
diff --git a/gpxe/src/include/gpxe/isa_ids.h b/gpxe/src/include/gpxe/isa_ids.h
index bf3f1015..1faf1148 100644
--- a/gpxe/src/include/gpxe/isa_ids.h
+++ b/gpxe/src/include/gpxe/isa_ids.h
@@ -19,6 +19,8 @@
* the underlying "meaning" is big-endian.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <byteswap.h>
/*
diff --git a/gpxe/src/include/gpxe/isapnp.h b/gpxe/src/include/gpxe/isapnp.h
index 07797a99..b58a87e4 100644
--- a/gpxe/src/include/gpxe/isapnp.h
+++ b/gpxe/src/include/gpxe/isapnp.h
@@ -33,6 +33,8 @@
*
***************************************************************************/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifndef ISAPNP_H
#define ISAPNP_H
@@ -223,8 +225,11 @@ struct isapnp_driver {
void ( * remove ) ( struct isapnp_device *isapnp );
};
+/** ISAPnP driver table */
+#define ISAPNP_DRIVERS __table ( struct isapnp_driver, "isapnp_drivers" )
+
/** Declare an ISAPnP driver */
-#define __isapnp_driver __table ( struct isapnp_driver, isapnp_drivers, 01 )
+#define __isapnp_driver __table_entry ( ISAPNP_DRIVERS, 01 )
extern uint16_t isapnp_read_port;
diff --git a/gpxe/src/include/gpxe/iscsi.h b/gpxe/src/include/gpxe/iscsi.h
index 0510974e..00717d2b 100644
--- a/gpxe/src/include/gpxe/iscsi.h
+++ b/gpxe/src/include/gpxe/iscsi.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/socket.h>
#include <gpxe/scsi.h>
@@ -247,7 +249,7 @@ struct iscsi_bhs_scsi_command {
/** Segment lengths */
union iscsi_segment_lengths lengths;
/** SCSI Logical Unit Number */
- uint64_t lun;
+ struct scsi_lun lun;
/** Initiator Task Tag */
uint32_t itt;
/** Expected data transfer length */
@@ -342,7 +344,7 @@ struct iscsi_bhs_data_in {
/** Segment lengths */
union iscsi_segment_lengths lengths;
/** Logical Unit Number */
- uint64_t lun;
+ struct scsi_lun lun;
/** Initiator Task Tag */
uint32_t itt;
/** Target Transfer Tag */
@@ -390,7 +392,7 @@ struct iscsi_bhs_data_out {
/** Segment lengths */
union iscsi_segment_lengths lengths;
/** Logical Unit Number */
- uint64_t lun;
+ struct scsi_lun lun;
/** Initiator Task Tag */
uint32_t itt;
/** Target Transfer Tag */
@@ -426,7 +428,7 @@ struct iscsi_bhs_r2t {
/** Segment lengths */
union iscsi_segment_lengths lengths;
/** Logical Unit Number */
- uint64_t lun;
+ struct scsi_lun lun;
/** Initiator Task Tag */
uint32_t itt;
/** Target Transfer Tag */
@@ -505,7 +507,7 @@ struct iscsi_session {
/** Target IQN */
char *target_iqn;
/** Logical Unit Number (LUN) */
- uint64_t lun;
+ struct scsi_lun lun;
/** Target socket address (recorded only for iBFT) */
struct sockaddr target_sockaddr;
@@ -612,11 +614,6 @@ struct iscsi_session {
* Set to NULL when command is complete.
*/
struct scsi_command *command;
- /** SCSI command return code
- *
- * Set to -EINPROGRESS while command is processing.
- */
- int rc;
/** Instant return code
*
* Set to a non-zero value if all requests should return
diff --git a/gpxe/src/include/gpxe/job.h b/gpxe/src/include/gpxe/job.h
index 8e11aa33..f1bcada4 100644
--- a/gpxe/src/include/gpxe/job.h
+++ b/gpxe/src/include/gpxe/job.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stddef.h>
#include <gpxe/interface.h>
@@ -66,6 +68,8 @@ extern struct job_interface_operations null_job_ops;
extern void job_done ( struct job_interface *job, int rc );
extern void job_kill ( struct job_interface *job );
+extern void job_progress ( struct job_interface *job,
+ struct job_progress *progress );
extern void ignore_job_done ( struct job_interface *job, int rc );
extern void ignore_job_kill ( struct job_interface *job );
diff --git a/gpxe/src/include/gpxe/keys.h b/gpxe/src/include/gpxe/keys.h
index 3da8a1ff..25bc9bc0 100644
--- a/gpxe/src/include/gpxe/keys.h
+++ b/gpxe/src/include/gpxe/keys.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/*
* Symbolic names for some standard ASCII characters
*
diff --git a/gpxe/src/include/gpxe/linebuf.h b/gpxe/src/include/gpxe/linebuf.h
index 676731a9..cfa21472 100644
--- a/gpxe/src/include/gpxe/linebuf.h
+++ b/gpxe/src/include/gpxe/linebuf.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <stddef.h>
diff --git a/gpxe/src/include/gpxe/linux_compat.h b/gpxe/src/include/gpxe/linux_compat.h
index 2c3cbbde..577512eb 100644
--- a/gpxe/src/include/gpxe/linux_compat.h
+++ b/gpxe/src/include/gpxe/linux_compat.h
@@ -10,6 +10,8 @@
* intended to be a substitute for proper porting.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <errno.h>
#include <stdio.h>
diff --git a/gpxe/src/include/gpxe/list.h b/gpxe/src/include/gpxe/list.h
index 602382be..22ba2015 100644
--- a/gpxe/src/include/gpxe/list.h
+++ b/gpxe/src/include/gpxe/list.h
@@ -9,6 +9,8 @@
* list.h.
*/
+FILE_LICENCE ( GPL2_ONLY );
+
#include <stddef.h>
#include <assert.h>
diff --git a/gpxe/src/include/gpxe/login_ui.h b/gpxe/src/include/gpxe/login_ui.h
index d92ba8f3..4196f7b1 100644
--- a/gpxe/src/include/gpxe/login_ui.h
+++ b/gpxe/src/include/gpxe/login_ui.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
extern int login_ui ( void );
#endif /* _GPXE_LOGIN_UI_H */
diff --git a/gpxe/src/include/gpxe/malloc.h b/gpxe/src/include/gpxe/malloc.h
index cce5d1d3..c02a8668 100644
--- a/gpxe/src/include/gpxe/malloc.h
+++ b/gpxe/src/include/gpxe/malloc.h
@@ -9,6 +9,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/*
* Prototypes for the standard functions (malloc() et al) are in
* stdlib.h. Include <gpxe/malloc.h> only if you need the
diff --git a/gpxe/src/include/gpxe/mca.h b/gpxe/src/include/gpxe/mca.h
index 21f9e74d..da9d73e4 100644
--- a/gpxe/src/include/gpxe/mca.h
+++ b/gpxe/src/include/gpxe/mca.h
@@ -5,6 +5,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifndef MCA_H
#define MCA_H
@@ -77,8 +79,11 @@ struct mca_driver {
void ( * remove ) ( struct mca_device *mca );
};
+/** MCA driver table */
+#define MCA_DRIVERS __table ( struct mca_driver, "mca_drivers" )
+
/** Declare an MCA driver */
-#define __mca_driver __table ( struct mca_driver, mca_drivers, 01 )
+#define __mca_driver __table_entry ( MCA_DRIVERS, 01 )
/**
* Set MCA driver-private data
diff --git a/gpxe/src/include/gpxe/md5.h b/gpxe/src/include/gpxe/md5.h
index f8976a19..03d65c1a 100644
--- a/gpxe/src/include/gpxe/md5.h
+++ b/gpxe/src/include/gpxe/md5.h
@@ -1,6 +1,8 @@
#ifndef _GPXE_MD5_H
#define _GPXE_MD5_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
struct digest_algorithm;
#include <stdint.h>
diff --git a/gpxe/src/include/gpxe/memmap.h b/gpxe/src/include/gpxe/memmap.h
index 836a1b92..dc5bec3b 100644
--- a/gpxe/src/include/gpxe/memmap.h
+++ b/gpxe/src/include/gpxe/memmap.h
@@ -10,6 +10,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/** A usable memory region */
struct memory_region {
/** Physical start address */
diff --git a/gpxe/src/include/gpxe/monojob.h b/gpxe/src/include/gpxe/monojob.h
index aaa38d03..35ff4fd3 100644
--- a/gpxe/src/include/gpxe/monojob.h
+++ b/gpxe/src/include/gpxe/monojob.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
struct job_interface;
extern struct job_interface monojob;
diff --git a/gpxe/src/include/gpxe/nap.h b/gpxe/src/include/gpxe/nap.h
index f9ae3cf4..6c2e40cf 100644
--- a/gpxe/src/include/gpxe/nap.h
+++ b/gpxe/src/include/gpxe/nap.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/api.h>
#include <config/nap.h>
diff --git a/gpxe/src/include/gpxe/net80211.h b/gpxe/src/include/gpxe/net80211.h
new file mode 100644
index 00000000..027e091c
--- /dev/null
+++ b/gpxe/src/include/gpxe/net80211.h
@@ -0,0 +1,1186 @@
+#ifndef _GPXE_NET80211_H
+#define _GPXE_NET80211_H
+
+#include <gpxe/process.h>
+#include <gpxe/ieee80211.h>
+#include <gpxe/iobuf.h>
+#include <gpxe/netdevice.h>
+#include <gpxe/rc80211.h>
+
+/** @file
+ *
+ * The gPXE 802.11 MAC layer.
+ */
+
+/*
+ * Major things NOT YET supported:
+ * - any type of security
+ * - 802.11n
+ *
+ * Major things that probably will NEVER be supported, barring a
+ * compelling use case and/or corporate sponsorship:
+ * - QoS
+ * - 802.1X authentication ("WPA Enterprise")
+ * - Contention-free periods
+ * - "ad-hoc" networks (IBSS), monitor mode, host AP mode
+ * - hidden networks on the 5GHz band due to regulatory issues
+ * - spectrum management on the 5GHz band (TPC and DFS), as required
+ * in some non-US regulatory domains
+ * - Clause 14 PHYs (Frequency-Hopping Spread Spectrum on 2.4GHz)
+ * and Clause 16 PHYs (infrared) - I'm not aware of any real-world
+ * use of these.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/* All 802.11 devices are handled using a generic "802.11 device"
+ net_device, with a link in its `priv' field to a net80211_device
+ which we use to handle 802.11-specific details. */
+
+
+/** @defgroup net80211_band RF bands on which an 802.11 device can transmit */
+/** @{ */
+
+/** The 2.4 GHz ISM band, unlicensed in most countries */
+#define NET80211_BAND_2GHZ 0
+/** The band from 4.9 GHz to 5.7 GHz, which tends to be more restricted */
+#define NET80211_BAND_5GHZ 1
+/** Number of RF bands */
+#define NET80211_NR_BANDS 2
+
+/** Bitmask for the 2GHz band */
+#define NET80211_BAND_BIT_2GHZ (1 << 0)
+/** Bitmask for the 5GHz band */
+#define NET80211_BAND_BIT_5GHZ (1 << 1)
+
+/** @} */
+
+
+/** @defgroup net80211_mode 802.11 operation modes supported by hardware */
+/** @{ */
+
+/** 802.11a: 54 Mbps operation using OFDM signaling on the 5GHz band */
+#define NET80211_MODE_A (1 << 0)
+
+/** 802.11b: 1-11 Mbps operation using DSSS/CCK signaling on the 2.4GHz band */
+#define NET80211_MODE_B (1 << 1)
+
+/** 802.11g: 54 Mbps operation using ERP/OFDM signaling on the 2.4GHz band */
+#define NET80211_MODE_G (1 << 2)
+
+/** 802.11n: High-rate operation using MIMO technology on 2.4GHz or 5GHz */
+#define NET80211_MODE_N (1 << 3)
+
+/** @} */
+
+
+/** @defgroup net80211_cfg Constants for the net80211 config callback */
+/** @{ */
+
+/** Channel choice (@c dev->channel) or regulatory parameters have changed */
+#define NET80211_CFG_CHANNEL (1 << 0)
+
+/** Requested transmission rate (@c dev->rate) has changed */
+#define NET80211_CFG_RATE (1 << 1)
+
+/** Association has been established with a new BSS (@c dev->bssid) */
+#define NET80211_CFG_ASSOC (1 << 2)
+
+/** Low-level link parameters (short preamble, protection, etc) have changed */
+#define NET80211_CFG_PHY_PARAMS (1 << 3)
+
+/** @} */
+
+
+/** An 802.11 security handshaking protocol */
+enum net80211_security_proto {
+ /** No security handshaking
+ *
+ * This might be used with an open network or with WEP, as
+ * WEP does not have a cryptographic handshaking phase.
+ */
+ NET80211_SECPROT_NONE = 0,
+
+ /** Pre-shared key handshaking
+ *
+ * This implements the "WPA Personal" handshake. 802.1X
+ * authentication is not performed -- the user supplies a
+ * pre-shared key directly -- but there is a 4-way handshake
+ * between client and AP to verify that both have the same key
+ * without revealing the contents of that key.
+ */
+ NET80211_SECPROT_PSK = 1,
+
+ /** Full EAP 802.1X handshaking
+ *
+ * This implements the "WPA Enterprise" handshake, connecting
+ * to an 802.1X authentication server to provide credentials
+ * and receive a pairwise master key (PMK), which is then used
+ * in the same 4-way handshake as the PSK method.
+ */
+ NET80211_SECPROT_EAP = 2,
+
+ /** Dummy value used when the handshaking type can't be detected */
+ NET80211_SECPROT_UNKNOWN = 3,
+};
+
+
+/** An 802.11 data encryption algorithm */
+enum net80211_crypto_alg {
+ /** No security, an "Open" network */
+ NET80211_CRYPT_NONE = 0,
+
+ /** Network protected with WEP (awful RC4-based system)
+ *
+ * WEP uses a naive application of RC4, with a monotonically
+ * increasing initialization vector that is prepended to the
+ * key to initialize the RC4 keystream. It is highly insecure
+ * and can be completely cracked or subverted using automated,
+ * robust, freely available tools (aircrack-ng) in minutes.
+ *
+ * 40-bit and 104-bit WEP are differentiated only by the size
+ * of the key. They may be advertised as 64-bit and 128-bit,
+ * counting the non-random IV as part of the key bits.
+ */
+ NET80211_CRYPT_WEP = 1,
+
+ /** Network protected with TKIP (better RC4-based system)
+ *
+ * Usually known by its trade name of WPA (Wi-Fi Protected
+ * Access), TKIP implements a message integrity code (MIC)
+ * called Michael, a timestamp counter for replay prevention,
+ * and a key mixing function that together remove almost all
+ * the security problems with WEP. Countermeasures are
+ * implemented to prevent high data-rate attacks.
+ *
+ * There exists one known attack on TKIP, that allows one to
+ * send between 7 and 15 arbitrary short data packets on a
+ * QoS-enabled network given about an hour of data
+ * gathering. Since gPXE does not support QoS for 802.11
+ * networks, this is not a threat to us. The only other method
+ * is a brute-force passphrase attack.
+ */
+ NET80211_CRYPT_TKIP = 2,
+
+ /** Network protected with CCMP (AES-based system)
+ *
+ * Often called WPA2 in commerce, or RSNA (Robust Security
+ * Network Architecture) in the 802.11 standard, CCMP is
+ * highly secure and does not have any known attack vectors.
+ * Since it is based on a block cipher, the statistical
+ * correlation and "chopchop" attacks used with great success
+ * against WEP and minor success against TKIP fail.
+ */
+ NET80211_CRYPT_CCMP = 3,
+
+ /** Dummy value used when the cryptosystem can't be detected */
+ NET80211_CRYPT_UNKNOWN = 4,
+};
+
+
+/** @defgroup net80211_state Bits for the 802.11 association state field */
+/** @{ */
+
+/** An error code indicating the failure mode, or 0 if successful */
+#define NET80211_STATUS_MASK 0x7F
+
+/** Whether the error code provided is a "reason" code, not a "status" code */
+#define NET80211_IS_REASON 0x80
+
+/** Whether we have found the network we will be associating with */
+#define NET80211_PROBED (1 << 8)
+
+/** Whether we have successfully authenticated with the network
+ *
+ * This usually has nothing to do with actual security; it is a
+ * holdover from older 802.11 implementation ideas.
+ */
+#define NET80211_AUTHENTICATED (1 << 9)
+
+/** Whether we have successfully associated with the network */
+#define NET80211_ASSOCIATED (1 << 10)
+
+/** Whether we have completed security handshaking with the network
+ *
+ * Once this is set, we can send data packets. For that reason this
+ * bit is set even in cases where no security handshaking is
+ * required.
+ */
+#define NET80211_CRYPTO_SYNCED (1 << 11)
+
+/** Whether the auto-association task is running */
+#define NET80211_WORKING (1 << 12)
+
+/** Whether the auto-association task is waiting for a reply from the AP */
+#define NET80211_WAITING (1 << 13)
+
+/** Whether the auto-association task should be suppressed
+ *
+ * This is set by the `iwlist' command so that it can open the device
+ * without starting another probe process that will interfere with its
+ * own.
+ */
+#define NET80211_NO_ASSOC (1 << 14)
+
+/** Whether this association was performed using a broadcast SSID
+ *
+ * If the user opened this device without netX/ssid set, the device's
+ * SSID will be set to that of the network it chooses to associate
+ * with, but the netX/ssid setting will remain blank. If we don't
+ * remember that we started from no specified SSID, it will appear
+ * every time settings are updated (e.g. after DHCP) that we need to
+ * reassociate due to the difference between the set SSID and our own.
+ */
+#define NET80211_AUTO_SSID (1 << 15)
+
+
+/** @} */
+
+
+/** @defgroup net80211_phy 802.11 physical layer flags */
+/** @{ */
+
+/** Whether to use RTS/CTS or CTS-to-self protection for transmissions
+ *
+ * Since the RTS or CTS is transmitted using 802.11b signaling, and
+ * includes a field indicating the amount of time that will be used by
+ * transmission of the following packet, this serves as an effective
+ * protection mechanism to avoid 802.11b clients interfering with
+ * 802.11g clients on mixed networks.
+ */
+#define NET80211_PHY_USE_PROTECTION (1 << 1)
+
+/** Whether to use 802.11b short preamble operation
+ *
+ * Short-preamble operation can moderately increase throughput on
+ * 802.11b networks operating between 2Mbps and 11Mbps. It is
+ * irrelevant for 802.11g data rates, since they use a different
+ * modulation scheme.
+ */
+#define NET80211_PHY_USE_SHORT_PREAMBLE (1 << 2)
+
+/** Whether to use 802.11g short slot operation
+ *
+ * This affects a low-level timing parameter of 802.11g transmissions.
+ */
+#define NET80211_PHY_USE_SHORT_SLOT (1 << 3)
+
+/** @} */
+
+
+/** The maximum number of TX rates we allow to be configured simultaneously */
+#define NET80211_MAX_RATES 16
+
+/** The maximum number of channels we allow to be configured simultaneously */
+#define NET80211_MAX_CHANNELS 32
+
+/** Seconds we'll wait to get all fragments of a packet */
+#define NET80211_FRAG_TIMEOUT 2
+
+/** The number of fragments we can receive at once
+ *
+ * The 802.11 standard requires that this be at least 3.
+ */
+#define NET80211_NR_CONCURRENT_FRAGS 3
+
+/** Maximum TX power to allow (dBm), if we don't get a regulatory hint */
+#define NET80211_REG_TXPOWER 20
+
+
+struct net80211_device;
+
+/** Operations that must be implemented by an 802.11 driver */
+struct net80211_device_operations {
+ /** Open 802.11 device
+ *
+ * @v dev 802.11 device
+ * @ret rc Return status code
+ *
+ * This method should allocate RX I/O buffers and enable the
+ * hardware to start transmitting and receiving packets on the
+ * channels its net80211_register() call indicated it could
+ * handle. It does not need to tune the antenna to receive
+ * packets on any particular channel.
+ */
+ int ( * open ) ( struct net80211_device *dev );
+
+ /** Close 802.11 network device
+ *
+ * @v dev 802.11 device
+ *
+ * This method should stop the flow of packets, and call
+ * net80211_tx_complete() for any packets remaining in the
+ * device's TX queue.
+ */
+ void ( * close ) ( struct net80211_device *dev );
+
+ /** Transmit packet on 802.11 network device
+ *
+ * @v dev 802.11 device
+ * @v iobuf I/O buffer
+ * @ret rc Return status code
+ *
+ * This method should cause the hardware to initiate
+ * transmission of the I/O buffer, using the channel and rate
+ * most recently indicated by an appropriate call to the
+ * @c config callback. The 802.11 layer guarantees that said
+ * channel and rate will be the same as those currently
+ * reflected in the fields of @a dev.
+ *
+ * If this method returns success, the I/O buffer remains
+ * owned by the network layer's TX queue, and the driver must
+ * eventually call net80211_tx_complete() to free the buffer
+ * whether transmission succeeded or not. If this method
+ * returns failure, it will be interpreted as "failure to
+ * enqueue buffer" and the I/O buffer will be immediately
+ * released.
+ *
+ * This method is guaranteed to be called only when the device
+ * is open.
+ */
+ int ( * transmit ) ( struct net80211_device *dev,
+ struct io_buffer *iobuf );
+
+ /** Poll for completed and received packets
+ *
+ * @v dev 802.11 device
+ *
+ * This method should cause the hardware to check for
+ * completed transmissions and received packets. Any received
+ * packets should be delivered via net80211_rx(), and
+ * completed transmissions should be indicated using
+ * net80211_tx_complete().
+ *
+ * This method is guaranteed to be called only when the device
+ * is open.
+ */
+ void ( * poll ) ( struct net80211_device *dev );
+
+ /** Enable or disable interrupts
+ *
+ * @v dev 802.11 device
+ * @v enable If TRUE, interrupts should be enabled
+ */
+ void ( * irq ) ( struct net80211_device *dev, int enable );
+
+ /** Update hardware state to match 802.11 layer state
+ *
+ * @v dev 802.11 device
+ * @v changed Set of flags indicating what may have changed
+ * @ret rc Return status code
+ *
+ * This method should cause the hardware state to be
+ * reinitialized from the state indicated in fields of
+ * net80211_device, in the areas indicated by bits set in
+ * @a changed. If the hardware is unable to do so, this method
+ * may return an appropriate error indication.
+ *
+ * This method is guaranteed to be called only when the device
+ * is open.
+ */
+ int ( * config ) ( struct net80211_device *dev, int changed );
+};
+
+/** An 802.11 RF channel. */
+struct net80211_channel
+{
+ /** The band with which this channel is associated */
+ u8 band;
+
+ /** A channel number interpreted according to the band
+ *
+ * The 2.4GHz band uses channel numbers from 1-13 at 5MHz
+ * intervals such that channel 1 is 2407 MHz; channel 14,
+ * legal for use only in Japan, is defined separately as 2484
+ * MHz. Adjacent channels will overlap, since 802.11
+ * transmissions use a 20 MHz (4-channel) bandwidth. Most
+ * commonly, channels 1, 6, and 11 are used.
+ *
+ * The 5GHz band uses channel numbers derived directly from
+ * the frequency; channel 0 is 5000 MHz, and channels are
+ * always spaced 5 MHz apart. Channel numbers over 180 are
+ * relative to 4GHz instead of 5GHz, but these are rarely
+ * seen. Most channels are not legal for use.
+ */
+ u8 channel_nr;
+
+ /** The center frequency for this channel
+ *
+ * Currently a bandwidth of 20 MHz is assumed.
+ */
+ u16 center_freq;
+
+ /** Hardware channel value */
+ u16 hw_value;
+
+ /** Maximum allowable transmit power, in dBm
+ *
+ * This should be interpreted as EIRP, the power supplied to
+ * an ideal isotropic antenna in order to achieve the same
+ * average signal intensity as the real hardware at a
+ * particular distance.
+ *
+ * Currently no provision is made for directional antennas.
+ */
+ u8 maxpower;
+};
+
+/** Information on the capabilities of an 802.11 hardware device
+ *
+ * In its probe callback, an 802.11 driver must read hardware
+ * registers to determine the appropriate contents of this structure,
+ * fill it, and pass it to net80211_register() so that the 802.11
+ * layer knows how to treat the hardware and what to advertise as
+ * supported to access points.
+ */
+struct net80211_hw_info
+{
+ /** Default hardware MAC address.
+ *
+ * The user may change this by setting the @c netX/mac setting
+ * before the driver's open function is called; in that case
+ * the driver must set the hardware MAC address to the address
+ * contained in the wrapping net_device's ll_addr field, or if
+ * that is impossible, set that ll_addr field back to the
+ * unchangeable hardware MAC address.
+ */
+ u8 hwaddr[ETH_ALEN];
+
+ /** A bitwise OR of the 802.11x modes supported by this device */
+ int modes;
+
+ /** A bitwise OR of the bands on which this device can communicate */
+ int bands;
+
+ /** A set of flags indicating peculiarities of this device. */
+ enum {
+ /** Received frames include a frame check sequence. */
+ NET80211_HW_RX_HAS_FCS = (1 << 1),
+
+ /** Hardware doesn't support 2.4GHz short preambles
+ *
+ * This is only relevant for 802.11b operation above
+ * 2Mbps. All 802.11g devices support short preambles.
+ */
+ NET80211_HW_NO_SHORT_PREAMBLE = (1 << 2),
+
+ /** Hardware doesn't support 802.11g short slot operation */
+ NET80211_HW_NO_SHORT_SLOT = (1 << 3),
+ } flags;
+
+ /** Signal strength information that can be provided by the device
+ *
+ * Signal strength is passed to net80211_rx(), primarily to
+ * allow determination of the closest access point for a
+ * multi-AP network. The units are provided for completeness
+ * of status displays.
+ */
+ enum {
+ /** No signal strength information supported */
+ NET80211_SIGNAL_NONE = 0,
+ /** Signal strength in arbitrary units */
+ NET80211_SIGNAL_ARBITRARY,
+ /** Signal strength in decibels relative to arbitrary base */
+ NET80211_SIGNAL_DB,
+ /** Signal strength in decibels relative to 1mW */
+ NET80211_SIGNAL_DBM,
+ } signal_type;
+
+ /** Maximum signal in arbitrary cases
+ *
+ * If signal_type is NET80211_SIGNAL_ARBITRARY or
+ * NET80211_SIGNAL_DB, the driver should report it on a scale
+ * from 0 to signal_max.
+ */
+ unsigned signal_max;
+
+ /** List of RF channels supported by the card */
+ struct net80211_channel channels[NET80211_MAX_CHANNELS];
+
+ /** Number of supported channels */
+ int nr_channels;
+
+ /** List of transmission rates supported by the card, indexed by band
+ *
+ * Rates should be in 100kbps increments (e.g. 11 Mbps would
+ * be represented as the number 110).
+ */
+ u16 rates[NET80211_NR_BANDS][NET80211_MAX_RATES];
+
+ /** Number of supported rates, indexed by band */
+ int nr_rates[NET80211_NR_BANDS];
+
+ /** Estimate of the time required to change channels, in microseconds
+ *
+ * If this is not known, a guess on the order of a few
+ * milliseconds (value of 1000-5000) is reasonable.
+ */
+ unsigned channel_change_time;
+};
+
+/** Structure tracking received fragments for a packet
+ *
+ * We set up a fragment cache entry when we receive a packet marked as
+ * fragment 0 with the "more fragments" bit set in its frame control
+ * header. We are required by the 802.11 standard to track 3
+ * fragmented packets arriving simultaneously; if we receive more we
+ * may drop some. Upon receipt of a new fragment-0 packet, if no entry
+ * is available or expired, we take over the most @e recent entry for
+ * the new packet, since we don't want to starve old entries from ever
+ * finishing at all. If we get a fragment after the zeroth with no
+ * cache entry for its packet, we drop it.
+ */
+struct net80211_frag_cache
+{
+ /** Whether this cache entry is in use */
+ u8 in_use;
+
+ /** Sequence number of this MSDU (packet) */
+ u16 seqnr;
+
+ /** Timestamp from point at which first fragment was collected */
+ u32 start_ticks;
+
+ /** Buffers for each fragment */
+ struct io_buffer *iob[16];
+};
+
+
+/** Interface to an 802.11 security handshaking protocol
+ *
+ * Security handshaking protocols handle parsing a user-specified key
+ * into a suitable input to the encryption algorithm, and for WPA and
+ * better systems, manage performing whatever authentication with the
+ * network is necessary.
+ *
+ * At all times when any method in this structure is called with a
+ * net80211_device argument @a dev, a dynamically allocated copy of
+ * the handshaker structure itself with space for the requested amount
+ * of private data may be accessed as @c dev->handshaker. The
+ * structure will not be modified, and will only be freed during
+ * reassociation and device closing after the @a stop method has been
+ * called.
+ */
+struct net80211_handshaker
+{
+ /** The security handshaking protocol implemented */
+ enum net80211_security_proto protocol;
+
+ /** Initialize security handshaking protocol
+ *
+ * @v dev 802.11 device
+ * @ret rc Return status code
+ *
+ * This method is expected to access @c netX/key or other
+ * applicable settings to determine the parameters for
+ * handshaking. If no handshaking is required, it should call
+ * sec80211_install() with the cryptosystem and key that are
+ * to be used, and @c start and @c step should be set to @c
+ * NULL.
+ *
+ * This is always called just before association is performed,
+ * but after its parameters have been set; in particular, you
+ * may rely on the contents of the @a essid field in @a dev.
+ */
+ int ( * init ) ( struct net80211_device *dev );
+
+ /** Start handshaking
+ *
+ * @v dev 802.11 device
+ * @ret rc Return status code
+ *
+ * This method is expected to set up internal state so that
+ * packets sent immediately after association, before @a step
+ * can be called, will be handled appropriately.
+ *
+ * This is always called just before association is attempted.
+ */
+ int ( * start ) ( struct net80211_device *dev );
+
+ /** Process handshaking state
+ *
+ * @v dev 802.11 device
+ * @ret rc Return status code, or positive if done
+ *
+ * This method is expected to perform as much progress on the
+ * protocol it implements as is possible without blocking. It
+ * should return 0 if it wishes to be called again, a negative
+ * return status code on error, or a positive value if
+ * handshaking is complete. In the case of a positive return,
+ * net80211_crypto_install() must have been called.
+ *
+ * If handshaking may require further action (e.g. an AP that
+ * might decide to rekey), handlers must be installed by this
+ * function that will act without further calls to @a step.
+ */
+ int ( * step ) ( struct net80211_device *dev );
+
+ /** Change cryptographic key based on setting
+ *
+ * @v dev 802.11 device
+ * @ret rc Return status code
+ *
+ * This method is called whenever the @c netX/key setting
+ * @e may have been changed. It is expected to determine
+ * whether it did in fact change, and if so, to install the
+ * new key using net80211_crypto_install(). If it is not
+ * possible to do this immediately, this method should return
+ * an error; in that case the 802.11 stack will reassociate,
+ * following the usual init/start/step sequence.
+ *
+ * This method is only relevant when it is possible to
+ * associate successfully with an incorrect key. When it is
+ * not, a failed association will be retried until the user
+ * changes the key setting, and a successful association will
+ * not be dropped due to such a change. When association with
+ * an incorrect key is impossible, this function should return
+ * 0 after performing no action.
+ */
+ int ( * change_key ) ( struct net80211_device *dev );
+
+ /** Stop security handshaking handlers
+ *
+ * @v dev 802.11 device
+ *
+ * This method is called just before freeing a security
+ * handshaker; it could, for example, delete a process that @a
+ * start had created to manage the security of the connection.
+ * If not needed it may be set to NULL.
+ */
+ void ( * stop ) ( struct net80211_device *dev );
+
+ /** Amount of private data requested
+ *
+ * Before @c init is called for the first time, this structure's
+ * @c priv pointer will point to this many bytes of allocated
+ * data, where the allocation will be performed separately for
+ * each net80211_device.
+ */
+ int priv_len;
+
+ /** Whether @a start has been called
+ *
+ * Reset to 0 after @a stop is called.
+ */
+ int started;
+
+ /** Pointer to private data
+ *
+ * In initializing this structure statically for a linker
+ * table, set this to NULL.
+ */
+ void *priv;
+};
+
+#define NET80211_HANDSHAKERS __table ( struct net80211_handshaker, \
+ "net80211_handshakers" )
+#define __net80211_handshaker __table_entry ( NET80211_HANDSHAKERS, 01 )
+
+
+/** Interface to an 802.11 cryptosystem
+ *
+ * Cryptosystems define a net80211_crypto structure statically, using
+ * a gPXE linker table to make it available to the 802.11 layer. When
+ * the cryptosystem needs to be used, the 802.11 code will allocate a
+ * copy of the static definition plus whatever space the algorithm has
+ * requested for private state, and point net80211_device::crypto or
+ * net80211_device::gcrypto at it.
+ */
+struct net80211_crypto
+{
+ /** The cryptographic algorithm implemented */
+ enum net80211_crypto_alg algorithm;
+
+ /** Initialize cryptosystem using a given key
+ *
+ * @v crypto 802.11 cryptosystem
+ * @v key Pointer to key bytes
+ * @v keylen Number of key bytes
+ * @v rsc Initial receive sequence counter, if applicable
+ * @ret rc Return status code
+ *
+ * This method is passed the communication key provided by the
+ * security handshake handler, which will already be in the
+ * low-level form required. It may not store a pointer to the
+ * key after returning; it must copy it to its private storage.
+ */
+ int ( * init ) ( struct net80211_crypto *crypto, const void *key,
+ int keylen, const void *rsc );
+
+ /** Encrypt a frame using the cryptosystem
+ *
+ * @v crypto 802.11 cryptosystem
+ * @v iob I/O buffer
+ * @ret eiob Newly allocated I/O buffer with encrypted packet
+ *
+ * This method is called to encrypt a single frame. It is
+ * guaranteed that initialize() will have completed
+ * successfully before this method is called.
+ *
+ * The frame passed already has an 802.11 header prepended,
+ * but the PROTECTED bit in the frame control field will not
+ * be set; this method is responsible for setting it. The
+ * returned I/O buffer should contain a complete copy of @a
+ * iob, including the 802.11 header, but with the PROTECTED
+ * bit set, the data encrypted, and whatever encryption
+ * headers/trailers are necessary added.
+ *
+ * This method should never free the passed I/O buffer.
+ *
+ * Return NULL if the packet could not be encrypted, due to
+ * memory limitations or otherwise.
+ */
+ struct io_buffer * ( * encrypt ) ( struct net80211_crypto *crypto,
+ struct io_buffer *iob );
+
+ /** Decrypt a frame using the cryptosystem
+ *
+ * @v crypto 802.11 cryptosystem
+ * @v eiob Encrypted I/O buffer
+ * @ret iob Newly allocated I/O buffer with decrypted packet
+ *
+ * This method is called to decrypt a single frame. It is
+ * guaranteed that initialize() will have completed
+ * successfully before this method is called.
+ *
+ * Decryption follows the reverse of the pattern used for
+ * encryption: this method must copy the 802.11 header into
+ * the returned packet, decrypt the data stream, remove any
+ * encryption header or trailer, and clear the PROTECTED bit
+ * in the frame control header.
+ *
+ * This method should never free the passed I/O buffer.
+ *
+ * Return NULL if memory was not available for decryption, if
+ * a consistency or integrity check on the decrypted frame
+ * failed, or if the decrypted frame should not be processed
+ * by the network stack for any other reason.
+ */
+ struct io_buffer * ( * decrypt ) ( struct net80211_crypto *crypto,
+ struct io_buffer *iob );
+
+ /** Length of private data requested to be allocated */
+ int priv_len;
+
+ /** Private data for the algorithm to store key and state info */
+ void *priv;
+};
+
+#define NET80211_CRYPTOS __table ( struct net80211_crypto, "net80211_cryptos" )
+#define __net80211_crypto __table_entry ( NET80211_CRYPTOS, 01 )
+
+
+struct net80211_probe_ctx;
+struct net80211_assoc_ctx;
+
+
+/** Structure encapsulating the complete state of an 802.11 device
+ *
+ * An 802.11 device is always wrapped by a network device, and this
+ * network device is always pointed to by the @a netdev field. In
+ * general, operations should never be performed by 802.11 code using
+ * netdev functions directly. It is usually the case that the 802.11
+ * layer might need to do some processing or bookkeeping on top of
+ * what the netdevice code will do.
+ */
+struct net80211_device
+{
+ /** The net_device that wraps us. */
+ struct net_device *netdev;
+
+ /** List of 802.11 devices. */
+ struct list_head list;
+
+ /** 802.11 device operations */
+ struct net80211_device_operations *op;
+
+ /** Driver private data */
+ void *priv;
+
+ /** Information about the hardware, provided to net80211_register() */
+ struct net80211_hw_info *hw;
+
+ /* ---------- Channel and rate fields ---------- */
+
+ /** A list of all possible channels we might use */
+ struct net80211_channel channels[NET80211_MAX_CHANNELS];
+
+ /** The number of channels in the channels array */
+ u8 nr_channels;
+
+ /** The channel currently in use, as an index into the channels array */
+ u8 channel;
+
+ /** A list of all possible TX rates we might use
+ *
+ * Rates are in units of 100 kbps.
+ */
+ u16 rates[NET80211_MAX_RATES];
+
+ /** The number of transmission rates in the rates array */
+ u8 nr_rates;
+
+ /** The rate currently in use, as an index into the rates array */
+ u8 rate;
+
+ /** The rate to use for RTS/CTS transmissions
+ *
+ * This is always the fastest basic rate that is not faster
+ * than the data rate in use. Also an index into the rates array.
+ */
+ u8 rtscts_rate;
+
+ /** Bitmask of basic rates
+ *
+ * If bit N is set in this value, with the LSB considered to
+ * be bit 0, then rate N in the rates array is a "basic" rate.
+ *
+ * We don't decide which rates are "basic"; our AP does, and
+ * we respect its wishes. We need to be able to identify basic
+ * rates in order to calculate the duration of a CTS packet
+ * used for 802.11 g/b interoperability.
+ */
+ u32 basic_rates;
+
+ /* ---------- Association fields ---------- */
+
+ /** The asynchronous association process.
+ *
+ * When an 802.11 netdev is opened, or when the user changes
+ * the SSID setting on an open 802.11 device, an
+ * autoassociation task is started by net80211_autoassocate()
+ * to associate with the new best network. The association is
+ * asynchronous, but no packets can be transmitted until it is
+ * complete. If it is successful, the wrapping net_device is
+ * set as "link up". If it fails, @c assoc_rc will be set with
+ * an error indication.
+ */
+ struct process proc_assoc;
+
+ /** Network with which we are associating
+ *
+ * This will be NULL when we are not actively in the process
+ * of associating with a network we have already successfully
+ * probed for.
+ */
+ struct net80211_wlan *associating;
+
+ /** Context for the association process
+ *
+ * This is a probe_ctx if the @c PROBED flag is not set in @c
+ * state, and an assoc_ctx otherwise.
+ */
+ union {
+ struct net80211_probe_ctx *probe;
+ struct net80211_assoc_ctx *assoc;
+ } ctx;
+
+ /** Security handshaker being used */
+ struct net80211_handshaker *handshaker;
+
+ /** State of our association to the network
+ *
+ * Since the association process happens asynchronously, it's
+ * necessary to have some channel of communication so the
+ * driver can say "I got an association reply and we're OK" or
+ * similar. This variable provides that link. It is a bitmask
+ * of any of NET80211_PROBED, NET80211_AUTHENTICATED,
+ * NET80211_ASSOCIATED, NET80211_CRYPTO_SYNCED to indicate how
+ * far along in associating we are; NET80211_WORKING if the
+ * association task is running; and NET80211_WAITING if a
+ * packet has been sent that we're waiting for a reply to. We
+ * can only be crypto-synced if we're associated, we can
+ * only be associated if we're authenticated, we can only be
+ * authenticated if we've probed.
+ *
+ * If an association process fails (that is, we receive a
+ * packet with an error indication), the error code is copied
+ * into bits 6-0 of this variable and bit 7 is set to specify
+ * what type of error code it is. An AP can provide either a
+ * "status code" (0-51 are defined) explaining why it refused
+ * an association immediately, or a "reason code" (0-45 are
+ * defined) explaining why it canceled an association after it
+ * had originally OK'ed it. Status and reason codes serve
+ * similar functions, but they use separate error message
+ * tables. A gPXE-formatted return status code (negative) is
+ * placed in @c assoc_rc.
+ *
+ * If the failure to associate is indicated by a status code,
+ * the NET80211_IS_REASON bit will be clear; if it is
+ * indicated by a reason code, the bit will be set. If we were
+ * successful, both zero status and zero reason mean success,
+ * so there is no ambiguity.
+ *
+ * To prevent association when opening the device, user code
+ * can set the NET80211_NO_ASSOC bit. The final bit in this
+ * variable, NET80211_AUTO_SSID, is used to remember whether
+ * we picked our SSID through automated probing as opposed to
+ * user specification; the distinction becomes relevant in the
+ * settings applicator.
+ */
+ u16 state;
+
+ /** Return status code associated with @c state */
+ int assoc_rc;
+
+ /** RSN or WPA information element to include with association
+ *
+ * If set to @c NULL, none will be included. It is expected
+ * that this will be set by the @a init function of a security
+ * handshaker if it is needed.
+ */
+ union ieee80211_ie *rsn_ie;
+
+ /* ---------- Parameters of currently associated network ---------- */
+
+ /** 802.11 cryptosystem for our current network
+ *
+ * For an open network, this will be set to NULL.
+ */
+ struct net80211_crypto *crypto;
+
+ /** 802.11 cryptosystem for multicast and broadcast frames
+ *
+ * If this is NULL, the cryptosystem used for receiving
+ * unicast frames will also be used for receiving multicast
+ * and broadcast frames. Transmitted multicast and broadcast
+ * frames are always sent unicast to the AP, who multicasts
+ * them on our behalf; thus they always use the unicast
+ * cryptosystem.
+ */
+ struct net80211_crypto *gcrypto;
+
+ /** MAC address of the access point most recently associated */
+ u8 bssid[ETH_ALEN];
+
+ /** SSID of the access point we are or will be associated with
+ *
+ * Although the SSID field in 802.11 packets is generally not
+ * NUL-terminated, here and in net80211_wlan we add a NUL for
+ * convenience.
+ */
+ char essid[IEEE80211_MAX_SSID_LEN+1];
+
+ /** Association ID given to us by the AP */
+ u16 aid;
+
+ /** TSFT value for last beacon received, microseconds */
+ u64 last_beacon_timestamp;
+
+ /** Time between AP sending beacons, microseconds */
+ u32 tx_beacon_interval;
+
+ /** Smoothed average time between beacons, microseconds */
+ u32 rx_beacon_interval;
+
+ /* ---------- Physical layer information ---------- */
+
+ /** Physical layer options
+ *
+ * These control the use of CTS protection, short preambles,
+ * and short-slot operation.
+ */
+ int phy_flags;
+
+ /** Signal strength of last received packet */
+ int last_signal;
+
+ /** Rate control state */
+ struct rc80211_ctx *rctl;
+
+ /* ---------- Packet handling state ---------- */
+
+ /** Fragment reassembly state */
+ struct net80211_frag_cache frags[NET80211_NR_CONCURRENT_FRAGS];
+
+ /** The sequence number of the last packet we sent */
+ u16 last_tx_seqnr;
+
+ /** Packet duplication elimination state
+ *
+ * We are only required to handle immediate duplicates for
+ * each direct sender, and since we can only have one direct
+ * sender (the AP), we need only keep the sequence control
+ * field from the most recent packet we've received. Thus,
+ * this field stores the last sequence control field we've
+ * received for a packet from the AP.
+ */
+ u16 last_rx_seq;
+
+ /** RX management packet queue
+ *
+ * Sometimes we want to keep probe, beacon, and action packets
+ * that we receive, such as when we're scanning for networks.
+ * Ordinarily we drop them because they are sent at a large
+ * volume (ten beacons per second per AP, broadcast) and we
+ * have no need of them except when we're scanning.
+ *
+ * When keep_mgmt is TRUE, received probe, beacon, and action
+ * management packets will be stored in this queue.
+ */
+ struct list_head mgmt_queue;
+
+ /** RX management packet info queue
+ *
+ * We need to keep track of the signal strength for management
+ * packets we're keeping, because that provides the only way
+ * to distinguish between multiple APs for the same network.
+ * Since we can't extend io_buffer to store signal, this field
+ * heads a linked list of "RX packet info" structures that
+ * contain that signal strength field. Its entries always
+ * parallel the entries in mgmt_queue, because the two queues
+ * are always added to or removed from in parallel.
+ */
+ struct list_head mgmt_info_queue;
+
+ /** Whether to store management packets
+ *
+ * Received beacon, probe, and action packets will be added to
+ * mgmt_queue (and their signal strengths added to
+ * mgmt_info_queue) only when this variable is TRUE. It should
+ * be set by net80211_keep_mgmt() (which returns the old
+ * value) only when calling code is prepared to poll the
+ * management queue frequently, because packets will otherwise
+ * pile up and exhaust memory.
+ */
+ int keep_mgmt;
+};
+
+/** Structure representing a probed network.
+ *
+ * This is returned from the net80211_probe_finish functions and
+ * passed to the low-level association functions. At least essid,
+ * bssid, channel, beacon, and security must be filled in if you want
+ * to build this structure manually.
+ */
+struct net80211_wlan
+{
+ /** The human-readable ESSID (network name)
+ *
+ * Although the 802.11 SSID field is generally not
+ * NUL-terminated, the gPXE code adds an extra NUL (and
+ * expects one in this structure) for convenience.
+ */
+ char essid[IEEE80211_MAX_SSID_LEN+1];
+
+ /** MAC address of the strongest-signal access point for this ESSID */
+ u8 bssid[ETH_ALEN];
+
+ /** Signal strength of beacon frame from that access point */
+ int signal;
+
+ /** The channel on which that access point communicates
+ *
+ * This is a raw channel number (net80211_channel::channel_nr),
+ * so that it will not be affected by reconfiguration of the
+ * device channels array.
+ */
+ int channel;
+
+ /** The complete beacon or probe-response frame received */
+ struct io_buffer *beacon;
+
+ /** Security handshaking method used on the network */
+ enum net80211_security_proto handshaking;
+
+ /** Cryptographic algorithm used on the network */
+ enum net80211_crypto_alg crypto;
+
+ /** Link to allow chaining multiple structures into a list to
+ be returned from net80211_probe_finish_all(). */
+ struct list_head list;
+};
+
+
+/** 802.11 encryption key setting */
+extern struct setting net80211_key_setting __setting;
+
+
+/**
+ * @defgroup net80211_probe 802.11 network location API
+ * @{
+ */
+int net80211_prepare_probe ( struct net80211_device *dev, int band,
+ int active );
+struct net80211_probe_ctx * net80211_probe_start ( struct net80211_device *dev,
+ const char *essid,
+ int active );
+int net80211_probe_step ( struct net80211_probe_ctx *ctx );
+struct net80211_wlan *
+net80211_probe_finish_best ( struct net80211_probe_ctx *ctx );
+struct list_head *net80211_probe_finish_all ( struct net80211_probe_ctx *ctx );
+
+void net80211_free_wlan ( struct net80211_wlan *wlan );
+void net80211_free_wlanlist ( struct list_head *list );
+/** @} */
+
+
+/**
+ * @defgroup net80211_mgmt 802.11 network management API
+ * @{
+ */
+struct net80211_device * net80211_get ( struct net_device *netdev );
+void net80211_autoassociate ( struct net80211_device *dev );
+
+int net80211_change_channel ( struct net80211_device *dev, int channel );
+void net80211_set_rate_idx ( struct net80211_device *dev, int rate );
+
+int net80211_keep_mgmt ( struct net80211_device *dev, int enable );
+struct io_buffer * net80211_mgmt_dequeue ( struct net80211_device *dev,
+ int *signal );
+int net80211_tx_mgmt ( struct net80211_device *dev, u16 fc,
+ u8 bssid[ETH_ALEN], struct io_buffer *iob );
+/** @} */
+
+
+/**
+ * @defgroup net80211_assoc 802.11 network association API
+ * @{
+ */
+int net80211_prepare_assoc ( struct net80211_device *dev,
+ struct net80211_wlan *wlan );
+int net80211_send_auth ( struct net80211_device *dev,
+ struct net80211_wlan *wlan, int method );
+int net80211_send_assoc ( struct net80211_device *dev,
+ struct net80211_wlan *wlan );
+void net80211_deauthenticate ( struct net80211_device *dev, int rc );
+/** @} */
+
+
+/**
+ * @defgroup net80211_driver 802.11 driver interface API
+ * @{
+ */
+struct net80211_device *net80211_alloc ( size_t priv_size );
+int net80211_register ( struct net80211_device *dev,
+ struct net80211_device_operations *ops,
+ struct net80211_hw_info *hw );
+u16 net80211_duration ( struct net80211_device *dev, int bytes, u16 rate );
+void net80211_rx ( struct net80211_device *dev, struct io_buffer *iob,
+ int signal, u16 rate );
+void net80211_rx_err ( struct net80211_device *dev,
+ struct io_buffer *iob, int rc );
+void net80211_tx_complete ( struct net80211_device *dev,
+ struct io_buffer *iob, int retries, int rc );
+void net80211_unregister ( struct net80211_device *dev );
+void net80211_free ( struct net80211_device *dev );
+/** @} */
+
+/**
+ * Calculate duration field for a CTS control frame
+ *
+ * @v dev 802.11 device
+ * @v size Size of the packet being cleared to send
+ *
+ * A CTS control frame's duration field captures the frame being
+ * protected and its 10-byte ACK.
+ */
+static inline u16 net80211_cts_duration ( struct net80211_device *dev,
+ int size )
+{
+ return ( net80211_duration ( dev, 10,
+ dev->rates[dev->rtscts_rate] ) +
+ net80211_duration ( dev, size, dev->rates[dev->rate] ) );
+}
+
+#endif
diff --git a/gpxe/src/include/gpxe/netdevice.h b/gpxe/src/include/gpxe/netdevice.h
index f1585de0..858d8e97 100644
--- a/gpxe/src/include/gpxe/netdevice.h
+++ b/gpxe/src/include/gpxe/netdevice.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/list.h>
#include <gpxe/tables.h>
@@ -19,11 +21,26 @@ struct net_protocol;
struct ll_protocol;
struct device;
-/** Maximum length of a link-layer address */
+/** Maximum length of a hardware address
+ *
+ * The longest currently-supported link-layer address is for IPoIB.
+ */
+#define MAX_HW_ADDR_LEN 8
+
+/** Maximum length of a link-layer address
+ *
+ * The longest currently-supported link-layer address is for IPoIB.
+ */
#define MAX_LL_ADDR_LEN 20
-/** Maximum length of a link-layer header */
-#define MAX_LL_HEADER_LEN 6
+/** Maximum length of a link-layer header
+ *
+ * The longest currently-supported link-layer header is for 802.11: a
+ * 24-byte frame header plus an 8-byte 802.3 LLC/SNAP header. (The
+ * IPoIB link-layer pseudo-header doesn't actually include link-layer
+ * addresses; see ipoib.c for details).
+ */
+#define MAX_LL_HEADER_LEN 32
/** Maximum length of a network-layer address */
#define MAX_NET_ADDR_LEN 4
@@ -78,30 +95,41 @@ struct ll_protocol {
/**
* Add link-layer header
*
+ * @v netdev Network device
* @v iobuf I/O buffer
* @v ll_dest Link-layer destination address
* @v ll_source Source link-layer address
* @v net_proto Network-layer protocol, in network-byte order
* @ret rc Return status code
*/
- int ( * push ) ( struct io_buffer *iobuf, const void *ll_dest,
- const void *ll_source, uint16_t net_proto );
+ int ( * push ) ( struct net_device *netdev, struct io_buffer *iobuf,
+ const void *ll_dest, const void *ll_source,
+ uint16_t net_proto );
/**
* Remove link-layer header
*
+ * @v netdev Network device
* @v iobuf I/O buffer
* @ret ll_dest Link-layer destination address
* @ret ll_source Source link-layer address
* @ret net_proto Network-layer protocol, in network-byte order
* @ret rc Return status code
*/
- int ( * pull ) ( struct io_buffer *iobuf, const void **ll_dest,
- const void **ll_source, uint16_t *net_proto );
+ int ( * pull ) ( struct net_device *netdev, struct io_buffer *iobuf,
+ const void **ll_dest, const void **ll_source,
+ uint16_t *net_proto );
+ /**
+ * Initialise link-layer address
+ *
+ * @v hw_addr Hardware address
+ * @v ll_addr Link-layer address to fill in
+ */
+ void ( * init_addr ) ( const void *hw_addr, void *ll_addr );
/**
* Transcribe link-layer address
*
- * @v ll_addr Link-layer address
- * @ret string Human-readable transcription of address
+ * @v ll_addr Link-layer address
+ * @ret string Human-readable transcription of address
*
* This method should convert the link-layer address into a
* human-readable format.
@@ -109,28 +137,35 @@ struct ll_protocol {
* The buffer used to hold the transcription is statically
* allocated.
*/
- const char * ( * ntoa ) ( const void * ll_addr );
+ const char * ( * ntoa ) ( const void *ll_addr );
/**
* Hash multicast address
*
- * @v af Address family
- * @v net_addr Network-layer address
- * @v ll_addr Link-layer address to fill in
- * @ret rc Return status code
+ * @v af Address family
+ * @v net_addr Network-layer address
+ * @v ll_addr Link-layer address to fill in
+ * @ret rc Return status code
*/
int ( * mc_hash ) ( unsigned int af, const void *net_addr,
void *ll_addr );
+ /**
+ * Generate Ethernet-compatible compressed link-layer address
+ *
+ * @v ll_addr Link-layer address
+ * @v eth_addr Ethernet-compatible address to fill in
+ */
+ int ( * eth_addr ) ( const void *ll_addr, void *eth_addr );
/** Link-layer protocol
*
* This is an ARPHRD_XXX constant, in network byte order.
*/
uint16_t ll_proto;
+ /** Hardware address length */
+ uint8_t hw_addr_len;
/** Link-layer address length */
uint8_t ll_addr_len;
/** Link-layer header length */
uint8_t ll_header_len;
- /** Link-layer broadcast address */
- const uint8_t *ll_broadcast;
};
/** Network device operations */
@@ -241,17 +276,35 @@ struct net_device {
/** Link-layer protocol */
struct ll_protocol *ll_protocol;
+ /** Hardware address
+ *
+ * This is an address which is an intrinsic property of the
+ * hardware, e.g. an address held in EEPROM.
+ *
+ * Note that the hardware address may not be the same length
+ * as the link-layer address.
+ */
+ uint8_t hw_addr[MAX_HW_ADDR_LEN];
/** Link-layer address
*
- * For Ethernet, this is the MAC address.
+ * This is the current link-layer address assigned to the
+ * device. It can be changed at runtime.
*/
uint8_t ll_addr[MAX_LL_ADDR_LEN];
+ /** Link-layer broadcast address */
+ const uint8_t *ll_broadcast;
/** Current device state
*
* This is the bitwise-OR of zero or more NETDEV_XXX constants.
*/
unsigned int state;
+ /** Link status code
+ *
+ * Zero indicates that the link is up; any other value
+ * indicates the error preventing link-up.
+ */
+ int link_rc;
/** Maximum packet length
*
* This length includes any link-layer headers.
@@ -267,7 +320,7 @@ struct net_device {
struct net_device_stats rx_stats;
/** Configuration settings applicable to this device */
- struct simple_settings settings;
+ struct generic_settings settings;
/** Driver private data */
void *priv;
@@ -276,17 +329,21 @@ struct net_device {
/** Network device is open */
#define NETDEV_OPEN 0x0001
-/** Network device has link */
-#define NETDEV_LINK_UP 0x0002
+/** Link-layer protocol table */
+#define LL_PROTOCOLS __table ( struct ll_protocol, "ll_protocols" )
/** Declare a link-layer protocol */
-#define __ll_protocol __table ( struct ll_protocol, ll_protocols, 01 )
+#define __ll_protocol __table_entry ( LL_PROTOCOLS, 01 )
+
+/** Network-layer protocol table */
+#define NET_PROTOCOLS __table ( struct net_protocol, "net_protocols" )
/** Declare a network-layer protocol */
-#define __net_protocol __table ( struct net_protocol, net_protocols, 01 )
+#define __net_protocol __table_entry ( NET_PROTOCOLS, 01 )
extern struct list_head net_devices;
extern struct net_device_operations null_netdev_operations;
+extern struct settings_operations netdev_settings_operations;
/**
* Initialise a network device
@@ -312,12 +369,12 @@ static inline void netdev_nullify ( struct net_device *netdev ) {
}
/**
- * Get printable network device hardware address
+ * Get printable network device link-layer address
*
* @v netdev Network device
- * @ret name Hardware address
+ * @ret name Link-layer address
*/
-static inline const char * netdev_hwaddr ( struct net_device *netdev ) {
+static inline const char * netdev_addr ( struct net_device *netdev ) {
return netdev->ll_protocol->ntoa ( netdev->ll_addr );
}
@@ -378,23 +435,38 @@ netdev_settings ( struct net_device *netdev ) {
}
/**
+ * Initialise a per-netdevice configuration settings block
+ *
+ * @v generics Generic settings block
+ * @v refcnt Containing object reference counter, or NULL
+ * @v name Settings block name
+ */
+static inline __attribute__ (( always_inline )) void
+netdev_settings_init ( struct net_device *netdev ) {
+ generic_settings_init ( &netdev->settings,
+ &netdev->refcnt, netdev->name );
+ netdev->settings.settings.op = &netdev_settings_operations;
+}
+
+/**
* Mark network device as having link up
*
* @v netdev Network device
*/
static inline __attribute__ (( always_inline )) void
netdev_link_up ( struct net_device *netdev ) {
- netdev->state |= NETDEV_LINK_UP;
+ netdev->link_rc = 0;
}
/**
- * Mark network device as having link down
+ * Mark network device as having link down due to a specific error
*
* @v netdev Network device
+ * @v rc Link status code
*/
static inline __attribute__ (( always_inline )) void
-netdev_link_down ( struct net_device *netdev ) {
- netdev->state &= ~NETDEV_LINK_UP;
+netdev_link_err ( struct net_device *netdev, int rc ) {
+ netdev->link_rc = rc;
}
/**
@@ -405,9 +477,10 @@ netdev_link_down ( struct net_device *netdev ) {
*/
static inline __attribute__ (( always_inline )) int
netdev_link_ok ( struct net_device *netdev ) {
- return ( netdev->state & NETDEV_LINK_UP );
+ return ( netdev->link_rc == 0 );
}
+extern void netdev_link_down ( struct net_device *netdev );
extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
extern void netdev_tx_complete_err ( struct net_device *netdev,
struct io_buffer *iobuf, int rc );
@@ -432,8 +505,6 @@ extern int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
uint16_t net_proto, const void *ll_source );
-extern struct settings_operations netdev_settings_operations;
-
/**
* Complete network transmission
*
diff --git a/gpxe/src/include/gpxe/null_nap.h b/gpxe/src/include/gpxe/null_nap.h
index 6dd0cda3..0f46eaa2 100644
--- a/gpxe/src/include/gpxe/null_nap.h
+++ b/gpxe/src/include/gpxe/null_nap.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifdef NAP_NULL
#define NAP_PREFIX_null
#else
diff --git a/gpxe/src/include/gpxe/nvo.h b/gpxe/src/include/gpxe/nvo.h
index 28068f4b..c9650706 100644
--- a/gpxe/src/include/gpxe/nvo.h
+++ b/gpxe/src/include/gpxe/nvo.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/dhcpopts.h>
#include <gpxe/settings.h>
diff --git a/gpxe/src/include/gpxe/nvs.h b/gpxe/src/include/gpxe/nvs.h
index b026dd46..5c90c655 100644
--- a/gpxe/src/include/gpxe/nvs.h
+++ b/gpxe/src/include/gpxe/nvs.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
/** A non-volatile storage device */
diff --git a/gpxe/src/include/gpxe/open.h b/gpxe/src/include/gpxe/open.h
index 81d5fc24..ebf754da 100644
--- a/gpxe/src/include/gpxe/open.h
+++ b/gpxe/src/include/gpxe/open.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdarg.h>
#include <gpxe/tables.h>
#include <gpxe/socket.h>
@@ -58,8 +60,11 @@ struct uri_opener {
int ( * open ) ( struct xfer_interface *xfer, struct uri *uri );
};
+/** URI opener table */
+#define URI_OPENERS __table ( struct uri_opener, "uri_openers" )
+
/** Register a URI opener */
-#define __uri_opener __table ( struct uri_opener, uri_openers, 01 )
+#define __uri_opener __table_entry ( URI_OPENERS, 01 )
/** A socket opener */
struct socket_opener {
@@ -78,8 +83,11 @@ struct socket_opener {
struct sockaddr *local );
};
+/** Socket opener table */
+#define SOCKET_OPENERS __table ( struct socket_opener, "socket_openers" )
+
/** Register a socket opener */
-#define __socket_opener __table ( struct socket_opener, socket_openers, 01 )
+#define __socket_opener __table_entry ( SOCKET_OPENERS, 01 )
extern int xfer_open_uri ( struct xfer_interface *xfer, struct uri *uri );
extern int xfer_open_uri_string ( struct xfer_interface *xfer,
@@ -91,5 +99,7 @@ extern int xfer_open_socket ( struct xfer_interface *xfer, int semantics,
struct sockaddr *peer, struct sockaddr *local );
extern int xfer_vopen ( struct xfer_interface *xfer, int type, va_list args );
extern int xfer_open ( struct xfer_interface *xfer, int type, ... );
+extern int xfer_vreopen ( struct xfer_interface *xfer, int type,
+ va_list args );
#endif /* _GPXE_OPEN_H */
diff --git a/gpxe/src/include/gpxe/pci.h b/gpxe/src/include/gpxe/pci.h
index 1ccdb100..8bcf1e0c 100644
--- a/gpxe/src/include/gpxe/pci.h
+++ b/gpxe/src/include/gpxe/pci.h
@@ -16,6 +16,8 @@
* your option) any later version.
*/
+FILE_LICENCE ( GPL2_ONLY );
+
#include <stdint.h>
#include <gpxe/device.h>
#include <gpxe/tables.h>
@@ -41,6 +43,7 @@
#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
+#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
#define PCI_VENDOR_ID 0x00 /* 16 bits */
@@ -233,6 +236,33 @@
#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
+/* Advanced Error Reporting */
+
+#define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */
+#define PCI_ERR_UNC_TRAIN 0x00000001 /* Training */
+#define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */
+#define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */
+#define PCI_ERR_UNC_FCP 0x00002000 /* Flow Control Protocol */
+#define PCI_ERR_UNC_COMP_TIME 0x00004000 /* Completion Timeout */
+#define PCI_ERR_UNC_COMP_ABORT 0x00008000 /* Completer Abort */
+#define PCI_ERR_UNC_UNX_COMP 0x00010000 /* Unexpected Completion */
+#define PCI_ERR_UNC_RX_OVER 0x00020000 /* Receiver Overflow */
+#define PCI_ERR_UNC_MALF_TLP 0x00040000 /* Malformed TLP */
+#define PCI_ERR_UNC_ECRC 0x00080000 /* ECRC Error Status */
+#define PCI_ERR_UNC_UNSUP 0x00100000 /* Unsupported Request */
+#define PCI_ERR_UNCOR_MASK 8 /* Uncorrectable Error Mask */
+ /* Same bits as above */
+#define PCI_ERR_UNCOR_SEVER 12 /* Uncorrectable Error Severity */
+ /* Same bits as above */
+#define PCI_ERR_COR_STATUS 16 /* Correctable Error Status */
+#define PCI_ERR_COR_RCVR 0x00000001 /* Receiver Error Status */
+#define PCI_ERR_COR_BAD_TLP 0x00000040 /* Bad TLP Status */
+#define PCI_ERR_COR_BAD_DLLP 0x00000080 /* Bad DLLP Status */
+#define PCI_ERR_COR_REP_ROLL 0x00000100 /* REPLAY_NUM Rollover */
+#define PCI_ERR_COR_REP_TIMER 0x00001000 /* Replay Timer Timeout */
+#define PCI_ERR_COR_MASK 20 /* Correctable Error Mask */
+ /* Same bits as above */
+
/** A PCI device ID list entry */
struct pci_device_id {
/** Name */
@@ -241,6 +271,8 @@ struct pci_device_id {
uint16_t vendor;
/** PCI device ID */
uint16_t device;
+ /** Arbitrary driver data */
+ unsigned long driver_data;
};
/** Match-anything ID */
@@ -308,12 +340,16 @@ struct pci_driver {
void ( * remove ) ( struct pci_device *pci );
};
+/** PCI driver table */
+#define PCI_DRIVERS __table ( struct pci_driver, "pci_drivers" )
+
/** Declare a PCI driver */
-#define __pci_driver __table ( struct pci_driver, pci_drivers, 01 )
+#define __pci_driver __table_entry ( PCI_DRIVERS, 01 )
#define PCI_DEVFN( slot, func ) ( ( (slot) << 3 ) | (func) )
#define PCI_SLOT( devfn ) ( ( (devfn) >> 3 ) & 0x1f )
#define PCI_FUNC( devfn ) ( (devfn) & 0x07 )
+#define PCI_BUS( busdevfn ) ( (busdevfn) >> 8 )
#define PCI_BUSDEVFN( bus, devfn ) ( ( (bus) << 8 ) | (devfn) )
#define PCI_BASE_CLASS( class ) ( (class) >> 16 )
@@ -324,12 +360,18 @@ struct pci_driver {
* PCI_ROM is used to build up entries in a struct pci_id array. It
* is also parsed by parserom.pl to generate Makefile rules and files
* for rom-o-matic.
+ *
+ * PCI_ID can be used to generate entries without creating a
+ * corresponding ROM in the build process.
*/
-#define PCI_ROM( _vendor, _device, _name, _description ) { \
- .vendor = _vendor, \
- .device = _device, \
- .name = _name, \
+#define PCI_ID( _vendor, _device, _name, _description, _data ) { \
+ .vendor = _vendor, \
+ .device = _device, \
+ .name = _name, \
+ .driver_data = _data \
}
+#define PCI_ROM( _vendor, _device, _name, _description, _data ) \
+ PCI_ID( _vendor, _device, _name, _description, _data )
extern void adjust_pci_device ( struct pci_device *pci );
extern unsigned long pci_bar_start ( struct pci_device *pci,
diff --git a/gpxe/src/include/gpxe/pci_ids.h b/gpxe/src/include/gpxe/pci_ids.h
index 075ff96b..42070138 100644
--- a/gpxe/src/include/gpxe/pci_ids.h
+++ b/gpxe/src/include/gpxe/pci_ids.h
@@ -7,6 +7,8 @@
* Please keep sorted.
*/
+FILE_LICENCE ( GPL2_ONLY );
+
/* Device classes and subclasses */
#define PCI_CLASS_NOT_DEFINED 0x0000
@@ -315,6 +317,7 @@
#define PCI_VENDOR_ID_TIMEDIA 0x1409
#define PCI_VENDOR_ID_OXSEMI 0x1415
#define PCI_VENDOR_ID_AIRONET 0x14b9
+#define PCI_VENDOR_ID_MYRICOM 0x14c1
#define PCI_VENDOR_ID_TITAN 0x14D2
#define PCI_VENDOR_ID_PANACOM 0x14d4
#define PCI_VENDOR_ID_BROADCOM 0x14e4
diff --git a/gpxe/src/include/gpxe/pci_io.h b/gpxe/src/include/gpxe/pci_io.h
index 365166c8..8b2729ab 100644
--- a/gpxe/src/include/gpxe/pci_io.h
+++ b/gpxe/src/include/gpxe/pci_io.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/api.h>
#include <config/ioapi.h>
diff --git a/gpxe/src/include/gpxe/pcibackup.h b/gpxe/src/include/gpxe/pcibackup.h
new file mode 100644
index 00000000..3d295c0f
--- /dev/null
+++ b/gpxe/src/include/gpxe/pcibackup.h
@@ -0,0 +1,33 @@
+#ifndef _GPXE_PCIBACKUP_H
+#define _GPXE_PCIBACKUP_H
+
+/** @file
+ *
+ * PCI configuration space backup and restoration
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdint.h>
+
+/** A PCI configuration space backup */
+struct pci_config_backup {
+ uint32_t dwords[64];
+};
+
+/** PCI configuration space backup exclusion list end marker */
+#define PCI_CONFIG_BACKUP_EXCLUDE_END 0xff
+
+/** Define a PCI configuration space backup exclusion list */
+#define PCI_CONFIG_BACKUP_EXCLUDE(...) \
+ { __VA_ARGS__, PCI_CONFIG_BACKUP_EXCLUDE_END }
+
+extern void pci_backup ( struct pci_device *pci,
+ struct pci_config_backup *backup,
+ const uint8_t *exclude );
+extern void pci_restore ( struct pci_device *pci,
+ struct pci_config_backup *backup,
+ const uint8_t *exclude );
+
+#endif /* _GPXE_PCIBACKUP_H */
diff --git a/gpxe/src/include/gpxe/posix_io.h b/gpxe/src/include/gpxe/posix_io.h
index 9984db00..3063dfff 100644
--- a/gpxe/src/include/gpxe/posix_io.h
+++ b/gpxe/src/include/gpxe/posix_io.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/uaccess.h>
diff --git a/gpxe/src/include/gpxe/process.h b/gpxe/src/include/gpxe/process.h
index 8d9b109a..944858d7 100644
--- a/gpxe/src/include/gpxe/process.h
+++ b/gpxe/src/include/gpxe/process.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/list.h>
#include <gpxe/refcnt.h>
#include <gpxe/tables.h>
@@ -45,6 +47,7 @@ static inline __attribute__ (( always_inline )) void
process_init_stopped ( struct process *process,
void ( * step ) ( struct process *process ),
struct refcnt *refcnt ) {
+ INIT_LIST_HEAD ( &process->list );
process->step = step;
process->refcnt = refcnt;
}
@@ -63,13 +66,15 @@ process_init ( struct process *process,
process_add ( process );
}
+/** Permanent process table */
+#define PERMANENT_PROCESSES __table ( struct process, "processes" )
+
/**
* Declare a permanent process
*
* Permanent processes will be automatically added to the process list
* at initialisation time.
*/
-#define __permanent_process \
- __table ( struct process, processes, 01 )
+#define __permanent_process __table_entry ( PERMANENT_PROCESSES, 01 )
#endif /* _GPXE_PROCESS_H */
diff --git a/gpxe/src/include/gpxe/profile.h b/gpxe/src/include/gpxe/profile.h
index d46ca05a..a5bdd3a4 100644
--- a/gpxe/src/include/gpxe/profile.h
+++ b/gpxe/src/include/gpxe/profile.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
/**
diff --git a/gpxe/src/include/gpxe/ramdisk.h b/gpxe/src/include/gpxe/ramdisk.h
index 4a77f05e..31a1d998 100644
--- a/gpxe/src/include/gpxe/ramdisk.h
+++ b/gpxe/src/include/gpxe/ramdisk.h
@@ -8,6 +8,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/uaccess.h>
#include <gpxe/blockdev.h>
diff --git a/gpxe/src/include/gpxe/rarp.h b/gpxe/src/include/gpxe/rarp.h
index 81e03bde..7ade8312 100644
--- a/gpxe/src/include/gpxe/rarp.h
+++ b/gpxe/src/include/gpxe/rarp.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
struct net_protocol;
extern struct net_protocol rarp_protocol;
diff --git a/gpxe/src/include/gpxe/rc80211.h b/gpxe/src/include/gpxe/rc80211.h
new file mode 100644
index 00000000..0856896c
--- /dev/null
+++ b/gpxe/src/include/gpxe/rc80211.h
@@ -0,0 +1,19 @@
+#ifndef _GPXE_RC80211_H
+#define _GPXE_RC80211_H
+
+/** @file
+ *
+ * Rate-control algorithm prototype for 802.11.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+struct net80211_device;
+struct rc80211_ctx;
+
+struct rc80211_ctx * rc80211_init ( struct net80211_device *dev );
+void rc80211_update_tx ( struct net80211_device *dev, int retries, int rc );
+void rc80211_update_rx ( struct net80211_device *dev, int retry, u16 rate );
+void rc80211_free ( struct rc80211_ctx *ctx );
+
+#endif /* _GPXE_RC80211_H */
diff --git a/gpxe/src/include/gpxe/refcnt.h b/gpxe/src/include/gpxe/refcnt.h
index 68e0fd4b..e56f1d31 100644
--- a/gpxe/src/include/gpxe/refcnt.h
+++ b/gpxe/src/include/gpxe/refcnt.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/**
* A reference counter
*
diff --git a/gpxe/src/include/gpxe/resolv.h b/gpxe/src/include/gpxe/resolv.h
index e73c8201..33bb0986 100644
--- a/gpxe/src/include/gpxe/resolv.h
+++ b/gpxe/src/include/gpxe/resolv.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/refcnt.h>
#include <gpxe/interface.h>
#include <gpxe/tables.h>
@@ -149,9 +151,11 @@ struct resolver {
/** Normal resolver priority */
#define RESOLV_NORMAL 02
+/** Resolvers table */
+#define RESOLVERS __table ( struct resolver, "resolvers" )
+
/** Register as a name resolver */
-#define __resolver( resolv_order ) \
- __table ( struct resolver, resolvers, resolv_order )
+#define __resolver( resolv_order ) __table_entry ( RESOLVERS, resolv_order )
extern void resolv_done ( struct resolv_interface *resolv,
struct sockaddr *sa, int rc );
diff --git a/gpxe/src/include/gpxe/retry.h b/gpxe/src/include/gpxe/retry.h
index 1e7fde4c..ada0204d 100644
--- a/gpxe/src/include/gpxe/retry.h
+++ b/gpxe/src/include/gpxe/retry.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/list.h>
/** Default timeout value */
diff --git a/gpxe/src/include/gpxe/rotate.h b/gpxe/src/include/gpxe/rotate.h
index 42ec7196..0371c578 100644
--- a/gpxe/src/include/gpxe/rotate.h
+++ b/gpxe/src/include/gpxe/rotate.h
@@ -6,6 +6,8 @@
* Bit operations
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
static inline uint32_t rol32 ( uint32_t data, unsigned int rotation ) {
diff --git a/gpxe/src/include/gpxe/rsa.h b/gpxe/src/include/gpxe/rsa.h
index e30e1a5a..5052ad46 100644
--- a/gpxe/src/include/gpxe/rsa.h
+++ b/gpxe/src/include/gpxe/rsa.h
@@ -1,6 +1,8 @@
#ifndef _GPXE_RSA_H
#define _GPXE_RSA_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
struct pubkey_algorithm;
extern struct pubkey_algorithm rsa_algorithm;
diff --git a/gpxe/src/include/gpxe/sanboot.h b/gpxe/src/include/gpxe/sanboot.h
index ea26a356..fd063164 100644
--- a/gpxe/src/include/gpxe/sanboot.h
+++ b/gpxe/src/include/gpxe/sanboot.h
@@ -1,6 +1,8 @@
#ifndef _GPXE_SANBOOT_H
#define _GPXE_SANBOOT_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/tables.h>
struct sanboot_protocol {
@@ -8,7 +10,11 @@ struct sanboot_protocol {
int ( * boot ) ( const char *root_path );
};
-#define __sanboot_protocol \
- __table ( struct sanboot_protocol, sanboot_protocols, 01 )
+#define SANBOOT_PROTOCOLS \
+ __table ( struct sanboot_protocol, "sanboot_protocols" )
+
+#define __sanboot_protocol __table_entry ( SANBOOT_PROTOCOLS, 01 )
+
+extern int keep_san ( void );
#endif /* _GPXE_SANBOOT_H */
diff --git a/gpxe/src/include/gpxe/scsi.h b/gpxe/src/include/gpxe/scsi.h
index e820117b..97416970 100644
--- a/gpxe/src/include/gpxe/scsi.h
+++ b/gpxe/src/include/gpxe/scsi.h
@@ -12,6 +12,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
/**
* @defgroup scsiops SCSI operation codes
* @{
@@ -234,18 +236,23 @@ struct scsi_command {
uint8_t status;
/** SCSI sense response code */
uint8_t sense_response;
+ /** Command status code */
+ int rc;
};
+/** A SCSI LUN
+ *
+ * This is a four-level LUN as specified by SAM-2, in big-endian
+ * order.
+ */
+struct scsi_lun {
+ uint16_t u16[4];
+} __attribute__ (( packed ));
+
/** A SCSI device */
struct scsi_device {
/** Block device interface */
struct block_device blockdev;
- /** Logical unit number (LUN)
- *
- * This is a four-level LUN as specified by SAM-2, in
- * big-endian order.
- */
- uint64_t lun;
/**
* Issue SCSI command
*
@@ -254,10 +261,11 @@ struct scsi_device {
* @ret rc Return status code
*
* Note that a successful return status code indicates only
- * that the SCSI command completed. The caller must check the
- * status field in the command structure to see if, for
- * example, the device returned CHECK CONDITION or some other
- * non-success status code.
+ * that the SCSI command was issued. The caller must check
+ * the status field in the command structure to see when the
+ * command completes and whether, for example, the device
+ * returned CHECK CONDITION or some other non-success status
+ * code.
*/
int ( * command ) ( struct scsi_device *scsi,
struct scsi_command *command );
@@ -265,6 +273,9 @@ struct scsi_device {
struct refcnt *backend;
};
+extern int scsi_detached_command ( struct scsi_device *scsi,
+ struct scsi_command *command );
extern int init_scsidev ( struct scsi_device *scsi );
+extern int scsi_parse_lun ( const char *lun_string, struct scsi_lun *lun );
#endif /* _GPXE_SCSI_H */
diff --git a/gpxe/src/include/gpxe/sec80211.h b/gpxe/src/include/gpxe/sec80211.h
new file mode 100644
index 00000000..502ebf7d
--- /dev/null
+++ b/gpxe/src/include/gpxe/sec80211.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _GPXE_SEC80211_H
+#define _GPXE_SEC80211_H
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <gpxe/net80211.h>
+#include <errno.h>
+
+/** @file
+ *
+ * Definitions for general secured-network routines.
+ *
+ * Any function in this file which may be referenced by code which is
+ * not exclusive to encryption-enabled builds (e.g. sec80211_detect(),
+ * which is called by net80211_probe_step() to fill the net80211_wlan
+ * structure's security fields) must be declared as a weak symbol,
+ * using an inline interface similar to that used for
+ * sec80211_detect() below. This prevents secure network support from
+ * bloating general builds by any more than a few tiny hooks to call
+ * crypto functions when crypto structures are non-NULL.
+ */
+
+int _sec80211_detect ( struct io_buffer *iob,
+ enum net80211_security_proto *secprot,
+ enum net80211_crypto_alg *crypt )
+ __attribute__ (( weak ));
+
+
+/**
+ * Inline safety wrapper for _sec80211_detect()
+ *
+ * @v iob I/O buffer containing beacon frame
+ * @ret secprot Security handshaking protocol used by network
+ * @ret crypt Cryptosystem used by network
+ * @ret rc Return status code
+ *
+ * This function transparently calls _sec80211_detect() if the file
+ * containing it was compiled in, or returns an error indication of
+ * @c -ENOTSUP if not.
+ */
+static inline int sec80211_detect ( struct io_buffer *iob,
+ enum net80211_security_proto *secprot,
+ enum net80211_crypto_alg *crypt ) {
+ if ( _sec80211_detect )
+ return _sec80211_detect ( iob, secprot, crypt );
+ return -ENOTSUP;
+}
+
+int sec80211_detect_ie ( int is_rsn, u8 *start, u8 *end,
+ enum net80211_security_proto *secprot,
+ enum net80211_crypto_alg *crypt );
+u8 * sec80211_find_rsn ( union ieee80211_ie *ie, void *ie_end,
+ int *is_rsn, u8 **end );
+
+int sec80211_install ( struct net80211_crypto **which,
+ enum net80211_crypto_alg crypt,
+ const void *key, int len, const void *rsc );
+
+u32 sec80211_rsn_get_crypto_desc ( enum net80211_crypto_alg crypt, int rsnie );
+u32 sec80211_rsn_get_akm_desc ( enum net80211_security_proto secprot,
+ int rsnie );
+enum net80211_crypto_alg sec80211_rsn_get_net80211_crypt ( u32 desc );
+
+#endif /* _GPXE_SEC80211_H */
+
diff --git a/gpxe/src/include/gpxe/segment.h b/gpxe/src/include/gpxe/segment.h
index 5ab91699..5b59c54c 100644
--- a/gpxe/src/include/gpxe/segment.h
+++ b/gpxe/src/include/gpxe/segment.h
@@ -8,6 +8,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/uaccess.h>
extern int prep_segment ( userptr_t segment, size_t filesz, size_t memsz );
diff --git a/gpxe/src/include/gpxe/serial.h b/gpxe/src/include/gpxe/serial.h
index 2825b936..a72ca7e8 100644
--- a/gpxe/src/include/gpxe/serial.h
+++ b/gpxe/src/include/gpxe/serial.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
extern void serial_putc ( int ch );
extern int serial_getc ( void );
extern int serial_ischar ( void );
diff --git a/gpxe/src/include/gpxe/settings.h b/gpxe/src/include/gpxe/settings.h
index 9e62cdea..efefe73a 100644
--- a/gpxe/src/include/gpxe/settings.h
+++ b/gpxe/src/include/gpxe/settings.h
@@ -7,11 +7,12 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/tables.h>
#include <gpxe/list.h>
#include <gpxe/refcnt.h>
-#include <gpxe/dhcpopts.h>
struct settings;
struct in_addr;
@@ -36,8 +37,11 @@ struct setting {
unsigned int tag;
};
+/** Configuration setting table */
+#define SETTINGS __table ( struct setting, "settings" )
+
/** Declare a configuration setting */
-#define __setting __table ( struct setting, settings, 01 )
+#define __setting __table_entry ( SETTINGS, 01 )
/** Settings block operations */
struct settings_operations {
@@ -64,6 +68,11 @@ struct settings_operations {
*/
int ( * fetch ) ( struct settings *settings, struct setting *setting,
void *data, size_t len );
+ /** Clear settings block
+ *
+ * @v settings Settings block
+ */
+ void ( * clear ) ( struct settings *settings );
};
/** A settings block */
@@ -123,9 +132,11 @@ struct setting_type {
char *buf, size_t len );
};
+/** Configuration setting type table */
+#define SETTING_TYPES __table ( struct setting_type, "setting_types" )
+
/** Declare a configuration setting type */
-#define __setting_type \
- __table ( struct setting_type, setting_types, 01 )
+#define __setting_type __table_entry ( SETTING_TYPES, 01 )
/**
* A settings applicator
@@ -139,28 +150,32 @@ struct settings_applicator {
int ( * apply ) ( void );
};
+/** Settings applicator table */
+#define SETTINGS_APPLICATORS \
+ __table ( struct settings_applicator, "settings_applicators" )
+
/** Declare a settings applicator */
-#define __settings_applicator \
- __table ( struct settings_applicator, settings_applicators, 01 )
+#define __settings_applicator __table_entry ( SETTINGS_APPLICATORS, 01 )
/**
- * A simple settings block
+ * A generic settings block
*
*/
-struct simple_settings {
+struct generic_settings {
/** Settings block */
struct settings settings;
- /** DHCP options */
- struct dhcp_options dhcpopts;
+ /** List of generic settings */
+ struct list_head list;
};
-extern struct settings_operations simple_settings_operations;
-extern int simple_settings_store ( struct settings *settings,
- struct setting *setting,
- const void *data, size_t len );
-extern int simple_settings_fetch ( struct settings *settings,
- struct setting *setting,
- void *data, size_t len );
+extern struct settings_operations generic_settings_operations;
+extern int generic_settings_store ( struct settings *settings,
+ struct setting *setting,
+ const void *data, size_t len );
+extern int generic_settings_fetch ( struct settings *settings,
+ struct setting *setting,
+ void *data, size_t len );
+extern void generic_settings_clear ( struct settings *settings );
extern int register_settings ( struct settings *settings,
struct settings *parent );
@@ -191,10 +206,9 @@ extern unsigned long fetch_uintz_setting ( struct settings *settings,
struct setting *setting );
extern int fetch_uuid_setting ( struct settings *settings,
struct setting *setting, union uuid *uuid );
+extern void clear_settings ( struct settings *settings );
extern int setting_cmp ( struct setting *a, struct setting *b );
-extern struct settings * find_child_settings ( struct settings *parent,
- const char *name );
extern struct settings * find_settings ( const char *name );
extern int storef_setting ( struct settings *settings,
@@ -228,6 +242,7 @@ extern struct setting priority_setting __setting;
extern struct setting uuid_setting __setting;
extern struct setting next_server_setting __setting;
extern struct setting mac_setting __setting;
+extern struct setting busid_setting __setting;
extern struct setting user_class_setting __setting;
/**
@@ -255,15 +270,16 @@ static inline void settings_init ( struct settings *settings,
/**
* Initialise a settings block
*
- * @v simple Simple settings block
+ * @v generics Generic settings block
* @v refcnt Containing object reference counter, or NULL
* @v name Settings block name
*/
-static inline void simple_settings_init ( struct simple_settings *simple,
- struct refcnt *refcnt,
- const char *name ) {
- settings_init ( &simple->settings, &simple_settings_operations,
+static inline void generic_settings_init ( struct generic_settings *generics,
+ struct refcnt *refcnt,
+ const char *name ) {
+ settings_init ( &generics->settings, &generic_settings_operations,
refcnt, name, 0 );
+ INIT_LIST_HEAD ( &generics->list );
}
/**
diff --git a/gpxe/src/include/gpxe/settings_ui.h b/gpxe/src/include/gpxe/settings_ui.h
index 48548fd5..a82d7336 100644
--- a/gpxe/src/include/gpxe/settings_ui.h
+++ b/gpxe/src/include/gpxe/settings_ui.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
struct settings;
extern int settings_ui ( struct settings *settings ) __nonnull;
diff --git a/gpxe/src/include/gpxe/sha1.h b/gpxe/src/include/gpxe/sha1.h
index 66370d42..c203d995 100644
--- a/gpxe/src/include/gpxe/sha1.h
+++ b/gpxe/src/include/gpxe/sha1.h
@@ -1,6 +1,8 @@
#ifndef _GPXE_SHA1_H
#define _GPXE_SHA1_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include "crypto/axtls/crypto.h"
struct digest_algorithm;
@@ -10,4 +12,13 @@ struct digest_algorithm;
extern struct digest_algorithm sha1_algorithm;
+/* SHA1-wrapping functions defined in sha1extra.c: */
+
+void prf_sha1 ( const void *key, size_t key_len, const char *label,
+ const void *data, size_t data_len, void *prf, size_t prf_len );
+
+void pbkdf2_sha1 ( const void *passphrase, size_t pass_len,
+ const void *salt, size_t salt_len,
+ int iterations, void *key, size_t key_len );
+
#endif /* _GPXE_SHA1_H */
diff --git a/gpxe/src/include/gpxe/shell.h b/gpxe/src/include/gpxe/shell.h
index c353fc4d..a65a3443 100644
--- a/gpxe/src/include/gpxe/shell.h
+++ b/gpxe/src/include/gpxe/shell.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
extern void shell ( void );
#endif /* _GPXE_SHELL_H */
diff --git a/gpxe/src/include/gpxe/shell_banner.h b/gpxe/src/include/gpxe/shell_banner.h
index f8e92a4d..28482be8 100644
--- a/gpxe/src/include/gpxe/shell_banner.h
+++ b/gpxe/src/include/gpxe/shell_banner.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
extern int shell_banner ( void );
#endif /* _GPXE_SHELL_BANNER_H */
diff --git a/gpxe/src/include/gpxe/smbios.h b/gpxe/src/include/gpxe/smbios.h
index 2b0fcbd1..4df25c3e 100644
--- a/gpxe/src/include/gpxe/smbios.h
+++ b/gpxe/src/include/gpxe/smbios.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/api.h>
#include <config/general.h>
@@ -113,6 +115,25 @@ struct smbios_system_information {
/** SMBIOS system information structure type */
#define SMBIOS_TYPE_SYSTEM_INFORMATION 1
+/** SMBIOS enclosure information structure */
+struct smbios_enclosure_information {
+ /** SMBIOS structure header */
+ struct smbios_header header;
+ /** Manufacturer string */
+ uint8_t manufacturer;
+ /** Type string */
+ uint8_t type;
+ /** Version string */
+ uint8_t version;
+ /** Serial number string */
+ uint8_t serial;
+ /** Asset tag */
+ uint8_t asset_tag;
+} __attribute__ (( packed ));
+
+/** SMBIOS enclosure information structure type */
+#define SMBIOS_TYPE_ENCLOSURE_INFORMATION 3
+
/**
* SMBIOS entry point descriptor
*
diff --git a/gpxe/src/include/gpxe/socket.h b/gpxe/src/include/gpxe/socket.h
index b683bed6..9ea0db94 100644
--- a/gpxe/src/include/gpxe/socket.h
+++ b/gpxe/src/include/gpxe/socket.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
/**
diff --git a/gpxe/src/include/gpxe/spi.h b/gpxe/src/include/gpxe/spi.h
index 8f90e3d4..8e4a6763 100644
--- a/gpxe/src/include/gpxe/spi.h
+++ b/gpxe/src/include/gpxe/spi.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/nvs.h>
/**
@@ -102,6 +104,14 @@ struct spi_device {
unsigned int munge_address : 1;
};
+/**
+ * SPI magic autodetection address length
+ *
+ * Set @c spi_device::address_len to @c SPI_AUTODETECT_ADDRESS_LEN if
+ * the address length should be autodetected.
+ */
+#define SPI_AUTODETECT_ADDRESS_LEN 0
+
static inline __attribute__ (( always_inline )) struct spi_device *
nvs_to_spi ( struct nvs_device *nvs ) {
return container_of ( nvs, struct spi_device, nvs );
diff --git a/gpxe/src/include/gpxe/spi_bit.h b/gpxe/src/include/gpxe/spi_bit.h
index ced85ceb..8bd25196 100644
--- a/gpxe/src/include/gpxe/spi_bit.h
+++ b/gpxe/src/include/gpxe/spi_bit.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/spi.h>
#include <gpxe/bitbash.h>
diff --git a/gpxe/src/include/gpxe/srp.h b/gpxe/src/include/gpxe/srp.h
new file mode 100644
index 00000000..85f39b93
--- /dev/null
+++ b/gpxe/src/include/gpxe/srp.h
@@ -0,0 +1,868 @@
+#ifndef _GPXE_SRP_H
+#define _GPXE_SRP_H
+
+/** @file
+ *
+ * SCSI RDMA Protocol
+ *
+ */
+
+FILE_LICENCE ( BSD2 );
+
+#include <stdint.h>
+#include <byteswap.h>
+#include <gpxe/iobuf.h>
+#include <gpxe/xfer.h>
+#include <gpxe/scsi.h>
+
+/*****************************************************************************
+ *
+ * Common fields
+ *
+ *****************************************************************************
+ */
+
+/** An SRP information unit tag */
+struct srp_tag {
+ uint32_t dwords[2];
+} __attribute__ (( packed ));
+
+/** An SRP port ID */
+struct srp_port_id {
+ uint8_t bytes[16];
+} __attribute__ (( packed ));
+
+/** An SRP port ID pair */
+struct srp_port_ids {
+ /** Initiator port ID */
+ struct srp_port_id initiator;
+ /** Target port ID */
+ struct srp_port_id target;
+} __attribute__ (( packed ));
+
+/** SRP information unit common fields */
+struct srp_common {
+ /** Information unit type */
+ uint8_t type;
+ /** Reserved */
+ uint8_t reserved0[7];
+ /** Tag */
+ struct srp_tag tag;
+} __attribute__ (( packed ));
+
+/*****************************************************************************
+ *
+ * Login request
+ *
+ *****************************************************************************
+ */
+
+/** An SRP login request information unit */
+struct srp_login_req {
+ /** Information unit type
+ *
+ * This must be @c SRP_LOGIN_REQ
+ */
+ uint8_t type;
+ /** Reserved */
+ uint8_t reserved0[7];
+ /** Tag */
+ struct srp_tag tag;
+ /** Requested maximum initiator to target IU length */
+ uint32_t max_i_t_iu_len;
+ /** Reserved */
+ uint8_t reserved1[4];
+ /** Required buffer formats
+ *
+ * This is the bitwise OR of one or more @c
+ * SRP_LOGIN_REQ_FMT_XXX constants.
+ */
+ uint16_t required_buffer_formats;
+ /** Flags
+ *
+ * This is the bitwise OR of zero or more @c
+ * SRP_LOGIN_REQ_FLAG_XXX and @c SRP_LOGIN_REQ_MCA_XXX
+ * constants.
+ */
+ uint8_t flags;
+ /** Reserved */
+ uint8_t reserved2[5];
+ /** Initiator and target port identifiers */
+ struct srp_port_ids port_ids;
+} __attribute__ (( packed ));
+
+/** Type of an SRP login request */
+#define SRP_LOGIN_REQ 0x00
+
+/** Require indirect data buffer descriptor format */
+#define SRP_LOGIN_REQ_FMT_IDBD 0x04
+
+/** Require direct data buffer descriptor format */
+#define SRP_LOGIN_REQ_FMT_DDBD 0x02
+
+/** Use solicited notification for asynchronous events */
+#define SRP_LOGIN_REQ_FLAG_AESOLNT 0x40
+
+/** Use solicited notification for credit request */
+#define SRP_LOGIN_REQ_FLAG_CRSOLNT 0x20
+
+/** Use solicited notification for logouts */
+#define SRP_LOGIN_REQ_FLAG_LOSOLNT 0x10
+
+/** Multi-channel action mask */
+#define SRP_LOGIN_REQ_MCA_MASK 0x03
+
+/** Single RDMA channel operation */
+#define SRP_LOGIN_REQ_MCA_SINGLE_CHANNEL 0x00
+
+/** Multiple independent RDMA channel operation */
+#define SRP_LOGIN_REQ_MCA_MULTIPLE_CHANNELS 0x01
+
+/*****************************************************************************
+ *
+ * Login response
+ *
+ *****************************************************************************
+ */
+
+/** An SRP login response */
+struct srp_login_rsp {
+ /** Information unit type
+ *
+ * This must be @c SRP_LOGIN_RSP
+ */
+ uint8_t type;
+ /** Reserved */
+ uint8_t reserved0[3];
+ /** Request limit delta */
+ uint32_t request_limit_delta;
+ /** Tag */
+ struct srp_tag tag;
+ /** Maximum initiator to target IU length */
+ uint32_t max_i_t_iu_len;
+ /** Maximum target to initiator IU length */
+ uint32_t max_t_i_iu_len;
+ /** Supported buffer formats
+ *
+ * This is the bitwise OR of one or more @c
+ * SRP_LOGIN_RSP_FMT_XXX constants.
+ */
+ uint16_t supported_buffer_formats;
+ /** Flags
+ *
+ * This is the bitwise OR of zero or more @c
+ * SRP_LOGIN_RSP_FLAG_XXX and @c SRP_LOGIN_RSP_MCR_XXX
+ * constants.
+ */
+ uint8_t flags;
+ /** Reserved */
+ uint8_t reserved1[25];
+} __attribute__ (( packed ));
+
+/** Type of an SRP login response */
+#define SRP_LOGIN_RSP 0xc0
+
+/** Indirect data buffer descriptor format supported */
+#define SRP_LOGIN_RSP_FMT_IDBD 0x04
+
+/** Direct data buffer descriptor format supported */
+#define SRP_LOGIN_RSP_FMT_DDBD 0x02
+
+/** Solicited notification is supported */
+#define SRP_LOGIN_RSP_FLAG_SOLNTSUP 0x10
+
+/** Multi-channel result mask */
+#define SRP_LOGIN_RSP_MCR_MASK 0x03
+
+/** No existing RDMA channels were associated with the same I_T nexus */
+#define SRP_LOGIN_RSP_MCR_NO_EXISTING_CHANNELS 0x00
+
+/** One or more existing RDMA channels were terminated */
+#define SRP_LOGIN_RSP_MCR_EXISTING_CHANNELS_TERMINATED 0x01
+
+/** One or more existing RDMA channels continue to operate independently */
+#define SRP_LOGIN_RSP_MCR_EXISTING_CHANNELS_CONTINUE 0x02
+
+/*****************************************************************************
+ *
+ * Login rejection
+ *
+ *****************************************************************************
+ */
+
+/** An SRP login rejection */
+struct srp_login_rej {
+ /** Information unit type
+ *
+ * This must be @c SRP_LOGIN_REJ
+ */
+ uint8_t type;
+ /** Reserved */
+ uint8_t reserved0[3];
+ /** Reason
+ *
+ * This is a @c SRP_LOGIN_REJ_REASON_XXX constant.
+ */
+ uint32_t reason;
+ /** Tag */
+ struct srp_tag tag;
+ /** Reserved */
+ uint8_t reserved1[8];
+ /** Supported buffer formats
+ *
+ * This is the bitwise OR of one or more @c
+ * SRP_LOGIN_REJ_FMT_XXX constants.
+ */
+ uint16_t supported_buffer_formats;
+ /** Reserved */
+ uint8_t reserved2[6];
+} __attribute__ (( packed ));
+
+/** Type of an SRP login rejection */
+#define SRP_LOGIN_REJ 0xc2
+
+/** Unable to establish RDMA channel, no reason specified */
+#define SRP_LOGIN_REJ_REASON_UNKNOWN 0x00010000UL
+
+/** Insufficient RDMA channel resources */
+#define SRP_LOGIN_REJ_REASON_INSUFFICIENT_RESOURCES 0x00010001UL
+
+/** Requested maximum initiator to target IU length value too large */
+#define SRP_LOGIN_REJ_REASON_BAD_MAX_I_T_IU_LEN 0x00010002UL
+
+/** Unable to associate RDMA channel with specified I_T nexus */
+#define SRP_LOGIN_REJ_REASON_CANNOT_ASSOCIATE 0x00010003UL
+
+/** One or more requested data buffer descriptor formats are not supported */
+#define SRP_LOGIN_REJ_REASON_UNSUPPORTED_BUFFER_FORMAT 0x00010004UL
+
+/** SRP target port does not support multiple RDMA channels per I_T nexus */
+#define SRP_LOGIN_REJ_REASON_NO_MULTIPLE_CHANNELS 0x00010005UL
+
+/** RDMA channel limit reached for this initiator */
+#define SRP_LOGIN_REJ_REASON_NO_MORE_CHANNELS 0x00010006UL
+
+/** Indirect data buffer descriptor format supported */
+#define SRP_LOGIN_REJ_FMT_IDBD 0x04
+
+/** Direct data buffer descriptor format supported */
+#define SRP_LOGIN_REJ_FMT_DDBD 0x02
+
+/*****************************************************************************
+ *
+ * Initiator logout
+ *
+ *****************************************************************************
+ */
+
+/** An SRP initiator logout request */
+struct srp_i_logout {
+ /** Information unit type
+ *
+ * This must be @c SRP_I_LOGOUT
+ */
+ uint8_t type;
+ /** Reserved */
+ uint8_t reserved0[7];
+ /** Tag */
+ struct srp_tag tag;
+} __attribute__ (( packed ));
+
+/** Type of an SRP initiator logout request */
+#define SRP_I_LOGOUT 0x03
+
+/*****************************************************************************
+ *
+ * Target logout
+ *
+ *****************************************************************************
+ */
+
+/** An SRP target logout request */
+struct srp_t_logout {
+ /** Information unit type
+ *
+ * This must be @c SRP_T_LOGOUT
+ */
+ uint8_t type;
+ /** Flags
+ *
+ * This is the bitwise OR of zero or more @c
+ * SRP_T_LOGOUT_FLAG_XXX constants.
+ */
+ uint8_t flags;
+ /** Reserved */
+ uint8_t reserved0[2];
+ /** Reason
+ *
+ * This is a @c SRP_T_LOGOUT_REASON_XXX constant.
+ */
+ uint32_t reason;
+ /** Tag */
+ struct srp_tag tag;
+} __attribute__ (( packed ));
+
+/** Type of an SRP target logout request */
+#define SRP_T_LOGOUT 0x80
+
+/** The initiator specified solicited notification of logouts */
+#define SRP_T_LOGOUT_FLAG_SOLNT 0x01
+
+/** No reason specified */
+#define SRP_T_LOGOUT_REASON_UNKNOWN 0x00000000UL
+
+/** Inactive RDMA channel (reclaiming resources) */
+#define SRP_T_LOGOUT_REASON_INACTIVE 0x00000001UL
+
+/** Invalid information unit type code received by SRP target port */
+#define SRP_T_LOGOUT_REASON_INVALID_TYPE 0x00000002UL
+
+/** SRP initiator port sent response with no corresponding request */
+#define SRP_T_LOGOUT_REASON_SPURIOUS_RESPONSE 0x00000003UL
+
+/** RDMA channel disconnected due to multi-channel action code in new login */
+#define SRP_T_LOGOUT_REASON_MCA 0x00000004UL
+
+/** Unsuppported format code value specified in data-out buffer descriptor */
+#define SRP_T_LOGOUT_UNSUPPORTED_DATA_OUT_FORMAT 0x00000005UL
+
+/** Unsuppported format code value specified in data-in buffer descriptor */
+#define SRP_T_LOGOUT_UNSUPPORTED_DATA_IN_FORMAT 0x00000006UL
+
+/** Invalid length for IU type */
+#define SRP_T_LOGOUT_INVALID_IU_LEN 0x00000008UL
+
+/*****************************************************************************
+ *
+ * Task management
+ *
+ *****************************************************************************
+ */
+
+/** An SRP task management request */
+struct srp_tsk_mgmt {
+ /** Information unit type
+ *
+ * This must be @c SRP_TSK_MGMT
+ */
+ uint8_t type;
+ /** Flags
+ *
+ * This is the bitwise OR of zero or more
+ * @c SRP_TSK_MGMT_FLAG_XXX constants.
+ */
+ uint8_t flags;
+ /** Reserved */
+ uint8_t reserved0[6];
+ /** Tag */
+ struct srp_tag tag;
+ /** Reserved */
+ uint8_t reserved1[4];
+ /** Logical unit number */
+ struct scsi_lun lun;
+ /** Reserved */
+ uint8_t reserved2[2];
+ /** Task management function
+ *
+ * This is a @c SRP_TASK_MGMT_FUNC_XXX constant
+ */
+ uint8_t function;
+ /** Reserved */
+ uint8_t reserved3[1];
+ /** Tag of task to be managed */
+ struct srp_tag managed_tag;
+ /** Reserved */
+ uint8_t reserved4[8];
+} __attribute__ (( packed ));
+
+/** Type of an SRP task management request */
+#define SRP_TSK_MGMT 0x01
+
+/** Use solicited notification for unsuccessful completions */
+#define SRP_TSK_MGMT_FLAG_UCSOLNT 0x04
+
+/** Use solicited notification for successful completions */
+#define SRP_TSK_MGMT_FLAG_SCSOLNT 0x02
+
+/** The task manager shall perform an ABORT TASK function */
+#define SRP_TSK_MGMT_FUNC_ABORT_TASK 0x01
+
+/** The task manager shall perform an ABORT TASK SET function */
+#define SRP_TSK_MGMT_FUNC_ABORT_TASK_SET 0x02
+
+/** The task manager shall perform a CLEAR TASK SET function */
+#define SRP_TSK_MGMT_FUNC_CLEAR_TASK_SET 0x04
+
+/** The task manager shall perform a LOGICAL UNIT RESET function */
+#define SRP_TSK_MGMT_FUNC_LOGICAL_UNIT_RESET 0x08
+
+/** The task manager shall perform a CLEAR ACA function */
+#define SRP_TSK_MGMT_FUNC_CLEAR_ACA 0x40
+
+/*****************************************************************************
+ *
+ * SCSI command
+ *
+ *****************************************************************************
+ */
+
+/** An SRP SCSI command */
+struct srp_cmd {
+ /** Information unit type
+ *
+ * This must be @c SRP_CMD
+ */
+ uint8_t type;
+ /** Flags
+ *
+ * This is the bitwise OR of zero or more @c SRP_CMD_FLAG_XXX
+ * constants.
+ */
+ uint8_t flags;
+ /** Reserved */
+ uint8_t reserved0[3];
+ /** Data buffer descriptor formats
+ *
+ * This is the bitwise OR of one @c SRP_CMD_DO_FMT_XXX and one @c
+ * SRP_CMD_DI_FMT_XXX constant.
+ */
+ uint8_t data_buffer_formats;
+ /** Data-out buffer descriptor count */
+ uint8_t data_out_buffer_count;
+ /** Data-in buffer descriptor count */
+ uint8_t data_in_buffer_count;
+ /** Tag */
+ struct srp_tag tag;
+ /** Reserved */
+ uint8_t reserved1[4];
+ /** Logical unit number */
+ struct scsi_lun lun;
+ /** Reserved */
+ uint8_t reserved2[1];
+ /** Task attribute
+ *
+ * This is a @c SRP_CMD_TASK_ATTR_XXX constant.
+ */
+ uint8_t task_attr;
+ /** Reserved */
+ uint8_t reserved3[1];
+ /** Additional CDB length */
+ uint8_t additional_cdb_len;
+ /** Command data block */
+ union scsi_cdb cdb;
+} __attribute__ (( packed ));
+
+/** Type of an SRP SCSI command */
+#define SRP_CMD 0x02
+
+/** Use solicited notification for unsuccessful completions */
+#define SRP_CMD_FLAG_UCSOLNT 0x04
+
+/** Use solicited notification for successful completions */
+#define SRP_CMD_FLAG_SCSOLNT 0x02
+
+/** Data-out buffer format mask */
+#define SRP_CMD_DO_FMT_MASK 0xf0
+
+/** Direct data-out buffer format */
+#define SRP_CMD_DO_FMT_DIRECT 0x10
+
+/** Indirect data-out buffer format */
+#define SRP_CMD_DO_FMT_INDIRECT 0x20
+
+/** Data-in buffer format mask */
+#define SRP_CMD_DI_FMT_MASK 0x0f
+
+/** Direct data-in buffer format */
+#define SRP_CMD_DI_FMT_DIRECT 0x01
+
+/** Indirect data-in buffer format */
+#define SRP_CMD_DI_FMT_INDIRECT 0x02
+
+/** Use the rules for a simple task attribute */
+#define SRP_CMD_TASK_ATTR_SIMPLE 0x00
+
+/** Use the rules for a head of queue task attribute */
+#define SRP_CMD_TASK_ATTR_QUEUE_HEAD 0x01
+
+/** Use the rules for an ordered task attribute */
+#define SRP_CMD_TASK_ATTR_ORDERED 0x02
+
+/** Use the rules for an automatic contingent allegiance task attribute */
+#define SRP_CMD_TASK_ATTR_AUTOMATIC_CONTINGENT_ALLEGIANCE 0x08
+
+/** An SRP memory descriptor */
+struct srp_memory_descriptor {
+ /** Virtual address */
+ uint64_t address;
+ /** Memory handle */
+ uint32_t handle;
+ /** Data length */
+ uint32_t len;
+} __attribute__ (( packed ));
+
+/*****************************************************************************
+ *
+ * SCSI response
+ *
+ *****************************************************************************
+ */
+
+/** An SRP SCSI response */
+struct srp_rsp {
+ /** Information unit type
+ *
+ * This must be @c SRP_RSP
+ */
+ uint8_t type;
+ /** Flags
+ *
+ * This is the bitwise OR of zero or more @c SRP_RSP_FLAG_XXX
+ * constants.
+ */
+ uint8_t flags;
+ /** Reserved */
+ uint8_t reserved0[2];
+ /** Request limit delta */
+ uint32_t request_limit_delta;
+ /** Tag */
+ struct srp_tag tag;
+ /** Reserved */
+ uint8_t reserved1[2];
+ /** Valid fields
+ *
+ * This is the bitwise OR of zero or more @c SRP_RSP_VALID_XXX
+ * constants.
+ */
+ uint8_t valid;
+ /** Status
+ *
+ * This is the SCSI status code.
+ */
+ uint8_t status;
+ /** Data-out residual count */
+ uint32_t data_out_residual_count;
+ /** Data-in residual count */
+ uint32_t data_in_residual_count;
+ /** Sense data list length */
+ uint32_t sense_data_len;
+ /** Response data list length */
+ uint32_t response_data_len;
+} __attribute__ (( packed ));
+
+/** Type of an SRP SCSI response */
+#define SRP_RSP 0xc1
+
+/** The initiator specified solicited notification of this response */
+#define SRP_RSP_FLAG_SOLNT 0x01
+
+/** Data-in residual count field is valid and represents an underflow */
+#define SRP_RSP_VALID_DIUNDER 0x20
+
+/** Data-in residual count field is valid and represents an overflow */
+#define SRP_RSP_VALID_DIOVER 0x10
+
+/** Data-out residual count field is valid and represents an underflow */
+#define SRP_RSP_VALID_DOUNDER 0x08
+
+/** Data-out residual count field is valid and represents an overflow */
+#define SRP_RSP_VALID_DOOVER 0x04
+
+/** Sense data list length field is valid */
+#define SRP_RSP_VALID_SNSVALID 0x02
+
+/** Response data list length field is valid */
+#define SRP_RSP_VALID_RSPVALID 0x01
+
+/**
+ * Get response data portion of SCSI response
+ *
+ * @v rsp SCSI response
+ * @ret response_data Response data, or NULL if not present
+ */
+static inline void * srp_rsp_response_data ( struct srp_rsp *rsp ) {
+ return ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ?
+ ( ( ( void * ) rsp ) + sizeof ( *rsp ) ) : NULL );
+}
+
+/**
+ * Get length of response data portion of SCSI response
+ *
+ * @v rsp SCSI response
+ * @ret response_data_len Response data length
+ */
+static inline size_t srp_rsp_response_data_len ( struct srp_rsp *rsp ) {
+ return ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ?
+ ntohl ( rsp->response_data_len ) : 0 );
+}
+
+/**
+ * Get sense data portion of SCSI response
+ *
+ * @v rsp SCSI response
+ * @ret sense_data Sense data, or NULL if not present
+ */
+static inline void * srp_rsp_sense_data ( struct srp_rsp *rsp ) {
+ return ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ?
+ ( ( ( void * ) rsp ) + sizeof ( *rsp ) +
+ srp_rsp_response_data_len ( rsp ) ) : NULL );
+}
+
+/**
+ * Get length of sense data portion of SCSI response
+ *
+ * @v rsp SCSI response
+ * @ret sense_data_len Sense data length
+ */
+static inline size_t srp_rsp_sense_data_len ( struct srp_rsp *rsp ) {
+ return ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ?
+ ntohl ( rsp->sense_data_len ) : 0 );
+}
+
+/*****************************************************************************
+ *
+ * Credit request
+ *
+ *****************************************************************************
+ */
+
+/** An SRP credit request */
+struct srp_cred_req {
+ /** Information unit type
+ *
+ * This must be @c SRP_CRED_REQ
+ */
+ uint8_t type;
+ /** Flags
+ *
+ * This is the bitwise OR of zero or more
+ * @c SRP_CRED_REQ_FLAG_XXX constants.
+ */
+ uint8_t flags;
+ /** Reserved */
+ uint8_t reserved0[2];
+ /** Request limit delta */
+ uint32_t request_limit_delta;
+ /** Tag */
+ struct srp_tag tag;
+} __attribute__ (( packed ));
+
+/** Type of an SRP credit request */
+#define SRP_CRED_REQ 0x81
+
+/** The initiator specified solicited notification of credit requests */
+#define SRP_CRED_REQ_FLAG_SOLNT 0x01
+
+/*****************************************************************************
+ *
+ * Credit response
+ *
+ *****************************************************************************
+ */
+
+/** An SRP credit response */
+struct srp_cred_rsp {
+ /** Information unit type
+ *
+ * This must be @c SRP_CRED_RSP
+ */
+ uint8_t type;
+ /** Reserved */
+ uint8_t reserved0[7];
+ /** Tag */
+ struct srp_tag tag;
+} __attribute__ (( packed ));
+
+/** Type of an SRP credit response */
+#define SRP_CRED_RSP 0x41
+
+/*****************************************************************************
+ *
+ * Asynchronous event request
+ *
+ *****************************************************************************
+ */
+
+/** An SRP asynchronous event request */
+struct srp_aer_req {
+ /** Information unit type
+ *
+ * This must be @c SRP_AER_REQ
+ */
+ uint8_t type;
+ /** Flags
+ *
+ * This is the bitwise OR of zero or more @c
+ * SRP_AER_REQ_FLAG_XXX constants.
+ */
+ uint8_t flags;
+ /** Reserved */
+ uint8_t reserved0[2];
+ /** Request limit delta */
+ uint32_t request_limit_delta;
+ /** Tag */
+ struct srp_tag tag;
+ /** Reserved */
+ uint8_t reserved1[4];
+ /** Logical unit number */
+ struct scsi_lun lun;
+ /** Sense data list length */
+ uint32_t sense_data_len;
+ /** Reserved */
+ uint8_t reserved2[4];
+} __attribute__ (( packed ));
+
+/** Type of an SRP asynchronous event request */
+#define SRP_AER_REQ 0x82
+
+/** The initiator specified solicited notification of asynchronous events */
+#define SRP_AER_REQ_FLAG_SOLNT 0x01
+
+/**
+ * Get sense data portion of asynchronous event request
+ *
+ * @v aer_req SRP asynchronous event request
+ * @ret sense_data Sense data
+ */
+static inline __always_inline void *
+srp_aer_req_sense_data ( struct srp_aer_req *aer_req ) {
+ return ( ( ( void * ) aer_req ) + sizeof ( *aer_req ) );
+}
+
+/**
+ * Get length of sense data portion of asynchronous event request
+ *
+ * @v aer_req SRP asynchronous event request
+ * @ret sense_data_len Sense data length
+ */
+static inline __always_inline size_t
+srp_aer_req_sense_data_len ( struct srp_aer_req *aer_req ) {
+ return ( ntohl ( aer_req->sense_data_len ) );
+}
+
+/*****************************************************************************
+ *
+ * Asynchronous event response
+ *
+ *****************************************************************************
+ */
+
+/** An SRP asynchronous event response */
+struct srp_aer_rsp {
+ /** Information unit type
+ *
+ * This must be @c SRP_AER_RSP
+ */
+ uint8_t type;
+ /** Reserved */
+ uint8_t reserved0[7];
+ /** Tag */
+ struct srp_tag tag;
+} __attribute__ (( packed ));
+
+/** Type of an SRP asynchronous event response */
+#define SRP_AER_RSP 0x42
+
+/*****************************************************************************
+ *
+ * Information units
+ *
+ *****************************************************************************
+ */
+
+/** Maximum length of any initiator-to-target IU that we will send
+ *
+ * The longest IU is a SRP_CMD with no additional CDB and two direct
+ * data buffer descriptors, which comes to 80 bytes.
+ */
+#define SRP_MAX_I_T_IU_LEN 80
+
+/*****************************************************************************
+ *
+ * SRP device
+ *
+ *****************************************************************************
+ */
+
+struct srp_device;
+
+/** An SRP transport type */
+struct srp_transport_type {
+ /** Length of transport private data */
+ size_t priv_len;
+ /** Parse root path
+ *
+ * @v srp SRP device
+ * @v root_path Root path
+ * @ret Return status code
+ */
+ int ( * parse_root_path ) ( struct srp_device *srp,
+ const char *root_path );
+ /** Connect SRP session
+ *
+ * @v srp SRP device
+ * @ret rc Return status code
+ *
+ * This method should open the underlying socket.
+ */
+ int ( * connect ) ( struct srp_device *srp );
+};
+
+/** An SRP device */
+struct srp_device {
+ /** Reference count */
+ struct refcnt refcnt;
+
+ /** Initiator and target port IDs */
+ struct srp_port_ids port_ids;
+ /** Logical unit number */
+ struct scsi_lun lun;
+ /** Memory handle */
+ uint32_t memory_handle;
+
+ /** Current state
+ *
+ * This is the bitwise-OR of zero or more @c SRP_STATE_XXX
+ * flags.
+ */
+ unsigned int state;
+ /** Retry counter */
+ unsigned int retry_count;
+ /** Current SCSI command */
+ struct scsi_command *command;
+
+ /** Underlying data transfer interface */
+ struct xfer_interface socket;
+
+ /** Transport type */
+ struct srp_transport_type *transport;
+ /** Transport private data */
+ char transport_priv[0];
+};
+
+/**
+ * Get SRP transport private data
+ *
+ * @v srp SRP device
+ * @ret priv SRP transport private data
+ */
+static inline __always_inline void *
+srp_transport_priv ( struct srp_device *srp ) {
+ return ( ( void * ) srp->transport_priv );
+}
+
+/** SRP state flags */
+enum srp_state {
+ /** Underlying socket is open */
+ SRP_STATE_SOCKET_OPEN = 0x0001,
+ /** Session is logged in */
+ SRP_STATE_LOGGED_IN = 0x0002,
+};
+
+/** Maximum number of SRP retry attempts */
+#define SRP_MAX_RETRIES 3
+
+extern int srp_attach ( struct scsi_device *scsi, const char *root_path );
+extern void srp_detach ( struct scsi_device *scsi );
+
+#endif /* _GPXE_SRP_H */
diff --git a/gpxe/src/include/gpxe/tables.h b/gpxe/src/include/gpxe/tables.h
index b2c56ab6..7dfced8c 100644
--- a/gpxe/src/include/gpxe/tables.h
+++ b/gpxe/src/include/gpxe/tables.h
@@ -1,6 +1,8 @@
#ifndef _GPXE_TABLES_H
#define _GPXE_TABLES_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
/** @page ifdef_harmful #ifdef considered harmful
*
* Overuse of @c #ifdef has long been a problem in Etherboot.
@@ -98,7 +100,7 @@
* The linker script takes care of assembling the tables for us. All
* our table sections have names of the format @c .tbl.NAME.NN where
* @c NAME designates the data structure stored in the table (e.g. @c
- * init_fn) and @c NN is a two-digit decimal number used to impose an
+ * init_fns) and @c NN is a two-digit decimal number used to impose an
* ordering upon the tables if required. @c NN=00 is reserved for the
* symbol indicating "table start", and @c NN=99 is reserved for the
* symbol indicating "table end".
@@ -115,7 +117,9 @@
* void ( *frob ) ( void ); // The frobnicating function itself
* };
*
- * #define __frobnicator __table ( frobnicators, 01 )
+ * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
+ *
+ * #define __frobnicator __table_entry ( FROBNICATORS, 01 )
*
* @endcode
*
@@ -145,14 +149,11 @@
*
* #include "frob.h"
*
- * static struct frob frob_start[0] __table_start ( frobnicators );
- * static struct frob frob_end[0] __table_end ( frobnicators );
- *
* // Call all linked-in frobnicators
* void frob_all ( void ) {
* struct frob *frob;
*
- * for ( frob = frob_start ; frob < frob_end ; frob++ ) {
+ * for_each_table ( frob, FROBNICATORS ) {
* printf ( "Calling frobnicator \"%s\"\n", frob->name );
* frob->frob ();
* }
@@ -168,62 +169,266 @@
#define __attribute__( x )
#endif
-#define __table_str( x ) #x
-#define __table_section( table, idx ) \
- __section__ ( ".tbl." __table_str ( table ) "." __table_str ( idx ) )
+/**
+ * Declare a linker table
+ *
+ * @v type Data type
+ * @v name Table name
+ * @ret table Linker table
+ */
+#define __table( type, name ) ( type, name )
-#define __table_section_start( table ) __table_section ( table, 00 )
-#define __table_section_end( table ) __table_section ( table, 99 )
+/**
+ * Get linker table data type
+ *
+ * @v table Linker table
+ * @ret type Data type
+ */
+#define __table_type( table ) __table_extract_type table
+#define __table_extract_type( type, name ) type
-#define __natural_alignment( type ) __aligned__ ( __alignof__ ( type ) )
+/**
+ * Get linker table name
+ *
+ * @v table Linker table
+ * @ret name Table name
+ */
+#define __table_name( table ) __table_extract_name table
+#define __table_extract_name( type, name ) name
/**
- * Linker table entry.
+ * Get linker table section name
*
- * Declares a data structure to be part of a linker table. Use as
- * e.g.
+ * @v table Linker table
+ * @v idx Sub-table index
+ * @ret section Section name
+ */
+#define __table_section( table, idx ) \
+ ".tbl." __table_name ( table ) "." __table_str ( idx )
+#define __table_str( x ) #x
+
+/**
+ * Get linker table alignment
+ *
+ * @v table Linker table
+ * @ret align Alignment
+ */
+#define __table_alignment( table ) __alignof__ ( __table_type ( table ) )
+
+/**
+ * Declare a linker table entry
+ *
+ * @v table Linker table
+ * @v idx Sub-table index
+ *
+ * Example usage:
*
* @code
*
- * struct my_foo __table ( foo, 01 ) = {
+ * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
+ *
+ * #define __frobnicator __table_entry ( FROBNICATORS, 01 )
+ *
+ * struct frobnicator my_frob __frobnicator = {
* ...
* };
*
* @endcode
+ */
+#define __table_entry( table, idx ) \
+ __attribute__ (( __section__ ( __table_section ( table, idx ) ),\
+ __aligned__ ( __table_alignment ( table ) ) ))
+
+/**
+ * Get start of linker table entries
+ *
+ * @v table Linker table
+ * @v idx Sub-table index
+ * @ret entries Start of entries
+ */
+#define __table_entries( table, idx ) ( { \
+ static __table_type ( table ) __table_entries[0] \
+ __table_entry ( table, idx ); \
+ __table_entries; } )
+
+/**
+ * Get start of linker table
+ *
+ * @v table Linker table
+ * @ret start Start of linker table
+ *
+ * Example usage:
+ *
+ * @code
+ *
+ * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
+ *
+ * struct frobnicator *frobs = table_start ( FROBNICATORS );
+ *
+ * @endcode
+ */
+#define table_start( table ) __table_entries ( table, 00 )
+
+/**
+ * Get end of linker table
+ *
+ * @v table Linker table
+ * @ret end End of linker table
+ *
+ * Example usage:
+ *
+ * @code
+ *
+ * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
+ *
+ * struct frobnicator *frobs_end = table_end ( FROBNICATORS );
+ *
+ * @endcode
+ */
+#define table_end( table ) __table_entries ( table, 99 )
+
+/**
+ * Get number of entries in linker table
+ *
+ * @v table Linker table
+ * @ret num_entries Number of entries in linker table
+ *
+ * Example usage:
+ *
+ * @code
+ *
+ * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
+ *
+ * unsigned int num_frobs = table_num_entries ( FROBNICATORS );
+ *
+ * @endcode
*
*/
-#define __table( type, table, idx ) \
- __attribute__ (( __table_section ( table, idx ), \
- __natural_alignment ( type ) ))
+#define table_num_entries( table ) \
+ ( ( unsigned int ) ( table_end ( table ) - \
+ table_start ( table ) ) )
/**
- * Linker table start marker.
+ * Iterate through all entries within a linker table
+ *
+ * @v pointer Entry pointer
+ * @v table Linker table
*
- * Declares a data structure (usually an empty data structure) to be
- * the start of a linker table. Use as e.g.
+ * Example usage:
*
* @code
*
- * static struct foo_start[0] __table_start ( foo );
+ * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
+ *
+ * struct frobnicator *frob;
+ *
+ * for_each_table_entry ( frob, FROBNICATORS ) {
+ * ...
+ * }
*
* @endcode
*
*/
-#define __table_start( type, table ) __table ( type, table, 00 )
+#define for_each_table_entry( pointer, table ) \
+ for ( pointer = table_start ( table ) ; \
+ pointer < table_end ( table ) ; \
+ pointer++ )
/**
- * Linker table end marker.
+ * Iterate through all entries within a linker table in reverse order
*
- * Declares a data structure (usually an empty data structure) to be
- * the end of a linker table. Use as e.g.
+ * @v pointer Entry pointer
+ * @v table Linker table
+ *
+ * Example usage:
*
* @code
*
- * static struct foo_end[0] __table_end ( foo );
+ * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
+ *
+ * struct frobnicator *frob;
+ *
+ * for_each_table_entry_reverse ( frob, FROBNICATORS ) {
+ * ...
+ * }
*
* @endcode
*
*/
-#define __table_end( type, table ) __table ( type, table, 99 )
+#define for_each_table_entry_reverse( pointer, table ) \
+ for ( pointer = ( table_end ( table ) - 1 ) ; \
+ pointer >= table_start ( table ) ; \
+ pointer-- )
+
+/******************************************************************************
+ *
+ * Intel's C compiler chokes on several of the constructs used in this
+ * file. The workarounds are ugly, so we use them only for an icc
+ * build.
+ *
+ */
+#define ICC_ALIGN_HACK_FACTOR 128
+#ifdef __ICC
+
+/*
+ * icc miscompiles zero-length arrays by inserting padding to a length
+ * of two array elements. We therefore have to generate the
+ * __table_entries() symbols by hand in asm.
+ *
+ */
+#undef __table_entries
+#define __table_entries( table, idx ) ( { \
+ extern __table_type ( table ) \
+ __table_temp_sym ( idx, __LINE__ ) [] \
+ __table_entry ( table, idx ) \
+ asm ( __table_entries_sym ( table, idx ) ); \
+ __asm__ ( ".ifndef %c0\n\t" \
+ ".section " __table_section ( table, idx ) "\n\t" \
+ ".align %c1\n\t" \
+ "\n%c0:\n\t" \
+ ".previous\n\t" \
+ ".endif\n\t" \
+ : : "i" ( __table_temp_sym ( idx, __LINE__ ) ), \
+ "i" ( __table_alignment ( table ) ) ); \
+ __table_temp_sym ( idx, __LINE__ ); } )
+#define __table_entries_sym( table, idx ) \
+ "__tbl_" __table_name ( table ) "_" #idx
+#define __table_temp_sym( a, b ) \
+ ___table_temp_sym( __table_, a, _, b )
+#define ___table_temp_sym( a, b, c, d ) a ## b ## c ## d
+
+/*
+ * icc ignores __attribute__ (( aligned (x) )) when it is used to
+ * decrease the compiler's default choice of alignment (which may be
+ * higher than the alignment actually required by the structure). We
+ * work around this by forcing the alignment to a large multiple of
+ * the required value (so that we are never attempting to decrease the
+ * default alignment) and then postprocessing the object file to
+ * reduce the alignment back down to the "real" value.
+ *
+ */
+#undef __table_alignment
+#define __table_alignment( table ) \
+ ( ICC_ALIGN_HACK_FACTOR * __alignof__ ( __table_type ( table ) ) )
+
+/*
+ * Because of the alignment hack, we must ensure that the compiler
+ * never tries to place multiple objects within the same section,
+ * otherwise the assembler will insert padding to the (incorrect)
+ * alignment boundary. Do this by appending the line number to table
+ * section names.
+ *
+ * Note that we don't need to worry about padding between array
+ * elements, since the alignment is declared on the variable (i.e. the
+ * whole array) rather than on the type (i.e. on all individual array
+ * elements).
+ */
+#undef __table_section
+#define __table_section( table, idx ) \
+ ".tbl." __table_name ( table ) "." __table_str ( idx ) \
+ "." __table_xstr ( __LINE__ )
+#define __table_xstr( x ) __table_str ( x )
+
+#endif /* __ICC */
#endif /* _GPXE_TABLES_H */
diff --git a/gpxe/src/include/gpxe/tcp.h b/gpxe/src/include/gpxe/tcp.h
index 264ec29b..7ae7eab9 100644
--- a/gpxe/src/include/gpxe/tcp.h
+++ b/gpxe/src/include/gpxe/tcp.h
@@ -9,6 +9,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/tcpip.h>
/**
@@ -227,6 +229,16 @@ struct tcp_options {
TCP_STATE_SENT ( TCP_FIN ) ) ) \
== TCP_STATE_ACKED ( TCP_SYN ) )
+/** Have ever been fully established
+ *
+ * We have been fully established if we have both received a SYN and
+ * had our own SYN acked.
+ */
+#define TCP_HAS_BEEN_ESTABLISHED(state) \
+ ( ( (state) & ( TCP_STATE_ACKED ( TCP_SYN ) | \
+ TCP_STATE_RCVD ( TCP_SYN ) ) ) \
+ == ( TCP_STATE_ACKED ( TCP_SYN ) | TCP_STATE_RCVD ( TCP_SYN ) ) )
+
/** Have closed gracefully
*
* We have closed gracefully if we have both received a FIN and had
diff --git a/gpxe/src/include/gpxe/tcpip.h b/gpxe/src/include/gpxe/tcpip.h
index da89530e..f71d7d6d 100644
--- a/gpxe/src/include/gpxe/tcpip.h
+++ b/gpxe/src/include/gpxe/tcpip.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/socket.h>
#include <gpxe/in.h>
@@ -98,13 +100,18 @@ struct tcpip_net_protocol {
uint16_t *trans_csum );
};
+/** TCP/IP transport-layer protocol table */
+#define TCPIP_PROTOCOLS __table ( struct tcpip_protocol, "tcpip_protocols" )
+
/** Declare a TCP/IP transport-layer protocol */
-#define __tcpip_protocol \
- __table ( struct tcpip_protocol, tcpip_protocols, 01 )
+#define __tcpip_protocol __table_entry ( TCPIP_PROTOCOLS, 01 )
+
+/** TCP/IP network-layer protocol table */
+#define TCPIP_NET_PROTOCOLS \
+ __table ( struct tcpip_net_protocol, "tcpip_net_protocols" )
/** Declare a TCP/IP network-layer protocol */
-#define __tcpip_net_protocol \
- __table ( struct tcpip_net_protocol, tcpip_net_protocols, 01 )
+#define __tcpip_net_protocol __table_entry ( TCPIP_NET_PROTOCOLS, 01 )
extern int tcpip_rx ( struct io_buffer *iobuf, uint8_t tcpip_proto,
struct sockaddr_tcpip *st_src,
diff --git a/gpxe/src/include/gpxe/tftp.h b/gpxe/src/include/gpxe/tftp.h
index 0177a95a..c57bb254 100644
--- a/gpxe/src/include/gpxe/tftp.h
+++ b/gpxe/src/include/gpxe/tftp.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#define TFTP_PORT 69 /**< Default TFTP server port */
diff --git a/gpxe/src/include/gpxe/threewire.h b/gpxe/src/include/gpxe/threewire.h
index 865fc25d..e23284af 100644
--- a/gpxe/src/include/gpxe/threewire.h
+++ b/gpxe/src/include/gpxe/threewire.h
@@ -10,6 +10,8 @@
* support.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/spi.h>
#include <limits.h>
@@ -43,6 +45,7 @@ extern int threewire_read ( struct nvs_device *nvs, unsigned int address,
void *data, size_t len );
extern int threewire_write ( struct nvs_device *nvs, unsigned int address,
const void *data, size_t len );
+extern int threewire_detect_address_len ( struct spi_device *device );
/**
* @defgroup tdevs Three-wire device types
@@ -84,6 +87,19 @@ init_at93c56 ( struct spi_device *device, unsigned int organisation ) {
init_at93cx6 ( device, organisation );
}
+/**
+ * Initialise Atmel AT93C66 serial EEPROM
+ *
+ * @v device SPI device
+ * @v organisation Word organisation (8 or 16)
+ */
+static inline __attribute__ (( always_inline )) void
+init_at93c66 ( struct spi_device *device, unsigned int organisation ) {
+ device->nvs.size = ( 4096 / organisation );
+ device->address_len = ( ( organisation == 8 ) ? 9 : 8 );
+ init_at93cx6 ( device, organisation );
+}
+
/** @} */
#endif /* _GPXE_THREEWIRE_H */
diff --git a/gpxe/src/include/gpxe/timer.h b/gpxe/src/include/gpxe/timer.h
index 862d87b3..86722dca 100644
--- a/gpxe/src/include/gpxe/timer.h
+++ b/gpxe/src/include/gpxe/timer.h
@@ -9,6 +9,8 @@
* for a monotonically increasing tick counter.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/api.h>
#include <config/timer.h>
diff --git a/gpxe/src/include/gpxe/tls.h b/gpxe/src/include/gpxe/tls.h
index ddec7bec..e2da0462 100644
--- a/gpxe/src/include/gpxe/tls.h
+++ b/gpxe/src/include/gpxe/tls.h
@@ -7,6 +7,8 @@
* Transport Layer Security Protocol
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <gpxe/refcnt.h>
#include <gpxe/filter.h>
diff --git a/gpxe/src/include/gpxe/uaccess.h b/gpxe/src/include/gpxe/uaccess.h
index 33aaed18..5a8f2921 100644
--- a/gpxe/src/include/gpxe/uaccess.h
+++ b/gpxe/src/include/gpxe/uaccess.h
@@ -19,6 +19,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <string.h>
#include <gpxe/api.h>
diff --git a/gpxe/src/include/gpxe/udp.h b/gpxe/src/include/gpxe/udp.h
index e515f650..670c5e5a 100644
--- a/gpxe/src/include/gpxe/udp.h
+++ b/gpxe/src/include/gpxe/udp.h
@@ -9,6 +9,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stddef.h>
#include <gpxe/iobuf.h>
#include <gpxe/tcpip.h>
diff --git a/gpxe/src/include/gpxe/umalloc.h b/gpxe/src/include/gpxe/umalloc.h
index e6fc7bf0..b0e55645 100644
--- a/gpxe/src/include/gpxe/umalloc.h
+++ b/gpxe/src/include/gpxe/umalloc.h
@@ -8,6 +8,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/api.h>
#include <config/umalloc.h>
#include <gpxe/uaccess.h>
diff --git a/gpxe/src/include/gpxe/uri.h b/gpxe/src/include/gpxe/uri.h
index 3803868d..405d0ce9 100644
--- a/gpxe/src/include/gpxe/uri.h
+++ b/gpxe/src/include/gpxe/uri.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stddef.h>
#include <stdlib.h>
#include <gpxe/refcnt.h>
@@ -18,6 +20,10 @@
*
* Note that all fields within a URI are optional and may be NULL.
*
+ * The pointers to the various fields are packed together so they can
+ * be accessed in array fashion in some places in uri.c where doing so
+ * saves significant code size.
+ *
* Some examples are probably helpful:
*
* http://www.etherboot.org/wiki :
@@ -59,8 +65,40 @@ struct uri {
const char *query;
/** Fragment */
const char *fragment;
+} __attribute__ (( packed ));
+
+/** A field in a URI
+ *
+ * The order of the indices in this enumeration must match the order
+ * of the fields in the URI structure.
+ */
+enum {
+ URI_SCHEME = 0, URI_SCHEME_BIT = ( 1 << URI_SCHEME ),
+ URI_OPAQUE = 1, URI_OPAQUE_BIT = ( 1 << URI_OPAQUE ),
+ URI_USER = 2, URI_USER_BIT = ( 1 << URI_USER ),
+ URI_PASSWORD = 3, URI_PASSWORD_BIT = ( 1 << URI_PASSWORD ),
+ URI_HOST = 4, URI_HOST_BIT = ( 1 << URI_HOST ),
+ URI_PORT = 5, URI_PORT_BIT = ( 1 << URI_PORT ),
+ URI_PATH = 6, URI_PATH_BIT = ( 1 << URI_PATH ),
+ URI_QUERY = 7, URI_QUERY_BIT = ( 1 << URI_QUERY ),
+ URI_FRAGMENT = 8, URI_FRAGMENT_BIT = ( 1 << URI_FRAGMENT ),
+
+ URI_FIRST_FIELD = URI_SCHEME,
+ URI_LAST_FIELD = URI_FRAGMENT,
};
+/** Extract field from URI */
+#define uri_get_field( uri, field ) (&uri->scheme)[field]
+
+/** All URI fields */
+#define URI_ALL ( URI_SCHEME_BIT | URI_OPAQUE_BIT | URI_USER_BIT | \
+ URI_PASSWORD_BIT | URI_HOST_BIT | URI_PORT_BIT | \
+ URI_PATH_BIT | URI_QUERY_BIT | URI_FRAGMENT_BIT )
+
+/** URI fields that should be decoded on storage */
+#define URI_ENCODED ( URI_USER_BIT | URI_PASSWORD_BIT | URI_HOST_BIT | \
+ URI_PATH_BIT | URI_QUERY_BIT | URI_FRAGMENT_BIT )
+
/**
* URI is an absolute URI
*
@@ -129,14 +167,16 @@ extern struct uri *cwuri;
extern struct uri * parse_uri ( const char *uri_string );
extern unsigned int uri_port ( struct uri *uri, unsigned int default_port );
-extern int unparse_uri ( char *buf, size_t size, struct uri *uri );
+extern int unparse_uri ( char *buf, size_t size, struct uri *uri,
+ unsigned int fields );
extern struct uri * uri_dup ( struct uri *uri );
extern char * resolve_path ( const char *base_path,
const char *relative_path );
extern struct uri * resolve_uri ( struct uri *base_uri,
struct uri *relative_uri );
extern void churi ( struct uri *uri );
-extern size_t uri_encode ( const char *raw_string, char *buf, size_t len );
-extern size_t uri_decode ( const char *encoded_string, char *buf, size_t len );
+extern size_t uri_encode ( const char *raw_string, char *buf, ssize_t len,
+ int field );
+extern size_t uri_decode ( const char *encoded_string, char *buf, ssize_t len );
#endif /* _GPXE_URI_H */
diff --git a/gpxe/src/include/gpxe/uuid.h b/gpxe/src/include/gpxe/uuid.h
index 18d1f141..019cd052 100644
--- a/gpxe/src/include/gpxe/uuid.h
+++ b/gpxe/src/include/gpxe/uuid.h
@@ -6,6 +6,8 @@
* Universally unique IDs
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
/** A universally unique ID */
diff --git a/gpxe/src/include/gpxe/vsprintf.h b/gpxe/src/include/gpxe/vsprintf.h
index aa8f8a33..ee860a52 100644
--- a/gpxe/src/include/gpxe/vsprintf.h
+++ b/gpxe/src/include/gpxe/vsprintf.h
@@ -31,6 +31,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
diff --git a/gpxe/src/include/gpxe/wpa.h b/gpxe/src/include/gpxe/wpa.h
new file mode 100644
index 00000000..a7f19d71
--- /dev/null
+++ b/gpxe/src/include/gpxe/wpa.h
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2009 Joshua Oreman <oremanj@rwcr.net>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _GPXE_WPA_H
+#define _GPXE_WPA_H
+
+#include <gpxe/ieee80211.h>
+#include <gpxe/list.h>
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Common definitions for all types of WPA-protected networks.
+ */
+
+
+/** EAPOL-Key type field for modern 802.11i/RSN WPA packets */
+#define EAPOL_KEY_TYPE_RSN 2
+
+/** Old EAPOL-Key type field used by WPA1 hardware before 802.11i ratified */
+#define EAPOL_KEY_TYPE_WPA 254
+
+
+/**
+ * @defgroup eapol_key_info EAPOL-Key Info field bits
+ * @{
+ */
+
+/** Key descriptor version, indicating WPA or WPA2 */
+#define EAPOL_KEY_INFO_VERSION 0x0007
+
+/** Key type bit, indicating pairwise or group */
+#define EAPOL_KEY_INFO_TYPE 0x0008
+
+/** Key install bit; set on message 3 except when legacy hacks are used */
+#define EAPOL_KEY_INFO_INSTALL 0x0040
+
+/** Key ACK bit; set when a response is required, on all messages except #4 */
+#define EAPOL_KEY_INFO_KEY_ACK 0x0080
+
+/** Key MIC bit; set when the MIC field is valid, on messages 3 and 4 */
+#define EAPOL_KEY_INFO_KEY_MIC 0x0100
+
+/** Secure bit; set when both sides have both keys, on messages 3 and 4 */
+#define EAPOL_KEY_INFO_SECURE 0x0200
+
+/** Error bit; set on a MIC failure for TKIP */
+#define EAPOL_KEY_INFO_ERROR 0x0400
+
+/** Request bit; set when authentication is initiated by the Peer (unusual) */
+#define EAPOL_KEY_INFO_REQUEST 0x0800
+
+/** Key Encrypted bit; set when the Key Data field is encrypted */
+#define EAPOL_KEY_INFO_KEY_ENC 0x1000
+
+/** SMC Message bit; set when this frame is part of an IBSS SMK handshake */
+#define EAPOL_KEY_INFO_SMC_MESS 0x2000
+
+
+/** Key descriptor version field value for WPA (TKIP) */
+#define EAPOL_KEY_VERSION_WPA 1
+
+/** Key descriptor version field value for WPA2 (CCMP) */
+#define EAPOL_KEY_VERSION_WPA2 2
+
+/** Key type field value for a PTK (pairwise) key handshake */
+#define EAPOL_KEY_TYPE_PTK 0x0008
+
+/** Key type field value for a GTK (group) key handshake */
+#define EAPOL_KEY_TYPE_GTK 0x0000
+
+/** @} */
+
+
+
+/** An EAPOL-Key packet.
+ *
+ * These are used for the WPA 4-Way Handshake, whether or not prior
+ * authentication has been performed using EAP.
+ *
+ * On LANs, an eapol_key_pkt is always encapsulated in the data field
+ * of an eapol_frame, with the frame's type code set to EAPOL_TYPE_KEY.
+ *
+ * Unlike 802.11 frame headers, the fields in this structure are
+ * stored in big-endian!
+ */
+struct eapol_key_pkt
+{
+ /** One of the EAPOL_KEY_TYPE_* defines. */
+ u8 type;
+
+ /** Bitfield of key characteristics, network byte order */
+ u16 info;
+
+ /** Length of encryption key to be used, network byte order
+ *
+ * This is 16 for CCMP, 32 for TKIP, and 5 or 13 for WEP.
+ */
+ u16 keysize;
+
+ /** Monotonically increasing value for EAPOL-Key conversations
+ *
+ * In another classic demonstration of overengineering, this
+ * 8-byte value will rarely be anything above 1. It's stored
+ * in network byte order.
+ */
+ u64 replay;
+
+ /** Nonce value
+ *
+ * This is the authenticator's ANonce in frame 1, the peer's
+ * SNonce in frame 2, and 0 in frames 3 and 4.
+ */
+ u8 nonce[32];
+
+ /** Initialization vector
+ *
+ * This contains the IV used with the Key Encryption Key, or 0
+ * if the key is unencrypted or encrypted using an algorithm
+ * that does not require an IV.
+ */
+ u8 iv[16];
+
+ /** Receive sequence counter for GTK
+ *
+ * This is used to synchronize the client's replay counter for
+ * ordinary data packets. The first six bytes contain PN0
+ * through PN5 for CCMP mode, or TSC0 through TSC5 for TKIP
+ * mode. The last two bytes are zero.
+ */
+ u8 rsc[8];
+
+ /** Reserved bytes */
+ u8 _reserved[8];
+
+ /** Message integrity code over the entire EAPOL frame
+ *
+ * This is calculated using HMAC-MD5 when the key descriptor
+ * version field in @a info is 1, and HMAC-SHA1 ignoring the
+ * last 4 bytes of the hash when the version field in @a info
+ * is 2.
+ */
+ u8 mic[16];
+
+ /** Length of the @a data field in bytes, network byte order */
+ u16 datalen;
+
+ /** Key data
+ *
+ * This is formatted as a series of 802.11 information
+ * elements, with cryptographic data encapsulated using a
+ * "vendor-specific IE" code and an IEEE-specified OUI.
+ */
+ u8 data[0];
+} __attribute__ (( packed ));
+
+
+/** WPA handshaking state */
+enum wpa_state {
+ /** Waiting for PMK to be set */
+ WPA_WAITING = 0,
+
+ /** Ready for 4-Way Handshake */
+ WPA_READY,
+
+ /** Performing 4-Way Handshake */
+ WPA_WORKING,
+
+ /** 4-Way Handshake succeeded */
+ WPA_SUCCESS,
+
+ /** 4-Way Handshake failed */
+ WPA_FAILURE,
+};
+
+/** Bitfield indicating a selection of WPA transient keys */
+enum wpa_keymask {
+ /** Pairwise transient key */
+ WPA_PTK = 1,
+
+ /** Group transient key */
+ WPA_GTK = 2,
+};
+
+
+/** Length of a nonce */
+#define WPA_NONCE_LEN 32
+
+/** Length of a TKIP main key */
+#define WPA_TKIP_KEY_LEN 16
+
+/** Length of a TKIP MIC key */
+#define WPA_TKIP_MIC_KEY_LEN 8
+
+/** Length of a CCMP key */
+#define WPA_CCMP_KEY_LEN 16
+
+/** Length of an EAPOL Key Confirmation Key */
+#define WPA_KCK_LEN 16
+
+/** Length of an EAPOL Key Encryption Key */
+#define WPA_KEK_LEN 16
+
+/** Usual length of a Pairwise Master Key */
+#define WPA_PMK_LEN 32
+
+/** Length of a PMKID */
+#define WPA_PMKID_LEN 16
+
+
+/** Structure of the Temporal Key for TKIP encryption */
+struct tkip_tk
+{
+ /** Main key: input to TKIP Phase 1 and Phase 2 key mixing functions */
+ u8 key[WPA_TKIP_KEY_LEN];
+
+ /** Michael MIC keys */
+ struct {
+ /** MIC key for packets from the AP */
+ u8 rx[WPA_TKIP_MIC_KEY_LEN];
+
+ /** MIC key for packets to the AP */
+ u8 tx[WPA_TKIP_MIC_KEY_LEN];
+ } __attribute__ (( packed )) mic;
+} __attribute__ (( packed ));
+
+/** Structure of a generic Temporal Key */
+union wpa_tk
+{
+ /** CCMP key */
+ u8 ccmp[WPA_CCMP_KEY_LEN];
+
+ /** TKIP keys */
+ struct tkip_tk tkip;
+};
+
+/** Structure of the Pairwise Transient Key */
+struct wpa_ptk
+{
+ /** EAPOL-Key Key Confirmation Key (KCK) */
+ u8 kck[WPA_KCK_LEN];
+
+ /** EAPOL-Key Key Encryption Key (KEK) */
+ u8 kek[WPA_KEK_LEN];
+
+ /** Temporal key */
+ union wpa_tk tk;
+} __attribute__ (( packed ));
+
+/** Structure of the Group Transient Key */
+struct wpa_gtk
+{
+ /** Temporal key */
+ union wpa_tk tk;
+} __attribute__ (( packed ));
+
+
+/** Common context for WPA security handshaking
+ *
+ * Any implementor of a particular handshaking type (e.g. PSK or EAP)
+ * must include this structure at the very beginning of their private
+ * data context structure, to allow the EAPOL-Key handling code to
+ * work. When the preliminary authentication is done, it is necessary
+ * to call wpa_start(), passing the PMK (derived from PSK or EAP MSK)
+ * as an argument. The handshaker can use its @a step function to
+ * monitor @a state in this wpa_ctx structure for success or
+ * failure. On success, the keys will be available in @a ptk and @a
+ * gtk according to the state of the @a valid bitmask.
+ *
+ * After an initial success, the parent handshaker does not need to
+ * concern itself with rekeying; the WPA common code takes care of
+ * that.
+ */
+struct wpa_common_ctx
+{
+ /** 802.11 device we are authenticating for */
+ struct net80211_device *dev;
+
+ /** The Pairwise Master Key to use in handshaking
+ *
+ * This is set either by running the PBKDF2 algorithm on a
+ * passphrase with the SSID as salt to generate a pre-shared
+ * key, or by copying the first 32 bytes of the EAP Master
+ * Session Key in 802.1X-served authentication.
+ */
+ u8 pmk[WPA_PMK_LEN];
+
+ /** Length of the Pairwise Master Key
+ *
+ * This is always 32 except with one EAP method which only
+ * gives 16 bytes.
+ */
+ int pmk_len;
+
+ /** State of EAPOL-Key handshaking */
+ enum wpa_state state;
+
+ /** Replay counter for this association
+ *
+ * This stores the replay counter value for the most recent
+ * packet we've accepted. It is initially initialised to ~0 to
+ * show we'll accept anything.
+ */
+ u64 replay;
+
+ /** Mask of valid keys after authentication success
+ *
+ * If the PTK is not valid, the GTK should be used for both
+ * unicast and multicast decryption; if the GTK is not valid,
+ * multicast packets cannot be decrypted.
+ */
+ enum wpa_keymask valid;
+
+ /** The cipher to use for unicast RX and all TX */
+ enum net80211_crypto_alg crypt;
+
+ /** The cipher to use for broadcast and multicast RX */
+ enum net80211_crypto_alg gcrypt;
+
+ /** The Pairwise Transient Key derived from the handshake */
+ struct wpa_ptk ptk;
+
+ /** The Group Transient Key derived from the handshake */
+ struct wpa_gtk gtk;
+
+ /** Authenticator-provided nonce */
+ u8 Anonce[WPA_NONCE_LEN];
+
+ /** Supplicant-generated nonce (that's us) */
+ u8 Snonce[WPA_NONCE_LEN];
+
+ /** Whether we should refrain from generating another SNonce */
+ int have_Snonce;
+
+ /** Data in WPA or RSN IE from AP's beacon frame */
+ void *ap_rsn_ie;
+
+ /** Length of @a ap_rsn_ie */
+ int ap_rsn_ie_len;
+
+ /** Whether @a ap_rsn_ie is an RSN IE (as opposed to old WPA) */
+ int ap_rsn_is_rsn;
+
+ /** List entry */
+ struct list_head list;
+};
+
+
+/** WPA handshake key integrity and encryption handler
+ *
+ * Note that due to the structure of the 4-Way Handshake we never
+ * actually need to encrypt key data, only decrypt it.
+ */
+struct wpa_kie {
+ /** Value of version bits in EAPOL-Key info field for which to use
+ *
+ * This should be one of the @c EAPOL_KEY_VERSION_* constants.
+ */
+ int version;
+
+ /** Calculate MIC over message
+ *
+ * @v kck Key Confirmation Key, 16 bytes
+ * @v msg Message to calculate MIC over
+ * @v len Number of bytes to calculate MIC over
+ * @ret mic Calculated MIC, 16 bytes long
+ *
+ * The @a mic return may point within @a msg, so it must not
+ * be filled until the calculation has been performed.
+ */
+ void ( * mic ) ( const void *kck, const void *msg, size_t len,
+ void *mic );
+
+ /** Decrypt key data
+ *
+ * @v kek Key Encryption Key, 16 bytes
+ * @v iv Initialisation vector for encryption, 16 bytes
+ * @v msg Message to decrypt (Key Data field)
+ * @v len Length of message
+ * @ret msg Decrypted message in place of original
+ * @ret len Updated to reflect encrypted length
+ * @ret rc Return status code
+ *
+ * The decrypted message is written over the encrypted one.
+ */
+ int ( * decrypt ) ( const void *kek, const void *iv, void *msg,
+ u16 *len );
+};
+
+#define WPA_KIES __table ( struct wpa_kie, "wpa_kies" )
+#define __wpa_kie __table_entry ( WPA_KIES, 01 )
+
+
+
+/**
+ * @defgroup wpa_kde Key descriptor element types
+ * @{
+ */
+
+/** Payload structure of the GTK-encapsulating KDE
+ *
+ * This does not include the IE type, length, or OUI bytes, which are
+ * generic to all KDEs.
+ */
+struct wpa_kde_gtk_encap
+{
+ /** Key ID and TX bit */
+ u8 id;
+
+ /** Reserved byte */
+ u8 _rsvd;
+
+ /** Encapsulated group transient key */
+ struct wpa_gtk gtk;
+} __attribute__ (( packed ));
+
+/** Mask for Key ID in wpa_kde_gtk::id field */
+#define WPA_GTK_KID 0x03
+
+/** Mask for Tx bit in wpa_kde_gtk::id field */
+#define WPA_GTK_TXBIT 0x04
+
+
+/** KDE type for an encapsulated Group Transient Key (requires encryption) */
+#define WPA_KDE_GTK _MKOUI ( 0x00, 0x0F, 0xAC, 0x01 )
+
+/** KDE type for a MAC address */
+#define WPA_KDE_MAC _MKOUI ( 0x00, 0x0F, 0xAC, 0x03 )
+
+/** KDE type for a PMKID */
+#define WPA_KDE_PMKID _MKOUI ( 0x00, 0x0F, 0xAC, 0x04 )
+
+/** KDE type for a nonce */
+#define WPA_KDE_NONCE _MKOUI ( 0x00, 0x0F, 0xAC, 0x06 )
+
+/** KDE type for a lifetime value */
+#define WPA_KDE_LIFETIME _MKOUI ( 0x00, 0x0F, 0xAC, 0x07 )
+
+
+/** Any key descriptor element type
+ *
+ * KDEs follow the 802.11 information element format of a type byte
+ * (in this case "vendor-specific", with the requisite OUI+subtype
+ * after length) and a length byte whose value does not include the
+ * length of the type and length bytes.
+ */
+struct wpa_kde
+{
+ /** Information element type: always 0xDD (IEEE80211_IE_VENDOR) */
+ u8 ie_type;
+
+ /** Length, not including ie_type and length fields */
+ u8 len;
+
+ /** OUI + type byte */
+ u32 oui_type;
+
+ /** Payload data */
+ union {
+ /** For GTK-type KDEs, encapsulated GTK */
+ struct wpa_kde_gtk_encap gtk_encap;
+
+ /** For MAC-type KDEs, the MAC address */
+ u8 mac[ETH_ALEN];
+
+ /** For PMKID-type KDEs, the PMKID */
+ u8 pmkid[WPA_PMKID_LEN];
+
+ /** For Nonce-type KDEs, the nonce */
+ u8 nonce[WPA_NONCE_LEN];
+
+ /** For Lifetime-type KDEs, the lifetime in seconds
+ *
+ * This is in network byte order!
+ */
+ u32 lifetime;
+ };
+} __attribute__ (( packed ));
+
+/** @} */
+
+int wpa_make_rsn_ie ( struct net80211_device *dev, union ieee80211_ie **ie );
+int wpa_start ( struct net80211_device *dev, struct wpa_common_ctx *ctx,
+ const void *pmk, size_t pmk_len );
+void wpa_stop ( struct net80211_device *dev );
+
+#endif /* _GPXE_WPA_H */
diff --git a/gpxe/src/include/gpxe/x509.h b/gpxe/src/include/gpxe/x509.h
index 071e1de5..1b9d9aab 100644
--- a/gpxe/src/include/gpxe/x509.h
+++ b/gpxe/src/include/gpxe/x509.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
struct asn1_cursor;
diff --git a/gpxe/src/include/gpxe/xfer.h b/gpxe/src/include/gpxe/xfer.h
index e592fa38..edd37034 100644
--- a/gpxe/src/include/gpxe/xfer.h
+++ b/gpxe/src/include/gpxe/xfer.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stddef.h>
#include <stdarg.h>
#include <gpxe/interface.h>
diff --git a/gpxe/src/include/hci/ifmgmt_cmd.h b/gpxe/src/include/hci/ifmgmt_cmd.h
new file mode 100644
index 00000000..e9c810ab
--- /dev/null
+++ b/gpxe/src/include/hci/ifmgmt_cmd.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _IFMGMT_CMD_H
+#define _IFMGMT_CMD_H
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+struct net_device;
+
+extern int ifcommon_exec ( int argc, char **argv,
+ int ( * payload ) ( struct net_device * ),
+ const char *verb );
+
+#endif /* _IFMGMT_CMD_H */
diff --git a/gpxe/src/include/igmp.h b/gpxe/src/include/igmp.h
deleted file mode 100644
index 8b3292f2..00000000
--- a/gpxe/src/include/igmp.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef IGMP_H
-#define IGMP_H
-
-#include "stdint.h"
-#include <gpxe/in.h>
-
-#define IGMP_QUERY 0x11
-#define IGMPv1_REPORT 0x12
-#define IGMPv2_REPORT 0x16
-#define IGMP_LEAVE 0x17
-#define GROUP_ALL_HOSTS 0xe0000001 /* 224.0.0.1 Host byte order */
-
-#define MULTICAST_MASK 0xf0000000
-#define MULTICAST_NETWORK 0xe0000000
-
-enum {
- IGMP_SERVER,
- MAX_IGMP
-};
-
-struct igmp {
- uint8_t type;
- uint8_t response_time;
- uint16_t chksum;
- struct in_addr group;
-} PACKED;
-
-struct igmp_ip_t { /* Format of an igmp ip packet */
- struct iphdr ip;
- uint8_t router_alert[4]; /* Router alert option */
- struct igmp igmp;
-} PACKED;
-
-struct igmptable_t {
- struct in_addr group;
- unsigned long time;
-} PACKED;
-
-extern void join_group ( int slot, unsigned long group );
-extern void leave_group ( int slot );
-
-#endif /* IGMP_H */
diff --git a/gpxe/src/include/lib.h b/gpxe/src/include/lib.h
deleted file mode 100644
index 400ea468..00000000
--- a/gpxe/src/include/lib.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef LIB_H
-#define LIB_H
-
-#include <stdint.h>
-
-int getline(char *buf, int max);
-
-extern struct pci_device *dev_list;
-extern int n_devs;
-
-extern void pci_init(void);
-extern struct pci_device *pci_find_device(int vendor, int device, int devclass,
-int prog_if, int index);
-
-void *calloc(size_t nmemb, size_t size);
-void *realloc(void *ptr, size_t size);
-
-char *strdup(const char *s);
-
-int isspace(int c);
-
-unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base);
-unsigned long long strtoull_with_suffix(const char *cp,char **endp,unsigned int base);
-
-unsigned int get_le32(const unsigned char *);
-unsigned int get_le16(const unsigned char *);
-void hexdump(const void *p, unsigned int len);
-
-long long simple_strtoll(const char *cp,char **endp,unsigned int base);
-
-#define LOADER_NOT_SUPPORT 0xbadf11e
-
-struct sys_info;
-int elf_load(struct sys_info *, const char *filename, const char *cmdline);
-
-#if LINUX_LOADER
-int linux_load(struct sys_info *, const char *filename, const char *cmdline);
-#else
-#define linux_load(x,y,z) LOADER_NOT_SUPPORT /* nop */
-#endif
-
-#endif /* LIB_H */
diff --git a/gpxe/src/include/libgen.h b/gpxe/src/include/libgen.h
index 56a2f760..7e94881a 100644
--- a/gpxe/src/include/libgen.h
+++ b/gpxe/src/include/libgen.h
@@ -1,6 +1,8 @@
#ifndef _LIBGEN_H
#define _LIBGEN_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
extern char * basename ( char *path );
extern char * dirname ( char *path );
diff --git a/gpxe/src/include/little_bswap.h b/gpxe/src/include/little_bswap.h
index e4f83753..a5dc9c87 100644
--- a/gpxe/src/include/little_bswap.h
+++ b/gpxe/src/include/little_bswap.h
@@ -1,6 +1,8 @@
#ifndef ETHERBOOT_LITTLE_BSWAP_H
#define ETHERBOOT_LITTLE_BSWAP_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#define ntohl(x) __bswap_32(x)
#define htonl(x) __bswap_32(x)
#define ntohs(x) __bswap_16(x)
diff --git a/gpxe/src/include/mii.h b/gpxe/src/include/mii.h
index 34c1ca9b..3b735d99 100644
--- a/gpxe/src/include/mii.h
+++ b/gpxe/src/include/mii.h
@@ -10,6 +10,11 @@
* 03/26/2004
*/
+FILE_LICENCE ( GPL2_ONLY );
+
+#ifndef _MII_H_
+#define _MII_H_
+
/* Generic MII registers. */
#define MII_BMCR 0x00 /* Basic mode control register */
@@ -19,6 +24,9 @@
#define MII_ADVERTISE 0x04 /* Advertisement control reg */
#define MII_LPA 0x05 /* Link partner ability reg */
#define MII_EXPANSION 0x06 /* Expansion register */
+#define MII_CTRL1000 0x09 /* 1000BASE-T control */
+#define MII_STAT1000 0x0a /* 1000BASE-T status */
+#define MII_ESTATUS 0x0f /* Extended Status */
#define MII_DCOUNTER 0x12 /* Disconnect counter */
#define MII_FCSCOUNTER 0x13 /* False carrier counter */
#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
@@ -32,7 +40,8 @@
#define MII_NCONFIG 0x1c /* Network interface config */
/* Basic mode control register. */
-#define BMCR_RESV 0x007f /* Unused... */
+#define BMCR_RESV 0x003f /* Unused... */
+#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
#define BMCR_CTST 0x0080 /* Collision test */
#define BMCR_FULLDPLX 0x0100 /* Full duplex */
#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
@@ -50,7 +59,10 @@
#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
#define BMSR_RFAULT 0x0010 /* Remote fault detected */
#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
-#define BMSR_RESV 0x07c0 /* Unused... */
+#define BMSR_RESV 0x00c0 /* Unused... */
+#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
+#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */
+#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */
#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
@@ -61,11 +73,17 @@
#define ADVERTISE_SLCT 0x001f /* Selector bits */
#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
+#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
+#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
+#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
+#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
-#define ADVERTISE_RESV 0x1c00 /* Unused... */
+#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
+#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */
+#define ADVERTISE_RESV 0x1000 /* Unused... */
#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
@@ -78,11 +96,17 @@
/* Link partner ability register. */
#define LPA_SLCT 0x001f /* Same as advertise selector */
#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
+#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */
#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
+#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */
#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
+#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */
#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
+#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/
#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
-#define LPA_RESV 0x1c00 /* Unused... */
+#define LPA_PAUSE_CAP 0x0400 /* Can pause */
+#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */
+#define LPA_RESV 0x1000 /* Unused... */
#define LPA_RFAULT 0x2000 /* Link partner faulted */
#define LPA_LPACK 0x4000 /* Link partner acked us */
#define LPA_NPAGE 0x8000 /* Next page bit */
@@ -98,8 +122,98 @@
#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */
#define EXPANSION_RESV 0xffe0 /* Unused... */
+#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */
+#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */
+
/* N-way test register. */
#define NWAYTEST_RESV1 0x00ff /* Unused... */
#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
#define NWAYTEST_RESV2 0xfe00 /* Unused... */
+/* 1000BASE-T Control register */
+#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
+#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */
+
+/* 1000BASE-T Status register */
+#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */
+#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */
+#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */
+#define LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */
+
+#include <gpxe/netdevice.h>
+
+struct mii_if_info {
+ int phy_id;
+ int advertising;
+ int phy_id_mask;
+ int reg_num_mask;
+
+ unsigned int full_duplex : 1; /* is full duplex? */
+ unsigned int force_media : 1; /* is autoneg. disabled? */
+ unsigned int supports_gmii : 1; /* are GMII registers supported? */
+
+ struct net_device *dev;
+ int (*mdio_read) (struct net_device *dev, int phy_id, int location);
+ void (*mdio_write) (struct net_device *dev, int phy_id, int location, int val);
+};
+
+
+extern int mii_link_ok (struct mii_if_info *mii);
+extern void mii_check_link (struct mii_if_info *mii);
+extern unsigned int mii_check_media (struct mii_if_info *mii,
+ unsigned int ok_to_print,
+ unsigned int init_media);
+
+
+/**
+ * mii_nway_result
+ * @negotiated: value of MII ANAR and'd with ANLPAR
+ *
+ * Given a set of MII abilities, check each bit and returns the
+ * currently supported media, in the priority order defined by
+ * IEEE 802.3u. We use LPA_xxx constants but note this is not the
+ * value of LPA solely, as described above.
+ *
+ * The one exception to IEEE 802.3u is that 100baseT4 is placed
+ * between 100T-full and 100T-half. If your phy does not support
+ * 100T4 this is fine. If your phy places 100T4 elsewhere in the
+ * priority order, you will need to roll your own function.
+ */
+static inline unsigned int mii_nway_result (unsigned int negotiated)
+{
+ unsigned int ret;
+
+ if (negotiated & LPA_100FULL)
+ ret = LPA_100FULL;
+ else if (negotiated & LPA_100BASE4)
+ ret = LPA_100BASE4;
+ else if (negotiated & LPA_100HALF)
+ ret = LPA_100HALF;
+ else if (negotiated & LPA_10FULL)
+ ret = LPA_10FULL;
+ else
+ ret = LPA_10HALF;
+
+ return ret;
+}
+
+/**
+ * mii_duplex
+ * @duplex_lock: Non-zero if duplex is locked at full
+ * @negotiated: value of MII ANAR and'd with ANLPAR
+ *
+ * A small helper function for a common case. Returns one
+ * if the media is operating or locked at full duplex, and
+ * returns zero otherwise.
+ */
+static inline unsigned int mii_duplex (unsigned int duplex_lock,
+ unsigned int negotiated)
+{
+ if (duplex_lock)
+ return 1;
+ if (mii_nway_result(negotiated) & LPA_DUPLEX)
+ return 1;
+ return 0;
+}
+
+#endif
diff --git a/gpxe/src/include/nfs.h b/gpxe/src/include/nfs.h
deleted file mode 100644
index 0877bb66..00000000
--- a/gpxe/src/include/nfs.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef _NFS_H
-#define _NFS_H
-
-#define SUNRPC_PORT 111
-
-#define PROG_PORTMAP 100000
-#define PROG_NFS 100003
-#define PROG_MOUNT 100005
-
-#define MSG_CALL 0
-#define MSG_REPLY 1
-
-#define PORTMAP_GETPORT 3
-
-#define MOUNT_ADDENTRY 1
-#define MOUNT_UMOUNTALL 4
-
-#define NFS_LOOKUP 4
-#define NFS_READLINK 5
-#define NFS_READ 6
-
-#define NFS_FHSIZE 32
-
-#define NFSERR_PERM 1
-#define NFSERR_NOENT 2
-#define NFSERR_ACCES 13
-#define NFSERR_ISDIR 21
-#define NFSERR_INVAL 22
-
-/* Block size used for NFS read accesses. A RPC reply packet (including all
- * headers) must fit within a single Ethernet frame to avoid fragmentation.
- * Chosen to be a power of two, as most NFS servers are optimized for this. */
-#define NFS_READ_SIZE 1024
-
-#define NFS_MAXLINKDEPTH 16
-
-struct rpc_t {
- struct iphdr ip;
- struct udphdr udp;
- union {
- uint8_t data[300]; /* longest RPC call must fit!!!! */
- struct {
- uint32_t id;
- uint32_t type;
- uint32_t rpcvers;
- uint32_t prog;
- uint32_t vers;
- uint32_t proc;
- uint32_t data[1];
- } call;
- struct {
- uint32_t id;
- uint32_t type;
- uint32_t rstatus;
- uint32_t verifier;
- uint32_t v2;
- uint32_t astatus;
- uint32_t data[1];
- } reply;
- } u;
-} PACKED;
-
-#endif /* _NFS_H */
diff --git a/gpxe/src/include/nic.h b/gpxe/src/include/nic.h
index 186b2ea4..c808972a 100644
--- a/gpxe/src/include/nic.h
+++ b/gpxe/src/include/nic.h
@@ -5,6 +5,8 @@
* your option) any later version.
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#ifndef NIC_H
#define NIC_H
@@ -18,7 +20,6 @@
#include <gpxe/eisa.h>
#include <gpxe/mca.h>
#include <gpxe/io.h>
-#include "dhcp.h"
typedef enum {
DISABLE = 0,
@@ -45,7 +46,6 @@ struct nic {
unsigned char irqno;
unsigned int mbps;
duplex_t duplex;
- struct dhcp_dev_id dhcp_dev_id;
void *priv_data; /* driver private data */
};
diff --git a/gpxe/src/include/nmb.h b/gpxe/src/include/nmb.h
deleted file mode 100644
index 3e551ffd..00000000
--- a/gpxe/src/include/nmb.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef NMB_H
-#define NMB_H
-
-#include <gpxe/dns.h>
-
-/*
- * NetBIOS name query packets are basically the same as DNS packets,
- * though the resource record format is different.
- *
- */
-
-#define DNS_TYPE_NB 0x20
-#define DNS_FLAG_BROADCAST ( 0x01 << 4 )
-#define NBNS_UDP_PORT 137
-
-struct dns_rr_info_nb {
- struct dns_rr_info info;
- uint16_t nb_flags;
- struct in_addr nb_address;
-} __attribute__ (( packed ));
-
-#endif /* NMB_H */
diff --git a/gpxe/src/include/readline/readline.h b/gpxe/src/include/readline/readline.h
index 1a03b483..700b7aa2 100644
--- a/gpxe/src/include/readline/readline.h
+++ b/gpxe/src/include/readline/readline.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
extern char * __malloc readline ( const char *prompt );
#endif /* _READLINE_H */
diff --git a/gpxe/src/include/stdarg.h b/gpxe/src/include/stdarg.h
index a4eb711d..78b261ae 100644
--- a/gpxe/src/include/stdarg.h
+++ b/gpxe/src/include/stdarg.h
@@ -1,6 +1,8 @@
#ifndef _STDARG_H
#define _STDARG_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
typedef __builtin_va_list va_list;
#define va_start( ap, last ) __builtin_va_start ( ap, last )
#define va_arg( ap, type ) __builtin_va_arg ( ap, type )
diff --git a/gpxe/src/include/stddef.h b/gpxe/src/include/stddef.h
index 11ea9345..2a02a898 100644
--- a/gpxe/src/include/stddef.h
+++ b/gpxe/src/include/stddef.h
@@ -1,6 +1,8 @@
#ifndef STDDEF_H
#define STDDEF_H
+FILE_LICENCE ( GPL2_ONLY );
+
/* for size_t */
#include <stdint.h>
diff --git a/gpxe/src/include/stdint.h b/gpxe/src/include/stdint.h
index 4b0e44f2..8cc9b84a 100644
--- a/gpxe/src/include/stdint.h
+++ b/gpxe/src/include/stdint.h
@@ -1,6 +1,18 @@
#ifndef _STDINT_H
#define _STDINT_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/*
+ * This is a standard predefined macro on all gcc's I've seen. It's
+ * important that we define size_t in the same way as the compiler,
+ * because that's what it's expecting when it checks %zd/%zx printf
+ * format specifiers.
+ */
+#ifndef __SIZE_TYPE__
+#define __SIZE_TYPE__ unsigned long /* safe choice on most systems */
+#endif
+
#include <bits/stdint.h>
typedef int8_t s8;
diff --git a/gpxe/src/include/stdio.h b/gpxe/src/include/stdio.h
index 82077e20..84181f0a 100644
--- a/gpxe/src/include/stdio.h
+++ b/gpxe/src/include/stdio.h
@@ -1,6 +1,8 @@
#ifndef _STDIO_H
#define _STDIO_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <stdarg.h>
diff --git a/gpxe/src/include/stdlib.h b/gpxe/src/include/stdlib.h
index 838a22ac..254e39b3 100644
--- a/gpxe/src/include/stdlib.h
+++ b/gpxe/src/include/stdlib.h
@@ -1,6 +1,8 @@
#ifndef STDLIB_H
#define STDLIB_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stdint.h>
#include <assert.h>
diff --git a/gpxe/src/include/string.h b/gpxe/src/include/string.h
index a2894a3a..2fd6acf1 100644
--- a/gpxe/src/include/string.h
+++ b/gpxe/src/include/string.h
@@ -11,6 +11,8 @@
* published by the Free Software Foundation.
*/
+FILE_LICENCE ( GPL2_ONLY );
+
#ifndef ETHERBOOT_STRING_H
#define ETHERBOOT_STRING_H
diff --git a/gpxe/src/include/strings.h b/gpxe/src/include/strings.h
index 968a7c11..c7063d68 100644
--- a/gpxe/src/include/strings.h
+++ b/gpxe/src/include/strings.h
@@ -1,6 +1,8 @@
#ifndef _STRINGS_H
#define _STRINGS_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <limits.h>
#include <string.h>
diff --git a/gpxe/src/include/unistd.h b/gpxe/src/include/unistd.h
index dc1f67f6..ef946947 100644
--- a/gpxe/src/include/unistd.h
+++ b/gpxe/src/include/unistd.h
@@ -1,6 +1,8 @@
#ifndef _UNISTD_H
#define _UNISTD_H
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <stddef.h>
#include <stdarg.h>
diff --git a/gpxe/src/include/usr/autoboot.h b/gpxe/src/include/usr/autoboot.h
index 1e9647c3..a9180202 100644
--- a/gpxe/src/include/usr/autoboot.h
+++ b/gpxe/src/include/usr/autoboot.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
#include <gpxe/in.h>
struct net_device;
@@ -16,6 +18,8 @@ extern void autoboot ( void );
extern int boot_next_server_and_filename ( struct in_addr next_server,
const char *filename );
extern int boot_root_path ( const char *root_path );
-extern int pxe_menu_boot ( struct net_device *netdev );
+
+extern int pxe_menu_boot ( struct net_device *netdev )
+ __attribute__ (( weak ));
#endif /* _USR_AUTOBOOT_H */
diff --git a/gpxe/src/include/usr/dhcpmgmt.h b/gpxe/src/include/usr/dhcpmgmt.h
index 0f275600..2394dac4 100644
--- a/gpxe/src/include/usr/dhcpmgmt.h
+++ b/gpxe/src/include/usr/dhcpmgmt.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
struct net_device;
extern int dhcp ( struct net_device *netdev );
diff --git a/gpxe/src/include/usr/ifmgmt.h b/gpxe/src/include/usr/ifmgmt.h
index 7b49d349..f762c7ba 100644
--- a/gpxe/src/include/usr/ifmgmt.h
+++ b/gpxe/src/include/usr/ifmgmt.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
struct net_device;
extern int ifopen ( struct net_device *netdev );
diff --git a/gpxe/src/include/usr/imgmgmt.h b/gpxe/src/include/usr/imgmgmt.h
index 438af003..0c8c8cf7 100644
--- a/gpxe/src/include/usr/imgmgmt.h
+++ b/gpxe/src/include/usr/imgmgmt.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
struct image;
extern int imgfetch ( struct image *image, const char *uri_string,
diff --git a/gpxe/src/include/usr/iwmgmt.h b/gpxe/src/include/usr/iwmgmt.h
new file mode 100644
index 00000000..c1bdc37a
--- /dev/null
+++ b/gpxe/src/include/usr/iwmgmt.h
@@ -0,0 +1,17 @@
+#ifndef _USR_IWMGMT_H
+#define _USR_IWMGMT_H
+
+/** @file
+ *
+ * Wireless network interface management
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+struct net80211_device;
+
+extern void iwstat ( struct net80211_device *dev );
+extern int iwlist ( struct net80211_device *dev );
+
+#endif /* _USR_IWMGMT_H */
diff --git a/gpxe/src/include/usr/route.h b/gpxe/src/include/usr/route.h
index fc855892..855fa7ba 100644
--- a/gpxe/src/include/usr/route.h
+++ b/gpxe/src/include/usr/route.h
@@ -7,6 +7,8 @@
*
*/
+FILE_LICENCE ( GPL2_OR_LATER );
+
extern void route ( void );
#endif /* _USR_ROUTE_H */