-- 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 CX5 = require 'hardware_config.CX5'
local libmgmt_protocol = require 'libmgmt_protocol'

local utils = require 'mc.utils'
local log = require 'mc.logging'

-- CX_4_LX 比CX5多支持了LLDP使能开关
-- SP380
local CX_4_LX = {
    properties = {
        GetLLDPCapability = {
            protocol = 'ncsi_mellanox',
            action = 'on_schedule',
            period_in_sec = 5,
            request = {
                -- 运行时需传入channel_id(也就是port id)
                cmd_mellanox = 0x00,
                mellanox_cmd_id = 0x00,
                parameter = 0x2E,
                extra_cmd = 0x00
            },
            response = function(data)
                local r = bs.new([[<<
                    _:32,
                    lldp_nb:8
                >>]]):unpack(data, true)
                local lldp_nb_tx_offset<const> = 3
                local lldp_nb_tx_mode_all<const> = 2
                local lldp_enabled = ((r.lldp_nb >> lldp_nb_tx_offset) & lldp_nb_tx_mode_all) ~= 0
                return lldp_enabled
            end
        },
        SetOffLLDPCapability = {
            protocol = 'ncsi_mellanox',
            action = 'on_demand',
            request = {
                -- 运行时需传入channel_id(也就是port id)
                package_id = 0x00,
                cmd_mellanox = 0x00,
                mellanox_cmd_id = 0x01,
                parameter = 0x2E,
                extra_cmd = 0x00,
                data = string.rep('\x00', 3) .. '\x04' -- data，格式：00 00 00 lldp_nb(0x4是关，0x14是开)
            },
            response = function(data)
                local r = bs.new([[<<
                    _:32,
                    lldp_nb:8
                >>]]):unpack(data, true)
                local lldp_nb_tx_offset<const> = 3
                local lldp_nb_tx_mode_all<const> = 2
                local lldp_enabled = ((r.lldp_nb >> lldp_nb_tx_offset) & lldp_nb_tx_mode_all) ~= 0
                return lldp_enabled == false
            end
        },
        SetOnLLDPCapability = {
            protocol = 'ncsi_mellanox',
            action = 'on_demand',
            request = {
                -- 运行时需传入channel_id(也就是port id)
                package_id = 0x00,
                cmd_mellanox = 0x00,
                mellanox_cmd_id = 0x01,
                parameter = 0x2E,
                extra_cmd = 0x00,
                data = string.rep('\x00', 3) .. '\x14' -- data，格式：00 00 00 lldp_nb(0x4是关，0x14是开)
            },
            response = function(data)
                local r = bs.new([[<<
                    _:32,
                    lldp_nb:8
                >>]]):unpack(data, true)
                local lldp_nb_tx_offset<const> = 3
                local lldp_nb_tx_mode_all<const> = 2
                local lldp_enabled = ((r.lldp_nb >> lldp_nb_tx_offset) & lldp_nb_tx_mode_all) ~= 0
                return lldp_enabled == true
            end
        },
        ResetNic = {
            protocol = 'ncsi_mellanox',
            action = 'on_demand',
            request = {
                package_id = 0x00,
                channel_id = 0x1F, -- Mellanox厂商FAE建议reset nic命令channel_id设置为1F
                cmd_mellanox = 0x00,
                mellanox_cmd_id = 0x12,
                parameter = 0x0A,
                extra_cmd = 0x02
            },
            response = function(data)
                return true
            end
        }
    }
}

return {
    smbus = nil,
    mctp = function(endpoint)
        local cx5 = CX5.mctp(endpoint)
        for k, v in pairs(CX_4_LX.properties) do
            cx5.properties[k] = v
        end
        return cx5
    end
}

