blob: 18c535dc1faa5fbae8767ecf9fa4bda9a31853cb [file] [log] [blame]
William A. Kennington III7d6fa422021-02-08 17:04:02 -08001#ifndef PLATFORMS_NEMORA_PORTABLE_NCSI_H_
2#define PLATFORMS_NEMORA_PORTABLE_NCSI_H_
3
4/*
5 * Module for interacting with NC-SI capable network cards.
6 *
7 * DMTF v1.0.0 NC-SI specification:
8 * http://www.dmtf.org/sites/default/files/standards/documents/DSP0222_1.0.0.pdf
9 */
10
11#include <stdbool.h>
12#include <stdint.h>
13
14#include "platforms/nemora/portable/net_types.h"
15
16#ifdef __cplusplus
17extern "C" {
18#endif
19
20#ifndef __packed
21#define __packed __attribute__((packed))
22#endif
23
24// Define states for our NC-SI connection to the NIC.
25// There is no mapping to the NC-SI specification for these states, but they
26// reflect the outcome of NC-SI commands used in our configuration state
27// machine.
28//
29// 'DOWN' - while in this state, periodically restart the configuration state
30// machine until it succeeds.
31// 'LOOPBACK' - the response to the first NC-SI command of the configuration
32// state machine was identical to the command: from this we infer we are in
33// loopback. While in this state, periodically restart the configuration state
34// machine.
35// 'UP' - all commands were responded successfully, but need DHCP configuration
36// to go to the next state. While in this state, the connection is tested
37// periodically for failures, which can bring back to 'DOWN'.
38// 'UP_AND_CONFIGURED' - NC-SI OEM commands for L3/L4 configuration (which
39// depend on DHCP configuration) were responded successfully. While in this
40// state, the connection and configuration are tested periodically for
41// failures, which can bring back to 'DOWN'.
42// 'DISABLED' - reset default state. As soon as network is enabled (which
43// noticeably means that ProdID must be disabled), the state goes to DOWN.
44// TODO: connection state has nothing to do with ncsi protocol and needs
45// to be moved to ncsi_fsm.h. The main problem with the move is that
46// ncsi_client.h defines an extern function with this return type, that is used
47// in a lot of places that have no business including ncsi_fsm.h
48typedef enum {
49 NCSI_CONNECTION_DOWN,
50 NCSI_CONNECTION_LOOPBACK,
51 NCSI_CONNECTION_UP,
52 NCSI_CONNECTION_UP_AND_CONFIGURED,
53 NCSI_CONNECTION_DISABLED,
54} ncsi_connection_state_t;
55
56typedef enum {
57 NCSI_RESPONSE_NONE,
58 NCSI_RESPONSE_ACK,
59 NCSI_RESPONSE_NACK,
60 NCSI_RESPONSE_UNDERSIZED,
61 NCSI_RESPONSE_UNEXPECTED_TYPE,
62 NCSI_RESPONSE_UNEXPECTED_SIZE,
63 NCSI_RESPONSE_OEM_FORMAT_ERROR,
64 NCSI_RESPONSE_TIMEOUT,
65 NCSI_RESPONSE_UNEXPECTED_PARAMS,
66} ncsi_response_type_t;
67
68// For NC-SI Rev 1.0.0, the management controller ID (mc_id) is 0.
69#define NCSI_MC_ID 0
70// For NC-SI Rev 1.0.0, the header revision is 0x01.
71#define NCSI_HEADER_REV 1
72#define NCSI_ETHERTYPE 0x88F8
73#define NCSI_RESPONSE 0x80
74
75// Command IDs
76enum {
77 NCSI_CLEAR_INITIAL_STATE,
78 NCSI_SELECT_PACKAGE,
79 NCSI_DESELECT_PACKAGE,
80 NCSI_ENABLE_CHANNEL,
81 NCSI_DISABLE_CHANNEL,
82 NCSI_RESET_CHANNEL,
83 NCSI_ENABLE_CHANNEL_NETWORK_TX,
84 NCSI_DISABLE_CHANNEL_NETWORK_TX,
85 NCSI_AEN_ENABLE,
86 NCSI_SET_LINK,
87 NCSI_GET_LINK_STATUS,
88 NCSI_SET_VLAN_FILTER,
89 NCSI_ENABLE_VLAN,
90 NCSI_DISABLE_VLAN,
91 NCSI_SET_MAC_ADDRESS,
92 // 0x0F is not a valid command
93 NCSI_ENABLE_BROADCAST_FILTER = 0x10,
94 NCSI_DISABLE_BROADCAST_FILTER,
95 NCSI_ENABLE_GLOBAL_MULTICAST_FILTER,
96 NCSI_DISABLE_GLOBAL_MULTICAST_FILTER,
97 NCSI_SET_NCSI_FLOW_CONTROL,
98 NCSI_GET_VERSION_ID,
99 NCSI_GET_CAPABILITIES,
100 NCSI_GET_PARAMETERS,
101 NCSI_GET_CONTROLLER_PACKET_STATISTICS,
102 NCSI_GET_NCSI_STATISTICS,
103 NCSI_GET_PASSTHROUGH_STATISTICS,
104 // 0x1B-0x4F are not valid commands
105 NCSI_OEM_COMMAND = 0x50,
106};
107// OEM Command IDs (subtypes of NCSI_OEM_COMMAND)
108#define NCSI_OEM_COMMAND_GET_HOST_MAC 0x00
109#define NCSI_OEM_COMMAND_SET_FILTER 0x01
110#define NCSI_OEM_COMMAND_GET_FILTER 0x02
111#define NCSI_OEM_COMMAND_ECHO 0x03
112
113#define NCSI_OEM_MANUFACTURER_ID 11129 // IANA Enterprise Number for Google.
114#define NCSI_OEM_ECHO_PATTERN_SIZE 64
115
116/*
117 * NCSI command frame with packet header as described in section 8.2.1.
118 * Prepended with an ethernet header.
119 */
120typedef struct __packed {
121 eth_hdr_t ethhdr;
122 uint8_t mc_id;
123 uint8_t header_revision;
124 uint8_t reserved_00;
125 uint8_t instance_id; // Destinguish retried commands from new ones.
126 uint8_t control_packet_type; // See section 8.3, and Table 17.
127 uint8_t channel_id;
128 uint16_t payload_length; // In Bytes. Excludes header, checksum, padding.
129 uint16_t reserved_01[4];
130} ncsi_header_t;
131
132/*
133 * Simple NCSI response packet.
134 */
135typedef struct __packed {
136 ncsi_header_t hdr;
137 uint16_t response_code;
138 uint16_t reason_code;
139} ncsi_simple_response_t;
140
141/*
142 * Simple NCSI command packet.
143 */
144typedef struct {
145 ncsi_header_t hdr;
146} ncsi_simple_command_t;
147
148/*
149 * Get Link Status Response. 8.4.24
150 */
151typedef struct __packed {
152 uint32_t link_status;
153 uint32_t other_indications;
154 uint32_t oem_link_status;
155} ncsi_link_status_t;
156
157typedef struct __packed {
158 ncsi_header_t hdr;
159 uint16_t response_code;
160 uint16_t reason_code;
161 ncsi_link_status_t link_status;
162} ncsi_link_status_response_t;
163
164#define NCSI_LINK_STATUS_UP (1 << 0)
165
166/*
167 * Set MAC Address packet. 8.4.31
168 */
169typedef struct __packed {
170 ncsi_header_t hdr;
171 mac_addr_t mac_addr;
172 uint8_t mac_addr_num;
173 uint8_t misc;
174} ncsi_set_mac_command_t;
175
176/*
177 * Enable Broadcast Filter packet. 8.4.33
178 */
179typedef struct __packed {
180 ncsi_header_t hdr;
181 uint32_t filter_settings;
182} ncsi_enable_broadcast_filter_command_t;
183
184#define NCSI_BROADCAST_FILTER_MASK_ARP (1 << 0)
185#define NCSI_BROADCAST_FILTER_MASK_DHCP_CLIENT (1 << 1)
186#define NCSI_BROADCAST_FILTER_MASK_DHCP_SERVER (1 << 2)
187#define NCSI_BROADCAST_FILTER_MASK_NETBIOS (1 << 3)
188
189/*
190 * Get Version ID Response. 8.4.44
191 */
192typedef struct __packed {
193 struct {
194 uint8_t major;
195 uint8_t minor;
196 uint8_t update;
197 uint8_t alpha1;
198 uint8_t reserved[3];
199 uint8_t alpha2;
200 } ncsi_version;
201 uint8_t firmware_name_string[12];
202 uint32_t firmware_version;
203 uint16_t pci_did;
204 uint16_t pci_vid;
205 uint16_t pci_ssid;
206 uint16_t pci_svid;
207 uint32_t manufacturer_id;
208} ncsi_version_id_t;
209
210typedef struct __packed {
211 ncsi_header_t hdr;
212 uint16_t response_code;
213 uint16_t reason_code;
214 ncsi_version_id_t version;
215} ncsi_version_id_response_t;
216
217/*
218 * Get Capabilities Response 8.4.46
219 */
220typedef struct __packed {
221 ncsi_header_t hdr;
222 uint16_t response_code;
223 uint16_t reason_code;
224 uint32_t capabilities_flags;
225 uint32_t broadcast_packet_filter_capabilties;
226 uint32_t multicast_packet_filter_capabilties;
227 uint32_t buffering_capability;
228 uint32_t aen_control_support;
229 uint8_t vlan_filter_count;
230 uint8_t mixed_filter_count;
231 uint8_t multicast_filter_count;
232 uint8_t unicast_filter_count;
233 uint16_t reserved;
234 uint8_t vlan_mode_support;
235 uint8_t channel_count;
236} ncsi_capabilities_response_t;
237
238/*
239 * Get Parameters Response 8.4.48
240 */
241typedef struct __packed {
242 ncsi_header_t hdr;
243 uint16_t response_code;
244 uint16_t reason_code;
245 // TODO: Note: Mellanox 1.4 FW has mac count swapped with mac flags.
246 uint8_t mac_address_count;
247 uint16_t reserved_01;
248 uint8_t mac_address_flags;
249 uint8_t vlan_tag_count;
250 uint8_t reserved_02;
251 uint16_t vlan_tag_flags;
252 uint32_t link_settings;
253 uint32_t broadcast_settings;
254 uint32_t configuration_flags;
255 uint8_t vlan_mode;
256 uint8_t flow_control_enable;
257 uint16_t reserved_03;
258 uint32_t aen_control;
259 mac_addr_t mac_address[2];
260 // TODO: Variable number of mac address filters (max 8. See 8.4.48)
261 uint16_t vlan_tags[2];
262 // TODO: Variable of vlan filters (up to 15 based on 8.4.48)
263} ncsi_parameters_response_t;
264
265/*
266 * Get Passthrough statistics response. 8.4.54
267 *
268 * The legacy data structure matches MLX implementation up to vX
269 * (Google vX), however the standard requires the first field to be
270 * 64bits and MLX fixed it in vX (Google vX).
271 *
272 */
273typedef struct __packed {
274 uint32_t tx_packets_received; // EC -> NIC
275 uint32_t tx_packets_dropped;
276 uint32_t tx_channel_errors;
277 uint32_t tx_undersized_errors;
278 uint32_t tx_oversized_errors;
279 uint32_t rx_packets_received; // Network -> NIC
280 uint32_t rx_packets_dropped;
281 uint32_t rx_channel_errors;
282 uint32_t rx_undersized_errors;
283 uint32_t rx_oversized_errors;
284} ncsi_passthrough_stats_legacy_t;
285
286typedef struct __packed {
287 uint32_t tx_packets_received_hi; // EC -> NIC (higher 32bit)
288 uint32_t tx_packets_received_lo; // EC -> NIC (lower 32bit)
289 uint32_t tx_packets_dropped;
290 uint32_t tx_channel_errors;
291 uint32_t tx_undersized_errors;
292 uint32_t tx_oversized_errors;
293 uint32_t rx_packets_received; // Network -> NIC
294 uint32_t rx_packets_dropped;
295 uint32_t rx_channel_errors;
296 uint32_t rx_undersized_errors;
297 uint32_t rx_oversized_errors;
298} ncsi_passthrough_stats_t;
299
300typedef struct __packed {
301 ncsi_header_t hdr;
302 uint16_t response_code;
303 uint16_t reason_code;
304 ncsi_passthrough_stats_legacy_t stats;
305} ncsi_passthrough_stats_legacy_response_t;
306
307typedef struct __packed {
308 ncsi_header_t hdr;
309 uint16_t response_code;
310 uint16_t reason_code;
311 ncsi_passthrough_stats_t stats;
312} ncsi_passthrough_stats_response_t;
313
314/*
315 * OEM extension header for custom commands.
316 */
317typedef struct __packed {
318 uint32_t manufacturer_id;
319 uint8_t reserved[3];
320 uint8_t oem_cmd;
321} ncsi_oem_extension_header_t;
322
323/*
324 * Response format for simple OEM command.
325 */
326typedef struct __packed {
327 ncsi_header_t hdr;
328 uint16_t response_code;
329 uint16_t reason_code;
330 ncsi_oem_extension_header_t oem_header;
331} ncsi_oem_simple_response_t;
332
333/*
334 * Response format for OEM get MAC command.
335 */
336typedef struct __packed {
337 ncsi_header_t hdr;
338 uint16_t response_code;
339 uint16_t reason_code;
340 ncsi_oem_extension_header_t oem_header;
341 uint16_t reserved0;
342 uint8_t mac[6];
343} ncsi_host_mac_response_t;
344
345/*
346 * Format for OEM filter.
347 */
348typedef struct __packed {
349 uint16_t reserved0;
350 uint8_t mac[6];
351 // If ip is set to zero, the filter will match any IP address, including any
352 // IPv6 address.
353 uint32_t ip; // Network order
354 uint16_t port; // Network order
355 uint8_t reserved1;
356 uint8_t flags;
357 uint8_t regid[8];
358} ncsi_oem_filter_t;
359
360// Set flags
361#define NCSI_OEM_FILTER_FLAGS_ENABLE (0x01)
362
363// Get flags
364#define NCSI_OEM_FILTER_FLAGS_ENABLED (0x01)
365#define NCSI_OEM_FILTER_FLAGS_REGISTERED (0x02)
366#define NCSI_OEM_FILTER_FLAGS_HOSTLESS (0x04)
367
368/*
369 * Command format for simple OEM command.
370 */
371typedef struct __packed {
372 ncsi_header_t hdr;
373 ncsi_oem_extension_header_t oem_header;
374} ncsi_oem_simple_cmd_t;
375
376/*
377 * Response format for OEM get filter command.
378 */
379typedef struct __packed {
380 ncsi_header_t hdr;
381 uint16_t response_code;
382 uint16_t reason_code;
383 ncsi_oem_extension_header_t oem_header;
384 ncsi_oem_filter_t filter;
385} ncsi_oem_get_filter_response_t;
386
387/*
388 * Command format for OEM set filter command.
389 */
390typedef struct __packed {
391 ncsi_header_t hdr;
392 ncsi_oem_extension_header_t oem_header;
393 ncsi_oem_filter_t filter;
394} ncsi_oem_set_filter_cmd_t;
395
396/*
397 * Command format for OEM echo command.
398 */
399typedef struct __packed {
400 ncsi_header_t hdr;
401 ncsi_oem_extension_header_t oem_header;
402 uint8_t pattern[NCSI_OEM_ECHO_PATTERN_SIZE];
403} ncsi_oem_echo_cmd_t;
404
405/*
406 * Response format for OEM echo command.
407 */
408typedef struct __packed {
409 ncsi_header_t hdr;
410 uint16_t response_code;
411 uint16_t reason_code;
412 ncsi_oem_extension_header_t oem_header;
413 uint8_t pattern[NCSI_OEM_ECHO_PATTERN_SIZE];
414} ncsi_oem_echo_response_t;
415
416#ifdef __cplusplus
417} /* extern "C" */
418#endif
419
420#endif // PLATFORMS_NEMORA_PORTABLE_NCSI_H_