1 /*
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 
17 #ifndef PLATFORMS_NEMORA_PORTABLE_NCSI_SERVER_H_
18 #define PLATFORMS_NEMORA_PORTABLE_NCSI_SERVER_H_
19 
20 /*
21  * Module for constructing NC-SI response commands on the NIC
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 <stdint.h>
28 
29 #include "platforms/nemora/portable/ncsi.h"
30 #include "platforms/nemora/portable/net_types.h"
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 /*
37  * Build the header for the response to the command in the buffer.
38  *
39  * Args:
40  *  request_buf: buffer containing NC-SI request.
41  *  response_buf: buffer, where to put the response. Must be big enough to fit
42  *    the response.
43  *  response_code: Response Code. Must be zero for ACK.
44  *  reason_code: Reason Code. Must be zero for ACK.
45  *  payload_length: size of a payload.
46  */
47 void ncsi_build_response_header(const uint8_t* request_buf,
48                                 uint8_t* response_buf, uint16_t response_code,
49                                 uint16_t reason_code, uint16_t payload_length);
50 
51 /*
52  * Construct simple ACK command in the buffer, given the buffer with the
53  * received command.
54  *
55  * Args:
56  *  request_buf: buffer containing NC-SI request.
57  *  response_buf: buffer, where to put the response. Must be big enough to fit
58  *    the response.
59  *
60  * Returns the size of the response in the buffer.
61  */
62 uint32_t ncsi_build_simple_ack(const uint8_t* request_buf,
63                                uint8_t* response_buf);
64 
65 /*
66  * Construct simple NACK command in the buffer, given the buffer with the
67  * received command.
68  *
69  * Args:
70  *  request_buf: buffer containing NC-SI request.
71  *  response_buf: buffer, where to put the response. Must be big enough to fit
72  *    the response.
73  *  response_code: Response Code
74  *  reason_code: Reason Code
75  *
76  * Returns the size of the response in the buffer.
77  */
78 uint32_t ncsi_build_simple_nack(const uint8_t* request_buf,
79                                 uint8_t* response_buf, uint16_t response_code,
80                                 uint16_t reason_code);
81 
82 /*
83  * Construct ACK command in the buffer, given the buffer with the
84  * received command, which in this case must be NCSI_GET_VERSION_ID command.
85  *
86  * Args:
87  *  request_buf: buffer containing NC-SI request.
88  *  response_buf: buffer, where to put the response. Must be big enough to fit
89  *    the response.
90  *  version_id: Version ID struct.
91  *
92  * Returns the size of the response in the buffer.
93  */
94 uint32_t ncsi_build_version_id_ack(const uint8_t* request_buf,
95                                    uint8_t* response_buf,
96                                    const ncsi_version_id_t* version_id);
97 
98 /*
99  * Construct OEM ACK command in the buffer, given the buffer with the
100  * received OEM command, which in this case must be
101  * NCSI_OEM_COMMAND_GET_HOST_MAC.
102  *
103  * Args:
104  *  request_buf: buffer containing NC-SI request.
105  *  response_buf: buffer, where to put the response. Must be big enough to fit
106  *    the response.
107  *  mac: NIC's MAC address.
108  *
109  * Returns the size of the response in the buffer.
110  */
111 uint32_t ncsi_build_oem_get_mac_ack(const uint8_t* request_buf,
112                                     uint8_t* response_buf,
113                                     const mac_addr_t* mac);
114 
115 /*
116  * Construct simple OEM ACK command in the buffer, given the buffer with the
117  * received command.
118  *
119  * Args:
120  *  request_buf: buffer containing NC-SI request.
121  *  response_buf: buffer, where to put the response. Must be big enough to fit
122  *    the response.
123  *
124  * Returns the size of the response in the buffer.
125  */
126 uint32_t ncsi_build_oem_simple_ack(const uint8_t* request_buf,
127                                    uint8_t* response_buf);
128 
129 /*
130  * Construct OEM ACK command in the buffer, given the buffer with the
131  * received command, which in this case must be NCSI_OEM_COMMAND_ECHO.
132  *
133  * Args:
134  *  request_buf: buffer containing NC-SI request.
135  *  response_buf: buffer, where to put the response. Must be big enough to fit
136  *    the response.
137  *
138  * Returns the size of the response in the buffer.
139  */
140 uint32_t ncsi_build_oem_echo_ack(const uint8_t* request_buf,
141                                  uint8_t* response_buf);
142 
143 /*
144  * Construct ACK response in the buffer, given the buffer with the
145  * received NCSI_OEM_COMMAND_GET_FILTER.
146  *
147  * Args:
148  *  request_buf: buffer containing NC-SI request.
149  *  response_buf: buffer, where to put the response. Must be big enough to fit
150  *    the response.
151  *  filter: active NIC traffic filter.
152  *
153  * Returns the size of the response in the buffer.
154  */
155 uint32_t ncsi_build_oem_get_filter_ack(const uint8_t* request_buf,
156                                        uint8_t* response_buf,
157                                        const ncsi_oem_filter_t* filter);
158 
159 /*
160  * Construct ACK response in the buffer, given the buffer with the
161  * received NCSI_GET_PASSTHROUGH_STATISTICS command.
162  *
163  * Args:
164  *  request_buf: buffer containing NC-SI request.
165  *  response_buf: buffer, where to put the response. Must be big enough to fit
166  *    the response.
167  *  stats: ncsi_passthrough_stats_t struct with stats.
168  *  TODO): it is not clear what is the endianness of the data in stats
169  *  struct. There does not seem to be any conversion on EC side.
170  *
171  * Returns the size of the response in the buffer.
172  */
173 uint32_t ncsi_build_pt_stats_ack(const uint8_t* request_buf,
174                                  uint8_t* response_buf,
175                                  const ncsi_passthrough_stats_t* stats);
176 
177 /*
178  * This function is similar to ncsi_build_pt_stats_ack, except that it simulates
179  * the bug in MLX X - X firmware. It should not be used outside of tests.
180  */
181 uint32_t ncsi_build_pt_stats_legacy_ack(
182     const uint8_t* request_buf, uint8_t* response_buf,
183     const ncsi_passthrough_stats_legacy_t* stats);
184 
185 /*
186  * Construct ACK response in the buffer, given the buffer with the
187  * received NCSI_GET_LINK_STATUS command.
188  *
189  * Args:
190  *  request_buf: buffer containing NC-SI request.
191  *  response_buf: buffer, where to put the response. Must be big enough to fit
192  *    the response.
193  *  link_status: ncsi_link_status_t struct.
194  *
195  * Returns the size of the response in the buffer.
196  */
197 uint32_t ncsi_build_link_status_ack(const uint8_t* request_buf,
198                                     uint8_t* response_buf,
199                                     const ncsi_link_status_t* link_status);
200 
201 #ifdef __cplusplus
202 }  /* extern "C" */
203 #endif
204 
205 #endif  // PLATFORMS_NEMORA_PORTABLE_NCSI_SERVER_H_
206