ncsid: Import from gBMC
This is the initial code drop from gBMC.
Google-Bug-Id: 179618516
Upstream: 1e71af914bc8c54d8b91d0a1cf377e2696713c2f
Change-Id: Ic653e8271dacd205e04f2bc713071ef2ec5936a4
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/ncsid/test/nic_mock.h b/ncsid/test/nic_mock.h
new file mode 100644
index 0000000..97a6737
--- /dev/null
+++ b/ncsid/test/nic_mock.h
@@ -0,0 +1,222 @@
+#pragma once
+
+#include "platforms/nemora/portable/ncsi.h"
+#include "platforms/nemora/portable/ncsi_fsm.h"
+#include "platforms/nemora/portable/ncsi_server.h"
+
+#include <netinet/in.h>
+
+#include <cstdint>
+#include <cstring>
+#include <vector>
+
+namespace mock
+{
+
+class NCSIFrame
+{
+ public:
+ mac_addr_t get_dst_mac() const
+ {
+ return dst_mac_;
+ }
+
+ mac_addr_t get_src_mac() const
+ {
+ return src_mac_;
+ }
+
+ uint16_t get_ethertype() const
+ {
+ return ethertype_;
+ }
+
+ bool is_ncsi() const
+ {
+ return ethertype_ == NCSI_ETHERTYPE;
+ }
+
+ uint8_t get_control_packet_type() const
+ {
+ return control_packet_type_;
+ }
+
+ void set_conrol_packet_type(uint8_t control_packet_type)
+ {
+ control_packet_type_ = control_packet_type;
+ }
+
+ bool is_oem_command() const
+ {
+ return control_packet_type_ == NCSI_OEM_COMMAND;
+ }
+
+ uint8_t get_channel_id() const
+ {
+ return channel_id_;
+ }
+
+ void set_channel_id(uint8_t channel_id)
+ {
+ channel_id_ = channel_id;
+ }
+
+ uint8_t get_oem_command() const
+ {
+ return oem_command_;
+ }
+
+ void set_oem_command(uint8_t oem_command)
+ {
+ set_conrol_packet_type(NCSI_OEM_COMMAND);
+ oem_command_ = oem_command;
+ }
+
+ uint32_t get_manufacturer_id() const
+ {
+ return manufacturer_id_;
+ }
+
+ std::vector<uint8_t>::size_type get_size() const
+ {
+ return packet_raw_.size();
+ }
+
+ bool is_response() const
+ {
+ return is_response_;
+ }
+
+ uint16_t get_response_code() const
+ {
+ return response_code_;
+ }
+
+ uint16_t get_reason_code() const
+ {
+ return reason_code_;
+ }
+
+ bool parse_ethernet_frame(const ncsi_buf_t& ncsi_buf);
+
+ private:
+ mac_addr_t dst_mac_;
+ mac_addr_t src_mac_;
+ uint16_t ethertype_ = NCSI_ETHERTYPE;
+ uint8_t control_packet_type_;
+ uint8_t channel_id_;
+ uint8_t oem_command_;
+ uint32_t manufacturer_id_;
+ uint16_t response_code_ = 0;
+ uint16_t reason_code_ = 0;
+ bool is_response_ = false;
+ std::vector<uint8_t> packet_raw_;
+};
+
+class NIC
+{
+ public:
+ explicit NIC(bool legacy = false, uint8_t channel_count = 1) :
+ channel_count_{channel_count}
+ {
+ if (legacy)
+ {
+ version_.firmware_version = htonl(0x08000000);
+ }
+ else
+ {
+ version_.firmware_version = 0xabcdef12;
+ }
+
+ is_legacy_ = legacy;
+
+ set_link_up();
+ }
+
+ void set_link_up()
+ {
+ link_status_.link_status |= htonl(NCSI_LINK_STATUS_UP);
+ }
+
+ void set_mac(const mac_addr_t& mac)
+ {
+ mac_ = mac;
+ }
+
+ mac_addr_t get_mac() const
+ {
+ return mac_;
+ }
+
+ uint8_t get_channel_count() const
+ {
+ return channel_count_;
+ }
+
+ // ????? NICs with Google firmware version ????
+ bool is_legacy() const
+ {
+ return is_legacy_;
+ }
+
+ uint32_t handle_request(const ncsi_buf_t& request_buf,
+ ncsi_buf_t* response_buf);
+
+ const std::vector<NCSIFrame>& get_command_log() const
+ {
+ return cmd_log_;
+ }
+
+ bool set_filter(uint8_t channel, const ncsi_oem_filter_t& filter);
+ const ncsi_oem_filter_t& get_filter(uint8_t channel) const;
+
+ void set_hostless(bool is_hostless);
+ void toggle_hostless();
+ bool is_hostless();
+
+ // The NIC itself does not really have a loopback. This is used to emulate
+ // the *absence* of NIC and loopback plug inserted.
+ void set_loopback()
+ {
+ is_loopback_ = true;
+ }
+
+ void reset_loopback()
+ {
+ is_loopback_ = false;
+ }
+
+ bool is_filter_configured(uint8_t channel) const;
+
+ private:
+ static const std::vector<uint8_t> simple_commands_;
+
+ uint32_t handle_oem_request(const ncsi_buf_t& request_buf,
+ ncsi_buf_t* response_buf);
+
+ void save_frame_to_log(const NCSIFrame& frame);
+
+ ncsi_version_id_t version_;
+ ncsi_oem_filter_t ch0_filter_;
+ ncsi_oem_filter_t ch1_filter_;
+ bool is_ch0_filter_configured_ = false;
+ bool is_ch1_filter_configured_ = false;
+ uint8_t channel_count_;
+ mac_addr_t mac_ = {{0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba}};
+ std::vector<NCSIFrame> cmd_log_;
+
+ /* If used in a continuous loop, cmd_log_ may grow too big over time.
+ * This constant determines how many (most recent) commands will be kept. */
+ const uint32_t max_log_size_ = 1000;
+
+ bool is_legacy_;
+ bool is_loopback_ = false;
+
+ // TODO: populate stats somehow.
+ ncsi_passthrough_stats_t stats_;
+ ncsi_passthrough_stats_legacy_t stats_legacy_;
+
+ ncsi_link_status_t link_status_;
+};
+
+} // namespace mock