-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

local bs = require 'mc.bitstring'
local log = require 'mc.logging'
local core = require 'network.core'
local ncsi_protocol_intf = require 'ncsi_protocol_intf'
local ncsi_utils = require 'ncsi.ncsi_protocol.ncsi_utils'
local ncsi_def = require 'ncsi.ncsi_protocol.ncsi_def'
local ncsi_packet = require 'ncsi.ncsi_protocol.ncsi_packet'
local ncsi_parameter = require 'ncsi.ncsi_protocol.ncsi_parameter'

local ncsi_clear_state = {}

local CLEAR_INITIAL_STATE = 0x00
local CLEAR_INITIAL_STATE_RSP = 0x80
local CLEAR_INITIAL_REQ_LEN = 0
local CLEAR_INITIAL_PKT_SIZE = 34
local CHANNEL_SUPPORT = 1

local clear_initial_state_req_bs = bs.new([[<<
    check_sum:32,
    data:26/string,
    fcs:32
>>]])

local function write_clear_initial_state_req(req_packet, eth_name)
    ncsi_utils.ncsi_cmd_common_config(req_packet)
    req_packet.packet_head.payload_len_hi = (CLEAR_INITIAL_REQ_LEN >> 8) & 0x0f
    req_packet.packet_head.payload_len_lo = CLEAR_INITIAL_REQ_LEN & 0xff

    local check_sum = ncsi_utils.get_checksum(req_packet, ncsi_def.PACKET_HEAD_LEN + CLEAR_INITIAL_REQ_LEN)
    local crc32 = ncsi_utils.get_crc32(req_packet, ncsi_def.PACKET_HEAD_LEN + CLEAR_INITIAL_PKT_SIZE - 4)
    local payload_data = clear_initial_state_req_bs:pack({
        check_sum = core.htonl(check_sum),
        data = '',
        fcs = core.htonl(crc32)
    })
    req_packet.payload = payload_data
    local req_data = ncsi_utils.ncsi_packet_bs:pack(req_packet)
    return ncsi_protocol_intf.send_ncsi_cmd(req_data, 
        CLEAR_INITIAL_PKT_SIZE + ncsi_def.ETHERNET_HEAD_LEN + ncsi_def.PACKET_HEAD_LEN, eth_name)
end

local function read_clear_initial_state_rsp(rsp)
    return ncsi_packet.read_common_rsp(rsp, 'clear initial state')
end

local clear_initial_state_table = {
    [CLEAR_INITIAL_STATE] = write_clear_initial_state_req,
    [CLEAR_INITIAL_STATE_RSP] = read_clear_initial_state_rsp
}

function ncsi_clear_state.ncsi_clear_initial_state(package_id, channel_id, eth_name)
    local req_packet = ncsi_packet.create_request_packet(package_id, channel_id, CLEAR_INITIAL_STATE)

    local ret = ncsi_utils.ncsi_cmd_ctrl(package_id, channel_id, req_packet, eth_name, clear_initial_state_table)
    if ret ~= ncsi_def.NCSI_SUCCESS then
        log:error('ncsi cmd ctrl clear initial state failed, package_id = %s, channel_id = %s, eth_name = %s',
            package_id, channel_id, eth_name)
    else
        ncsi_parameter.get_instance():get_ncsi_parameter().channel_exist[package_id][channel_id] = CHANNEL_SUPPORT
    end
    return ret
end

return ncsi_clear_state