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