aboutsummaryrefslogtreecommitdiffstats
path: root/gpxe/src/include/gpxe/aoe.h
blob: 6b42fd5b4c09499e831f68c94f9d3cf0db4a2934 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#ifndef _GPXE_AOE_H
#define _GPXE_AOE_H

/** @file
 *
 * AoE protocol
 *
 */

FILE_LICENCE ( GPL2_OR_LATER );

#include <stdint.h>
#include <gpxe/list.h>
#include <gpxe/if_ether.h>
#include <gpxe/retry.h>
#include <gpxe/ata.h>

/** An AoE config command */
struct aoecfg {
	/** AoE Queue depth */
	uint16_t bufcnt;
	/** ATA target firmware version */
	uint16_t fwver;
	/** ATA target sector count */
	uint8_t scnt;
	/** AoE config string subcommand */
	uint8_t aoeccmd;
	/** AoE config string length */
	uint16_t cfglen;
	/** AoE config string */
	uint8_t data[0];
} __attribute__ (( packed ));

/** An AoE ATA command */
struct aoeata {
	/** AoE command flags */
	uint8_t aflags;
	/** ATA error/feature register */
	uint8_t err_feat;
	/** ATA sector count register */
	uint8_t count;
	/** ATA command/status register */
	uint8_t cmd_stat;
	/** Logical block address, in little-endian order */
	union {
		uint64_t u64;
		uint8_t bytes[6];
	} lba;
	/** Data payload */
	uint8_t data[0];
} __attribute__ (( packed ));

#define AOE_FL_EXTENDED	0x40	/**< LBA48 extended addressing */
#define AOE_FL_DEV_HEAD	0x10	/**< Device/head flag */
#define AOE_FL_ASYNC	0x02	/**< Asynchronous write */
#define AOE_FL_WRITE	0x01	/**< Write command */

/** An AoE command */
union aoecmd {
	/** Config command */
	struct aoecfg cfg;
	/** ATA command */
	struct aoeata ata;
};

/** An AoE header */
struct aoehdr {
	/** Protocol version number and flags */
	uint8_t ver_flags;
	/** Error code */
	uint8_t error;
	/** Major device number, in network byte order */
	uint16_t major;
	/** Minor device number */
	uint8_t minor;
	/** Command number */
	uint8_t command;
	/** Tag, in network byte order */
	uint32_t tag;
	/** Payload */
	union aoecmd cmd[0];
} __attribute__ (( packed ));

#define AOE_VERSION	0x10	/**< Version 1 */
#define AOE_VERSION_MASK 0xf0	/**< Version part of ver_flags field */

#define AOE_FL_RESPONSE	0x08	/**< Message is a response */
#define AOE_FL_ERROR	0x04	/**< Command generated an error */

#define AOE_MAJOR_BROADCAST 0xffff
#define AOE_MINOR_BROADCAST 0xff

#define AOE_CMD_ATA	0x00	/**< Issue ATA command */
#define AOE_CMD_CONFIG	0x01	/**< Query Config Information */

#define AOE_TAG_MAGIC	0xebeb0000

#define AOE_ERR_BAD_COMMAND	1 /**< Unrecognised command code */
#define AOE_ERR_BAD_PARAMETER	2 /**< Bad argument parameter */
#define AOE_ERR_UNAVAILABLE	3 /**< Device unavailable */
#define AOE_ERR_CONFIG_EXISTS	4 /**< Config string present */
#define AOE_ERR_BAD_VERSION	5 /**< Unsupported version */

/** An AoE session */
struct aoe_session {
	/** Reference counter */
	struct refcnt refcnt;

	/** List of all AoE sessions */
	struct list_head list;

	/** Network device */
	struct net_device *netdev;

	/** Major number */
	uint16_t major;
	/** Minor number */
	uint8_t minor;
	/** Target MAC address */
	uint8_t target[ETH_ALEN];

	/** Tag for current AoE command */
	uint32_t tag;

	/** Current AOE command */
	uint8_t aoe_cmd_type;
	/** Current ATA command */
	struct ata_command *command;
	/** Overall status of current ATA command */
	unsigned int status;
	/** Byte offset within command's data buffer */
	unsigned int command_offset;
	/** Return status code for command */
	int rc;

	/** Retransmission timer */
	struct retry_timer timer;
};

#define AOE_STATUS_ERR_MASK	0x0f /**< Error portion of status code */ 
#define AOE_STATUS_PENDING	0x80 /**< Command pending */

/** Maximum number of sectors per packet */
#define AOE_MAX_COUNT 2

extern void aoe_detach ( struct ata_device *ata );
extern int aoe_attach ( struct ata_device *ata, struct net_device *netdev,
			const char *root_path );

#endif /* _GPXE_AOE_H */