-- 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 log = require 'mc.logging'
local class = require 'mc.class'
local singleton = require 'mc.singleton'
local skynet = require 'skynet'

local ncsi_parameter = class()

local NCSI_CHANNEL_MAX_ID = 4 -- channel从0开始，最大为3
local NCSI_PACKAGE_MAX_ID = 8
local MAX_ETH_NUM = 16

-- 初始化NCSI参数
function ncsi_parameter:init_ncsi_parameter()
    self.g_ncsi_parameter = {
        recv_buf = '',
        send_buf = '',
        iid = 1, -- 有效范围:1 - 255
        package_exist = {},
        channel_exist = {},
        ncsi_ver = '',
        firmware_ver = '',
        firmware_name = '',
        current_channel = 0,
        manufacture_id = 0,
        channel_cap = {},  -- 通道能力
        link_status = {},  -- 链路状态
        oem_link_status = {},  -- OEM链路状态
        pcie_device_ids = {  -- PCI设备ID
            pci_did = 0,
            pci_vid = 0,
            pci_ssid = 0,
            pci_svid = 0
        },
        multicast_filter_cap = 0,
        channel_cnt = 0
    }

    -- 初始化package和channel数组
    for i = 0, NCSI_PACKAGE_MAX_ID - 1 do
        self.g_ncsi_parameter.package_exist[i] = 0
        self.g_ncsi_parameter.channel_exist[i] = {}
        self.g_ncsi_parameter.channel_cap[i] = {}
        for j = 0, NCSI_CHANNEL_MAX_ID - 1 do
            self.g_ncsi_parameter.channel_exist[i][j] = 0
            self.g_ncsi_parameter.channel_cap[i][j] = {
                capbility_flag = {  -- 通道支持的可选特性
                    hard_arbition_sup = 0,  -- 硬件仲裁支持
                    OS_presence_sup = 0,    -- OS存在支持
                    n_m_flow_ctrl_sup = 0,  -- N-M流控制支持
                    m_n_flow_ctrl_sup = 0,  -- M-N流控制支持
                    multicast_sup = 0,      -- 多播支持
                    reserved = 0            -- 保留字段
                },
                broadcast_filter_capality = {  -- 广播包过滤能力
                    reserved1 = {0, 0, 0},     -- 保留字段1
                    arp_packet = 0,            -- ARP包过滤
                    dhcp_client_packet = 0,    -- DHCP客户端包过滤
                    dhcp_server_packet = 0,    -- DHCP服务器包过滤
                    netbios_packet = 0,        -- NetBIOS包过滤
                    reserved2 = 0              -- 保留字段2
                },
                multicast_filter_capality = 0,  -- 多播包过滤能力
                buffer_capality = 0,  -- 入站数据包缓冲能力
                aen_support = 0,  -- 支持的AEN类型
                vlan_filter_cnt = 0,  -- VLAN过滤器数量
                mix_filter_cnt = 0,  -- 混合地址过滤器数量
                mul_filter_cnt = 0,  -- 多播MAC地址过滤器数量
                unicast_filter_cnt = 0,  -- 单播MAC地址过滤器数量
                reserved = {0, 0},  -- 保留字段
                vlan_mode = 0,  -- VLAN模式
                channel_cnt = 0  -- 支持的通道数量
            }
        end
    end

    -- 初始化链路状态数组
    for i = 0, MAX_ETH_NUM - 1 do
        self.g_ncsi_parameter.link_status[i] = {}
        self.g_ncsi_parameter.oem_link_status[i] = {}
        for j = 0, NCSI_CHANNEL_MAX_ID - 1 do
            self.g_ncsi_parameter.link_status[i][j] = {
                reserved3 = 0,
                tx_flow_control = 0,  -- 发送流控制
                rx_flow_control = 0,  -- 接收流控制
                link_partner8 = 0,  -- 链路伙伴8
                serdes_link = 0,  -- SerDes链路
                oem_link_speed = 0,  -- OEM链路速度
                reserved2 = 0,
                channel_available = 0,  -- 通道可用
                link_partner1 = 0,  -- 链路伙伴1
                link_partner2 = 0,  -- 链路伙伴2
                link_partner3 = 0,  -- 链路伙伴3
                link_partner4 = 0,  -- 链路伙伴4
                link_partner5 = 0,  -- 链路伙伴5
                link_partner6 = 0,  -- 链路伙伴6
                link_partner7 = 0,  -- 链路伙伴7
                link_flag = 0,  -- 链路标志
                speed_duplex = 0,  -- 速度和双工
                negotiate_flag = 0,  -- 协商标志
                negotiate_complete = 0,  -- 协商完成
                parallel_detection = 0  -- 并行检测
            }
            self.g_ncsi_parameter.oem_link_status[i][j] = 0
        end
    end
end

-- 获取NCSI参数
function ncsi_parameter:get_ncsi_parameter()
    return self.g_ncsi_parameter
end

function ncsi_parameter:ctor()
    log:notice('create g_ncsi_parameter')
    self.g_ncsi_parameter = {}

end

pcall(function()
    skynet.register_protocol({
        name = 'ncsi_packet_recv',
        id = 251,
        pack = skynet.pack,
        unpack = skynet.unpack
    })
end)

function ncsi_parameter:init()
    skynet.dispatch('ncsi_packet_recv', function(_, _, key, value)
        if key == 'data' then
            self.g_ncsi_parameter.recv_buf = value
        end
    end)
end

return singleton(ncsi_parameter)