aboutsummaryrefslogtreecommitdiffstats
path: root/gpxe/src/include/gpxe
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-03 16:06:41 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-02-03 16:06:41 -0800
commitaddaeaeb3949d576c4e0eb5cfc133b7c3bcfa8fa (patch)
tree2ffea726dc494e87ecc9f506bc6a2bc9242730e3 /gpxe/src/include/gpxe
parent5c0f48e49f8d7d084810ecf0b98a76aaebb44835 (diff)
parente7a5f95432132c8fc8f8ede39fda1d368002ddd8 (diff)
downloadsyslinux.git-addaeaeb3949d576c4e0eb5cfc133b7c3bcfa8fa.tar.gz
syslinux.git-addaeaeb3949d576c4e0eb5cfc133b7c3bcfa8fa.tar.xz
syslinux.git-addaeaeb3949d576c4e0eb5cfc133b7c3bcfa8fa.zip
Merge branch 'master' into i915res
Diffstat (limited to 'gpxe/src/include/gpxe')
-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
145 files changed, 5781 insertions, 319 deletions
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>