1*1285115cSWilliam A. Kennington III /* 2*1285115cSWilliam A. Kennington III * Copyright 2021 Google LLC 3*1285115cSWilliam A. Kennington III * 4*1285115cSWilliam A. Kennington III * Licensed under the Apache License, Version 2.0 (the "License"); 5*1285115cSWilliam A. Kennington III * you may not use this file except in compliance with the License. 6*1285115cSWilliam A. Kennington III * You may obtain a copy of the License at 7*1285115cSWilliam A. Kennington III * 8*1285115cSWilliam A. Kennington III * http://www.apache.org/licenses/LICENSE-2.0 9*1285115cSWilliam A. Kennington III * 10*1285115cSWilliam A. Kennington III * Unless required by applicable law or agreed to in writing, software 11*1285115cSWilliam A. Kennington III * distributed under the License is distributed on an "AS IS" BASIS, 12*1285115cSWilliam A. Kennington III * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*1285115cSWilliam A. Kennington III * See the License for the specific language governing permissions and 14*1285115cSWilliam A. Kennington III * limitations under the License. 15*1285115cSWilliam A. Kennington III */ 16*1285115cSWilliam A. Kennington III 17*1285115cSWilliam A. Kennington III #pragma once 18*1285115cSWilliam A. Kennington III 19*1285115cSWilliam A. Kennington III #include "platforms/nemora/portable/ncsi.h" 20*1285115cSWilliam A. Kennington III #include "platforms/nemora/portable/ncsi_fsm.h" 21*1285115cSWilliam A. Kennington III #include "platforms/nemora/portable/ncsi_server.h" 22*1285115cSWilliam A. Kennington III 23*1285115cSWilliam A. Kennington III #include <netinet/in.h> 24*1285115cSWilliam A. Kennington III 25*1285115cSWilliam A. Kennington III #include <cstdint> 26*1285115cSWilliam A. Kennington III #include <cstring> 27*1285115cSWilliam A. Kennington III #include <vector> 28*1285115cSWilliam A. Kennington III 29*1285115cSWilliam A. Kennington III namespace mock 30*1285115cSWilliam A. Kennington III { 31*1285115cSWilliam A. Kennington III 32*1285115cSWilliam A. Kennington III class NCSIFrame 33*1285115cSWilliam A. Kennington III { 34*1285115cSWilliam A. Kennington III public: 35*1285115cSWilliam A. Kennington III mac_addr_t get_dst_mac() const 36*1285115cSWilliam A. Kennington III { 37*1285115cSWilliam A. Kennington III return dst_mac_; 38*1285115cSWilliam A. Kennington III } 39*1285115cSWilliam A. Kennington III 40*1285115cSWilliam A. Kennington III mac_addr_t get_src_mac() const 41*1285115cSWilliam A. Kennington III { 42*1285115cSWilliam A. Kennington III return src_mac_; 43*1285115cSWilliam A. Kennington III } 44*1285115cSWilliam A. Kennington III 45*1285115cSWilliam A. Kennington III uint16_t get_ethertype() const 46*1285115cSWilliam A. Kennington III { 47*1285115cSWilliam A. Kennington III return ethertype_; 48*1285115cSWilliam A. Kennington III } 49*1285115cSWilliam A. Kennington III 50*1285115cSWilliam A. Kennington III bool is_ncsi() const 51*1285115cSWilliam A. Kennington III { 52*1285115cSWilliam A. Kennington III return ethertype_ == NCSI_ETHERTYPE; 53*1285115cSWilliam A. Kennington III } 54*1285115cSWilliam A. Kennington III 55*1285115cSWilliam A. Kennington III uint8_t get_control_packet_type() const 56*1285115cSWilliam A. Kennington III { 57*1285115cSWilliam A. Kennington III return control_packet_type_; 58*1285115cSWilliam A. Kennington III } 59*1285115cSWilliam A. Kennington III 60*1285115cSWilliam A. Kennington III void set_conrol_packet_type(uint8_t control_packet_type) 61*1285115cSWilliam A. Kennington III { 62*1285115cSWilliam A. Kennington III control_packet_type_ = control_packet_type; 63*1285115cSWilliam A. Kennington III } 64*1285115cSWilliam A. Kennington III 65*1285115cSWilliam A. Kennington III bool is_oem_command() const 66*1285115cSWilliam A. Kennington III { 67*1285115cSWilliam A. Kennington III return control_packet_type_ == NCSI_OEM_COMMAND; 68*1285115cSWilliam A. Kennington III } 69*1285115cSWilliam A. Kennington III 70*1285115cSWilliam A. Kennington III uint8_t get_channel_id() const 71*1285115cSWilliam A. Kennington III { 72*1285115cSWilliam A. Kennington III return channel_id_; 73*1285115cSWilliam A. Kennington III } 74*1285115cSWilliam A. Kennington III 75*1285115cSWilliam A. Kennington III void set_channel_id(uint8_t channel_id) 76*1285115cSWilliam A. Kennington III { 77*1285115cSWilliam A. Kennington III channel_id_ = channel_id; 78*1285115cSWilliam A. Kennington III } 79*1285115cSWilliam A. Kennington III 80*1285115cSWilliam A. Kennington III uint8_t get_oem_command() const 81*1285115cSWilliam A. Kennington III { 82*1285115cSWilliam A. Kennington III return oem_command_; 83*1285115cSWilliam A. Kennington III } 84*1285115cSWilliam A. Kennington III 85*1285115cSWilliam A. Kennington III void set_oem_command(uint8_t oem_command) 86*1285115cSWilliam A. Kennington III { 87*1285115cSWilliam A. Kennington III set_conrol_packet_type(NCSI_OEM_COMMAND); 88*1285115cSWilliam A. Kennington III oem_command_ = oem_command; 89*1285115cSWilliam A. Kennington III } 90*1285115cSWilliam A. Kennington III 91*1285115cSWilliam A. Kennington III uint32_t get_manufacturer_id() const 92*1285115cSWilliam A. Kennington III { 93*1285115cSWilliam A. Kennington III return manufacturer_id_; 94*1285115cSWilliam A. Kennington III } 95*1285115cSWilliam A. Kennington III 96*1285115cSWilliam A. Kennington III std::vector<uint8_t>::size_type get_size() const 97*1285115cSWilliam A. Kennington III { 98*1285115cSWilliam A. Kennington III return packet_raw_.size(); 99*1285115cSWilliam A. Kennington III } 100*1285115cSWilliam A. Kennington III 101*1285115cSWilliam A. Kennington III bool is_response() const 102*1285115cSWilliam A. Kennington III { 103*1285115cSWilliam A. Kennington III return is_response_; 104*1285115cSWilliam A. Kennington III } 105*1285115cSWilliam A. Kennington III 106*1285115cSWilliam A. Kennington III uint16_t get_response_code() const 107*1285115cSWilliam A. Kennington III { 108*1285115cSWilliam A. Kennington III return response_code_; 109*1285115cSWilliam A. Kennington III } 110*1285115cSWilliam A. Kennington III 111*1285115cSWilliam A. Kennington III uint16_t get_reason_code() const 112*1285115cSWilliam A. Kennington III { 113*1285115cSWilliam A. Kennington III return reason_code_; 114*1285115cSWilliam A. Kennington III } 115*1285115cSWilliam A. Kennington III 116*1285115cSWilliam A. Kennington III bool parse_ethernet_frame(const ncsi_buf_t& ncsi_buf); 117*1285115cSWilliam A. Kennington III 118*1285115cSWilliam A. Kennington III private: 119*1285115cSWilliam A. Kennington III mac_addr_t dst_mac_; 120*1285115cSWilliam A. Kennington III mac_addr_t src_mac_; 121*1285115cSWilliam A. Kennington III uint16_t ethertype_ = NCSI_ETHERTYPE; 122*1285115cSWilliam A. Kennington III uint8_t control_packet_type_; 123*1285115cSWilliam A. Kennington III uint8_t channel_id_; 124*1285115cSWilliam A. Kennington III uint8_t oem_command_; 125*1285115cSWilliam A. Kennington III uint32_t manufacturer_id_; 126*1285115cSWilliam A. Kennington III uint16_t response_code_ = 0; 127*1285115cSWilliam A. Kennington III uint16_t reason_code_ = 0; 128*1285115cSWilliam A. Kennington III bool is_response_ = false; 129*1285115cSWilliam A. Kennington III std::vector<uint8_t> packet_raw_; 130*1285115cSWilliam A. Kennington III }; 131*1285115cSWilliam A. Kennington III 132*1285115cSWilliam A. Kennington III class NIC 133*1285115cSWilliam A. Kennington III { 134*1285115cSWilliam A. Kennington III public: 135*1285115cSWilliam A. Kennington III explicit NIC(bool legacy = false, uint8_t channel_count = 1) : 136*1285115cSWilliam A. Kennington III channel_count_{channel_count} 137*1285115cSWilliam A. Kennington III { 138*1285115cSWilliam A. Kennington III if (legacy) 139*1285115cSWilliam A. Kennington III { 140*1285115cSWilliam A. Kennington III version_.firmware_version = htonl(0x08000000); 141*1285115cSWilliam A. Kennington III } 142*1285115cSWilliam A. Kennington III else 143*1285115cSWilliam A. Kennington III { 144*1285115cSWilliam A. Kennington III version_.firmware_version = 0xabcdef12; 145*1285115cSWilliam A. Kennington III } 146*1285115cSWilliam A. Kennington III 147*1285115cSWilliam A. Kennington III is_legacy_ = legacy; 148*1285115cSWilliam A. Kennington III 149*1285115cSWilliam A. Kennington III set_link_up(); 150*1285115cSWilliam A. Kennington III } 151*1285115cSWilliam A. Kennington III 152*1285115cSWilliam A. Kennington III void set_link_up() 153*1285115cSWilliam A. Kennington III { 154*1285115cSWilliam A. Kennington III link_status_.link_status |= htonl(NCSI_LINK_STATUS_UP); 155*1285115cSWilliam A. Kennington III } 156*1285115cSWilliam A. Kennington III 157*1285115cSWilliam A. Kennington III void set_mac(const mac_addr_t& mac) 158*1285115cSWilliam A. Kennington III { 159*1285115cSWilliam A. Kennington III mac_ = mac; 160*1285115cSWilliam A. Kennington III } 161*1285115cSWilliam A. Kennington III 162*1285115cSWilliam A. Kennington III mac_addr_t get_mac() const 163*1285115cSWilliam A. Kennington III { 164*1285115cSWilliam A. Kennington III return mac_; 165*1285115cSWilliam A. Kennington III } 166*1285115cSWilliam A. Kennington III 167*1285115cSWilliam A. Kennington III uint8_t get_channel_count() const 168*1285115cSWilliam A. Kennington III { 169*1285115cSWilliam A. Kennington III return channel_count_; 170*1285115cSWilliam A. Kennington III } 171*1285115cSWilliam A. Kennington III 172*1285115cSWilliam A. Kennington III // ????? NICs with Google firmware version ???? 173*1285115cSWilliam A. Kennington III bool is_legacy() const 174*1285115cSWilliam A. Kennington III { 175*1285115cSWilliam A. Kennington III return is_legacy_; 176*1285115cSWilliam A. Kennington III } 177*1285115cSWilliam A. Kennington III 178*1285115cSWilliam A. Kennington III uint32_t handle_request(const ncsi_buf_t& request_buf, 179*1285115cSWilliam A. Kennington III ncsi_buf_t* response_buf); 180*1285115cSWilliam A. Kennington III 181*1285115cSWilliam A. Kennington III const std::vector<NCSIFrame>& get_command_log() const 182*1285115cSWilliam A. Kennington III { 183*1285115cSWilliam A. Kennington III return cmd_log_; 184*1285115cSWilliam A. Kennington III } 185*1285115cSWilliam A. Kennington III 186*1285115cSWilliam A. Kennington III bool set_filter(uint8_t channel, const ncsi_oem_filter_t& filter); 187*1285115cSWilliam A. Kennington III const ncsi_oem_filter_t& get_filter(uint8_t channel) const; 188*1285115cSWilliam A. Kennington III 189*1285115cSWilliam A. Kennington III void set_hostless(bool is_hostless); 190*1285115cSWilliam A. Kennington III void toggle_hostless(); 191*1285115cSWilliam A. Kennington III bool is_hostless(); 192*1285115cSWilliam A. Kennington III 193*1285115cSWilliam A. Kennington III // The NIC itself does not really have a loopback. This is used to emulate 194*1285115cSWilliam A. Kennington III // the *absence* of NIC and loopback plug inserted. 195*1285115cSWilliam A. Kennington III void set_loopback() 196*1285115cSWilliam A. Kennington III { 197*1285115cSWilliam A. Kennington III is_loopback_ = true; 198*1285115cSWilliam A. Kennington III } 199*1285115cSWilliam A. Kennington III 200*1285115cSWilliam A. Kennington III void reset_loopback() 201*1285115cSWilliam A. Kennington III { 202*1285115cSWilliam A. Kennington III is_loopback_ = false; 203*1285115cSWilliam A. Kennington III } 204*1285115cSWilliam A. Kennington III 205*1285115cSWilliam A. Kennington III bool is_filter_configured(uint8_t channel) const; 206*1285115cSWilliam A. Kennington III 207*1285115cSWilliam A. Kennington III private: 208*1285115cSWilliam A. Kennington III static const std::vector<uint8_t> simple_commands_; 209*1285115cSWilliam A. Kennington III 210*1285115cSWilliam A. Kennington III uint32_t handle_oem_request(const ncsi_buf_t& request_buf, 211*1285115cSWilliam A. Kennington III ncsi_buf_t* response_buf); 212*1285115cSWilliam A. Kennington III 213*1285115cSWilliam A. Kennington III void save_frame_to_log(const NCSIFrame& frame); 214*1285115cSWilliam A. Kennington III 215*1285115cSWilliam A. Kennington III ncsi_version_id_t version_; 216*1285115cSWilliam A. Kennington III ncsi_oem_filter_t ch0_filter_; 217*1285115cSWilliam A. Kennington III ncsi_oem_filter_t ch1_filter_; 218*1285115cSWilliam A. Kennington III bool is_ch0_filter_configured_ = false; 219*1285115cSWilliam A. Kennington III bool is_ch1_filter_configured_ = false; 220*1285115cSWilliam A. Kennington III uint8_t channel_count_; 221*1285115cSWilliam A. Kennington III mac_addr_t mac_ = {{0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba}}; 222*1285115cSWilliam A. Kennington III std::vector<NCSIFrame> cmd_log_; 223*1285115cSWilliam A. Kennington III 224*1285115cSWilliam A. Kennington III /* If used in a continuous loop, cmd_log_ may grow too big over time. 225*1285115cSWilliam A. Kennington III * This constant determines how many (most recent) commands will be kept. */ 226*1285115cSWilliam A. Kennington III const uint32_t max_log_size_ = 1000; 227*1285115cSWilliam A. Kennington III 228*1285115cSWilliam A. Kennington III bool is_legacy_; 229*1285115cSWilliam A. Kennington III bool is_loopback_ = false; 230*1285115cSWilliam A. Kennington III 231*1285115cSWilliam A. Kennington III // TODO: populate stats somehow. 232*1285115cSWilliam A. Kennington III ncsi_passthrough_stats_t stats_; 233*1285115cSWilliam A. Kennington III ncsi_passthrough_stats_legacy_t stats_legacy_; 234*1285115cSWilliam A. Kennington III 235*1285115cSWilliam A. Kennington III ncsi_link_status_t link_status_; 236*1285115cSWilliam A. Kennington III }; 237*1285115cSWilliam A. Kennington III 238*1285115cSWilliam A. Kennington III } // namespace mock 239