/* Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
 * 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.
 */
 
#include "sml_errcodes.h"
#include "vendor.h"
 
#define LSI_STORELIB_TYPE_MR    0
#define LSI_STORELIB_TYPE_IR1   1
#define LSI_STORELIB_TYPE_IR2   2
#define LSI_STORELIB_TYPE_IR3   4
#define LSI_STORELIB_TYPE_IT    5
#define LSI_STORELIB_TYPE_CUSTOM    6
#define LSI_IT_CHIP_SLAVE_ADDRESS 0x05 // 7bit i2c slave address
 
#define EID_OFFSET 8
#define PHY_ADDR_OFFSET 16
 
static const SML_CTRL_ID g_sml_lsi_ctrl[] = {
#ifdef ITEST_ENABLED
    {ITEST_SIMULATE, VENDER_ITEST_SIMULATE, 0},
#endif
    {LSI_3004_WITH_IMR, VENDER_LSI,  (LSI_STORELIB_TYPE_MR << TYPE_OFFSET) | ((LSI_3004_WITH_IMR & 0x7F) << 16)},
    {LSI_3108_WITH_IT, VENDER_LSI, (LSI_STORELIB_TYPE_IR3 << TYPE_OFFSET) | (LSI_IT_CHIP_SLAVE_ADDRESS << 8)},
    {LSI_3008_WITH_IT, VENDER_LSI, (LSI_STORELIB_TYPE_IR3 << TYPE_OFFSET) | (LSI_IT_CHIP_SLAVE_ADDRESS << 8)},
    {LSI_3008_WITH_IT_PCIE, VENDER_LSI, (LSI_STORELIB_TYPE_IR3 << TYPE_OFFSET) | (LSI_IT_CHIP_SLAVE_ADDRESS << 8)},
    {LSI_3408_WITH_IT, VENDER_LSI, (LSI_STORELIB_TYPE_IT << TYPE_OFFSET) | (LSI_IT_CHIP_SLAVE_ADDRESS << 8)},
    {LSI_3416_WITH_IT, VENDER_LSI, (LSI_STORELIB_TYPE_IT << TYPE_OFFSET) | (LSI_IT_CHIP_SLAVE_ADDRESS << 8)},
    {LSI_3808_WITH_IT, VENDER_LSI, (LSI_STORELIB_TYPE_IT << TYPE_OFFSET) | (LSI_IT_CHIP_SLAVE_ADDRESS << 8)},
    {LSI_3816_WITH_IT, VENDER_LSI, (LSI_STORELIB_TYPE_IT << TYPE_OFFSET) | (LSI_IT_CHIP_SLAVE_ADDRESS << 8)},
    {LSI_3108_WITH_MR, VENDER_LSI, LSI_STORELIB_TYPE_MR << TYPE_OFFSET},
    {LSI_3008_WITH_MR, VENDER_LSI, LSI_STORELIB_TYPE_MR << TYPE_OFFSET},
    {LSI_3508_WITH_MR, VENDER_LSI, LSI_STORELIB_TYPE_MR << TYPE_OFFSET},
    {LSI_3516_WITH_MR, VENDER_LSI, LSI_STORELIB_TYPE_MR << TYPE_OFFSET},
    {LSI_3408_WITH_IMR, VENDER_LSI, LSI_STORELIB_TYPE_MR << TYPE_OFFSET},
    {LSI_3416_WITH_IMR, VENDER_LSI, LSI_STORELIB_TYPE_MR << TYPE_OFFSET},
    {LSI_3908_WITH_MR, VENDER_LSI, LSI_STORELIB_TYPE_MR << TYPE_OFFSET},
    {LSI_3916_WITH_MR, VENDER_LSI, LSI_STORELIB_TYPE_MR << TYPE_OFFSET},
    {LSI_3808_WITH_MR, VENDER_LSI, LSI_STORELIB_TYPE_MR << TYPE_OFFSET},
    {LSI_3816_WITH_IMR, VENDER_LSI, LSI_STORELIB_TYPE_MR << TYPE_OFFSET},
    {LSI_3808_WITH_IMR, VENDER_LSI, LSI_STORELIB_TYPE_MR << TYPE_OFFSET}
};
/*
 Description: lsi构建控制器id
 */
gint32 construct_ctrl_id(SML_CTRL_OOB_INFO_S *ctrl, guint32 *controller_id, gint8 *vender_index)
{
    guint8 ctrl_index = ctrl->i_controller_index;
    guint8 ctrl_typeid = ctrl->i_controller_typeid;
    guint8 ctrl_eid = ctrl->register_info.over_mctp.eid;
    guint16 ctrl_phy_addr = ctrl->register_info.over_mctp.phy_addr;
 
    // 根据typeid组装controllerID
    guint8 size = (guint8)G_N_ELEMENTS(g_sml_lsi_ctrl);
    for (guint8 i = 0; i < size; i++) {
        if (ctrl_typeid == g_sml_lsi_ctrl[i].type_id) {
            *controller_id = g_sml_lsi_ctrl[i].controller_id | ctrl_index;
            *vender_index = g_sml_lsi_ctrl[i].vendor_id;
            return SML_SUCCESS;
        }
    }

    if (ctrl_typeid == PMC_3152_8I_SMART_RAID || ctrl_typeid == PMC_2100_8I_SMART_HBA) {
        *controller_id = (ctrl_phy_addr << PHY_ADDR_OFFSET) | (ctrl_eid << EID_OFFSET) | ctrl_index;
        *vender_index = VENDER_PMC;
        return SML_SUCCESS;
    }

    if (ctrl_typeid == LSI_CUSTOM_TYPE_ID) {
        *controller_id = (LSI_STORELIB_TYPE_CUSTOM << TYPE_OFFSET);
        *vender_index = VENDER_LSI;
        return SML_SUCCESS;
    }

    return SML_ERR_CTRL_PARAM_ILLEGAL;
}